+ ignore_route_list_reorder = false;
+}
+
+void
+Editor::route_list_display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
+ int x, int y,
+ const SelectionData& data,
+ guint info, guint time)
+{
+ if (data.get_target() == "GTK_TREE_MODEL_ROW") {
+ route_list_display.on_drag_data_received (context, x, y, data, info, time);
+ return;
+ }
+ context->drag_finish (true, false, time);
+}
+
+RouteTimeAxisView*
+Editor::get_route_view_by_id (PBD::ID& id)
+{
+ RouteTimeAxisView* v;
+
+ for(TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ if((v = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
+ if(v->route()->id() == id) {
+ return v;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void
+Editor::foreach_time_axis_view (sigc::slot<void,TimeAxisView&> theslot)
+{
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ theslot (**i);
+ }
+}
+
+void
+Editor::move_selected_tracks (bool up)
+{
+ if (selection->tracks.empty()) {
+ return;
+ }
+
+ typedef std::pair<TimeAxisView*,boost::shared_ptr<Route> > ViewRoute;
+ std::list<ViewRoute> view_routes;
+ std::vector<int> neworder;
+ TreeModel::Children rows = route_display_model->children();
+ TreeModel::Children::iterator ri;
+
+ for (ri = rows.begin(); ri != rows.end(); ++ri) {
+ TimeAxisView* tv = (*ri)[route_display_columns.tv];
+ boost::shared_ptr<Route> route = (*ri)[route_display_columns.route];
+
+ view_routes.push_back (ViewRoute (tv, route));
+ }
+
+ list<ViewRoute>::iterator trailing;
+ list<ViewRoute>::iterator leading;
+
+ if (up) {
+
+ trailing = view_routes.begin();
+ leading = view_routes.begin();
+
+ ++leading;
+
+ while (leading != view_routes.end()) {
+ if (selection->selected (leading->first)) {
+ view_routes.insert (trailing, ViewRoute (leading->first, leading->second));
+ leading = view_routes.erase (leading);
+ } else {
+ ++leading;
+ ++trailing;
+ }
+ }
+
+ } else {
+
+ /* 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.
+ */
+
+ trailing = view_routes.end();
+ leading = view_routes.end();
+
+ --leading; if (leading == view_routes.begin()) { return; }
+ --leading;
+ --trailing;
+
+ while (1) {
+
+ if (selection->selected (leading->first)) {
+ list<ViewRoute>::iterator tmp;
+
+ /* need to insert *after* trailing, not *before* it,
+ which is what insert (iter, val) normally does.
+ */
+
+ tmp = trailing;
+ tmp++;
+
+ view_routes.insert (tmp, ViewRoute (leading->first, leading->second));
+
+ /* can't use iter = cont.erase (iter); form here, because
+ we need iter to move backwards.
+ */
+
+ tmp = leading;
+ --tmp;
+
+ bool done = false;
+
+ if (leading == view_routes.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;
+ }
+
+ view_routes.erase (leading);
+
+ if (done) {
+ break;
+ }
+
+ leading = tmp;
+
+ } else {
+ if (leading == view_routes.begin()) {
+ break;
+ }
+ --leading;
+ --trailing;
+ }
+ };
+ }
+
+ for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
+ neworder.push_back (leading->second->order_key (_order_key));
+ }
+
+ route_display_model->reorder (neworder);
+
+ session->sync_order_keys (_order_key);