summaryrefslogtreecommitdiff
path: root/src/tools/dcpomatic.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/dcpomatic.cc')
-rw-r--r--src/tools/dcpomatic.cc246
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
);