diff options
| author | Carl Hetherington <cth@carlh.net> | 2018-11-15 22:07:13 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2018-11-22 23:26:18 +0000 |
| commit | 1b4d5951147bc88d771d0afaa98bbfa4ed85a822 (patch) | |
| tree | ee67880b8107aca4a8335a32a0ed09aa1c79200a /src | |
| parent | a3f6e20d055cdf1697eab011622dc569010ad617 (diff) | |
Basic save/load of playlists.
Diffstat (limited to 'src')
| -rw-r--r-- | src/tools/dcpomatic_playlist.cc | 77 | ||||
| -rw-r--r-- | src/wx/content_view.cc | 13 | ||||
| -rw-r--r-- | src/wx/content_view.h | 2 |
3 files changed, 89 insertions, 3 deletions
diff --git a/src/tools/dcpomatic_playlist.cc b/src/tools/dcpomatic_playlist.cc index 04beb0250..43cb70550 100644 --- a/src/tools/dcpomatic_playlist.cc +++ b/src/tools/dcpomatic_playlist.cc @@ -32,6 +32,7 @@ using std::exception; using std::cout; +using std::string; using boost::optional; using boost::shared_ptr; using boost::weak_ptr; @@ -46,21 +47,48 @@ public: , disable_timeline (false) , stop_after_play (false) { + construct (content); + } + + PlaylistEntry (boost::shared_ptr<Content> content, cxml::ConstNodePtr node) + : skippable (node->bool_child("Skippable")) + , disable_timeline (node->bool_child("DisableTimeline")) + , stop_after_play (node->bool_child("StopAfterPlay")) + { + construct (content); + } + + void construct (shared_ptr<Content> content) + { shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (content); + digest = content->digest (); if (dcp) { name = dcp->name (); - cpl_id = dcp->cpl().get_value_or(""); + DCPOMATIC_ASSERT (dcp->cpl()); + id = *dcp->cpl(); kind = dcp->content_kind().get_value_or(dcp::FEATURE); type = DCP; encrypted = dcp->encrypted (); } else { name = content->path(0).filename().string(); type = ECINEMA; + kind = dcp::FEATURE; } } + void as_xml (xmlpp::Element* e) + { + e->add_child("Digest")->add_child_text(digest); + e->add_child("Skippable")->add_child_text(skippable ? "1" : "0"); + e->add_child("DisableTimeline")->add_child_text(disable_timeline ? "1" : "0"); + e->add_child("StopAfterPlay")->add_child_text(stop_after_play ? "1" : "0"); + } + std::string name; - std::string cpl_id; + /** Digest of this content */ + std::string digest; + /** CPL ID or something else for MP4 (?) */ + std::string id; dcp::ContentKind kind; enum Type { DCP, @@ -100,6 +128,11 @@ public: return _content_view->selected (); } + shared_ptr<Content> get (string digest) const + { + return _content_view->get (digest); + } + private: ContentView* _content_view; }; @@ -175,6 +208,8 @@ public: _down->Bind (wxEVT_BUTTON, bind(&DOMFrame::down_clicked, this)); _add->Bind (wxEVT_BUTTON, bind(&DOMFrame::add_clicked, this)); _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)); setup_sensitivity (); } @@ -198,7 +233,7 @@ private: void set_item (long N, PlaylistEntry e) { _list->SetItem (N, 0, std_to_wx(e.name)); - _list->SetItem (N, 1, std_to_wx(e.cpl_id)); + _list->SetItem (N, 1, std_to_wx(e.id)); _list->SetItem (N, 2, std_to_wx(dcp::content_kind_to_string(e.kind))); _list->SetItem (N, 3, e.type == PlaylistEntry::DCP ? _("DCP") : _("E-cinema")); _list->SetItem (N, 4, e.encrypted ? _("Y") : _("N")); @@ -302,6 +337,42 @@ private: _list->DeleteItem (s); } + void save_clicked () + { + wxFileDialog* d = new wxFileDialog (this, _("Select playlist file"), wxEmptyString, wxEmptyString, wxT("XML files (*.xml)|*.xml"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + if (d->ShowModal() == wxID_OK) { + xmlpp::Document doc; + xmlpp::Element* root = doc.create_root_node ("SPL"); + BOOST_FOREACH (PlaylistEntry i, _playlist) { + i.as_xml (root->add_child("Entry")); + } + doc.write_to_file_formatted (wx_to_std(d->GetPath())); + } + } + + void load_clicked () + { + wxFileDialog* d = new wxFileDialog (this, _("Select playlist file"), wxEmptyString, wxEmptyString, wxT("XML files (*.xml)|*.xml")); + if (d->ShowModal() == wxID_OK) { + _list->DeleteAllItems (); + _playlist.clear (); + cxml::Document doc ("SPL"); + doc.read_file (wx_to_std(d->GetPath())); + bool missing = false; + BOOST_FOREACH (cxml::ConstNodePtr i, doc.node_children("Entry")) { + shared_ptr<Content> c = _content_dialog->get(i->string_child("Digest")); + if (c) { + add (PlaylistEntry(c, i)); + } else { + missing = true; + } + } + if (missing) { + error_dialog (this, _("Some content in this playlist was not found.")); + } + } + } + wxListCtrl* _list; wxButton* _up; wxButton* _down; diff --git a/src/wx/content_view.cc b/src/wx/content_view.cc index 4eab80339..aeefb65df 100644 --- a/src/wx/content_view.cc +++ b/src/wx/content_view.cc @@ -32,6 +32,7 @@ #include <boost/optional.hpp> #include <wx/progdlg.h> +using std::string; using boost::shared_ptr; using boost::weak_ptr; using boost::optional; @@ -145,3 +146,15 @@ ContentView::add (shared_ptr<Content> content) it.SetText(std_to_wx(content->summary())); SetItem(it); } + +shared_ptr<Content> +ContentView::get (string digest) const +{ + BOOST_FOREACH (shared_ptr<Content> i, _content) { + if (i->digest() == digest) { + return i; + } + } + + return shared_ptr<Content>(); +} diff --git a/src/wx/content_view.h b/src/wx/content_view.h index 0da53f636..ac64600e1 100644 --- a/src/wx/content_view.h +++ b/src/wx/content_view.h @@ -34,6 +34,8 @@ public: boost::shared_ptr<Content> selected () const; void update (); + boost::shared_ptr<Content> get (std::string digest) const; + private: void add (boost::shared_ptr<Content> content); |
