#include <boost/function.hpp>
+#include "pbd/libpbd_visibility.h"
#include "pbd/convert.h"
#include "pbd/id.h"
#include "pbd/property_basics.h"
#include "pbd/property_list.h"
#include "pbd/stateful_diff_command.h"
+#include "pbd/error.h"
namespace PBD {
* any change.
*/
template<typename Container>
-class SequenceProperty : public PropertyBase
+class /*LIBPBD_API*/ SequenceProperty : public PropertyBase
{
public:
typedef std::set<typename Container::value_type> ChangeContainer;
/* record the change described in our change member */
if (!_changes.added.empty()) {
- for (typename ChangeContainer::iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) {
+ for (typename ChangeContainer::const_iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) {
XMLNode* add_node = new XMLNode ("Add");
child->add_child_nocopy (*add_node);
get_content_as_xml (*i, *add_node);
}
}
if (!_changes.removed.empty()) {
- for (typename ChangeContainer::iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) {
+ for (typename ChangeContainer::const_iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) {
XMLNode* remove_node = new XMLNode ("Remove");
child->add_child_nocopy (*remove_node);
get_content_as_xml (*i, *remove_node);
/** Get a representation of one of our items as XML. The representation must be sufficient to
* restore the item's state later; an ID is ok if someone else is storing the item state,
- * otherwise it needs to be the full state. The supplied node is an <Add> or <Remove>
+ * otherwise it needs to be the full state. The supplied node is an \<Add\> or \<Remove\>
* which this method can either add properties or children to.
*/
virtual void get_content_as_xml (typename ChangeContainer::value_type, XMLNode &) const = 0;
with this diff().
*/
- for (typename ChangeContainer::iterator i = a->changes().added.begin(); i != a->changes().added.end(); ++i) {
+ for (typename ChangeContainer::const_iterator i = a->changes().added.begin(); i != a->changes().added.end(); ++i) {
(*i)->DropReferences.connect_same_thread (*cmd, boost::bind (&Destructible::drop_references, cmd));
}
}
for (XMLNodeList::const_iterator j = grandchildren.begin(); j != grandchildren.end(); ++j) {
typename Container::value_type v = get_content_from_xml (**j);
- assert (v);
-
- if ((*j)->name() == "Add") {
+
+ if (!v) {
+ warning << "undo transaction references an unknown object" << endmsg;
+ } else if ((*j)->name() == "Add") {
p->_changes.added.insert (v);
} else if ((*j)->name() == "Remove") {
p->_changes.removed.insert (v);
return p;
}
- /** Given an <Add> or <Remove> node as passed into get_content_to_xml, obtain an item */
+ /** Given an \<Add\> or \<Remove\> node as passed into get_content_to_xml, obtain an item */
virtual typename Container::value_type get_content_from_xml (XMLNode const & node) const = 0;
void clear_owned_changes () {
}
Container& operator= (const Container& other) {
- for (typename Container::iterator i = _val.begin(); i != _val.end(); ++i) {
+ for (typename Container::const_iterator i = _val.begin(); i != _val.end(); ++i) {
_changes.remove (*i);
}
- for (typename Container::iterator i = other.begin(); i != other.end(); ++i) {
+ for (typename Container::const_iterator i = other.begin(); i != other.end(); ++i) {
_changes.add (*i);
}
return _val = other;