From 03dd6e03f5ee261b9c1ed9328ad2762ef3b62057 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Dec 2015 00:23:19 +0000 Subject: [PATCH] Add a stored list of DKDMs to the creator rather than just a load button (#767). --- ChangeLog | 4 ++ cscript | 4 +- src/lib/config.cc | 10 ++++ src/lib/config.h | 12 +++++ src/tools/dcpomatic_kdm.cc | 100 ++++++++++++++++++------------------- src/wx/editable_list.h | 27 ++++++++-- src/wx/screen_dialog.cc | 43 ++++------------ src/wx/screen_dialog.h | 4 +- src/wx/screens_panel.cc | 2 +- 9 files changed, 113 insertions(+), 93 deletions(-) diff --git a/ChangeLog b/ChangeLog index 560f09ef1..3e3804890 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2015-12-23 Carl Hetherington + + * Add stored list of DKDMs to KDM creator (#767). + 2015-12-22 Carl Hetherington * Fix hang when removing screens in some cases. diff --git a/cscript b/cscript index 9bee9b497..c25a68e59 100644 --- a/cscript +++ b/cscript @@ -279,8 +279,8 @@ def dependencies(target): ffmpeg_options = {} return (('ffmpeg-cdist', 'b559555', ffmpeg_options), - ('libdcp', 'fb03c08'), - ('libsub', 'f368daf')) + ('libdcp', '2a4eb72'), + ('libsub', '4e6d9c9')) def configure_options(target): opt = '' diff --git a/src/lib/config.cc b/src/lib/config.cc index b9e25e37a..54d42a1b9 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -284,6 +284,12 @@ Config::read () } else { _decryption_chain = create_certificate_chain (); } + + list dkdm = f.node_children ("DKDM"); + BOOST_FOREACH (cxml::NodePtr i, f.node_children ("DKDM")) { + _dkdms.push_back (dcp::EncryptedKDM (i->content ())); + } + } /** @return Filename to write configuration to */ @@ -416,6 +422,10 @@ Config::write () const root->add_child("History")->add_child_text (i->string ()); } + BOOST_FOREACH (dcp::EncryptedKDM i, _dkdms) { + root->add_child("DKDM")->add_child_text (i.as_xml ()); + } + try { doc.write_to_file_formatted (file().string ()); } catch (xmlpp::exception& e) { diff --git a/src/lib/config.h b/src/lib/config.h index 664020a2a..6b1f3fb87 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -27,6 +27,7 @@ #include "isdcf_metadata.h" #include "types.h" #include +#include #include #include #include @@ -244,6 +245,10 @@ public: return _history; } + std::vector dkdms () const { + return _dkdms; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { maybe_set (_num_local_encoding_threads, n); @@ -432,6 +437,12 @@ public: } #endif + void set_dkdms (std::vector dkdms) + { + _dkdms = dkdms; + changed (); + } + void clear_history () { _history.clear (); changed (); @@ -531,6 +542,7 @@ private: bool _win32_console; #endif std::vector _history; + std::vector _dkdms; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index ae5802e74..929fab37b 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -27,6 +27,8 @@ #include "wx/kdm_timing_panel.h" #include "wx/kdm_output_panel.h" #include "wx/job_view_dialog.h" +#include "wx/file_dialog_wrapper.h" +#include "wx/editable_list.h" #include "lib/config.h" #include "lib/util.h" #include "lib/screen.h" @@ -35,6 +37,7 @@ #include "lib/exceptions.h" #include "lib/cinema_kdms.h" #include "lib/send_kdm_email_job.h" +#include "lib/compose.hpp" #include #include #include @@ -54,6 +57,7 @@ using std::exception; using std::list; using std::string; +using std::vector; using boost::shared_ptr; using boost::bind; @@ -61,6 +65,22 @@ enum { ID_help_report_a_problem = 1, }; +class KDMFileDialogWrapper : public FileDialogWrapper +{ +public: + KDMFileDialogWrapper (wxWindow* parent) + : FileDialogWrapper (parent, _("Select DKDM file")) + { + + } +}; + +static string +column (dcp::EncryptedKDM k) +{ + return String::compose ("%1 (%2)", k.content_title_text(), k.cpl_id()); +} + class DOMFrame : public wxFrame { public: @@ -118,20 +138,16 @@ public: _timing = new KDMTimingPanel (overall_panel); vertical->Add (_timing, 0, wxALL, DCPOMATIC_SIZER_Y_GAP); - wxSizer* dkdm = new wxFlexGridSizer (2, DCPOMATIC_SIZER_X_GAP, DCPOMATIC_SIZER_Y_GAP); - add_label_to_sizer (dkdm, overall_panel, _("DKDM file"), true); - _dkdm = new FilePickerCtrl (overall_panel, _("Select a DKDM XML file..."), "*.xml"); - dkdm->Add (_dkdm, 1, wxEXPAND); - add_label_to_sizer (dkdm, overall_panel, _("Content title"), true); - _content_title_text = new wxStaticText (overall_panel, wxID_ANY, wxT("")); - dkdm->Add (_content_title_text, 1, wxEXPAND); - add_label_to_sizer (dkdm, overall_panel, _("Annotation"), true); - _annotation_text = new wxStaticText (overall_panel, wxID_ANY, wxT("")); - dkdm->Add (_annotation_text, 1, wxEXPAND); - add_label_to_sizer (dkdm, overall_panel, _("Issue date"), true); - _issue_date = new wxStaticText (overall_panel, wxID_ANY, wxT("")); - dkdm->Add (_issue_date, 1, wxEXPAND); - vertical->Add (dkdm, 0, wxALL, DCPOMATIC_SIZER_X_GAP); + h = new wxStaticText (overall_panel, wxID_ANY, _("DKDM")); + h->SetFont (subheading_font); + vertical->Add (h, 0, wxALIGN_CENTER_VERTICAL | wxTOP, DCPOMATIC_SIZER_Y_GAP * 2); + + vector columns; + columns.push_back (wx_to_std (_("CPL"))); + _dkdm = new EditableList ( + overall_panel, columns, bind (&DOMFrame::dkdms, this), bind (&DOMFrame::set_dkdms, this, _1), bind (&column, _1), false + ); + vertical->Add (_dkdm, 0, wxEXPAND | wxALL, DCPOMATIC_SIZER_Y_GAP); h = new wxStaticText (overall_panel, wxID_ANY, _("Output")); h->SetFont (subheading_font); @@ -150,13 +166,23 @@ public: Config::instance()->Changed.connect (boost::bind (&Config::write, Config::instance ())); _screens->ScreensChanged.connect (boost::bind (&DOMFrame::setup_sensitivity, this)); - _dkdm->Bind (wxEVT_COMMAND_FILEPICKER_CHANGED, bind (&DOMFrame::dkdm_changed, this)); _create->Bind (wxEVT_COMMAND_BUTTON_CLICKED, bind (&DOMFrame::create_kdms, this)); + _dkdm->SelectionChanged.connect (boost::bind (&DOMFrame::setup_sensitivity, this)); setup_sensitivity (); } private: + vector dkdms () const + { + return Config::instance()->dkdms (); + } + + void set_dkdms (vector dkdms) + { + Config::instance()->set_dkdms (dkdms); + } + void file_exit () { /* false here allows the close handler to veto the close request */ @@ -219,41 +245,15 @@ private: m->Append (help, _("&Help")); } - void dkdm_changed () - { - if (_dkdm->GetPath().IsEmpty()) { - return; - } - - try { - dcp::EncryptedKDM encrypted (dcp::file_to_string (wx_to_std (_dkdm->GetPath()))); - dcp::DecryptedKDM decrypted (encrypted, Config::instance()->decryption_chain()->key().get()); - _annotation_text->Enable (true); - _annotation_text->SetLabel (std_to_wx (decrypted.annotation_text ())); - _content_title_text->Enable (true); - _content_title_text->SetLabel (std_to_wx (decrypted.content_title_text ())); - _issue_date->Enable (true); - _issue_date->SetLabel (std_to_wx (decrypted.issue_date ())); - } catch (exception& e) { - error_dialog (this, wxString::Format (_("Could not load DKDM (%s)"), std_to_wx (e.what()).data())); - _dkdm->SetPath (wxT("")); - _annotation_text->SetLabel (wxT("")); - _annotation_text->Enable (false); - _content_title_text->SetLabel (wxT("")); - _content_title_text->Enable (false); - _issue_date->SetLabel (wxT("")); - _issue_date->Enable (false); - } - - setup_sensitivity (); - } - void create_kdms () { try { + if (!_dkdm->selection()) { + return; + } + /* Decrypt the DKDM */ - dcp::EncryptedKDM encrypted (dcp::file_to_string (wx_to_std (_dkdm->GetPath()))); - dcp::DecryptedKDM decrypted (encrypted, Config::instance()->decryption_chain()->key().get()); + dcp::DecryptedKDM decrypted (_dkdm->selection().get(), Config::instance()->decryption_chain()->key().get()); /* This is the signer for our new KDMs */ shared_ptr signer = Config::instance()->signer_chain (); @@ -324,17 +324,13 @@ private: { _screens->setup_sensitivity (); _output->setup_sensitivity (); - _create->Enable (!_screens->screens().empty() && !_dkdm->GetPath().IsEmpty()); + _create->Enable (!_screens->screens().empty() && _dkdm->selection()); } wxPreferencesEditor* _config_dialog; ScreensPanel* _screens; KDMTimingPanel* _timing; - /* I can't seem to clear the value in a wxFilePickerCtrl, so use our own */ - FilePickerCtrl* _dkdm; - wxStaticText* _annotation_text; - wxStaticText* _content_title_text; - wxStaticText* _issue_date; + EditableList* _dkdm; wxButton* _create; KDMOutputPanel* _output; JobViewDialog* _job_view; diff --git a/src/wx/editable_list.h b/src/wx/editable_list.h index f895e4a0a..1f0ead3cd 100644 --- a/src/wx/editable_list.h +++ b/src/wx/editable_list.h @@ -39,7 +39,8 @@ public: boost::function ()> get, boost::function)> set, boost::function column, - bool can_edit = true + bool can_edit = true, + bool title = true ) : wxPanel (parent) , _get (get) @@ -55,7 +56,11 @@ public: table->AddGrowableCol (0, 1); s->Add (table, 1, wxEXPAND); - _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (columns.size() * 200, 100), wxLC_REPORT | wxLC_SINGLE_SEL); + long style = wxLC_REPORT | wxLC_SINGLE_SEL; + if (title) { + style |= wxLC_NO_HEADER; + } + _list = new wxListCtrl (this, wxID_ANY, wxDefaultPosition, wxSize (columns.size() * 200, 100), style); for (size_t i = 0; i < columns.size(); ++i) { wxListItem ip; @@ -104,6 +109,20 @@ public: } } + boost::optional selection () const + { + int item = _list->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) { + return boost::optional (); + } + + std::vector all = _get (); + DCPOMATIC_ASSERT (item >= 0 && item < int (all.size ())); + return all[item]; + } + + boost::signals2::signal SelectionChanged; + private: void add_to_control (T item) @@ -125,13 +144,13 @@ private: _edit->Enable (i >= 0); } _remove->Enable (i >= 0); + + SelectionChanged (); } void add_clicked () { - T new_item; S* dialog = new S (this); - dialog->set (new_item); if (dialog->ShowModal() == wxID_OK) { add_to_control (dialog->get ()); diff --git a/src/wx/screen_dialog.cc b/src/wx/screen_dialog.cc index 6c95c0bae..fcb878bc0 100644 --- a/src/wx/screen_dialog.cc +++ b/src/wx/screen_dialog.cc @@ -19,6 +19,7 @@ #include "screen_dialog.h" #include "wx_util.h" +#include "file_dialog_wrapper.h" #include "download_certificate_dialog.h" #include "lib/compose.hpp" #include "lib/util.h" @@ -33,44 +34,22 @@ using std::vector; using boost::optional; using boost::bind; -class FileDialogWrapper +static string +column (dcp::Certificate c) { -public: - FileDialogWrapper (wxWindow* parent) - : _parent (parent) - { - _dialog = new wxFileDialog (parent, _("Select certificate file")); - } - - void set (dcp::Certificate) {} - - dcp::Certificate get () { - return dcp::Certificate (dcp::file_to_string (wx_to_std (_dialog->GetPath ()))); - } + return c.thumbprint (); +} - int ShowModal () +class CertificateFileDialogWrapper : public FileDialogWrapper +{ +public: + CertificateFileDialogWrapper (wxWindow* parent) + : FileDialogWrapper (parent, _("Select certificate file")) { - return _dialog->ShowModal (); - } - void Destroy () - { - _dialog->Destroy (); - /* eek! */ - delete this; } - -private: - wxWindow* _parent; - wxFileDialog* _dialog; }; -static string -column (dcp::Certificate c) -{ - return c.thumbprint (); -} - ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, optional recipient, vector trusted_devices) : wxDialog (parent, wxID_ANY, std_to_wx (title)) , _recipient (recipient) @@ -112,7 +91,7 @@ ScreenDialog::ScreenDialog (wxWindow* parent, string title, string name, optiona vector columns; columns.push_back (wx_to_std (_("Thumbprint"))); - _trusted_device_list = new EditableList ( + _trusted_device_list = new EditableList ( this, columns, bind (&ScreenDialog::trusted_devices, this), bind (&ScreenDialog::set_trusted_devices, this, _1), bind (&column, _1), false ); diff --git a/src/wx/screen_dialog.h b/src/wx/screen_dialog.h index 2985516c4..5ae369415 100644 --- a/src/wx/screen_dialog.h +++ b/src/wx/screen_dialog.h @@ -24,7 +24,7 @@ #include class Progress; -class FileDialogWrapper; +class CertificateFileDialogWrapper; class ScreenDialog : public wxDialog { @@ -59,7 +59,7 @@ private: wxStaticText* _recipient_thumbprint; wxButton* _get_recipient_from_file; wxButton* _download_recipient; - EditableList* _trusted_device_list; + EditableList* _trusted_device_list; boost::optional _recipient; std::vector _trusted_devices; diff --git a/src/wx/screens_panel.cc b/src/wx/screens_panel.cc index e45f036d2..bc7fd43df 100644 --- a/src/wx/screens_panel.cc +++ b/src/wx/screens_panel.cc @@ -39,7 +39,7 @@ ScreensPanel::ScreensPanel (wxWindow* parent) wxBoxSizer* targets = new wxBoxSizer (wxHORIZONTAL); _targets = new wxTreeCtrl (this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT); - targets->Add (_targets, 1, wxEXPAND | wxTOP | wxRIGHT, DCPOMATIC_SIZER_GAP); + targets->Add (_targets, 1, wxEXPAND | wxRIGHT, DCPOMATIC_SIZER_GAP); _root = _targets->AddRoot ("Foo"); -- 2.30.2