summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/SAE-de.bindings.in2
-rw-r--r--gtk2_ardour/ardour-sae.menus2
-rw-r--r--gtk2_ardour/ardour.menus2
-rw-r--r--gtk2_ardour/editor.cc4
-rw-r--r--gtk2_ardour/editor.h9
-rw-r--r--gtk2_ardour/editor_actions.cc5
-rw-r--r--gtk2_ardour/editor_mixer.cc1
-rw-r--r--gtk2_ardour/editor_mouse.cc2
-rw-r--r--gtk2_ardour/editor_route_list.cc301
-rw-r--r--gtk2_ardour/mixer_ui.cc80
-rw-r--r--gtk2_ardour/mixer_ui.h5
-rw-r--r--gtk2_ardour/mnemonic-us.bindings.in2
-rw-r--r--gtk2_ardour/route_time_axis.cc41
-rw-r--r--gtk2_ardour/route_ui.cc2
-rw-r--r--libs/ardour/ardour/route.h4
-rw-r--r--libs/ardour/ardour/session.h4
-rw-r--r--libs/ardour/audioengine.cc1
-rw-r--r--libs/ardour/jack_slave.cc1
-rw-r--r--libs/ardour/route.cc32
-rw-r--r--libs/ardour/session.cc8
-rw-r--r--libs/ardour/session_state.cc5
21 files changed, 394 insertions, 119 deletions
diff --git a/gtk2_ardour/SAE-de.bindings.in b/gtk2_ardour/SAE-de.bindings.in
index b03738b7d4..fa4f3bcc37 100644
--- a/gtk2_ardour/SAE-de.bindings.in
+++ b/gtk2_ardour/SAE-de.bindings.in
@@ -140,8 +140,10 @@
(gtk_accel_path "<Actions>/Editor/select-prev-route" "uparrow")
(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow")
+(gtk_accel_path "<Actions>/Editor/move-selected-tracks-up" "<%TERTIARY%>uparrow")
(gtk_accel_path "<Actions>/Editor/select-next-route" "downarrow")
(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow")
+(gtk_accel_path "<Actions>/Editor/move-selected-tracks-down" "<%TERTIARY%>downarrow")
;; keypad
diff --git a/gtk2_ardour/ardour-sae.menus b/gtk2_ardour/ardour-sae.menus
index dd57e2aa36..021d8c3b0e 100644
--- a/gtk2_ardour/ardour-sae.menus
+++ b/gtk2_ardour/ardour-sae.menus
@@ -177,6 +177,8 @@
<menu action='TrackMenu'>
<menuitem action='AddTrackBus'/>
+ <menuitem action="move-selected-tracks-up"/>
+ <menuitem action="move-selected-tracks-down"/>
<menu action='TrackHeightMenu'>
<menuitem action='track-height-largest'/>
<menuitem action='track-height-large'/>
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index 9d4f57465b..e1209296d6 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -241,6 +241,8 @@
<menu action='TrackMenu'>
<menuitem action='AddTrackBus'/>
<menuitem action='insert-time'/>
+ <menuitem action="move-selected-tracks-up"/>
+ <menuitem action="move-selected-tracks-down"/>
<menu action='TrackHeightMenu'>
<menuitem action='fit-tracks'/>
<menuitem action='track-height-largest'/>
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index c27c5cf272..6cc35252d5 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -298,7 +298,8 @@ Editor::Editor ()
_show_waveforms_recording = true;
first_action_message = 0;
show_gain_after_trim = false;
- ignore_route_list_reorder = false;
+ route_redisplay_does_not_sync_order_keys = false;
+ route_redisplay_does_not_reset_order_keys = false;
no_route_list_redisplay = false;
verbose_cursor_on = true;
route_removal = false;
@@ -358,7 +359,6 @@ Editor::Editor ()
scrubbing_direction = 0;
sfbrowser = 0;
- ignore_route_order_sync = false;
location_marker_color = ARDOUR_UI::config()->canvasvar_LocationMarker.get();
location_range_color = ARDOUR_UI::config()->canvasvar_LocationRange.get();
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 394c1ad121..0fb988bafd 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -370,6 +370,8 @@ class Editor : public PublicEditor
void scroll_tracks_down_line ();
void scroll_tracks_up_line ();
+ void move_selected_tracks (bool up);
+
bool new_regionviews_display_gain () { return _new_regionviews_show_envelope; }
void prepare_for_cleanup ();
void finish_cleanup ();
@@ -548,7 +550,7 @@ class Editor : public PublicEditor
void set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false);
void select_all_tracks ();
-
+
int get_regionview_count_from_region_list (boost::shared_ptr<ARDOUR::Region> region);
bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false);
@@ -1844,8 +1846,9 @@ public:
void update_route_visibility ();
- void sync_order_keys ();
- bool ignore_route_order_sync;
+ void sync_order_keys (const char*);
+ bool route_redisplay_does_not_sync_order_keys;
+ bool route_redisplay_does_not_reset_order_keys;
bool route_list_display_button_press (GdkEventButton*);
void route_list_display_drag_data_received (const Glib::RefPtr<Gdk::DragContext>& context,
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 0f78b60f74..a8f3bf3028 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -316,6 +316,11 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "toggle-zoom", _("Toggle Zoom State"), mem_fun(*this, &Editor::swap_visual_state));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "move-selected-tracks-up", _("Move Selected Tracks Up"), bind (mem_fun(*this, &Editor::move_selected_tracks), true));
+ ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "move-selected-tracks-down", _("Move Selected Tracks Down"), bind (mem_fun(*this, &Editor::move_selected_tracks), false));
+ ActionManager::session_sensitive_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "scroll-tracks-up", _("Scroll Tracks Up"), mem_fun(*this, &Editor::scroll_tracks_up));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "scroll-tracks-down", _("Scroll Tracks Down"), mem_fun(*this, &Editor::scroll_tracks_down));
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index cb10b2f551..e6b30232cd 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -227,7 +227,6 @@ Editor::set_selected_mixer_strip (TimeAxisView& view)
}
}
-
double current = 0.0;
bool currentInitialized = 0;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 652ab49343..1a03f66f24 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -4002,7 +4002,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
}
if (changed_position && !drag_info.x_constrained) {
-- where = rv->region()->position() - drag_delta;
+ where = rv->region()->position() - drag_delta;
} else {
where = rv->region()->position();
}
diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc
index 4bc1059354..db3c4918c2 100644
--- a/gtk2_ardour/editor_route_list.cc
+++ b/gtk2_ardour/editor_route_list.cc
@@ -17,6 +17,8 @@
*/
+#include <list>
+#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
@@ -43,6 +45,7 @@ using namespace PBD;
using namespace Gtk;
using namespace Glib;
+const char* _order_key = N_("editor");
void
Editor::handle_new_route (Session::RouteList& routes)
@@ -54,8 +57,7 @@ Editor::handle_new_route (Session::RouteList& routes)
TreeModel::Row parent;
TreeModel::Row row;
- ignore_route_list_reorder = true;
- ignore_route_order_sync = true;
+ route_redisplay_does_not_sync_order_keys = true;
no_route_list_redisplay = true;
for (Session::RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
@@ -116,22 +118,19 @@ Editor::handle_new_route (Session::RouteList& routes)
if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv)) != 0) {
/* added a new fresh one at the end */
- if (rtv->route()->order_key(N_("editor")) == -1) {
- rtv->route()->set_order_key (N_("editor"), route_display_model->children().size()-1);
+ if (rtv->route()->order_key(_order_key) == -1) {
+ rtv->route()->set_order_key (_order_key, route_display_model->children().size()-1);
}
rtv->effective_gain_display ();
}
ignore_route_list_reorder = false;
- tv->set_old_order_key (route_display_model->children().size() - 1);
route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv));
}
- ignore_route_list_reorder = false;
- ignore_route_order_sync = false;
no_route_list_redisplay = false;
redisplay_route_list ();
@@ -139,7 +138,9 @@ Editor::handle_new_route (Session::RouteList& routes)
if (show_editor_mixer_when_tracks_arrive) {
show_editor_mixer (true);
}
+
editor_list_button.set_sensitive(true);
+ route_redisplay_does_not_sync_order_keys = false;
}
void
@@ -173,13 +174,11 @@ Editor::remove_route (TimeAxisView *tv)
entered_track = 0;
}
- /* Decrement old order keys for tracks `above' the one that is being removed */
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
- TimeAxisView* v = (*ri)[route_display_columns.tv];
- if (v->old_order_key() > tv->old_order_key()) {
- v->set_old_order_key (v->old_order_key() - 1);
- }
- }
+ /* the core model has changed, there is no need to sync
+ view orders.
+ */
+
+ route_redisplay_does_not_sync_order_keys = true;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
if ((*ri)[route_display_columns.tv] == tv) {
@@ -188,6 +187,8 @@ Editor::remove_route (TimeAxisView *tv)
}
}
+ route_redisplay_does_not_sync_order_keys = false;
+
if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) {
track_views.erase (i);
}
@@ -276,13 +277,13 @@ Editor::route_list_reordered (const TreeModel::Path& path,const TreeModel::itera
void
-Editor::sync_order_keys ()
+Editor::sync_order_keys (const char *src)
{
vector<int> neworder;
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator ri;
- if (ignore_route_order_sync || !session || (session->state_of_the_state() & Session::Loading) || rows.empty()) {
+ if ((strcmp (src, _order_key) == 0) || !session || (session->state_of_the_state() & Session::Loading) || rows.empty()) {
return;
}
@@ -290,15 +291,27 @@ Editor::sync_order_keys ()
neworder.push_back (0);
}
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
- TimeAxisView* tv = (*ri)[route_display_columns.tv];
+ bool changed = false;
+ int order;
+
+ for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
boost::shared_ptr<Route> route = (*ri)[route_display_columns.route];
- neworder[route->order_key (X_("editor"))] = tv->old_order_key ();
+
+ int old_key = order;
+ int new_key = route->order_key (_order_key);
+
+ neworder[new_key] = old_key;
+
+ if (new_key != old_key) {
+ changed = true;
+ }
}
- ignore_route_list_reorder = true;
- route_display_model->reorder (neworder);
- ignore_route_list_reorder = false;
+ if (changed) {
+ route_redisplay_does_not_reset_order_keys = true;
+ route_display_model->reorder (neworder);
+ route_redisplay_does_not_reset_order_keys = false;
+ }
}
void
@@ -316,23 +329,20 @@ Editor::redisplay_route_list ()
for (n = 0, order = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
TimeAxisView *tv = (*i)[route_display_columns.tv];
- RouteTimeAxisView* rt;
+ boost::shared_ptr<Route> route = (*i)[route_display_columns.route];
if (tv == 0) {
// just a "title" row
continue;
}
- if (!ignore_route_list_reorder) {
+ if (!route_redisplay_does_not_reset_order_keys) {
/* this reorder is caused by user action, so reassign sort order keys
to tracks.
*/
- if ((rt = dynamic_cast<RouteTimeAxisView*> (tv)) != 0) {
- rt->route()->set_order_key (N_("editor"), order);
- ++order;
- }
+ route->set_order_key (_order_key, order);
}
bool visible = (*i)[route_display_columns.visible];
@@ -360,12 +370,9 @@ Editor::redisplay_route_list ()
vertical_adjustment.set_value (full_canvas_height - canvas_height);
}
- if (Config->get_sync_all_route_ordering() && !ignore_route_list_reorder) {
- ignore_route_order_sync = true;
- Route::SyncOrderKeys (); // EMIT SIGNAL
- ignore_route_order_sync = false;
+ if (!route_redisplay_does_not_reset_order_keys && !route_redisplay_does_not_sync_order_keys) {
+ session->sync_order_keys (_order_key);
}
-
}
void
@@ -577,7 +584,7 @@ Editor::route_list_selection_filter (const Glib::RefPtr<TreeModel>& model, const
struct EditorOrderRouteSorter {
bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
/* use of ">" forces the correct sort order */
- return a->order_key ("editor") < b->order_key ("editor");
+ return a->order_key (_order_key) < b->order_key (_order_key);
}
};
@@ -604,20 +611,26 @@ Editor::initial_route_list_display ()
void
Editor::track_list_reorder (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter, int* new_order)
{
+ route_redisplay_does_not_sync_order_keys = true;
session->set_remote_control_ids();
redisplay_route_list ();
+ route_redisplay_does_not_sync_order_keys = false;
}
void
Editor::route_list_change (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter)
{
+ /* never reset order keys because of a property change */
+ route_redisplay_does_not_reset_order_keys = true;
session->set_remote_control_ids();
redisplay_route_list ();
+ route_redisplay_does_not_reset_order_keys = false;
}
void
Editor::route_list_delete (const Gtk::TreeModel::Path& path)
{
+ /* this could require an order reset & sync */
session->set_remote_control_ids();
ignore_route_list_reorder = true;
redisplay_route_list ();
@@ -664,3 +677,223 @@ Editor::foreach_time_axis_view (sigc::slot<void,TimeAxisView&> theslot)
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);
+}
+
+#if 0
+ vector<boost::shared_ptr<Route> > selected_block;
+ boost::shared_ptr<Route> target_unselected_route;
+ bool last_track_was_selected = false;
+ vector<int> neworder;
+ TreeModel::Children rows = route_display_model->children();
+ TreeModel::Children::iterator ri;
+ uint32_t old_key;
+ uint32_t new_key;
+ int n;
+
+ /* preload "neworder" with the current order */
+
+ for (n = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++n) {
+ neworder.push_back (n);
+ }
+
+ 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];
+
+ if (selection->selected (tv)) {
+
+ selected_block.push_back (route);
+ cerr << "--SAVE as SELECTED " << route->name() << endl;
+ last_track_was_selected = true;
+ continue;
+
+ } else {
+
+ if (!last_track_was_selected) {
+ /* keep moving through unselected tracks, but save this
+ one in case we need it later as the one that will
+ move *down* as the selected block moves up.
+ */
+ target_unselected_route = route;
+ cerr << "--pre-SAVE as UNSELECTED " << route->name() << endl;
+ continue;
+ }
+
+ last_track_was_selected = false;
+
+ if (!up) {
+ /* this is the track immediately after a selected block,
+ and this is the one that will move *up* as
+ the selected block moves down.
+ */
+
+ target_unselected_route = route;
+ cerr << "--post-SAVE as UNSELECTED " << route->name() << endl;
+ } else {
+ cerr << "--(up) plan to use existing unselected target\n";
+ }
+ }
+
+ cerr << "TRANSITION: sel = " << selected_block.size() << " unsel = " << target_unselected_route << endl;
+
+ /* transitioned between selected/not-selected */
+
+ uint32_t distance;
+
+ for (vector<boost::shared_ptr<Route> >::iterator x = selected_block.begin(); x != selected_block.end(); ++x) {
+ old_key = (*x)->order_key (_order_key);
+ new_key = compute_new_key (old_key, up, 1, rows.size());
+ neworder[new_key] = old_key;
+ cerr << "--SELECTED, reorder from " << old_key << " => " << new_key << endl;
+ }
+
+ /* now move the unselected tracks in the opposite direction */
+
+ if (!selected_block.empty() && target_unselected_route) {
+ distance = selected_block.size();
+ old_key = target_unselected_route->order_key (_order_key);
+ new_key = compute_new_key (old_key, !up, distance, rows.size());
+ neworder[new_key] = old_key;
+ cerr << "--UNSELECTED, reorder from " << old_key << " => " << new_key << endl;
+ }
+
+ selected_block.clear ();
+ target_unselected_route.reset ();
+ }
+
+ cerr << "when done ... sel = " << selected_block.size() << " unsel = " << target_unselected_route << endl;
+
+ if (!selected_block.empty() || target_unselected_route) {
+
+ /* left over blocks */
+
+ uint32_t distance;
+
+ for (vector<boost::shared_ptr<Route> >::iterator x = selected_block.begin(); x != selected_block.end(); ++x) {
+ old_key = (*x)->order_key (_order_key);
+ new_key = compute_new_key (old_key, up, 1, rows.size());
+ neworder[new_key] = old_key;
+ cerr << "--SELECTED, reorder from " << old_key << " => " << new_key << endl;
+ }
+
+ if (!selected_block.empty() && target_unselected_route) {
+ distance = selected_block.size();
+ old_key = target_unselected_route->order_key (_order_key);
+ new_key = compute_new_key (old_key, !up, distance, rows.size());
+ neworder[new_key] = old_key;
+ cerr << "--UNSELECTED, reorder from " << old_key << " => " << new_key << endl;
+ }
+ }
+
+ route_display_model->reorder (neworder);
+#endif
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index 5b96cc03c4..0be9b03444 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -68,7 +68,8 @@ Mixer_UI::Mixer_UI ()
no_track_list_redisplay = false;
in_group_row_change = false;
_visible = false;
- ignore_route_reorder = false;
+ strip_redisplay_does_not_reset_order_keys = false;
+ strip_redisplay_does_not_sync_order_keys = false;
ignore_sync = false;
Route::SyncOrderKeys.connect (mem_fun (*this, &Mixer_UI::sync_order_keys));
@@ -302,6 +303,9 @@ Mixer_UI::add_strip (Session::RouteList& routes)
MixerStrip* strip;
+ no_track_list_redisplay = true;
+ strip_redisplay_does_not_sync_order_keys = true;
+
for (Session::RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
boost::shared_ptr<Route> route = (*x);
@@ -322,25 +326,28 @@ Mixer_UI::add_strip (Session::RouteList& routes)
show_strip (strip);
- no_track_list_redisplay = true;
-
TreeModel::Row row = *(track_model->append());
row[track_columns.text] = route->name();
-
row[track_columns.visible] = strip->marked_for_display();
row[track_columns.route] = route;
row[track_columns.strip] = strip;
-
- strip->set_old_order_key (track_model->children().size() - 1);
- no_track_list_redisplay = false;
- redisplay_track_list ();
+ if (route->order_key (N_("signal")) == -1) {
+ route->set_order_key (N_("signal"), track_model->children().size()-1);
+ }
route->NameChanged.connect (bind (mem_fun(*this, &Mixer_UI::strip_name_changed), strip));
+
strip->GoingAway.connect (bind (mem_fun(*this, &Mixer_UI::remove_strip), strip));
strip->signal_button_release_event().connect (bind (mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
}
+
+ no_track_list_redisplay = false;
+
+ redisplay_track_list ();
+
+ strip_redisplay_does_not_sync_order_keys = false;
}
void
@@ -356,13 +363,7 @@ Mixer_UI::remove_strip (MixerStrip* strip)
strips.erase (i);
}
- /* Decrement old order keys for strips `above' the one that is being removed */
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
- MixerStrip* s = (*ri)[track_columns.strip];
- if (s->old_order_key() > strip->old_order_key()) {
- s->set_old_order_key (s->old_order_key() - 1);
- }
- }
+ strip_redisplay_does_not_sync_order_keys = true;
for (ri = rows.begin(); ri != rows.end(); ++ri) {
if ((*ri)[track_columns.strip] == strip) {
@@ -370,26 +371,31 @@ Mixer_UI::remove_strip (MixerStrip* strip)
break;
}
}
+
+ strip_redisplay_does_not_sync_order_keys = false;
}
const char*
Mixer_UI::get_order_key()
{
+ return X_("signal");
+#if 0
if (Config->get_sync_all_route_ordering()) {
return X_("editor");
} else {
return X_("signal");
}
+#endif
}
void
-Mixer_UI::sync_order_keys ()
+Mixer_UI::sync_order_keys (const char *src)
{
vector<int> neworder;
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator ri;
- if (ignore_sync || !session || (session->state_of_the_state() & Session::Loading) || rows.empty()) {
+ if ((strcmp (src, get_order_key()) == 0) || !session || (session->state_of_the_state() & Session::Loading) || rows.empty()) {
return;
}
@@ -397,15 +403,26 @@ Mixer_UI::sync_order_keys ()
neworder.push_back (0);
}
- for (ri = rows.begin(); ri != rows.end(); ++ri) {
+ bool changed = false;
+ int order;
+
+ for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
boost::shared_ptr<Route> route = (*ri)[track_columns.route];
- MixerStrip* strip = (*ri)[track_columns.strip];
- neworder[route->order_key (get_order_key())] = strip->old_order_key ();
+ int old_key = order;
+ int new_key = route->order_key (get_order_key());
+
+ neworder[new_key] = old_key;
+
+ if (new_key != old_key) {
+ changed = true;
+ }
}
- ignore_route_reorder = true;
- track_model->reorder (neworder);
- ignore_route_reorder = false;
+ if (changed) {
+ strip_redisplay_does_not_reset_order_keys = true;
+ track_model->reorder (neworder);
+ strip_redisplay_does_not_reset_order_keys = false;
+ }
}
void
@@ -655,24 +672,28 @@ Mixer_UI::hide_all_audiotracks ()
void
Mixer_UI::track_list_reorder (const TreeModel::Path& path, const TreeModel::iterator& iter, int* new_order)
{
+ strip_redisplay_does_not_sync_order_keys = true;
session->set_remote_control_ids();
redisplay_track_list ();
+ strip_redisplay_does_not_sync_order_keys = false;
}
void
Mixer_UI::track_list_change (const Gtk::TreeModel::Path& path,const Gtk::TreeModel::iterator& iter)
{
+ // never reset order keys because of a property change
+ strip_redisplay_does_not_reset_order_keys = true;
session->set_remote_control_ids();
redisplay_track_list ();
+ strip_redisplay_does_not_reset_order_keys = false;
}
void
Mixer_UI::track_list_delete (const Gtk::TreeModel::Path& path)
{
+ /* this could require an order sync */
session->set_remote_control_ids();
- ignore_route_reorder = true;
redisplay_track_list ();
- ignore_route_reorder = false;
}
void
@@ -700,7 +721,7 @@ Mixer_UI::redisplay_track_list ()
strip->set_marked_for_display (true);
strip->route()->set_order_key (N_("signal"), order);
- if (!ignore_route_reorder) {
+ if (!strip_redisplay_does_not_reset_order_keys) {
strip->route()->set_order_key (get_order_key(), order);
}
@@ -736,17 +757,14 @@ Mixer_UI::redisplay_track_list ()
}
}
- if (Config->get_sync_all_route_ordering() && !ignore_route_reorder) {
- ignore_sync = true;
- Route::SyncOrderKeys (); // EMIT SIGNAL
- ignore_sync = false;
+ if (!strip_redisplay_does_not_reset_order_keys && !strip_redisplay_does_not_sync_order_keys) {
+ session->sync_order_keys (get_order_key());
}
// Rebind all of the midi controls automatically
if (auto_rebinding)
auto_rebind_midi_controls ();
-
}
void
diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h
index 01460b61dc..4765256d58 100644
--- a/gtk2_ardour/mixer_ui.h
+++ b/gtk2_ardour/mixer_ui.h
@@ -242,8 +242,9 @@ class Mixer_UI : public Gtk::Window
Width _strip_width;
- void sync_order_keys ();
- bool ignore_route_reorder;
+ void sync_order_keys (const char *src);
+ bool strip_redisplay_does_not_reset_order_keys;
+ bool strip_redisplay_does_not_sync_order_keys;
bool ignore_sync;
static const int32_t default_width = 478;
diff --git a/gtk2_ardour/mnemonic-us.bindings.in b/gtk2_ardour/mnemonic-us.bindings.in
index 4a29f85fb0..8a2a1923ba 100644
--- a/gtk2_ardour/mnemonic-us.bindings.in
+++ b/gtk2_ardour/mnemonic-us.bindings.in
@@ -115,10 +115,12 @@
(gtk_accel_path "<Actions>/Editor/step-tracks-up" "uparrow")
(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<%PRIMARY%>uparrow")
(gtk_accel_path "<Actions>/Editor/select-prev-route" "<%SECONDARY%>uparrow")
+(gtk_accel_path "<Actions>/Editor/move-selected-tracks-up" "<%TERTIARY%>uparrow")
(gtk_accel_path "<Actions>/Editor/step-tracks-down" "downarrow")
(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<%PRIMARY%>downarrow")
(gtk_accel_path "<Actions>/Editor/select-next-route" "<%SECONDARY%>downarrow")
+(gtk_accel_path "<Actions>/Editor/move-selected-tracks-down" "<%TERTIARY%>downarrow")
(gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-boundary" "leftarrow")
(gtk_accel_path "<Actions>/Editor/tab-to-transient-backwards" "<%PRIMARY%>leftarrow")
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 8985e85071..a36a6bc35a 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -960,33 +960,30 @@ RouteTimeAxisView::resolve_new_group_playlist_name(std::string &basename, vector
std::string group_string = "."+edit_group()->name()+".";
- if (basename.find(group_string) == string::npos) {
- int maxnumber = 0;
-
- // iterate through all playlists
- for (vector<boost::shared_ptr<Playlist> >::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
- std::string tmp = (*i)->name();
-
- std::string::size_type idx = tmp.find(group_string);
- // find those which belong to this group
- if (idx != string::npos) {
- tmp = tmp.substr(idx + group_string.length());
-
- // and find the largest current number
- int x = atoi(tmp.c_str());
- if (x > maxnumber) {
- maxnumber = x;
- }
+ // iterate through all playlists
+ int maxnumber = 0;
+ for (vector<boost::shared_ptr<Playlist> >::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ std::string tmp = (*i)->name();
+
+ std::string::size_type idx = tmp.find(group_string);
+ // find those which belong to this group
+ if (idx != string::npos) {
+ tmp = tmp.substr(idx + group_string.length());
+
+ // and find the largest current number
+ int x = atoi(tmp.c_str());
+ if (x > maxnumber) {
+ maxnumber = x;
}
}
+ }
- maxnumber++;
+ maxnumber++;
- char buf[32];
- snprintf (buf, sizeof(buf), "%d", maxnumber);
+ char buf[32];
+ snprintf (buf, sizeof(buf), "%d", maxnumber);
- ret = this->name()+"."+edit_group()->name()+"."+buf;
- }
+ ret = this->name()+"."+edit_group()->name()+"."+buf;
return ret;
}
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 3019d954fc..26c99488cc 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -575,7 +575,7 @@ RouteUI::update_rec_display ()
void
RouteUI::build_remote_control_menu ()
{
- remote_control_menu = manage (new Menu);
+ remote_control_menu = new Menu;
refresh_remote_control_menu ();
}
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index fb98cb57a7..f963d3b2cf 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -256,8 +256,8 @@ class Route : public IO
uint32_t remote_control_id () const;
sigc::signal<void> RemoteControlIDChanged;
- void sync_order_keys ();
- static sigc::signal<void> SyncOrderKeys;
+ void sync_order_keys (const char* base);
+ static sigc::signal<void,const char*> SyncOrderKeys;
protected:
friend class Session;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index a5245b73f8..017a78a015 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -319,6 +319,8 @@ class Session : public PBD::StatefulDestructible
struct RoutePublicOrderSorter {
bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
};
+
+ void sync_order_keys (const char* base);
template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
@@ -1395,8 +1397,6 @@ class Session : public PBD::StatefulDestructible
void change_midi_ports ();
int use_config_midi_ports ();
- mutable gint butler_active;
-
void set_play_loop (bool yn);
void overwrite_some_buffers (Diskstream*);
void flush_all_inserts ();
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 0ae71f739c..788017555a 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -1103,7 +1103,6 @@ AudioEngine::transport_stop ()
void
AudioEngine::transport_start ()
{
- // cerr << "tell JACK to start\n";
if (_jack) {
jack_transport_start (_jack);
}
diff --git a/libs/ardour/jack_slave.cc b/libs/ardour/jack_slave.cc
index 7865f5253b..40729d3370 100644
--- a/libs/ardour/jack_slave.cc
+++ b/libs/ardour/jack_slave.cc
@@ -67,7 +67,6 @@ JACK_Slave::speed_and_position (float& sp, nframes_t& position)
{
jack_position_t pos;
jack_transport_state_t state;
-
state = jack_transport_query (jack, &pos);
switch (state) {
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 78d4a85e61..5d1a26d3d0 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -57,7 +57,7 @@ using namespace ARDOUR;
using namespace PBD;
uint32_t Route::order_key_cnt = 0;
-sigc::signal<void> Route::SyncOrderKeys;
+sigc::signal<void,const char*> Route::SyncOrderKeys;
Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
: IO (sess, name, input_min, input_max, output_min, output_max, default_type),
@@ -177,20 +177,32 @@ Route::set_order_key (const char* name, long n)
}
void
-Route::sync_order_keys ()
+Route::sync_order_keys (const char* base)
{
- uint32_t key;
-
if (order_keys.empty()) {
return;
}
-
- OrderKeys::iterator x = order_keys.begin();
- key = x->second;
- ++x;
- for (; x != order_keys.end(); ++x) {
- x->second = key;
+ OrderKeys::iterator i;
+ uint32_t key;
+
+ if ((i = order_keys.find (base)) == order_keys.end()) {
+ /* key doesn't exist, use the first existing
+ key (this is done during session initialization)
+ */
+ i = order_keys.begin();
+ key = i->second;
+ ++i;
+ } else {
+ /* key exists - use it and reset all others
+ (actually, itself included)
+ */
+ i = order_keys.begin();
+ key = i->second;
+ }
+
+ for (; i != order_keys.end(); ++i) {
+ i->second = key;
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 3b9b48a2de..14ef0e1ac5 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2114,6 +2114,8 @@ Session::remove_route (shared_ptr<Route> route)
route->drop_references ();
+ sync_order_keys (N_("session"));
+
/* save the new state of the world */
if (save_state (_current_snapshot_name)) {
@@ -4274,7 +4276,7 @@ Session::compute_initial_length ()
}
void
-Session::sync_order_keys ()
+Session::sync_order_keys (const char* base)
{
if (!Config->get_sync_all_route_ordering()) {
/* leave order keys as they are */
@@ -4284,10 +4286,10 @@ Session::sync_order_keys ()
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- (*i)->sync_order_keys ();
+ (*i)->sync_order_keys (base);
}
- Route::SyncOrderKeys (); // EMIT SIGNAL
+ Route::SyncOrderKeys (base); // EMIT SIGNAL
}
void
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 0ac6e08827..a1b4f34a25 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -193,7 +193,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
session_send_mtc = false;
post_transport_work = PostTransportWork (0);
g_atomic_int_set (&butler_should_do_transport_work, 0);
- g_atomic_int_set (&butler_active, 0);
g_atomic_int_set (&_playback_load, 100);
g_atomic_int_set (&_capture_load, 100);
g_atomic_int_set (&_playback_load_min, 100);
@@ -255,7 +254,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* slave stuff */
- average_slave_delta = 1800;
+ average_slave_delta = 1800; // !!! why 1800 ????
have_first_delta_accumulator = false;
delta_accumulator_cnt = 0;
slave_state = Stopped;
@@ -3260,7 +3259,7 @@ Session::config_changed (const char* parameter_name)
} else if (PARAM_IS ("history-depth")) {
set_history_depth (Config->get_history_depth());
} else if (PARAM_IS ("sync-all-route-ordering")) {
- sync_order_keys ();
+ sync_order_keys ("session");
} else if (PARAM_IS ("initial-program-change")) {
if (_mmc_port && Config->get_initial_program_change() >= 0) {