Merge.
authorCarl Hetherington <cth@carlh.net>
Tue, 7 Mar 2017 10:18:31 +0000 (10:18 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 7 Mar 2017 10:18:31 +0000 (10:18 +0000)
13 files changed:
ChangeLog
src/lib/cinema_kdms.cc
src/lib/cinema_kdms.h
src/lib/config.cc
src/lib/config.h
src/tools/dcpomatic.cc
src/tools/dcpomatic_kdm.cc
src/tools/dcpomatic_kdm_cli.cc
src/wx/about_dialog.cc
src/wx/kdm_dialog.cc
src/wx/kdm_output_panel.cc
src/wx/kdm_output_panel.h
src/wx/name_format_editor.cc

index f7e10cc3e7e6fe6547f59e9e16ec3277dcc59015..19cd66c71cb40c4cd8b142352f62a9179c45746d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
 
        * Handle failure to write to cinemas file more nicely.
 
+2017-03-03  Carl Hetherington  <cth@carlh.net>
+
+       * Add option to write KDMs to separate folders
+       or ZIP files.
+
 2017-02-28  Carl Hetherington  <cth@carlh.net>
 
        * Updated de_DE translation from Carsten Kurz.
index e82a987e846f49dc1ea0bd772fecadc8e80f4456..8cac65f41574602973b300d03ba22b10f6b9569e 100644 (file)
@@ -37,6 +37,7 @@ using std::cout;
 using std::string;
 using std::runtime_error;
 using boost::shared_ptr;
+using boost::function;
 
 void
 CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, dcp::NameFormat name_format, dcp::NameFormat::Map name_values) const
@@ -113,24 +114,67 @@ CinemaKDMs::collect (list<ScreenKDM> screen_kdms)
        return cinema_kdms;
 }
 
+/** Write one directory per cinema into another directory */
+int
+CinemaKDMs::write_directories (
+       list<CinemaKDMs> cinema_kdms,
+       boost::filesystem::path directory,
+       dcp::NameFormat container_name_format,
+       dcp::NameFormat filename_format,
+       dcp::NameFormat::Map name_values,
+       function<bool (boost::filesystem::path)> confirm_overwrite
+       )
+{
+       /* No specific screen */
+       name_values['s'] = "";
+
+       int written = 0;
+
+       BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
+               boost::filesystem::path path = directory;
+               name_values['c'] = i.cinema->name;
+               path /= container_name_format.get(name_values, "");
+               if (!boost::filesystem::exists (path) || confirm_overwrite (path)) {
+                       boost::filesystem::create_directories (path);
+                       ScreenKDM::write_files (i.screen_kdms, path, filename_format, name_values, confirm_overwrite);
+               }
+               written += i.screen_kdms.size();
+       }
+
+       return written;
+}
+
 /** Write one ZIP file per cinema into a directory */
-void
+int
 CinemaKDMs::write_zip_files (
        list<CinemaKDMs> cinema_kdms,
        boost::filesystem::path directory,
-       dcp::NameFormat name_format,
-       dcp::NameFormat::Map name_values
+       dcp::NameFormat container_name_format,
+       dcp::NameFormat filename_format,
+       dcp::NameFormat::Map name_values,
+       function<bool (boost::filesystem::path)> confirm_overwrite
        )
 {
        /* No specific screen */
        name_values['s'] = "";
 
+       int written = 0;
+
        BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
                boost::filesystem::path path = directory;
                name_values['c'] = i.cinema->name;
-               path /= name_format.get(name_values, ".zip");
-               i.make_zip_file (path, name_format, name_values);
+               path /= container_name_format.get(name_values, ".zip");
+               if (!boost::filesystem::exists (path) || confirm_overwrite (path)) {
+                       if (boost::filesystem::exists (path)) {
+                               /* Creating a new zip file over an existing one is an error */
+                               boost::filesystem::remove (path);
+                       }
+                       i.make_zip_file (path, filename_format, name_values);
+                       written += i.screen_kdms.size();
+               }
        }
+
+       return written;
 }
 
 /** Email one ZIP file per cinema to the cinema.
index e29fa5cbdc8037a1032f7e0de6a26aee4bde15c1..98cb84541677f2518f8b71a7750ce311cc066059 100644 (file)
@@ -31,11 +31,22 @@ public:
 
        static std::list<CinemaKDMs> collect (std::list<ScreenKDM> kdms);
 
-       static void write_zip_files (
+       static int write_directories (
                std::list<CinemaKDMs> cinema_kdms,
                boost::filesystem::path directory,
-               dcp::NameFormat name_format,
-               dcp::NameFormat::Map name_values
+               dcp::NameFormat container_name_format,
+               dcp::NameFormat filename_format,
+               dcp::NameFormat::Map name_values,
+               boost::function<bool (boost::filesystem::path)> confirm_overwrite
+               );
+
+       static int write_zip_files (
+               std::list<CinemaKDMs> cinema_kdms,
+               boost::filesystem::path directory,
+               dcp::NameFormat container_name_format,
+               dcp::NameFormat filename_format,
+               dcp::NameFormat::Map name_values,
+               boost::function<bool (boost::filesystem::path)> confirm_overwrite
                );
 
        static void email (
index 6a08125cfef35f08e008c97f46fdc418a02dc6c2..f41d40e0931300ae9a8f648067a18154309a568c 100644 (file)
@@ -111,6 +111,7 @@ Config::set_defaults ()
        _cinemas_file = path ("cinemas.xml");
        _show_hints_before_make_dcp = true;
        _confirm_kdm_email = true;
+       _kdm_container_name_format = dcp::NameFormat ("KDM %f %c");
        _kdm_filename_format = dcp::NameFormat ("KDM %f %c %s");
        _dcp_metadata_filename_format = dcp::NameFormat ("%t");
        _dcp_asset_filename_format = dcp::NameFormat ("%t");
@@ -302,6 +303,7 @@ try
        _cinemas_file = f.optional_string_child("CinemasFile").get_value_or (path ("cinemas.xml").string ());
        _show_hints_before_make_dcp = f.optional_bool_child("ShowHintsBeforeMakeDCP").get_value_or (true);
        _confirm_kdm_email = f.optional_bool_child("ConfirmKDMEmail").get_value_or (true);
+       _kdm_container_name_format = dcp::NameFormat (f.optional_string_child("KDMContainerNameFormat").get_value_or ("KDM %f %c"));
        _kdm_filename_format = dcp::NameFormat (f.optional_string_child("KDMFilenameFormat").get_value_or ("KDM %f %c %s"));
        _dcp_metadata_filename_format = dcp::NameFormat (f.optional_string_child("DCPMetadataFilenameFormat").get_value_or ("%t"));
        _dcp_asset_filename_format = dcp::NameFormat (f.optional_string_child("DCPAssetFilenameFormat").get_value_or ("%t"));
@@ -469,6 +471,7 @@ Config::write_config () const
        root->add_child("ShowHintsBeforeMakeDCP")->add_child_text (_show_hints_before_make_dcp ? "1" : "0");
        root->add_child("ConfirmKDMEmail")->add_child_text (_confirm_kdm_email ? "1" : "0");
        root->add_child("KDMFilenameFormat")->add_child_text (_kdm_filename_format.specification ());
+       root->add_child("KDMContainerNameFormat")->add_child_text (_kdm_container_name_format.specification ());
        root->add_child("DCPMetadataFilenameFormat")->add_child_text (_dcp_metadata_filename_format.specification ());
        root->add_child("DCPAssetFilenameFormat")->add_child_text (_dcp_asset_filename_format.specification ());
 
index 1bdbcb96e284247f30f2020afd56a5fd2e8e59e4..c02b12eb5456ec68ff66b08df9344b8bc9973fb6 100644 (file)
@@ -286,6 +286,10 @@ public:
                return _confirm_kdm_email;
        }
 
+       dcp::NameFormat kdm_container_name_format () const {
+               return _kdm_container_name_format;
+       }
+
        dcp::NameFormat kdm_filename_format () const {
                return _kdm_filename_format;
        }
@@ -513,6 +517,10 @@ public:
                maybe_set (_confirm_kdm_email, s);
        }
 
+       void set_kdm_container_name_format (dcp::NameFormat n) {
+               maybe_set (_kdm_container_name_format, n);
+       }
+
        void set_kdm_filename_format (dcp::NameFormat n) {
                maybe_set (_kdm_filename_format, n);
        }
@@ -650,6 +658,7 @@ private:
        bool _show_hints_before_make_dcp;
        bool _confirm_kdm_email;
        dcp::NameFormat _kdm_filename_format;
+       dcp::NameFormat _kdm_container_name_format;
        dcp::NameFormat _dcp_metadata_filename_format;
        dcp::NameFormat _dcp_asset_filename_format;
 
index d091512a04a94eed1073d43bf5a99b6570abaaa2..92de9a1f0a0d3d49d4720abc2a466977a5707f3e 100644 (file)
@@ -61,6 +61,7 @@
 #include "lib/cinema_kdms.h"
 #include "lib/dcpomatic_socket.h"
 #include "lib/hints.h"
+#include "lib/dcp_content.h"
 #include <dcp/exceptions.h>
 #include <dcp/raw_convert.h>
 #include <wx/generic/aboutdlgg.h>
@@ -1029,7 +1030,8 @@ private:
 
 static const wxCmdLineEntryDesc command_line_description[] = {
        { wxCMD_LINE_SWITCH, "n", "new", "create new film", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL },
-       { wxCMD_LINE_OPTION, "c", "content", "add content file", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
+       { wxCMD_LINE_OPTION, "c", "content", "add content file / directory", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
+       { wxCMD_LINE_OPTION, "d", "dcp", "add content DCP", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
        { wxCMD_LINE_PARAM, 0, 0, "film to load or create", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
        { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 }
 };
@@ -1127,6 +1129,9 @@ private:
                                        _frame->film()->examine_and_add_content (i);
                                }
                        }
+                       if (!_dcp_to_add.empty ()) {
+                               _frame->film()->examine_and_add_content (shared_ptr<DCPContent> (new DCPContent (_frame->film(), _dcp_to_add)));
+                       }
                }
 
                signal_manager = new wxSignalManager (this);
@@ -1169,6 +1174,11 @@ private:
                        _content_to_add = wx_to_std (content);
                }
 
+               wxString dcp;
+               if (parser.Found (wxT ("dcp"), &dcp)) {
+                       _dcp_to_add = wx_to_std (dcp);
+               }
+
                return true;
        }
 
@@ -1235,6 +1245,7 @@ private:
        string _film_to_load;
        string _film_to_create;
        string _content_to_add;
+       string _dcp_to_add;
 };
 
 IMPLEMENT_APP (App)
index 880aec454e073bed9d1320ca356c838ae9bbb926..e79448be7b376398c0562f22da8702e3bb7b8ff3 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -60,6 +60,7 @@ using std::exception;
 using std::list;
 using std::string;
 using std::vector;
+using std::pair;
 using boost::shared_ptr;
 using boost::bind;
 using boost::optional;
@@ -318,46 +319,28 @@ private:
                                screen_kdms.push_back (ScreenKDM (i, kdm.encrypt (signer, i->recipient.get(), i->trusted_devices, _output->formulation())));
                        }
 
-                       dcp::NameFormat::Map name_values;
-                       name_values['f'] = decrypted.content_title_text();
-                       name_values['b'] = dcp::LocalTime(_timing->from()).date() + " " + dcp::LocalTime(_timing->from()).time_of_day();
-                       name_values['e'] = dcp::LocalTime(_timing->until()).date() + " " + dcp::LocalTime(_timing->until()).time_of_day();
-
-                       if (_output->write_to()) {
-                               int written = ScreenKDM::write_files (
-                                       screen_kdms, _output->directory(), _output->name_format(), name_values,
-                                       bind (&DOMFrame::confirm_overwrite, this, _1)
-                                       );
+                       pair<shared_ptr<Job>, int> result = _output->make (
+                               screen_kdms, decrypted.content_title_text(), _timing, bind (&DOMFrame::confirm_overwrite, this, _1), shared_ptr<Log> ()
+                               );
 
-                               if (written > 0) {
-                                       /* XXX: proper plural form support in wxWidgets? */
-                                       wxString s = written == 1 ? _("%d KDM written to %s") : _("%d KDMs written to %s");
-                                       message_dialog (
-                                               this,
-                                               wxString::Format (s, written, std_to_wx(_output->directory().string()).data())
-                                               );
-                               }
-                       } else {
-                               string film_name = decrypted.annotation_text().get_value_or ("");
-                               if (film_name.empty ()) {
-                                       film_name = decrypted.content_title_text ();
-                               }
-                               shared_ptr<Job> job (new SendKDMEmailJob (
-                                                            CinemaKDMs::collect (screen_kdms),
-                                                            _output->name_format(),
-                                                            name_values,
-                                                            decrypted.content_title_text(),
-                                                            shared_ptr<Log> ()
-                                                            ));
-
-                               JobManager::instance()->add (job);
+                       if (result.first) {
+                               JobManager::instance()->add (result.first);
                                if (_job_view) {
                                        _job_view->Destroy ();
                                        _job_view = 0;
                                }
-                               _job_view = new JobViewDialog (this, _("Send KDM emails"), job);
+                               _job_view = new JobViewDialog (this, _("Send KDM emails"), result.first);
                                _job_view->ShowModal ();
                        }
+
+                       if (result.second > 0) {
+                               /* XXX: proper plural form support in wxWidgets? */
+                               wxString s = result.second == 1 ? _("%d KDM written to %s") : _("%d KDMs written to %s");
+                               message_dialog (
+                                       this,
+                                       wxString::Format (s, result.second, std_to_wx(_output->directory().string()).data())
+                                       );
+                       }
                } catch (dcp::NotEncryptedError& e) {
                        error_dialog (this, _("CPL's content is not encrypted."));
                } catch (exception& e) {
index 7cfcaa1712b50a39f645dc266518cf950e0fdf22..e06b9844bf2273850b645ce1cd0e2be6f98a994d 100644 (file)
@@ -302,24 +302,26 @@ int main (int argc, char* argv[])
                                );
 
                        if (zip) {
-                               CinemaKDMs::write_zip_files (
+                               int const N = CinemaKDMs::write_zip_files (
                                        CinemaKDMs::collect (screen_kdms),
                                        output,
+                                       Config::instance()->kdm_container_name_format(),
                                        Config::instance()->kdm_filename_format(),
-                                       values
+                                       values,
+                                       bind (&always_overwrite)
                                        );
 
                                if (verbose) {
-                                       cout << "Wrote ZIP files to " << output << "\n";
+                                       cout << "Wrote " << N << " ZIP files to " << output << "\n";
                                }
                        } else {
-                               ScreenKDM::write_files (
+                               int const N = ScreenKDM::write_files (
                                        screen_kdms, output, Config::instance()->kdm_filename_format(), values,
                                        bind (&always_overwrite)
                                        );
 
                                if (verbose) {
-                                       cout << "Wrote KDM files to " << output << "\n";
+                                       cout << "Wrote " << N << " KDM files to " << output << "\n";
                                }
                        }
                } catch (FileError& e) {
index dd54a2d1f206fdb8fc6ddf0b998c27a2629a20e0..c5c53849bb904fa6aade8649a42196fda5259399 100644 (file)
@@ -192,6 +192,7 @@ AboutDialog::AboutDialog (wxWindow* parent)
        supported_by.Add (wxT ("Thierry Journet"));
        supported_by.Add (wxT ("Mario Kalogjera"));
        supported_by.Add (wxT ("Zbigniew KamiƄski"));
+       supported_by.Add (wxT ("Ikram Karimov"));
        supported_by.Add (wxT ("Chris Kay"));
        supported_by.Add (wxT ("Lars Kelto"));
        supported_by.Add (wxT ("Erwan Kerzanet"));
index 5ed1169b13390a3ac8504f39609dd7ce428dcee1..5679cf0cb14c2822338d4a78d62e03574b8e9984 100644 (file)
@@ -139,65 +139,21 @@ KDMDialog::make_clicked ()
        shared_ptr<const Film> film = _film.lock ();
        DCPOMATIC_ASSERT (film);
 
-       _output->save_kdm_name_format ();
+       list<ScreenKDM> screen_kdms = film->make_kdms (
+               _screens->screens(), _cpl->cpl(), _timing->from(), _timing->until(), _output->formulation()
+               );
 
-       try {
-               list<ScreenKDM> screen_kdms = film->make_kdms (
-                       _screens->screens(), _cpl->cpl(), _timing->from(), _timing->until(), _output->formulation()
-                       );
+       pair<shared_ptr<Job>, int> result = _output->make (screen_kdms, film->name(), _timing, bind (&KDMDialog::confirm_overwrite, this, _1), film->log());
+       if (result.first) {
+               JobManager::instance()->add (result.first);
+       }
 
-               dcp::NameFormat::Map name_values;
-               name_values['f'] = film->name();
-               name_values['b'] = dcp::LocalTime(_timing->from()).date() + " " + dcp::LocalTime(_timing->from()).time_of_day();
-               name_values['e'] = dcp::LocalTime(_timing->until()).date() + " " + dcp::LocalTime(_timing->until()).time_of_day();
-
-               if (_output->write_to ()) {
-                       ScreenKDM::write_files (
-                               screen_kdms,
-                               _output->directory(),
-                               _output->name_format(),
-                               name_values,
-                               bind (&KDMDialog::confirm_overwrite, this, _1)
-                               );
-               }
-
-               if (_output->email ()) {
-
-                       list<CinemaKDMs> const cinema_kdms = CinemaKDMs::collect (screen_kdms);
-
-                       bool ok = true;
-
-                       if (Config::instance()->confirm_kdm_email ()) {
-                               list<string> emails;
-                               BOOST_FOREACH (CinemaKDMs i, cinema_kdms) {
-                                       BOOST_FOREACH (string j, i.cinema->emails) {
-                                               emails.push_back (j);
-                                       }
-                               }
-
-                               ConfirmKDMEmailDialog* d = new ConfirmKDMEmailDialog (this, emails);
-                               if (d->ShowModal() == wxID_CANCEL) {
-                                       ok = false;
-                               }
-                       }
-
-                       if (ok) {
-                               JobManager::instance()->add (
-                                       shared_ptr<Job> (new SendKDMEmailJob (
-                                                                cinema_kdms,
-                                                                _output->name_format(),
-                                                                name_values,
-                                                                film->dcp_name(),
-                                                                film->log()
-                                                                ))
-                                       );
-                       }
-               }
-       } catch (dcp::NotEncryptedError& e) {
-               error_dialog (this, _("CPL's content is not encrypted."));
-       } catch (exception& e) {
-               error_dialog (this, e.what ());
-       } catch (...) {
-               error_dialog (this, _("An unknown exception occurred."));
+       if (result.second > 0) {
+               /* XXX: proper plural form support in wxWidgets? */
+               wxString s = result.second == 1 ? _("%d KDM written to %s") : _("%d KDMs written to %s");
+               message_dialog (
+                       this,
+                       wxString::Format (s, result.second, std_to_wx(_output->directory().string()).data())
+                       );
        }
 }
index a36c82024dfdf01740a14ae5ac7f7a73e8e2bd38..f9078eac45729a9f249d62996bda5738b61078e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 */
 
 #include "lib/config.h"
+#include "lib/cinema.h"
+#include "lib/cinema_kdms.h"
+#include "lib/send_kdm_email_job.h"
 #include "kdm_output_panel.h"
+#include "kdm_timing_panel.h"
+#include "confirm_kdm_email_dialog.h"
 #include "wx_util.h"
 #include "name_format_editor.h"
+#include <dcp/exceptions.h>
 #include <dcp/types.h>
 #ifdef DCPOMATIC_USE_OWN_PICKER
 #include "dir_picker_ctrl.h"
 #endif
 #include <wx/stdpaths.h>
 
+using std::pair;
+using std::string;
+using std::list;
+using std::exception;
+using std::make_pair;
+using boost::shared_ptr;
+using boost::function;
+
 KDMOutputPanel::KDMOutputPanel (wxWindow* parent, bool interop)
        : wxPanel (parent, wxID_ANY)
 {
@@ -46,6 +60,20 @@ KDMOutputPanel::KDMOutputPanel (wxWindow* parent, bool interop)
        table->Add (_type, 1, wxEXPAND);
        _type->SetSelection (0);
 
+       {
+               int flags = wxALIGN_TOP | wxTOP | wxLEFT | wxRIGHT;
+               wxString t = _("Folder / ZIP name format");
+#ifdef __WXOSX__
+               flags |= wxALIGN_RIGHT;
+               t += wxT (":");
+#endif
+               wxStaticText* m = new wxStaticText (this, wxID_ANY, t);
+               table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP);
+       }
+
+       _container_name_format = new NameFormatEditor (this, Config::instance()->kdm_container_name_format(), dcp::NameFormat::Map(), dcp::NameFormat::Map(), "");
+       table->Add (_container_name_format->panel(), 1, wxEXPAND);
+
        {
                int flags = wxALIGN_TOP | wxTOP | wxLEFT | wxRIGHT;
                wxString t = _("Filename format");
@@ -90,6 +118,16 @@ KDMOutputPanel::KDMOutputPanel (wxWindow* parent, bool interop)
 
        table->Add (_folder, 1, wxEXPAND);
 
+       wxSizer* write_options = new wxBoxSizer(wxVERTICAL);
+       _write_flat = new wxRadioButton (this, wxID_ANY, _("Write all KDMs to the same folder"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+       write_options->Add (_write_flat);
+       _write_folder = new wxRadioButton (this, wxID_ANY, _("Write a folder for each cinema's KDMs"));
+       write_options->Add (_write_folder);
+       _write_zip = new wxRadioButton (this, wxID_ANY, _("Write a ZIP file for each cinema's KDMs"));
+       write_options->Add (_write_zip);
+       table->AddSpacer (0);
+       table->Add (write_options);
+
        _email = new wxCheckBox (this, wxID_ANY, _("Send by email"));
        table->Add (_email, 1, wxEXPAND);
        table->AddSpacer (0);
@@ -105,25 +143,100 @@ KDMOutputPanel::KDMOutputPanel (wxWindow* parent, bool interop)
 void
 KDMOutputPanel::setup_sensitivity ()
 {
-       _folder->Enable (_write_to->GetValue ());
-}
-
-boost::filesystem::path
-KDMOutputPanel::directory () const
-{
-       return wx_to_std (_folder->GetPath ());
+       bool const write = _write_to->GetValue ();
+       _folder->Enable (write);
+       _write_flat->Enable (write);
+       _write_folder->Enable (write);
+       _write_zip->Enable (write);
 }
 
-bool
-KDMOutputPanel::write_to () const
+pair<shared_ptr<Job>, int>
+KDMOutputPanel::make (
+       list<ScreenKDM> screen_kdms, string name, KDMTimingPanel* timing, function<bool (boost::filesystem::path)> confirm_overwrite, shared_ptr<Log> log
+       )
 {
-       return _write_to->GetValue ();
-}
+       Config::instance()->set_kdm_filename_format (_filename_format->get ());
+
+       int written = 0;
+       shared_ptr<Job> job;
+
+       try {
+               dcp::NameFormat::Map name_values;
+               name_values['f'] = name;
+               name_values['b'] = dcp::LocalTime(timing->from()).date() + " " + dcp::LocalTime(timing->from()).time_of_day();
+               name_values['e'] = dcp::LocalTime(timing->until()).date() + " " + dcp::LocalTime(timing->until()).time_of_day();
+
+               if (_write_to->GetValue()) {
+                       if (_write_flat->GetValue()) {
+                               written = ScreenKDM::write_files (
+                                       screen_kdms,
+                                       directory(),
+                                       _filename_format->get(),
+                                       name_values,
+                                       confirm_overwrite
+                                       );
+                       } else if (_write_folder->GetValue()) {
+                               written = CinemaKDMs::write_directories (
+                                       CinemaKDMs::collect (screen_kdms),
+                                       directory(),
+                                       _container_name_format->get(),
+                                       _filename_format->get(),
+                                       name_values,
+                                       confirm_overwrite
+                                       );
+                       } else if (_write_zip->GetValue()) {
+                               written = CinemaKDMs::write_zip_files (
+                                       CinemaKDMs::collect (screen_kdms),
+                                       directory(),
+                                       _container_name_format->get(),
+                                       _filename_format->get(),
+                                       name_values,
+                                       confirm_overwrite
+                                       );
+                       }
+               }
+
+               if (_email->GetValue ()) {
+
+                       list<CinemaKDMs> const cinema_kdms = CinemaKDMs::collect (screen_kdms);
+
+                       bool ok = true;
+
+                       if (Config::instance()->confirm_kdm_email ()) {
+                               list<string> emails;
+                               BOOST_FOREACH (CinemaKDMs i, cinema_kdms) {
+                                       BOOST_FOREACH (string j, i.cinema->emails) {
+                                               emails.push_back (j);
+                                       }
+                               }
+
+                               ConfirmKDMEmailDialog* d = new ConfirmKDMEmailDialog (this, emails);
+                               if (d->ShowModal() == wxID_CANCEL) {
+                                       ok = false;
+                               }
+                       }
+
+                       if (ok) {
+                               job.reset (
+                                       new SendKDMEmailJob (
+                                               cinema_kdms,
+                                               _filename_format->get(),
+                                               name_values,
+                                               name,
+                                               log
+                                               )
+                                       );
+                       }
+               }
+       } catch (dcp::NotEncryptedError& e) {
+               error_dialog (this, _("CPL's content is not encrypted."));
+       } catch (exception& e) {
+               error_dialog (this, e.what ());
+       } catch (...) {
+               error_dialog (this, _("An unknown exception occurred."));
+       }
 
-bool
-KDMOutputPanel::email () const
-{
-       return _email->GetValue ();
+       return make_pair (job, written);
 }
 
 dcp::Formulation
@@ -132,14 +245,8 @@ KDMOutputPanel::formulation () const
        return (dcp::Formulation) reinterpret_cast<intptr_t> (_type->GetClientData (_type->GetSelection()));
 }
 
-void
-KDMOutputPanel::save_kdm_name_format () const
-{
-       Config::instance()->set_kdm_filename_format (name_format ());
-}
-
-dcp::NameFormat
-KDMOutputPanel::name_format () const
+boost::filesystem::path
+KDMOutputPanel::directory () const
 {
-       return _filename_format->get ();
+       return wx_to_std (_folder->GetPath ());
 }
index 98e2622a9b77b00809b5a5e98b9bbc705f22b084..cb6f9a1ca69fe85f044d3ef7562ceec578dc548b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2015-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+#include "lib/screen_kdm.h"
 #include "wx_util.h"
 #include "name_format_editor.h"
 #include <dcp/types.h>
 #include <wx/wx.h>
 #include <boost/filesystem.hpp>
 
+class wxRadioButton;
 class wxDirPickerCtrl;
 class DirPickerCtrl;
+class KDMTimingPanel;
+class Job;
+class Log;
 
 class KDMOutputPanel : public wxPanel
 {
 public:
        KDMOutputPanel (wxWindow* parent, bool interop);
 
+       void setup_sensitivity ();
+
        boost::filesystem::path directory () const;
-       bool write_to () const;
-       bool email () const;
        dcp::Formulation formulation () const;
-       dcp::NameFormat name_format () const;
 
-       void setup_sensitivity ();
-       void save_kdm_name_format () const;
+       std::pair<boost::shared_ptr<Job>, int> make (
+               std::list<ScreenKDM> screen_kdms,
+               std::string name,
+               KDMTimingPanel* timing,
+               boost::function<bool (boost::filesystem::path)> confirm_overwrite,
+               boost::shared_ptr<Log> log
+               );
 
 private:
        wxChoice* _type;
+       NameFormatEditor* _container_name_format;
        NameFormatEditor* _filename_format;
        wxCheckBox* _write_to;
 #ifdef DCPOMATIC_USE_OWN_PICKER
@@ -50,5 +60,8 @@ private:
 #else
        wxDirPickerCtrl* _folder;
 #endif
+       wxRadioButton* _write_flat;
+       wxRadioButton* _write_folder;
+       wxRadioButton* _write_zip;
        wxCheckBox* _email;
 };
index 1f7ca109bbb802f3eaaf6f5f23b7f803a8d68239..82adc3f55d36cadc11caf2ba1153bcf1bea8d7cc 100644 (file)
@@ -34,7 +34,9 @@ NameFormatEditor::NameFormatEditor (wxWindow* parent, dcp::NameFormat name, dcp:
        , _suffix (suffix)
 {
        _sizer->Add (_specification, 0, wxEXPAND, DCPOMATIC_SIZER_Y_GAP);
-       _sizer->Add (_example, 0, wxBOTTOM, DCPOMATIC_SIZER_Y_GAP);
+       if (!_examples.empty ()) {
+               _sizer->Add (_example, 0, wxBOTTOM, DCPOMATIC_SIZER_Y_GAP);
+       }
        _panel->SetSizer (_sizer);
 
        for (dcp::NameFormat::Map::const_iterator i = titles.begin(); i != titles.end(); ++i) {
@@ -63,6 +65,10 @@ NameFormatEditor::changed ()
 void
 NameFormatEditor::update_example ()
 {
+       if (_examples.empty ()) {
+               return;
+       }
+
        _name.set_specification (careful_string_filter (wx_to_std (_specification->GetValue ())));
 
        wxString example = wxString::Format (_("e.g. %s"), std_to_wx (_name.get (_examples, _suffix)));