I took a stab at it:
diff --git a/modules/juce_data_structures/values/juce_ValueTree.cpp b/modules/juce_data_structures/values/juce_ValueTree.cpp
index e185d8d81..a00337937 100644
--- a/modules/juce_data_structures/values/juce_ValueTree.cpp
+++ b/modules/juce_data_structures/values/juce_ValueTree.cpp
@@ -202,32 +202,62 @@ public:
setProperty (source.properties.getName (i), source.properties.getValueAt (i), undoManager);
}
- ValueTree getChildWithName (const Identifier& typeToMatch) const
+ ValueTree getChildWithName (const Identifier& typeToMatch, bool recursive) const
{
for (auto* s : children)
if (s->type == typeToMatch)
return ValueTree (*s);
+ if (recursive)
+ {
+ for (auto* s : children)
+ {
+ auto v = s->getChildWithName(typeToMatch, true);
+ if (v.isValid())
+ return v;
+ }
+ }
+
return {};
}
- ValueTree getOrCreateChildWithName (const Identifier& typeToMatch, UndoManager* undoManager)
+ ValueTree getOrCreateChildWithName (const Identifier& typeToMatch, UndoManager* undoManager, bool recursive)
{
for (auto* s : children)
if (s->type == typeToMatch)
return ValueTree (*s);
+ if (recursive)
+ {
+ for (auto* s : children)
+ {
+ auto v = s->getChildWithName(typeToMatch, true);
+ if (v.isValid())
+ return v;
+ }
+ }
+
auto newObject = new SharedObject (typeToMatch);
addChild (newObject, -1, undoManager);
return ValueTree (*newObject);
}
- ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
+ ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue, bool recursive = false) const
{
for (auto* s : children)
if (s->properties[propertyName] == propertyValue)
return ValueTree (*s);
+ if (recursive)
+ {
+ for (auto* s : children)
+ {
+ auto v = s->getChildWithProperty(propertyName, propertyValue, true);
+ if (v.isValid())
+ return v;
+ }
+ }
+
return {};
}
@@ -885,19 +915,19 @@ ValueTree ValueTree::Iterator::operator*() const
ValueTree::Iterator ValueTree::begin() const noexcept { return Iterator (*this, false); }
ValueTree::Iterator ValueTree::end() const noexcept { return Iterator (*this, true); }
-ValueTree ValueTree::getChildWithName (const Identifier& type) const
+ValueTree ValueTree::getChildWithName (const Identifier& type, bool recursive) const
{
- return object != nullptr ? object->getChildWithName (type) : ValueTree();
+ return object != nullptr ? object->getChildWithName (type, recursive) : ValueTree();
}
-ValueTree ValueTree::getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager)
+ValueTree ValueTree::getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager, bool recursive)
{
- return object != nullptr ? object->getOrCreateChildWithName (type, undoManager) : ValueTree();
+ return object != nullptr ? object->getOrCreateChildWithName (type, undoManager, recursive) : ValueTree();
}
-ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
+ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue, bool recursive) const
{
- return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree();
+ return object != nullptr ? object->getChildWithProperty (propertyName, propertyValue, recursive) : ValueTree();
}
bool ValueTree::isAChildOf (const ValueTree& possibleParent) const noexcept
diff --git a/modules/juce_data_structures/values/juce_ValueTree.h b/modules/juce_data_structures/values/juce_ValueTree.h
index 0f4f725a4..c758b617f 100644
--- a/modules/juce_data_structures/values/juce_ValueTree.h
+++ b/modules/juce_data_structures/values/juce_ValueTree.h
@@ -296,7 +296,7 @@ public:
check whether a tree is valid)
@see getOrCreateChildWithName
*/
- ValueTree getChildWithName (const Identifier& type) const;
+ ValueTree getChildWithName (const Identifier& type, bool recursive = false) const;
/** Returns the first sub-tree with the specified type name, creating and adding
a child with this name if there wasn't already one there.
@@ -304,7 +304,7 @@ public:
the method on is itself invalid.
@see getChildWithName
*/
- ValueTree getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager);
+ ValueTree getOrCreateChildWithName (const Identifier& type, UndoManager* undoManager, bool recursive = false);
/** Looks for the first sub-tree that has the specified property value.
This will scan the child trees in order, until it finds one that has property that matches
@@ -312,7 +312,7 @@ public:
If no such tree is found, it'll return an invalid object. (You can use isValid() to
check whether a tree is valid)
*/
- ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
+ ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue, bool recursive = false) const;
/** Adds a child to this tree.
Make sure that the child being added has first been removed from any former parent before
I didn’t add anything to the documentation though.