diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index 1323388b25..c42dc67aa4 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -70,13 +70,14 @@ struct ColumnInfo { EditorRoutes::EditorRoutes (Editor* e) : EditorComponent (e) - , _ignore_reorder (false) - , _no_redisplay (false) - , _adding_routes (false) - , _menu (0) - , old_focus (0) - , selection_countdown (0) - , name_editable (0) + , _ignore_reorder (false) + , _no_redisplay (false) + , _adding_routes (false) + , _route_deletion_in_progress (false) + , _menu (0) + , old_focus (0) + , selection_countdown (0) + , name_editable (0) { static const int column_width = 22; @@ -274,7 +275,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); @@ -563,18 +564,38 @@ 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"); + + if (_route_deletion_in_progress) { + suspend_redisplay (); + } + sync_order_keys_from_treeview (); + + if (_route_deletion_in_progress) { + resume_redisplay (); + } } 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 (); } @@ -737,10 +758,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 uw (_route_deletion_in_progress, true); _model->erase (ri); + found = true; break; } } diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h index 54560137d3..7b994ae8b1 100644 --- a/gtk2_ardour/editor_routes.h +++ b/gtk2_ardour/editor_routes.h @@ -73,7 +73,7 @@ private: void build_menu (); void show_menu (); void sync_treeview_from_order_keys (); - void route_deleted (Gtk::TreeModel::Path const &); + void row_deleted (Gtk::TreeModel::Path const &); void visible_changed (std::string const &); void active_changed (std::string const &); void reordered (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int *); @@ -161,7 +161,8 @@ private: bool _ignore_reorder; bool _no_redisplay; - bool _adding_routes; + bool _adding_routes; + bool _route_deletion_in_progress; Gtk::Menu* _menu; Gtk::Widget* old_focus; diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index 5bdebff3c8..97494a1e6c 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -93,6 +93,9 @@ Mixer_UI::Mixer_UI () , _strip_width (Config->get_default_narrow_ms() ? Narrow : Wide) , ignore_reorder (false) , _following_editor_selection (false) + , _in_group_rebuild_or_clear (false) + , _route_deletion_in_progress (false) + , _maximised (false) { /* allow this window to become the key focus window */ set_flags (CAN_FOCUS); @@ -240,9 +243,6 @@ Mixer_UI::Mixer_UI () list_hpane.show(); group_display.show(); - _in_group_rebuild_or_clear = false; - _maximised = false; - MixerStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::remove_strip, this, _1), gui_context()); MonitorSection::setup_knob_images (); @@ -421,6 +421,7 @@ Mixer_UI::remove_strip (MixerStrip* strip) for (ri = rows.begin(); ri != rows.end(); ++ri) { if ((*ri)[track_columns.strip] == strip) { + PBD::Unwinder uw (_route_deletion_in_progress, true); track_model->erase (ri); break; } @@ -1000,9 +1001,17 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&) { /* this happens as the second step of a DnD within the treeview as well as when a row/route is actually deleted. + + if it was a deletion then we have to force a redisplay because + order keys may not have changed. */ + DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n"); sync_order_keys_from_treeview (); + + if (_route_deletion_in_progress) { + redisplay_track_list (); + } } void diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 5af36c39e2..f49088b0aa 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -272,6 +272,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR it during a session teardown. */ bool _in_group_rebuild_or_clear; + bool _route_deletion_in_progress; void update_title (); MixerStrip* strip_by_x (int x);