+ }
+
+ 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_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_VIDEO_CONTENT) && !have_selected_video_content) {
+ enabled = false;
+ }
+
+ j->first->Enable (enabled);
+ }
+ }
+
+ void maybe_save_then_delete_film ()
+ {
+ if (!_film) {
+ return;
+ }
+
+ if (_film->dirty ()) {
+ FilmChangedDialog d (_film->name ());
+ switch (d.run ()) {
+ case wxID_NO:
+ break;
+ case wxID_YES:
+ _film->write_metadata ();
+ break;
+ }
+ }
+
+ _film.reset ();
+ }
+
+ 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);
+
+ _history_position = _file_menu->GetMenuItems().GetCount();
+
+#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
+
+#ifdef __WXOSX__
+ add_item (_file_menu, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS);
+#else
+ wxMenu* edit = new wxMenu;
+ add_item (edit, _("&Preferences...\tCtrl-P"), wxID_PREFERENCES, ALWAYS);
+#endif
+
+ wxMenu* content = new wxMenu;
+ add_item (content, _("Scale to fit &width"), ID_content_scale_to_fit_width, NEEDS_FILM | NEEDS_SELECTED_VIDEO_CONTENT);
+ add_item (content, _("Scale to fit &height"), ID_content_scale_to_fit_height, NEEDS_FILM | NEEDS_SELECTED_VIDEO_CONTENT);
+
+ 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 &KDMs...\tCtrl-K"), ID_jobs_make_kdms, NEEDS_FILM);
+ add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+ add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION | NEEDS_CPL);
+
+ wxMenu* tools = new wxMenu;
+ add_item (tools, _("Video waveform..."), ID_tools_video_waveform, NEEDS_FILM);
+ add_item (tools, _("Hints..."), ID_tools_hints, 0);
+ add_item (tools, _("Encoding servers..."), ID_tools_encoding_servers, 0);
+ add_item (tools, _("Check for updates"), ID_tools_check_for_updates, 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"));
+#ifndef __WXOSX__
+ m->Append (edit, _("&Edit"));
+#endif
+ m->Append (content, _("&Content"));
+ m->Append (jobs_menu, _("&Jobs"));
+ m->Append (tools, _("&Tools"));
+ m->Append (help, _("&Help"));
+ }
+
+ void config_changed ()
+ {
+ for (int i = 0; i < _history_items; ++i) {
+ delete _file_menu->Remove (ID_file_history + i);
+ }
+
+ if (_history_separator) {
+ _file_menu->Remove (_history_separator);
+ }
+ delete _history_separator;
+ _history_separator = 0;
+
+ int pos = _history_position;
+
+ vector<boost::filesystem::path> history = Config::instance()->history ();
+
+ if (!history.empty ()) {
+ _history_separator = _file_menu->InsertSeparator (pos++);
+ }
+
+ for (size_t i = 0; i < history.size(); ++i) {
+ SafeStringStream s;
+ if (i < 9) {
+ s << "&" << (i + 1) << " ";
+ }
+ s << history[i].string();
+ _file_menu->Insert (pos++, ID_file_history + i, std_to_wx (s.str ()));
+ }
+
+ _history_items = history.size ();
+ }
+
+ void update_checker_state_changed ()
+ {
+ UpdateChecker* uc = UpdateChecker::instance ();
+
+ bool const announce =
+ _update_news_requested ||
+ (uc->stable() && Config::instance()->check_for_updates()) ||
+ (uc->test() && Config::instance()->check_for_updates() && Config::instance()->check_for_test_updates());
+
+ _update_news_requested = false;
+
+ if (!announce) {
+ return;
+ }
+
+ if (uc->state() == UpdateChecker::YES) {
+ UpdateDialog* dialog = new UpdateDialog (this, uc->stable (), uc->test ());
+ dialog->ShowModal ();
+ dialog->Destroy ();
+ } else if (uc->state() == UpdateChecker::FAILED) {
+ error_dialog (this, _("The DCP-o-matic download server could not be contacted."));
+ } else {
+ error_dialog (this, _("There are no new versions of DCP-o-matic available."));
+ }
+
+ _update_news_requested = false;
+ }
+
+ FilmEditor* _film_editor;
+ FilmViewer* _film_viewer;
+ VideoWaveformDialog* _video_waveform_dialog;
+ HintsDialog* _hints_dialog;
+ ServersListDialog* _servers_list_dialog;
+ wxPreferencesEditor* _config_dialog;
+ wxMenu* _file_menu;
+ shared_ptr<Film> _film;
+ int _history_items;
+ int _history_position;
+ wxMenuItem* _history_separator;
+ boost::signals2::scoped_connection _config_changed_connection;
+ bool _update_news_requested;