| @@ -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, | ||||
| @@ -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"/> | ||||
| @@ -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"/> | ||||
| @@ -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"/> | ||||
| @@ -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"/> | ||||
| @@ -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> | ||||
| @@ -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, | ||||
| @@ -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" | ||||
| @@ -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(); | ||||
| } | } | ||||
| @@ -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: | ||||
| @@ -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(); | ||||
| } | } | ||||
| @@ -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); | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -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) | ||||
| @@ -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(); } | ||||
| @@ -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 | ||||
| @@ -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); | ||||
| @@ -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) | ||||
| { | { | ||||
| @@ -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; | ||||
| @@ -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; | ||||
| @@ -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. | ||||
| @@ -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(); | ||||
| } | } | ||||
| @@ -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 | ||||
| @@ -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. | ||||
| @@ -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); | ||||
| } | } | ||||
| @@ -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); | ||||
| @@ -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()); | ||||
| @@ -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()); | ||||
| @@ -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 | ||||
| @@ -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 | ||||
| @@ -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) | ||||
| { | { | ||||
| @@ -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__ | |||||
| @@ -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 | ||||
| { | { | ||||
| @@ -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)); | ||||
| @@ -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 | ||||
| { | { | ||||
| @@ -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() | ||||
| @@ -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); | ||||
| } | } | ||||
| @@ -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); | ||||
| @@ -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) | ||||
| @@ -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; | ||||