Fix a potential memory-corruption
[ardour.git] / libs / ardour / stripable.cc
index d322fd75deb3c42db785095d3d24a02a48bb8a1d..24167438c377b88ae2d04b26884ed8ed00c2ba74 100644 (file)
 
 #include "pbd/compose.h"
 #include "pbd/convert.h"
+#include "pbd/i18n.h"
+
 
 #include "ardour/debug.h"
 #include "ardour/rc_configuration.h"
+#include "ardour/session.h"
+#include "ardour/selection.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)
+       , Automatable (s)
        , _presentation_info (pi)
+       , _active_color_picker (0)
 {
 }
 
-void
-Stripable::set_presentation_group_order (PresentationInfo::order_t order, bool notify_class_listeners)
+Stripable::~Stripable ()
 {
-       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;
+       if (!_session.deletion_in_progress ()) {
+               _session.selection().remove_stripable_by_id (id());
        }
-
-       set_presentation_info_internal (pi, notify_class_listeners);
 }
 
 void
-Stripable::set_presentation_info_internal (PresentationInfo pi, bool notify_class_listeners)
+Stripable::set_presentation_order (PresentationInfo::order_t order)
 {
-       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);
+       _presentation_info.set_order (order);
 }
 
 int
@@ -99,24 +63,17 @@ Stripable::set_state (XMLNode const& node, int version)
        XMLNodeConstIterator niter;
        XMLNode *child;
 
-       if (version > 3000) {
-
-               std::cerr << "Looking for PI\n";
+       if (version > 3001) {
 
                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;
-                               }
+                       if (child->name() == PresentationInfo::state_node_name) {
+                               _presentation_info.set_state (*child, version);
                        }
                }
 
        } 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.
@@ -146,15 +103,84 @@ Stripable::set_state (XMLNode const& node, int version)
                        _presentation_info.set_flags (flags);
 
                }
+
+               if (!_presentation_info.special(false)) {
+                       if ((prop = node.property (X_("order-key"))) != 0) {
+                               _presentation_info.set_order (atol (prop->value()));
+                       }
+               }
        }
 
        return 0;
 }
 
-void
-Stripable::add_state (XMLNode& node) const
+bool
+Stripable::is_selected() 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);
+       try {
+               boost::shared_ptr<const Stripable> s (shared_from_this());
+       } catch (...) {
+               std::cerr << "cannot shared-from-this for " << this << std::endl;
+               abort ();
+       }
+       return _session.selection().selected (shared_from_this());
+}
+
+bool
+Stripable::Sorter::operator() (boost::shared_ptr<ARDOUR::Stripable> a, boost::shared_ptr<ARDOUR::Stripable> b)
+{
+       if (a->presentation_info().flags () == b->presentation_info().flags ()) {
+               return a->presentation_info().order() < b->presentation_info().order();
+       }
+
+       int cmp_a = 0;
+       int cmp_b = 0;
+
+       if (a->is_auditioner ()) { cmp_a = -2; }
+       if (b->is_auditioner ()) { cmp_b = -2; }
+       if (a->is_monitor ())    { cmp_a = -1; }
+       if (b->is_monitor ())    { cmp_b = -1; }
+
+       /* ARDOUR-Editor: [Track|Bus|Master] (0) < VCA (3)
+        * ARDOUR-Mixer : [Track|Bus] (0) < VCA (3) < Master (4)
+        *
+        * Mixbus-Editor: [Track|Bus] (0) < Mixbus (1) < VCA (3) < Master (4)
+        * Mixbus-Mixer : [Track|Bus] (0) < Mixbus (1) < Master (2) < VCA (3)
+        */
+
+       if (a->presentation_info().flags () & ARDOUR::PresentationInfo::VCA) {
+               cmp_a = 3;
+       }
+#ifdef MIXBUS
+       else if (a->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut) {
+               cmp_a = _mixer_order ? 2 : 4;
+       }
+       else if ((a->presentation_info().flags () & ARDOUR::PresentationInfo::Mixbus) || a->mixbus()) {
+               cmp_a = 1;
+       }
+#endif
+       else if (_mixer_order && (a->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut)) {
+               cmp_a = 4;
+       }
+
+
+       if (b->presentation_info().flags () & ARDOUR::PresentationInfo::VCA) {
+               cmp_b = 3;
+       }
+#ifdef MIXBUS
+       else if (b->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut) {
+               cmp_b = _mixer_order ? 2 : 4;
+       }
+       else if ((b->presentation_info().flags () & ARDOUR::PresentationInfo::Mixbus) || b->mixbus()) {
+               cmp_b = 1;
+       }
+#endif
+       else if (_mixer_order && (b->presentation_info().flags () & ARDOUR::PresentationInfo::MasterOut)) {
+               cmp_b = 4;
+       }
+
+       if (cmp_a == cmp_b) {
+               return a->presentation_info().order() < b->presentation_info().order();
+       }
+       return cmp_a < cmp_b;
 }