remove Track::hidden(); replace with Stripable::is_private_route()
[ardour.git] / libs / ardour / presentation_info.cc
index 654a80f6cede68415eeaab03d9aae2e91c5ffc98..23d82f6409ed6c5731284baf3be8ef76bbd055ca 100644 (file)
 
 #include <cassert>
 
-#include "pbd/convert.h"
 #include "pbd/debug.h"
+#include "pbd/enum_convert.h"
 #include "pbd/enumwriter.h"
 #include "pbd/error.h"
 #include "pbd/failed_constructor.h"
+#include "pbd/stacktrace.h"
 #include "pbd/xml++.h"
 
 #include "ardour/presentation_info.h"
+#include "ardour/selection.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
+
+namespace PBD {
+       DEFINE_ENUM_CONVERT(ARDOUR::PresentationInfo::Flag);
+}
 
 using namespace ARDOUR;
 using namespace PBD;
 using std::string;
 
 string PresentationInfo::state_node_name = X_("PresentationInfo");
-PBD::Signal0<void> PresentationInfo::Change;
+
+PBD::Signal1<void,PropertyChange const &> PresentationInfo::Change;
+Glib::Threads::Mutex PresentationInfo::static_signal_lock;
+int PresentationInfo::_change_signal_suspended = 0;
+PBD::PropertyChange PresentationInfo::_pending_static_changes;
+int PresentationInfo::selection_counter= 0;
 
 namespace ARDOUR {
        namespace Properties {
@@ -47,6 +58,59 @@ namespace ARDOUR {
        }
 }
 
+void
+PresentationInfo::suspend_change_signal ()
+{
+       g_atomic_int_add (&_change_signal_suspended, 1);
+}
+
+void
+PresentationInfo::unsuspend_change_signal ()
+{
+       Glib::Threads::Mutex::Lock lm (static_signal_lock);
+
+       if (g_atomic_int_get (const_cast<gint*> (&_change_signal_suspended)) == 1) {
+
+               /* atomically grab currently pending flags */
+
+               PropertyChange pc = _pending_static_changes;
+               _pending_static_changes.clear ();
+
+               if (!pc.empty()) {
+
+                       /* emit the signal with further emissions still blocked
+                        * by _change_signal_suspended, but not by the lock.
+                        *
+                        * This means that if the handlers modify other PI
+                        * states, the signal for that won't be sent while they
+                        * are handling the current signal.
+                        */
+                       lm.release ();
+                       Change (pc); /* EMIT SIGNAL */
+                       lm.acquire ();
+               }
+       }
+
+       g_atomic_int_add (const_cast<gint*>(&_change_signal_suspended), -1);
+}
+
+void
+PresentationInfo::send_static_change (const PropertyChange& what_changed)
+{
+       if (what_changed.empty()) {
+               return;
+       }
+
+
+       if (g_atomic_int_get (&_change_signal_suspended)) {
+               Glib::Threads::Mutex::Lock lm (static_signal_lock);
+               _pending_static_changes.add (what_changed);
+               return;
+       }
+
+       Change (what_changed);
+}
+
 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);
@@ -81,7 +145,8 @@ PresentationInfo::PresentationInfo (order_t o, Flag f)
        /* OrderSet is set */
 }
 PresentationInfo::PresentationInfo (PresentationInfo const& other)
-       : _order (other.order())
+       : PBD::Stateful ()
+       , _order (other.order())
        , _flags (other.flags())
        , _color (other.color())
 {
@@ -91,9 +156,9 @@ XMLNode&
 PresentationInfo::get_state ()
 {
        XMLNode* node = new XMLNode (state_node_name);
-       node->add_property ("order", PBD::to_string (_order, std::dec));
-       node->add_property ("flags", enum_2_string (_flags));
-       node->add_property ("color", PBD::to_string (_color, std::dec));
+       node->set_property ("order", _order);
+       node->set_property ("flags", _flags);
+       node->set_property ("color", _color);
 
        return *node;
 }
@@ -105,30 +170,29 @@ PresentationInfo::set_state (XMLNode const& node, int /* version */)
                return -1;
        }
 
-       XMLProperty const* prop;
        PropertyChange pc;
 
-       if ((prop = node.property (X_("order"))) != 0) {
-               order_t o = atoi (prop->value());
+       order_t o;
+       if (node.get_property (X_("order"), o)) {
                if (o != _order) {
                        pc.add (Properties::order);
                        _order = o;
                }
-               _order = atoi (prop->value());
+               _order = o; // huh?
        }
 
-       if ((prop = node.property (X_("flags"))) != 0) {
-               Flag f = Flag (string_2_enum (prop->value(), f));
+       Flag f;
+       if (node.get_property (X_("flags"), f)) {
                if ((f&Hidden) != (_flags&Hidden)) {
                        pc.add (Properties::hidden);
                }
                _flags = f;
        }
 
-       if ((prop = node.property (X_("color"))) != 0) {
-               color_t c = atoi (prop->value());
+       color_t c;
+       if (node.get_property (X_("color"), c)) {
                if (c != _color) {
-                       pc.add (Properties::order);
+                       pc.add (Properties::color);
                        _color = c;
                }
        }
@@ -148,9 +212,8 @@ PresentationInfo::get_flags (XMLNode const& node)
                XMLNode* child = *niter;
 
                if (child->name() == PresentationInfo::state_node_name) {
-                       XMLProperty const* prop = child->property (X_("flags"));
-                       if (prop) {
-                               Flag f = (Flag) string_2_enum (prop->value(), f);
+                       Flag f;
+                       if (child->get_property (X_("flags"), f)) {
                                return f;
                        }
                }
@@ -164,6 +227,7 @@ PresentationInfo::set_color (PresentationInfo::color_t c)
        if (c != _color) {
                _color = c;
                send_change (PropertyChange (Properties::color));
+               send_static_change (PropertyChange (Properties::color));
        }
 }
 
@@ -175,23 +239,9 @@ PresentationInfo::color_set () const
         * this is heuristic, but it is fairly realistic. who will ever set
         * a color to completely transparent black? only the constructor ..
         */
-
        return _color != 0;
 }
 
-void
-PresentationInfo::set_selected (bool yn)
-{
-       if (yn != selected()) {
-               if (yn) {
-                       _flags = Flag (_flags | Selected);
-               } else {
-                       _flags = Flag (_flags & ~Selected);
-               }
-               send_change (PropertyChange (Properties::selected));
-       }
-}
-
 void
 PresentationInfo::set_hidden (bool yn)
 {
@@ -204,6 +254,7 @@ PresentationInfo::set_hidden (bool yn)
                }
 
                send_change (PropertyChange (Properties::hidden));
+               send_static_change (PropertyChange (Properties::hidden));
        }
 }
 
@@ -215,6 +266,7 @@ PresentationInfo::set_order (order_t order)
        if (order != _order) {
                _order = order;
                send_change (PropertyChange (Properties::order));
+               send_static_change (PropertyChange (Properties::order));
        }
 }