fix merge errors with master
[ardour.git] / gtk2_ardour / ardour_ui.cc
index d09544fcf4b784b092d2b8f65a6961eb5079b90a..6337b1919fed3ea6b2a5b5fef17fb3a68b85272c 100644 (file)
@@ -101,6 +101,7 @@ typedef uint64_t microseconds_t;
 #include "missing_plugin_dialog.h"
 #include "mixer_ui.h"
 #include "mouse_cursors.h"
+#include "nsm.h"
 #include "opts.h"
 #include "pingback.h"
 #include "processor_box.h"
@@ -214,6 +215,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
 
        ui_config = new UIConfiguration();
 
+       ui_config->ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed));
+       boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
+       ui_config->map_parameters (pc);
+
        editor = 0;
        mixer = 0;
        meterbridge = 0;
@@ -435,7 +440,7 @@ ARDOUR_UI::engine_halted (const char* reason, bool free_reason)
                msgstr = string_compose (_("The audio backend was shutdown because:\n\n%1"), reason);
        } else {
                msgstr = string_compose (_("\
-`The audio backend has either been shutdown or it\n\
+The audio backend has either been shutdown or it\n\
 disconnected %1 because %1\n\
 was not fast enough. Try to restart\n\
 the audio backend and save the session."), PROGRAM_NAME);
@@ -717,7 +722,8 @@ int
 ARDOUR_UI::starting ()
 {
        Application* app = Application::instance ();
-       char *nsm_url;
+       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::idle_load));
@@ -728,9 +734,17 @@ ARDOUR_UI::starting ()
 
        app->ready ();
 
-       nsm_url = getenv ("NSM_URL");
+       /* we need to create this early because it may need to set the
+        *  audio backend end up.
+        */
+       
+       try {
+               audio_midi_setup.get (true);
+       } catch (...) {
+               return -1;
+       }
 
-       if (nsm_url) {
+       if ((nsm_url = g_getenv ("NSM_URL")) != 0) {
                nsm = new NSM_Client;
                if (!nsm->init (nsm_url)) {
                        nsm->announce (PROGRAM_NAME, ":dirty:", "ardour3");
@@ -740,19 +754,33 @@ ARDOUR_UI::starting ()
                        for ( i = 0; i < 5000; ++i) {
                                nsm->check ();
                                usleep (i);
-                               if (nsm->is_active())
+                               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 ();
                                usleep (1000);
-                               if (nsm->client_id ())
+                               if (nsm->client_id ()) {
                                        break;
+                               }
+                       }
+
+                       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;
                        }
 
                        // nsm requires these actions disabled
@@ -771,36 +799,33 @@ ARDOUR_UI::starting ()
                                }
                        }
 
-               }
-               else {
+               } else {
                        delete nsm;
                        nsm = 0;
+                       error << _("NSM: initialization failed") << endmsg;
+                       return -1;
                }
 
        } else  {
-
-               if (ArdourStartup::required()) {
+               
+               if (brand_new_user) {
                        ArdourStartup s;
                        s.present ();
                        main().run();
                        s.hide ();
                        switch (s.response ()) {
-                       case Gtk::RESPONSE_REJECT:
-                               return -1;
-                       default:
+                       case Gtk::RESPONSE_OK:
                                break;
+                       default:
+                               return -1;
                        }
                }
 
-               /* we need to create this early because it may need to set the
-                *  audio backend end up.
-                */
-
-               audio_midi_setup.get (true);
-
                /* go get a session */
 
-               if (get_session_parameters (false, ARDOUR_COMMAND_LINE::new_session, ARDOUR_COMMAND_LINE::load_template)) {
+               const bool new_session_required = (ARDOUR_COMMAND_LINE::new_session || brand_new_user);
+
+               if (get_session_parameters (false, new_session_required, ARDOUR_COMMAND_LINE::load_template)) {
                        return -1;
                }
        }
@@ -820,13 +845,6 @@ ARDOUR_UI::starting ()
        return 0;
 }
 
-void
-ARDOUR_UI::no_memory_warning ()
-{
-       XMLNode node (X_("no-memory-warning"));
-       Config->add_instant_xml (node);
-}
-
 void
 ARDOUR_UI::check_memory_locking ()
 {
@@ -883,9 +901,6 @@ ARDOUR_UI::check_memory_locking ()
                                VBox* vbox = msg.get_vbox();
                                HBox hbox;
                                CheckButton cb (_("Do not show this window again"));
-
-                               cb.signal_toggled().connect (sigc::mem_fun (*this, &ARDOUR_UI::no_memory_warning));
-                               
                                hbox.pack_start (cb, true, false);
                                vbox->pack_start (hbox);
                                cb.show();
@@ -896,6 +911,11 @@ ARDOUR_UI::check_memory_locking ()
 
                                editor->ensure_float (msg);
                                msg.run ();
+
+                               if (cb.get_active()) {
+                                       XMLNode node (X_("no-memory-warning"));
+                                       Config->add_instant_xml (node);
+                               }
                        }
                }
        }
@@ -1197,7 +1217,7 @@ ARDOUR_UI::update_cpu_load ()
           should also be changed.
        */
 
-       float const c = AudioEngine::instance()->get_cpu_load ();
+       float const c = AudioEngine::instance()->get_dsp_load ();
        snprintf (buf, sizeof (buf), _("DSP: <span foreground=\"%s\">%5.1f%%</span>"), c >= 90 ? X_("red") : X_("green"), c);
        cpu_load_label.set_markup (buf);
 }
@@ -2174,8 +2194,13 @@ ARDOUR_UI::snapshot_session (bool switch_to_it)
 
        prompter.set_name ("Prompter");
        prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
-       prompter.set_title (_("Take Snapshot"));
-       prompter.set_prompt (_("Name of new snapshot"));
+       if (switch_to_it) {
+               prompter.set_title (_("Save as..."));
+               prompter.set_prompt (_("New session name"));
+       } else {
+               prompter.set_title (_("Take Snapshot"));
+               prompter.set_prompt (_("Name of new snapshot"));
+       }
 
        if (!switch_to_it) {
                char timebuf[128];
@@ -2847,6 +2872,22 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
                }
        }
 
+       if (!new_session->writable()) {
+               MessageDialog msg (_("This session has been opened in read-only mode.\n\nYou will not be able to record or save."),
+                                  true,
+                                  Gtk::MESSAGE_INFO,
+                                  BUTTONS_OK);
+               
+               msg.set_keep_above (true);
+               msg.set_title (_("Read-only Session"));
+               msg.set_position (Gtk::WIN_POS_CENTER);
+               pop_back_splash (msg);
+               msg.present ();
+               (void) msg.run ();
+               msg.hide ();
+       }
+       
+
        /* Now the session been created, add the transport controls */
        new_session->add_controllable(roll_controllable);
        new_session->add_controllable(stop_controllable);
@@ -3203,6 +3244,57 @@ ARDOUR_UI::flush_trash ()
        display_cleanup_results (rep, _("deleted file"), true);
 }
 
+void
+ARDOUR_UI::setup_order_hint ()
+{
+       uint32_t order_hint = 0;
+
+       /*
+         we want the new routes to have their order keys set starting from 
+         the highest order key in the selection + 1 (if available).
+       */
+       if (add_route_dialog->get_transient_for () == mixer->get_toplevel()) {
+               for (RouteUISelection::iterator s = mixer->selection().routes.begin(); s != mixer->selection().routes.end(); ++s) {
+                       if ((*s)->route()->order_key() > order_hint) {
+                               order_hint = (*s)->route()->order_key();
+                       }
+               }
+
+               if (!mixer->selection().routes.empty()) {
+                       order_hint++;
+               }
+
+       } else {
+               for (TrackSelection::iterator s = editor->get_selection().tracks.begin(); s != editor->get_selection().tracks.end(); ++s) {
+                       RouteTimeAxisView* tav = dynamic_cast<RouteTimeAxisView*> (*s);
+                       if (tav->route()->order_key() > order_hint) {
+                               order_hint = tav->route()->order_key();
+                       }
+               }
+
+               if (!editor->get_selection().tracks.empty()) {
+                       order_hint++;
+               }
+       }
+
+       _session->set_order_hint (order_hint);
+
+       /* create a gap in the existing route order keys to accomodate new routes.*/
+
+       boost::shared_ptr <RouteList> rd = _session->get_routes();
+       for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
+               boost::shared_ptr<Route> rt (*ri);
+                       
+               if (rt->is_monitor()) {
+                       continue;
+               }
+
+               if (rt->order_key () >= order_hint) {
+                       rt->set_order_key (rt->order_key () + add_route_dialog->count());
+               }
+       }
+}
+
 void
 ARDOUR_UI::add_route (Gtk::Window* float_window)
 {
@@ -3218,6 +3310,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
        }
 
        if (float_window) {
+               add_route_dialog->unset_transient_for ();
                add_route_dialog->set_transient_for (*float_window);
        }
 
@@ -3237,6 +3330,8 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
                return;
        }
 
+       setup_order_hint();
+
        PBD::ScopedConnection idle_connection;
 
        if (count > 8) {
@@ -3474,7 +3569,8 @@ ARDOUR_UI::add_video (Gtk::Window* float_window)
                                if (!transcode_video_dialog->get_audiofile().empty()) {
                                        editor->embed_audio_from_video(
                                                        transcode_video_dialog->get_audiofile(),
-                                                       video_timeline->get_offset()
+                                                       video_timeline->get_offset(),
+                                                       (transcode_video_dialog->import_option() != VTL_IMPORT_NO_VIDEO)
                                                        );
                                }
                                switch (transcode_video_dialog->import_option()) {
@@ -3714,8 +3810,8 @@ ARDOUR_UI::session_dialog (std::string msg)
 int
 ARDOUR_UI::pending_state_dialog ()
 {
-       HBox* hbox = new HBox();
-       Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
+       HBox* hbox = manage (new HBox());
+       Image* image = manage (new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG));
        ArdourDialog dialog (_("Crash Recovery"), true);
        Label  message (string_compose (_("\
 This session appears to have been in the\n\
@@ -3803,8 +3899,13 @@ int
 ARDOUR_UI::reconnect_to_engine ()
 {
        if (AudioEngine::instance()->start ()) {
-               MessageDialog msg (*editor,  _("Could not reconnect to the Audio/MIDI engine"));
-               msg.run ();
+               if (editor) {
+                       MessageDialog msg (*editor,  _("Could not reconnect to the Audio/MIDI engine"));
+                       msg.run ();
+               } else {
+                       MessageDialog msg (_("Could not reconnect to the Audio/MIDI engine"));
+                       msg.run ();
+               }
                return -1;
        }
        
@@ -4121,6 +4222,7 @@ int
 ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
 {
        audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
+       audio_midi_setup->set_position (WIN_POS_CENTER);
 
        switch (audio_midi_setup->run()) {
        case Gtk::RESPONSE_OK: