diff options
Diffstat (limited to 'src/tools/dcpomatic.cc')
| -rw-r--r-- | src/tools/dcpomatic.cc | 246 |
1 files changed, 155 insertions, 91 deletions
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 584ebd27d..8f65fa83d 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -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" @@ -41,6 +42,7 @@ #include "wx/id.h" #include "wx/job_manager_view.h" #include "wx/kdm_dialog.h" +#include "wx/load_config_from_zip_dialog.h" #include "wx/nag_dialog.h" #include "wx/paste_dialog.h" #include "wx/recreate_chain_dialog.h" @@ -55,6 +57,7 @@ #include "wx/video_waveform_dialog.h" #include "wx/wx_signal_manager.h" #include "wx/wx_util.h" +#include "wx/wx_variant.h" #include "lib/analytics.h" #include "lib/audio_content.h" #include "lib/check_content_job.h" @@ -73,9 +76,12 @@ #include "lib/email.h" #include "lib/encode_server_finder.h" #include "lib/exceptions.h" -#include "lib/ffmpeg_encoder.h" +#include "lib/ffmpeg_film_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" @@ -85,10 +91,12 @@ #include "lib/screen.h" #include "lib/send_kdm_email_job.h" #include "lib/signal_manager.h" -#include "lib/subtitle_encoder.h" +#include "lib/subtitle_film_encoder.h" #include "lib/text_content.h" #include "lib/transcode_job.h" +#include "lib/unzipper.h" #include "lib/update_checker.h" +#include "lib/variant.h" #include "lib/version.h" #include "lib/video_content.h" #include <dcp/exceptions.h> @@ -207,6 +215,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 +245,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, @@ -318,7 +328,7 @@ public: #endif _config_changed_connection = Config::instance()->Changed.connect(boost::bind(&DOMFrame::config_changed, this, _1)); - config_changed (Config::OTHER); + config_changed(Config::OTHER); _analytics_message_connection = Analytics::instance()->Message.connect(boost::bind(&DOMFrame::analytics_message, this, _1, _2)); @@ -347,6 +357,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); @@ -458,6 +469,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 ( @@ -479,8 +491,10 @@ public: auto const dir = e.file().parent_path(); if (dcp::filesystem::exists(dir / "ASSETMAP") || dcp::filesystem::exists(dir / "ASSETMAP.xml")) { error_dialog ( - this, _("Could not open this folder as a DCP-o-matic project."), - _("It looks like you are trying to open a DCP. File -> Open is for loading DCP-o-matic projects, not DCPs. To import a DCP, create a new project with File -> New and then click the \"Add DCP...\" button.") + this, variant::wx::insert_dcpomatic(_("Could not open this folder as a %s project.")), + variant::wx::insert_dcpomatic( + _("It looks like you are trying to open a DCP. File -> Open is for loading %s projects, not DCPs. " + "To import a DCP, create a new project with File -> New and then click the \"Add DCP...\" button.")) ); } else { auto const p = std_to_wx(file.string ()); @@ -564,7 +578,7 @@ private: if (!found_bad_chars.empty()) { message += wxString::Format (_("Try removing the %s characters from your folder name."), std_to_wx(found_bad_chars).data()); } else { - message += _("Please check that you do not have Windows controlled folder access enabled for DCP-o-matic."); + message += variant::wx::insert_dcpomatic(_("Please check that you do not have Windows controlled folder access enabled for %s.")); } error_dialog (this, message, std_to_wx(e.what())); #else @@ -780,9 +794,22 @@ private: { FileDialog dialog(this, _("Specify ZIP file"), wxT("ZIP files (*.zip)|*.zip"), wxFD_OPEN, "Preferences"); - if (dialog.show()) { - Config::instance()->load_from_zip(dialog.path()); + if (!dialog.show()) { + return; } + + auto action = Config::CinemasAction::WRITE_TO_CURRENT_PATH; + + if (Config::zip_contains_cinemas(dialog.path()) && Config::cinemas_file_from_zip(dialog.path()) != Config::instance()->cinemas_file()) { + LoadConfigFromZIPDialog how(this, dialog.path()); + if (how.ShowModal() == wxID_CANCEL) { + return; + } + + action = how.action(); + } + + Config::instance()->load_from_zip(dialog.path(), action); } void jobs_make_dcp () @@ -1014,7 +1041,7 @@ private: auto job = make_shared<TranscodeJob>(_film, TranscodeJob::ChangedBehaviour::EXAMINE_THEN_STOP); job->set_encoder ( - make_shared<FFmpegEncoder> ( + make_shared<FFmpegFilmEncoder>( _film, job, dialog.path(), dialog.format(), dialog.mixdown_to_stereo(), dialog.split_reels(), dialog.split_streams(), dialog.x264_crf()) ); JobManager::instance()->add (job); @@ -1029,7 +1056,7 @@ private: } auto job = make_shared<TranscodeJob>(_film, TranscodeJob::ChangedBehaviour::EXAMINE_THEN_STOP); job->set_encoder( - make_shared<SubtitleEncoder>(_film, job, dialog.path(), _film->isdcf_name(true), dialog.split_reels(), dialog.include_font()) + make_shared<SubtitleFilmEncoder>(_film, job, dialog.path(), _film->isdcf_name(true), dialog.split_reels(), dialog.include_font()) ); JobManager::instance()->add(job); } @@ -1071,6 +1098,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) { @@ -1170,6 +1208,7 @@ private: FontConfig::drop(); ev.Skip (); + JobManager::drop (); } void active_jobs_changed() @@ -1193,6 +1232,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) { @@ -1230,6 +1276,10 @@ private: enabled = false; } + if ((j.second & NEEDS_DCP_CONTENT) && !have_dcp_content) { + enabled = false; + } + j.first->Enable (enabled); } } @@ -1340,7 +1390,7 @@ private: add_item (jobs_menu, _("Make &KDMs...\tCtrl-K"), ID_jobs_make_kdms, NEEDS_FILM); /* [Shortcut] Ctrl+D:Make DKDMs */ add_item (jobs_menu, _("Make &DKDMs...\tCtrl-D"), ID_jobs_make_dkdms, NEEDS_FILM); - add_item (jobs_menu, _("Make DKDM for DCP-o-matic..."), ID_jobs_make_self_dkdm, NEEDS_FILM | NEEDS_ENCRYPTION); + add_item(jobs_menu, variant::wx::insert_dcpomatic(_("Make DKDM for %s...")), ID_jobs_make_self_dkdm, NEEDS_FILM | NEEDS_ENCRYPTION); jobs_menu->AppendSeparator (); /* [Shortcut] Ctrl+E:Export video file */ add_item (jobs_menu, _("Export video file...\tCtrl-E"), ID_jobs_export_video_file, NEEDS_FILM); @@ -1363,6 +1413,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); @@ -1376,11 +1427,13 @@ private: wxMenu* help = new wxMenu; #ifdef __WXOSX__ - add_item (help, _("About DCP-o-matic"), wxID_ABOUT, ALWAYS); + add_item(help, variant::wx::insert_dcpomatic(_("About %s")), wxID_ABOUT, ALWAYS); #else add_item (help, _("About"), wxID_ABOUT, ALWAYS); #endif - add_item (help, _("Report a problem..."), ID_help_report_a_problem, NEEDS_FILM); + if (variant::show_report_a_problem()) { + add_item(help, _("Report a problem..."), ID_help_report_a_problem, NEEDS_FILM); + } m->Append (_file_menu, _("&File")); m->Append (edit, _("&Edit")); @@ -1390,48 +1443,19 @@ private: m->Append (help, _("&Help")); } - void config_changed (Config::Property what) + void config_changed(Config::Property what) { /* Instantly save any config changes when using the DCP-o-matic GUI */ - switch (what) { - case Config::CINEMAS: - try { - Config::instance()->write_cinemas(); - } catch (exception& e) { - error_dialog ( - this, - wxString::Format ( - _("Could not write to cinemas file at %s. Your changes have not been saved."), - std_to_wx (Config::instance()->cinemas_file().string()).data() - ) - ); - } - break; - case Config::DKDM_RECIPIENTS: - try { - Config::instance()->write_dkdm_recipients(); - } catch (exception& e) { - error_dialog ( - this, - wxString::Format ( - _("Could not write to DKDM recipients file at %s. Your changes have not been saved."), - std_to_wx(Config::instance()->dkdm_recipients_file().string()).data() - ) - ); - } - break; - default: - try { - Config::instance()->write_config(); - } catch (exception& e) { - error_dialog ( - this, - wxString::Format ( - _("Could not write to config file at %s. Your changes have not been saved."), - std_to_wx (Config::instance()->cinemas_file().string()).data() - ) - ); - } + try { + Config::instance()->write_config(); + } catch (exception& e) { + error_dialog ( + this, + wxString::Format ( + _("Could not write to config file at %s. Your changes have not been saved."), + std_to_wx (Config::instance()->cinemas_file().string()).data() + ) + ); } for (int i = 0; i < _history_items; ++i) { @@ -1467,6 +1491,14 @@ private: _history_items = history.size (); dcpomatic_log->set_types (Config::instance()->log_types()); + +#ifdef DCPOMATIC_GROK + if (what == Config::GROK) { + setup_grok_library_path(); + } +#else + LIBDCP_UNUSED(what); +#endif } void update_checker_state_changed () @@ -1488,9 +1520,9 @@ private: UpdateDialog dialog(this, uc->stable(), uc->test()); dialog.ShowModal(); } else if (uc->state() == UpdateChecker::State::FAILED) { - error_dialog (this, _("The DCP-o-matic download server could not be contacted.")); + error_dialog(this, variant::wx::insert_dcpomatic(_("The %s download server could not be contacted."))); } else { - error_dialog (this, _("There are no new versions of DCP-o-matic available.")); + error_dialog(this, variant::wx::insert_dcpomatic(_("There are no new versions of %s available."))); } _update_news_requested = false; @@ -1528,7 +1560,7 @@ private: void set_title () { - auto s = wx_to_std(_("DCP-o-matic")); + auto s = variant::dcpomatic(); if (_film) { if (_film->directory()) { s += " - " + _film->directory()->string(); @@ -1548,6 +1580,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; @@ -1571,7 +1604,7 @@ 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 / 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_SWITCH, "v", "version", "show DCP-o-matic version", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, "v", "version", "show version", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_OPTION, "", "config", "directory containing config.xml and cinemas.xml", 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 } @@ -1615,7 +1648,7 @@ private: setvbuf(hf_in, NULL, _IONBF, 128); *stdin = *hf_in; - cout << "DCP-o-matic is starting." << "\n"; + cout << variant::insert_dcpomatic("%1 is starting.") << "\n"; } #endif wxInitAllImageHandlers (); @@ -1625,7 +1658,7 @@ private: _splash = maybe_show_splash (); - SetAppName (_("DCP-o-matic")); + SetAppName(variant::wx::dcpomatic()); if (!wxApp::OnInit()) { return false; @@ -1664,7 +1697,7 @@ private: */ Config::Bad.connect (boost::bind(&App::config_bad, this, _1)); - _frame = new DOMFrame (_("DCP-o-matic")); + _frame = new DOMFrame(variant::wx::dcpomatic()); SetTopWindow (_frame); _frame->Maximize (); close_splash (); @@ -1672,7 +1705,14 @@ private: if (running_32_on_64 ()) { NagDialog::maybe_nag ( _frame, Config::NAG_32_ON_64, - _("You are running the 32-bit version of DCP-o-matic on a 64-bit version of Windows. This will limit the memory available to DCP-o-matic and may cause errors. You are strongly advised to install the 64-bit version of DCP-o-matic."), + wxString::Format( + _("You are running the 32-bit version of %s on a 64-bit version of Windows. " + "This will limit the memory available to %s and may cause errors. You are " + "strongly advised to install the 64-bit version of %s."), + variant::wx::dcpomatic(), + variant::wx::dcpomatic(), + variant::wx::dcpomatic() + ), false); } @@ -1715,11 +1755,16 @@ private: notes.Centre(); notes.ShowModal(); } + +#ifdef DCPOMATIC_GROK + grk_plugin::setMessengerLogger(new grk_plugin::GrokLogger("[GROK] ")); + setup_grok_library_path(); +#endif } catch (exception& e) { close_splash(); - error_dialog (nullptr, wxString::Format ("DCP-o-matic could not start."), std_to_wx(e.what())); + error_dialog(nullptr, variant::wx::insert_dcpomatic(_("%s could not start.")), std_to_wx(e.what())); } return true; @@ -1772,31 +1817,34 @@ private: error_dialog ( nullptr, wxString::Format( - _("An exception occurred: %s (%s)\n\n") + REPORT_PROBLEM, - std_to_wx (e.what()), - std_to_wx (e.file().string().c_str()) + _("An exception occurred: %s (%s)\n\n%s"), + std_to_wx(e.what()), + std_to_wx(e.file().string().c_str()), + wx::report_problem() ) ); } catch (boost::filesystem::filesystem_error& e) { error_dialog ( nullptr, wxString::Format( - _("An exception occurred: %s (%s) (%s)\n\n") + REPORT_PROBLEM, - std_to_wx (e.what()), - std_to_wx (e.path1().string()), - std_to_wx (e.path2().string()) + _("An exception occurred: %s (%s) (%s)\n\n%s"), + std_to_wx(e.what()), + std_to_wx(e.path1().string()), + std_to_wx(e.path2().string()), + wx::report_problem() ) ); } catch (exception& e) { error_dialog ( nullptr, wxString::Format( - _("An exception occurred: %s.\n\n") + REPORT_PROBLEM, - std_to_wx (e.what ()) + _("An exception occurred: %s.\n\n%s"), + std_to_wx(e.what()), + wx::report_problem() ) ); } catch (...) { - error_dialog (0, _("An unknown exception occurred.") + " " + REPORT_PROBLEM); + error_dialog(nullptr, _("An unknown exception occurred.") + " " + wx::report_problem()); } } @@ -1862,9 +1910,11 @@ private: } RecreateChainDialog dialog( _frame, _("Recreate signing certificates"), - _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error\n" - "which will prevent DCPs from being validated correctly on some systems. Do you want to re-create\n" - "the certificate chain for signing DCPs and KDMs?"), + variant::wx::insert_dcpomatic( + _("The certificate chain that %s uses for signing DCPs and KDMs contains a small error\n" + "which will prevent DCPs from being validated correctly on some systems. Do you want to re-create\n" + "the certificate chain for signing DCPs and KDMs?") + ), _("Do nothing"), Config::NAG_BAD_SIGNER_CHAIN_UTF8 ); @@ -1877,9 +1927,11 @@ private: } RecreateChainDialog dialog( _frame, _("Recreate signing certificates"), - _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs has a validity period\n" - "that is too long. This will cause problems playing back DCPs on some systems.\n" - "Do you want to re-create the certificate chain for signing DCPs and KDMs?"), + variant::wx::insert_dcpomatic( + _("The certificate chain that %s uses for signing DCPs and KDMs has a validity period\n" + "that is too long. This will cause problems playing back DCPs on some systems.\n" + "Do you want to re-create the certificate chain for signing DCPs and KDMs?") + ), _("Do nothing"), Config::NAG_BAD_SIGNER_CHAIN_VALIDITY ); @@ -1889,10 +1941,14 @@ private: { RecreateChainDialog dialog( _frame, _("Recreate signing certificates"), - _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs is inconsistent and\n" - "cannot be used. DCP-o-matic cannot start unless you re-create it. Do you want to re-create\n" - "the certificate chain for signing DCPs and KDMs?"), - _("Close DCP-o-matic") + wxString::Format( + _("The certificate chain that %s uses for signing DCPs and KDMs is inconsistent and\n" + "cannot be used. %s cannot start unless you re-create it. Do you want to re-create\n" + "the certificate chain for signing DCPs and KDMs?"), + variant::wx::dcpomatic(), + variant::wx::dcpomatic() + ), + variant::wx::insert_dcpomatic(_("Close %s")) ); if (dialog.ShowModal() != wxID_OK) { exit (EXIT_FAILURE); @@ -1903,11 +1959,15 @@ private: { RecreateChainDialog dialog( _frame, _("Recreate KDM decryption chain"), - _("The certificate chain that DCP-o-matic uses for decrypting KDMs is inconsistent and\n" - "cannot be used. DCP-o-matic cannot start unless you re-create it. Do you want to re-create\n" - "the certificate chain for decrypting KDMs? You may want to say \"No\" here and back up your\n" - "configuration before continuing."), - _("Close DCP-o-matic") + wxString::Format( + _("The certificate chain that %s uses for decrypting KDMs is inconsistent and\n" + "cannot be used. %s cannot start unless you re-create it. Do you want to re-create\n" + "the certificate chain for decrypting KDMs? You may want to say \"No\" here and back up your\n" + "configuration before continuing."), + variant::wx::dcpomatic(), + variant::wx::dcpomatic() + ), + variant::wx::insert_dcpomatic(_("Close %s")) ); if (dialog.ShowModal() != wxID_OK) { exit (EXIT_FAILURE); @@ -1918,10 +1978,14 @@ private: { RecreateChainDialog dialog( _frame, _("Recreate signing certificates"), - _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error\n" - "which will prevent DCPs from being validated correctly on some systems. This error was caused\n" - "by a bug in DCP-o-matic which has now been fixed. Do you want to re-create the certificate chain\n" - "for signing DCPs and KDMs?"), + wxString::Format( + _("The certificate chain that %s uses for signing DCPs and KDMs contains a small error\n" + "which will prevent DCPs from being validated correctly on some systems. This error was caused\n" + "by a bug in %s which has now been fixed. Do you want to re-create the certificate chain\n" + "for signing DCPs and KDMs?"), + variant::wx::dcpomatic(), + variant::wx::dcpomatic() + ), _("Do nothing"), Config::NAG_BAD_SIGNER_DN_QUALIFIER ); |
