X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_routes.cc;h=b1618bde49b12892daad4d100434d04bfc7f3c4b;hb=5db22a33c1ec13a14dd6654bf08b0ecd377ae67d;hp=cec0969863107a9ed36c3e8c481500a1e2a78f9e;hpb=353eb5601c764c28f433e3f7b29fb2ab4b478765;p=ardour.git diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index cec0969863..b1618bde49 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -1167,8 +1167,10 @@ EditorRoutes::sync_treeview_from_presentation_info (PropertyChange const & what_ * 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) + * (re-order drag -> remove row -> sync PI from TV -> notify -> sync TV from PI -> crash) */ + Unwinder uw2 (_ignore_selection_change, true); + _display.unset_model(); _model->reorder (neworder); _display.set_model (_model); @@ -1195,7 +1197,6 @@ EditorRoutes::sync_treeview_from_presentation_info (PropertyChange const & what_ } /* step two: set the Selection (for stripables/routes) */ - _editor->get_selection().set (tvl); } @@ -1581,13 +1582,15 @@ struct PresentationInfoVCASorter void EditorRoutes::initial_display () { - DisplaySuspender ds; - _model->clear (); if (!_session) { + _model->clear (); return; } + DisplaySuspender ds; + _model->clear (); + StripableList s; RouteList r (*_session->get_routes()); @@ -1622,146 +1625,116 @@ EditorRoutes::display_drag_data_received (const RefPtr& contex struct ViewStripable { TimeAxisView* tav; boost::shared_ptr stripable; - uint32_t old_order; - ViewStripable (TimeAxisView* t, boost::shared_ptr s, uint32_t n) - : tav (t), stripable (s), old_order (n) {} + ViewStripable (TimeAxisView* t, boost::shared_ptr s) + : tav (t), stripable (s) {} }; void EditorRoutes::move_selected_tracks (bool up) { - if (_editor->selection->tracks.empty()) { + TimeAxisView* scroll_to = 0; + StripableList sl; + _session->get_stripables (sl); + + if (sl.size() < 2) { + /* nope */ return; } + sl.sort (Stripable::PresentationOrderSorter()); + std::list view_stripables; - std::vector neworder; - TreeModel::Children rows = _model->children(); - TreeModel::Children::iterator ri; - TreeModel::Children::size_type n; - for (n = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++n) { - TimeAxisView* tv = (*ri)[_columns.tv]; - boost::shared_ptr stripable = (*ri)[_columns.stripable]; - view_stripables.push_back (ViewStripable (tv, stripable, n)); + /* build a list that includes time axis view information */ + + for (StripableList::const_iterator sli = sl.begin(); sli != sl.end(); ++sli) { + TimeAxisView* tv = _editor->axis_view_from_stripable (*sli); + view_stripables.push_back (ViewStripable (tv, *sli)); } - list::iterator trailing; - list::iterator leading; + /* for each selected stripable, move it above or below the adjacent + * stripable that has a time-axis view representation here. If there's + * no such representation, then + */ - TimeAxisView* scroll_to = NULL; + list::iterator unselected_neighbour; + list::iterator vsi; - if (up) { + { + PresentationInfo::ChangeSuspender cs; - trailing = view_stripables.begin(); - leading = view_stripables.begin(); + if (up) { + unselected_neighbour = view_stripables.end (); + vsi = view_stripables.begin(); - ++leading; + while (vsi != view_stripables.end()) { - while (leading != view_stripables.end()) { - if (_editor->selection->selected (leading->tav)) { - view_stripables.insert (trailing, ViewStripable (*leading)); - if (!scroll_to) { - scroll_to = leading->tav; - } - leading = view_stripables.erase (leading); - } else { - ++leading; - ++trailing; - } - } + if (vsi->stripable->presentation_info().selected()) { - } else { + if (unselected_neighbour != view_stripables.end()) { - /* if we could use reverse_iterator in list::insert, this code - would be a beautiful reflection of the code above. but we can't - and so it looks like a bit of a mess. - */ + PresentationInfo::order_t unselected_neighbour_order = unselected_neighbour->stripable->presentation_info().order(); + PresentationInfo::order_t my_order = vsi->stripable->presentation_info().order(); - trailing = view_stripables.end(); - leading = view_stripables.end(); + unselected_neighbour->stripable->set_presentation_order (my_order); + vsi->stripable->set_presentation_order (unselected_neighbour_order); - --leading; if (leading == view_stripables.begin()) { return; } - --leading; - --trailing; + if (!scroll_to) { + scroll_to = vsi->tav; + } + } - while (1) { + } else { + + if (vsi->tav) { + unselected_neighbour = vsi; + } - if (_editor->selection->selected (leading->tav)) { - if (!scroll_to) { - scroll_to = leading->tav; } - list::iterator tmp; - /* need to insert *after* trailing, not *before* it, - which is what insert (iter, val) normally does. - */ + ++vsi; + } - tmp = trailing; - tmp++; + } else { - view_stripables.insert (tmp, ViewStripable (*leading)); + unselected_neighbour = view_stripables.end(); + vsi = unselected_neighbour; - /* can't use iter = cont.erase (iter); form here, because - we need iter to move backwards. - */ + do { - tmp = leading; - --tmp; + --vsi; - bool done = false; + if (vsi->stripable->presentation_info().selected()) { - if (leading == view_stripables.begin()) { - /* the one we've just inserted somewhere else - was the first in the list. erase this copy, - and then break, because we're done. - */ - done = true; - } + if (unselected_neighbour != view_stripables.end()) { - view_stripables.erase (leading); + PresentationInfo::order_t unselected_neighbour_order = unselected_neighbour->stripable->presentation_info().order(); + PresentationInfo::order_t my_order = vsi->stripable->presentation_info().order(); - if (done) { - break; - } + unselected_neighbour->stripable->set_presentation_order (my_order); + vsi->stripable->set_presentation_order (unselected_neighbour_order); - leading = tmp; + if (!scroll_to) { + scroll_to = vsi->tav; + } + } + + } else { + + if (vsi->tav) { + unselected_neighbour = vsi; + } - } else { - if (leading == view_stripables.begin()) { - break; } - --leading; - --trailing; - } - }; - } - for (leading = view_stripables.begin(); leading != view_stripables.end(); ++leading) { - neworder.push_back (leading->old_order); -#ifndef NDEBUG - if (leading->old_order != neworder.size() - 1) { - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("move %1 to %2\n", leading->old_order, neworder.size() - 1)); + } while (vsi != view_stripables.begin()); } -#endif } -#ifndef NDEBUG - DEBUG_TRACE (DEBUG::OrderKeys, "New order after moving tracks:\n"); - for (vector::iterator i = neworder.begin(); i != neworder.end(); ++i) { - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("\t%1\n", *i)); - } - DEBUG_TRACE (DEBUG::OrderKeys, "-------\n"); -#endif - - - _model->reorder (neworder); - if (scroll_to) { _editor->ensure_time_axis_view_is_visible (*scroll_to, false); } - } void