diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile
index 978c2608dc..3e09722b69 100644
--- a/Builds/Linux/Makefile
+++ b/Builds/Linux/Makefile
@@ -93,6 +93,7 @@ OBJECTS := \
$(OBJDIR)/juce_Synthesiser.o \
$(OBJDIR)/juce_BigInteger.o \
$(OBJDIR)/juce_DynamicObject.o \
+ $(OBJDIR)/juce_Identifier.o \
$(OBJDIR)/juce_MemoryBlock.o \
$(OBJDIR)/juce_NamedValueSet.o \
$(OBJDIR)/juce_PropertySet.o \
@@ -322,6 +323,7 @@ OBJECTS := \
$(OBJDIR)/juce_String.o \
$(OBJDIR)/juce_StringArray.o \
$(OBJDIR)/juce_StringPairArray.o \
+ $(OBJDIR)/juce_StringPool.o \
$(OBJDIR)/juce_XmlDocument.o \
$(OBJDIR)/juce_XmlElement.o \
$(OBJDIR)/juce_ReadWriteLock.o \
@@ -619,6 +621,11 @@ $(OBJDIR)/juce_DynamicObject.o: ../../src/containers/juce_DynamicObject.cpp
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+$(OBJDIR)/juce_Identifier.o: ../../src/containers/juce_Identifier.cpp
+ -@mkdir -p $(OBJDIR)
+ @echo $(notdir $<)
+ @$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
$(OBJDIR)/juce_MemoryBlock.o: ../../src/containers/juce_MemoryBlock.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@@ -1764,6 +1771,11 @@ $(OBJDIR)/juce_StringPairArray.o: ../../src/text/juce_StringPairArray.cpp
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+$(OBJDIR)/juce_StringPool.o: ../../src/text/juce_StringPool.cpp
+ -@mkdir -p $(OBJDIR)
+ @echo $(notdir $<)
+ @$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
$(OBJDIR)/juce_XmlDocument.o: ../../src/text/juce_XmlDocument.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
diff --git a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj
index f9e39456af..728df2c27e 100644
--- a/Builds/MacOSX/Juce.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/Juce.xcodeproj/project.pbxproj
@@ -62,6 +62,7 @@
E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; };
BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; };
4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; };
+ 95577AE91AA6CBA7FE9434F3 = { isa = PBXBuildFile; fileRef = 1CF7CC0EB057F995BBBEFC90; };
21BA256CBCC9C15265928A23 = { isa = PBXBuildFile; fileRef = FF40DA899AE16A5E1D8AA54A; };
9D2D1BA65C27BDA1F7C44769 = { isa = PBXBuildFile; fileRef = 70E5409425A76782B6188B31; };
43B3119E2F1B559263AE956C = { isa = PBXBuildFile; fileRef = 9BD379D2F7995BFE0B3E5369; };
@@ -317,6 +318,7 @@
C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; };
50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; };
82568CF438EF4C950E4A42DF = { isa = PBXBuildFile; fileRef = 81B36E7C56DF1A777AA04F71; };
+ B2E9D0C534DDE9F96921A054 = { isa = PBXBuildFile; fileRef = 0EC7DE81A516F4130AC59557; };
C8D06AE9C68A675A87DC9C99 = { isa = PBXBuildFile; fileRef = 5715BC14D93D61D71206FCB2; };
FE2999972FE3D6E251DA6653 = { isa = PBXBuildFile; fileRef = 95F21C2733BD5932372E4157; };
8B2193898D3465B5995EE98A = { isa = PBXBuildFile; fileRef = 8E78623B2D21CFE68DEC0483; };
@@ -457,6 +459,8 @@
34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; };
7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; };
F364AA2637B7CB89D3657DFF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_HeapBlock.h; path = ../../src/containers/juce_HeapBlock.h; sourceTree = SOURCE_ROOT; };
+ 1CF7CC0EB057F995BBBEFC90 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/containers/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; };
+ C16848F86DF014F1CBECE248 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/containers/juce_Identifier.h; sourceTree = SOURCE_ROOT; };
FF40DA899AE16A5E1D8AA54A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MemoryBlock.cpp; path = ../../src/containers/juce_MemoryBlock.cpp; sourceTree = SOURCE_ROOT; };
2E5D896B8DB2B357D7440F60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MemoryBlock.h; path = ../../src/containers/juce_MemoryBlock.h; sourceTree = SOURCE_ROOT; };
70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; };
@@ -949,6 +953,8 @@
D4FED84C92ADC4B2C41A4275 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringArray.h; path = ../../src/text/juce_StringArray.h; sourceTree = SOURCE_ROOT; };
81B36E7C56DF1A777AA04F71 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPairArray.cpp; path = ../../src/text/juce_StringPairArray.cpp; sourceTree = SOURCE_ROOT; };
E5458BE2F33DBBF5AF834BB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPairArray.h; path = ../../src/text/juce_StringPairArray.h; sourceTree = SOURCE_ROOT; };
+ 0EC7DE81A516F4130AC59557 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPool.cpp; path = ../../src/text/juce_StringPool.cpp; sourceTree = SOURCE_ROOT; };
+ C972C24A7D2FC817362E1FD7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPool.h; path = ../../src/text/juce_StringPool.h; sourceTree = SOURCE_ROOT; };
5715BC14D93D61D71206FCB2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlDocument.cpp; path = ../../src/text/juce_XmlDocument.cpp; sourceTree = SOURCE_ROOT; };
B4575FEE10C67D45C9532540 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_XmlDocument.h; path = ../../src/text/juce_XmlDocument.h; sourceTree = SOURCE_ROOT; };
95F21C2733BD5932372E4157 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlElement.cpp; path = ../../src/text/juce_XmlElement.cpp; sourceTree = SOURCE_ROOT; };
@@ -1133,6 +1139,8 @@
34C402EF9ADCAD34FB657D43,
7DA9AC75A4D9227C8FC4B2F7,
F364AA2637B7CB89D3657DFF,
+ 1CF7CC0EB057F995BBBEFC90,
+ C16848F86DF014F1CBECE248,
FF40DA899AE16A5E1D8AA54A,
2E5D896B8DB2B357D7440F60,
70E5409425A76782B6188B31,
@@ -1690,6 +1698,8 @@
D4FED84C92ADC4B2C41A4275,
81B36E7C56DF1A777AA04F71,
E5458BE2F33DBBF5AF834BB6,
+ 0EC7DE81A516F4130AC59557,
+ C972C24A7D2FC817362E1FD7,
5715BC14D93D61D71206FCB2,
B4575FEE10C67D45C9532540,
95F21C2733BD5932372E4157,
@@ -1874,6 +1884,7 @@
E8DFABC1603D55B97429A8E4,
BE25871C34D79FEFFD1B94B6,
4AB5E55BDF79028F82F83D8E,
+ 95577AE91AA6CBA7FE9434F3,
21BA256CBCC9C15265928A23,
9D2D1BA65C27BDA1F7C44769,
43B3119E2F1B559263AE956C,
@@ -2129,6 +2140,7 @@
C8F81E843F446868FAD88197,
50D91A2EC0ABF894E612D936,
82568CF438EF4C950E4A42DF,
+ B2E9D0C534DDE9F96921A054,
C8D06AE9C68A675A87DC9C99,
FE2999972FE3D6E251DA6653,
8B2193898D3465B5995EE98A,
diff --git a/Builds/VisualStudio2005/Juce.vcproj b/Builds/VisualStudio2005/Juce.vcproj
index 59717b9384..2824c4f33c 100644
--- a/Builds/VisualStudio2005/Juce.vcproj
+++ b/Builds/VisualStudio2005/Juce.vcproj
@@ -251,6 +251,8 @@
+
+
@@ -815,6 +817,8 @@
+
+
diff --git a/Builds/VisualStudio2008/Juce.vcproj b/Builds/VisualStudio2008/Juce.vcproj
index 63f9e9e586..6fdf00727f 100644
--- a/Builds/VisualStudio2008/Juce.vcproj
+++ b/Builds/VisualStudio2008/Juce.vcproj
@@ -251,6 +251,8 @@
+
+
@@ -815,6 +817,8 @@
+
+
diff --git a/Builds/VisualStudio2008_DLL/Juce.vcproj b/Builds/VisualStudio2008_DLL/Juce.vcproj
index de09f23a74..5e55d73ebe 100644
--- a/Builds/VisualStudio2008_DLL/Juce.vcproj
+++ b/Builds/VisualStudio2008_DLL/Juce.vcproj
@@ -253,6 +253,8 @@
+
+
@@ -817,6 +819,8 @@
+
+
diff --git a/Builds/iPhone/Juce.xcodeproj/project.pbxproj b/Builds/iPhone/Juce.xcodeproj/project.pbxproj
index bf76287b13..0682b1b781 100644
--- a/Builds/iPhone/Juce.xcodeproj/project.pbxproj
+++ b/Builds/iPhone/Juce.xcodeproj/project.pbxproj
@@ -62,6 +62,7 @@
E8DFABC1603D55B97429A8E4 = { isa = PBXBuildFile; fileRef = 35668D8EEA19957C6C9AC83A; };
BE25871C34D79FEFFD1B94B6 = { isa = PBXBuildFile; fileRef = 895D742F49DA9F100990879C; };
4AB5E55BDF79028F82F83D8E = { isa = PBXBuildFile; fileRef = F77C9170829579FABA5679AD; };
+ 95577AE91AA6CBA7FE9434F3 = { isa = PBXBuildFile; fileRef = 1CF7CC0EB057F995BBBEFC90; };
21BA256CBCC9C15265928A23 = { isa = PBXBuildFile; fileRef = FF40DA899AE16A5E1D8AA54A; };
9D2D1BA65C27BDA1F7C44769 = { isa = PBXBuildFile; fileRef = 70E5409425A76782B6188B31; };
43B3119E2F1B559263AE956C = { isa = PBXBuildFile; fileRef = 9BD379D2F7995BFE0B3E5369; };
@@ -317,6 +318,7 @@
C8F81E843F446868FAD88197 = { isa = PBXBuildFile; fileRef = B507B4A8712A54D7A8C03223; };
50D91A2EC0ABF894E612D936 = { isa = PBXBuildFile; fileRef = 23252E4C97AEFAE0C5EEAA77; };
82568CF438EF4C950E4A42DF = { isa = PBXBuildFile; fileRef = 81B36E7C56DF1A777AA04F71; };
+ B2E9D0C534DDE9F96921A054 = { isa = PBXBuildFile; fileRef = 0EC7DE81A516F4130AC59557; };
C8D06AE9C68A675A87DC9C99 = { isa = PBXBuildFile; fileRef = 5715BC14D93D61D71206FCB2; };
FE2999972FE3D6E251DA6653 = { isa = PBXBuildFile; fileRef = 95F21C2733BD5932372E4157; };
8B2193898D3465B5995EE98A = { isa = PBXBuildFile; fileRef = 8E78623B2D21CFE68DEC0483; };
@@ -457,6 +459,8 @@
34C402EF9ADCAD34FB657D43 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_DynamicObject.h; path = ../../src/containers/juce_DynamicObject.h; sourceTree = SOURCE_ROOT; };
7DA9AC75A4D9227C8FC4B2F7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ElementComparator.h; path = ../../src/containers/juce_ElementComparator.h; sourceTree = SOURCE_ROOT; };
F364AA2637B7CB89D3657DFF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_HeapBlock.h; path = ../../src/containers/juce_HeapBlock.h; sourceTree = SOURCE_ROOT; };
+ 1CF7CC0EB057F995BBBEFC90 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Identifier.cpp; path = ../../src/containers/juce_Identifier.cpp; sourceTree = SOURCE_ROOT; };
+ C16848F86DF014F1CBECE248 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_Identifier.h; path = ../../src/containers/juce_Identifier.h; sourceTree = SOURCE_ROOT; };
FF40DA899AE16A5E1D8AA54A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_MemoryBlock.cpp; path = ../../src/containers/juce_MemoryBlock.cpp; sourceTree = SOURCE_ROOT; };
2E5D896B8DB2B357D7440F60 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_MemoryBlock.h; path = ../../src/containers/juce_MemoryBlock.h; sourceTree = SOURCE_ROOT; };
70E5409425A76782B6188B31 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_NamedValueSet.cpp; path = ../../src/containers/juce_NamedValueSet.cpp; sourceTree = SOURCE_ROOT; };
@@ -949,6 +953,8 @@
D4FED84C92ADC4B2C41A4275 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringArray.h; path = ../../src/text/juce_StringArray.h; sourceTree = SOURCE_ROOT; };
81B36E7C56DF1A777AA04F71 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPairArray.cpp; path = ../../src/text/juce_StringPairArray.cpp; sourceTree = SOURCE_ROOT; };
E5458BE2F33DBBF5AF834BB6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPairArray.h; path = ../../src/text/juce_StringPairArray.h; sourceTree = SOURCE_ROOT; };
+ 0EC7DE81A516F4130AC59557 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_StringPool.cpp; path = ../../src/text/juce_StringPool.cpp; sourceTree = SOURCE_ROOT; };
+ C972C24A7D2FC817362E1FD7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_StringPool.h; path = ../../src/text/juce_StringPool.h; sourceTree = SOURCE_ROOT; };
5715BC14D93D61D71206FCB2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlDocument.cpp; path = ../../src/text/juce_XmlDocument.cpp; sourceTree = SOURCE_ROOT; };
B4575FEE10C67D45C9532540 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_XmlDocument.h; path = ../../src/text/juce_XmlDocument.h; sourceTree = SOURCE_ROOT; };
95F21C2733BD5932372E4157 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_XmlElement.cpp; path = ../../src/text/juce_XmlElement.cpp; sourceTree = SOURCE_ROOT; };
@@ -1133,6 +1139,8 @@
34C402EF9ADCAD34FB657D43,
7DA9AC75A4D9227C8FC4B2F7,
F364AA2637B7CB89D3657DFF,
+ 1CF7CC0EB057F995BBBEFC90,
+ C16848F86DF014F1CBECE248,
FF40DA899AE16A5E1D8AA54A,
2E5D896B8DB2B357D7440F60,
70E5409425A76782B6188B31,
@@ -1690,6 +1698,8 @@
D4FED84C92ADC4B2C41A4275,
81B36E7C56DF1A777AA04F71,
E5458BE2F33DBBF5AF834BB6,
+ 0EC7DE81A516F4130AC59557,
+ C972C24A7D2FC817362E1FD7,
5715BC14D93D61D71206FCB2,
B4575FEE10C67D45C9532540,
95F21C2733BD5932372E4157,
@@ -1874,6 +1884,7 @@
E8DFABC1603D55B97429A8E4,
BE25871C34D79FEFFD1B94B6,
4AB5E55BDF79028F82F83D8E,
+ 95577AE91AA6CBA7FE9434F3,
21BA256CBCC9C15265928A23,
9D2D1BA65C27BDA1F7C44769,
43B3119E2F1B559263AE956C,
@@ -2129,6 +2140,7 @@
C8F81E843F446868FAD88197,
50D91A2EC0ABF894E612D936,
82568CF438EF4C950E4A42DF,
+ B2E9D0C534DDE9F96921A054,
C8D06AE9C68A675A87DC9C99,
FE2999972FE3D6E251DA6653,
8B2193898D3465B5995EE98A,
diff --git a/Juce.jucer b/Juce.jucer
index a1562a0982..f714b9aa8d 100644
--- a/Juce.jucer
+++ b/Juce.jucer
@@ -311,6 +311,10 @@
file="src/containers/juce_ElementComparator.h"/>
+
+
+
+
+
+
+
+
-
-
+
+
+
diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
index 83dded36e4..04412dbf47 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
@@ -223,17 +223,22 @@
+
+
+
+
-
-
+
+
+
diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp
index 804b52248c..862d572556 100644
--- a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp
+++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.cpp
@@ -694,10 +694,6 @@ static const unsigned char temp_73015554[] =
"%%staticMemberDefinitions%%\r\n"
"\r\n"
"//==============================================================================\r\n"
-"/* This data contains the ValueTree that holds all the Jucer-generated settings for the components */\r\n"
-"const unsigned char %%className%%_ComponentStateData[] = %%statedata%%;\r\n"
-"\r\n"
-"//==============================================================================\r\n"
"//======================= Jucer Information Section ==========================\r\n"
"//==============================================================================\r\n"
"#if 0\r\n"
@@ -770,8 +766,6 @@ static const unsigned char temp_b930c59[] =
" %%privateMemberDeclarations%%\r\n"
"\r\n"
" //==============================================================================\r\n"
-" ValueTree componentState;\r\n"
-" \r\n"
" // (prevent copy constructor and operator= being generated..)\r\n"
" %%className%% (const %%className%%&);\r\n"
" %%className%%& operator= (const %%className%%&);\r\n"
diff --git a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h
index 50f94d0b3c..0c156266ad 100644
--- a/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h
+++ b/extras/Jucer (experimental)/JuceLibraryCode/BinaryData.h
@@ -26,10 +26,10 @@ namespace BinaryData
const int jucer_AudioPluginFilterTemplate_hSize = 2353;
extern const char* jucer_ComponentTemplate_cpp;
- const int jucer_ComponentTemplate_cppSize = 2534;
+ const int jucer_ComponentTemplate_cppSize = 2274;
extern const char* jucer_ComponentTemplate_h;
- const int jucer_ComponentTemplate_hSize = 2276;
+ const int jucer_ComponentTemplate_hSize = 2239;
extern const char* jucer_MainConsoleAppTemplate_cpp;
const int jucer_MainConsoleAppTemplate_cppSize = 749;
diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer
index fef6f242de..74d06366e8 100644
--- a/extras/Jucer (experimental)/Jucer.jucer
+++ b/extras/Jucer (experimental)/Jucer.jucer
@@ -14,9 +14,9 @@
+ rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/>
+ rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../.." libraryType="1"/>
@@ -193,6 +193,10 @@
+
+
+
+
-
-
+
+
+
diff --git a/extras/Jucer (experimental)/Source/jucer_Headers.h b/extras/Jucer (experimental)/Source/jucer_Headers.h
index 3dd37e6943..29b413038e 100644
--- a/extras/Jucer (experimental)/Source/jucer_Headers.h
+++ b/extras/Jucer (experimental)/Source/jucer_Headers.h
@@ -34,7 +34,9 @@
//==============================================================================
#include "../JuceLibraryCode/JuceHeader.h"
#include "utility/jucer_StoredSettings.h"
-#include "utility/jucer_UtilityFunctions.h"
+#include "utility/jucer_MiscUtilities.h"
+#include "utility/jucer_CodeHelpers.h"
+#include "utility/jucer_FileHelpers.h"
#include "utility/jucer_RelativePath.h"
#include "utility/jucer_ValueRemapperSource.h"
#include "ui/jucer_CommandIDs.h"
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h
index b280c11f31..59da4d5986 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComboBox.h
@@ -50,11 +50,11 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("items", "Item 1\nItem 2");
- item.set ("editable", false);
- item.set ("textJustification", (int) Justification::centredLeft);
- item.set ("unselectedText", "");
- item.set ("noItemsText", "(No Choices)");
+ item.set (Ids::items, "Item 1\nItem 2");
+ item.set (Ids::editable, false);
+ item.set (Ids::textJustification, (int) Justification::centredLeft);
+ item.set (Ids::unselectedText, "");
+ item.set (Ids::noItemsText, "(No Choices)");
}
void updateItems (ComboBox* comp, const String& itemString)
@@ -79,11 +79,11 @@ public:
void update (ComponentTypeInstance& item, ComboBox* comp)
{
- updateItems (comp, item ["items"]);
- comp->setEditableText (item ["editable"]);
- comp->setJustificationType ((int) item ["textJustification"]);
- comp->setTextWhenNothingSelected (item ["unselectedText"].toString());
- comp->setTextWhenNoChoicesAvailable (item ["noItemsText"].toString());
+ updateItems (comp, item [Ids::items]);
+ comp->setEditableText (item [Ids::editable]);
+ comp->setJustificationType ((int) item [Ids::textJustification]);
+ comp->setTextWhenNothingSelected (item [Ids::unselectedText].toString());
+ comp->setTextWhenNoChoicesAvailable (item [Ids::noItemsText].toString());
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -91,20 +91,43 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("items"), "Items", 16384, true));
+ props.add (new TextPropertyComponent (item.getValue (Ids::items), "Items", 16384, true));
props.getLast()->setTooltip ("A list of items to use to initialise the ComboBox");
- props.add (new BooleanPropertyComponent (item.getValue ("editable"), "Editable", "Text is editable"));
- item.addJustificationProperty (props, "Text Position", item.getValue ("textJustification"), false);
- props.add (new TextPropertyComponent (item.getValue ("unselectedText"), "Text when none selected", 512, false));
- props.add (new TextPropertyComponent (item.getValue ("noItemsText"), "Text when no items", 512, false));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::editable), "Editable", "Text is editable"));
+ item.addJustificationProperty (props, "Text Position", item.getValue (Ids::textJustification), false);
+ props.add (new TextPropertyComponent (item.getValue (Ids::unselectedText), "Text when none selected", 512, false));
+ props.add (new TextPropertyComponent (item.getValue (Ids::noItemsText), "Text when no items", 512, false));
addEditableColourProperties (item, props);
}
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
{
- code.constructorCode << item.createConstructorStatement (String::empty);
+ ComboBox defaultBox;
+
+ code.constructorCode
+ << item.createConstructorStatement (String::empty)
+ << item.getMemberName() << "->setEditableText (" << CodeHelpers::boolLiteral (item [Ids::editable]) << ");" << newLine;
+
+ Justification justification ((int) item [Ids::textJustification]);
+ if (justification.getFlags() != 0 && justification.getFlags() != defaultBox.getJustificationType().getFlags())
+ code.constructorCode << item.getMemberName() << "->setJustificationType (" << CodeHelpers::justificationToCode (justification) << ");" << newLine;
+
+ if (item [Ids::unselectedText].toString() != defaultBox.getTextWhenNothingSelected())
+ code.constructorCode << item.getMemberName() << "->setTextWhenNothingSelected ("
+ << CodeHelpers::stringLiteral (item [Ids::unselectedText]) << ");" << newLine;
+
+ if (item [Ids::noItemsText].toString() != defaultBox.getTextWhenNoChoicesAvailable())
+ code.constructorCode << item.getMemberName() << "->setTextWhenNoChoicesAvailable ("
+ << CodeHelpers::stringLiteral (item [Ids::noItemsText]) << ");" << newLine;
+
+ StringArray items;
+ items.addLines (item [Ids::items]);
+ items.removeEmptyStrings (true);
+
+ for (int i = 0; i < items.size(); ++i)
+ code.constructorCode << item.getMemberName() << "->addItem (" << CodeHelpers::stringLiteral (items[i]) << ");" << newLine;
}
};
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp
index db20f38549..e87dec5688 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.cpp
@@ -24,6 +24,46 @@
*/
#include "jucer_ComponentTypeManager.h"
+
+// Handy list of static ids for use by component types..
+namespace Ids
+{
+ #define DECLARE_ID(name) const Identifier name (#name)
+
+ DECLARE_ID (text);
+ DECLARE_ID (font);
+ DECLARE_ID (mode);
+ DECLARE_ID (type);
+ DECLARE_ID (readOnly);
+ DECLARE_ID (editMode);
+ DECLARE_ID (justification);
+ DECLARE_ID (items);
+ DECLARE_ID (editable);
+ DECLARE_ID (textJustification);
+ DECLARE_ID (unselectedText);
+ DECLARE_ID (noItemsText);
+ DECLARE_ID (min);
+ DECLARE_ID (max);
+ DECLARE_ID (interval);
+ DECLARE_ID (textBoxPos);
+ DECLARE_ID (textBoxWidth);
+ DECLARE_ID (textBoxHeight);
+ DECLARE_ID (skew);
+ DECLARE_ID (scrollBarV);
+ DECLARE_ID (scrollBarH);
+ DECLARE_ID (scrollbarWidth);
+ DECLARE_ID (initialState);
+ DECLARE_ID (scrollbarsShown);
+ DECLARE_ID (caretVisible);
+ DECLARE_ID (popupMenuEnabled);
+ DECLARE_ID (radioGroup);
+ DECLARE_ID (connectedLeft);
+ DECLARE_ID (connectedRight);
+ DECLARE_ID (connectedTop);
+ DECLARE_ID (connectedBottom);
+ const Identifier class_ ("class");
+}
+
#include "jucer_ComponentTypes.h"
#include "../../../utility/jucer_CoordinatePropertyComponent.h"
@@ -261,12 +301,12 @@ ComponentTypeInstance::ComponentTypeInstance (ComponentDocument& document_, cons
{
}
-Value ComponentTypeInstance::getValue (const var::identifier& name) const
+Value ComponentTypeInstance::getValue (const Identifier& name) const
{
return state.getPropertyAsValue (name, document.getUndoManager());
}
-void ComponentTypeInstance::set (const var::identifier& name, const var& value)
+void ComponentTypeInstance::set (const Identifier& name, const var& value)
{
state.setProperty (name, value, 0);
}
@@ -352,7 +392,7 @@ void ComponentTypeInstance::addFocusOrderProperty (Array & p
"Focus Order", 10, false));
}
-void ComponentTypeInstance::addColourProperty (Array & props, int colourId, const String& name, const String& propertyName)
+void ComponentTypeInstance::addColourProperty (Array & props, int colourId, const String& name, const Identifier& propertyName)
{
props.add (new ColourPropertyComponent (document, name, getValue (propertyName),
LookAndFeel::getDefaultLookAndFeel().findColour (colourId), true));
@@ -498,7 +538,7 @@ private:
Value sourceValue;
};
-void ComponentTypeInstance::addFontProperties (Array & props, const var::identifier& name)
+void ComponentTypeInstance::addFontProperties (Array & props, const Identifier& name)
{
Value v (getValue (name));
props.add (FontNameValueSource::createProperty ("Font", v));
@@ -551,7 +591,7 @@ const String ComponentTypeInstance::createConstructorStatement (const String& pa
else
{
s << " (";
- s << CodeFormatting::indent (params.trim(), s.length(), false) << "));" << newLine;
+ s << CodeHelpers::indent (params.trim(), s.length(), false) << "));" << newLine;
}
// s << getMemberName() << "->updateStateFrom (componentStateList.getChild ("
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h
index 8865010532..8a9f95cf85 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h
@@ -29,6 +29,7 @@
#include "../../../jucer_Headers.h"
#include "../jucer_ComponentDocument.h"
#include "../../../utility/jucer_ColourEditorComponent.h"
+
class ComponentTypeHandler;
class JucerState
@@ -60,9 +61,9 @@ public:
ComponentDocument& getDocument() throw() { return document; }
ValueTree& getState() throw() { return state; }
- Value getValue (const var::identifier& name) const;
- void set (const var::identifier& name, const var& value);
- const var operator[] (const var::identifier& name) const { return state [name] ;}
+ Value getValue (const Identifier& name) const;
+ void set (const Identifier& name, const var& value);
+ const var operator[] (const Identifier& name) const { return state [name] ;}
const String getMemberName() const { return state [ComponentDocument::memberNameProperty]; }
const String getComponentName() const { return state [ComponentDocument::compNameProperty]; }
@@ -75,8 +76,8 @@ public:
void addBoundsProperties (Array & props);
void addTooltipProperty (Array & props);
void addFocusOrderProperty (Array & props);
- void addColourProperty (Array & props, int colourId, const String& name, const String& propertyName);
- void addFontProperties (Array & props, const var::identifier& name);
+ void addColourProperty (Array & props, int colourId, const String& name, const Identifier& propertyName);
+ void addFontProperties (Array & props, const Identifier& name);
void addJustificationProperty (Array & props, const String& name, const Value& value, bool onlyHorizontal);
//==============================================================================
@@ -104,7 +105,7 @@ public:
virtual ~ComponentTypeHandler();
const String& getDisplayName() const { return displayName; }
- const String& getXmlTag() const { return xmlTag; }
+ const Identifier& getXmlTag() const { return xmlTag; }
const String& getMemberNameRoot() const { return memberNameRoot; }
virtual Component* createComponent() = 0;
@@ -118,7 +119,8 @@ public:
protected:
//==============================================================================
- const String displayName, className, xmlTag, memberNameRoot;
+ const String displayName, className, memberNameRoot;
+ const Identifier xmlTag;
private:
ComponentTypeHandler (const ComponentTypeHandler&);
@@ -196,12 +198,13 @@ protected:
struct EditableColour
{
int colourId;
- String name, propertyName;
+ String name;
+ Identifier propertyName;
};
Array editableColours;
- void addEditableColour (int colourId, const String& displayName, const String& propertyName)
+ void addEditableColour (int colourId, const String& displayName, const Identifier& propertyName)
{
EditableColour ec;
ec.colourId = colourId;
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h
index 99e05c274f..4a1db5efd9 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GenericComponent.h
@@ -68,26 +68,26 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("class", "Component");
+ item.set (Ids::class_, "Component");
}
void update (ComponentTypeInstance& item, Component* comp)
{
static_cast (comp)->setDetails (item [ComponentDocument::memberNameProperty],
- item ["class"]);
+ item [Ids::class_]);
}
void createProperties (ComponentTypeInstance& item, Array & props)
{
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("class"), "Class", 256, false));
+ props.add (new TextPropertyComponent (item.getValue (Ids::class_), "Class", 256, false));
props.getLast()->setTooltip ("The class that this component is an instance of.");
}
const String getClassName (ComponentTypeInstance& item) const
{
- return item ["class"];
+ return item [Ids::class_];
}
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h
index 78abea46d7..277555514a 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_GroupComponent.h
@@ -47,14 +47,14 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("text", "Group");
- item.set ("justification", (int) Justification::left);
+ item.set (Ids::text, "Group");
+ item.set (Ids::justification, (int) Justification::left);
}
void update (ComponentTypeInstance& item, GroupComponent* comp)
{
- comp->setText (item ["text"].toString());
- comp->setTextLabelPosition ((int) item ["justification"]);
+ comp->setText (item [Ids::text].toString());
+ comp->setTextLabelPosition ((int) item [Ids::justification]);
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -62,10 +62,10 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("text"), "Label", 512, false));
+ props.add (new TextPropertyComponent (item.getValue (Ids::text), "Label", 512, false));
props.getLast()->setTooltip ("The group's display name.");
- item.addJustificationProperty (props, "Text Position", item.getValue ("justification"), true);
+ item.addJustificationProperty (props, "Text Position", item.getValue (Ids::justification), true);
addEditableColourProperties (item, props);
}
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h
index 0b28894830..bf0c1df98f 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h
@@ -48,19 +48,19 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("text", "New Label");
- item.set ("font", Font (14.0f).toString());
- item.set ("editMode", 1);
- item.set ("justification", (int) Justification::centredLeft);
+ item.set (Ids::text, "New Label");
+ item.set (Ids::font, Font (14.0f).toString());
+ item.set (Ids::editMode, 1);
+ item.set (Ids::justification, (int) Justification::centredLeft);
}
void update (ComponentTypeInstance& item, Label* comp)
{
- comp->setText (item ["text"].toString(), false);
- comp->setFont (Font::fromString (item ["font"]));
- int editMode = (int) item ["editMode"];
+ comp->setText (item [Ids::text].toString(), false);
+ comp->setFont (Font::fromString (item [Ids::font]));
+ int editMode = (int) item [Ids::editMode];
comp->setEditable (editMode == 2, editMode == 3, false);
- comp->setJustificationType ((int) item ["justification"]);
+ comp->setJustificationType ((int) item [Ids::justification]);
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -68,22 +68,34 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("text"), "Text", 16384, true));
+ props.add (new TextPropertyComponent (item.getValue (Ids::text), "Text", 16384, true));
props.getLast()->setTooltip ("The label's text.");
item.addJustificationProperty (props, "Layout", item.getValue ("justification"), false);
const char* const editModes[] = { "Read-only", "Edit on Single-Click", "Edit on Double-Click", 0 };
- props.add (new ChoicePropertyComponent (item.getValue ("editMode"), "Edit Mode", StringArray (editModes)));
+ props.add (new ChoicePropertyComponent (item.getValue (Ids::editMode), "Edit Mode", StringArray (editModes)));
- item.addFontProperties (props, "font");
+ item.addFontProperties (props, Ids::font);
addEditableColourProperties (item, props);
}
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
{
- code.constructorCode << item.createConstructorStatement (String::empty);
+ int editMode = (int) item [Ids::editMode];
+
+ code.constructorCode
+ << item.createConstructorStatement (String::empty)
+ << item.getMemberName() << "->setText (" << CodeHelpers::stringLiteral (item [Ids::text]) << ");" << newLine
+ << item.getMemberName() << "->setFont (" << CodeHelpers::fontToCode (Font::fromString (item [Ids::font])) << ");" << newLine
+ << item.getMemberName() << "->setEditable (" << CodeHelpers::boolLiteral (editMode == 2)
+ << ", " << CodeHelpers::boolLiteral (editMode == 3) << ", false);" << newLine;
+
+ Justification justification ((int) item ["textJustification"]);
+ if (justification.getFlags() != 0)
+ code.constructorCode << item.getMemberName() << "->setJustificationType ("
+ << CodeHelpers::justificationToCode (justification) << ");" << newLine;
}
};
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h
index 2009617240..4b32a078a9 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h
@@ -54,25 +54,25 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("min", 0);
- item.set ("max", 100);
- item.set ("interval", 1);
- item.set ("type", 1 + Slider::LinearHorizontal);
- item.set ("textBoxPos", 2);
- item.set ("editable", true);
- item.set ("textBoxWidth", 80);
- item.set ("textBoxHeight", 20);
- item.set ("skew", 1);
+ item.set (Ids::min, 0);
+ item.set (Ids::max, 100);
+ item.set (Ids::interval, 1);
+ item.set (Ids::type, 1 + Slider::LinearHorizontal);
+ item.set (Ids::textBoxPos, 2);
+ item.set (Ids::editable, true);
+ item.set (Ids::textBoxWidth, 80);
+ item.set (Ids::textBoxHeight, 20);
+ item.set (Ids::skew, 1);
}
void update (ComponentTypeInstance& item, Slider* comp)
{
- comp->setRange ((double) item ["min"], (double) item ["max"], (double) item ["interval"]);
- comp->setSliderStyle ((Slider::SliderStyle) ((int) item ["type"] - 1));
- comp->setTextBoxStyle ((Slider::TextEntryBoxPosition) ((int) item ["textBoxPos"] - 1),
- ! (bool) item ["editable"],
- (int) item ["textBoxWidth"], (int) item ["textBoxHeight"]);
- comp->setSkewFactor ((double) item ["skew"]);
+ comp->setRange ((double) item [Ids::min], (double) item [Ids::max], (double) item [Ids::interval]);
+ comp->setSliderStyle ((Slider::SliderStyle) ((int) item [Ids::type] - 1));
+ comp->setTextBoxStyle ((Slider::TextEntryBoxPosition) ((int) item [Ids::textBoxPos] - 1),
+ ! (bool) item [Ids::editable],
+ (int) item [Ids::textBoxWidth], (int) item [Ids::textBoxHeight]);
+ comp->setSkewFactor ((double) item [Ids::skew]);
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -80,28 +80,79 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("min"))), "Minimum", 16, false));
- props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("max"))), "Maximum", 16, false));
- props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("interval"))), "Interval", 16, false));
+ props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::min))), "Minimum", 16, false));
+ props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::max))), "Maximum", 16, false));
+ props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::interval))), "Interval", 16, false));
const char* const types[] = { "LinearHorizontal", "LinearVertical", "LinearBar", "Rotary", "RotaryHorizontalDrag", "RotaryVerticalDrag",
"IncDecButtons", "TwoValueHorizontal", "TwoValueVertical", "ThreeValueHorizontal", "ThreeValueVertical", 0 };
- props.add (new ChoicePropertyComponent (item.getValue ("type"), "Type", StringArray (types)));
+ props.add (new ChoicePropertyComponent (item.getValue (Ids::type), "Type", StringArray (types)));
const char* const textBoxPositions[] = { "NoTextBox", "TextBoxLeft", "TextBoxRight", "TextBoxAbove", "TextBoxBelow", 0 };
- props.add (new ChoicePropertyComponent (item.getValue ("textBoxPos"), "Text Box", StringArray (textBoxPositions)));
+ props.add (new ChoicePropertyComponent (item.getValue (Ids::textBoxPos), "Text Box", StringArray (textBoxPositions)));
- props.add (new BooleanPropertyComponent (item.getValue ("editable"), "Editable", "Value can be edited"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::editable), "Editable", "Value can be edited"));
props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("textBoxWidth"))), "Text Box Width", 8, false));
props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("textBoxHeight"))), "Text Box Height", 8, false));
- props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("skew"))), "Skew Factor", 16, false));
+ props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::skew))), "Skew Factor", 16, false));
addEditableColourProperties (item, props);
}
+ static const char* sliderTypeString (int type) throw()
+ {
+ switch (type)
+ {
+ case Slider::LinearHorizontal: return "LinearHorizontal";
+ case Slider::LinearVertical: return "LinearVertical";
+ case Slider::LinearBar: return "LinearBar";
+ case Slider::Rotary: return "Rotary";
+ case Slider::RotaryHorizontalDrag: return "RotaryHorizontalDrag";
+ case Slider::RotaryVerticalDrag: return "RotaryVerticalDrag";
+ case Slider::IncDecButtons: return "IncDecButtons";
+ case Slider::TwoValueHorizontal: return "TwoValueHorizontal";
+ case Slider::TwoValueVertical: return "TwoValueVertical";
+ case Slider::ThreeValueHorizontal: return "ThreeValueHorizontal";
+ case Slider::ThreeValueVertical: return "ThreeValueVertical";
+ default: jassertfalse; break;
+ }
+
+ return "";
+ }
+
+ static const char* sliderTextBoxString (int type) throw()
+ {
+ switch (type)
+ {
+ case Slider::NoTextBox: return "NoTextBox";
+ case Slider::TextBoxLeft: return "TextBoxLeft";
+ case Slider::TextBoxRight: return "TextBoxRight";
+ case Slider::TextBoxAbove: return "TextBoxAbove";
+ case Slider::TextBoxBelow: return "TextBoxBelow";
+ default: jassertfalse; break;
+ }
+
+ return "";
+ }
+
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
{
- code.constructorCode << item.createConstructorStatement (CodeFormatting::stringLiteral (item.getComponentName()));
+ code.constructorCode
+ << item.createConstructorStatement (CodeHelpers::stringLiteral (item.getComponentName()))
+ << item.getMemberName() << "->setRange (" << CodeHelpers::doubleLiteral (item [Ids::min])
+ << ", " << CodeHelpers::doubleLiteral (item [Ids::max])
+ << ", " << CodeHelpers::doubleLiteral (item [Ids::interval])
+ << ");" << newLine
+ << item.getMemberName() << "->setSliderStyle (Slider::" << sliderTypeString ((int) item [Ids::type] - 1) << ");" << newLine
+ << item.getMemberName() << "->setTextBoxStyle (Slider::" << sliderTextBoxString ((int) item [Ids::type] - 1)
+ << ", " << CodeHelpers::boolLiteral (! (bool) item [Ids::editable])
+ << ", " << String ((int) item [Ids::textBoxWidth])
+ << ", " << String ((int) item [Ids::textBoxHeight])
+ << ");" << newLine;
+
+ double skew = (double) item [Ids::skew];
+ if (skew != 1.0 && skew != 0)
+ code.constructorCode << item.getMemberName() << "->setSkewFactor (" << CodeHelpers::doubleLiteral (skew) << ");" << newLine;
}
};
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h
index 1f4aa2fc91..034f65d960 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h
@@ -47,26 +47,29 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("text", "New Button");
- item.set ("radioGroup", 0);
- item.set ("connectedLeft", false);
- item.set ("connectedRight", false);
- item.set ("connectedTop", false);
- item.set ("connectedBottom", false);
+ item.set (Ids::text, "New Button");
+ item.set (Ids::radioGroup, 0);
+ item.set (Ids::connectedLeft, false);
+ item.set (Ids::connectedRight, false);
+ item.set (Ids::connectedTop, false);
+ item.set (Ids::connectedBottom, false);
}
- void update (ComponentTypeInstance& item, TextButton* comp)
+ static int getConnectedFlags (ComponentTypeInstance& item)
{
- comp->setButtonText (item ["text"].toString());
- comp->setRadioGroupId (item ["radioGroup"]);
-
int connected = 0;
- if (item ["connectedLeft"]) connected |= TextButton::ConnectedOnLeft;
- if (item ["connectedRight"]) connected |= TextButton::ConnectedOnRight;
- if (item ["connectedTop"]) connected |= TextButton::ConnectedOnTop;
- if (item ["connectedBottom"]) connected |= TextButton::ConnectedOnBottom;
+ if (item [Ids::connectedLeft]) connected |= TextButton::ConnectedOnLeft;
+ if (item [Ids::connectedRight]) connected |= TextButton::ConnectedOnRight;
+ if (item [Ids::connectedTop]) connected |= TextButton::ConnectedOnTop;
+ if (item [Ids::connectedBottom]) connected |= TextButton::ConnectedOnBottom;
+ return connected;
+ }
- comp->setConnectedEdges (connected);
+ void update (ComponentTypeInstance& item, TextButton* comp)
+ {
+ comp->setButtonText (item [Ids::text].toString());
+ comp->setRadioGroupId (item [Ids::radioGroup]);
+ comp->setConnectedEdges (getConnectedFlags (item));
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -74,23 +77,31 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("text"), "Button Text", 1024, false));
+ props.add (new TextPropertyComponent (item.getValue (Ids::text), "Button Text", 1024, false));
props.getLast()->setTooltip ("The button's text.");
- props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue ("radioGroup"))), "Radio Group", 8, false));
+ props.add (new TextPropertyComponent (Value (new NumericValueSource (item.getValue (Ids::radioGroup))), "Radio Group", 8, false));
props.getLast()->setTooltip ("The radio group that this button is a member of.");
- props.add (new BooleanPropertyComponent (item.getValue ("connectedLeft"), "Connected left", "Connected"));
- props.add (new BooleanPropertyComponent (item.getValue ("connectedRight"), "Connected right", "Connected"));
- props.add (new BooleanPropertyComponent (item.getValue ("connectedTop"), "Connected top", "Connected"));
- props.add (new BooleanPropertyComponent (item.getValue ("connectedBottom"), "Connected bottom", "Connected"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedLeft), "Connected left", "Connected"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedRight), "Connected right", "Connected"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedTop), "Connected top", "Connected"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::connectedBottom), "Connected bottom", "Connected"));
addEditableColourProperties (item, props);
}
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
{
- code.constructorCode += item.createConstructorStatement (String::empty);
+ code.constructorCode
+ << item.createConstructorStatement (String::empty)
+ << item.getMemberName() << "->setButtonText (" << CodeHelpers::stringLiteral (item [Ids::text]) << ");" << newLine;
+
+ if ((int) item [Ids::radioGroup] != 0)
+ code.constructorCode << item.getMemberName() << "->setRadioGroupId (" << String ((int) item [Ids::radioGroup]) << ");" << newLine;
+
+ if (getConnectedFlags (item) != 0)
+ code.constructorCode << item.getMemberName() << "->setConnectedEdges (" << String (getConnectedFlags (item)) << ");" << newLine;
}
};
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h
index a433b50847..8b6f273e95 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h
@@ -53,24 +53,32 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("text", "Text Editor Content");
- item.set ("readOnly", false);
- item.set ("scrollbarsShown", true);
- item.set ("caretVisible", true);
- item.set ("popupMenuEnabled", true);
- item.set ("mode", 1);
+ TextEditor defaultComp;
+
+ item.set (Ids::text, "Text Editor Content");
+ item.set (Ids::readOnly, false);
+ item.set (Ids::scrollbarsShown, true);
+ item.set (Ids::caretVisible, true);
+ item.set (Ids::popupMenuEnabled, true);
+ item.set (Ids::mode, 1);
+ item.set (Ids::font, defaultComp.getFont().toString());
}
void update (ComponentTypeInstance& item, TextEditor* comp)
{
- comp->setReadOnly (item ["readOnly"]);
- comp->setScrollbarsShown (item ["scrollbarsShown"]);
- comp->setCaretVisible (item ["caretVisible"]);
- comp->setPopupMenuEnabled (item ["popupMenuEnabled"]);
- int mode = item ["mode"];
+ comp->setReadOnly (item [Ids::readOnly]);
+ comp->setScrollbarsShown (item [Ids::scrollbarsShown]);
+ comp->setCaretVisible (item [Ids::caretVisible]);
+ comp->setPopupMenuEnabled (item [Ids::popupMenuEnabled]);
+ int mode = item [Ids::mode];
comp->setMultiLine (mode > 1, true);
comp->setReturnKeyStartsNewLine (mode != 3);
- comp->setText (item ["text"].toString());
+
+ const Font font (Font::fromString (item [Ids::font]));
+ if (comp->getFont() != font)
+ comp->applyFontToAllText (font);
+
+ comp->setText (item [Ids::text].toString());
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -78,23 +86,53 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("text"), "Text", 16384, true));
+ props.add (new TextPropertyComponent (item.getValue (Ids::text), "Text", 16384, true));
props.getLast()->setTooltip ("The editor's initial content.");
const char* const modes[] = { "Single-Line", "Multi-Line (Return key starts new line)", "Multi-Line (Return key disabled)", 0 };
- props.add (new ChoicePropertyComponent (item.getValue ("mode"), "Mode", StringArray (modes)));
+ props.add (new ChoicePropertyComponent (item.getValue (Ids::mode), "Mode", StringArray (modes)));
+
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::readOnly), "Read-Only", "Read-Only"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::scrollbarsShown), "Scrollbars", "Scrollbars Shown"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::caretVisible), "Caret", "Caret Visible"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::popupMenuEnabled), "Popup Menu", "Popup Menu Enabled"));
- props.add (new BooleanPropertyComponent (item.getValue ("readOnly"), "Read-Only", "Read-Only"));
- props.add (new BooleanPropertyComponent (item.getValue ("scrollbarsShown"), "Scrollbars", "Scrollbars Shown"));
- props.add (new BooleanPropertyComponent (item.getValue ("caretVisible"), "Caret", "Caret Visible"));
- props.add (new BooleanPropertyComponent (item.getValue ("popupMenuEnabled"), "Popup Menu", "Popup Menu Enabled"));
+ item.addFontProperties (props, Ids::font);
addEditableColourProperties (item, props);
}
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
{
- code.constructorCode += item.createConstructorStatement (String::empty);
+ TextEditor defaultComp;
+
+ code.constructorCode
+ << item.createConstructorStatement (String::empty);
+
+ if (defaultComp.isReadOnly() != (bool) item [Ids::readOnly])
+ code.constructorCode << item.getMemberName() << "->setReadOnly (" << CodeHelpers::boolLiteral (item [Ids::readOnly]) << ");" << newLine;
+
+ if (defaultComp.areScrollbarsShown() != (bool) item [Ids::scrollbarsShown])
+ code.constructorCode << item.getMemberName() << "->setScrollbarsShown (" << CodeHelpers::boolLiteral (item [Ids::scrollbarsShown]) << ");" << newLine;
+
+ if (defaultComp.isCaretVisible() != (bool) item [Ids::caretVisible])
+ code.constructorCode << item.getMemberName() << "->setCaretVisible (" << CodeHelpers::boolLiteral (item [Ids::caretVisible]) << ");" << newLine;
+
+ if (defaultComp.isPopupMenuEnabled() != (bool) item [Ids::popupMenuEnabled])
+ code.constructorCode << item.getMemberName() << "->setPopupMenuEnabled (" << CodeHelpers::boolLiteral (item [Ids::popupMenuEnabled]) << ");" << newLine;
+
+ int mode = item [Ids::mode];
+ if (defaultComp.isMultiLine() != (mode > 1))
+ code.constructorCode << item.getMemberName() << "->setMultiLine (" << CodeHelpers::boolLiteral (mode > 1) << ", true);" << newLine;
+
+ if (defaultComp.getReturnKeyStartsNewLine() != (mode != 3))
+ code.constructorCode << item.getMemberName() << "->setReturnKeyStartsNewLine (" << CodeHelpers::boolLiteral (mode != 3) << ");" << newLine;
+
+ const Font font (Font::fromString (item [Ids::font]));
+ if (font != defaultComp.getFont())
+ code.constructorCode << item.getMemberName() << "->setFont (" << CodeHelpers::fontToCode (font) << ");" << newLine;
+
+ code.constructorCode << item.getMemberName() << "->setText (" << CodeHelpers::stringLiteral (item [Ids::text]) << ");" << newLine;
}
};
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h
index c3f0fd6dda..f5cc185c03 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h
@@ -46,14 +46,14 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("text", "New Toggle Button");
- item.set ("initialState", false);
+ item.set (Ids::text, "New Toggle Button");
+ item.set (Ids::initialState, false);
}
void update (ComponentTypeInstance& item, ToggleButton* comp)
{
- comp->setButtonText (item ["text"].toString());
- comp->setToggleState (item ["initialState"], false);
+ comp->setButtonText (item [Ids::text].toString());
+ comp->setToggleState (item [Ids::initialState], false);
}
void createProperties (ComponentTypeInstance& item, Array & props)
@@ -61,10 +61,10 @@ public:
item.addTooltipProperty (props);
item.addFocusOrderProperty (props);
- props.add (new TextPropertyComponent (item.getValue ("text"), "Button Text", 1024, false));
+ props.add (new TextPropertyComponent (item.getValue (Ids::text), "Button Text", 1024, false));
props.getLast()->setTooltip ("The button's text.");
- props.add (new BooleanPropertyComponent (item.getValue ("initialState"), "Initial State", "Enabled initially"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::initialState), "Initial State", "Enabled initially"));
addEditableColourProperties (item, props);
}
diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h
index 8c0224eb72..2654477535 100644
--- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h
+++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h
@@ -62,29 +62,30 @@ public:
void initialiseNew (ComponentTypeInstance& item)
{
- item.set ("scrollBarV", true);
- item.set ("scrollBarH", true);
- item.set ("scrollbarWidth", 18);
+ item.set (Ids::scrollBarV, true);
+ item.set (Ids::scrollBarH, true);
+ item.set (Ids::scrollbarWidth, 18);
}
void update (ComponentTypeInstance& item, Viewport* comp)
{
- comp->setScrollBarsShown (item ["scrollBarV"], item ["scrollBarH"]);
- comp->setScrollBarThickness (item ["scrollbarWidth"]);
+ comp->setScrollBarsShown (item [Ids::scrollBarV], item [Ids::scrollBarH]);
+ comp->setScrollBarThickness (item [Ids::scrollbarWidth]);
}
void createProperties (ComponentTypeInstance& item, Array & props)
{
- props.add (new BooleanPropertyComponent (item.getValue ("scrollBarV"), "Scrollbar V", "Vertical scrollbar shown"));
- props.add (new BooleanPropertyComponent (item.getValue ("scrollBarH"), "Scrollbar H", "Horizontal scrollbar shown"));
- props.add (new SliderPropertyComponent (item.getValue ("scrollbarWidth"), "Scrollbar Thickness", 3, 40, 1));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::scrollBarV), "Scrollbar V", "Vertical scrollbar shown"));
+ props.add (new BooleanPropertyComponent (item.getValue (Ids::scrollBarH), "Scrollbar H", "Horizontal scrollbar shown"));
+ props.add (new SliderPropertyComponent (item.getValue (Ids::scrollbarWidth), "Scrollbar Thickness", 3, 40, 1));
addEditableColourProperties (item, props);
}
void createCode (ComponentTypeInstance& item, CodeGenerator& code)
{
- code.constructorCode << item.createConstructorStatement (CodeFormatting::stringLiteral (item.getComponentName()));
+ code.constructorCode << item.createConstructorStatement (CodeHelpers::stringLiteral (item.getComponentName()));
}
};
+
#endif
diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp b/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp
index f54538e334..a951f0021d 100644
--- a/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp
+++ b/extras/Jucer (experimental)/Source/model/Component/jucer_CodeGenerator.cpp
@@ -127,7 +127,7 @@ const String CodeGenerator::getCallbackDefinitions() const
{
CallbackMethod* const cm = callbacks.getUnchecked(i);
- const String userCodeBlockName ("User" + CodeFormatting::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false),
+ const String userCodeBlockName ("User" + CodeHelpers::makeValidIdentifier (cm->prototype.upToFirstOccurrenceOf ("(", false, false),
true, true, false).trim());
if (userCodeBlockName.isNotEmpty() && cm->hasPrePostUserSections)
@@ -138,7 +138,7 @@ const String CodeGenerator::getCallbackDefinitions() const
<< " //[" << userCodeBlockName << "_Pre]" << newLine
<< " //[/" << userCodeBlockName
<< "_Pre]" << newLine << newLine
- << " " << CodeFormatting::indent (cm->content.trim(), 4, false) << newLine
+ << " " << CodeHelpers::indent (cm->content.trim(), 4, false) << newLine
<< newLine
<< " //[" << userCodeBlockName << "_Post]" << newLine
<< " //[/" << userCodeBlockName << "_Post]" << newLine
@@ -149,7 +149,7 @@ const String CodeGenerator::getCallbackDefinitions() const
{
s << cm->returnType << " " << className << "::" << cm->prototype << newLine
<< "{" << newLine
- << " " << CodeFormatting::indent (cm->content.trim(), 4, false) << newLine
+ << " " << CodeHelpers::indent (cm->content.trim(), 4, false) << newLine
<< "}" << newLine
<< newLine;
}
@@ -250,7 +250,7 @@ static void replaceTemplate (String& text, const String& itemName, const String&
}
}
- text = text.replaceSection (index, itemName.length() + 4, CodeFormatting::indent (value, indentLevel, false));
+ text = text.replaceSection (index, itemName.length() + 4, CodeHelpers::indent (value, indentLevel, false));
}
}
@@ -259,7 +259,7 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile,
bool isForPreview, Project* project) const
{
replaceTemplate (code, "juceVersion", SystemStats::getJUCEVersion());
- replaceTemplate (code, "headerGuard", CodeFormatting::makeHeaderGuardName (targetFile));
+ replaceTemplate (code, "headerGuard", CodeHelpers::makeHeaderGuardName (targetFile));
replaceTemplate (code, "className", className);
replaceTemplate (code, "constructorParams", constructorParams);
@@ -272,7 +272,7 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile,
replaceTemplate (code, "methodDefinitions", getCallbackDefinitions());
if (project != 0)
- replaceTemplate (code, "defaultJuceInclude", CodeFormatting::createIncludeStatement (project->getAppIncludeFile(), targetFile));
+ replaceTemplate (code, "defaultJuceInclude", CodeHelpers::createIncludeStatement (project->getAppIncludeFile(), targetFile));
else
replaceTemplate (code, "defaultJuceInclude", "#include \"juce_amalgamated.h\"");
@@ -293,13 +293,13 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile,
replaceTemplate (code, "staticMemberDefinitions", "// Static member declarations and resources would go here... (these aren't shown in the code preview)");
}
- {
+ /*{
MemoryOutputStream compDataCpp;
- CodeFormatting::writeDataAsCppLiteral (componentStateData, compDataCpp);
+ CodeHelpers::writeDataAsCppLiteral (componentStateData, compDataCpp);
replaceTemplate (code, "statedata", compDataCpp.toUTF8(), false);
replaceTemplate (code, "statedatasize", String ((int) componentStateData.getSize()));
- }
+ }*/
}
diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp
index b39e4270e3..5e6f15a55f 100644
--- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp
+++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp
@@ -29,20 +29,21 @@
//==============================================================================
-static const char* const componentDocumentTag = "COMPONENT";
-static const char* const componentGroupTag = "COMPONENTS";
-static const char* const markersGroupXTag = "MARKERS_X";
-static const char* const markersGroupYTag = "MARKERS_Y";
+static const Identifier componentDocumentTag ("COMPONENT");
+static const Identifier componentGroupTag ("COMPONENTS");
+static const Identifier markersGroupXTag ("MARKERS_X");
+static const Identifier markersGroupYTag ("MARKERS_Y");
-static const char* const metadataTagStart = "JUCER_" "COMPONENT_METADATA_START"; // written like this to avoid thinking this file is a component!
-static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_END";
+static const char* const metadataTagStart = "JUCER_" "COMPONENT_METADATA_START"; // written like this to avoid thinking this file is a component!
+static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_END";
-const char* const ComponentDocument::idProperty = "id";
-const char* const ComponentDocument::compBoundsProperty = "position";
-const char* const ComponentDocument::memberNameProperty = "memberName";
-const char* const ComponentDocument::compNameProperty = "name";
-const char* const ComponentDocument::compTooltipProperty = "tooltip";
-const char* const ComponentDocument::compFocusOrderProperty = "focusOrder";
+const Identifier ComponentDocument::idProperty ("id");
+const Identifier ComponentDocument::compBoundsProperty ("position");
+const Identifier ComponentDocument::memberNameProperty ("memberName");
+const Identifier ComponentDocument::compNameProperty ("name");
+const Identifier ComponentDocument::compTooltipProperty ("tooltip");
+const Identifier ComponentDocument::compFocusOrderProperty ("focusOrder");
+const Identifier ComponentDocument::jucerIDProperty ("jucerID");
//==============================================================================
@@ -84,7 +85,7 @@ void ComponentDocument::changed()
changedSinceSaved = true;
}
-void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property)
+void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property)
{
changed();
}
@@ -196,8 +197,8 @@ bool ComponentDocument::save()
MemoryOutputStream cpp, header;
writeCode (cpp, header);
- bool savedOk = FileUtils::overwriteFileWithNewDataIfDifferent (cppFile, cpp)
- && FileUtils::overwriteFileWithNewDataIfDifferent (cppFile.withFileExtension (".h"), header);
+ bool savedOk = FileHelpers::overwriteFileWithNewDataIfDifferent (cppFile, cpp)
+ && FileHelpers::overwriteFileWithNewDataIfDifferent (cppFile.withFileExtension (".h"), header);
if (savedOk)
changedSinceSaved = false;
@@ -247,9 +248,9 @@ bool ComponentDocument::reload()
ScopedPointer xml (doc.getDocumentElement());
if (xml == 0 && hadMetaDataTags)
- xml = new XmlElement (componentDocumentTag);
+ xml = new XmlElement (componentDocumentTag.toString());
- if (xml != 0 && xml->hasTagName (componentDocumentTag))
+ if (xml != 0 && xml->hasTagName (componentDocumentTag.toString()))
{
ValueTree newTree (ValueTree::fromXml (*xml));
@@ -278,7 +279,7 @@ bool ComponentDocument::hasChangedSinceLastSave()
return changedSinceSaved || customCode.needsSaving();
}
-void ComponentDocument::createSubTreeIfNotThere (const String& name)
+void ComponentDocument::createSubTreeIfNotThere (const Identifier& name)
{
if (! root.getChildWithName (name).isValid())
root.addChild (ValueTree (name), -1, 0);
@@ -562,7 +563,7 @@ bool ComponentDocument::setCoordsFor (ValueTree& state, const RectangleCoordinat
const String ComponentDocument::getNonexistentMemberName (String name)
{
- String n (CodeFormatting::makeValidIdentifier (name, false, true, false));
+ String n (CodeHelpers::makeValidIdentifier (name, false, true, false));
int suffix = 2;
while (markersX->getMarkerNamed (n).isValid() || markersY->getMarkerNamed (n).isValid()
@@ -857,8 +858,6 @@ UndoManager* ComponentDocument::getUndoManager() const
}
//==============================================================================
-const char* const ComponentDocument::jucerIDProperty = "jucerID";
-
const String ComponentDocument::getJucerIDFor (Component* c)
{
if (c == 0)
diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h
index f74887f59b..d8f0988870 100644
--- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h
+++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h
@@ -148,18 +148,18 @@ public:
UndoManager* getUndoManager() const;
void beginNewTransaction();
- void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property);
+ void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
- static const char* const idProperty;
- static const char* const compBoundsProperty;
- static const char* const memberNameProperty;
- static const char* const compNameProperty;
- static const char* const compTooltipProperty;
- static const char* const compFocusOrderProperty;
+ static const Identifier idProperty;
+ static const Identifier compBoundsProperty;
+ static const Identifier memberNameProperty;
+ static const Identifier compNameProperty;
+ static const Identifier compTooltipProperty;
+ static const Identifier compFocusOrderProperty;
- static const char* const jucerIDProperty;
+ static const Identifier jucerIDProperty;
static const String getJucerIDFor (Component* c);
//==============================================================================
@@ -192,12 +192,12 @@ private:
Value tempCanvasWidth, tempCanvasHeight;
void checkRootObject();
- void createSubTreeIfNotThere (const String& name);
+ void createSubTreeIfNotThere (const Identifier& name);
void addMarkerMenuItem (int i, const Coordinate& coord, const String& name, PopupMenu& menu,
bool isAnchor1, const String& fullCoordName);
- Value getRootValueUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); }
- Value getRootValueNonUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, 0); }
+ Value getRootValueUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); }
+ Value getRootValueNonUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, 0); }
void writeCode (OutputStream& cpp, OutputStream& header);
void writeMetadata (OutputStream& out);
diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp
index ccc4b9b155..7bccc6fd87 100644
--- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp
+++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp
@@ -248,7 +248,7 @@ void DrawableDocument::addImage (const File& imageFile)
}
//==============================================================================
-void DrawableDocument::valueTreePropertyChanged (ValueTree& tree, const var::identifier& name)
+void DrawableDocument::valueTreePropertyChanged (ValueTree& tree, const Identifier& name)
{
changed();
}
@@ -392,7 +392,7 @@ const String DrawableDocument::MarkerList::getNonexistentMarkerName (const Strin
const String DrawableDocument::getNonexistentMarkerName (const String& name)
{
- String n (CodeFormatting::makeValidIdentifier (name, false, true, false));
+ String n (CodeHelpers::makeValidIdentifier (name, false, true, false));
int suffix = 2;
while (markersX->getMarkerNamed (n).isValid() || markersY->getMarkerNamed (n).isValid())
diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h
index 8e118843d5..957d6bf453 100644
--- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h
+++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h
@@ -92,7 +92,7 @@ public:
void renameAnchor (const String& oldName, const String& newName);
//==============================================================================
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& name);
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& name);
void valueTreeChildrenChanged (ValueTree& tree);
void valueTreeParentChanged (ValueTree& tree);
@@ -108,8 +108,8 @@ private:
void checkRootObject();
- Value getRootValueUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); }
- Value getRootValueNonUndoable (const var::identifier& name) const { return root.getPropertyAsValue (name, 0); }
+ Value getRootValueUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, getUndoManager()); }
+ Value getRootValueNonUndoable (const Identifier& name) const { return root.getPropertyAsValue (name, 0); }
void save (OutputStream& output);
bool load (InputStream& input);
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp
index b6a18d79e4..cb26b10633 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_NewFileWizard.cpp
@@ -35,9 +35,9 @@ static bool fillInNewCppFileTemplate (const File& file, const Project::Item& ite
.replace ("FILENAME", file.getFileName(), false)
.replace ("DATE", Time::getCurrentTime().toString (true, true, true), false)
.replace ("AUTHOR", SystemStats::getFullUserName(), false)
- .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (file), false);
+ .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (file), false);
- return FileUtils::overwriteFileWithNewDataIfDifferent (file, s);
+ return FileHelpers::overwriteFileWithNewDataIfDifferent (file, s);
}
//==============================================================================
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp
index 378cca6d9d..5e4c6fa624 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.cpp
@@ -33,13 +33,13 @@
//==============================================================================
namespace Tags
{
- const char* const projectRoot = "JUCERPROJECT";
- const char* const projectMainGroup = "MAINGROUP";
- const char* const group = "GROUP";
- const char* const file = "FILE";
- const char* const configurations = "CONFIGURATIONS";
- const char* const configuration = "CONFIGURATION";
- const char* const exporters = "EXPORTFORMATS";
+ const Identifier projectRoot ("JUCERPROJECT");
+ const Identifier projectMainGroup ("MAINGROUP");
+ const Identifier group ("GROUP");
+ const Identifier file ("FILE");
+ const Identifier configurations ("CONFIGURATIONS");
+ const Identifier configuration ("CONFIGURATION");
+ const Identifier exporters ("EXPORTFORMATS");
}
const char* Project::projectFileExtension = ".jucer";
@@ -122,7 +122,7 @@ void Project::setMissingDefaultValues()
if (! projectRoot.getChildWithName (Tags::exporters).isValid())
createDefaultExporters();
- const String sanitisedProjectName (CodeFormatting::makeValidIdentifier (getProjectName().toString(), false, true, false));
+ const String sanitisedProjectName (CodeHelpers::makeValidIdentifier (getProjectName().toString(), false, true, false));
if (! projectRoot.hasProperty ("buildVST"))
{
@@ -157,7 +157,7 @@ const String Project::loadDocument (const File& file)
XmlDocument doc (file);
ScopedPointer xml (doc.getDocumentElement());
- if (xml == 0 || ! xml->hasTagName (Tags::projectRoot))
+ if (xml == 0 || ! xml->hasTagName (Tags::projectRoot.toString()))
return "Not a valid Jucer project!";
ValueTree newTree (ValueTree::fromXml (*xml));
@@ -184,7 +184,7 @@ const String Project::saveDocument (const File& file)
getJuceConfigFlags (flags);
}
- if (FileUtils::isJuceFolder (getLocalJuceFolder()))
+ if (FileHelpers::isJuceFolder (getLocalJuceFolder()))
StoredSettings::getInstance()->setLastKnownJuceFolder (getLocalJuceFolder().getFullPathName());
StoredSettings::getInstance()->recentFiles.addFile (file);
@@ -207,7 +207,7 @@ void Project::setLastDocumentOpened (const File& file)
}
//==============================================================================
-void Project::valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
+void Project::valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
if (isLibrary())
getJuceLinkageModeValue() = (int) notLinkedToJuce;
@@ -310,7 +310,7 @@ const File Project::getLocalJuceFolder()
{
File f (resolveFilename (exp->getJuceFolder().toString()));
- if (FileUtils::isJuceFolder (f))
+ if (FileHelpers::isJuceFolder (f))
return f;
}
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h
index 0b0c550e7a..1941d74ce0 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_Project.h
@@ -85,7 +85,7 @@ public:
Value getVersion() const { return getProjectValue ("version"); }
Value getBundleIdentifier() const { return getProjectValue ("bundleIdentifier"); }
- void setBundleIdentifierToDefault() { getBundleIdentifier() = "com.yourcompany." + CodeFormatting::makeValidIdentifier (getProjectName().toString(), false, true, false); }
+ void setBundleIdentifierToDefault() { getBundleIdentifier() = "com.yourcompany." + CodeHelpers::makeValidIdentifier (getProjectName().toString(), false, true, false); }
//==============================================================================
enum JuceLinkage
@@ -107,7 +107,7 @@ public:
bool isUsingMultipleTemplateFiles() const { return getJuceLinkageMode() == useAmalgamatedJuceViaMultipleTemplates; }
//==============================================================================
- Value getProjectValue (const var::identifier& name) const { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); }
+ Value getProjectValue (const Identifier& name) const { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); }
Value shouldBuildVST() const { return getProjectValue ("buildVST"); }
Value shouldBuildRTAS() const { return getProjectValue ("buildRTAS"); }
@@ -281,7 +281,7 @@ public:
const String getFileTemplate (const String& templateName);
//==============================================================================
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property);
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& tree);
void valueTreeParentChanged (ValueTree& tree);
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
index 6a17d45a26..bcba4b7134 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_MSVC.h
@@ -145,7 +145,7 @@ public:
MemoryOutputStream mo;
writeVC6Project (mo);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (getDSPFile(), mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSPFile(), mo))
return "Can't write to the VC project file: " + getDSPFile().getFullPathName();
}
@@ -153,7 +153,7 @@ public:
MemoryOutputStream mo;
writeDSWFile (mo);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (getDSWFile(), mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getDSWFile(), mo))
return "Can't write to the VC solution file: " + getDSWFile().getFullPathName();
}
}
@@ -168,7 +168,7 @@ public:
MemoryOutputStream mo;
masterXml.writeToStream (mo, String::empty, false, true, "UTF-8", 10);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getVCProjFile(), mo))
return "Can't write to the VC project file: " + getVCProjFile().getFullPathName();
}
@@ -176,7 +176,7 @@ public:
MemoryOutputStream mo;
writeSolutionFile (mo);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (getSLNFile(), mo))
return "Can't write to the VC solution file: " + getSLNFile().getFullPathName();
}
}
@@ -370,7 +370,7 @@ private:
{
RelativePath rtasFolder (getRTASFolder().toString(), RelativePath::unknown);
defines.add ("JucePlugin_WinBag_path="
- + CodeFormatting::addEscapeChars (rtasFolder.getChildFile ("WinBag")
+ + CodeHelpers::addEscapeChars (rtasFolder.getChildFile ("WinBag")
.toWindowsStyle().quoted()));
}
@@ -452,8 +452,8 @@ private:
const String binaryName (File::createLegalFileName (config.getTargetBinaryName().toString()));
xml.setAttribute ("Name", createConfigName (config));
- xml.setAttribute ("OutputDirectory", FileUtils::windowsStylePath (binariesPath));
- xml.setAttribute ("IntermediateDirectory", FileUtils::windowsStylePath (intermediatesPath));
+ xml.setAttribute ("OutputDirectory", FileHelpers::windowsStylePath (binariesPath));
+ xml.setAttribute ("IntermediateDirectory", FileHelpers::windowsStylePath (intermediatesPath));
xml.setAttribute ("ConfigurationType", (project.isAudioPlugin() || project.isBrowserPlugin() || isLibraryDLL())
? "2" : (project.isLibrary() ? "4" : "1"));
xml.setAttribute ("UseOfMFC", "0");
@@ -485,7 +485,7 @@ private:
midl->setAttribute ("MkTypLibCompatible", "true");
midl->setAttribute ("SuppressStartupBanner", "true");
midl->setAttribute ("TargetEnvironment", "1");
- midl->setAttribute ("TypeLibraryName", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".tlb"));
+ midl->setAttribute ("TypeLibraryName", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".tlb"));
midl->setAttribute ("HeaderFileName", "");
}
@@ -512,10 +512,10 @@ private:
: (isDebug ? 1 : 0)); // MT static
compiler->setAttribute ("RuntimeTypeInfo", "true");
compiler->setAttribute ("UsePrecompiledHeader", "0");
- compiler->setAttribute ("PrecompiledHeaderFile", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".pch"));
- compiler->setAttribute ("AssemblerListingLocation", FileUtils::windowsStylePath (intermediatesPath + "/"));
- compiler->setAttribute ("ObjectFile", FileUtils::windowsStylePath (intermediatesPath + "/"));
- compiler->setAttribute ("ProgramDataBaseFileName", FileUtils::windowsStylePath (intermediatesPath + "/"));
+ compiler->setAttribute ("PrecompiledHeaderFile", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pch"));
+ compiler->setAttribute ("AssemblerListingLocation", FileHelpers::windowsStylePath (intermediatesPath + "/"));
+ compiler->setAttribute ("ObjectFile", FileHelpers::windowsStylePath (intermediatesPath + "/"));
+ compiler->setAttribute ("ProgramDataBaseFileName", FileHelpers::windowsStylePath (intermediatesPath + "/"));
compiler->setAttribute ("WarningLevel", project.isLibrary() ? "4" : "3");
compiler->setAttribute ("SuppressStartupBanner", "true");
@@ -538,7 +538,7 @@ private:
{
XmlElement* linker = createToolElement (xml, "VCLinkerTool");
- linker->setAttribute ("OutputFile", FileUtils::windowsStylePath (binariesPath + "/" + outputFileName));
+ linker->setAttribute ("OutputFile", FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName));
linker->setAttribute ("SuppressStartupBanner", "true");
if (project.getJuceLinkageMode() == Project::useLinkedJuce)
@@ -546,7 +546,7 @@ private:
linker->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : "");
linker->setAttribute ("GenerateDebugInformation", isDebug ? "true" : "false");
- linker->setAttribute ("ProgramDatabaseFile", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb"));
+ linker->setAttribute ("ProgramDatabaseFile", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".pdb"));
linker->setAttribute ("SubSystem", project.isCommandLineApp() ? "1" : "2");
if (! isDebug)
@@ -579,17 +579,17 @@ private:
XmlElement* linker = createToolElement (xml, "VCLinkerTool");
String extraLinkerOptions (getExtraLinkerFlags().toString());
- extraLinkerOptions << " /IMPLIB:" << FileUtils::windowsStylePath (binariesPath + "/" + outputFileName.upToLastOccurrenceOf (".", false, false) + ".lib");
+ extraLinkerOptions << " /IMPLIB:" << FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName.upToLastOccurrenceOf (".", false, false) + ".lib");
linker->setAttribute ("AdditionalOptions", extraLinkerOptions.trim());
- linker->setAttribute ("OutputFile", FileUtils::windowsStylePath (binariesPath + "/" + outputFileName));
+ linker->setAttribute ("OutputFile", FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName));
linker->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : "");
}
else
{
XmlElement* librarian = createToolElement (xml, "VCLibrarianTool");
- librarian->setAttribute ("OutputFile", FileUtils::windowsStylePath (binariesPath + "/" + outputFileName));
+ librarian->setAttribute ("OutputFile", FileHelpers::windowsStylePath (binariesPath + "/" + outputFileName));
librarian->setAttribute ("IgnoreDefaultLibraryNames", isDebug ? "libcmt.lib, msvcrt.lib" : "");
}
}
@@ -601,7 +601,7 @@ private:
{
XmlElement* bscMake = createToolElement (xml, "VCBscMakeTool");
bscMake->setAttribute ("SuppressStartupBanner", "true");
- bscMake->setAttribute ("OutputFile", FileUtils::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc"));
+ bscMake->setAttribute ("OutputFile", FileHelpers::windowsStylePath (intermediatesPath + "/" + binaryName + ".bsc"));
}
createToolElement (xml, "VCFxCopTool");
@@ -727,7 +727,7 @@ private:
targetList << "# Name \"" << configName << '"' << newLine;
const String binariesPath (getConfigTargetPath (config));
- const String targetBinary (FileUtils::windowsStylePath (binariesPath + "/" + getBinaryFileForConfig (config)));
+ const String targetBinary (FileHelpers::windowsStylePath (binariesPath + "/" + getBinaryFileForConfig (config)));
const String optimisationFlag (((int) config.getOptimisationLevel().getValue() <= 1) ? "Od" : (config.getOptimisationLevel() == 2 ? "O2" : "O3"));
const String defines (getPreprocessorDefs (config, " /D "));
const bool isDebug = (bool) config.isDebug().getValue();
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h
index b8d6adf82e..ef054ef86e 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h
@@ -101,7 +101,7 @@ public:
writeMakefile (mo, files);
const File makefile (getTargetFolder().getChildFile ("Makefile"));
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (makefile, mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (makefile, mo))
return "Can't write to the Makefile: " + makefile.getFullPathName();
return String::empty;
@@ -152,7 +152,7 @@ private:
headerPaths.insert (0, "/usr/include");
for (int i = 0; i < headerPaths.size(); ++i)
- out << " -I " << FileUtils::unixStylePath (headerPaths[i]).quoted();
+ out << " -I " << FileHelpers::unixStylePath (headerPaths[i]).quoted();
}
void writeCppFlags (OutputStream& out, const Project::BuildConfiguration& config)
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h
index 3f8a347b6b..60cdeb923c 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_XCode.h
@@ -122,7 +122,7 @@ public:
MemoryOutputStream mo;
writeProjectFile (mo);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (projectFile, mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (projectFile, mo))
return "Can't write to file: " + projectFile.getFullPathName();
}
@@ -266,7 +266,7 @@ private:
MemoryOutputStream mo;
plist.writeToStream (mo, "");
- return FileUtils::overwriteFileWithNewDataIfDifferent (infoPlistFile, mo);
+ return FileHelpers::overwriteFileWithNewDataIfDifferent (infoPlistFile, mo);
}
const StringArray getHeaderSearchPaths (const Project::BuildConfiguration& config)
@@ -566,7 +566,7 @@ private:
for (int j = 0; j < o.getNumProperties(); ++j)
{
- const var::identifier propertyName (o.getPropertyName(j));
+ const Identifier propertyName (o.getPropertyName(j));
String val (o.getProperty (propertyName).toString());
if (val.isEmpty() || (val.containsAnyOf (" \t;<>()=,-\r\n")
@@ -574,7 +574,7 @@ private:
|| val.trimStart().startsWithChar ('{'))))
val = val.quoted();
- output << propertyName.name << " = " << val << "; ";
+ output << propertyName.toString() << " = " << val << "; ";
}
output << "};\n";
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
index 29969a74ea..3b781802bb 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.cpp
@@ -75,7 +75,7 @@ ProjectExporter* ProjectExporter::createNewExporter (Project& project, const int
File juceFolder (StoredSettings::getInstance()->getLastKnownJuceFolder());
File target (exp->getTargetFolder());
- if (FileUtils::shouldPathsBeRelative (juceFolder.getFullPathName(), project.getFile().getFullPathName()))
+ if (FileHelpers::shouldPathsBeRelative (juceFolder.getFullPathName(), project.getFile().getFullPathName()))
exp->getJuceFolder() = juceFolder.getRelativePathFrom (project.getFile().getParentDirectory());
else
exp->getJuceFolder() = juceFolder.getFullPathName();
@@ -121,7 +121,7 @@ const String ProjectExporter::getIncludePathForFileInJuceFolder (const String& p
if (juceFolderPath.startsWithChar ('<'))
{
- juceFolderPath = FileUtils::unixStylePath (File::addTrailingSeparator (juceFolderPath.substring (1).dropLastCharacters(1)));
+ juceFolderPath = FileHelpers::unixStylePath (File::addTrailingSeparator (juceFolderPath.substring (1).dropLastCharacters(1)));
if (juceFolderPath == "/")
juceFolderPath = String::empty;
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
index 9289372893..720c4581b9 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExporter.h
@@ -62,7 +62,7 @@ public:
const File getTargetFolder() const;
const ValueTree& getSettings() const { return settings; }
- Value getSetting (const var::identifier& name_) const { return settings.getPropertyAsValue (name_, project.getUndoManagerFor (settings)); }
+ Value getSetting (const Identifier& name_) const { return settings.getPropertyAsValue (name_, project.getUndoManagerFor (settings)); }
Value getJuceFolder() const { return getSetting ("juceFolder"); }
Value getTargetLocation() const { return getSetting ("targetFolder"); }
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
index 21c54d6c4e..b72d9fc398 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectSaver.h
@@ -123,7 +123,7 @@ private:
MemoryOutputStream mo;
xml->writeToStream (mo, String::empty);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (projectFile, mo))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (projectFile, mo))
errors.add ("Couldn't write to the target file!");
}
}
@@ -192,7 +192,7 @@ private:
<< newLine
<< "*/"
<< newLine << newLine
- << CodeFormatting::createIncludeStatement (appConfigFile, appConfigFile) << newLine;
+ << CodeHelpers::createIncludeStatement (appConfigFile, appConfigFile) << newLine;
if (fileNumber == 0)
writeInclude (out, project.isUsingFullyAmalgamatedFile() ? "juce_amalgamated.cpp"
@@ -216,7 +216,7 @@ private:
<< "#define " << headerGuard << newLine << newLine;
if (hasAppConfigFile)
- out << CodeFormatting::createIncludeStatement (appConfigFile, appConfigFile) << newLine;
+ out << CodeHelpers::createIncludeStatement (appConfigFile, appConfigFile) << newLine;
if (project.getJuceLinkageMode() != Project::notLinkedToJuce)
{
@@ -228,13 +228,13 @@ private:
}
if (binaryDataCpp.exists())
- out << CodeFormatting::createIncludeStatement (binaryDataCpp.withFileExtension (".h"), appConfigFile) << newLine;
+ out << CodeHelpers::createIncludeStatement (binaryDataCpp.withFileExtension (".h"), appConfigFile) << newLine;
out << newLine
<< "namespace ProjectInfo" << newLine
<< "{" << newLine
- << " const char* const projectName = " << CodeFormatting::addEscapeChars (project.getProjectName().toString()).quoted() << ";" << newLine
- << " const char* const versionString = " << CodeFormatting::addEscapeChars (project.getVersion().toString()).quoted() << ";" << newLine
+ << " const char* const projectName = " << CodeHelpers::addEscapeChars (project.getProjectName().toString()).quoted() << ";" << newLine
+ << " const char* const versionString = " << CodeHelpers::addEscapeChars (project.getVersion().toString()).quoted() << ";" << newLine
<< " const int versionNumber = " << createVersionCode (project.getVersion().toString()) << ";" << newLine
<< "}" << newLine
<< newLine
@@ -370,7 +370,7 @@ private:
bool replaceFileIfDifferent (const File& f, const MemoryOutputStream& newData)
{
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (f, newData))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (f, newData))
{
errors.add ("Can't write to file: " + f.getFullPathName());
return false;
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp
index 490426cd89..effd1c47c8 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectWizard.cpp
@@ -79,30 +79,30 @@ public:
for (int i = project.getNumConfigurations(); --i >= 0;)
project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle);
- String appHeaders (CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), mainCppFile));
+ String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile));
String initCode, shutdownCode, anotherInstanceStartedCode, privateMembers, memberInitialisers;
if (createWindow)
{
- appHeaders << newLine << CodeFormatting::createIncludeStatement (mainWindowH, mainCppFile);
+ appHeaders << newLine << CodeHelpers::createIncludeStatement (mainWindowH, mainCppFile);
memberInitialisers = " : mainWindow (0)";
initCode = "mainWindow = new " + windowClassName + "();";
shutdownCode = "deleteAndZero (mainWindow);";
privateMembers = windowClassName + "* mainWindow;";
String windowH = project.getFileTemplate ("jucer_WindowTemplate_h")
- .replace ("INCLUDES", CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), mainWindowH), false)
+ .replace ("INCLUDES", CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainWindowH), false)
.replace ("WINDOWCLASS", windowClassName, false)
- .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (mainWindowH), false);
+ .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (mainWindowH), false);
String windowCpp = project.getFileTemplate ("jucer_WindowTemplate_cpp")
- .replace ("INCLUDES", CodeFormatting::createIncludeStatement (mainWindowH, mainWindowCpp), false)
+ .replace ("INCLUDES", CodeHelpers::createIncludeStatement (mainWindowH, mainWindowCpp), false)
.replace ("WINDOWCLASS", windowClassName, false);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainWindowH, windowH))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainWindowH, windowH))
failedFiles.add (mainWindowH.getFullPathName());
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainWindowCpp, windowCpp))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainWindowCpp, windowCpp))
failedFiles.add (mainWindowCpp.getFullPathName());
group.addFile (mainWindowCpp, -1);
@@ -113,17 +113,17 @@ public:
{
String mainCpp = project.getFileTemplate ("jucer_MainTemplate_cpp")
.replace ("APPHEADERS", appHeaders, false)
- .replace ("APPCLASSNAME", CodeFormatting::makeValidIdentifier (appTitle + "Application", false, true, false), false)
+ .replace ("APPCLASSNAME", CodeHelpers::makeValidIdentifier (appTitle + "Application", false, true, false), false)
.replace ("MEMBERINITIALISERS", memberInitialisers, false)
.replace ("APPINITCODE", initCode, false)
.replace ("APPSHUTDOWNCODE", shutdownCode, false)
- .replace ("APPNAME", CodeFormatting::addEscapeChars (appTitle), false)
+ .replace ("APPNAME", CodeHelpers::addEscapeChars (appTitle), false)
.replace ("APPVERSION", "1.0", false)
.replace ("ALLOWMORETHANONEINSTANCE", "true", false)
.replace ("ANOTHERINSTANCECODE", anotherInstanceStartedCode, false)
.replace ("PRIVATEMEMBERS", privateMembers, false);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp))
failedFiles.add (mainCppFile.getFullPathName());
group.addFile (mainCppFile, -1);
@@ -186,12 +186,12 @@ public:
if (createMainCpp)
{
- String appHeaders (CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), mainCppFile));
+ String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), mainCppFile));
String mainCpp = project.getFileTemplate ("jucer_MainConsoleAppTemplate_cpp")
.replace ("APPHEADERS", appHeaders, false);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (mainCppFile, mainCpp))
failedFiles.add (mainCppFile.getFullPathName());
group.addFile (mainCppFile, -1);
@@ -228,7 +228,7 @@ public:
if (! getSourceFilesFolder().createDirectory())
failedFiles.add (getSourceFilesFolder().getFullPathName());
- String filterClassName = CodeFormatting::makeValidIdentifier (appTitle, true, true, false) + "AudioProcessor";
+ String filterClassName = CodeHelpers::makeValidIdentifier (appTitle, true, true, false) + "AudioProcessor";
filterClassName = filterClassName.substring (0, 1).toUpperCase() + filterClassName.substring (1);
String editorClassName = filterClassName + "Editor";
@@ -247,42 +247,42 @@ public:
for (int i = project.getNumConfigurations(); --i >= 0;)
project.getConfiguration(i).getTargetBinaryName() = File::createLegalFileName (appTitle);
- String appHeaders (CodeFormatting::createIncludeStatement (project.getAppIncludeFile(), filterCppFile));
- appHeaders << newLine << CodeFormatting::createIncludeStatement (project.getPluginCharacteristicsFile(), filterCppFile);
+ String appHeaders (CodeHelpers::createIncludeStatement (project.getAppIncludeFile(), filterCppFile));
+ appHeaders << newLine << CodeHelpers::createIncludeStatement (project.getPluginCharacteristicsFile(), filterCppFile);
String filterCpp = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_cpp")
- .replace ("FILTERHEADERS", CodeFormatting::createIncludeStatement (filterHFile, filterCppFile)
- + newLine + CodeFormatting::createIncludeStatement (editorHFile, filterCppFile), false)
+ .replace ("FILTERHEADERS", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile)
+ + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false)
.replace ("FILTERCLASSNAME", filterClassName, false)
.replace ("EDITORCLASSNAME", editorClassName, false);
String filterH = project.getFileTemplate ("jucer_AudioPluginFilterTemplate_h")
.replace ("APPHEADERS", appHeaders, false)
.replace ("FILTERCLASSNAME", filterClassName, false)
- .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (filterHFile), false);
+ .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (filterHFile), false);
String editorCpp = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_cpp")
- .replace ("EDITORCPPHEADERS", CodeFormatting::createIncludeStatement (filterHFile, filterCppFile)
- + newLine + CodeFormatting::createIncludeStatement (editorHFile, filterCppFile), false)
+ .replace ("EDITORCPPHEADERS", CodeHelpers::createIncludeStatement (filterHFile, filterCppFile)
+ + newLine + CodeHelpers::createIncludeStatement (editorHFile, filterCppFile), false)
.replace ("FILTERCLASSNAME", filterClassName, false)
.replace ("EDITORCLASSNAME", editorClassName, false);
String editorH = project.getFileTemplate ("jucer_AudioPluginEditorTemplate_h")
- .replace ("EDITORHEADERS", appHeaders + newLine + CodeFormatting::createIncludeStatement (filterHFile, filterCppFile), false)
+ .replace ("EDITORHEADERS", appHeaders + newLine + CodeHelpers::createIncludeStatement (filterHFile, filterCppFile), false)
.replace ("FILTERCLASSNAME", filterClassName, false)
.replace ("EDITORCLASSNAME", editorClassName, false)
- .replace ("HEADERGUARD", CodeFormatting::makeHeaderGuardName (editorHFile), false);
+ .replace ("HEADERGUARD", CodeHelpers::makeHeaderGuardName (editorHFile), false);
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterCppFile, filterCpp))
failedFiles.add (filterCppFile.getFullPathName());
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (filterHFile, filterH))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (filterHFile, filterH))
failedFiles.add (filterHFile.getFullPathName());
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorCppFile, editorCpp))
failedFiles.add (editorCppFile.getFullPathName());
- if (! FileUtils::overwriteFileWithNewDataIfDifferent (editorHFile, editorH))
+ if (! FileHelpers::overwriteFileWithNewDataIfDifferent (editorHFile, editorH))
failedFiles.add (editorHFile.getFullPathName());
group.addFile (filterCppFile, -1);
@@ -381,7 +381,7 @@ Project* ProjectWizard::runWizard (Component* ownerWindow_)
failedFiles.add (newProjectFolder.getFullPathName());
}
- if (FileUtils::containsAnyNonHiddenFiles (newProjectFolder))
+ if (FileHelpers::containsAnyNonHiddenFiles (newProjectFolder))
{
if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon, "New Juce Project",
"The folder you chose isn't empty - are you sure you want to create the project there?\n\nAny existing files with the same names may be overwritten by the new files."))
@@ -480,7 +480,7 @@ Project* ProjectWizard::runNewProjectWizard (Component* ownerWindow)
if (aw.runModalLoop() == 0)
return 0;
- if (FileUtils::isJuceFolder (juceFolderSelector.getCurrentFile()))
+ if (FileHelpers::isJuceFolder (juceFolderSelector.getCurrentFile()))
{
wizard = createWizard (aw.getComboBoxComponent ("type")->getSelectedItemIndex());
break;
diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp b/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp
index b47a4af618..18ae54deae 100644
--- a/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp
+++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ResourceFile.cpp
@@ -100,16 +100,6 @@ int64 ResourceFile::getTotalDataSize() const
return total;
}
-static int calcResourceHashCode (const String& s)
-{
- const char* t = s.toUTF8();
- int hash = 0;
- while (*t != 0)
- hash = 31 * hash + *t++;
-
- return hash;
-}
-
bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream& header)
{
String comment;
@@ -125,15 +115,15 @@ bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream&
<< comment;
if (juceHeader.exists())
- header << CodeFormatting::createIncludeStatement (juceHeader, cppFile) << newLine;
+ header << CodeHelpers::createIncludeStatement (juceHeader, cppFile) << newLine;
const String namespaceName (className);
- StringArray variableNames;
+ StringArray variableNames, returnCodes;
int i;
for (i = 0; i < files.size(); ++i)
{
- String variableNameRoot (CodeFormatting::makeValidIdentifier (files.getUnchecked(i)->getFileName()
+ String variableNameRoot (CodeHelpers::makeValidIdentifier (files.getUnchecked(i)->getFileName()
.replaceCharacters (" .", "__")
.retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"),
false, true, false));
@@ -144,32 +134,19 @@ bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream&
variableName = variableNameRoot + String (suffix++);
variableNames.add (variableName);
+ returnCodes.add ("numBytes = " + namespaceName + "::" + variableName + "Size; return "
+ + namespaceName + "::" + variableName + ";");
}
- cpp << CodeFormatting::createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine
+ cpp << CodeHelpers::createIncludeStatement (cppFile.withFileExtension (".h"), cppFile) << newLine
<< newLine
<< newLine
<< "const char* " << namespaceName << "::getNamedResource (const char* resourceNameUTF8, int& numBytes) throw()" << newLine
- << "{" << newLine
- << " int hash = 0;" << newLine
- << " if (resourceNameUTF8 != 0)" << newLine
- << " while (*resourceNameUTF8 != 0)" << newLine
- << " hash = 31 * hash + *resourceNameUTF8++;" << newLine
- << newLine
- << " switch (hash)" << newLine
- << " {" << newLine;
+ << "{" << newLine;
- for (i = 0; i < files.size(); ++i)
- {
- cpp << " case 0x" << hexString8Digits (calcResourceHashCode (variableNames[i]))
- << ": numBytes = " << namespaceName << "::" << variableNames[i] << "Size; return "
- << namespaceName << "::" << variableNames[i] << ";" << newLine;
- }
+ CodeHelpers::createStringMatcher (cpp, "resourceNameUTF8", variableNames, returnCodes, 4);
- cpp << " default: break;" << newLine
- << " }" << newLine
- << newLine
- << " numBytes = 0;" << newLine
+ cpp << " numBytes = 0;" << newLine
<< " return 0;" << newLine
<< "}" << newLine
<< newLine;
@@ -199,7 +176,7 @@ bool ResourceFile::write (const File& cppFile, OutputStream& cpp, OutputStream&
{
MemoryBlock data;
fileStream->readIntoMemoryBlock (data);
- CodeFormatting::writeDataAsCppLiteral (data, cpp);
+ CodeHelpers::writeDataAsCppLiteral (data, cpp);
}
cpp << newLine << newLine
@@ -231,8 +208,8 @@ bool ResourceFile::write (const File& cppFile)
cppOut = 0;
hppOut = 0;
- return (FileUtils::areFilesIdentical (tempCpp.getFile(), tempCpp.getTargetFile()) || tempCpp.overwriteTargetFileWithTemporary())
- && (FileUtils::areFilesIdentical (tempH.getFile(), tempH.getTargetFile()) || tempH.overwriteTargetFileWithTemporary());
+ return (tempCpp.getFile().hasIdenticalContentTo (tempCpp.getTargetFile()) || tempCpp.overwriteTargetFileWithTemporary())
+ && (tempH.getFile().hasIdenticalContentTo (tempH.getTargetFile()) || tempH.overwriteTargetFileWithTemporary());
}
}
diff --git a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp
index 38bf48bdd7..6719826221 100644
--- a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp
+++ b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.cpp
@@ -58,10 +58,6 @@ extern const unsigned char %%className%%_ComponentStateData[];
%%staticMemberDefinitions%%
-//==============================================================================
-/* This data contains the ValueTree that holds all the Jucer-generated settings for the components */
-const unsigned char %%className%%_ComponentStateData[] = %%statedata%%;
-
//==============================================================================
//======================= Jucer Information Section ==========================
//==============================================================================
diff --git a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h
index f2b14961f7..fcb197e0af 100644
--- a/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h
+++ b/extras/Jucer (experimental)/Source/templates/jucer_ComponentTemplate.h
@@ -57,8 +57,6 @@ private:
%%privateMemberDeclarations%%
//==============================================================================
- ValueTree componentState;
-
// (prevent copy constructor and operator= being generated..)
%%className%% (const %%className%%&);
%%className%%& operator= (const %%className%%&);
diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h
index 75ec2a305a..be5046be39 100644
--- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h
+++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h
@@ -189,7 +189,7 @@ public:
float getMarkerPosition (const ValueTree& marker, bool isX)
{
ComponentDocument& doc = getDocument();
- return doc.getMarkerList (isX).getCoordinate (marker).resolve (doc);
+ return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (doc);
}
};
diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h
index 9867899a68..e8d14cabe0 100644
--- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h
+++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorToolbar.h
@@ -52,7 +52,7 @@ public:
return true;
}
- void paintButton (Graphics& g, const bool over, const bool down)
+ void paintButton (Graphics& g, bool over, bool down)
{
Path p;
p.addRoundedRectangle (1.5f, 2.5f, getWidth() - 3.0f, getHeight() - 5.0f, 3.0f);
diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h
index b4bc06c77a..b349746dde 100644
--- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h
+++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorTreeView.h
@@ -48,7 +48,7 @@ namespace ComponentEditorTreeView
}
//==============================================================================
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property) {}
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& property) {}
void valueTreeParentChanged (ValueTree& tree) {}
void valueTreeChildrenChanged (ValueTree& tree) {}
@@ -128,7 +128,7 @@ namespace ComponentEditorTreeView
const String getDragSourceDescription() { return getDragIdFor (editor); }
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
if (property == ComponentDocument::memberNameProperty)
repaintItem();
@@ -303,7 +303,7 @@ namespace ComponentEditorTreeView
const String getDragSourceDescription() { return String::empty; }
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
if (property == MarkerListBase::getMarkerNameProperty())
repaintItem();
diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h
index 3e1ee597b8..e25f8d5495 100644
--- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h
+++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h
@@ -79,7 +79,7 @@ public:
}
//==============================================================================
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
}
diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
index 419263b26b..f58846a25c 100644
--- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
+++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
@@ -24,6 +24,7 @@
*/
#include "../../jucer_Headers.h"
+#include "../../utility/jucer_TickIterator.h"
#include "jucer_EditorCanvas.h"
#include "jucer_EditorPanel.h"
@@ -53,7 +54,7 @@ public:
g.drawRect (0, 0, getWidth(), getHeight(), borderThickness);
}
- void valueTreePropertyChanged (ValueTree&, const var::identifier&) { updatePosition(); }
+ void valueTreePropertyChanged (ValueTree&, const Identifier&) { updatePosition(); }
void valueTreeChildrenChanged (ValueTree&) { updatePosition(); }
void valueTreeParentChanged (ValueTree&)
{
@@ -346,7 +347,7 @@ public:
MarkerListBase& getMarkerList() { return canvas->getMarkerList (isX); }
- void valueTreePropertyChanged (ValueTree&, const var::identifier&) { updatePosition(); }
+ void valueTreePropertyChanged (ValueTree&, const Identifier&) { updatePosition(); }
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) {}
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {}
@@ -536,7 +537,7 @@ public:
}
}
- void valueTreePropertyChanged (ValueTree&, const var::identifier&) { updateMarkers(); }
+ void valueTreePropertyChanged (ValueTree&, const Identifier&) { updateMarkers(); }
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) { updateMarkers(); }
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {}
diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h
index 9546c1dab6..f58f217377 100644
--- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h
+++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h
@@ -54,7 +54,7 @@ public:
void drawYAxis (Graphics& g, const Rectangle& r);
//==============================================================================
- void valueTreePropertyChanged (ValueTree&, const var::identifier&) { update(); }
+ void valueTreePropertyChanged (ValueTree&, const Identifier&) { update(); }
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) { update(); }
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {}
diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
index b2014730c6..8ae795d117 100644
--- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
+++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
@@ -62,7 +62,7 @@ public:
verticalSnapPositions.add (SnapLine (floatPos.getX(), floatPos.getY(), floatPos.getBottom()));
if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge()))
- verticalSnapPositions.add (SnapLine ((int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom()));
+ verticalSnapPositions.add (SnapLine ((float) (int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom()));
if (zone.isDraggingWholeObject() || zone.isDraggingRightEdge())
verticalSnapPositions.add (SnapLine (floatPos.getRight(), floatPos.getY(), floatPos.getBottom()));
@@ -71,7 +71,7 @@ public:
horizontalSnapPositions.add (SnapLine (floatPos.getY(), floatPos.getX(), floatPos.getRight()));
if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge()))
- horizontalSnapPositions.add (SnapLine ((int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight()));
+ horizontalSnapPositions.add (SnapLine ((float) (int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight()));
if (zone.isDraggingWholeObject() || zone.isDraggingBottomEdge())
horizontalSnapPositions.add (SnapLine (floatPos.getBottom(), floatPos.getX(), floatPos.getRight()));
@@ -116,7 +116,7 @@ public:
}
if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge()))
- verticalSnapTargets.add (SnapLine ((int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom()));
+ verticalSnapTargets.add (SnapLine ((float) (int) floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom()));
if (isDraggingUpDown())
{
@@ -125,7 +125,7 @@ public:
}
if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge()))
- horizontalSnapTargets.add (SnapLine ((int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight()));
+ horizontalSnapTargets.add (SnapLine ((float) (int) floatPos.getCentreY(), floatPos.getX(), floatPos.getRight()));
}
mergeSnapLines (verticalSnapTargets);
diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp
index 02c8154f93..cd8ecd049a 100644
--- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp
+++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.cpp
@@ -57,7 +57,7 @@ void GroupInformationComponent::paintListBoxItem (int rowNumber, Graphics& g, in
}
//==============================================================================
-void GroupInformationComponent::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property)
+void GroupInformationComponent::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property)
{
list->updateContent();
}
diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h
index cb542340c2..dbffee4e77 100644
--- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h
+++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_GroupInformationComponent.h
@@ -48,7 +48,7 @@ public:
Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate);
//==============================================================================
- void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property);
+ void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp
index 953c010d11..c240fe68bb 100644
--- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp
+++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.cpp
@@ -362,7 +362,7 @@ void ProjectTreeViewBase::itemDropped (const String& sourceDescription, Componen
}
//==============================================================================
-void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const var::identifier& property)
+void ProjectTreeViewBase::valueTreePropertyChanged (ValueTree& tree, const Identifier& property)
{
if (tree == item.getNode())
repaintItem();
diff --git a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h
index 3ac6cfae08..14bd610492 100644
--- a/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h
+++ b/extras/Jucer (experimental)/Source/ui/Project Editor/jucer_ProjectTreeViewBase.h
@@ -71,7 +71,7 @@ public:
virtual ProjectTreeViewBase* findTreeViewItem (const Project::Item& itemToFind);
//==============================================================================
- void valueTreePropertyChanged (ValueTree& tree, const var::identifier& property);
+ void valueTreePropertyChanged (ValueTree& tree, const Identifier& property);
void valueTreeChildrenChanged (ValueTree& tree);
void valueTreeParentChanged (ValueTree& tree);
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp
new file mode 100644
index 0000000000..68e4c98a76
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp
@@ -0,0 +1,456 @@
+/*
+ ==============================================================================
+
+ 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.
+
+ ==============================================================================
+*/
+
+#include "../jucer_Headers.h"
+#include "jucer_CodeHelpers.h"
+
+
+//==============================================================================
+namespace CodeHelpers
+{
+ const String indent (const String& code, const int numSpaces, bool indentFirstLine)
+ {
+ if (numSpaces == 0)
+ return code;
+
+ const String space (String::repeatedString (" ", numSpaces));
+
+ StringArray lines;
+ lines.addLines (code);
+
+ for (int i = (indentFirstLine ? 0 : 1); i < lines.size(); ++i)
+ {
+ String s (lines[i].trimEnd());
+ if (s.isNotEmpty())
+ s = space + s;
+
+ lines.set (i, s);
+ }
+
+ return lines.joinIntoString (newLine);
+ }
+
+ const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates)
+ {
+ if (s.isEmpty())
+ return "unknown";
+
+ if (removeColons)
+ s = s.replaceCharacters (".,;:/@", "______");
+ else
+ s = s.replaceCharacters (".,;/@", "_____");
+
+ int i;
+ for (i = s.length(); --i > 0;)
+ if (CharacterFunctions::isLetter (s[i])
+ && CharacterFunctions::isLetter (s[i - 1])
+ && CharacterFunctions::isUpperCase (s[i])
+ && ! CharacterFunctions::isUpperCase (s[i - 1]))
+ s = s.substring (0, i) + " " + s.substring (i);
+
+ String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789");
+ if (allowTemplates)
+ allowedChars += "<>";
+
+ if (! removeColons)
+ allowedChars += ":";
+
+ StringArray words;
+ words.addTokens (s.retainCharacters (allowedChars), false);
+ words.trim();
+
+ String n (words[0]);
+
+ if (capitalise)
+ n = n.toLowerCase();
+
+ for (i = 1; i < words.size(); ++i)
+ {
+ if (capitalise && words[i].length() > 1)
+ n << words[i].substring (0, 1).toUpperCase()
+ << words[i].substring (1).toLowerCase();
+ else
+ n << words[i];
+ }
+
+ if (CharacterFunctions::isDigit (n[0]))
+ n = "_" + n;
+
+ if (CPlusPlusCodeTokeniser::isReservedKeyword (n))
+ n << '_';
+
+ return n;
+ }
+
+ template
+ static void writeEscapeChars (OutputStream& out, const CharType* data, const int numChars,
+ const int maxCharsOnLine, const bool breakAtNewLines, const bool replaceSingleQuotes)
+ {
+ int charsOnLine = 0;
+ bool lastWasHexEscapeCode = false;
+
+ for (int i = 0; i < numChars || numChars < 0; ++i)
+ {
+ const CharType c = data[i];
+ bool startNewLine = false;
+
+ switch (c)
+ {
+ case '\t': out << "\\t"; lastWasHexEscapeCode = false; break;
+ case '\r': out << "\\r"; lastWasHexEscapeCode = false; break;
+ case '\n': out << "\\n"; lastWasHexEscapeCode = false; startNewLine = breakAtNewLines; break;
+ case '\\': out << "\\\\"; lastWasHexEscapeCode = false; break;
+ case '\"': out << "\\\""; lastWasHexEscapeCode = false; break;
+
+ case 0:
+ if (numChars < 0)
+ return;
+
+ out << "\\0";
+ lastWasHexEscapeCode = true;
+ break;
+
+ case '\'':
+ if (replaceSingleQuotes)
+ {
+ out << "\\\'";
+ lastWasHexEscapeCode = false;
+ break;
+ }
+
+ // deliberate fall-through...
+
+ default:
+ if (c >= 32 && c < 127 && ! (lastWasHexEscapeCode // (have to avoid following a hex escape sequence with a valid hex digit)
+ && ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))))
+ {
+ out << (char) c;
+ lastWasHexEscapeCode = false;
+ }
+ else
+ {
+ out << (c < 16 ? "\\x0" : "\\x") << String::toHexString ((int) (unsigned int) c);
+ lastWasHexEscapeCode = true;
+ }
+
+ break;
+ }
+
+ if ((startNewLine || (maxCharsOnLine > 0 && ++charsOnLine >= maxCharsOnLine))
+ && (numChars < 0 || i < numChars - 1))
+ {
+ charsOnLine = 0;
+ out << "\"" << newLine << "\"";
+ }
+ }
+ }
+
+ const String addEscapeChars (const String& s)
+ {
+ MemoryOutputStream out;
+ writeEscapeChars (out, (const juce_wchar*) s, -1, -1, false, true);
+ return out.toUTF8();
+ }
+
+ const String createIncludeStatement (const File& includeFile, const File& targetFile)
+ {
+ return "#include \"" + FileHelpers::unixStylePath (includeFile.getRelativePathFrom (targetFile.getParentDirectory())) + "\"";
+ }
+
+ const String makeHeaderGuardName (const File& file)
+ {
+ return "__" + file.getFileName().toUpperCase()
+ .replaceCharacters (" .", "__")
+ .retainCharacters ("_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
+ + "_" + String::toHexString (file.hashCode()).toUpperCase() + "__";
+ }
+
+ const String stringLiteral (const String& text)
+ {
+ if (text.isEmpty())
+ return "String::empty";
+
+ return CodeHelpers::addEscapeChars (text).quoted();
+ }
+
+ const String boolLiteral (const bool b)
+ {
+ return b ? "true" : "false";
+ }
+
+ const String floatLiteral (float v)
+ {
+ String s ((double) v, 4);
+
+ if (s.containsChar ('.'))
+ {
+ s = s.trimCharactersAtEnd ("0");
+ if (s.endsWithChar ('.'))
+ s << '0';
+
+ s << 'f';
+ }
+ else
+ {
+ s << ".0f";
+ }
+
+ return s;
+ }
+
+ const String doubleLiteral (double v)
+ {
+ String s (v, 7);
+
+ if (s.containsChar ('.'))
+ {
+ s = s.trimCharactersAtEnd ("0");
+ if (s.endsWithChar ('.'))
+ s << '0';
+ }
+ else
+ {
+ s << ".0";
+ }
+
+ return s;
+ }
+
+ const String colourToCode (const Colour& col)
+ {
+ const Colour colours[] =
+ {
+ #define COL(col) Colours::col,
+ #include "jucer_Colours.h"
+ #undef COL
+ Colours::transparentBlack
+ };
+
+ static const char* colourNames[] =
+ {
+ #define COL(col) #col,
+ #include "jucer_Colours.h"
+ #undef COL
+ 0
+ };
+
+ for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i)
+ if (col == colours[i])
+ return "Colours::" + String (colourNames[i]);
+
+ return "Colour (0x" + hexString8Digits ((int) col.getARGB()) + ')';
+ }
+
+ const String justificationToCode (const Justification& justification)
+ {
+ switch (justification.getFlags())
+ {
+ case Justification::centred: return "Justification::centred";
+ case Justification::centredLeft: return "Justification::centredLeft";
+ case Justification::centredRight: return "Justification::centredRight";
+ case Justification::centredTop: return "Justification::centredTop";
+ case Justification::centredBottom: return "Justification::centredBottom";
+ case Justification::topLeft: return "Justification::topLeft";
+ case Justification::topRight: return "Justification::topRight";
+ case Justification::bottomLeft: return "Justification::bottomLeft";
+ case Justification::bottomRight: return "Justification::bottomRight";
+ case Justification::left: return "Justification::left";
+ case Justification::right: return "Justification::right";
+ case Justification::horizontallyCentred: return "Justification::horizontallyCentred";
+ case Justification::top: return "Justification::top";
+ case Justification::bottom: return "Justification::bottom";
+ case Justification::verticallyCentred: return "Justification::verticallyCentred";
+ case Justification::horizontallyJustified: return "Justification::horizontallyJustified";
+ default: jassertfalse; break;
+ }
+
+ return "Justification (" + String (justification.getFlags()) + ")";
+ }
+
+ const String fontToCode (const Font& font)
+ {
+ String s ("Font (");
+ String name (font.getTypefaceName());
+
+ if (name != Font::getDefaultSansSerifFontName())
+ {
+ if (name == Font::getDefaultSerifFontName())
+ name = "Font::getDefaultSerifFontName()";
+ else if (name == Font::getDefaultMonospacedFontName())
+ name = "Font::getDefaultMonospacedFontName()";
+ else
+ name = stringLiteral (font.getTypefaceName());
+
+ s << name << ", ";
+ }
+
+ s << floatLiteral (font.getHeight());
+
+ if (font.isBold() && font.isItalic())
+ s << ", Font::bold | Font::italic";
+ else if (font.isBold())
+ s << ", Font::bold";
+ else if (font.isItalic())
+ s << ", Font::italic";
+
+ return s + ")";
+ }
+
+ const String castToFloat (const String& expression)
+ {
+ if (expression.containsOnly ("0123456789.f"))
+ {
+ String s (expression.getFloatValue());
+
+ if (s.containsChar (T('.')))
+ return s + "f";
+
+ return s + ".0f";
+ }
+
+ return "(float) (" + expression + ")";
+ }
+
+ void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out)
+ {
+ const int maxCharsOnLine = 250;
+
+ const unsigned char* data = (const unsigned char*) mb.getData();
+ int charsOnLine = 0;
+
+ bool canUseStringLiteral = mb.getSize() < 32768; // MS compilers can't handle big string literals..
+
+ if (canUseStringLiteral)
+ {
+ int numEscaped = 0;
+
+ for (size_t i = 0; i < mb.getSize(); ++i)
+ {
+ const unsigned int num = (unsigned int) data[i];
+ if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n'))
+ {
+ if (++numEscaped > mb.getSize() / 4)
+ {
+ canUseStringLiteral = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (! canUseStringLiteral)
+ {
+ out << "{ ";
+
+ for (size_t i = 0; i < mb.getSize(); ++i)
+ {
+ const int num = (int) (unsigned int) data[i];
+ out << num << ',';
+
+ charsOnLine += 2;
+ if (num >= 10)
+ ++charsOnLine;
+ if (num >= 100)
+ ++charsOnLine;
+
+ if (charsOnLine >= maxCharsOnLine)
+ {
+ charsOnLine = 0;
+ out << newLine;
+ }
+ }
+
+ out << "0,0 };";
+ }
+ else
+ {
+ out << "\"";
+ writeEscapeChars (out, data, (int) mb.getSize(), maxCharsOnLine, true, false);
+ out << "\";";
+ }
+ }
+
+ static int calculateHash (const String& s, const int hashMultiplier)
+ {
+ const char* t = s.toUTF8();
+ int hash = 0;
+ while (*t != 0)
+ hash = hashMultiplier * hash + *t++;
+
+ return hash;
+ }
+
+ static int findBestHashMultiplier (const StringArray& strings)
+ {
+ int v = 31;
+
+ for (;;)
+ {
+ SortedSet hashes;
+ bool collision = false;
+ for (int i = strings.size(); --i >= 0;)
+ {
+ const int hash = calculateHash (strings[i], v);
+ if (hashes.contains (hash))
+ {
+ collision = true;
+ break;
+ }
+
+ hashes.add (hash);
+ }
+
+ if (! collision)
+ break;
+
+ v += 2;
+ }
+
+ return v;
+ }
+
+ void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
+ const StringArray& strings, const StringArray& codeToExecute, const int indentLevel)
+ {
+ jassert (strings.size() == codeToExecute.size());
+ const String indent (String::repeatedString (" ", indentLevel));
+ const int hashMultiplier = findBestHashMultiplier (strings);
+
+ out << indent << "int hash = 0;" << newLine
+ << indent << "if (" << utf8PointerVariable << " != 0)" << newLine
+ << indent << " while (*" << utf8PointerVariable << " != 0)" << newLine
+ << indent << " hash = " << hashMultiplier << " * hash + *" << utf8PointerVariable << "++;" << newLine
+ << newLine
+ << indent << "switch (hash)" << newLine
+ << indent << "{" << newLine;
+
+ for (int i = 0; i < strings.size(); ++i)
+ out << indent << " case 0x" << hexString8Digits (calculateHash (strings[i], hashMultiplier))
+ << ": " << codeToExecute[i] << newLine;
+
+ out << indent << " default: break;" << newLine
+ << indent << "}" << newLine << newLine;
+ }
+}
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.h b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.h
new file mode 100644
index 0000000000..91965b815a
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.h
@@ -0,0 +1,57 @@
+/*
+ ==============================================================================
+
+ 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 __JUCER_CODEUTILITIES_H_B86AA5D2__
+#define __JUCER_CODEUTILITIES_H_B86AA5D2__
+
+
+//==============================================================================
+namespace CodeHelpers
+{
+ const String indent (const String& code, const int numSpaces, bool indentFirstLine);
+ const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates);
+ const String addEscapeChars (const String& text);
+ const String createIncludeStatement (const File& includeFile, const File& targetFile);
+ const String makeHeaderGuardName (const File& file);
+
+ const String stringLiteral (const String& text);
+ const String boolLiteral (bool b);
+ const String floatLiteral (float v);
+ const String doubleLiteral (double v);
+
+ const String colourToCode (const Colour& col);
+ const String justificationToCode (const Justification& justification);
+ const String castToFloat (const String& expression);
+ const String fontToCode (const Font& font);
+
+ void writeDataAsCppLiteral (const MemoryBlock& data, OutputStream& out);
+
+ void createStringMatcher (OutputStream& out, const String& utf8PointerVariable,
+ const StringArray& strings, const StringArray& codeToExecute, const int indentLevel);
+
+}
+
+
+#endif // __JUCER_CODEUTILITIES_H_B86AA5D2__
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h b/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h
index d0b2e359ff..6c69f83aad 100644
--- a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h
+++ b/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h
@@ -166,5 +166,20 @@ public:
Coordinate left, right, top, bottom;
};
+//==============================================================================
+class ComponentAutoLayoutManager : public ComponentListener
+{
+public:
+ ComponentAutoLayoutManager (Component* parentComponent);
+ ~ComponentAutoLayoutManager();
+
+ void addMarker (bool isX, const String& name, const String& position);
+ void moveMarker (const String& name, int newPosition);
+
+private:
+ Array components;
+
+};
+
#endif // __JUCER_COORDINATE_H_EF56ACFA__
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.cpp b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.cpp
new file mode 100644
index 0000000000..5aebac4fc3
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.cpp
@@ -0,0 +1,177 @@
+/*
+ ==============================================================================
+
+ jucer_FileUtilities.cpp
+ Created: 14 May 2010 11:24:09pm
+ Author: Julian Storer
+
+ ==============================================================================
+*/
+
+#include "../jucer_Headers.h"
+#include "jucer_CodeHelpers.h"
+
+
+//==============================================================================
+namespace FileHelpers
+{
+ int64 calculateStreamHashCode (InputStream& in)
+ {
+ int64 t = 0;
+
+ const int bufferSize = 4096;
+ HeapBlock buffer;
+ buffer.malloc (bufferSize);
+
+ for (;;)
+ {
+ const int num = in.read (buffer, bufferSize);
+
+ if (num <= 0)
+ break;
+
+ for (int i = 0; i < num; ++i)
+ t = t * 65599 + buffer[i];
+ }
+
+ return t;
+ }
+
+ int64 calculateFileHashCode (const File& file)
+ {
+ ScopedPointer stream (file.createInputStream());
+ return stream != 0 ? calculateStreamHashCode (*stream) : 0;
+ }
+
+ bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes)
+ {
+ if (file.getSize() == numBytes)
+ {
+ MemoryInputStream newStream (data, numBytes, false);
+
+ if (calculateStreamHashCode (newStream) == calculateFileHashCode (file))
+ return true;
+ }
+
+ TemporaryFile temp (file);
+
+ return temp.getFile().appendData (data, numBytes)
+ && temp.overwriteTargetFileWithTemporary();
+ }
+
+ bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
+ {
+ return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
+ }
+
+ bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData)
+ {
+ return overwriteFileWithNewDataIfDifferent (file, newData.toUTF8(), strlen ((const char*) newData.toUTF8()));
+ }
+
+ bool containsAnyNonHiddenFiles (const File& folder)
+ {
+ DirectoryIterator di (folder, false);
+
+ while (di.next())
+ if (! di.getFile().isHidden())
+ return true;
+
+ return false;
+ }
+
+ const String unixStylePath (const String& path)
+ {
+ return path.replaceCharacter ('\\', '/');
+ }
+
+ const String windowsStylePath (const String& path)
+ {
+ return path.replaceCharacter ('/', '\\');
+ }
+
+ const String appendPath (const String& path, const String& subpath)
+ {
+ if (File::isAbsolutePath (subpath)
+ || subpath.startsWithChar ('$')
+ || subpath.startsWithChar ('~')
+ || (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == ':'))
+ return subpath.replaceCharacter ('\\', '/');
+
+ String path1 (path.replaceCharacter ('\\', '/'));
+ if (! path1.endsWithChar ('/'))
+ path1 << '/';
+
+ return path1 + subpath.replaceCharacter ('\\', '/');
+ }
+
+ bool shouldPathsBeRelative (String path1, String path2)
+ {
+ path1 = unixStylePath (path1);
+ path2 = unixStylePath (path2);
+
+ const int len = jmin (path1.length(), path2.length());
+ int commonBitLength = 0;
+
+ for (int i = 0; i < len; ++i)
+ {
+ if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i]))
+ break;
+
+ ++commonBitLength;
+ }
+
+ return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty();
+ }
+
+ //==============================================================================
+ bool isJuceFolder (const File& folder)
+ {
+ return folder.getFileName().containsIgnoreCase ("juce")
+ && folder.getChildFile ("juce.h").exists()
+ && folder.getChildFile ("juce_Config.h").exists();
+ }
+
+ static const File lookInFolderForJuceFolder (const File& folder)
+ {
+ for (DirectoryIterator di (folder, false, "*juce*", File::findDirectories); di.next();)
+ {
+ if (isJuceFolder (di.getFile()))
+ return di.getFile();
+ }
+
+ return File::nonexistent;
+ }
+
+ const File findParentJuceFolder (const File& file)
+ {
+ File f (file);
+
+ while (f.exists() && f.getParentDirectory() != f)
+ {
+ if (isJuceFolder (f))
+ return f;
+
+ File found = lookInFolderForJuceFolder (f);
+ if (found.exists())
+ return found;
+
+ f = f.getParentDirectory();
+ }
+
+ return File::nonexistent;
+ }
+
+ const File findDefaultJuceFolder()
+ {
+ File f = findParentJuceFolder (File::getSpecialLocation (File::currentApplicationFile));
+
+ if (! f.exists())
+ f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userHomeDirectory));
+
+ if (! f.exists())
+ f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userDocumentsDirectory));
+
+ return f;
+ }
+}
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.h b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.h
new file mode 100644
index 0000000000..dd19d66aa3
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_FileHelpers.h
@@ -0,0 +1,86 @@
+/*
+ ==============================================================================
+
+ 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 __JUCER_FILEUTILITIES_H_EEE25EE3__
+#define __JUCER_FILEUTILITIES_H_EEE25EE3__
+
+
+//==============================================================================
+namespace FileHelpers
+{
+ int64 calculateStreamHashCode (InputStream& stream);
+ int64 calculateFileHashCode (const File& file);
+
+ bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes);
+ bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData);
+ bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData);
+
+ bool containsAnyNonHiddenFiles (const File& folder);
+
+ const String unixStylePath (const String& path);
+ const String windowsStylePath (const String& path);
+
+ bool shouldPathsBeRelative (String path1, String path2);
+
+ //==============================================================================
+ bool isJuceFolder (const File& folder);
+ const File findParentJuceFolder (const File& file);
+ const File findDefaultJuceFolder();
+}
+
+//==============================================================================
+class FileModificationDetector
+{
+public:
+ FileModificationDetector (const File& file_)
+ : file (file_)
+ {
+ }
+
+ const File& getFile() const { return file; }
+ void fileHasBeenRenamed (const File& newFile) { file = newFile; }
+
+ bool hasBeenModified() const
+ {
+ return fileModificationTime != file.getLastModificationTime()
+ && (fileSize != file.getSize()
+ || FileHelpers::calculateFileHashCode (file) != fileHashCode);
+ }
+
+ void updateHash()
+ {
+ fileModificationTime = file.getLastModificationTime();
+ fileSize = file.getSize();
+ fileHashCode = FileHelpers::calculateFileHashCode (file);
+ }
+
+private:
+ File file;
+ Time fileModificationTime;
+ int64 fileHashCode, fileSize;
+};
+
+
+#endif // __JUCER_FILEUTILITIES_H_EEE25EE3__
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp
new file mode 100644
index 0000000000..19c23cc1ab
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp
@@ -0,0 +1,268 @@
+/*
+ ==============================================================================
+
+ 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.
+
+ ==============================================================================
+*/
+
+#include "../jucer_Headers.h"
+
+
+//==============================================================================
+const int64 hashCode64 (const String& s)
+{
+ return s.hashCode64() + s.length() * s.hashCode() + s.toUpperCase().hashCode();
+}
+
+const String createAlphaNumericUID()
+{
+ String uid;
+ static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ Random r (Random::getSystemRandom().nextInt64());
+
+ for (int i = 9; --i >= 0;)
+ {
+ r.setSeedRandomly();
+ uid << (juce_wchar) chars [r.nextInt (sizeof (chars))];
+ }
+
+ return uid;
+}
+
+const String randomHexString (Random& random, int numChars)
+{
+ String s;
+ const char hexChars[] = "0123456789ABCDEF";
+
+ while (--numChars >= 0)
+ s << hexChars [random.nextInt (16)];
+
+ return s;
+}
+
+const String hexString8Digits (int value)
+{
+ return String::toHexString (value).paddedLeft ('0', 8);
+}
+
+const String createGUID (const String& seed)
+{
+ String guid;
+ Random r (hashCode64 (seed + "_jucersalt"));
+ guid << "{" << randomHexString (r, 8); // (written as separate statements to enforce the order of execution)
+ guid << "-" << randomHexString (r, 4);
+ guid << "-" << randomHexString (r, 4);
+ guid << "-" << randomHexString (r, 4);
+ guid << "-" << randomHexString (r, 12) << "}";
+ return guid;
+}
+
+//==============================================================================
+void autoScrollForMouseEvent (const MouseEvent& e)
+{
+ Viewport* const viewport = e.eventComponent->findParentComponentOfClass ((Viewport*) 0);
+
+ if (viewport != 0)
+ {
+ const MouseEvent e2 (e.getEventRelativeTo (viewport));
+ viewport->autoScroll (e2.x, e2.y, 8, 16);
+ }
+}
+
+void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text)
+{
+ g.fillAll (Colours::white.withAlpha (0.4f));
+ g.setColour (Colours::grey);
+ g.drawRect (0, 0, w, h);
+
+ g.drawLine (0.5f, 0.5f, w - 0.5f, h - 0.5f);
+ g.drawLine (0.5f, h - 0.5f, w - 0.5f, 0.5f);
+
+ g.setColour (Colours::black);
+ g.setFont (11.0f);
+ g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2);
+}
+
+void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize)
+{
+ ColourGradient cg (Colours::black.withAlpha (0.15f), 0, 0,
+ Colours::transparentBlack, 0, (float) shadowSize, false);
+ cg.addColour (0.4, Colours::black.withAlpha (0.07f));
+ cg.addColour (0.6, Colours::black.withAlpha (0.02f));
+
+ g.setGradientFill (cg);
+ g.fillRect (0, 0, w, shadowSize);
+
+ cg.point1.setXY (0.0f, (float) h);
+ cg.point2.setXY (0.0f, (float) h - shadowSize);
+ g.setGradientFill (cg);
+ g.fillRect (0, h - shadowSize, w, shadowSize);
+
+ cg.point1.setXY (0.0f, 0.0f);
+ cg.point2.setXY ((float) shadowSize, 0.0f);
+ g.setGradientFill (cg);
+ g.fillRect (0, 0, shadowSize, h);
+
+ cg.point1.setXY ((float) w, 0.0f);
+ cg.point2.setXY ((float) w - shadowSize, 0.0f);
+ g.setGradientFill (cg);
+ g.fillRect (w - shadowSize, 0, shadowSize, h);
+}
+
+//==============================================================================
+int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex)
+{
+ startIndex = jmax (0, startIndex);
+
+ while (startIndex < lines.size())
+ {
+ if (lines[startIndex].trimStart().startsWithIgnoreCase (text))
+ return startIndex;
+
+ ++startIndex;
+ }
+
+ return -1;
+}
+
+
+//==============================================================================
+PropertyPanelWithTooltips::PropertyPanelWithTooltips()
+ : lastComp (0)
+{
+ addAndMakeVisible (panel = new PropertyPanel());
+ startTimer (150);
+}
+
+PropertyPanelWithTooltips::~PropertyPanelWithTooltips()
+{
+ deleteAllChildren();
+}
+
+void PropertyPanelWithTooltips::paint (Graphics& g)
+{
+ g.setColour (Colour::greyLevel (0.15f));
+ g.setFont (13.0f);
+
+ TextLayout tl;
+ tl.appendText (lastTip, Font (14.0f));
+ tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice
+ if (tl.getNumLines() > 3)
+ tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in..
+
+ tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10,
+ getHeight() - panel->getBottom() - 4,
+ Justification::centredLeft);
+}
+
+void PropertyPanelWithTooltips::resized()
+{
+ panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f)));
+}
+
+void PropertyPanelWithTooltips::timerCallback()
+{
+ Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
+
+ if (newComp != lastComp)
+ {
+ lastComp = newComp;
+
+ String newTip (findTip (newComp));
+
+ if (newTip != lastTip)
+ {
+ lastTip = newTip;
+ repaint (0, panel->getBottom(), getWidth(), getHeight());
+ }
+ }
+}
+
+const String PropertyPanelWithTooltips::findTip (Component* c)
+{
+ while (c != 0 && c != this)
+ {
+ TooltipClient* const tc = dynamic_cast (c);
+ if (tc != 0)
+ {
+ const String tip (tc->getTooltip());
+
+ if (tip.isNotEmpty())
+ return tip;
+ }
+
+ c = c->getParentComponent();
+ }
+
+ return String::empty;
+}
+
+//==============================================================================
+FloatingLabelComponent::FloatingLabelComponent()
+ : font (10.0f)
+{
+ setInterceptsMouseClicks (false ,false);
+}
+
+void FloatingLabelComponent::remove()
+{
+ if (getParentComponent() != 0)
+ getParentComponent()->removeChildComponent (this);
+}
+
+void FloatingLabelComponent::update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below)
+{
+ colour = textColour;
+
+ Rectangle r;
+
+ if (text != getName())
+ {
+ setName (text);
+ glyphs.clear();
+ glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left);
+ glyphs.justifyGlyphs (0, std::numeric_limits::max(), 0, 0, 1000, 1000, Justification::topLeft);
+
+ r = glyphs.getBoundingBox (0, std::numeric_limits::max(), false)
+ .getSmallestIntegerContainer().expanded (2, 2);
+ }
+ else
+ {
+ r = getLocalBounds();
+ }
+
+ r.setPosition (x + (toRight ? 3 : -(r.getWidth() + 3)), y + (below ? 2 : -(r.getHeight() + 2)));
+ setBounds (r);
+ parent->addAndMakeVisible (this);
+}
+
+void FloatingLabelComponent::paint (Graphics& g)
+{
+ g.setFont (font);
+ g.setColour (Colours::white.withAlpha (0.5f));
+
+ for (int y = -1; y <= 1; ++y)
+ for (int x = -1; x <= 1; ++x)
+ glyphs.draw (g, AffineTransform::translation (1.0f + x, 1.0f + y));
+
+ g.setColour (colour);
+ glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f));
+}
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h
new file mode 100644
index 0000000000..85879d6400
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h
@@ -0,0 +1,82 @@
+/*
+ ==============================================================================
+
+ 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.
+
+ ==============================================================================
+*/
+
+
+//==============================================================================
+// String::hashCode64 actually hit some dupes, so this is a more powerful version.
+const int64 hashCode64 (const String& s);
+const String randomHexString (Random& random, int numChars);
+const String hexString8Digits (int value);
+
+const String createAlphaNumericUID();
+const String createGUID (const String& seed); // Turns a seed into a windows GUID
+
+//==============================================================================
+int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex);
+
+void autoScrollForMouseEvent (const MouseEvent& e);
+
+void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text);
+void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize);
+
+
+//==============================================================================
+class PropertyPanelWithTooltips : public Component,
+ public Timer
+{
+public:
+ PropertyPanelWithTooltips();
+ ~PropertyPanelWithTooltips();
+
+ PropertyPanel* getPanel() const { return panel; }
+
+ void paint (Graphics& g);
+ void resized();
+ void timerCallback();
+
+private:
+ PropertyPanel* panel;
+ TextLayout layout;
+ Component* lastComp;
+ String lastTip;
+
+ const String findTip (Component* c);
+};
+
+//==============================================================================
+class FloatingLabelComponent : public Component
+{
+public:
+ FloatingLabelComponent();
+
+ void remove();
+ void update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below);
+ void paint (Graphics& g);
+
+private:
+ Font font;
+ Colour colour;
+ GlyphArrangement glyphs;
+};
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h b/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h
index 4931634310..100754efe3 100644
--- a/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h
+++ b/extras/Jucer (experimental)/Source/utility/jucer_RelativePath.h
@@ -59,8 +59,8 @@ public:
RootFolder getRoot() const { return root; }
- const String toUnixStyle() const { return FileUtils::unixStylePath (path); }
- const String toWindowsStyle() const { return FileUtils::windowsStylePath (path); }
+ const String toUnixStyle() const { return FileHelpers::unixStylePath (path); }
+ const String toWindowsStyle() const { return FileHelpers::windowsStylePath (path); }
const String getFileName() const { return getFakeFile().getFileName(); }
const String getFileNameWithoutExtension() const { return getFakeFile().getFileNameWithoutExtension(); }
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp
index c5250d3dc4..514f262ef7 100644
--- a/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp
+++ b/extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp
@@ -112,10 +112,10 @@ void StoredSettings::setLastProject (const File& file)
const File StoredSettings::getLastKnownJuceFolder() const
{
- File defaultJuceFolder (FileUtils::findDefaultJuceFolder());
+ File defaultJuceFolder (FileHelpers::findDefaultJuceFolder());
File f (props->getValue ("lastJuceFolder", defaultJuceFolder.getFullPathName()));
- if ((! FileUtils::isJuceFolder (f)) && FileUtils::isJuceFolder (defaultJuceFolder))
+ if ((! FileHelpers::isJuceFolder (f)) && FileHelpers::isJuceFolder (defaultJuceFolder))
f = defaultJuceFolder;
return f;
@@ -123,7 +123,7 @@ const File StoredSettings::getLastKnownJuceFolder() const
void StoredSettings::setLastKnownJuceFolder (const File& file)
{
- jassert (FileUtils::isJuceFolder (file));
+ jassert (FileHelpers::isJuceFolder (file));
props->setValue ("lastJuceFolder", file.getFullPathName());
}
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_TickIterator.h b/extras/Jucer (experimental)/Source/utility/jucer_TickIterator.h
new file mode 100644
index 0000000000..3751c9757b
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/utility/jucer_TickIterator.h
@@ -0,0 +1,148 @@
+/*
+ ==============================================================================
+
+ 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 __JUCER_TICKITERATOR_H_8D744D8A__
+#define __JUCER_TICKITERATOR_H_8D744D8A__
+
+
+//==============================================================================
+class TickIterator
+{
+public:
+ TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_,
+ int minPixelsPerTick, int minWidthForLabels)
+ : startValue (startValue_),
+ endValue (endValue_),
+ valuePerPixel (valuePerPixel_)
+ {
+ tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick);
+ labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels);
+
+ tickPosition = pixelsToValue (-minWidthForLabels);
+ tickPosition = snapValueDown (tickPosition, tickLevelIndex);
+ }
+
+ bool getNextTick (float& pixelX, float& tickLength, String& label)
+ {
+ const double tickUnits = getTickSizes() [tickLevelIndex];
+ tickPosition += tickUnits;
+
+ const int totalLevels = getNumTickSizes();
+ int highestIndex = tickLevelIndex;
+
+ while (++highestIndex < totalLevels)
+ {
+ const double ticksAtThisLevel = tickPosition / getTickSizes() [highestIndex];
+
+ if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001)
+ break;
+ }
+
+ --highestIndex;
+
+ if (highestIndex >= labelLevelIndex)
+ label = getDescriptionOfValue (tickPosition, labelLevelIndex);
+ else
+ label = String::empty;
+
+ tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex);
+ pixelX = valueToPixels (tickPosition);
+
+ return tickPosition < endValue;
+ }
+
+private:
+ double tickPosition;
+ int tickLevelIndex, labelLevelIndex;
+ const double startValue, endValue, valuePerPixel;
+
+ static int getNumTickSizes()
+ {
+ return 10;
+ }
+
+ static const double* getTickSizes()
+ {
+ static const double tickSizes[] = { 1.0, 2.0, 5.0,
+ 10.0, 20.0, 50.0,
+ 100.0, 200.0, 500.0, 1000.0 };
+ return tickSizes;
+ }
+
+ int findLevelIndexForValue (const double value) const
+ {
+ int i;
+ for (i = 0; i < getNumTickSizes(); ++i)
+ if (getTickSizes() [i] >= value)
+ break;
+
+ return i;
+ }
+
+ double pixelsToValue (int pixels) const
+ {
+ return startValue + pixels * valuePerPixel;
+ }
+
+ float valueToPixels (double value) const
+ {
+ return (float) ((value - startValue) / valuePerPixel);
+ }
+
+ static double snapValueToNearest (const double t, const int valueLevelIndex)
+ {
+ const double unitsPerInterval = getTickSizes() [valueLevelIndex];
+ return unitsPerInterval * floor (t / unitsPerInterval + 0.5);
+ }
+
+ static double snapValueDown (const double t, const int valueLevelIndex)
+ {
+ const double unitsPerInterval = getTickSizes() [valueLevelIndex];
+ return unitsPerInterval * floor (t / unitsPerInterval);
+ }
+
+ static inline int roundDoubleToInt (const double value)
+ {
+ union { int asInt[2]; double asDouble; } n;
+ n.asDouble = value + 6755399441055744.0;
+
+ #if TARGET_RT_BIG_ENDIAN
+ return n.asInt [1];
+ #else
+ return n.asInt [0];
+ #endif
+ }
+
+ static const String getDescriptionOfValue (const double value, const int valueLevelIndex)
+ {
+ return String (roundToInt (value));
+ }
+
+ TickIterator (const TickIterator&);
+ TickIterator& operator= (const TickIterator&);
+};
+
+
+#endif // __JUCER_TICKITERATOR_H_8D744D8A__
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp
deleted file mode 100644
index 1c28b76e55..0000000000
--- a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- ==============================================================================
-
- 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.
-
- ==============================================================================
-*/
-
-#include "../jucer_Headers.h"
-
-
-//==============================================================================
-const int64 hashCode64 (const String& s)
-{
- return s.hashCode64() + s.length() * s.hashCode() + s.toUpperCase().hashCode();
-}
-
-const String createAlphaNumericUID()
-{
- String uid;
- static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
- Random r (Random::getSystemRandom().nextInt64());
-
- for (int i = 9; --i >= 0;)
- {
- r.setSeedRandomly();
- uid << (juce_wchar) chars [r.nextInt (sizeof (chars))];
- }
-
- return uid;
-}
-
-const String randomHexString (Random& random, int numChars)
-{
- String s;
- const char hexChars[] = "0123456789ABCDEF";
-
- while (--numChars >= 0)
- s << hexChars [random.nextInt (16)];
-
- return s;
-}
-
-const String hexString8Digits (int value)
-{
- return String::toHexString (value).paddedLeft ('0', 8);
-}
-
-const String createGUID (const String& seed)
-{
- String guid;
- Random r (hashCode64 (seed + "_jucersalt"));
- guid << "{" << randomHexString (r, 8); // (written as separate statements to enforce the order of execution)
- guid << "-" << randomHexString (r, 4);
- guid << "-" << randomHexString (r, 4);
- guid << "-" << randomHexString (r, 4);
- guid << "-" << randomHexString (r, 12) << "}";
- return guid;
-}
-
-//==============================================================================
-namespace FileUtils
-{
- int64 calculateStreamHashCode (InputStream& in)
- {
- int64 t = 0;
-
- const int bufferSize = 4096;
- HeapBlock buffer;
- buffer.malloc (bufferSize);
-
- for (;;)
- {
- const int num = in.read (buffer, bufferSize);
-
- if (num <= 0)
- break;
-
- for (int i = 0; i < num; ++i)
- t = t * 65599 + buffer[i];
- }
-
- return t;
- }
-
- int64 calculateFileHashCode (const File& file)
- {
- ScopedPointer stream (file.createInputStream());
- return stream != 0 ? calculateStreamHashCode (*stream) : 0;
- }
-
- bool areFilesIdentical (const File& file1, const File& file2)
- {
- return file1.getSize() == file2.getSize()
- && calculateFileHashCode (file1) == calculateFileHashCode (file2);
- }
-
- bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes)
- {
- if (file.getSize() == numBytes)
- {
- MemoryInputStream newStream (data, numBytes, false);
-
- if (calculateStreamHashCode (newStream) == calculateFileHashCode (file))
- return true;
- }
-
- TemporaryFile temp (file);
-
- return temp.getFile().appendData (data, numBytes)
- && temp.overwriteTargetFileWithTemporary();
- }
-
- bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData)
- {
- return overwriteFileWithNewDataIfDifferent (file, newData.getData(), newData.getDataSize());
- }
-
- bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData)
- {
- return overwriteFileWithNewDataIfDifferent (file, newData.toUTF8(), strlen ((const char*) newData.toUTF8()));
- }
-
- bool containsAnyNonHiddenFiles (const File& folder)
- {
- DirectoryIterator di (folder, false);
-
- while (di.next())
- if (! di.getFile().isHidden())
- return true;
-
- return false;
- }
-
- const String unixStylePath (const String& path)
- {
- return path.replaceCharacter ('\\', '/');
- }
-
- const String windowsStylePath (const String& path)
- {
- return path.replaceCharacter ('/', '\\');
- }
-
- const String appendPath (const String& path, const String& subpath)
- {
- if (File::isAbsolutePath (subpath)
- || subpath.startsWithChar ('$')
- || subpath.startsWithChar ('~')
- || (CharacterFunctions::isLetter (subpath[0]) && subpath[1] == ':'))
- return subpath.replaceCharacter ('\\', '/');
-
- String path1 (path.replaceCharacter ('\\', '/'));
- if (! path1.endsWithChar ('/'))
- path1 << '/';
-
- return path1 + subpath.replaceCharacter ('\\', '/');
- }
-
- bool shouldPathsBeRelative (String path1, String path2)
- {
- path1 = unixStylePath (path1);
- path2 = unixStylePath (path2);
-
- const int len = jmin (path1.length(), path2.length());
- int commonBitLength = 0;
-
- for (int i = 0; i < len; ++i)
- {
- if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i]))
- break;
-
- ++commonBitLength;
- }
-
- return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty();
- }
-
- //==============================================================================
- bool isJuceFolder (const File& folder)
- {
- return folder.getFileName().containsIgnoreCase ("juce")
- && folder.getChildFile ("juce.h").exists()
- && folder.getChildFile ("juce_Config.h").exists();
- }
-
- static const File lookInFolderForJuceFolder (const File& folder)
- {
- for (DirectoryIterator di (folder, false, "*juce*", File::findDirectories); di.next();)
- {
- if (isJuceFolder (di.getFile()))
- return di.getFile();
- }
-
- return File::nonexistent;
- }
-
- const File findParentJuceFolder (const File& file)
- {
- File f (file);
-
- while (f.exists() && f.getParentDirectory() != f)
- {
- if (isJuceFolder (f))
- return f;
-
- File found = lookInFolderForJuceFolder (f);
- if (found.exists())
- return found;
-
- f = f.getParentDirectory();
- }
-
- return File::nonexistent;
- }
-
- const File findDefaultJuceFolder()
- {
- File f = findParentJuceFolder (File::getSpecialLocation (File::currentApplicationFile));
-
- if (! f.exists())
- f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userHomeDirectory));
-
- if (! f.exists())
- f = lookInFolderForJuceFolder (File::getSpecialLocation (File::userDocumentsDirectory));
-
- return f;
- }
-}
-
-//==============================================================================
-void autoScrollForMouseEvent (const MouseEvent& e)
-{
- Viewport* const viewport = e.eventComponent->findParentComponentOfClass ((Viewport*) 0);
-
- if (viewport != 0)
- {
- const MouseEvent e2 (e.getEventRelativeTo (viewport));
- viewport->autoScroll (e2.x, e2.y, 8, 16);
- }
-}
-
-void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text)
-{
- g.fillAll (Colours::white.withAlpha (0.4f));
- g.setColour (Colours::grey);
- g.drawRect (0, 0, w, h);
-
- g.drawLine (0.5f, 0.5f, w - 0.5f, h - 0.5f);
- g.drawLine (0.5f, h - 0.5f, w - 0.5f, 0.5f);
-
- g.setColour (Colours::black);
- g.setFont (11.0f);
- g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2);
-}
-
-void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize)
-{
- ColourGradient cg (Colours::black.withAlpha (0.15f), 0, 0,
- Colours::transparentBlack, 0, (float) shadowSize, false);
- cg.addColour (0.4, Colours::black.withAlpha (0.07f));
- cg.addColour (0.6, Colours::black.withAlpha (0.02f));
-
- g.setGradientFill (cg);
- g.fillRect (0, 0, w, shadowSize);
-
- cg.point1.setXY (0.0f, (float) h);
- cg.point2.setXY (0.0f, (float) h - shadowSize);
- g.setGradientFill (cg);
- g.fillRect (0, h - shadowSize, w, shadowSize);
-
- cg.point1.setXY (0.0f, 0.0f);
- cg.point2.setXY ((float) shadowSize, 0.0f);
- g.setGradientFill (cg);
- g.fillRect (0, 0, shadowSize, h);
-
- cg.point1.setXY ((float) w, 0.0f);
- cg.point2.setXY ((float) w - shadowSize, 0.0f);
- g.setGradientFill (cg);
- g.fillRect (w - shadowSize, 0, shadowSize, h);
-}
-
-//==============================================================================
-namespace CodeFormatting
-{
- const String indent (const String& code, const int numSpaces, bool indentFirstLine)
- {
- if (numSpaces == 0)
- return code;
-
- const String space (String::repeatedString (" ", numSpaces));
-
- StringArray lines;
- lines.addLines (code);
-
- for (int i = (indentFirstLine ? 0 : 1); i < lines.size(); ++i)
- {
- String s (lines[i].trimEnd());
- if (s.isNotEmpty())
- s = space + s;
-
- lines.set (i, s);
- }
-
- return lines.joinIntoString (newLine);
- }
-
- const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates)
- {
- if (s.isEmpty())
- return "unknown";
-
- if (removeColons)
- s = s.replaceCharacters (".,;:/@", "______");
- else
- s = s.replaceCharacters (".,;/@", "_____");
-
- int i;
- for (i = s.length(); --i > 0;)
- if (CharacterFunctions::isLetter (s[i])
- && CharacterFunctions::isLetter (s[i - 1])
- && CharacterFunctions::isUpperCase (s[i])
- && ! CharacterFunctions::isUpperCase (s[i - 1]))
- s = s.substring (0, i) + " " + s.substring (i);
-
- String allowedChars ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ 0123456789");
- if (allowTemplates)
- allowedChars += "<>";
-
- if (! removeColons)
- allowedChars += ":";
-
- StringArray words;
- words.addTokens (s.retainCharacters (allowedChars), false);
- words.trim();
-
- String n (words[0]);
-
- if (capitalise)
- n = n.toLowerCase();
-
- for (i = 1; i < words.size(); ++i)
- {
- if (capitalise && words[i].length() > 1)
- n << words[i].substring (0, 1).toUpperCase()
- << words[i].substring (1).toLowerCase();
- else
- n << words[i];
- }
-
- if (CharacterFunctions::isDigit (n[0]))
- n = "_" + n;
-
- if (CPlusPlusCodeTokeniser::isReservedKeyword (n))
- n << '_';
-
- return n;
- }
-
- const String addEscapeChars (const String& s)
- {
- const int len = s.length();
- String r;
- r.preallocateStorage (len + 2);
- bool lastWasHexEscapeCode = false;
-
- for (int i = 0; i < len; ++i)
- {
- const juce_wchar c = s[i];
-
- switch (c)
- {
- case '\t': r << "\\t"; lastWasHexEscapeCode = false; break;
- case '\r': r << "\\r"; lastWasHexEscapeCode = false; break;
- case '\n': r << "\\n"; lastWasHexEscapeCode = false; break;
- case '\\': r << "\\\\"; lastWasHexEscapeCode = false; break;
- case '\'': r << "\\\'"; lastWasHexEscapeCode = false; break;
- case '\"': r << "\\\""; lastWasHexEscapeCode = false; break;
-
- default:
- if (c < 128
- && ! (lastWasHexEscapeCode
- && String ("0123456789abcdefABCDEF").containsChar (c))) // (have to avoid following a hex escape sequence with a valid hex digit)
- {
- r << c;
- lastWasHexEscapeCode = false;
- }
- else
- {
- r << "\\x" << String::toHexString ((int) c);
- lastWasHexEscapeCode = true;
- }
-
- break;
- }
- }
-
- return r;
- }
-
- const String createIncludeStatement (const File& includeFile, const File& targetFile)
- {
- return "#include \"" + FileUtils::unixStylePath (includeFile.getRelativePathFrom (targetFile.getParentDirectory())) + "\"";
- }
-
- const String makeHeaderGuardName (const File& file)
- {
- return "__" + file.getFileName().toUpperCase()
- .replaceCharacters (" .", "__")
- .retainCharacters ("_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
- + "_" + String::toHexString (file.hashCode()).toUpperCase() + "__";
- }
-
- const String stringLiteral (const String& text)
- {
- if (text.isEmpty())
- return "String::empty";
-
- return CodeFormatting::addEscapeChars (text).quoted();
- }
-
- const String boolLiteral (bool b)
- {
- return b ? "true" : "false";
- }
-
- const String floatLiteral (float v)
- {
- String s ((double) v, 4);
-
- if (s.containsChar ('.'))
- s << 'f';
- else
- s << ".0f";
-
- return s;
- }
-
- const String doubleLiteral (double v)
- {
- String s (v, 7);
-
- if (! s.containsChar ('.'))
- s << ".0";
-
- return s;
- }
-
- const String colourToCode (const Colour& col)
- {
- const Colour colours[] =
- {
- #define COL(col) Colours::col,
- #include "jucer_Colours.h"
- #undef COL
- Colours::transparentBlack
- };
-
- static const char* colourNames[] =
- {
- #define COL(col) #col,
- #include "jucer_Colours.h"
- #undef COL
- 0
- };
-
- for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i)
- if (col == colours[i])
- return "Colours::" + String (colourNames[i]);
-
- return "Colour (0x" + hexString8Digits ((int) col.getARGB()) + ')';
- }
-
- const String justificationToCode (const Justification& justification)
- {
- switch (justification.getFlags())
- {
- case Justification::centred: return "Justification::centred";
- case Justification::centredLeft: return "Justification::centredLeft";
- case Justification::centredRight: return "Justification::centredRight";
- case Justification::centredTop: return "Justification::centredTop";
- case Justification::centredBottom: return "Justification::centredBottom";
- case Justification::topLeft: return "Justification::topLeft";
- case Justification::topRight: return "Justification::topRight";
- case Justification::bottomLeft: return "Justification::bottomLeft";
- case Justification::bottomRight: return "Justification::bottomRight";
- case Justification::left: return "Justification::left";
- case Justification::right: return "Justification::right";
- case Justification::horizontallyCentred: return "Justification::horizontallyCentred";
- case Justification::top: return "Justification::top";
- case Justification::bottom: return "Justification::bottom";
- case Justification::verticallyCentred: return "Justification::verticallyCentred";
- case Justification::horizontallyJustified: return "Justification::horizontallyJustified";
- default: jassertfalse; break;
- }
-
- return "Justification (" + String (justification.getFlags()) + ")";
- }
-
- const String castToFloat (const String& expression)
- {
- if (expression.containsOnly ("0123456789.f"))
- {
- String s (expression.getFloatValue());
-
- if (s.containsChar (T('.')))
- return s + "f";
-
- return s + ".0f";
- }
-
- return "(float) (" + expression + ")";
- }
-
- void writeDataAsCppLiteral (const MemoryBlock& mb, OutputStream& out)
- {
- const int maxCharsOnLine = 250;
-
- const unsigned char* data = (const unsigned char*) mb.getData();
- int charsOnLine = 0;
-
- bool canUseStringLiteral = mb.getSize() < 65535; // MS compilers can't handle strings bigger than 65536 chars..
-
- if (canUseStringLiteral)
- {
- int numEscaped = 0;
-
- for (size_t i = 0; i < mb.getSize(); ++i)
- {
- const unsigned int num = (unsigned int) data[i];
- if (! ((num >= 32 && num < 127) || num == '\t' || num == '\r' || num == '\n'))
- {
- if (++numEscaped > mb.getSize() / 4)
- {
- canUseStringLiteral = false;
- break;
- }
- }
- }
- }
-
- if (! canUseStringLiteral)
- {
- out << "{ ";
-
- for (size_t i = 0; i < mb.getSize(); ++i)
- {
- const int num = (int) (unsigned int) data[i];
- out << num << ',';
-
- charsOnLine += 2;
- if (num >= 10)
- ++charsOnLine;
- if (num >= 100)
- ++charsOnLine;
-
- if (charsOnLine >= maxCharsOnLine)
- {
- charsOnLine = 0;
- out << newLine;
- }
- }
-
- out << "0,0 };";
- }
- else
- {
- out << "\"";
-
- for (size_t i = 0; i < mb.getSize(); ++i)
- {
- const unsigned int num = (unsigned int) data[i];
-
- switch (num)
- {
- case '\t': out << "\\t"; break;
- case '\r': out << "\\r"; break;
- case '\n': out << "\\n"; charsOnLine = maxCharsOnLine; break;
- case '"': out << "\\\""; break;
- case '\\': out << "\\\\"; break;
- default:
- if (num >= 32 && num < 127)
- out << (char) num;
- else if (num <= 0x0f)
- out << "\\x0" << String::toHexString ((int) num);
- else
- out << "\\x" << String::toHexString ((int) num);
- break;
- }
-
- if (++charsOnLine >= maxCharsOnLine && i < mb.getSize() - 1)
- {
- charsOnLine = 0;
- out << "\"" << newLine << "\"";
- }
- }
-
- out << "\";";
- }
- }
-}
-
-//==============================================================================
-int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex)
-{
- startIndex = jmax (0, startIndex);
-
- while (startIndex < lines.size())
- {
- if (lines[startIndex].trimStart().startsWithIgnoreCase (text))
- return startIndex;
-
- ++startIndex;
- }
-
- return -1;
-}
-
-
-//==============================================================================
-PropertyPanelWithTooltips::PropertyPanelWithTooltips()
- : lastComp (0)
-{
- addAndMakeVisible (panel = new PropertyPanel());
- startTimer (150);
-}
-
-PropertyPanelWithTooltips::~PropertyPanelWithTooltips()
-{
- deleteAllChildren();
-}
-
-void PropertyPanelWithTooltips::paint (Graphics& g)
-{
- g.setColour (Colour::greyLevel (0.15f));
- g.setFont (13.0f);
-
- TextLayout tl;
- tl.appendText (lastTip, Font (14.0f));
- tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice
- if (tl.getNumLines() > 3)
- tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in..
-
- tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10,
- getHeight() - panel->getBottom() - 4,
- Justification::centredLeft);
-}
-
-void PropertyPanelWithTooltips::resized()
-{
- panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f)));
-}
-
-void PropertyPanelWithTooltips::timerCallback()
-{
- Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse();
-
- if (newComp != lastComp)
- {
- lastComp = newComp;
-
- String newTip (findTip (newComp));
-
- if (newTip != lastTip)
- {
- lastTip = newTip;
- repaint (0, panel->getBottom(), getWidth(), getHeight());
- }
- }
-}
-
-const String PropertyPanelWithTooltips::findTip (Component* c)
-{
- while (c != 0 && c != this)
- {
- TooltipClient* const tc = dynamic_cast (c);
- if (tc != 0)
- {
- const String tip (tc->getTooltip());
-
- if (tip.isNotEmpty())
- return tip;
- }
-
- c = c->getParentComponent();
- }
-
- return String::empty;
-}
-
-//==============================================================================
-FloatingLabelComponent::FloatingLabelComponent()
- : font (10.0f)
-{
- setInterceptsMouseClicks (false ,false);
-}
-
-void FloatingLabelComponent::remove()
-{
- if (getParentComponent() != 0)
- getParentComponent()->removeChildComponent (this);
-}
-
-void FloatingLabelComponent::update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below)
-{
- colour = textColour;
-
- Rectangle r;
-
- if (text != getName())
- {
- setName (text);
- glyphs.clear();
- glyphs.addJustifiedText (font, text, 0, 0, 200.0f, Justification::left);
- glyphs.justifyGlyphs (0, std::numeric_limits::max(), 0, 0, 1000, 1000, Justification::topLeft);
-
- r = glyphs.getBoundingBox (0, std::numeric_limits::max(), false)
- .getSmallestIntegerContainer().expanded (2, 2);
- }
- else
- {
- r = getLocalBounds();
- }
-
- r.setPosition (x + (toRight ? 3 : -(r.getWidth() + 3)), y + (below ? 2 : -(r.getHeight() + 2)));
- setBounds (r);
- parent->addAndMakeVisible (this);
-}
-
-void FloatingLabelComponent::paint (Graphics& g)
-{
- g.setFont (font);
- g.setColour (Colours::white.withAlpha (0.5f));
-
- for (int y = -1; y <= 1; ++y)
- for (int x = -1; x <= 1; ++x)
- glyphs.draw (g, AffineTransform::translation (1.0f + x, 1.0f + y));
-
- g.setColour (colour);
- glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f));
-}
diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h
deleted file mode 100644
index 7d443e2609..0000000000
--- a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- ==============================================================================
-
- 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.
-
- ==============================================================================
-*/
-
-
-//==============================================================================
-namespace FileUtils
-{
- int64 calculateStreamHashCode (InputStream& stream);
- int64 calculateFileHashCode (const File& file);
- bool areFilesIdentical (const File& file1, const File& file2);
-
- bool overwriteFileWithNewDataIfDifferent (const File& file, const char* data, int numBytes);
- bool overwriteFileWithNewDataIfDifferent (const File& file, const MemoryOutputStream& newData);
- bool overwriteFileWithNewDataIfDifferent (const File& file, const String& newData);
-
- bool containsAnyNonHiddenFiles (const File& folder);
-
- const String unixStylePath (const String& path);
- const String windowsStylePath (const String& path);
-
- bool shouldPathsBeRelative (String path1, String path2);
-
- //==============================================================================
- bool isJuceFolder (const File& folder);
- const File findParentJuceFolder (const File& file);
- const File findDefaultJuceFolder();
-}
-
-//==============================================================================
-// String::hashCode64 actually hit some dupes, so this is a more powerful version.
-const int64 hashCode64 (const String& s);
-const String randomHexString (Random& random, int numChars);
-const String hexString8Digits (int value);
-
-const String createAlphaNumericUID();
-const String createGUID (const String& seed); // Turns a seed into a windows GUID
-
-//==============================================================================
-int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex);
-
-void autoScrollForMouseEvent (const MouseEvent& e);
-
-void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text);
-void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize);
-
-//==============================================================================
-class FileModificationDetector
-{
-public:
- FileModificationDetector (const File& file_)
- : file (file_)
- {
- }
-
- const File& getFile() const { return file; }
- void fileHasBeenRenamed (const File& newFile) { file = newFile; }
-
- bool hasBeenModified() const
- {
- return fileModificationTime != file.getLastModificationTime()
- && (fileSize != file.getSize()
- || FileUtils::calculateFileHashCode (file) != fileHashCode);
- }
-
- void updateHash()
- {
- fileModificationTime = file.getLastModificationTime();
- fileSize = file.getSize();
- fileHashCode = FileUtils::calculateFileHashCode (file);
- }
-
-private:
- File file;
- Time fileModificationTime;
- int64 fileHashCode, fileSize;
-};
-
-//==============================================================================
-namespace CodeFormatting
-{
- const String indent (const String& code, const int numSpaces, bool indentFirstLine);
- const String makeValidIdentifier (String s, bool capitalise, bool removeColons, bool allowTemplates);
- const String addEscapeChars (const String& text);
- const String createIncludeStatement (const File& includeFile, const File& targetFile);
- const String makeHeaderGuardName (const File& file);
-
- const String stringLiteral (const String& text);
- const String boolLiteral (bool b);
- const String floatLiteral (float v);
- const String doubleLiteral (double v);
-
- const String colourToCode (const Colour& col);
- const String justificationToCode (const Justification& justification);
- const String castToFloat (const String& expression);
-
- void writeDataAsCppLiteral (const MemoryBlock& data, OutputStream& out);
-}
-
-//==============================================================================
-class PropertyPanelWithTooltips : public Component,
- public Timer
-{
-public:
- PropertyPanelWithTooltips();
- ~PropertyPanelWithTooltips();
-
- PropertyPanel* getPanel() const { return panel; }
-
- void paint (Graphics& g);
- void resized();
- void timerCallback();
-
-private:
- PropertyPanel* panel;
- TextLayout layout;
- Component* lastComp;
- String lastTip;
-
- const String findTip (Component* c);
-};
-
-//==============================================================================
-class FloatingLabelComponent : public Component
-{
-public:
- FloatingLabelComponent();
-
- void remove();
- void update (Component* parent, const String& text, const Colour& textColour, int x, int y, bool toRight, bool below);
- void paint (Graphics& g);
-
-private:
- Font font;
- Colour colour;
- GlyphArrangement glyphs;
-};
-
-//==============================================================================
-static const double tickSizes[] = { 1.0, 2.0, 5.0,
- 10.0, 20.0, 50.0,
- 100.0, 200.0, 500.0, 1000.0 };
-
-class TickIterator
-{
-public:
- TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_,
- int minPixelsPerTick, int minWidthForLabels)
- : startValue (startValue_),
- endValue (endValue_),
- valuePerPixel (valuePerPixel_)
- {
- tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick);
- labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels);
-
- tickPosition = pixelsToValue (-minWidthForLabels);
- tickPosition = snapValueDown (tickPosition, tickLevelIndex);
- }
-
- bool getNextTick (float& pixelX, float& tickLength, String& label)
- {
- const double tickUnits = tickSizes [tickLevelIndex];
- tickPosition += tickUnits;
-
- const int totalLevels = sizeof (tickSizes) / sizeof (*tickSizes);
- int highestIndex = tickLevelIndex;
-
- while (++highestIndex < totalLevels)
- {
- const double ticksAtThisLevel = tickPosition / tickSizes [highestIndex];
-
- if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001)
- break;
- }
-
- --highestIndex;
-
- if (highestIndex >= labelLevelIndex)
- label = getDescriptionOfValue (tickPosition, labelLevelIndex);
- else
- label = String::empty;
-
- tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex);
- pixelX = valueToPixels (tickPosition);
-
- return tickPosition < endValue;
- }
-
-private:
- double tickPosition;
- int tickLevelIndex, labelLevelIndex;
- const double startValue, endValue, valuePerPixel;
-
- int findLevelIndexForValue (const double value) const
- {
- int i;
- for (i = 0; i < (int) (sizeof (tickSizes) / sizeof (*tickSizes)); ++i)
- if (tickSizes [i] >= value)
- break;
-
- return i;
- }
-
- double pixelsToValue (int pixels) const
- {
- return startValue + pixels * valuePerPixel;
- }
-
- float valueToPixels (double value) const
- {
- return (float) ((value - startValue) / valuePerPixel);
- }
-
- static double snapValueToNearest (const double t, const int valueLevelIndex)
- {
- const double unitsPerInterval = tickSizes [valueLevelIndex];
- return unitsPerInterval * floor (t / unitsPerInterval + 0.5);
- }
-
- static double snapValueDown (const double t, const int valueLevelIndex)
- {
- const double unitsPerInterval = tickSizes [valueLevelIndex];
- return unitsPerInterval * floor (t / unitsPerInterval);
- }
-
- static inline int roundDoubleToInt (const double value)
- {
- union { int asInt[2]; double asDouble; } n;
- n.asDouble = value + 6755399441055744.0;
-
- #if TARGET_RT_BIG_ENDIAN
- return n.asInt [1];
- #else
- return n.asInt [0];
- #endif
- }
-
- static const String getDescriptionOfValue (const double value, const int valueLevelIndex)
- {
- return String (roundToInt (value));
- }
-
- TickIterator (const TickIterator&);
- TickIterator& operator= (const TickIterator&);
-};
diff --git a/extras/juce demo/Juce Demo.jucer b/extras/juce demo/Juce Demo.jucer
index 800c840baf..355914ee01 100644
--- a/extras/juce demo/Juce Demo.jucer
+++ b/extras/juce demo/Juce Demo.jucer
@@ -14,9 +14,9 @@
+ rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"/>
+ rtasFolder="c:\SDKs\PT_80_SDK" juceFolder="../../../juce" libraryType="1"/>
diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp
index 31a6f3314c..2a3c0b84fe 100644
--- a/juce_amalgamated.cpp
+++ b/juce_amalgamated.cpp
@@ -3879,6 +3879,62 @@ END_JUCE_NAMESPACE
/*** End of inlined file: juce_PropertySet.cpp ***/
+/*** Start of inlined file: juce_Identifier.cpp ***/
+BEGIN_JUCE_NAMESPACE
+
+class Identifier::Pool : public DeletedAtShutdown
+{
+public:
+ Pool() {}
+ ~Pool() {}
+
+ StringPool pool;
+
+ juce_DeclareSingleton_SingleThreaded_Minimal (Pool);
+};
+
+juce_ImplementSingleton_SingleThreaded (Identifier::Pool);
+
+Identifier::Identifier() throw()
+ : name (0)
+{
+}
+
+Identifier::Identifier (const Identifier& other) throw()
+ : name (other.name)
+{
+}
+
+Identifier& Identifier::operator= (const Identifier& other) throw()
+{
+ name = other.name;
+ return *this;
+}
+
+Identifier::Identifier (const String& name_)
+ : name (Identifier::Pool::getInstance()->pool.getPooledString (name_))
+{
+ /* An Identifier string must be suitable for use as a script variable or XML
+ attribute, so it can only contain this limited set of characters.. */
+ jassert (name_.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name_.isNotEmpty());
+}
+
+Identifier::Identifier (const char* const name_)
+ : name (Identifier::Pool::getInstance()->pool.getPooledString (name_))
+{
+ /* An Identifier string must be suitable for use as a script variable or XML
+ attribute, so it can only contain this limited set of characters.. */
+ jassert (toString().containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && toString().isNotEmpty());
+}
+
+Identifier::~Identifier()
+{
+}
+
+END_JUCE_NAMESPACE
+/*** End of inlined file: juce_Identifier.cpp ***/
+
+
/*** Start of inlined file: juce_Variant.cpp ***/
BEGIN_JUCE_NAMESPACE
@@ -4129,7 +4185,7 @@ const var var::readFromStream (InputStream& input)
return var::null;
}
-const var var::operator[] (const var::identifier& propertyName) const
+const var var::operator[] (const Identifier& propertyName) const
{
if (type == objectType && value.objectValue != 0)
return value.objectValue->getProperty (propertyName);
@@ -4137,7 +4193,7 @@ const var var::operator[] (const var::identifier& propertyName) const
return var::null;
}
-const var var::invoke (const var::identifier& method, const var* arguments, int numArguments) const
+const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const
{
if (type == objectType && value.objectValue != 0)
return value.objectValue->invokeMethod (method, arguments, numArguments);
@@ -4158,67 +4214,40 @@ const var var::invoke (const var& targetObject, const var* arguments, int numArg
return var::null;
}
-const var var::call (const var::identifier& method) const
+const var var::call (const Identifier& method) const
{
return invoke (method, 0, 0);
}
-const var var::call (const var::identifier& method, const var& arg1) const
+const var var::call (const Identifier& method, const var& arg1) const
{
return invoke (method, &arg1, 1);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2) const
+const var var::call (const Identifier& method, const var& arg1, const var& arg2) const
{
var args[] = { arg1, arg2 };
return invoke (method, args, 2);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3)
+const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3)
{
var args[] = { arg1, arg2, arg3 };
return invoke (method, args, 3);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
+const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
{
var args[] = { arg1, arg2, arg3, arg4 };
return invoke (method, args, 4);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
+const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
{
var args[] = { arg1, arg2, arg3, arg4, arg5 };
return invoke (method, args, 5);
}
-var::identifier::identifier() throw()
- : hashCode (0)
-{
-}
-
-var::identifier::identifier (const String& name_)
- : name (name_),
- hashCode (name_.hashCode())
-{
- /* An identifier string must be suitable for use as a script variable or XML
- attribute, so it can only contain this limited set of characters.. */
- jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty());
-}
-
-var::identifier::identifier (const char* const name_)
- : name (name_),
- hashCode (name.hashCode())
-{
- /* An identifier string must be suitable for use as a script variable or XML
- attribute, so it can only contain this limited set of characters.. */
- jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty());
-}
-
-var::identifier::~identifier()
-{
-}
-
END_JUCE_NAMESPACE
/*** End of inlined file: juce_Variant.cpp ***/
@@ -4230,7 +4259,7 @@ NamedValueSet::NamedValue::NamedValue() throw()
{
}
-inline NamedValueSet::NamedValue::NamedValue (const var::identifier& name_, const var& value_)
+inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var& value_)
: name (name_), value (value_)
{
}
@@ -4259,7 +4288,7 @@ int NamedValueSet::size() const throw()
return values.size();
}
-const var& NamedValueSet::operator[] (const var::identifier& name) const
+const var& NamedValueSet::operator[] (const Identifier& name) const
{
for (int i = values.size(); --i >= 0;)
{
@@ -4272,13 +4301,13 @@ const var& NamedValueSet::operator[] (const var::identifier& name) const
return var::null;
}
-const var NamedValueSet::getWithDefault (const var::identifier& name, const var& defaultReturnValue) const
+const var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const
{
const var* v = getItem (name);
return v != 0 ? *v : defaultReturnValue;
}
-var* NamedValueSet::getItem (const var::identifier& name) const
+var* NamedValueSet::getItem (const Identifier& name) const
{
for (int i = values.size(); --i >= 0;)
{
@@ -4291,7 +4320,7 @@ var* NamedValueSet::getItem (const var::identifier& name) const
return 0;
}
-bool NamedValueSet::set (const var::identifier& name, const var& newValue)
+bool NamedValueSet::set (const Identifier& name, const var& newValue)
{
for (int i = values.size(); --i >= 0;)
{
@@ -4311,12 +4340,12 @@ bool NamedValueSet::set (const var::identifier& name, const var& newValue)
return true;
}
-bool NamedValueSet::contains (const var::identifier& name) const
+bool NamedValueSet::contains (const Identifier& name) const
{
return getItem (name) != 0;
}
-bool NamedValueSet::remove (const var::identifier& name)
+bool NamedValueSet::remove (const Identifier& name)
{
for (int i = values.size(); --i >= 0;)
{
@@ -4330,7 +4359,7 @@ bool NamedValueSet::remove (const var::identifier& name)
return false;
}
-const var::identifier NamedValueSet::getName (const int index) const
+const Identifier NamedValueSet::getName (const int index) const
{
jassert (((unsigned int) index) < (unsigned int) values.size());
return values [index].name;
@@ -4362,40 +4391,40 @@ DynamicObject::~DynamicObject()
{
}
-bool DynamicObject::hasProperty (const var::identifier& propertyName) const
+bool DynamicObject::hasProperty (const Identifier& propertyName) const
{
var* const v = properties.getItem (propertyName);
return v != 0 && ! v->isMethod();
}
-const var DynamicObject::getProperty (const var::identifier& propertyName) const
+const var DynamicObject::getProperty (const Identifier& propertyName) const
{
return properties [propertyName];
}
-void DynamicObject::setProperty (const var::identifier& propertyName, const var& newValue)
+void DynamicObject::setProperty (const Identifier& propertyName, const var& newValue)
{
properties.set (propertyName, newValue);
}
-void DynamicObject::removeProperty (const var::identifier& propertyName)
+void DynamicObject::removeProperty (const Identifier& propertyName)
{
properties.remove (propertyName);
}
-bool DynamicObject::hasMethod (const var::identifier& methodName) const
+bool DynamicObject::hasMethod (const Identifier& methodName) const
{
return getProperty (methodName).isMethod();
}
-const var DynamicObject::invokeMethod (const var::identifier& methodName,
+const var DynamicObject::invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters)
{
return properties [methodName].invoke (var (this), parameters, numParameters);
}
-void DynamicObject::setMethod (const var::identifier& name,
+void DynamicObject::setMethod (const Identifier& name,
var::MethodFunction methodFunction)
{
properties.set (name, var (methodFunction));
@@ -6673,6 +6702,39 @@ bool File::replaceWithText (const String& textToWrite,
return tempFile.overwriteTargetFileWithTemporary();
}
+bool File::hasIdenticalContentTo (const File& other) const
+{
+ if (other == *this)
+ return true;
+
+ if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile())
+ {
+ FileInputStream in1 (*this), in2 (other);
+
+ const int bufferSize = 4096;
+ HeapBlock buffer1, buffer2;
+ buffer1.malloc (bufferSize);
+ buffer2.malloc (bufferSize);
+
+ for (;;)
+ {
+ const int num1 = in1.read (buffer1, bufferSize);
+ const int num2 = in2.read (buffer2, bufferSize);
+
+ if (num1 != num2)
+ break;
+
+ if (num1 <= 0)
+ return true;
+
+ if (memcmp (buffer1, buffer2, num1) != 0)
+ break;
+ }
+ }
+
+ return false;
+}
+
const String File::createLegalPathName (const String& original)
{
String s (original);
@@ -10079,12 +10141,17 @@ bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) throw()
int CharacterFunctions::getHexDigitValue (const juce_wchar digit) throw()
{
- if (digit >= '0' && digit <= '9')
- return digit - '0';
- else if (digit >= 'a' && digit <= 'f')
- return digit - ('a' - 10);
- else if (digit >= 'A' && digit <= 'F')
- return digit - ('A' - 10);
+ unsigned int d = digit - '0';
+ if (d < (unsigned int) 10)
+ return (int) d;
+
+ d += '0' - 'a';
+ if (d < (unsigned int) 6)
+ return (int) d + 10;
+
+ d += 'a' - 'A';
+ if (d < (unsigned int) 6)
+ return (int) d + 10;
return -1;
}
@@ -12955,6 +13022,84 @@ END_JUCE_NAMESPACE
/*** End of inlined file: juce_StringPairArray.cpp ***/
+/*** Start of inlined file: juce_StringPool.cpp ***/
+BEGIN_JUCE_NAMESPACE
+
+StringPool::StringPool() throw() {}
+StringPool::~StringPool() {}
+
+template
+static const juce_wchar* getPooledStringFromArray (Array& strings, StringType newString)
+{
+ int start = 0;
+ int end = strings.size();
+
+ for (;;)
+ {
+ if (start >= end)
+ {
+ jassert (start <= end);
+ strings.insert (start, newString);
+ return strings.getReference (start);
+ }
+ else
+ {
+ const String& startString = strings.getReference (start);
+
+ if (startString == newString)
+ return startString;
+
+ const int halfway = (start + end) >> 1;
+
+ if (halfway == start)
+ {
+ if (startString.compare (newString) < 0)
+ ++start;
+
+ strings.insert (start, newString);
+ return strings.getReference (start);
+ }
+
+ const int comp = strings.getReference (halfway).compare (newString);
+
+ if (comp == 0)
+ return strings.getReference (halfway);
+ else if (comp < 0)
+ start = halfway;
+ else
+ end = halfway;
+ }
+ }
+}
+
+const juce_wchar* StringPool::getPooledString (const String& s)
+{
+ if (s.isEmpty())
+ return String::empty;
+
+ return getPooledStringFromArray (strings, s);
+}
+
+const juce_wchar* StringPool::getPooledString (const char* const s)
+{
+ if (s == 0 || *s == 0)
+ return String::empty;
+
+ return getPooledStringFromArray (strings, s);
+}
+
+const juce_wchar* StringPool::getPooledString (const juce_wchar* const s)
+{
+ if (s == 0 || *s == 0)
+ return String::empty;
+
+ return getPooledStringFromArray (strings, s);
+}
+
+END_JUCE_NAMESPACE
+/*** End of inlined file: juce_StringPool.cpp ***/
+
+
/*** Start of inlined file: juce_XmlDocument.cpp ***/
BEGIN_JUCE_NAMESPACE
@@ -15811,7 +15956,7 @@ BEGIN_JUCE_NAMESPACE
class ValueTree::SetPropertyAction : public UndoableAction
{
public:
- SetPropertyAction (const SharedObjectPtr& target_, const var::identifier& name_,
+ SetPropertyAction (const SharedObjectPtr& target_, const Identifier& name_,
const var& newValue_, const var& oldValue_,
const bool isAddingNewProperty_, const bool isDeletingProperty_)
: target (target_), name (name_), newValue (newValue_), oldValue (oldValue_),
@@ -15866,7 +16011,7 @@ public:
private:
const SharedObjectPtr target;
- const var::identifier name;
+ const Identifier name;
const var newValue;
var oldValue;
const bool isAddingNewProperty : 1, isDeletingProperty : 1;
@@ -15979,7 +16124,7 @@ private:
MoveChildAction& operator= (const MoveChildAction&);
};
-ValueTree::SharedObject::SharedObject (const String& type_)
+ValueTree::SharedObject::SharedObject (const Identifier& type_)
: type (type_), parent (0)
{
}
@@ -16008,7 +16153,7 @@ ValueTree::SharedObject::~SharedObject()
}
}
-void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property)
+void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const Identifier& property)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
@@ -16018,7 +16163,7 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const
}
}
-void ValueTree::SharedObject::sendPropertyChangeMessage (const var::identifier& property)
+void ValueTree::SharedObject::sendPropertyChangeMessage (const Identifier& property)
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;
@@ -16072,17 +16217,17 @@ void ValueTree::SharedObject::sendParentChangeMessage()
}
}
-const var& ValueTree::SharedObject::getProperty (const var::identifier& name) const
+const var& ValueTree::SharedObject::getProperty (const Identifier& name) const
{
return properties [name];
}
-const var ValueTree::SharedObject::getProperty (const var::identifier& name, const var& defaultReturnValue) const
+const var ValueTree::SharedObject::getProperty (const Identifier& name, const var& defaultReturnValue) const
{
return properties.getWithDefault (name, defaultReturnValue);
}
-void ValueTree::SharedObject::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager)
+void ValueTree::SharedObject::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager)
{
if (undoManager == 0)
{
@@ -16105,12 +16250,12 @@ void ValueTree::SharedObject::setProperty (const var::identifier& name, const va
}
}
-bool ValueTree::SharedObject::hasProperty (const var::identifier& name) const
+bool ValueTree::SharedObject::hasProperty (const Identifier& name) const
{
return properties.contains (name);
}
-void ValueTree::SharedObject::removeProperty (const var::identifier& name, UndoManager* const undoManager)
+void ValueTree::SharedObject::removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (undoManager == 0)
{
@@ -16130,7 +16275,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage
{
while (properties.size() > 0)
{
- const var::identifier name (properties.getName (properties.size() - 1));
+ const Identifier name (properties.getName (properties.size() - 1));
properties.remove (name);
sendPropertyChangeMessage (name);
}
@@ -16142,7 +16287,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage
}
}
-ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch) const
+ValueTree ValueTree::SharedObject::getChildWithName (const Identifier& typeToMatch) const
{
for (int i = 0; i < children.size(); ++i)
if (children.getUnchecked(i)->type == typeToMatch)
@@ -16151,7 +16296,7 @@ ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch)
return ValueTree::invalid;
}
-ValueTree ValueTree::SharedObject::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const
+ValueTree ValueTree::SharedObject::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
for (int i = 0; i < children.size(); ++i)
if (children.getUnchecked(i)->getProperty (propertyName) == propertyValue)
@@ -16277,10 +16422,10 @@ ValueTree::ValueTree() throw()
const ValueTree ValueTree::invalid;
-ValueTree::ValueTree (const String& type_)
+ValueTree::ValueTree (const Identifier& type_)
: object (new ValueTree::SharedObject (type_))
{
- jassert (type_.isNotEmpty()); // All objects should be given a sensible type name!
+ jassert (type_.toString().isNotEmpty()); // All objects should be given a sensible type name!
}
ValueTree::ValueTree (SharedObject* const object_)
@@ -16330,14 +16475,14 @@ ValueTree ValueTree::createCopy() const
return ValueTree (object != 0 ? new SharedObject (*object) : 0);
}
-bool ValueTree::hasType (const String& typeName) const
+bool ValueTree::hasType (const Identifier& typeName) const
{
return object != 0 && object->type == typeName;
}
const String ValueTree::getType() const
{
- return object != 0 ? object->type : String::empty;
+ return object != 0 ? object->type.toString() : String::empty;
}
ValueTree ValueTree::getParent() const
@@ -16345,35 +16490,35 @@ ValueTree ValueTree::getParent() const
return ValueTree (object != 0 ? object->parent : (SharedObject*) 0);
}
-const var& ValueTree::operator[] (const var::identifier& name) const
+const var& ValueTree::operator[] (const Identifier& name) const
{
return object == 0 ? var::null : object->getProperty (name);
}
-const var& ValueTree::getProperty (const var::identifier& name) const
+const var& ValueTree::getProperty (const Identifier& name) const
{
return object == 0 ? var::null : object->getProperty (name);
}
-const var ValueTree::getProperty (const var::identifier& name, const var& defaultReturnValue) const
+const var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const
{
return object == 0 ? defaultReturnValue : object->getProperty (name, defaultReturnValue);
}
-void ValueTree::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager)
+void ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager)
{
- jassert (name.name.isNotEmpty());
+ jassert (name.toString().isNotEmpty());
- if (object != 0 && name.name.isNotEmpty())
+ if (object != 0 && name.toString().isNotEmpty())
object->setProperty (name, newValue, undoManager);
}
-bool ValueTree::hasProperty (const var::identifier& name) const
+bool ValueTree::hasProperty (const Identifier& name) const
{
return object != 0 && object->hasProperty (name);
}
-void ValueTree::removeProperty (const var::identifier& name, UndoManager* const undoManager)
+void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (object != 0)
object->removeProperty (name, undoManager);
@@ -16390,9 +16535,9 @@ int ValueTree::getNumProperties() const
return object == 0 ? 0 : object->properties.size();
}
-const var::identifier ValueTree::getPropertyName (const int index) const
+const Identifier ValueTree::getPropertyName (const int index) const
{
- return object == 0 ? var::identifier()
+ return object == 0 ? Identifier()
: object->properties.getName (index);
}
@@ -16401,7 +16546,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource,
{
public:
ValueTreePropertyValueSource (const ValueTree& tree_,
- const var::identifier& property_,
+ const Identifier& property_,
UndoManager* const undoManager_)
: tree (tree_),
property (property_),
@@ -16425,7 +16570,7 @@ public:
tree.setProperty (property, newValue, undoManager);
}
- void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& changedProperty)
+ void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& changedProperty)
{
if (tree == treeWhosePropertyHasChanged && property == changedProperty)
sendChangeMessage (false);
@@ -16436,13 +16581,13 @@ public:
private:
ValueTree tree;
- const var::identifier property;
+ const Identifier property;
UndoManager* const undoManager;
ValueTreePropertyValueSource& operator= (const ValueTreePropertyValueSource&);
};
-Value ValueTree::getPropertyAsValue (const var::identifier& name, UndoManager* const undoManager) const
+Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager) const
{
return Value (new ValueTreePropertyValueSource (*this, name, undoManager));
}
@@ -16457,12 +16602,12 @@ ValueTree ValueTree::getChild (int index) const
return ValueTree (object != 0 ? (SharedObject*) object->children [index] : (SharedObject*) 0);
}
-ValueTree ValueTree::getChildWithName (const String& type) const
+ValueTree ValueTree::getChildWithName (const Identifier& type) const
{
return object != 0 ? object->getChildWithName (type) : ValueTree::invalid;
}
-ValueTree ValueTree::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const
+ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
return object != 0 ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree::invalid;
}
@@ -16528,17 +16673,17 @@ void ValueTree::removeListener (Listener* listener)
XmlElement* ValueTree::SharedObject::createXml() const
{
- XmlElement* xml = new XmlElement (type);
+ XmlElement* xml = new XmlElement (type.toString());
int i;
for (i = 0; i < properties.size(); ++i)
{
- var::identifier name (properties.getName(i));
+ Identifier name (properties.getName(i));
const var& v = properties [name];
jassert (! v.isObject()); // DynamicObjects can't be stored as XML!
- xml->setAttribute (name.name, v.toString());
+ xml->setAttribute (name.toString(), v.toString());
}
for (i = 0; i < children.size(); ++i)
@@ -16579,8 +16724,8 @@ void ValueTree::writeToStream (OutputStream& output)
int i;
for (i = 0; i < numProps; ++i)
{
- const var::identifier name (getPropertyName(i));
- output.writeString (name.name);
+ const Identifier name (getPropertyName(i));
+ output.writeString (name.toString());
getProperty(name).writeToStream (output);
}
@@ -39985,7 +40130,7 @@ void Component::sendLookAndFeelChange()
}
}
-static const var::identifier getColourPropertyId (const int colourId)
+static const Identifier getColourPropertyId (const int colourId)
{
String s;
s.preallocateStorage (18);
@@ -40029,9 +40174,9 @@ void Component::copyAllExplicitColoursTo (Component& target) const
for (int i = properties.size(); --i >= 0;)
{
- const var::identifier name (properties.getName(i));
+ const Identifier name (properties.getName(i));
- if (name.name.startsWith ("jcclr_"))
+ if (name.toString().startsWith ("jcclr_"))
if (target.properties.set (name, properties [name]))
changed = true;
}
@@ -50357,7 +50502,7 @@ public:
{
jassert (row >= 0);
- const var::identifier tagPropertyName ("_tableLastUseNum");
+ const Identifier tagPropertyName ("_tableLastUseNum");
const int newTag = Random::getSystemRandom().nextInt();
const TableHeaderComponent* const header = owner.getHeader();
diff --git a/juce_amalgamated.h b/juce_amalgamated.h
index 0f961e5bef..a8c5c3f0ec 100644
--- a/juce_amalgamated.h
+++ b/juce_amalgamated.h
@@ -1620,7 +1620,6 @@ public:
/** Destructor. */
~String() throw();
- //========================juce_wchar======================================================
/** This is an empty string that can be used whenever one is needed.
It's better to use this than String() because it explains what's going on
@@ -4684,6 +4683,65 @@ typedef BigInteger BitArray;
#define __JUCE_VARIANT_JUCEHEADER__
+/*** Start of inlined file: juce_Identifier.h ***/
+#ifndef __JUCE_IDENTIFIER_JUCEHEADER__
+#define __JUCE_IDENTIFIER_JUCEHEADER__
+
+/**
+ Represents a string identifier, designed for accessing properties by name.
+
+ Identifier objects are very light and fast to copy, but slower to initialise
+ from a string, so it's much faster to keep a static identifier object to refer
+ to frequently-used names, rather than constructing them each time you need it.
+
+ @see NamedPropertySet, ValueTree
+*/
+class JUCE_API Identifier
+{
+public:
+ /** Creates a null identifier. */
+ Identifier() throw();
+
+ /** Creates an identifier with a specified name.
+ Because this name may need to be used in contexts such as script variables or XML
+ tags, it must only contain ascii letters and digits, or the underscore character.
+ */
+ Identifier (const char* name);
+
+ /** Creates an identifier with a specified name.
+ Because this name may need to be used in contexts such as script variables or XML
+ tags, it must only contain ascii letters and digits, or the underscore character.
+ */
+ Identifier (const String& name);
+
+ /** Creates a copy of another identifier. */
+ Identifier (const Identifier& other) throw();
+
+ /** Creates a copy of another identifier. */
+ Identifier& operator= (const Identifier& other) throw();
+
+ /** Destructor */
+ ~Identifier();
+
+ /** Compares two identifiers. This is a very fast operation. */
+ inline bool operator== (const Identifier& other) const throw() { return name == other.name; }
+
+ /** Compares two identifiers. This is a very fast operation. */
+ inline bool operator!= (const Identifier& other) const throw() { return name != other.name; }
+
+ const String toString() const { return name; }
+
+private:
+
+ const juce_wchar* name;
+
+ class Pool;
+};
+
+#endif // __JUCE_IDENTIFIER_JUCEHEADER__
+/*** End of inlined file: juce_Identifier.h ***/
+
+
/*** Start of inlined file: juce_OutputStream.h ***/
#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__
#define __JUCE_OUTPUTSTREAM_JUCEHEADER__
@@ -5356,6 +5414,7 @@ class JUCE_API var
public:
typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);
+ typedef Identifier identifier;
/** Creates a void variant. */
var() throw();
@@ -5415,55 +5474,24 @@ public:
*/
static const var readFromStream (InputStream& input);
- class JUCE_API identifier
- {
- public:
- /** Creates a null identifier. */
- identifier() throw();
-
- /** Creates an identifier with a specified name.
- Because this name may need to be used in contexts such as script variables or XML
- tags, it must only contain ascii letters and digits, or the underscore character.
- */
- identifier (const char* name);
-
- /** Creates an identifier with a specified name.
- Because this name may need to be used in contexts such as script variables or XML
- tags, it must only contain ascii letters and digits, or the underscore character.
- */
- identifier (const String& name);
-
- /** Destructor */
- ~identifier();
-
- bool operator== (const identifier& other) const throw()
- {
- jassert (hashCode != other.hashCode || name == other.name); // check for name hash collisions
- return hashCode == other.hashCode;
- }
-
- String name;
- int hashCode;
- };
-
/** If this variant is an object, this returns one of its properties. */
- const var operator[] (const identifier& propertyName) const;
+ const var operator[] (const Identifier& propertyName) const;
/** If this variant is an object, this invokes one of its methods with no arguments. */
- const var call (const identifier& method) const;
+ const var call (const Identifier& method) const;
/** If this variant is an object, this invokes one of its methods with one argument. */
- const var call (const identifier& method, const var& arg1) const;
+ const var call (const Identifier& method, const var& arg1) const;
/** If this variant is an object, this invokes one of its methods with 2 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2) const;
+ const var call (const Identifier& method, const var& arg1, const var& arg2) const;
/** If this variant is an object, this invokes one of its methods with 3 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3);
+ const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3);
/** If this variant is an object, this invokes one of its methods with 4 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
+ const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
/** If this variant is an object, this invokes one of its methods with 5 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
+ const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
/** If this variant is an object, this invokes one of its methods with a list of arguments. */
- const var invoke (const identifier& method, const var* arguments, int numArguments) const;
+ const var invoke (const Identifier& method, const var* arguments, int numArguments) const;
/** If this variant is a method pointer, this invokes it on a target object. */
const var invoke (const var& targetObject, const var* arguments, int numArguments) const;
@@ -5534,37 +5562,37 @@ public:
If the name isn't found, this will return a void variant.
@see getProperty
*/
- const var& operator[] (const var::identifier& name) const;
+ const var& operator[] (const Identifier& name) const;
/** Tries to return the named value, but if no such value is found, this will
instead return the supplied default value.
*/
- const var getWithDefault (const var::identifier& name, const var& defaultReturnValue) const;
+ const var getWithDefault (const Identifier& name, const var& defaultReturnValue) const;
/** Returns a pointer to the object holding a named value, or
null if there is no value with this name. */
- var* getItem (const var::identifier& name) const;
+ var* getItem (const Identifier& name) const;
/** Changes or adds a named value.
@returns true if a value was changed or added; false if the
value was already set the the value passed-in.
*/
- bool set (const var::identifier& name, const var& newValue);
+ bool set (const Identifier& name, const var& newValue);
/** Returns true if the set contains an item with the specified name. */
- bool contains (const var::identifier& name) const;
+ bool contains (const Identifier& name) const;
/** Removes a value from the set.
@returns true if a value was removed; false if there was no value
with the name that was given.
*/
- bool remove (const var::identifier& name);
+ bool remove (const Identifier& name);
/** Returns the name of the value at a given index.
The index must be between 0 and size() - 1. Out-of-range indexes will
return an empty identifier.
*/
- const var::identifier getName (int index) const;
+ const Identifier getName (int index) const;
/** Returns the value of the item at a given index.
The index must be between 0 and size() - 1. Out-of-range indexes will
@@ -5581,9 +5609,9 @@ private:
struct NamedValue
{
NamedValue() throw();
- NamedValue (const var::identifier& name, const var& value);
+ NamedValue (const Identifier& name, const var& value);
- var::identifier name;
+ Identifier name;
var value;
};
@@ -6153,19 +6181,19 @@ public:
/** Returns true if the object has a property with this name.
Note that if the property is actually a method, this will return false.
*/
- virtual bool hasProperty (const var::identifier& propertyName) const;
+ virtual bool hasProperty (const Identifier& propertyName) const;
/** Returns a named property.
This returns a void if no such property exists.
*/
- virtual const var getProperty (const var::identifier& propertyName) const;
+ virtual const var getProperty (const Identifier& propertyName) const;
/** Sets a named property. */
- virtual void setProperty (const var::identifier& propertyName, const var& newValue);
+ virtual void setProperty (const Identifier& propertyName, const var& newValue);
/** Removes a named property. */
- virtual void removeProperty (const var::identifier& propertyName);
+ virtual void removeProperty (const Identifier& propertyName);
/** Checks whether this object has the specified method.
@@ -6173,7 +6201,7 @@ public:
with this name that's actually a method, but this can be overridden for
building objects with dynamic invocation.
*/
- virtual bool hasMethod (const var::identifier& methodName) const;
+ virtual bool hasMethod (const Identifier& methodName) const;
/** Invokes a named method on this object.
@@ -6183,7 +6211,7 @@ public:
This method is virtual to allow more dynamic invocation to used for objects
where the methods may not already be set as properies.
*/
- virtual const var invokeMethod (const var::identifier& methodName,
+ virtual const var invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters);
@@ -6198,7 +6226,7 @@ public:
setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething);
@endcode
*/
- void setMethod (const var::identifier& methodName,
+ void setMethod (const Identifier& methodName,
var::MethodFunction methodFunction);
/** Removes all properties and methods from the object. */
@@ -6220,6 +6248,9 @@ private:
#endif
#ifndef __JUCE_HEAPBLOCK_JUCEHEADER__
+#endif
+#ifndef __JUCE_IDENTIFIER_JUCEHEADER__
+
#endif
#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__
@@ -8676,6 +8707,11 @@ public:
bool asUnicode = false,
bool writeUnicodeHeaderBytes = false) const;
+ /** Attempts to scan the contents of this file and compare it to another file, returning
+ true if this is possible and they match byte-for-byte.
+ */
+ bool hasIdenticalContentTo (const File& other) const;
+
/** Creates a set of files to represent each file root.
e.g. on Windows this will create files for "c:\", "d:\" etc according
@@ -12875,7 +12911,7 @@ public:
Like an XmlElement, each ValueTree node has a type, which you can access with
getType() and hasType().
*/
- explicit ValueTree (const String& type);
+ explicit ValueTree (const Identifier& type);
/** Creates a reference to another ValueTree. */
ValueTree (const ValueTree& other);
@@ -12916,44 +12952,44 @@ public:
/** Returns true if the node has this type.
The comparison is case-sensitive.
*/
- bool hasType (const String& typeName) const;
+ bool hasType (const Identifier& typeName) const;
/** Returns the value of a named property.
If no such property has been set, this will return a void variant.
You can also use operator[] to get a property.
@see var, setProperty, hasProperty
*/
- const var& getProperty (const var::identifier& name) const;
+ const var& getProperty (const Identifier& name) const;
/** Returns the value of a named property, or a user-specified default if the property doesn't exist.
If no such property has been set, this will return the value of defaultReturnValue.
You can also use operator[] and getProperty to get a property.
@see var, getProperty, setProperty, hasProperty
*/
- const var getProperty (const var::identifier& name, const var& defaultReturnValue) const;
+ const var getProperty (const Identifier& name, const var& defaultReturnValue) const;
/** Returns the value of a named property.
If no such property has been set, this will return a void variant. This is the same as
calling getProperty().
@see getProperty
*/
- const var& operator[] (const var::identifier& name) const;
+ const var& operator[] (const Identifier& name) const;
/** Changes a named property of the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
so that this change can be undone.
@see var, getProperty, removeProperty
*/
- void setProperty (const var::identifier& name, const var& newValue, UndoManager* undoManager);
+ void setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager);
/** Returns true if the node contains a named property. */
- bool hasProperty (const var::identifier& name) const;
+ bool hasProperty (const Identifier& name) const;
/** Removes a property from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
so that this change can be undone.
*/
- void removeProperty (const var::identifier& name, UndoManager* undoManager);
+ void removeProperty (const Identifier& name, UndoManager* undoManager);
/** Removes all properties from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
@@ -12969,7 +13005,7 @@ public:
/** Returns the identifier of the property with a given index.
@see getNumProperties
*/
- const var::identifier getPropertyName (int index) const;
+ const Identifier getPropertyName (int index) const;
/** Returns a Value object that can be used to control and respond to one of the tree's properties.
@@ -12977,7 +13013,7 @@ public:
it needs to change the value. Attaching a Value::Listener to the value object will provide
callbacks whenever the property changes.
*/
- Value getPropertyAsValue (const var::identifier& name, UndoManager* undoManager) const;
+ Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager) const;
/** Returns the number of child nodes belonging to this one.
@see getChild
@@ -12994,7 +13030,7 @@ public:
If no such node is found, it'll return an invalid node. (See isValid() to find out
whether a node is valid).
*/
- ValueTree getChildWithName (const String& type) const;
+ ValueTree getChildWithName (const Identifier& type) const;
/** Looks for the first child node that has the speficied property value.
@@ -13004,7 +13040,7 @@ public:
If no such node is found, it'll return an invalid node. (See isValid() to find out
whether a node is valid).
*/
- ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const;
+ ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
/** Adds a child to this node.
@@ -13121,7 +13157,7 @@ public:
simply check the tree parameter in this callback to make sure it's the tree you're interested in.
*/
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
- const var::identifier& property) = 0;
+ const Identifier& property) = 0;
/** This method is called when a child sub-tree is added or removed.
@@ -13214,31 +13250,31 @@ private:
class JUCE_API SharedObject : public ReferenceCountedObject
{
public:
- explicit SharedObject (const String& type);
+ explicit SharedObject (const Identifier& type);
SharedObject (const SharedObject& other);
~SharedObject();
- const String type;
+ const Identifier type;
NamedValueSet properties;
ReferenceCountedArray children;
SortedSet valueTreesWithListeners;
SharedObject* parent;
- void sendPropertyChangeMessage (const var::identifier& property);
- void sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property);
+ void sendPropertyChangeMessage (const Identifier& property);
+ void sendPropertyChangeMessage (ValueTree& tree, const Identifier& property);
void sendChildChangeMessage();
void sendChildChangeMessage (ValueTree& tree);
void sendParentChangeMessage();
- const var& getProperty (const var::identifier& name) const;
- const var getProperty (const var::identifier& name, const var& defaultReturnValue) const;
- void setProperty (const var::identifier& name, const var& newValue, UndoManager*);
- bool hasProperty (const var::identifier& name) const;
- void removeProperty (const var::identifier& name, UndoManager*);
+ const var& getProperty (const Identifier& name) const;
+ const var getProperty (const Identifier& name, const var& defaultReturnValue) const;
+ void setProperty (const Identifier& name, const var& newValue, UndoManager*);
+ bool hasProperty (const Identifier& name) const;
+ void removeProperty (const Identifier& name, UndoManager*);
void removeAllProperties (UndoManager*);
bool isAChildOf (const SharedObject* possibleParent) const;
int indexOf (const ValueTree& child) const;
- ValueTree getChildWithName (const String& type) const;
- ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const;
+ ValueTree getChildWithName (const Identifier& type) const;
+ ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
void addChild (SharedObject* child, int index, UndoManager*);
void removeChild (int childIndex, UndoManager*);
void removeAllChildren (UndoManager*);
@@ -16743,6 +16779,64 @@ private:
#endif
#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__
+#endif
+#ifndef __JUCE_STRINGPOOL_JUCEHEADER__
+
+/*** Start of inlined file: juce_StringPool.h ***/
+#ifndef __JUCE_STRINGPOOL_JUCEHEADER__
+#define __JUCE_STRINGPOOL_JUCEHEADER__
+
+/**
+ A StringPool holds a set of shared strings, which reduces storage overheads and improves
+ comparison speed when dealing with many duplicate strings.
+
+ When you add a string to a pool using getPooledString, it'll return a character
+ array containing the same string. This array is owned by the pool, and the same array
+ is returned every time a matching string is asked for. This means that it's trivial to
+ compare two pooled strings for equality, as you can simply compare their pointers. It
+ also cuts down on storage if you're using many copies of the same string.
+*/
+class JUCE_API StringPool
+{
+public:
+ /** Creates an empty pool. */
+ StringPool() throw();
+
+ /** Destructor */
+ ~StringPool();
+
+ /** Returns a pointer to a copy of the string that is passed in.
+
+ The pool will always return the same pointer when asked for a string that matches it.
+ The pool will own all the pointers that it returns, deleting them when the pool itself
+ is deleted.
+ */
+ const juce_wchar* getPooledString (const String& original);
+
+ /** Returns a pointer to a copy of the string that is passed in.
+
+ The pool will always return the same pointer when asked for a string that matches it.
+ The pool will own all the pointers that it returns, deleting them when the pool itself
+ is deleted.
+ */
+ const juce_wchar* getPooledString (const char* original);
+
+ /** Returns a pointer to a copy of the string that is passed in.
+
+ The pool will always return the same pointer when asked for a string that matches it.
+ The pool will own all the pointers that it returns, deleting them when the pool itself
+ is deleted.
+ */
+ const juce_wchar* getPooledString (const juce_wchar* original);
+
+private:
+ Array strings;
+};
+
+#endif // __JUCE_STRINGPOOL_JUCEHEADER__
+/*** End of inlined file: juce_StringPool.h ***/
+
+
#endif
#ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__
diff --git a/src/containers/juce_DynamicObject.cpp b/src/containers/juce_DynamicObject.cpp
index 38ea1b96c4..497379e559 100644
--- a/src/containers/juce_DynamicObject.cpp
+++ b/src/containers/juce_DynamicObject.cpp
@@ -39,40 +39,40 @@ DynamicObject::~DynamicObject()
{
}
-bool DynamicObject::hasProperty (const var::identifier& propertyName) const
+bool DynamicObject::hasProperty (const Identifier& propertyName) const
{
var* const v = properties.getItem (propertyName);
return v != 0 && ! v->isMethod();
}
-const var DynamicObject::getProperty (const var::identifier& propertyName) const
+const var DynamicObject::getProperty (const Identifier& propertyName) const
{
return properties [propertyName];
}
-void DynamicObject::setProperty (const var::identifier& propertyName, const var& newValue)
+void DynamicObject::setProperty (const Identifier& propertyName, const var& newValue)
{
properties.set (propertyName, newValue);
}
-void DynamicObject::removeProperty (const var::identifier& propertyName)
+void DynamicObject::removeProperty (const Identifier& propertyName)
{
properties.remove (propertyName);
}
-bool DynamicObject::hasMethod (const var::identifier& methodName) const
+bool DynamicObject::hasMethod (const Identifier& methodName) const
{
return getProperty (methodName).isMethod();
}
-const var DynamicObject::invokeMethod (const var::identifier& methodName,
+const var DynamicObject::invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters)
{
return properties [methodName].invoke (var (this), parameters, numParameters);
}
-void DynamicObject::setMethod (const var::identifier& name,
+void DynamicObject::setMethod (const Identifier& name,
var::MethodFunction methodFunction)
{
properties.set (name, var (methodFunction));
diff --git a/src/containers/juce_DynamicObject.h b/src/containers/juce_DynamicObject.h
index 0bfff07029..0a321ee00d 100644
--- a/src/containers/juce_DynamicObject.h
+++ b/src/containers/juce_DynamicObject.h
@@ -54,19 +54,19 @@ public:
/** Returns true if the object has a property with this name.
Note that if the property is actually a method, this will return false.
*/
- virtual bool hasProperty (const var::identifier& propertyName) const;
+ virtual bool hasProperty (const Identifier& propertyName) const;
/** Returns a named property.
This returns a void if no such property exists.
*/
- virtual const var getProperty (const var::identifier& propertyName) const;
+ virtual const var getProperty (const Identifier& propertyName) const;
/** Sets a named property. */
- virtual void setProperty (const var::identifier& propertyName, const var& newValue);
+ virtual void setProperty (const Identifier& propertyName, const var& newValue);
/** Removes a named property. */
- virtual void removeProperty (const var::identifier& propertyName);
+ virtual void removeProperty (const Identifier& propertyName);
//==============================================================================
/** Checks whether this object has the specified method.
@@ -75,7 +75,7 @@ public:
with this name that's actually a method, but this can be overridden for
building objects with dynamic invocation.
*/
- virtual bool hasMethod (const var::identifier& methodName) const;
+ virtual bool hasMethod (const Identifier& methodName) const;
/** Invokes a named method on this object.
@@ -85,7 +85,7 @@ public:
This method is virtual to allow more dynamic invocation to used for objects
where the methods may not already be set as properies.
*/
- virtual const var invokeMethod (const var::identifier& methodName,
+ virtual const var invokeMethod (const Identifier& methodName,
const var* parameters,
int numParameters);
@@ -100,7 +100,7 @@ public:
setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething);
@endcode
*/
- void setMethod (const var::identifier& methodName,
+ void setMethod (const Identifier& methodName,
var::MethodFunction methodFunction);
//==============================================================================
diff --git a/src/containers/juce_Identifier.cpp b/src/containers/juce_Identifier.cpp
new file mode 100644
index 0000000000..0d00961ce6
--- /dev/null
+++ b/src/containers/juce_Identifier.cpp
@@ -0,0 +1,88 @@
+/*
+ ==============================================================================
+
+ 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.
+
+ ==============================================================================
+*/
+
+#include "../core/juce_StandardHeader.h"
+
+BEGIN_JUCE_NAMESPACE
+
+#include "juce_Identifier.h"
+#include "../utilities/juce_DeletedAtShutdown.h"
+#include "../core/juce_Singleton.h"
+#include "../text/juce_StringPool.h"
+
+
+//==============================================================================
+class Identifier::Pool : public DeletedAtShutdown
+{
+public:
+ Pool() {}
+ ~Pool() {}
+
+ StringPool pool;
+
+ juce_DeclareSingleton_SingleThreaded_Minimal (Pool);
+};
+
+juce_ImplementSingleton_SingleThreaded (Identifier::Pool);
+
+
+//==============================================================================
+Identifier::Identifier() throw()
+ : name (0)
+{
+}
+
+Identifier::Identifier (const Identifier& other) throw()
+ : name (other.name)
+{
+}
+
+Identifier& Identifier::operator= (const Identifier& other) throw()
+{
+ name = other.name;
+ return *this;
+}
+
+Identifier::Identifier (const String& name_)
+ : name (Identifier::Pool::getInstance()->pool.getPooledString (name_))
+{
+ /* An Identifier string must be suitable for use as a script variable or XML
+ attribute, so it can only contain this limited set of characters.. */
+ jassert (name_.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name_.isNotEmpty());
+}
+
+Identifier::Identifier (const char* const name_)
+ : name (Identifier::Pool::getInstance()->pool.getPooledString (name_))
+{
+ /* An Identifier string must be suitable for use as a script variable or XML
+ attribute, so it can only contain this limited set of characters.. */
+ jassert (toString().containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && toString().isNotEmpty());
+}
+
+Identifier::~Identifier()
+{
+}
+
+END_JUCE_NAMESPACE
diff --git a/src/containers/juce_Identifier.h b/src/containers/juce_Identifier.h
new file mode 100644
index 0000000000..549a1f31f8
--- /dev/null
+++ b/src/containers/juce_Identifier.h
@@ -0,0 +1,85 @@
+/*
+ ==============================================================================
+
+ 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_IDENTIFIER_JUCEHEADER__
+#define __JUCE_IDENTIFIER_JUCEHEADER__
+
+#include "../text/juce_String.h"
+
+
+//==============================================================================
+/**
+ Represents a string identifier, designed for accessing properties by name.
+
+ Identifier objects are very light and fast to copy, but slower to initialise
+ from a string, so it's much faster to keep a static identifier object to refer
+ to frequently-used names, rather than constructing them each time you need it.
+
+ @see NamedPropertySet, ValueTree
+*/
+class JUCE_API Identifier
+{
+public:
+ /** Creates a null identifier. */
+ Identifier() throw();
+
+ /** Creates an identifier with a specified name.
+ Because this name may need to be used in contexts such as script variables or XML
+ tags, it must only contain ascii letters and digits, or the underscore character.
+ */
+ Identifier (const char* name);
+
+ /** Creates an identifier with a specified name.
+ Because this name may need to be used in contexts such as script variables or XML
+ tags, it must only contain ascii letters and digits, or the underscore character.
+ */
+ Identifier (const String& name);
+
+ /** Creates a copy of another identifier. */
+ Identifier (const Identifier& other) throw();
+
+ /** Creates a copy of another identifier. */
+ Identifier& operator= (const Identifier& other) throw();
+
+ /** Destructor */
+ ~Identifier();
+
+ /** Compares two identifiers. This is a very fast operation. */
+ inline bool operator== (const Identifier& other) const throw() { return name == other.name; }
+
+ /** Compares two identifiers. This is a very fast operation. */
+ inline bool operator!= (const Identifier& other) const throw() { return name != other.name; }
+
+ const String toString() const { return name; }
+
+private:
+ //==============================================================================
+ const juce_wchar* name;
+
+ class Pool;
+};
+
+
+#endif // __JUCE_IDENTIFIER_JUCEHEADER__
diff --git a/src/containers/juce_NamedValueSet.cpp b/src/containers/juce_NamedValueSet.cpp
index 32ba2df022..e6ae1c033e 100644
--- a/src/containers/juce_NamedValueSet.cpp
+++ b/src/containers/juce_NamedValueSet.cpp
@@ -35,7 +35,7 @@ NamedValueSet::NamedValue::NamedValue() throw()
{
}
-inline NamedValueSet::NamedValue::NamedValue (const var::identifier& name_, const var& value_)
+inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var& value_)
: name (name_), value (value_)
{
}
@@ -65,7 +65,7 @@ int NamedValueSet::size() const throw()
return values.size();
}
-const var& NamedValueSet::operator[] (const var::identifier& name) const
+const var& NamedValueSet::operator[] (const Identifier& name) const
{
for (int i = values.size(); --i >= 0;)
{
@@ -78,13 +78,13 @@ const var& NamedValueSet::operator[] (const var::identifier& name) const
return var::null;
}
-const var NamedValueSet::getWithDefault (const var::identifier& name, const var& defaultReturnValue) const
+const var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const
{
const var* v = getItem (name);
return v != 0 ? *v : defaultReturnValue;
}
-var* NamedValueSet::getItem (const var::identifier& name) const
+var* NamedValueSet::getItem (const Identifier& name) const
{
for (int i = values.size(); --i >= 0;)
{
@@ -97,7 +97,7 @@ var* NamedValueSet::getItem (const var::identifier& name) const
return 0;
}
-bool NamedValueSet::set (const var::identifier& name, const var& newValue)
+bool NamedValueSet::set (const Identifier& name, const var& newValue)
{
for (int i = values.size(); --i >= 0;)
{
@@ -117,12 +117,12 @@ bool NamedValueSet::set (const var::identifier& name, const var& newValue)
return true;
}
-bool NamedValueSet::contains (const var::identifier& name) const
+bool NamedValueSet::contains (const Identifier& name) const
{
return getItem (name) != 0;
}
-bool NamedValueSet::remove (const var::identifier& name)
+bool NamedValueSet::remove (const Identifier& name)
{
for (int i = values.size(); --i >= 0;)
{
@@ -136,7 +136,7 @@ bool NamedValueSet::remove (const var::identifier& name)
return false;
}
-const var::identifier NamedValueSet::getName (const int index) const
+const Identifier NamedValueSet::getName (const int index) const
{
jassert (((unsigned int) index) < (unsigned int) values.size());
return values [index].name;
diff --git a/src/containers/juce_NamedValueSet.h b/src/containers/juce_NamedValueSet.h
index a364deecd3..1edf78d4fb 100644
--- a/src/containers/juce_NamedValueSet.h
+++ b/src/containers/juce_NamedValueSet.h
@@ -59,37 +59,37 @@ public:
If the name isn't found, this will return a void variant.
@see getProperty
*/
- const var& operator[] (const var::identifier& name) const;
+ const var& operator[] (const Identifier& name) const;
/** Tries to return the named value, but if no such value is found, this will
instead return the supplied default value.
*/
- const var getWithDefault (const var::identifier& name, const var& defaultReturnValue) const;
+ const var getWithDefault (const Identifier& name, const var& defaultReturnValue) const;
/** Returns a pointer to the object holding a named value, or
null if there is no value with this name. */
- var* getItem (const var::identifier& name) const;
+ var* getItem (const Identifier& name) const;
/** Changes or adds a named value.
@returns true if a value was changed or added; false if the
value was already set the the value passed-in.
*/
- bool set (const var::identifier& name, const var& newValue);
+ bool set (const Identifier& name, const var& newValue);
/** Returns true if the set contains an item with the specified name. */
- bool contains (const var::identifier& name) const;
+ bool contains (const Identifier& name) const;
/** Removes a value from the set.
@returns true if a value was removed; false if there was no value
with the name that was given.
*/
- bool remove (const var::identifier& name);
+ bool remove (const Identifier& name);
/** Returns the name of the value at a given index.
The index must be between 0 and size() - 1. Out-of-range indexes will
return an empty identifier.
*/
- const var::identifier getName (int index) const;
+ const Identifier getName (int index) const;
/** Returns the value of the item at a given index.
The index must be between 0 and size() - 1. Out-of-range indexes will
@@ -107,9 +107,9 @@ private:
struct NamedValue
{
NamedValue() throw();
- NamedValue (const var::identifier& name, const var& value);
+ NamedValue (const Identifier& name, const var& value);
- var::identifier name;
+ Identifier name;
var value;
};
diff --git a/src/containers/juce_ValueTree.cpp b/src/containers/juce_ValueTree.cpp
index a2927866c3..d340a22a3c 100644
--- a/src/containers/juce_ValueTree.cpp
+++ b/src/containers/juce_ValueTree.cpp
@@ -35,7 +35,7 @@ BEGIN_JUCE_NAMESPACE
class ValueTree::SetPropertyAction : public UndoableAction
{
public:
- SetPropertyAction (const SharedObjectPtr& target_, const var::identifier& name_,
+ SetPropertyAction (const SharedObjectPtr& target_, const Identifier& name_,
const var& newValue_, const var& oldValue_,
const bool isAddingNewProperty_, const bool isDeletingProperty_)
: target (target_), name (name_), newValue (newValue_), oldValue (oldValue_),
@@ -90,7 +90,7 @@ public:
private:
const SharedObjectPtr target;
- const var::identifier name;
+ const Identifier name;
const var newValue;
var oldValue;
const bool isAddingNewProperty : 1, isDeletingProperty : 1;
@@ -207,7 +207,7 @@ private:
//==============================================================================
-ValueTree::SharedObject::SharedObject (const String& type_)
+ValueTree::SharedObject::SharedObject (const Identifier& type_)
: type (type_), parent (0)
{
}
@@ -237,7 +237,7 @@ ValueTree::SharedObject::~SharedObject()
}
//==============================================================================
-void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property)
+void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const Identifier& property)
{
for (int i = valueTreesWithListeners.size(); --i >= 0;)
{
@@ -247,7 +247,7 @@ void ValueTree::SharedObject::sendPropertyChangeMessage (ValueTree& tree, const
}
}
-void ValueTree::SharedObject::sendPropertyChangeMessage (const var::identifier& property)
+void ValueTree::SharedObject::sendPropertyChangeMessage (const Identifier& property)
{
ValueTree tree (this);
ValueTree::SharedObject* t = this;
@@ -302,17 +302,17 @@ void ValueTree::SharedObject::sendParentChangeMessage()
}
//==============================================================================
-const var& ValueTree::SharedObject::getProperty (const var::identifier& name) const
+const var& ValueTree::SharedObject::getProperty (const Identifier& name) const
{
return properties [name];
}
-const var ValueTree::SharedObject::getProperty (const var::identifier& name, const var& defaultReturnValue) const
+const var ValueTree::SharedObject::getProperty (const Identifier& name, const var& defaultReturnValue) const
{
return properties.getWithDefault (name, defaultReturnValue);
}
-void ValueTree::SharedObject::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager)
+void ValueTree::SharedObject::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager)
{
if (undoManager == 0)
{
@@ -335,12 +335,12 @@ void ValueTree::SharedObject::setProperty (const var::identifier& name, const va
}
}
-bool ValueTree::SharedObject::hasProperty (const var::identifier& name) const
+bool ValueTree::SharedObject::hasProperty (const Identifier& name) const
{
return properties.contains (name);
}
-void ValueTree::SharedObject::removeProperty (const var::identifier& name, UndoManager* const undoManager)
+void ValueTree::SharedObject::removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (undoManager == 0)
{
@@ -360,7 +360,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage
{
while (properties.size() > 0)
{
- const var::identifier name (properties.getName (properties.size() - 1));
+ const Identifier name (properties.getName (properties.size() - 1));
properties.remove (name);
sendPropertyChangeMessage (name);
}
@@ -372,7 +372,7 @@ void ValueTree::SharedObject::removeAllProperties (UndoManager* const undoManage
}
}
-ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch) const
+ValueTree ValueTree::SharedObject::getChildWithName (const Identifier& typeToMatch) const
{
for (int i = 0; i < children.size(); ++i)
if (children.getUnchecked(i)->type == typeToMatch)
@@ -381,7 +381,7 @@ ValueTree ValueTree::SharedObject::getChildWithName (const String& typeToMatch)
return ValueTree::invalid;
}
-ValueTree ValueTree::SharedObject::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const
+ValueTree ValueTree::SharedObject::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
for (int i = 0; i < children.size(); ++i)
if (children.getUnchecked(i)->getProperty (propertyName) == propertyValue)
@@ -508,10 +508,10 @@ ValueTree::ValueTree() throw()
const ValueTree ValueTree::invalid;
-ValueTree::ValueTree (const String& type_)
+ValueTree::ValueTree (const Identifier& type_)
: object (new ValueTree::SharedObject (type_))
{
- jassert (type_.isNotEmpty()); // All objects should be given a sensible type name!
+ jassert (type_.toString().isNotEmpty()); // All objects should be given a sensible type name!
}
ValueTree::ValueTree (SharedObject* const object_)
@@ -561,14 +561,14 @@ ValueTree ValueTree::createCopy() const
return ValueTree (object != 0 ? new SharedObject (*object) : 0);
}
-bool ValueTree::hasType (const String& typeName) const
+bool ValueTree::hasType (const Identifier& typeName) const
{
return object != 0 && object->type == typeName;
}
const String ValueTree::getType() const
{
- return object != 0 ? object->type : String::empty;
+ return object != 0 ? object->type.toString() : String::empty;
}
ValueTree ValueTree::getParent() const
@@ -576,35 +576,35 @@ ValueTree ValueTree::getParent() const
return ValueTree (object != 0 ? object->parent : (SharedObject*) 0);
}
-const var& ValueTree::operator[] (const var::identifier& name) const
+const var& ValueTree::operator[] (const Identifier& name) const
{
return object == 0 ? var::null : object->getProperty (name);
}
-const var& ValueTree::getProperty (const var::identifier& name) const
+const var& ValueTree::getProperty (const Identifier& name) const
{
return object == 0 ? var::null : object->getProperty (name);
}
-const var ValueTree::getProperty (const var::identifier& name, const var& defaultReturnValue) const
+const var ValueTree::getProperty (const Identifier& name, const var& defaultReturnValue) const
{
return object == 0 ? defaultReturnValue : object->getProperty (name, defaultReturnValue);
}
-void ValueTree::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager)
+void ValueTree::setProperty (const Identifier& name, const var& newValue, UndoManager* const undoManager)
{
- jassert (name.name.isNotEmpty());
+ jassert (name.toString().isNotEmpty());
- if (object != 0 && name.name.isNotEmpty())
+ if (object != 0 && name.toString().isNotEmpty())
object->setProperty (name, newValue, undoManager);
}
-bool ValueTree::hasProperty (const var::identifier& name) const
+bool ValueTree::hasProperty (const Identifier& name) const
{
return object != 0 && object->hasProperty (name);
}
-void ValueTree::removeProperty (const var::identifier& name, UndoManager* const undoManager)
+void ValueTree::removeProperty (const Identifier& name, UndoManager* const undoManager)
{
if (object != 0)
object->removeProperty (name, undoManager);
@@ -621,9 +621,9 @@ int ValueTree::getNumProperties() const
return object == 0 ? 0 : object->properties.size();
}
-const var::identifier ValueTree::getPropertyName (const int index) const
+const Identifier ValueTree::getPropertyName (const int index) const
{
- return object == 0 ? var::identifier()
+ return object == 0 ? Identifier()
: object->properties.getName (index);
}
@@ -633,7 +633,7 @@ class ValueTreePropertyValueSource : public Value::ValueSource,
{
public:
ValueTreePropertyValueSource (const ValueTree& tree_,
- const var::identifier& property_,
+ const Identifier& property_,
UndoManager* const undoManager_)
: tree (tree_),
property (property_),
@@ -657,7 +657,7 @@ public:
tree.setProperty (property, newValue, undoManager);
}
- void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& changedProperty)
+ void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& changedProperty)
{
if (tree == treeWhosePropertyHasChanged && property == changedProperty)
sendChangeMessage (false);
@@ -668,13 +668,13 @@ public:
private:
ValueTree tree;
- const var::identifier property;
+ const Identifier property;
UndoManager* const undoManager;
ValueTreePropertyValueSource& operator= (const ValueTreePropertyValueSource&);
};
-Value ValueTree::getPropertyAsValue (const var::identifier& name, UndoManager* const undoManager) const
+Value ValueTree::getPropertyAsValue (const Identifier& name, UndoManager* const undoManager) const
{
return Value (new ValueTreePropertyValueSource (*this, name, undoManager));
}
@@ -690,12 +690,12 @@ ValueTree ValueTree::getChild (int index) const
return ValueTree (object != 0 ? (SharedObject*) object->children [index] : (SharedObject*) 0);
}
-ValueTree ValueTree::getChildWithName (const String& type) const
+ValueTree ValueTree::getChildWithName (const Identifier& type) const
{
return object != 0 ? object->getChildWithName (type) : ValueTree::invalid;
}
-ValueTree ValueTree::getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const
+ValueTree ValueTree::getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const
{
return object != 0 ? object->getChildWithProperty (propertyName, propertyValue) : ValueTree::invalid;
}
@@ -763,17 +763,17 @@ void ValueTree::removeListener (Listener* listener)
//==============================================================================
XmlElement* ValueTree::SharedObject::createXml() const
{
- XmlElement* xml = new XmlElement (type);
+ XmlElement* xml = new XmlElement (type.toString());
int i;
for (i = 0; i < properties.size(); ++i)
{
- var::identifier name (properties.getName(i));
+ Identifier name (properties.getName(i));
const var& v = properties [name];
jassert (! v.isObject()); // DynamicObjects can't be stored as XML!
- xml->setAttribute (name.name, v.toString());
+ xml->setAttribute (name.toString(), v.toString());
}
for (i = 0; i < children.size(); ++i)
@@ -815,8 +815,8 @@ void ValueTree::writeToStream (OutputStream& output)
int i;
for (i = 0; i < numProps; ++i)
{
- const var::identifier name (getPropertyName(i));
- output.writeString (name.name);
+ const Identifier name (getPropertyName(i));
+ output.writeString (name.toString());
getProperty(name).writeToStream (output);
}
diff --git a/src/containers/juce_ValueTree.h b/src/containers/juce_ValueTree.h
index d591c819ab..27007a20a0 100644
--- a/src/containers/juce_ValueTree.h
+++ b/src/containers/juce_ValueTree.h
@@ -87,7 +87,7 @@ public:
Like an XmlElement, each ValueTree node has a type, which you can access with
getType() and hasType().
*/
- explicit ValueTree (const String& type);
+ explicit ValueTree (const Identifier& type);
/** Creates a reference to another ValueTree. */
ValueTree (const ValueTree& other);
@@ -130,7 +130,7 @@ public:
/** Returns true if the node has this type.
The comparison is case-sensitive.
*/
- bool hasType (const String& typeName) const;
+ bool hasType (const Identifier& typeName) const;
//==============================================================================
/** Returns the value of a named property.
@@ -138,37 +138,37 @@ public:
You can also use operator[] to get a property.
@see var, setProperty, hasProperty
*/
- const var& getProperty (const var::identifier& name) const;
+ const var& getProperty (const Identifier& name) const;
/** Returns the value of a named property, or a user-specified default if the property doesn't exist.
If no such property has been set, this will return the value of defaultReturnValue.
You can also use operator[] and getProperty to get a property.
@see var, getProperty, setProperty, hasProperty
*/
- const var getProperty (const var::identifier& name, const var& defaultReturnValue) const;
+ const var getProperty (const Identifier& name, const var& defaultReturnValue) const;
/** Returns the value of a named property.
If no such property has been set, this will return a void variant. This is the same as
calling getProperty().
@see getProperty
*/
- const var& operator[] (const var::identifier& name) const;
+ const var& operator[] (const Identifier& name) const;
/** Changes a named property of the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
so that this change can be undone.
@see var, getProperty, removeProperty
*/
- void setProperty (const var::identifier& name, const var& newValue, UndoManager* undoManager);
+ void setProperty (const Identifier& name, const var& newValue, UndoManager* undoManager);
/** Returns true if the node contains a named property. */
- bool hasProperty (const var::identifier& name) const;
+ bool hasProperty (const Identifier& name) const;
/** Removes a property from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
so that this change can be undone.
*/
- void removeProperty (const var::identifier& name, UndoManager* undoManager);
+ void removeProperty (const Identifier& name, UndoManager* undoManager);
/** Removes all properties from the node.
If the undoManager parameter is non-null, its UndoManager::perform() method will be used,
@@ -184,7 +184,7 @@ public:
/** Returns the identifier of the property with a given index.
@see getNumProperties
*/
- const var::identifier getPropertyName (int index) const;
+ const Identifier getPropertyName (int index) const;
/** Returns a Value object that can be used to control and respond to one of the tree's properties.
@@ -192,7 +192,7 @@ public:
it needs to change the value. Attaching a Value::Listener to the value object will provide
callbacks whenever the property changes.
*/
- Value getPropertyAsValue (const var::identifier& name, UndoManager* undoManager) const;
+ Value getPropertyAsValue (const Identifier& name, UndoManager* undoManager) const;
//==============================================================================
/** Returns the number of child nodes belonging to this one.
@@ -210,7 +210,7 @@ public:
If no such node is found, it'll return an invalid node. (See isValid() to find out
whether a node is valid).
*/
- ValueTree getChildWithName (const String& type) const;
+ ValueTree getChildWithName (const Identifier& type) const;
/** Looks for the first child node that has the speficied property value.
@@ -220,7 +220,7 @@ public:
If no such node is found, it'll return an invalid node. (See isValid() to find out
whether a node is valid).
*/
- ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const;
+ ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
/** Adds a child to this node.
@@ -340,7 +340,7 @@ public:
simply check the tree parameter in this callback to make sure it's the tree you're interested in.
*/
virtual void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged,
- const var::identifier& property) = 0;
+ const Identifier& property) = 0;
/** This method is called when a child sub-tree is added or removed.
@@ -435,31 +435,31 @@ private:
class JUCE_API SharedObject : public ReferenceCountedObject
{
public:
- explicit SharedObject (const String& type);
+ explicit SharedObject (const Identifier& type);
SharedObject (const SharedObject& other);
~SharedObject();
- const String type;
+ const Identifier type;
NamedValueSet properties;
ReferenceCountedArray children;
SortedSet valueTreesWithListeners;
SharedObject* parent;
- void sendPropertyChangeMessage (const var::identifier& property);
- void sendPropertyChangeMessage (ValueTree& tree, const var::identifier& property);
+ void sendPropertyChangeMessage (const Identifier& property);
+ void sendPropertyChangeMessage (ValueTree& tree, const Identifier& property);
void sendChildChangeMessage();
void sendChildChangeMessage (ValueTree& tree);
void sendParentChangeMessage();
- const var& getProperty (const var::identifier& name) const;
- const var getProperty (const var::identifier& name, const var& defaultReturnValue) const;
- void setProperty (const var::identifier& name, const var& newValue, UndoManager*);
- bool hasProperty (const var::identifier& name) const;
- void removeProperty (const var::identifier& name, UndoManager*);
+ const var& getProperty (const Identifier& name) const;
+ const var getProperty (const Identifier& name, const var& defaultReturnValue) const;
+ void setProperty (const Identifier& name, const var& newValue, UndoManager*);
+ bool hasProperty (const Identifier& name) const;
+ void removeProperty (const Identifier& name, UndoManager*);
void removeAllProperties (UndoManager*);
bool isAChildOf (const SharedObject* possibleParent) const;
int indexOf (const ValueTree& child) const;
- ValueTree getChildWithName (const String& type) const;
- ValueTree getChildWithProperty (const var::identifier& propertyName, const var& propertyValue) const;
+ ValueTree getChildWithName (const Identifier& type) const;
+ ValueTree getChildWithProperty (const Identifier& propertyName, const var& propertyValue) const;
void addChild (SharedObject* child, int index, UndoManager*);
void removeChild (int childIndex, UndoManager*);
void removeAllChildren (UndoManager*);
diff --git a/src/containers/juce_Variant.cpp b/src/containers/juce_Variant.cpp
index ce30252db3..b12258a5d9 100644
--- a/src/containers/juce_Variant.cpp
+++ b/src/containers/juce_Variant.cpp
@@ -30,6 +30,7 @@ BEGIN_JUCE_NAMESPACE
#include "juce_Variant.h"
#include "juce_DynamicObject.h"
+
//==============================================================================
var::var() throw()
: type (voidType)
@@ -283,7 +284,7 @@ const var var::readFromStream (InputStream& input)
return var::null;
}
-const var var::operator[] (const var::identifier& propertyName) const
+const var var::operator[] (const Identifier& propertyName) const
{
if (type == objectType && value.objectValue != 0)
return value.objectValue->getProperty (propertyName);
@@ -291,7 +292,7 @@ const var var::operator[] (const var::identifier& propertyName) const
return var::null;
}
-const var var::invoke (const var::identifier& method, const var* arguments, int numArguments) const
+const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const
{
if (type == objectType && value.objectValue != 0)
return value.objectValue->invokeMethod (method, arguments, numArguments);
@@ -312,68 +313,39 @@ const var var::invoke (const var& targetObject, const var* arguments, int numArg
return var::null;
}
-const var var::call (const var::identifier& method) const
+const var var::call (const Identifier& method) const
{
return invoke (method, 0, 0);
}
-const var var::call (const var::identifier& method, const var& arg1) const
+const var var::call (const Identifier& method, const var& arg1) const
{
return invoke (method, &arg1, 1);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2) const
+const var var::call (const Identifier& method, const var& arg1, const var& arg2) const
{
var args[] = { arg1, arg2 };
return invoke (method, args, 2);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3)
+const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3)
{
var args[] = { arg1, arg2, arg3 };
return invoke (method, args, 3);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
+const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const
{
var args[] = { arg1, arg2, arg3, arg4 };
return invoke (method, args, 4);
}
-const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
+const var var::call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const
{
var args[] = { arg1, arg2, arg3, arg4, arg5 };
return invoke (method, args, 5);
}
-//==============================================================================
-var::identifier::identifier() throw()
- : hashCode (0)
-{
-}
-
-var::identifier::identifier (const String& name_)
- : name (name_),
- hashCode (name_.hashCode())
-{
- /* An identifier string must be suitable for use as a script variable or XML
- attribute, so it can only contain this limited set of characters.. */
- jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty());
-}
-
-var::identifier::identifier (const char* const name_)
- : name (name_),
- hashCode (name.hashCode())
-{
- /* An identifier string must be suitable for use as a script variable or XML
- attribute, so it can only contain this limited set of characters.. */
- jassert (name.containsOnly ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") && name.isNotEmpty());
-}
-
-var::identifier::~identifier()
-{
-}
-
-
END_JUCE_NAMESPACE
diff --git a/src/containers/juce_Variant.h b/src/containers/juce_Variant.h
index aa59713831..17b6b8c32a 100644
--- a/src/containers/juce_Variant.h
+++ b/src/containers/juce_Variant.h
@@ -26,6 +26,7 @@
#ifndef __JUCE_VARIANT_JUCEHEADER__
#define __JUCE_VARIANT_JUCEHEADER__
+#include "juce_Identifier.h"
#include "../io/streams/juce_OutputStream.h"
#include "../io/streams/juce_InputStream.h"
@@ -47,6 +48,7 @@ class JUCE_API var
public:
//==============================================================================
typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);
+ typedef Identifier identifier;
//==============================================================================
/** Creates a void variant. */
@@ -109,56 +111,25 @@ public:
static const var readFromStream (InputStream& input);
//==============================================================================
- class JUCE_API identifier
- {
- public:
- /** Creates a null identifier. */
- identifier() throw();
-
- /** Creates an identifier with a specified name.
- Because this name may need to be used in contexts such as script variables or XML
- tags, it must only contain ascii letters and digits, or the underscore character.
- */
- identifier (const char* name);
-
- /** Creates an identifier with a specified name.
- Because this name may need to be used in contexts such as script variables or XML
- tags, it must only contain ascii letters and digits, or the underscore character.
- */
- identifier (const String& name);
-
- /** Destructor */
- ~identifier();
-
- bool operator== (const identifier& other) const throw()
- {
- jassert (hashCode != other.hashCode || name == other.name); // check for name hash collisions
- return hashCode == other.hashCode;
- }
-
- String name;
- int hashCode;
- };
-
/** If this variant is an object, this returns one of its properties. */
- const var operator[] (const identifier& propertyName) const;
+ const var operator[] (const Identifier& propertyName) const;
//==============================================================================
/** If this variant is an object, this invokes one of its methods with no arguments. */
- const var call (const identifier& method) const;
+ const var call (const Identifier& method) const;
/** If this variant is an object, this invokes one of its methods with one argument. */
- const var call (const identifier& method, const var& arg1) const;
+ const var call (const Identifier& method, const var& arg1) const;
/** If this variant is an object, this invokes one of its methods with 2 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2) const;
+ const var call (const Identifier& method, const var& arg1, const var& arg2) const;
/** If this variant is an object, this invokes one of its methods with 3 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3);
+ const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3);
/** If this variant is an object, this invokes one of its methods with 4 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
+ const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
/** If this variant is an object, this invokes one of its methods with 5 arguments. */
- const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
+ const var call (const Identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
/** If this variant is an object, this invokes one of its methods with a list of arguments. */
- const var invoke (const identifier& method, const var* arguments, int numArguments) const;
+ const var invoke (const Identifier& method, const var* arguments, int numArguments) const;
//==============================================================================
/** If this variant is a method pointer, this invokes it on a target object. */
diff --git a/src/gui/components/controls/juce_TableListBox.cpp b/src/gui/components/controls/juce_TableListBox.cpp
index 8ce0111bb4..834091d34f 100644
--- a/src/gui/components/controls/juce_TableListBox.cpp
+++ b/src/gui/components/controls/juce_TableListBox.cpp
@@ -100,7 +100,7 @@ public:
{
jassert (row >= 0);
- const var::identifier tagPropertyName ("_tableLastUseNum");
+ const Identifier tagPropertyName ("_tableLastUseNum");
const int newTag = Random::getSystemRandom().nextInt();
const TableHeaderComponent* const header = owner.getHeader();
diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp
index 407df7202b..bd2f98cbdb 100644
--- a/src/gui/components/juce_Component.cpp
+++ b/src/gui/components/juce_Component.cpp
@@ -1783,7 +1783,7 @@ void Component::sendLookAndFeelChange()
}
}
-static const var::identifier getColourPropertyId (const int colourId)
+static const Identifier getColourPropertyId (const int colourId)
{
String s;
s.preallocateStorage (18);
@@ -1827,9 +1827,9 @@ void Component::copyAllExplicitColoursTo (Component& target) const
for (int i = properties.size(); --i >= 0;)
{
- const var::identifier name (properties.getName(i));
+ const Identifier name (properties.getName(i));
- if (name.name.startsWith ("jcclr_"))
+ if (name.toString().startsWith ("jcclr_"))
if (target.properties.set (name, properties [name]))
changed = true;
}
diff --git a/src/io/files/juce_File.cpp b/src/io/files/juce_File.cpp
index 92cd7b60ff..a862d06fc5 100644
--- a/src/io/files/juce_File.cpp
+++ b/src/io/files/juce_File.cpp
@@ -826,6 +826,39 @@ bool File::replaceWithText (const String& textToWrite,
return tempFile.overwriteTargetFileWithTemporary();
}
+bool File::hasIdenticalContentTo (const File& other) const
+{
+ if (other == *this)
+ return true;
+
+ if (getSize() == other.getSize() && existsAsFile() && other.existsAsFile())
+ {
+ FileInputStream in1 (*this), in2 (other);
+
+ const int bufferSize = 4096;
+ HeapBlock buffer1, buffer2;
+ buffer1.malloc (bufferSize);
+ buffer2.malloc (bufferSize);
+
+ for (;;)
+ {
+ const int num1 = in1.read (buffer1, bufferSize);
+ const int num2 = in2.read (buffer2, bufferSize);
+
+ if (num1 != num2)
+ break;
+
+ if (num1 <= 0)
+ return true;
+
+ if (memcmp (buffer1, buffer2, num1) != 0)
+ break;
+ }
+ }
+
+ return false;
+}
+
//==============================================================================
const String File::createLegalPathName (const String& original)
{
diff --git a/src/io/files/juce_File.h b/src/io/files/juce_File.h
index ed8f3fcb3e..4c67c297db 100644
--- a/src/io/files/juce_File.h
+++ b/src/io/files/juce_File.h
@@ -669,6 +669,11 @@ public:
bool asUnicode = false,
bool writeUnicodeHeaderBytes = false) const;
+ /** Attempts to scan the contents of this file and compare it to another file, returning
+ true if this is possible and they match byte-for-byte.
+ */
+ bool hasIdenticalContentTo (const File& other) const;
+
//==============================================================================
/** Creates a set of files to represent each file root.
diff --git a/src/juce_core_includes.h b/src/juce_core_includes.h
index fe2cf41560..3865fa2db5 100644
--- a/src/juce_core_includes.h
+++ b/src/juce_core_includes.h
@@ -44,6 +44,9 @@
#ifndef __JUCE_HEAPBLOCK_JUCEHEADER__
#include "containers/juce_HeapBlock.h"
#endif
+#ifndef __JUCE_IDENTIFIER_JUCEHEADER__
+ #include "containers/juce_Identifier.h"
+#endif
#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__
#include "containers/juce_MemoryBlock.h"
#endif
@@ -224,6 +227,9 @@
#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__
#include "text/juce_StringPairArray.h"
#endif
+#ifndef __JUCE_STRINGPOOL_JUCEHEADER__
+ #include "text/juce_StringPool.h"
+#endif
#ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__
#include "text/juce_XmlDocument.h"
#endif
diff --git a/src/text/juce_CharacterFunctions.cpp b/src/text/juce_CharacterFunctions.cpp
index 0c8c7ceffa..f620f4d3e3 100644
--- a/src/text/juce_CharacterFunctions.cpp
+++ b/src/text/juce_CharacterFunctions.cpp
@@ -781,12 +781,17 @@ bool CharacterFunctions::isLetterOrDigit (const juce_wchar character) throw()
int CharacterFunctions::getHexDigitValue (const juce_wchar digit) throw()
{
- if (digit >= '0' && digit <= '9')
- return digit - '0';
- else if (digit >= 'a' && digit <= 'f')
- return digit - ('a' - 10);
- else if (digit >= 'A' && digit <= 'F')
- return digit - ('A' - 10);
+ unsigned int d = digit - '0';
+ if (d < (unsigned int) 10)
+ return (int) d;
+
+ d += '0' - 'a';
+ if (d < (unsigned int) 6)
+ return (int) d + 10;
+
+ d += 'a' - 'A';
+ if (d < (unsigned int) 6)
+ return (int) d + 10;
return -1;
}
diff --git a/src/text/juce_String.h b/src/text/juce_String.h
index 5416913e03..401123d5f7 100644
--- a/src/text/juce_String.h
+++ b/src/text/juce_String.h
@@ -81,7 +81,7 @@ public:
/** Destructor. */
~String() throw();
- //========================juce_wchar======================================================
+ //==============================================================================
/** This is an empty string that can be used whenever one is needed.
It's better to use this than String() because it explains what's going on
diff --git a/src/text/juce_StringPool.cpp b/src/text/juce_StringPool.cpp
new file mode 100644
index 0000000000..9ef0f9a8d7
--- /dev/null
+++ b/src/text/juce_StringPool.cpp
@@ -0,0 +1,105 @@
+/*
+ ==============================================================================
+
+ 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.
+
+ ==============================================================================
+*/
+
+#include "../core/juce_StandardHeader.h"
+
+BEGIN_JUCE_NAMESPACE
+
+#include "juce_StringPool.h"
+
+
+//==============================================================================
+StringPool::StringPool() throw() {}
+StringPool::~StringPool() {}
+
+template
+static const juce_wchar* getPooledStringFromArray (Array& strings, StringType newString)
+{
+ int start = 0;
+ int end = strings.size();
+
+ for (;;)
+ {
+ if (start >= end)
+ {
+ jassert (start <= end);
+ strings.insert (start, newString);
+ return strings.getReference (start);
+ }
+ else
+ {
+ const String& startString = strings.getReference (start);
+
+ if (startString == newString)
+ return startString;
+
+ const int halfway = (start + end) >> 1;
+
+ if (halfway == start)
+ {
+ if (startString.compare (newString) < 0)
+ ++start;
+
+ strings.insert (start, newString);
+ return strings.getReference (start);
+ }
+
+ const int comp = strings.getReference (halfway).compare (newString);
+
+ if (comp == 0)
+ return strings.getReference (halfway);
+ else if (comp < 0)
+ start = halfway;
+ else
+ end = halfway;
+ }
+ }
+}
+
+const juce_wchar* StringPool::getPooledString (const String& s)
+{
+ if (s.isEmpty())
+ return String::empty;
+
+ return getPooledStringFromArray (strings, s);
+}
+
+const juce_wchar* StringPool::getPooledString (const char* const s)
+{
+ if (s == 0 || *s == 0)
+ return String::empty;
+
+ return getPooledStringFromArray (strings, s);
+}
+
+const juce_wchar* StringPool::getPooledString (const juce_wchar* const s)
+{
+ if (s == 0 || *s == 0)
+ return String::empty;
+
+ return getPooledStringFromArray (strings, s);
+}
+
+END_JUCE_NAMESPACE
diff --git a/src/text/juce_StringPool.h b/src/text/juce_StringPool.h
new file mode 100644
index 0000000000..ed1607e0d6
--- /dev/null
+++ b/src/text/juce_StringPool.h
@@ -0,0 +1,82 @@
+/*
+ ==============================================================================
+
+ 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_STRINGPOOL_JUCEHEADER__
+#define __JUCE_STRINGPOOL_JUCEHEADER__
+
+#include "juce_String.h"
+#include "../containers/juce_Array.h"
+
+
+//==============================================================================
+/**
+ A StringPool holds a set of shared strings, which reduces storage overheads and improves
+ comparison speed when dealing with many duplicate strings.
+
+ When you add a string to a pool using getPooledString, it'll return a character
+ array containing the same string. This array is owned by the pool, and the same array
+ is returned every time a matching string is asked for. This means that it's trivial to
+ compare two pooled strings for equality, as you can simply compare their pointers. It
+ also cuts down on storage if you're using many copies of the same string.
+*/
+class JUCE_API StringPool
+{
+public:
+ /** Creates an empty pool. */
+ StringPool() throw();
+
+ /** Destructor */
+ ~StringPool();
+
+ /** Returns a pointer to a copy of the string that is passed in.
+
+ The pool will always return the same pointer when asked for a string that matches it.
+ The pool will own all the pointers that it returns, deleting them when the pool itself
+ is deleted.
+ */
+ const juce_wchar* getPooledString (const String& original);
+
+ /** Returns a pointer to a copy of the string that is passed in.
+
+ The pool will always return the same pointer when asked for a string that matches it.
+ The pool will own all the pointers that it returns, deleting them when the pool itself
+ is deleted.
+ */
+ const juce_wchar* getPooledString (const char* original);
+
+ /** Returns a pointer to a copy of the string that is passed in.
+
+ The pool will always return the same pointer when asked for a string that matches it.
+ The pool will own all the pointers that it returns, deleting them when the pool itself
+ is deleted.
+ */
+ const juce_wchar* getPooledString (const juce_wchar* original);
+
+private:
+ Array strings;
+};
+
+
+#endif // __JUCE_STRINGPOOL_JUCEHEADER__