@@ -97,6 +97,7 @@ | |||
<Option compile="0"/> | |||
<Option link="0"/> | |||
</Unit> | |||
<Unit filename="../../Source/Application/jucer_AutoUpdater.cpp"/> | |||
<Unit filename="../../Source/Application/jucer_Application.h"> | |||
<Option compile="0"/> | |||
<Option link="0"/> | |||
@@ -1498,6 +1499,10 @@ | |||
<Option compile="0"/> | |||
<Option link="0"/> | |||
</Unit> | |||
<Unit filename="../../../../modules/juce_core/native/juce_curl_Network.cpp"> | |||
<Option compile="0"/> | |||
<Option link="0"/> | |||
</Unit> | |||
<Unit filename="../../../../modules/juce_core/native/juce_linux_CommonFile.cpp"> | |||
<Option compile="0"/> | |||
<Option link="0"/> | |||
@@ -21,7 +21,7 @@ ifeq ($(CONFIG),Debug) | |||
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=3.1.1" -D "JUCE_APP_VERSION_HEX=0x30101" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../../../modules | |||
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 -std=gnu++0x -Wreorder -Wuninitialized -Wunused-parameter -Wstrict-aliasing -Wshadow -Wsign-compare | |||
CXXFLAGS += $(CFLAGS) -std=c++11 | |||
LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -L/usr/X11R6/lib/ -lX11 -lXext -lXinerama -ldl -lfreetype -lpthread -lrt | |||
LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -L/usr/X11R6/lib/ -lX11 -lXext -lXinerama -ldl -lfreetype -lpthread -lrt -lcurl | |||
TARGET := Introjucer | |||
BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) | |||
@@ -41,7 +41,7 @@ ifeq ($(CONFIG),Release) | |||
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -D "JUCER_LINUX_MAKE_7346DA2A=1" -D "JUCE_APP_VERSION=3.1.1" -D "JUCE_APP_VERSION_HEX=0x30101" -I /usr/include -I /usr/include/freetype2 -I ../../JuceLibraryCode -I ../../../../modules | |||
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -std=gnu++0x -Wreorder -Wuninitialized -Wunused-parameter -Wstrict-aliasing -Wshadow -Wsign-compare | |||
CXXFLAGS += $(CFLAGS) -std=c++11 | |||
LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -fvisibility=hidden -L/usr/X11R6/lib/ -lX11 -lXext -lXinerama -ldl -lfreetype -lpthread -lrt | |||
LDFLAGS += $(TARGET_ARCH) -L$(BINDIR) -L$(LIBDIR) -fvisibility=hidden -L/usr/X11R6/lib/ -lX11 -lXext -lXinerama -ldl -lfreetype -lpthread -lrt -lcurl | |||
TARGET := Introjucer | |||
BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) | |||
@@ -50,6 +50,7 @@ endif | |||
OBJECTS := \ | |||
$(OBJDIR)/jucer_AppearanceSettings_788d9889.o \ | |||
$(OBJDIR)/jucer_AutoUpdater_ca658dc2.o \ | |||
$(OBJDIR)/jucer_CommandLine_f35de107.o \ | |||
$(OBJDIR)/jucer_DocumentEditorComponent_695dff1d.o \ | |||
$(OBJDIR)/jucer_Main_f8488f5b.o \ | |||
@@ -122,6 +123,11 @@ $(OBJDIR)/jucer_AppearanceSettings_788d9889.o: ../../Source/Application/jucer_Ap | |||
@echo "Compiling jucer_AppearanceSettings.cpp" | |||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
$(OBJDIR)/jucer_AutoUpdater_ca658dc2.o: ../../Source/Application/jucer_AutoUpdater.cpp | |||
-@mkdir -p $(OBJDIR) | |||
@echo "Compiling jucer_AutoUpdater.cpp" | |||
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||
$(OBJDIR)/jucer_CommandLine_f35de107.o: ../../Source/Application/jucer_CommandLine.cpp | |||
-@mkdir -p $(OBJDIR) | |||
@echo "Compiling jucer_CommandLine.cpp" | |||
@@ -14,6 +14,7 @@ | |||
2610F357881240ACBF612F48 = {isa = PBXBuildFile; fileRef = 6678E9B3EEACAD47F438B264; }; | |||
1321E6C1C6170B6C898AD09D = {isa = PBXBuildFile; fileRef = 951128CA33CCDEF570436B1C; }; | |||
357A6AA6960EF95D92929BEE = {isa = PBXBuildFile; fileRef = 441CFEA771BAA50E187342E9; }; | |||
6DD9DA1677A6CF789CDAB478 = {isa = PBXBuildFile; fileRef = 0D4D508C638BC74943B9976D; }; | |||
954A036F5DDB375DB23FFB3E = {isa = PBXBuildFile; fileRef = 0400CB0E056A1D840304D2DE; }; | |||
3EB3D569250C4BA4CA9AF578 = {isa = PBXBuildFile; fileRef = C7608A3967D9AB9481848F2B; }; | |||
95B44E6C74B1DED31DBE37EB = {isa = PBXBuildFile; fileRef = 8C52A3DDA62A746AA7A68535; }; | |||
@@ -109,6 +110,7 @@ | |||
0CEF14D37EC664CA49A2B04D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ComponentPeer.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ComponentPeer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
0D100A1B27A72355323CB637 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_win32_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
0D1C432D74433308E05942AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextDiff.cpp"; path = "../../../../modules/juce_core/text/juce_TextDiff.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
0D4D508C638BC74943B9976D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_AutoUpdater.cpp"; path = "../../Source/Application/jucer_AutoUpdater.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
0DB0A9E30EEDDEA720BC5A03 = {isa = PBXFileReference; lastKnownFileType = file.svg; name = "wizard_StaticLibrary.svg"; path = "../../Source/BinaryData/wizard_StaticLibrary.svg"; sourceTree = "SOURCE_ROOT"; }; | |||
0E80EFDB550393DB1C94F291 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Font.h"; path = "../../../../modules/juce_graphics/fonts/juce_Font.h"; sourceTree = "SOURCE_ROOT"; }; | |||
0F01067432AC314EAC213C1C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectWizard_Blank.h"; path = "../../Source/Wizards/jucer_ProjectWizard_Blank.h"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -736,6 +738,7 @@ | |||
C2990A8D054BC230E7C637C3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_NewProjectWizardClasses.h"; path = "../../Source/Wizards/jucer_NewProjectWizardClasses.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C2D43E4F571D16F0E9B1E44E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileTreeComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C2ECD077AC4C784A67BC3DDE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Socket.h"; path = "../../../../modules/juce_core/network/juce_Socket.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C3447B6A7C639350E98E43AF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_curl_Network.cpp"; path = "../../../../modules/juce_core/native/juce_curl_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C38DFB0C94BBC1CE46A3D4E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_TooltipWindow.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C4718AEAC94D07FEB9DA0312 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Misc.cpp"; path = "../../../../modules/juce_core/native/juce_android_Misc.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C48DCD3879352EB40F468B0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsList.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.h"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -746,7 +749,6 @@ | |||
C5D5D2FFB030BD43160167EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C5FCECA838D4D12D03929139 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C61E82D93918A611FAFD9E9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C68355AA4D62939EECAD469E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../../../modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C6861DB44A31CE7A3DEFA083 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../../../modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C6E46DBD249D9426C95E2235 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C717D2384896547D1CD993F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -755,7 +757,6 @@ | |||
C7B47372A9D5970E3D9A5400 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GroupInformationComponent.h"; path = "../../Source/Project/jucer_GroupInformationComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C7E19F79947BEFC7DB7A9CE7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_GlowEffect.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C83992DA0BE30EA3CD06EA98 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ProgressBar.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C85B4D62B96F4A44890F20E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../../../modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C8A229ACD244F402C57286CD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_MSVC.h"; path = "../../Source/Project Saving/jucer_ProjectExport_MSVC.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C90C66C5727759D5CBD5FB07 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_AbstractFifo.cpp"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C9616830BB2474066AC8C910 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ResourceFile.h"; path = "../../Source/Project Saving/jucer_ResourceFile.h"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -770,16 +771,16 @@ | |||
CD140A1C0161176682F6CA29 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ResizableWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
CD3216F23C7B273B010A8D12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CustomTypeface.h"; path = "../../../../modules/juce_graphics/fonts/juce_CustomTypeface.h"; sourceTree = "SOURCE_ROOT"; }; | |||
CDCAF0EC777DA2884AEB2B59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
CDDF5BDC75277F7B83A38885 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
CDF8F65F9079B2C14A740F0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; }; | |||
CE1DFE4E3908943656E180AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
CF0615A1AF1A514A60322B50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; }; | |||
CF21D9DB3AEC0A4DCAB36A99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_Icons.cpp"; path = "../../Source/Utility/jucer_Icons.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
CF6C8BD0DA3D8CD4E99EBADA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; }; | |||
CF8011B3C67B609032974DA5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_NewCppFileTemplate.cpp"; path = "../../Source/BinaryData/jucer_NewCppFileTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D00F311BFC3C2625C457CB9B = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; | |||
D041043D3B554B88F855C174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D0D8B580D0689FFF4B9B823B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_StrokeType.h"; path = "../../Source/ComponentEditor/paintelements/jucer_StrokeType.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D0F1614CC861E8E0B59B7A06 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Messaging.cpp"; path = "../../../../modules/juce_events/native/juce_linux_Messaging.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D10D51A0A2D63F38B4D86A60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ResourceFile.cpp"; path = "../../Source/Project Saving/jucer_ResourceFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D141433D3FE81F20490DE928 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Desktop.h"; path = "../../../../modules/juce_gui_basics/components/juce_Desktop.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D1F9B0E9F5D54FE48BEB46EA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; | |||
D253F74B7F5734984E568CA7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -791,66 +792,64 @@ | |||
D4697A0232AECE5DAC5E332E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D4E56676E2EF83404EDCBA8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D4F2D42C58F4D86E00E76F31 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandID.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandID.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D503780AB98993E8F0BA1311 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D5057D7B18ABD5E810A6F830 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D526C38D581425949BA0E4AC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FilePreviewComponent.h"; path = "../../Source/Application/jucer_FilePreviewComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D53B54D1786A1FFC024BF064 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_cryptography.mm"; path = "../../../../modules/juce_cryptography/juce_cryptography.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
D678882D133090214AF681BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../../../modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D6C91E2BF537F75A80F5C1DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D75EAC16FAECCC51E3669193 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D780ED33573AED5AD383A036 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D782DA091AD3ECE158FC6A5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D800DE818BEDBF4579D15B1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
D87FC8F6834E9DC9C8E88B94 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JustificationProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_JustificationProperty.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D926E13AB5AD647A7A00F486 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D92A6E9404A30EED32DCE4ED = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_RelativePositionedRectangle.h"; path = "../../Source/ComponentEditor/ui/jucer_RelativePositionedRectangle.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DA345D5B9DABD049F90DC96F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GeneratedCode.h"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DBE0CDE1B017190ABBFF557C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_CodeBlocks.h"; path = "../../Source/Project Saving/jucer_ProjectExport_CodeBlocks.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DC5E7FF30B01118F6DAEC38F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D9342535EA61901A1AD816C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DC922C6A65D260C18E888E49 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentTemplate.cpp"; path = "../../Source/BinaryData/jucer_ComponentTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DCCB75165B7C73A589498E87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DD00494140C86144306A9356 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Array.h"; path = "../../../../modules/juce_core/containers/juce_Array.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DE8DF5D263F40F65581CFDE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DF725A596B7BCD7520CC0A9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ResourceEditorPanel.cpp"; path = "../../Source/ComponentEditor/ui/jucer_ResourceEditorPanel.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DFC6364D81D9C60BD4CA9D12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../../../modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E0F9CA57E44F7F7E7E217E47 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentUndoableAction.h"; path = "../../Source/ComponentEditor/components/jucer_ComponentUndoableAction.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E19160CF7208320D128786CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../../../modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E1D8CCD9F4ACBE1EC1D5BEA0 = {isa = PBXFileReference; lastKnownFileType = file.svg; name = "wizard_AudioApp.svg"; path = "../../Source/BinaryData/wizard_AudioApp.svg"; sourceTree = "SOURCE_ROOT"; }; | |||
E2374E15D65425C4101237E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_NewComponentTemplate.h"; path = "../../Source/BinaryData/jucer_NewComponentTemplate.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E2C1C995D554A3F0A363CE58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../../../modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E2DBA3307837B64AFCCD8F8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../../../modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E3B56C5718D87CA0EFCB2662 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_AudioComponentTemplate.cpp"; path = "../../Source/BinaryData/jucer_AudioComponentTemplate.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E4BB22E27C5AA4B666F265BD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TextButtonHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TextButtonHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E4BD4C43370651B49F75855B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_MainTemplate_SimpleWindow.cpp"; path = "../../Source/BinaryData/jucer_MainTemplate_SimpleWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E570E57CC1FCEF78B54A7084 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E5D6C36496F5BC84D7213BE8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; | |||
E62D9BA6E92FE7BB6EF65699 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E65A820D34BF39478B7C5925 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_DocumentEditorComponent.h"; path = "../../Source/Application/jucer_DocumentEditorComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E6F5CEC32EDC917B054467EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E720FBCD836FF3AA466C31B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E96597BBC6A98255B51B94DC = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; | |||
25F52316D256B4534BED16D1 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Introjucer.app; sourceTree = "BUILT_PRODUCTS_DIR"; }; | |||
CF21D9DB3AEC0A4DCAB36A99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_Icons.cpp"; path = "../../Source/Utility/jucer_Icons.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D10D51A0A2D63F38B4D86A60 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ResourceFile.cpp"; path = "../../Source/Project Saving/jucer_ResourceFile.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
C68355AA4D62939EECAD469E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../../../modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; }; | |||
C85B4D62B96F4A44890F20E2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SortedSet.h"; path = "../../../../modules/juce_core/containers/juce_SortedSet.h"; sourceTree = "SOURCE_ROOT"; }; | |||
CDDF5BDC75277F7B83A38885 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D041043D3B554B88F855C174 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_HighResolutionTimer.h"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D3E139185095C486DD3D61F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TranslationTool.h"; path = "../../Source/Utility/jucer_TranslationTool.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D503780AB98993E8F0BA1311 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageComponent.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ImageComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D5057D7B18ABD5E810A6F830 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_DirectWriteTypeface.cpp"; path = "../../../../modules/juce_graphics/native/juce_win32_DirectWriteTypeface.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D6C91E2BF537F75A80F5C1DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D780ED33573AED5AD383A036 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D782DA091AD3ECE158FC6A5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D678882D133090214AF681BC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ThreadLocalValue.h"; path = "../../../../modules/juce_core/threads/juce_ThreadLocalValue.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D7A7F1AA9F313B0CCAAA73A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D800DE818BEDBF4579D15B1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
D9342535EA61901A1AD816C6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
D95D7B49EC6C6BDCB5A1B988 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
D9B077E2ECDDA94961E134D7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../../../modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; }; | |||
D9E59DE07A815AB303A297D9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../../../modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; }; | |||
DA345D5B9DABD049F90DC96F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GeneratedCode.h"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DAF84A553D264705FA6EB6FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TreeViewHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TreeViewHandler.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DB20268A566DABEAE3F2CBEE = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DB876F7873F42DC685A58CA7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DCCB75165B7C73A589498E87 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_linux_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DBE0CDE1B017190ABBFF557C = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_CodeBlocks.h"; path = "../../Source/Project Saving/jucer_ProjectExport_CodeBlocks.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DC5E7FF30B01118F6DAEC38F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Time.cpp"; path = "../../../../modules/juce_core/time/juce_Time.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DD2494D5F1C081898D616AF5 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_KeyListener.cpp"; path = "../../../../modules/juce_gui_basics/keyboard/juce_KeyListener.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DD985A60FB76E976AF91852D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SHA256.h"; path = "../../../../modules/juce_cryptography/hashing/juce_SHA256.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DE40B42B57F29C650CB7F2AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RecentlyOpenedFilesList.h"; path = "../../../../modules/juce_gui_extra/misc/juce_RecentlyOpenedFilesList.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DE5F3C9EF6BFFDE73AF9E7FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DE8DF5D263F40F65581CFDE4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChildProcess.cpp"; path = "../../../../modules/juce_core/threads/juce_ChildProcess.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DEF579B1433EB8DEE7AB50F8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Drawable.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
DF7BB5B6B394EDEEF5F5B4B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallbackMessage.h"; path = "../../../../modules/juce_events/messages/juce_CallbackMessage.h"; sourceTree = "SOURCE_ROOT"; }; | |||
DFC6364D81D9C60BD4CA9D12 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeTime.cpp"; path = "../../../../modules/juce_core/time/juce_RelativeTime.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E07C56267CBB46FC44EF2026 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Image.cpp"; path = "../../../../modules/juce_graphics/images/juce_Image.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E19160CF7208320D128786CF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Javascript.h"; path = "../../../../modules/juce_core/javascript/juce_Javascript.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E1C16C872E34BCB144B469F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E27F0860F27023BAA9798B46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../../../modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E284B565DBD647DC0830D23B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E2C1C995D554A3F0A363CE58 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Thread.h"; path = "../../../../modules/juce_core/threads/juce_Thread.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E2DBA3307837B64AFCCD8F8D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_File.cpp"; path = "../../../../modules/juce_core/files/juce_File.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E3869AC657E984565F1718AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConnectedChildProcess.h"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E3FF16862AA1B2F943DC616C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E446FFE889CD490FDE3F0F2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -858,11 +857,15 @@ | |||
E4F9D1E097CC2C1D1291823C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LookAndFeel_V2.cpp"; path = "../../../../modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E530742870F07704E9616358 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E54D0994D31E20A0A05EBA2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E570E57CC1FCEF78B54A7084 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E60E28D1B7491047DEA236AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectContentComponent.h"; path = "../../Source/Project/jucer_ProjectContentComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E62D9BA6E92FE7BB6EF65699 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E63F54CF8D5D922A319C6962 = {isa = PBXFileReference; lastKnownFileType = image.png; name = projectIconXcodeIOS.png; path = ../../Source/BinaryData/projectIconXcodeIOS.png; sourceTree = "SOURCE_ROOT"; }; | |||
E642193A9990C48CFB6479A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E654E3A3CD45A888C5F773DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E6F5CEC32EDC917B054467EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E70CA21960A64CCB835725FF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ProjectType.cpp"; path = "../../Source/Project/jucer_ProjectType.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E720FBCD836FF3AA466C31B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E73C7E17116F6085765622E3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Drawable.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.h"; sourceTree = "SOURCE_ROOT"; }; | |||
E7A4604F766ABC8BE26C94A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeParallelogram.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeParallelogram.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
E7B6A0CBA0D27A095E83F5B7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; | |||
@@ -943,6 +946,7 @@ | |||
ACBAFA7D92DD82AD44ABE68A = {isa = PBXGroup; children = ( | |||
441CFEA771BAA50E187342E9, | |||
223C4209F18A221EB183A056, | |||
0D4D508C638BC74943B9976D, | |||
EE690110171E1648FF2118B8, | |||
4D698BF12BCD6B0896BCDF17, | |||
23A8DE16C0CDB8EED18B008B, | |||
@@ -1369,6 +1373,7 @@ | |||
F07EA5078D6BB60B698F5E12, | |||
68351D69C94230D1DCDB8345, | |||
A243C85FC2C37FD73F115E67, | |||
C3447B6A7C639350E98E43AF, | |||
A4422A360A9FB7BCC315BEF4, | |||
D253F74B7F5734984E568CA7, | |||
D926E13AB5AD647A7A00F486, | |||
@@ -2075,6 +2080,7 @@ | |||
1321E6C1C6170B6C898AD09D, ); runOnlyForDeploymentPostprocessing = 0; }; | |||
84449D044096A03F2582904B = {isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | |||
357A6AA6960EF95D92929BEE, | |||
6DD9DA1677A6CF789CDAB478, | |||
954A036F5DDB375DB23FFB3E, | |||
3EB3D569250C4BA4CA9AF578, | |||
95B44E6C74B1DED31DBE37EB, | |||
@@ -128,6 +128,7 @@ | |||
<Filter Name="Application"> | |||
<File RelativePath="..\..\Source\Application\jucer_AppearanceSettings.cpp"/> | |||
<File RelativePath="..\..\Source\Application\jucer_AppearanceSettings.h"/> | |||
<File RelativePath="..\..\Source\Application\jucer_AutoUpdater.cpp"/> | |||
<File RelativePath="..\..\Source\Application\jucer_Application.h"/> | |||
<File RelativePath="..\..\Source\Application\jucer_AutoUpdater.h"/> | |||
<File RelativePath="..\..\Source\Application\jucer_CommandIDs.h"/> | |||
@@ -1535,6 +1536,16 @@ | |||
</FileConfiguration> | |||
</File> | |||
<File RelativePath="..\..\..\..\modules\juce_core\native\juce_BasicNativeHeaders.h"/> | |||
<File RelativePath="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<FileConfiguration Name="Debug|Win32" | |||
ExcludedFromBuild="true"> | |||
<Tool Name="VCCLCompilerTool"/> | |||
</FileConfiguration> | |||
<FileConfiguration Name="Release|Win32" | |||
ExcludedFromBuild="true"> | |||
<Tool Name="VCCLCompilerTool"/> | |||
</FileConfiguration> | |||
</File> | |||
<File RelativePath="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<FileConfiguration Name="Debug|Win32" | |||
ExcludedFromBuild="true"> | |||
@@ -128,6 +128,7 @@ | |||
<Filter Name="Application"> | |||
<File RelativePath="..\..\Source\Application\jucer_AppearanceSettings.cpp"/> | |||
<File RelativePath="..\..\Source\Application\jucer_AppearanceSettings.h"/> | |||
<File RelativePath="..\..\Source\Application\jucer_AutoUpdater.cpp"/> | |||
<File RelativePath="..\..\Source\Application\jucer_Application.h"/> | |||
<File RelativePath="..\..\Source\Application\jucer_AutoUpdater.h"/> | |||
<File RelativePath="..\..\Source\Application\jucer_CommandIDs.h"/> | |||
@@ -1535,6 +1536,16 @@ | |||
</FileConfiguration> | |||
</File> | |||
<File RelativePath="..\..\..\..\modules\juce_core\native\juce_BasicNativeHeaders.h"/> | |||
<File RelativePath="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<FileConfiguration Name="Debug|Win32" | |||
ExcludedFromBuild="true"> | |||
<Tool Name="VCCLCompilerTool"/> | |||
</FileConfiguration> | |||
<FileConfiguration Name="Release|Win32" | |||
ExcludedFromBuild="true"> | |||
<Tool Name="VCCLCompilerTool"/> | |||
</FileConfiguration> | |||
</File> | |||
<File RelativePath="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<FileConfiguration Name="Debug|Win32" | |||
ExcludedFromBuild="true"> | |||
@@ -124,6 +124,7 @@ | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClCompile Include="..\..\Source\Application\jucer_AppearanceSettings.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_AutoUpdater.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> | |||
@@ -396,6 +397,9 @@ | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_android_Threads.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
@@ -253,6 +253,9 @@ | |||
<ClCompile Include="..\..\Source\Application\jucer_AppearanceSettings.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\Source\Application\jucer_AutoUpdater.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
@@ -607,6 +610,9 @@ | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_android_Threads.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
@@ -130,6 +130,7 @@ | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClCompile Include="..\..\Source\Application\jucer_AppearanceSettings.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_AutoUpdater.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> | |||
@@ -402,6 +403,9 @@ | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_android_Threads.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
@@ -253,6 +253,9 @@ | |||
<ClCompile Include="..\..\Source\Application\jucer_AppearanceSettings.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\Source\Application\jucer_AutoUpdater.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
@@ -607,6 +610,9 @@ | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_android_Threads.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
@@ -130,6 +130,7 @@ | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClCompile Include="..\..\Source\Application\jucer_AppearanceSettings.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_AutoUpdater.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/> | |||
<ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> | |||
@@ -402,6 +403,9 @@ | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_android_Threads.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<ExcludedFromBuild>true</ExcludedFromBuild> | |||
</ClCompile> | |||
@@ -253,6 +253,9 @@ | |||
<ClCompile Include="..\..\Source\Application\jucer_AppearanceSettings.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\Source\Application\jucer_AutoUpdater.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\Source\Application\jucer_CommandLine.cpp"> | |||
<Filter>The Introjucer\Application</Filter> | |||
</ClCompile> | |||
@@ -607,6 +610,9 @@ | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_android_Threads.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_curl_Network.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
<ClCompile Include="..\..\..\..\modules\juce_core\native\juce_linux_CommonFile.cpp"> | |||
<Filter>Juce Modules\juce_core\native</Filter> | |||
</ClCompile> | |||
@@ -160,6 +160,8 @@ | |||
file="Source/Application/jucer_AppearanceSettings.cpp"/> | |||
<FILE id="oCCddi" name="jucer_AppearanceSettings.h" compile="0" resource="0" | |||
file="Source/Application/jucer_AppearanceSettings.h"/> | |||
<FILE id="IvfYzk" name="jucer_AutoUpdater.cpp" compile="1" resource="0" | |||
file="Source/Application/jucer_AutoUpdater.cpp"/> | |||
<FILE id="PXX8Yi" name="jucer_Application.h" compile="0" resource="0" | |||
file="Source/Application/jucer_Application.h"/> | |||
<FILE id="RWf1Jy" name="jucer_AutoUpdater.h" compile="0" resource="0" | |||
@@ -602,7 +604,7 @@ | |||
JUCE_USE_FLAC="disabled" JUCE_USE_CDBURNER="disabled" JUCE_USE_CDREADER="disabled" | |||
JUCE_USE_CAMERA="disabled" JUCE_PLUGINHOST_VST="disabled" JUCE_PLUGINHOST_AU="disabled" | |||
JUCE_USE_OGGVORBIS="disabled" JUCE_USE_COREIMAGE_LOADER="disabled" | |||
JUCE_LOG_ASSERTIONS="enabled"/> | |||
JUCE_LOG_ASSERTIONS="enabled" JUCE_USE_CURL="enabled"/> | |||
<MODULES> | |||
<MODULE id="juce_core" showAllCode="1"/> | |||
<MODULE id="juce_cryptography" showAllCode="1"/> | |||
@@ -59,7 +59,7 @@ | |||
#endif | |||
#ifndef JUCE_USE_CURL | |||
//#define JUCE_USE_CURL | |||
#define JUCE_USE_CURL 1 | |||
#endif | |||
//============================================================================== | |||
@@ -0,0 +1,789 @@ | |||
/* | |||
============================================================================== | |||
This file is part of the JUCE library. | |||
Copyright (c) 2013 - Raw Material Software Ltd. | |||
Permission is granted to use this software under the terms of either: | |||
a) the GPL v2 (or any later version) | |||
b) the Affero GPL v3 | |||
Details of these licenses can be found 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.juce.com for more information. | |||
============================================================================== | |||
*/ | |||
#include "jucer_Application.h" | |||
#include "jucer_AutoUpdater.h" | |||
LatestVersionChecker::JuceVersionTriple::JuceVersionTriple() | |||
: major (JUCE_MAJOR_VERSION), | |||
minor (JUCE_MINOR_VERSION), | |||
build (JUCE_BUILDNUMBER) | |||
{} | |||
LatestVersionChecker::JuceVersionTriple::JuceVersionTriple (int majorInt, int minorInt, int buildNumber) | |||
: major (majorInt), | |||
minor (minorInt), | |||
build (buildNumber) | |||
{} | |||
bool LatestVersionChecker::JuceVersionTriple::fromString (const String& versionString, | |||
LatestVersionChecker::JuceVersionTriple& result) | |||
{ | |||
StringArray tokenizedString = StringArray::fromTokens (versionString, ".", StringRef()); | |||
if (tokenizedString.size() != 3) | |||
return false; | |||
result.major = tokenizedString [0].getIntValue(); | |||
result.minor = tokenizedString [1].getIntValue(); | |||
result.build = tokenizedString [2].getIntValue(); | |||
return true; | |||
} | |||
String LatestVersionChecker::JuceVersionTriple::toString() const | |||
{ | |||
String retval; | |||
retval << major << '.' << minor << '.' << build; | |||
return retval; | |||
} | |||
bool LatestVersionChecker::JuceVersionTriple::operator> (const LatestVersionChecker::JuceVersionTriple& b) const noexcept | |||
{ | |||
if (major == b.major) | |||
{ | |||
if (minor == b.minor) | |||
return build > b.build; | |||
return minor > b.minor; | |||
} | |||
return major > b.major; | |||
} | |||
//============================================================================== | |||
struct RelaunchTimer : private Timer | |||
{ | |||
RelaunchTimer (const File& f) : parentFolder (f) | |||
{ | |||
startTimer (1500); | |||
} | |||
void timerCallback() override | |||
{ | |||
stopTimer(); | |||
File app = parentFolder.getChildFile ( | |||
#if JUCE_MAC | |||
"Introjucer.app"); | |||
#elif JUCE_WINDOWS | |||
"Introjucer.exe"); | |||
#elif JUCE_LINUX | |||
"Introjucer"); | |||
#endif | |||
JUCEApplication::quit(); | |||
if (app.exists()) | |||
{ | |||
app.setExecutePermission (true); | |||
#if JUCE_MAC | |||
app.getChildFile ("Contents") | |||
.getChildFile ("MacOS") | |||
.getChildFile ("Introjucer").setExecutePermission (true); | |||
#endif | |||
app.startAsProcess(); | |||
} | |||
delete this; | |||
} | |||
File parentFolder; | |||
}; | |||
//============================================================================== | |||
class DownloadNewVersionThread : public ThreadWithProgressWindow | |||
{ | |||
public: | |||
DownloadNewVersionThread (URL u, const String& extraHeaders, File target) | |||
: ThreadWithProgressWindow ("Downloading New Version", true, true), | |||
result (Result::ok()), | |||
url (u), headers (extraHeaders), targetFolder (target) | |||
{ | |||
} | |||
static void performDownload (URL u, const String& extraHeaders, File targetFolder) | |||
{ | |||
DownloadNewVersionThread d (u, extraHeaders, targetFolder); | |||
if (d.runThread()) | |||
{ | |||
if (d.result.failed()) | |||
{ | |||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, | |||
"Installation Failed", | |||
d.result.getErrorMessage()); | |||
} | |||
else | |||
{ | |||
new RelaunchTimer (targetFolder); | |||
} | |||
} | |||
} | |||
void run() override | |||
{ | |||
setProgress (-1.0); | |||
MemoryBlock zipData; | |||
result = download (zipData); | |||
if (result.wasOk() && ! threadShouldExit()) | |||
result = unzip (zipData); | |||
} | |||
Result download (MemoryBlock& dest) | |||
{ | |||
setStatusMessage ("Downloading..."); | |||
int statusCode = 302; | |||
const int maxRedirects = 5; | |||
// we need to do the redirecting manually due to inconsistencies on the way headers are handled on redirects | |||
ScopedPointer<InputStream> in; | |||
for (int redirect = 0; redirect < maxRedirects; ++redirect) | |||
{ | |||
StringPairArray responseHeaders; | |||
in = url.createInputStream (false, nullptr, nullptr, headers, 10000, &responseHeaders, &statusCode, 0); | |||
if (in == nullptr || statusCode != 302) | |||
break; | |||
String redirectPath = responseHeaders ["Location"]; | |||
if (redirectPath.isEmpty()) | |||
break; | |||
url = LatestVersionChecker::getLatestVersionURL (headers, redirectPath); | |||
} | |||
if (in != nullptr && statusCode == 200) | |||
{ | |||
int64 total = 0; | |||
MemoryOutputStream mo (dest, true); | |||
for (;;) | |||
{ | |||
if (threadShouldExit()) | |||
return Result::fail ("cancel"); | |||
int64 written = mo.writeFromInputStream (*in, 8192); | |||
if (written == 0) | |||
break; | |||
total += written; | |||
setStatusMessage (String (TRANS ("Downloading... (123)")) | |||
.replace ("123", File::descriptionOfSizeInBytes (total))); | |||
} | |||
return Result::ok(); | |||
} | |||
return Result::fail ("Failed to download from: " + url.toString (false)); | |||
} | |||
Result unzip (const MemoryBlock& data) | |||
{ | |||
setStatusMessage ("Installing..."); | |||
File unzipTarget; | |||
bool isUsingTempFolder = false; | |||
{ | |||
MemoryInputStream input (data, false); | |||
ZipFile zip (input); | |||
if (zip.getNumEntries() == 0) | |||
return Result::fail ("The downloaded file wasn't a valid JUCE file!"); | |||
unzipTarget = targetFolder; | |||
if (unzipTarget.exists()) | |||
{ | |||
isUsingTempFolder = true; | |||
unzipTarget = targetFolder.getNonexistentSibling(); | |||
if (! unzipTarget.createDirectory()) | |||
return Result::fail ("Couldn't create a folder to unzip the new version!"); | |||
} | |||
Result r (zip.uncompressTo (unzipTarget)); | |||
if (r.failed()) | |||
{ | |||
if (isUsingTempFolder) | |||
unzipTarget.deleteRecursively(); | |||
return r; | |||
} | |||
} | |||
if (isUsingTempFolder) | |||
{ | |||
File oldFolder (targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old") | |||
.getNonexistentSibling()); | |||
if (! targetFolder.moveFileTo (oldFolder)) | |||
{ | |||
unzipTarget.deleteRecursively(); | |||
return Result::fail ("Could not remove the existing folder!"); | |||
} | |||
if (! unzipTarget.moveFileTo (targetFolder)) | |||
{ | |||
unzipTarget.deleteRecursively(); | |||
return Result::fail ("Could not overwrite the existing folder!"); | |||
} | |||
} | |||
return Result::ok(); | |||
} | |||
Result result; | |||
URL url; | |||
String headers; | |||
File targetFolder; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadNewVersionThread) | |||
}; | |||
//============================================================================== | |||
class UpdateUserDialog : public Component, | |||
public ButtonListener | |||
{ | |||
public: | |||
UpdateUserDialog (const LatestVersionChecker::JuceVersionTriple& version, | |||
const String& releaseNotes, | |||
const char* overwriteFolderPath) | |||
: hasOverwriteButton (overwriteFolderPath != nullptr) | |||
{ | |||
addAndMakeVisible (titleLabel = new Label ("Title Label", | |||
TRANS ("Download JUCE version 123?"). | |||
replace ("123", version.toString()))); | |||
titleLabel->setFont (Font (15.00f, Font::bold)); | |||
titleLabel->setJustificationType (Justification::centredLeft); | |||
titleLabel->setEditable (false, false, false); | |||
titleLabel->setColour (TextEditor::textColourId, Colours::black); | |||
titleLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (contentLabel = new Label ("Content Label", | |||
TRANS("A new version of JUCE is available - would you like to download it?"))); | |||
contentLabel->setFont (Font (15.00f, Font::plain)); | |||
contentLabel->setJustificationType (Justification::topLeft); | |||
contentLabel->setEditable (false, false, false); | |||
contentLabel->setColour (TextEditor::textColourId, Colours::black); | |||
contentLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (okButton = new TextButton ("OK Button")); | |||
okButton->setButtonText (TRANS(hasOverwriteButton ? "Choose Another Folder..." : "OK")); | |||
okButton->addListener (this); | |||
addAndMakeVisible (cancelButton = new TextButton ("Cancel Button")); | |||
cancelButton->setButtonText (TRANS("Cancel")); | |||
cancelButton->addListener (this); | |||
addAndMakeVisible (changeLogLabel = new Label ("Change Log Label", | |||
TRANS("Release Notes:"))); | |||
changeLogLabel->setFont (Font (15.00f, Font::plain)); | |||
changeLogLabel->setJustificationType (Justification::topLeft); | |||
changeLogLabel->setEditable (false, false, false); | |||
changeLogLabel->setColour (TextEditor::textColourId, Colours::black); | |||
changeLogLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (changeLog = new TextEditor ("Change Log")); | |||
changeLog->setMultiLine (true); | |||
changeLog->setReturnKeyStartsNewLine (true); | |||
changeLog->setReadOnly (true); | |||
changeLog->setScrollbarsShown (true); | |||
changeLog->setCaretVisible (false); | |||
changeLog->setPopupMenuEnabled (false); | |||
changeLog->setText (releaseNotes); | |||
if (hasOverwriteButton) | |||
{ | |||
addAndMakeVisible (overwriteLabel = new Label ("Overwrite Label", | |||
TRANS("Updating will overwrite everything in the following folder:"))); | |||
overwriteLabel->setFont (Font (15.00f, Font::plain)); | |||
overwriteLabel->setJustificationType (Justification::topLeft); | |||
overwriteLabel->setEditable (false, false, false); | |||
overwriteLabel->setColour (TextEditor::textColourId, Colours::black); | |||
overwriteLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (overwritePath = new Label ("Overwrite Path", overwriteFolderPath)); | |||
overwritePath->setFont (Font (15.00f, Font::bold)); | |||
overwritePath->setJustificationType (Justification::topLeft); | |||
overwritePath->setEditable (false, false, false); | |||
overwritePath->setColour (TextEditor::textColourId, Colours::black); | |||
overwritePath->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (overwriteButton = new TextButton ("Overwrite Button")); | |||
overwriteButton->setButtonText (TRANS("Overwrite")); | |||
overwriteButton->addListener (this); | |||
} | |||
juceIcon = Drawable::createFromImageData (BinaryData::juce_icon_png, | |||
BinaryData::juce_icon_pngSize); | |||
setSize (518, overwritePath ? 345 : 269); | |||
} | |||
~UpdateUserDialog() | |||
{ | |||
titleLabel = nullptr; | |||
contentLabel = nullptr; | |||
okButton = nullptr; | |||
cancelButton = nullptr; | |||
changeLogLabel = nullptr; | |||
changeLog = nullptr; | |||
overwriteLabel = nullptr; | |||
overwritePath = nullptr; | |||
overwriteButton = nullptr; | |||
juceIcon = nullptr; | |||
} | |||
void paint (Graphics& g) override | |||
{ | |||
g.fillAll (Colours::lightgrey); | |||
g.setColour (Colours::black); | |||
if (juceIcon != nullptr) | |||
juceIcon->drawWithin (g, Rectangle<float> (20, 17, 64, 64), | |||
RectanglePlacement::stretchToFit, 1.000f); | |||
} | |||
void resized() override | |||
{ | |||
titleLabel->setBounds (88, 10, 397, 24); | |||
contentLabel->setBounds (88, 40, 397, 51); | |||
changeLogLabel->setBounds (22, 92, 341, 24); | |||
changeLog->setBounds (24, 112, 476, 102); | |||
if (hasOverwriteButton) | |||
{ | |||
okButton->setBounds (getWidth() - 24 - 174, getHeight() - 37, 174, 28); | |||
overwriteButton->setBounds ((getWidth() - 24 - 174) + -14 - 86, getHeight() - 37, 86, 28); | |||
cancelButton->setBounds (24, getHeight() - 37, 70, 28); | |||
overwriteLabel->setBounds (24, 238, 472, 16); | |||
overwritePath->setBounds (24, 262, 472, 40); | |||
} | |||
else | |||
{ | |||
okButton->setBounds (getWidth() - 24 - 47, getHeight() - 37, 47, 28); | |||
cancelButton->setBounds ((getWidth() - 24 - 47) + -14 - 70, getHeight() - 37, 70, 28); | |||
} | |||
} | |||
void buttonClicked (Button* clickedButton) override | |||
{ | |||
if (DialogWindow* parentDialog = findParentComponentOfClass<DialogWindow>()) | |||
{ | |||
if (clickedButton == overwriteButton) parentDialog->exitModalState (1); | |||
else if (clickedButton == okButton) parentDialog->exitModalState (2); | |||
else if (clickedButton == cancelButton) parentDialog->exitModalState (-1); | |||
} | |||
else | |||
jassertfalse; | |||
} | |||
static DialogWindow* launch (const LatestVersionChecker::JuceVersionTriple& version, | |||
const String& releaseNotes, | |||
const char* overwritePath = nullptr) | |||
{ | |||
OptionalScopedPointer<Component> userDialog (new UpdateUserDialog (version, releaseNotes, overwritePath), true); | |||
DialogWindow::LaunchOptions lo; | |||
lo.dialogTitle = TRANS ("Download JUCE version 123?").replace ("123", version.toString()); | |||
lo.dialogBackgroundColour = Colours::lightgrey; | |||
lo.content = userDialog; | |||
lo.componentToCentreAround = nullptr; | |||
lo.escapeKeyTriggersCloseButton = true; | |||
lo.useNativeTitleBar = true; | |||
lo.resizable = false; | |||
lo.useBottomRightCornerResizer = false; | |||
return lo.launchAsync(); | |||
} | |||
private: | |||
bool hasOverwriteButton; | |||
ScopedPointer<Label> titleLabel, contentLabel, changeLogLabel, overwriteLabel, overwritePath; | |||
ScopedPointer<TextButton> okButton, cancelButton; | |||
ScopedPointer<TextEditor> changeLog; | |||
ScopedPointer<TextButton> overwriteButton; | |||
ScopedPointer<Drawable> juceIcon; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UpdateUserDialog) | |||
}; | |||
//============================================================================== | |||
class UpdaterDialogModalCallback : public ModalComponentManager::Callback | |||
{ | |||
public: | |||
struct DelayedCallback : private Timer | |||
{ | |||
DelayedCallback (LatestVersionChecker& versionChecker, | |||
URL& newVersionToDownload, | |||
const String& extraHeaders, | |||
const File& appParentFolder, | |||
int returnValue) | |||
: parent (versionChecker), download (newVersionToDownload), | |||
headers (extraHeaders), folder (appParentFolder), result (returnValue) | |||
{ | |||
startTimer (200); | |||
} | |||
private: | |||
void timerCallback() override | |||
{ | |||
stopTimer(); | |||
parent.modalStateFinished (result, download, headers, folder); | |||
delete this; | |||
} | |||
LatestVersionChecker& parent; | |||
URL download; | |||
String headers; | |||
File folder; | |||
int result; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DelayedCallback) | |||
}; | |||
UpdaterDialogModalCallback (LatestVersionChecker& versionChecker, | |||
URL& newVersionToDownload, | |||
const String& extraHeaders, | |||
const File& appParentFolder) | |||
: parent (versionChecker), download (newVersionToDownload), | |||
headers (extraHeaders), folder (appParentFolder) | |||
{} | |||
void modalStateFinished (int returnValue) override | |||
{ | |||
// the dialog window is only closed after this function exits | |||
// so we need a deferred callback to the parent. Unfortunately | |||
// our instance is also deleted after this function is used | |||
// so we can't use our own instance for a timer callback | |||
// we must allocate a new one. | |||
new DelayedCallback (parent, download, headers, folder, returnValue); | |||
} | |||
private: | |||
LatestVersionChecker& parent; | |||
URL download; | |||
String headers; | |||
File folder; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UpdaterDialogModalCallback) | |||
}; | |||
//============================================================================== | |||
LatestVersionChecker::LatestVersionChecker() : Thread ("Updater"), | |||
statusCode (-1), | |||
hasAttemptedToReadWebsite (false) | |||
{ | |||
startTimer (2000); | |||
} | |||
LatestVersionChecker::~LatestVersionChecker() | |||
{ | |||
stopThread (20000); | |||
} | |||
String LatestVersionChecker::getOSString() | |||
{ | |||
SystemStats::OperatingSystemType osType = SystemStats::getOperatingSystemType(); | |||
if ((osType & SystemStats::MacOSX) != 0) return "OSX"; | |||
else if ((osType & SystemStats::Windows) != 0) return "Windows"; | |||
else if ((osType & SystemStats::Linux) != 0) return "Linux"; | |||
else return SystemStats::getOperatingSystemName(); | |||
} | |||
URL LatestVersionChecker::getLatestVersionURL (String& headers, const String& path) | |||
{ | |||
static const char* updateSeverHostname = "https://my.roli.com"; | |||
static const char* publicAPIKey = "495fb2d-cce9a8-3c52824-2da2679"; | |||
static const int apiVersion = 1; | |||
static const char* updatePath = "/software_versions/update_to/Introjucer/"; | |||
String updateURL; | |||
bool isAbsolute = (path.startsWith ("http://") || path.startsWith ("https://")); | |||
bool isRedirect = path.isNotEmpty(); | |||
if (isAbsolute) | |||
{ | |||
updateURL = path; | |||
} | |||
else | |||
{ | |||
updateURL << updateSeverHostname | |||
<< (isRedirect ? path : String (updatePath)); | |||
if (! isRedirect) | |||
{ | |||
updateURL << JuceVersionTriple().toString() << '/' | |||
<< getOSString() << "?language=" << SystemStats::getUserLanguage(); | |||
} | |||
} | |||
headers.clear(); | |||
if (! isAbsolute) | |||
{ | |||
headers << "X-API-Key: " << publicAPIKey; | |||
if (! isRedirect) | |||
{ | |||
headers << "\nContent-Type: application/json\n" | |||
<< "Accept: application/json; version=" << apiVersion; | |||
} | |||
} | |||
return URL (updateURL); | |||
} | |||
URL LatestVersionChecker::getLatestVersionURL (String& headers) | |||
{ | |||
String emptyString; | |||
return getLatestVersionURL (headers, emptyString); | |||
} | |||
void LatestVersionChecker::checkForNewVersion() | |||
{ | |||
hasAttemptedToReadWebsite = true; | |||
{ | |||
String extraHeaders; | |||
URL updateURL (getLatestVersionURL (extraHeaders)); | |||
StringPairArray responseHeaders; | |||
const int numRedirects = 0; | |||
const ScopedPointer<InputStream> in (updateURL.createInputStream (false, nullptr, nullptr, | |||
extraHeaders, 0, &responseHeaders, | |||
&statusCode, numRedirects)); | |||
if (in == nullptr || threadShouldExit()) | |||
return; // can't connect: fail silently. | |||
if (statusCode != 303 && statusCode != 400) | |||
return; | |||
// if this doesn't fail then there is a new version available. | |||
// By leaving the scope of this function we will abort the download | |||
// to give the user a chance to cancel an update | |||
if (statusCode == 303) | |||
{ | |||
newRelativeDownloadPath = responseHeaders ["Location"]; | |||
// A 303 without a redirect target? Let's quickly get out of here | |||
if (newRelativeDownloadPath.isEmpty()) | |||
return; | |||
} | |||
jsonReply = JSON::parse (in->readEntireStreamAsString()); | |||
} | |||
if (threadShouldExit()) | |||
return; | |||
if (jsonReply.isObject()) | |||
startTimer (100); | |||
} | |||
void LatestVersionChecker::processResult (var reply, const String& downloadPath) | |||
{ | |||
if (statusCode == 303) | |||
{ | |||
String versionString = reply.getProperty ("version", var()).toString(); | |||
String releaseNotes = reply.getProperty ("notes", var()).toString(); | |||
JuceVersionTriple version; | |||
if (versionString.isNotEmpty() && releaseNotes.isNotEmpty()) | |||
{ | |||
if (JuceVersionTriple::fromString (versionString, version)) | |||
{ | |||
String extraHeaders; | |||
URL newVersionToDownload = getLatestVersionURL (extraHeaders, downloadPath); | |||
askUserAboutNewVersion (version, releaseNotes, newVersionToDownload, extraHeaders); | |||
} | |||
} | |||
} | |||
else if (statusCode == 400) | |||
{ | |||
// In the far-distant future, this may be contacting a defunct | |||
// URL, so hopefully the website will contain a helpful message | |||
// for the user.. | |||
var errorObj = reply.getDynamicObject()->getProperty ("error"); | |||
if (errorObj.isObject()) | |||
{ | |||
String message = errorObj.getProperty ("message", var()).toString(); | |||
if (message.isNotEmpty()) | |||
{ | |||
AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||
TRANS("JUCE Updater"), | |||
message); | |||
} | |||
} | |||
} | |||
} | |||
void LatestVersionChecker::askUserAboutNewVersion (const LatestVersionChecker::JuceVersionTriple& version, | |||
const String& releaseNotes, | |||
URL& newVersionToDownload, | |||
const String& extraHeaders) | |||
{ | |||
// Currently we do not show the release notes | |||
ignoreUnused (releaseNotes); | |||
JuceVersionTriple currentVersion; | |||
if (version > currentVersion) | |||
{ | |||
File appParentFolder (File::getSpecialLocation (File::currentApplicationFile).getParentDirectory()); | |||
DialogWindow* modalDialog = nullptr; | |||
if (isZipFolder (appParentFolder)) | |||
{ | |||
modalDialog = UpdateUserDialog::launch (version, releaseNotes, | |||
appParentFolder.getFullPathName().toRawUTF8()); | |||
} | |||
else | |||
{ | |||
modalDialog = UpdateUserDialog::launch (version, releaseNotes); | |||
} | |||
if (modalDialog != nullptr) | |||
{ | |||
UpdaterDialogModalCallback* callback = new UpdaterDialogModalCallback (*this, | |||
newVersionToDownload, | |||
extraHeaders, | |||
appParentFolder); | |||
// attachCallback will delete callback | |||
if (ModalComponentManager* mm = ModalComponentManager::getInstance()) | |||
mm->attachCallback (modalDialog, callback); | |||
} | |||
} | |||
} | |||
void LatestVersionChecker::modalStateFinished (int result, | |||
URL& newVersionToDownload, | |||
const String& extraHeaders, | |||
File appParentFolder) | |||
{ | |||
if (result == 1) | |||
DownloadNewVersionThread::performDownload (newVersionToDownload, extraHeaders, appParentFolder); | |||
if (result == 2) | |||
askUserForLocationToDownload (newVersionToDownload, extraHeaders); | |||
} | |||
void LatestVersionChecker::askUserForLocationToDownload (URL& newVersionToDownload, const String& extraHeaders) | |||
{ | |||
File targetFolder (findDefaultModulesFolder()); | |||
if (isJuceModulesFolder (targetFolder)) | |||
targetFolder = targetFolder.getParentDirectory(); | |||
FileChooser chooser (TRANS("Please select the location into which you'd like to install the new version"), | |||
targetFolder); | |||
if (chooser.browseForDirectory()) | |||
{ | |||
targetFolder = chooser.getResult(); | |||
if (isJuceModulesFolder (targetFolder)) | |||
targetFolder = targetFolder.getParentDirectory(); | |||
if (targetFolder.getChildFile ("JUCE").isDirectory()) | |||
targetFolder = targetFolder.getChildFile ("JUCE"); | |||
if (targetFolder.getChildFile (".git").isDirectory()) | |||
{ | |||
AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||
TRANS ("Downloading new JUCE version"), | |||
TRANS ("This folder is a GIT repository!\n\n" | |||
"You should use a \"git pull\" to update it to the latest version. " | |||
"Or to use the Introjucer to get an update, you should select an empty " | |||
"folder into which you'd like to download the new code.")); | |||
return; | |||
} | |||
if (isJuceFolder (targetFolder)) | |||
{ | |||
if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | |||
TRANS("Overwrite existing JUCE folder?"), | |||
TRANS("Do you want to overwrite the folder:\n\n" | |||
"xfldrx\n\n" | |||
" ..with the latest version from juce.com?\n\n" | |||
"(Please note that this will overwrite everything in that folder!)") | |||
.replace ("xfldrx", targetFolder.getFullPathName()))) | |||
{ | |||
return; | |||
} | |||
} | |||
else | |||
{ | |||
targetFolder = targetFolder.getChildFile ("JUCE").getNonexistentSibling(); | |||
} | |||
DownloadNewVersionThread::performDownload (newVersionToDownload, extraHeaders, targetFolder); | |||
} | |||
} | |||
bool LatestVersionChecker::isZipFolder (const File& f) | |||
{ | |||
return f.getChildFile ("modules").isDirectory() | |||
&& f.getChildFile ("extras").isDirectory() | |||
&& f.getChildFile ("examples").isDirectory() | |||
&& ! f.getChildFile (".git").isDirectory(); | |||
} | |||
void LatestVersionChecker::timerCallback() | |||
{ | |||
stopTimer(); | |||
if (hasAttemptedToReadWebsite) | |||
processResult (jsonReply, newRelativeDownloadPath); | |||
else | |||
startThread (3); | |||
} | |||
void LatestVersionChecker::run() | |||
{ | |||
checkForNewVersion(); | |||
} |
@@ -25,395 +25,63 @@ | |||
#ifndef JUCER_AUTOUPDATER_H_INCLUDED | |||
#define JUCER_AUTOUPDATER_H_INCLUDED | |||
class UpdaterDialogModalCallback; | |||
//============================================================================== | |||
class LatestVersionChecker : private Thread, | |||
private Timer | |||
{ | |||
public: | |||
LatestVersionChecker() : Thread ("Updater"), | |||
hasAttemptedToReadWebsite (false) | |||
{ | |||
startTimer (2000); | |||
} | |||
~LatestVersionChecker() | |||
{ | |||
stopThread (20000); | |||
} | |||
static URL getLatestVersionURL() | |||
{ | |||
return URL ("http://www.juce.com/juce/updates/updatelist.php"); | |||
} | |||
void checkForNewVersion() | |||
{ | |||
hasAttemptedToReadWebsite = true; | |||
{ | |||
const ScopedPointer<InputStream> in (getLatestVersionURL().createInputStream (false)); | |||
if (in == nullptr || threadShouldExit()) | |||
return; // can't connect: fail silently. | |||
jsonReply = JSON::parse (in->readEntireStreamAsString()); | |||
} | |||
if (threadShouldExit()) | |||
return; | |||
if (jsonReply.isArray() || jsonReply.isObject()) | |||
startTimer (100); | |||
} | |||
void processResult (var reply) | |||
{ | |||
if (reply.isArray()) | |||
{ | |||
askUserAboutNewVersion (VersionInfo (reply[0])); | |||
} | |||
else if (reply.isObject()) | |||
{ | |||
// In the far-distant future, this may be contacting a defunct | |||
// URL, so hopefully the website will contain a helpful message | |||
// for the user.. | |||
String message = reply.getProperty ("message", var()).toString(); | |||
if (message.isNotEmpty()) | |||
{ | |||
AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||
TRANS("JUCE Updater"), | |||
message); | |||
} | |||
} | |||
} | |||
struct VersionInfo | |||
struct JuceVersionTriple | |||
{ | |||
VersionInfo (var v) | |||
{ | |||
version = v.getProperty ("version", var()).toString().trim(); | |||
JuceVersionTriple(); | |||
JuceVersionTriple (int majorInt, int minorInt, int buildNumber); | |||
url = v.getProperty ( | |||
#if JUCE_MAC | |||
"url_osx", | |||
#elif JUCE_WINDOWS | |||
"url_win", | |||
#elif JUCE_LINUX | |||
"url_linux", | |||
#endif | |||
var()).toString(); | |||
} | |||
static bool fromString (const String& versionString, JuceVersionTriple& result); | |||
String toString() const; | |||
bool isDifferentVersionToCurrent() const | |||
{ | |||
return version != JUCE_STRINGIFY(JUCE_MAJOR_VERSION) | |||
"." JUCE_STRINGIFY(JUCE_MINOR_VERSION) | |||
"." JUCE_STRINGIFY(JUCE_BUILDNUMBER) | |||
&& version.containsChar ('.') | |||
&& version.length() > 2; | |||
} | |||
bool operator> (const JuceVersionTriple& b) const noexcept; | |||
String version; | |||
URL url; | |||
int major, minor, build; | |||
}; | |||
void askUserAboutNewVersion (const VersionInfo& info) | |||
{ | |||
if (info.isDifferentVersionToCurrent()) | |||
{ | |||
File appParentFolder (File::getSpecialLocation (File::currentApplicationFile).getParentDirectory()); | |||
if (isZipFolder (appParentFolder)) | |||
{ | |||
int result = AlertWindow::showYesNoCancelBox (AlertWindow::InfoIcon, | |||
TRANS("Download JUCE version 123?").replace ("123", info.version), | |||
TRANS("A new version of JUCE is available - would you like to overwrite the folder:\n\n" | |||
"xfldrx\n\n" | |||
" ..with the latest version from juce.com?\n\n" | |||
"(Please note that this will overwrite everything in that folder!)") | |||
.replace ("xfldrx", appParentFolder.getFullPathName()), | |||
TRANS("Overwrite"), | |||
TRANS("Choose another folder..."), | |||
TRANS("Cancel")); | |||
if (result == 1) | |||
DownloadNewVersionThread::performDownload (info.url, appParentFolder); | |||
if (result == 2) | |||
askUserForLocationToDownload (info); | |||
} | |||
else | |||
{ | |||
if (AlertWindow::showOkCancelBox (AlertWindow::InfoIcon, | |||
TRANS("Download JUCE version 123?").replace ("123", info.version), | |||
TRANS("A new version of JUCE is available - would you like to download it?"))) | |||
askUserForLocationToDownload (info); | |||
} | |||
} | |||
} | |||
void askUserForLocationToDownload (const VersionInfo& info) | |||
{ | |||
File targetFolder (findDefaultModulesFolder()); | |||
if (isJuceModulesFolder (targetFolder)) | |||
targetFolder = targetFolder.getParentDirectory(); | |||
FileChooser chooser (TRANS("Please select the location into which you'd like to install the new version"), | |||
targetFolder); | |||
if (chooser.browseForDirectory()) | |||
{ | |||
targetFolder = chooser.getResult(); | |||
//============================================================================== | |||
LatestVersionChecker(); | |||
~LatestVersionChecker(); | |||
if (isJuceModulesFolder (targetFolder)) | |||
targetFolder = targetFolder.getParentDirectory(); | |||
static String getOSString(); | |||
if (targetFolder.getChildFile ("JUCE").isDirectory()) | |||
targetFolder = targetFolder.getChildFile ("JUCE"); | |||
static URL getLatestVersionURL (String& headers, const String& path); | |||
static URL getLatestVersionURL (String& headers); | |||
if (targetFolder.getChildFile (".git").isDirectory()) | |||
{ | |||
AlertWindow::showMessageBox (AlertWindow::WarningIcon, | |||
TRANS ("Downloading new JUCE version"), | |||
TRANS ("This folder is a GIT repository!\n\n" | |||
"You should use a \"git pull\" to update it to the latest version. " | |||
"Or to use the Introjucer to get an update, you should select an empty " | |||
"folder into which you'd like to download the new code.")); | |||
void checkForNewVersion(); | |||
void processResult (var reply, const String& downloadPath); | |||
return; | |||
} | |||
void askUserAboutNewVersion (const JuceVersionTriple& version, | |||
const String& releaseNotes, | |||
URL& newVersionToDownload, | |||
const String& extraHeaders); | |||
if (isJuceFolder (targetFolder)) | |||
{ | |||
if (! AlertWindow::showOkCancelBox (AlertWindow::WarningIcon, | |||
TRANS("Overwrite existing JUCE folder?"), | |||
TRANS("Do you want to overwrite the folder:\n\n" | |||
"xfldrx\n\n" | |||
" ..with the latest version from juce.com?\n\n" | |||
"(Please note that this will overwrite everything in that folder!)") | |||
.replace ("xfldrx", targetFolder.getFullPathName()))) | |||
{ | |||
return; | |||
} | |||
} | |||
else | |||
{ | |||
targetFolder = targetFolder.getChildFile ("JUCE").getNonexistentSibling(); | |||
} | |||
void askUserForLocationToDownload (URL& newVersionToDownload, const String& extraHeaders); | |||
DownloadNewVersionThread::performDownload (info.url, targetFolder); | |||
} | |||
} | |||
static bool isZipFolder (const File& f) | |||
{ | |||
return f.getChildFile ("modules").isDirectory() | |||
&& f.getChildFile ("extras").isDirectory() | |||
&& f.getChildFile ("examples").isDirectory() | |||
&& ! f.getChildFile (".git").isDirectory(); | |||
} | |||
static bool isZipFolder (const File&); | |||
private: | |||
void timerCallback() override | |||
{ | |||
stopTimer(); | |||
if (hasAttemptedToReadWebsite) | |||
processResult (jsonReply); | |||
else | |||
startThread (3); | |||
} | |||
//============================================================================== | |||
friend class UpdaterDialogModalCallback; | |||
void run() override | |||
{ | |||
checkForNewVersion(); | |||
} | |||
// callbacks | |||
void timerCallback() override; | |||
void run() override; | |||
void modalStateFinished (int result, | |||
URL& newVersionToDownload, | |||
const String& extraHeaders, | |||
File appParentFolder); | |||
int statusCode; | |||
var jsonReply; | |||
bool hasAttemptedToReadWebsite; | |||
URL newVersionToDownload; | |||
//============================================================================== | |||
class DownloadNewVersionThread : public ThreadWithProgressWindow | |||
{ | |||
public: | |||
DownloadNewVersionThread (URL u, File target) | |||
: ThreadWithProgressWindow ("Downloading New Version", true, true), | |||
result (Result::ok()), | |||
url (u), targetFolder (target) | |||
{ | |||
} | |||
static void performDownload (URL u, File targetFolder) | |||
{ | |||
DownloadNewVersionThread d (u, targetFolder); | |||
if (d.runThread()) | |||
{ | |||
if (d.result.failed()) | |||
{ | |||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon, | |||
"Installation Failed", | |||
d.result.getErrorMessage()); | |||
} | |||
else | |||
{ | |||
new RelaunchTimer (targetFolder); | |||
} | |||
} | |||
} | |||
void run() override | |||
{ | |||
setProgress (-1.0); | |||
MemoryBlock zipData; | |||
result = download (zipData); | |||
if (result.wasOk() && ! threadShouldExit()) | |||
result = unzip (zipData); | |||
} | |||
Result download (MemoryBlock& dest) | |||
{ | |||
setStatusMessage ("Downloading..."); | |||
const ScopedPointer<InputStream> in (url.createInputStream (false, nullptr, nullptr, String::empty, 10000)); | |||
if (in != nullptr) | |||
{ | |||
int64 total = 0; | |||
MemoryOutputStream mo (dest, true); | |||
for (;;) | |||
{ | |||
if (threadShouldExit()) | |||
return Result::fail ("cancel"); | |||
int64 written = mo.writeFromInputStream (*in, 8192); | |||
if (written == 0) | |||
break; | |||
total += written; | |||
setStatusMessage (String (TRANS ("Downloading... (123)")) | |||
.replace ("123", File::descriptionOfSizeInBytes (total))); | |||
} | |||
return Result::ok(); | |||
} | |||
return Result::fail ("Failed to download from: " + url.toString (false)); | |||
} | |||
Result unzip (const MemoryBlock& data) | |||
{ | |||
setStatusMessage ("Installing..."); | |||
File unzipTarget; | |||
bool isUsingTempFolder = false; | |||
{ | |||
MemoryInputStream input (data, false); | |||
ZipFile zip (input); | |||
if (zip.getNumEntries() == 0) | |||
return Result::fail ("The downloaded file wasn't a valid JUCE file!"); | |||
unzipTarget = targetFolder; | |||
if (unzipTarget.exists()) | |||
{ | |||
isUsingTempFolder = true; | |||
unzipTarget = targetFolder.getNonexistentSibling(); | |||
if (! unzipTarget.createDirectory()) | |||
return Result::fail ("Couldn't create a folder to unzip the new version!"); | |||
} | |||
Result r (zip.uncompressTo (unzipTarget)); | |||
if (r.failed()) | |||
{ | |||
if (isUsingTempFolder) | |||
unzipTarget.deleteRecursively(); | |||
return r; | |||
} | |||
} | |||
if (isUsingTempFolder) | |||
{ | |||
File oldFolder (targetFolder.getSiblingFile (targetFolder.getFileNameWithoutExtension() + "_old").getNonexistentSibling()); | |||
if (! targetFolder.moveFileTo (oldFolder)) | |||
{ | |||
unzipTarget.deleteRecursively(); | |||
return Result::fail ("Could not remove the existing folder!"); | |||
} | |||
if (! unzipTarget.moveFileTo (targetFolder)) | |||
{ | |||
unzipTarget.deleteRecursively(); | |||
return Result::fail ("Could not overwrite the existing folder!"); | |||
} | |||
} | |||
return Result::ok(); | |||
} | |||
Result result; | |||
URL url; | |||
File targetFolder; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadNewVersionThread) | |||
}; | |||
struct RelaunchTimer : private Timer | |||
{ | |||
RelaunchTimer (const File& f) : parentFolder (f) | |||
{ | |||
startTimer (1500); | |||
} | |||
void timerCallback() override | |||
{ | |||
stopTimer(); | |||
File app = parentFolder.getChildFile ( | |||
#if JUCE_MAC | |||
"Introjucer.app"); | |||
#elif JUCE_WINDOWS | |||
"Introjucer.exe"); | |||
#elif JUCE_LINUX | |||
"Introjucer"); | |||
#endif | |||
JUCEApplication::quit(); | |||
if (app.exists()) | |||
{ | |||
app.setExecutePermission (true); | |||
#if JUCE_MAC | |||
app.getChildFile("Contents") | |||
.getChildFile("MacOS") | |||
.getChildFile("Introjucer").setExecutePermission (true); | |||
#endif | |||
app.startAsProcess(); | |||
} | |||
delete this; | |||
} | |||
File parentFolder; | |||
}; | |||
String newRelativeDownloadPath; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LatestVersionChecker) | |||
}; | |||
@@ -114,6 +114,8 @@ | |||
#undef TYPE_BOOL | |||
#undef max | |||
#undef min | |||
#undef major | |||
#undef minor | |||
//============================================================================== | |||
// DLL building settings on Windows | |||