enough with umpteen "i18n.h" files. Consolidate on pbd/i18n.h
[ardour.git] / libs / pbd / stateful.cc
index c4077f60af43e184739525b8f4b9b880275d7782..8b8219f7e2243306f201f95257b035ec20b18cf0 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2000-2001 Paul Davis 
+    Copyright (C) 2000-2001 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
@@ -35,7 +35,7 @@
 #include "pbd/xml++.h"
 #include "pbd/error.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 
@@ -44,19 +44,21 @@ namespace PBD {
 int Stateful::current_state_version = 0;
 int Stateful::loading_state_version = 0;
 
+Glib::Threads::Private<bool> Stateful::_regenerate_xml_or_string_ids;
+
 Stateful::Stateful ()
-       : _properties (new OwnedPropertyList)
+       : _extra_xml (0)
+       , _instant_xml (0)
+       , _properties (new OwnedPropertyList)
        , _stateful_frozen (0)
 {
-       _extra_xml = 0;
-       _instant_xml = 0;
 }
 
 Stateful::~Stateful ()
 {
        delete _properties;
 
-       // Do not delete _extra_xml.  The use of add_child_nocopy() 
+       // Do not delete _extra_xml.  The use of add_child_nocopy()
        // means it needs to live on indefinately.
 
        delete _instant_xml;
@@ -69,7 +71,7 @@ Stateful::add_extra_xml (XMLNode& node)
                _extra_xml = new XMLNode ("Extra");
        }
 
-       _extra_xml->remove_nodes (node.name());
+       _extra_xml->remove_nodes_and_delete (node.name());
        _extra_xml->add_child_nocopy (node);
 }
 
@@ -85,7 +87,7 @@ Stateful::extra_xml (const string& str, bool add_if_missing)
        if (!node && add_if_missing) {
                node = new XMLNode (str);
                add_extra_xml (*node);
-       } 
+       }
 
        return node;
 }
@@ -93,12 +95,12 @@ Stateful::extra_xml (const string& str, bool add_if_missing)
 void
 Stateful::save_extra_xml (const XMLNode& node)
 {
-       /* Looks for the child node called "Extra" and makes _extra_xml 
+       /* Looks for the child node called "Extra" and makes _extra_xml
           point to a copy of it. Will delete any existing node pointed
           to by _extra_xml if a new Extra node is found, but not
           otherwise.
        */
-       
+
        const XMLNode* xtra = node.child ("Extra");
 
        if (xtra) {
@@ -125,17 +127,17 @@ Stateful::add_instant_xml (XMLNode& node, const std::string& directory_path)
        _instant_xml->add_child_copy (node);
 
        std::string instant_xml_path = Glib::build_filename (directory_path, "instant.xml");
-       
+
        XMLTree tree;
        tree.set_filename(instant_xml_path);
 
        /* Important: the destructor for an XMLTree deletes
           all of its nodes, starting at _root. We therefore
-          cannot simply hand it our persistent _instant_xml 
+          cannot simply hand it our persistent _instant_xml
           node as its _root, because we will lose it whenever
           the Tree goes out of scope.
 
-          So instead, copy the _instant_xml node (which does 
+          So instead, copy the _instant_xml node (which does
           a deep copy), and hand that to the tree.
        */
 
@@ -192,7 +194,7 @@ PropertyList *
 Stateful::get_changes_as_properties (Command* cmd) const
 {
        PropertyList* pl = new PropertyList;
-       
+
        for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
                i->second->get_changes_as_properties (*pl, cmd);
        }
@@ -209,7 +211,7 @@ PropertyChange
 Stateful::set_values (XMLNode const & node)
 {
        PropertyChange c;
-       
+
        for (OwnedPropertyList::iterator i = _properties->begin(); i != _properties->end(); ++i) {
                if (i->second->set_value (node)) {
                        c.add (i->first);
@@ -232,7 +234,7 @@ Stateful::apply_changes (const PropertyList& property_list)
        for (PropertyList::const_iterator pp = property_list.begin(); pp != property_list.end(); ++pp) {
                DEBUG_TRACE (DEBUG::Stateful, string_compose ("in plist: %1\n", pp->second->property_name()));
        }
-       
+
        for (PropertyList::const_iterator i = property_list.begin(); i != property_list.end(); ++i) {
                if ((p = _properties->find (i->first)) != _properties->end()) {
 
@@ -240,7 +242,7 @@ Stateful::apply_changes (const PropertyList& property_list)
                                DEBUG::Stateful,
                                string_compose ("actually setting property %1 using %2\n", p->second->property_name(), i->second->property_name())
                                );
-                       
+
                        if (apply_changes (*i->second)) {
                                c.add (i->first);
                        }
@@ -249,7 +251,7 @@ Stateful::apply_changes (const PropertyList& property_list)
                                                                      i->second->property_name()));
                }
        }
-       
+
        post_set (c);
 
        send_change (c);
@@ -322,7 +324,7 @@ Stateful::resume_property_changes ()
 }
 
 bool
-Stateful::changed() const  
+Stateful::changed() const
 {
        for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
                if (i->second->changed()) {
@@ -376,16 +378,22 @@ Stateful::clear_owned_changes ()
                i->second->clear_owned_changes ();
        }
 }
-  
+
 bool
-Stateful::set_id (const XMLNode& node) 
+Stateful::set_id (const XMLNode& node)
 {
        const XMLProperty* prop;
+       bool* regen = _regenerate_xml_or_string_ids.get();
+
+       if (regen && *regen) {
+               reset_id ();
+               return true;
+       }
 
        if ((prop = node.property ("id")) != 0) {
                _id = prop->value ();
                return true;
-       } 
+       }
 
        return false;
 }
@@ -399,7 +407,31 @@ Stateful::reset_id ()
 void
 Stateful::set_id (const string& str)
 {
-       _id = str;
+       bool* regen = _regenerate_xml_or_string_ids.get();
+
+       if (regen && *regen) {
+               reset_id ();
+       } else {
+               _id = str;
+       }
+}
+
+bool
+Stateful::regenerate_xml_or_string_ids () const
+{
+       bool* regen = _regenerate_xml_or_string_ids.get();
+       if (regen && *regen) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
+void
+Stateful::set_regenerate_xml_and_string_ids_in_this_thread (bool yn)
+{
+       bool* val = new bool (yn);
+       _regenerate_xml_or_string_ids.set (val);
 }
 
 } // namespace PBD