/*
- 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
#include "pbd/debug.h"
#include "pbd/stateful.h"
+#include "pbd/types_convert.h"
#include "pbd/property_list.h"
#include "pbd/properties.h"
#include "pbd/destructible.h"
#include "pbd/xml++.h"
#include "pbd/error.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace std;
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;
_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);
}
if (!node && add_if_missing) {
node = new XMLNode (str);
add_extra_xml (*node);
- }
+ }
return node;
}
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) {
_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.
*/
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);
}
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);
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()) {
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);
}
i->second->property_name()));
}
}
-
+
post_set (c);
send_change (c);
}
bool
-Stateful::changed() const
+Stateful::changed() const
{
for (OwnedPropertyList::const_iterator i = _properties->begin(); i != _properties->end(); ++i) {
if (i->second->changed()) {
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 ((prop = node.property ("id")) != 0) {
- _id = prop->value ();
+ if (regen && *regen) {
+ reset_id ();
return true;
- }
+ }
+
+ if (node.get_property ("id", _id)) {
+ return true;
+ }
return false;
}
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