Merge remote-tracking branch 'origin/main' into v2.17.x
[dcpomatic.git] / src / tools / dcpomatic.cc
index c0a182eb6d373041352107e87cad4669c728bc21..d516c6f5bea3c41ca8728139f0cbfb9a74314fd7 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "wx/about_dialog.h"
 #include "wx/content_panel.h"
+#include "wx/dcp_referencing_dialog.h"
 #include "wx/dkdm_dialog.h"
 #include "wx/export_subtitles_dialog.h"
 #include "wx/export_video_file_dialog.h"
@@ -36,6 +37,7 @@
 #include "wx/full_config_dialog.h"
 #include "wx/hints_dialog.h"
 #include "wx/html_dialog.h"
+#include "wx/file_dialog.h"
 #include "wx/i18n_hook.h"
 #include "wx/id.h"
 #include "wx/job_manager_view.h"
 #include "lib/dcpomatic_log.h"
 #include "lib/dcpomatic_socket.h"
 #include "lib/dkdm_wrapper.h"
-#include "lib/emailer.h"
+#include "lib/email.h"
 #include "lib/encode_server_finder.h"
 #include "lib/exceptions.h"
 #include "lib/ffmpeg_encoder.h"
 #include "lib/film.h"
 #include "lib/font_config.h"
+#ifdef DCPOMATIC_GROK
+#include "lib/grok/context.h"
+#endif
 #include "lib/hints.h"
 #include "lib/job_manager.h"
 #include "lib/kdm_with_metadata.h"
@@ -207,6 +212,7 @@ private:
 #define NEEDS_SELECTED_VIDEO_CONTENT  0x20
 #define NEEDS_CLIPBOARD               0x40
 #define NEEDS_ENCRYPTION              0x80
+#define NEEDS_DCP_CONTENT             0x100
 
 
 map<wxMenuItem*, int> menu_items;
@@ -236,6 +242,7 @@ enum {
        ID_jobs_open_dcp_in_player,
        ID_view_closed_captions,
        ID_view_video_waveform,
+       ID_tools_version_file,
        ID_tools_hints,
        ID_tools_encoding_servers,
        ID_tools_manage_templates,
@@ -244,6 +251,7 @@ enum {
        ID_tools_system_information,
        ID_tools_restore_default_preferences,
        ID_tools_export_preferences,
+       ID_tools_import_preferences,
        ID_help_report_a_problem,
        /* IDs for shortcuts (with no associated menu item) */
        ID_add_file,
@@ -347,6 +355,7 @@ public:
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::jobs_open_dcp_in_player, this), ID_jobs_open_dcp_in_player);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::view_closed_captions, this),    ID_view_closed_captions);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::view_video_waveform, this),     ID_view_video_waveform);
+               Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_version_file, this),      ID_tools_version_file);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_hints, this),             ID_tools_hints);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_encoding_servers, this),  ID_tools_encoding_servers);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_manage_templates, this),  ID_tools_manage_templates);
@@ -355,6 +364,7 @@ public:
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_system_information, this),ID_tools_system_information);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_restore_default_preferences, this), ID_tools_restore_default_preferences);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_export_preferences, this), ID_tools_export_preferences);
+               Bind (wxEVT_MENU, boost::bind (&DOMFrame::tools_import_preferences, this), ID_tools_import_preferences);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::help_about, this),              wxID_ABOUT);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::help_report_a_problem, this),   ID_help_report_a_problem);
 
@@ -458,6 +468,7 @@ public:
        {
                auto film = make_shared<Film>(file);
                auto const notes = film->read_metadata ();
+               film->read_ui_state();
 
                if (film->state_version() == 4) {
                        error_dialog (
@@ -757,9 +768,8 @@ private:
 
        void tools_export_preferences ()
        {
-               wxFileDialog dialog(
-                       this, _("Specify ZIP file"), wxEmptyString, wxT("dcpomatic_config.zip"), wxT("ZIP files (*.zip)|*.zip"),
-                       wxFD_SAVE | wxFD_OVERWRITE_PROMPT
+               FileDialog dialog(
+                       this, _("Specify ZIP file"), wxT("ZIP files (*.zip)|*.zip"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, "Preferences", string("dcpomatic_config.zip")
                        );
 
                if (dialog.ShowModal() == wxID_OK) {
@@ -777,6 +787,15 @@ private:
                }
        }
 
+       void tools_import_preferences()
+       {
+               FileDialog dialog(this, _("Specify ZIP file"), wxT("ZIP files (*.zip)|*.zip"), wxFD_OPEN, "Preferences");
+
+               if (dialog.show()) {
+                       Config::instance()->load_from_zip(dialog.path());
+               }
+       }
+
        void jobs_make_dcp ()
        {
                double required;
@@ -1063,6 +1082,17 @@ private:
                _system_information_dialog->Show ();
        }
 
+       void tools_version_file()
+       {
+               if (_dcp_referencing_dialog) {
+                       _dcp_referencing_dialog->Destroy();
+                       _dcp_referencing_dialog = nullptr;
+               }
+
+               _dcp_referencing_dialog = new DCPReferencingDialog(this, _film);
+               _dcp_referencing_dialog->Show();
+       }
+
        void tools_hints ()
        {
                if (!_hints_dialog) {
@@ -1116,9 +1146,9 @@ private:
                        error_dialog (this, _("You must enter a valid email address when sending translations, "
                                              "otherwise the DCP-o-matic maintainers cannot credit you or contact you with questions."));
                } else {
-                       Emailer emailer(dialog.email(), { "carl@dcpomatic.com" }, "DCP-o-matic translations", body);
+                       Email email(dialog.email(), { "carl@dcpomatic.com" }, "DCP-o-matic translations", body);
                        try {
-                               emailer.send ("main.carlh.net", 2525, EmailProtocol::STARTTLS);
+                               email.send("main.carlh.net", 2525, EmailProtocol::STARTTLS);
                        } catch (NetworkError& e) {
                                error_dialog (this, _("Could not send translations"), std_to_wx(e.what()));
                        }
@@ -1191,6 +1221,7 @@ private:
                FontConfig::drop();
 
                ev.Skip ();
+               JobManager::drop ();
        }
 
        void active_jobs_changed()
@@ -1214,6 +1245,13 @@ private:
                bool const have_single_selected_content = _film_editor->content_panel()->selected().size() == 1;
                bool const have_selected_content = !_film_editor->content_panel()->selected().empty();
                bool const have_selected_video_content = !_film_editor->content_panel()->selected_video().empty();
+               vector<shared_ptr<Content>> content;
+               if (_film) {
+                       content = _film->content();
+               }
+               bool const have_dcp_content = std::find_if(content.begin(), content.end(), [](shared_ptr<const Content> content) {
+                       return static_cast<bool>(dynamic_pointer_cast<const DCPContent>(content));
+               }) != content.end();
 
                for (auto j: menu_items) {
 
@@ -1251,6 +1289,10 @@ private:
                                enabled = false;
                        }
 
+                       if ((j.second & NEEDS_DCP_CONTENT) && !have_dcp_content) {
+                               enabled = false;
+                       }
+
                        j.first->Enable (enabled);
                }
        }
@@ -1384,6 +1426,7 @@ private:
                add_item (view, _("Video waveform..."), ID_view_video_waveform, NEEDS_FILM);
 
                auto tools = new wxMenu;
+               add_item (tools, _("Version File (VF)..."), ID_tools_version_file, NEEDS_FILM | NEEDS_DCP_CONTENT);
                add_item (tools, _("Hints..."), ID_tools_hints, NEEDS_FILM);
                add_item (tools, _("Encoding servers..."), ID_tools_encoding_servers, 0);
                add_item (tools, _("Manage templates..."), ID_tools_manage_templates, 0);
@@ -1394,6 +1437,7 @@ private:
                add_item (tools, _("Restore default preferences"), ID_tools_restore_default_preferences, ALWAYS);
                tools->AppendSeparator ();
                add_item (tools, _("Export preferences..."), ID_tools_export_preferences, ALWAYS);
+               add_item (tools, _("Import preferences..."), ID_tools_import_preferences, ALWAYS);
 
                wxMenu* help = new wxMenu;
 #ifdef __WXOSX__
@@ -1488,6 +1532,12 @@ private:
                _history_items = history.size ();
 
                dcpomatic_log->set_types (Config::instance()->log_types());
+
+#ifdef DCPOMATIC_GROK
+               if (what == Config::GROK) {
+                       setup_grok_library_path();
+               }
+#endif
        }
 
        void update_checker_state_changed ()
@@ -1569,6 +1619,7 @@ private:
        StandardControls* _controls;
        wx_ptr<VideoWaveformDialog> _video_waveform_dialog;
        SystemInformationDialog* _system_information_dialog = nullptr;
+       DCPReferencingDialog* _dcp_referencing_dialog = nullptr;
        HintsDialog* _hints_dialog = nullptr;
        ServersListDialog* _servers_list_dialog = nullptr;
        wxPreferencesEditor* _config_dialog = nullptr;
@@ -1736,6 +1787,11 @@ private:
                                notes.Centre();
                                notes.ShowModal();
                        }
+
+#ifdef DCPOMATIC_GROK
+                       grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] "));
+                       setup_grok_library_path();
+#endif
                }
                catch (exception& e)
                {