More player debugging for butler video-full states.
[dcpomatic.git] / src / tools / dcpomatic.cc
index ad1dcde90b647d7336e831421122f7e092f71aa2..4505cff84cfea5b8e7fb91cc554310dedda39f2e 100644 (file)
@@ -211,7 +211,8 @@ enum {
        ID_file_duplicate_and_open,
        ID_file_history,
        /* Allow spare IDs after _history for the recent files list */
-       ID_edit_copy = 100,
+       ID_file_close = 100,
+       ID_edit_copy,
        ID_edit_paste,
        ID_content_scale_to_fit_width,
        ID_content_scale_to_fit_height,
@@ -295,6 +296,7 @@ public:
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_save_as_template, this),   ID_file_save_as_template);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_duplicate, this),          ID_file_duplicate);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_duplicate_and_open, this), ID_file_duplicate_and_open);
+               Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_close, this),              ID_file_close);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_history, this, _1),        ID_file_history, ID_file_history + HISTORY_SIZE);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::file_exit, this),               wxID_EXIT);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::edit_copy, this),               ID_edit_copy);
@@ -339,8 +341,8 @@ public:
                right_sizer->Add (job_manager_view, 1, wxEXPAND | wxALL, 6);
 
                wxBoxSizer* main_sizer = new wxBoxSizer (wxHORIZONTAL);
-               main_sizer->Add (_film_editor, 1, wxEXPAND | wxALL, 6);
-               main_sizer->Add (right_sizer, 2, wxEXPAND | wxALL, 6);
+               main_sizer->Add (_film_editor, 0, wxEXPAND | wxALL, 6);
+               main_sizer->Add (right_sizer, 1, wxEXPAND | wxALL, 6);
 
                set_menu_sensitivity ();
 
@@ -374,7 +376,7 @@ public:
                accel[4].Set (wxACCEL_NORMAL, WXK_LEFT, ID_back_frame);
                accel[5].Set (wxACCEL_NORMAL, WXK_RIGHT, ID_forward_frame);
 #ifdef __WXOSX__
-               accel[6].Set (wxACCEL_CTRL, static_cast<int>('W'), wxID_EXIT);
+               accel[6].Set (wxACCEL_CTRL, static_cast<int>('W'), ID_file_close);
 #endif
                Bind (wxEVT_MENU, boost::bind (&ContentPanel::add_file_clicked, _film_editor->content_panel()), ID_add_file);
                Bind (wxEVT_MENU, boost::bind (&DOMFrame::remove_clicked, this, _1), ID_remove);
@@ -450,10 +452,13 @@ public:
                        _video_waveform_dialog = 0;
                }
                set_menu_sensitivity ();
-               if (_film->directory()) {
+               if (_film && _film->directory()) {
                        Config::instance()->add_to_history (_film->directory().get());
                }
-               _film->Change.connect (boost::bind (&DOMFrame::film_change, this, _1));
+               if (_film) {
+                       _film->Change.connect (boost::bind (&DOMFrame::film_change, this, _1));
+                       _film->Message.connect (boost::bind(&DOMFrame::film_message, this, _1));
+               }
        }
 
        shared_ptr<Film> film () const {
@@ -462,6 +467,11 @@ public:
 
 private:
 
+       void film_message (string m)
+       {
+               message_dialog (this, std_to_wx(m));
+       }
+
        void film_change (ChangeType type)
        {
                if (type == CHANGE_TYPE_DONE) {
@@ -584,6 +594,31 @@ private:
                d->Destroy ();
        }
 
+       void file_close ()
+       {
+               if (_film && _film->dirty ()) {
+
+                       FilmChangedClosingDialog* dialog = new FilmChangedClosingDialog (_film->name ());
+                       int const r = dialog->run ();
+                       delete dialog;
+
+                       switch (r) {
+                       case wxID_NO:
+                               /* Don't save and carry on to close */
+                               break;
+                       case wxID_YES:
+                               /* Save and carry on to close */
+                               _film->write_metadata ();
+                               break;
+                       case wxID_CANCEL:
+                               /* Stop */
+                               return;
+                       }
+               }
+
+               set_film (shared_ptr<Film>());
+       }
+
        void file_history (wxCommandEvent& event)
        {
                vector<boost::filesystem::path> history = Config::instance()->history ();
@@ -670,9 +705,9 @@ private:
                if (!_film->should_be_enough_disk_space (required, available, can_hard_link)) {
                        wxString message;
                        if (can_hard_link) {
-                               message = wxString::Format (_("The DCP for this film will take up about %.1f Gb, and the disk that you are using only has %.1f Gb available.  Do you want to continue anyway?"), required, available);
+                               message = wxString::Format (_("The DCP for this film will take up about %.1f GB, and the disk that you are using only has %.1f GB available.  Do you want to continue anyway?"), required, available);
                        } else {
-                               message = wxString::Format (_("The DCP and intermediate files for this film will take up about %.1f Gb, and the disk that you are using only has %.1f Gb available.  You would need half as much space if the filesystem supported hard links, but it does not.  Do you want to continue anyway?"), required, available);
+                               message = wxString::Format (_("The DCP and intermediate files for this film will take up about %.1f GB, and the disk that you are using only has %.1f GB available.  You would need half as much space if the filesystem supported hard links, but it does not.  Do you want to continue anyway?"), required, available);
                        }
                        if (!confirm_dialog (this, message)) {
                                return;
@@ -1180,6 +1215,9 @@ private:
 
                _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
@@ -1305,6 +1343,8 @@ private:
                }
 
                _history_items = history.size ();
+
+               dcpomatic_log->set_types (Config::instance()->log_types());
        }
 
        void update_checker_state_changed ()
@@ -1400,107 +1440,112 @@ public:
 private:
 
        bool OnInit ()
-       try
        {
-               wxInitAllImageHandlers ();
+               wxSplashScreen* splash = 0;
+               try {
+                       wxInitAllImageHandlers ();
 
-               Config::FailedToLoad.connect (boost::bind (&App::config_failed_to_load, this));
-               Config::Warning.connect (boost::bind (&App::config_warning, this, _1));
+                       Config::FailedToLoad.connect (boost::bind (&App::config_failed_to_load, this));
+                       Config::Warning.connect (boost::bind (&App::config_warning, this, _1));
 
-               wxSplashScreen* splash = maybe_show_splash ();
+                       splash = maybe_show_splash ();
 
-               SetAppName (_("DCP-o-matic"));
+                       SetAppName (_("DCP-o-matic"));
 
-               if (!wxApp::OnInit()) {
-                       return false;
-               }
+                       if (!wxApp::OnInit()) {
+                               return false;
+                       }
 
 #ifdef DCPOMATIC_LINUX
-               unsetenv ("UBUNTU_MENUPROXY");
+                       unsetenv ("UBUNTU_MENUPROXY");
 #endif
 
 #ifdef __WXOSX__
-               ProcessSerialNumber serial;
-               GetCurrentProcess (&serial);
-               TransformProcessType (&serial, kProcessTransformToForegroundApplication);
+                       ProcessSerialNumber serial;
+                       GetCurrentProcess (&serial);
+                       TransformProcessType (&serial, kProcessTransformToForegroundApplication);
 #endif
 
-               dcpomatic_setup_path_encoding ();
+                       dcpomatic_setup_path_encoding ();
 
-               /* Enable i18n; this will create a Config object
-                  to look for a force-configured language.  This Config
-                  object will be wrong, however, because dcpomatic_setup
-                  hasn't yet been called and there aren't any filters etc.
-                  set up yet.
-               */
-               dcpomatic_setup_i18n ();
+                       /* Enable i18n; this will create a Config object
+                          to look for a force-configured language.  This Config
+                          object will be wrong, however, because dcpomatic_setup
+                          hasn't yet been called and there aren't any filters etc.
+                          set up yet.
+                       */
+                       dcpomatic_setup_i18n ();
 
-               /* Set things up, including filters etc.
-                  which will now be internationalised correctly.
-               */
-               dcpomatic_setup ();
+                       /* Set things up, including filters etc.
+                          which will now be internationalised correctly.
+                       */
+                       dcpomatic_setup ();
 
-               /* Force the configuration to be re-loaded correctly next
-                  time it is needed.
-               */
-               Config::drop ();
+                       /* Force the configuration to be re-loaded correctly next
+                          time it is needed.
+                       */
+                       Config::drop ();
 
-               Config::BadSignerChain.connect (boost::bind (&App::config_bad_signer_chain, this));
+                       Config::BadSignerChain.connect (boost::bind (&App::config_bad_signer_chain, this));
 
-               _frame = new DOMFrame (_("DCP-o-matic"));
-               SetTopWindow (_frame);
-               _frame->Maximize ();
-               if (splash) {
-                       splash->Destroy ();
-               }
+                       _frame = new DOMFrame (_("DCP-o-matic"));
+                       SetTopWindow (_frame);
+                       _frame->Maximize ();
+                       if (splash) {
+                               splash->Destroy ();
+                               splash = 0;
+                       }
 
-               if (!Config::instance()->nagged(Config::NAG_INITIAL_SETUP)) {
-                       InitialSetupDialog* d = new InitialSetupDialog ();
-                       d->ShowModal ();
-                       d->Destroy ();
-                       Config::instance()->set_nagged(Config::NAG_INITIAL_SETUP, true);
-               }
+                       if (!Config::instance()->nagged(Config::NAG_INITIAL_SETUP)) {
+                               InitialSetupDialog* d = new InitialSetupDialog ();
+                               d->ShowModal ();
+                               d->Destroy ();
+                               Config::instance()->set_nagged(Config::NAG_INITIAL_SETUP, true);
+                       }
 
-               _frame->Show ();
+                       _frame->Show ();
 
-               if (!_film_to_load.empty() && boost::filesystem::is_directory (_film_to_load)) {
-                       try {
-                               _frame->load_film (_film_to_load);
-                       } catch (exception& e) {
-                               error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), _film_to_load)), std_to_wx(e.what()));
+                       if (!_film_to_load.empty() && boost::filesystem::is_directory (_film_to_load)) {
+                               try {
+                                       _frame->load_film (_film_to_load);
+                               } catch (exception& e) {
+                                       error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), _film_to_load)), std_to_wx(e.what()));
+                               }
                        }
-               }
 
-               if (!_film_to_create.empty ()) {
-                       _frame->new_film (_film_to_create, optional<string> ());
-                       if (!_content_to_add.empty ()) {
-                               BOOST_FOREACH (shared_ptr<Content> i, content_factory(_content_to_add)) {
-                                       _frame->film()->examine_and_add_content (i);
+                       if (!_film_to_create.empty ()) {
+                               _frame->new_film (_film_to_create, optional<string> ());
+                               if (!_content_to_add.empty ()) {
+                                       BOOST_FOREACH (shared_ptr<Content> i, content_factory(_content_to_add)) {
+                                               _frame->film()->examine_and_add_content (i);
+                                       }
+                               }
+                               if (!_dcp_to_add.empty ()) {
+                                       _frame->film()->examine_and_add_content(shared_ptr<DCPContent>(new DCPContent(_dcp_to_add)));
                                }
                        }
-                       if (!_dcp_to_add.empty ()) {
-                               _frame->film()->examine_and_add_content(shared_ptr<DCPContent>(new DCPContent(_dcp_to_add)));
-                       }
-               }
 
-               signal_manager = new wxSignalManager (this);
-               Bind (wxEVT_IDLE, boost::bind (&App::idle, this));
+                       signal_manager = new wxSignalManager (this);
+                       Bind (wxEVT_IDLE, boost::bind (&App::idle, this));
 
-               Bind (wxEVT_TIMER, boost::bind (&App::check, this));
-               _timer.reset (new wxTimer (this));
-               _timer->Start (1000);
+                       Bind (wxEVT_TIMER, boost::bind (&App::check, this));
+                       _timer.reset (new wxTimer (this));
+                       _timer->Start (1000);
 
-               if (Config::instance()->check_for_updates ()) {
-                       UpdateChecker::instance()->run ();
+                       if (Config::instance()->check_for_updates ()) {
+                               UpdateChecker::instance()->run ();
+                       }
+               }
+               catch (exception& e)
+               {
+                       if (splash) {
+                               splash->Destroy ();
+                       }
+                       error_dialog (0, wxString::Format ("DCP-o-matic could not start."), std_to_wx(e.what()));
                }
 
                return true;
        }
-       catch (exception& e)
-       {
-               error_dialog (0, wxString::Format ("DCP-o-matic could not start."), std_to_wx(e.what()));
-               return true;
-       }
 
        void OnInitCmdLine (wxCmdLineParser& parser)
        {