first vaguely working version using PresentationInfo
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 16 May 2016 11:30:28 +0000 (07:30 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 31 May 2016 19:30:42 +0000 (15:30 -0400)
remote control ID and "order keys" have been removed.

65 files changed:
gtk2_ardour/ardour_ui.cc
gtk2_ardour/ardour_ui.h
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_canvas_events.cc
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_pt_import.cc
gtk2_ardour/editor_routes.cc
gtk2_ardour/editor_routes.h
gtk2_ardour/editor_selection.cc
gtk2_ardour/editor_summary.cc
gtk2_ardour/export_channel_selector.cc
gtk2_ardour/group_tabs.cc
gtk2_ardour/group_tabs.h
gtk2_ardour/luasignal_syms.h
gtk2_ardour/meter_strip.cc
gtk2_ardour/meterbridge.cc
gtk2_ardour/meterbridge.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/port_matrix.cc
gtk2_ardour/route_ui.cc
gtk2_ardour/vca_master_strip.cc
gtk2_ardour/vca_master_strip.h
libs/ardour/ardour/audio_track.h
libs/ardour/ardour/midi_track.h
libs/ardour/ardour/mute_control.h
libs/ardour/ardour/presentation_info.h [new file with mode: 0644]
libs/ardour/ardour/route.h
libs/ardour/ardour/route_sorters.h [deleted file]
libs/ardour/ardour/session.h
libs/ardour/ardour/stripable.h
libs/ardour/ardour/track.h
libs/ardour/audio_track.cc
libs/ardour/auditioner.cc
libs/ardour/enums.cc
libs/ardour/luabindings.cc
libs/ardour/midi_track.cc
libs/ardour/presentation_info.cc [new file with mode: 0644]
libs/ardour/route.cc
libs/ardour/route_graph.cc
libs/ardour/route_group.cc
libs/ardour/session.cc
libs/ardour/session_midi.cc
libs/ardour/session_state.cc
libs/ardour/stripable.cc [new file with mode: 0644]
libs/ardour/track.cc
libs/ardour/vca.cc
libs/ardour/wscript
libs/surfaces/control_protocol/control_protocol.cc
libs/surfaces/control_protocol/control_protocol/control_protocol.h
libs/surfaces/generic_midi/generic_midi_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/strip.cc
libs/surfaces/osc/osc.cc
libs/surfaces/osc/osc_controllable.cc
libs/surfaces/osc/osc_route_observer.cc

index 6ecfd9772c7116e5e21821e3c04f9bb110977918..3ca1bd9394f685d934ba8289ed940b22219a0c8d 100644 (file)
@@ -1818,7 +1818,8 @@ ARDOUR_UI::session_add_mixed_track (
                const string& name_template,
                bool strict_io,
                PluginInfoPtr instrument,
                const string& name_template,
                bool strict_io,
                PluginInfoPtr instrument,
-               Plugin::PresetRecord* pset)
+               Plugin::PresetRecord* pset,
+               ARDOUR::PresentationInfo::order_t order)
 {
        list<boost::shared_ptr<MidiTrack> > tracks;
 
 {
        list<boost::shared_ptr<MidiTrack> > tracks;
 
@@ -1828,7 +1829,7 @@ ARDOUR_UI::session_add_mixed_track (
        }
 
        try {
        }
 
        try {
-               tracks = _session->new_midi_track (input, output, instrument, ARDOUR::Normal, route_group, how_many, name_template, pset);
+               tracks = _session->new_midi_track (input, output, instrument, pset, route_group, how_many, name_template, order, ARDOUR::Normal);
 
                if (tracks.size() != how_many) {
                        error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg;
 
                if (tracks.size() != how_many) {
                        error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg;
@@ -1854,7 +1855,8 @@ ARDOUR_UI::session_add_midi_bus (
                const string& name_template,
                bool strict_io,
                PluginInfoPtr instrument,
                const string& name_template,
                bool strict_io,
                PluginInfoPtr instrument,
-               Plugin::PresetRecord* pset)
+               Plugin::PresetRecord* pset,
+               ARDOUR::PresentationInfo::order_t order)
 {
        RouteList routes;
 
 {
        RouteList routes;
 
@@ -1864,7 +1866,8 @@ ARDOUR_UI::session_add_midi_bus (
        }
 
        try {
        }
 
        try {
-               routes = _session->new_midi_route (route_group, how_many, name_template, instrument, pset);
+
+               routes = _session->new_midi_route (route_group, how_many, name_template, instrument, pset, PresentationInfo::MidiBus, order);
                if (routes.size() != how_many) {
                        error << string_compose(P_("could not create %1 new Midi Bus", "could not create %1 new Midi Busses", how_many), how_many) << endmsg;
                }
                if (routes.size() != how_many) {
                        error << string_compose(P_("could not create %1 new Midi Bus", "could not create %1 new Midi Busses", how_many), how_many) << endmsg;
                }
@@ -1890,15 +1893,16 @@ ARDOUR_UI::session_add_midi_route (
                const string& name_template,
                bool strict_io,
                PluginInfoPtr instrument,
                const string& name_template,
                bool strict_io,
                PluginInfoPtr instrument,
-               Plugin::PresetRecord* pset)
+               Plugin::PresetRecord* pset,
+               ARDOUR::PresentationInfo::order_t order)
 {
        ChanCount one_midi_channel;
        one_midi_channel.set (DataType::MIDI, 1);
 
        if (disk) {
 {
        ChanCount one_midi_channel;
        one_midi_channel.set (DataType::MIDI, 1);
 
        if (disk) {
-               session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, strict_io, instrument, pset);
+               session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, strict_io, order, instrument, pset);
        } else {
        } else {
-               session_add_midi_bus (route_group, how_many, name_template, strict_io, instrument, pset);
+               session_add_midi_bus (route_group, how_many, name_template, strict_io, order, instrument, pset);
        }
 }
 
        }
 }
 
@@ -1911,8 +1915,8 @@ ARDOUR_UI::session_add_audio_route (
        RouteGroup* route_group,
        uint32_t how_many,
        string const & name_template,
        RouteGroup* route_group,
        uint32_t how_many,
        string const & name_template,
-       bool strict_io
-       )
+       bool strict_io,
+       ARDOUR::PresentationInfo::order_t order)
 {
        list<boost::shared_ptr<AudioTrack> > tracks;
        RouteList routes;
 {
        list<boost::shared_ptr<AudioTrack> > tracks;
        RouteList routes;
@@ -1924,7 +1928,7 @@ ARDOUR_UI::session_add_audio_route (
 
        try {
                if (track) {
 
        try {
                if (track) {
-                       tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many, name_template);
+                       tracks = _session->new_audio_track (input_channels, output_channels, route_group, how_many, name_template, order, mode);
 
                        if (tracks.size() != how_many) {
                                error << string_compose (P_("could not create %1 new audio track", "could not create %1 new audio tracks", how_many), how_many)
 
                        if (tracks.size() != how_many) {
                                error << string_compose (P_("could not create %1 new audio track", "could not create %1 new audio tracks", how_many), how_many)
@@ -1933,7 +1937,7 @@ ARDOUR_UI::session_add_audio_route (
 
                } else {
 
 
                } else {
 
-                       routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template);
+                       routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template, PresentationInfo::AudioBus, order);
 
                        if (routes.size() != how_many) {
                                error << string_compose (P_("could not create %1 new audio bus", "could not create %1 new audio busses", how_many), how_many)
 
                        if (routes.size() != how_many) {
                                error << string_compose (P_("could not create %1 new audio bus", "could not create %1 new audio busses", how_many), how_many)
@@ -2377,7 +2381,7 @@ ARDOUR_UI::transport_forward (int option)
 }
 
 void
 }
 
 void
-ARDOUR_UI::toggle_record_enable (uint32_t rid)
+ARDOUR_UI::toggle_record_enable (uint16_t rid)
 {
        if (!_session) {
                return;
 {
        if (!_session) {
                return;
@@ -2385,7 +2389,7 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid)
 
        boost::shared_ptr<Route> r;
 
 
        boost::shared_ptr<Route> r;
 
-       if ((r = _session->route_by_remote_id (rid)) != 0) {
+       if ((r = _session->get_remote_nth_route (rid)) != 0) {
 
                boost::shared_ptr<Track> t;
 
 
                boost::shared_ptr<Track> t;
 
@@ -3902,15 +3906,15 @@ ARDOUR_UI::cleanup_peakfiles ()
        }
 }
 
        }
 }
 
-void
-ARDOUR_UI::setup_order_hint (AddRouteDialog::InsertAt place)
+PresentationInfo::order_t
+ARDOUR_UI::translate_order (AddRouteDialog::InsertAt place)
 {
 {
-       uint32_t order_hint = UINT32_MAX;
-
        if (editor->get_selection().tracks.empty()) {
        if (editor->get_selection().tracks.empty()) {
-               return;
+               return PresentationInfo::max_order;
        }
 
        }
 
+       PresentationInfo::order_t order_hint = PresentationInfo::max_order;
+
        /*
          we want the new routes to have their order keys set starting from
          the highest order key in the selection + 1 (if available).
        /*
          we want the new routes to have their order keys set starting from
          the highest order key in the selection + 1 (if available).
@@ -3919,42 +3923,21 @@ ARDOUR_UI::setup_order_hint (AddRouteDialog::InsertAt place)
        if (place == AddRouteDialog::AfterSelection) {
                RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.back());
                if (rtav) {
        if (place == AddRouteDialog::AfterSelection) {
                RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.back());
                if (rtav) {
-                       order_hint = rtav->route()->order_key();
+                       order_hint = rtav->route()->presentation_info().group_order();
                        order_hint++;
                }
        } else if (place == AddRouteDialog::BeforeSelection) {
                RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.front());
                if (rtav) {
                        order_hint++;
                }
        } else if (place == AddRouteDialog::BeforeSelection) {
                RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.front());
                if (rtav) {
-                       order_hint = rtav->route()->order_key();
+                       order_hint = rtav->route()->presentation_info().group_order();
                }
        } else if (place == AddRouteDialog::First) {
                order_hint = 0;
        } else {
                }
        } else if (place == AddRouteDialog::First) {
                order_hint = 0;
        } else {
-               /* leave order_hint at UINT32_MAX */
-       }
-
-       if (order_hint == UINT32_MAX) {
-               /** AddRouteDialog::Last or selection with first/last not a RouteTimeAxisView
-                * not setting an order hint will place new routes last.
-                */
-               return;
+               /* leave order_hint at max_order */
        }
 
        }
 
-       _session->set_order_hint (order_hint);
-
-       /* create a gap in the existing route order keys to accomodate new routes.*/
-       boost::shared_ptr <RouteList> rd = _session->get_routes();
-       for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
-               boost::shared_ptr<Route> rt (*ri);
-
-               if (rt->is_monitor()) {
-                       continue;
-               }
-
-               if (rt->order_key () >= order_hint) {
-                       rt->set_order_key (rt->order_key () + add_route_dialog->count());
-               }
-       }
+       return order_hint;
 }
 
 void
 }
 
 void
@@ -4001,7 +3984,7 @@ ARDOUR_UI::add_route ()
                return;
        }
 
                return;
        }
 
-       setup_order_hint(add_route_dialog->insert_at());
+       PresentationInfo::order_t order = translate_order (add_route_dialog->insert_at());
        string template_path = add_route_dialog->track_template();
        DisplaySuspender ds;
 
        string template_path = add_route_dialog->track_template();
        DisplaySuspender ds;
 
@@ -4033,19 +4016,19 @@ ARDOUR_UI::add_route ()
 
        switch (add_route_dialog->type_wanted()) {
        case AddRouteDialog::AudioTrack:
 
        switch (add_route_dialog->type_wanted()) {
        case AddRouteDialog::AudioTrack:
-               session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io);
+               session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io, order);
                break;
        case AddRouteDialog::MidiTrack:
                break;
        case AddRouteDialog::MidiTrack:
-               session_add_midi_track (route_group, count, name_template, strict_io, instrument);
+               session_add_midi_track (route_group, count, name_template, strict_io, instrument, 0, order);
                break;
        case AddRouteDialog::MixedTrack:
                break;
        case AddRouteDialog::MixedTrack:
-               session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0);
+               session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0, order);
                break;
        case AddRouteDialog::AudioBus:
                break;
        case AddRouteDialog::AudioBus:
-               session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template, strict_io);
+               session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template, strict_io, order);
                break;
        case AddRouteDialog::MidiBus:
                break;
        case AddRouteDialog::MidiBus:
-               session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0);
+               session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0, order);
                break;
        case AddRouteDialog::VCAMaster:
                session_add_vca (name_template, count);
                break;
        case AddRouteDialog::VCAMaster:
                session_add_vca (name_template, count);
index 737cb110af0ed8c2f43059818e158e026375a126..0a7996ebbd4e9fb5e980f85aa2d975558642b905 100644 (file)
@@ -281,9 +281,10 @@ public:
                ARDOUR::RouteGroup* route_group,
                uint32_t how_many,
                std::string const & name_template,
                ARDOUR::RouteGroup* route_group,
                uint32_t how_many,
                std::string const & name_template,
-               bool strict_io
+               bool strict_io,
+               ARDOUR::PresentationInfo::order_t order
                ) {
                ) {
-               session_add_audio_route (true, input_channels, output_channels, mode, route_group, how_many, name_template, strict_io);
+               session_add_audio_route (true, input_channels, output_channels, mode, route_group, how_many, name_template, strict_io, order);
        }
 
        void session_add_audio_bus (
        }
 
        void session_add_audio_bus (
@@ -292,9 +293,10 @@ public:
                        ARDOUR::RouteGroup* route_group,
                        uint32_t how_many,
                        std::string const & name_template,
                        ARDOUR::RouteGroup* route_group,
                        uint32_t how_many,
                        std::string const & name_template,
-                       bool strict_io
+                       bool strict_io,
+                       ARDOUR::PresentationInfo::order_t order
                        ) {
                        ) {
-               session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, route_group, how_many, name_template, strict_io);
+               session_add_audio_route (false, input_channels, output_channels, ARDOUR::Normal, route_group, how_many, name_template, strict_io, order);
        }
 
        void session_add_midi_track (
        }
 
        void session_add_midi_track (
@@ -302,15 +304,20 @@ public:
                        uint32_t how_many,
                        std::string const & name_template,
                        bool strict_io,
                        uint32_t how_many,
                        std::string const & name_template,
                        bool strict_io,
+                       ARDOUR::PresentationInfo::order_t order,
                        ARDOUR::PluginInfoPtr instrument,
                        ARDOUR::Plugin::PresetRecord* preset = NULL) {
                        ARDOUR::PluginInfoPtr instrument,
                        ARDOUR::Plugin::PresetRecord* preset = NULL) {
-               session_add_midi_route (true, route_group, how_many, name_template, strict_io, instrument, preset);
+               session_add_midi_route (true, route_group, how_many, name_template, strict_io, order, instrument, preset);
        }
 
        }
 
-       void session_add_mixed_track (const ARDOUR::ChanCount&, const ARDOUR::ChanCount&, ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
-       void session_add_midi_bus (ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
-       void session_add_audio_route (bool, int32_t, int32_t, ARDOUR::TrackMode, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool);
-       void session_add_midi_route (bool, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
+       void session_add_mixed_track (const ARDOUR::ChanCount&, const ARDOUR::ChanCount&, ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr,
+                                     ARDOUR::PresentationInfo::order_t order);
+       void session_add_midi_bus (ARDOUR::RouteGroup*, uint32_t, std::string const &, bool, ARDOUR::PluginInfoPtr,
+                                  ARDOUR::PresentationInfo::order_t order);
+       void session_add_audio_route (bool, int32_t, int32_t, ARDOUR::TrackMode, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool,
+                                     ARDOUR::PresentationInfo::order_t order);
+       void session_add_midi_route (bool, ARDOUR::RouteGroup *, uint32_t, std::string const &, bool, ARDOUR::PresentationInfo::order_t order,
+                                    ARDOUR::PluginInfoPtr, ARDOUR::Plugin::PresetRecord*);
 
        void display_insufficient_ports_message ();
 
 
        void display_insufficient_ports_message ();
 
@@ -401,7 +408,7 @@ private:
        void button_change_tabbable_visibility (Gtkmm2ext::Tabbable*);
        void key_change_tabbable_visibility (Gtkmm2ext::Tabbable*);
        void toggle_editor_and_mixer ();
        void button_change_tabbable_visibility (Gtkmm2ext::Tabbable*);
        void key_change_tabbable_visibility (Gtkmm2ext::Tabbable*);
        void toggle_editor_and_mixer ();
-       
+
        void tabbable_state_change (Gtkmm2ext::Tabbable&);
 
        void toggle_meterbridge ();
        void tabbable_state_change (Gtkmm2ext::Tabbable&);
 
        void toggle_meterbridge ();
@@ -664,7 +671,7 @@ private:
        bool save_as_progress_update (float fraction, int64_t cnt, int64_t total, Gtk::Label* label, Gtk::ProgressBar* bar);
        void save_session_as ();
        void rename_session ();
        bool save_as_progress_update (float fraction, int64_t cnt, int64_t total, Gtk::Label* label, Gtk::ProgressBar* bar);
        void save_session_as ();
        void rename_session ();
-       void setup_order_hint (AddRouteDialog::InsertAt);
+       ARDOUR::PresentationInfo::order_t translate_order (AddRouteDialog::InsertAt);
 
        int         create_mixer ();
        int         create_editor ();
 
        int         create_mixer ();
        int         create_editor ();
@@ -720,7 +727,7 @@ private:
 
        void install_actions ();
 
 
        void install_actions ();
 
-       void toggle_record_enable (uint32_t);
+       void toggle_record_enable (uint16_t);
 
        uint32_t rec_enabled_streams;
        void count_recenabled_streams (ARDOUR::Route&);
 
        uint32_t rec_enabled_streams;
        void count_recenabled_streams (ARDOUR::Route&);
index 345694d1015de02cb12811ee1f3c4fb9fbb23af5..3dbdd8a9925913cbfd3f09022ae688db71829bdc 100644 (file)
@@ -1000,7 +1000,7 @@ Editor::control_unselect ()
 }
 
 void
 }
 
 void
-Editor::control_select (uint32_t rid, Selection::Operation op)
+Editor::control_select (uint16_t rid, Selection::Operation op)
 {
        /* handles the (static) signal from the ControlProtocol class that
         * requests setting the selected track to a given RID
 {
        /* handles the (static) signal from the ControlProtocol class that
         * requests setting the selected track to a given RID
@@ -1010,7 +1010,7 @@ Editor::control_select (uint32_t rid, Selection::Operation op)
                return;
        }
 
                return;
        }
 
-       boost::shared_ptr<Route> r = _session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = _session->get_remote_nth_route (rid);
 
        if (!r) {
                return;
 
        if (!r) {
                return;
index 0fd9fccec188e6b3cefc45f993af26f2e189dcbf..9f579a3d81cb976c7a8de135145a6ee7cf8408ee 100644 (file)
@@ -1088,7 +1088,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
        void control_step_tracks_down ();
        void control_view (uint32_t);
        void control_scroll (float);
        void control_step_tracks_down ();
        void control_view (uint32_t);
        void control_scroll (float);
-       void control_select (uint32_t rid, Selection::Operation);
+       void control_select (uint16_t rid, Selection::Operation);
        void control_unselect ();
        void access_action (std::string,std::string);
        bool deferred_control_scroll (framepos_t);
        void control_unselect ();
        void access_action (std::string,std::string);
        bool deferred_control_scroll (framepos_t);
index e35e566dee96c9f2cadc639fc42f8d808970b32b..11a53c426873a8527a95615a018d9bc503ea9365 100644 (file)
@@ -937,7 +937,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
        {
                if (!existing_track) {
                        if (ar) {
        {
                if (!existing_track) {
                        if (ar) {
-                               list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Normal, 0, 1));
+                               list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, 0, 1, string(), PresentationInfo::max_order, Normal));
 
                                if (at.empty()) {
                                        return -1;
 
                                if (at.empty()) {
                                        return -1;
@@ -954,7 +954,8 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
                                        _session->new_midi_track (ChanCount (DataType::MIDI, 1),
                                                                  ChanCount (DataType::MIDI, 1),
                                                                  instrument,
                                        _session->new_midi_track (ChanCount (DataType::MIDI, 1),
                                                                  ChanCount (DataType::MIDI, 1),
                                                                  instrument,
-                                                                 Normal, 0, 1));
+                                                                 0, 1, string(),
+                                                                 PresentationInfo::max_order));
 
                                if (mt.empty()) {
                                        return -1;
 
                                if (mt.empty()) {
                                        return -1;
@@ -990,7 +991,7 @@ Editor::finish_bringing_in_material (boost::shared_ptr<Region> region,
                        return -1;
                }
 
                        return -1;
                }
 
-               list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, Destructive));
+               list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (in_chans, out_chans, 0, 1, string(), PresentationInfo::max_order, Destructive));
                if (!at.empty()) {
                        boost::shared_ptr<Playlist> playlist = at.front()->playlist();
                        boost::shared_ptr<Region> copy (RegionFactory::create (region, true));
                if (!at.empty()) {
                        boost::shared_ptr<Playlist> playlist = at.front()->playlist();
                        boost::shared_ptr<Region> copy (RegionFactory::create (region, true));
index 22c701673eb2c120e3a155c235eb6bc8e049faf8..559961512dbd3411af511d54c3f483967c53c60a 100644 (file)
@@ -1280,12 +1280,12 @@ Editor::drop_regions (const Glib::RefPtr<Gdk::DragContext>& /*context*/,
                                        output_chan =  session()->master_out()->n_inputs().n_audio();
                                }
                                list<boost::shared_ptr<AudioTrack> > audio_tracks;
                                        output_chan =  session()->master_out()->n_inputs().n_audio();
                                }
                                list<boost::shared_ptr<AudioTrack> > audio_tracks;
-                               audio_tracks = session()->new_audio_track (region->n_channels(), output_chan, ARDOUR::Normal, 0, 1, region->name());
+                               audio_tracks = session()->new_audio_track (region->n_channels(), output_chan, 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
                                rtav = axis_view_from_route (audio_tracks.front());
                        } else if (boost::dynamic_pointer_cast<MidiRegion> (region)) {
                                ChanCount one_midi_port (DataType::MIDI, 1);
                                list<boost::shared_ptr<MidiTrack> > midi_tracks;
                                rtav = axis_view_from_route (audio_tracks.front());
                        } else if (boost::dynamic_pointer_cast<MidiRegion> (region)) {
                                ChanCount one_midi_port (DataType::MIDI, 1);
                                list<boost::shared_ptr<MidiTrack> > midi_tracks;
-                               midi_tracks = session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), ARDOUR::Normal, 0, 1, region->name());
+                               midi_tracks = session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
                                rtav = axis_view_from_route (midi_tracks.front());
                        } else {
                                return;
                                rtav = axis_view_from_route (midi_tracks.front());
                        } else {
                                return;
index f209aed59da1b32141c0536163aafd6d2ad66426..16b52b9330e24aa53ad8d2ded42e04354b80c162 100644 (file)
@@ -525,12 +525,12 @@ Drag::add_midi_region (MidiTimeAxisView* view, bool commit)
        return boost::shared_ptr<Region>();
 }
 
        return boost::shared_ptr<Region>();
 }
 
-struct EditorOrderTimeAxisViewSorter {
+struct PresentationInfoTimeAxisViewSorter {
        bool operator() (TimeAxisView* a, TimeAxisView* b) {
                RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a);
                RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b);
                assert (ra && rb);
        bool operator() (TimeAxisView* a, TimeAxisView* b) {
                RouteTimeAxisView* ra = dynamic_cast<RouteTimeAxisView*> (a);
                RouteTimeAxisView* rb = dynamic_cast<RouteTimeAxisView*> (b);
                assert (ra && rb);
-               return ra->route()->order_key () < rb->route()->order_key ();
+               return ra->route()->presentation_info () < rb->route()->presentation_info();
        }
 };
 
        }
 };
 
@@ -546,7 +546,7 @@ RegionDrag::RegionDrag (Editor* e, ArdourCanvas::Item* i, RegionView* p, list<Re
        */
 
        TrackViewList track_views = _editor->track_views;
        */
 
        TrackViewList track_views = _editor->track_views;
-       track_views.sort (EditorOrderTimeAxisViewSorter ());
+       track_views.sort (PresentationInfoTimeAxisViewSorter ());
 
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                _time_axis_views.push_back (*i);
 
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                _time_axis_views.push_back (*i);
@@ -1397,7 +1397,7 @@ RegionMoveDrag::create_destination_time_axis (boost::shared_ptr<Region> region,
                        if ((Config->get_output_auto_connect() & AutoConnectMaster) && _editor->session()->master_out()) {
                                output_chan =  _editor->session()->master_out()->n_inputs().n_audio();
                        }
                        if ((Config->get_output_auto_connect() & AutoConnectMaster) && _editor->session()->master_out()) {
                                output_chan =  _editor->session()->master_out()->n_inputs().n_audio();
                        }
-                       audio_tracks = _editor->session()->new_audio_track (region->n_channels(), output_chan, ARDOUR::Normal, 0, 1, region->name());
+                       audio_tracks = _editor->session()->new_audio_track (region->n_channels(), output_chan, 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
                        RouteTimeAxisView* rtav = _editor->axis_view_from_route (audio_tracks.front());
                        if (rtav) {
                                rtav->set_height (original->current_height());
                        RouteTimeAxisView* rtav = _editor->axis_view_from_route (audio_tracks.front());
                        if (rtav) {
                                rtav->set_height (original->current_height());
@@ -1406,7 +1406,7 @@ RegionMoveDrag::create_destination_time_axis (boost::shared_ptr<Region> region,
                } else {
                        ChanCount one_midi_port (DataType::MIDI, 1);
                        list<boost::shared_ptr<MidiTrack> > midi_tracks;
                } else {
                        ChanCount one_midi_port (DataType::MIDI, 1);
                        list<boost::shared_ptr<MidiTrack> > midi_tracks;
-                       midi_tracks = _editor->session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), ARDOUR::Normal, 0, 1, region->name());
+                       midi_tracks = _editor->session()->new_midi_track (one_midi_port, one_midi_port, boost::shared_ptr<ARDOUR::PluginInfo>(), 0, 1, region->name(), PresentationInfo::max_order, ARDOUR::Normal);
                        RouteTimeAxisView* rtav = _editor->axis_view_from_route (midi_tracks.front());
                        if (rtav) {
                                rtav->set_height (original->current_height());
                        RouteTimeAxisView* rtav = _editor->axis_view_from_route (midi_tracks.front());
                        if (rtav) {
                                rtav->set_height (original->current_height());
index 48fe9e231dae1eec498e2b9990da9d23c7445a80..04446c7ce759e0e82e8a09b2907be6c51f6f9ed8 100644 (file)
@@ -192,8 +192,3 @@ EditorGroupTabs::selected_routes () const
        return rl;
 }
 
        return rl;
 }
 
-void
-EditorGroupTabs::sync_order_keys ()
-{
-       _editor->_routes->sync_order_keys_from_treeview ();
-}
index 7377911f8bd754e4546bd3374ea120284a1645a2..61e0ecfd0fdb15ddd30c5b72a1b11504cd8354b7 100644 (file)
@@ -37,5 +37,4 @@ private:
        }
        void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
        ARDOUR::RouteList selected_routes () const;
        }
        void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *);
        ARDOUR::RouteList selected_routes () const;
-       void sync_order_keys ();
 };
 };
index eb84428f92b75f1b28edc0820d4e3ae6c993b214..598725c72cd3ab019d192e3d4eeb7773f32e7d61 100644 (file)
@@ -6153,12 +6153,6 @@ Editor::split_region ()
        }
 }
 
        }
 }
 
-struct EditorOrderRouteSorter {
-    bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-           return a->order_key () < b->order_key ();
-    }
-};
-
 void
 Editor::select_next_route()
 {
 void
 Editor::select_next_route()
 {
index 23a6fd2f066f939223068b564a5040d67166063e..d0bfdec27d49e5e6028b9c01977f7de348390214 100644 (file)
@@ -244,7 +244,7 @@ Editor::do_ptimport (std::string ptpath,
                                } else {
                                        // Put on a new track
                                        DEBUG_TRACE (DEBUG::FileUtils, string_compose ("\twav(%1) reg(%2) new_tr(%3)\n", a->reg.wave.filename.c_str(), a->reg.index, nth));
                                } else {
                                        // Put on a new track
                                        DEBUG_TRACE (DEBUG::FileUtils, string_compose ("\twav(%1) reg(%2) new_tr(%3)\n", a->reg.wave.filename.c_str(), a->reg.index, nth));
-                                       list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (1, 2, Normal, 0, 1));
+                                       list<boost::shared_ptr<AudioTrack> > at (_session->new_audio_track (1, 2, 0, 1, string(), PresentationInfo::max_order, Normal));
                                        if (at.empty()) {
                                                return;
                                        }
                                        if (at.empty()) {
                                                return;
                                        }
index 7daeea3d7c9e585933e4f1dd54cd75ca012bfa1a..d28eb5d0067908388c47bd6f39f8059cdf396713 100644 (file)
@@ -28,6 +28,7 @@
 #include "pbd/unwind.h"
 
 #include "ardour/debug.h"
 #include "pbd/unwind.h"
 
 #include "ardour/debug.h"
+#include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
 #include "ardour/route.h"
 #include "ardour/session.h"
 #include "ardour/midi_track.h"
 #include "ardour/route.h"
 #include "ardour/session.h"
@@ -313,9 +314,8 @@ EditorRoutes::EditorRoutes (Editor* e)
 
        _display.set_enable_search (false);
 
 
        _display.set_enable_search (false);
 
-       Route::SyncOrderKeys.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_treeview_from_order_keys, this), gui_context());
        Route::PluginSetup.connect_same_thread (*this, boost::bind (&EditorRoutes::plugin_setup, this, _1, _2, _3));
        Route::PluginSetup.connect_same_thread (*this, boost::bind (&EditorRoutes::plugin_setup, this, _1, _2, _3));
-
+       Stripable::PresentationInfoChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::sync_treeview_from_presentation_info, this), gui_context());
 }
 
 bool
 }
 
 bool
@@ -623,27 +623,28 @@ EditorRoutes::row_deleted (Gtk::TreeModel::Path const &)
         * when a route is actually removed. we don't differentiate between
         * the two cases.
         *
         * when a route is actually removed. we don't differentiate between
         * the two cases.
         *
-        * note that the sync_orders_keys() step may not actually change any
-        * RID's (e.g. the last track may be removed, so all other tracks keep
-        * the same RID), which means that no redisplay would happen. so we
-        * have to force a redisplay.
+        * note that the sync_presentation_info_from_treeview() step may not
+        * actually change any presentation info (e.g. the last track may be
+        * removed, so all other tracks keep the same presentation info), which
+        * means that no redisplay would happen. so we have to force a
+        * redisplay.
         */
 
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n");
 
        DisplaySuspender ds;
         */
 
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview row deleted\n");
 
        DisplaySuspender ds;
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 void
 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
 {
 }
 
 void
 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
 {
-       /* reordering implies that RID's will change, so sync_order_keys() will
-          cause a redisplay.
+       /* reordering implies that RID's will change, so
+          sync_presentation_info_from_treeview() will cause a redisplay.
        */
 
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n");
        */
 
        DEBUG_TRACE (DEBUG::OrderKeys, "editor routes treeview reordered\n");
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 void
 }
 
 void
@@ -691,7 +692,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
        for (Gtk::TreeModel::Children::iterator it = _model->children().begin(); it != _model->children().end(); ++it) {
                boost::shared_ptr<Route> r = (*it)[_columns.route];
 
        for (Gtk::TreeModel::Children::iterator it = _model->children().begin(); it != _model->children().end(); ++it) {
                boost::shared_ptr<Route> r = (*it)[_columns.route];
 
-               if (r->order_key() == (routes.front()->route()->order_key() + routes.size())) {
+               if (r->presentation_info().group_order() == (routes.front()->route()->presentation_info().group_order() + routes.size())) {
                        insert_iter = it;
                        break;
                }
                        insert_iter = it;
                        break;
                }
@@ -767,7 +768,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
 
        /* now update route order keys from the treeview/track display order */
        if (!from_scratch) {
 
        /* now update route order keys from the treeview/track display order */
        if (!from_scratch) {
-               sync_order_keys_from_treeview ();
+               sync_presentation_info_from_treeview ();
        }
 }
 
        }
 }
 
@@ -862,7 +863,7 @@ EditorRoutes::update_visibility ()
        /* force route order keys catch up with visibility changes
         */
 
        /* force route order keys catch up with visibility changes
         */
 
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 void
 }
 
 void
@@ -905,60 +906,10 @@ EditorRoutes::reset_remote_control_ids ()
                return;
        }
 
                return;
        }
 
-       TreeModel::Children rows = _model->children();
-
-       if (rows.empty()) {
-               return;
-       }
-
-
-       DEBUG_TRACE (DEBUG::OrderKeys, "editor reset remote control ids\n");
-
-       TreeModel::Children::iterator ri;
-       bool rid_change = false;
-       uint32_t rid = 1;
-       uint32_t invisible_key = UINT32_MAX;
-
-       for (ri = rows.begin(); ri != rows.end(); ++ri) {
-
-               /* skip two special values */
-
-               if (rid == Route::MasterBusRemoteControlID) {
-                       rid++;
-               }
-
-               if (rid == Route::MonitorBusRemoteControlID) {
-                       rid++;
-               }
-
-               boost::shared_ptr<Route> route = (*ri)[_columns.route];
-               bool visible = (*ri)[_columns.visible];
-
-               if (!route->is_master() && !route->is_monitor()) {
-
-                       uint32_t new_rid = (visible ? rid : invisible_key--);
-
-                       if (new_rid != route->remote_control_id()) {
-                               route->set_remote_control_id_explicit (new_rid);
-                               rid_change = true;
-                       }
-
-                       if (visible) {
-                               rid++;
-                       }
-
-               }
-       }
-
-       if (rid_change) {
-               /* tell the world that we changed the remote control IDs */
-               _session->notify_remote_id_change ();
-       }
+       sync_presentation_info_from_treeview ();
 }
 }
-
-
 void
 void
-EditorRoutes::sync_order_keys_from_treeview ()
+EditorRoutes::sync_presentation_info_from_treeview ()
 {
        if (_ignore_reorder || !_session || _session->deletion_in_progress()) {
                return;
 {
        if (_ignore_reorder || !_session || _session->deletion_in_progress()) {
                return;
@@ -970,60 +921,46 @@ EditorRoutes::sync_order_keys_from_treeview ()
                return;
        }
 
                return;
        }
 
-
        DEBUG_TRACE (DEBUG::OrderKeys, "editor sync order keys from treeview\n");
 
        TreeModel::Children::iterator ri;
        DEBUG_TRACE (DEBUG::OrderKeys, "editor sync order keys from treeview\n");
 
        TreeModel::Children::iterator ri;
-       bool changed = false;
-       bool rid_change = false;
-       uint32_t order = 0;
-       uint32_t rid = 1;
-       uint32_t invisible_key = UINT32_MAX;
+       bool change = false;
+       PresentationInfo::order_t order = 0;
+
+       /* hmm, problem ... editor doesn't represent all Stripables... we can't
+          reset the whole presentation order from here.
+       */
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
 
                boost::shared_ptr<Route> route = (*ri)[_columns.route];
                bool visible = (*ri)[_columns.visible];
 
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
 
                boost::shared_ptr<Route> route = (*ri)[_columns.route];
                bool visible = (*ri)[_columns.visible];
 
-               uint32_t old_key = route->order_key ();
-
-               if (order != old_key) {
-                       route->set_order_key (order);
-
-                       changed = true;
+               if (route->presentation_info().special ()) {
+                       continue;
                }
 
                }
 
-               if ((Config->get_remote_model() == MixerOrdered) && !route->is_master() && !route->is_monitor()) {
-
-                       uint32_t new_rid = (visible ? rid : invisible_key--);
-
-                       if (new_rid != route->remote_control_id()) {
-                               route->set_remote_control_id_explicit (new_rid);
-                               rid_change = true;
-                       }
-
-                       if (visible) {
-                               rid++;
-                       }
+               if (!visible) {
+                       route->presentation_info().set_flag (PresentationInfo::Hidden);
+               } else {
+                       route->presentation_info().unset_flag (PresentationInfo::Hidden);
+               }
 
 
+               if (order != route->presentation_info().group_order()) {
+                       route->set_presentation_group_order_explicit (order);
+                       change = true;
                }
 
                ++order;
        }
 
                }
 
                ++order;
        }
 
-       if (changed) {
-               /* tell the world that we changed the editor sort keys */
-               _session->sync_order_keys ();
-       }
-
-       if (rid_change) {
-               /* tell the world that we changed the remote control IDs */
-               _session->notify_remote_id_change ();
+       if (change) {
+               Stripable::PresentationInfoChange(); /* EMIT SIGNAL */
        }
 }
 
 void
        }
 }
 
 void
-EditorRoutes::sync_treeview_from_order_keys ()
+EditorRoutes::sync_treeview_from_presentation_info ()
 {
        /* Some route order key(s) have been changed, make sure that
           we update out tree/list model and GUI to reflect the change.
 {
        /* Some route order key(s) have been changed, make sure that
           we update out tree/list model and GUI to reflect the change.
@@ -1033,7 +970,7 @@ EditorRoutes::sync_treeview_from_order_keys ()
                return;
        }
 
                return;
        }
 
-       DEBUG_TRACE (DEBUG::OrderKeys, "editor sync model from order keys.\n");
+       DEBUG_TRACE (DEBUG::OrderKeys, "editor sync model from presentation info.\n");
 
        /* we could get here after either a change in the Mixer or Editor sort
         * order, but either way, the mixer order keys reflect the intended
 
        /* we could get here after either a change in the Mixer or Editor sort
         * order, but either way, the mixer order keys reflect the intended
@@ -1053,7 +990,11 @@ EditorRoutes::sync_treeview_from_order_keys ()
 
        for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
                boost::shared_ptr<Route> route = (*ri)[_columns.route];
 
        for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri, ++old_order) {
                boost::shared_ptr<Route> route = (*ri)[_columns.route];
-               sorted.push_back (OrderKeys (old_order, route->order_key ()));
+               sorted.push_back (OrderKeys (old_order, route->presentation_info().group_order()));
+               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("build new order: route %3  old = %1 new = %1\n",
+                                                              old_order,
+                                                              route->presentation_info().group_order(),
+                                                              route->name()));
        }
 
        SortByNewDisplayOrder cmp;
        }
 
        SortByNewDisplayOrder cmp;
@@ -1128,7 +1069,7 @@ EditorRoutes::set_all_tracks_visibility (bool yn)
        /* force route order keys catch up with visibility changes
         */
 
        /* force route order keys catch up with visibility changes
         */
 
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 void
 }
 
 void
@@ -1193,7 +1134,7 @@ EditorRoutes::set_all_audio_midi_visibility (int tracks, bool yn)
        /* force route order keys catch up with visibility changes
         */
 
        /* force route order keys catch up with visibility changes
         */
 
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 void
 }
 
 void
@@ -1427,7 +1368,7 @@ EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path
        return true;
 }
 
        return true;
 }
 
-struct EditorOrderRouteSorter
+struct PresentationInfoRouteSorter
 {
        bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
                if (a->is_master()) {
 {
        bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
                if (a->is_master()) {
@@ -1437,7 +1378,7 @@ struct EditorOrderRouteSorter
                        /* everything else before master */
                        return false;
                }
                        /* everything else before master */
                        return false;
                }
-               return a->order_key () < b->order_key ();
+               return a->presentation_info().global_order () < b->presentation_info().global_order ();
        }
 };
 
        }
 };
 
@@ -1453,7 +1394,7 @@ EditorRoutes::initial_display ()
 
        RouteList r (*_session->get_routes());
 
 
        RouteList r (*_session->get_routes());
 
-       r.sort (EditorOrderRouteSorter ());
+       r.sort (PresentationInfoRouteSorter ());
        _editor->add_routes (r);
 }
 
        _editor->add_routes (r);
 }
 
@@ -1575,7 +1516,7 @@ EditorRoutes::move_selected_tracks (bool up)
        }
 
        for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
        }
 
        for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
-               uint32_t order = leading->second->order_key ();
+               uint32_t order = (uint32_t) leading->second->presentation_info().group_order ();
                neworder.push_back (order);
        }
 
                neworder.push_back (order);
        }
 
@@ -1781,7 +1722,7 @@ EditorRoutes::show_tracks_with_regions_at_playhead ()
        /* force route order keys catch up with visibility changes
         */
 
        /* force route order keys catch up with visibility changes
         */
 
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 int
 }
 
 int
index 460f66af3291bf754244a1d9972baa9d19dc2948..cd2e4deb43b412bfff657c43c3c9134548fde49f 100644 (file)
@@ -61,7 +61,7 @@ public:
        std::list<TimeAxisView*> views () const;
        void hide_all_tracks (bool);
        void clear ();
        std::list<TimeAxisView*> views () const;
        void hide_all_tracks (bool);
        void clear ();
-       void sync_order_keys_from_treeview ();
+       void sync_presentation_info_from_treeview ();
        void reset_remote_control_ids ();
 
 private:
        void reset_remote_control_ids ();
 
 private:
@@ -76,7 +76,7 @@ private:
        void on_tv_solo_safe_toggled (std::string const &);
        void build_menu ();
        void show_menu ();
        void on_tv_solo_safe_toggled (std::string const &);
        void build_menu ();
        void show_menu ();
-       void sync_treeview_from_order_keys ();
+       void sync_treeview_from_presentation_info ();
        void row_deleted (Gtk::TreeModel::Path const &);
        void visible_changed (std::string const &);
        void active_changed (std::string const &);
        void row_deleted (Gtk::TreeModel::Path const &);
        void visible_changed (std::string const &);
        void active_changed (std::string const &);
index 64d17f9ae5dbfde993a8dcff9fd9132ab72db2e4..10dc282aa0ce6612d3245b4299df129aacc72f21 100644 (file)
@@ -791,7 +791,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
 
                                        RouteTimeAxisView* closest = 0;
                                        int distance = INT_MAX;
 
                                        RouteTimeAxisView* closest = 0;
                                        int distance = INT_MAX;
-                                       int key = rtv->route()->order_key ();
+                                       int key = rtv->route()->presentation_info().global_order ();
 
                                        for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
 
 
                                        for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
 
@@ -806,7 +806,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
                                                        if (result.second) {
                                                                /* newly added to already_in_selection */
 
                                                        if (result.second) {
                                                                /* newly added to already_in_selection */
 
-                                                               int d = artv->route()->order_key ();
+                                                               int d = artv->route()->presentation_info().global_order ();
 
                                                                d -= key;
 
 
                                                                d -= key;
 
@@ -822,7 +822,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
 
                                                /* now add all tracks between that one and this one */
 
 
                                                /* now add all tracks between that one and this one */
 
-                                               int okey = closest->route()->order_key ();
+                                               int okey = closest->route()->presentation_info().global_order ();
 
                                                if (okey > key) {
                                                        swap (okey, key);
 
                                                if (okey > key) {
                                                        swap (okey, key);
@@ -832,7 +832,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op)
                                                        RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x);
                                                        if (artv && artv != rtv) {
 
                                                        RouteTimeAxisView* artv = dynamic_cast<RouteTimeAxisView*>(*x);
                                                        if (artv && artv != rtv) {
 
-                                                               int k = artv->route()->order_key ();
+                                                               int k = artv->route()->presentation_info().global_order ();
 
                                                                if (k >= okey && k <= key) {
 
 
                                                                if (k >= okey && k <= key) {
 
index ba03d91e2dce2cb9b9253c232db5fdbe84ead6e6..ecc29757f29f906d3b130db239b7a6b50b36461c 100644 (file)
@@ -107,7 +107,7 @@ EditorSummary::set_session (Session* s)
 
        if (_session) {
                Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
 
        if (_session) {
                Region::RegionPropertyChanged.connect (region_property_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
-               Route::RemoteControlIDChange.connect (route_ctrl_id_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
+               Stripable::PresentationInfoChange.connect (route_ctrl_id_connection, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
                _editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), boost::bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
                _session->StartTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
                _session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
                _editor->playhead_cursor->PositionChanged.connect (position_connection, invalidator (*this), boost::bind (&EditorSummary::playhead_position_changed, this, _1), gui_context());
                _session->StartTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
                _session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&EditorSummary::set_background_dirty, this), gui_context());
index c411c2b22c3acc490cc8ea5ae1c9406eb6d5871a..45fdc07c459d34e7d47ae960f023c69069981dc7 100644 (file)
@@ -18,8 +18,6 @@
 
 */
 
 
 */
 
-#include "export_channel_selector.h"
-
 #include <algorithm>
 
 #include "pbd/convert.h"
 #include <algorithm>
 
 #include "pbd/convert.h"
@@ -33,6 +31,9 @@
 
 #include <sstream>
 
 
 #include <sstream>
 
+#include "export_channel_selector.h"
+#include "route_sorter.h"
+
 #include "i18n.h"
 
 using namespace std;
 #include "i18n.h"
 
 using namespace std;
@@ -40,12 +41,6 @@ using namespace Glib;
 using namespace ARDOUR;
 using namespace PBD;
 
 using namespace ARDOUR;
 using namespace PBD;
 
-struct EditorOrderRouteSorter {
-    bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-           return a->order_key () < b->order_key ();
-    }
-};
-
 PortExportChannelSelector::PortExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager) :
   ExportChannelSelector (session, manager),
   channels_label (_("Channels:"), Gtk::ALIGN_LEFT),
 PortExportChannelSelector::PortExportChannelSelector (ARDOUR::Session * session, ProfileManagerPtr manager) :
   ExportChannelSelector (session, manager),
   channels_label (_("Channels:"), Gtk::ALIGN_LEFT),
@@ -126,7 +121,7 @@ PortExportChannelSelector::fill_route_list ()
                channel_view.add_route (master);
        }
 
                channel_view.add_route (master);
        }
 
-       routes.sort (EditorOrderRouteSorter ());
+       routes.sort (PresentationInfoSorter ());
 
        for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
                if ((*it)->is_master () || (*it)->is_monitor ()) {
 
        for (RouteList::iterator it = routes.begin(); it != routes.end(); ++it) {
                if ((*it)->is_master () || (*it)->is_monitor ()) {
@@ -700,7 +695,7 @@ TrackExportChannelSelector::add_track (boost::shared_ptr<Route> route)
        row[track_cols.selected] = false;
        row[track_cols.label] = route->name();
        row[track_cols.route] = route;
        row[track_cols.selected] = false;
        row[track_cols.label] = route->name();
        row[track_cols.route] = route;
-       row[track_cols.order_key] = route->order_key();
+       row[track_cols.order_key] = route->presentation_info().global_order();
 }
 
 void
 }
 
 void
index a930fbbce4b59d194cb71e8e8d68b31d0300617f..e079aa13869ae95212f6a1f79bf08a68a591b708 100644 (file)
@@ -451,13 +451,13 @@ GroupTabs::un_subgroup (RouteGroup* g)
 
 struct CollectSorter {
        bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
 
 struct CollectSorter {
        bool operator () (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-               return a->order_key () < b->order_key ();
+               return a->presentation_info () < b->presentation_info();
        }
 };
 
 struct OrderSorter {
        bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
        }
 };
 
 struct OrderSorter {
        bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-               return a->order_key () < b->order_key ();
+               return a->presentation_info() < b->presentation_info();
        }
 };
 
        }
 };
 
@@ -480,7 +480,7 @@ GroupTabs::collect (RouteGroup* g)
        int coll = -1;
        while (i != group_routes->end() && j != routes->end()) {
 
        int coll = -1;
        while (i != group_routes->end() && j != routes->end()) {
 
-               int const k = (*j)->order_key ();
+               PresentationInfo::order_t const k = (*j)->presentation_info ().group_order();
 
                if (*i == *j) {
 
 
                if (*i == *j) {
 
@@ -491,21 +491,21 @@ GroupTabs::collect (RouteGroup* g)
                                --diff;
                        }
 
                                --diff;
                        }
 
-                       (*j)->set_order_key (coll);
+                       (*j)->set_presentation_group_order_explicit (coll);
 
                        ++coll;
                        ++i;
 
                } else {
 
 
                        ++coll;
                        ++i;
 
                } else {
 
-                       (*j)->set_order_key (k + diff);
+                       (*j)->set_presentation_group_order_explicit (k + diff);
 
                }
 
                ++j;
        }
 
 
                }
 
                ++j;
        }
 
-       _session->sync_order_keys ();
+       _session->notify_presentation_info_change ();
 }
 
 void
 }
 
 void
index e31ad9643e519d7d880f7d13ca419c9b6ec7da4d..325e3f7ee76494de35964ddbee8e974cc2a1900e 100644 (file)
@@ -92,7 +92,6 @@ private:
 
        virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
        virtual ARDOUR::RouteList selected_routes () const = 0;
 
        virtual void add_menu_items (Gtk::Menu *, ARDOUR::RouteGroup *) {}
        virtual ARDOUR::RouteList selected_routes () const = 0;
-       virtual void sync_order_keys () = 0;
 
        void new_from_selection ();
        void new_from_rec_enabled ();
 
        void new_from_selection ();
        void new_from_rec_enabled ();
index 85bed3fbc46ab3f6bf5f4e2f8c813d7458fd3c7a..290db843ee57b9a790f9797dce734afed3931542 100644 (file)
@@ -61,7 +61,6 @@ SESSION(PositionChanged, PositionChanged, 1)
 SESSION(Located, Located, 0)
 SESSION(RoutesReconnected, session_routes_reconnected, 0)
 SESSION(RouteAdded, RouteAdded, 1)
 SESSION(Located, Located, 0)
 SESSION(RoutesReconnected, session_routes_reconnected, 0)
 SESSION(RouteAdded, RouteAdded, 1)
-SESSION(RouteAddedOrRemoved, RouteAddedOrRemoved, 1)
 SESSION(RouteGroupPropertyChanged, RouteGroupPropertyChanged, 1)
 SESSION(RouteAddedToRouteGroup, RouteAddedToRouteGroup, 2)
 SESSION(RouteRemovedFromRouteGroup, RouteRemovedFromRouteGroup, 2)
 SESSION(RouteGroupPropertyChanged, RouteGroupPropertyChanged, 1)
 SESSION(RouteAddedToRouteGroup, RouteAddedToRouteGroup, 2)
 SESSION(RouteRemovedFromRouteGroup, RouteRemovedFromRouteGroup, 2)
@@ -70,9 +69,6 @@ SESSION(RouteGroupAdded, route_group_added, 1)
 SESSION(RouteGroupRemoved, route_group_removed, 0)
 SESSION(RouteGroupsReordered, route_groups_reordered, 0)
 
 SESSION(RouteGroupRemoved, route_group_removed, 0)
 SESSION(RouteGroupsReordered, route_groups_reordered, 0)
 
-// route static globals
-STATIC(SyncOrderKeys, &Route::SyncOrderKeys, 0)
-
 // plugin manager instance
 STATIC(PluginListChanged, &(PluginManager::instance().PluginListChanged), 0)
 STATIC(PluginStatusesChanged, &(PluginManager::instance().PluginStatusesChanged), 0)
 // plugin manager instance
 STATIC(PluginListChanged, &(PluginManager::instance().PluginListChanged), 0)
 STATIC(PluginStatusesChanged, &(PluginManager::instance().PluginStatusesChanged), 0)
index b324a846ff7b68836ea3a24ea852108fc921c737..c8992ee0b25ba7fa20941aa6fcb38ce069b073ea 100644 (file)
@@ -801,12 +801,12 @@ MeterStrip::name_changed () {
        }
        name_label.set_text(_route->name ());
        if (_session && _session->config.get_track_name_number()) {
        }
        name_label.set_text(_route->name ());
        if (_session && _session->config.get_track_name_number()) {
-               const int64_t track_number = _route->track_number ();
+               const uint64_t track_number = _route->track_number();
                if (track_number == 0) {
                        number_label.set_text("-");
                        number_label.hide();
                } else {
                if (track_number == 0) {
                        number_label.set_text("-");
                        number_label.hide();
                } else {
-                       number_label.set_text (PBD::to_string (abs(_route->track_number ()), std::dec));
+                       number_label.set_text (PBD::to_string (track_number, std::dec));
                        number_label.show();
                }
                const int tnh = 4 + std::max(2u, _session->track_number_decimals()) * 8; // TODO 8 = max_width_of_digit_0_to_9()
                        number_label.show();
                }
                const int tnh = 4 + std::max(2u, _session->track_number_decimals()) * 8; // TODO 8 = max_width_of_digit_0_to_9()
index 5906d7343a950d7102f0f865ab25f68997c446dc..f687d0c72d5a37bafe6894b580ee885962586a9c 100644 (file)
@@ -40,7 +40,6 @@
 
 #include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
 
 #include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
-#include "ardour/route_sorters.h"
 
 #include "meterbridge.h"
 
 
 #include "meterbridge.h"
 
@@ -124,7 +123,6 @@ Meterbridge::Meterbridge ()
 
        signal_delete_event().connect (sigc::mem_fun (*this, &Meterbridge::hide_window));
        signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
 
        signal_delete_event().connect (sigc::mem_fun (*this, &Meterbridge::hide_window));
        signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
-       Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Meterbridge::sync_order_keys, this), gui_context());
        MeterStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Meterbridge::remove_strip, this, _1), gui_context());
        MeterStrip::MetricChanged.connect (*this, invalidator (*this), boost::bind(&Meterbridge::resync_order, this), gui_context());
        MeterStrip::ConfigurationChanged.connect (*this, invalidator (*this), boost::bind(&Meterbridge::queue_resize, this), gui_context());
        MeterStrip::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Meterbridge::remove_strip, this, _1), gui_context());
        MeterStrip::MetricChanged.connect (*this, invalidator (*this), boost::bind(&Meterbridge::resync_order, this), gui_context());
        MeterStrip::ConfigurationChanged.connect (*this, invalidator (*this), boost::bind(&Meterbridge::queue_resize, this), gui_context());
@@ -400,6 +398,20 @@ Meterbridge::on_scroll()
        metrics_right.set_metric_mode(mm_right, mt_right);
 }
 
        metrics_right.set_metric_mode(mm_right, mt_right);
 }
 
+struct PresentationInfoRouteSorter
+{
+       bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
+               if (a->is_master()) {
+                       /* master before everything else */
+                       return true;
+               } else if (b->is_master()) {
+                       /* everything else before b */
+                       return false;
+               }
+               return a->presentation_info() < b->presentation_info();
+       }
+};
+
 void
 Meterbridge::set_session (Session* s)
 {
 void
 Meterbridge::set_session (Session* s)
 {
@@ -422,7 +434,7 @@ Meterbridge::set_session (Session* s)
        _show_master = _session->config.get_show_master_on_meterbridge();
        _show_midi = _session->config.get_show_midi_on_meterbridge();
 
        _show_master = _session->config.get_show_master_on_meterbridge();
        _show_midi = _session->config.get_show_midi_on_meterbridge();
 
-       ARDOUR::SignalOrderRouteSorter sorter;
+       PresentationInfoRouteSorter sorter;
        boost::shared_ptr<RouteList> routes = _session->get_routes();
 
        RouteList copy(*routes);
        boost::shared_ptr<RouteList> routes = _session->get_routes();
 
        RouteList copy(*routes);
index 1709455ae4cf735f0d418d85875d732552d31165..5e0690791738170cc6001181e66e8f4da6ae3b3f 100644 (file)
@@ -107,7 +107,7 @@ class Meterbridge :
                                /* everything comes before b */
                                return true;
                        }
                                /* everything comes before b */
                                return true;
                        }
-                       return a->order_key () < b->order_key ();
+                       return a->presentation_info() < b->presentation_info ();
                }
        };
 
                }
        };
 
index bccf649b42df9f08220d1c28dfd7dbfe5e8ae621..e9977b0b512c8a53369229e0233ff879451c2422 100644 (file)
@@ -193,8 +193,3 @@ MixerGroupTabs::selected_routes () const
        return rl;
 }
 
        return rl;
 }
 
-void
-MixerGroupTabs::sync_order_keys ()
-{
-       _mixer->sync_order_keys_from_treeview ();
-}
index 5f15255c5c912f7def68f77d900b91c94e2b6525..8da5a1be4981dedef0a969cdba00327f9755a22a 100644 (file)
@@ -36,7 +36,6 @@ private:
        }
 
        ARDOUR::RouteList selected_routes () const;
        }
 
        ARDOUR::RouteList selected_routes () const;
-       void sync_order_keys ();
 
        Mixer_UI* _mixer;
 };
 
        Mixer_UI* _mixer;
 };
index 4d0c2c3e7f972fe52d37e4533edae260644292a3..9f5cb5684f901977bfca48d16203134e2a3b8735 100644 (file)
 
 #include "ardour/amp.h"
 #include "ardour/debug.h"
 
 #include "ardour/amp.h"
 #include "ardour/debug.h"
+#include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
 #include "ardour/plugin_manager.h"
 #include "ardour/route_group.h"
 #include "ardour/midi_track.h"
 #include "ardour/plugin_manager.h"
 #include "ardour/route_group.h"
-#include "ardour/route_sorters.h"
 #include "ardour/session.h"
 #include "ardour/vca.h"
 #include "ardour/vca_manager.h"
 #include "ardour/session.h"
 #include "ardour/vca.h"
 #include "ardour/vca_manager.h"
@@ -107,7 +107,7 @@ Mixer_UI::Mixer_UI ()
        , _maximised (false)
        , _show_mixer_list (true)
 {
        , _maximised (false)
        , _show_mixer_list (true)
 {
-       Route::SyncOrderKeys.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_order_keys, this), gui_context());
+       Stripable::PresentationInfoChange.connect (*this, invalidator (*this), boost::bind (&Mixer_UI::sync_treeview_from_presentation_info, this), gui_context());
 
        /* bindings was already set in MixerActor constructor */
 
 
        /* bindings was already set in MixerActor constructor */
 
@@ -427,7 +427,7 @@ Mixer_UI::add_strips (RouteList& routes)
 
                nroutes++;
 
 
                nroutes++;
 
-               if (r->order_key() == (routes.front()->order_key() + routes.size())) {
+               if (r->presentation_info().group_order() == (routes.front()->presentation_info().group_order() + routes.size())) {
                        insert_iter = it;
                        break;
                }
                        insert_iter = it;
                        break;
                }
@@ -512,7 +512,7 @@ Mixer_UI::add_strips (RouteList& routes)
        no_track_list_redisplay = false;
        track_display.set_model (track_model);
 
        no_track_list_redisplay = false;
        track_display.set_model (track_model);
 
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
        redisplay_track_list ();
 }
 
        redisplay_track_list ();
 }
 
@@ -576,69 +576,9 @@ Mixer_UI::remove_strip (MixerStrip* strip)
 }
 
 void
 }
 
 void
-Mixer_UI::reset_remote_control_ids ()
+Mixer_UI::sync_presentation_info_from_treeview ()
 {
 {
-       if (Config->get_remote_model() == UserOrdered || !_session || _session->deletion_in_progress()) {
-               return;
-       }
-
-       TreeModel::Children rows = track_model->children();
-
-       if (rows.empty()) {
-               return;
-       }
-
-       DEBUG_TRACE (DEBUG::OrderKeys, "mixer resets remote control ids after remote model change\n");
-
-       TreeModel::Children::iterator ri;
-       bool rid_change = false;
-       uint32_t rid = 1;
-       uint32_t invisible_key = UINT32_MAX;
-
-       for (ri = rows.begin(); ri != rows.end(); ++ri) {
-
-               /* skip two special values */
-
-               if (rid == Route::MasterBusRemoteControlID) {
-                       rid++;
-               }
-
-               if (rid == Route::MonitorBusRemoteControlID) {
-                       rid++;
-               }
-
-               boost::shared_ptr<Route> route = (*ri)[track_columns.route];
-               bool visible = (*ri)[track_columns.visible];
-
-               if (!route) {
-                       continue;
-               }
-
-               if (!route->is_master() && !route->is_monitor()) {
-
-                       uint32_t new_rid = (visible ? rid : invisible_key--);
-
-                       if (new_rid != route->remote_control_id()) {
-                               route->set_remote_control_id_explicit (new_rid);
-                               rid_change = true;
-                       }
-
-                       if (visible) {
-                               rid++;
-                       }
-               }
-       }
-
-       if (rid_change) {
-               /* tell the world that we changed the remote control IDs */
-               _session->notify_remote_id_change ();
-       }
-}
-
-void
-Mixer_UI::sync_order_keys_from_treeview ()
-{
-       if (ignore_reorder || !_session || _session->deletion_in_progress()) {
+       if (ignore_reorder || !_session || _session->deletion_in_progress() || (Config->get_remote_model() != MixerOrdered)) {
                return;
        }
 
                return;
        }
 
@@ -651,58 +591,46 @@ Mixer_UI::sync_order_keys_from_treeview ()
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer sync order keys from model\n");
 
        TreeModel::Children::iterator ri;
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer sync order keys from model\n");
 
        TreeModel::Children::iterator ri;
-       bool changed = false;
-       bool rid_change = false;
+       bool change = false;
        uint32_t order = 0;
        uint32_t order = 0;
-       uint32_t rid = 1;
-       uint32_t invisible_key = UINT32_MAX;
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
                boost::shared_ptr<Route> route = (*ri)[track_columns.route];
                bool visible = (*ri)[track_columns.visible];
 
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
                boost::shared_ptr<Route> route = (*ri)[track_columns.route];
                bool visible = (*ri)[track_columns.visible];
 
+
                if (!route) {
                        continue;
                }
 
                if (!route) {
                        continue;
                }
 
-               uint32_t old_key = route->order_key ();
-
-               if (order != old_key) {
-                       route->set_order_key (order);
-                       changed = true;
+               if (route->presentation_info().special()) {
+                       continue;
                }
 
                }
 
-               if ((Config->get_remote_model() == MixerOrdered) && !route->is_master() && !route->is_monitor()) {
-
-                       uint32_t new_rid = (visible ? rid : invisible_key--);
-
-                       if (new_rid != route->remote_control_id()) {
-                               route->set_remote_control_id_explicit (new_rid);
-                               rid_change = true;
-                       }
+               if (!visible) {
+                       route->presentation_info().set_flag (PresentationInfo::Hidden);
+               } else {
+                       route->presentation_info().unset_flag (PresentationInfo::Hidden);
+               }
 
 
-                       if (visible) {
-                               rid++;
-                       }
+               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("route %1 old order %2 new order %3\n", route->name(), route->presentation_info().group_order(), order));
 
 
+               if (order != route->presentation_info().group_order()) {
+                       route->set_presentation_group_order_explicit (order);
+                       change = true;
                }
 
                ++order;
        }
 
                }
 
                ++order;
        }
 
-       if (changed) {
-               /* tell everyone that we changed the mixer sort keys */
-               _session->sync_order_keys ();
-       }
-
-       if (rid_change) {
-               /* tell the world that we changed the remote control IDs */
-               _session->notify_remote_id_change ();
+       if (change) {
+               DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from mixer GUI\n");
+               _session->notify_presentation_info_change ();
        }
 }
 
 void
        }
 }
 
 void
-Mixer_UI::sync_treeview_from_order_keys ()
+Mixer_UI::sync_treeview_from_presentation_info ()
 {
        if (!_session || _session->deletion_in_progress()) {
                return;
 {
        if (!_session || _session->deletion_in_progress()) {
                return;
@@ -736,7 +664,7 @@ Mixer_UI::sync_treeview_from_order_keys ()
        for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri) {
                boost::shared_ptr<Route> route = (*ri)[track_columns.route];
                if (route) {
        for (TreeModel::Children::iterator ri = rows.begin(); ri != rows.end(); ++ri) {
                boost::shared_ptr<Route> route = (*ri)[track_columns.route];
                if (route) {
-                       max_route_order_key = max (route->order_key(), max_route_order_key);
+                       max_route_order_key = max (route->presentation_info().group_order(), max_route_order_key);
                }
        }
 
                }
        }
 
@@ -749,7 +677,7 @@ Mixer_UI::sync_treeview_from_order_keys ()
                         */
                        sorted.push_back (OrderKeys (old_order, max_route_order_key + ++vca_cnt));
                } else {
                         */
                        sorted.push_back (OrderKeys (old_order, max_route_order_key + ++vca_cnt));
                } else {
-                       sorted.push_back (OrderKeys (old_order, route->order_key ()));
+                       sorted.push_back (OrderKeys (old_order, route->presentation_info().group_order()));
                }
        }
 
                }
        }
 
@@ -1007,10 +935,10 @@ Mixer_UI::update_track_visibility ()
                        }
                }
 
                        }
                }
 
-               /* force route order keys catch up with visibility changes
+               /* force presentation catch up with visibility changes
                 */
 
                 */
 
-               sync_order_keys_from_treeview ();
+               sync_presentation_info_from_treeview ();
        }
 
        redisplay_track_list ();
        }
 
        redisplay_track_list ();
@@ -1207,7 +1135,7 @@ void
 Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
 {
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview reordered\n");
 Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
 {
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview reordered\n");
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 }
 
 void
 }
 
 void
@@ -1221,7 +1149,7 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
        */
 
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n");
        */
 
        DEBUG_TRACE (DEBUG::OrderKeys, "mixer UI treeview row deleted\n");
-       sync_order_keys_from_treeview ();
+       sync_presentation_info_from_treeview ();
 
         if (_route_deletion_in_progress) {
                 redisplay_track_list ();
 
         if (_route_deletion_in_progress) {
                 redisplay_track_list ();
@@ -1302,8 +1230,10 @@ Mixer_UI::redisplay_track_list ()
 
        if (n_masters == 0) {
                UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::remove_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
 
        if (n_masters == 0) {
                UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::remove_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
+               vca_scroller.hide ();
        } else {
                UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::add_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
        } else {
                UIConfiguration::instance().set_mixer_strip_visibility (VisibilityGroup::add_element (UIConfiguration::instance().get_mixer_strip_visibility(), X_("VCA")));
+               vca_scroller.show ();
        }
 
        _group_tabs->set_dirty ();
        }
 
        _group_tabs->set_dirty ();
@@ -1336,12 +1266,19 @@ Mixer_UI::strip_width_changed ()
 
 }
 
 
 }
 
+struct PresentationInfoRouteSorter
+{
+       bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
+               return a->presentation_info().global_order () < b->presentation_info().global_order ();
+       }
+};
+
 void
 Mixer_UI::initial_track_display ()
 {
        boost::shared_ptr<RouteList> routes = _session->get_routes();
        RouteList copy (*routes);
 void
 Mixer_UI::initial_track_display ()
 {
        boost::shared_ptr<RouteList> routes = _session->get_routes();
        RouteList copy (*routes);
-       ARDOUR::SignalOrderRouteSorter sorter;
+       PresentationInfoRouteSorter sorter;
 
        copy.sort (sorter);
 
 
        copy.sort (sorter);
 
@@ -1355,8 +1292,6 @@ Mixer_UI::initial_track_display ()
                add_strips (copy);
        }
 
                add_strips (copy);
        }
 
-       _session->sync_order_keys ();
-
        redisplay_track_list ();
 }
 
        redisplay_track_list ();
 }
 
@@ -2133,8 +2068,6 @@ Mixer_UI::parameter_changed (string const & p)
                for (list<MixerStrip*>::iterator i = strips.begin(); i != strips.end(); ++i) {
                        (*i)->set_width_enum (s ? Narrow : Wide, this);
                }
                for (list<MixerStrip*>::iterator i = strips.begin(); i != strips.end(); ++i) {
                        (*i)->set_width_enum (s ? Narrow : Wide, this);
                }
-       } else if (p == "remote-model") {
-               reset_remote_control_ids ();
        } else if (p == "use-monitor-bus") {
                if (_session && !_session->monitor_out()) {
                        monitor_section_detached ();
        } else if (p == "use-monitor-bus") {
                if (_session && !_session->monitor_out()) {
                        monitor_section_detached ();
index e8e7dc5864a4dba73e9a903cbbaf0d7dd2ffa7c8..413e5900f3fc6f126ac1008422bf7fcb560f6c6b 100644 (file)
@@ -320,10 +320,8 @@ class Mixer_UI : public Gtkmm2ext::Tabbable, public PBD::ScopedConnectionList, p
 
        Width _strip_width;
 
 
        Width _strip_width;
 
-        void sync_order_keys_from_treeview ();
-        void sync_treeview_from_order_keys ();
-        void reset_remote_control_ids ();
-        void reset_order_keys ();
+        void sync_presentation_info_from_treeview ();
+        void sync_treeview_from_presentation_info ();
 
         bool ignore_reorder;
 
 
         bool ignore_reorder;
 
index 2d445dcbb273ee9bab208c6981ea49a0da439de7..b23ebd21a2a939f3cef9eba494874a7761b79203 100644 (file)
@@ -316,7 +316,7 @@ struct RouteIOs {
 class RouteIOsComparator {
 public:
        bool operator() (RouteIOs const & a, RouteIOs const & b) {
 class RouteIOsComparator {
 public:
        bool operator() (RouteIOs const & a, RouteIOs const & b) {
-               return a.route->order_key () < b.route->order_key ();
+               return a.route->presentation_info ().group_order() < b.route->presentation_info().group_order();
        }
 };
 
        }
 };
 
index 1bfb920c3becec80e8abb3e73cce484d80b889c2..84349d8236e29c5267c444d8d37d363245bbed5a 100644 (file)
@@ -159,7 +159,7 @@ PortMatrix::init ()
        _session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
 
        /* watch for route order keys changing, which changes the order of things in our global ports list(s) */
        _session->engine().PortRegisteredOrUnregistered.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports, this), gui_context());
 
        /* watch for route order keys changing, which changes the order of things in our global ports list(s) */
-       Route::SyncOrderKeys.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports_proxy, this), gui_context());
+       Stripable::PresentationInfoChange.connect (_session_connections, invalidator (*this), boost::bind (&PortMatrix::setup_global_ports_proxy, this), gui_context());
 
        /* Part 3: other stuff */
 
 
        /* Part 3: other stuff */
 
index 126e3af99670696b9ec270c6cf423f302baf65c2..1175aa620a8aa21c0fb580d1dca40ca2cc87dce4 100644 (file)
@@ -2031,7 +2031,7 @@ RouteUI::open_remote_control_id_dialog ()
                spin->set_digits (0);
                spin->set_increments (1, 10);
                spin->set_range (0, limit);
                spin->set_digits (0);
                spin->set_increments (1, 10);
                spin->set_range (0, limit);
-               spin->set_value (_route->remote_control_id());
+               spin->set_value (_route->presentation_info().group_order());
                hbox->pack_start (*spin);
                dialog.get_vbox()->pack_start (*hbox);
 
                hbox->pack_start (*spin);
                dialog.get_vbox()->pack_start (*hbox);
 
@@ -2043,14 +2043,14 @@ RouteUI::open_remote_control_id_dialog ()
                        l->set_markup (string_compose (_("The remote control ID of %1 is: %2\n\n\n"
                                                         "The remote control ID of %3 cannot be changed."),
                                                       Gtkmm2ext::markup_escape_text (_route->name()),
                        l->set_markup (string_compose (_("The remote control ID of %1 is: %2\n\n\n"
                                                         "The remote control ID of %3 cannot be changed."),
                                                       Gtkmm2ext::markup_escape_text (_route->name()),
-                                                      _route->remote_control_id(),
+                                                      _route->presentation_info().group_order(),
                                                       (_route->is_master() ? _("the master bus") : _("the monitor bus"))));
                } else {
                        l->set_markup (string_compose (_("The remote control ID of %5 is: %2\n\n\n"
                                                         "Remote Control IDs are currently determined by track/bus ordering in %6.\n\n"
                                                         "%3Use the User Interaction tab of the Preferences window if you want to change this%4"),
                                                       (is_track() ? _("track") : _("bus")),
                                                       (_route->is_master() ? _("the master bus") : _("the monitor bus"))));
                } else {
                        l->set_markup (string_compose (_("The remote control ID of %5 is: %2\n\n\n"
                                                         "Remote Control IDs are currently determined by track/bus ordering in %6.\n\n"
                                                         "%3Use the User Interaction tab of the Preferences window if you want to change this%4"),
                                                       (is_track() ? _("track") : _("bus")),
-                                                      _route->remote_control_id(),
+                                                      _route->presentation_info().group_order(),
                                                       "<span size=\"small\" style=\"italic\">",
                                                       "</span>",
                                                       Gtkmm2ext::markup_escape_text (_route->name()),
                                                       "<span size=\"small\" style=\"italic\">",
                                                       "</span>",
                                                       Gtkmm2ext::markup_escape_text (_route->name()),
@@ -2064,7 +2064,7 @@ RouteUI::open_remote_control_id_dialog ()
        int const r = dialog.run ();
 
        if (r == RESPONSE_ACCEPT && spin) {
        int const r = dialog.run ();
 
        if (r == RESPONSE_ACCEPT && spin) {
-               _route->set_remote_control_id (spin->get_value_as_int ());
+               _route->set_presentation_group_order_explicit (spin->get_value_as_int ());
        }
 }
 
        }
 }
 
index ba1b58d3bcbbd2bd5645d487f8c7d109e5eda6bd..332ca230ff319297575e8445539971756f58a335 100644 (file)
@@ -16,6 +16,8 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include <gtkmm/stock.h>
+
 #include "pbd/convert.h"
 
 #include "ardour/rc_configuration.h"
 #include "pbd/convert.h"
 
 #include "ardour/rc_configuration.h"
@@ -26,8 +28,9 @@
 #include "gtkmm2ext/doi.h"
 #include "gtkmm2ext/keyboard.h"
 
 #include "gtkmm2ext/doi.h"
 #include "gtkmm2ext/keyboard.h"
 
-#include "gui_thread.h"
+#include "ardour_dialog.h"
 #include "floating_text_entry.h"
 #include "floating_text_entry.h"
+#include "gui_thread.h"
 #include "tooltips.h"
 #include "vca_master_strip.h"
 
 #include "tooltips.h"
 #include "vca_master_strip.h"
 
@@ -47,6 +50,7 @@ VCAMasterStrip::VCAMasterStrip (Session* s, boost::shared_ptr<VCA> v)
        , _vca (v)
        , gain_meter (s, 250)
        , context_menu (0)
        , _vca (v)
        , gain_meter (s, 250)
        , context_menu (0)
+       , delete_dialog (0)
 {
        gain_meter.set_controls (boost::shared_ptr<Route>(),
                                 boost::shared_ptr<PeakMeter>(),
 {
        gain_meter.set_controls (boost::shared_ptr<Route>(),
                                 boost::shared_ptr<PeakMeter>(),
@@ -150,6 +154,9 @@ VCAMasterStrip::VCAMasterStrip (Session* s, boost::shared_ptr<VCA> v)
 
 VCAMasterStrip::~VCAMasterStrip ()
 {
 
 VCAMasterStrip::~VCAMasterStrip ()
 {
+       delete delete_dialog;
+       delete context_menu;
+
        CatchDeletion (this); /* EMIT SIGNAL */
 }
 
        CatchDeletion (this); /* EMIT SIGNAL */
 }
 
@@ -193,10 +200,31 @@ VCAMasterStrip::name() const
 void
 VCAMasterStrip::hide_clicked ()
 {
 void
 VCAMasterStrip::hide_clicked ()
 {
-       /* get everything to deassign. This will also delete ourselves (when
-        * idle) and that in turn will remove us from the Mixer GUI
-        */
-       _session->vca_manager().remove_vca (_vca);
+       if (!delete_dialog) {
+               delete_dialog = new MessageDialog (_("Removing a Master will deassign all slaves. Remove it anyway?"),
+                                                  true, MESSAGE_WARNING, BUTTONS_YES_NO, true);
+               delete_dialog->signal_response().connect (sigc::mem_fun (*this, &VCAMasterStrip::hide_confirmation));
+       }
+
+       delete_dialog->set_position (Gtk::WIN_POS_MOUSE);
+       delete_dialog->present ();
+}
+
+void
+VCAMasterStrip::hide_confirmation (int response)
+{
+       delete_dialog->hide ();
+
+       switch (response) {
+       case RESPONSE_OK:
+               /* get everything to deassign. This will also delete ourselves (when
+                * idle) and that in turn will remove us from the Mixer GUI
+                */
+               _session->vca_manager().remove_vca (_vca);
+               break;
+       default:
+               break;
+       }
 }
 
 bool
 }
 
 bool
index b3fdc5d31003e955d41e503bdb408af4d7ba8329..1e0779aa1f2b2942912966361e8897c01a75ce99 100644 (file)
@@ -68,6 +68,7 @@ class VCAMasterStrip : public AxisView, public Gtk::EventBox
        ArdourButton assign_button;
        Gtk::Menu*   context_menu;
        PBD::ScopedConnectionList vca_connections;
        ArdourButton assign_button;
        Gtk::Menu*   context_menu;
        PBD::ScopedConnectionList vca_connections;
+       Gtk::MessageDialog* delete_dialog;
 
        void hide_clicked();
        bool width_button_pressed (GdkEventButton *);
 
        void hide_clicked();
        bool width_button_pressed (GdkEventButton *);
@@ -87,6 +88,7 @@ class VCAMasterStrip : public AxisView, public Gtk::EventBox
        void vca_property_changed (PBD::PropertyChange const & what_changed);
        void update_vca_name ();
        void build_context_menu ();
        void vca_property_changed (PBD::PropertyChange const & what_changed);
        void update_vca_name ();
        void build_context_menu ();
+       void hide_confirmation (int);
        void self_delete ();
 };
 
        void self_delete ();
 };
 
index 17e22236800aadd3ec88f5a7e0a13de3ccb54c48..d80042a252384e478863df52805661cd2ce2f4a4 100644 (file)
@@ -34,7 +34,7 @@ class AudioFileSource;
 class LIBARDOUR_API AudioTrack : public Track
 {
   public:
 class LIBARDOUR_API AudioTrack : public Track
 {
   public:
-       AudioTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
+       AudioTrack (Session&, std::string name, TrackMode m = Normal);
        ~AudioTrack ();
 
        int set_mode (TrackMode m);
        ~AudioTrack ();
 
        int set_mode (TrackMode m);
index 69f498104756dc2a10258ed0351e443eabe3e437..f756812e7142433f4c0a5e1d73ba42720ea22961 100644 (file)
@@ -37,7 +37,7 @@ class Session;
 class LIBARDOUR_API MidiTrack : public Track
 {
 public:
 class LIBARDOUR_API MidiTrack : public Track
 {
 public:
-       MidiTrack (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
+       MidiTrack (Session&, std::string name, TrackMode m = Normal);
        ~MidiTrack ();
 
        int init ();
        ~MidiTrack ();
 
        int init ();
index 5332fd4fa714a2cf4b05cdb5c0c202fca755c24e..36d5e112ccdf8fbd1e216fdbfe081cbbf9f47c0e 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "ardour/slavable_automation_control.h"
 
 
 #include "ardour/slavable_automation_control.h"
 
+#include "ardour/mute_master.h"
 #include "ardour/libardour_visibility.h"
 
 namespace ARDOUR {
 #include "ardour/libardour_visibility.h"
 
 namespace ARDOUR {
diff --git a/libs/ardour/ardour/presentation_info.h b/libs/ardour/ardour/presentation_info.h
new file mode 100644 (file)
index 0000000..f7446a7
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+    Copyright (C) 2016 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 __libardour_presentation_info_h__
+#define __libardour_presentation_info_h__
+
+#include <iostream>
+#include <string>
+
+#include <stdint.h>
+
+#include "ardour/libardour_visibility.h"
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class LIBARDOUR_API PresentationInfo
+{
+  public:
+
+       /* a PresentationInfo object exists to share information between
+        * different user interfaces (e.g. GUI and a Mackie Control surface)
+        * about:
+        *
+        *     - ordering
+        *     - selection status
+        *     - visibility
+        *     - object identity
+        *
+        * ORDERING
+        *
+        * One UI takes control of ordering by setting the "order" value for
+        * the PresentationInfo component of every Stripable object. In Ardour,
+        * this is done by the GUI (mostly because it is very hard for the user
+        * to re-order things on a control surface).
+        *
+        * Ordering is a complex beast, however. Different user interfaces may
+        * display things in different ways. For example, the GUI of Ardour
+        * allows the user to mix busses in between tracks. A control surface
+        * may do the same, but may also allow the user to press a button that
+        * makes it show only busses, or only MIDI tracks. At that point, the
+        * ordering on the surface differs from the ordering in the GUI.
+        *
+        * The ordering is given via a combination of an object type and a
+        * simple numeric position within that type. The object types at this
+        * time are:
+        *
+        *     Route
+        *        - object has inputs and outputs; processes data
+        *     Output
+        *        - Route used to connect to outside the application (MasterOut, MonitorOut)
+        *     Special
+        *        - special type of Route (e.g. Auditioner)
+        *     VCA
+        *        - no data flows through; control only
+        *
+        * Objects with a numeric order of zero are considered unsorted. This
+        * applies (for now) to special objects such as the master out,
+        * auditioner and monitor out.  The rationale here is that the GUI
+        * presents these objects in special ways, rather than as part of some
+        * (potentially) re-orderable container. The same is true for hardware
+        * surfaces, where the master fader (for instance) is typically
+        * separate and distinct from anything else.
+        *
+        * There are several pathways for the order being set:
+        *
+        *   - object created during session loading from XML
+        *           - numeric order will be set during ::set_state(), based on
+        *           - type will be set during ctor call
+        *
+        *   - object created in response to user request
+        *              - numeric order will be set by Session, before adding
+        *                   to container.
+        *              - type set during ctor call
+        *
+        *
+        * OBJECT IDENTITY
+        *
+        * Control surfaces/protocols often need to be able to get a handle on
+        * an object identified only abstractly, such as the "5th audio track"
+        * or "the master out". A PresentationInfo object uniquely identifies
+        * all objects in this way through the combination of its _order member
+        * and part of its _flags member. The _flags member identifies the type
+        * of object, as well as selection/hidden status. The type may never
+        * change after construction (not strictly the constructor itself, but
+        * a more generalized notion of construction, as in "ready to use").
+        *
+        * SELECTION
+        *
+        * When an object is selected, its _flags member will have the Selected
+        * bit set.
+        *
+        * VISIBILITY
+        *
+        * When an object is hidden, its _flags member will have the Hidden
+        * bit set.
+        *
+        *
+        */
+
+
+       enum Flag {
+               /* Type information */
+               AudioTrack = 0x1,
+               MidiTrack = 0x2,
+               AudioBus = 0x4,
+               MidiBus = 0x8,
+               VCA = 0x10,
+
+               /* These need to be at the high end */
+               MasterOut = 0x800,
+               MonitorOut = 0x1000,
+               Auditioner = 0x2000,
+
+               /* These are for sharing Stripable states between the GUI and other
+                * user interfaces/control surfaces
+                */
+               Selected = 0x4000,
+               Hidden = 0x8000,
+
+               /* single bit indicates that the group order is set */
+               GroupOrderSet = 0x100000000,
+
+               /* Masks */
+
+               GroupMask = (AudioTrack|MidiTrack|AudioBus|MidiBus|VCA),
+               SpecialMask = (MasterOut|MonitorOut|Auditioner),
+               StatusMask = (Selected|Hidden),
+       };
+
+       static const Flag Route;
+       static const Flag Track;
+       static const Flag Bus;
+
+       typedef uint32_t order_t;
+       typedef uint64_t global_order_t;
+
+       PresentationInfo (Flag f) : _order (0), _flags (Flag (f & ~GroupOrderSet)) { /* GroupOrderSet is not set */ }
+       PresentationInfo (order_t o, Flag f) : _order (o), _flags (Flag (f | GroupOrderSet)) { /* GroupOrderSet is set */ }
+
+       static const order_t max_order;
+
+       order_t  group_order() const { return _order; }
+       global_order_t global_order () const {
+               if (_flags & Route) {
+
+                       /* set all bits related to Route so that all Routes
+                          sort together, with order() in the range of
+                          64424509440..68719476735
+
+                          Consider the following arrangement:
+
+                          Track   1
+                          Bus     1
+                          Track   2
+                          ---------
+                          VCA     1
+                          ---------
+                          Master
+                          ---------
+                          Monitor
+
+                          these translate into the following
+
+                          _order  |  _flags            | order()
+                          --------------------------------------
+                          1       |   0x1   AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|1 = 64424509441
+                          2       |   0x2   AudioBus   | ((0x1|0x2|0x4|0x8)<<32)|2 = 64424509442
+                          3       |   0x1   AudioTrack | ((0x1|0x2|0x4|0x8)<<32)|3 = 64424509443
+
+                          1       |   0x10  VCA        | ((0x10)<<32)|1 = 68719476737
+
+                          0       |   0x800 Master     | (0x800<<32) = 8796093022208
+
+                          0       |   0x1000 Monitor   | (0x1000<<32) = 17592186044416
+
+                       */
+
+                       return (((global_order_t) (_flags | Route)) << sizeof(order_t)) | _order;
+               } else {
+                       return (((global_order_t) _flags) << sizeof(order_t)) | _order;
+               }
+       }
+
+       PresentationInfo::Flag flags() const { return _flags; }
+
+       bool order_set() const { return _order != 0; }
+
+       /* these objects have no defined order */
+       bool special () const { return _flags & SpecialMask; }
+
+       /* detect group order set/not set */
+       bool unordered() const { return !(_flags & GroupOrderSet); }
+       bool ordered() const { return _flags & GroupOrderSet; }
+
+       void set_flag (PresentationInfo::Flag f) {
+               _flags = PresentationInfo::Flag (_flags | f);
+       }
+
+       void unset_flag (PresentationInfo::Flag f) {
+               _flags = PresentationInfo::Flag (_flags & ~f);
+       }
+
+       void set_flags (Flag f) {
+               _flags = f;
+       }
+
+       bool flag_match (Flag f) const {
+               /* no flags, match all */
+
+               if (f == Flag (0)) {
+                       return true;
+               }
+
+               if (f & StatusMask) {
+                       /* status bits set, must match them */
+                       if ((_flags & StatusMask) != (f & StatusMask)) {
+                               return false;
+                       }
+               }
+
+               /* Generic flags in f, match the right stuff */
+
+               if (f == Bus && (_flags & Bus)) {
+                       /* some kind of bus */
+                       return true;
+               }
+               if (f == Track && (_flags & Track)) {
+                       /* some kind of track */
+                       return true;
+               }
+               if (f == Route && (_flags & Route)) {
+                       /* any kind of route */
+                       return true;
+               }
+
+               return f == _flags;
+       }
+
+       std::string to_string () const;
+
+       uint64_t to_integer () const {
+               return ((uint64_t) _flags << sizeof(order_t)) | _order;
+       }
+
+       bool operator< (PresentationInfo const& other) const {
+               return global_order() < other.global_order();
+       }
+
+       PresentationInfo& operator= (std::string const& str) {
+               parse (str);
+               return *this;
+       }
+
+       bool match (PresentationInfo const& other) const {
+               return (_order == other.group_order()) && flag_match (other.flags());
+       }
+
+       bool operator==(PresentationInfo const& other) {
+               return (_order == other.group_order()) && (_flags == other.flags());
+       }
+
+       bool operator!=(PresentationInfo const& other) {
+               return (_order != other.group_order()) || (_flags != other.flags());
+       }
+
+       static Flag get_flags (XMLNode const& node);
+
+  protected:
+       friend class Stripable;
+       void set_group_order (order_t order) { _order = order; _flags = Flag (_flags|GroupOrderSet); }
+
+  private:
+       order_t _order;
+       Flag    _flags;
+
+       PresentationInfo (std::string const & str);
+       int parse (std::string const&);
+       int parse (order_t, Flag f);
+};
+
+}
+
+std::ostream& operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid);
+
+#endif /* __libardour_presentation_info_h__ */
index 2e2c1ccf7221e3624b1c87a10d4ac5380732e96e..7a6b50436894aa60d7158b51177db369f4b6fd22 100644 (file)
@@ -97,13 +97,7 @@ public:
 
        typedef std::list<boost::shared_ptr<Processor> > ProcessorList;
 
 
        typedef std::list<boost::shared_ptr<Processor> > ProcessorList;
 
-       enum Flag {
-               Auditioner = 0x1,
-               MasterOut = 0x2,
-               MonitorOut = 0x4
-       };
-
-       Route (Session&, std::string name, Flag flags = Flag(0), DataType default_type = DataType::AUDIO);
+       Route (Session&, std::string name, PresentationInfo::Flag flags = PresentationInfo::Flag(0), DataType default_type = DataType::AUDIO);
        virtual ~Route();
 
        virtual int init ();
        virtual ~Route();
 
        virtual int init ();
@@ -127,14 +121,6 @@ public:
        bool set_name (const std::string& str);
        static void set_name_in_state (XMLNode &, const std::string &, bool rename_playlist = true);
 
        bool set_name (const std::string& str);
        static void set_name_in_state (XMLNode &, const std::string &, bool rename_playlist = true);
 
-       uint32_t order_key () const;
-       bool has_order_key () const;
-       void set_order_key (uint32_t);
-
-       bool is_auditioner() const { return _flags & Auditioner; }
-       bool is_master() const { return _flags & MasterOut; }
-       bool is_monitor() const { return _flags & MonitorOut; }
-
        MonitorState monitoring_state () const;
        virtual MeterState metering_state () const;
 
        MonitorState monitoring_state () const;
        virtual MeterState metering_state () const;
 
@@ -569,28 +555,6 @@ public:
 
        void protect_automation ();
 
 
        void protect_automation ();
 
-       enum {
-               /* These numbers are taken from MIDI Machine Control,
-                  which can only control up to 317 tracks without
-                  doing sysex segmentation.
-               */
-               MasterBusRemoteControlID = 318,
-               MonitorBusRemoteControlID = 319,
-       };
-
-       void     set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
-       uint32_t remote_control_id () const;
-       void     set_remote_control_id_explicit (uint32_t order_key);
-
-       /* for things concerned about *this* route's RID */
-
-       PBD::Signal0<void> RemoteControlIDChanged;
-
-       /* for things concerned about *any* route's RID changes */
-
-       static PBD::Signal0<void> RemoteControlIDChange;
-       static PBD::Signal0<void> SyncOrderKeys;
-
        bool has_external_redirects() const;
 
        /* can only be executed by a route for which is_monitor() is true
        bool has_external_redirects() const;
 
        /* can only be executed by a route for which is_monitor() is true
@@ -663,7 +627,6 @@ public:
        gint           _pending_process_reorder; // atomic
        gint           _pending_signals; // atomic
 
        gint           _pending_process_reorder; // atomic
        gint           _pending_signals; // atomic
 
-       Flag           _flags;
        int            _pending_declick;
        MeterPoint     _meter_point;
        MeterPoint     _pending_meter_point;
        int            _pending_declick;
        MeterPoint     _meter_point;
        MeterPoint     _pending_meter_point;
@@ -718,16 +681,12 @@ protected:
 
        boost::shared_ptr<Processor> the_instrument_unlocked() const;
 
 
        boost::shared_ptr<Processor> the_instrument_unlocked() const;
 
-private:
+  private:
+       int64_t _track_number;
+
        int set_state_2X (const XMLNode&, int);
        void set_processor_state_2X (XMLNodeList const &, int);
 
        int set_state_2X (const XMLNode&, int);
        void set_processor_state_2X (XMLNodeList const &, int);
 
-       uint32_t _order_key;
-       bool _has_order_key;
-       uint32_t _remote_control_id;
-
-       int64_t _track_number;
-
        void input_change_handler (IOChange, void *src);
        void output_change_handler (IOChange, void *src);
        void sidechain_change_handler (IOChange, void *src);
        void input_change_handler (IOChange, void *src);
        void output_change_handler (IOChange, void *src);
        void sidechain_change_handler (IOChange, void *src);
@@ -810,7 +769,6 @@ private:
 
        void reset_instrument_info ();
 
 
        void reset_instrument_info ();
 
-       void set_remote_control_id_internal (uint32_t id, bool notify_class_listeners = true);
         void solo_control_changed (bool self, PBD::Controllable::GroupControlDisposition);
 };
 
         void solo_control_changed (bool self, PBD::Controllable::GroupControlDisposition);
 };
 
diff --git a/libs/ardour/ardour/route_sorters.h b/libs/ardour/ardour/route_sorters.h
deleted file mode 100644 (file)
index 022d5a2..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-    Copyright (C) 2000-2014 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 __libardour_route_sorters_h__
-#define __libardour_route_sorters_h__
-
-#include "ardour/route.h"
-
-namespace ARDOUR {
-
-struct SignalOrderRouteSorter {
-       bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
-               if (a->is_master() || a->is_monitor()) {
-                       /* "a" is a special route (master, monitor, etc), and comes
-                        * last in the mixer ordering
-                        */
-                       return false;
-               } else if (b->is_master() || b->is_monitor()) {
-                       /* everything comes before b */
-                       return true;
-               }
-               return a->order_key () < b->order_key ();
-       }
-};
-
-} // namespace
-
-#endif /* __libardour_route_sorters_h__ */
index 6f2c0f1fa90e8dcf87430693b83ce024b228b36a..f3a11a953c41b1359c093fcf87ab4e5dda240c99 100644 (file)
 #include "ardour/luascripting.h"
 #include "ardour/location.h"
 #include "ardour/monitor_processor.h"
 #include "ardour/luascripting.h"
 #include "ardour/location.h"
 #include "ardour/monitor_processor.h"
+#include "ardour/presentation_info.h"
 #include "ardour/rc_configuration.h"
 #include "ardour/session_configuration.h"
 #include "ardour/session_event.h"
 #include "ardour/interpolation.h"
 #include "ardour/plugin.h"
 #include "ardour/rc_configuration.h"
 #include "ardour/session_configuration.h"
 #include "ardour/session_event.h"
 #include "ardour/interpolation.h"
 #include "ardour/plugin.h"
+#include "ardour/presentation_info.h"
 #include "ardour/route.h"
 #include "ardour/route_graph.h"
 
 #include "ardour/route.h"
 #include "ardour/route_graph.h"
 
@@ -215,8 +217,6 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        PBD::Signal0<void> DirtyChanged;
 
 
        PBD::Signal0<void> DirtyChanged;
 
-       PBD::Signal1<void, bool> RouteAddedOrRemoved;
-
        const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
 
        static PBD::Signal1<void,std::string> Dialog;
        const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
 
        static PBD::Signal1<void,std::string> Dialog;
@@ -293,22 +293,20 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
                bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
        };
 
                bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
        };
 
-       void set_order_hint (int32_t order_hint) {_order_hint = order_hint;};
-       void notify_remote_id_change ();
-       void sync_order_keys ();
+       void notify_presentation_info_change ();
 
        template<class T> void foreach_route (T *obj, void (T::*func)(Route&), bool sort = true);
        template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>), bool sort = true);
        template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg, bool sort = true);
 
        static char session_name_is_legal (const std::string&);
 
        template<class T> void foreach_route (T *obj, void (T::*func)(Route&), bool sort = true);
        template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>), bool sort = true);
        template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg, bool sort = true);
 
        static char session_name_is_legal (const std::string&);
-       bool io_name_is_legal (const std::string&);
-       boost::shared_ptr<Route> route_by_name (std::string);
-       boost::shared_ptr<Route> route_by_id (PBD::ID);
-       boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
-       boost::shared_ptr<Stripable> stripable_by_remote_id (uint32_t id);
-       boost::shared_ptr<Route> route_by_selected_count (uint32_t cnt);
-       boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
+       bool io_name_is_legal (const std::string&) const;
+       boost::shared_ptr<Route> route_by_name (std::string) const;
+       boost::shared_ptr<Route> route_by_id (PBD::ID) const;
+       boost::shared_ptr<Stripable> get_remote_nth_stripable (uint16_t n, PresentationInfo::Flag) const;
+       boost::shared_ptr<Route> get_remote_nth_route (uint16_t n) const;
+       boost::shared_ptr<Route> route_by_selected_count (uint32_t cnt) const;
+       boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID) const;
        void routes_using_input_from (const std::string& str, RouteList& rl);
 
        bool route_name_unique (std::string) const;
        void routes_using_input_from (const std::string& str, RouteList& rl);
 
        bool route_name_unique (std::string) const;
@@ -595,29 +593,24 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        std::list<boost::shared_ptr<AudioTrack> > new_audio_track (
                int input_channels,
                int output_channels,
        std::list<boost::shared_ptr<AudioTrack> > new_audio_track (
                int input_channels,
                int output_channels,
-               TrackMode mode = Normal,
-               RouteGroup* route_group = 0,
-               uint32_t how_many = 1,
-               std::string name_template = ""
-               );
-
-       RouteList new_audio_route (
-               int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template = ""
+               RouteGroup* route_group,
+               uint32_t how_many,
+               std::string name_template,
+               PresentationInfo::order_t order,
+               TrackMode mode = Normal
                );
 
        std::list<boost::shared_ptr<MidiTrack> > new_midi_track (
                const ChanCount& input, const ChanCount& output,
                );
 
        std::list<boost::shared_ptr<MidiTrack> > new_midi_track (
                const ChanCount& input, const ChanCount& output,
-               boost::shared_ptr<PluginInfo> instrument = boost::shared_ptr<PluginInfo>(),
-               TrackMode mode = Normal,
-               RouteGroup* route_group = 0, uint32_t how_many = 1, std::string name_template = "",
-               Plugin::PresetRecord* pset = 0
+               boost::shared_ptr<PluginInfo> instrument,
+               Plugin::PresetRecord* pset = 0,
+               RouteGroup* route_group, uint32_t how_many, std::string name_template,
+               PresentationInfo::order_t,
+               TrackMode mode = Normal
                );
 
                );
 
-       RouteList new_midi_route (RouteGroup* route_group,
-                       uint32_t how_many,
-                       std::string name_template = "",
-                       boost::shared_ptr<PluginInfo> instrument = boost::shared_ptr<PluginInfo>(),
-                       Plugin::PresetRecord* pset = 0);
+       RouteList new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, std::string name_template, PresentationInfo::Flag, PresentationInfo::order_t);
+       RouteList new_midi_route (RouteGroup* route_group, uint32_t how_many, std::string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord*, PresentationInfo::Flag, PresentationInfo::order_t);
 
        void remove_routes (boost::shared_ptr<RouteList>);
        void remove_route (boost::shared_ptr<Route>);
 
        void remove_routes (boost::shared_ptr<RouteList>);
        void remove_route (boost::shared_ptr<Route>);
@@ -1658,8 +1651,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        SerializedRCUManager<RouteList>  routes;
 
 
        SerializedRCUManager<RouteList>  routes;
 
-       void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save);
-       void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect);
+       void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t);
+       void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t);
        bool _adding_routes_in_progress;
        bool _reconnecting_routes_in_progress;
        bool _route_deletion_in_progress;
        bool _adding_routes_in_progress;
        bool _reconnecting_routes_in_progress;
        bool _route_deletion_in_progress;
@@ -1976,8 +1969,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        */
        GraphEdges _current_route_graph;
 
        */
        GraphEdges _current_route_graph;
 
-       uint32_t next_control_id () const;
-       int32_t _order_hint;
+       void ensure_presentation_info_gap (PresentationInfo::order_t, uint32_t gap_size);
        bool ignore_route_processor_changes;
 
        MidiClockTicker* midi_clock;
        bool ignore_route_processor_changes;
 
        MidiClockTicker* midi_clock;
@@ -2005,6 +1997,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        std::string _template_state_dir;
 
        VCAManager* _vca_manager;
        std::string _template_state_dir;
 
        VCAManager* _vca_manager;
+
+       boost::shared_ptr<Route> get_midi_nth_route_by_id (PresentationInfo::order_t n) const;
 };
 
 
 };
 
 
index cee6075a51d03f1cb8e1e7bf51b4bebdbdd92e06..1b8239707423adf4fd51632f4d263a2885a95934 100644 (file)
 #include <boost/utility.hpp>
 #include <boost/shared_ptr.hpp>
 
 #include <boost/utility.hpp>
 #include <boost/shared_ptr.hpp>
 
+#include "pbd/signals.h"
+
+#include "ardour/presentation_info.h"
 #include "ardour/session_object.h"
 #include "ardour/session_object.h"
+#include "ardour/libardour_visibility.h"
 
 namespace ARDOUR {
 
 
 namespace ARDOUR {
 
@@ -46,18 +50,44 @@ class MonitorControl;
  * and behaviour of the object.
  */
 
  * and behaviour of the object.
  */
 
-class Stripable : public SessionObject {
+class LIBARDOUR_API Stripable : public SessionObject {
    public:
    public:
-       Stripable (Session& session, const std::string& name)
-               : SessionObject (session, name) {}
+       Stripable (Session& session, std::string const & name, PresentationInfo const &);
+       virtual ~Stripable () {}
 
        /* XXX
           midi on/off
 
        /* XXX
           midi on/off
-          selected status
-          visible/hidden
         */
 
         */
 
-       virtual uint32_t remote_control_id () const = 0;
+       bool is_auditioner() const { return _presentation_info.flags() & PresentationInfo::Auditioner; }
+       bool is_master() const { return _presentation_info.flags() & PresentationInfo::MasterOut; }
+       bool is_monitor() const { return _presentation_info.flags() & PresentationInfo::MonitorOut; }
+
+       int set_state (XMLNode const&, int);
+
+       bool is_hidden() const { return _presentation_info.flags() & PresentationInfo::Hidden; }
+       bool is_selected() const { return _presentation_info.flags() & PresentationInfo::Selected; }
+
+       PresentationInfo const & presentation_info () const { return _presentation_info; }
+       PresentationInfo& presentation_info () { return _presentation_info; }
+
+       /* set just the order */
+
+       void  set_presentation_group_order (PresentationInfo::order_t, bool notify_class_listeners = true);
+       void  set_presentation_group_order_explicit (PresentationInfo::order_t);
+
+       /* for things concerned about *this* route's RID */
+
+       PBD::Signal0<void> PresentationInfoChanged;
+
+       /* for things concerned about *any* route's RID changes */
+
+       static PBD::Signal0<void> PresentationInfoChange;
+
+       /***************************************************************
+        * Pure interface begins here
+        ***************************************************************/
+
 
        virtual boost::shared_ptr<PeakMeter>       peak_meter() = 0;
        virtual boost::shared_ptr<const PeakMeter> peak_meter() const = 0;
 
        virtual boost::shared_ptr<PeakMeter>       peak_meter() = 0;
        virtual boost::shared_ptr<const PeakMeter> peak_meter() const = 0;
@@ -140,6 +170,28 @@ class Stripable : public SessionObject {
        virtual boost::shared_ptr<AutomationControl> master_send_enable_controllable () const = 0;
 
        virtual bool muted_by_others_soloing () const = 0;
        virtual boost::shared_ptr<AutomationControl> master_send_enable_controllable () const = 0;
 
        virtual bool muted_by_others_soloing () const = 0;
+
+   protected:
+       PresentationInfo _presentation_info;
+
+       /* set the entire info. This should only be used in cases where the
+        * derived could not supply the correct Flag and/or order information
+        * in its constructor.
+        */
+
+       void set_presentation_info (PresentationInfo id, bool notify_class_listeners = true);
+       void set_presentation_info_explicit (PresentationInfo);
+
+       void add_state (XMLNode&) const;
+
+  private:
+       void set_presentation_info_internal (PresentationInfo id, bool notify_class_listeners = true);
+};
+
+struct PresentationInfoSorter {
+       bool operator() (boost::shared_ptr<Stripable> a, boost::shared_ptr<Stripable> b) {
+               return a->presentation_info() < b->presentation_info();
+       }
 };
 
 
 };
 
 
index bb955265c806c68fedd3ca2cf537c5ccf6bb7393..d57e0a2b5a9b33e1f69b3297a3db8b0ad065bca8 100644 (file)
@@ -45,7 +45,7 @@ class MonitorControl;
 class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskstream
 {
   public:
 class LIBARDOUR_API Track : public Route, public Recordable, public PublicDiskstream
 {
   public:
-       Track (Session&, std::string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
+       Track (Session&, std::string name, PresentationInfo::Flag f = PresentationInfo::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
        virtual ~Track ();
 
        int init ();
        virtual ~Track ();
 
        int init ();
index 2ed200d6f6c6fdaa71cbe5c909e54f762de94f2d..1b544bfb57f0a9dd19d046816d0158423ec65f17 100644 (file)
@@ -50,8 +50,8 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
 using namespace ARDOUR;
 using namespace PBD;
 
-AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
-       : Track (sess, name, flag, mode)
+AudioTrack::AudioTrack (Session& sess, string name, TrackMode mode)
+       : Track (sess, name, PresentationInfo::AudioTrack, mode)
 {
 }
 
 {
 }
 
index 33f74faf8037eb557a015f9b5a0feaf85b41ea65..0c7ba0bc1c15b81c4c335ad2430df2a9d5c3485f 100644 (file)
@@ -46,7 +46,7 @@ using namespace PBD;
 #include "i18n.h"
 
 Auditioner::Auditioner (Session& s)
 #include "i18n.h"
 
 Auditioner::Auditioner (Session& s)
-       : Track (s, "auditioner", Route::Auditioner)
+       : Track (s, "auditioner", PresentationInfo::Auditioner)
        , current_frame (0)
        , _auditioning (0)
        , length (0)
        , current_frame (0)
        , _auditioning (0)
        , length (0)
index 85634640b95ddb7a0311557a021747dd35638328..817126847d0eed41b1be733e70af0579c755fe1a 100644 (file)
@@ -32,6 +32,7 @@
 #include "ardour/location.h"
 #include "ardour/midi_model.h"
 #include "ardour/mute_master.h"
 #include "ardour/location.h"
 #include "ardour/midi_model.h"
 #include "ardour/mute_master.h"
+#include "ardour/presentation_info.h"
 #include "ardour/session.h"
 #include "ardour/source.h"
 #include "ardour/tempo.h"
 #include "ardour/session.h"
 #include "ardour/source.h"
 #include "ardour/tempo.h"
@@ -99,7 +100,6 @@ setup_enum_writer ()
        AutoConnectOption _AutoConnectOption;
        TracksAutoNamingRule _TracksAutoNamingRule;
        Session::StateOfTheState _Session_StateOfTheState;
        AutoConnectOption _AutoConnectOption;
        TracksAutoNamingRule _TracksAutoNamingRule;
        Session::StateOfTheState _Session_StateOfTheState;
-       Route::Flag _Route_Flag;
        Source::Flag _Source_Flag;
        Diskstream::Flag _Diskstream_Flag;
        Location::Flags _Location_Flags;
        Source::Flag _Source_Flag;
        Diskstream::Flag _Diskstream_Flag;
        Location::Flags _Location_Flags;
@@ -134,6 +134,7 @@ setup_enum_writer ()
        Evoral::OverlapType _OverlapType;
         BufferingPreset _BufferingPreset;
        AutoReturnTarget _AutoReturnTarget;
        Evoral::OverlapType _OverlapType;
         BufferingPreset _BufferingPreset;
        AutoReturnTarget _AutoReturnTarget;
+       PresentationInfo::Flag _PresentationInfo_Flag;
 
 #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
 #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
 
 #define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
 #define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
@@ -491,11 +492,6 @@ setup_enum_writer ()
        REGISTER_CLASS_ENUM (Session, pullup_Minus4Minus1);
        REGISTER (_Session_PullupFormat);
 
        REGISTER_CLASS_ENUM (Session, pullup_Minus4Minus1);
        REGISTER (_Session_PullupFormat);
 
-       REGISTER_CLASS_ENUM (Route, Auditioner);
-       REGISTER_CLASS_ENUM (Route, MasterOut);
-       REGISTER_CLASS_ENUM (Route, MonitorOut);
-       REGISTER_BITS (_Route_Flag);
-
        REGISTER_CLASS_ENUM (Source, Writable);
        REGISTER_CLASS_ENUM (Source, CanRename);
        REGISTER_CLASS_ENUM (Source, Broadcast);
        REGISTER_CLASS_ENUM (Source, Writable);
        REGISTER_CLASS_ENUM (Source, CanRename);
        REGISTER_CLASS_ENUM (Source, Broadcast);
@@ -709,6 +705,20 @@ setup_enum_writer ()
        REGISTER_ENUM (Loop);
        REGISTER_ENUM (RegionSelectionStart);
        REGISTER_BITS (_AutoReturnTarget);
        REGISTER_ENUM (Loop);
        REGISTER_ENUM (RegionSelectionStart);
        REGISTER_BITS (_AutoReturnTarget);
+
+       REGISTER_CLASS_ENUM (PresentationInfo, AudioTrack);
+       REGISTER_CLASS_ENUM (PresentationInfo, MidiTrack);
+       REGISTER_CLASS_ENUM (PresentationInfo, AudioBus);
+       REGISTER_CLASS_ENUM (PresentationInfo, MidiBus);
+       REGISTER_CLASS_ENUM (PresentationInfo, MasterOut);
+       REGISTER_CLASS_ENUM (PresentationInfo, MonitorOut);
+       REGISTER_CLASS_ENUM (PresentationInfo, VCA);
+       REGISTER_CLASS_ENUM (PresentationInfo, Bus);
+       REGISTER_CLASS_ENUM (PresentationInfo, Track);
+       REGISTER_CLASS_ENUM (PresentationInfo, Route);
+       REGISTER_CLASS_ENUM (PresentationInfo, Selected);
+       REGISTER_CLASS_ENUM (PresentationInfo, Hidden);
+       REGISTER (_PresentationInfo_Flag);
 }
 
 } /* namespace ARDOUR */
 }
 
 } /* namespace ARDOUR */
index 28214b7e62dcf89e052807a1b7b66a33bb5fb9e5..765402efac93285c1638455c99ef170172472865 100644 (file)
@@ -1033,7 +1033,7 @@ LuaBindings::common (lua_State* L)
                .addFunction ("record_status", &Session::record_status)
                .addFunction ("route_by_id", &Session::route_by_id)
                .addFunction ("route_by_name", &Session::route_by_name)
                .addFunction ("record_status", &Session::record_status)
                .addFunction ("route_by_id", &Session::route_by_id)
                .addFunction ("route_by_name", &Session::route_by_name)
-               .addFunction ("route_by_remote_id", &Session::route_by_remote_id)
+               // STRIPABLE .addFunction ("route_by_remote_id", &Session::route_by_remote_id)
                .addFunction ("track_by_diskstream_id", &Session::track_by_diskstream_id)
                .addFunction ("source_by_id", &Session::source_by_id)
                .addFunction ("controllable_by_id", &Session::controllable_by_id)
                .addFunction ("track_by_diskstream_id", &Session::track_by_diskstream_id)
                .addFunction ("source_by_id", &Session::source_by_id)
                .addFunction ("controllable_by_id", &Session::controllable_by_id)
index f078f1afc2a64430036a6fde60a5266a0846ec6a..6402d9057c437e02cfd6712371cb26e49e391457 100644 (file)
@@ -67,8 +67,8 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
 using namespace ARDOUR;
 using namespace PBD;
 
-MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
-       : Track (sess, name, flag, mode, DataType::MIDI)
+MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
+       : Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
        , _immediate_events(1024) // FIXME: size?
        , _step_edit_ring_buffer(64) // FIXME: size?
        , _note_mode(Sustained)
        , _immediate_events(1024) // FIXME: size?
        , _step_edit_ring_buffer(64) // FIXME: size?
        , _note_mode(Sustained)
diff --git a/libs/ardour/presentation_info.cc b/libs/ardour/presentation_info.cc
new file mode 100644 (file)
index 0000000..6ec45a7
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+    Copyright (C) 2016 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.
+*/
+
+#include <sstream>
+#include <typeinfo>
+
+#include <cassert>
+
+#include "pbd/enumwriter.h"
+#include "pbd/error.h"
+#include "pbd/failed_constructor.h"
+#include "pbd/xml++.h"
+
+#include "ardour/presentation_info.h"
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+using std::string;
+
+const PresentationInfo::order_t PresentationInfo::max_order = UINT32_MAX;
+const PresentationInfo::Flag PresentationInfo::Bus = PresentationInfo::Flag (PresentationInfo::AudioBus|PresentationInfo::MidiBus);
+const PresentationInfo::Flag PresentationInfo::Track = PresentationInfo::Flag (PresentationInfo::AudioTrack|PresentationInfo::MidiTrack);
+const PresentationInfo::Flag PresentationInfo::Route = PresentationInfo::Flag (PresentationInfo::Bus|PresentationInfo::Track);
+
+PresentationInfo::PresentationInfo (std::string const & str)
+{
+       if (parse (str)) {
+               throw failed_constructor ();
+       }
+}
+
+int
+PresentationInfo::parse (string const& str)
+{
+       std::stringstream s (str);
+
+       /* new school, segmented string "NNN:TYPE" */
+       string f;
+       char c;
+       s >> _order;
+       /* skip colon */
+       s >> c;
+       /* grab flags */
+       s >> f;
+       _flags = Flag (string_2_enum (f, _flags)|GroupOrderSet);
+       std::cerr << "Parsed [" << str << "] as " << _order << " + " << enum_2_string (_flags) << std::endl;
+       return 0;
+}
+
+int
+PresentationInfo::parse (uint32_t n, Flag f)
+{
+       if (n < UINT16_MAX) {
+               assert (f != Flag (0));
+               _order = n;
+               _flags = Flag (f|GroupOrderSet);
+       } else {
+               _order = (n & 0xffff);
+               _flags = Flag ((n >> 16)|GroupOrderSet);
+       }
+
+       return 0;
+}
+
+std::string
+PresentationInfo::to_string() const
+{
+       std::stringstream ss;
+
+       /* Do not save or selected hidden status, or group-order set bit */
+
+       Flag f = Flag (_flags & ~(Hidden|Selected|GroupOrderSet));
+
+       ss << _order << ':' << enum_2_string (f);
+
+       return ss.str();
+}
+
+PresentationInfo::Flag
+PresentationInfo::get_flags (XMLNode const& node)
+{
+       const XMLProperty *prop;
+       XMLNodeList nlist = node.children ();
+       XMLNodeConstIterator niter;
+       XMLNode *child;
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter){
+               child = *niter;
+
+               if (child->name() == X_("PresentationInfo")) {
+                       if ((prop = child->property (X_("value"))) != 0) {
+                               PresentationInfo pi (prop->value());
+                               return pi.flags ();
+                       }
+               }
+       }
+       return Flag (0);
+}
+
+std::ostream&
+operator<<(std::ostream& o, ARDOUR::PresentationInfo const& rid)
+{
+       return o << rid.to_string ();
+}
index a449540c6fbf82e64b5bc1d0e910c73f0f58fb54..fead0dc234f5de32b5699f5cc2619a7391a6b452 100644 (file)
@@ -80,14 +80,12 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
 using namespace ARDOUR;
 using namespace PBD;
 
-PBD::Signal0<void> Route::SyncOrderKeys;
-PBD::Signal0<void> Route::RemoteControlIDChange;
 PBD::Signal3<int,boost::shared_ptr<Route>, boost::shared_ptr<PluginInsert>, Route::PluginSetupOptions > Route::PluginSetup;
 
 /** Base class for all routable/mixable objects (tracks and busses) */
 PBD::Signal3<int,boost::shared_ptr<Route>, boost::shared_ptr<PluginInsert>, Route::PluginSetupOptions > Route::PluginSetup;
 
 /** Base class for all routable/mixable objects (tracks and busses) */
-Route::Route (Session& sess, string name, Flag flg, DataType default_type)
+Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType default_type)
        : GraphNode (sess._process_graph)
        : GraphNode (sess._process_graph)
-       , Stripable (sess, name)
+       , Stripable (sess, name, PresentationInfo (flag))
        , Muteable (sess, name)
        , Automatable (sess)
        , _active (true)
        , Muteable (sess, name)
        , Automatable (sess)
        , _active (true)
@@ -98,7 +96,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
        , _roll_delay (0)
        , _pending_process_reorder (0)
        , _pending_signals (0)
        , _roll_delay (0)
        , _pending_process_reorder (0)
        , _pending_signals (0)
-       , _flags (flg)
        , _pending_declick (true)
        , _meter_point (MeterPostFader)
        , _pending_meter_point (MeterPostFader)
        , _pending_declick (true)
        , _meter_point (MeterPostFader)
        , _pending_meter_point (MeterPostFader)
@@ -109,10 +106,6 @@ Route::Route (Session& sess, string name, Flag flg, DataType default_type)
        , _declickable (false)
        , _have_internal_generator (false)
        , _default_type (default_type)
        , _declickable (false)
        , _have_internal_generator (false)
        , _default_type (default_type)
-       , _order_key (0)
-       , _has_order_key (false)
-       , _remote_control_id (0)
-       , _track_number (0)
        , _in_configure_processors (false)
        , _initial_io_setup (false)
        , _in_sidechain_setup (false)
        , _in_configure_processors (false)
        , _initial_io_setup (false)
        , _in_sidechain_setup (false)
@@ -162,7 +155,7 @@ Route::init ()
 
        /* panning */
 
 
        /* panning */
 
-       if (!(_flags & Route::MonitorOut)) {
+       if (!(_presentation_info.flags() & PresentationInfo::MonitorOut)) {
                _pannable.reset (new Pannable (_session));
        }
 
                _pannable.reset (new Pannable (_session));
        }
 
@@ -270,120 +263,6 @@ Route::~Route ()
        _processors.clear ();
 }
 
        _processors.clear ();
 }
 
-void
-Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
-{
-       if (Config->get_remote_model() != UserOrdered) {
-               return;
-       }
-
-       set_remote_control_id_internal (id, notify_class_listeners);
-}
-
-void
-Route::set_remote_control_id_internal (uint32_t id, bool notify_class_listeners)
-{
-       /* force IDs for master/monitor busses and prevent
-          any other route from accidentally getting these IDs
-          (i.e. legacy sessions)
-       */
-
-       if (is_master() && id != MasterBusRemoteControlID) {
-               id = MasterBusRemoteControlID;
-       }
-
-       if (is_monitor() && id != MonitorBusRemoteControlID) {
-               id = MonitorBusRemoteControlID;
-       }
-
-       if (id < 1) {
-               return;
-       }
-
-       /* don't allow it to collide */
-
-       if (!is_master () && !is_monitor() &&
-           (id == MasterBusRemoteControlID || id == MonitorBusRemoteControlID)) {
-               id += MonitorBusRemoteControlID;
-       }
-
-       if (id != remote_control_id()) {
-               _remote_control_id = id;
-               RemoteControlIDChanged ();
-
-               if (notify_class_listeners) {
-                       RemoteControlIDChange ();
-               }
-       }
-}
-
-uint32_t
-Route::remote_control_id() const
-{
-       if (is_master()) {
-               return MasterBusRemoteControlID;
-       }
-
-       if (is_monitor()) {
-               return MonitorBusRemoteControlID;
-       }
-
-       return _remote_control_id;
-}
-
-bool
-Route::has_order_key () const
-{
-       return _has_order_key;
-}
-
-uint32_t
-Route::order_key () const
-{
-       return _order_key;
-}
-
-void
-Route::set_remote_control_id_explicit (uint32_t rid)
-{
-       if (is_master() || is_monitor() || is_auditioner()) {
-               /* hard-coded remote IDs, or no remote ID */
-               return;
-       }
-
-       if (_remote_control_id != rid) {
-               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set edit-based RID to %2\n", name(), rid));
-               _remote_control_id = rid;
-               RemoteControlIDChanged (); /* EMIT SIGNAL (per-route) */
-       }
-
-       /* don't emit the class-level RID signal RemoteControlIDChange here,
-          leave that to the entity that changed the order key, so that we
-          don't get lots of emissions for no good reasons (e.g. when changing
-          all route order keys).
-
-          See Session::sync_remote_id_from_order_keys() for the (primary|only)
-          spot where that is emitted.
-       */
-}
-
-void
-Route::set_order_key (uint32_t n)
-{
-       _has_order_key = true;
-
-       if (_order_key == n) {
-               return;
-       }
-
-       _order_key = n;
-
-       DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1 order key set to %2\n",
-                                                      name(), order_key ()));
-
-       _session.set_dirty ();
-}
-
 string
 Route::ensure_track_or_route_name(string name, Session &session)
 {
 string
 Route::ensure_track_or_route_name(string name, Session &session)
 {
@@ -2357,9 +2236,7 @@ Route::state(bool full_state)
        node->add_property("default-type", _default_type.to_string());
        node->add_property ("strict-io", _strict_io);
 
        node->add_property("default-type", _default_type.to_string());
        node->add_property ("strict-io", _strict_io);
 
-       if (_flags) {
-               node->add_property("flags", enum_2_string (_flags));
-       }
+       Stripable::add_state (*node);
 
        node->add_property("active", _active?"yes":"no");
        string p;
 
        node->add_property("active", _active?"yes":"no");
        string p;
@@ -2372,9 +2249,6 @@ Route::state(bool full_state)
                node->add_property("route-group", _route_group->name());
        }
 
                node->add_property("route-group", _route_group->name());
        }
 
-       snprintf (buf, sizeof (buf), "%d", _order_key);
-       node->add_property ("order-key", buf);
-
        node->add_child_nocopy (_solo_control->get_state ());
        node->add_child_nocopy (_solo_isolate_control->get_state ());
        node->add_child_nocopy (_solo_safe_control->get_state ());
        node->add_child_nocopy (_solo_control->get_state ());
        node->add_child_nocopy (_solo_isolate_control->get_state ());
        node->add_child_nocopy (_solo_safe_control->get_state ());
@@ -2390,11 +2264,6 @@ Route::state(bool full_state)
                node->add_child_nocopy (Automatable::get_automation_xml_state ());
        }
 
                node->add_child_nocopy (Automatable::get_automation_xml_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 (_comment.length()) {
                XMLNode *cmt = node->add_child ("Comment");
                cmt->add_content (_comment);
        if (_comment.length()) {
                XMLNode *cmt = node->add_child ("Comment");
                cmt->add_content (_comment);
@@ -2474,11 +2343,7 @@ Route::set_state (const XMLNode& node, int version)
        set_id (node);
        _initial_io_setup = true;
 
        set_id (node);
        _initial_io_setup = true;
 
-       if ((prop = node.property (X_("flags"))) != 0) {
-               _flags = Flag (string_2_enum (prop->value(), _flags));
-       } else {
-               _flags = Flag (0);
-       }
+       Stripable::set_state (node, version);
 
        if ((prop = node.property (X_("strict-io"))) != 0) {
                _strict_io = string_is_affirmative (prop->value());
 
        if ((prop = node.property (X_("strict-io"))) != 0) {
                _strict_io = string_is_affirmative (prop->value());
@@ -2575,46 +2440,6 @@ Route::set_state (const XMLNode& node, int version)
                set_active (yn, this);
        }
 
                set_active (yn, this);
        }
 
-       if ((prop = node.property (X_("order-key"))) != 0) { // New order key (no separate mixer/editor ordering)
-               set_order_key (atoi(prop->value()));
-       }
-
-       if ((prop = node.property (X_("order-keys"))) != 0) { // Deprecated order keys
-
-               int32_t n;
-
-               string::size_type colon, equal;
-               string remaining = prop->value();
-
-               while (remaining.length()) {
-
-                       if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
-                               error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
-                                     << endmsg;
-                       } else {
-                               if (sscanf (remaining.substr (equal+1).c_str(), "%d", &n) != 1) {
-                                       error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
-                                             << endmsg;
-                               } else {
-                                       string keyname = remaining.substr (0, equal);
-
-                                       if ((keyname == "EditorSort") || (keyname == "editor")) {
-                                               cerr << "Setting " << name() << " order key to " << n << " using saved Editor order." << endl;
-                                               set_order_key (n);
-                                       }
-                               }
-                       }
-
-                       colon = remaining.find_first_of (':');
-
-                       if (colon != string::npos) {
-                               remaining = remaining.substr (colon+1);
-                       } else {
-                               break;
-                       }
-               }
-       }
-
        if ((prop = node.property (X_("processor-after-last-custom-meter"))) != 0) {
                PBD::ID id (prop->value ());
                Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
        if ((prop = node.property (X_("processor-after-last-custom-meter"))) != 0) {
                PBD::ID id (prop->value ());
                Glib::Threads::RWLock::ReaderLock lm (_processor_lock);
@@ -2646,13 +2471,6 @@ Route::set_state (const XMLNode& node, int version)
                                _mute_control->set_state (*child, version);
                        }
 
                                _mute_control->set_state (*child, version);
                        }
 
-               } else if (child->name() == X_("RemoteControl")) {
-                       if ((prop = child->property (X_("id"))) != 0) {
-                               int32_t x;
-                               sscanf (prop->value().c_str(), "%d", &x);
-                               set_remote_control_id_internal (x);
-                       }
-
                } else if (child->name() == MuteMaster::xml_node_name) {
                        _mute_master->set_state (*child, version);
 
                } else if (child->name() == MuteMaster::xml_node_name) {
                        _mute_master->set_state (*child, version);
 
@@ -2684,13 +2502,7 @@ Route::set_state_2X (const XMLNode& node, int version)
                return -1;
        }
 
                return -1;
        }
 
-       if ((prop = node.property (X_("flags"))) != 0) {
-               string f = prop->value ();
-               boost::replace_all (f, "ControlOut", "MonitorOut");
-               _flags = Flag (string_2_enum (f, _flags));
-       } else {
-               _flags = Flag (0);
-       }
+       Stripable::set_state (node, version);
 
        if (is_master() || is_monitor() || is_auditioner()) {
                _mute_master->set_solo_ignore (true);
 
        if (is_master() || is_monitor() || is_auditioner()) {
                _mute_master->set_solo_ignore (true);
@@ -2764,46 +2576,6 @@ Route::set_state_2X (const XMLNode& node, int version)
                _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
        }
 
                _meter_point = MeterPoint (string_2_enum (prop->value (), _meter_point));
        }
 
-       /* do not carry over edit/mix groups from 2.X because (a) its hard (b) they
-          don't mean the same thing.
-       */
-
-       if ((prop = node.property (X_("order-keys"))) != 0) {
-
-               int32_t n;
-
-               string::size_type colon, equal;
-               string remaining = prop->value();
-
-               while (remaining.length()) {
-
-                       if ((equal = remaining.find_first_of ('=')) == string::npos || equal == remaining.length()) {
-                               error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
-                                       << endmsg;
-                       } else {
-                               if (sscanf (remaining.substr (equal+1).c_str(), "%d", &n) != 1) {
-                                       error << string_compose (_("badly formed order key string in state file! [%1] ... ignored."), remaining)
-                                               << endmsg;
-                               } else {
-                                       string keyname = remaining.substr (0, equal);
-
-                                       if (keyname == "EditorSort" || keyname == "editor") {
-                                               info << string_compose(_("Converting deprecated order key for %1 using Editor order %2"), name (), n) << endmsg;
-                                               set_order_key (n);
-                                       }
-                               }
-                       }
-
-                       colon = remaining.find_first_of (':');
-
-                       if (colon != string::npos) {
-                               remaining = remaining.substr (colon+1);
-                       } else {
-                               break;
-                       }
-               }
-       }
-
        /* IOs */
 
        nlist = node.children ();
        /* IOs */
 
        nlist = node.children ();
@@ -2893,13 +2665,6 @@ Route::set_state_2X (const XMLNode& node, int version)
                                _mute_control->set_state (*child, version);
                        }
 
                                _mute_control->set_state (*child, version);
                        }
 
-               } else if (child->name() == X_("RemoteControl")) {
-                       if ((prop = child->property (X_("id"))) != 0) {
-                               int32_t x;
-                               sscanf (prop->value().c_str(), "%d", &x);
-                               set_remote_control_id_internal (x);
-                       }
-
                }
        }
 
                }
        }
 
index 70b9b48d6feb95241e93f002b5c742ca622c6720..7939b29c7c37825ef84ace19de123e4a1dc34d4e 100644 (file)
@@ -198,11 +198,13 @@ struct RouteRecEnabledComparator
        {
                boost::shared_ptr<Track> t1 (boost::dynamic_pointer_cast<Track>(r1));
                boost::shared_ptr<Track> t2 (boost::dynamic_pointer_cast<Track>(r2));
        {
                boost::shared_ptr<Track> t1 (boost::dynamic_pointer_cast<Track>(r1));
                boost::shared_ptr<Track> t2 (boost::dynamic_pointer_cast<Track>(r2));
+               PresentationInfo::global_order_t r1o = r1->presentation_info().global_order();
+               PresentationInfo::global_order_t r2o = r2->presentation_info().global_order();
 
                if (!t1) {
                        if (!t2) {
 
                if (!t1) {
                        if (!t2) {
-                               /* makes no difference which is first, use signal order */
-                               return r1->order_key () < r2->order_key ();
+                               /* makes no difference which is first, use presentation order */
+                               return r1o < r2o;
                        } else {
                                /* r1 is not a track, r2 is, run it early */
                                return false;
                        } else {
                                /* r1 is not a track, r2 is, run it early */
                                return false;
@@ -210,14 +212,14 @@ struct RouteRecEnabledComparator
                }
 
                if (!t2) {
                }
 
                if (!t2) {
-                       /* we already tested !t1, so just use signal order */
-                       return r1->order_key () < r2->order_key ();
+                       /* we already tested !t1, so just use presentation order */
+                       return r1o < r2o;
                }
 
                if (t1->rec_enable_control()->get_value()) {
                        if (t2->rec_enable_control()->get_value()) {
                                /* both rec-enabled, just use signal order */
                }
 
                if (t1->rec_enable_control()->get_value()) {
                        if (t2->rec_enable_control()->get_value()) {
                                /* both rec-enabled, just use signal order */
-                               return t1->order_key () < t2->order_key ();
+                               return r1o < r2o;
                        } else {
                                /* t1 rec-enabled, t2 not rec-enabled, run t2 early */
                                return false;
                        } else {
                                /* t1 rec-enabled, t2 not rec-enabled, run t2 early */
                                return false;
@@ -227,8 +229,8 @@ struct RouteRecEnabledComparator
                                /* t2 rec-enabled, t1 not rec-enabled, run t1 early */
                                return true;
                        } else {
                                /* t2 rec-enabled, t1 not rec-enabled, run t1 early */
                                return true;
                        } else {
-                               /* neither rec-enabled, use signal order */
-                               return t1->order_key () < t2->order_key ();
+                               /* neither rec-enabled, use presentation order */
+                               return r1o < r2o;
                        }
                }
        }
                        }
                }
        }
index 137e2c4734edd324a96f505dd9708765ab7f4d3f..b5f15412f9c2af4394469f25c05756126a1f3e73 100644 (file)
@@ -473,7 +473,7 @@ RouteGroup::make_subgroup (bool aux, Placement placement)
                 * (since tracks can't have fewer outs than ins,
                 * "nin" currently defines the number of outpus if nin > 2)
                 */
                 * (since tracks can't have fewer outs than ins,
                 * "nin" currently defines the number of outpus if nin > 2)
                 */
-               rl = _session.new_audio_route (nin, 2 /*XXX*/, 0, 1);
+               rl = _session.new_audio_route (nin, 2, 0, 1, string(), PresentationInfo::AudioBus, PresentationInfo::max_order);
        } catch (...) {
                return;
        }
        } catch (...) {
                return;
        }
index 55cd1f9ae829df570ff3704c46e15c92344140bc..8856d9d3233503957bfccc32ce00865d677b0ca5 100644 (file)
@@ -92,7 +92,6 @@
 #include "ardour/region_factory.h"
 #include "ardour/route_graph.h"
 #include "ardour/route_group.h"
 #include "ardour/region_factory.h"
 #include "ardour/route_graph.h"
 #include "ardour/route_group.h"
-#include "ardour/route_sorters.h"
 #include "ardour/send.h"
 #include "ardour/session.h"
 #include "ardour/session_directory.h"
 #include "ardour/send.h"
 #include "ardour/session.h"
 #include "ardour/session_directory.h"
@@ -308,7 +307,6 @@ Session::Session (AudioEngine &eng,
        , _step_editors (0)
        , _suspend_timecode_transmission (0)
        ,  _speakers (new Speakers)
        , _step_editors (0)
        , _suspend_timecode_transmission (0)
        ,  _speakers (new Speakers)
-       , _order_hint (-1)
        , ignore_route_processor_changes (false)
        , midi_clock (0)
        , _scene_changer (0)
        , ignore_route_processor_changes (false)
        , midi_clock (0)
        , _scene_changer (0)
@@ -1149,7 +1147,7 @@ Session::add_monitor_section ()
                return;
        }
 
                return;
        }
 
-       boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), Route::MonitorOut, DataType::AUDIO));
+       boost::shared_ptr<Route> r (new Route (*this, _("Monitor"), PresentationInfo::MonitorOut, DataType::AUDIO));
 
        if (r->init ()) {
                return;
 
        if (r->init ()) {
                return;
@@ -1167,7 +1165,7 @@ Session::add_monitor_section ()
        }
 
        rl.push_back (r);
        }
 
        rl.push_back (r);
-       add_routes (rl, false, false, false);
+       add_routes (rl, false, false, false, 0);
 
        assert (_monitor_out);
 
 
        assert (_monitor_out);
 
@@ -2307,8 +2305,7 @@ Session::resort_routes_using (boost::shared_ptr<RouteList> r)
 #ifndef NDEBUG
                DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
                for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 #ifndef NDEBUG
                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 ()));
+                       DEBUG_TRACE (DEBUG::Graph, string_compose ("\t%1 presentation order %2\n", (*i)->name(), (*i)->presentation_info().global_order()));
                }
 #endif
 
                }
 #endif
 
@@ -2426,8 +2423,9 @@ Session::default_track_name_pattern (DataType t)
  *  @param instrument plugin info for the instrument to insert pre-fader, if any
  */
 list<boost::shared_ptr<MidiTrack> >
  *  @param instrument plugin info for the instrument to insert pre-fader, if any
  */
 list<boost::shared_ptr<MidiTrack> >
-Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost::shared_ptr<PluginInfo> instrument,
-                        TrackMode mode, RouteGroup* route_group, uint32_t how_many, string name_template, Plugin::PresetRecord* pset)
+Session::new_midi_track (boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
+                         RouteGroup* route_group, uint32_t how_many, string name_template, PresentationInfo::order_t order, 
+                         TrackMode mode)
 {
        string track_name;
        uint32_t track_id = 0;
 {
        string track_name;
        uint32_t track_id = 0;
@@ -2447,7 +2445,7 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
                boost::shared_ptr<MidiTrack> track;
 
                try {
                boost::shared_ptr<MidiTrack> track;
 
                try {
-                       track.reset (new MidiTrack (*this, track_name, Route::Flag (0), mode));
+                       track.reset (new MidiTrack (*this, track_name, mode));
 
                        if (track->init ()) {
                                goto failed;
 
                        if (track->init ()) {
                                goto failed;
@@ -2482,14 +2480,8 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
 
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
 
 
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
 
-                       if (Config->get_remote_model() == UserOrdered) {
-                               track->set_remote_control_id (next_control_id());
-                       }
-
                        new_routes.push_back (track);
                        ret.push_back (track);
                        new_routes.push_back (track);
                        ret.push_back (track);
-
-                       RouteAddedOrRemoved (true); /* EMIT SIGNAL */
                }
 
                catch (failed_constructor &err) {
                }
 
                catch (failed_constructor &err) {
@@ -2510,9 +2502,9 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
        if (!new_routes.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
        if (!new_routes.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
-                       add_routes (new_routes, false, false, false);
+                       add_routes (new_routes, false, false, false, order);
                } else {
                } else {
-                       add_routes (new_routes, true, true, false);
+                       add_routes (new_routes, true, true, false, order);
                }
 
                if (instrument) {
                }
 
                if (instrument) {
@@ -2532,7 +2524,8 @@ Session::new_midi_track (const ChanCount& input, const ChanCount& output, boost:
 }
 
 RouteList
 }
 
 RouteList
-Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset)
+Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name_template, boost::shared_ptr<PluginInfo> instrument, Plugin::PresetRecord* pset,
+                         PresentationInfo::Flag flag, PresentationInfo::order_t order)
 {
        string bus_name;
        uint32_t bus_id = 0;
 {
        string bus_name;
        uint32_t bus_id = 0;
@@ -2546,9 +2539,9 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
                        error << "cannot find name for new midi bus" << endmsg;
                        goto failure;
                }
                        error << "cannot find name for new midi bus" << endmsg;
                        goto failure;
                }
-
+               
                try {
                try {
-                       boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
+                       boost::shared_ptr<Route> bus (new Route (*this, bus_name, flag, DataType::AUDIO)); // XXX Editor::add_routes is not ready for ARDOUR::DataType::MIDI
 
                        if (bus->init ()) {
                                goto failure;
 
                        if (bus->init ()) {
                                goto failure;
@@ -2578,13 +2571,8 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
                        if (route_group) {
                                route_group->add (bus);
                        }
                        if (route_group) {
                                route_group->add (bus);
                        }
-                       if (Config->get_remote_model() == UserOrdered) {
-                               bus->set_remote_control_id (next_control_id());
-                       }
 
                        ret.push_back (bus);
 
                        ret.push_back (bus);
-                       RouteAddedOrRemoved (true); /* EMIT SIGNAL */
-                       ARDOUR::GUIIdle ();
                }
 
                catch (failed_constructor &err) {
                }
 
                catch (failed_constructor &err) {
@@ -2604,7 +2592,7 @@ Session::new_midi_route (RouteGroup* route_group, uint32_t how_many, string name
   failure:
        if (!ret.empty()) {
                StateProtector sp (this);
   failure:
        if (!ret.empty()) {
                StateProtector sp (this);
-               add_routes (ret, false, false, false);
+               add_routes (ret, false, false, false, order);
 
                if (instrument) {
                        for (RouteList::iterator r = ret.begin(); r != ret.end(); ++r) {
 
                if (instrument) {
                        for (RouteList::iterator r = ret.begin(); r != ret.end(); ++r) {
@@ -2931,12 +2919,36 @@ Session::reconnect_mmc_ports(bool inputs)
 
 #endif
 
 
 #endif
 
+void
+Session::ensure_presentation_info_gap (PresentationInfo::order_t first_new_order, uint32_t how_many)
+{
+       if (first_new_order == PresentationInfo::max_order) {
+               /* adding at end, no worries */
+               return;
+       }
+
+       /* create a gap in the existing route order keys to accomodate new routes.*/
+       boost::shared_ptr <RouteList> rd = routes.reader();
+       for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
+               boost::shared_ptr<Route> rt (*ri);
+
+               if (rt->presentation_info().special()) {
+                       continue;
+               }
+
+               if (rt->presentation_info().group_order () >= first_new_order) {
+                       rt->set_presentation_group_order (rt->presentation_info().group_order () + how_many);
+               }
+       }
+}
+
 /** Caller must not hold process lock
  *  @param name_template string to use for the start of the name, or "" to use "Audio".
  */
 list< boost::shared_ptr<AudioTrack> >
 /** Caller must not hold process lock
  *  @param name_template string to use for the start of the name, or "" to use "Audio".
  */
 list< boost::shared_ptr<AudioTrack> >
-Session::new_audio_track (int input_channels, int output_channels, TrackMode mode, RouteGroup* route_group,
-                         uint32_t how_many, string name_template)
+Session::new_audio_track (int input_channels, int output_channels, RouteGroup* route_group,
+                          uint32_t how_many, string name_template, PresentationInfo::order_t order,
+                          TrackMode mode)
 {
        string track_name;
        uint32_t track_id = 0;
 {
        string track_name;
        uint32_t track_id = 0;
@@ -2957,7 +2969,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
                boost::shared_ptr<AudioTrack> track;
 
                try {
                boost::shared_ptr<AudioTrack> track;
 
                try {
-                       track.reset (new AudioTrack (*this, track_name, Route::Flag (0), mode));
+                       track.reset (new AudioTrack (*this, track_name, mode));
 
                        if (track->init ()) {
                                goto failed;
 
                        if (track->init ()) {
                                goto failed;
@@ -2967,7 +2979,6 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
                                track->set_strict_io (true);
                        }
 
                                track->set_strict_io (true);
                        }
 
-
                        if (ARDOUR::Profile->get_trx ()) {
                                // TRACKS considers it's not a USE CASE, it's
                                // a piece of behavior of the session model:
                        if (ARDOUR::Profile->get_trx ()) {
                                // TRACKS considers it's not a USE CASE, it's
                                // a piece of behavior of the session model:
@@ -3013,14 +3024,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->non_realtime_input_change();
 
                        track->DiskstreamChanged.connect_same_thread (*this, boost::bind (&Session::resort_routes, this));
-                       if (Config->get_remote_model() == UserOrdered) {
-                               track->set_remote_control_id (next_control_id());
-                       }
 
                        new_routes.push_back (track);
                        ret.push_back (track);
 
                        new_routes.push_back (track);
                        ret.push_back (track);
-
-                       RouteAddedOrRemoved (true); /* EMIT SIGNAL */
                }
 
                catch (failed_constructor &err) {
                }
 
                catch (failed_constructor &err) {
@@ -3041,9 +3047,9 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
        if (!new_routes.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
        if (!new_routes.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
-                       add_routes (new_routes, false, false, false);
+                       add_routes (new_routes, false, false, false, order);
                } else {
                } else {
-                       add_routes (new_routes, true, true, false);
+                       add_routes (new_routes, true, true, false, order);
                }
        }
 
                }
        }
 
@@ -3054,7 +3060,8 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
  *  @param name_template string to use for the start of the name, or "" to use "Bus".
  */
 RouteList
  *  @param name_template string to use for the start of the name, or "" to use "Bus".
  */
 RouteList
-Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template)
+Session::new_audio_route (int input_channels, int output_channels, RouteGroup* route_group, uint32_t how_many, string name_template,
+                          PresentationInfo::Flag flags, PresentationInfo::order_t order)
 {
        string bus_name;
        uint32_t bus_id = 0;
 {
        string bus_name;
        uint32_t bus_id = 0;
@@ -3063,6 +3070,8 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
 
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
 
 
        bool const use_number = (how_many != 1) || name_template.empty () || name_template == _("Bus");
 
+       ensure_presentation_info_gap (order, how_many);
+
        while (how_many) {
                if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, use_number)) {
                        error << "cannot find name for new audio bus" << endmsg;
        while (how_many) {
                if (!find_route_name (name_template.empty () ? _("Bus") : name_template, ++bus_id, bus_name, use_number)) {
                        error << "cannot find name for new audio bus" << endmsg;
@@ -3070,7 +3079,7 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
                }
 
                try {
                }
 
                try {
-                       boost::shared_ptr<Route> bus (new Route (*this, bus_name, Route::Flag(0), DataType::AUDIO));
+                       boost::shared_ptr<Route> bus (new Route (*this, bus_name, flags, DataType::AUDIO));
 
                        if (bus->init ()) {
                                goto failure;
 
                        if (bus->init ()) {
                                goto failure;
@@ -3104,20 +3113,11 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
                        if (route_group) {
                                route_group->add (bus);
                        }
                        if (route_group) {
                                route_group->add (bus);
                        }
-                       if (Config->get_remote_model() == UserOrdered) {
-                               bus->set_remote_control_id (next_control_id());
-                       }
 
                        bus->add_internal_return ();
 
                        bus->add_internal_return ();
-
                        ret.push_back (bus);
                        ret.push_back (bus);
-
-                       RouteAddedOrRemoved (true); /* EMIT SIGNAL */
-
-                       ARDOUR::GUIIdle ();
                }
 
                }
 
-
                catch (failed_constructor &err) {
                        error << _("Session: could not create new audio route.") << endmsg;
                        goto failure;
                catch (failed_constructor &err) {
                        error << _("Session: could not create new audio route.") << endmsg;
                        goto failure;
@@ -3136,9 +3136,9 @@ Session::new_audio_route (int input_channels, int output_channels, RouteGroup* r
        if (!ret.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
        if (!ret.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
-                       add_routes (ret, false, false, false);
+                       add_routes (ret, false, false, false, order);
                } else {
                } else {
-                       add_routes (ret, false, true, true); // autoconnect // outputs only
+                       add_routes (ret, false, true, true, order); // autoconnect // outputs only
                }
        }
 
                }
        }
 
@@ -3162,7 +3162,6 @@ RouteList
 Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::string& name_base, PlaylistDisposition pd)
 {
        RouteList ret;
 Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::string& name_base, PlaylistDisposition pd)
 {
        RouteList ret;
-       uint32_t control_id;
        uint32_t number = 0;
        const uint32_t being_added = how_many;
        /* This will prevent the use of any existing XML-provided PBD::ID
        uint32_t number = 0;
        const uint32_t being_added = how_many;
        /* This will prevent the use of any existing XML-provided PBD::ID
@@ -3171,8 +3170,6 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
        Stateful::ForceIDRegeneration force_ids;
        IO::disable_connecting ();
 
        Stateful::ForceIDRegeneration force_ids;
        IO::disable_connecting ();
 
-       control_id = next_control_id ();
-
        while (how_many) {
 
                /* We're going to modify the node contents a bit so take a
        while (how_many) {
 
                /* We're going to modify the node contents a bit so take a
@@ -3293,9 +3290,6 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
                                route->output()->changed (change, this);
                        }
 
                                route->output()->changed (change, this);
                        }
 
-                       route->set_remote_control_id (control_id);
-                       ++control_id;
-
                        boost::shared_ptr<Track> track;
 
                        if ((track = boost::dynamic_pointer_cast<Track> (route))) {
                        boost::shared_ptr<Track> track;
 
                        if ((track = boost::dynamic_pointer_cast<Track> (route))) {
@@ -3312,8 +3306,6 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
                        };
 
                        ret.push_back (route);
                        };
 
                        ret.push_back (route);
-
-                       RouteAddedOrRemoved (true); /* EMIT SIGNAL */
                }
 
                catch (failed_constructor &err) {
                }
 
                catch (failed_constructor &err) {
@@ -3333,9 +3325,9 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
        if (!ret.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
        if (!ret.empty()) {
                StateProtector sp (this);
                if (Profile->get_trx()) {
-                       add_routes (ret, false, false, false);
+                       add_routes (ret, false, false, false, PresentationInfo::max_order);
                } else {
                } else {
-                       add_routes (ret, true, true, false);
+                       add_routes (ret, true, true, false, PresentationInfo::max_order);
                }
                IO::enable_connecting ();
        }
                }
                IO::enable_connecting ();
        }
@@ -3344,11 +3336,11 @@ Session::new_route_from_template (uint32_t how_many, XMLNode& node, const std::s
 }
 
 void
 }
 
 void
-Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save)
+Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, bool save, PresentationInfo::order_t order)
 {
        try {
                PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
 {
        try {
                PBD::Unwinder<bool> aip (_adding_routes_in_progress, true);
-               add_routes_inner (new_routes, input_auto_connect, output_auto_connect);
+               add_routes_inner (new_routes, input_auto_connect, output_auto_connect, order);
 
        } catch (...) {
                error << _("Adding new tracks/busses failed") << endmsg;
 
        } catch (...) {
                error << _("Adding new tracks/busses failed") << endmsg;
@@ -3365,25 +3357,18 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output
                save_state (_current_snapshot_name);
        }
 
                save_state (_current_snapshot_name);
        }
 
-       reassign_track_numbers();
-
        update_route_record_state ();
 
        RouteAdded (new_routes); /* EMIT SIGNAL */
 }
 
 void
        update_route_record_state ();
 
        RouteAdded (new_routes); /* EMIT SIGNAL */
 }
 
 void
-Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect)
+Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool output_auto_connect, PresentationInfo::order_t order)
 {
        ChanCount existing_inputs;
        ChanCount existing_outputs;
 {
        ChanCount existing_inputs;
        ChanCount existing_outputs;
-       uint32_t order = next_control_id();
-
-
-       if (_order_hint > -1) {
-               order = _order_hint;
-               _order_hint = -1;
-       }
+       uint32_t n_routes;
+       uint32_t added = 0;
 
        count_existing_track_channels (existing_inputs, existing_outputs);
 
 
        count_existing_track_channels (existing_inputs, existing_outputs);
 
@@ -3391,6 +3376,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
                RCUWriter<RouteList> writer (routes);
                boost::shared_ptr<RouteList> r = writer.get_copy ();
                r->insert (r->end(), new_routes.begin(), new_routes.end());
                RCUWriter<RouteList> writer (routes);
                boost::shared_ptr<RouteList> r = writer.get_copy ();
                r->insert (r->end(), new_routes.begin(), new_routes.end());
+               n_routes = r->size();
 
                /* if there is no control out and we're not in the middle of loading,
                 * resort the graph here. if there is a control out, we will resort
 
                /* if there is no control out and we're not in the middle of loading,
                 * resort the graph here. if there is a control out, we will resort
@@ -3403,7 +3389,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
                }
        }
 
                }
        }
 
-       for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
+       DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("ensure order gap starting at %1 for %2\n", order, new_routes.size()));
+       ensure_presentation_info_gap (order, new_routes.size());
+
+       for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x, ++added) {
 
                boost::weak_ptr<Route> wpr (*x);
                boost::shared_ptr<Route> r (*x);
 
                boost::weak_ptr<Route> wpr (*x);
                boost::shared_ptr<Route> r (*x);
@@ -3436,28 +3425,41 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
                        }
                }
 
                        }
                }
 
-               if (input_auto_connect || output_auto_connect) {
-                       auto_connect_route (r, input_auto_connect, ChanCount (), ChanCount (), existing_inputs, existing_outputs);
-                       existing_inputs += r->n_inputs();
-                       existing_outputs += r->n_outputs();
-               }
+               if (!r->presentation_info().special()) {
 
 
-               /* order keys are a GUI responsibility but we need to set up
-                        reasonable defaults because they also affect the remote control
-                        ID in most situations.
-                        */
+                       DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("checking PI state for %1\n", r->name()));
+
+                       /* presentation info order may already have been set from XML */
+
+                       if (r->presentation_info().unordered()) {
 
 
-               if (!r->has_order_key ()) {
-                       if (r->is_auditioner()) {
-                               /* use an arbitrarily high value */
-                               r->set_order_key (UINT_MAX);
+                               if (order == PresentationInfo::max_order) {
+                                       /* just add to the end */
+                                       r->set_presentation_group_order_explicit (n_routes + added);
+                                       DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to NR %1 + %2 = %3\n", n_routes, added, n_routes + added));
+                               } else {
+                                       r->set_presentation_group_order_explicit (order + added);
+                                       DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order not set, set to %1 + %2 = %3\n", order, added, order + added));
+                               }
                        } else {
                        } else {
-                               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("while adding, set %1 to order key %2\n", r->name(), order));
-                               r->set_order_key (order);
-                               order++;
+                               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("group order already set to %1\n", r->presentation_info().group_order()));
                        }
                }
 
                        }
                }
 
+               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("added route %1, group order %2 global order %3 type %4 (summary: %5)\n",
+                                                              r->name(),
+                                                              r->presentation_info().group_order(),
+                                                              r->presentation_info().global_order(),
+                                                              enum_2_string (r->presentation_info().flags()),
+                                                              r->presentation_info().to_string()));
+
+
+               if (input_auto_connect || output_auto_connect) {
+                       auto_connect_route (r, input_auto_connect, ChanCount (), ChanCount (), existing_inputs, existing_outputs);
+                       existing_inputs += r->n_inputs();
+                       existing_outputs += r->n_outputs();
+               }
+
                ARDOUR::GUIIdle ();
        }
 
                ARDOUR::GUIIdle ();
        }
 
@@ -3631,7 +3633,6 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
        } // end of RCU Writer scope
 
        update_route_solo_state ();
        } // end of RCU Writer scope
 
        update_route_solo_state ();
-       RouteAddedOrRemoved (false); /* EMIT SIGNAL */
        update_latency_compensation ();
        set_dirty();
 
        update_latency_compensation ();
        set_dirty();
 
@@ -3668,7 +3669,7 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
                return;
        }
 
                return;
        }
 
-       Route::RemoteControlIDChange(); /* EMIT SIGNAL */
+       Stripable::PresentationInfoChange(); /* EMIT SIGNAL */
 
        /* save the new state of the world */
 
 
        /* save the new state of the world */
 
@@ -3676,7 +3677,6 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
                save_history (_current_snapshot_name);
        }
 
                save_history (_current_snapshot_name);
        }
 
-       reassign_track_numbers();
        update_route_record_state ();
 }
 
        update_route_record_state ();
 }
 
@@ -4028,7 +4028,7 @@ Session::get_routes_with_internal_returns() const
 }
 
 bool
 }
 
 bool
-Session::io_name_is_legal (const std::string& name)
+Session::io_name_is_legal (const std::string& name) const
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
@@ -4137,7 +4137,7 @@ Session::routes_using_input_from (const string& str, RouteList& rl)
 }
 
 boost::shared_ptr<Route>
 }
 
 boost::shared_ptr<Route>
-Session::route_by_name (string name)
+Session::route_by_name (string name) const
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
@@ -4151,7 +4151,7 @@ Session::route_by_name (string name)
 }
 
 boost::shared_ptr<Route>
 }
 
 boost::shared_ptr<Route>
-Session::route_by_id (PBD::ID id)
+Session::route_by_id (PBD::ID id) const
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
@@ -4180,7 +4180,7 @@ Session::processor_by_id (PBD::ID id) const
 }
 
 boost::shared_ptr<Track>
 }
 
 boost::shared_ptr<Track>
-Session::track_by_diskstream_id (PBD::ID id)
+Session::track_by_diskstream_id (PBD::ID id) const
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
@@ -4195,37 +4195,34 @@ Session::track_by_diskstream_id (PBD::ID id)
 }
 
 boost::shared_ptr<Route>
 }
 
 boost::shared_ptr<Route>
-Session::route_by_remote_id (uint32_t id)
+Session::get_remote_nth_route (uint16_t n) const
 {
 {
-       boost::shared_ptr<RouteList> r = routes.reader ();
-
-       for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-               if ((*i)->remote_control_id() == id) {
-                       return *i;
-               }
-       }
-
-       return boost::shared_ptr<Route> ((Route*) 0);
+       return boost::dynamic_pointer_cast<Route> (get_remote_nth_stripable (n, PresentationInfo::Route));
 }
 
 }
 
-
 boost::shared_ptr<Stripable>
 boost::shared_ptr<Stripable>
-Session::stripable_by_remote_id (uint32_t id)
+Session::get_remote_nth_stripable (uint16_t n, PresentationInfo::Flag flags) const
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
+       vector<boost::shared_ptr<Route> > v;
+
+       if (n > r->size()) {
+               return boost::shared_ptr<Route> ();
+       }
+
+       v.assign (r->size(), boost::shared_ptr<Route>());
 
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
 
        for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-               if ((*i)->remote_control_id() == id) {
-                       return *i;
+               if ((*i)->presentation_info().flag_match (flags)) {
+                       v[(*i)->presentation_info().group_order()] = (*i);
                }
        }
 
                }
        }
 
-       return boost::shared_ptr<Route> ((Route*) 0);
+       return v[n];
 }
 
 }
 
-
 boost::shared_ptr<Route>
 boost::shared_ptr<Route>
-Session::route_by_selected_count (uint32_t id)
+Session::route_by_selected_count (uint32_t id) const
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
 {
        boost::shared_ptr<RouteList> r = routes.reader ();
 
@@ -4236,6 +4233,19 @@ Session::route_by_selected_count (uint32_t id)
        return boost::shared_ptr<Route> ((Route*) 0);
 }
 
        return boost::shared_ptr<Route> ((Route*) 0);
 }
 
+struct PresentationOrderSorter {
+       bool operator() (boost::shared_ptr<Stripable> a, boost::shared_ptr<Stripable> b) {
+               if (a->presentation_info().special() && !b->presentation_info().special()) {
+                       /* a is not ordered, b is; b comes before a */
+                       return false;
+               } else if (b->presentation_info().unordered() && !a->presentation_info().unordered()) {
+                       /* b is not ordered, a is; a comes before b */
+                       return true;
+               } else {
+                       return a->presentation_info().global_order() < b->presentation_info().global_order();
+               }
+       }
+};
 
 void
 Session::reassign_track_numbers ()
 
 void
 Session::reassign_track_numbers ()
@@ -4243,7 +4253,7 @@ Session::reassign_track_numbers ()
        int64_t tn = 0;
        int64_t bn = 0;
        RouteList r (*(routes.reader ()));
        int64_t tn = 0;
        int64_t bn = 0;
        RouteList r (*(routes.reader ()));
-       SignalOrderRouteSorter sorter;
+       PresentationOrderSorter sorter;
        r.sort (sorter);
 
        StateProtector sp (this);
        r.sort (sorter);
 
        StateProtector sp (this);
@@ -5319,7 +5329,7 @@ Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::
        if (b->is_monitor()) {
                return false;
        }
        if (b->is_monitor()) {
                return false;
        }
-       return a->order_key () < b->order_key ();
+       return a->presentation_info() < b->presentation_info();
 }
 
 bool
 }
 
 bool
@@ -6659,31 +6669,8 @@ Session::session_name_is_legal (const string& path)
        return 0;
 }
 
        return 0;
 }
 
-uint32_t
-Session::next_control_id () const
-{
-       int subtract = 0;
-
-       /* the monitor bus remote ID is in a different
-        * "namespace" than regular routes. its existence doesn't
-        * affect normal (low) numbered routes.
-        */
-
-       if (_monitor_out) {
-               subtract++;
-       }
-
-       /* the same about masterbus in Waves Tracks */
-
-       if (Profile->get_trx() && _master_out) {
-               subtract++;
-       }
-
-       return nroutes() - subtract;
-}
-
 void
 void
-Session::notify_remote_id_change ()
+Session::notify_presentation_info_change ()
 {
        if (deletion_in_progress()) {
                return;
 {
        if (deletion_in_progress()) {
                return;
@@ -6691,41 +6678,21 @@ Session::notify_remote_id_change ()
 
        switch (Config->get_remote_model()) {
        case MixerOrdered:
 
        switch (Config->get_remote_model()) {
        case MixerOrdered:
-               Route::RemoteControlIDChange (); /* EMIT SIGNAL */
+               Stripable::PresentationInfoChange (); /* EMIT SIGNAL */
                break;
        default:
                break;
        }
 
                break;
        default:
                break;
        }
 
-#ifdef USE_TRACKS_CODE_FEATURES
-               /* Waves Tracks: for Waves Tracks session it's required to reconnect their IOs
-                * if track order has been changed by user
-                */
-               reconnect_existing_routes(true, true);
-#endif
-
-}
-
-void
-Session::sync_order_keys ()
-{
-       if (deletion_in_progress()) {
-               return;
-       }
-
-       /* tell everyone that something has happened to the sort keys
-          and let them sync up with the change(s)
-          this will give objects that manage the sort order keys the
-          opportunity to keep them in sync if they wish to.
-       */
-
-       DEBUG_TRACE (DEBUG::OrderKeys, "Sync Order Keys.\n");
-
        reassign_track_numbers();
 
        reassign_track_numbers();
 
-       Route::SyncOrderKeys (); /* EMIT SIGNAL */
+#ifdef USE_TRACKS_CODE_FEATURES
+       /* Waves Tracks: for Waves Tracks session it's required to reconnect their IOs
+        * if track order has been changed by user
+        */
+       reconnect_existing_routes(true, true);
+#endif
 
 
-       DEBUG_TRACE (DEBUG::OrderKeys, "\tsync done\n");
 }
 
 bool
 }
 
 bool
index 390f1de32f6dea56900a265c111d5d43c2a45040..f3a8d7dd81bd58d2e538535406b7cd8fdbc4eaa8 100644 (file)
@@ -335,6 +335,30 @@ Session::mmc_shuttle (MIDI::MachineControl &/*mmc*/, float speed, bool forw)
        }
 }
 
        }
 }
 
+boost::shared_ptr<Route>
+Session::get_midi_nth_route_by_id (PresentationInfo::order_t n) const
+{
+       PresentationInfo id (PresentationInfo::Flag (0));
+
+       if (n == 318) {
+               id.set_flags (PresentationInfo::MasterOut);
+       } else if (n == 319) {
+               id.set_flags (PresentationInfo::MonitorOut);
+       } else {
+               id = PresentationInfo (n, PresentationInfo::Route);
+       }
+
+       boost::shared_ptr<RouteList> r = routes.reader ();
+
+       for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+               if ((*i)->presentation_info().match (id)) {
+                       return *i;
+               }
+       }
+
+       return boost::shared_ptr<Route>();
+}
+
 void
 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
 {
 void
 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
 {
@@ -342,17 +366,13 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
                return;
        }
 
                return;
        }
 
-       RouteList::iterator i;
-       boost::shared_ptr<RouteList> r = routes.reader();
+       boost::shared_ptr<Route> r = get_midi_nth_route_by_id (trk);
 
 
-       for (i = r->begin(); i != r->end(); ++i) {
-               AudioTrack *at;
+       if (r) {
+               boost::shared_ptr<AudioTrack> at;
 
 
-               if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
-                       if (trk == at->remote_control_id()) {
-                               at->rec_enable_control()->set_value (enabled, Controllable::UseGroup);
-                               break;
-                       }
+               if ((at = boost::dynamic_pointer_cast<AudioTrack> (r))) {
+                       at->rec_enable_control()->set_value (enabled, Controllable::UseGroup);
                }
        }
 }
                }
        }
 }
@@ -696,4 +716,3 @@ Session::mtc_input_port () const
 {
        return _midi_ports->mtc_input_port ();
 }
 {
        return _midi_ports->mtc_input_port ();
 }
-
index ebbd37e4f9a71bc26702b04599a98bf4074fcd90..5b10389a3f620f0a058db2719f4d91adacf3e8b3 100644 (file)
@@ -628,7 +628,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
 
        _state_of_the_state = Clean;
 
 
        _state_of_the_state = Clean;
 
-        /* set up Master Out and Control Out if necessary */
+        /* set up Master Out and Monitor Out if necessary */
 
         if (bus_profile) {
 
 
         if (bus_profile) {
 
@@ -637,7 +637,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
 
                 // Waves Tracks: always create master bus for Tracks
                 if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) {
 
                 // Waves Tracks: always create master bus for Tracks
                 if (ARDOUR::Profile->get_trx() || bus_profile->master_out_channels) {
-                       boost::shared_ptr<Route> r (new Route (*this, _("Master"), Route::MasterOut, DataType::AUDIO));
+                       boost::shared_ptr<Route> r (new Route (*this, _("Master"), PresentationInfo::MasterOut, DataType::AUDIO));
                         if (r->init ()) {
                                 return -1;
                         }
                         if (r->init ()) {
                                 return -1;
                         }
@@ -658,7 +658,7 @@ Session::create (const string& session_template, BusProfile* bus_profile)
                }
 
                if (!rl.empty()) {
                }
 
                if (!rl.empty()) {
-                       add_routes (rl, false, false, false);
+                       add_routes (rl, false, false, false, PresentationInfo::max_order);
                }
 
                // Waves Tracks: Skip this. Always use autoconnection for Tracks
                }
 
                // Waves Tracks: Skip this. Always use autoconnection for Tracks
@@ -1593,7 +1593,7 @@ Session::load_routes (const XMLNode& node, int version)
 
        BootMessage (_("Tracks/busses loaded;  Adding to Session"));
 
 
        BootMessage (_("Tracks/busses loaded;  Adding to Session"));
 
-       add_routes (new_routes, false, false, false);
+       add_routes (new_routes, false, false, false, PresentationInfo::max_order);
 
        BootMessage (_("Finished adding tracks/busses"));
 
 
        BootMessage (_("Finished adding tracks/busses"));
 
@@ -1642,12 +1642,7 @@ Session::XMLRouteFactory (const XMLNode& node, int version)
                 ret = track;
 
        } else {
                 ret = track;
 
        } else {
-               enum Route::Flag flags = Route::Flag(0);
-               XMLProperty const * prop = node.property("flags");
-               if (prop) {
-                       flags = Route::Flag (string_2_enum (prop->value(), flags));
-               }
-
+               PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
                boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
 
                 if (r->init () == 0 && r->set_state (node, version) == 0) {
                boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
 
                 if (r->init () == 0 && r->set_state (node, version) == 0) {
@@ -1716,12 +1711,7 @@ Session::XMLRouteFactory_2X (const XMLNode& node, int version)
                 ret = track;
 
        } else {
                 ret = track;
 
        } else {
-               enum Route::Flag flags = Route::Flag(0);
-               XMLProperty const * prop = node.property("flags");
-               if (prop) {
-                       flags = Route::Flag (string_2_enum (prop->value(), flags));
-               }
-
+               PresentationInfo::Flag flags = PresentationInfo::get_flags (node);
                boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
 
                 if (r->init () == 0 && r->set_state (node, version) == 0) {
                boost::shared_ptr<Route> r (new Route (*this, X_("toBeResetFroXML"), flags));
 
                 if (r->init () == 0 && r->set_state (node, version) == 0) {
@@ -3423,7 +3413,7 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
        }
 
        case ControllableDescriptor::RemoteControlID:
        }
 
        case ControllableDescriptor::RemoteControlID:
-               r = route_by_remote_id (desc.rid());
+               r = get_remote_nth_route (desc.rid());
                break;
 
        case ControllableDescriptor::SelectionCount:
                break;
 
        case ControllableDescriptor::SelectionCount:
diff --git a/libs/ardour/stripable.cc b/libs/ardour/stripable.cc
new file mode 100644 (file)
index 0000000..d322fd7
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+    Copyright (C) 2016 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.
+
+*/
+
+#include <boost/algorithm/string.hpp>
+
+#include "pbd/compose.h"
+#include "pbd/convert.h"
+
+#include "ardour/debug.h"
+#include "ardour/rc_configuration.h"
+#include "ardour/stripable.h"
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+using std::string;
+
+PBD::Signal0<void> Stripable::PresentationInfoChange;
+
+Stripable::Stripable (Session& s, string const & name, PresentationInfo const & pi)
+       : SessionObject (s, name)
+       , _presentation_info (pi)
+{
+}
+
+void
+Stripable::set_presentation_group_order (PresentationInfo::order_t order, bool notify_class_listeners)
+{
+       set_presentation_info_internal (PresentationInfo (order, _presentation_info.flags()), notify_class_listeners);
+}
+
+void
+Stripable::set_presentation_group_order_explicit (PresentationInfo::order_t order)
+{
+       set_presentation_group_order (order, false);
+}
+
+void
+Stripable::set_presentation_info (PresentationInfo pi, bool notify_class_listeners)
+{
+       if (Config->get_remote_model() != UserOrdered) {
+               return;
+       }
+
+       set_presentation_info_internal (pi, notify_class_listeners);
+}
+
+void
+Stripable::set_presentation_info_internal (PresentationInfo pi, bool notify_class_listeners)
+{
+       if (pi != presentation_info()) {
+
+               DEBUG_TRACE (DEBUG::OrderKeys, string_compose ("%1: set edit-based RID to %2\n", name(), pi));
+
+               if (is_master()) {
+                       _presentation_info = PresentationInfo (0, PresentationInfo::MasterOut);
+               } else if (is_monitor()) {
+                       _presentation_info = PresentationInfo (0, PresentationInfo::MonitorOut);
+               } else {
+                       _presentation_info = pi;
+               }
+
+               PresentationInfoChanged ();
+
+               if (notify_class_listeners) {
+                       PresentationInfoChange ();
+               }
+       }
+}
+
+void
+Stripable::set_presentation_info_explicit (PresentationInfo pi)
+{
+       set_presentation_info_internal (pi, false);
+}
+
+int
+Stripable::set_state (XMLNode const& node, int version)
+{
+       const XMLProperty *prop;
+       XMLNodeList const & nlist (node.children());
+       XMLNodeConstIterator niter;
+       XMLNode *child;
+
+       if (version > 3000) {
+
+               std::cerr << "Looking for PI\n";
+
+               for (niter = nlist.begin(); niter != nlist.end(); ++niter){
+                       child = *niter;
+
+                       if (child->name() == X_("PresentationInfo")) {
+                               std::cerr << "Found it\n";
+                               if ((prop = child->property (X_("value"))) != 0) {
+                                       _presentation_info = prop->value ();
+                                       std::cerr << "Set pinfo to " << _presentation_info << " from " << prop->value() << std::endl;
+                               }
+                       }
+               }
+
+       } else {
+               std::cerr << "Old\n";
+
+               /* Older versions of Ardour stored "_flags" as a property of the Route
+                * node, only for 3 special Routes (MasterOut, MonitorOut, Auditioner.
+                *
+                * Their presentation order was stored in a node called "RemoteControl"
+                *
+                * This information is now part of the PresentationInfo of every Stripable.
+                */
+
+               if ((prop = node.property (X_("flags"))) != 0) {
+
+                       /* 4.x and earlier - didn't have Stripable but the
+                        * relevant enums have the same names (MasterOut,
+                        * MonitorOut, Auditioner), so we can use string_2_enum
+                        */
+
+                       PresentationInfo::Flag flags;
+
+                       if (version < 3000) {
+                               string f (prop->value());
+                               boost::replace_all (f, "ControlOut", "MonitorOut");
+                               flags = PresentationInfo::Flag (string_2_enum (f, flags));
+                       } else {
+                               flags = PresentationInfo::Flag (string_2_enum (prop->value(), flags));
+                       }
+
+                       _presentation_info.set_flags (flags);
+
+               }
+       }
+
+       return 0;
+}
+
+void
+Stripable::add_state (XMLNode& node) const
+{
+       XMLNode* remote_control_node = new XMLNode (X_("PresentationInfo"));
+       remote_control_node->add_property (X_("value"), _presentation_info.to_string());
+       node.add_child_nocopy (*remote_control_node);
+}
index 80169bf5a173661133510af7511cdf31fd3fb573..17a7c13295de391afc3bb8186d6b3c5e00fdde28 100644 (file)
@@ -40,7 +40,7 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
 using namespace ARDOUR;
 using namespace PBD;
 
-Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
+Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode mode, DataType default_type)
        : Route (sess, name, flag, default_type)
         , _saved_meter_point (_meter_point)
         , _mode (mode)
        : Route (sess, name, flag, default_type)
         , _saved_meter_point (_meter_point)
         , _mode (mode)
@@ -75,7 +75,6 @@ Track::init ()
        _monitoring_control.reset (new MonitorControl (_session, X_("monitoring"), *this));
        add_control (_monitoring_control);
 
        _monitoring_control.reset (new MonitorControl (_session, X_("monitoring"), *this));
        add_control (_monitoring_control);
 
-       track_number_changed.connect_same_thread (*this, boost::bind (&Track::resync_track_name, this));
        _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
 
         _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
        _session.config.ParameterChanged.connect_same_thread (*this, boost::bind (&Track::parameter_changed, this, _1));
 
         _monitoring_control->Changed.connect_same_thread (*this, boost::bind (&Track::monitoring_changed, this, _1, _2));
index 3310c924cb4b14e181c5ddf49320861c6d4975cd..d3c614debf27849da3a572ddfd7fb3a8669118ee 100644 (file)
@@ -65,7 +65,7 @@ VCA::get_next_vca_number ()
 }
 
 VCA::VCA (Session& s,  uint32_t num, const string& name)
 }
 
 VCA::VCA (Session& s,  uint32_t num, const string& name)
-       : Stripable (s, name)
+       : Stripable (s, name, PresentationInfo (num, PresentationInfo::VCA))
        , Muteable (s, name)
        , Automatable (s)
        , _number (num)
        , Muteable (s, name)
        , Automatable (s)
        , _number (num)
@@ -106,6 +106,8 @@ VCA::get_state ()
        node->add_property (X_("name"), _name);
        node->add_property (X_("number"), _number);
 
        node->add_property (X_("name"), _name);
        node->add_property (X_("number"), _number);
 
+       Stripable::add_state (*node);
+
        node->add_child_nocopy (_gain_control->get_state());
        node->add_child_nocopy (_solo_control->get_state());
        node->add_child_nocopy (_mute_control->get_state());
        node->add_child_nocopy (_gain_control->get_state());
        node->add_child_nocopy (_solo_control->get_state());
        node->add_child_nocopy (_mute_control->get_state());
@@ -121,6 +123,8 @@ VCA::set_state (XMLNode const& node, int version)
 {
        XMLProperty const* prop;
 
 {
        XMLProperty const* prop;
 
+       Stripable::set_state (node, version);
+
        if ((prop = node.property ("name")) != 0) {
                set_name (prop->value());
        }
        if ((prop = node.property ("name")) != 0) {
                set_name (prop->value());
        }
index 9a9b650a66af585b43150f19ef8ef94acb61a732..1be40f7f6391a2503d7ef95e14eb4bc225102cc4 100644 (file)
@@ -169,6 +169,7 @@ libardour_sources = [
         'port_insert.cc',
         'port_manager.cc',
         'port_set.cc',
         'port_insert.cc',
         'port_manager.cc',
         'port_set.cc',
+        'presentation_info.cc',
         'process_thread.cc',
         'processor.cc',
         'progress.cc',
         'process_thread.cc',
         'processor.cc',
         'progress.cc',
@@ -225,6 +226,7 @@ libardour_sources = [
         'source_factory.cc',
         'speakers.cc',
         'srcfilesource.cc',
         'source_factory.cc',
         'speakers.cc',
         'srcfilesource.cc',
+        'stripable.cc',
         'strip_silence.cc',
         'system_exec.cc',
         'revision.cc',
         'strip_silence.cc',
         'system_exec.cc',
         'revision.cc',
index f413ad82d60ab2068e00d617391121ba3589f06b..2562edebcbedac9847b97883a5c8f279fa8b061a 100644 (file)
@@ -46,10 +46,10 @@ PBD::Signal0<void> ControlProtocol::VerticalZoomOutAll;
 PBD::Signal0<void> ControlProtocol::VerticalZoomInSelected;
 PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
 PBD::Signal1<void,RouteNotificationListPtr> ControlProtocol::TrackSelectionChanged;
 PBD::Signal0<void> ControlProtocol::VerticalZoomInSelected;
 PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
 PBD::Signal1<void,RouteNotificationListPtr> ControlProtocol::TrackSelectionChanged;
-PBD::Signal1<void,uint32_t> ControlProtocol::AddRouteToSelection;
-PBD::Signal1<void,uint32_t> ControlProtocol::SetRouteSelection;
-PBD::Signal1<void,uint32_t> ControlProtocol::ToggleRouteSelection;
-PBD::Signal1<void,uint32_t> ControlProtocol::RemoveRouteFromSelection;
+PBD::Signal1<void,uint64_t> ControlProtocol::AddRouteToSelection;
+PBD::Signal1<void,uint64_t> ControlProtocol::SetRouteSelection;
+PBD::Signal1<void,uint64_t> ControlProtocol::ToggleRouteSelection;
+PBD::Signal1<void,uint64_t> ControlProtocol::RemoveRouteFromSelection;
 PBD::Signal0<void>          ControlProtocol::ClearRouteSelection;
 PBD::Signal0<void>          ControlProtocol::StepTracksDown;
 PBD::Signal0<void>          ControlProtocol::StepTracksUp;
 PBD::Signal0<void>          ControlProtocol::ClearRouteSelection;
 PBD::Signal0<void>          ControlProtocol::StepTracksDown;
 PBD::Signal0<void>          ControlProtocol::StepTracksUp;
@@ -77,82 +77,18 @@ ControlProtocol::set_active (bool yn)
 void
 ControlProtocol::next_track (uint32_t initial_id)
 {
 void
 ControlProtocol::next_track (uint32_t initial_id)
 {
-       uint32_t limit = session->nroutes();
-       boost::shared_ptr<Route> cr = route_table[0];
-       uint32_t id;
-
-       if (cr) {
-               id = cr->remote_control_id ();
-       } else {
-               id = 0;
-       }
-
-       if (id == limit) {
-               id = 0;
-       } else {
-               id++;
-       }
-
-       while (id <= limit) {
-               if ((cr = session->route_by_remote_id (id)) != 0) {
-                       break;
-               }
-               id++;
-       }
-
-       if (id >= limit) {
-               id = 0;
-               while (id != initial_id) {
-                       if ((cr = session->route_by_remote_id (id)) != 0) {
-                               break;
-                       }
-                       id++;
-               }
-       }
-
-       route_table[0] = cr;
+       // STRIPABLE route_table[0] = _session->get_nth_stripable (++initial_id, RemoteControlID::Route);
 }
 
 void
 ControlProtocol::prev_track (uint32_t initial_id)
 {
 }
 
 void
 ControlProtocol::prev_track (uint32_t initial_id)
 {
-       uint32_t limit = session->nroutes();
-       boost::shared_ptr<Route> cr = route_table[0];
-       int32_t id;
-
-       if (cr) {
-               id = cr->remote_control_id ();
-       } else {
-               id = 0;
-       }
-
-       if (id == 0) {
-               id = limit;
-       } else {
-               id--;
-       }
-
-       while (id >= 0) {
-               if ((cr = session->route_by_remote_id (id)) != 0) {
-                       break;
-               }
-               id--;
-       }
-
-       if (id < 0) {
-               uint32_t i = limit;
-               while (i > initial_id) {
-                       if ((cr = session->route_by_remote_id (i)) != 0) {
-                               break;
-                       }
-                       i--;
-               }
+       if (!initial_id) {
+               return;
        }
        }
-
-       route_table[0] = cr;
+       // STRIPABLE route_table[0] = _session->get_nth_stripable (--initial_id, RemoteControlID::Route);
 }
 
 }
 
-
 void
 ControlProtocol::set_route_table_size (uint32_t size)
 {
 void
 ControlProtocol::set_route_table_size (uint32_t size)
 {
@@ -176,6 +112,7 @@ ControlProtocol::set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR
 bool
 ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id)
 {
 bool
 ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id)
 {
+#if 0 // STRIPABLE
        boost::shared_ptr<Route> r = session->route_by_remote_id (remote_control_id);
 
        if (!r) {
        boost::shared_ptr<Route> r = session->route_by_remote_id (remote_control_id);
 
        if (!r) {
@@ -183,7 +120,7 @@ ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_
        }
 
        set_route_table (table_index, r);
        }
 
        set_route_table (table_index, r);
-
+#endif
        return true;
 }
 
        return true;
 }
 
index 71e875419ad777b3d798c2519a003a16f18b8206..d0294511f69df4c5b1c0b020d54bbcef336a807c 100644 (file)
@@ -78,10 +78,10 @@ class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::Scope
        static PBD::Signal0<void> StepTracksDown;
        static PBD::Signal0<void> StepTracksUp;
 
        static PBD::Signal0<void> StepTracksDown;
        static PBD::Signal0<void> StepTracksUp;
 
-       static PBD::Signal1<void,uint32_t> AddRouteToSelection;
-       static PBD::Signal1<void,uint32_t> SetRouteSelection;
-       static PBD::Signal1<void,uint32_t> ToggleRouteSelection;
-       static PBD::Signal1<void,uint32_t> RemoveRouteFromSelection;
+       static PBD::Signal1<void,uint64_t> AddRouteToSelection;
+       static PBD::Signal1<void,uint64_t> SetRouteSelection;
+       static PBD::Signal1<void,uint64_t> ToggleRouteSelection;
+       static PBD::Signal1<void,uint64_t> RemoveRouteFromSelection;
        static PBD::Signal0<void>          ClearRouteSelection;
 
        /* signals that one UI (e.g. the GUI) can emit to get all other UI's to
        static PBD::Signal0<void>          ClearRouteSelection;
 
        /* signals that one UI (e.g. the GUI) can emit to get all other UI's to
index ec6e82222f0916dba9ebd8d440bb656444ac6cde..6277adc84e0ede668162645e1880650b81db8938 100644 (file)
@@ -95,7 +95,7 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
 
        /* this one is cross-thread */
 
 
        /* this one is cross-thread */
 
-       Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
+       Stripable::PresentationInfoChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
 
        /* Catch port connections and disconnections (cross-thread) */
        ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR,
 
        /* Catch port connections and disconnections (cross-thread) */
        ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR,
index df464643343cdfc8c1878821a3e79014cc7a19f4..eaff43121f40f75e07ba19fcc9ddc294066cec37 100644 (file)
@@ -242,21 +242,21 @@ MackieControlProtocol::route_is_locked_to_strip (boost::shared_ptr<Route> r) con
 }
 
 // predicate for sort call in get_sorted_routes
 }
 
 // predicate for sort call in get_sorted_routes
-struct RouteByRemoteId
+struct RouteByPresentationOrder
 {
        bool operator () (const boost::shared_ptr<Route> & a, const boost::shared_ptr<Route> & b) const
        {
 {
        bool operator () (const boost::shared_ptr<Route> & a, const boost::shared_ptr<Route> & b) const
        {
-               return a->remote_control_id() < b->remote_control_id();
+               return a->presentation_info() < b->presentation_info();
        }
 
        bool operator () (const Route & a, const Route & b) const
        {
        }
 
        bool operator () (const Route & a, const Route & b) const
        {
-               return a.remote_control_id() < b.remote_control_id();
+               return a.presentation_info() < b.presentation_info();
        }
 
        bool operator () (const Route * a, const Route * b) const
        {
        }
 
        bool operator () (const Route * a, const Route * b) const
        {
-               return a->remote_control_id() < b->remote_control_id();
+               return a->presentation_info() < b->presentation_info();
        }
 };
 
        }
 };
 
@@ -267,30 +267,22 @@ MackieControlProtocol::get_sorted_routes()
 
        // fetch all routes
        boost::shared_ptr<RouteList> routes = session->get_routes();
 
        // fetch all routes
        boost::shared_ptr<RouteList> routes = session->get_routes();
-       set<uint32_t> remote_ids;
+       set<PresentationInfo> remote_ids;
 
 
-       // routes with remote_id 0 should never be added
-       // TODO verify this with ardour devs
-       // remote_ids.insert (0);
-
-       // sort in remote_id order, and exclude master, control and hidden routes
+       // sort in presentation order, and exclude master, control and hidden routes
        // and any routes that are already set.
 
        for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it) {
 
                boost::shared_ptr<Route> route = *it;
 
        // and any routes that are already set.
 
        for (RouteList::iterator it = routes->begin(); it != routes->end(); ++it) {
 
                boost::shared_ptr<Route> route = *it;
 
-               if (remote_ids.find (route->remote_control_id()) != remote_ids.end()) {
-                       continue;
-               }
-
                if (route->is_auditioner() || route->is_master() || route->is_monitor()) {
                        continue;
                }
 
                /* don't include locked routes */
 
                if (route->is_auditioner() || route->is_master() || route->is_monitor()) {
                        continue;
                }
 
                /* don't include locked routes */
 
-               if (route_is_locked_to_strip(route)) {
+               if (route_is_locked_to_strip (route)) {
                        continue;
                }
 
                        continue;
                }
 
@@ -298,13 +290,13 @@ MackieControlProtocol::get_sorted_routes()
                case Mixer:
                        if (! is_hidden(route)) {
                                sorted.push_back (route);
                case Mixer:
                        if (! is_hidden(route)) {
                                sorted.push_back (route);
-                               remote_ids.insert (route->remote_control_id());
+                               remote_ids.insert (route->presentation_info());
                        }
                        break;
                case AudioTracks:
                        if (is_audio_track(route) && !is_hidden(route)) {
                                sorted.push_back (route);
                        }
                        break;
                case AudioTracks:
                        if (is_audio_track(route) && !is_hidden(route)) {
                                sorted.push_back (route);
-                               remote_ids.insert (route->remote_control_id());
+                               remote_ids.insert (route->presentation_info());
                        }
                        break;
                case Busses:
                        }
                        break;
                case Busses:
@@ -312,20 +304,20 @@ MackieControlProtocol::get_sorted_routes()
 #ifdef MIXBUS
                                if (route->mixbus()) {
                                        sorted.push_back (route);
 #ifdef MIXBUS
                                if (route->mixbus()) {
                                        sorted.push_back (route);
-                                       remote_ids.insert (route->remote_control_id());
+                                       remote_ids.insert (route->presentation_info());
                                }
 #endif
                        } else {
                                if (!is_track(route) && !is_hidden(route)) {
                                        sorted.push_back (route);
                                }
 #endif
                        } else {
                                if (!is_track(route) && !is_hidden(route)) {
                                        sorted.push_back (route);
-                                       remote_ids.insert (route->remote_control_id());
+                                       remote_ids.insert (route->presentation_info());
                                }
                        }
                        break;
                case MidiTracks:
                        if (is_midi_track(route) && !is_hidden(route)) {
                                sorted.push_back (route);
                                }
                        }
                        break;
                case MidiTracks:
                        if (is_midi_track(route) && !is_hidden(route)) {
                                sorted.push_back (route);
-                               remote_ids.insert (route->remote_control_id());
+                               remote_ids.insert (route->presentation_info());
                        }
                        break;
                case Plugins:
                        }
                        break;
                case Plugins:
@@ -338,27 +330,27 @@ MackieControlProtocol::get_sorted_routes()
 #endif
                        {
                                sorted.push_back (route);
 #endif
                        {
                                sorted.push_back (route);
-                               remote_ids.insert (route->remote_control_id());
+                               remote_ids.insert (route->presentation_info());
                        }
                        break;
                case Hidden: // Show all the tracks we have hidden
                        if (is_hidden(route)) {
                                // maybe separate groups
                                sorted.push_back (route);
                        }
                        break;
                case Hidden: // Show all the tracks we have hidden
                        if (is_hidden(route)) {
                                // maybe separate groups
                                sorted.push_back (route);
-                               remote_ids.insert (route->remote_control_id());
+                               remote_ids.insert (route->presentation_info());
                        }
                        break;
                case Selected: // For example: a group (this is USER)
                        if (selected(route) && !is_hidden(route)) {
                                sorted.push_back (route);
                        }
                        break;
                case Selected: // For example: a group (this is USER)
                        if (selected(route) && !is_hidden(route)) {
                                sorted.push_back (route);
-                               remote_ids.insert (route->remote_control_id());
+                               remote_ids.insert (route->presentation_info());
                        }
                        break;
                }
 
        }
 
                        }
                        break;
                }
 
        }
 
-       sort (sorted.begin(), sorted.end(), RouteByRemoteId());
+       sort (sorted.begin(), sorted.end(), RouteByPresentationOrder());
        return sorted;
 }
 
        return sorted;
 }
 
@@ -716,7 +708,6 @@ MackieControlProtocol::connect_session_signals()
 {
        // receive routes added
        session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_route_added, this, _1), this);
 {
        // receive routes added
        session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_route_added, this, _1), this);
-       session->RouteAddedOrRemoved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_route_added_or_removed, this), this);
        // receive record state toggled
        session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_record_state_changed, this), this);
        // receive transport state changed
        // receive record state toggled
        session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_record_state_changed, this), this);
        // receive transport state changed
@@ -733,7 +724,7 @@ MackieControlProtocol::connect_session_signals()
        Sorted sorted = get_sorted_routes();
 
        for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
        Sorted sorted = get_sorted_routes();
 
        for (Sorted::iterator it = sorted.begin(); it != sorted.end(); ++it) {
-               (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_remote_id_changed, this), this);
+               (*it)->PresentationInfoChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this);
        }
 }
 
        }
 }
 
@@ -1251,7 +1242,7 @@ void MackieControlProtocol::notify_parameter_changed (std::string const & p)
 }
 
 void
 }
 
 void
-MackieControlProtocol::notify_route_added_or_removed ()
+MackieControlProtocol::notify_route_removed ()
 {
        Glib::Threads::Mutex::Lock lm (surfaces_lock);
        for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
 {
        Glib::Threads::Mutex::Lock lm (surfaces_lock);
        for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
@@ -1291,7 +1282,7 @@ MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
        typedef ARDOUR::RouteList ARS;
 
        for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
        typedef ARDOUR::RouteList ARS;
 
        for (ARS::iterator it = rl.begin(); it != rl.end(); ++it) {
-               (*it)->RemoteControlIDChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_remote_id_changed, this), this);
+               (*it)->PresentationInfoChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::notify_presentation_info_changed, this), this);
        }
 }
 
        }
 }
 
@@ -1320,7 +1311,7 @@ MackieControlProtocol::notify_solo_active_changed (bool active)
 }
 
 void
 }
 
 void
-MackieControlProtocol::notify_remote_id_changed()
+MackieControlProtocol::notify_presentation_info_changed()
 {
        {
                Glib::Threads::Mutex::Lock lm (surfaces_lock);
 {
        {
                Glib::Threads::Mutex::Lock lm (surfaces_lock);
@@ -2120,12 +2111,15 @@ MackieControlProtocol::select_range ()
                for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
 
                        if (main_modifier_state() == MODIFIER_SHIFT) {
                for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
 
                        if (main_modifier_state() == MODIFIER_SHIFT) {
-                               ToggleRouteSelection ((*r)->remote_control_id ());
+                               /* XXX can only use numeric part of ID at present */
+                               ToggleRouteSelection ((*r)->presentation_info ().global_order());
                        } else {
                                if (r == routes.begin()) {
                        } else {
                                if (r == routes.begin()) {
-                                       SetRouteSelection ((*r)->remote_control_id());
+                                       /* XXX can only use numeric part of ID at present */
+                                       SetRouteSelection ((*r)->presentation_info().global_order());
                                } else {
                                } else {
-                                       AddRouteToSelection ((*r)->remote_control_id());
+                                       /* XXX can only use numeric part of ID at present */
+                                       AddRouteToSelection ((*r)->presentation_info().global_order());
                                }
                        }
                }
                                }
                        }
                }
@@ -2441,7 +2435,7 @@ MackieControlProtocol::is_hidden (boost::shared_ptr<Route> r) const
        if (!r) {
                return false;
        }
        if (!r) {
                return false;
        }
-       return (((r->remote_control_id()) >>31) != 0);
+       return (r->presentation_info().flags() & PresentationInfo::Hidden);
 }
 
 bool
 }
 
 bool
index 667f0c36cfb0b98af1c9507ef813a6314abe571a..37d0b69bb39f9ee7c1b171ec49b2f21169899374 100644 (file)
@@ -206,9 +206,9 @@ class MackieControlProtocol
        void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);
 
        void notify_subview_route_deleted ();
        void handle_button_event (Mackie::Surface&, Mackie::Button& button, Mackie::ButtonState);
 
        void notify_subview_route_deleted ();
-       void notify_route_added_or_removed ();
+       void notify_route_removed ();
        void notify_route_added (ARDOUR::RouteList &);
        void notify_route_added (ARDOUR::RouteList &);
-       void notify_remote_id_changed();
+       void notify_presentation_info_changed();
 
        void recalibrate_faders ();
        void toggle_backlight ();
 
        void recalibrate_faders ();
        void toggle_backlight ();
index 9c3fc21bdacaa16089f26a4f5e12e100ff78b4b1..95371bc212f4741d4e4a1c1533a798acfca7f9cb 100644 (file)
@@ -321,6 +321,7 @@ Strip::notify_active_changed ()
 void
 Strip::notify_route_deleted ()
 {
 void
 Strip::notify_route_deleted ()
 {
+       _surface->mcp().notify_route_removed ();
        _surface->mcp().refresh_current_bank();
 }
 
        _surface->mcp().refresh_current_bank();
 }
 
index d758e29f03d93c6fcfef9816aa9cf2d05a0e551d..1d87cdebc557dcef1539866b584ee258539bb33a 100644 (file)
@@ -658,7 +658,7 @@ OSC::send_current_value (const char* path, lo_arg** argv, int argc, lo_message m
                lo_message_add_string (reply, "bad syntax");
        } else {
                id = argv[0]->i;
                lo_message_add_string (reply, "bad syntax");
        } else {
                id = argv[0]->i;
-               r = session->route_by_remote_id (id);
+               r = session->get_remote_nth_route (id);
 
                if (!r) {
                        lo_message_add_string (reply, "not found");
 
                if (!r) {
                        lo_message_add_string (reply, "not found");
@@ -729,7 +729,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
                } else {
                        for (int n = 0; n < argc; ++n) {
 
                } else {
                        for (int n = 0; n < argc; ++n) {
 
-                               boost::shared_ptr<Route> r = session->route_by_remote_id (argv[n]->i);
+                               boost::shared_ptr<Route> r = session->get_remote_nth_route (argv[n]->i);
 
                                if (!r) {
                                        lo_message_add_string (reply, "not found");
 
                                if (!r) {
                                        lo_message_add_string (reply, "not found");
@@ -752,7 +752,7 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_
 
                for (int n = 0; n < argc; ++n) {
 
 
                for (int n = 0; n < argc; ++n) {
 
-                       boost::shared_ptr<Route> r = session->route_by_remote_id (argv[n]->i);
+                       boost::shared_ptr<Route> r = session->get_remote_nth_route (argv[n]->i);
 
                        if (r) {
                                end_listen (r, lo_message_get_source (msg));
 
                        if (r) {
                                end_listen (r, lo_message_get_source (msg));
@@ -949,7 +949,7 @@ OSC::routes_list (lo_message msg)
        }
        for (int n = 0; n < (int) session->nroutes(); ++n) {
 
        }
        for (int n = 0; n < (int) session->nroutes(); ++n) {
 
-               boost::shared_ptr<Route> r = session->route_by_remote_id (n);
+               boost::shared_ptr<Route> r = session->get_remote_nth_route (n);
 
                if (r) {
 
 
                if (r) {
 
@@ -968,7 +968,8 @@ OSC::routes_list (lo_message msg)
                        lo_message_add_int32 (reply, r->n_outputs().n_audio());
                        lo_message_add_int32 (reply, r->muted());
                        lo_message_add_int32 (reply, r->soloed());
                        lo_message_add_int32 (reply, r->n_outputs().n_audio());
                        lo_message_add_int32 (reply, r->muted());
                        lo_message_add_int32 (reply, r->soloed());
-                       lo_message_add_int32 (reply, r->remote_control_id());
+                       /* XXX Can only use group ID at this point */
+                       lo_message_add_int32 (reply, r->presentation_info().group_order());
 
                        if (boost::dynamic_pointer_cast<AudioTrack>(r)
                                        || boost::dynamic_pointer_cast<MidiTrack>(r)) {
 
                        if (boost::dynamic_pointer_cast<AudioTrack>(r)
                                        || boost::dynamic_pointer_cast<MidiTrack>(r)) {
@@ -1051,7 +1052,7 @@ OSC::route_mute (int rid, int yn)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                r->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
 
        if (r) {
                r->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
@@ -1065,7 +1066,7 @@ OSC::route_solo (int rid, int yn)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                r->solo_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
 
        if (r) {
                r->solo_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
@@ -1079,7 +1080,7 @@ OSC::route_recenable (int rid, int yn)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (r);
 
        if (r) {
                boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (r);
@@ -1096,7 +1097,7 @@ OSC::route_set_gain_abs (int rid, float level)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                r->gain_control()->set_value (level, PBD::Controllable::NoGroup);
 
        if (r) {
                r->gain_control()->set_value (level, PBD::Controllable::NoGroup);
@@ -1126,7 +1127,7 @@ OSC::route_set_trim_abs (int rid, float level)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                r->set_trim (level, PBD::Controllable::NoGroup);
 
        if (r) {
                r->set_trim (level, PBD::Controllable::NoGroup);
@@ -1147,7 +1148,7 @@ OSC::route_set_pan_stereo_position (int rid, float pos)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                boost::shared_ptr<Panner> panner = r->panner();
 
        if (r) {
                boost::shared_ptr<Panner> panner = r->panner();
@@ -1165,7 +1166,7 @@ OSC::route_set_pan_stereo_width (int rid, float pos)
 {
        if (!session) return -1;
 
 {
        if (!session) return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (r) {
                boost::shared_ptr<Panner> panner = r->panner();
 
        if (r) {
                boost::shared_ptr<Panner> panner = r->panner();
@@ -1185,7 +1186,7 @@ OSC::route_set_send_gain_abs (int rid, int sid, float val)
                return -1;
        }
 
                return -1;
        }
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (!r) {
                return -1;
 
        if (!r) {
                return -1;
@@ -1217,7 +1218,7 @@ OSC::route_set_send_gain_dB (int rid, int sid, float val)
                return -1;
        }
 
                return -1;
        }
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (!r) {
                return -1;
 
        if (!r) {
                return -1;
@@ -1248,7 +1249,7 @@ OSC::route_plugin_parameter (int rid, int piid, int par, float val)
        if (!session)
                return -1;
 
        if (!session)
                return -1;
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (!r) {
                PBD::error << "OSC: Invalid Remote Control ID '" << rid << "'" << endmsg;
 
        if (!r) {
                PBD::error << "OSC: Invalid Remote Control ID '" << rid << "'" << endmsg;
@@ -1307,7 +1308,7 @@ OSC::route_plugin_parameter_print (int rid, int piid, int par)
                return -1;
        }
 
                return -1;
        }
 
-       boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
+       boost::shared_ptr<Route> r = session->get_remote_nth_route (rid);
 
        if (!r) {
                return -1;
 
        if (!r) {
                return -1;
index 2cd4c310808c115df9d7cbd98d5851109cee0ec2..dae6ee6d6d2d894db1524d58b47061a6536fa5b8 100644 (file)
@@ -90,7 +90,9 @@ OSCRouteControllable::send_change_message ()
 {
        lo_message msg = lo_message_new ();
 
 {
        lo_message msg = lo_message_new ();
 
-       lo_message_add_int32 (msg, _route->remote_control_id());
+       /* Can only send ID part of RID at present */
+
+       lo_message_add_int32 (msg, _route->presentation_info().group_order());
        lo_message_add_float (msg, (float) controllable->get_value());
 
        /* XXX thread issues */
        lo_message_add_float (msg, (float) controllable->get_value());
 
        /* XXX thread issues */
index 8bb511b94fe56eabd27e758ac165e7bd357b7022..a9e797621c0b0ac2e1b03d2ad9aabcfbaedfc048 100644 (file)
@@ -82,7 +82,8 @@ OSCRouteObserver::name_changed (const PBD::PropertyChange& what_changed)
 
        lo_message msg = lo_message_new ();
 
 
        lo_message msg = lo_message_new ();
 
-       lo_message_add_int32 (msg, _route->remote_control_id());
+       /* XXX can only use group part of ID at present */
+       lo_message_add_int32 (msg, _route->presentation_info().group_order());
        lo_message_add_string (msg, _route->name().c_str());
 
        lo_send_message (addr, "/route/name", msg);
        lo_message_add_string (msg, _route->name().c_str());
 
        lo_send_message (addr, "/route/name", msg);
@@ -94,7 +95,8 @@ OSCRouteObserver::send_change_message (string path, boost::shared_ptr<Controllab
 {
        lo_message msg = lo_message_new ();
 
 {
        lo_message msg = lo_message_new ();
 
-       lo_message_add_int32 (msg, _route->remote_control_id());
+       /* XXX can only use group part of ID at present */
+       lo_message_add_int32 (msg, _route->presentation_info().group_order());
        lo_message_add_float (msg, (float) controllable->get_value());
 
        /* XXX thread issues */
        lo_message_add_float (msg, (float) controllable->get_value());
 
        /* XXX thread issues */