Extract save_playlist().
[dcpomatic.git] / src / tools / dcpomatic_playlist.cc
index c327a8603d1f11a0c87c73da8ab0f69b7298dbf4..636a50f8ab9d6a3daafd36e564ba8d2ef65c871e 100644 (file)
@@ -59,6 +59,16 @@ using namespace boost::placeholders;
 #endif
 
 
+static
+void
+save_playlist(shared_ptr<const SPL> playlist)
+{
+       if (auto dir = Config::instance()->player_playlist_directory()) {
+               playlist->write(*dir / (playlist->id() + ".xml"));
+       }
+}
+
+
 class ContentDialog : public wxDialog, public ContentStore
 {
 public:
@@ -106,6 +116,7 @@ public:
        PlaylistList (wxPanel* parent, ContentStore* content_store)
                : _sizer (new wxBoxSizer(wxVERTICAL))
                , _content_store (content_store)
+               , _parent(parent)
        {
                auto label = new wxStaticText (parent, wxID_ANY, wxEmptyString);
                label->SetLabelMarkup (_("<b>Playlists</b>"));
@@ -136,6 +147,8 @@ public:
                _list->Bind (wxEVT_COMMAND_LIST_ITEM_DESELECTED, bind(&PlaylistList::selection_changed, this));
                _new->Bind (wxEVT_BUTTON, bind(&PlaylistList::new_playlist, this));
                _delete->Bind (wxEVT_BUTTON, bind(&PlaylistList::delete_playlist, this));
+
+               setup_sensitivity();
        }
 
        wxSizer* sizer ()
@@ -155,6 +168,11 @@ public:
        boost::signals2::signal<void (shared_ptr<SignalSPL>)> Edit;
 
 private:
+       void setup_sensitivity()
+       {
+               _delete->Enable(static_cast<bool>(selected()));
+       }
+
        void add_playlist_to_view (shared_ptr<const SignalSPL> playlist)
        {
                wxListItem item;
@@ -166,22 +184,31 @@ private:
        void add_playlist_to_model (shared_ptr<SignalSPL> playlist)
        {
                _playlists.push_back (playlist);
-               playlist->NameChanged.connect (bind(&PlaylistList::name_changed, this, weak_ptr<SignalSPL>(playlist)));
+               playlist->Changed.connect(bind(&PlaylistList::changed, this, weak_ptr<SignalSPL>(playlist), _1));
        }
 
-       void name_changed (weak_ptr<SignalSPL> wp)
+       void changed(weak_ptr<SignalSPL> wp, SignalSPL::Change change)
        {
                auto playlist = wp.lock ();
                if (!playlist) {
                        return;
                }
 
-               int N = 0;
-               for (auto i: _playlists) {
-                       if (i == playlist) {
-                               _list->SetItem (N, 0, std_to_wx(i->name()));
+               switch (change) {
+               case SignalSPL::Change::NAME:
+               {
+                       int N = 0;
+                       for (auto i: _playlists) {
+                               if (i == playlist) {
+                                       _list->SetItem (N, 0, std_to_wx(i->name()));
+                               }
+                               ++N;
                        }
-                       ++N;
+                       break;
+               }
+               case SignalSPL::Change::CONTENT:
+                       save_playlist(playlist);
+                       break;
                }
        }
 
@@ -209,16 +236,32 @@ private:
 
        void new_playlist ()
        {
+               auto dir = Config::instance()->player_playlist_directory();
+               if (!dir) {
+                       error_dialog(_parent, _("No playlist folder is specified in preferences.  Please set one and then try again."));
+                       return;
+               }
+
                shared_ptr<SignalSPL> spl (new SignalSPL(wx_to_std(_("New Playlist"))));
                add_playlist_to_model (spl);
                add_playlist_to_view (spl);
                _list->SetItemState (_list->GetItemCount() - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
        }
 
-       void delete_playlist ()
+       boost::optional<int> selected() const
        {
-               long int selected = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+               long int selected = _list->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
                if (selected < 0 || selected >= int(_playlists.size())) {
+                       return {};
+               }
+
+               return selected;
+       }
+
+       void delete_playlist ()
+       {
+               auto index = selected();
+               if (!index) {
                        return;
                }
 
@@ -227,11 +270,11 @@ private:
                        return;
                }
 
-               boost::filesystem::remove (*dir / (_playlists[selected]->id() + ".xml"));
-               _list->DeleteItem (selected);
-               _playlists.erase (_playlists.begin() + selected);
+               boost::filesystem::remove(*dir / (_playlists[*index]->id() + ".xml"));
+               _list->DeleteItem(*index);
+               _playlists.erase(_playlists.begin() + *index);
 
-               Edit (shared_ptr<SignalSPL>());
+               Edit(shared_ptr<SignalSPL>());
        }
 
        void selection_changed ()
@@ -242,6 +285,8 @@ private:
                } else {
                        Edit (_playlists[selected]);
                }
+
+               setup_sensitivity();
        }
 
        wxBoxSizer* _sizer;
@@ -250,6 +295,7 @@ private:
        wxButton* _delete;
        vector<shared_ptr<SignalSPL>> _playlists;
        ContentStore* _content_store;
+       wxWindow* _parent;
 };
 
 
@@ -312,6 +358,8 @@ public:
                _down->Bind (wxEVT_BUTTON, bind(&PlaylistContent::down_clicked, this));
                _add->Bind (wxEVT_BUTTON, bind(&PlaylistContent::add_clicked, this));
                _remove->Bind (wxEVT_BUTTON, bind(&PlaylistContent::remove_clicked, this));
+
+               setup_sensitivity();
        }
 
        wxSizer* sizer ()
@@ -400,9 +448,7 @@ private:
 
                DCPOMATIC_ASSERT (_playlist);
 
-               auto tmp = (*_playlist)[s];
-               (*_playlist)[s] = (*_playlist)[s-1];
-               (*_playlist)[s-1] = tmp;
+               _playlist->swap(s, s - 1);
 
                set_item (s - 1, (*_playlist)[s-1]);
                set_item (s, (*_playlist)[s]);
@@ -417,9 +463,7 @@ private:
 
                DCPOMATIC_ASSERT (_playlist);
 
-               auto tmp = (*_playlist)[s];
-               (*_playlist)[s] = (*_playlist)[s+1];
-               (*_playlist)[s+1] = tmp;
+               _playlist->swap(s, s + 1);
 
                set_item (s + 1, (*_playlist)[s+1]);
                set_item (s, (*_playlist)[s]);
@@ -477,8 +521,6 @@ public:
 
                _playlist_list->Edit.connect (bind(&DOMFrame::change_playlist, this, _1));
 
-               _playlist_content->set (_playlist_list->first_playlist());
-
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_exit, this), wxID_EXIT);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::help_about, this), wxID_ABOUT);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::edit_preferences, this), wxID_PREFERENCES);
@@ -518,16 +560,6 @@ private:
                _playlist_content->set (playlist);
        }
 
-       void save_playlist (shared_ptr<SignalSPL> playlist)
-       {
-               auto dir = Config::instance()->player_playlist_directory();
-               if (!dir) {
-                       error_dialog (this, _("No playlist folder is specified in preferences.  Please set one and then try again."));
-                       return;
-               }
-               playlist->write (*dir / (playlist->id() + ".xml"));
-       }
-
        void setup_menu (wxMenuBar* m)
        {
                auto file = new wxMenu;