swaroop: allowed-shows state in playlist.
authorCarl Hetherington <cth@carlh.net>
Sun, 9 Jun 2019 22:59:12 +0000 (23:59 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 9 Jun 2019 22:59:12 +0000 (23:59 +0100)
src/lib/spl.cc
src/lib/spl.h
src/tools/dcpomatic_playlist.cc
src/wx/swaroop_controls.cc
src/wx/swaroop_controls.h

index cd33c4047815386ec7ef524872e2fd06619e198e..e8e86f89ce227b401c4ade2210e176bdd45dec1d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 #include "spl.h"
 #include "content_store.h"
 #include <libcxml/cxml.h>
+#include <dcp/raw_convert.h>
 #include <libxml++/libxml++.h>
 #include <boost/foreach.hpp>
 #include <iostream>
 
 using std::cout;
+using std::string;
 using boost::shared_ptr;
+using dcp::raw_convert;
 
 void
 SPL::read (boost::filesystem::path path, ContentStore* store)
 {
+       _path = path;
+
        _spl.clear ();
        _missing = false;
        cxml::Document doc ("SPL");
@@ -45,17 +50,22 @@ SPL::read (boost::filesystem::path path, ContentStore* store)
                }
        }
 
-       _name = path.filename().string();
+       _allowed_shows = doc.optional_number_child<int>("AllowedShows");
 }
 
 void
 SPL::write (boost::filesystem::path path) const
 {
+       _path = path;
+
        xmlpp::Document doc;
        xmlpp::Element* root = doc.create_root_node ("SPL");
        root->add_child("Id")->add_child_text (_id);
        BOOST_FOREACH (SPLEntry i, _spl) {
                i.as_xml (root->add_child("Entry"));
        }
+       if (_allowed_shows) {
+               root->add_child("AllowedShows")->add_child_text(raw_convert<string>(*_allowed_shows));
+       }
        doc.write_to_file_formatted (path.string());
 }
index b19ef7e7a1c9f9d7e267a2aab9a9e1ad18a87b93..18892993fcb1575cd8695339fa10ce03a0e1c7b7 100644 (file)
@@ -61,20 +61,52 @@ public:
                return _id;
        }
 
+       boost::optional<boost::filesystem::path> path () const {
+               return _path;
+       }
+
        std::string name () const {
-               return _name;
+               if (!_path) {
+                       return "";
+               }
+               return _path->filename().string();
        }
 
        bool missing () const {
                return _missing;
        }
 
+       boost::optional<int> allowed_shows () const {
+               return _allowed_shows;
+       }
+
+       bool have_allowed_shows () const {
+               return !_allowed_shows || *_allowed_shows > 0;
+       }
+
+       void set_allowed_shows (int s) {
+               _allowed_shows = s;
+       }
+
+       void unset_allowed_shows () {
+               _allowed_shows = boost::optional<int>();
+       }
+
+       void decrement_allowed_shows () {
+               if (_allowed_shows) {
+                       (*_allowed_shows)--;
+               }
+
+       }
+
 private:
        std::string _id;
-       std::string _name;
+       mutable boost::optional<boost::filesystem::path> _path;
        std::vector<SPLEntry> _spl;
        /** true if any content was missing when read() was last called on this SPL */
        bool _missing;
+       /** number of times left that the player will allow this playlist to be played (unset means infinite shows) */
+       boost::optional<int> _allowed_shows;
 };
 
 #endif
index 64549765fd8acad416c823bf3fdc69694c519a39..de6ae107b36883bdc05914a5c044ccf30482779e 100644 (file)
@@ -32,6 +32,7 @@
 #include <wx/wx.h>
 #include <wx/listctrl.h>
 #include <wx/imaglist.h>
+#include <wx/spinctrl.h>
 #ifdef __WXOSX__
 #include <ApplicationServices/ApplicationServices.h>
 #endif
@@ -92,7 +93,7 @@ public:
                   the dark-grey background on Windows.
                */
                wxPanel* overall_panel = new wxPanel (this, wxID_ANY);
-               wxBoxSizer* main_sizer = new wxBoxSizer (wxHORIZONTAL);
+               wxBoxSizer* h_sizer = new wxBoxSizer (wxHORIZONTAL);
 
                _list = new wxListCtrl (
                        overall_panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL
@@ -124,7 +125,7 @@ public:
 
                _list->SetImageList (images, wxIMAGE_LIST_SMALL);
 
-               main_sizer->Add (_list, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_GAP);
+               h_sizer->Add (_list, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_GAP);
 
                wxBoxSizer* button_sizer = new wxBoxSizer (wxVERTICAL);
                _up = new Button (overall_panel, _("Up"));
@@ -140,8 +141,20 @@ public:
                button_sizer->Add (_save, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
                button_sizer->Add (_load, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
 
-               main_sizer->Add (button_sizer, 0, wxALL, DCPOMATIC_SIZER_GAP);
-               overall_panel->SetSizer (main_sizer);
+               h_sizer->Add (button_sizer, 0, wxALL, DCPOMATIC_SIZER_GAP);
+
+               wxBoxSizer* v_sizer = new wxBoxSizer (wxVERTICAL);
+
+               wxBoxSizer* allowed_shows_sizer = new wxBoxSizer (wxHORIZONTAL);
+               _allowed_shows_enable = new wxCheckBox (overall_panel, wxID_ANY, _("Limit number of shows with this playlist to"));
+               allowed_shows_sizer->Add (_allowed_shows_enable, 0, wxRIGHT, DCPOMATIC_SIZER_GAP);
+               _allowed_shows = new wxSpinCtrl (overall_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 65536, 100);
+               allowed_shows_sizer->Add (_allowed_shows);
+
+               v_sizer->Add (allowed_shows_sizer, 0, wxALL, DCPOMATIC_SIZER_GAP);
+               v_sizer->Add (h_sizer);
+
+               overall_panel->SetSizer (v_sizer);
 
                _list->Bind (wxEVT_LEFT_DOWN, bind(&DOMFrame::list_left_click, this, _1));
                _list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, boost::bind (&DOMFrame::selection_changed, this));
@@ -152,12 +165,24 @@ public:
                _remove->Bind (wxEVT_BUTTON, bind(&DOMFrame::remove_clicked, this));
                _save->Bind (wxEVT_BUTTON, bind(&DOMFrame::save_clicked, this));
                _load->Bind (wxEVT_BUTTON, bind(&DOMFrame::load_clicked, this));
+               _allowed_shows_enable->Bind (wxEVT_CHECKBOX, bind(&DOMFrame::allowed_shows_changed, this));
+               _allowed_shows->Bind (wxEVT_SPINCTRL, bind(&DOMFrame::allowed_shows_changed, this));
 
                setup_sensitivity ();
        }
 
 private:
 
+       void allowed_shows_changed ()
+       {
+               if (_allowed_shows_enable->GetValue()) {
+                       _playlist.set_allowed_shows (_allowed_shows->GetValue());
+               } else {
+                       _playlist.unset_allowed_shows ();
+               }
+               setup_sensitivity ();
+       }
+
        void add (SPLEntry e)
        {
                wxListItem item;
@@ -190,6 +215,7 @@ private:
                _up->Enable (selected > 0);
                _down->Enable (selected != -1 && selected < (_list->GetItemCount() - 1));
                _remove->Enable (num_selected > 0);
+               _allowed_shows->Enable (_allowed_shows_enable->GetValue());
        }
 
        void list_left_click (wxMouseEvent& ev)
@@ -308,6 +334,14 @@ private:
                        } else {
                                error_dialog (this, _("Some content in this playlist was not found."));
                        }
+                       optional<int> allowed_shows = _playlist.allowed_shows ();
+                       _allowed_shows_enable->SetValue (static_cast<bool>(allowed_shows));
+                       if (allowed_shows) {
+                               _allowed_shows->SetValue (*allowed_shows);
+                       } else {
+                               _allowed_shows->SetValue (65536);
+                       }
+                       setup_sensitivity ();
                }
        }
 
@@ -318,6 +352,8 @@ private:
        wxButton* _remove;
        wxButton* _save;
        wxButton* _load;
+       wxCheckBox* _allowed_shows_enable;
+       wxSpinCtrl* _allowed_shows;
        SPL _playlist;
        ContentDialog* _content_dialog;
 
index d8019a41e7b840b4dc82a4bbee143ba167f59b48..2be5aae236e463edba072563dffd10aecb98900f 100644 (file)
@@ -30,6 +30,7 @@
 #include "lib/scoped_temporary.h"
 #include "lib/internet.h"
 #include "lib/ffmpeg_content.h"
+#include "lib/compose.hpp"
 #include <dcp/raw_convert.h>
 #include <dcp/exceptions.h>
 #include <wx/listctrl.h>
@@ -193,6 +194,18 @@ SwaroopControls::stopped ()
        _pause_button->Enable (false);
 }
 
+void
+SwaroopControls::decrement_allowed_shows ()
+{
+       if (_selected_playlist) {
+               SPL& spl = _playlists[*_selected_playlist];
+               spl.decrement_allowed_shows();
+               if (spl.path()) {
+                       spl.write (*spl.path());
+               }
+       }
+}
+
 void
 SwaroopControls::play_clicked ()
 {
@@ -229,6 +242,7 @@ SwaroopControls::stop_clicked ()
                update_current_content ();
        }
        _viewer->set_background_image (true);
+       decrement_allowed_shows ();
 }
 
 bool
@@ -430,6 +444,11 @@ SwaroopControls::spl_selection_changed ()
                return;
        }
 
+       if (!_playlists[selected].have_allowed_shows()) {
+               error_dialog (this, "There are no more allowed shows of this playlist.");
+               return;
+       }
+
        select_playlist (selected, 0);
 }
 
@@ -568,4 +587,6 @@ SwaroopControls::viewer_finished ()
                _viewer->set_background_image (true);
                ResetFilm (shared_ptr<Film>(new Film(optional<boost::filesystem::path>())));
        }
+
+       decrement_allowed_shows ();
 }
index 1f740d2283825c7164212e1d954adce40ff71f33..10919b7678e8f146eb37a136542dde90bac07354 100644 (file)
@@ -59,6 +59,7 @@ private:
        void update_current_content ();
        bool can_do_previous ();
        bool can_do_next ();
+       void decrement_allowed_shows ();
 
        boost::optional<dcp::EncryptedKDM> get_kdm_from_url (boost::shared_ptr<DCPContent> dcp);
        boost::optional<dcp::EncryptedKDM> get_kdm_from_directory (boost::shared_ptr<DCPContent> dcp);