diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc index f453caf831..acbbb697f2 100644 --- a/gtk2_ardour/editor_routes.cc +++ b/gtk2_ardour/editor_routes.cc @@ -45,6 +45,7 @@ #include "gui_thread.h" #include "actions.h" #include "utils.h" +#include "route_sorter.h" #include "editor_group_tabs.h" #include "editor_routes.h" @@ -961,21 +962,30 @@ EditorRoutes::sync_treeview_from_order_keys (RouteSortOrderKey src) return; } - neworder.assign (rows.size(), 0); + OrderKeySortedRoutes sorted_routes; for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { boost::shared_ptr route = (*ri)[_columns.route]; - uint32_t new_order = route->order_key (EditorSort); - - DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("EDITOR change order for %1 from %2 to %3\n", - route->name(), old_order, new_order)); - - neworder[new_order] = old_order; + sorted_routes.push_back (RoutePlusOrderKey (route, old_order, route->order_key (EditorSort))); + } - if (old_order != new_order) { + SortByNewDisplayOrder cmp; + + sort (sorted_routes.begin(), sorted_routes.end(), cmp); + neworder.assign (sorted_routes.size(), 0); + + uint32_t n = 0; + + for (OrderKeySortedRoutes::iterator sr = sorted_routes.begin(); sr != sorted_routes.end(); ++sr, ++n) { + + neworder[n] = sr->old_display_order; + + if (sr->old_display_order != n) { changed = true; } + DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("EDITOR change order for %1 from %2 to %3\n", + sr->route->name(), sr->old_display_order, n)); } if (changed) { diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc index a141999277..468cdf2244 100644 --- a/gtk2_ardour/mixer_ui.cc +++ b/gtk2_ardour/mixer_ui.cc @@ -51,6 +51,7 @@ #include "ardour_ui.h" #include "prompter.h" #include "utils.h" +#include "route_sorter.h" #include "actions.h" #include "gui_thread.h" #include "mixer_group_tabs.h" @@ -543,20 +544,30 @@ Mixer_UI::sync_treeview_from_order_keys (RouteSortOrderKey src) return; } - neworder.assign (rows.size(), 0); - + OrderKeySortedRoutes sorted_routes; + for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) { boost::shared_ptr route = (*ri)[track_columns.route]; - uint32_t new_order = route->order_key (MixerSort); + sorted_routes.push_back (RoutePlusOrderKey (route, old_order, route->order_key (MixerSort))); + } - neworder[new_order] = old_order; + SortByNewDisplayOrder cmp; - if (old_order != new_order) { + sort (sorted_routes.begin(), sorted_routes.end(), cmp); + neworder.assign (sorted_routes.size(), 0); + + uint32_t n = 0; + + for (OrderKeySortedRoutes::iterator sr = sorted_routes.begin(); sr != sorted_routes.end(); ++sr, ++n) { + + neworder[n] = sr->old_display_order; + + if (sr->old_display_order != n) { changed = true; } DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("MIXER change order for %1 from %2 to %3\n", - route->name(), old_order, new_order)); + sr->route->name(), sr->old_display_order, n)); } if (changed) { diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h index 90af35822b..624181356e 100644 --- a/gtk2_ardour/mixer_ui.h +++ b/gtk2_ardour/mixer_ui.h @@ -249,6 +249,8 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR void sync_order_keys_from_treeview (); void sync_treeview_from_order_keys (ARDOUR::RouteSortOrderKey); void reset_remote_control_ids (); + void reset_order_keys (ARDOUR::RouteSortOrderKey); + bool ignore_reorder; void parameter_changed (std::string const &); diff --git a/gtk2_ardour/route_sorter.h b/gtk2_ardour/route_sorter.h new file mode 100644 index 0000000000..768eac66f3 --- /dev/null +++ b/gtk2_ardour/route_sorter.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2012 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __gtk2_ardour_route_sorter_h__ +#define __gtk2_ardour_route_sorter_h__ + +#include +#include +#include + +namespace ARDOUR { + class Route; +} + +struct RoutePlusOrderKey { + boost::shared_ptr route; /* we don't really need this, but its handy to keep around */ + uint32_t old_display_order; + uint32_t new_display_order; + + RoutePlusOrderKey (boost::shared_ptr r, uint32_t ok, uint32_t nk) + : route (r) + , old_display_order (ok) + , new_display_order (nk) {} +}; + +typedef std::vector OrderKeySortedRoutes; + +struct SortByNewDisplayOrder { + bool operator() (const RoutePlusOrderKey& a, const RoutePlusOrderKey& b) { + return a.new_display_order < b.new_display_order; + } +}; + +#endif /* __gtk2_ardour_route_sorter_h__ */