make "New Session" open NSD on the right page
[ardour.git] / gtk2_ardour / ardour_ui.cc
index 8823ad8ad0562788f2a65ac90b4e2a8c02583b36..74234bb12aef06cb554e70826d65e829ffc7a1d3 100644 (file)
 #include <gtkmm2ext/fastmeter.h>
 #include <gtkmm2ext/stop_signal.h>
 #include <gtkmm2ext/popup.h>
+#include <gtkmm2ext/window_title.h>
 
 #include <midi++/port.h>
 #include <midi++/mmc.h>
 
 #include <ardour/ardour.h>
+#include <ardour/profile.h>
 #include <ardour/session_route.h>
 #include <ardour/port.h>
 #include <ardour/audioengine.h>
@@ -87,13 +89,12 @@ ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
 
 sigc::signal<void,bool> ARDOUR_UI::Blink;
 sigc::signal<void>      ARDOUR_UI::RapidScreenUpdate;
-sigc::signal<void>      ARDOUR_UI::MidRapidScreenUpdate;
 sigc::signal<void>      ARDOUR_UI::SuperRapidScreenUpdate;
 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
 
 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
 
-       : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
+       : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp, rcfile),
          
          primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
          secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
@@ -186,7 +187,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
        keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
 
        can_save_keybindings = false;
-       Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
 
        last_configure_time.tv_sec = 0;
        last_configure_time.tv_usec = 0;
@@ -263,10 +263,6 @@ ARDOUR_UI::set_engine (AudioEngine& e)
        AudioFileSource::set_build_peakfiles (true);
        AudioFileSource::set_build_missing_peakfiles (true);
 
-       if (AudioSource::start_peak_thread ()) {
-               throw failed_constructor();
-       }
-
        /* set default clock modes */
 
        primary_clock.set_mode (AudioClock::SMPTE);
@@ -304,8 +300,6 @@ ARDOUR_UI::~ARDOUR_UI ()
        if (add_route_dialog) {
                delete add_route_dialog;
        }
-
-       AudioSource::stop_peak_thread ();
 }
 
 gint
@@ -434,30 +428,108 @@ ARDOUR_UI::save_ardour_state ()
        save_keybindings ();
 }
 
+gint
+ARDOUR_UI::autosave_session ()
+{
+        if (!Config->get_periodic_safety_backups())
+                return 1;
+        
+        if (session) {
+                session->maybe_write_autosave();
+        }
+
+        return 1;
+}
+
+void
+ARDOUR_UI::update_autosave ()
+{
+        ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
+        
+        if (session->dirty()) {
+                if (_autosave_connection.connected()) {
+                        _autosave_connection.disconnect();
+                }
+
+                _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
+                                                                   Config->get_periodic_safety_backup_interval() * 1000);
+
+        } else {
+                if (_autosave_connection.connected()) {
+                        _autosave_connection.disconnect();
+                }               
+        }
+}
+
 void
 ARDOUR_UI::startup ()
 {
-       if (engine->is_realtime()) {
+       check_memory_locking();
+}
+
+void
+ARDOUR_UI::no_memory_warning ()
+{
+       XMLNode node (X_("no-memory-warning"));
+       Config->add_instant_xml (node, get_user_ardour_path());
+}
+
+void
+ARDOUR_UI::check_memory_locking ()
+{
+#ifdef __APPLE__
+       /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
+       return;
+#else // !__APPLE__
+
+       XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"), get_user_ardour_path());
+
+       if (engine->is_realtime() && memory_warning_node == 0) {
 
                struct rlimit limits;
-               
+               int64_t ram;
+               long pages, page_size;
+
+               if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
+                       ram = 0;
+               } else {
+                       ram = (int64_t) pages * (int64_t) page_size;
+               }
+
                if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
                        return;
                }
                
                if (limits.rlim_cur != RLIM_INFINITY) {
-                       MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
-                                            "This might cause Ardour to run out of memory before your system "
-                                            "runs out of memory. \n\n"
-                                            "You can view the memory limit with 'ulimit -l', "
-                                            "and it is normally controlled by /etc/security/limits.conf"));
+
+                       if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
                        
-                       editor->ensure_float (msg);
-                       msg.run ();
+
+                               MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
+                                                    "This might cause Ardour to run out of memory before your system "
+                                                    "runs out of memory. \n\n"
+                                                    "You can view the memory limit with 'ulimit -l', "
+                                                    "and it is normally controlled by /etc/security/limits.conf"));
+                               
+                               VBox* vbox = msg.get_vbox();
+                               HBox hbox;
+                               CheckButton cb (_("Do not show this window again"));
+                               
+                               cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
+                               
+                               hbox.pack_start (cb, true, false);
+                               vbox->pack_start (hbox);
+                               hbox.show_all ();
+                               
+                               editor->ensure_float (msg);
+                               msg.run ();
+                       }
                }
        }
+#endif // !__APPLE__
 }
 
+
 void
 ARDOUR_UI::finish()
 {
@@ -580,13 +652,6 @@ ARDOUR_UI::every_point_one_seconds ()
        return TRUE;
 }
 
-gint
-ARDOUR_UI::every_point_oh_five_seconds ()
-{
-       MidRapidScreenUpdate(); /* EMIT_SIGNAL */
-       return true;
-}
-
 gint
 ARDOUR_UI::every_point_zero_one_seconds ()
 {
@@ -610,11 +675,11 @@ ARDOUR_UI::update_sample_rate (nframes_t ignored)
                nframes_t rate = engine->frame_rate();
                
                if (fmod (rate, 1000.0) != 0.0) {
-                       snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"), 
+                       snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"), 
                                  (float) rate/1000.0f,
                                  (engine->frames_per_cycle() / (float) rate) * 1000.0f);
                } else {
-                       snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"), 
+                       snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"), 
                                  rate/1000,
                                  (engine->frames_per_cycle() / (float) rate) * 1000.0f);
                }
@@ -627,7 +692,7 @@ void
 ARDOUR_UI::update_cpu_load ()
 {
        char buf[32];
-       snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
+       snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
        cpu_load_label.set_text (buf);
 }
 
@@ -952,7 +1017,8 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t
                                if (how_many == 1) {
                                        error << _("could not create a new audio track") << endmsg;
                                } else {
-                                       error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
+                                       error << string_compose (_("could only create %1 of %2 new audio %3"), 
+                                                                tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
                                }
                        }
 
@@ -983,6 +1049,7 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t
        }
 
        catch (...) {
+               cerr << "About to complain about JACK\n";
                MessageDialog msg (*editor, 
                                   _("There are insufficient JACK ports available\n\
 to create a new track or bus.\n\
@@ -1100,8 +1167,6 @@ ARDOUR_UI::remove_last_capture()
 void
 ARDOUR_UI::transport_record ()
 {
-       cerr << "transport record\n";
-
        if (session) {
                switch (session->record_status()) {
                case Session::Disabled:
@@ -1505,6 +1570,8 @@ ARDOUR_UI::name_io_setup (AudioEngine& engine,
        }
 }
 
+/** Ask the user for the name of a new shapshot and then take it.
+ */
 void
 ARDOUR_UI::snapshot_session ()
 {
@@ -1678,7 +1745,7 @@ ARDOUR_UI::save_template ()
        }
 }
 
-void
+bool
 ARDOUR_UI::new_session (std::string predetermined_path)
 {
        string session_name;
@@ -1687,7 +1754,7 @@ ARDOUR_UI::new_session (std::string predetermined_path)
        if (!engine->connected()) {
                MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
                msg.run ();
-               return;
+               return false;
        }
 
        int response = Gtk::RESPONSE_NONE;
@@ -1696,15 +1763,16 @@ ARDOUR_UI::new_session (std::string predetermined_path)
        new_session_dialog->set_name (predetermined_path);
        new_session_dialog->reset_recent();
        new_session_dialog->show();
+       new_session_dialog->set_current_page (0);
 
        do {
                response = new_session_dialog->run ();
 
                if (!engine->connected()) {
                        new_session_dialog->hide ();
-                       MessageDialog msg (_("Ardour is no longer connected to JACK. Creating a new session is not possible."));
+                       MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
                        msg.run ();
-                       return;
+                       return false;
                }
                
                _session_is_new = false;
@@ -1715,7 +1783,7 @@ ARDOUR_UI::new_session (std::string predetermined_path)
                                quit();
                        }
                        new_session_dialog->hide ();
-                       return;
+                       return false;
 
                } else if (response == Gtk::RESPONSE_NONE) {
 
@@ -1866,15 +1934,20 @@ ARDOUR_UI::new_session (std::string predetermined_path)
                                        uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
                                        uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
                                                        
-                                       build_session (session_path,
-                                                      session_name,
-                                                      cchns,
-                                                      mchns,
-                                                      iconnect,
-                                                      oconnect,
-                                                      nphysin,
-                                                      nphysout, 
-                                                      engine->frame_rate() * 60 * 5);
+                                       if (build_session (session_path,
+                                                          session_name,
+                                                          cchns,
+                                                          mchns,
+                                                          iconnect,
+                                                          oconnect,
+                                                          nphysin,
+                                                          nphysout, 
+                                                          engine->frame_rate() * 60 * 5)) {
+
+                                               response = Gtk::RESPONSE_NONE;
+                                               new_session_dialog->reset ();
+                                               continue;
+                                       }
                                }
                        }
                }
@@ -1885,6 +1958,7 @@ ARDOUR_UI::new_session (std::string predetermined_path)
        show();
        new_session_dialog->get_window()->set_cursor();
        new_session_dialog->hide();
+       return true;
 }
 
 void
@@ -1940,6 +2014,7 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string*
                session->set_clean ();
        }
 
+       editor->edit_cursor_position (true);
        return 0;
 }
 
@@ -1973,7 +2048,8 @@ ARDOUR_UI::build_session (const string & path, const string & snap_name,
 
        catch (...) {
 
-               error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
+               MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
+               msg.run ();
                return -1;
        }
 
@@ -2208,7 +2284,7 @@ releasing %4 %5bytes of disk space"));
 }
 
 void
-ARDOUR_UI::add_route ()
+ARDOUR_UI::add_route (Gtk::Window* float_window)
 {
        int count;
 
@@ -2218,7 +2294,9 @@ ARDOUR_UI::add_route ()
 
        if (add_route_dialog == 0) {
                add_route_dialog = new AddRouteDialog;
-               editor->ensure_float (*add_route_dialog);
+               if (float_window) {
+                       add_route_dialog->set_transient_for (*float_window);
+               }
        }
 
        if (add_route_dialog->is_visible()) {
@@ -2329,7 +2407,7 @@ ARDOUR_UI::disk_overrun_handler ()
 
        if (!have_disk_speed_dialog_displayed) {
                have_disk_speed_dialog_displayed = true;
-               MessageDialog* msg = new MessageDialog (*editor, X_("diskrate dialog"), _("\
+               MessageDialog* msg = new MessageDialog (*editor, _("\
 The disk system on your computer\n\
 was not able to keep up with Ardour.\n\
 \n\
@@ -2541,6 +2619,9 @@ ARDOUR_UI::save_keybindings ()
 bool
 ARDOUR_UI::first_idle ()
 {
+       if (session) {
+               session->allow_auto_play (true);
+       }
        can_save_keybindings = true;
        return false;
 }
@@ -2664,3 +2745,11 @@ ARDOUR_UI::TransportControllable::set_id (const string& str)
 {
        _id = str;
 }
+
+void
+ARDOUR_UI::setup_profile ()
+{
+       if (gdk_screen_width() < 1200) {
+               Profile->set_small_screen ();
+       }
+}