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; }; 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; }; 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; }; 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; }; 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; }; 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; }; 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, 4007410FACA2F865FD8EF769,
663746215E9BA6C761172B85, 663746215E9BA6C761172B85,
C3FD9D93626F80A45F9B6DDE, C3FD9D93626F80A45F9B6DDE,
72F5ED2E8B945988C37EA9CF,
8273A206FB309671284959DD, 8273A206FB309671284959DD,
BF888BC540B64D5C61E46A34, BF888BC540B64D5C61E46A34,
4A97C8D2FF6454DDD3AF4BE5, 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_UTF8.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF32.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.cpp"/>
<File RelativePath="..\..\src\text\juce_Identifier.h"/> <File RelativePath="..\..\src\text\juce_Identifier.h"/>
<File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> <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_UTF8.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF32.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.cpp"/>
<File RelativePath="..\..\src\text\juce_Identifier.h"/> <File RelativePath="..\..\src\text\juce_Identifier.h"/>
<File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> <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_UTF8.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/> <File RelativePath="..\..\src\text\juce_CharPointer_UTF16.h"/>
<File RelativePath="..\..\src\text\juce_CharPointer_UTF32.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.cpp"/>
<File RelativePath="..\..\src\text\juce_Identifier.h"/> <File RelativePath="..\..\src\text\juce_Identifier.h"/>
<File RelativePath="..\..\src\text\juce_LocalisedStrings.cpp"/> <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_UTF8.h"/>
<ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"/> <ClInclude Include="..\..\src\text\juce_CharPointer_UTF16.h"/>
<ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.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_Identifier.h"/>
<ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"/> <ClInclude Include="..\..\src\text\juce_LocalisedStrings.h"/>
<ClInclude Include="..\..\src\text\juce_NewLine.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"> <ClInclude Include="..\..\src\text\juce_CharPointer_UTF32.h">
<Filter>Juce\Source\text</Filter> <Filter>Juce\Source\text</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\text\juce_CharPointer_ASCII.h">
<Filter>Juce\Source\text</Filter>
</ClInclude>
<ClInclude Include="..\..\src\text\juce_Identifier.h"> <ClInclude Include="..\..\src\text\juce_Identifier.h">
<Filter>Juce\Source\text</Filter> <Filter>Juce\Source\text</Filter>
</ClInclude> </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; }; 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; }; 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; }; 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; }; 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; }; 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; }; 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, 4007410FACA2F865FD8EF769,
663746215E9BA6C761172B85, 663746215E9BA6C761172B85,
C3FD9D93626F80A45F9B6DDE, C3FD9D93626F80A45F9B6DDE,
72F5ED2E8B945988C37EA9CF,
8273A206FB309671284959DD, 8273A206FB309671284959DD,
BF888BC540B64D5C61E46A34, BF888BC540B64D5C61E46A34,
4A97C8D2FF6454DDD3AF4BE5, 4A97C8D2FF6454DDD3AF4BE5,


+ 2
- 0
Juce.jucer View File

@@ -1477,6 +1477,8 @@
file="src/text/juce_CharPointer_UTF16.h"/> file="src/text/juce_CharPointer_UTF16.h"/>
<FILE id="rE1hlF" name="juce_CharPointer_UTF32.h" compile="0" resource="0" <FILE id="rE1hlF" name="juce_CharPointer_UTF32.h" compile="0" resource="0"
file="src/text/juce_CharPointer_UTF32.h"/> 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 id="iGtCiI8" name="juce_Identifier.cpp" compile="1" resource="0"
file="src/text/juce_Identifier.cpp"/> file="src/text/juce_Identifier.cpp"/>
<FILE id="CPlhWqs" name="juce_Identifier.h" compile="0" resource="0" <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(); list.updateContent();
} }
void GroupInformationComponent::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged)
void GroupInformationComponent::valueTreeChildAdded (ValueTree&, ValueTree&)
{ {
list.updateContent(); 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(); 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 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); void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
private: 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(); 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(); 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 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); 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) void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{ {
if (tree == item.getNode()) if (tree == item.getNode())
repaintItem(); 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) 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 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); void valueTreeParentChanged (ValueTree& tree);
//============================================================================== //==============================================================================
@@ -99,6 +101,7 @@ protected:
bool isFileMissing; bool isFileMissing;
//============================================================================== //==============================================================================
void treeChildrenChanged (const ValueTree& parentTree);
virtual void addSubItems(); virtual void addSubItems();
virtual ProjectTreeViewBase* createSubItem (const Project::Item& node) = 0; virtual ProjectTreeViewBase* createSubItem (const Project::Item& node) = 0;
const Drawable* getIcon() const { return item.getIcon(); } 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) 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) 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) String::String (const CharPointer_UTF8& t)
: text (StringHolder::createFromCharPointer (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 #if JUCE_WINDOWS
String::String (const wchar_t* const t) String::String (const wchar_t* const t)
: text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t))) : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t)))
@@ -11621,16 +11664,6 @@ String::String (const wchar_t* const t, size_t maxChars)
} }
#endif #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) const String String::charToString (const juce_wchar character)
{ {
String result (Preallocation (1)); String result (Preallocation (1));
@@ -12004,7 +12037,7 @@ String& String::operator+= (const juce_wchar ch)
} }


#if JUCE_WINDOWS #if JUCE_WINDOWS
String& String::operator+= (wchar_t ch)
String& String::operator+= (const wchar_t ch)
{ {
return operator+= ((juce_wchar) 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; lastError = String::empty;
errorOccurred = false; errorOccurred = false;
outOfData = false; outOfData = false;
@@ -14662,7 +14695,7 @@ void XmlDocument::skipHeader()
return; return;


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


int n = 1; int n = 1;


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


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


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


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


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


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


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


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


int len = 0; int len = 0;


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


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


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


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


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


if (closingSemiColon < 0) 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;) for (int i = valueTreesWithListeners.size(); --i >= 0;)
{ {
ValueTree* const v = valueTreesWithListeners[i]; ValueTree* const v = valueTreesWithListeners[i];
if (v != 0) 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 tree (this);
ValueTree::SharedObject* t = this; ValueTree::SharedObject* t = this;


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


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


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


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


static int getChannelMask (const int numChannels) throw() static int getChannelMask (const int numChannels) throw()
{ {
@@ -23152,14 +23233,15 @@ private:
const int bytesPerFrame = numChannels * bitsPerSample / 8; const int bytesPerFrame = numChannels * bitsPerSample / 8;
int64 audioDataSize = bytesPerFrame * lengthInSamples; 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) + 8 + audioDataSize + (audioDataSize & 1)
+ (bwavChunk.getSize() > 0 ? (8 + bwavChunk.getSize()) : 0) + (bwavChunk.getSize() > 0 ? (8 + bwavChunk.getSize()) : 0)
+ (smplChunk.getSize() > 0 ? (8 + smplChunk.getSize()) : 0) + (smplChunk.getSize() > 0 ? (8 + smplChunk.getSize()) : 0)
+ (8 + 28); // (JUNK chunk)
+ (8 + 28); // (ds64 chunk)


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


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


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


output->writeInt (chunkName ("fmt ")); 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->writeShort ((short) numChannels);
output->writeInt ((int) sampleRate); output->writeInt ((int) sampleRate);
output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec
output->writeShort ((short) bytesPerFrame); // nBlockAlign output->writeShort ((short) bytesPerFrame); // nBlockAlign
output->writeShort ((short) bitsPerSample); // wBitsPerSample 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) if (bwavChunk.getSize() > 0)
{ {
@@ -43750,6 +43846,7 @@ void DrawableButton::buttonStateChanged()


if (currentImage != 0) if (currentImage != 0)
{ {
currentImage->setInterceptsMouseClicks (false, false);
addAndMakeVisible (currentImage); addAndMakeVisible (currentImage);
DrawableButton::resized(); 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_JUCE_NAMESPACE
/*** End of inlined file: juce_TextEditor.cpp ***/ /*** End of inlined file: juce_TextEditor.cpp ***/


@@ -61303,7 +61405,17 @@ void ComponentBuilder::valueTreePropertyChanged (ValueTree& tree, const Identifi
ComponentBuilderHelpers::updateComponent (*this, tree); 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); ComponentBuilderHelpers::updateComponent (*this, tree);
} }
@@ -68738,17 +68850,21 @@ class PopupMenu::ItemComponent : public Component
{ {
public: public:


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


parent->addAndMakeVisible (this);

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

addMouseListener (parent, false);
} }


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


for (int i = 0; i < menu.items.size(); ++i) 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); calculateWindowPos (target, alignToRectangle);
setTopLeftPosition (windowPos.getX(), windowPos.getY()); setTopLeftPosition (windowPos.getX(), windowPos.getY());
@@ -86175,6 +86286,12 @@ const Rectangle<float> DrawableShape::getDrawableBounds() const


bool DrawableShape::hitTest (int x, int y) 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 globalX = (float) (x - originRelativeToComponent.getX());
const float globalY = (float) (y - originRelativeToComponent.getY()); const float globalY = (float) (y - originRelativeToComponent.getY());


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


if (bytesNeeded > 0) if (bytesNeeded > 0)
{ {
@@ -263990,7 +264107,7 @@ namespace FileHelpers
FSRef ref; FSRef ref;
LSItemInfoRecord info; 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 && LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr
&& (info.flags & kLSItemInfoIsInvisible) != 0; && (info.flags & kLSItemInfoIsInvisible) != 0;
#endif #endif


+ 536
- 25
juce_amalgamated.h View File

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


/** Current Juce version number. /** Current Juce version number.


@@ -2496,9 +2496,9 @@ public:
if (byte >= 0) if (byte >= 0)
return byte; 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; size_t numExtraValues = 0;


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


return n;
return (juce_wchar) n;
} }


/** Moves this pointer along to the next character in the string. */ /** 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. */ /** Returns the first non-whitespace character in the string. */
CharPointer_UTF8 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); } 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. */ /** These values are the byte-order-mark (BOM) values for a UTF-8 stream. */
enum enum
{ {
@@ -3268,6 +3313,43 @@ public:
/** Returns the first non-whitespace character in the string. */ /** Returns the first non-whitespace character in the string. */
CharPointer_UTF16 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); } 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. */ /** These values are the byte-order-mark (BOM) values for a UTF-16 stream. */
enum enum
{ {
@@ -3377,7 +3459,7 @@ public:
CharPointer_UTF32 operator++ (int) throw() CharPointer_UTF32 operator++ (int) throw()
{ {
CharPointer_UTF32 temp (*this); CharPointer_UTF32 temp (*this);
++*this;
++data;
return temp; return temp;
} }


@@ -3612,6 +3694,25 @@ public:
/** Returns the first non-whitespace character in the string. */ /** Returns the first non-whitespace character in the string. */
CharPointer_UTF32 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); } 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) CharPointer_UTF32 atomicSwap (const CharPointer_UTF32& newValue)
{ {
return CharPointer_UTF32 (reinterpret_cast <Atomic<CharType*>&> (data).exchange (newValue.data)); return CharPointer_UTF32 (reinterpret_cast <Atomic<CharType*>&> (data).exchange (newValue.data));
@@ -3624,6 +3725,364 @@ private:
#endif // __JUCE_CHARPOINTER_UTF32_JUCEHEADER__ #endif // __JUCE_CHARPOINTER_UTF32_JUCEHEADER__
/*** End of inlined file: juce_CharPointer_UTF32.h ***/ /*** 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 #if JUCE_MSVC
#pragma warning (pop) #pragma warning (pop)
#endif #endif
@@ -3644,7 +4103,6 @@ class JUCE_API String
public: public:


/** Creates an empty string. /** Creates an empty string.

@see empty @see empty
*/ */
String() throw(); String() throw();
@@ -3652,15 +4110,36 @@ public:
/** Creates a copy of another string. */ /** Creates a copy of another string. */
String (const String& other) throw(); 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); 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); String (const char* text, size_t maxChars);


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


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

#if JUCE_WINDOWS #if JUCE_WINDOWS
/** Creates a string from a UTF-16 character string */ /** Creates a string from a UTF-16 character string */
String (const wchar_t* text); String (const wchar_t* text);
@@ -15559,16 +16041,34 @@ public:
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
const Identifier& property) = 0; 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 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, 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. /** 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 (const Identifier& property);
void sendPropertyChangeMessage (ValueTree& tree, 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(); void sendParentChangeMessage();
const var& getProperty (const Identifier& name) const; const var& getProperty (const Identifier& name) const;
const var getProperty (const Identifier& name, const var& defaultReturnValue) const; const var getProperty (const Identifier& name, const var& defaultReturnValue) const;
@@ -20054,6 +20558,9 @@ private:
#endif #endif
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ #ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__


#endif
#ifndef __JUCE_CHARPOINTER_ASCII_JUCEHEADER__

#endif #endif
#ifndef __JUCE_CHARPOINTER_UTF16_JUCEHEADER__ #ifndef __JUCE_CHARPOINTER_UTF16_JUCEHEADER__


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


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


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


/** Called when the user changes the text in some way. */ /** 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. */ /** 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. */ /** 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. */ /** 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. /** Registers a listener to be told when things happen to the text.
@@ -47918,7 +48425,11 @@ public:
/** @internal */ /** @internal */
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property); void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
/** @internal */ /** @internal */
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
/** @internal */
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
/** @internal */
void valueTreeChildOrderChanged (ValueTree& parentTree);
/** @internal */ /** @internal */
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged); 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), : AudioFormatWriter (out, TRANS (wavFormatName), sampleRate_, numChannels_, bits),
lengthInSamples (0), lengthInSamples (0),
bytesWritten (0), bytesWritten (0),
writeFailed (false),
isRF64 (false)
writeFailed (false)
{ {
using namespace WavFileHelpers; using namespace WavFileHelpers;
@@ -567,7 +566,7 @@ private:
MemoryBlock tempBlock, bwavChunk, smplChunk; MemoryBlock tempBlock, bwavChunk, smplChunk;
uint64 lengthInSamples, bytesWritten; uint64 lengthInSamples, bytesWritten;
int64 headerPosition; int64 headerPosition;
bool writeFailed, isRF64;
bool writeFailed;
static int getChannelMask (const int numChannels) throw() static int getChannelMask (const int numChannels) throw()
{ {
@@ -596,14 +595,15 @@ private:
const int bytesPerFrame = numChannels * bitsPerSample / 8; const int bytesPerFrame = numChannels * bitsPerSample / 8;
int64 audioDataSize = bytesPerFrame * lengthInSamples; 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) + 8 + audioDataSize + (audioDataSize & 1)
+ (bwavChunk.getSize() > 0 ? (8 + bwavChunk.getSize()) : 0) + (bwavChunk.getSize() > 0 ? (8 + bwavChunk.getSize()) : 0)
+ (smplChunk.getSize() > 0 ? (8 + smplChunk.getSize()) : 0) + (smplChunk.getSize() > 0 ? (8 + smplChunk.getSize()) : 0)
+ (8 + 28); // (JUNK chunk)
+ (8 + 28); // (ds64 chunk)
riffChunkSize += (riffChunkSize & 0x1); riffChunkSize += (riffChunkSize & 0x1);
isRF64 = (riffChunkSize > 0xffffffff);
output->writeInt (chunkName (isRF64 ? "RF64" : "RIFF")); output->writeInt (chunkName (isRF64 ? "RF64" : "RIFF"));
output->writeInt (isRF64 ? -1 : (int) riffChunkSize); output->writeInt (isRF64 ? -1 : (int) riffChunkSize);
@@ -611,10 +611,9 @@ private:
if (! isRF64) if (! isRF64)
{ {
// write Junk chunk
output->writeInt (chunkName ("JUNK")); output->writeInt (chunkName ("JUNK"));
output->writeInt (28);
output->writeRepeatedByte (0, 28);
output->writeInt (28 + 24);
output->writeRepeatedByte (0, 28 /* ds64 */ + 24 /* extra waveformatex */);
} }
else else
{ {
@@ -627,29 +626,44 @@ private:
} }
output->writeInt (chunkName ("fmt ")); 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->writeShort ((short) numChannels);
output->writeInt ((int) sampleRate); output->writeInt ((int) sampleRate);
output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec output->writeInt ((int) (bytesPerFrame * sampleRate)); // nAvgBytesPerSec
output->writeShort ((short) bytesPerFrame); // nBlockAlign output->writeShort ((short) bytesPerFrame); // nBlockAlign
output->writeShort ((short) bitsPerSample); // wBitsPerSample 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) 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;) for (int i = valueTreesWithListeners.size(); --i >= 0;)
{ {
ValueTree* const v = valueTreesWithListeners[i]; ValueTree* const v = valueTreesWithListeners[i];
if (v != 0) 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 tree (this);
ValueTree::SharedObject* t = this; ValueTree::SharedObject* t = this;
while (t != 0) 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; t = t->parent;
} }
} }
@@ -434,7 +478,7 @@ void ValueTree::SharedObject::addChild (SharedObject* child, int index, UndoMana
{ {
children.insert (index, child); children.insert (index, child);
child->parent = this; child->parent = this;
sendChildChangeMessage();
sendChildAddedMessage (ValueTree (child));
child->sendParentChangeMessage(); child->sendParentChangeMessage();
} }
else else
@@ -464,7 +508,7 @@ void ValueTree::SharedObject::removeChild (const int childIndex, UndoManager* co
{ {
children.remove (childIndex); children.remove (childIndex);
child->parent = 0; child->parent = 0;
sendChildChangeMessage();
sendChildRemovedMessage (ValueTree (child));
child->sendParentChangeMessage(); child->sendParentChangeMessage();
} }
else else
@@ -491,7 +535,7 @@ void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoMan
if (undoManager == 0) if (undoManager == 0)
{ {
children.move (currentIndex, newIndex); children.move (currentIndex, newIndex);
sendChildChangeMessage();
sendChildOrderChangedMessage();
} }
else else
{ {
@@ -510,16 +554,19 @@ void ValueTree::SharedObject::reorderChildren (const ReferenceCountedArray <Shar
if (undoManager == 0) if (undoManager == 0)
{ {
children = newOrder; children = newOrder;
sendChildChangeMessage();
sendChildOrderChangedMessage();
} }
else else
{ {
for (int i = 0; i < children.size(); ++i) 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); sendChangeMessage (false);
} }
void valueTreeChildrenChanged (ValueTree&) {}
void valueTreeParentChanged (ValueTree&) {}
void valueTreeChildAdded (ValueTree&, ValueTree&) {}
void valueTreeChildRemoved (ValueTree&, ValueTree&) {}
void valueTreeChildOrderChanged (ValueTree&) {}
void valueTreeParentChanged (ValueTree&) {}
private: private:
ValueTree tree; ValueTree tree;


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

@@ -368,16 +368,34 @@ public:
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
const Identifier& property) = 0; 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 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, 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. /** 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 (const Identifier& property);
void sendPropertyChangeMessage (ValueTree& tree, 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(); void sendParentChangeMessage();
const var& getProperty (const Identifier& name) const; const var& getProperty (const Identifier& name) const;
const var getProperty (const Identifier& name, const var& defaultReturnValue) 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_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53 #define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 21
#define JUCE_BUILDNUMBER 23
/** Current Juce version number. /** 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) if (currentImage != 0)
{ {
currentImage->setInterceptsMouseClicks (false, false);
addAndMakeVisible (currentImage); addAndMakeVisible (currentImage);
DrawableButton::resized(); 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 END_JUCE_NAMESPACE

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

@@ -313,16 +313,16 @@ public:
virtual ~Listener() {} virtual ~Listener() {}
/** Called when the user changes the text in some way. */ /** 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. */ /** 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. */ /** 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. */ /** 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. /** 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); 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); ComponentBuilderHelpers::updateComponent (*this, tree);
} }


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

@@ -229,7 +229,11 @@ public:
/** @internal */ /** @internal */
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property); void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
/** @internal */ /** @internal */
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& childWhichHasBeenAdded);
/** @internal */
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& childWhichHasBeenRemoved);
/** @internal */
void valueTreeChildOrderChanged (ValueTree& parentTree);
/** @internal */ /** @internal */
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged); 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: public:
//============================================================================== //==============================================================================
ItemComponent (const PopupMenu::Item& itemInfo_, int standardItemHeight)
ItemComponent (const PopupMenu::Item& itemInfo_, int standardItemHeight, Component* const parent)
: itemInfo (itemInfo_), : itemInfo (itemInfo_),
isHighlighted (false) isHighlighted (false)
{ {
if (itemInfo.customComp != 0) if (itemInfo.customComp != 0)
addAndMakeVisible (itemInfo.customComp); addAndMakeVisible (itemInfo.customComp);
parent->addAndMakeVisible (this);
int itemW = 80; int itemW = 80;
int itemH = 16; int itemH = 16;
getIdealSize (itemW, itemH, standardItemHeight); getIdealSize (itemW, itemH, standardItemHeight);
setSize (itemW, jlimit (2, 600, itemH)); setSize (itemW, jlimit (2, 600, itemH));
addMouseListener (parent, false);
} }
~ItemComponent() ~ItemComponent()
@@ -277,12 +281,7 @@ public:
setOpaque (getLookAndFeel().findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows()); setOpaque (getLookAndFeel().findColour (PopupMenu::backgroundColourId).isOpaque() || ! Desktop::canUseSemiTransparentWindows());
for (int i = 0; i < menu.items.size(); ++i) 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); calculateWindowPos (target, alignToRectangle);
setTopLeftPosition (windowPos.getX(), windowPos.getY()); 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 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 globalX = (float) (x - originRelativeToComponent.getX());
const float globalY = (float) (y - originRelativeToComponent.getY()); const float globalY = (float) (y - originRelativeToComponent.getY());


+ 3
- 0
src/juce_core_includes.h View File

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


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

@@ -92,7 +92,7 @@ namespace FileHelpers
FSRef ref; FSRef ref;
LSItemInfoRecord info; 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 && LSCopyItemInfoForRef (&ref, kLSRequestBasicFlagsOnly, &info) == noErr
&& (info.flags & kLSItemInfoIsInvisible) != 0; && (info.flags & kLSItemInfoIsInvisible) != 0;
#endif #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) if (EmptyClipboard() != 0)
{ {
const int bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
const int bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer()) + 4;
if (bytesNeeded > 0) 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. */ /** Returns the first non-whitespace character in the string. */
CharPointer_UTF16 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); } 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. */ /** These values are the byte-order-mark (BOM) values for a UTF-16 stream. */
enum enum
{ {


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

@@ -106,7 +106,7 @@ public:
CharPointer_UTF32 operator++ (int) throw() CharPointer_UTF32 operator++ (int) throw()
{ {
CharPointer_UTF32 temp (*this); CharPointer_UTF32 temp (*this);
++*this;
++data;
return temp; return temp;
} }
@@ -341,6 +341,25 @@ public:
/** Returns the first non-whitespace character in the string. */ /** Returns the first non-whitespace character in the string. */
CharPointer_UTF32 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); } 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) CharPointer_UTF32 atomicSwap (const CharPointer_UTF32& newValue)
{ {
return CharPointer_UTF32 (reinterpret_cast <Atomic<CharType*>&> (data).exchange (newValue.data)); 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) if (byte >= 0)
return byte; 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; size_t numExtraValues = 0;
while ((n & bit) != 0 && bit > 0x10) while ((n & bit) != 0 && bit > 0x10)
@@ -113,7 +113,7 @@ public:
n |= (nextByte & 0x3f); n |= (nextByte & 0x3f);
} }
return n;
return (juce_wchar) n;
} }
/** Moves this pointer along to the next character in the string. */ /** 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. */ /** Returns the first non-whitespace character in the string. */
CharPointer_UTF8 findEndOfWhitespace() const throw() { return CharacterFunctions::findEndOfWhitespace (*this); } 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. */ /** These values are the byte-order-mark (BOM) values for a UTF-8 stream. */
enum enum
{ {


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

@@ -40,6 +40,7 @@
BEGIN_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE
#include "juce_String.h" #include "juce_String.h"
#include "../memory/juce_HeapBlock.h"
//============================================================================== //==============================================================================
juce_wchar CharacterFunctions::toUpperCase (const juce_wchar character) throw() 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) 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) 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) String::String (const CharPointer_UTF8& t)
: text (StringHolder::createFromCharPointer (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 #if JUCE_WINDOWS
String::String (const wchar_t* const t) String::String (const wchar_t* const t)
: text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t))) : text (StringHolder::createFromCharPointer (CharPointer_UTF16 (t)))
@@ -291,16 +334,6 @@ String::String (const wchar_t* const t, size_t maxChars)
} }
#endif #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) const String String::charToString (const juce_wchar character)
{ {
String result (Preallocation (1)); String result (Preallocation (1));
@@ -679,7 +712,7 @@ String& String::operator+= (const juce_wchar ch)
} }
#if JUCE_WINDOWS #if JUCE_WINDOWS
String& String::operator+= (wchar_t ch)
String& String::operator+= (const wchar_t ch)
{ {
return operator+= ((juce_wchar) 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_UTF8.h"
#include "juce_CharPointer_UTF16.h" #include "juce_CharPointer_UTF16.h"
#include "juce_CharPointer_UTF32.h" #include "juce_CharPointer_UTF32.h"
#include "juce_CharPointer_ASCII.h"
#if JUCE_MSVC #if JUCE_MSVC
#pragma warning (pop) #pragma warning (pop)
@@ -60,7 +61,6 @@ class JUCE_API String
public: public:
//============================================================================== //==============================================================================
/** Creates an empty string. /** Creates an empty string.
@see empty @see empty
*/ */
String() throw(); String() throw();
@@ -68,15 +68,36 @@ public:
/** Creates a copy of another string. */ /** Creates a copy of another string. */
String (const String& other) throw(); 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); 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); String (const char* text, size_t maxChars);
@@ -102,6 +123,9 @@ public:
/** Creates a string from a UTF-32 character string */ /** Creates a string from a UTF-32 character string */
String (const CharPointer_UTF32& text, size_t maxChars); String (const CharPointer_UTF32& text, size_t maxChars);
/** Creates a string from an ASCII character string */
String (const CharPointer_ASCII& text);
#if JUCE_WINDOWS #if JUCE_WINDOWS
/** Creates a string from a UTF-16 character string */ /** Creates a string from a UTF-16 character string */
String (const wchar_t* text); 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; lastError = String::empty;
errorOccurred = false; errorOccurred = false;
outOfData = false; outOfData = false;
@@ -235,7 +235,7 @@ void XmlDocument::skipHeader()
return; return;
input += docTypeIndex + 9; input += docTypeIndex + 9;
const CharPointer_UTF32 docType (input);
const String::CharPointerType docType (input);
int n = 1; int n = 1;
@@ -324,7 +324,7 @@ void XmlDocument::readQuotedString (String& result)
else else
{ {
--input; --input;
const CharPointer_UTF32 start (input);
const String::CharPointerType start (input);
for (;;) for (;;)
{ {
@@ -332,14 +332,14 @@ void XmlDocument::readQuotedString (String& result)
if (character == quote) if (character == quote)
{ {
result.append (start.getAddress(), (int) (input.getAddress() - start.getAddress()));
result.appendCharPointer (start, (int) (input.getAddress() - start.getAddress()));
++input; ++input;
return; return;
} }
else if (character == '&') else if (character == '&')
{ {
result.append (start.getAddress(), (int) (input.getAddress() - start.getAddress()));
result.appendCharPointer (start, (int) (input.getAddress() - start.getAddress()));
break; break;
} }
else if (character == 0) else if (character == 0)
@@ -419,7 +419,7 @@ XmlElement* XmlDocument::readNextElement (const bool alsoParseSubElements)
if (attNameLen > 0) if (attNameLen > 0)
{ {
const CharPointer_UTF32 attNameStart (input);
const String::CharPointerType attNameStart (input);
input += attNameLen; input += attNameLen;
skipNextWhiteSpace(); skipNextWhiteSpace();
@@ -462,7 +462,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
for (;;) for (;;)
{ {
const CharPointer_UTF32 preWhitespaceInput (input);
const String::CharPointerType preWhitespaceInput (input);
skipNextWhiteSpace(); skipNextWhiteSpace();
if (outOfData) if (outOfData)
@@ -493,7 +493,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
&& input[8] == '[') && input[8] == '[')
{ {
input += 9; input += 9;
const CharPointer_UTF32 inputStart (input);
const String::CharPointerType inputStart (input);
int len = 0; int len = 0;
@@ -556,10 +556,10 @@ void XmlDocument::readChildElements (XmlElement* parent)
if (entity.startsWithChar ('<') && entity [1] != 0) if (entity.startsWithChar ('<') && entity [1] != 0)
{ {
const CharPointer_UTF32 oldInput (input);
const String::CharPointerType oldInput (input);
const bool oldOutOfData = outOfData; const bool oldOutOfData = outOfData;
input = static_cast <const juce_wchar*> (entity);
input = entity.getCharPointer();
outOfData = false; outOfData = false;
for (;;) for (;;)
@@ -582,7 +582,7 @@ void XmlDocument::readChildElements (XmlElement* parent)
} }
else else
{ {
const CharPointer_UTF32 start (input);
const String::CharPointerType start (input);
int len = 0; int len = 0;
for (;;) for (;;)
@@ -701,7 +701,7 @@ void XmlDocument::readEntity (String& result)
} }
else else
{ {
const CharPointer_UTF32 entityNameStart (input);
const String::CharPointerType entityNameStart (input);
const int closingSemiColon = input.indexOf ((juce_wchar) ';'); const int closingSemiColon = input.indexOf ((juce_wchar) ';');
if (closingSemiColon < 0) if (closingSemiColon < 0)


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

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


Loading…
Cancel
Save