30class ValueTree::SharedObject :
public ReferenceCountedObject
33 using Ptr = ReferenceCountedObjectPtr<SharedObject>;
35 explicit SharedObject (
const Identifier& t) noexcept : type (t) {}
37 SharedObject (
const SharedObject& other)
40 for (
auto* c : other.children)
42 auto* child =
new SharedObject (*c);
48 SharedObject& operator= (
const SharedObject&) =
delete;
52 jassert (parent ==
nullptr);
54 for (
auto i = children.size(); --i >= 0;)
56 const Ptr c (children.getObjectPointerUnchecked (i));
59 c->sendParentChangeMessage();
63 SharedObject& getRoot() noexcept
65 return parent ==
nullptr ? *this : parent->getRoot();
68 template <
typename Function>
69 void callListeners (ValueTree::Listener* listenerToExclude, Function fn)
const
71 auto numListeners = valueTreesWithListeners.size();
73 if (numListeners == 1)
75 valueTreesWithListeners.getUnchecked (0)->listeners.callExcluding (listenerToExclude, fn);
77 else if (numListeners > 0)
79 auto listenersCopy = valueTreesWithListeners;
81 for (
int i = 0; i < numListeners; ++i)
83 auto* v = listenersCopy.getUnchecked (i);
85 if (i == 0 || valueTreesWithListeners.contains (v))
86 v->listeners.callExcluding (listenerToExclude, fn);
91 template <
typename Function>
92 void callListenersForAllParents (ValueTree::Listener* listenerToExclude, Function fn)
const
94 for (
auto* t =
this; t !=
nullptr; t = t->parent)
95 t->callListeners (listenerToExclude, fn);
98 void sendPropertyChangeMessage (
const Identifier& property, ValueTree::Listener* listenerToExclude =
nullptr)
101 callListenersForAllParents (listenerToExclude, [&] (Listener& l) { l.valueTreePropertyChanged (tree, property); });
104 void sendChildAddedMessage (
ValueTree child)
107 callListenersForAllParents (
nullptr, [&] (Listener& l) { l.valueTreeChildAdded (tree, child); });
110 void sendChildRemovedMessage (
ValueTree child,
int index)
113 callListenersForAllParents (
nullptr, [=, &tree, &child] (Listener& l) { l.valueTreeChildRemoved (tree, child, index); });
116 void sendChildOrderChangedMessage (
int oldIndex,
int newIndex)
119 callListenersForAllParents (
nullptr, [=, &tree] (Listener& l) { l.valueTreeChildOrderChanged (tree, oldIndex, newIndex); });
122 void sendParentChangeMessage()
126 for (
auto j = children.size(); --j >= 0;)
127 if (
auto* child = children.getObjectPointer (j))
128 child->sendParentChangeMessage();
130 callListeners (
nullptr, [&] (Listener& l) { l.valueTreeParentChanged (tree); });
133 void setProperty (
const Identifier& name,
const var& newValue, UndoManager* undoManager,
134 ValueTree::Listener* listenerToExclude =
nullptr)
136 if (undoManager ==
nullptr)
138 if (properties.set (name, newValue))
139 sendPropertyChangeMessage (name, listenerToExclude);
143 if (
auto* existingValue = properties.getVarPointer (name))
145 if (*existingValue != newValue)
146 undoManager->perform (
new SetPropertyAction (*
this, name, newValue, *existingValue,
147 false,
false, listenerToExclude));
151 undoManager->perform (
new SetPropertyAction (*
this, name, newValue, {},
152 true,
false, listenerToExclude));
157 bool hasProperty (
const Identifier& name)
const noexcept
159 return properties.contains (name);
162 void removeProperty (
const Identifier& name, UndoManager* undoManager)
164 if (undoManager ==
nullptr)
166 if (properties.remove (name))
167 sendPropertyChangeMessage (name);
171 if (properties.contains (name))
172 undoManager->perform (
new SetPropertyAction (*
this, name, {}, properties[name],
false,
true));
176 void removeAllProperties (UndoManager* undoManager)
178 if (undoManager ==
nullptr)
180 while (properties.size() > 0)
182 auto name = properties.getName (properties.size() - 1);
183 properties.remove (name);
184 sendPropertyChangeMessage (name);
189 for (
auto i = properties.size(); --i >= 0;)
190 undoManager->perform (
new SetPropertyAction (*
this, properties.getName (i), {},
191 properties.getValueAt (i),
false,
true));
195 void copyPropertiesFrom (
const SharedObject& source, UndoManager* undoManager)
197 for (
auto i = properties.size(); --i >= 0;)
198 if (! source.properties.contains (properties.getName (i)))
199 removeProperty (properties.getName (i), undoManager);
201 for (
int i = 0; i < source.properties.size(); ++i)
202 setProperty (source.properties.getName (i), source.properties.getValueAt (i), undoManager);
205 ValueTree getChildWithName (
const Identifier& typeToMatch)
const
207 for (
auto* s : children)
208 if (s->type == typeToMatch)
214 ValueTree getOrCreateChildWithName (
const Identifier& typeToMatch, UndoManager* undoManager)
216 for (
auto* s : children)
217 if (s->type == typeToMatch)
220 auto newObject =
new SharedObject (typeToMatch);
221 addChild (newObject, -1, undoManager);
225 ValueTree getChildWithProperty (
const Identifier& propertyName,
const var& propertyValue)
const
227 for (
auto* s : children)
228 if (s->properties[propertyName] == propertyValue)
234 bool isAChildOf (
const SharedObject* possibleParent)
const noexcept
236 for (
auto* p = parent; p !=
nullptr; p = p->parent)
237 if (p == possibleParent)
243 int indexOf (
const ValueTree& child)
const noexcept
245 return children.indexOf (child.object);
248 void addChild (SharedObject* child,
int index, UndoManager* undoManager)
250 if (child !=
nullptr && child->parent !=
this)
252 if (child !=
this && ! isAChildOf (child))
257 jassert (child->parent ==
nullptr);
259 if (child->parent !=
nullptr)
261 jassert (child->parent->children.indexOf (child) >= 0);
262 child->parent->removeChild (child->parent->children.indexOf (child), undoManager);
265 if (undoManager ==
nullptr)
267 children.insert (index, child);
268 child->parent =
this;
269 sendChildAddedMessage (
ValueTree (*child));
270 child->sendParentChangeMessage();
274 if (! isPositiveAndBelow (index, children.size()))
275 index = children.size();
277 undoManager->perform (
new AddOrRemoveChildAction (*
this, index, child));
289 void removeChild (
int childIndex, UndoManager* undoManager)
291 if (
auto child = Ptr (children.getObjectPointer (childIndex)))
293 if (undoManager ==
nullptr)
295 children.remove (childIndex);
296 child->parent =
nullptr;
297 sendChildRemovedMessage (
ValueTree (child), childIndex);
298 child->sendParentChangeMessage();
302 undoManager->perform (
new AddOrRemoveChildAction (*
this, childIndex, {}));
307 void removeAllChildren (UndoManager* undoManager)
309 while (children.size() > 0)
310 removeChild (children.size() - 1, undoManager);
313 void moveChild (
int currentIndex,
int newIndex, UndoManager* undoManager)
316 jassert (isPositiveAndBelow (currentIndex, children.size()));
318 if (currentIndex != newIndex
319 && isPositiveAndBelow (currentIndex, children.size()))
321 if (undoManager ==
nullptr)
323 children.move (currentIndex, newIndex);
324 sendChildOrderChangedMessage (currentIndex, newIndex);
328 if (! isPositiveAndBelow (newIndex, children.size()))
329 newIndex = children.size() - 1;
331 undoManager->perform (
new MoveChildAction (*
this, currentIndex, newIndex));
336 void reorderChildren (
const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager)
338 jassert (newOrder.size() == children.size());
340 for (
int i = 0; i < children.size(); ++i)
342 auto* child = newOrder.getUnchecked (i)->object.get();
344 if (children.getObjectPointerUnchecked (i) != child)
346 auto oldIndex = children.indexOf (child);
347 jassert (oldIndex >= 0);
348 moveChild (oldIndex, i, undoManager);
353 bool isEquivalentTo (
const SharedObject& other)
const noexcept
355 if (type != other.type
356 || properties.size() != other.properties.size()
357 || children.size() != other.children.size()
358 || properties != other.properties)
361 for (
int i = 0; i < children.size(); ++i)
362 if (! children.getObjectPointerUnchecked (i)->isEquivalentTo (*other.children.getObjectPointerUnchecked (i)))
368 XmlElement* createXml()
const
370 auto* xml =
new XmlElement (type);
371 properties.copyToXmlAttributes (*xml);
374 for (
auto i = children.size(); --i >= 0;)
375 xml->prependChildElement (children.getObjectPointerUnchecked (i)->createXml());
380 void writeToStream (OutputStream& output)
const
382 output.writeString (type.toString());
383 output.writeCompressedInt (properties.size());
385 for (
int j = 0; j < properties.size(); ++j)
387 output.writeString (properties.getName (j).toString());
388 properties.getValueAt (j).writeToStream (output);
391 output.writeCompressedInt (children.size());
393 for (
auto* c : children)
394 writeObjectToStream (output, c);
397 static void writeObjectToStream (OutputStream& output,
const SharedObject*
object)
399 if (
object !=
nullptr)
401 object->writeToStream (output);
405 output.writeString ({});
406 output.writeCompressedInt (0);
407 output.writeCompressedInt (0);
412 struct SetPropertyAction :
public UndoableAction
414 SetPropertyAction (Ptr targetObject,
const Identifier& propertyName,
415 const var& newVal,
const var& oldVal,
bool isAdding,
bool isDeleting,
416 ValueTree::Listener* listenerToExclude =
nullptr)
417 : target (std::move (targetObject)),
418 name (propertyName), newValue (newVal), oldValue (oldVal),
419 isAddingNewProperty (isAdding), isDeletingProperty (isDeleting),
420 excludeListener (listenerToExclude)
424 bool perform()
override
426 jassert (! (isAddingNewProperty && target->hasProperty (name)));
428 if (isDeletingProperty)
429 target->removeProperty (name,
nullptr);
431 target->setProperty (name, newValue,
nullptr, excludeListener);
438 if (isAddingNewProperty)
439 target->removeProperty (name,
nullptr);
441 target->setProperty (name, oldValue,
nullptr);
446 int getSizeInUnits()
override
448 return (
int)
sizeof (*this);
453 if (! (isAddingNewProperty || isDeletingProperty))
455 if (
auto* next =
dynamic_cast<SetPropertyAction*
> (nextAction))
456 if (next->target == target && next->name == name
457 && ! (next->isAddingNewProperty || next->isDeletingProperty))
458 return new SetPropertyAction (*target, name, next->newValue, oldValue,
false,
false);
466 const Identifier name;
469 const bool isAddingNewProperty : 1, isDeletingProperty : 1;
470 ValueTree::Listener* excludeListener;
472 JUCE_DECLARE_NON_COPYABLE (SetPropertyAction)
476 struct AddOrRemoveChildAction :
public UndoableAction
478 AddOrRemoveChildAction (Ptr parentObject,
int index, SharedObject* newChild)
479 : target (std::move (parentObject)),
480 child (newChild != nullptr ? newChild : target->children.getObjectPointer (index)),
482 isDeleting (newChild == nullptr)
484 jassert (child !=
nullptr);
487 bool perform()
override
490 target->removeChild (childIndex,
nullptr);
492 target->addChild (child.get(), childIndex,
nullptr);
501 target->addChild (child.get(), childIndex,
nullptr);
507 jassert (childIndex < target->children.size());
508 target->removeChild (childIndex,
nullptr);
514 int getSizeInUnits()
override
516 return (
int)
sizeof (*this);
520 const Ptr target, child;
521 const int childIndex;
522 const bool isDeleting;
524 JUCE_DECLARE_NON_COPYABLE (AddOrRemoveChildAction)
528 struct MoveChildAction :
public UndoableAction
530 MoveChildAction (Ptr parentObject,
int fromIndex,
int toIndex) noexcept
531 : parent (std::move (parentObject)), startIndex (fromIndex), endIndex (toIndex)
535 bool perform()
override
537 parent->moveChild (startIndex, endIndex,
nullptr);
543 parent->moveChild (endIndex, startIndex,
nullptr);
547 int getSizeInUnits()
override
549 return (
int)
sizeof (*this);
554 if (
auto* next =
dynamic_cast<MoveChildAction*
> (nextAction))
555 if (next->parent == parent && next->startIndex == endIndex)
556 return new MoveChildAction (parent, startIndex, next->endIndex);
563 const int startIndex, endIndex;
565 JUCE_DECLARE_NON_COPYABLE (MoveChildAction)
569 const Identifier type;
570 NamedValueSet properties;
571 ReferenceCountedArray<SharedObject> children;
572 SortedSet<ValueTree*> valueTreesWithListeners;
573 SharedObject* parent =
nullptr;
575 JUCE_LEAK_DETECTOR (SharedObject)
583JUCE_DECLARE_DEPRECATED_STATIC (
const ValueTree ValueTree::invalid;)
587 jassert (type.
toString().isNotEmpty());
591 std::initializer_list<NamedValueSet::NamedValue> properties,
592 std::initializer_list<ValueTree>
subTrees)
610 if (
object !=
other.object)
614 object =
other.object;
618 if (
object !=
nullptr)
619 object->valueTreesWithListeners.removeValue (
this);
621 if (
other.object !=
nullptr)
622 other.object->valueTreesWithListeners.
add (
this);
624 object =
other.object;
626 listeners.call ([
this] (
Listener&
l) {
l.valueTreeRedirected (*
this); });
634 : object (std::move (
other.object))
636 if (
object !=
nullptr)
637 object->valueTreesWithListeners.removeValue (&
other);
642 if (! listeners.
isEmpty() &&
object !=
nullptr)
643 object->valueTreesWithListeners.removeValue (
this);
648 return object ==
other.object;
653 return object !=
other.object;
658 return object ==
other.object
659 || (
object !=
nullptr &&
other.object !=
nullptr
660 &&
object->isEquivalentTo (*
other.object));
665 if (
object !=
nullptr)
666 return ValueTree (*
new SharedObject (*
object));
673 jassert (
object !=
nullptr || source.object ==
nullptr);
675 if (source.object ==
nullptr)
677 else if (
object !=
nullptr)
678 object->copyPropertiesFrom (*(source.object), undoManager);
683 jassert (
object !=
nullptr || source.object ==
nullptr);
688 if (
object !=
nullptr && source.object !=
nullptr)
689 for (
auto& child : source.object->children)
690 object->addChild (createCopyIfNotNull (child), -1, undoManager);
695 return object !=
nullptr &&
object->type == typeName;
700 return object !=
nullptr ?
object->type :
Identifier();
705 if (
object !=
nullptr)
706 if (
auto p = object->parent)
714 if (
object !=
nullptr)
722 if (
object !=
nullptr)
723 if (
auto* p = object->parent)
724 if (
auto*
c = p->children.getObjectPointer (p->indexOf (*
this) +
delta))
738 return object ==
nullptr ? getNullVarRef() :
object->properties[name];
743 return object ==
nullptr ? getNullVarRef() :
object->properties[name];
754 return object ==
nullptr ?
nullptr
755 :
object->properties.getVarPointer (name);
766 jassert (name.
toString().isNotEmpty());
767 jassert (
object !=
nullptr);
769 if (
object !=
nullptr)
777 return object !=
nullptr &&
object->hasProperty (name);
782 if (
object !=
nullptr)
783 object->removeProperty (name, undoManager);
788 if (
object !=
nullptr)
789 object->removeAllProperties (undoManager);
794 return object ==
nullptr ? 0 :
object->properties.
size();
800 :
object->properties.getName (index);
805 return object !=
nullptr ?
object->getReferenceCount() : 0;
813 : tree (
vt), property (
prop), undoManager (
um), updateSynchronously (
sync)
815 tree.addListener (
this);
818 ~ValueTreePropertyValueSource()
override
820 tree.removeListener (
this);
823 var getValue()
const override {
return tree[property]; }
824 void setValue (
const var& newValue)
override { tree.setProperty (property, newValue, undoManager); }
828 const Identifier property;
829 UndoManager*
const undoManager;
830 const bool updateSynchronously;
832 void valueTreePropertyChanged (ValueTree& changedTree,
const Identifier& changedProperty)
override
834 if (tree == changedTree && property == changedProperty)
838 void valueTreeChildAdded (ValueTree&, ValueTree&)
override {}
839 void valueTreeChildRemoved (ValueTree&, ValueTree&,
int)
override {}
840 void valueTreeChildOrderChanged (ValueTree&,
int,
int)
override {}
841 void valueTreeParentChanged (ValueTree&)
override {}
843 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueTreePropertyValueSource)
848 return Value (
new ValueTreePropertyValueSource (*
this, name, undoManager, updateSynchronously));
854 return object ==
nullptr ? 0 :
object->children.
size();
859 if (
object !=
nullptr)
860 if (
auto*
c = object->children.getObjectPointer (index))
867 : internal (v.object !=
nullptr ? (
isEnd ? v.object->children.end() : v.object->children.begin()) :
nullptr)
871ValueTree::Iterator& ValueTree::Iterator::operator++()
873 internal =
static_cast<SharedObject**
> (internal) + 1;
877bool ValueTree::Iterator::operator== (
const Iterator& other)
const {
return internal == other.internal; }
878bool ValueTree::Iterator::operator!= (
const Iterator& other)
const {
return internal != other.internal; }
880ValueTree ValueTree::Iterator::operator*()
const
882 return ValueTree (SharedObject::Ptr (*
static_cast<SharedObject**
> (internal)));
905 return object !=
nullptr &&
object->isAChildOf (
possibleParent.object.get());
910 return object !=
nullptr ?
object->
indexOf (child) : -1;
915 jassert (
object !=
nullptr);
917 if (
object !=
nullptr)
918 object->addChild (child.object.
get(), index, undoManager);
928 if (
object !=
nullptr)
929 object->removeChild (childIndex, undoManager);
934 if (
object !=
nullptr)
935 object->removeChild (object->children.indexOf (child.object), undoManager);
940 if (
object !=
nullptr)
941 object->removeAllChildren (undoManager);
946 if (
object !=
nullptr)
953 jassert (
object !=
nullptr);
955 for (
auto*
o : object->children)
957 jassert (
o !=
nullptr);
962void ValueTree::reorderChildren (
const OwnedArray<ValueTree>& newOrder, UndoManager* undoManager)
964 jassert (
object !=
nullptr);
965 object->reorderChildren (newOrder, undoManager);
971 if (listener !=
nullptr)
973 if (listeners.
isEmpty() &&
object !=
nullptr)
974 object->valueTreesWithListeners.
add (
this);
976 listeners.
add (listener);
982 listeners.
remove (listener);
984 if (listeners.
isEmpty() &&
object !=
nullptr)
985 object->valueTreesWithListeners.removeValue (
this);
990 if (
object !=
nullptr)
991 object->sendPropertyChangeMessage (property);
997 return std::unique_ptr<XmlElement> (
object !=
nullptr ? object->createXml() :
nullptr);
1005 v.object->properties.setFromXmlAttributes (xml);
1007 forEachXmlChildElement (xml,
e)
1020 if (
auto xml = parseXML (
xmlText))
1029 return xml->toString (format);
1037 SharedObject::writeObjectToStream (output,
object.get());
1061 if (name.isNotEmpty())
1068 v.object->children.ensureStorageAllocated (
numChildren);
1074 if (! child.isValid())
1077 v.object->children.add (child.object);
1078 child.object->parent = v.object.
get();
1113 :
UnitTest (
"ValueTrees", UnitTestCategories::values)
1118 char buffer[50] = { 0 };
1119 const char chars[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-:";
1121 for (
int i = 1 + r.
nextInt (numElementsInArray (buffer) - 2); --i >= 0;)
1122 buffer[i] = chars[r.
nextInt (sizeof (chars) - 1)];
1124 String result (buffer);
1126 if (! XmlElement::isValidXmlName (result))
1127 result = createRandomIdentifier (r);
1132 static String createRandomWideCharString (Random& r)
1134 juce_wchar buffer[50] = { 0 };
1136 for (
int i = r.nextInt (numElementsInArray (buffer) - 1); --i >= 0;)
1142 buffer[i] = (juce_wchar) (1 + r.nextInt (0x10ffff - 1));
1144 while (! CharPointer_UTF16::canRepresent (buffer[i]));
1147 buffer[i] = (juce_wchar) (1 + r.nextInt (0x7e));
1150 return CharPointer_UTF32 (buffer);
1153 static ValueTree createRandomTree (UndoManager* undoManager,
int depth, Random& r)
1155 ValueTree v (createRandomIdentifier (r));
1157 for (
int i = r.nextInt (10); --i >= 0;)
1159 switch (r.nextInt (5))
1161 case 0: v.setProperty (createRandomIdentifier (r), createRandomWideCharString (r), undoManager);
break;
1162 case 1: v.setProperty (createRandomIdentifier (r), r.nextInt(), undoManager);
break;
1163 case 2:
if (depth < 5) v.addChild (createRandomTree (undoManager, depth + 1, r), r.nextInt (v.getNumChildren() + 1), undoManager);
break;
1164 case 3: v.setProperty (createRandomIdentifier (r), r.nextBool(), undoManager);
break;
1165 case 4: v.setProperty (createRandomIdentifier (r), r.nextDouble(), undoManager);
break;
1173 void runTest()
override
1176 beginTest (
"ValueTree");
1178 auto r = getRandom();
1180 for (
int i = 10; --i >= 0;)
1182 MemoryOutputStream mo;
1183 auto v1 = createRandomTree (
nullptr, 0, r);
1184 v1.writeToStream (mo);
1186 MemoryInputStream mi (mo.getData(), mo.getDataSize(),
false);
1187 auto v2 = ValueTree::readFromStream (mi);
1188 expect (v1.isEquivalentTo (v2));
1190 MemoryOutputStream zipped;
1192 GZIPCompressorOutputStream zippedOut (zipped);
1193 v1.writeToStream (zippedOut);
1195 expect (v1.isEquivalentTo (ValueTree::readFromGZIPData (zipped.getData(), zipped.getDataSize())));
1197 auto xml1 = v1.createXml();
1198 auto xml2 = v2.createCopy().createXml();
1199 expect (xml1->isEquivalentTo (xml2.get(),
false));
1201 auto v4 = v2.createCopy();
1202 expect (v1.isEquivalentTo (v4));
1207 beginTest (
"Float formatting");
1209 ValueTree testVT (
"Test");
1210 Identifier number (
"number");
1212 std::map<double, String> tests;
1215 tests[1.01] =
"1.01";
1216 tests[0.76378] =
"0.76378";
1217 tests[-10] =
"-10.0";
1218 tests[10.01] =
"10.01";
1219 tests[0.0123] =
"0.0123";
1220 tests[-3.7e-27] =
"-3.7e-27";
1221 tests[1e+40] =
"1.0e40";
1222 tests[-12345678901234567.0] =
"-1.234567890123457e16";
1223 tests[192000] =
"192000.0";
1224 tests[1234567] =
"1.234567e6";
1225 tests[0.00006] =
"0.00006";
1226 tests[0.000006] =
"6.0e-6";
1228 for (
auto& test : tests)
1230 testVT.setProperty (number, test.first,
nullptr);
1231 auto lines = StringArray::fromLines (testVT.toXmlString());
1232 lines.removeEmptyStrings();
1233 auto numLines = lines.size();
1234 expect (numLines > 1);
1235 expectEquals (lines[numLines - 1],
"<Test number=\"" + test.second +
"\"/>");
1241static ValueTreeTests valueTreeTests;
bool isEmpty() const noexcept
int size() const noexcept
void remove(int indexToRemove)
int indexOf(ParameterType elementToLookFor) const
void add(const ElementType &newElement)
const String & toString() const noexcept
ReferencedType * get() const noexcept
ReferenceCountedObject()=default
virtual void valueTreeRedirected(ValueTree &treeWhichHasBeenChanged)
virtual void valueTreeChildRemoved(ValueTree &parentTree, ValueTree &childWhichHasBeenRemoved, int indexFromWhichChildWasRemoved)
virtual void valueTreeChildOrderChanged(ValueTree &parentTreeWhoseChildrenHaveMoved, int oldIndex, int newIndex)
virtual void valueTreeParentChanged(ValueTree &treeWhoseParentHasChanged)
virtual void valueTreePropertyChanged(ValueTree &treeWhosePropertyHasChanged, const Identifier &property)
virtual void valueTreeChildAdded(ValueTree &parentTree, ValueTree &childWhichHasBeenAdded)
Value getPropertyAsValue(const Identifier &name, UndoManager *undoManager, bool shouldUpdateSynchronously=false)
Identifier getPropertyName(int index) const noexcept
Iterator begin() const noexcept
bool operator!=(const ValueTree &) const noexcept
std::unique_ptr< XmlElement > createXml() const
bool hasType(const Identifier &typeName) const noexcept
static ValueTree readFromStream(InputStream &input)
void removeChild(const ValueTree &child, UndoManager *undoManager)
String toXmlString(const XmlElement::TextFormat &format={}) const
static ValueTree readFromGZIPData(const void *data, size_t numBytes)
ValueTree getChild(int index) const
int getNumProperties() const noexcept
int getNumChildren() const noexcept
void copyPropertiesFrom(const ValueTree &source, UndoManager *undoManager)
int getReferenceCount() const noexcept
const var * getPropertyPointer(const Identifier &name) const noexcept
ValueTree & setProperty(const Identifier &name, const var &newValue, UndoManager *undoManager)
void removeAllChildren(UndoManager *undoManager)
bool isAChildOf(const ValueTree &possibleParent) const noexcept
void removeAllProperties(UndoManager *undoManager)
void addListener(Listener *listener)
void appendChild(const ValueTree &child, UndoManager *undoManager)
int indexOf(const ValueTree &child) const noexcept
bool operator==(const ValueTree &) const noexcept
ValueTree & setPropertyExcludingListener(Listener *listenerToExclude, const Identifier &name, const var &newValue, UndoManager *undoManager)
void addChild(const ValueTree &child, int index, UndoManager *undoManager)
ValueTree getParent() const noexcept
const var & getProperty(const Identifier &name) const noexcept
static ValueTree fromXml(const XmlElement &xml)
ValueTree createCopy() const
Identifier getType() const noexcept
ValueTree getChildWithName(const Identifier &type) const
Iterator end() const noexcept
ValueTree & operator=(const ValueTree &)
void removeListener(Listener *listener)
void writeToStream(OutputStream &output) const
bool isEquivalentTo(const ValueTree &) const
ValueTree getOrCreateChildWithName(const Identifier &type, UndoManager *undoManager)
void moveChild(int currentIndex, int newIndex, UndoManager *undoManager)
void sendPropertyChangeMessage(const Identifier &property)
void removeProperty(const Identifier &name, UndoManager *undoManager)
const var & operator[](const Identifier &name) const noexcept
ValueTree getSibling(int delta) const noexcept
ValueTree getChildWithProperty(const Identifier &propertyName, const var &propertyValue) const
void copyPropertiesAndChildrenFrom(const ValueTree &source, UndoManager *undoManager)
ValueTree getRoot() const noexcept
static ValueTree readFromData(const void *data, size_t numBytes)
bool hasProperty(const Identifier &name) const noexcept
void sendChangeMessage(bool dispatchSynchronously)
bool isTextElement() const noexcept
const String & getTagName() const noexcept
static var readFromStream(InputStream &input)