From: Robin Gareus Date: Fri, 6 Jan 2017 17:40:21 +0000 (+0100) Subject: fix route ordering (and related possible crash on re-order) X-Git-Tag: 5.6~338 X-Git-Url: https://main.carlh.net/gitweb/?p=ardour.git;a=commitdiff_plain;h=94a57e64f655c238aebd2780ea6c8b6727c48177 fix route ordering (and related possible crash on re-order) --- diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index d0ff0dfbfe..5c32330139 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -1016,6 +1016,9 @@ EditorRoutes::sync_presentation_info_from_treeview () bool master_is_first = false; uint32_t count = 0; + OrderingKeys sorted; + const size_t cmp_max = rows.size (); + // special case master if it's got PI order 0 lets keep it there if (_session->master_out() && (_session->master_out()->presentation_info().order() == 0)) { order++; @@ -1060,10 +1063,24 @@ EditorRoutes::sync_presentation_info_from_treeview () change = true; } + sorted.push_back (OrderKeys (order, stripable, cmp_max)); + ++order; ++count; } + if (!change) { + // VCA (and Mixbus) special cases according to SortByNewDisplayOrder + uint32_t n = 0; + SortByNewDisplayOrder cmp; + sort (sorted.begin(), sorted.end(), cmp); + for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { + if (sr->old_display_order != n) { + change = true; + } + } + } + if (change) { DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from editor GUI\n"); _session->notify_presentation_info_change (); @@ -1120,7 +1137,17 @@ EditorRoutes::sync_treeview_from_presentation_info () if (changed) { Unwinder uw (_ignore_reorder, true); + /* prevent traverse_cells: assertion 'row_path != NULL' + * in case of DnD re-order: row-removed + row-inserted. + * + * The rows (stripables) are not actually removed from the model, + * but only from the display in the DnDTreeView. + * ->reorder() will fail to find the row_path. + * (re-order drag -> remove row -> rync PI from TV -> notify -> sync TV from PI -> crash) + */ + _display.unset_model(); _model->reorder (neworder); + _display.set_model (_model); } redisplay (); @@ -1514,6 +1541,7 @@ EditorRoutes::initial_display () } _editor->add_stripables (s); + sync_treeview_from_presentation_info (); } void diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index ce6ed294a3..49862c36a5 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -706,6 +706,9 @@ Mixer_UI::sync_presentation_info_from_treeview () bool change = false; uint32_t order = 0; + OrderingKeys sorted; + const size_t cmp_max = rows.size (); + // special case master if it's got PI order 0 lets keep it there if (_session->master_out() && (_session->master_out()->presentation_info().order() == 0)) { order++; @@ -743,9 +746,23 @@ Mixer_UI::sync_presentation_info_from_treeview () change = true; } + sorted.push_back (OrderKeys (order, stripable, cmp_max)); + ++order; } + if (!change) { + // VCA (and Mixbus) special cases according to SortByNewDisplayOrder + uint32_t n = 0; + SortByNewDisplayOrder cmp; + sort (sorted.begin(), sorted.end(), cmp); + for (OrderingKeys::iterator sr = sorted.begin(); sr != sorted.end(); ++sr, ++n) { + if (sr->old_display_order != n) { + change = true; + } + } + } + if (change) { DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from mixer GUI\n"); _session->notify_presentation_info_change (); @@ -1487,6 +1504,7 @@ Mixer_UI::initial_track_display () } redisplay_track_list (); + sync_treeview_from_presentation_info (); } void