diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-10-20 00:45:17 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2026-02-03 21:37:04 +0100 |
| commit | 9b841fddd3aa4a1117b03299bce964c5e4b205d9 (patch) | |
| tree | 61022295269b8e55a5fbefabb88183dd96d1afcf /src/wx | |
| parent | 8a4591d1f77e2de6e92385e0ab0b3efc714feeb9 (diff) | |
Use SQLite for show playlists.
Diffstat (limited to 'src/wx')
| -rw-r--r-- | src/wx/file_picker_ctrl.h | 10 | ||||
| -rw-r--r-- | src/wx/locations_preferences_page.cc | 19 | ||||
| -rw-r--r-- | src/wx/locations_preferences_page.h | 5 | ||||
| -rw-r--r-- | src/wx/playlist_controls.cc | 77 | ||||
| -rw-r--r-- | src/wx/playlist_controls.h | 14 | ||||
| -rw-r--r-- | src/wx/show_playlist_entry_dialog.cc (renamed from src/wx/spl_entry_dialog.cc) | 28 | ||||
| -rw-r--r-- | src/wx/show_playlist_entry_dialog.h (renamed from src/wx/spl_entry_dialog.h) | 10 | ||||
| -rw-r--r-- | src/wx/wscript | 2 |
8 files changed, 87 insertions, 78 deletions
diff --git a/src/wx/file_picker_ctrl.h b/src/wx/file_picker_ctrl.h index 57363b0c7..df68588b8 100644 --- a/src/wx/file_picker_ctrl.h +++ b/src/wx/file_picker_ctrl.h @@ -25,6 +25,9 @@ LIBDCP_DISABLE_WARNINGS LIBDCP_ENABLE_WARNINGS #include <boost/filesystem.hpp> #include <boost/optional.hpp> +LIBDCP_DISABLE_WARNINGS +#include <boost/signals2.hpp> +LIBDCP_ENABLE_WARNINGS class FilePickerCtrl : public wxPanel @@ -45,6 +48,13 @@ public: void set_path(boost::optional<boost::filesystem::path> path); void set_wildcard(wxString); + template <typename... Args> + void bind(Args... args) { + Changed.connect(boost::bind(std::forward<Args>(args)...)); + } + + boost::signals2::signal<void ()> Changed; + private: void browse_clicked (); void set_filename(boost::optional<std::string> filename); diff --git a/src/wx/locations_preferences_page.cc b/src/wx/locations_preferences_page.cc index f77f88fb4..0eaa5dca0 100644 --- a/src/wx/locations_preferences_page.cc +++ b/src/wx/locations_preferences_page.cc @@ -19,6 +19,7 @@ */ +#include "file_picker_ctrl.h" #include "locations_preferences_page.h" #include "wx_util.h" #include <wx/filepicker.h> @@ -68,9 +69,9 @@ LocationsPage::setup() table->Add(_content_directory, wxGBPosition(r, 1)); ++r; - add_label_to_sizer(table, _panel, _("Playlist directory"), true, wxGBPosition(r, 0)); - _playlist_directory = new wxDirPickerCtrl(_panel, wxID_ANY, wxEmptyString, char_to_wx(wxDirSelectorPromptStr), wxDefaultPosition, wxSize(300, -1)); - table->Add(_playlist_directory, wxGBPosition(r, 1)); + add_label_to_sizer(table, _panel, _("Show playlists file"), true, wxGBPosition(r, 0)); + _show_playlists_file = new FilePickerCtrl(_panel, _("Select show playlists file"), char_to_wx("*.sqlite3"), false, true, "ShowPlaylistsPath"); + table->Add(_show_playlists_file, wxGBPosition(r, 1)); ++r; add_label_to_sizer(table, _panel, _("KDM directory"), true, wxGBPosition(r, 0)); @@ -79,7 +80,7 @@ LocationsPage::setup() ++r; _content_directory->Bind(wxEVT_DIRPICKER_CHANGED, bind(&LocationsPage::content_directory_changed, this)); - _playlist_directory->Bind(wxEVT_DIRPICKER_CHANGED, bind(&LocationsPage::playlist_directory_changed, this)); + _show_playlists_file->bind(&LocationsPage::show_playlists_file_changed, this); _kdm_directory->Bind(wxEVT_DIRPICKER_CHANGED, bind(&LocationsPage::kdm_directory_changed, this)); } @@ -91,9 +92,7 @@ LocationsPage::config_changed() if (config->player_content_directory()) { checked_set(_content_directory, *config->player_content_directory()); } - if (config->player_playlist_directory()) { - checked_set(_playlist_directory, *config->player_playlist_directory()); - } + checked_set(_show_playlists_file, config->show_playlists_file()); if (config->player_kdm_directory()) { checked_set(_kdm_directory, *config->player_kdm_directory()); } @@ -106,9 +105,11 @@ LocationsPage::content_directory_changed() } void -LocationsPage::playlist_directory_changed() +LocationsPage::show_playlists_file_changed() { - Config::instance()->set_player_playlist_directory(wx_to_std(_playlist_directory->GetPath())); + if (auto path = _show_playlists_file->path()) { + Config::instance()->set_show_playlists_file(*path); + } } void diff --git a/src/wx/locations_preferences_page.h b/src/wx/locations_preferences_page.h index 8bb9e3e5a..cd3f3593f 100644 --- a/src/wx/locations_preferences_page.h +++ b/src/wx/locations_preferences_page.h @@ -22,6 +22,7 @@ #include "preferences_page.h" +class FilePickerCtrl; class wxDirPickerCtrl; @@ -44,11 +45,11 @@ private: void setup() override; void config_changed() override; void content_directory_changed(); - void playlist_directory_changed(); + void show_playlists_file_changed(); void kdm_directory_changed(); wxDirPickerCtrl* _content_directory; - wxDirPickerCtrl* _playlist_directory; + FilePickerCtrl* _show_playlists_file; wxDirPickerCtrl* _kdm_directory; }; diff --git a/src/wx/playlist_controls.cc b/src/wx/playlist_controls.cc index 0356738e1..380831ab8 100644 --- a/src/wx/playlist_controls.cc +++ b/src/wx/playlist_controls.cc @@ -34,6 +34,8 @@ #include "lib/internet.h" #include "lib/player_video.h" #include "lib/scoped_temporary.h" +#include "lib/show_playlist.h" +#include "lib/show_playlist_list.h" #include <dcp/exceptions.h> #include <dcp/warnings.h> LIBDCP_DISABLE_WARNINGS @@ -118,10 +120,10 @@ PlaylistControls::PlaylistControls(wxWindow* parent, FilmViewer& viewer) _spl_view->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&PlaylistControls::spl_selection_changed, this)); _spl_view->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&PlaylistControls::spl_selection_changed, this)); _viewer.Finished.connect(boost::bind(&PlaylistControls::viewer_finished, this)); - _refresh_spl_view->Bind(wxEVT_BUTTON, boost::bind(&PlaylistControls::update_playlist_directory, this)); + _refresh_spl_view->Bind(wxEVT_BUTTON, boost::bind(&PlaylistControls::update_playlists, this)); _refresh_content_view->Bind(wxEVT_BUTTON, boost::bind(&ContentView::update, _content_view)); - update_playlist_directory(); + update_playlists(); } @@ -219,7 +221,7 @@ PlaylistControls::previous_clicked() bool PlaylistControls::can_do_next() { - return _selected_playlist && (_selected_playlist_position + 1) < int(_playlists[*_selected_playlist].get().size()); + return _selected_playlist && (_selected_playlist_position + 1) < static_cast<int>(_playlists->entries(*_selected_playlist).size()); } @@ -236,15 +238,19 @@ PlaylistControls::next_clicked() void -PlaylistControls::add_playlist_to_list(SPL spl) +PlaylistControls::add_playlist_to_list(ShowPlaylist spl) { int const N = _spl_view->GetItemCount(); wxListItem it; it.SetId(N); it.SetColumn(0); + auto id = _playlists->get_show_playlist_id(spl.uuid()); + DCPOMATIC_ASSERT(id); + it.SetData(id->get()); string t = spl.name(); - if (spl.missing()) { + + if (_playlists->missing(spl.uuid())) { t += " (content missing)"; } it.SetText(std_to_wx(t)); @@ -253,33 +259,15 @@ PlaylistControls::add_playlist_to_list(SPL spl) void -PlaylistControls::update_playlist_directory() +PlaylistControls::update_playlists() { using namespace boost::filesystem; _spl_view->DeleteAllItems(); - optional<path> dir = Config::instance()->player_playlist_directory(); - if (!dir) { - return; - } - - _playlists.clear(); - - for (directory_iterator i = directory_iterator(*dir); i != directory_iterator(); ++i) { - try { - if (is_regular_file(i->path()) && i->path().extension() == ".xml") { - SPL spl; - spl.read(i->path(), ShowPlaylistContentStore::instance()); - _playlists.push_back(spl); - } - } catch (exception& e) { - /* Never mind */ - } - } + _playlists.reset(new ShowPlaylistList()); - sort(_playlists.begin(), _playlists.end(), [](SPL const& a, SPL const& b) { return a.name() < b.name(); }); - for (auto i: _playlists) { - add_playlist_to_list(i); + for (auto i: _playlists->show_playlists()) { + add_playlist_to_list(i.second); } _selected_playlist = boost::none; @@ -321,29 +309,32 @@ PlaylistControls::spl_selection_changed() return; } - if (_playlists[selected].missing()) { + auto const id = ShowPlaylistID(_spl_view->GetItemData(selected)); + + if (_playlists->missing(id)) { error_dialog(this, _("This playlist cannot be loaded as some content is missing.")); deselect_playlist(); return; } - if (_playlists[selected].get().empty()) { + if (_playlists->entries(id).empty()) { error_dialog(this, _("This playlist is empty.")); return; } - select_playlist(selected, 0); + select_playlist(id, 0); } void -PlaylistControls::select_playlist(int selected, int position) +PlaylistControls::select_playlist(ShowPlaylistID selected, int position) { wxProgressDialog dialog(variant::wx::dcpomatic(), _("Loading playlist and KDMs")); - for (auto const& i: _playlists[selected].get()) { + auto const store = ShowPlaylistContentStore::instance(); + for (auto const& i: _playlists->entries(selected)) { dialog.Pulse(); - auto dcp = dynamic_pointer_cast<DCPContent>(i.content); + auto dcp = dynamic_pointer_cast<DCPContent>(store->get(i)); if (dcp && dcp->needs_kdm()) { optional<dcp::EncryptedKDM> kdm; kdm = get_kdm_from_directory(dcp); @@ -367,11 +358,11 @@ PlaylistControls::select_playlist(int selected, int position) _current_spl_view->DeleteAllItems(); int N = 0; - for (auto i: _playlists[selected].get()) { + for (auto const& i: _playlists->entries(selected)) { wxListItem it; it.SetId(N); it.SetColumn(0); - it.SetText(std_to_wx(i.name)); + it.SetText(std_to_wx(i.name())); _current_spl_view->InsertItem(it); ++N; } @@ -389,10 +380,14 @@ void PlaylistControls::reset_film() { DCPOMATIC_ASSERT(_selected_playlist); + auto film = std::make_shared<Film>(optional<boost::filesystem::path>()); - auto entry = _playlists[*_selected_playlist].get(_selected_playlist_position); - film->add_content(vector<shared_ptr<Content>>{entry.content}); - ResetFilm(film, entry.crop_to_ratio); + + auto const entries = _playlists->entries(*_selected_playlist); + DCPOMATIC_ASSERT(_selected_playlist_position < static_cast<int>(entries.size())); + auto const entry = entries[_selected_playlist_position]; + film->add_content(vector<shared_ptr<Content>>{ShowPlaylistContentStore::instance()->get(entry)}); + ResetFilm(film, entry.crop_to_ratio()); } @@ -403,8 +398,8 @@ PlaylistControls::config_changed(int property) if (property == Config::PLAYER_CONTENT_DIRECTORY) { _content_view->update(); - } else if (property == Config::PLAYER_PLAYLIST_DIRECTORY) { - update_playlist_directory(); + } else if (property == Config::SHOW_PLAYLISTS_FILE) { + update_playlists(); } } @@ -431,7 +426,7 @@ PlaylistControls::viewer_finished() } _selected_playlist_position++; - if (_selected_playlist_position < int(_playlists[*_selected_playlist].get().size())) { + if (_selected_playlist_position < int(_playlists->entries(*_selected_playlist).size())) { /* Next piece of content on the SPL */ update_current_content(); _viewer.start(); diff --git a/src/wx/playlist_controls.h b/src/wx/playlist_controls.h index e99e54b65..ea9e79cf4 100644 --- a/src/wx/playlist_controls.h +++ b/src/wx/playlist_controls.h @@ -20,10 +20,12 @@ #include "controls.h" -#include "lib/spl.h" +#include "lib/show_playlist.h" +#include "lib/show_playlist_id.h" class DCPContent; +class ShowPlaylistList; class PlaylistControls : public Controls @@ -46,11 +48,11 @@ private: void stop_clicked(); void next_clicked(); void previous_clicked(); - void add_playlist_to_list(SPL spl); + void add_playlist_to_list(ShowPlaylist spl); void update_content_directory(); - void update_playlist_directory(); + void update_playlists(); void spl_selection_changed(); - void select_playlist(int selected, int position); + void select_playlist(ShowPlaylistID selected, int position); void started() override; void stopped() override; void setup_sensitivity() override; @@ -76,7 +78,7 @@ private: wxButton* _refresh_spl_view; wxListCtrl* _current_spl_view; - std::vector<SPL> _playlists; - boost::optional<int> _selected_playlist; + std::unique_ptr<ShowPlaylistList> _playlists; + boost::optional<ShowPlaylistID> _selected_playlist; int _selected_playlist_position; }; diff --git a/src/wx/spl_entry_dialog.cc b/src/wx/show_playlist_entry_dialog.cc index 332b7840c..07e1d2e92 100644 --- a/src/wx/spl_entry_dialog.cc +++ b/src/wx/show_playlist_entry_dialog.cc @@ -21,9 +21,9 @@ #include "check_box.h" #include "ratio_picker.h" -#include "spl_entry_dialog.h" +#include "show_playlist_entry_dialog.h" #include "wx_util.h" -#include "lib/spl.h" +#include "lib/show_playlist_entry.h" #include <wx/wx.h> @@ -34,43 +34,43 @@ using namespace boost::placeholders; -SPLEntryDialog::SPLEntryDialog(wxWindow* parent, SPLEntry entry) +ShowPlaylistEntryDialog::ShowPlaylistEntryDialog(wxWindow* parent, ShowPlaylistEntry entry) : TableDialog(parent, _("Playlist item"), 2, 1, true) , _entry(entry) { add(_("Name"), true); - auto name = _entry.name; + auto name = _entry.name(); #ifdef DCPOMATIC_LINUX boost::replace_all(name, "_", "__"); #endif add(std_to_wx(name), false); - add(_("CPL"), true); - add(std_to_wx(_entry.id.get_value_or("")), false); + add(_("UUID"), true); + add(std_to_wx(_entry.uuid()), false); add(_("Type"), true); - add(std_to_wx(_entry.kind->name()), false); + add(std_to_wx(_entry.kind().name()), false); add(_("Encrypted"), true); - add(_entry.encrypted ? _("Yes") : _("No"), false); + add(_entry.encrypted() ? _("Yes") : _("No"), false); - _crop = new RatioPicker(this, entry.crop_to_ratio); + _crop = new RatioPicker(this, entry.crop_to_ratio()); add(_crop->enable_checkbox(), false); add(_crop, false); layout(); - _crop->Changed.connect(boost::bind(&SPLEntryDialog::crop_changed, this, _1)); + _crop->Changed.connect(boost::bind(&ShowPlaylistEntryDialog::crop_changed, this, _1)); } -SPLEntry -SPLEntryDialog::get() const +ShowPlaylistEntry +ShowPlaylistEntryDialog::get() const { return _entry; } void -SPLEntryDialog::crop_changed(optional<float> ratio) +ShowPlaylistEntryDialog::crop_changed(optional<float> ratio) { - _entry.crop_to_ratio = ratio; + _entry.set_crop_to_ratio(ratio); } diff --git a/src/wx/spl_entry_dialog.h b/src/wx/show_playlist_entry_dialog.h index 63e4ba56f..3b644d5ad 100644 --- a/src/wx/spl_entry_dialog.h +++ b/src/wx/show_playlist_entry_dialog.h @@ -20,23 +20,23 @@ #include "table_dialog.h" -#include "lib/spl.h" +#include "lib/show_playlist_entry.h" class RatioPicker; -class SPLEntryDialog : public TableDialog +class ShowPlaylistEntryDialog : public TableDialog { public: - SPLEntryDialog(wxWindow* parent, SPLEntry entry); + ShowPlaylistEntryDialog(wxWindow* parent, ShowPlaylistEntry entry); - SPLEntry get() const; + ShowPlaylistEntry get() const; private: void crop_changed(boost::optional<float> ratio); - SPLEntry _entry; + ShowPlaylistEntry _entry; RatioPicker* _crop; }; diff --git a/src/wx/wscript b/src/wx/wscript index d3f3db88a..99a6f4814 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -166,7 +166,7 @@ sources = """ simple_video_view.cc smpte_metadata_dialog.cc sound_preferences_page.cc - spl_entry_dialog.cc + show_playlist_entry_dialog.cc standard_controls.cc static_text.cc subtag_list_ctrl.cc |
