+ parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL
+ );
+
+ _list->AppendColumn (_("Name"), wxLIST_FORMAT_LEFT, 840);
+ _list->AppendColumn (_("Length"), wxLIST_FORMAT_LEFT, 100);
+
+ wxBoxSizer* button_sizer = new wxBoxSizer (wxVERTICAL);
+ _new = new Button (parent, _("New"));
+ button_sizer->Add (_new, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+ _delete = new Button (parent, _("Delete"));
+ button_sizer->Add (_delete, 0, wxEXPAND | wxBOTTOM, DCPOMATIC_BUTTON_STACK_GAP);
+
+ wxSizer* list = new wxBoxSizer (wxHORIZONTAL);
+ list->Add (_list, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_GAP);
+ list->Add (button_sizer, 0, wxALL, DCPOMATIC_SIZER_GAP);
+
+ _sizer->Add (list);
+
+ load_playlists ();
+
+ _list->Bind (wxEVT_COMMAND_LIST_ITEM_SELECTED, bind(&PlaylistList::selection_changed, this));
+ _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));
+ }
+
+ wxSizer* sizer ()
+ {
+ return _sizer;
+ }
+
+ shared_ptr<SignalSPL> first_playlist () const
+ {
+ if (_playlists.empty()) {
+ return shared_ptr<SignalSPL>();
+ }
+
+ return _playlists.front ();
+ }
+
+ boost::signals2::signal<void (shared_ptr<SignalSPL>)> Edit;
+
+private:
+ void add_playlist_to_view (shared_ptr<const SignalSPL> playlist)
+ {
+ wxListItem item;
+ item.SetId (_list->GetItemCount());
+ long const N = _list->InsertItem (item);
+ _list->SetItem (N, 0, std_to_wx(playlist->name()));
+ }
+
+ 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)));
+ }
+
+ void name_changed (weak_ptr<SignalSPL> wp)
+ {
+ shared_ptr<SignalSPL> playlist = wp.lock ();
+ if (!playlist) {
+ return;
+ }
+
+ int N = 0;
+ BOOST_FOREACH (shared_ptr<SignalSPL> i, _playlists) {
+ if (i == playlist) {
+ _list->SetItem (N, 0, std_to_wx(i->name()));
+ }
+ ++N;
+ }
+ }
+
+ void load_playlists ()
+ {
+ optional<boost::filesystem::path> path = Config::instance()->player_playlist_directory();
+ if (!path) {
+ return;
+ }
+
+ _list->DeleteAllItems ();
+ _playlists.clear ();
+ for (boost::filesystem::directory_iterator i(*path); i != boost::filesystem::directory_iterator(); ++i) {
+ shared_ptr<SignalSPL> spl(new SignalSPL);
+ try {
+ spl->read (*i, _content_store);
+ add_playlist_to_model (spl);
+ } catch (...) {}
+ }
+
+ BOOST_FOREACH (shared_ptr<SignalSPL> i, _playlists) {
+ add_playlist_to_view (i);
+ }
+ }
+
+ void new_playlist ()
+ {
+ 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 ()
+ {
+ long int selected = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected < 0 || selected >= int(_playlists.size())) {
+ return;
+ }
+
+ optional<boost::filesystem::path> dir = Config::instance()->player_playlist_directory();
+ if (!dir) {
+ return;
+ }
+
+ boost::filesystem::remove (*dir / (_playlists[selected]->id() + ".xml"));
+ _list->DeleteItem (selected);
+ _playlists.erase (_playlists.begin() + selected);
+
+ Edit (shared_ptr<SignalSPL>());
+ }
+
+ void selection_changed ()
+ {
+ long int selected = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected < 0 || selected >= int(_playlists.size())) {
+ Edit (shared_ptr<SignalSPL>());
+ } else {
+ Edit (_playlists[selected]);
+ }
+ }
+
+ wxBoxSizer* _sizer;
+ wxListCtrl* _list;
+ wxButton* _new;
+ wxButton* _delete;
+ vector<shared_ptr<SignalSPL> > _playlists;
+ ContentStore* _content_store;
+};
+
+
+class PlaylistContent
+{
+public:
+ PlaylistContent (wxPanel* parent, ContentDialog* content_dialog)
+ : _content_dialog (content_dialog)
+ , _sizer (new wxBoxSizer(wxVERTICAL))
+ {
+ wxBoxSizer* title = new wxBoxSizer (wxHORIZONTAL);
+ wxStaticText* label = new wxStaticText (parent, wxID_ANY, wxEmptyString);
+ label->SetLabelMarkup (_("<b>Playlist:</b>"));
+ title->Add (label, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, DCPOMATIC_SIZER_GAP);
+ _name = new wxTextCtrl (parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(400, -1));
+ title->Add (_name, 0, wxRIGHT, DCPOMATIC_SIZER_GAP);
+ _sizer->Add (title, 0, wxTOP | wxLEFT, DCPOMATIC_SIZER_GAP * 2);
+
+ wxBoxSizer* list = new wxBoxSizer (wxHORIZONTAL);
+
+ _list = new wxListCtrl (
+ parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL