use reverse-reading of MIDI data in DiskReader
[ardour.git] / gtk2_ardour / ardour_ui_startup.cc
index e9875e93387050e9c2d31b7822ea441f417f29f7..a56b1a38e2c26dc5dc3a0910ed2fc359ea1f8853 100644 (file)
 #include "ardour/filename_extensions.h"
 #include "ardour/filesystem_paths.h"
 #include "ardour/profile.h"
-#include "ardour/recent_sessions.h"
 
 #include "gtkmm2ext/application.h"
 
 #include "ambiguous_file_dialog.h"
 #include "ardour_ui.h"
+#include "debug.h"
 #include "engine_dialog.h"
 #include "keyboard.h"
 #include "missing_file_dialog.h"
@@ -71,7 +71,6 @@
 #include "pingback.h"
 #include "public_editor.h"
 #include "splash.h"
-#include "startup.h"
 
 #include "pbd/i18n.h"
 
@@ -327,40 +326,10 @@ ARDOUR_UI::keyboard_settings () const
        return node;
 }
 
-
-void
-ARDOUR_UI::loading_message (const std::string& msg)
-{
-       if (ARDOUR_COMMAND_LINE::no_splash) {
-               return;
-       }
-
-       if (!splash) {
-               show_splash ();
-       }
-
-       splash->message (msg);
-}
-
-void
-ARDOUR_UI::show_splash ()
-{
-       if (splash == 0) {
-               try {
-                       splash = new Splash;
-               } catch (...) {
-                       return;
-               }
-       }
-
-       splash->display ();
-}
-
 void
 ARDOUR_UI::hide_splash ()
 {
-       delete splash;
-       splash = 0;
+       Splash::drop ();
 }
 
 void
@@ -399,212 +368,185 @@ ARDOUR_UI::check_announcements ()
 }
 
 int
-ARDOUR_UI::starting ()
+ARDOUR_UI::nsm_init ()
 {
-       Application* app = Application::instance ();
        const char *nsm_url;
-       bool brand_new_user = ArdourStartup::required ();
 
-       app->ShouldQuit.connect (sigc::mem_fun (*this, &ARDOUR_UI::queue_finish));
-       app->ShouldLoad.connect (sigc::mem_fun (*this, &ARDOUR_UI::load_from_application_api));
-
-       if (ARDOUR_COMMAND_LINE::check_announcements) {
-               check_announcements ();
+       if ((nsm_url = g_getenv ("NSM_URL")) == 0) {
+               return 0;
        }
 
-       app->ready ();
+       nsm = new NSM_Client;
 
-       /* we need to create this early because it may need to set the
-        *  audio backend end up.
+       if (nsm->init (nsm_url)) {
+               delete nsm;
+               nsm = 0;
+               error << _("NSM: initialization failed") << endmsg;
+               return -1;
+       }
+
+       /* the ardour executable may have different names:
+        *
+        * waf's obj.target for distro versions: eg ardour4, ardourvst4
+        * Ardour4, Mixbus3 for bundled versions + full path on OSX & windows
+        * argv[0] does not apply since we need the wrapper-script (not the binary itself)
+        *
+        * The wrapper startup script should set the environment variable 'ARDOUR_SELF'
         */
+       const char *process_name = g_getenv ("ARDOUR_SELF");
+       nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour6");
 
-       try {
-               audio_midi_setup.get (true);
-       } catch (...) {
-               std::cerr << "audio-midi engine setup failed."<< std::endl;
+       unsigned int i = 0;
+       // wait for announce reply from nsm server
+       for ( i = 0; i < 5000; ++i) {
+               nsm->check ();
+
+               Glib::usleep (i);
+               if (nsm->is_active()) {
+                       break;
+               }
+       }
+       if (i == 5000) {
+               error << _("NSM server did not announce itself") << endmsg;
                return -1;
        }
+       // wait for open command from nsm server
+       for ( i = 0; i < 5000; ++i) {
+               nsm->check ();
+               Glib::usleep (1000);
+               if (nsm->client_id ()) {
+                       break;
+               }
+       }
 
-       if ((nsm_url = g_getenv ("NSM_URL")) != 0) {
-               nsm = new NSM_Client;
-               if (!nsm->init (nsm_url)) {
-                       /* the ardour executable may have different names:
-                        *
-                        * waf's obj.target for distro versions: eg ardour4, ardourvst4
-                        * Ardour4, Mixbus3 for bundled versions + full path on OSX & windows
-                        * argv[0] does not apply since we need the wrapper-script (not the binary itself)
-                        *
-                        * The wrapper startup script should set the environment variable 'ARDOUR_SELF'
-                        */
-                       const char *process_name = g_getenv ("ARDOUR_SELF");
-                       nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour6");
-
-                       unsigned int i = 0;
-                       // wait for announce reply from nsm server
-                       for ( i = 0; i < 5000; ++i) {
-                               nsm->check ();
-
-                               Glib::usleep (i);
-                               if (nsm->is_active()) {
-                                       break;
-                               }
-                       }
-                       if (i == 5000) {
-                               error << _("NSM server did not announce itself") << endmsg;
-                               return -1;
-                       }
-                       // wait for open command from nsm server
-                       for ( i = 0; i < 5000; ++i) {
-                               nsm->check ();
-                               Glib::usleep (1000);
-                               if (nsm->client_id ()) {
-                                       break;
-                               }
-                       }
+       if (i == 5000) {
+               error << _("NSM: no client ID provided") << endmsg;
+               return -1;
+       }
 
-                       if (i == 5000) {
-                               error << _("NSM: no client ID provided") << endmsg;
-                               return -1;
-                       }
+       if (_session && nsm) {
+               _session->set_nsm_state( nsm->is_active() );
+       } else {
+               error << _("NSM: no session created") << endmsg;
+               return -1;
+       }
 
-                       if (_session && nsm) {
-                               _session->set_nsm_state( nsm->is_active() );
-                       } else {
-                               error << _("NSM: no session created") << endmsg;
-                               return -1;
-                       }
+       // nsm requires these actions disabled
+       vector<string> action_names;
+       action_names.push_back("SaveAs");
+       action_names.push_back("Rename");
+       action_names.push_back("New");
+       action_names.push_back("Open");
+       action_names.push_back("Recent");
+       action_names.push_back("Close");
+
+       for (vector<string>::const_iterator n = action_names.begin(); n != action_names.end(); ++n) {
+               Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), (*n).c_str());
+               if (act) {
+                       act->set_sensitive (false);
+               }
+       }
 
-                       // nsm requires these actions disabled
-                       vector<string> action_names;
-                       action_names.push_back("SaveAs");
-                       action_names.push_back("Rename");
-                       action_names.push_back("New");
-                       action_names.push_back("Open");
-                       action_names.push_back("Recent");
-                       action_names.push_back("Close");
-
-                       for (vector<string>::const_iterator n = action_names.begin(); n != action_names.end(); ++n) {
-                               Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), (*n).c_str());
-                               if (act) {
-                                       act->set_sensitive (false);
-                               }
-                       }
+       return 0;
+}
 
-               } else {
-                       delete nsm;
-                       nsm = 0;
-                       error << _("NSM: initialization failed") << endmsg;
-                       return -1;
-               }
+void
+ARDOUR_UI::sfsm_response (StartupFSM::Result r)
+{
+       DEBUG_TRACE (DEBUG::GuiStartup, string_compose (X_("startup FSM response %1\n"), r));
 
-       } else  {
+       switch (r) {
+       case StartupFSM::ExitProgram:
+               queue_finish ();
+               break;
 
-               if (brand_new_user) {
-                       _initial_verbose_plugin_scan = true;
-                       ArdourStartup s;
-                       s.present ();
-                       main().run();
-                       s.hide ();
-                       _initial_verbose_plugin_scan = false;
-                       switch (s.response ()) {
-                       case Gtk::RESPONSE_OK:
-                               break;
-                       default:
-                               return -1;
-                       }
-               }
+       case StartupFSM::LoadSession:
 
-               // TODO: maybe IFF brand_new_user
-               if (ARDOUR::Profile->get_mixbus () && Config->get_copy_demo_sessions ()) {
-                       std::string dspd (Config->get_default_session_parent_dir());
-                       Searchpath ds (ARDOUR::ardour_data_search_path());
-                       ds.add_subdirectory_to_paths ("sessions");
-                       vector<string> demos;
-                       find_files_matching_pattern (demos, ds, ARDOUR::session_archive_suffix);
-
-                       ARDOUR::RecentSessions rs;
-                       ARDOUR::read_recent_sessions (rs);
-
-                       for (vector<string>::iterator i = demos.begin(); i != demos.end (); ++i) {
-                               /* "demo-session" must be inside "demo-session.<session_archive_suffix>" */
-                               std::string name = basename_nosuffix (basename_nosuffix (*i));
-                               std::string path = Glib::build_filename (dspd, name);
-                               /* skip if session-dir already exists */
-                               if (Glib::file_test(path.c_str(), Glib::FILE_TEST_IS_DIR)) {
-                                       continue;
-                               }
-                               /* skip sessions that are already in 'recent'.
-                                * eg. a new user changed <session-default-dir> shorly after installation
-                                */
-                               for (ARDOUR::RecentSessions::iterator r = rs.begin(); r != rs.end(); ++r) {
-                                       if ((*r).first == name) {
-                                               continue;
-                                       }
-                               }
-                               try {
-                                       PBD::FileArchive ar (*i);
-                                       if (0 == ar.inflate (dspd)) {
-                                               store_recent_sessions (name, path);
-                                               info << string_compose (_("Copied Demo Session %1."), name) << endmsg;
-                                       }
-                               } catch (...) {}
-                       }
+               if (load_session_from_startup_fsm () == 0) {
+                       delete startup_fsm;
+                       startup_fsm = 0;
+                       startup_done ();
+               } else {
+                       startup_fsm->reset ();
                }
 
-#ifdef NO_PLUGIN_STATE
-
-               ARDOUR::RecentSessions rs;
-               ARDOUR::read_recent_sessions (rs);
+               break;
+       }
+}
 
-               string path = Glib::build_filename (user_config_directory(), ".iknowaboutfreeversion");
+int
+ARDOUR_UI::starting ()
+{
+       if (ARDOUR_COMMAND_LINE::check_announcements) {
+               check_announcements ();
+       }
 
-               if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS) && !rs.empty()) {
+       /* we need to create this early because it may need to set the
+        *  audio backend end up.
+        */
 
-                       /* already used Ardour, have sessions ... warn about plugin state */
+       EngineControl* amd;
 
-                       ArdourDialog d (_("Free/Demo Version Warning"), true);
-                       Label l;
-                       Button b (string_compose (_("Subscribe and support development of %1"), PROGRAM_NAME));
-                       CheckButton c (_("Don't warn me about this again"));
+       try {
+               amd = dynamic_cast<EngineControl*> (audio_midi_setup.get (true));
+       } catch (...) {
+               std::cerr << "audio-midi engine setup failed."<< std::endl;
+               return -1;
+       }
 
-                       l.set_markup (string_compose (_("<span weight=\"bold\" size=\"large\">%1</span>\n\n<b>%2</b>\n\n<i>%3</i>\n\n%4"),
-                                                     string_compose (_("This is a free/demo version of %1"), PROGRAM_NAME),
-                                                     _("It will not restore OR save any plugin settings"),
-                                                     _("If you load an existing session with plugin settings\n"
-                                                       "they will not be used and will be lost."),
-                                                     _("To get full access to updates without this limitation\n"
-                                                       "consider becoming a subscriber for a low cost every month.")));
-                       l.set_justify (JUSTIFY_CENTER);
+       if (nsm_init ()) {
+               return -1;
+       } else  {
 
-                       b.signal_clicked().connect (mem_fun(*this, &ARDOUR_UI::launch_subscribe));
 
-                       d.get_vbox()->pack_start (l, true, true);
-                       d.get_vbox()->pack_start (b, false, false, 12);
-                       d.get_vbox()->pack_start (c, false, false, 12);
+               startup_fsm = new StartupFSM (*amd);
+               startup_fsm->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::sfsm_response));
 
-                       d.add_button (_("Quit now"), RESPONSE_CANCEL);
-                       d.add_button (string_compose (_("Continue using %1"), PROGRAM_NAME), RESPONSE_OK);
+               /* Note: entire startup process could happen in this one call
+                * if:
+                *
+                * 1) not a new user
+                * 2) session name provided on command line (and valid)
+                * 3) no audio/MIDI setup required
+                */
 
-                       d.show_all ();
+               startup_fsm->start ();
+       }
 
-                       c.signal_toggled().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (toggle_file_existence), path)));
+       return 0;
+}
 
-                       if (d.run () != RESPONSE_OK) {
-                               _exit (EXIT_SUCCESS);
-                       }
-               }
-#endif
+int
+ARDOUR_UI::load_session_from_startup_fsm ()
+{
+       const string session_path = startup_fsm->session_path;
+       const string session_name = startup_fsm->session_name;
+       const string session_template = startup_fsm->session_template;
+       const bool   session_is_new = startup_fsm->session_is_new;
+       const BusProfile bus_profile = startup_fsm->bus_profile;
 
-               /* go get a session */
+       std::cerr  << " loading from " << session_path << " as " << session_name << " templ " << session_template << " is_new " << session_is_new << " bp " << bus_profile.master_out_channels << std::endl;
 
-               const bool new_session_required = (ARDOUR_COMMAND_LINE::new_session || (!ARDOUR::Profile->get_mixbus() && brand_new_user));
+       if (session_is_new) {
 
-               if (get_session_parameters (false, new_session_required, ARDOUR_COMMAND_LINE::load_template)) {
-                       std::cerr << "Cannot get session parameters."<< std::endl;
+               if (build_session (session_path, session_name, &bus_profile)) {
                        return -1;
                }
+
+               if (!session_template.empty() && session_template.substr (0, 11) == "urn:ardour:") {
+                       meta_session_setup (session_template.substr (11));
+               }
+
+               return 0;
        }
 
+       return load_session (session_path, session_name, session_template);
+
+}
+
+void
+ARDOUR_UI::startup_done ()
+{
        use_config ();
 
        WM::Manager::instance().show_visible ();
@@ -615,10 +557,6 @@ ARDOUR_UI::starting ()
        _status_bar_visibility.update ();
 
        BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
-
-       /* all other dialogs are created conditionally */
-
-       return 0;
 }
 
 void
@@ -705,4 +643,3 @@ ARDOUR_UI::check_memory_locking ()
        }
 #endif // !__APPLE__
 }
-