+ void set_menu_sensitivity ()
+ {
+ list<shared_ptr<Job> > jobs = JobManager::instance()->get ();
+ list<shared_ptr<Job> >::iterator i = jobs.begin();
+ while (i != jobs.end() && (*i)->json_name() != "transcode") {
+ ++i;
+ }
+ bool const dcp_creation = (i != jobs.end ()) && !(*i)->finished ();
+ bool const have_cpl = _film && !_film->cpls().empty ();
+ 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();
+
+ for (map<wxMenuItem*, int>::iterator j = menu_items.begin(); j != menu_items.end(); ++j) {
+
+ bool enabled = true;
+
+ if ((j->second & NEEDS_FILM) && !_film) {
+ enabled = false;
+ }
+
+ if ((j->second & NOT_DURING_DCP_CREATION) && dcp_creation) {
+ enabled = false;
+ }
+
+ if ((j->second & NEEDS_CPL) && !have_cpl) {
+ enabled = false;
+ }
+
+ if ((j->second & NEEDS_SELECTED_CONTENT) && !have_selected_content) {
+ enabled = false;
+ }
+
+ if ((j->second & NEEDS_SINGLE_SELECTED_CONTENT) && !have_single_selected_content) {
+ enabled = false;
+ }
+
+ if ((j->second & NEEDS_SELECTED_VIDEO_CONTENT) && !have_selected_video_content) {
+ enabled = false;
+ }
+
+ if ((j->second & NEEDS_CLIPBOARD) && !_clipboard) {
+ enabled = false;
+ }
+
+ if ((j->second & NEEDS_ENCRYPTION) && (!_film || !_film->encrypted())) {
+ enabled = false;
+ }
+
+ j->first->Enable (enabled);
+ }
+ }
+
+ /** @return true if the operation that called this method
+ * should continue, false to abort it.
+ */
+ template <class T>
+ bool maybe_save_film ()
+ {
+ if (!_film) {
+ return true;
+ }
+
+ if (_film->dirty ()) {
+ T d (_film->name ());
+ switch (d.run ()) {
+ case wxID_NO:
+ return true;
+ case wxID_YES:
+ _film->write_metadata ();
+ return true;
+ case wxID_CANCEL:
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ template <class T>
+ bool maybe_save_then_delete_film ()
+ {
+ bool const r = maybe_save_film<T> ();
+ if (r) {
+ _film.reset ();
+ }
+ return r;
+ }
+
+ void add_item (wxMenu* menu, wxString text, int id, int sens)
+ {
+ wxMenuItem* item = menu->Append (id, text);
+ menu_items.insert (make_pair (item, sens));
+ }
+
+ void setup_menu (wxMenuBar* m)
+ {
+ _file_menu = new wxMenu;
+ add_item (_file_menu, _("New...\tCtrl-N"), ID_file_new, ALWAYS);
+ add_item (_file_menu, _("&Open...\tCtrl-O"), ID_file_open, ALWAYS);
+ _file_menu->AppendSeparator ();
+ add_item (_file_menu, _("&Save\tCtrl-S"), ID_file_save, NEEDS_FILM);
+ _file_menu->AppendSeparator ();
+ add_item (_file_menu, _("Save as &template..."), ID_file_save_as_template, NEEDS_FILM);
+ add_item (_file_menu, _("Duplicate..."), ID_file_duplicate, NEEDS_FILM);
+ add_item (_file_menu, _("Duplicate and open..."), ID_file_duplicate_and_open, NEEDS_FILM);
+
+ _history_position = _file_menu->GetMenuItems().GetCount();
+
+ _file_menu->AppendSeparator ();
+ add_item (_file_menu, _("&Close\tCtrl-W"), ID_file_close, NEEDS_FILM);
+
+#ifndef __WXOSX__
+ _file_menu->AppendSeparator ();
+#endif
+
+#ifdef __WXOSX__
+ add_item (_file_menu, _("&Exit"), wxID_EXIT, ALWAYS);
+#else
+ add_item (_file_menu, _("&Quit"), wxID_EXIT, ALWAYS);
+#endif
+
+ wxMenu* edit = new wxMenu;
+ add_item (edit, _("Copy settings\tCtrl-C"), ID_edit_copy, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_SINGLE_SELECTED_CONTENT);
+ add_item (edit, _("Paste settings...\tCtrl-V"), ID_edit_paste, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_SELECTED_CONTENT | NEEDS_CLIPBOARD);
+
+#ifdef __WXOSX__
+ add_item (_file_menu, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS);
+#else
+ add_item (edit, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS);
+#endif
+
+ wxMenu* jobs_menu = new wxMenu;
+ add_item (jobs_menu, _("&Make DCP\tCtrl-M"), ID_jobs_make_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION);
+ add_item (jobs_menu, _("Make DCP in &batch converter\tCtrl-B"), ID_jobs_make_dcp_batch, NEEDS_FILM | NOT_DURING_DCP_CREATION);
+ jobs_menu->AppendSeparator ();
+ add_item (jobs_menu, _("Make &KDMs...\tCtrl-K"), ID_jobs_make_kdms, NEEDS_FILM);
+ 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);
+ jobs_menu->AppendSeparator ();
+ add_item (jobs_menu, _("Export...\tCtrl-E"), ID_jobs_export, NEEDS_FILM);
+ jobs_menu->AppendSeparator ();
+ add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+
+#if defined(DCPOMATIC_OSX)
+ add_item (jobs_menu, _("S&how DCP in Finder"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+#elif defined(DCPOMATIC_WINDOWS)
+ add_item (jobs_menu, _("S&how DCP in Explorer"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+#else
+ add_item (jobs_menu, _("S&how DCP in Files"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+#endif
+
+ add_item (jobs_menu, _("Open DCP in &player"), ID_jobs_open_dcp_in_player, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+
+ wxMenu* view = new wxMenu;
+ add_item (view, _("Closed captions..."), ID_view_closed_captions, NEEDS_FILM);
+ add_item (view, _("Video waveform..."), ID_view_video_waveform, NEEDS_FILM);
+
+ wxMenu* tools = new wxMenu;
+ 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);
+ add_item (tools, _("Check for updates"), ID_tools_check_for_updates, 0);
+ add_item (tools, _("Send translations..."), ID_tools_send_translations, 0);
+ add_item (tools, _("System information..."), ID_tools_system_information, 0);
+ tools->AppendSeparator ();
+ add_item (tools, _("Restore default preferences"), ID_tools_restore_default_preferences, ALWAYS);
+
+ wxMenu* help = new wxMenu;
+#ifdef __WXOSX__
+ add_item (help, _("About DCP-o-matic"), 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);
+
+ m->Append (_file_menu, _("&File"));
+ m->Append (edit, _("&Edit"));
+ m->Append (jobs_menu, _("&Jobs"));
+ m->Append (view, _("&View"));
+ m->Append (tools, _("&Tools"));
+ m->Append (help, _("&Help"));
+ }
+
+ void config_changed (Config::Property what)
+ {
+ /* Instantly save any config changes when using the DCP-o-matic GUI */
+ if (what == 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()
+ )
+ );
+ }
+ } else {