mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Add release notes text field to Introjucer's auto-updater dialog. Minor auto-updater infrastructure updates and code refactoring.
This commit is contained in:
parent
5fc9f44581
commit
0e7729590f
16 changed files with 928 additions and 398 deletions
|
|
@ -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
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
789
extras/Introjucer/Source/Application/jucer_AutoUpdater.cpp
Normal file
789
extras/Introjucer/Source/Application/jucer_AutoUpdater.cpp
Normal file
|
|
@ -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)
|
||||
struct JuceVersionTriple
|
||||
{
|
||||
startTimer (2000);
|
||||
}
|
||||
JuceVersionTriple();
|
||||
JuceVersionTriple (int majorInt, int minorInt, int buildNumber);
|
||||
|
||||
~LatestVersionChecker()
|
||||
{
|
||||
stopThread (20000);
|
||||
}
|
||||
static bool fromString (const String& versionString, JuceVersionTriple& result);
|
||||
String toString() const;
|
||||
|
||||
static URL getLatestVersionURL()
|
||||
{
|
||||
return URL ("http://www.juce.com/juce/updates/updatelist.php");
|
||||
}
|
||||
bool operator> (const JuceVersionTriple& b) const noexcept;
|
||||
|
||||
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
|
||||
{
|
||||
VersionInfo (var v)
|
||||
{
|
||||
version = v.getProperty ("version", var()).toString().trim();
|
||||
|
||||
url = v.getProperty (
|
||||
#if JUCE_MAC
|
||||
"url_osx",
|
||||
#elif JUCE_WINDOWS
|
||||
"url_win",
|
||||
#elif JUCE_LINUX
|
||||
"url_linux",
|
||||
#endif
|
||||
var()).toString();
|
||||
}
|
||||
|
||||
bool isDifferentVersionToCurrent() const
|
||||
{
|
||||
return version != JUCE_STRINGIFY(JUCE_MAJOR_VERSION)
|
||||
"." JUCE_STRINGIFY(JUCE_MINOR_VERSION)
|
||||
"." JUCE_STRINGIFY(JUCE_BUILDNUMBER)
|
||||
&& version.containsChar ('.')
|
||||
&& version.length() > 2;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
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 (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();
|
||||
}
|
||||
|
||||
private:
|
||||
void timerCallback() override
|
||||
{
|
||||
stopTimer();
|
||||
|
||||
if (hasAttemptedToReadWebsite)
|
||||
processResult (jsonReply);
|
||||
else
|
||||
startThread (3);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
checkForNewVersion();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
LatestVersionChecker();
|
||||
~LatestVersionChecker();
|
||||
|
||||
static void performDownload (URL u, File targetFolder)
|
||||
{
|
||||
DownloadNewVersionThread d (u, targetFolder);
|
||||
static String getOSString();
|
||||
|
||||
if (d.runThread())
|
||||
{
|
||||
if (d.result.failed())
|
||||
{
|
||||
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
|
||||
"Installation Failed",
|
||||
d.result.getErrorMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
new RelaunchTimer (targetFolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
static URL getLatestVersionURL (String& headers, const String& path);
|
||||
static URL getLatestVersionURL (String& headers);
|
||||
|
||||
void run() override
|
||||
{
|
||||
setProgress (-1.0);
|
||||
void checkForNewVersion();
|
||||
void processResult (var reply, const String& downloadPath);
|
||||
|
||||
MemoryBlock zipData;
|
||||
result = download (zipData);
|
||||
void askUserAboutNewVersion (const JuceVersionTriple& version,
|
||||
const String& releaseNotes,
|
||||
URL& newVersionToDownload,
|
||||
const String& extraHeaders);
|
||||
|
||||
if (result.wasOk() && ! threadShouldExit())
|
||||
result = unzip (zipData);
|
||||
}
|
||||
void askUserForLocationToDownload (URL& newVersionToDownload, const String& extraHeaders);
|
||||
|
||||
Result download (MemoryBlock& dest)
|
||||
{
|
||||
setStatusMessage ("Downloading...");
|
||||
static bool isZipFolder (const File&);
|
||||
|
||||
const ScopedPointer<InputStream> in (url.createInputStream (false, nullptr, nullptr, String::empty, 10000));
|
||||
private:
|
||||
//==============================================================================
|
||||
friend class UpdaterDialogModalCallback;
|
||||
|
||||
if (in != nullptr)
|
||||
{
|
||||
int64 total = 0;
|
||||
MemoryOutputStream mo (dest, true);
|
||||
// callbacks
|
||||
void timerCallback() override;
|
||||
void run() override;
|
||||
void modalStateFinished (int result,
|
||||
URL& newVersionToDownload,
|
||||
const String& extraHeaders,
|
||||
File appParentFolder);
|
||||
|
||||
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;
|
||||
};
|
||||
int statusCode;
|
||||
var jsonReply;
|
||||
bool hasAttemptedToReadWebsite;
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue