Browse Source

Minor fixes for mac strings, WAV format, DrawableButton hit tests, win32 clipboard. New class: CharPointer_ASCII. Changes to the callback methods for ValueTree::Listener, to provide more detailed information about the event.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
c10c810aee
39 changed files with 1540 additions and 204 deletions
  1. +2
    -0
      Builds/MacOSX/Juce.xcodeproj/project.pbxproj
  2. +1
    -0
      Builds/VisualStudio2005/Juce.vcproj
  3. +1
    -0
      Builds/VisualStudio2008/Juce.vcproj
  4. +1
    -0
      Builds/VisualStudio2008_DLL/Juce.vcproj
  5. +1
    -0
      Builds/VisualStudio2010/Juce.vcxproj
  6. +3
    -0
      Builds/VisualStudio2010/Juce.vcxproj.filters
  7. +2
    -0
      Builds/iOS/Juce.xcodeproj/project.pbxproj
  8. +2
    -0
      Juce.jucer
  9. +12
    -2
      extras/Jucer (experimental)/Source/Project/jucer_GroupInformationComponent.cpp
  10. +3
    -1
      extras/Jucer (experimental)/Source/Project/jucer_GroupInformationComponent.h
  11. +11
    -1
      extras/Jucer (experimental)/Source/Project/jucer_Project.cpp
  12. +3
    -1
      extras/Jucer (experimental)/Source/Project/jucer_Project.h
  13. +22
    -7
      extras/Jucer (experimental)/Source/Project/jucer_ProjectTreeViewBase.cpp
  14. +4
    -1
      extras/Jucer (experimental)/Source/Project/jucer_ProjectTreeViewBase.h
  15. +188
    -71
      juce_amalgamated.cpp
  16. +536
    -25
      juce_amalgamated.h
  17. +37
    -23
      src/audio/audio_file_formats/juce_WavAudioFormat.cpp
  18. +62
    -13
      src/containers/juce_ValueTree.cpp
  19. +29
    -7
      src/containers/juce_ValueTree.h
  20. +1
    -1
      src/core/juce_StandardHeader.h
  21. +1
    -0
      src/gui/components/buttons/juce_DrawableButton.cpp
  22. +4
    -0
      src/gui/components/controls/juce_TextEditor.cpp
  23. +4
    -4
      src/gui/components/controls/juce_TextEditor.h
  24. +11
    -1
      src/gui/components/layout/juce_ComponentBuilder.cpp
  25. +5
    -1
      src/gui/components/layout/juce_ComponentBuilder.h
  26. +6
    -7
      src/gui/components/menus/juce_PopupMenu.cpp
  27. +6
    -0
      src/gui/graphics/drawables/juce_DrawableShape.cpp
  28. +3
    -0
      src/juce_core_includes.h
  29. +1
    -1
      src/native/mac/juce_mac_Files.mm
  30. +1
    -1
      src/native/windows/juce_win32_Misc.cpp
  31. +382
    -0
      src/text/juce_CharPointer_ASCII.h
  32. +37
    -0
      src/text/juce_CharPointer_UTF16.h
  33. +20
    -1
      src/text/juce_CharPointer_UTF32.h
  34. +49
    -4
      src/text/juce_CharPointer_UTF8.h
  35. +1
    -0
      src/text/juce_CharacterFunctions.cpp
  36. +45
    -12
      src/text/juce_String.cpp
  37. +30
    -6
      src/text/juce_String.h
  38. +12
    -12
      src/text/juce_XmlDocument.cpp
  39. +1
    -1
      src/text/juce_XmlDocument.h

+ 2
- 0
Builds/MacOSX/Juce.xcodeproj/project.pbxproj View File

@@ -1035,6 +1035,7 @@
4007410FACA2F865FD8EF769 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF8.h; path = ../../src/text/juce_CharPointer_UTF8.h; sourceTree = SOURCE_ROOT; };
663746215E9BA6C761172B85 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF16.h; path = ../../src/text/juce_CharPointer_UTF16.h; sourceTree = SOURCE_ROOT; };
C3FD9D93626F80A45F9B6DDE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF32.h; path = ../../src/text/juce_CharPointer_UTF32.h; sourceTree = SOURCE_ROOT; };
72F5ED2E8B945988C37EA9CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_ASCII.h; path = ../../src/text/juce_CharPointer_ASCII.h; sourceTree = SOURCE_ROOT; };
8273A206FB309671284959DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/text/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; };
BF888BC540B64D5C61E46A34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/text/juce_Identifier.h; sourceTree = SOURCE_ROOT; };
4A97C8D2FF6454DDD3AF4BE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_LocalisedStrings.cpp; path = ../../src/text/juce_LocalisedStrings.cpp; sourceTree = SOURCE_ROOT; };
@@ -1861,6 +1862,7 @@
4007410FACA2F865FD8EF769,
663746215E9BA6C761172B85,
C3FD9D93626F80A45F9B6DDE,
72F5ED2E8B945988C37EA9CF,
8273A206FB309671284959DD,
BF888BC540B64D5C61E46A34,
4A97C8D2FF6454DDD3AF4BE5,


+ 1
- 0
Builds/VisualStudio2005/Juce.vcproj View File

@@ -959,6 +959,7 @@
<File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/>
<File RelativePath="..\..\src\text\juce_Identifier.cpp"/>
<File RelativePath="..\..\src\text\juce_Identifier.h"/>
<File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/>


+ 1
- 0
Builds/VisualStudio2008/Juce.vcproj View File

@@ -959,6 +959,7 @@
<File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/>
<File RelativePath="..\..\src\text\juce_Identifier.cpp"/>
<File RelativePath="..\..\src\text\juce_Identifier.h"/>
<File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/>


+ 1
- 0
Builds/VisualStudio2008_DLL/Juce.vcproj View File

@@ -961,6 +961,7 @@
<File RelativePath="..\..\src\text\juce_CharPointer_UTF8.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF32.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_ASCII.h"/>
<File RelativePath="..\..\src\text\juce_Identifier.cpp"/>
<File RelativePath="..\..\src\text\juce_Identifier.h"/>
<File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/>


+ 1
- 0
Builds/VisualStudio2010/Juce.vcxproj View File

@@ -777,6 +777,7 @@
<ClInclude Include="..\..\src\text\juce_CharPointer_UTF8.h"/>
<ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"/>
<ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h"/>
<ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h"/>
<ClInclude Include="..\..\src\text\juce_Identifier.h"/>
<ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"/>
<ClInclude Include="..\..\src\text\juce_NewLine.h"/>


+ 3
- 0
Builds/VisualStudio2010/Juce.vcxproj.filters View File

@@ -2265,6 +2265,9 @@
<ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h">
<Filter>Juce\Source\text</Filter>
</ClInclude>
<ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h">
<Filter>Juce\Source\text</Filter>
</ClInclude>
<ClInclude Include="..\..\src\text\juce_Identifier.h">
<Filter>Juce\Source\text</Filter>
</ClInclude>


+ 2
- 0
Builds/iOS/Juce.xcodeproj/project.pbxproj View File

@@ -1035,6 +1035,7 @@
4007410FACA2F865FD8EF769 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF8.h; path = ../../src/text/juce_CharPointer_UTF8.h; sourceTree = SOURCE_ROOT; };
663746215E9BA6C761172B85 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF16.h; path = ../../src/text/juce_CharPointer_UTF16.h; sourceTree = SOURCE_ROOT; };
C3FD9D93626F80A45F9B6DDE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_UTF32.h; path = ../../src/text/juce_CharPointer_UTF32.h; sourceTree = SOURCE_ROOT; };
72F5ED2E8B945988C37EA9CF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_CharPointer_ASCII.h; path = ../../src/text/juce_CharPointer_ASCII.h; sourceTree = SOURCE_ROOT; };
8273A206FB309671284959DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/text/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; };
BF888BC540B64D5C61E46A34 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/text/juce_Identifier.h; sourceTree = SOURCE_ROOT; };
4A97C8D2FF6454DDD3AF4BE5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_LocalisedStrings.cpp; path = ../../src/text/juce_LocalisedStrings.cpp; sourceTree = SOURCE_ROOT; };
@@ -1861,6 +1862,7 @@
4007410FACA2F865FD8EF769,
663746215E9BA6C761172B85,
C3FD9D93626F80A45F9B6DDE,
72F5ED2E8B945988C37EA9CF,
8273A206FB309671284959DD,
BF888BC540B64D5C61E46A34,
4A97C8D2FF6454DDD3AF4BE5,


+ 2
- 0
Juce.jucer View File

@@ -1477,6 +1477,8 @@
file="src/text/juce_CharPointer_UTF16.h"/>
<FILE id="rE1hlF" name="juce_CharPointer_UTF32.h" compile="0" resource="0"
file="src/text/juce_CharPointer_UTF32.h"/>
<FILE id="rdfOEc" name="juce_CharPointer_ASCII.h" compile="0" resource="0"
file="src/text/juce_CharPointer_ASCII.h"/>
<FILE id="iGtCiI8" name="juce_Identifier.cpp" compile="1" resource="0"
file="src/text/juce_Identifier.cpp"/>
<FILE id="CPlhWqs" name="juce_Identifier.h" compile="0" resource="0"


+ 12
- 2
extras/Jucer (experimental)/Source/Project/jucer_GroupInformationComponent.cpp View File

@@ -62,12 +62,22 @@ void GroupInformationComponent::valueTreePropertyChanged (ValueTree& treeWhosePr
list.updateContent();
}
void GroupInformationComponent::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged)
void GroupInformationComponent::valueTreeChildAdded (ValueTree&, ValueTree&)
{
list.updateContent();
}
void GroupInformationComponent::valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged)
void GroupInformationComponent::valueTreeChildRemoved (ValueTree&, ValueTree&)
{
list.updateContent();
}
void GroupInformationComponent::valueTreeChildOrderChanged (ValueTree&)
{
list.updateContent();
}
void GroupInformationComponent::valueTreeParentChanged (ValueTree&)
{
list.updateContent();
}


+ 3
- 1
extras/Jucer (experimental)/Source/Project/jucer_GroupInformationComponent.h View File

@@ -49,7 +49,9 @@ public:
//==============================================================================
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
void valueTreeChildOrderChanged (ValueTree& parentTree);
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
private:


+ 11
- 1
extras/Jucer (experimental)/Source/Project/jucer_Project.cpp View File

@@ -217,7 +217,17 @@ void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& prope
changed();
}
void Project::valueTreeChildrenChanged (ValueTree& tree)
void Project::valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded)
{
changed();
}
void Project::valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved)
{
changed();
}
void Project::valueTreeChildOrderChanged (ValueTree& parentTree)
{
changed();
}


+ 3
- 1
extras/Jucer (experimental)/Source/Project/jucer_Project.h View File

@@ -298,7 +298,9 @@ public:
//==============================================================================
void valueTreePropertyChanged (ValueTree& tree, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& tree);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
void valueTreeChildOrderChanged (ValueTree& parentTree);
void valueTreeParentChanged (ValueTree& tree);
//==============================================================================


+ 22
- 7
extras/Jucer (experimental)/Source/Project/jucer_ProjectTreeViewBase.cpp View File

@@ -365,20 +365,35 @@ void ProjectTreeViewBase::itemDropped (const String& sourceDescription, Componen
}
//==============================================================================
void ProjectTreeViewBase::treeChildrenChanged (const ValueTree& parentTree)
{
if (parentTree == item.getNode())
{
refreshSubItems();
treeHasChanged();
setOpen (true);
}
}
void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
if (tree == item.getNode())
repaintItem();
}
void ProjectTreeViewBase::valueTreeChildrenChanged (ValueTree& tree)
void ProjectTreeViewBase::valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded)
{
if (tree == item.getNode())
{
refreshSubItems();
treeHasChanged();
setOpen (true);
}
treeChildrenChanged (parentTree);
}
void ProjectTreeViewBase::valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved)
{
treeChildrenChanged (parentTree);
}
void ProjectTreeViewBase::valueTreeChildOrderChanged (ValueTree& parentTree)
{
treeChildrenChanged (parentTree);
}
void ProjectTreeViewBase::valueTreeParentChanged (ValueTree& tree)


+ 4
- 1
extras/Jucer (experimental)/Source/Project/jucer_ProjectTreeViewBase.h View File

@@ -70,7 +70,9 @@ public:
//==============================================================================
void valueTreePropertyChanged (ValueTree& tree, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& tree);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
void valueTreeChildOrderChanged (ValueTree& parentTree);
void valueTreeParentChanged (ValueTree& tree);
//==============================================================================
@@ -99,6 +101,7 @@ protected:
bool isFileMissing;
//==============================================================================
void treeChildrenChanged (const ValueTree& parentTree);
virtual void addSubItems();
virtual ProjectTreeViewBase* createSubItem (const Project::Item& node) = 0;
const Drawable* getIcon() const { return item.getIcon(); }


+ 188
- 71
juce_amalgamated.cpp View File

@@ -11580,8 +11580,41 @@ String::String (const String& stringToCopy, const size_t charsToAllocate)
}

String::String (const char* const t)
: text (StringHolder::createFromCharPointer (CharPointer_UTF8 (t)))
{
: text (StringHolder::createFromCharPointer (CharPointer_ASCII (t)))
{
/* If you get an assertion here, then you're trying to create a string from 8-bit data
that contains values greater than 127. These can NOT be correctly converted to unicode
because there's no way for the String class to know what encoding was used to
create them. The source data could be UTF-8, ASCII or one of many local code-pages.

To get around this problem, you must be more explicit when you pass an ambiguous 8-bit
string to the String class - so for example if your source data is actually UTF-8,
you'd call String (CharPointer_UTF8 ("my utf8 string..")), and it would be able to
correctly convert the multi-byte characters to unicode. It's *highly* recommended that
you use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent these strings in a way that isn't dependent on
the compiler, source code editor and platform.
*/
jassert (CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max()));
}

String::String (const char* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_ASCII (t), maxChars))
{
/* If you get an assertion here, then you're trying to create a string from 8-bit data
that contains values greater than 127. These can NOT be correctly converted to unicode
because there's no way for the String class to know what encoding was used to
create them. The source data could be UTF-8, ASCII or one of many local code-pages.

To get around this problem, you must be more explicit when you pass an ambiguous 8-bit
string to the String class - so for example if your source data is actually UTF-8,
you'd call String (CharPointer_UTF8 ("my utf8 string..")), and it would be able to
correctly convert the multi-byte characters to unicode. It's *highly* recommended that
you use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent these strings in a way that isn't dependent on
the compiler, source code editor and platform.
*/
jassert (CharPointer_ASCII::isValidString (t, (int) maxChars));
}

String::String (const juce_wchar* const t)
@@ -11589,6 +11622,11 @@ String::String (const juce_wchar* const t)
{
}

String::String (const juce_wchar* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_UTF32 (t), maxChars))
{
}

String::String (const CharPointer_UTF8& t)
: text (StringHolder::createFromCharPointer (t))
{
@@ -11609,6 +11647,11 @@ String::String (const CharPointer_UTF32& t, const size_t maxChars)
{
}

String::String (const CharPointer_ASCII& t)
: text (StringHolder::createFromCharPointer (t))
{
}

#if JUCE_WINDOWS
String::String (const wchar_t* const t)
: text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t)))
@@ -11621,16 +11664,6 @@ String::String (const wchar_t* const t, size_t maxChars)
}
#endif

String::String (const char* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_UTF8 (t), maxChars))
{
}

String::String (const juce_wchar* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_UTF32 (t), maxChars))
{
}

const String String::charToString (const juce_wchar character)
{
String result (Preallocation (1));
@@ -12004,7 +12037,7 @@ String& String::operator+= (const juce_wchar ch)
}

#if JUCE_WINDOWS
String& String::operator+= (wchar_t ch)
String& String::operator+= (const wchar_t ch)
{
return operator+= ((juce_wchar) ch);
}
@@ -14551,7 +14584,7 @@ XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentEle
}
}

input = static_cast <const juce_wchar*> (textToParse);
input = textToParse.getCharPointer();
lastError = String::empty;
errorOccurred = false;
outOfData = false;
@@ -14662,7 +14695,7 @@ void XmlDocument::skipHeader()
return;

input += docTypeIndex + 9;
const CharPointer_UTF32 docType (input);
const String::CharPointerType docType (input);

int n = 1;

@@ -14751,7 +14784,7 @@ void XmlDocument::readQuotedString (String& result)
else
{
--input;
const CharPointer_UTF32 start (input);
const String::CharPointerType start (input);

for (;;)
{
@@ -14759,14 +14792,14 @@ void XmlDocument::readQuotedString (String& result)

if (character == quote)
{
result.append (start.getAddress(), (int) (input.getAddress() - start.getAddress()));
result.appendCharPointer (start, (int) (input.getAddress() - start.getAddress()));
++input;

return;
}
else if (character == '&')
{
result.append (start.getAddress(), (int) (input.getAddress() - start.getAddress()));
result.appendCharPointer (start, (int) (input.getAddress() - start.getAddress()));
break;
}
else if (character == 0)
@@ -14846,7 +14879,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)

if (attNameLen > 0)
{
const CharPointer_UTF32 attNameStart (input);
const String::CharPointerType attNameStart (input);
input += attNameLen;

skipNextWhiteSpace();
@@ -14889,7 +14922,7 @@ void XmlDocument::readChildElements (XmlElement* parent)

for (;;)
{
const CharPointer_UTF32 preWhitespaceInput (input);
const String::CharPointerType preWhitespaceInput (input);
skipNextWhiteSpace();

if (outOfData)
@@ -14920,7 +14953,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
&& input[8] == '[')
{
input += 9;
const CharPointer_UTF32 inputStart (input);
const String::CharPointerType inputStart (input);

int len = 0;

@@ -14983,10 +15016,10 @@ void XmlDocument::readChildElements (XmlElement* parent)

if (entity.startsWithChar ('<') && entity [1] != 0)
{
const CharPointer_UTF32 oldInput (input);
const String::CharPointerType oldInput (input);
const bool oldOutOfData = outOfData;

input = static_cast <const juce_wchar*> (entity);
input = entity.getCharPointer();
outOfData = false;

for (;;)
@@ -15009,7 +15042,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
}
else
{
const CharPointer_UTF32 start (input);
const String::CharPointerType start (input);
int len = 0;

for (;;)
@@ -15128,7 +15161,7 @@ void XmlDocument::readEntity (String& result)
}
else
{
const CharPointer_UTF32 entityNameStart (input);
const String::CharPointerType entityNameStart (input);
const int closingSemiColon = input.indexOf ((juce_wchar) ';');

if (closingSemiColon < 0)
@@ -17525,24 +17558,68 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (const Identifier& prope
}
}

void ValueTree::SharedObject::sendChildChangeMessage (ValueTree& tree)
void ValueTree::SharedObject::sendChildAddedMessage (ValueTree& tree, ValueTree& child)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
ValueTree* const v = valueTreesWithListeners[i];
if (v != 0)
v->listeners.call (&ValueTree::Listener::valueTreeChildrenChanged, tree);
v->listeners.call (&ValueTree::Listener::valueTreeChildAdded, tree, child);
}
}

void ValueTree::SharedObject::sendChildChangeMessage()
void ValueTree::SharedObject::sendChildAddedMessage (ValueTree child)
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;

while (t != 0)
{
t->sendChildChangeMessage (tree);
t->sendChildAddedMessage (tree, child);
t = t->parent;
}
}

void ValueTree::SharedObject::sendChildRemovedMessage (ValueTree& tree, ValueTree& child)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
ValueTree* const v = valueTreesWithListeners[i];
if (v != 0)
v->listeners.call (&ValueTree::Listener::valueTreeChildRemoved, tree, child);
}
}

void ValueTree::SharedObject::sendChildRemovedMessage (ValueTree child)
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;

while (t != 0)
{
t->sendChildRemovedMessage (tree, child);
t = t->parent;
}
}

void ValueTree::SharedObject::sendChildOrderChangedMessage (ValueTree& tree)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
ValueTree* const v = valueTreesWithListeners[i];
if (v != 0)
v->listeners.call (&ValueTree::Listener::valueTreeChildOrderChanged, tree);
}
}

void ValueTree::SharedObject::sendChildOrderChangedMessage()
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;

while (t != 0)
{
t->sendChildOrderChangedMessage (tree);
t = t->parent;
}
}
@@ -17708,7 +17785,7 @@ void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoMana
{
children.insert (index, child);
child->parent = this;
sendChildChangeMessage();
sendChildAddedMessage (ValueTree (child));
child->sendParentChangeMessage();
}
else
@@ -17738,7 +17815,7 @@ void ValueTree::SharedObject::removeChild (const int childIndex, UndoManager* co
{
children.remove (childIndex);
child->parent = 0;
sendChildChangeMessage();
sendChildRemovedMessage (ValueTree (child));
child->sendParentChangeMessage();
}
else
@@ -17765,7 +17842,7 @@ void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoMan
if (undoManager == 0)
{
children.move (currentIndex, newIndex);
sendChildChangeMessage();
sendChildOrderChangedMessage();
}
else
{
@@ -17784,16 +17861,19 @@ void ValueTree::SharedObject::reorderChildren (const ReferenceCountedArray <Shar
if (undoManager == 0)
{
children = newOrder;
sendChildChangeMessage();
sendChildOrderChangedMessage();
}
else
{
for (int i = 0; i < children.size(); ++i)
{
if (children.getUnchecked(i) != newOrder.getUnchecked(i))
const SharedObjectPtr child (newOrder.getUnchecked(i));

if (children.getUnchecked(i) != child)
{
jassert (children.contains (newOrder.getUnchecked(i)));
moveChild (children.indexOf (newOrder.getUnchecked(i)), i, undoManager);
const int oldIndex = children.indexOf (child);
jassert (oldIndex >= 0);
moveChild (oldIndex, i, undoManager);
}
}
}
@@ -17990,8 +18070,10 @@ public:
sendChangeMessage (false);
}

void valueTreeChildrenChanged (ValueTree&) {}
void valueTreeParentChanged (ValueTree&) {}
void valueTreeChildAdded (ValueTree&, ValueTree&) {}
void valueTreeChildRemoved (ValueTree&, ValueTree&) {}
void valueTreeChildOrderChanged (ValueTree&) {}
void valueTreeParentChanged (ValueTree&) {}

private:
ValueTree tree;
@@ -23055,8 +23137,7 @@ public:
: AudioFormatWriter (out, TRANS (wavFormatName), sampleRate_, numChannels_, bits),
lengthInSamples (0),
bytesWritten (0),
writeFailed (false),
isRF64 (false)
writeFailed (false)
{
using namespace WavFileHelpers;

@@ -23123,7 +23204,7 @@ private:
MemoryBlock tempBlock, bwavChunk, smplChunk;
uint64 lengthInSamples, bytesWritten;
int64 headerPosition;
bool writeFailed, isRF64;
bool writeFailed;

static int getChannelMask (const int numChannels) throw()
{
@@ -23152,14 +23233,15 @@ private:
const int bytesPerFrame = numChannels * bitsPerSample / 8;
int64 audioDataSize = bytesPerFrame * lengthInSamples;

int64 riffChunkSize = 4 /* 'WAVE' */ + 8 + 40 /* WAVEFORMATEX */
const bool isRF64 = (bytesWritten >= literal64bit (0x100000000));

int64 riffChunkSize = 4 /* 'RIFF' */ + 8 + 40 /* WAVEFORMATEX */
+ 8 + audioDataSize + (audioDataSize & 1)
+ (bwavChunk.getSize() > 0 ? (8 + bwavChunk.getSize()) : 0)
+ (smplChunk.getSize() > 0 ? (8 + smplChunk.getSize()) : 0)
+ (8 + 28); // (JUNK chunk)
+ (8 + 28); // (ds64 chunk)

riffChunkSize += (riffChunkSize & 0x1);
isRF64 = (riffChunkSize > 0xffffffff);

output->writeInt (chunkName (isRF64 ? "RF64" : "RIFF"));
output->writeInt (isRF64 ? -1 : (int) riffChunkSize);
@@ -23167,10 +23249,9 @@ private:

if (! isRF64)
{
// write Junk chunk
output->writeInt (chunkName ("JUNK"));
output->writeInt (28);
output->writeRepeatedByte (0, 28);
output->writeInt (28 + 24);
output->writeRepeatedByte (0, 28 /* ds64 */ + 24 /* extra waveformatex */);
}
else
{
@@ -23183,29 +23264,44 @@ private:
}

output->writeInt (chunkName ("fmt "));
output->writeInt (40); // WAVEFORMATEX chunk size
output->writeShort ((short) (uint16) 0xfffe); // WAVE_FORMAT_EXTENSIBLE

if (isRF64)
{
output->writeInt (40); // chunk size
output->writeShort ((short) (uint16) 0xfffe); // WAVE_FORMAT_EXTENSIBLE
}
else
{
output->writeInt (16); // chunk size
output->writeShort (bitsPerSample < 32 ? (short) 1 /*WAVE_FORMAT_PCM*/
: (short) 3 /*WAVE_FORMAT_IEEE_FLOAT*/);
}

output->writeShort ((short) numChannels);
output->writeInt ((int) sampleRate);
output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec
output->writeShort ((short) bytesPerFrame); // nBlockAlign
output->writeShort ((short) bitsPerSample); // wBitsPerSample
output->writeShort (22); // cbSize (size of the extension)
output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
output->writeInt (getChannelMask (numChannels));

const ExtensibleWavSubFormat pcmFormat
= { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
if (isRF64)
{
output->writeShort (22); // cbSize (size of the extension)
output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
output->writeInt (getChannelMask (numChannels));

const ExtensibleWavSubFormat pcmFormat
= { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };

const ExtensibleWavSubFormat IEEEFloatFormat
= { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
const ExtensibleWavSubFormat IEEEFloatFormat
= { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };

const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;
const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;

output->writeInt ((int) subFormat.data1);
output->writeShort ((short) subFormat.data2);
output->writeShort ((short) subFormat.data3);
output->write (subFormat.data4, sizeof (subFormat.data4));
output->writeInt ((int) subFormat.data1);
output->writeShort ((short) subFormat.data2);
output->writeShort ((short) subFormat.data3);
output->write (subFormat.data4, sizeof (subFormat.data4));
}

if (bwavChunk.getSize() > 0)
{
@@ -43750,6 +43846,7 @@ void DrawableButton::buttonStateChanged()

if (currentImage != 0)
{
currentImage->setInterceptsMouseClicks (false, false);
addAndMakeVisible (currentImage);
DrawableButton::resized();
}
@@ -54423,6 +54520,11 @@ void TextEditor::coalesceSimilarSections()
}
}

void TextEditor::Listener::textEditorTextChanged (TextEditor&) {}
void TextEditor::Listener::textEditorReturnKeyPressed (TextEditor&) {}
void TextEditor::Listener::textEditorEscapeKeyPressed (TextEditor&) {}
void TextEditor::Listener::textEditorFocusLost (TextEditor&) {}

END_JUCE_NAMESPACE
/*** End of inlined file: juce_TextEditor.cpp ***/

@@ -61303,7 +61405,17 @@ void ComponentBuilder::valueTreePropertyChanged (ValueTree& tree, const Identifi
ComponentBuilderHelpers::updateComponent (*this, tree);
}

void ComponentBuilder::valueTreeChildrenChanged (ValueTree& tree)
void ComponentBuilder::valueTreeChildAdded (ValueTree& tree, ValueTree&)
{
ComponentBuilderHelpers::updateComponent (*this, tree);
}

void ComponentBuilder::valueTreeChildRemoved (ValueTree& tree, ValueTree&)
{
ComponentBuilderHelpers::updateComponent (*this, tree);
}

void ComponentBuilder::valueTreeChildOrderChanged (ValueTree& tree)
{
ComponentBuilderHelpers::updateComponent (*this, tree);
}
@@ -68738,17 +68850,21 @@ class PopupMenu::ItemComponent : public Component
{
public:

ItemComponent (const PopupMenu::Item& itemInfo_, int standardItemHeight)
ItemComponent (const PopupMenu::Item& itemInfo_, int standardItemHeight, Component* const parent)
: itemInfo (itemInfo_),
isHighlighted (false)
{
if (itemInfo.customComp != 0)
addAndMakeVisible (itemInfo.customComp);

parent->addAndMakeVisible (this);

int itemW = 80;
int itemH = 16;
getIdealSize (itemW, itemH, standardItemHeight);
setSize (itemW, jlimit (2, 600, itemH));

addMouseListener (parent, false);
}

~ItemComponent()
@@ -68877,12 +68993,7 @@ public:
setOpaque (getLookAndFeel().findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows());

for (int i = 0; i < menu.items.size(); ++i)
{
PopupMenu::ItemComponent* const itemComp = new PopupMenu::ItemComponent (*menu.items.getUnchecked(i), standardItemHeight);
items.add (itemComp);
addAndMakeVisible (itemComp);
itemComp->addMouseListener (this, false);
}
items.add (new PopupMenu::ItemComponent (*menu.items.getUnchecked(i), standardItemHeight, this));

calculateWindowPos (target, alignToRectangle);
setTopLeftPosition (windowPos.getX(), windowPos.getY());
@@ -86175,6 +86286,12 @@ const Rectangle<float> DrawableShape::getDrawableBounds() const

bool DrawableShape::hitTest (int x, int y)
{
bool allowsClicksOnThisComponent, allowsClicksOnChildComponents;
getInterceptsMouseClicks (allowsClicksOnThisComponent, allowsClicksOnChildComponents);

if (! allowsClicksOnThisComponent)
return false;

const float globalX = (float) (x - originRelativeToComponent.getX());
const float globalY = (float) (y - originRelativeToComponent.getY());

@@ -244209,7 +244326,7 @@ void SystemClipboard::copyTextToClipboard (const String& text)
{
if (EmptyClipboard() != 0)
{
const int bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
const int bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()) + 4;

if (bytesNeeded > 0)
{
@@ -263990,7 +264107,7 @@ namespace FileHelpers
FSRef ref;
LSItemInfoRecord info;

return FSPathMakeRefWithOptions ((const UInt8*) path.toUTF8(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr
return FSPathMakeRefWithOptions ((const UInt8*) path.toUTF8().getAddress(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr
&& LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr
&& (info.flags & kLSItemInfoIsInvisible) != 0;
#endif


+ 536
- 25
juce_amalgamated.h View File

@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 21
#define JUCE_BUILDNUMBER 23

/** Current Juce version number.

@@ -2496,9 +2496,9 @@ public:
if (byte >= 0)
return byte;

juce_wchar n = byte;
juce_wchar mask = 0x7f;
juce_wchar bit = 0x40;
uint32 n = (uint32) (uint8) byte;
uint32 mask = 0x7f;
uint32 bit = 0x40;
size_t numExtraValues = 0;

while ((n & bit) != 0 && bit > 0x10)
@@ -2521,7 +2521,7 @@ public:
n |= (nextByte & 0x3f);
}

return n;
return (juce_wchar) n;
}

/** Moves this pointer along to the next character in the string. */
@@ -2881,6 +2881,51 @@ public:
/** Returns the first non-whitespace character in the string. */
CharPointer_UTF8 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }

/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 0x10ffff;
}

/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
while (--maxBytesToRead >= 0 && *dataToTest != 0)
{
const char byte = *dataToTest;

if (byte < 0)
{
uint32 n = (uint32) (uint8) byte;
uint32 mask = 0x7f;
uint32 bit = 0x40;
int numExtraValues = 0;

while ((n & bit) != 0)
{
if (bit <= 0x10)
return false;

mask >>= 1;
++numExtraValues;
bit >>= 1;
}

n &= mask;

while (--numExtraValues >= 0)
{
const uint32 nextByte = (uint32) (uint8) *dataToTest++;

if ((nextByte & 0xc0) != 0x80)
return false;
}
}
}

return true;
}

/** These values are the byte-order-mark (BOM) values for a UTF-8 stream. */
enum
{
@@ -3268,6 +3313,43 @@ public:
/** Returns the first non-whitespace character in the string. */
CharPointer_UTF16 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }

/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 0x10ffff
&& (((unsigned int) character) < 0xd800 || ((unsigned int) character) > 0xdfff);
}

/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
maxBytesToRead /= sizeof (CharType);

while (--maxBytesToRead >= 0 && *dataToTest != 0)
{
const uint32 n = (uint32) (uint16) *dataToTest++;

if (n >= 0xd800)
{
if (n > 0x10ffff)
return false;

if (n <= 0xdfff)
{
if (n > 0xdc00)
return false;

const uint32 nextChar = (uint32) (uint16) *dataToTest++;

if (nextChar < 0xdc00 || nextChar > 0xdfff)
return false;
}
}
}

return true;
}

/** These values are the byte-order-mark (BOM) values for a UTF-16 stream. */
enum
{
@@ -3377,7 +3459,7 @@ public:
CharPointer_UTF32 operator++ (int) throw()
{
CharPointer_UTF32 temp (*this);
++*this;
++data;
return temp;
}

@@ -3612,6 +3694,25 @@ public:
/** Returns the first non-whitespace character in the string. */
CharPointer_UTF32 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }

/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 0x10ffff;
}

/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
maxBytesToRead /= sizeof (CharType);

while (--maxBytesToRead >= 0 && *dataToTest != 0)
if (! canRepresent (*dataToTest++))
return false;

return true;
}

/** Atomically swaps this pointer for a new value, returning the previous value. */
CharPointer_UTF32 atomicSwap (const CharPointer_UTF32& newValue)
{
return CharPointer_UTF32 (reinterpret_cast <Atomic<CharType*>&> (data).exchange (newValue.data));
@@ -3624,6 +3725,364 @@ private:
#endif // __JUCE_CHARPOINTER_UTF32_JUCEHEADER__
/*** End of inlined file: juce_CharPointer_UTF32.h ***/


/*** Start of inlined file: juce_CharPointer_ASCII.h ***/
#ifndef __JUCE_CHARPOINTER_ASCII_JUCEHEADER__
#define __JUCE_CHARPOINTER_ASCII_JUCEHEADER__

/**
Wraps a pointer to a null-terminated ASCII character string, and provides
various methods to operate on the data.

A valid ASCII string is assumed to not contain any characters above 127.

@see CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32
*/
class CharPointer_ASCII
{
public:
typedef char CharType;

inline explicit CharPointer_ASCII (const CharType* const rawPointer) throw()
: data (const_cast <CharType*> (rawPointer))
{
}

inline CharPointer_ASCII (const CharPointer_ASCII& other) throw()
: data (other.data)
{
}

inline CharPointer_ASCII& operator= (const CharPointer_ASCII& other) throw()
{
data = other.data;
return *this;
}

inline CharPointer_ASCII& operator= (const CharType* text) throw()
{
data = const_cast <CharType*> (text);
return *this;
}

/** This is a pointer comparison, it doesn't compare the actual text. */
inline bool operator== (const CharPointer_ASCII& other) const throw()
{
return data == other.data;
}

/** This is a pointer comparison, it doesn't compare the actual text. */
inline bool operator!= (const CharPointer_ASCII& other) const throw()
{
return data == other.data;
}

/** Returns the address that this pointer is pointing to. */
inline CharType* getAddress() const throw() { return data; }

/** Returns the address that this pointer is pointing to. */
inline operator const CharType*() const throw() { return data; }

/** Returns true if this pointer is pointing to a null character. */
inline bool isEmpty() const throw() { return *data == 0; }

/** Returns the unicode character that this pointer is pointing to. */
inline juce_wchar operator*() const throw() { return *data; }

/** Moves this pointer along to the next character in the string. */
inline CharPointer_ASCII& operator++() throw()
{
++data;
return *this;
}

/** Moves this pointer to the previous character in the string. */
inline CharPointer_ASCII& operator--() throw()
{
--data;
return *this;
}

/** Returns the character that this pointer is currently pointing to, and then
advances the pointer to point to the next character. */
inline juce_wchar getAndAdvance() throw() { return *data++; }

/** Moves this pointer along to the next character in the string. */
CharPointer_ASCII operator++ (int) throw()
{
CharPointer_ASCII temp (*this);
++data;
return temp;
}

/** Moves this pointer forwards by the specified number of characters. */
inline void operator+= (const int numToSkip) throw()
{
data += numToSkip;
}

inline void operator-= (const int numToSkip) throw()
{
data -= numToSkip;
}

/** Returns the character at a given character index from the start of the string. */
inline juce_wchar operator[] (const int characterIndex) const throw()
{
return (juce_wchar) (unsigned char) data [characterIndex];
}

/** Returns a pointer which is moved forwards from this one by the specified number of characters. */
CharPointer_ASCII operator+ (const int numToSkip) const throw()
{
return CharPointer_ASCII (data + numToSkip);
}

/** Returns a pointer which is moved backwards from this one by the specified number of characters. */
CharPointer_ASCII operator- (const int numToSkip) const throw()
{
return CharPointer_ASCII (data - numToSkip);
}

/** Writes a unicode character to this string, and advances this pointer to point to the next position. */
inline void write (const juce_wchar charToWrite) throw()
{
*data++ = (char) charToWrite;
}

inline void replaceChar (const juce_wchar newChar) throw()
{
*data = (char) newChar;
}

/** Writes a null character to this string (leaving the pointer's position unchanged). */
inline void writeNull() const throw()
{
*data = 0;
}

/** Returns the number of characters in this string. */
size_t length() const throw()
{
return (size_t) strlen (data);
}

/** Returns the number of characters in this string, or the given value, whichever is lower. */
size_t lengthUpTo (const size_t maxCharsToCount) const throw()
{
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
}

/** Returns the number of bytes that are used to represent this string.
This includes the terminating null character.
*/
size_t sizeInBytes() const throw()
{
return length() + 1;
}

/** Returns the number of bytes that would be needed to represent the given
unicode character in this encoding format.
*/
static inline size_t getBytesRequiredFor (const juce_wchar) throw()
{
return 1;
}

/** Returns the number of bytes that would be needed to represent the given
string in this encoding format.
The value returned does NOT include the terminating null character.
*/
template <class CharPointer>
static size_t getBytesRequiredFor (const CharPointer& text) throw()
{
return text.length();
}

/** Returns a pointer to the null character that terminates this string. */
CharPointer_ASCII findTerminatingNull() const throw()
{
return CharPointer_ASCII (data + length());
}

/** Copies a source string to this pointer, advancing this pointer as it goes. */
template <typename CharPointer>
void writeAll (const CharPointer& src) throw()
{
CharacterFunctions::copyAll (*this, src);
}

/** Copies a source string to this pointer, advancing this pointer as it goes. */
void writeAll (const CharPointer_ASCII& src) throw()
{
strcpy (data, src.data);
}

/** Copies a source string to this pointer, advancing this pointer as it goes.
The maxDestBytes parameter specifies the maximum number of bytes that can be written
to the destination buffer before stopping.
*/
template <typename CharPointer>
int writeWithDestByteLimit (const CharPointer& src, const int maxDestBytes) throw()
{
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
}

/** Copies a source string to this pointer, advancing this pointer as it goes.
The maxChars parameter specifies the maximum number of characters that can be
written to the destination buffer before stopping (including the terminating null).
*/
template <typename CharPointer>
void writeWithCharLimit (const CharPointer& src, const int maxChars) throw()
{
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
}

/** Compares this string with another one. */
template <typename CharPointer>
int compare (const CharPointer& other) const throw()
{
return CharacterFunctions::compare (*this, other);
}

/** Compares this string with another one. */
int compare (const CharPointer_ASCII& other) const throw()
{
return strcmp (data, other.data);
}

/** Compares this string with another one, up to a specified number of characters. */
template <typename CharPointer>
int compareUpTo (const CharPointer& other, const int maxChars) const throw()
{
return CharacterFunctions::compareUpTo (*this, other, maxChars);
}

/** Compares this string with another one, up to a specified number of characters. */
int compareUpTo (const CharPointer_ASCII& other, const int maxChars) const throw()
{
return strncmp (data, other.data, (size_t) maxChars);
}

/** Compares this string with another one. */
template <typename CharPointer>
int compareIgnoreCase (const CharPointer& other) const
{
return CharacterFunctions::compareIgnoreCase (*this, other);
}

int compareIgnoreCase (const CharPointer_ASCII& other) const
{
#if JUCE_WINDOWS
return stricmp (data, other.data);
#else
return strcasecmp (data, other.data);
#endif
}

/** Compares this string with another one, up to a specified number of characters. */
template <typename CharPointer>
int compareIgnoreCaseUpTo (const CharPointer& other, const int maxChars) const throw()
{
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
}

/** Returns the character index of a substring, or -1 if it isn't found. */
template <typename CharPointer>
int indexOf (const CharPointer& stringToFind) const throw()
{
return CharacterFunctions::indexOf (*this, stringToFind);
}

/** Returns the character index of a unicode character, or -1 if it isn't found. */
int indexOf (const juce_wchar charToFind) const throw()
{
int i = 0;

while (data[i] != 0)
{
if (data[i] == (char) charToFind)
return i;

++i;
}

return -1;
}

/** Returns the character index of a unicode character, or -1 if it isn't found. */
int indexOf (const juce_wchar charToFind, const bool ignoreCase) const throw()
{
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
: CharacterFunctions::indexOfChar (*this, charToFind);
}

/** Returns true if the first character of this string is whitespace. */
bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; }
/** Returns true if the first character of this string is a digit. */
bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; }
/** Returns true if the first character of this string is a letter. */
bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; }
/** Returns true if the first character of this string is a letter or digit. */
bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; }
/** Returns true if the first character of this string is upper-case. */
bool isUpperCase() const { return CharacterFunctions::isUpperCase (*data) != 0; }
/** Returns true if the first character of this string is lower-case. */
bool isLowerCase() const { return CharacterFunctions::isLowerCase (*data) != 0; }

/** Returns an upper-case version of the first character of this string. */
juce_wchar toUpperCase() const throw() { return CharacterFunctions::toUpperCase (*data); }
/** Returns a lower-case version of the first character of this string. */
juce_wchar toLowerCase() const throw() { return CharacterFunctions::toLowerCase (*data); }

/** Parses this string as a 32-bit integer. */
int getIntValue32() const throw() { return atoi (data); }

/** Parses this string as a 64-bit integer. */
int64 getIntValue64() const throw()
{
#if JUCE_LINUX || JUCE_ANDROID
return atoll (data);
#elif JUCE_WINDOWS
return _atoi64 (data);
#else
return CharacterFunctions::getIntValue <int64, CharPointer_ASCII> (*this);
#endif
}

/** Parses this string as a floating point double. */
double getDoubleValue() const throw() { return CharacterFunctions::getDoubleValue (*this); }

/** Returns the first non-whitespace character in the string. */
CharPointer_ASCII findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }

/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 128;
}

/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
while (--maxBytesToRead >= 0)
{
if (*dataToTest <= 0)
return *dataToTest == 0;

++dataToTest;
}

return true;
}

private:
CharType* data;
};

#endif // __JUCE_CHARPOINTER_ASCII_JUCEHEADER__
/*** End of inlined file: juce_CharPointer_ASCII.h ***/

#if JUCE_MSVC
#pragma warning (pop)
#endif
@@ -3644,7 +4103,6 @@ class JUCE_API String
public:

/** Creates an empty string.

@see empty
*/
String() throw();
@@ -3652,15 +4110,36 @@ public:
/** Creates a copy of another string. */
String (const String& other) throw();

/** Creates a string from a zero-terminated text string.
The string is assumed to be stored in the default system encoding.
/** Creates a string from a zero-terminated ascii text string.

The string passed-in must not contain any characters with a value above 127, because
these can't be converted to unicode without knowing the original encoding that was
used to create the string. If you attempt to pass-in values above 127, you'll get an
assertion.

To create strings with extended characters from UTF-8, you should explicitly call
String (CharPointer_UTF8 ("my utf8 string..")). It's *highly* recommended that you
use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent unicode strings in a way that isn't dependent
on the compiler, source code editor and platform.
*/
String (const char* text);

/** Creates a string from an string of characters.
/** Creates a string from a string of 8-bit ascii characters.

This will use up the the first maxChars characters of the string (or
less if the string is actually shorter)
The string passed-in must not contain any characters with a value above 127, because
these can't be converted to unicode without knowing the original encoding that was
used to create the string. If you attempt to pass-in values above 127, you'll get an
assertion.

To create strings with extended characters from UTF-8, you should explicitly call
String (CharPointer_UTF8 ("my utf8 string..")). It's *highly* recommended that you
use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent unicode strings in a way that isn't dependent
on the compiler, source code editor and platform.

This will use up the the first maxChars characters of the string (or less if the string
is actually shorter).
*/
String (const char* text, size_t maxChars);

@@ -3686,6 +4165,9 @@ public:
/** Creates a string from a UTF-32 character string */
String (const CharPointer_UTF32& text, size_t maxChars);

/** Creates a string from an ASCII character string */
String (const CharPointer_ASCII& text);

#if JUCE_WINDOWS
/** Creates a string from a UTF-16 character string */
String (const wchar_t* text);
@@ -15559,16 +16041,34 @@ public:
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
const Identifier& property) = 0;

/** This method is called when a child sub-tree is added or removed.
/** This method is called when a child sub-tree is added.

Note that when you register a listener to a tree, it will receive this callback for
child changes in both that tree and any of its children, (recursively, at any depth).
If your tree has sub-trees but you only want to know about changes to the top level tree,
just check the parentTree parameter to make sure it's the one that you're interested in.
*/
virtual void valueTreeChildAdded (ValueTree& parentTree,
ValueTree& childWhichHasBeenAdded) = 0;

/** This method is called when a child sub-tree is removed.

Note that when you register a listener to a tree, it will receive this callback for
child changes in both that tree and any of its children, (recursively, at any depth).
If your tree has sub-trees but you only want to know about changes to the top level tree,
just check the parentTree parameter to make sure it's the one that you're interested in.
*/
virtual void valueTreeChildRemoved (ValueTree& parentTree,
ValueTree& childWhichHasBeenRemoved) = 0;

The tree parameter indicates the tree whose child was added or removed.
/** This method is called when a tree's children have been re-shuffled.

Note that when you register a listener to a tree, it will receive this callback for
child changes in that tree, and also in any of its children, (recursively, at any depth).
child changes in both that tree and any of its children, (recursively, at any depth).
If your tree has sub-trees but you only want to know about changes to the top level tree,
simply check the tree parameter in this callback to make sure it's the tree you're interested in.
just check the parameter to make sure it's the tree that you're interested in.
*/
virtual void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) = 0;
virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved) = 0;

/** This method is called when a tree has been added or removed from a parent node.

@@ -15660,8 +16160,12 @@ private:

void sendPropertyChangeMessage (const Identifier& property);
void sendPropertyChangeMessage (ValueTree& tree, const Identifier& property);
void sendChildChangeMessage();
void sendChildChangeMessage (ValueTree& tree);
void sendChildAddedMessage (ValueTree& parent, ValueTree& child);
void sendChildAddedMessage (ValueTree child);
void sendChildRemovedMessage (ValueTree& parent, ValueTree& child);
void sendChildRemovedMessage (ValueTree child);
void sendChildOrderChangedMessage (ValueTree& parent);
void sendChildOrderChangedMessage();
void sendParentChangeMessage();
const var& getProperty (const Identifier& name) const;
const var getProperty (const Identifier& name, const var& defaultReturnValue) const;
@@ -20054,6 +20558,9 @@ private:
#endif
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__

#endif
#ifndef __JUCE_CHARPOINTER_ASCII_JUCEHEADER__

#endif
#ifndef __JUCE_CHARPOINTER_UTF16_JUCEHEADER__

@@ -20368,7 +20875,7 @@ public:

private:
String originalText;
CharPointer_UTF32 input;
String::CharPointerType input;
bool outOfData, errorOccurred;

String lastError, dtdText;
@@ -40505,16 +41012,16 @@ public:
virtual ~Listener() {}

/** Called when the user changes the text in some way. */
virtual void textEditorTextChanged (TextEditor& editor) = 0;
virtual void textEditorTextChanged (TextEditor& editor);

/** Called when the user presses the return key. */
virtual void textEditorReturnKeyPressed (TextEditor& editor) = 0;
virtual void textEditorReturnKeyPressed (TextEditor& editor);

/** Called when the user presses the escape key. */
virtual void textEditorEscapeKeyPressed (TextEditor& editor) = 0;
virtual void textEditorEscapeKeyPressed (TextEditor& editor);

/** Called when the text editor loses focus. */
virtual void textEditorFocusLost (TextEditor& editor) = 0;
virtual void textEditorFocusLost (TextEditor& editor);
};

/** Registers a listener to be told when things happen to the text.
@@ -47918,7 +48425,11 @@ public:
/** @internal */
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
/** @internal */
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
/** @internal */
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
/** @internal */
void valueTreeChildOrderChanged (ValueTree& parentTree);
/** @internal */
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);



+ 37
- 23
src/audio/audio_file_formats/juce_WavAudioFormat.cpp View File

@@ -498,8 +498,7 @@ public:
: AudioFormatWriter (out, TRANS (wavFormatName), sampleRate_, numChannels_, bits),
lengthInSamples (0),
bytesWritten (0),
writeFailed (false),
isRF64 (false)
writeFailed (false)
{
using namespace WavFileHelpers;
@@ -567,7 +566,7 @@ private:
MemoryBlock tempBlock, bwavChunk, smplChunk;
uint64 lengthInSamples, bytesWritten;
int64 headerPosition;
bool writeFailed, isRF64;
bool writeFailed;
static int getChannelMask (const int numChannels) throw()
{
@@ -596,14 +595,15 @@ private:
const int bytesPerFrame = numChannels * bitsPerSample / 8;
int64 audioDataSize = bytesPerFrame * lengthInSamples;
int64 riffChunkSize = 4 /* 'WAVE' */ + 8 + 40 /* WAVEFORMATEX */
const bool isRF64 = (bytesWritten >= literal64bit (0x100000000));
int64 riffChunkSize = 4 /* 'RIFF' */ + 8 + 40 /* WAVEFORMATEX */
+ 8 + audioDataSize + (audioDataSize & 1)
+ (bwavChunk.getSize() > 0 ? (8 + bwavChunk.getSize()) : 0)
+ (smplChunk.getSize() > 0 ? (8 + smplChunk.getSize()) : 0)
+ (8 + 28); // (JUNK chunk)
+ (8 + 28); // (ds64 chunk)
riffChunkSize += (riffChunkSize & 0x1);
isRF64 = (riffChunkSize > 0xffffffff);
output->writeInt (chunkName (isRF64 ? "RF64" : "RIFF"));
output->writeInt (isRF64 ? -1 : (int) riffChunkSize);
@@ -611,10 +611,9 @@ private:
if (! isRF64)
{
// write Junk chunk
output->writeInt (chunkName ("JUNK"));
output->writeInt (28);
output->writeRepeatedByte (0, 28);
output->writeInt (28 + 24);
output->writeRepeatedByte (0, 28 /* ds64 */ + 24 /* extra waveformatex */);
}
else
{
@@ -627,29 +626,44 @@ private:
}
output->writeInt (chunkName ("fmt "));
output->writeInt (40); // WAVEFORMATEX chunk size
output->writeShort ((short) (uint16) 0xfffe); // WAVE_FORMAT_EXTENSIBLE
if (isRF64)
{
output->writeInt (40); // chunk size
output->writeShort ((short) (uint16) 0xfffe); // WAVE_FORMAT_EXTENSIBLE
}
else
{
output->writeInt (16); // chunk size
output->writeShort (bitsPerSample < 32 ? (short) 1 /*WAVE_FORMAT_PCM*/
: (short) 3 /*WAVE_FORMAT_IEEE_FLOAT*/);
}
output->writeShort ((short) numChannels);
output->writeInt ((int) sampleRate);
output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec
output->writeShort ((short) bytesPerFrame); // nBlockAlign
output->writeShort ((short) bitsPerSample); // wBitsPerSample
output->writeShort (22); // cbSize (size of the extension)
output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
output->writeInt (getChannelMask (numChannels));
const ExtensibleWavSubFormat pcmFormat
= { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
if (isRF64)
{
output->writeShort (22); // cbSize (size of the extension)
output->writeShort ((short) bitsPerSample); // wValidBitsPerSample
output->writeInt (getChannelMask (numChannels));
const ExtensibleWavSubFormat pcmFormat
= { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
const ExtensibleWavSubFormat IEEEFloatFormat
= { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
const ExtensibleWavSubFormat IEEEFloatFormat
= { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;
const ExtensibleWavSubFormat& subFormat = bitsPerSample < 32 ? pcmFormat : IEEEFloatFormat;
output->writeInt ((int) subFormat.data1);
output->writeShort ((short) subFormat.data2);
output->writeShort ((short) subFormat.data3);
output->write (subFormat.data4, sizeof (subFormat.data4));
output->writeInt ((int) subFormat.data1);
output->writeShort ((short) subFormat.data2);
output->writeShort ((short) subFormat.data3);
output->write (subFormat.data4, sizeof (subFormat.data4));
}
if (bwavChunk.getSize() > 0)
{


+ 62
- 13
src/containers/juce_ValueTree.cpp View File

@@ -250,24 +250,68 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (const Identifier& prope
}
}
void ValueTree::SharedObject::sendChildChangeMessage (ValueTree& tree)
void ValueTree::SharedObject::sendChildAddedMessage (ValueTree& tree, ValueTree& child)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
ValueTree* const v = valueTreesWithListeners[i];
if (v != 0)
v->listeners.call (&ValueTree::Listener::valueTreeChildrenChanged, tree);
v->listeners.call (&ValueTree::Listener::valueTreeChildAdded, tree, child);
}
}
void ValueTree::SharedObject::sendChildChangeMessage()
void ValueTree::SharedObject::sendChildAddedMessage (ValueTree child)
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;
while (t != 0)
{
t->sendChildChangeMessage (tree);
t->sendChildAddedMessage (tree, child);
t = t->parent;
}
}
void ValueTree::SharedObject::sendChildRemovedMessage (ValueTree& tree, ValueTree& child)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
ValueTree* const v = valueTreesWithListeners[i];
if (v != 0)
v->listeners.call (&ValueTree::Listener::valueTreeChildRemoved, tree, child);
}
}
void ValueTree::SharedObject::sendChildRemovedMessage (ValueTree child)
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;
while (t != 0)
{
t->sendChildRemovedMessage (tree, child);
t = t->parent;
}
}
void ValueTree::SharedObject::sendChildOrderChangedMessage (ValueTree& tree)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
ValueTree* const v = valueTreesWithListeners[i];
if (v != 0)
v->listeners.call (&ValueTree::Listener::valueTreeChildOrderChanged, tree);
}
}
void ValueTree::SharedObject::sendChildOrderChangedMessage()
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;
while (t != 0)
{
t->sendChildOrderChangedMessage (tree);
t = t->parent;
}
}
@@ -434,7 +478,7 @@ void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoMana
{
children.insert (index, child);
child->parent = this;
sendChildChangeMessage();
sendChildAddedMessage (ValueTree (child));
child->sendParentChangeMessage();
}
else
@@ -464,7 +508,7 @@ void ValueTree::SharedObject::removeChild (const int childIndex, UndoManager* co
{
children.remove (childIndex);
child->parent = 0;
sendChildChangeMessage();
sendChildRemovedMessage (ValueTree (child));
child->sendParentChangeMessage();
}
else
@@ -491,7 +535,7 @@ void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoMan
if (undoManager == 0)
{
children.move (currentIndex, newIndex);
sendChildChangeMessage();
sendChildOrderChangedMessage();
}
else
{
@@ -510,16 +554,19 @@ void ValueTree::SharedObject::reorderChildren (const ReferenceCountedArray <Shar
if (undoManager == 0)
{
children = newOrder;
sendChildChangeMessage();
sendChildOrderChangedMessage();
}
else
{
for (int i = 0; i < children.size(); ++i)
{
if (children.getUnchecked(i) != newOrder.getUnchecked(i))
const SharedObjectPtr child (newOrder.getUnchecked(i));
if (children.getUnchecked(i) != child)
{
jassert (children.contains (newOrder.getUnchecked(i)));
moveChild (children.indexOf (newOrder.getUnchecked(i)), i, undoManager);
const int oldIndex = children.indexOf (child);
jassert (oldIndex >= 0);
moveChild (oldIndex, i, undoManager);
}
}
}
@@ -719,8 +766,10 @@ public:
sendChangeMessage (false);
}
void valueTreeChildrenChanged (ValueTree&) {}
void valueTreeParentChanged (ValueTree&) {}
void valueTreeChildAdded (ValueTree&, ValueTree&) {}
void valueTreeChildRemoved (ValueTree&, ValueTree&) {}
void valueTreeChildOrderChanged (ValueTree&) {}
void valueTreeParentChanged (ValueTree&) {}
private:
ValueTree tree;


+ 29
- 7
src/containers/juce_ValueTree.h View File

@@ -368,16 +368,34 @@ public:
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
const Identifier& property) = 0;
/** This method is called when a child sub-tree is added or removed.
/** This method is called when a child sub-tree is added.
The tree parameter indicates the tree whose child was added or removed.
Note that when you register a listener to a tree, it will receive this callback for
child changes in both that tree and any of its children, (recursively, at any depth).
If your tree has sub-trees but you only want to know about changes to the top level tree,
just check the parentTree parameter to make sure it's the one that you're interested in.
*/
virtual void valueTreeChildAdded (ValueTree& parentTree,
ValueTree& childWhichHasBeenAdded) = 0;
/** This method is called when a child sub-tree is removed.
Note that when you register a listener to a tree, it will receive this callback for
child changes in that tree, and also in any of its children, (recursively, at any depth).
child changes in both that tree and any of its children, (recursively, at any depth).
If your tree has sub-trees but you only want to know about changes to the top level tree,
simply check the tree parameter in this callback to make sure it's the tree you're interested in.
just check the parentTree parameter to make sure it's the one that you're interested in.
*/
virtual void valueTreeChildRemoved (ValueTree& parentTree,
ValueTree& childWhichHasBeenRemoved) = 0;
/** This method is called when a tree's children have been re-shuffled.
Note that when you register a listener to a tree, it will receive this callback for
child changes in both that tree and any of its children, (recursively, at any depth).
If your tree has sub-trees but you only want to know about changes to the top level tree,
just check the parameter to make sure it's the tree that you're interested in.
*/
virtual void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) = 0;
virtual void valueTreeChildOrderChanged (ValueTree& parentTreeWhoseChildrenHaveMoved) = 0;
/** This method is called when a tree has been added or removed from a parent node.
@@ -470,8 +488,12 @@ private:
void sendPropertyChangeMessage (const Identifier& property);
void sendPropertyChangeMessage (ValueTree& tree, const Identifier& property);
void sendChildChangeMessage();
void sendChildChangeMessage (ValueTree& tree);
void sendChildAddedMessage (ValueTree& parent, ValueTree& child);
void sendChildAddedMessage (ValueTree child);
void sendChildRemovedMessage (ValueTree& parent, ValueTree& child);
void sendChildRemovedMessage (ValueTree child);
void sendChildOrderChangedMessage (ValueTree& parent);
void sendChildOrderChangedMessage();
void sendParentChangeMessage();
const var& getProperty (const Identifier& name) const;
const var getProperty (const Identifier& name, const var& defaultReturnValue) const;


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 21
#define JUCE_BUILDNUMBER 23
/** Current Juce version number.


+ 1
- 0
src/gui/components/buttons/juce_DrawableButton.cpp View File

@@ -180,6 +180,7 @@ void DrawableButton::buttonStateChanged()
if (currentImage != 0)
{
currentImage->setInterceptsMouseClicks (false, false);
addAndMakeVisible (currentImage);
DrawableButton::resized();
}


+ 4
- 0
src/gui/components/controls/juce_TextEditor.cpp View File

@@ -2621,5 +2621,9 @@ void TextEditor::coalesceSimilarSections()
}
}
void TextEditor::Listener::textEditorTextChanged (TextEditor&) {}
void TextEditor::Listener::textEditorReturnKeyPressed (TextEditor&) {}
void TextEditor::Listener::textEditorEscapeKeyPressed (TextEditor&) {}
void TextEditor::Listener::textEditorFocusLost (TextEditor&) {}
END_JUCE_NAMESPACE

+ 4
- 4
src/gui/components/controls/juce_TextEditor.h View File

@@ -313,16 +313,16 @@ public:
virtual ~Listener() {}
/** Called when the user changes the text in some way. */
virtual void textEditorTextChanged (TextEditor& editor) = 0;
virtual void textEditorTextChanged (TextEditor& editor);
/** Called when the user presses the return key. */
virtual void textEditorReturnKeyPressed (TextEditor& editor) = 0;
virtual void textEditorReturnKeyPressed (TextEditor& editor);
/** Called when the user presses the escape key. */
virtual void textEditorEscapeKeyPressed (TextEditor& editor) = 0;
virtual void textEditorEscapeKeyPressed (TextEditor& editor);
/** Called when the text editor loses focus. */
virtual void textEditorFocusLost (TextEditor& editor) = 0;
virtual void textEditorFocusLost (TextEditor& editor);
};
/** Registers a listener to be told when things happen to the text.


+ 11
- 1
src/gui/components/layout/juce_ComponentBuilder.cpp View File

@@ -201,7 +201,17 @@ void ComponentBuilder::valueTreePropertyChanged (ValueTree& tree, const Identifi
ComponentBuilderHelpers::updateComponent (*this, tree);
}
void ComponentBuilder::valueTreeChildrenChanged (ValueTree& tree)
void ComponentBuilder::valueTreeChildAdded (ValueTree& tree, ValueTree&)
{
ComponentBuilderHelpers::updateComponent (*this, tree);
}
void ComponentBuilder::valueTreeChildRemoved (ValueTree& tree, ValueTree&)
{
ComponentBuilderHelpers::updateComponent (*this, tree);
}
void ComponentBuilder::valueTreeChildOrderChanged (ValueTree& tree)
{
ComponentBuilderHelpers::updateComponent (*this, tree);
}


+ 5
- 1
src/gui/components/layout/juce_ComponentBuilder.h View File

@@ -229,7 +229,11 @@ public:
/** @internal */
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
/** @internal */
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
/** @internal */
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
/** @internal */
void valueTreeChildOrderChanged (ValueTree& parentTree);
/** @internal */
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);


+ 6
- 7
src/gui/components/menus/juce_PopupMenu.cpp View File

@@ -135,17 +135,21 @@ class PopupMenu::ItemComponent : public Component
{
public:
//==============================================================================
ItemComponent (const PopupMenu::Item& itemInfo_, int standardItemHeight)
ItemComponent (const PopupMenu::Item& itemInfo_, int standardItemHeight, Component* const parent)
: itemInfo (itemInfo_),
isHighlighted (false)
{
if (itemInfo.customComp != 0)
addAndMakeVisible (itemInfo.customComp);
parent->addAndMakeVisible (this);
int itemW = 80;
int itemH = 16;
getIdealSize (itemW, itemH, standardItemHeight);
setSize (itemW, jlimit (2, 600, itemH));
addMouseListener (parent, false);
}
~ItemComponent()
@@ -277,12 +281,7 @@ public:
setOpaque (getLookAndFeel().findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows());
for (int i = 0; i < menu.items.size(); ++i)
{
PopupMenu::ItemComponent* const itemComp = new PopupMenu::ItemComponent (*menu.items.getUnchecked(i), standardItemHeight);
items.add (itemComp);
addAndMakeVisible (itemComp);
itemComp->addMouseListener (this, false);
}
items.add (new PopupMenu::ItemComponent (*menu.items.getUnchecked(i), standardItemHeight, this));
calculateWindowPos (target, alignToRectangle);
setTopLeftPosition (windowPos.getX(), windowPos.getY());


+ 6
- 0
src/gui/graphics/drawables/juce_DrawableShape.cpp View File

@@ -198,6 +198,12 @@ const Rectangle<float> DrawableShape::getDrawableBounds() const
bool DrawableShape::hitTest (int x, int y)
{
bool allowsClicksOnThisComponent, allowsClicksOnChildComponents;
getInterceptsMouseClicks (allowsClicksOnThisComponent, allowsClicksOnChildComponents);
if (! allowsClicksOnThisComponent)
return false;
const float globalX = (float) (x - originRelativeToComponent.getX());
const float globalY = (float) (y - originRelativeToComponent.getY());


+ 3
- 0
src/juce_core_includes.h View File

@@ -233,6 +233,9 @@
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
#include "text/juce_CharacterFunctions.h"
#endif
#ifndef __JUCE_CHARPOINTER_ASCII_JUCEHEADER__
#include "text/juce_CharPointer_ASCII.h"
#endif
#ifndef __JUCE_CHARPOINTER_UTF16_JUCEHEADER__
#include "text/juce_CharPointer_UTF16.h"
#endif


+ 1
- 1
src/native/mac/juce_mac_Files.mm View File

@@ -92,7 +92,7 @@ namespace FileHelpers
FSRef ref;
LSItemInfoRecord info;
return FSPathMakeRefWithOptions ((const UInt8*) path.toUTF8(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr
return FSPathMakeRefWithOptions ((const UInt8*) path.toUTF8().getAddress(), kFSPathMakeRefDoNotFollowLeafSymlink, &ref, 0) == noErr
&& LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr
&& (info.flags & kLSItemInfoIsInvisible) != 0;
#endif


+ 1
- 1
src/native/windows/juce_win32_Misc.cpp View File

@@ -35,7 +35,7 @@ void SystemClipboard::copyTextToClipboard (const String& text)
{
if (EmptyClipboard() != 0)
{
const int bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
const int bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()) + 4;
if (bytesNeeded > 0)
{


+ 382
- 0
src/text/juce_CharPointer_ASCII.h View File

@@ -0,0 +1,382 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#ifndef __JUCE_CHARPOINTER_ASCII_JUCEHEADER__
#define __JUCE_CHARPOINTER_ASCII_JUCEHEADER__
//==============================================================================
/**
Wraps a pointer to a null-terminated ASCII character string, and provides
various methods to operate on the data.
A valid ASCII string is assumed to not contain any characters above 127.
@see CharPointer_UTF8, CharPointer_UTF16, CharPointer_UTF32
*/
class CharPointer_ASCII
{
public:
typedef char CharType;
inline explicit CharPointer_ASCII (const CharType* const rawPointer) throw()
: data (const_cast <CharType*> (rawPointer))
{
}
inline CharPointer_ASCII (const CharPointer_ASCII& other) throw()
: data (other.data)
{
}
inline CharPointer_ASCII& operator= (const CharPointer_ASCII& other) throw()
{
data = other.data;
return *this;
}
inline CharPointer_ASCII& operator= (const CharType* text) throw()
{
data = const_cast <CharType*> (text);
return *this;
}
/** This is a pointer comparison, it doesn't compare the actual text. */
inline bool operator== (const CharPointer_ASCII& other) const throw()
{
return data == other.data;
}
/** This is a pointer comparison, it doesn't compare the actual text. */
inline bool operator!= (const CharPointer_ASCII& other) const throw()
{
return data == other.data;
}
/** Returns the address that this pointer is pointing to. */
inline CharType* getAddress() const throw() { return data; }
/** Returns the address that this pointer is pointing to. */
inline operator const CharType*() const throw() { return data; }
/** Returns true if this pointer is pointing to a null character. */
inline bool isEmpty() const throw() { return *data == 0; }
/** Returns the unicode character that this pointer is pointing to. */
inline juce_wchar operator*() const throw() { return *data; }
/** Moves this pointer along to the next character in the string. */
inline CharPointer_ASCII& operator++() throw()
{
++data;
return *this;
}
/** Moves this pointer to the previous character in the string. */
inline CharPointer_ASCII& operator--() throw()
{
--data;
return *this;
}
/** Returns the character that this pointer is currently pointing to, and then
advances the pointer to point to the next character. */
inline juce_wchar getAndAdvance() throw() { return *data++; }
/** Moves this pointer along to the next character in the string. */
CharPointer_ASCII operator++ (int) throw()
{
CharPointer_ASCII temp (*this);
++data;
return temp;
}
/** Moves this pointer forwards by the specified number of characters. */
inline void operator+= (const int numToSkip) throw()
{
data += numToSkip;
}
inline void operator-= (const int numToSkip) throw()
{
data -= numToSkip;
}
/** Returns the character at a given character index from the start of the string. */
inline juce_wchar operator[] (const int characterIndex) const throw()
{
return (juce_wchar) (unsigned char) data [characterIndex];
}
/** Returns a pointer which is moved forwards from this one by the specified number of characters. */
CharPointer_ASCII operator+ (const int numToSkip) const throw()
{
return CharPointer_ASCII (data + numToSkip);
}
/** Returns a pointer which is moved backwards from this one by the specified number of characters. */
CharPointer_ASCII operator- (const int numToSkip) const throw()
{
return CharPointer_ASCII (data - numToSkip);
}
/** Writes a unicode character to this string, and advances this pointer to point to the next position. */
inline void write (const juce_wchar charToWrite) throw()
{
*data++ = (char) charToWrite;
}
inline void replaceChar (const juce_wchar newChar) throw()
{
*data = (char) newChar;
}
/** Writes a null character to this string (leaving the pointer's position unchanged). */
inline void writeNull() const throw()
{
*data = 0;
}
/** Returns the number of characters in this string. */
size_t length() const throw()
{
return (size_t) strlen (data);
}
/** Returns the number of characters in this string, or the given value, whichever is lower. */
size_t lengthUpTo (const size_t maxCharsToCount) const throw()
{
return CharacterFunctions::lengthUpTo (*this, maxCharsToCount);
}
/** Returns the number of bytes that are used to represent this string.
This includes the terminating null character.
*/
size_t sizeInBytes() const throw()
{
return length() + 1;
}
/** Returns the number of bytes that would be needed to represent the given
unicode character in this encoding format.
*/
static inline size_t getBytesRequiredFor (const juce_wchar) throw()
{
return 1;
}
/** Returns the number of bytes that would be needed to represent the given
string in this encoding format.
The value returned does NOT include the terminating null character.
*/
template <class CharPointer>
static size_t getBytesRequiredFor (const CharPointer& text) throw()
{
return text.length();
}
/** Returns a pointer to the null character that terminates this string. */
CharPointer_ASCII findTerminatingNull() const throw()
{
return CharPointer_ASCII (data + length());
}
/** Copies a source string to this pointer, advancing this pointer as it goes. */
template <typename CharPointer>
void writeAll (const CharPointer& src) throw()
{
CharacterFunctions::copyAll (*this, src);
}
/** Copies a source string to this pointer, advancing this pointer as it goes. */
void writeAll (const CharPointer_ASCII& src) throw()
{
strcpy (data, src.data);
}
/** Copies a source string to this pointer, advancing this pointer as it goes.
The maxDestBytes parameter specifies the maximum number of bytes that can be written
to the destination buffer before stopping.
*/
template <typename CharPointer>
int writeWithDestByteLimit (const CharPointer& src, const int maxDestBytes) throw()
{
return CharacterFunctions::copyWithDestByteLimit (*this, src, maxDestBytes);
}
/** Copies a source string to this pointer, advancing this pointer as it goes.
The maxChars parameter specifies the maximum number of characters that can be
written to the destination buffer before stopping (including the terminating null).
*/
template <typename CharPointer>
void writeWithCharLimit (const CharPointer& src, const int maxChars) throw()
{
CharacterFunctions::copyWithCharLimit (*this, src, maxChars);
}
/** Compares this string with another one. */
template <typename CharPointer>
int compare (const CharPointer& other) const throw()
{
return CharacterFunctions::compare (*this, other);
}
/** Compares this string with another one. */
int compare (const CharPointer_ASCII& other) const throw()
{
return strcmp (data, other.data);
}
/** Compares this string with another one, up to a specified number of characters. */
template <typename CharPointer>
int compareUpTo (const CharPointer& other, const int maxChars) const throw()
{
return CharacterFunctions::compareUpTo (*this, other, maxChars);
}
/** Compares this string with another one, up to a specified number of characters. */
int compareUpTo (const CharPointer_ASCII& other, const int maxChars) const throw()
{
return strncmp (data, other.data, (size_t) maxChars);
}
/** Compares this string with another one. */
template <typename CharPointer>
int compareIgnoreCase (const CharPointer& other) const
{
return CharacterFunctions::compareIgnoreCase (*this, other);
}
int compareIgnoreCase (const CharPointer_ASCII& other) const
{
#if JUCE_WINDOWS
return stricmp (data, other.data);
#else
return strcasecmp (data, other.data);
#endif
}
/** Compares this string with another one, up to a specified number of characters. */
template <typename CharPointer>
int compareIgnoreCaseUpTo (const CharPointer& other, const int maxChars) const throw()
{
return CharacterFunctions::compareIgnoreCaseUpTo (*this, other, maxChars);
}
/** Returns the character index of a substring, or -1 if it isn't found. */
template <typename CharPointer>
int indexOf (const CharPointer& stringToFind) const throw()
{
return CharacterFunctions::indexOf (*this, stringToFind);
}
/** Returns the character index of a unicode character, or -1 if it isn't found. */
int indexOf (const juce_wchar charToFind) const throw()
{
int i = 0;
while (data[i] != 0)
{
if (data[i] == (char) charToFind)
return i;
++i;
}
return -1;
}
/** Returns the character index of a unicode character, or -1 if it isn't found. */
int indexOf (const juce_wchar charToFind, const bool ignoreCase) const throw()
{
return ignoreCase ? CharacterFunctions::indexOfCharIgnoreCase (*this, charToFind)
: CharacterFunctions::indexOfChar (*this, charToFind);
}
/** Returns true if the first character of this string is whitespace. */
bool isWhitespace() const { return CharacterFunctions::isWhitespace (*data) != 0; }
/** Returns true if the first character of this string is a digit. */
bool isDigit() const { return CharacterFunctions::isDigit (*data) != 0; }
/** Returns true if the first character of this string is a letter. */
bool isLetter() const { return CharacterFunctions::isLetter (*data) != 0; }
/** Returns true if the first character of this string is a letter or digit. */
bool isLetterOrDigit() const { return CharacterFunctions::isLetterOrDigit (*data) != 0; }
/** Returns true if the first character of this string is upper-case. */
bool isUpperCase() const { return CharacterFunctions::isUpperCase (*data) != 0; }
/** Returns true if the first character of this string is lower-case. */
bool isLowerCase() const { return CharacterFunctions::isLowerCase (*data) != 0; }
/** Returns an upper-case version of the first character of this string. */
juce_wchar toUpperCase() const throw() { return CharacterFunctions::toUpperCase (*data); }
/** Returns a lower-case version of the first character of this string. */
juce_wchar toLowerCase() const throw() { return CharacterFunctions::toLowerCase (*data); }
/** Parses this string as a 32-bit integer. */
int getIntValue32() const throw() { return atoi (data); }
/** Parses this string as a 64-bit integer. */
int64 getIntValue64() const throw()
{
#if JUCE_LINUX || JUCE_ANDROID
return atoll (data);
#elif JUCE_WINDOWS
return _atoi64 (data);
#else
return CharacterFunctions::getIntValue <int64, CharPointer_ASCII> (*this);
#endif
}
/** Parses this string as a floating point double. */
double getDoubleValue() const throw() { return CharacterFunctions::getDoubleValue (*this); }
/** Returns the first non-whitespace character in the string. */
CharPointer_ASCII findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }
/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 128;
}
/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
while (--maxBytesToRead >= 0)
{
if (*dataToTest <= 0)
return *dataToTest == 0;
++dataToTest;
}
return true;
}
private:
CharType* data;
};
#endif // __JUCE_CHARPOINTER_ASCII_JUCEHEADER__

+ 37
- 0
src/text/juce_CharPointer_UTF16.h View File

@@ -395,6 +395,43 @@ public:
/** Returns the first non-whitespace character in the string. */
CharPointer_UTF16 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }
/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 0x10ffff
&& (((unsigned int) character) < 0xd800 || ((unsigned int) character) > 0xdfff);
}
/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
maxBytesToRead /= sizeof (CharType);
while (--maxBytesToRead >= 0 && *dataToTest != 0)
{
const uint32 n = (uint32) (uint16) *dataToTest++;
if (n >= 0xd800)
{
if (n > 0x10ffff)
return false;
if (n <= 0xdfff)
{
if (n > 0xdc00)
return false;
const uint32 nextChar = (uint32) (uint16) *dataToTest++;
if (nextChar < 0xdc00 || nextChar > 0xdfff)
return false;
}
}
}
return true;
}
/** These values are the byte-order-mark (BOM) values for a UTF-16 stream. */
enum
{


+ 20
- 1
src/text/juce_CharPointer_UTF32.h View File

@@ -106,7 +106,7 @@ public:
CharPointer_UTF32 operator++ (int) throw()
{
CharPointer_UTF32 temp (*this);
++*this;
++data;
return temp;
}
@@ -341,6 +341,25 @@ public:
/** Returns the first non-whitespace character in the string. */
CharPointer_UTF32 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }
/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 0x10ffff;
}
/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
maxBytesToRead /= sizeof (CharType);
while (--maxBytesToRead >= 0 && *dataToTest != 0)
if (! canRepresent (*dataToTest++))
return false;
return true;
}
/** Atomically swaps this pointer for a new value, returning the previous value. */
CharPointer_UTF32 atomicSwap (const CharPointer_UTF32& newValue)
{
return CharPointer_UTF32 (reinterpret_cast <Atomic<CharType*>&> (data).exchange (newValue.data));


+ 49
- 4
src/text/juce_CharPointer_UTF8.h View File

@@ -88,9 +88,9 @@ public:
if (byte >= 0)
return byte;
juce_wchar n = byte;
juce_wchar mask = 0x7f;
juce_wchar bit = 0x40;
uint32 n = (uint32) (uint8) byte;
uint32 mask = 0x7f;
uint32 bit = 0x40;
size_t numExtraValues = 0;
while ((n & bit) != 0 && bit > 0x10)
@@ -113,7 +113,7 @@ public:
n |= (nextByte & 0x3f);
}
return n;
return (juce_wchar) n;
}
/** Moves this pointer along to the next character in the string. */
@@ -473,6 +473,51 @@ public:
/** Returns the first non-whitespace character in the string. */
CharPointer_UTF8 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); }
/** Returns true if the given unicode character can be represented in this encoding. */
static bool canRepresent (juce_wchar character) throw()
{
return ((unsigned int) character) < (unsigned int) 0x10ffff;
}
/** Returns true if this data contains a valid string in this encoding. */
static bool isValidString (const CharType* dataToTest, int maxBytesToRead)
{
while (--maxBytesToRead >= 0 && *dataToTest != 0)
{
const char byte = *dataToTest;
if (byte < 0)
{
uint32 n = (uint32) (uint8) byte;
uint32 mask = 0x7f;
uint32 bit = 0x40;
int numExtraValues = 0;
while ((n & bit) != 0)
{
if (bit <= 0x10)
return false;
mask >>= 1;
++numExtraValues;
bit >>= 1;
}
n &= mask;
while (--numExtraValues >= 0)
{
const uint32 nextByte = (uint32) (uint8) *dataToTest++;
if ((nextByte & 0xc0) != 0x80)
return false;
}
}
}
return true;
}
/** These values are the byte-order-mark (BOM) values for a UTF-8 stream. */
enum
{


+ 1
- 0
src/text/juce_CharacterFunctions.cpp View File

@@ -40,6 +40,7 @@
BEGIN_JUCE_NAMESPACE
#include "juce_String.h"
#include "../memory/juce_HeapBlock.h"
//==============================================================================
juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) throw()


+ 45
- 12
src/text/juce_String.cpp View File

@@ -250,8 +250,41 @@ String::String (const String& stringToCopy, const size_t charsToAllocate)
}
String::String (const char* const t)
: text (StringHolder::createFromCharPointer (CharPointer_UTF8 (t)))
: text (StringHolder::createFromCharPointer (CharPointer_ASCII (t)))
{
/* If you get an assertion here, then you're trying to create a string from 8-bit data
that contains values greater than 127. These can NOT be correctly converted to unicode
because there's no way for the String class to know what encoding was used to
create them. The source data could be UTF-8, ASCII or one of many local code-pages.
To get around this problem, you must be more explicit when you pass an ambiguous 8-bit
string to the String class - so for example if your source data is actually UTF-8,
you'd call String (CharPointer_UTF8 ("my utf8 string..")), and it would be able to
correctly convert the multi-byte characters to unicode. It's *highly* recommended that
you use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent these strings in a way that isn't dependent on
the compiler, source code editor and platform.
*/
jassert (CharPointer_ASCII::isValidString (t, std::numeric_limits<int>::max()));
}
String::String (const char* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_ASCII (t), maxChars))
{
/* If you get an assertion here, then you're trying to create a string from 8-bit data
that contains values greater than 127. These can NOT be correctly converted to unicode
because there's no way for the String class to know what encoding was used to
create them. The source data could be UTF-8, ASCII or one of many local code-pages.
To get around this problem, you must be more explicit when you pass an ambiguous 8-bit
string to the String class - so for example if your source data is actually UTF-8,
you'd call String (CharPointer_UTF8 ("my utf8 string..")), and it would be able to
correctly convert the multi-byte characters to unicode. It's *highly* recommended that
you use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent these strings in a way that isn't dependent on
the compiler, source code editor and platform.
*/
jassert (CharPointer_ASCII::isValidString (t, (int) maxChars));
}
String::String (const juce_wchar* const t)
@@ -259,6 +292,11 @@ String::String (const juce_wchar* const t)
{
}
String::String (const juce_wchar* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_UTF32 (t), maxChars))
{
}
String::String (const CharPointer_UTF8& t)
: text (StringHolder::createFromCharPointer (t))
{
@@ -279,6 +317,11 @@ String::String (const CharPointer_UTF32& t, const size_t maxChars)
{
}
String::String (const CharPointer_ASCII& t)
: text (StringHolder::createFromCharPointer (t))
{
}
#if JUCE_WINDOWS
String::String (const wchar_t* const t)
: text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t)))
@@ -291,16 +334,6 @@ String::String (const wchar_t* const t, size_t maxChars)
}
#endif
String::String (const char* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_UTF8 (t), maxChars))
{
}
String::String (const juce_wchar* const t, const size_t maxChars)
: text (StringHolder::createFromCharPointer (CharPointer_UTF32 (t), maxChars))
{
}
const String String::charToString (const juce_wchar character)
{
String result (Preallocation (1));
@@ -679,7 +712,7 @@ String& String::operator+= (const juce_wchar ch)
}
#if JUCE_WINDOWS
String& String::operator+= (wchar_t ch)
String& String::operator+= (const wchar_t ch)
{
return operator+= ((juce_wchar) ch);
}


+ 30
- 6
src/text/juce_String.h View File

@@ -37,6 +37,7 @@
#include "juce_CharPointer_UTF8.h"
#include "juce_CharPointer_UTF16.h"
#include "juce_CharPointer_UTF32.h"
#include "juce_CharPointer_ASCII.h"
#if JUCE_MSVC
#pragma warning (pop)
@@ -60,7 +61,6 @@ class JUCE_API String
public:
//==============================================================================
/** Creates an empty string.
@see empty
*/
String() throw();
@@ -68,15 +68,36 @@ public:
/** Creates a copy of another string. */
String (const String& other) throw();
/** Creates a string from a zero-terminated text string.
The string is assumed to be stored in the default system encoding.
/** Creates a string from a zero-terminated ascii text string.
The string passed-in must not contain any characters with a value above 127, because
these can't be converted to unicode without knowing the original encoding that was
used to create the string. If you attempt to pass-in values above 127, you'll get an
assertion.
To create strings with extended characters from UTF-8, you should explicitly call
String (CharPointer_UTF8 ("my utf8 string..")). It's *highly* recommended that you
use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent unicode strings in a way that isn't dependent
on the compiler, source code editor and platform.
*/
String (const char* text);
/** Creates a string from an string of characters.
/** Creates a string from a string of 8-bit ascii characters.
This will use up the the first maxChars characters of the string (or
less if the string is actually shorter)
The string passed-in must not contain any characters with a value above 127, because
these can't be converted to unicode without knowing the original encoding that was
used to create the string. If you attempt to pass-in values above 127, you'll get an
assertion.
To create strings with extended characters from UTF-8, you should explicitly call
String (CharPointer_UTF8 ("my utf8 string..")). It's *highly* recommended that you
use UTF-8 with escape characters in your source code to represent extended characters,
because there's no other way to represent unicode strings in a way that isn't dependent
on the compiler, source code editor and platform.
This will use up the the first maxChars characters of the string (or less if the string
is actually shorter).
*/
String (const char* text, size_t maxChars);
@@ -102,6 +123,9 @@ public:
/** Creates a string from a UTF-32 character string */
String (const CharPointer_UTF32& text, size_t maxChars);
/** Creates a string from an ASCII character string */
String (const CharPointer_ASCII& text);
#if JUCE_WINDOWS
/** Creates a string from a UTF-16 character string */
String (const wchar_t* text);


+ 12
- 12
src/text/juce_XmlDocument.cpp View File

@@ -124,7 +124,7 @@ XmlElement* XmlDocument::getDocumentElement (const bool onlyReadOuterDocumentEle
}
}
input = static_cast <const juce_wchar*> (textToParse);
input = textToParse.getCharPointer();
lastError = String::empty;
errorOccurred = false;
outOfData = false;
@@ -235,7 +235,7 @@ void XmlDocument::skipHeader()
return;
input += docTypeIndex + 9;
const CharPointer_UTF32 docType (input);
const String::CharPointerType docType (input);
int n = 1;
@@ -324,7 +324,7 @@ void XmlDocument::readQuotedString (String& result)
else
{
--input;
const CharPointer_UTF32 start (input);
const String::CharPointerType start (input);
for (;;)
{
@@ -332,14 +332,14 @@ void XmlDocument::readQuotedString (String& result)
if (character == quote)
{
result.append (start.getAddress(), (int) (input.getAddress() - start.getAddress()));
result.appendCharPointer (start, (int) (input.getAddress() - start.getAddress()));
++input;
return;
}
else if (character == '&')
{
result.append (start.getAddress(), (int) (input.getAddress() - start.getAddress()));
result.appendCharPointer (start, (int) (input.getAddress() - start.getAddress()));
break;
}
else if (character == 0)
@@ -419,7 +419,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
if (attNameLen > 0)
{
const CharPointer_UTF32 attNameStart (input);
const String::CharPointerType attNameStart (input);
input += attNameLen;
skipNextWhiteSpace();
@@ -462,7 +462,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
for (;;)
{
const CharPointer_UTF32 preWhitespaceInput (input);
const String::CharPointerType preWhitespaceInput (input);
skipNextWhiteSpace();
if (outOfData)
@@ -493,7 +493,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
&& input[8] == '[')
{
input += 9;
const CharPointer_UTF32 inputStart (input);
const String::CharPointerType inputStart (input);
int len = 0;
@@ -556,10 +556,10 @@ void XmlDocument::readChildElements (XmlElement* parent)
if (entity.startsWithChar ('<') && entity [1] != 0)
{
const CharPointer_UTF32 oldInput (input);
const String::CharPointerType oldInput (input);
const bool oldOutOfData = outOfData;
input = static_cast <const juce_wchar*> (entity);
input = entity.getCharPointer();
outOfData = false;
for (;;)
@@ -582,7 +582,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
}
else
{
const CharPointer_UTF32 start (input);
const String::CharPointerType start (input);
int len = 0;
for (;;)
@@ -701,7 +701,7 @@ void XmlDocument::readEntity (String& result)
}
else
{
const CharPointer_UTF32 entityNameStart (input);
const String::CharPointerType entityNameStart (input);
const int closingSemiColon = input.indexOf ((juce_wchar) ';');
if (closingSemiColon < 0)


+ 1
- 1
src/text/juce_XmlDocument.h View File

@@ -153,7 +153,7 @@ public:
//==============================================================================
private:
String originalText;
CharPointer_UTF32 input;
String::CharPointerType input;
bool outOfData, errorOccurred;
String lastError, dtdText;


Loading…
Cancel
Save