scroll up/down by tracks uses top edge as "focal point"; fix some other nasty code...
[ardour.git] / gtk2_ardour / ardour_ui.cc
index 96ad085b685453fa59da1ac9dc7e4e20e60fba71..8384eee20877f3ee480ec6af310fc3d138f395c3 100644 (file)
@@ -50,6 +50,7 @@
 #include "pbd/enumwriter.h"
 #include "pbd/memento_command.h"
 #include "pbd/openuri.h"
+#include "pbd/stl_delete.h"
 #include "pbd/file_utils.h"
 #include "pbd/localtime_r.h"
 
@@ -137,6 +138,7 @@ typedef uint64_t microseconds_t;
 #include "i18n.h"
 
 using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
 using namespace PBD;
 using namespace Gtkmm2ext;
 using namespace Gtk;
@@ -219,6 +221,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
 
        splash = 0;
 
+       _numpad_locate_happening = false;
+
        if (theArdourUI == 0) {
                theArdourUI = this;
        }
@@ -488,8 +492,6 @@ ARDOUR_UI::post_engine ()
 
        _tooltips.enable();
 
-       ActionManager::load_menus (ARDOUR_COMMAND_LINE::menus_file);
-
        if (setup_windows ()) {
                throw failed_constructor ();
        }
@@ -755,6 +757,7 @@ ARDOUR_UI::starting ()
        try {
                audio_midi_setup.get (true);
        } catch (...) {
+               std::cerr << "audio-midi engine setup failed."<< std::endl;
                return -1;
        }
 
@@ -841,6 +844,7 @@ ARDOUR_UI::starting ()
                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)) {
+                       std::cerr << "Cannot get session parameters."<< std::endl;
                        return -1;
                }
        }
@@ -1413,7 +1417,7 @@ ARDOUR_UI::redisplay_recent_sessions ()
 
                get_state_files_in_directory (*i, state_file_paths);
 
-               vector<string*>* states;
+               vector<string> states;
                vector<const gchar*> item;
                string fullpath = *i;
 
@@ -1430,8 +1434,9 @@ ARDOUR_UI::redisplay_recent_sessions ()
                }
 
                /* now get available states for this session */
+               states = Session::possible_states (fullpath);
 
-               if ((states = Session::possible_states (fullpath)) == 0) {
+               if (states.empty()) {
                        /* no state file? */
                        continue;
                }
@@ -1828,10 +1833,39 @@ ARDOUR_UI::transport_stop ()
        _session->request_stop (false, true);
 }
 
+/** Check if any tracks are record enabled. If none are, record enable all of them.
+ * @return true if track record-enabled status was changed, false otherwise.
+ */  
+bool
+ARDOUR_UI::trx_record_enable_all_tracks ()
+{
+       if (!_session) {
+               return false;
+       }
+
+       boost::shared_ptr<RouteList> rl = _session->get_tracks ();
+       bool none_record_enabled = true;
+
+       for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
+               boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*r);
+               assert (t);
+
+               if (t->record_enabled()) {
+                       none_record_enabled = false;
+                       break;
+               }
+       }
+
+       if (none_record_enabled) {
+               _session->set_record_enabled (rl, true, Session::rt_cleanup);
+       } 
+
+       return none_record_enabled;
+}
+
 void
 ARDOUR_UI::transport_record (bool roll)
 {
-
        if (_session) {
                switch (_session->record_status()) {
                case Session::Disabled:
@@ -1840,6 +1874,9 @@ ARDOUR_UI::transport_record (bool roll)
                                msg.run ();
                                return;
                        }
+                       if (Profile->get_trx()) {
+                               roll = trx_record_enable_all_tracks ();
+                       }
                        _session->maybe_enable_record ();
                        if (roll) {
                                transport_roll ();
@@ -1904,7 +1941,7 @@ ARDOUR_UI::transport_roll ()
                        }
                } 
 
-       } else if (_session->get_play_range () && !Config->get_always_play_range()) {
+       } else if (_session->get_play_range () ) {
                /* stop playing a range if we currently are */
                _session->request_play_range (0, true);
        }
@@ -1971,10 +2008,10 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
                if (rolling) {
                        _session->request_stop (with_abort, true);
                } else {
-                       if ( Config->get_always_play_range() ) {
+                       if ( Config->get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_frame() ) ) {  //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits
                                _session->request_play_range (&editor->get_selection().time, true);
+                               _session->set_requested_return_frame( editor->get_selection().time.front().start );  //force an auto-return here
                        }
-
                        _session->request_transport_speed (1.0f);
                }
        }
@@ -2148,7 +2185,7 @@ ARDOUR_UI::map_transport_state ()
                        auto_loop_button.set_active (false);
                }
 
-               if (Config->get_always_play_range()) {
+               if (Config->get_follow_edits()) {
                        /* light up both roll and play-selection if they are joined */
                        roll_button.set_active (true);
                        play_selection_button.set_active (true);
@@ -3388,6 +3425,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
        setup_order_hint();
 
        string template_path = add_route_dialog->track_template();
+       DisplaySuspender ds;
 
        if (!template_path.empty()) {
                if (add_route_dialog->name_template_is_default())  {
@@ -4270,6 +4308,10 @@ ARDOUR_UI::setup_profile ()
        if (g_getenv ("TRX")) {
                Profile->set_trx ();
        }
+
+       if (g_getenv ("MIXBUS")) {
+               Profile->set_mixbus ();
+       }
 }
 
 int
@@ -4405,3 +4447,47 @@ ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
 }
 
 
+gint
+ARDOUR_UI::transport_numpad_timeout ()
+{
+       _numpad_locate_happening = false;
+       if (_numpad_timeout_connection.connected() )
+               _numpad_timeout_connection.disconnect();
+       return 1;
+}
+
+void
+ARDOUR_UI::transport_numpad_decimal ()
+{
+       _numpad_timeout_connection.disconnect();
+
+       if (_numpad_locate_happening) {
+               if (editor) editor->goto_nth_marker(_pending_locate_num - 1);
+               _numpad_locate_happening = false;
+       } else {
+               _pending_locate_num = 0;
+               _numpad_locate_happening = true;
+               _numpad_timeout_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::transport_numpad_timeout), 2*1000);
+       }
+}
+
+void
+ARDOUR_UI::transport_numpad_event (int num)
+{
+       if ( _numpad_locate_happening ) {
+               _pending_locate_num = _pending_locate_num*10 + num;
+       } else {
+               switch (num) {          
+                       case 0:  toggle_roll(false, false);             break;
+                       case 1:  transport_rewind(1);                           break;
+                       case 2:  transport_forward(1);                          break;
+                       case 3:  transport_record(true);                        break;
+                       case 4:  if (_session) _session->request_play_loop(true);                                       break;
+                       case 5:  if (_session) _session->request_play_loop(true); transport_record(false);      break;
+                       case 6:  toggle_punch();                                                break;
+                       case 7:  toggle_click();                                break;
+                       case 8:  toggle_auto_return();                  break;
+                       case 9:  toggle_follow_edits();         break;
+               }
+       }
+}