summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2022-03-01 22:41:56 +0100
committerCarl Hetherington <cth@carlh.net>2022-03-09 17:04:02 +0100
commit47d83b296248119d04b9226fd51a67e2fd3faac5 (patch)
treed9516f352dc28f1c42cc6e16247295611637ad42
parent161f7c27bd1aff63938a9512ab991de886691f97 (diff)
Improve ratings dialog to allow only valid values (#2199).
-rw-r--r--cscript7
-rw-r--r--platform/osx/make_dmg.sh1
-rw-r--r--platform/windows/wscript2
-rwxr-xr-xrun/tests1
-rw-r--r--run/tests.bat1
-rw-r--r--src/lib/cross.h3
-rw-r--r--src/lib/cross_linux.cc16
-rw-r--r--src/lib/cross_osx.cc11
-rw-r--r--src/lib/cross_windows.cc11
-rw-r--r--src/lib/dcp_content.h9
-rw-r--r--src/lib/dcp_examiner.h7
-rw-r--r--src/lib/film.h1
-rw-r--r--src/lib/util.cc2
-rw-r--r--src/lib/verify_dcp_job.cc2
-rw-r--r--src/wx/rating_dialog.cc302
-rw-r--r--src/wx/rating_dialog.h79
-rw-r--r--src/wx/wscript2
-rw-r--r--src/wx/wx_util.cc2
-rw-r--r--wscript4
19 files changed, 399 insertions, 64 deletions
diff --git a/cscript b/cscript
index e5b881098..06bf0eb51 100644
--- a/cscript
+++ b/cscript
@@ -354,6 +354,7 @@ def make_spec(filename, version, target, options, requires=None):
print('%%{_datadir}/locale/%s/LC_MESSAGES/libdcpomatic2.mo' % l, file=f)
print('%{_datadir}/libdcp/tags/*', file=f)
print('%{_datadir}/libdcp/xsd/*', file=f)
+ print('%{_datadir}/libdcp/ratings', file=f)
print('%{_datadir}/polkit-1/actions/com.dcpomatic.write-drive.policy', file=f)
print('', file=f)
print('%prep', file=f)
@@ -372,6 +373,7 @@ def make_spec(filename, version, target, options, requires=None):
print('/bin/mkdir -p %{buildroot}/usr/share/libdcp', file=f)
print('/bin/cp -r %s/src/libdcp/tags %%{buildroot}/usr/share/libdcp' % target.directory, file=f)
print('/bin/cp -r %s/src/libdcp/xsd %%{buildroot}/usr/share/libdcp' % target.directory, file=f)
+ print('/bin/cp %s/src/libdcp/ratings %%{buildroot}/usr/share/libdcp' % target.directory, file=f)
print('/bin/mv %s/bin/dcpverify %%{buildroot}/usr/bin/dcpomatic2_verify' % target.directory, file=f)
print('', file=f)
print('%post', file=f)
@@ -400,8 +402,8 @@ def dependencies(target, options):
# Use distro-provided FFmpeg on Arch
deps = []
- deps.append(('libdcp', 'v1.8.8'))
- deps.append(('libsub', 'v1.6.8'))
+ deps.append(('libdcp', 'v1.8.10'))
+ deps.append(('libsub', 'v1.6.10'))
deps.append(('leqm-nrt', '93ae9e6'))
deps.append(('rtaudio', 'f619b76'))
# We get our OpenSSL libraries from the environment, but we
@@ -676,6 +678,7 @@ def make_appimage(target, nice_name, internal_name, version):
target.command(f'cp -r {target.directory}/share/dcpomatic2 {appdir}/usr/share/')
target.command(f'cp -r {target.directory}/share/libdcp/xsd {appdir}/usr/share/libdcp/')
target.command(f'cp -r {target.directory}/share/libdcp/tags {appdir}/usr/share/libdcp/')
+ target.command(f'cp {target.directory}/share/libdcp/ratings {appdir}/usr/share/libdcp/')
lib = 'usr/lib/x86_64-linux-gnu'
target.command(f'mkdir -p build/{nice_filename}.AppDir/{lib}/gdk-pixbuf-2.0/2.10.0')
target.command(f'cp -a /{lib}/gdk-pixbuf-2.0 build/{nice_filename}.AppDir/usr/lib/x86_64-linux-gnu/')
diff --git a/platform/osx/make_dmg.sh b/platform/osx/make_dmg.sh
index f997af817..6f36839f7 100644
--- a/platform/osx/make_dmg.sh
+++ b/platform/osx/make_dmg.sh
@@ -244,6 +244,7 @@ function copy_resources {
cp $prefix/src/dcpomatic/graphics/no_tick.png "$dest"
cp -r $prefix/share/libdcp/xsd "$dest"
cp -r $prefix/share/libdcp/tags "$dest"
+ cp -r $prefix/share/libdcp/ratings "$dest"
# i18n: DCP-o-matic .mo files
for lang in de_DE es_ES fr_FR it_IT sv_SE nl_NL ru_RU pl_PL da_DK pt_PT pt_BR sk_SK cs_CZ uk_UA zh_CN tr_TR; do
diff --git a/platform/windows/wscript b/platform/windows/wscript
index 426b9b7ae..46974ed0f 100644
--- a/platform/windows/wscript
+++ b/platform/windows/wscript
@@ -336,6 +336,8 @@ File "%cdist_deps%/share/libdcp/tags/region"
File "%cdist_deps%/share/libdcp/tags/script"
File "%cdist_deps%/share/libdcp/tags/variant"
File "%cdist_deps%/share/libdcp/tags/dcnc"
+SetOutPath "$INSTDIR"
+File "%cdist_deps%/share/libdcp/ratings"
SectionEnd
""", file=f)
diff --git a/run/tests b/run/tests
index aa8c8c193..ab0fcf2f5 100755
--- a/run/tests
+++ b/run/tests
@@ -18,6 +18,7 @@ if [ "$(uname)" == "Darwin" ]; then
cp fonts/*.ttf $resources
cp -r ../libdcp/tags $resources
cp -r ../libdcp/xsd $resources
+ cp ../libdcp/ratings $resources
rm -f build/test/openssl
ln -s ../../../openssl/apps/openssl build/test/openssl
# SIP stops this being passed in from the caller's environment
diff --git a/run/tests.bat b/run/tests.bat
index a6ae38fa7..598338f17 100644
--- a/run/tests.bat
+++ b/run/tests.bat
@@ -1,6 +1,7 @@
set PATH=%PATH%;c:\users\ci\bin;c:\users\ci\workspace\dcpomatic\bin;c:\users\ci\workspace\dcpomatic\lib
set DCPOMATIC_TEST_PRIVATE=c:\users\ci\dcpomatic-test-private
xcopy ..\libdcp\tags build\tags\
+copy ..\libdcp\ratings build\
copy ..\openssl\apps\openssl.exe build\test\
xcopy fonts build\fonts\
build\test\unit-tests.exe --log_level=test_suite %1 %2
diff --git a/src/lib/cross.h b/src/lib/cross.h
index aad223d60..99c6bc299 100644
--- a/src/lib/cross.h
+++ b/src/lib/cross.h
@@ -53,8 +53,7 @@ extern boost::filesystem::path disk_writer_path ();
extern void maybe_open_console ();
#endif
extern boost::filesystem::path resources_path ();
-extern boost::filesystem::path xsd_path ();
-extern boost::filesystem::path tags_path ();
+extern boost::filesystem::path libdcp_resources_path ();
extern FILE * fopen_boost (boost::filesystem::path, std::string);
extern int dcpomatic_fseek (FILE *, int64_t, int);
extern void start_batch_converter ();
diff --git a/src/lib/cross_linux.cc b/src/lib/cross_linux.cc
index 07a70cc0b..14b8c71ba 100644
--- a/src/lib/cross_linux.cc
+++ b/src/lib/cross_linux.cc
@@ -109,22 +109,12 @@ resources_path ()
boost::filesystem::path
-xsd_path ()
+libdcp_resources_path ()
{
if (auto appdir = getenv("APPDIR")) {
- return boost::filesystem::path(appdir) / "usr" / "share" / "libdcp" / "xsd";
+ return boost::filesystem::path(appdir) / "usr" / "share" / "libdcp";
}
- return boost::filesystem::canonical(LINUX_SHARE_PREFIX) / "libdcp" / "xsd";
-}
-
-
-boost::filesystem::path
-tags_path ()
-{
- if (auto appdir = getenv("APPDIR")) {
- return boost::filesystem::path(appdir) / "usr" / "share" / "libdcp" / "tags";
- }
- return boost::filesystem::canonical(LINUX_SHARE_PREFIX) / "libdcp" / "tags";
+ return boost::filesystem::canonical(LINUX_SHARE_PREFIX) / "libdcp";
}
diff --git a/src/lib/cross_osx.cc b/src/lib/cross_osx.cc
index b06f45a77..b11ac90ef 100644
--- a/src/lib/cross_osx.cc
+++ b/src/lib/cross_osx.cc
@@ -115,16 +115,9 @@ resources_path ()
boost::filesystem::path
-xsd_path ()
+libdcp_resources_path ()
{
- return resources_path() / "xsd";
-}
-
-
-boost::filesystem::path
-tags_path ()
-{
- return resources_path() / "tags";
+ return resources_path();
}
diff --git a/src/lib/cross_windows.cc b/src/lib/cross_windows.cc
index 4990f53ee..324b8cd8b 100644
--- a/src/lib/cross_windows.cc
+++ b/src/lib/cross_windows.cc
@@ -210,16 +210,9 @@ resources_path ()
boost::filesystem::path
-xsd_path ()
+libdcp_resources_path ()
{
- return directory_containing_executable().parent_path() / "xsd";
-}
-
-
-boost::filesystem::path
-tags_path ()
-{
- return directory_containing_executable().parent_path() / "tags";
+ return resources_path ();
}
diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h
index 69520fbd6..40ed181fe 100644
--- a/src/lib/dcp_content.h
+++ b/src/lib/dcp_content.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2014-2022 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -18,16 +18,21 @@
*/
+
#ifndef DCPOMATIC_DCP_CONTENT_H
#define DCPOMATIC_DCP_CONTENT_H
+
/** @file src/lib/dcp_content.h
* @brief DCPContent class.
*/
+
#include "content.h"
#include <libcxml/cxml.h>
#include <dcp/encrypted_kdm.h>
+#include <dcp/rating.h>
+
class DCPContentProperty
{
@@ -42,7 +47,6 @@ public:
static int const CPL;
};
-class ContentPart;
/** @class DCPContent
* @brief An existing DCP used as input.
@@ -217,4 +221,5 @@ private:
std::vector<std::string> _content_versions;
};
+
#endif
diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h
index fd643a754..757e3ff03 100644
--- a/src/lib/dcp_examiner.h
+++ b/src/lib/dcp_examiner.h
@@ -18,19 +18,24 @@
*/
+
/** @file src/lib/dcp_examiner.h
* @brief DCPExaminer class.
*/
-#include "video_examiner.h"
+
#include "audio_examiner.h"
#include "dcp.h"
#include "dcp_text_track.h"
#include "dcpomatic_assert.h"
+#include "video_examiner.h"
#include <dcp/dcp_time.h>
+#include <dcp/rating.h>
+
class DCPContent;
+
class DCPExaminer : public DCP, public VideoExaminer, public AudioExaminer
{
public:
diff --git a/src/lib/film.h b/src/lib/film.h
index 78a66e17f..a1bec3d53 100644
--- a/src/lib/film.h
+++ b/src/lib/film.h
@@ -36,6 +36,7 @@
#include <dcp/encrypted_kdm.h>
#include <dcp/key.h>
#include <dcp/language_tag.h>
+#include <dcp/rating.h>
#include <boost/filesystem.hpp>
#include <boost/signals2.hpp>
#include <boost/thread.hpp>
diff --git a/src/lib/util.cc b/src/lib/util.cc
index c165a5129..ccd505e57 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -399,7 +399,7 @@ DCPOMATIC_ENABLE_WARNINGS
#endif
Pango::init ();
- dcp::init (tags_path());
+ dcp::init (libdcp_resources_path());
#if defined(DCPOMATIC_WINDOWS) || defined(DCPOMATIC_OSX)
/* Render something to fontconfig to create its cache */
diff --git a/src/lib/verify_dcp_job.cc b/src/lib/verify_dcp_job.cc
index 1b30b2112..b59f5bfab 100644
--- a/src/lib/verify_dcp_job.cc
+++ b/src/lib/verify_dcp_job.cc
@@ -76,7 +76,7 @@ VerifyDCPJob::update_stage (string s, optional<boost::filesystem::path> path)
void
VerifyDCPJob::run ()
{
- _notes = dcp::verify (_directories, bind (&VerifyDCPJob::update_stage, this, _1, _2), bind (&VerifyDCPJob::set_progress, this, _1, false), xsd_path());
+ _notes = dcp::verify (_directories, bind (&VerifyDCPJob::update_stage, this, _1, _2), bind (&VerifyDCPJob::set_progress, this, _1, false), libdcp_resources_path() / "xsd");
bool failed = false;
for (auto i: _notes) {
diff --git a/src/wx/rating_dialog.cc b/src/wx/rating_dialog.cc
index 6f574e83b..9886436a0 100644
--- a/src/wx/rating_dialog.cc
+++ b/src/wx/rating_dialog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2019-2022 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -18,34 +18,308 @@
*/
+
+#include "dcpomatic_spin_ctrl.h"
#include "rating_dialog.h"
#include "wx_util.h"
+#include <unicode/unistr.h>
+#include <wx/listctrl.h>
+#include <wx/notebook.h>
+#include <wx/srchctrl.h>
+
+
+using std::string;
+using std::vector;
+using boost::optional;
+#if BOOST_VERSION >= 106100
+using namespace boost::placeholders;
+#endif
+
RatingDialog::RatingDialog (wxWindow* parent)
- : TableDialog (parent, _("Ratings"), 2, 1, true)
+ : wxDialog (parent, wxID_ANY, _("Rating"))
{
- add (_("Agency"), true);
- _agency = new wxTextCtrl (this, wxID_ANY);
- add (_agency);
+ _notebook = new wxNotebook (this, wxID_ANY);
+
+ _standard_page = new StandardRatingDialogPage (_notebook);
+ _custom_page = new CustomRatingDialogPage (_notebook);
+
+ _notebook->AddPage (_standard_page, _("Standard"));
+ _notebook->AddPage (_custom_page, _("Custom"));
+
+ _active_page = _standard_page;
- add (_("Label"), true);
- _label = new wxTextCtrl (this, wxID_ANY);
- add (_label);
+ auto overall_sizer = new wxBoxSizer (wxVERTICAL);
+ overall_sizer->Add (_notebook, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
- layout ();
+ auto buttons = CreateSeparatedButtonSizer (wxOK | wxCANCEL);
+ if (buttons) {
+ overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+ }
- _agency->SetFocus ();
+ SetSizerAndFit (overall_sizer);
+
+ _notebook->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, boost::bind(&RatingDialog::page_changed, this));
+
+ _standard_page->Changed.connect(boost::bind(&RatingDialog::setup_sensitivity, this, _1));
+ _custom_page->Changed.connect(boost::bind(&RatingDialog::setup_sensitivity, this, _1));
}
+
void
-RatingDialog::set (dcp::Rating r)
+RatingDialog::page_changed ()
{
- _agency->SetValue (std_to_wx(r.agency));
- _label->SetValue (std_to_wx(r.label));
+ if (_notebook->GetSelection() == 0) {
+ _active_page = _standard_page;
+ } else {
+ _active_page = _custom_page;
+ }
}
+
+void
+RatingDialog::set (dcp::Rating rating)
+{
+ if (_standard_page->set(rating)) {
+ _notebook->SetSelection(0);
+ } else {
+ _custom_page->set(rating);
+ _notebook->SetSelection(1);
+ }
+}
+
+
dcp::Rating
RatingDialog::get () const
{
- return dcp::Rating(wx_to_std(_agency->GetValue()), wx_to_std(_label->GetValue()));
+ return _active_page->get();
+}
+
+
+void
+RatingDialog::setup_sensitivity (bool ok_valid)
+{
+ auto ok = dynamic_cast<wxButton *>(FindWindowById(wxID_OK, this));
+ if (ok) {
+ ok->Enable (ok_valid);
+ }
+}
+
+
+RatingDialogPage::RatingDialogPage (wxNotebook* notebook)
+ : wxPanel (notebook, wxID_ANY)
+{
+
}
+
+
+StandardRatingDialogPage::StandardRatingDialogPage (wxNotebook* notebook)
+ : RatingDialogPage (notebook)
+{
+ _search = new wxSearchCtrl (this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200, search_ctrl_height()));
+#ifndef __WXGTK3__
+ /* The cancel button seems to be strangely broken in GTK3; clicking on it twice sometimes works */
+ _search->ShowCancelButton (true);
+#endif
+
+ _found_systems_view = new wxListView (this, wxID_ANY, wxDefaultPosition, wxSize(600, 400), wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_NO_HEADER);
+ _found_systems_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 150);
+ _found_systems_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 50);
+ _found_systems_view->AppendColumn (wxT(""), wxLIST_FORMAT_LEFT, 400);
+ _rating = new wxChoice (this, wxID_ANY);
+
+ auto sizer = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+
+ add_label_to_sizer (sizer, this, _("Agency"), true, 0, wxALIGN_CENTER_VERTICAL);
+ sizer->Add (_search, 0, wxEXPAND, DCPOMATIC_SIZER_Y_GAP);
+
+ sizer->AddSpacer (0);
+ sizer->Add (_found_systems_view, 1, wxEXPAND | wxBOTTOM, DCPOMATIC_SIZER_Y_GAP);
+
+ add_label_to_sizer (sizer, this, _("Rating"), true, 0, wxALIGN_CENTER_VERTICAL);
+ sizer->Add (_rating, 1, wxEXPAND);
+
+ auto pad_sizer = new wxBoxSizer (wxVERTICAL);
+ pad_sizer->Add (sizer, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+
+ SetSizerAndFit (pad_sizer);
+
+ _search->Bind (wxEVT_TEXT, boost::bind(&StandardRatingDialogPage::search_changed, this));
+ _found_systems_view->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind(&StandardRatingDialogPage::found_systems_view_selection_changed, this));
+ _found_systems_view->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind(&StandardRatingDialogPage::found_systems_view_selection_changed, this));
+
+ search_changed ();
+}
+
+
+/** The user clicked something different in the list of systems found by the search */
+void
+StandardRatingDialogPage::found_systems_view_selection_changed ()
+{
+ auto selected_index = _found_systems_view->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (selected_index < 0 || selected_index >= static_cast<int>(_found_systems.size())) {
+ _selected_system = boost::none;
+ } else {
+ _selected_system = _found_systems[selected_index];
+ }
+
+ /* Update the ratings dropdown */
+ vector<wxString> items;
+ if (_selected_system) {
+ for (auto rating: _selected_system->ratings) {
+ items.push_back(std_to_wx(rating.label));
+ }
+ }
+
+ _rating->Set(items);
+
+ if (!items.empty()) {
+ _rating->SetSelection(0);
+ }
+
+ Changed (static_cast<bool>(_selected_system));
+}
+
+
+void
+StandardRatingDialogPage::search_changed ()
+{
+ _found_systems_view->DeleteAllItems();
+ _found_systems.clear();
+
+ icu::UnicodeString term(wx_to_std(_search->GetValue()).c_str(), "UTF-8");
+ term = term.toLower();
+
+ int N = 0;
+ for (auto const& system: dcp::rating_systems()) {
+ icu::UnicodeString name(system.name.c_str(), "UTF-8");
+ name = name.toLower();
+ icu::UnicodeString country_and_region_names(system.country_and_region_names.c_str(), "UTF-8");
+ country_and_region_names = country_and_region_names.toLower();
+ icu::UnicodeString country_code(system.country_code.c_str(), "UTF-8");
+ country_code = country_code.toLower();
+ if (term.isEmpty() || name.indexOf(term) != -1 || country_and_region_names.indexOf(term) != -1 || country_code.indexOf(term) != -1) {
+ wxListItem item;
+ item.SetId(N);
+ _found_systems_view->InsertItem(item);
+ _found_systems_view->SetItem(N, 0, std_to_wx(system.name));
+ _found_systems_view->SetItem(N, 1, std_to_wx(system.country_code));
+ _found_systems_view->SetItem(N, 2, std_to_wx(system.country_and_region_names));
+ _found_systems.push_back(system);
+ ++N;
+ }
+ }
+
+ update_found_system_selection ();
+}
+
+
+/** Reflect _selected_system in the current _found_systems_view */
+void
+StandardRatingDialogPage::update_found_system_selection ()
+{
+ if (!_selected_system) {
+ for (auto i = 0; i < _found_systems_view->GetItemCount(); ++i) {
+ _found_systems_view->Select(i, false);
+ }
+ return;
+ }
+
+ int index = 0;
+ for (auto const& system: _found_systems) {
+ bool const selected = system.agency == _selected_system->agency;
+ _found_systems_view->Select(index, selected);
+ if (selected) {
+ _found_systems_view->EnsureVisible(index);
+ }
+ ++index;
+ }
+}
+
+
+bool
+StandardRatingDialogPage::set (dcp::Rating rating)
+{
+ _selected_system = boost::none;
+ for (auto const& system: dcp::rating_systems()) {
+ if (system.agency == rating.agency) {
+ _selected_system = system;
+ break;
+ }
+ }
+
+ if (!_selected_system) {
+ return false;
+ }
+
+ update_found_system_selection ();
+
+ int rating_index = 0;
+ for (auto const& possible_rating: _selected_system->ratings) {
+ if (possible_rating.label == rating.label) {
+ _rating->SetSelection (rating_index);
+ return true;
+ }
+ ++rating_index;
+ }
+
+ return false;
+}
+
+
+dcp::Rating
+StandardRatingDialogPage::get () const
+{
+ DCPOMATIC_ASSERT (_selected_system);
+ auto selected_rating = _rating->GetSelection();
+ DCPOMATIC_ASSERT (selected_rating >= 0);
+ DCPOMATIC_ASSERT (selected_rating < static_cast<int>(_selected_system->ratings.size()));
+ return dcp::Rating(_selected_system->agency, _selected_system->ratings[selected_rating].label);
+}
+
+
+CustomRatingDialogPage::CustomRatingDialogPage (wxNotebook* notebook)
+ : RatingDialogPage (notebook)
+{
+ auto sizer = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP);
+
+ _agency = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(400, -1));
+ _rating = new wxTextCtrl (this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(400, -1));
+
+ add_label_to_sizer (sizer, this, _("Agency"), true, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
+ sizer->Add (_agency, 1, wxEXPAND);
+ add_label_to_sizer (sizer, this, _("Rating"), true, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL);
+ sizer->Add (_rating, 1, wxEXPAND);
+
+ auto pad_sizer = new wxBoxSizer (wxVERTICAL);
+ pad_sizer->Add (sizer, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
+
+ SetSizerAndFit (pad_sizer);
+
+ _agency->Bind(wxEVT_TEXT, boost::bind(&CustomRatingDialogPage::changed, this));
+ _rating->Bind(wxEVT_TEXT, boost::bind(&CustomRatingDialogPage::changed, this));
+}
+
+
+void
+CustomRatingDialogPage::changed ()
+{
+ Changed (!_agency->IsEmpty() && !_rating->IsEmpty());
+}
+
+
+dcp::Rating
+CustomRatingDialogPage::get () const
+{
+ return dcp::Rating(wx_to_std(_agency->GetValue()), wx_to_std(_rating->GetValue()));
+}
+
+
+bool
+CustomRatingDialogPage::set (dcp::Rating rating)
+{
+ _agency->SetValue(std_to_wx(rating.agency));
+ _rating->SetValue(std_to_wx(rating.label));
+ return true;
+}
+
diff --git a/src/wx/rating_dialog.h b/src/wx/rating_dialog.h
index 51869c0ab..27887baa2 100644
--- a/src/wx/rating_dialog.h
+++ b/src/wx/rating_dialog.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2019 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2019-2022 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -18,10 +18,70 @@
*/
-#include "table_dialog.h"
-#include <dcp/types.h>
-class RatingDialog : public TableDialog
+#include <dcp/rating.h>
+#include <wx/wx.h>
+#include <boost/signals2.hpp>
+
+
+class wxChoice;
+class wxListView;
+class wxNotebook;
+class wxSearchCtrl;
+
+
+class RatingDialogPage : public wxPanel
+{
+public:
+ RatingDialogPage (wxNotebook* notebook);
+ virtual dcp::Rating get () const = 0;
+ virtual bool set (dcp::Rating rating) = 0;
+
+ /** Emitted when the page has been changed, the parameter being true if OK
+ * should now be enabled in the main dialogue.
+ */
+ boost::signals2::signal<void (bool)> Changed;
+};
+
+
+class StandardRatingDialogPage : public RatingDialogPage
+{
+public:
+ StandardRatingDialogPage (wxNotebook* notebook);
+
+ dcp::Rating get () const override;
+ bool set (dcp::Rating rating) override;
+
+private:
+ void search_changed ();
+ void found_systems_view_selection_changed ();
+ void update_found_system_selection ();
+
+ wxSearchCtrl* _search;
+ wxListView* _found_systems_view;
+ boost::optional<dcp::RatingSystem> _selected_system;
+ wxChoice* _rating;
+ std::vector<dcp::RatingSystem> _found_systems;
+};
+
+
+class CustomRatingDialogPage : public RatingDialogPage
+{
+public:
+ CustomRatingDialogPage (wxNotebook* notebook);
+
+ dcp::Rating get () const override;
+ bool set (dcp::Rating rating) override;
+
+private:
+ void changed ();
+
+ wxTextCtrl* _agency;
+ wxTextCtrl* _rating;
+};
+
+
+class RatingDialog : public wxDialog
{
public:
RatingDialog (wxWindow* parent);
@@ -30,6 +90,13 @@ public:
dcp::Rating get () const;
private:
- wxTextCtrl* _agency;
- wxTextCtrl* _label;
+ void setup_sensitivity (bool ok_valid);
+ void page_changed ();
+
+ wxNotebook* _notebook;
+
+ StandardRatingDialogPage* _standard_page;
+ CustomRatingDialogPage* _custom_page;
+ RatingDialogPage* _active_page;
};
+
diff --git a/src/wx/wscript b/src/wx/wscript
index 93afaeda2..7e028274e 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -309,7 +309,7 @@ def build(bld):
obj.name = 'libdcpomatic2-wx'
obj.export_includes = ['..']
- obj.uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX WXWIDGETS DCP SUB ZIP CXML RTAUDIO '
+ obj.uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX WXWIDGETS DCP SUB ZIP CXML RTAUDIO ICU '
if bld.env.TARGET_LINUX:
obj.uselib += 'GTK GL GLU '
if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32:
diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc
index 988adeecc..fad3779bd 100644
--- a/src/wx/wx_util.cc
+++ b/src/wx/wx_util.cc
@@ -86,7 +86,7 @@ setup_osx_flags (wxSizer* s, bool left, int& flags)
#endif
-/** Add a wxStaticText to a wxSizer, aligning it at vertical centre.
+/** Add a wxStaticText to a wxSizer.
* @param s Sizer to add to.
* @param p Parent window for the wxStaticText.
* @param t Text for the wxStaticText.
diff --git a/wscript b/wscript
index d1b9fd46d..91a0ee243 100644
--- a/wscript
+++ b/wscript
@@ -35,8 +35,8 @@ except ImportError:
from waflib import Logs, Context
APPNAME = 'dcpomatic'
-libdcp_version = '1.8.5'
-libsub_version = '1.6.5'
+libdcp_version = '1.8.9'
+libsub_version = '1.6.9'
this_version = subprocess.Popen(shlex.split('git tag -l --points-at HEAD'), stdout=subprocess.PIPE).communicate()[0]
last_version = subprocess.Popen(shlex.split('git describe --tags --match v* --abbrev=0'), stdout=subprocess.PIPE).communicate()[0]