add icons for cut mouse mode button and cut cursor (both need improving)
[ardour.git] / gtk2_ardour / editor_routes.cc
index b05e4617282849ca75337aa6952307f16c1920da..025633b0909af55e7cf73aaf7dcc50ec99ae313a 100644 (file)
@@ -53,6 +53,7 @@
 
 using namespace std;
 using namespace ARDOUR;
+using namespace ARDOUR_UI_UTILS;
 using namespace PBD;
 using namespace Gtk;
 using namespace Gtkmm2ext;
@@ -70,6 +71,7 @@ EditorRoutes::EditorRoutes (Editor* e)
         , _ignore_reorder (false)
         , _no_redisplay (false)
         , _adding_routes (false)
+        , _route_deletion_in_progress (false)
         , _menu (0)
         , old_focus (0)
         , selection_countdown (0)
@@ -222,6 +224,7 @@ EditorRoutes::EditorRoutes (Editor* e)
        _display.set_headers_visible (true);
        _display.get_selection()->set_mode (SELECTION_SINGLE);
        _display.get_selection()->set_select_function (sigc::mem_fun (*this, &EditorRoutes::selection_filter));
+       _display.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &EditorRoutes::selection_changed));
        _display.set_reorderable (true);
        _display.set_name (X_("EditGroupList"));
        _display.set_rules_hint (true);
@@ -270,7 +273,7 @@ EditorRoutes::EditorRoutes (Editor* e)
        active_col->set_fixed_width (30);
        active_col->set_alignment (ALIGN_CENTER);
        
-       _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::route_deleted));
+       _model->signal_row_deleted().connect (sigc::mem_fun (*this, &EditorRoutes::row_deleted));
        _model->signal_rows_reordered().connect (sigc::mem_fun (*this, &EditorRoutes::reordered));
 
        _display.signal_button_press_event().connect (sigc::mem_fun (*this, &EditorRoutes::button_press), false);
@@ -518,7 +521,6 @@ EditorRoutes::redisplay ()
                /* show or hide the TimeAxisView */
                if (visible) {
                        position += tv->show_at (position, n, &_editor->edit_controls_vbox);
-                       // SHOWTRACKS
                } else {
                        tv->hide ();
                }
@@ -546,18 +548,31 @@ EditorRoutes::redisplay ()
 }
 
 void
-EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
+EditorRoutes::row_deleted (Gtk::TreeModel::Path const &)
 {
-       /* this happens as the second step of a DnD within the treeview as well
-          as when a row/route is actually deleted.
+       /* this happens as the second step of a DnD within the treeview, and
+          when a route is actually removed. we don't differentiate between
+          the two cases.
+          
+          note that the sync_orders_keys() step may not actually change any
+          RID's (e.g. the last track may be removed, so all other tracks keep
+          the same RID), which means that no redisplay would happen. so we 
+           have to force a redisplay.
        */
+
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n");
+
+       DisplaySuspender ds;
        sync_order_keys_from_treeview ();
 }
 
 void
 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
 {
+       /* reordering implies that RID's will change, so sync_order_keys() will
+          cause a redisplay.
+       */
+
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n");
        sync_order_keys_from_treeview ();
 }
@@ -569,6 +584,7 @@ EditorRoutes::visible_changed (std::string const & path)
                return;
        }
 
+       DisplaySuspender ds;
        TreeIter iter;
 
        if ((iter = _model->get_iter (path))) {
@@ -617,7 +633,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
                _editor->selection->tracks.clear();
        } 
 
-       suspend_redisplay ();
+       DisplaySuspender ds;
 
        _display.set_model (Glib::RefPtr<ListStore>());
 
@@ -686,7 +702,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
        update_input_active_display ();
        update_active_display ();
 
-       resume_redisplay ();
        _display.set_model (_model);
 
        /* now update route order keys from the treeview/track display order */
@@ -720,10 +735,13 @@ EditorRoutes::route_removed (TimeAxisView *tv)
 
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator ri;
+       bool found = false;
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
                if ((*ri)[_columns.tv] == tv) {
+                        PBD::Unwinder<bool> uw (_route_deletion_in_progress, true);
                        _model->erase (ri);
+                       found = true;
                        break;
                }
        }
@@ -778,7 +796,7 @@ EditorRoutes::update_visibility ()
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator i;
 
-       suspend_redisplay ();
+       DisplaySuspender ds ();
 
        for (i = rows.begin(); i != rows.end(); ++i) {
                TimeAxisView *tv = (*i)[_columns.tv];
@@ -789,8 +807,6 @@ EditorRoutes::update_visibility ()
         */
 
        sync_order_keys_from_treeview ();
-
-       resume_redisplay ();
 }
 
 void
@@ -1008,7 +1024,7 @@ EditorRoutes::hide_all_tracks (bool /*with_select*/)
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator i;
 
-       suspend_redisplay ();
+       DisplaySuspender ds;
 
        for (i = rows.begin(); i != rows.end(); ++i) {
 
@@ -1021,8 +1037,6 @@ EditorRoutes::hide_all_tracks (bool /*with_select*/)
 
                row[_columns.visible] = false;
        }
-
-       resume_redisplay ();
 }
 
 void
@@ -1031,7 +1045,7 @@ EditorRoutes::set_all_tracks_visibility (bool yn)
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator i;
 
-       suspend_redisplay ();
+       DisplaySuspender ds;
 
        for (i = rows.begin(); i != rows.end(); ++i) {
 
@@ -1050,8 +1064,6 @@ EditorRoutes::set_all_tracks_visibility (bool yn)
         */
 
        sync_order_keys_from_treeview ();
-
-       resume_redisplay ();
 }
 
 void
@@ -1060,7 +1072,7 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn)
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator i;
 
-       suspend_redisplay ();
+       DisplaySuspender ds;
 
        for (i = rows.begin(); i != rows.end(); ++i) {
 
@@ -1112,8 +1124,6 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn)
         */
 
        sync_order_keys_from_treeview ();
-
-       resume_redisplay ();
 }
 
 void
@@ -1288,27 +1298,46 @@ EditorRoutes::button_press (GdkEventButton* ev)
        //Scroll editor canvas to selected track
        if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
 
-               // Get the model row.
                Gtk::TreeModel::Row row = *_model->get_iter (path);
-
                TimeAxisView *tv = row[_columns.tv];
 
-               int y_pos = tv->y_position();
-
-               //Clamp the y pos so that we do not extend beyond the canvas full height.
-               if (_editor->_full_canvas_height - y_pos < _editor->_visible_canvas_height){
-                   y_pos = _editor->_full_canvas_height - _editor->_visible_canvas_height;
-               }
-
-               //Only scroll to if the track is visible
-               if(y_pos != -1){
-                   _editor->reset_y_origin (y_pos);
+               if (tv) {
+                       _editor->ensure_time_axis_view_is_visible (*tv, true);
                }
        }
 
        return false;
 }
 
+void
+EditorRoutes::selection_changed ()
+{
+       if (_display.get_selection()->count_selected_rows() > 0) {
+
+               TreeIter iter;
+               TreeView::Selection::ListHandle_Path rows = _display.get_selection()->get_selected_rows ();
+               TrackViewList selected;
+
+               _editor->get_selection().clear_regions ();
+
+               for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin(); i != rows.end(); ++i) {
+
+                       if ((iter = _model->get_iter (*i))) {
+
+                               TimeAxisView* tv = (*iter)[_columns.tv];
+                               selected.push_back (tv);
+                       }
+                       
+               }
+
+               _editor->get_selection().set (selected);
+               _editor->ensure_time_axis_view_is_visible (*(selected.front()), true);
+
+       } else {
+               _editor->get_selection().clear_tracks ();
+       }
+}
+
 bool
 EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path const&, bool /*selected*/)
 {
@@ -1339,11 +1368,10 @@ struct EditorOrderRouteSorter {
 void
 EditorRoutes::initial_display ()
 {
-       suspend_redisplay ();
+       DisplaySuspender ds;
        _model->clear ();
 
        if (!_session) {
-               resume_redisplay ();
                return;
        }
 
@@ -1370,8 +1398,6 @@ EditorRoutes::initial_display ()
                _editor->add_routes (r);
                
        }
-
-       resume_redisplay ();
 }
 
 void
@@ -1680,14 +1706,11 @@ EditorRoutes::show_tracks_with_regions_at_playhead ()
                }
        }
 
-       suspend_redisplay ();
+       DisplaySuspender ds;
 
        TreeModel::Children rows = _model->children ();
        for (TreeModel::Children::iterator i = rows.begin(); i != rows.end(); ++i) {
                TimeAxisView* tv = (*i)[_columns.tv];
                (*i)[_columns.visible] = (show.find (tv) != show.end());
        }
-
-       resume_redisplay ();
 }
-