do not pass a non-zero offset to plugins AFTER the first call to connect_and_run...
[ardour.git] / gtk2_ardour / ardour_ui.cc
index b5a19e388e13b22801b36c4afb264b313186ba7c..411f8d4f62102b6b5ca0c991691d81d5b9188285 100644 (file)
@@ -58,6 +58,7 @@
 #include <ardour/audioengine.h>
 #include <ardour/playlist.h>
 #include <ardour/utils.h>
+#include <ardour/plugin.h>
 #include <ardour/audio_diskstream.h>
 #include <ardour/audiofilesource.h>
 #include <ardour/recent_sessions.h>
@@ -131,13 +132,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
          shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
          shuttle_controller_binding_proxy (shuttle_controllable),
 
-         roll_button (roll_controllable),
-         stop_button (stop_controllable),
-         goto_start_button (goto_start_controllable),
-         goto_end_button (goto_end_controllable),
-         auto_loop_button (auto_loop_controllable),
-         play_selection_button (play_selection_controllable),
-         rec_button (rec_controllable),
+         roll_button (&roll_controllable),
+         stop_button (&stop_controllable),
+         goto_start_button (&goto_start_controllable),
+         goto_end_button (&goto_end_controllable),
+         auto_loop_button (&auto_loop_controllable),
+         play_selection_button (&play_selection_controllable),
+         rec_button (&rec_controllable),
          
          shuttle_units_button (_("% ")),
 
@@ -199,6 +200,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
        session_loaded = false;
        last_speed_displayed = -1.0f;
        ignore_dual_punch = false;
+       _mixer_on_top = false;
+
+       roll_button.unset_flags (Gtk::CAN_FOCUS);
+       stop_button.unset_flags (Gtk::CAN_FOCUS);
+       goto_start_button.unset_flags (Gtk::CAN_FOCUS);
+       goto_end_button.unset_flags (Gtk::CAN_FOCUS);
+       auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
+       play_selection_button.unset_flags (Gtk::CAN_FOCUS);
+       rec_button.unset_flags (Gtk::CAN_FOCUS);
 
        last_configure_time= 0;
 
@@ -216,6 +226,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
        ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
        ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
 
+       ARDOUR::Plugin::PresetFileExists.connect (mem_fun(*this, &ARDOUR_UI::preset_file_exists_handler));
+
        /* handle dialog requests */
 
        ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
@@ -337,11 +349,12 @@ ARDOUR_UI::post_engine ()
        /* set default clock modes */
 
        if (Profile->get_sae()) {
-               primary_clock.set_mode (AudioClock::MinSec);
+               primary_clock.set_mode (AudioClock::BBT);
+               secondary_clock.set_mode (AudioClock::MinSec);
        }  else {
                primary_clock.set_mode (AudioClock::SMPTE);
+               secondary_clock.set_mode (AudioClock::BBT);
        }
-       secondary_clock.set_mode (AudioClock::BBT);
 
        /* start the time-of-day-clock */
        
@@ -627,7 +640,7 @@ void
 ARDOUR_UI::startup ()
 {
        string name, path;
-
+       
        new_session_dialog = new NewSessionDialog();
 
        bool backend_audio_is_running = EngineControl::engine_running();
@@ -746,6 +759,7 @@ If you still wish to quit, please use the\n\n\
                session->set_deletion_in_progress ();
        }
 
+       ArdourDialog::close_all_dialogs ();
        engine->stop (true);
        save_ardour_state ();
        quit ();
@@ -1285,7 +1299,7 @@ ARDOUR_UI::do_transport_locate (nframes_t new_position)
 }
 
 void
-ARDOUR_UI::transport_goto_start ()
+ARDOUR_UI::transport_goto_start ()  
 {
        if (session) {
                session->goto_start();
@@ -1667,8 +1681,8 @@ ARDOUR_UI::engine_halted ()
                           _("\
 JACK has either been shutdown or it\n\
 disconnected Ardour because Ardour\n\
-was not fast enough. You can save the\n\
-session and/or try to reconnect to JACK ."));
+was not fast enough. Try to restart\n\
+JACK, reconnect and save the session."));
        pop_back_splash ();
        msg.run ();
 }
@@ -1917,14 +1931,6 @@ ARDOUR_UI::transport_rec_enable_blink (bool onoff)
        }
 }
 
-gint
-ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
-{
-       window->hide();
-       Gtk::Main::quit ();
-       return TRUE;
-}
-
 void
 ARDOUR_UI::save_template ()
 
@@ -2161,7 +2167,7 @@ ARDOUR_UI::loading_message (const std::string& msg)
        splash->message (msg);
        flush_pending ();
 }
-       
+
 void
 ARDOUR_UI::idle_load (const Glib::ustring& path)
 {
@@ -2174,11 +2180,16 @@ ARDOUR_UI::idle_load (const Glib::ustring& path)
                        load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
                }
        } else {
+
                ARDOUR_COMMAND_LINE::session_name = path;
+
                if (new_session_dialog) {
+
+
                        /* make it break out of Dialog::run() and
                           start again.
                         */
+
                        new_session_dialog->response (1);
                }
        }
@@ -2247,6 +2258,9 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be
                case Gtk::RESPONSE_CANCEL:
                case Gtk::RESPONSE_DELETE_EVENT:
                        if (!session) {
+                               if (engine && engine->running()) {
+                                       engine->stop (true);
+                               }
                                quit();
                        }
                        new_session_dialog->hide ();
@@ -2299,7 +2313,7 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be
                        if (session_name[0] == '/' || 
                            (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
                            (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
-                               
+
                                session_path = Glib::path_get_dirname (session_name);
                                session_name = Glib::path_get_basename (session_name);
                                
@@ -2357,7 +2371,7 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be
                        
                  loadit:
                        new_session_dialog->hide ();
-                       
+
                        if (load_session (session_path, session_name, template_name)) {
                                /* force a retry */
                                response = Gtk::RESPONSE_NONE;
@@ -2437,10 +2451,10 @@ ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_na
                MessageDialog msg (err.what(),
                                   true,
                                   Gtk::MESSAGE_INFO,
-                                  Gtk::BUTTONS_OK_CANCEL);
+                                  Gtk::BUTTONS_CLOSE);
                
-               msg.set_title (_("Loading Error"));
-               msg.set_secondary_text (_("Click the OK button to try again."));
+               msg.set_title (_("Port Registration Error"));
+               msg.set_secondary_text (_("Click the Close button to try again."));
                msg.set_position (Gtk::WIN_POS_CENTER);
                pop_back_splash ();
                msg.present ();
@@ -2463,10 +2477,10 @@ ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_na
                MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
                                   true,
                                   Gtk::MESSAGE_INFO,
-                                  Gtk::BUTTONS_OK_CANCEL);
+                                  Gtk::BUTTONS_CLOSE);
                
                msg.set_title (_("Loading Error"));
-               msg.set_secondary_text (_("Click the OK button to try again."));
+               msg.set_secondary_text (_("Click the Close button to try again."));
                msg.set_position (Gtk::WIN_POS_CENTER);
                pop_back_splash ();
                msg.present ();
@@ -2548,6 +2562,9 @@ ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_n
        connect_to_session (new_session);
 
        session_loaded = true;
+
+       new_session->save_state(new_session->name());
+
        return 0;
 }
 
@@ -2839,6 +2856,13 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
                return;
        }
 
+       string template_path = add_route_dialog->track_template();
+
+       if (!template_path.empty()) {
+         session->new_route_from_template (count, template_path);
+         return;
+       }
+       
        uint32_t input_chan = add_route_dialog->channels ();
        uint32_t output_chan;
        string name_template = add_route_dialog->name_template ();
@@ -2854,8 +2878,6 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
 
        /* XXX do something with name template */
 
-       cerr << "Adding with " << input_chan << " in and " << output_chan << "out\n";
-
        if (track) {
                session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
        } else {
@@ -2891,6 +2913,12 @@ ARDOUR_UI::editor_settings () const
        } else {
                node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
        }
+       
+       if (!node) {
+               if (getenv("ARDOUR_INSTANT_XML_PATH")) {
+                       node = Config->instant_xml(X_("Editor"), getenv("ARDOUR_INSTANT_XML_PATH"));
+               }
+       }
 
        if (!node) {
                node = new XMLNode (X_("Editor"));
@@ -2914,7 +2942,6 @@ ARDOUR_UI::keyboard_settings () const
 void
 ARDOUR_UI::create_xrun_marker(nframes_t where)
 {
-       ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::create_xrun_marker), where));
        editor->mouse_add_new_marker (where, false, true);
 }
 
@@ -2929,15 +2956,60 @@ ARDOUR_UI::halt_on_xrun_message ()
 void
 ARDOUR_UI::xrun_handler(nframes_t where)
 {
-       if (Config->get_create_xrun_marker() && session->actively_recording()) {
+       if (!session) {
+               return;
+       }
+
+       ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
+
+       if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
                create_xrun_marker(where);
        }
 
-       if (Config->get_stop_recording_on_xrun() && session->actively_recording()) {
+       if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
                halt_on_xrun_message ();
        }
 }
 
+bool
+ARDOUR_UI::preset_file_exists_handler ()
+{
+       /* if driven from another thread, say "do not overwrite" and show the user nothing.
+        */
+
+       if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {        \
+               return false;
+       }
+       
+       HBox* hbox = new HBox();
+       Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
+       Gtk::Dialog dialog (_("Preset Exists"), true, false);
+       Label  message (_("\
+A preset with this name already exists for this plugin.\n\
+\n\
+What you would like to do?\n"));
+       image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
+       hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
+       hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
+       dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
+       dialog.add_button (_("Overwrite the existing preset"), RESPONSE_ACCEPT);
+       dialog.add_button (_("Leave the existing preset alone"), RESPONSE_REJECT);
+       dialog.set_default_response (RESPONSE_ACCEPT);
+       dialog.set_position (WIN_POS_MOUSE);
+       dialog.set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY); // need to make it float above the preset name dialog
+
+       message.show();
+       image->show();
+       hbox->show();
+
+       switch (dialog.run ()) {
+       case RESPONSE_ACCEPT:
+               return true;
+       default:
+               return false;
+       }
+}
+
 void
 ARDOUR_UI::disk_overrun_handler ()
 {