diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj
index ccef91fca7..f8eea8800c 100644
--- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj
@@ -490,6 +490,7 @@
F77C9170829579FABA5679AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DynamicObject.cpp; path = ../../src/containers/juce_DynamicObject.cpp; sourceTree = SOURCE_ROOT; };
34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; };
7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; };
+ 9289A1E6B141F24C57FF0927 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LinkedListPointer.h; path = ../../src/containers/juce_LinkedListPointer.h; sourceTree = SOURCE_ROOT; };
70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; };
BB4A73064B0FC74ECCA19116 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NamedValueSet.h; path = ../../src/containers/juce_NamedValueSet.h; sourceTree = SOURCE_ROOT; };
C1913C90ED7BE51E823887CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_OwnedArray.h; path = ../../src/containers/juce_OwnedArray.h; sourceTree = SOURCE_ROOT; };
@@ -1217,6 +1218,7 @@
F77C9170829579FABA5679AD,
34C402EF9ADCAD34FB657D43,
7DA9AC75A4D9227C8FC4B2F7,
+ 9289A1E6B141F24C57FF0927,
70E5409425A76782B6188B31,
BB4A73064B0FC74ECCA19116,
C1913C90ED7BE51E823887CD,
diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj
index 7a33854fd7..0a16d06e48 100644
--- a/Builds/VisualStudio2005/Juce.vcproj
+++ b/Builds/VisualStudio2005/Juce.vcproj
@@ -353,6 +353,7 @@
+
diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj
index 98880a41df..2cd35bb5d8 100644
--- a/Builds/VisualStudio2008/Juce.vcproj
+++ b/Builds/VisualStudio2008/Juce.vcproj
@@ -353,6 +353,7 @@
+
diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj
index 0a7c4c4aa5..bc877c0ad3 100644
--- a/Builds/VisualStudio2008_DLL/Juce.vcproj
+++ b/Builds/VisualStudio2008_DLL/Juce.vcproj
@@ -355,6 +355,7 @@
+
diff --git a/Builds/VisualStudio2010/Juce.vcxproj b/Builds/VisualStudio2010/Juce.vcxproj
index 0575408dbf..a131ef48d7 100644
--- a/Builds/VisualStudio2010/Juce.vcxproj
+++ b/Builds/VisualStudio2010/Juce.vcxproj
@@ -509,6 +509,7 @@
+
diff --git a/Builds/VisualStudio2010/Juce.vcxproj.filters b/Builds/VisualStudio2010/Juce.vcxproj.filters
index 9ce5385872..7e199964b5 100644
--- a/Builds/VisualStudio2010/Juce.vcxproj.filters
+++ b/Builds/VisualStudio2010/Juce.vcxproj.filters
@@ -1455,6 +1455,9 @@
Juce\Source\containers
+
+ Juce\Source\containers
+
Juce\Source\containers
diff --git a/Builds/iPhone/Juce.xcodeproj/project.pbxproj b/Builds/iPhone/Juce.xcodeproj/project.pbxproj
index 5c7f217411..2e47dd4fb0 100644
--- a/Builds/iPhone/Juce.xcodeproj/project.pbxproj
+++ b/Builds/iPhone/Juce.xcodeproj/project.pbxproj
@@ -490,6 +490,7 @@
F77C9170829579FABA5679AD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_DynamicObject.cpp; path = ../../src/containers/juce_DynamicObject.cpp; sourceTree = SOURCE_ROOT; };
34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; };
7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; };
+ 9289A1E6B141F24C57FF0927 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_LinkedListPointer.h; path = ../../src/containers/juce_LinkedListPointer.h; sourceTree = SOURCE_ROOT; };
70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; };
BB4A73064B0FC74ECCA19116 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_NamedValueSet.h; path = ../../src/containers/juce_NamedValueSet.h; sourceTree = SOURCE_ROOT; };
C1913C90ED7BE51E823887CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_OwnedArray.h; path = ../../src/containers/juce_OwnedArray.h; sourceTree = SOURCE_ROOT; };
@@ -1217,6 +1218,7 @@
F77C9170829579FABA5679AD,
34C402EF9ADCAD34FB657D43,
7DA9AC75A4D9227C8FC4B2F7,
+ 9289A1E6B141F24C57FF0927,
70E5409425A76782B6188B31,
BB4A73064B0FC74ECCA19116,
C1913C90ED7BE51E823887CD,
diff --git a/Juce.jucer b/Juce.jucer
index 9e942b250e..056b57a198 100644
--- a/Juce.jucer
+++ b/Juce.jucer
@@ -365,6 +365,8 @@
file="src/containers/juce_DynamicObject.h"/>
+
::Appender attributeAppender (node->attributes);
// look for attributes
for (;;)
@@ -15107,14 +15107,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
String::empty);
readQuotedString (newAtt->value);
-
- if (lastAttribute == 0)
- node->attributes = newAtt;
- else
- lastAttribute->next = newAtt;
-
- lastAttribute = newAtt;
-
+ attributeAppender.append (newAtt);
continue;
}
}
@@ -15135,7 +15128,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
void XmlDocument::readChildElements (XmlElement* parent)
{
- XmlElement* lastChildNode = 0;
+ LinkedListPointer::Appender childAppender (parent->firstChildElement);
for (;;)
{
@@ -15191,14 +15184,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
++len;
}
- XmlElement* const e = XmlElement::createTextElement (String (inputStart, len));
-
- if (lastChildNode != 0)
- lastChildNode->nextElement = e;
- else
- parent->addChildElement (e);
-
- lastChildNode = e;
+ childAppender.append (XmlElement::createTextElement (String (inputStart, len)));
}
else
{
@@ -15206,18 +15192,9 @@ void XmlDocument::readChildElements (XmlElement* parent)
XmlElement* const n = readNextElement (true);
if (n != 0)
- {
- if (lastChildNode == 0)
- parent->addChildElement (n);
- else
- lastChildNode->nextElement = n;
-
- lastChildNode = n;
- }
+ childAppender.append (n);
else
- {
return;
- }
}
}
else // must be a character block
@@ -15259,12 +15236,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
if (n == 0)
break;
- if (lastChildNode == 0)
- parent->addChildElement (n);
- else
- lastChildNode->nextElement = n;
-
- lastChildNode = n;
+ childAppender.append (n);
}
input = oldInput;
@@ -15305,14 +15277,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
if ((! ignoreEmptyTextElements) || textElementContent.containsNonWhitespaceChars())
{
- XmlElement* const textElement = XmlElement::createTextElement (textElementContent);
-
- if (lastChildNode != 0)
- lastChildNode->nextElement = textElement;
- else
- parent->addChildElement (textElement);
-
- lastChildNode = textElement;
+ childAppender.append (XmlElement::createTextElement (textElementContent));
}
}
}
@@ -15540,18 +15505,16 @@ const String XmlDocument::getParameterEntity (const String& entity)
{
for (int i = 0; i < tokenisedDTD.size(); ++i)
{
- if (tokenisedDTD[i] == entity)
+ if (tokenisedDTD[i] == entity
+ && tokenisedDTD [i - 1] == "%"
+ && tokenisedDTD [i - 2].equalsIgnoreCase (""));
+ const String ent (tokenisedDTD [i + 1].trimCharactersAtEnd (">"));
- if (ent.equalsIgnoreCase ("system"))
- return getFileContents (tokenisedDTD [i + 2].trimCharactersAtEnd (">"));
- else
- return ent.trim().unquoted();
- }
+ if (ent.equalsIgnoreCase ("system"))
+ return getFileContents (tokenisedDTD [i + 2].trimCharactersAtEnd (">"));
+ else
+ return ent.trim().unquoted();
}
}
@@ -15567,15 +15530,13 @@ BEGIN_JUCE_NAMESPACE
XmlElement::XmlAttributeNode::XmlAttributeNode (const XmlAttributeNode& other) throw()
: name (other.name),
- value (other.value),
- next (0)
+ value (other.value)
{
}
XmlElement::XmlAttributeNode::XmlAttributeNode (const String& name_, const String& value_) throw()
: name (name_),
- value (value_),
- next (0)
+ value (value_)
{
#if JUCE_DEBUG
// this checks whether the attribute name string contains any illegals characters..
@@ -15590,10 +15551,7 @@ inline bool XmlElement::XmlAttributeNode::hasName (const String& nameToMatch) co
}
XmlElement::XmlElement (const String& tagName_) throw()
- : tagName (tagName_),
- firstChildElement (0),
- nextElement (0),
- attributes (0)
+ : tagName (tagName_)
{
// the tag name mustn't be empty, or it'll look like a text element!
jassert (tagName_.containsNonWhitespaceChars())
@@ -15603,17 +15561,11 @@ XmlElement::XmlElement (const String& tagName_) throw()
}
XmlElement::XmlElement (int /*dummy*/) throw()
- : firstChildElement (0),
- nextElement (0),
- attributes (0)
{
}
XmlElement::XmlElement (const XmlElement& other)
- : tagName (other.tagName),
- firstChildElement (0),
- nextElement (0),
- attributes (0)
+ : tagName (other.tagName)
{
copyChildrenAndAttributesFrom (other);
}
@@ -15635,58 +15587,17 @@ XmlElement& XmlElement::operator= (const XmlElement& other)
void XmlElement::copyChildrenAndAttributesFrom (const XmlElement& other)
{
- XmlElement* child = other.firstChildElement;
- XmlElement* lastChild = 0;
+ jassert (firstChildElement.get() == 0);
+ firstChildElement.addCopyOfList (other.firstChildElement);
- while (child != 0)
- {
- XmlElement* const copiedChild = new XmlElement (*child);
-
- if (lastChild != 0)
- lastChild->nextElement = copiedChild;
- else
- firstChildElement = copiedChild;
-
- lastChild = copiedChild;
- child = child->nextElement;
- }
-
- const XmlAttributeNode* att = other.attributes;
- XmlAttributeNode* lastAtt = 0;
-
- while (att != 0)
- {
- XmlAttributeNode* const newAtt = new XmlAttributeNode (*att);
-
- if (lastAtt != 0)
- lastAtt->next = newAtt;
- else
- attributes = newAtt;
-
- lastAtt = newAtt;
- att = att->next;
- }
+ jassert (attributes.get() == 0);
+ attributes.addCopyOfList (other.attributes);
}
XmlElement::~XmlElement() throw()
{
- XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- XmlElement* const nextChild = child->nextElement;
- delete child;
- child = nextChild;
- }
-
- XmlAttributeNode* att = attributes;
-
- while (att != 0)
- {
- XmlAttributeNode* const nextAtt = att->next;
- delete att;
- att = nextAtt;
- }
+ firstChildElement.deleteAll();
+ attributes.deleteAll();
}
namespace XmlOutputFunctions
@@ -15807,7 +15718,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream,
const int attIndent = indentationLevel + tagName.length() + 1;
int lineLen = 0;
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
{
if (lineLen > lineWrapLength && indentationLevel >= 0)
{
@@ -15850,7 +15761,7 @@ void XmlElement::writeElementAsText (OutputStream& outputStream,
lastWasTextNode = false;
}
- child = child->nextElement;
+ child = child->getNextElement();
}
if (indentationLevel >= 0 && ! lastWasTextNode)
@@ -15965,57 +15876,34 @@ bool XmlElement::hasTagName (const String& tagNameWanted) const throw()
XmlElement* XmlElement::getNextElementWithTagName (const String& requiredTagName) const
{
- XmlElement* e = nextElement;
+ XmlElement* e = nextListItem;
while (e != 0 && ! e->hasTagName (requiredTagName))
- e = e->nextElement;
+ e = e->nextListItem;
return e;
}
int XmlElement::getNumAttributes() const throw()
{
- int count = 0;
-
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
- ++count;
-
- return count;
+ return attributes.size();
}
const String& XmlElement::getAttributeName (const int index) const throw()
{
- int count = 0;
-
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
- {
- if (count == index)
- return att->name;
-
- ++count;
- }
-
- return String::empty;
+ const XmlAttributeNode* const att = attributes [index];
+ return att != 0 ? att->name : String::empty;
}
const String& XmlElement::getAttributeValue (const int index) const throw()
{
- int count = 0;
-
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
- {
- if (count == index)
- return att->value;
-
- ++count;
- }
-
- return String::empty;
+ const XmlAttributeNode* const att = attributes [index];
+ return att != 0 ? att->value : String::empty;
}
bool XmlElement::hasAttribute (const String& attributeName) const throw()
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return true;
@@ -16024,7 +15912,7 @@ bool XmlElement::hasAttribute (const String& attributeName) const throw()
const String& XmlElement::getStringAttribute (const String& attributeName) const throw()
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value;
@@ -16033,7 +15921,7 @@ const String& XmlElement::getStringAttribute (const String& attributeName) const
const String XmlElement::getStringAttribute (const String& attributeName, const String& defaultReturnValue) const
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value;
@@ -16042,7 +15930,7 @@ const String XmlElement::getStringAttribute (const String& attributeName, const
int XmlElement::getIntAttribute (const String& attributeName, const int defaultReturnValue) const
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value.getIntValue();
@@ -16051,7 +15939,7 @@ int XmlElement::getIntAttribute (const String& attributeName, const int defaultR
double XmlElement::getDoubleAttribute (const String& attributeName, const double defaultReturnValue) const
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return att->value.getDoubleValue();
@@ -16060,7 +15948,7 @@ double XmlElement::getDoubleAttribute (const String& attributeName, const double
bool XmlElement::getBoolAttribute (const String& attributeName, const bool defaultReturnValue) const
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
{
if (att->hasName (attributeName))
{
@@ -16084,7 +15972,7 @@ bool XmlElement::compareAttribute (const String& attributeName,
const String& stringToCompareAgainst,
const bool ignoreCase) const throw()
{
- for (const XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ for (const XmlAttributeNode* att = attributes; att != 0; att = att->nextListItem)
if (att->hasName (attributeName))
return ignoreCase ? att->value.equalsIgnoreCase (stringToCompareAgainst)
: att->value == stringToCompareAgainst;
@@ -16109,13 +15997,13 @@ void XmlElement::setAttribute (const String& attributeName, const String& value)
att->value = value;
break;
}
- else if (att->next == 0)
+ else if (att->nextListItem == 0)
{
- att->next = new XmlAttributeNode (attributeName, value);
+ att->nextListItem = new XmlAttributeNode (attributeName, value);
break;
}
- att = att->next;
+ att = att->nextListItem;
}
}
}
@@ -16132,61 +16020,33 @@ void XmlElement::setAttribute (const String& attributeName, const double number)
void XmlElement::removeAttribute (const String& attributeName) throw()
{
- XmlAttributeNode* lastAtt = 0;
+ LinkedListPointer* att = &attributes;
- for (XmlAttributeNode* att = attributes; att != 0; att = att->next)
+ while (att->get() != 0)
{
- if (att->hasName (attributeName))
+ if (att->get()->hasName (attributeName))
{
- if (lastAtt == 0)
- attributes = att->next;
- else
- lastAtt->next = att->next;
-
- delete att;
+ delete att->removeNext();
break;
}
- lastAtt = att;
+ att = &(att->get()->nextListItem);
}
}
void XmlElement::removeAllAttributes() throw()
{
- while (attributes != 0)
- {
- XmlAttributeNode* const nextAtt = attributes->next;
- delete attributes;
- attributes = nextAtt;
- }
+ attributes.deleteAll();
}
int XmlElement::getNumChildElements() const throw()
{
- int count = 0;
- const XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- ++count;
- child = child->nextElement;
- }
-
- return count;
+ return firstChildElement.size();
}
XmlElement* XmlElement::getChildElement (const int index) const throw()
{
- int count = 0;
- XmlElement* child = firstChildElement;
-
- while (child != 0 && count < index)
- {
- child = child->nextElement;
- ++count;
- }
-
- return child;
+ return firstChildElement [index].get();
}
XmlElement* XmlElement::getChildByName (const String& childName) const throw()
@@ -16198,7 +16058,7 @@ XmlElement* XmlElement::getChildByName (const String& childName) const throw()
if (child->hasTagName (childName))
break;
- child = child->nextElement;
+ child = child->nextListItem;
}
return child;
@@ -16207,25 +16067,7 @@ XmlElement* XmlElement::getChildByName (const String& childName) const throw()
void XmlElement::addChildElement (XmlElement* const newNode) throw()
{
if (newNode != 0)
- {
- if (firstChildElement == 0)
- {
- firstChildElement = newNode;
- }
- else
- {
- XmlElement* child = firstChildElement;
-
- while (child->nextElement != 0)
- child = child->nextElement;
-
- child->nextElement = newNode;
-
- // if this is non-zero, then something's probably
- // gone wrong..
- jassert (newNode->nextElement == 0);
- }
- }
+ firstChildElement.append (newNode);
}
void XmlElement::insertChildElement (XmlElement* const newNode,
@@ -16234,32 +16076,7 @@ void XmlElement::insertChildElement (XmlElement* const newNode,
if (newNode != 0)
{
removeChildElement (newNode, false);
-
- if (indexToInsertAt == 0)
- {
- newNode->nextElement = firstChildElement;
- firstChildElement = newNode;
- }
- else
- {
- if (firstChildElement == 0)
- {
- firstChildElement = newNode;
- }
- else
- {
- if (indexToInsertAt < 0)
- indexToInsertAt = std::numeric_limits::max();
-
- XmlElement* child = firstChildElement;
-
- while (child->nextElement != 0 && --indexToInsertAt > 0)
- child = child->nextElement;
-
- newNode->nextElement = child->nextElement;
- child->nextElement = newNode;
- }
- }
+ firstChildElement.insertAtIndex (indexToInsertAt, newNode);
}
}
@@ -16275,30 +16092,14 @@ bool XmlElement::replaceChildElement (XmlElement* const currentChildElement,
{
if (newNode != 0)
{
- XmlElement* child = firstChildElement;
- XmlElement* previousNode = 0;
+ LinkedListPointer* const p = firstChildElement.findPointerTo (currentChildElement);
- while (child != 0)
+ if (p != 0)
{
- if (child == currentChildElement)
- {
- if (child != newNode)
- {
- if (previousNode == 0)
- firstChildElement = newNode;
- else
- previousNode->nextElement = newNode;
+ if (currentChildElement != newNode)
+ delete p->replaceNext (newNode);
- newNode->nextElement = child->nextElement;
-
- delete child;
- }
-
- return true;
- }
-
- previousNode = child;
- child = child->nextElement;
+ return true;
}
}
@@ -16310,33 +16111,7 @@ void XmlElement::removeChildElement (XmlElement* const childToRemove,
{
if (childToRemove != 0)
{
- if (firstChildElement == childToRemove)
- {
- firstChildElement = childToRemove->nextElement;
- childToRemove->nextElement = 0;
- }
- else
- {
- XmlElement* child = firstChildElement;
- XmlElement* last = 0;
-
- while (child != 0)
- {
- if (child == childToRemove)
- {
- if (last == 0)
- firstChildElement = child->nextElement;
- else
- last->nextElement = child->nextElement;
-
- childToRemove->nextElement = 0;
- break;
- }
-
- last = child;
- child = child->nextElement;
- }
- }
+ firstChildElement.remove (childToRemove);
if (shouldDeleteTheChild)
delete childToRemove;
@@ -16361,7 +16136,7 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
if (! other->compareAttribute (att->name, att->value))
return false;
- att = att->next;
+ att = att->nextListItem;
++totalAtts;
}
@@ -16389,8 +16164,8 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
return false;
}
- thisAtt = thisAtt->next;
- otherAtt = otherAtt->next;
+ thisAtt = thisAtt->nextListItem;
+ otherAtt = otherAtt->nextListItem;
}
}
@@ -16410,8 +16185,8 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
if (! thisChild->isEquivalentTo (otherChild, ignoreOrderOfAttributes))
return false;
- thisChild = thisChild->nextElement;
- otherChild = otherChild->nextElement;
+ thisChild = thisChild->nextListItem;
+ otherChild = otherChild->nextListItem;
}
}
@@ -16420,12 +16195,7 @@ bool XmlElement::isEquivalentTo (const XmlElement* const other,
void XmlElement::deleteAllChildElements() throw()
{
- while (firstChildElement != 0)
- {
- XmlElement* const nextChild = firstChildElement->nextElement;
- delete firstChildElement;
- firstChildElement = nextChild;
- }
+ firstChildElement.deleteAll();
}
void XmlElement::deleteAllChildElementsWithTagName (const String& name) throw()
@@ -16434,32 +16204,18 @@ void XmlElement::deleteAllChildElementsWithTagName (const String& name) throw()
while (child != 0)
{
+ XmlElement* const nextChild = child->nextListItem;
+
if (child->hasTagName (name))
- {
- XmlElement* const nextChild = child->nextElement;
removeChildElement (child, true);
- child = nextChild;
- }
- else
- {
- child = child->nextElement;
- }
+
+ child = nextChild;
}
}
bool XmlElement::containsChildElement (const XmlElement* const possibleChild) const throw()
{
- const XmlElement* child = firstChildElement;
-
- while (child != 0)
- {
- if (child == possibleChild)
- return true;
-
- child = child->nextElement;
- }
-
- return false;
+ return firstChildElement.contains (possibleChild);
}
XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLookFor) throw()
@@ -16479,7 +16235,7 @@ XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLo
if (found != 0)
return found;
- child = child->nextElement;
+ child = child->nextListItem;
}
return 0;
@@ -16487,13 +16243,7 @@ XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLo
void XmlElement::getChildElementsAsArray (XmlElement** elems) const throw()
{
- XmlElement* e = firstChildElement;
-
- while (e != 0)
- {
- *elems++ = e;
- e = e->nextElement;
- }
+ firstChildElement.copyToArray (elems);
}
void XmlElement::reorderChildElements (XmlElement** const elems, const int num) throw()
@@ -16502,11 +16252,11 @@ void XmlElement::reorderChildElements (XmlElement** const elems, const int num)
for (int i = 1; i < num; ++i)
{
- e->nextElement = elems[i];
- e = e->nextElement;
+ e->nextListItem = elems[i];
+ e = e->nextListItem;
}
- e->nextElement = 0;
+ e->nextListItem = 0;
}
bool XmlElement::isTextElement() const throw()
@@ -16545,7 +16295,7 @@ const String XmlElement::getAllSubText() const
while (child != 0)
{
concatenator.append (child->getAllSubText());
- child = child->nextElement;
+ child = child->nextListItem;
}
return result;
@@ -16580,7 +16330,7 @@ void XmlElement::deleteAllTextElements() throw()
while (child != 0)
{
- XmlElement* const next = child->nextElement;
+ XmlElement* const next = child->nextListItem;
if (child->isTextElement())
removeChildElement (child, true);
@@ -40725,33 +40475,40 @@ void Component::setBounds (const int x, const int y, int w, int h)
void Component::sendMovedResizedMessages (const bool wasMoved, const bool wasResized)
{
- JUCE_TRY
+ BailOutChecker checker (this);
+
+ if (wasMoved)
{
- if (wasMoved)
- moved();
+ moved();
- if (wasResized)
- {
- resized();
-
- for (int i = childComponentList_.size(); --i >= 0;)
- {
- childComponentList_.getUnchecked(i)->parentSizeChanged();
-
- i = jmin (i, childComponentList_.size());
- }
- }
-
- BailOutChecker checker (this);
-
- if (parentComponent_ != 0)
- parentComponent_->childBoundsChanged (this);
-
- if (! checker.shouldBailOut())
- componentListeners.callChecked (checker, &ComponentListener::componentMovedOrResized,
- *this, wasMoved, wasResized);
+ if (checker.shouldBailOut())
+ return;
}
- JUCE_CATCH_EXCEPTION
+
+ if (wasResized)
+ {
+ resized();
+
+ if (checker.shouldBailOut())
+ return;
+
+ for (int i = childComponentList_.size(); --i >= 0;)
+ {
+ childComponentList_.getUnchecked(i)->parentSizeChanged();
+
+ if (checker.shouldBailOut())
+ return;
+
+ i = jmin (i, childComponentList_.size());
+ }
+ }
+
+ if (parentComponent_ != 0)
+ parentComponent_->childBoundsChanged (this);
+
+ if (! checker.shouldBailOut())
+ componentListeners.callChecked (checker, &ComponentListener::componentMovedOrResized,
+ *this, wasMoved, wasResized);
}
void Component::setSize (const int w, const int h)
@@ -42242,12 +41999,15 @@ void Component::focusGained (FocusChangeType)
void Component::internalFocusGain (const FocusChangeType cause)
{
- WeakReference safePointer (this);
+ internalFocusGain (cause, WeakReference (this));
+}
+void Component::internalFocusGain (const FocusChangeType cause, const WeakReference& safePointer)
+{
focusGained (cause);
if (safePointer != 0)
- internalChildFocusChange (cause);
+ internalChildFocusChange (cause, safePointer);
}
void Component::focusLost (FocusChangeType)
@@ -42262,7 +42022,7 @@ void Component::internalFocusLoss (const FocusChangeType cause)
focusLost (focusChangedDirectly);
if (safePointer != 0)
- internalChildFocusChange (cause);
+ internalChildFocusChange (cause, safePointer);
}
void Component::focusOfChildComponentChanged (FocusChangeType /*cause*/)
@@ -42270,7 +42030,7 @@ void Component::focusOfChildComponentChanged (FocusChangeType /*cause*/)
// base class does nothing
}
-void Component::internalChildFocusChange (FocusChangeType cause)
+void Component::internalChildFocusChange (FocusChangeType cause, const WeakReference& safePointer)
{
const bool childIsNowFocused = hasKeyboardFocus (true);
@@ -42278,7 +42038,6 @@ void Component::internalChildFocusChange (FocusChangeType cause)
{
flags.childCompFocusedFlag = childIsNowFocused;
- WeakReference safePointer (this);
focusOfChildComponentChanged (cause);
if (safePointer == 0)
@@ -42286,7 +42045,7 @@ void Component::internalChildFocusChange (FocusChangeType cause)
}
if (parentComponent_ != 0)
- parentComponent_->internalChildFocusChange (cause);
+ parentComponent_->internalChildFocusChange (cause, WeakReference (parentComponent_));
}
bool Component::isEnabled() const throw()
@@ -42390,54 +42149,32 @@ void Component::takeKeyboardFocus (const FocusChangeType cause)
// give the focus to this component
if (currentlyFocusedComponent != this)
{
- JUCE_TRY
+ // get the focus onto our desktop window
+ ComponentPeer* const peer = getPeer();
+
+ if (peer != 0)
{
- // get the focus onto our desktop window
- ComponentPeer* const peer = getPeer();
+ WeakReference safePointer (this);
- if (peer != 0)
+ peer->grabFocus();
+
+ if (peer->isFocused() && currentlyFocusedComponent != this)
{
- WeakReference safePointer (this);
+ WeakReference componentLosingFocus (currentlyFocusedComponent);
- peer->grabFocus();
+ currentlyFocusedComponent = this;
- if (peer->isFocused() && currentlyFocusedComponent != this)
- {
- WeakReference componentLosingFocus (currentlyFocusedComponent);
+ Desktop::getInstance().triggerFocusCallback();
- currentlyFocusedComponent = this;
+ // call this after setting currentlyFocusedComponent so that the one that's
+ // losing it has a chance to see where focus is going
+ if (componentLosingFocus != 0)
+ componentLosingFocus->internalFocusLoss (cause);
- Desktop::getInstance().triggerFocusCallback();
-
- // call this after setting currentlyFocusedComponent so that the one that's
- // losing it has a chance to see where focus is going
- if (componentLosingFocus != 0)
- componentLosingFocus->internalFocusLoss (cause);
-
- if (currentlyFocusedComponent == this)
- {
- focusGained (cause);
-
- if (safePointer != 0)
- internalChildFocusChange (cause);
- }
- }
+ if (currentlyFocusedComponent == this)
+ internalFocusGain (cause, safePointer);
}
}
-#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
- catch (const std::exception& e)
- {
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__);
- }
- catch (...)
- {
- currentlyFocusedComponent = 0;
- Desktop::getInstance().triggerFocusCallback();
- JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__);
- }
-#endif
}
}
@@ -43485,9 +43222,10 @@ void Button::setToggleState (const bool shouldBeOn,
lastToggleState = shouldBeOn;
repaint();
+ WeakReference deletionWatcher (this);
+
if (sendChangeNotification)
{
- WeakReference deletionWatcher (this);
sendClickMessage (ModifierKeys());
if (deletionWatcher == 0)
@@ -43495,7 +43233,14 @@ void Button::setToggleState (const bool shouldBeOn,
}
if (lastToggleState)
+ {
turnOffOtherButtonsInGroup (sendChangeNotification);
+
+ if (deletionWatcher == 0)
+ return;
+ }
+
+ sendStateMessage();
}
}
@@ -77835,11 +77580,11 @@ DocumentWindow::DocumentWindow (const String& title,
titleBarHeight (26),
menuBarHeight (24),
requiredButtons (requiredButtons_),
-#if JUCE_MAC
+ #if JUCE_MAC
positionTitleBarButtonsOnLeft (true),
-#else
+ #else
positionTitleBarButtonsOnLeft (false),
-#endif
+ #endif
drawTitleTextCentred (true),
menuBarModel (0)
{
@@ -77905,28 +77650,39 @@ void DocumentWindow::setTitleBarTextCentred (const bool textShouldBeCentred)
repaintTitleBar();
}
-void DocumentWindow::setMenuBar (MenuBarModel* menuBarModel_,
- const int menuBarHeight_)
+void DocumentWindow::setMenuBar (MenuBarModel* newMenuBarModel, const int newMenuBarHeight)
{
- if (menuBarModel != menuBarModel_)
+ if (menuBarModel != newMenuBarModel)
{
menuBar = 0;
- menuBarModel = menuBarModel_;
- menuBarHeight = (menuBarHeight_ > 0) ? menuBarHeight_
+ menuBarModel = newMenuBarModel;
+ menuBarHeight = newMenuBarHeight > 0 ? newMenuBarHeight
: getLookAndFeel().getDefaultMenuBarHeight();
if (menuBarModel != 0)
- {
- // (call the Component method directly to avoid the assertion in ResizableWindow)
- Component::addAndMakeVisible (menuBar = new MenuBarComponent (menuBarModel));
- menuBar->setEnabled (isActiveWindow());
- }
+ setMenuBarComponent (new MenuBarComponent (menuBarModel));
resized();
}
}
+Component* DocumentWindow::getMenuBarComponent() const throw()
+{
+ return menuBar;
+}
+
+void DocumentWindow::setMenuBarComponent (Component* newMenuBarComponent)
+{
+ // (call the Component method directly to avoid the assertion in ResizableWindow)
+ Component::addAndMakeVisible (menuBar = newMenuBarComponent);
+
+ if (menuBar != 0)
+ menuBar->setEnabled (isActiveWindow());
+
+ resized();
+}
+
void DocumentWindow::closeButtonPressed()
{
/* If you've got a close button, you have to override this method to get
@@ -78033,8 +77789,8 @@ const BorderSize DocumentWindow::getContentComponentBorder()
BorderSize border (getBorderThickness());
border.setTop (border.getTop()
- + (isUsingNativeTitleBar() ? 0 : titleBarHeight)
- + (menuBar != 0 ? menuBarHeight : 0));
+ + (isUsingNativeTitleBar() ? 0 : titleBarHeight)
+ + (menuBar != 0 ? menuBarHeight : 0));
return border;
}
@@ -78053,20 +77809,9 @@ const Rectangle DocumentWindow::getTitleBarArea()
getTitleBarHeight());
}
-Button* DocumentWindow::getCloseButton() const throw()
-{
- return titleBarButtons[2];
-}
-
-Button* DocumentWindow::getMinimiseButton() const throw()
-{
- return titleBarButtons[0];
-}
-
-Button* DocumentWindow::getMaximiseButton() const throw()
-{
- return titleBarButtons[1];
-}
+Button* DocumentWindow::getCloseButton() const throw() { return titleBarButtons[2]; }
+Button* DocumentWindow::getMinimiseButton() const throw() { return titleBarButtons[0]; }
+Button* DocumentWindow::getMaximiseButton() const throw() { return titleBarButtons[1]; }
int DocumentWindow::getDesktopWindowStyleFlags() const
{
@@ -78092,14 +77837,16 @@ void DocumentWindow::lookAndFeelChanged()
if (! isUsingNativeTitleBar())
{
- titleBarButtons[0] = ((requiredButtons & minimiseButton) != 0)
- ? getLookAndFeel().createDocumentWindowButton (minimiseButton) : 0;
+ LookAndFeel& lf = getLookAndFeel();
- titleBarButtons[1] = ((requiredButtons & maximiseButton) != 0)
- ? getLookAndFeel().createDocumentWindowButton (maximiseButton) : 0;
+ if ((requiredButtons & minimiseButton) != 0)
+ titleBarButtons[0] = lf.createDocumentWindowButton (minimiseButton);
- titleBarButtons[2] = ((requiredButtons & closeButton) != 0)
- ? getLookAndFeel().createDocumentWindowButton (closeButton) : 0;
+ if ((requiredButtons & maximiseButton) != 0)
+ titleBarButtons[1] = lf.createDocumentWindowButton (maximiseButton);
+
+ if ((requiredButtons & closeButton) != 0)
+ titleBarButtons[2] = lf.createDocumentWindowButton (closeButton);
for (i = 0; i < 3; ++i)
{
@@ -78118,11 +77865,11 @@ void DocumentWindow::lookAndFeelChanged()
if (getCloseButton() != 0)
{
-#if JUCE_MAC
+ #if JUCE_MAC
getCloseButton()->addShortcut (KeyPress ('w', ModifierKeys::commandModifier, 0));
-#else
+ #else
getCloseButton()->addShortcut (KeyPress (KeyPress::F4Key, ModifierKeys::altModifier, 0));
-#endif
+ #endif
}
}
@@ -85925,6 +85672,7 @@ void DrawableShape::paint (Graphics& g)
void DrawableShape::pathChanged()
{
+ rebuildPath (path);
strokeChanged();
}
@@ -86986,13 +86734,18 @@ void DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider*
const RelativeParallelogram newBounds (controller.getBoundingBox());
- if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage)
+ if (bounds != newBounds || newOpacity != opacity
+ || overlayColour != newOverlayColour || image != newImage)
{
repaint();
opacity = newOpacity;
overlayColour = newOverlayColour;
bounds = newBounds;
- setImage (newImage);
+
+ if (image != newImage)
+ setImage (newImage);
+ else
+ refreshTransformFromBounds();
}
}
@@ -241780,6 +241533,7 @@ public:
isDragging (false),
isMouseOver (false),
hasCreatedCaret (false),
+ constrainerIsResizing (false),
currentWindowIcon (0),
dropTarget (0),
updateLayeredWindowAlpha (255),
@@ -242311,7 +242065,7 @@ private:
#if JUCE_DIRECT2D
ScopedPointer direct2DContext;
#endif
- bool fullScreen, isDragging, isMouseOver, hasCreatedCaret;
+ bool fullScreen, isDragging, isMouseOver, hasCreatedCaret, constrainerIsResizing;
BorderSize windowBorder;
HICON currentWindowIcon;
ScopedPointer taskBarIcon;
@@ -242816,6 +242570,14 @@ private:
void doCaptureChanged()
{
+ if (constrainerIsResizing)
+ {
+ if (constrainer != 0)
+ constrainer->resizeEnd();
+
+ constrainerIsResizing = false;
+ }
+
if (isDragging)
doMouseUp (getCurrentMousePos(), (WPARAM) 0);
}
@@ -243037,9 +242799,15 @@ private:
return false;
}
+ bool isConstrainedNativeWindow() const
+ {
+ return constrainer != 0
+ && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable);
+ }
+
LRESULT handleSizeConstraining (RECT* const r, const WPARAM wParam)
{
- if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
+ if (isConstrainedNativeWindow())
{
Rectangle pos (r->left, r->top, r->right - r->left, r->bottom - r->top);
@@ -243060,7 +242828,7 @@ private:
LRESULT handlePositionChanging (WINDOWPOS* const wp)
{
- if (constrainer != 0 && (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable))
+ if (isConstrainedNativeWindow())
{
if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)
&& ! Component::isMouseButtonDownAnywhere())
@@ -243545,6 +243313,32 @@ private:
break;
case WM_NCLBUTTONDOWN:
+ if (! sendInputAttemptWhenModalMessage())
+ {
+ switch (wParam)
+ {
+ case HTBOTTOM:
+ case HTBOTTOMLEFT:
+ case HTBOTTOMRIGHT:
+ case HTGROWBOX:
+ case HTLEFT:
+ case HTRIGHT:
+ case HTTOP:
+ case HTTOPLEFT:
+ case HTTOPRIGHT:
+ if (isConstrainedNativeWindow())
+ {
+ constrainerIsResizing = true;
+ constrainer->resizeStart();
+ }
+ break;
+
+ default:
+ break;
+ };
+ }
+ break;
+
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
sendInputAttemptWhenModalMessage();
@@ -261025,7 +260819,7 @@ void* juce_load_jack_function (const char* const name)
if (fn) (*fn)arguments; \
}
-JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status), (client_name, options, status));
+JUCE_DECL_JACK_FUNCTION (jack_client_t*, jack_client_open, (const char* client_name, jack_options_t options, jack_status_t* status, ...), (client_name, options, status));
JUCE_DECL_JACK_FUNCTION (int, jack_client_close, (jack_client_t *client), (client));
JUCE_DECL_JACK_FUNCTION (int, jack_activate, (jack_client_t* client), (client));
JUCE_DECL_JACK_FUNCTION (int, jack_deactivate, (jack_client_t* client), (client));
diff --git a/juce_amalgamated.h b/juce_amalgamated.h
index e119ed66a9..5cb26e41ef 100644
--- a/juce_amalgamated.h
+++ b/juce_amalgamated.h
@@ -64,7 +64,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52
-#define JUCE_BUILDNUMBER 110
+#define JUCE_BUILDNUMBER 111
/** Current Juce version number.
@@ -6624,6 +6624,325 @@ private:
#endif
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
+#endif
+#ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
+
+/*** Start of inlined file: juce_LinkedListPointer.h ***/
+#ifndef __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
+#define __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
+
+/**
+ Helps to manipulate singly-linked lists of objects.
+
+ For objects that are designed to contain a pointer to the subsequent item in the
+ list, this class contains methods to deal with the list. To use it, the ObjectType
+ class that it points to must contain a LinkedListPointer called nextListItem, e.g.
+
+ @code
+ struct MyObject
+ {
+ int x, y, z;
+
+ // A linkable object must contain a member with this name and type, which must be
+ // accessible by the LinkedListPointer class. (This doesn't mean it has to be public -
+ // you could make your class a friend of a LinkedListPointer instead).
+ LinkedListPointer nextListItem;
+ };
+
+ LinkedListPointer myList;
+ myList.append (new MyObject());
+ myList.append (new MyObject());
+
+ int numItems = myList.size(); // returns 2
+ MyObject* lastInList = myList.getLast();
+ @endcode
+*/
+template
+class LinkedListPointer
+{
+public:
+
+ /** Creates a null pointer to an empty list. */
+ LinkedListPointer() throw()
+ : item (0)
+ {
+ }
+
+ /** Creates a pointer to a list whose head is the item provided. */
+ explicit LinkedListPointer (ObjectType* const headItem) throw()
+ : item (headItem)
+ {
+ }
+
+ /** Sets this pointer to point to a new list. */
+ LinkedListPointer& operator= (ObjectType* const newItem) throw()
+ {
+ item = newItem;
+ return *this;
+ }
+
+ /** Returns the item which this pointer points to. */
+ inline operator ObjectType*() const throw()
+ {
+ return item;
+ }
+
+ /** Returns the item which this pointer points to. */
+ inline ObjectType* get() const throw()
+ {
+ return item;
+ }
+
+ /** Returns the last item in the list which this pointer points to.
+ This will iterate the list and return the last item found. Obviously the speed
+ of this operation will be proportional to the size of the list. If the list is
+ empty the return value will be this object.
+ If you're planning on appending a number of items to your list, it's much more
+ efficient to use the Appender class than to repeatedly call getLast() to find the end.
+ */
+ LinkedListPointer& getLast() throw()
+ {
+ LinkedListPointer* l = this;
+
+ while (l->item != 0)
+ l = &(l->item->nextListItem);
+
+ return *l;
+ }
+
+ /** Returns the number of items in the list.
+ Obviously with a simple linked list, getting the size involves iterating the list, so
+ this can be a lengthy operation - be careful when using this method in your code.
+ */
+ int size() const throw()
+ {
+ int total = 0;
+
+ for (ObjectType* i = item; i != 0; i = i->nextListItem)
+ ++total;
+
+ return total;
+ }
+
+ /** Returns the item at a given index in the list.
+ Since the only way to find an item is to iterate the list, this operation can obviously
+ be slow, depending on its size, so you should be careful when using this in algorithms.
+ */
+ LinkedListPointer& operator[] (int index) throw()
+ {
+ LinkedListPointer* l = this;
+
+ while (--index >= 0 && l->item != 0)
+ l = &(l->item->nextListItem);
+
+ return *l;
+ }
+
+ /** Returns the item at a given index in the list.
+ Since the only way to find an item is to iterate the list, this operation can obviously
+ be slow, depending on its size, so you should be careful when using this in algorithms.
+ */
+ const LinkedListPointer& operator[] (int index) const throw()
+ {
+ const LinkedListPointer* l = this;
+
+ while (--index >= 0 && l->item != 0)
+ l = &(l->item->nextListItem);
+
+ return *l;
+ }
+
+ /** Returns true if the list contains the given item. */
+ bool contains (const ObjectType* const itemToLookFor) const throw()
+ {
+ for (ObjectType* i = item; i != 0; i = i->nextListItem)
+ if (itemToLookFor == i)
+ return true;
+
+ return false;
+ }
+
+ /** Inserts an item into the list, placing it before the item that this pointer
+ currently points to.
+ */
+ void insertNext (ObjectType* const newItem)
+ {
+ jassert (newItem != 0);
+ jassert (newItem->nextListItem == 0);
+ newItem->nextListItem = item;
+ item = newItem;
+ }
+
+ /** Inserts an item at a numeric index in the list.
+ Obviously this will involve iterating the list to find the item at the given index,
+ so be careful about the impact this may have on execution time.
+ */
+ void insertAtIndex (int index, ObjectType* newItem)
+ {
+ jassert (newItem != 0);
+ LinkedListPointer* l = this;
+
+ while (index != 0 && l->item != 0)
+ {
+ l = &(l->item->nextListItem);
+ --index;
+ }
+
+ l->insertNext (newItem);
+ }
+
+ /** Replaces the object that this pointer points to, appending the rest of the list to
+ the new object, and returning the old one.
+ */
+ ObjectType* replaceNext (ObjectType* const newItem) throw()
+ {
+ jassert (newItem != 0);
+ jassert (newItem->nextListItem == 0);
+
+ ObjectType* const oldItem = item;
+ item = newItem;
+ item->nextListItem = oldItem->nextListItem;
+ oldItem->nextListItem = 0;
+ return oldItem;
+ }
+
+ /** Adds an item to the end of the list.
+
+ This operation involves iterating the whole list, so can be slow - if you need to
+ append a number of items to your list, it's much more efficient to use the Appender
+ class than to repeatedly call append().
+ */
+ void append (ObjectType* const newItem)
+ {
+ getLast().item = newItem;
+ }
+
+ /** Creates copies of all the items in another list and adds them to this one.
+ This will use the ObjectType's copy constructor to try to create copies of each
+ item in the other list, and appends them to this list.
+ */
+ void addCopyOfList (const LinkedListPointer& other)
+ {
+ LinkedListPointer* insertPoint = this;
+
+ for (ObjectType* i = other.item; i != 0; i = i->nextListItem)
+ {
+ insertPoint->insertNext (new ObjectType (*i));
+ insertPoint = &(insertPoint->item->nextListItem);
+ }
+ }
+
+ /** Removes the head item from the list.
+ This won't delete the object that is removed, but returns it, so the caller can
+ delete it if necessary.
+ */
+ ObjectType* removeNext() throw()
+ {
+ if (item == 0)
+ return 0;
+
+ ObjectType* const oldItem = item;
+ oldItem->nextListItem = 0;
+ item = item->nextListItem;
+ return oldItem;
+ }
+
+ /** Removes a specific item from the list.
+ Note that this will not delete the item, it simply unlinks it from the list.
+ */
+ void remove (ObjectType* const item)
+ {
+ LinkedListPointer* l = findPointerTo (item);
+
+ if (l != 0)
+ l->removeNext();
+ }
+
+ /** Iterates the list, calling the delete operator on all of its elements and
+ leaving this pointer empty.
+ */
+ void deleteAll()
+ {
+ while (item != 0)
+ {
+ ObjectType* const oldItem = item;
+ item = oldItem->nextListItem;
+ delete oldItem;
+ }
+ }
+
+ /** Finds a pointer to a given item.
+ If the item is found in the list, this returns the pointer that points to it. If
+ the item isn't found, this returns null.
+ */
+ LinkedListPointer* findPointerTo (ObjectType* const itemToLookFor) throw()
+ {
+ LinkedListPointer* l = this;
+
+ while (l->item != 0)
+ {
+ if (l->item == itemToLookFor)
+ return l;
+
+ l = &(l->item->nextListItem);
+ }
+
+ return 0;
+ }
+
+ /** Copies the items in the list to an array.
+ The destArray must contain enough elements to hold the entire list - no checks are
+ made for this!
+ */
+ void copyToArray (ObjectType** destArray) const throw()
+ {
+ jassert (destArray != 0);
+
+ for (ObjectType* i = item; i != 0; i = i->nextListItem)
+ *destArray++ = i;
+ }
+
+ /**
+ Allows efficient repeated insertions into a list.
+
+ You can create an Appender object which points to the last element in your
+ list, and then repeatedly call Appender::append() to add items to the end
+ of the list in O(1) time.
+ */
+ class Appender
+ {
+ public:
+ /** Creates an appender which will add items to the given list.
+ */
+ Appender (LinkedListPointer& endOfListPointer) throw()
+ : endOfList (&endOfListPointer)
+ {
+ // This can only be used to add to the end of a list.
+ jassert (endOfListPointer.item == 0);
+ }
+
+ /** Appends an item to the list. */
+ void append (ObjectType* const newItem) throw()
+ {
+ *endOfList = newItem;
+ endOfList = &(newItem->nextListItem);
+ }
+
+ private:
+ LinkedListPointer* endOfList;
+
+ JUCE_DECLARE_NON_COPYABLE (Appender);
+ };
+
+private:
+
+ ObjectType* item;
+};
+
+#endif // __JUCE_LINKEDLISTPOINTER_JUCEHEADER__
+/*** End of inlined file: juce_LinkedListPointer.h ***/
+
+
#endif
#ifndef __JUCE_NAMEDVALUESET_JUCEHEADER__
@@ -9835,7 +10154,7 @@ public:
@see getNextElement, isTextElement, forEachXmlChildElement
*/
- inline XmlElement* getNextElement() const throw() { return nextElement; }
+ inline XmlElement* getNextElement() const throw() { return nextListItem; }
/** Returns the next of this element's siblings which has the specified tag
name.
@@ -10070,8 +10389,9 @@ private:
friend class XmlDocument;
String tagName;
- XmlElement* firstChildElement;
- XmlElement* nextElement;
+ friend class LinkedListPointer ;
+ LinkedListPointer firstChildElement;
+ LinkedListPointer nextListItem;
struct XmlAttributeNode
{
@@ -10079,7 +10399,7 @@ private:
XmlAttributeNode (const String& name, const String& value) throw();
String name, value;
- XmlAttributeNode* next;
+ LinkedListPointer nextListItem;
bool hasName (const String& name) const throw();
@@ -10087,7 +10407,8 @@ private:
XmlAttributeNode& operator= (const XmlAttributeNode&);
};
- XmlAttributeNode* attributes;
+ friend class LinkedListPointer;
+ LinkedListPointer attributes;
XmlElement (int) throw();
void copyChildrenAndAttributesFrom (const XmlElement& other);
@@ -28618,9 +28939,10 @@ private:
void internalMouseMove (MouseInputSource& source, const Point& relativePos, const Time& time);
void internalMouseWheel (MouseInputSource& source, const Point& relativePos, const Time& time, float amountX, float amountY);
void internalBroughtToFront();
+ void internalFocusGain (const FocusChangeType cause, const WeakReference&);
void internalFocusGain (const FocusChangeType cause);
void internalFocusLoss (const FocusChangeType cause);
- void internalChildFocusChange (FocusChangeType cause);
+ void internalChildFocusChange (FocusChangeType cause, const WeakReference&);
void internalModalInputAttempt();
void internalModifierKeysChanged();
void internalChildrenChanged();
@@ -53892,11 +54214,6 @@ private:
#define __JUCE_DOCUMENTWINDOW_JUCEHEADER__
-/*** Start of inlined file: juce_MenuBarComponent.h ***/
-#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__
-#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__
-
-
/*** Start of inlined file: juce_MenuBarModel.h ***/
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__
#define __JUCE_MENUBARMODEL_JUCEHEADER__
@@ -54043,97 +54360,6 @@ typedef MenuBarModel::Listener MenuBarModelListener;
#endif // __JUCE_MENUBARMODEL_JUCEHEADER__
/*** End of inlined file: juce_MenuBarModel.h ***/
-/**
- A menu bar component.
-
- @see MenuBarModel
-*/
-class JUCE_API MenuBarComponent : public Component,
- private MenuBarModel::Listener,
- private Timer
-{
-public:
-
- /** Creates a menu bar.
-
- @param model the model object to use to control this bar. You can
- pass 0 into this if you like, and set the model later
- using the setModel() method
- */
- MenuBarComponent (MenuBarModel* model);
-
- /** Destructor. */
- ~MenuBarComponent();
-
- /** Changes the model object to use to control the bar.
-
- This can be 0, in which case the bar will be empty. Don't delete the object
- that is passed-in while it's still being used by this MenuBar.
- */
- void setModel (MenuBarModel* newModel);
-
- /** Returns the current menu bar model being used.
- */
- MenuBarModel* getModel() const throw();
-
- /** Pops up one of the menu items.
-
- This lets you manually open one of the menus - it could be triggered by a
- key shortcut, for example.
- */
- void showMenu (int menuIndex);
-
- /** @internal */
- void paint (Graphics& g);
- /** @internal */
- void resized();
- /** @internal */
- void mouseEnter (const MouseEvent& e);
- /** @internal */
- void mouseExit (const MouseEvent& e);
- /** @internal */
- void mouseDown (const MouseEvent& e);
- /** @internal */
- void mouseDrag (const MouseEvent& e);
- /** @internal */
- void mouseUp (const MouseEvent& e);
- /** @internal */
- void mouseMove (const MouseEvent& e);
- /** @internal */
- void handleCommandMessage (int commandId);
- /** @internal */
- bool keyPressed (const KeyPress& key);
- /** @internal */
- void menuBarItemsChanged (MenuBarModel* menuBarModel);
- /** @internal */
- void menuCommandInvoked (MenuBarModel* menuBarModel,
- const ApplicationCommandTarget::InvocationInfo& info);
-
-private:
-
- class AsyncCallback;
- friend class AsyncCallback;
- MenuBarModel* model;
-
- StringArray menuNames;
- Array xPositions;
- int itemUnderMouse, currentPopupIndex, topLevelIndexClicked;
- int lastMouseX, lastMouseY;
-
- int getItemAt (int x, int y);
- void setItemUnderMouse (int index);
- void setOpenItem (int index);
- void updateItemUnderMouse (int x, int y);
- void timerCallback();
- void repaintMenuItem (int index);
- void menuDismissed (int topLevelIndex, int itemId);
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarComponent);
-};
-
-#endif // __JUCE_MENUBARCOMPONENT_JUCEHEADER__
-/*** End of inlined file: juce_MenuBarComponent.h ***/
-
/**
A resizable window with a title bar and maximise, minimise and close buttons.
@@ -54256,6 +54482,17 @@ public:
void setMenuBar (MenuBarModel* menuBarModel,
int menuBarHeight = 0);
+ /** Returns the current menu bar component, or null if there isn't one.
+ This is probably a MenuBarComponent, unless a custom one has been set using
+ setMenuBarComponent().
+ */
+ Component* getMenuBarComponent() const throw();
+
+ /** Replaces the current menu bar with a custom component.
+ The component will be owned and deleted by the document window.
+ */
+ void setMenuBarComponent (Component* newMenuBarComponent);
+
/** This method is called when the user tries to close the window.
This is triggered by the user clicking the close button, or using some other
@@ -54344,7 +54581,7 @@ private:
bool positionTitleBarButtonsOnLeft, drawTitleTextCentred;
ScopedPointer