fix route ordering (and related possible crash on re-order)
authorRobin Gareus <robin@gareus.org>
Fri, 6 Jan 2017 17:40:21 +0000 (18:40 +0100)
committerRobin Gareus <robin@gareus.org>
Fri, 6 Jan 2017 17:41:51 +0000 (18:41 +0100)
gtk2_ardour/editor_routes.cc
gtk2_ardour/mixer_ui.cc

index d0ff0dfbfed3e0ab8d45b1056b5ab0f5a63398eb..5c32330139d56fe05f87664bb25177e29e50d3cf 100644 (file)
@@ -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<bool> 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
index ce6ed294a381fbe6652d1b97c3b59b91503b0392..49862c36a505564c1c308db8a582a419ed6c86ff 100644 (file)
@@ -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