drastic rethink of the relationship between remote control ID and route order keys...
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 25 Jun 2012 12:46:13 +0000 (12:46 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 25 Jun 2012 12:46:13 +0000 (12:46 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@12923 d708f5d6-7413-0410-9779-e7cbd77b26cf

23 files changed:
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_group_tabs.cc
gtk2_ardour/editor_group_tabs.h
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_routes.cc
gtk2_ardour/editor_routes.h
gtk2_ardour/editor_selection.cc
gtk2_ardour/group_tabs.cc
gtk2_ardour/group_tabs.h
gtk2_ardour/mixer_group_tabs.cc
gtk2_ardour/mixer_group_tabs.h
gtk2_ardour/mixer_ui.cc
gtk2_ardour/mixer_ui.h
gtk2_ardour/port_group.cc
gtk2_ardour/route_ui.cc
libs/ardour/ardour/route.h
libs/ardour/ardour/session.h
libs/ardour/ardour/types.h
libs/ardour/enums.cc
libs/ardour/route.cc
libs/ardour/route_graph.cc
libs/ardour/session.cc
libs/ardour/session_state.cc

index ae3795f7fa39e4e4f3063dc4f4792992cb7f5b3e..8ae618b37f32ab17cf7075cc5238a18b0a7850fb 100644 (file)
@@ -420,7 +420,7 @@ struct EditorOrderTimeAxisViewSorter {
            RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a);
            RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b);
            assert (ra && rb);
-           return ra->route()->order_key (N_ ("editor")) < rb->route()->order_key (N_ ("editor"));
+           return ra->route()->order_key (EditorSort) < rb->route()->order_key (EditorSort);
     }
 };
 
index 352eec88ccbe886ae5780fd27dd5ebcb50930784..5a1e9c8aaa2cb3bc4fde327ca114e4f24cb4255b 100644 (file)
@@ -177,10 +177,10 @@ EditorGroupTabs::default_properties () const
        return plist;
 }
 
-string
+RouteSortOrderKey
 EditorGroupTabs::order_key () const
 {
-       return X_("editor");
+       return EditorSort;
 }
 
 RouteList
@@ -201,5 +201,5 @@ EditorGroupTabs::selected_routes () const
 void
 EditorGroupTabs::sync_order_keys ()
 {
-       _editor->_routes->sync_order_keys ("");
+       _editor->_routes->sync_order_keys (UndefinedSort);
 }
index e2ed6055aa99f06b7da55cf52aca061c5f1f8c37..a0021e4833aad2798937105df55693f22f6e5f14 100644 (file)
@@ -37,7 +37,7 @@ private:
        }
        void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
        PBD::PropertyList default_properties () const;
-       std::string order_key () const;
+        ARDOUR::RouteSortOrderKey order_key () const;
        ARDOUR::RouteList selected_routes () const;
        void sync_order_keys ();
 };
index 46a69ce6af87fb06380bb1d0f2c932713512885f..d891db6651462071bbc3969cda6b1df07e32db77 100644 (file)
@@ -5411,8 +5411,7 @@ Editor::split_region ()
 
 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 (EditorSort) < b->order_key (EditorSort);
     }
 };
 
index c4443cbed0c96d24b83c164821b198043e6bd41c..3faeba183f3fbf332bb27dc98b73aa964e9024ab 100644 (file)
@@ -520,7 +520,14 @@ EditorRoutes::redisplay ()
                        /* this reorder is caused by user action, so reassign sort order keys
                           to tracks.
                        */
-                       route->set_order_key (N_ ("editor"), order_key);
+                       
+                       if (route->is_master()) {
+                               route->set_order_key (EditorSort, Route::MasterBusRemoteControlID);
+                       } else if (route->is_monitor()) {
+                               route->set_order_key (EditorSort, Route::MonitorBusRemoteControlID);
+                       } else {
+                               route->set_order_key (EditorSort, order_key++);
+                       }
                }
 
                bool visible = tv->marked_for_display ();
@@ -534,7 +541,6 @@ EditorRoutes::redisplay ()
                }
 
                n++;
-               order_key++;
        }
 
        /* whenever we go idle, update the track view list to reflect the new order.
@@ -557,7 +563,7 @@ EditorRoutes::redisplay ()
        }
 
        if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
-               _session->sync_order_keys (N_ ("editor"));
+               _session->sync_order_keys (EditorSort);
        }
 }
 
@@ -569,7 +575,6 @@ EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
        }
 
         /* this could require an order reset & sync */
-       _session->set_remote_control_ids();
        _ignore_reorder = true;
        redisplay ();
        _ignore_reorder = false;
@@ -591,7 +596,6 @@ EditorRoutes::visible_changed (std::string const & path)
 
                        if (tv->set_marked_for_display (!visible)) {
                                _redisplay_does_not_reset_order_keys = true;
-                               _session->set_remote_control_ids();
                                update_visibility ();
                                redisplay ();
                                _redisplay_does_not_reset_order_keys = false;
@@ -649,15 +653,6 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
                row[_columns.solo_safe_state] = (*x)->route()->solo_safe();
                row[_columns.name_editable] = true;
 
-               _ignore_reorder = true;
-
-               /* added a new fresh one at the end */
-               if ((*x)->route()->order_key (N_ ("editor")) == -1) {
-                       (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
-               }
-
-               _ignore_reorder = false;
-
                boost::weak_ptr<Route> wr ((*x)->route());
 
                (*x)->route()->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
@@ -833,13 +828,13 @@ EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, i
  *  route list so that the visual arrangement of routes matches the order keys from the routes.
  */
 void
-EditorRoutes::sync_order_keys (string const & src)
+EditorRoutes::sync_order_keys (RouteSortOrderKey src)
 {
        map<int, int> new_order;
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator ri;
 
-       if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
+       if (src == EditorSort || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
                return;
        }
 
@@ -850,7 +845,7 @@ EditorRoutes::sync_order_keys (string const & src)
                boost::shared_ptr<Route> route = (*ri)[_columns.route];
 
                int const old_key = order;
-               int const new_key = route->order_key (N_ ("editor"));
+               int const new_key = route->order_key (EditorSort);
 
                new_order[new_key] = old_key;
 
@@ -1193,7 +1188,7 @@ EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path
 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 (N_ ("editor")) < b->order_key (N_ ("editor"));
+           return a->order_key (EditorSort) < b->order_key (EditorSort);
     }
 };
 
@@ -1247,7 +1242,6 @@ void
 EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
 {
        _redisplay_does_not_sync_order_keys = true;
-       _session->set_remote_control_ids();
        redisplay ();
        _redisplay_does_not_sync_order_keys = false;
 }
@@ -1370,7 +1364,7 @@ EditorRoutes::move_selected_tracks (bool up)
        }
 
        for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
-               neworder.push_back (leading->second->order_key (N_ ("editor")));
+               neworder.push_back (leading->second->order_key (EditorSort));
        }
 
 #ifndef NDEBUG
@@ -1381,7 +1375,7 @@ EditorRoutes::move_selected_tracks (bool up)
 
        _model->reorder (neworder);
 
-       _session->sync_order_keys (N_ ("editor"));
+       _session->sync_order_keys (EditorSort);
 }
 
 void
index 5fad890faffff1260365e4b1da8dc892b130f9ac..00631d914af524879409e03029e2feeac4b3bdf6 100644 (file)
@@ -55,7 +55,7 @@ public:
        std::list<TimeAxisView*> views () const;
        void hide_all_tracks (bool);
        void clear ();
-       void sync_order_keys (std::string const &);
+        void sync_order_keys (ARDOUR::RouteSortOrderKey);
 
 private:
 
index eb9ea5c72121cf21f985fd3e1514713a20ce26d1..7b08eaeaa6765aea2db48504efd9a6fa9a09037e 100644 (file)
@@ -779,7 +779,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
 
                                        RouteTimeAxisView* closest = 0;
                                        int distance = INT_MAX;
-                                       int key = rtv->route()->order_key ("editor");
+                                       int key = rtv->route()->order_key (EditorSort);
 
                                        for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
 
@@ -794,7 +794,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
                                                        if (result.second) {
                                                                /* newly added to already_in_selection */
 
-                                                               int d = artv->route()->order_key ("editor");
+                                                               int d = artv->route()->order_key (EditorSort);
 
                                                                d -= key;
 
@@ -810,7 +810,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
 
                                                /* now add all tracks between that one and this one */
 
-                                               int okey = closest->route()->order_key ("editor");
+                                               int okey = closest->route()->order_key (EditorSort);
 
                                                if (okey > key) {
                                                        swap (okey, key);
@@ -820,7 +820,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
                                                        RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x);
                                                        if (artv && artv != rtv) {
 
-                                                               int k = artv->route()->order_key ("editor");
+                                                               int k = artv->route()->order_key (EditorSort);
 
                                                                if (k >= okey && k <= key) {
 
index 9ce3b150460029822cabdf1ebc0ec7269f76126a..d53b90584695111dcb528107d4f353beea3c7570 100644 (file)
@@ -435,24 +435,23 @@ GroupTabs::subgroup (RouteGroup* g, bool aux, Placement placement)
 }
 
 struct CollectSorter {
-       CollectSorter (string const & key) : _key (key) {}
+       CollectSorter (RouteSortOrderKey key) : _key (key) {}
 
        bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
                return a->order_key (_key) < b->order_key (_key);
        }
 
-       string _key;
+        RouteSortOrderKey _key;
 };
 
 struct OrderSorter {
-       OrderSorter (string const & key) : _key (key) {}
+       OrderSorter (RouteSortOrderKey key) : _key (key) {}
        
        bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-               /* use of ">" forces the correct sort order */
                return a->order_key (_key) < b->order_key (_key);
        }
 
-       string _key;
+       RouteSortOrderKey _key;
 };
 
 /** Collect all members of a RouteGroup so that they are together in the Editor or Mixer.
index d8c488c70f9665d07eae66d3683f49788fd87f21..fa6a7bac532bcddf84f43b8516bf5dabe5628bb6 100644 (file)
@@ -92,7 +92,7 @@ private:
 
        virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
        virtual PBD::PropertyList default_properties () const = 0;
-       virtual std::string order_key () const = 0;
+        virtual ARDOUR::RouteSortOrderKey order_key () const = 0;
        virtual ARDOUR::RouteList selected_routes () const = 0;
        virtual void sync_order_keys () = 0;
 
index db586eed7e15393a28213f516ad037acaa9aff29..60a625c96db505867946bb17459115901e857620 100644 (file)
@@ -170,10 +170,10 @@ MixerGroupTabs::default_properties () const
        return plist;
 }
 
-string
+RouteSortOrderKey
 MixerGroupTabs::order_key () const
 {
-       return X_("signal");
+       return MixerSort;
 }
 
 RouteList
@@ -192,5 +192,5 @@ MixerGroupTabs::selected_routes () const
 void
 MixerGroupTabs::sync_order_keys ()
 {
-       _mixer->sync_order_keys ("");
+       _mixer->sync_order_keys (UndefinedSort);
 }
index d8dd0622803466ed0cc597ce53b4a114b8751364..0999dd9808b14d605d4bd8c9485e1f83b6666a56 100644 (file)
@@ -36,7 +36,7 @@ private:
        }
 
        PBD::PropertyList default_properties () const;
-       std::string order_key () const;
+        ARDOUR::RouteSortOrderKey  order_key () const;
        ARDOUR::RouteList selected_routes () const;
        void sync_order_keys ();
 
index 8dd83ad771dccd7ebb582c0e22c44c6bd45dc702..a29717211e659c65c7ac970bc5ecdc46596b5e54 100644 (file)
@@ -307,13 +307,11 @@ Mixer_UI::hide_window (GdkEventAny *ev)
 void
 Mixer_UI::add_strip (RouteList& routes)
 {
-       ENSURE_GUI_THREAD (*this, &Mixer_UI::add_strip, routes)
-
        MixerStrip* strip;
 
        no_track_list_redisplay = true;
        strip_redisplay_does_not_sync_order_keys = true;
-
+       
        for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
                boost::shared_ptr<Route> route = (*x);
 
@@ -360,10 +358,6 @@ Mixer_UI::add_strip (RouteList& routes)
                row[track_columns.route] = route;
                row[track_columns.strip] = strip;
 
-               if (route->order_key (N_("signal")) == -1) {
-                       route->set_order_key (N_("signal"), track_model->children().size()-1);
-               }
-
                route->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::strip_property_changed, this, _1, strip), gui_context());
 
                strip->WidthChanged.connect (sigc::mem_fun(*this, &Mixer_UI::strip_width_changed));
@@ -406,12 +400,12 @@ Mixer_UI::remove_strip (MixerStrip* strip)
 }
 
 void
-Mixer_UI::sync_order_keys (string const & src)
+Mixer_UI::sync_order_keys (RouteSortOrderKey src)
 {
        TreeModel::Children rows = track_model->children();
        TreeModel::Children::iterator ri;
 
-       if (src == N_("signal") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
+       if (src == MixerSort || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
                return;
        }
 
@@ -423,7 +417,7 @@ Mixer_UI::sync_order_keys (string const & src)
        for (ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
                boost::shared_ptr<Route> route = (*ri)[track_columns.route];
                unsigned int old_key = order;
-               unsigned int new_key = route->order_key (N_("signal"));
+               unsigned int new_key = route->order_key (MixerSort);
 
                keys[new_key] = old_key;
 
@@ -802,7 +796,6 @@ void
 Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, 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;
 }
@@ -812,7 +805,6 @@ Mixer_UI::track_list_change (const Gtk::TreeModel::Path&, const Gtk::TreeModel::
 {
        // 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;
 }
@@ -822,7 +814,6 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
 {
        /* this could require an order sync */
        if (_session && !_session->deletion_in_progress()) {
-               _session->set_remote_control_ids();
                redisplay_track_list ();
        }
 }
@@ -832,13 +823,15 @@ Mixer_UI::redisplay_track_list ()
 {
        TreeModel::Children rows = track_model->children();
        TreeModel::Children::iterator i;
-       long order;
-
+       long regular_order = 0;
+       long hidden_order = 999999; // arbitary high number
+       
        if (no_track_list_redisplay) {
                return;
        }
 
-       for (order = 0, i = rows.begin(); i != rows.end(); ++i, ++order) {
+       for (i = rows.begin(); i != rows.end(); ++i) {
+
                MixerStrip* strip = (*i)[track_columns.strip];
 
                if (strip == 0) {
@@ -846,10 +839,6 @@ Mixer_UI::redisplay_track_list ()
                        continue;
                }
 
-               if (!strip_redisplay_does_not_reset_order_keys) {
-                       strip->route()->set_order_key (N_("signal"), order);
-               }
-
                bool const visible = (*i)[track_columns.visible];
 
                if (visible) {
@@ -859,16 +848,41 @@ Mixer_UI::redisplay_track_list ()
 
                                if (strip->route()->is_master() || strip->route()->is_monitor()) {
                                        out_packer.reorder_child (*strip, -1);
+                                       
+                                       if (!strip_redisplay_does_not_reset_order_keys) {
+                                               if (strip->route()->is_master()) {
+                                                       strip->route()->set_order_key (MixerSort, Route::MasterBusRemoteControlID);
+                                               } else {
+                                                       strip->route()->set_order_key (MixerSort, Route::MonitorBusRemoteControlID);
+                                               }
+                                       }
+
                                } else {
                                        strip_packer.reorder_child (*strip, -1); /* put at end */
+
+                                       if (!strip_redisplay_does_not_reset_order_keys) {
+                                               strip->route()->set_order_key (MixerSort, regular_order++);
+                                       }
+
                                }
 
                        } else {
 
                                if (strip->route()->is_master() || strip->route()->is_monitor()) {
                                        out_packer.pack_start (*strip, false, false);
+                                       if (!strip_redisplay_does_not_reset_order_keys) {
+                                               if (strip->route()->is_master()) {
+                                                       strip->route()->set_order_key (MixerSort, Route::MasterBusRemoteControlID);
+                                               } else {
+                                                       strip->route()->set_order_key (MixerSort, Route::MonitorBusRemoteControlID);
+                                               }
+                                       }
                                } else {
                                        strip_packer.pack_start (*strip, false, false);
+
+                                       if (!strip_redisplay_does_not_reset_order_keys) {
+                                               strip->route()->set_order_key (MixerSort, regular_order++);
+                                       }
                                }
                                strip->set_packed (true);
                        }
@@ -884,12 +898,16 @@ Mixer_UI::redisplay_track_list ()
                                        strip_packer.remove (*strip);
                                        strip->set_packed (false);
                                }
+
+                               if (!strip_redisplay_does_not_reset_order_keys) {
+                                       strip->route()->set_order_key (MixerSort, hidden_order++);
+                               }
                        }
                }
        }
 
        if (!strip_redisplay_does_not_reset_order_keys && !strip_redisplay_does_not_sync_order_keys) {
-               _session->sync_order_keys (N_("signal"));
+               _session->sync_order_keys (MixerSort);
        }
 
        _group_tabs->set_dirty ();
@@ -924,8 +942,7 @@ Mixer_UI::strip_width_changed ()
 
 struct SignalOrderRouteSorter {
     bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-           /* use of ">" forces the correct sort order */
-           return a->order_key (N_("signal")) < b->order_key (N_("signal"));
+           return a->order_key (MixerSort) < b->order_key (MixerSort);
     }
 };
 
index 08d7b6e487f5c077a001e321cf8aeab97dfff2f5..f3d7845461cfa0bf3d6bbf1ad094fbf96fc7bac8 100644 (file)
@@ -37,6 +37,7 @@
 #include "pbd/signals.h"
 
 #include "ardour/ardour.h"
+#include "ardour/types.h"
 #include "ardour/session_handle.h"
 
 #include "enums.h"
@@ -244,7 +245,7 @@ class Mixer_UI : public Gtk::Window, public PBD::ScopedConnectionList, public AR
 
        Width _strip_width;
 
-       void sync_order_keys (std::string const &);
+        void sync_order_keys (ARDOUR::RouteSortOrderKey);
        bool strip_redisplay_does_not_reset_order_keys;
        bool strip_redisplay_does_not_sync_order_keys;
        bool ignore_sync;
index 36b9ea1187254192533f57008ef75b3baccead06..f313b2973fc80ac509efbf09c93195bbceb96bde 100644 (file)
@@ -312,7 +312,7 @@ struct RouteIOs {
 class RouteIOsComparator {
 public:
        bool operator() (RouteIOs const & a, RouteIOs const & b) {
-               return a.route->order_key (X_("editor")) < b.route->order_key (X_("editor"));
+               return a.route->order_key (EditorSort) < b.route->order_key (EditorSort);
        }
 };
 
index 0da6bde4f08b072ad2a932ace50bc22db5158ab1..b6c81717a23caa82115a159da83e9d03a9407505 100644 (file)
@@ -1716,27 +1716,39 @@ void
 RouteUI::open_remote_control_id_dialog ()
 {
        ArdourDialog dialog (_("Remote Control ID"));
+       SpinButton* spin = 0;
 
-       uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
+       dialog.get_vbox()->set_border_width (18);
 
-       HBox* hbox = manage (new HBox);
-       hbox->set_spacing (6);
-       hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
-       SpinButton* spin = manage (new SpinButton);
-       spin->set_digits (0);
-       spin->set_increments (1, 10);
-       spin->set_range (0, limit);
-       spin->set_value (_route->remote_control_id());
-       hbox->pack_start (*spin);
-       dialog.get_vbox()->pack_start (*hbox);
-
-       dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
-       dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
+       if (Config->get_remote_model() == UserOrdered) {
+               uint32_t const limit = _session->ntracks() + _session->nbusses () + 4;
+               
+               HBox* hbox = manage (new HBox);
+               hbox->set_spacing (6);
+               hbox->pack_start (*manage (new Label (_("Remote control ID:"))));
+               spin = manage (new SpinButton);
+               spin->set_digits (0);
+               spin->set_increments (1, 10);
+               spin->set_range (0, limit);
+               spin->set_value (_route->remote_control_id());
+               hbox->pack_start (*spin);
+               dialog.get_vbox()->pack_start (*hbox);
+               
+               dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
+               dialog.add_button (Stock::APPLY, RESPONSE_ACCEPT);
+       } else {
+               Label* l = manage (new Label());
+               l->set_markup (string_compose (_("Remote Control IDs are currently determined by track/bus ordering in %1\n\n\n"
+                                                "<span size=\"small\" style=\"italic\">Use the User Interaction tab of the Preferences window if you want to change this</span>"),
+                                              (Config->get_remote_model() == MixerOrdered ? _("the mixer") : ("the editor"))));
+               dialog.get_vbox()->pack_start (*l);
+               dialog.add_button (Stock::OK, RESPONSE_CANCEL);
+       }
 
        dialog.show_all ();
        int const r = dialog.run ();
 
-       if (r == RESPONSE_ACCEPT) {
+       if (r == RESPONSE_ACCEPT && spin) {
                _route->set_remote_control_id (spin->get_value_as_int ());
        }
 }
index d1248d8b03af11334348ffa61b9bd130360cea78..a15937377eccf4902b1f99dbe52c06913a35a096 100644 (file)
@@ -101,8 +101,8 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
        bool set_name (const std::string& str);
        static void set_name_in_state (XMLNode &, const std::string &);
 
-       int32_t order_key (std::string const &) const;
-       void set_order_key (std::string const &, int32_t);
+       int32_t order_key (RouteSortOrderKey) const;
+       void set_order_key (RouteSortOrderKey, int32_t);
 
        bool is_hidden() const { return _flags & Hidden; }
        bool is_master() const { return _flags & MasterOut; }
@@ -420,19 +420,19 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
                MonitorBusRemoteControlID = 319,
        };
 
-       void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
+       void     set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
        uint32_t remote_control_id () const;
 
        /* for things concerned about *this* route's RID */
 
        PBD::Signal0<void> RemoteControlIDChanged;
 
-       /* for things concerned about any route's RID changes */
+       /* for things concerned about *any* route's RID changes */
 
        static PBD::Signal0<void> RemoteControlIDChange;
 
-       void sync_order_keys (std::string const &);
-       static PBD::Signal1<void,std::string const &> SyncOrderKeys;
+       void sync_order_keys (RouteSortOrderKey);
+       static PBD::Signal1<void,RouteSortOrderKey> SyncOrderKeys;
 
        bool has_external_redirects() const;
 
@@ -518,7 +518,6 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
        void silence_unlocked (framecnt_t);
 
        ChanCount processor_max_streams;
-       uint32_t _remote_control_id;
 
        uint32_t pans_required() const;
        ChanCount n_process_buffers ();
@@ -534,8 +533,9 @@ class Route : public SessionObject, public Automatable, public RouteGroupMember,
 
        static uint32_t order_key_cnt;
 
-       typedef std::map<std::string, long> OrderKeys;
-       OrderKeys order_keys;
+       typedef std::map<RouteSortOrderKey,int32_t> OrderKeys;
+       OrderKeys order_keys;
+       uint32_t* _remote_control_id;
 
        void input_change_handler (IOChange, void *src);
        void output_change_handler (IOChange, void *src);
index 7f73d3ae775e8629074a3b7b5f3a5c9c0b5b2ea9..eb84c0685e53f6e6a945a7f24cbead7a3e2964c7 100644 (file)
@@ -235,7 +235,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
                bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
        };
 
-       void sync_order_keys (std::string const &);
+        void sync_order_keys (RouteSortOrderKey);
 
        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>));
@@ -464,8 +464,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void   resort_routes ();
        void   resort_routes_using (boost::shared_ptr<RouteList>);
 
-       void   set_remote_control_ids();
-
        AudioEngine & engine() { return _engine; }
        AudioEngine const & engine () const { return _engine; }
 
@@ -1488,7 +1486,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        XMLNode& get_control_protocol_state ();
 
        void set_history_depth (uint32_t depth);
-       void sync_order_keys ();
 
        static bool _disable_all_loaded_plugins;
 
index 6d05bdbbd8d79e902115d46497af12ea580bbab2..713e35ebab1a1f6b808808e94d21f4ef96c58e2f 100644 (file)
@@ -351,6 +351,12 @@ namespace ARDOUR {
                PostFader
        };
 
+        enum RouteSortOrderKey { 
+               UndefinedSort,
+               EditorSort,
+               MixerSort
+       };
+           
        enum MonitorModel {
                HardwareMonitoring, ///< JACK does monitoring
                SoftwareMonitoring, ///< Ardour does monitoring
index afe92ed5f7babf961f327241d94aa5ded0a7dc56..1ef9047f57711ec9b61312bcc34a0dc19c2b3eee 100644 (file)
@@ -89,6 +89,7 @@ setup_enum_writer ()
        AutoState _AutoState;
        AutoStyle _AutoStyle;
        AutoConnectOption _AutoConnectOption;
+       RouteSortOrderKey _RouteSortOrderKey;
        Session::StateOfTheState _Session_StateOfTheState;
        Route::Flag _Route_Flag;
        Source::Flag _Source_Flag;
@@ -397,6 +398,10 @@ setup_enum_writer ()
        REGISTER_CLASS_ENUM (Route, MonitorOut);
        REGISTER_BITS (_Route_Flag);
 
+       REGISTER_ENUM (MixerSort);
+       REGISTER_ENUM (EditorSort);
+       REGISTER_BITS (_RouteSortOrderKey);
+
        REGISTER_CLASS_ENUM (Source, Writable);
        REGISTER_CLASS_ENUM (Source, CanRename);
        REGISTER_CLASS_ENUM (Source, Broadcast);
index 83b1efce767a804016cb860883fc3932143064c2..af30a112dbb3154064cd41f8e0f64631ea7f6eff 100644 (file)
@@ -67,7 +67,7 @@ using namespace ARDOUR;
 using namespace PBD;
 
 uint32_t Route::order_key_cnt = 0;
-PBD::Signal1<void,string const&> Route::SyncOrderKeys;
+PBD::Signal1<void,RouteSortOrderKey> Route::SyncOrderKeys;
 PBD::Signal0<void> Route::RemoteControlIDChange;
 
 Route::Route (Session& sess, string name, Flag flg, DataType default_type)
@@ -99,14 +99,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
        , _last_custom_meter_was_at_end (false)
 {
        processor_max_streams.reset();
-       order_keys[N_("signal")] = order_key_cnt++;
-
-       if (is_master()) {
-               set_remote_control_id (MasterBusRemoteControlID);
-       } else if (is_monitor()) {
-               set_remote_control_id (MonitorBusRemoteControlID);
-       }
-               
 }
 
 int
@@ -203,11 +195,22 @@ Route::~Route ()
        }
 
        _processors.clear ();
+
+       delete _remote_control_id;
 }
 
 void
 Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
 {
+       if (Config->get_remote_model() != UserOrdered) {
+               return;
+       }
+       
+       if (id < 1) {
+               error << _("Remote Control ID's start at one, not zero") << endmsg;
+               return;
+       }
+
        /* force IDs for master/monitor busses and prevent 
           any other route from accidentally getting these IDs
           (i.e. legacy sessions)
@@ -228,8 +231,11 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
                id += MonitorBusRemoteControlID;
        }
 
-       if (id != _remote_control_id) {
-               _remote_control_id = id;
+       if (id != remote_control_id()) {
+               if (!_remote_control_id) {
+                       _remote_control_id = new uint32_t;
+               }
+               *_remote_control_id = id;
                RemoteControlIDChanged ();
                if (notify_class_listeners) {
                        RemoteControlIDChange ();
@@ -240,13 +246,27 @@ Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
 uint32_t
 Route::remote_control_id() const
 {
-       return _remote_control_id;
+       switch (Config->get_remote_model()) {
+       case MixerOrdered:
+               return order_key (MixerSort) + 1;
+       case EditorOrdered:
+               return order_key (EditorSort) + 1;
+       case UserOrdered:
+               if (_remote_control_id) {
+                       return *_remote_control_id;
+               }
+       }
+
+       /* fall back to MixerSort as the default */
+
+       return order_key (MixerSort) + 1;
 }
 
 int32_t
-Route::order_key (std::string const & name) const
+Route::order_key (RouteSortOrderKey key) const
 {
-       OrderKeys::const_iterator i = order_keys.find (name);
+       OrderKeys::const_iterator i = order_keys.find (key);
+
        if (i == order_keys.end()) {
                return -1;
        }
@@ -255,7 +275,7 @@ Route::order_key (std::string const & name) const
 }
 
 void
-Route::set_order_key (std::string const & name, int32_t n)
+Route::set_order_key (RouteSortOrderKey key, int32_t n)
 {
        bool changed = false;
 
@@ -265,16 +285,24 @@ Route::set_order_key (std::string const & name, int32_t n)
           signal.
        */
 
-       if (order_keys.find(name) == order_keys.end() || order_keys[name] != n) {
-               order_keys[name] = n;
+       if (order_keys.find (key) == order_keys.end() || order_keys[key] != n) {
+               order_keys[key] = n;
                changed = true;
        }
 
        if (Config->get_sync_all_route_ordering()) {
                for (OrderKeys::iterator x = order_keys.begin(); x != order_keys.end(); ++x) {
-                       if (x->second != n) {
-                               x->second = n;
-                               changed = true;
+
+                       /* we do not sync the signal order keys for mixer +
+                        * monitor because they are considered "external" to
+                        * the ordering of other routes.
+                        */
+                       
+                       if ((!is_master() && !is_monitor()) || x->first != MixerSort) {
+                               if (x->second != n) {
+                                       x->second = n;
+                                       changed = true;
+                               }
                        }
                }
        }
@@ -290,7 +318,7 @@ Route::set_order_key (std::string const & name, int32_t n)
  *  @param base Base key.
  */
 void
-Route::sync_order_keys (std::string const & base)
+Route::sync_order_keys (RouteSortOrderKey base)
 {
        if (order_keys.empty()) {
                return;
@@ -313,9 +341,17 @@ Route::sync_order_keys (std::string const & base)
        bool changed = false;
 
        for (; i != order_keys.end(); ++i) {
-               if (i->second != key) {
-                       i->second = key;
-                       changed = true;
+
+               /* we do not sync the signal order keys for mixer +
+                * monitor because they are considered "external" to
+                * the ordering of other routes.
+                */
+
+               if ((!is_master() && !is_monitor()) || i->first != MixerSort) {
+                       if (i->second != key) {
+                               i->second = key;
+                               changed = true;
+                       }
                }
        }
 
@@ -1421,12 +1457,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
                                boost::shared_ptr<IOProcessor> iop;
 
                                if ((iop = boost::dynamic_pointer_cast<IOProcessor> (*i)) != 0) {
-                                       if (iop->input()) {
-                                               iop->input()->disconnect (this);
-                                       }
-                                       if (iop->output()) {
-                                               iop->output()->disconnect (this);
-                                       }
+                                       iop->disconnect ();
                                }
 
                                i = _processors.erase (i);
@@ -1867,9 +1898,9 @@ Route::state(bool full_state)
        OrderKeys::iterator x = order_keys.begin();
 
        while (x != order_keys.end()) {
-               order_string += string ((*x).first);
+               order_string += enum_2_string ((*x).first);
                order_string += '=';
-               snprintf (buf, sizeof(buf), "%ld", (*x).second);
+               snprintf (buf, sizeof(buf), "%" PRId32, (*x).second);
                order_string += buf;
 
                ++x;
@@ -1895,10 +1926,12 @@ Route::state(bool full_state)
        node->add_child_nocopy (_mute_control->get_state ());
        node->add_child_nocopy (_mute_master->get_state ());
 
-       XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
-       snprintf (buf, sizeof (buf), "%d", _remote_control_id);
-       remote_control_node->add_property (X_("id"), buf);
-       node->add_child_nocopy (*remote_control_node);
+       if (_remote_control_id) {
+               XMLNode* remote_control_node = new XMLNode (X_("RemoteControl"));
+               snprintf (buf, sizeof (buf), "%d", *_remote_control_id);
+               remote_control_node->add_property (X_("id"), buf);
+               node->add_child_nocopy (*remote_control_node);
+       }
 
        if (_comment.length()) {
                XMLNode *cmt = node->add_child ("Comment");
@@ -2089,7 +2122,18 @@ Route::set_state (const XMLNode& node, int version)
                                        error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
                                              << endmsg;
                                } else {
-                                       set_order_key (remaining.substr (0, equal), n);
+                                       string keyname = remaining.substr (0, equal);
+                                       RouteSortOrderKey sk;
+
+                                       if (keyname == "signal") {
+                                               sk = MixerSort;
+                                       } else if (keyname == "editor") {
+                                               sk = EditorSort;
+                                       } else {
+                                               RouteSortOrderKey sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk);
+                                       }
+
+                                       set_order_key (sk, n);
                                }
                        }
 
@@ -2285,7 +2329,18 @@ Route::set_state_2X (const XMLNode& node, int version)
                                        error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
                                                << endmsg;
                                } else {
-                                       set_order_key (remaining.substr (0, equal), n);
+                                       string keyname = remaining.substr (0, equal);
+                                       RouteSortOrderKey sk;
+
+                                       if (keyname == "signal") {
+                                               sk = MixerSort;
+                                       } else if (keyname == "editor") {
+                                               sk = EditorSort;
+                                       } else {
+                                               RouteSortOrderKey sk = (RouteSortOrderKey) string_2_enum (remaining.substr (0, equal), sk);
+                                       }
+
+                                       set_order_key (sk, n);
                                }
                        }
 
index fbf406fd9245acb66abfbc5e2d522fd54d264f0e..13264ff9fa342c210a0771273304b3e7e7643629 100644 (file)
@@ -170,7 +170,7 @@ struct RouteRecEnabledComparator
                if (r1->record_enabled()) {
                        if (r2->record_enabled()) {
                                /* both rec-enabled, just use signal order */
-                               return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+                               return r1->order_key (MixerSort) < r2->order_key (MixerSort);
                        } else {
                                /* r1 rec-enabled, r2 not rec-enabled, run r2 early */
                                return false;
@@ -181,7 +181,7 @@ struct RouteRecEnabledComparator
                                return true;
                        } else {
                                /* neither rec-enabled, use signal order */
-                               return r1->order_key(N_("signal")) < r2->order_key(N_("signal"));
+                               return r1->order_key (MixerSort) < r2->order_key (MixerSort);
                        }
                }
        }
index f6d5b2bbd1dba04a47a59c1b1231c6447802cba6..a38f6a129a6fb54f4a29c1cce9b8a3d0fe06445e 100644 (file)
@@ -1515,7 +1515,7 @@ Session::resort_routes_using (boost::shared_ptr<RouteList> r)
                DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
                        DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 signal order %2\n",
-                                                                  (*i)->name(), (*i)->order_key ("signal")));
+                                                                  (*i)->name(), (*i)->order_key (MixerSort)));
                }
 #endif
 
@@ -1602,12 +1602,9 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
        string port;
        RouteList new_routes;
        list<boost::shared_ptr<MidiTrack> > ret;
-       uint32_t control_id;
 
        cerr << "Adding MIDI track with in = " << input << " out = " << output << endl;
 
-       control_id = next_control_id ();
-
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("MIDI");
 
        while (how_many) {
@@ -1650,7 +1647,10 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
                        }
 
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
-                       track->set_remote_control_id (control_id);
+
+                       if (Config->get_remote_model() == UserOrdered) {
+                               track->set_remote_control_id (next_control_id());
+                       }
 
                        new_routes.push_back (track);
                        ret.push_back (track);
@@ -1839,9 +1839,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
        string port;
        RouteList new_routes;
        list<boost::shared_ptr<AudioTrack> > ret;
-       uint32_t control_id;
-
-       control_id = next_control_id ();
 
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Audio");
 
@@ -1892,8 +1889,9 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
                        track->non_realtime_input_change();
 
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
-                       track->set_remote_control_id (control_id);
-                       ++control_id;
+                       if (Config->get_remote_model() == UserOrdered) {
+                               track->set_remote_control_id (next_control_id());
+                       }
 
                        new_routes.push_back (track);
                        ret.push_back (track);
@@ -1921,33 +1919,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
        return ret;
 }
 
-void
-Session::set_remote_control_ids ()
-{
-       RemoteModel m = Config->get_remote_model();
-       bool emit_signal = false;
-
-       boost::shared_ptr<RouteList> r = routes.reader ();
-
-       for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-               if (MixerOrdered == m) {
-                       int32_t order = (*i)->order_key(N_("signal"));
-                       (*i)->set_remote_control_id (order+1, false);
-                       emit_signal = true;
-               } else if (EditorOrdered == m) {
-                       int32_t order = (*i)->order_key(N_("editor"));
-                       (*i)->set_remote_control_id (order+1, false);
-                       emit_signal = true;
-               } else if (UserOrdered == m) {
-                       //do nothing ... only changes to remote id's are initiated by user
-               }
-       }
-
-       if (emit_signal) {
-               Route::RemoteControlIDChange();
-       }
-}
-
 /** Caller must not hold process lock.
  *  @param name_template string to use for the start of the name, or "" to use "Bus".
  */
@@ -1958,9 +1929,6 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
        uint32_t bus_id = 0;
        string port;
        RouteList ret;
-       uint32_t control_id;
-
-       control_id = next_control_id ();
 
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
        
@@ -2002,8 +1970,9 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
                        if (route_group) {
                                route_group->add (bus);
                        }
-                       bus->set_remote_control_id (control_id);
-                       ++control_id;
+                       if (Config->get_remote_model() == UserOrdered) {
+                               bus->set_remote_control_id (next_control_id());
+                       }
 
                        bus->add_internal_return ();
 
@@ -2390,7 +2359,7 @@ Session::remove_route (boost::shared_ptr<Route> route)
 
        route->drop_references ();
 
-       sync_order_keys (N_("session"));
+       sync_order_keys (UndefinedSort);
 
        Route::RemoteControlIDChange(); /* EMIT SIGNAL */
 
@@ -3481,7 +3450,7 @@ Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::
        if (b->is_monitor()) {
                return false;
        }
-       return a->order_key(N_("signal")) < b->order_key(N_("signal"));
+       return a->order_key (MixerSort) < b->order_key (MixerSort);
 }
 
 bool
@@ -4182,7 +4151,7 @@ Session::add_automation_list(AutomationList *al)
 }
 
 void
-Session::sync_order_keys (std::string const & base)
+Session::sync_order_keys (RouteSortOrderKey base)
 {
        if (deletion_in_progress()) {
                return;
@@ -4200,10 +4169,6 @@ Session::sync_order_keys (std::string const & base)
        }
 
        Route::SyncOrderKeys (base); // EMIT SIGNAL
-
-       /* this might not do anything */
-
-       set_remote_control_ids ();
 }
 
 /** @return true if there is at least one record-enabled track, otherwise false */
@@ -4781,7 +4746,32 @@ Session::session_name_is_legal (const string& path)
 uint32_t 
 Session::next_control_id () const
 {
-       return ntracks() + nbusses() + 1;
+       int subtract = 0;
+
+       /* the master and monitor bus remote ID's occupy a different
+        * "namespace" than regular routes. their existence doesn't
+        * affect normal (low) numbered routes.
+        */
+
+       if (_master_out) {
+               subtract++;
+       }
+
+       if (_monitor_out) {
+               subtract++;
+       }
+
+       /* remote control IDs are based either on this
+          value, or signal order, which is zero-based. so we have
+          to ensure consistency of zero-based-ness for both
+          sources of the number.
+          
+          we actually add 1 to the value to form an actual
+          remote control ID, which is 1-based.
+       */
+
+       cerr << "Next control ID will be " << ntracks() + (nbusses() - subtract) << endl;
+       return ntracks() + (nbusses() - subtract);
 }
 
 bool
index 9ea202ee671ff1f6f9a83cefa88c48dd63691084..1509a757ebf8cfd1428594666a8e7ee38fa6f00d 100644 (file)
@@ -3109,11 +3109,13 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
        }
 
        case ControllableDescriptor::RemoteControlID:
+               cerr << "RID " << desc.rid() << endl;
                r = route_by_remote_id (desc.rid());
                break;
        }
 
        if (!r) {
+               cerr << "no controllable with no route\n";
                return c;
        }
 
@@ -3196,11 +3198,15 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
                        --send;
                }
 
+               cerr << "Look for send " << send << endl;
+
                boost::shared_ptr<Processor> p = r->nth_send (send);
 
                if (p) {
                        boost::shared_ptr<Send> s = boost::dynamic_pointer_cast<Send>(p);
                        boost::shared_ptr<Amp> a = s->amp();
+                       
+                       cerr << " looked for send " << send << " got " << s << " amp = " << a << endl;
 
                        if (a) {
                                c = s->amp()->gain_control();
@@ -3551,14 +3557,12 @@ Session::config_changed (std::string p, bool ours)
                } else {
                        switch_to_sync_source (config.get_sync_source());
                }
-       } else if (p == "remote-model") {
-               set_remote_control_ids ();
        }  else if (p == "denormal-model") {
                setup_fpu ();
        } else if (p == "history-depth") {
                set_history_depth (Config->get_history_depth());
        } else if (p == "sync-all-route-ordering") {
-               sync_order_keys ("session");
+               sync_order_keys (UndefinedSort);
        } else if (p == "initial-program-change") {
 
                if (MIDI::Manager::instance()->mmc()->output_port() && Config->get_initial_program_change() >= 0) {