From 25b1934f24206b6dda5ce5a7686930d605ff6ccc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 9 Jun 2019 23:59:12 +0100 Subject: [PATCH] swaroop: allowed-shows state in playlist. --- src/lib/spl.cc | 14 +++++++++-- src/lib/spl.h | 36 +++++++++++++++++++++++++-- src/tools/dcpomatic_playlist.cc | 44 ++++++++++++++++++++++++++++++--- src/wx/swaroop_controls.cc | 21 ++++++++++++++++ src/wx/swaroop_controls.h | 1 + 5 files changed, 108 insertions(+), 8 deletions(-) diff --git a/src/lib/spl.cc b/src/lib/spl.cc index cd33c4047..e8e86f89c 100644 --- a/src/lib/spl.cc +++ b/src/lib/spl.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2018 Carl Hetherington + Copyright (C) 2018-2019 Carl Hetherington This file is part of DCP-o-matic. @@ -21,16 +21,21 @@ #include "spl.h" #include "content_store.h" #include +#include #include #include #include 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("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(*_allowed_shows)); + } doc.write_to_file_formatted (path.string()); } diff --git a/src/lib/spl.h b/src/lib/spl.h index b19ef7e7a..18892993f 100644 --- a/src/lib/spl.h +++ b/src/lib/spl.h @@ -61,20 +61,52 @@ public: return _id; } + boost::optional path () const { + return _path; + } + std::string name () const { - return _name; + if (!_path) { + return ""; + } + return _path->filename().string(); } bool missing () const { return _missing; } + boost::optional 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(); + } + + void decrement_allowed_shows () { + if (_allowed_shows) { + (*_allowed_shows)--; + } + + } + private: std::string _id; - std::string _name; + mutable boost::optional _path; std::vector _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 _allowed_shows; }; #endif diff --git a/src/tools/dcpomatic_playlist.cc b/src/tools/dcpomatic_playlist.cc index 64549765f..de6ae107b 100644 --- a/src/tools/dcpomatic_playlist.cc +++ b/src/tools/dcpomatic_playlist.cc @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef __WXOSX__ #include #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 allowed_shows = _playlist.allowed_shows (); + _allowed_shows_enable->SetValue (static_cast(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; diff --git a/src/wx/swaroop_controls.cc b/src/wx/swaroop_controls.cc index d8019a41e..2be5aae23 100644 --- a/src/wx/swaroop_controls.cc +++ b/src/wx/swaroop_controls.cc @@ -30,6 +30,7 @@ #include "lib/scoped_temporary.h" #include "lib/internet.h" #include "lib/ffmpeg_content.h" +#include "lib/compose.hpp" #include #include #include @@ -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(new Film(optional()))); } + + decrement_allowed_shows (); } diff --git a/src/wx/swaroop_controls.h b/src/wx/swaroop_controls.h index 1f740d228..10919b767 100644 --- a/src/wx/swaroop_controls.h +++ b/src/wx/swaroop_controls.h @@ -59,6 +59,7 @@ private: void update_current_content (); bool can_do_previous (); bool can_do_next (); + void decrement_allowed_shows (); boost::optional get_kdm_from_url (boost::shared_ptr dcp); boost::optional get_kdm_from_directory (boost::shared_ptr dcp); -- 2.30.2