Only show user-presets in favorite sidebar
[ardour.git] / libs / ardour / stripable.cc
1 /*
2     Copyright (C) 2016 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <boost/algorithm/string.hpp>
21
22 #include "pbd/compose.h"
23 #include "pbd/convert.h"
24 #include "pbd/i18n.h"
25
26
27 #include "ardour/debug.h"
28 #include "ardour/rc_configuration.h"
29 #include "ardour/session.h"
30 #include "ardour/selection.h"
31 #include "ardour/stripable.h"
32
33 using namespace ARDOUR;
34 using namespace PBD;
35 using std::string;
36
37 Stripable::Stripable (Session& s, string const & name, PresentationInfo const & pi)
38         : SessionObject (s, name)
39         , Automatable (s)
40         , _presentation_info (pi)
41         , _active_color_picker (0)
42 {
43 }
44
45 Stripable::~Stripable ()
46 {
47         if (!_session.deletion_in_progress ()) {
48                 _session.selection().remove_stripable_by_id (id());
49         }
50 }
51
52 void
53 Stripable::set_presentation_order (PresentationInfo::order_t order)
54 {
55         _presentation_info.set_order (order);
56 }
57
58 int
59 Stripable::set_state (XMLNode const& node, int version)
60 {
61         const XMLProperty *prop;
62         XMLNodeList const & nlist (node.children());
63         XMLNodeConstIterator niter;
64         XMLNode *child;
65
66         if (version > 3001) {
67
68                 for (niter = nlist.begin(); niter != nlist.end(); ++niter){
69                         child = *niter;
70
71                         if (child->name() == PresentationInfo::state_node_name) {
72                                 _presentation_info.set_state (*child, version);
73                         }
74                 }
75
76         } else {
77
78                 /* Older versions of Ardour stored "_flags" as a property of the Route
79                  * node, only for 3 special Routes (MasterOut, MonitorOut, Auditioner.
80                  *
81                  * Their presentation order was stored in a node called "RemoteControl"
82                  *
83                  * This information is now part of the PresentationInfo of every Stripable.
84                  */
85
86                 if ((prop = node.property (X_("flags"))) != 0) {
87
88                         /* 4.x and earlier - didn't have Stripable but the
89                          * relevant enums have the same names (MasterOut,
90                          * MonitorOut, Auditioner), so we can use string_2_enum
91                          */
92
93                         PresentationInfo::Flag flags;
94
95                         if (version < 3000) {
96                                 string f (prop->value());
97                                 boost::replace_all (f, "ControlOut", "MonitorOut");
98                                 flags = PresentationInfo::Flag (string_2_enum (f, flags));
99                         } else {
100                                 flags = PresentationInfo::Flag (string_2_enum (prop->value(), flags));
101                         }
102
103                         _presentation_info.set_flags (flags);
104
105                 }
106
107                 if (!_presentation_info.special(false)) {
108                         if ((prop = node.property (X_("order-key"))) != 0) {
109                                 _presentation_info.set_order (atol (prop->value()));
110                         }
111                 }
112         }
113
114         return 0;
115 }
116
117 bool
118 Stripable::is_selected() const
119 {
120         try {
121                 boost::shared_ptr<const Stripable> s (shared_from_this());
122         } catch (...) {
123                 std::cerr << "cannot shared-from-this for " << this << std::endl;
124                 abort ();
125         }
126         return _session.selection().selected (shared_from_this());
127 }
128
129 bool
130 Stripable::Sorter::operator() (boost::shared_ptr<ARDOUR::Stripable> a, boost::shared_ptr<ARDOUR::Stripable> b)
131 {
132         if (a->presentation_info().flags () == b->presentation_info().flags ()) {
133                 return a->presentation_info().order() < b->presentation_info().order();
134         }
135
136         int cmp_a = 0;
137         int cmp_b = 0;
138
139         if (a->is_auditioner ()) { cmp_a = -2; }
140         if (b->is_auditioner ()) { cmp_b = -2; }
141         if (a->is_monitor ())    { cmp_a = -1; }
142         if (b->is_monitor ())    { cmp_b = -1; }
143
144         /* ARDOUR-Editor: [Track|Bus|Master] (0) < VCA (3)
145          * ARDOUR-Mixer : [Track|Bus] (0) < VCA (3) < Master (4)
146          *
147          * Mixbus-Editor: [Track|Bus] (0) < Mixbus (1) < VCA (3) < Master (4)
148          * Mixbus-Mixer : [Track|Bus] (0) < Mixbus (1) < Master (2) < VCA (3)
149          */
150
151         if (a->presentation_info().flags () & ARDOUR::PresentationInfo::VCA) {
152                 cmp_a = 3;
153         }
154 #ifdef MIXBUS
155         else if (a->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut) {
156                 cmp_a = _mixer_order ? 2 : 4;
157         }
158         else if ((a->presentation_info().flags () & ARDOUR::PresentationInfo::Mixbus) || a->mixbus()) {
159                 cmp_a = 1;
160         }
161 #endif
162         else if (_mixer_order && (a->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut)) {
163                 cmp_a = 4;
164         }
165
166
167         if (b->presentation_info().flags () & ARDOUR::PresentationInfo::VCA) {
168                 cmp_b = 3;
169         }
170 #ifdef MIXBUS
171         else if (b->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut) {
172                 cmp_b = _mixer_order ? 2 : 4;
173         }
174         else if ((b->presentation_info().flags () & ARDOUR::PresentationInfo::Mixbus) || b->mixbus()) {
175                 cmp_b = 1;
176         }
177 #endif
178         else if (_mixer_order && (b->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut)) {
179                 cmp_b = 4;
180         }
181
182         if (cmp_a == cmp_b) {
183                 return a->presentation_info().order() < b->presentation_info().order();
184         }
185         return cmp_a < cmp_b;
186 }