| @@ -287,8 +287,8 @@ XmlElement* KnownPluginList::createXml() const | |||||
| { | { | ||||
| XmlElement* const e = new XmlElement ("KNOWNPLUGINS"); | XmlElement* const e = new XmlElement ("KNOWNPLUGINS"); | ||||
| for (int i = 0; i < types.size(); ++i) | |||||
| e->addChildElement (types.getUnchecked(i)->createXml()); | |||||
| for (int i = types.size(); --i >= 0;) | |||||
| e->prependChildElement (types.getUnchecked(i)->createXml()); | |||||
| for (int i = 0; i < blacklist.size(); ++i) | for (int i = 0; i < blacklist.size(); ++i) | ||||
| e->createNewChildElement ("BLACKLISTED")->setAttribute ("id", blacklist[i]); | e->createNewChildElement ("BLACKLISTED")->setAttribute ("id", blacklist[i]); | ||||
| @@ -585,18 +585,36 @@ XmlElement* XmlElement::getChildByAttribute (StringRef attributeName, StringRef | |||||
| void XmlElement::addChildElement (XmlElement* const newNode) noexcept | void XmlElement::addChildElement (XmlElement* const newNode) noexcept | ||||
| { | { | ||||
| if (newNode != nullptr) | if (newNode != nullptr) | ||||
| { | |||||
| // The element being added must not be a child of another node! | |||||
| jassert (newNode->nextListItem == nullptr); | |||||
| firstChildElement.append (newNode); | firstChildElement.append (newNode); | ||||
| } | |||||
| } | } | ||||
| void XmlElement::insertChildElement (XmlElement* const newNode, int indexToInsertAt) noexcept | void XmlElement::insertChildElement (XmlElement* const newNode, int indexToInsertAt) noexcept | ||||
| { | { | ||||
| if (newNode != nullptr) | if (newNode != nullptr) | ||||
| { | { | ||||
| removeChildElement (newNode, false); | |||||
| // The element being added must not be a child of another node! | |||||
| jassert (newNode->nextListItem == nullptr); | |||||
| firstChildElement.insertAtIndex (indexToInsertAt, newNode); | firstChildElement.insertAtIndex (indexToInsertAt, newNode); | ||||
| } | } | ||||
| } | } | ||||
| void XmlElement::prependChildElement (XmlElement* newNode) noexcept | |||||
| { | |||||
| if (newNode != nullptr) | |||||
| { | |||||
| // The element being added must not be a child of another node! | |||||
| jassert (newNode->nextListItem == nullptr); | |||||
| firstChildElement.insertNext (newNode); | |||||
| } | |||||
| } | |||||
| XmlElement* XmlElement::createNewChildElement (const String& childTagName) | XmlElement* XmlElement::createNewChildElement (const String& childTagName) | ||||
| { | { | ||||
| XmlElement* const newElement = new XmlElement (childTagName); | XmlElement* const newElement = new XmlElement (childTagName); | ||||
| @@ -504,6 +504,10 @@ public: | |||||
| make sure the object that you pass in will not be deleted by anything else, | make sure the object that you pass in will not be deleted by anything else, | ||||
| and make sure it's not already the child of another element. | and make sure it's not already the child of another element. | ||||
| Note that due to the XmlElement using a singly-linked-list, prependChildElement() | |||||
| is an O(1) operation, but addChildElement() is an O(N) operation - so if | |||||
| you're adding large number of elements, you may prefer to do so in reverse order! | |||||
| @see getFirstChildElement, getNextElement, getNumChildElements, | @see getFirstChildElement, getNextElement, getNumChildElements, | ||||
| getChildElement, removeChildElement | getChildElement, removeChildElement | ||||
| */ | */ | ||||
| @@ -523,6 +527,21 @@ public: | |||||
| void insertChildElement (XmlElement* newChildNode, | void insertChildElement (XmlElement* newChildNode, | ||||
| int indexToInsertAt) noexcept; | int indexToInsertAt) noexcept; | ||||
| /** Inserts an element at the beginning of this element's list of children. | |||||
| Child elements are deleted automatically when their parent is deleted, so | |||||
| make sure the object that you pass in will not be deleted by anything else, | |||||
| and make sure it's not already the child of another element. | |||||
| Note that due to the XmlElement using a singly-linked-list, prependChildElement() | |||||
| is an O(1) operation, but addChildElement() is an O(N) operation - so if | |||||
| you're adding large number of elements, you may prefer to do so in reverse order! | |||||
| @param newChildNode the element to add | |||||
| @see addChildElement, insertChildElement | |||||
| */ | |||||
| void prependChildElement (XmlElement* newChildElement) noexcept; | |||||
| /** Creates a new element with the given name and returns it, after adding it | /** Creates a new element with the given name and returns it, after adding it | ||||
| as a child element. | as a child element. | ||||
| @@ -412,8 +412,9 @@ public: | |||||
| XmlElement* const xml = new XmlElement (type.toString()); | XmlElement* const xml = new XmlElement (type.toString()); | ||||
| properties.copyToXmlAttributes (*xml); | properties.copyToXmlAttributes (*xml); | ||||
| for (int i = 0; i < children.size(); ++i) | |||||
| xml->addChildElement (children.getObjectPointerUnchecked(i)->createXml()); | |||||
| // (NB: it's faster to add nodes to XML elements in reverse order) | |||||
| for (int i = children.size(); --i >= 0;) | |||||
| xml->prependChildElement (children.getObjectPointerUnchecked(i)->createXml()); | |||||
| return xml; | return xml; | ||||
| } | } | ||||
| @@ -1840,8 +1840,8 @@ XmlElement* TreeViewItem::getOpennessState (const bool canReturnNull) const | |||||
| e = new XmlElement ("OPEN"); | e = new XmlElement ("OPEN"); | ||||
| for (int i = 0; i < subItems.size(); ++i) | |||||
| e->addChildElement (subItems.getUnchecked(i)->getOpennessState (true)); | |||||
| for (int i = subItems.size(); --i >= 0;) | |||||
| e->prependChildElement (subItems.getUnchecked(i)->getOpennessState (true)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||