Merge master.
authorCarl Hetherington <cth@carlh.net>
Mon, 25 Aug 2014 15:56:17 +0000 (16:56 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 25 Aug 2014 15:56:17 +0000 (16:56 +0100)
ChangeLog
src/lib/config.cc
src/lib/config.h
src/lib/util.h
src/tools/dcpomatic.cc
src/wx/film_editor.cc
src/wx/film_editor.h
src/wx/film_viewer.cc
src/wx/film_viewer.h

index d1d008b5e96feff8b417de07099e5ca98035074b..c34750ad6595a5e25ea72c042e903a728c8bb5f5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
        * Add subtitle view.
 
+2014-08-25  Carl Hetherington  <cth@carlh.net>
+
+       * Basic recent files list in the File menu.
+
 2014-08-23  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.72.12 released.
index d20536f14afc00f3c4c2539322a7af89499f75e1..7e37625878191a87db0e7bf1cf3959e5b3fb68e3 100644 (file)
 #include "i18n.h"
 
 using std::vector;
+using std::cout;
 using std::ifstream;
 using std::string;
 using std::list;
 using std::max;
+using std::remove;
 using std::exception;
 using std::cerr;
 using boost::shared_ptr;
@@ -215,6 +217,11 @@ Config::read ()
 
        _log_types = f.optional_number_child<int> ("LogTypes").get_value_or (Log::TYPE_GENERAL | Log::TYPE_WARNING | Log::TYPE_ERROR);
 
+       list<cxml::NodePtr> his = f.node_children ("History");
+       for (list<cxml::NodePtr>::const_iterator i = his.begin(); i != his.end(); ++i) {
+               _history.push_back ((*i)->content ());
+       }
+
        cxml::NodePtr signer = f.optional_node_child ("Signer");
        dcp::CertificateChain signer_chain;
        if (signer) {
@@ -371,6 +378,10 @@ Config::write () const
        root->add_child("DecryptionCertificate")->add_child_text (_decryption_certificate.certificate (true));
        root->add_child("DecryptionPrivateKey")->add_child_text (_decryption_private_key);
 
+       for (vector<boost::filesystem::path>::const_iterator i = _history.begin(); i != _history.end(); ++i) {
+               root->add_child("History")->add_child_text (i->string ());
+       }
+       
        doc.write_to_file_formatted (file(false).string ());
 }
 
@@ -416,3 +427,17 @@ Config::reset_kdm_email ()
                "Best regards,\nDCP-o-matic"
                );
 }
+
+void
+Config::add_to_history (boost::filesystem::path p)
+{
+       /* Remove existing instances of this path in the history */
+       _history.erase (remove (_history.begin(), _history.end(), p), _history.end ());
+       
+       _history.insert (_history.begin (), p);
+       if (_history.size() > HISTORY_SIZE) {
+               _history.pop_back ();
+       }
+
+       changed ();
+}
index 3cfaa12007677a1c4f6939a9751ba4a127dee824..05bc7945f1df80bb77c6f846d01c0a161ac80810 100644 (file)
@@ -221,7 +221,11 @@ public:
        int log_types () const {
                return _log_types;
        }
-       
+
+       std::vector<boost::filesystem::path> history () const {
+               return _history;
+       }
+
        /** @param n New number of local encoding threads */
        void set_num_local_encoding_threads (int n) {
                _num_local_encoding_threads = n;
@@ -414,6 +418,13 @@ public:
                _log_types = t;
                changed ();
        }
+
+       void clear_history () {
+               _history.clear ();
+               changed ();
+       }
+
+       void add_to_history (boost::filesystem::path p);
        
        void changed ();
        boost::signals2::signal<void ()> Changed;
@@ -482,7 +493,8 @@ private:
        /** maximum allowed J2K bandwidth in bits per second */
        int _maximum_j2k_bandwidth;
        int _log_types;
-
+       std::vector<boost::filesystem::path> _history;
+       
        /** Singleton instance, or 0 */
        static Config* _instance;
 };
index 1bbdfb2cf23dc56864241f1669b6cc87f8feea97..724e8937ca3e4fb3b7b22c36bd2e6650efaf9b7b 100644 (file)
@@ -44,8 +44,8 @@ extern "C" {
 
 /** The maximum number of audio channels that we can have in a DCP */
 #define MAX_DCP_AUDIO_CHANNELS 12
-
 #define DCPOMATIC_HELLO "Boys, you gotta learn not to talk to nuns that way"
+#define HISTORY_SIZE 10
 
 class Job;
 struct AVSubtitle;
index 4246455378fb8c401aec5ac96206d54ff093ff0b..8763e35cb2abc2e2000323c2dd06ba62787f0595 100644 (file)
@@ -64,6 +64,7 @@
 
 using std::cout;
 using std::string;
+using std::vector;
 using std::wstring;
 using std::map;
 using std::make_pair;
@@ -72,22 +73,16 @@ using std::exception;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
-static shared_ptr<Film> film;
-static std::string film_to_load;
-static std::string film_to_create;
-static std::string content_to_add;
-static wxMenu* jobs_menu = 0;
-
 // #define DCPOMATIC_WINDOWS_CONSOLE 1
 
 class FilmChangedDialog
 {
 public:
-       FilmChangedDialog ()
+       FilmChangedDialog (string name)
        {
                _dialog = new wxMessageDialog (
                        0,
-                       wxString::Format (_("Save changes to film \"%s\" before closing?"), std_to_wx (film->name ()).data()),
+                       wxString::Format (_("Save changes to film \"%s\" before closing?"), std_to_wx (name).data()),
                        _("Film changed"),
                        wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION
                        );
@@ -110,51 +105,6 @@ private:
        wxMessageDialog* _dialog;
 };
 
-
-static void
-maybe_save_then_delete_film ()
-{
-       if (!film) {
-               return;
-       }
-                       
-       if (film->dirty ()) {
-               FilmChangedDialog d;
-               switch (d.run ()) {
-               case wxID_NO:
-                       break;
-               case wxID_YES:
-                       film->write_metadata ();
-                       break;
-               }
-       }
-       
-       film.reset ();
-}
-
-static void
-check_film_state_version (int v)
-{
-       if (v == 4) {
-               error_dialog (
-                       0,
-                       _("This film was created with an old version of DVD-o-matic and may not load correctly "
-                         "in this version.  Please check the film's settings carefully.")
-                       );
-       }
-}
-
-static void
-load_film (boost::filesystem::path file)
-{
-       film.reset (new Film (file));
-       list<string> const notes = film->read_metadata ();
-       check_film_state_version (film->state_version ());
-       for (list<string>::const_iterator i = notes.begin(); i != notes.end(); ++i) {
-               error_dialog (0, std_to_wx (*i));
-       }
-}
-
 #define ALWAYS                       0x0
 #define NEEDS_FILM                   0x1
 #define NOT_DURING_DCP_CREATION      0x2
@@ -163,19 +113,14 @@ load_film (boost::filesystem::path file)
 
 map<wxMenuItem*, int> menu_items;
        
-static void
-add_item (wxMenu* menu, wxString text, int id, int sens)
-{
-       wxMenuItem* item = menu->Append (id, text);
-       menu_items.insert (make_pair (item, sens));
-}
-
 enum {
        ID_file_new = 1,
        ID_file_open,
        ID_file_save,
        ID_file_properties,
-       ID_content_scale_to_fit_width,
+       ID_file_history,
+       /* Allow spare IDs after _history for the recent files list */
+       ID_content_scale_to_fit_width = 100,
        ID_content_scale_to_fit_height,
        ID_jobs_make_dcp,
        ID_jobs_make_kdms,
@@ -186,66 +131,6 @@ enum {
        ID_tools_check_for_updates
 };
 
-static void
-setup_menu (wxMenuBar* m)
-{
-       wxMenu* file = new wxMenu;
-       add_item (file, _("New..."), ID_file_new, ALWAYS);
-       add_item (file, _("&Open..."), ID_file_open, ALWAYS);
-       file->AppendSeparator ();
-       add_item (file, _("&Save"), ID_file_save, NEEDS_FILM);
-       file->AppendSeparator ();
-       add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM);
-#ifndef __WXOSX__      
-       file->AppendSeparator ();
-#endif
-
-#ifdef __WXOSX__       
-       add_item (file, _("&Exit"), wxID_EXIT, ALWAYS);
-#else
-       add_item (file, _("&Quit"), wxID_EXIT, ALWAYS);
-#endif 
-       
-
-#ifdef __WXOSX__       
-       add_item (file, _("&Preferences..."), wxID_PREFERENCES, ALWAYS);
-#else
-       wxMenu* edit = new wxMenu;
-       add_item (edit, _("&Preferences..."), 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);
-
-       jobs_menu = new wxMenu;
-       add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION);
-       add_item (jobs_menu, _("Make &KDMs..."), 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, _("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);
-
-       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 
-
-       m->Append (file, _("&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"));
-}
-
 class Frame : public wxFrame
 {
 public:
@@ -254,6 +139,10 @@ public:
                , _hints_dialog (0)
                , _servers_list_dialog (0)
                , _config_dialog (0)
+               , _file_menu (0)
+               , _history_items (0)
+               , _history_position (0)
+               , _history_separator (0)
        {
 #if defined(DCPOMATIC_WINDOWS) && defined(DCPOMATIC_WINDOWS_CONSOLE)
                 AllocConsole();
@@ -275,10 +164,14 @@ public:
                setup_menu (bar);
                SetMenuBar (bar);
 
+               Config::instance()->Changed.connect (boost::bind (&Frame::config_changed, this));
+               config_changed ();
+
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_new, this),                ID_file_new);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_open, this),               ID_file_open);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_save, this),               ID_file_save);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_properties, this),         ID_file_properties);
+               Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_history, this, _1),        ID_file_history, ID_file_history + HISTORY_SIZE);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::file_exit, this),               wxID_EXIT);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::edit_preferences, this),        wxID_PREFERENCES);
                Bind (wxEVT_COMMAND_MENU_SELECTED, boost::bind (&Frame::content_scale_to_fit_width, this), ID_content_scale_to_fit_width);
@@ -299,8 +192,8 @@ public:
                */
                wxPanel* overall_panel = new wxPanel (this, wxID_ANY);
 
-               _film_editor = new FilmEditor (film, overall_panel);
-               _film_viewer = new FilmViewer (film, overall_panel);
+               _film_editor = new FilmEditor (overall_panel);
+               _film_viewer = new FilmViewer (overall_panel);
                JobManagerView* job_manager_view = new JobManagerView (overall_panel, static_cast<JobManagerView::Buttons> (0));
 
                wxBoxSizer* right_sizer = new wxBoxSizer (wxVERTICAL);
@@ -314,27 +207,64 @@ public:
                set_menu_sensitivity ();
 
                _film_editor->FileChanged.connect (bind (&Frame::file_changed, this, _1));
-               if (film) {
-                       file_changed (film->directory ());
-               } else {
-                       file_changed ("");
-               }
+               file_changed ("");
 
                JobManager::instance()->ActiveJobsChanged.connect (boost::bind (&Frame::set_menu_sensitivity, this));
 
-               set_film ();
                overall_panel->SetSizer (main_sizer);
        }
 
-private:
+       void new_film (boost::filesystem::path path)
+       {
+               shared_ptr<Film> film (new Film (path));
+               film->write_metadata ();
+               film->set_name (path.filename().generic_string());
+               set_film (film);
+       }
 
-       void set_film ()
+       void load_film (boost::filesystem::path file)
+       try
        {
-               _film_viewer->set_film (film);
-               _film_editor->set_film (film);
+               maybe_save_then_delete_film ();
+               
+               shared_ptr<Film> film (new Film (file));
+               list<string> const notes = film->read_metadata ();
+
+               if (film->state_version() == 4) {
+                       error_dialog (
+                               0,
+                               _("This film was created with an old version of DVD-o-matic and may not load correctly "
+                                 "in this version.  Please check the film's settings carefully.")
+                               );
+               }
+               
+               for (list<string>::const_iterator i = notes.begin(); i != notes.end(); ++i) {
+                       error_dialog (0, std_to_wx (*i));
+               }
+               
+               set_film (film);
+       }
+       catch (std::exception& e) {
+               wxString p = std_to_wx (file.string ());
+               wxCharBuffer b = p.ToUTF8 ();
+               error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data()));
+       }
+
+       void set_film (shared_ptr<Film> film)
+       {
+               _film = film;
+               _film_viewer->set_film (_film);
+               _film_editor->set_film (_film);
                set_menu_sensitivity ();
+               Config::instance()->add_to_history (_film->directory ());
        }
 
+       shared_ptr<Film> film () const {
+               return _film;
+       }
+       
+private:
+
        void file_changed (boost::filesystem::path f)
        {
                string s = wx_to_std (_("DCP-o-matic"));
@@ -372,10 +302,7 @@ private:
                        }
                        
                        maybe_save_then_delete_film ();
-                       film.reset (new Film (d->get_path ()));
-                       film->write_metadata ();
-                       film->set_name (boost::filesystem::path (d->get_path()).filename().generic_string());
-                       set_film ();
+                       new_film (d->get_path ());
                }
                
                d->Destroy ();
@@ -401,15 +328,7 @@ private:
                }
                        
                if (r == wxID_OK) {
-                       maybe_save_then_delete_film ();
-                       try {
-                               load_film (wx_to_std (c->GetPath ()));
-                               set_film ();
-                       } catch (std::exception& e) {
-                               wxString p = c->GetPath ();
-                               wxCharBuffer b = p.ToUTF8 ();
-                               error_dialog (this, wxString::Format (_("Could not open film at %s (%s)"), p.data(), std_to_wx (e.what()).data()));
-                       }
+                       load_film (wx_to_std (c->GetPath ()));
                }
 
                c->Destroy ();
@@ -417,15 +336,24 @@ private:
 
        void file_save ()
        {
-               film->write_metadata ();
+               _film->write_metadata ();
        }
 
        void file_properties ()
        {
-               PropertiesDialog* d = new PropertiesDialog (this, film);
+               PropertiesDialog* d = new PropertiesDialog (this, _film);
                d->ShowModal ();
                d->Destroy ();
        }
+
+       void file_history (wxCommandEvent& event)
+       {
+               vector<boost::filesystem::path> history = Config::instance()->history ();
+               int n = event.GetId() - ID_file_history;
+               if (n >= 0 && n < static_cast<int> (history.size ())) {
+                       load_film (history[n]);
+               }
+       }
        
        void file_exit ()
        {
@@ -446,22 +374,22 @@ private:
                double required;
                double available;
 
-               if (!film->should_be_enough_disk_space (required, available)) {
+               if (!_film->should_be_enough_disk_space (required, available)) {
                        if (!confirm_dialog (this, 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))) {
                                return;
                        }
                }
                
-               JobWrapper::make_dcp (this, film);
+               JobWrapper::make_dcp (this, _film);
        }
 
        void jobs_make_kdms ()
        {
-               if (!film) {
+               if (!_film) {
                        return;
                }
                
-               KDMDialog* d = new KDMDialog (this, film);
+               KDMDialog* d = new KDMDialog (this, _film);
                if (d->ShowModal () != wxID_OK) {
                        d->Destroy ();
                        return;
@@ -469,10 +397,10 @@ private:
 
                try {
                        if (d->write_to ()) {
-                               write_kdm_files (film, d->screens (), d->cpl (), d->from (), d->until (), d->formulation (), d->directory ());
+                               write_kdm_files (_film, d->screens (), d->cpl (), d->from (), d->until (), d->formulation (), d->directory ());
                        } else {
                                JobManager::instance()->add (
-                                       shared_ptr<Job> (new SendKDMEmailJob (film, d->screens (), d->cpl (), d->from (), d->until (), d->formulation ()))
+                                       shared_ptr<Job> (new SendKDMEmailJob (_film, d->screens (), d->cpl (), d->from (), d->until (), d->formulation ()))
                                        );
                        }
                } catch (dcp::NotEncryptedError& e) {
@@ -504,27 +432,27 @@ private:
        
        void jobs_send_dcp_to_tms ()
        {
-               film->send_dcp_to_tms ();
+               _film->send_dcp_to_tms ();
        }
 
        void jobs_show_dcp ()
        {
 #ifdef __WXMSW__
-               string d = film->directory().string ();
+               string d = _film->directory().string ();
                wstring w;
                w.assign (d.begin(), d.end());
                ShellExecute (0, L"open", w.c_str(), 0, 0, SW_SHOWDEFAULT);
 #else
                int r = system ("which nautilus");
                if (WEXITSTATUS (r) == 0) {
-                       r = system (string ("nautilus " + film->directory().string()).c_str ());
+                       r = system (string ("nautilus " + _film->directory().string()).c_str ());
                        if (WEXITSTATUS (r)) {
                                error_dialog (this, _("Could not show DCP (could not run nautilus)"));
                        }
                } else {
                        int r = system ("which konqueror");
                        if (WEXITSTATUS (r) == 0) {
-                               r = system (string ("konqueror " + film->directory().string()).c_str ());
+                               r = system (string ("konqueror " + _film->directory().string()).c_str ());
                                if (WEXITSTATUS (r)) {
                                        error_dialog (this, _("Could not show DCP (could not run konqueror)"));
                                }
@@ -536,7 +464,7 @@ private:
        void tools_hints ()
        {
                if (!_hints_dialog) {
-                       _hints_dialog = new HintsDialog (this, film);
+                       _hints_dialog = new HintsDialog (this, _film);
                }
 
                _hints_dialog->Show ();
@@ -601,14 +529,14 @@ private:
                        ++i;
                }
                bool const dcp_creation = (i != jobs.end ()) && !(*i)->finished ();
-               bool const have_cpl = film && !film->cpls().empty ();
+               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 == 0) {
+                       if ((j->second & NEEDS_FILM) && !_film) {
                                enabled = false;
                        }
                        
@@ -627,12 +555,136 @@ private:
                        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..."), ID_file_new, ALWAYS);
+               add_item (_file_menu, _("&Open..."), ID_file_open, ALWAYS);
+               _file_menu->AppendSeparator ();
+               add_item (_file_menu, _("&Save"), ID_file_save, NEEDS_FILM);
+               _file_menu->AppendSeparator ();
+               add_item (_file_menu, _("&Properties..."), ID_file_properties, 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..."), wxID_PREFERENCES, ALWAYS);
+#else
+               wxMenu* edit = new wxMenu;
+               add_item (edit, _("&Preferences..."), 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"), ID_jobs_make_dcp, NEEDS_FILM | NOT_DURING_DCP_CREATION);
+               add_item (jobs_menu, _("Make &KDMs..."), 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, _("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);
+               
+               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 
+               
+               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 ();
+       }
        
        FilmEditor* _film_editor;
        FilmViewer* _film_viewer;
        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;
 };
 
 static const wxCmdLineEntryDesc command_line_description[] = {
@@ -686,29 +738,26 @@ class App : public wxApp
                */
                Config::drop ();
 
-               if (!film_to_load.empty() && boost::filesystem::is_directory (film_to_load)) {
+               _frame = new Frame (_("DCP-o-matic"));
+               SetTopWindow (_frame);
+               _frame->Maximize ();
+               _frame->Show ();
+
+               if (!_film_to_load.empty() && boost::filesystem::is_directory (_film_to_load)) {
                        try {
-                               load_film (film_to_load);
+                               _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, e.what())));
+                               error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), _film_to_load, e.what())));
                        }
                }
 
-               if (!film_to_create.empty ()) {
-                       film.reset (new Film (film_to_create));
-                       film->write_metadata ();
-                       film->set_name (boost::filesystem::path (film_to_create).filename().generic_string ());
-               }
-
-               if (!content_to_add.empty ()) {
-                       film->examine_and_add_content (content_factory (film, content_to_add));
+               if (!_film_to_create.empty ()) {
+                       _frame->new_film (_film_to_create);
+                       if (!_content_to_add.empty ()) {
+                               _frame->film()->examine_and_add_content (content_factory (_frame->film(), _content_to_add));
+                       }
                }
 
-               _frame = new Frame (_("DCP-o-matic"));
-               SetTopWindow (_frame);
-               _frame->Maximize ();
-               _frame->Show ();
-
                ui_signaller = new wxUISignaller (this);
                Bind (wxEVT_IDLE, boost::bind (&App::idle, this));
 
@@ -716,10 +765,6 @@ class App : public wxApp
                _timer.reset (new wxTimer (this));
                _timer->Start (1000);
 
-               if (film) {
-                       check_film_state_version (film->state_version ());
-               }
-
                UpdateChecker::instance()->StateChanged.connect (boost::bind (&App::update_checker_state_changed, this));
                if (Config::instance()->check_for_updates ()) {
                        UpdateChecker::instance()->run ();
@@ -743,15 +788,15 @@ class App : public wxApp
        {
                if (parser.GetParamCount() > 0) {
                        if (parser.Found (wxT ("new"))) {
-                               film_to_create = wx_to_std (parser.GetParam (0));
+                               _film_to_create = wx_to_std (parser.GetParam (0));
                        } else {
-                               film_to_load = wx_to_std (parser.GetParam (0));
+                               _film_to_load = wx_to_std (parser.GetParam (0));
                        }
                }
 
                wxString content;
                if (parser.Found (wxT ("content"), &content)) {
-                       content_to_add = wx_to_std (content);
+                       _content_to_add = wx_to_std (content);
                }
 
                return true;
@@ -812,6 +857,9 @@ class App : public wxApp
 
        Frame* _frame;
        shared_ptr<wxTimer> _timer;
+       string _film_to_load;
+       string _film_to_create;
+       string _content_to_add;
 };
 
 IMPLEMENT_APP (App)
index 1ce4695d6bf83c2e00c09df358667e5551374da1..7f9461d940fb4ba6f4035707fc1f930c214c62f9 100644 (file)
@@ -71,7 +71,7 @@ using boost::dynamic_pointer_cast;
 using boost::lexical_cast;
 
 /** @param f Film to edit */
-FilmEditor::FilmEditor (shared_ptr<Film> f, wxWindow* parent)
+FilmEditor::FilmEditor (wxWindow* parent)
        : wxPanel (parent)
 {
        wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
@@ -84,12 +84,12 @@ FilmEditor::FilmEditor (shared_ptr<Film> f, wxWindow* parent)
        _dcp_panel = new DCPPanel (_main_notebook, _film);
        _main_notebook->AddPage (_dcp_panel->panel (), _("DCP"), false);
        
-       set_film (f);
-
        JobManager::instance()->ActiveJobsChanged.connect (
                bind (&FilmEditor::active_jobs_changed, this, _1)
                );
 
+       set_film (shared_ptr<Film> ());
+       
        SetSizerAndFit (s);
 }
 
index 28baf410c6fe5f9d627de23fceaeee4d07fcc01c..a198d7aa7d0ce221b0e246a13b3bd24bdd6667d6 100644 (file)
@@ -38,7 +38,7 @@ class DCPPanel;
 class FilmEditor : public wxPanel
 {
 public:
-       FilmEditor (boost::shared_ptr<Film>, wxWindow *);
+       FilmEditor (wxWindow *);
 
        void set_film (boost::shared_ptr<Film>);
 
index 2416c6776841690fee63786d52b20725a578d8fd..ef5c78f24ae2b628751b493fb9a2f618c7ec047a 100644 (file)
@@ -55,7 +55,7 @@ using boost::dynamic_pointer_cast;
 using boost::weak_ptr;
 using dcp::Size;
 
-FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
+FilmViewer::FilmViewer (wxWindow* p)
        : wxPanel (p)
        , _panel (new wxPanel (this))
        , _outline_content (new wxCheckBox (this, wxID_ANY, _("Outline content")))
@@ -109,8 +109,8 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
        _back_button->Bind    (wxEVT_COMMAND_BUTTON_CLICKED,       boost::bind (&FilmViewer::back_clicked,    this));
        _forward_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED,       boost::bind (&FilmViewer::forward_clicked, this));
 
-       set_film (f);
-
+       set_film (shared_ptr<Film> ());
+       
        JobManager::instance()->ActiveJobsChanged.connect (
                bind (&FilmViewer::active_jobs_changed, this, _1)
                );
index 0235d225fc030eb125b48b96fbb7a2bf6eb60b07..e502c6f45cd2922e3d9fe90c32fe7553c67d83a6 100644 (file)
@@ -36,7 +36,7 @@ class PlayerVideo;
 class FilmViewer : public wxPanel
 {
 public:
-       FilmViewer (boost::shared_ptr<Film>, wxWindow *);
+       FilmViewer (wxWindow *);
 
        void set_film (boost::shared_ptr<Film>);