Early prototype for _LV2UI_Request_Parameter extension
[ardour.git] / gtk2_ardour / gui_object.cc
index fa708b25ad4ffb4319e81b44713450eb1f327de7..e9f93e0ebccaf21099f000990e15ee5770f89e44 100644 (file)
 */
 
 #include <iostream>
-#include <iomanip>
 #include <sstream>
 
-#include <boost/variant/static_visitor.hpp>
-
 #include "gui_object.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using std::string;
 
+/*static*/ XMLNode *
+GUIObjectState::get_node (const XMLNode* parent, const string& id)
+{
+       XMLNodeList const & children = parent->children ();
+       for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+               if ((*i)->name() != X_("Object")) {
+                       continue;
+               }
+               if ((*i)->has_property_with_value(X_("id"), id)) {
+                       return *i;
+               }
+       }
+       return 0;
+}
+
+/*static*/ XMLNode *
+GUIObjectState::get_or_add_node (XMLNode* parent, const string& id)
+{
+       XMLNode* child = get_node (parent, id);
+       if (!child) {
+               child = new XMLNode (X_("Object"));
+               child->set_property (X_("id"), id);
+               parent->add_child_nocopy (*child);
+       }
+       return child;
+}
+
+
 const string GUIObjectState::xml_node_name (X_("GUIObjectState"));
 
-GUIObjectState::~GUIObjectState ()
+GUIObjectState::GUIObjectState ()
+       : _state (X_("GUIObjectState"))
 {
-       clear_maps ();
+}
+
+XMLNode *
+GUIObjectState::get_or_add_node (const string& id)
+{
+       std::map <std::string, XMLNode*>::iterator i = object_map.find (id);
+       if (i != object_map.end()) {
+               return i->second;
+       }
+       //assert (get_node (&_state, id) == 0); // XXX performance penalty due to get_node()
+       XMLNode* child = new XMLNode (X_("Object"));
+       child->set_property (X_("id"), id);
+       _state.add_child_nocopy (*child);
+       object_map[id] = child;
+       return child;
 }
 
 void
-GUIObjectState::clear_maps ()
+GUIObjectState::remove_node (const std::string& id)
 {
-       _property_maps.clear ();
+       object_map.erase (id);
+       _state.remove_nodes_and_delete(X_("id"), id );
 }
 
-class gos_string_vistor : public boost::static_visitor<> {
-  public:
-    gos_string_vistor (std::ostream& o) 
-           : stream (o) {}
-           
-    void operator() (const int64_t& i) {
-           stream << i;
-    }
-
-    void operator() (const std::string& s) {
-           stream << s;
-    }
-
-  private:
-    std::ostream& stream;
-};
-
-std::string 
-GUIObjectState::get_string (const std::string& id, const std::string& prop_name, bool* empty)
+string
+GUIObjectState::get_string (const string& id, const string& prop_name, bool* empty)
 {
-       StringPropertyMap::iterator i = _property_maps.find (id);
-       
-       if (i == _property_maps.end()) {
+       std::map <std::string, XMLNode*>::const_iterator i = object_map.find (id);
+       if (i == object_map.end()) {
+               //assert (get_node (&_state, id) == 0); // XXX performance penalty due to get_node()
                if (empty) {
                        *empty = true;
                }
-               return string();
+               return string ();
        }
-       
-       const PropertyMap& pmap (i->second);
-       PropertyMap::const_iterator p = pmap.find (prop_name);
-       
-       if (p == pmap.end()) {
+       //assert (get_node (&_state, id) == i->second); // XXX performance penalty due to get_node()
+
+       XMLProperty const * p (i->second->property (prop_name));
+       if (!p) {
                if (empty) {
                        *empty = true;
                }
-               return string();
+               return string ();
        }
-       
-       std::stringstream ss;
-       gos_string_vistor gsv (ss);
-
-       boost::apply_visitor (gsv, p->second);
 
        if (empty) {
                *empty = false;
        }
-       
-       return ss.str ();
+
+       return p->value ();
 }
 
 XMLNode&
 GUIObjectState::get_state () const
 {
-       XMLNode* root = new XMLNode (xml_node_name);
-       
-       for (StringPropertyMap::const_iterator i = _property_maps.begin(); i != _property_maps.end(); ++i) {
-
-               const PropertyMap& pmap (i->second);
-               XMLNode* id_node = new XMLNode (X_("Object"));
-               
-               id_node->add_property ("id", i->first);
-               
-               for (PropertyMap::const_iterator p = pmap.begin(); p != pmap.end(); ++p) {
-                       std::stringstream ss;
-                       gos_string_vistor gsv (ss);
-                       boost::apply_visitor (gsv, p->second);
-                       id_node->add_property (p->first.c_str(), ss.str());
-               }
-               
-               root->add_child_nocopy (*id_node);
-       }
-
-
-       return *root;
+       return *new XMLNode (_state);
 }
 
 int
@@ -124,63 +122,37 @@ GUIObjectState::set_state (const XMLNode& node)
        if (node.name() != xml_node_name) {
                return -1;
        }
-       
-       clear_maps ();
-       
-       for (XMLNodeList::const_iterator i = node.children().begin(); i != node.children().end(); ++i) {
-               if ((*i)->name() == X_("Object")) {
-
-                       XMLNode* child = (*i);
-                       const XMLProperty* idp = child->property (X_("id"));
-
-                       if (!idp) {
-                               continue;
-                       }
-
-                       string id (idp->value());
-                       
-                       for (XMLPropertyList::const_iterator p = child->properties().begin(); p != child->properties().end(); ++p) {
-                               /* note that this always sets the property with
-                                  a string value, and so is not equivalent to
-                                  a call made by the program that passed a
-                                  scalar.
-                               */
-                               if ((*p)->name() != X_("id")) {
-                                       set (id, (*p)->name(), (*p)->value());
-                               }
-                       }
+
+       object_map.clear ();
+       _state = node;
+
+       XMLNodeList const & children (_state.children ());
+       for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
+               if ((*i)->name() != X_("Object")) {
+                       continue;
+               }
+               XMLProperty const * prop = (*i)->property (X_("id"));
+               if (!prop) {
+                       continue;
                }
+               object_map[prop->value ()] = *i;
        }
-
        return 0;
 }
 
-
 void
 GUIObjectState::load (const XMLNode& node)
 {
        (void) set_state (node);
 }
 
-GUIObjectState&
-GUIObjectState::operator= (const GUIObjectState& other)
+std::list<string>
+GUIObjectState::all_ids () const
 {
-       _property_maps = other._property_maps;
-
-       return *this;
-}
-
-/** @return begin iterator into our StringPropertyMap */
-GUIObjectState::StringPropertyMap::const_iterator
-GUIObjectState::begin () const
-{
-       return _property_maps.begin ();
-}
-
-/** @return end iterator into our StringPropertyMap */
-GUIObjectState::StringPropertyMap::const_iterator
-GUIObjectState::end () const
-{
-       return _property_maps.end ();
+       std::list<string> ids;
+       for (std::map <std::string, XMLNode*>::const_iterator i = object_map.begin ();
+                       i != object_map.end (); ++i) {
+               ids.push_back (i->first);
+       }
+       return ids;
 }
-