| @@ -45,6 +45,7 @@ endif | |||||
| OBJECTS := \ | OBJECTS := \ | ||||
| $(OBJDIR)/jucer_DocumentEditorComponent_695dff1d.o \ | $(OBJDIR)/jucer_DocumentEditorComponent_695dff1d.o \ | ||||
| $(OBJDIR)/jucer_FilePreviewComponent_55512f53.o \ | $(OBJDIR)/jucer_FilePreviewComponent_55512f53.o \ | ||||
| $(OBJDIR)/jucer_JuceUpdater_cf7865c4.o \ | |||||
| $(OBJDIR)/jucer_Main_f8488f5b.o \ | $(OBJDIR)/jucer_Main_f8488f5b.o \ | ||||
| $(OBJDIR)/jucer_MainWindow_1e163aeb.o \ | $(OBJDIR)/jucer_MainWindow_1e163aeb.o \ | ||||
| $(OBJDIR)/jucer_OpenDocumentManager_4c72d210.o \ | $(OBJDIR)/jucer_OpenDocumentManager_4c72d210.o \ | ||||
| @@ -95,6 +96,11 @@ $(OBJDIR)/jucer_FilePreviewComponent_55512f53.o: ../../Source/Application/jucer_ | |||||
| @echo "Compiling jucer_FilePreviewComponent.cpp" | @echo "Compiling jucer_FilePreviewComponent.cpp" | ||||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | ||||
| $(OBJDIR)/jucer_JuceUpdater_cf7865c4.o: ../../Source/Application/jucer_JuceUpdater.cpp | |||||
| -@mkdir -p $(OBJDIR) | |||||
| @echo "Compiling jucer_JuceUpdater.cpp" | |||||
| @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" | |||||
| $(OBJDIR)/jucer_Main_f8488f5b.o: ../../Source/Application/jucer_Main.cpp | $(OBJDIR)/jucer_Main_f8488f5b.o: ../../Source/Application/jucer_Main.cpp | ||||
| -@mkdir -p $(OBJDIR) | -@mkdir -p $(OBJDIR) | ||||
| @echo "Compiling jucer_Main.cpp" | @echo "Compiling jucer_Main.cpp" | ||||
| @@ -19,6 +19,7 @@ | |||||
| 2E6836738CE7EB452FDC7E9A = { isa = PBXBuildFile; fileRef = D9FB1A5365FEEB854A0FF7BF; }; | 2E6836738CE7EB452FDC7E9A = { isa = PBXBuildFile; fileRef = D9FB1A5365FEEB854A0FF7BF; }; | ||||
| D6D0659F3F3504012246F13D = { isa = PBXBuildFile; fileRef = AA3CBE4A2AC3E9411426F630; }; | D6D0659F3F3504012246F13D = { isa = PBXBuildFile; fileRef = AA3CBE4A2AC3E9411426F630; }; | ||||
| 8BAE4D8EA7F247DA0A4D3A5C = { isa = PBXBuildFile; fileRef = F617CE0630ADB0628A34D6BF; }; | 8BAE4D8EA7F247DA0A4D3A5C = { isa = PBXBuildFile; fileRef = F617CE0630ADB0628A34D6BF; }; | ||||
| 280FE650B3F02AD9E821EA37 = { isa = PBXBuildFile; fileRef = 832701705EC0EC9484F9D9C2; }; | |||||
| 9950893AA82F86F1EEE55BED = { isa = PBXBuildFile; fileRef = D77EAC704C96F798B1C69A0D; }; | 9950893AA82F86F1EEE55BED = { isa = PBXBuildFile; fileRef = D77EAC704C96F798B1C69A0D; }; | ||||
| C2F198C7058FC1A88A600645 = { isa = PBXBuildFile; fileRef = B06694E3C7EB89E3DDEFCBD0; }; | C2F198C7058FC1A88A600645 = { isa = PBXBuildFile; fileRef = B06694E3C7EB89E3DDEFCBD0; }; | ||||
| A7C05B907BBCB4288FBC6428 = { isa = PBXBuildFile; fileRef = 194F6B951CBC3E8F897FB646; }; | A7C05B907BBCB4288FBC6428 = { isa = PBXBuildFile; fileRef = 194F6B951CBC3E8F897FB646; }; | ||||
| @@ -64,6 +65,8 @@ | |||||
| F617CE0630ADB0628A34D6BF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_FilePreviewComponent.cpp; path = ../../Source/Application/jucer_FilePreviewComponent.cpp; sourceTree = SOURCE_ROOT; }; | F617CE0630ADB0628A34D6BF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_FilePreviewComponent.cpp; path = ../../Source/Application/jucer_FilePreviewComponent.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 330CB15608DEAF19D28C18DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_FilePreviewComponent.h; path = ../../Source/Application/jucer_FilePreviewComponent.h; sourceTree = SOURCE_ROOT; }; | 330CB15608DEAF19D28C18DD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_FilePreviewComponent.h; path = ../../Source/Application/jucer_FilePreviewComponent.h; sourceTree = SOURCE_ROOT; }; | ||||
| 0CA0CCCEBFA0AC8C577FC915 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Headers.h; path = ../../Source/jucer_Headers.h; sourceTree = SOURCE_ROOT; }; | 0CA0CCCEBFA0AC8C577FC915 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Headers.h; path = ../../Source/jucer_Headers.h; sourceTree = SOURCE_ROOT; }; | ||||
| 832701705EC0EC9484F9D9C2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_JuceUpdater.cpp; path = ../../Source/Application/jucer_JuceUpdater.cpp; sourceTree = SOURCE_ROOT; }; | |||||
| AFC2F9A887CDBF7A0051CD09 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_JuceUpdater.h; path = ../../Source/Application/jucer_JuceUpdater.h; sourceTree = SOURCE_ROOT; }; | |||||
| D77EAC704C96F798B1C69A0D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Main.cpp; path = ../../Source/Application/jucer_Main.cpp; sourceTree = SOURCE_ROOT; }; | D77EAC704C96F798B1C69A0D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Main.cpp; path = ../../Source/Application/jucer_Main.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| B06694E3C7EB89E3DDEFCBD0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MainWindow.cpp; path = ../../Source/Application/jucer_MainWindow.cpp; sourceTree = SOURCE_ROOT; }; | B06694E3C7EB89E3DDEFCBD0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_MainWindow.cpp; path = ../../Source/Application/jucer_MainWindow.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| 24378294003DC2D038D0534D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_MainWindow.h; path = ../../Source/Application/jucer_MainWindow.h; sourceTree = SOURCE_ROOT; }; | 24378294003DC2D038D0534D = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_MainWindow.h; path = ../../Source/Application/jucer_MainWindow.h; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -139,6 +142,8 @@ | |||||
| F617CE0630ADB0628A34D6BF, | F617CE0630ADB0628A34D6BF, | ||||
| 330CB15608DEAF19D28C18DD, | 330CB15608DEAF19D28C18DD, | ||||
| 0CA0CCCEBFA0AC8C577FC915, | 0CA0CCCEBFA0AC8C577FC915, | ||||
| 832701705EC0EC9484F9D9C2, | |||||
| AFC2F9A887CDBF7A0051CD09, | |||||
| D77EAC704C96F798B1C69A0D, | D77EAC704C96F798B1C69A0D, | ||||
| B06694E3C7EB89E3DDEFCBD0, | B06694E3C7EB89E3DDEFCBD0, | ||||
| 24378294003DC2D038D0534D, | 24378294003DC2D038D0534D, | ||||
| @@ -304,6 +309,7 @@ | |||||
| 5362E03ADF975A126C1F2F7B = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | 5362E03ADF975A126C1F2F7B = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | ||||
| D6D0659F3F3504012246F13D, | D6D0659F3F3504012246F13D, | ||||
| 8BAE4D8EA7F247DA0A4D3A5C, | 8BAE4D8EA7F247DA0A4D3A5C, | ||||
| 280FE650B3F02AD9E821EA37, | |||||
| 9950893AA82F86F1EEE55BED, | 9950893AA82F86F1EEE55BED, | ||||
| C2F198C7058FC1A88A600645, | C2F198C7058FC1A88A600645, | ||||
| A7C05B907BBCB4288FBC6428, | A7C05B907BBCB4288FBC6428, | ||||
| @@ -137,6 +137,8 @@ | |||||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.h"/> | <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.h"/> | ||||
| <File RelativePath="..\..\Source\jucer_Headers.h"/> | <File RelativePath="..\..\Source\jucer_Headers.h"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_JuceUpdater.cpp"/> | |||||
| <File RelativePath="..\..\Source\Application\jucer_JuceUpdater.h"/> | |||||
| <File RelativePath="..\..\Source\Application\jucer_Main.cpp"/> | <File RelativePath="..\..\Source\Application\jucer_Main.cpp"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_MainWindow.cpp"/> | <File RelativePath="..\..\Source\Application\jucer_MainWindow.cpp"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_MainWindow.h"/> | <File RelativePath="..\..\Source\Application\jucer_MainWindow.h"/> | ||||
| @@ -137,6 +137,8 @@ | |||||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.h"/> | <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.h"/> | ||||
| <File RelativePath="..\..\Source\jucer_Headers.h"/> | <File RelativePath="..\..\Source\jucer_Headers.h"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_JuceUpdater.cpp"/> | |||||
| <File RelativePath="..\..\Source\Application\jucer_JuceUpdater.h"/> | |||||
| <File RelativePath="..\..\Source\Application\jucer_Main.cpp"/> | <File RelativePath="..\..\Source\Application\jucer_Main.cpp"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_MainWindow.cpp"/> | <File RelativePath="..\..\Source\Application\jucer_MainWindow.cpp"/> | ||||
| <File RelativePath="..\..\Source\Application\jucer_MainWindow.h"/> | <File RelativePath="..\..\Source\Application\jucer_MainWindow.h"/> | ||||
| @@ -124,6 +124,7 @@ | |||||
| <ItemGroup> | <ItemGroup> | ||||
| <ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/> | <ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.cpp"/> | ||||
| <ClCompile Include="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | <ClCompile Include="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | ||||
| <ClCompile Include="..\..\Source\Application\jucer_JuceUpdater.cpp"/> | |||||
| <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> | <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"/> | ||||
| <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/> | <ClCompile Include="..\..\Source\Application\jucer_MainWindow.cpp"/> | ||||
| <ClCompile Include="..\..\Source\Application\jucer_OpenDocumentManager.cpp"/> | <ClCompile Include="..\..\Source\Application\jucer_OpenDocumentManager.cpp"/> | ||||
| @@ -156,6 +157,7 @@ | |||||
| <ClInclude Include="..\..\Source\Application\jucer_DocumentEditorComponent.h"/> | <ClInclude Include="..\..\Source\Application\jucer_DocumentEditorComponent.h"/> | ||||
| <ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h"/> | <ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.h"/> | ||||
| <ClInclude Include="..\..\Source\jucer_Headers.h"/> | <ClInclude Include="..\..\Source\jucer_Headers.h"/> | ||||
| <ClInclude Include="..\..\Source\Application\jucer_JuceUpdater.h"/> | |||||
| <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/> | <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"/> | ||||
| <ClInclude Include="..\..\Source\Application\jucer_OpenDocumentManager.h"/> | <ClInclude Include="..\..\Source\Application\jucer_OpenDocumentManager.h"/> | ||||
| <ClInclude Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"/> | <ClInclude Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"/> | ||||
| @@ -31,6 +31,9 @@ | |||||
| <ClCompile Include="..\..\Source\Application\jucer_FilePreviewComponent.cpp"> | <ClCompile Include="..\..\Source\Application\jucer_FilePreviewComponent.cpp"> | ||||
| <Filter>The Jucer\Application</Filter> | <Filter>The Jucer\Application</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||
| <ClCompile Include="..\..\Source\Application\jucer_JuceUpdater.cpp"> | |||||
| <Filter>The Jucer\Application</Filter> | |||||
| </ClCompile> | |||||
| <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"> | <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"> | ||||
| <Filter>The Jucer\Application</Filter> | <Filter>The Jucer\Application</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||
| @@ -150,6 +153,9 @@ | |||||
| <ClInclude Include="..\..\Source\jucer_Headers.h"> | <ClInclude Include="..\..\Source\jucer_Headers.h"> | ||||
| <Filter>The Jucer\Application</Filter> | <Filter>The Jucer\Application</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\Source\Application\jucer_JuceUpdater.h"> | |||||
| <Filter>The Jucer\Application</Filter> | |||||
| </ClInclude> | |||||
| <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"> | <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"> | ||||
| <Filter>The Jucer\Application</Filter> | <Filter>The Jucer\Application</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| @@ -45,6 +45,10 @@ | |||||
| resource="0" file="Source/Application/jucer_FilePreviewComponent.h"/> | resource="0" file="Source/Application/jucer_FilePreviewComponent.h"/> | ||||
| <FILE id="qXOJtpg" name="jucer_Headers.h" compile="0" resource="0" | <FILE id="qXOJtpg" name="jucer_Headers.h" compile="0" resource="0" | ||||
| file="Source/jucer_Headers.h"/> | file="Source/jucer_Headers.h"/> | ||||
| <FILE id="uXkdSAZ" name="jucer_JuceUpdater.cpp" compile="1" resource="0" | |||||
| file="Source/Application/jucer_JuceUpdater.cpp"/> | |||||
| <FILE id="QWUk0cM" name="jucer_JuceUpdater.h" compile="0" resource="0" | |||||
| file="Source/Application/jucer_JuceUpdater.h"/> | |||||
| <FILE id="ga7xgxf" name="jucer_Main.cpp" compile="1" resource="0" file="Source/Application/jucer_Main.cpp"/> | <FILE id="ga7xgxf" name="jucer_Main.cpp" compile="1" resource="0" file="Source/Application/jucer_Main.cpp"/> | ||||
| <FILE id="Glk9Bg" name="jucer_MainWindow.cpp" compile="1" resource="0" | <FILE id="Glk9Bg" name="jucer_MainWindow.cpp" compile="1" resource="0" | ||||
| file="Source/Application/jucer_MainWindow.cpp"/> | file="Source/Application/jucer_MainWindow.cpp"/> | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "../jucer_Headers.h" | #include "../jucer_Headers.h" | ||||
| #include "jucer_MainWindow.h" | #include "jucer_MainWindow.h" | ||||
| #include "jucer_JuceUpdater.h" | |||||
| #include "../Project/jucer_NewProjectWizard.h" | #include "../Project/jucer_NewProjectWizard.h" | ||||
| @@ -161,7 +162,7 @@ public: | |||||
| const StringArray getMenuBarNames() | const StringArray getMenuBarNames() | ||||
| { | { | ||||
| const char* const names[] = { "File", "Edit", "View", "Window", 0 }; | |||||
| const char* const names[] = { "File", "Edit", "View", "Window", "Update", 0 }; | |||||
| return StringArray ((const char**) names); | return StringArray ((const char**) names); | ||||
| } | } | ||||
| @@ -251,6 +252,10 @@ public: | |||||
| menu.addSeparator(); | menu.addSeparator(); | ||||
| menu.addCommandItem (commandManager, CommandIDs::closeAllDocuments); | menu.addCommandItem (commandManager, CommandIDs::closeAllDocuments); | ||||
| } | } | ||||
| else if (topLevelMenuIndex == 4) // "Juce" menu | |||||
| { | |||||
| menu.addCommandItem (commandManager, CommandIDs::showJuceVersion); | |||||
| } | |||||
| return menu; | return menu; | ||||
| } | } | ||||
| @@ -287,7 +292,8 @@ public: | |||||
| CommandIDs::open, | CommandIDs::open, | ||||
| CommandIDs::showPrefs, | CommandIDs::showPrefs, | ||||
| CommandIDs::closeAllDocuments, | CommandIDs::closeAllDocuments, | ||||
| CommandIDs::saveAll }; | |||||
| CommandIDs::saveAll, | |||||
| CommandIDs::showJuceVersion }; | |||||
| commands.addArray (ids, numElementsInArray (ids)); | commands.addArray (ids, numElementsInArray (ids)); | ||||
| } | } | ||||
| @@ -321,6 +327,10 @@ public: | |||||
| result.setActive (OpenDocumentManager::getInstance()->anyFilesNeedSaving()); | result.setActive (OpenDocumentManager::getInstance()->anyFilesNeedSaving()); | ||||
| break; | break; | ||||
| case CommandIDs::showJuceVersion: | |||||
| result.setInfo ("Download the latest JUCE version", "Checks online for any Juce updates", CommandCategories::general, 0); | |||||
| break; | |||||
| default: | default: | ||||
| JUCEApplication::getCommandInfo (commandID, result); | JUCEApplication::getCommandInfo (commandID, result); | ||||
| break; | break; | ||||
| @@ -336,6 +346,7 @@ public: | |||||
| case CommandIDs::showPrefs: showPrefsPanel(); break; | case CommandIDs::showPrefs: showPrefsPanel(); break; | ||||
| case CommandIDs::saveAll: OpenDocumentManager::getInstance()->saveAll(); break; | case CommandIDs::saveAll: OpenDocumentManager::getInstance()->saveAll(); break; | ||||
| case CommandIDs::closeAllDocuments: closeAllDocuments (true); break; | case CommandIDs::closeAllDocuments: closeAllDocuments (true); break; | ||||
| case CommandIDs::showJuceVersion: JuceUpdater::show (mainWindows[0]); break; | |||||
| default: return JUCEApplication::perform (info); | default: return JUCEApplication::perform (info); | ||||
| } | } | ||||
| @@ -39,6 +39,7 @@ namespace CommandIDs | |||||
| static const int saveProjectAs = 0x200070; | static const int saveProjectAs = 0x200070; | ||||
| static const int openProjectInIDE = 0x200071; | static const int openProjectInIDE = 0x200071; | ||||
| static const int showProjectSettings = 0x200072; | static const int showProjectSettings = 0x200072; | ||||
| static const int showJuceVersion = 0x200073; | |||||
| static const int saveAll = 0x200080; | static const int saveAll = 0x200080; | ||||
| static const int undo = 0x200090; | static const int undo = 0x200090; | ||||
| @@ -0,0 +1,402 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-10 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #include "../jucer_Headers.h" | |||||
| #include "jucer_JuceUpdater.h" | |||||
| //============================================================================== | |||||
| JuceUpdater::JuceUpdater() | |||||
| : filenameComp ("Juce Folder", StoredSettings::getInstance()->getLastKnownJuceFolder(), | |||||
| true, true, false, "*", String::empty, "Select your Juce folder"), | |||||
| checkNowButton ("Check Online for Available Updates...", | |||||
| "Contacts the website to see if this version is up-to-date") | |||||
| { | |||||
| addAndMakeVisible (&label); | |||||
| addAndMakeVisible (&filenameComp); | |||||
| addAndMakeVisible (&checkNowButton); | |||||
| addAndMakeVisible (¤tVersionLabel); | |||||
| checkNowButton.addButtonListener (this); | |||||
| filenameComp.addListener (this); | |||||
| currentVersionLabel.setFont (Font (14.0f, Font::italic)); | |||||
| label.setFont (Font (12.0f)); | |||||
| label.setText ("Destination folder:", false); | |||||
| addAndMakeVisible (&availableVersionsList); | |||||
| availableVersionsList.setModel (this); | |||||
| setSize (600, 300); | |||||
| } | |||||
| JuceUpdater::~JuceUpdater() | |||||
| { | |||||
| checkNowButton.removeButtonListener (this); | |||||
| filenameComp.removeListener (this); | |||||
| } | |||||
| void JuceUpdater::show (Component* mainWindow) | |||||
| { | |||||
| JuceUpdater updater; | |||||
| DialogWindow::showModalDialog ("Juce Update...", &updater, mainWindow, | |||||
| Colours::lightgrey, | |||||
| true, false, false); | |||||
| } | |||||
| void JuceUpdater::resized() | |||||
| { | |||||
| filenameComp.setBounds (20, 40, getWidth() - 40, 22); | |||||
| label.setBounds (filenameComp.getX(), filenameComp.getY() - 18, filenameComp.getWidth(), 18); | |||||
| currentVersionLabel.setBounds (filenameComp.getX(), filenameComp.getBottom(), filenameComp.getWidth(), 25); | |||||
| checkNowButton.changeWidthToFitText (20); | |||||
| checkNowButton.setCentrePosition (getWidth() / 2, filenameComp.getBottom() + 40); | |||||
| availableVersionsList.setBounds (filenameComp.getX(), checkNowButton.getBottom() + 20, filenameComp.getWidth(), getHeight() - (checkNowButton.getBottom() + 20)); | |||||
| } | |||||
| void JuceUpdater::paint (Graphics& g) | |||||
| { | |||||
| g.fillAll (Colours::white); | |||||
| } | |||||
| const String findVersionNum (const String& file, const String& token) | |||||
| { | |||||
| return file.fromFirstOccurrenceOf (token, false, false) | |||||
| .upToFirstOccurrenceOf ("\n", false, false) | |||||
| .trim(); | |||||
| } | |||||
| const String JuceUpdater::getCurrentVersion() | |||||
| { | |||||
| const String header (filenameComp.getCurrentFile() | |||||
| .getChildFile ("src/core/juce_StandardHeader.h").loadFileAsString()); | |||||
| const String v1 (findVersionNum (header, "JUCE_MAJOR_VERSION")); | |||||
| const String v2 (findVersionNum (header, "JUCE_MINOR_VERSION")); | |||||
| const String v3 (findVersionNum (header, "JUCE_BUILDNUMBER")); | |||||
| if ((v1 + v2 + v3).isEmpty()) | |||||
| return String::empty; | |||||
| return v1 + "." + v2 + "." + v3; | |||||
| } | |||||
| XmlElement* JuceUpdater::downloadVersionList() | |||||
| { | |||||
| return URL ("http://www.rawmaterialsoftware.com/juce/downloads/juce_versions.php").readEntireXmlStream(); | |||||
| } | |||||
| void JuceUpdater::updateVersions (const XmlElement& xml) | |||||
| { | |||||
| availableVersions.clear(); | |||||
| forEachXmlChildElementWithTagName (xml, v, "VERSION") | |||||
| { | |||||
| VersionInfo* vi = new VersionInfo(); | |||||
| vi->url = URL (v->getStringAttribute ("url")); | |||||
| vi->desc = v->getStringAttribute ("desc"); | |||||
| vi->version = v->getStringAttribute ("version"); | |||||
| vi->date = v->getStringAttribute ("date"); | |||||
| availableVersions.add (vi); | |||||
| } | |||||
| availableVersionsList.updateContent(); | |||||
| } | |||||
| void JuceUpdater::buttonClicked (Button*) | |||||
| { | |||||
| ScopedPointer<XmlElement> xml (downloadVersionList()); | |||||
| if (xml == 0 || xml->hasTagName ("html")) | |||||
| { | |||||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "Connection Problems...", | |||||
| "Couldn't connect to the Raw Material Software website!"); | |||||
| return; | |||||
| } | |||||
| if (! xml->hasTagName ("JUCEVERSIONS")) | |||||
| { | |||||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "Update Problems...", | |||||
| "This version of the Jucer may be too old to receive automatic updates!\n\n" | |||||
| "Please visit www.rawmaterialsoftware.com and get the latest version manually!"); | |||||
| return; | |||||
| } | |||||
| const String currentVersion (getCurrentVersion()); | |||||
| OwnedArray<VersionInfo> versions; | |||||
| updateVersions (*xml); | |||||
| } | |||||
| //============================================================================== | |||||
| class NewVersionDownloader : public ThreadWithProgressWindow | |||||
| { | |||||
| public: | |||||
| NewVersionDownloader (const String& title, const URL& url_, const File& target_) | |||||
| : ThreadWithProgressWindow (title, true, true), | |||||
| url (url_), target (target_) | |||||
| { | |||||
| } | |||||
| void run() | |||||
| { | |||||
| setStatusMessage ("Contacting website..."); | |||||
| ScopedPointer<InputStream> input (url.createInputStream (false)); | |||||
| if (input == 0) | |||||
| { | |||||
| error = "Couldn't connect to the website..."; | |||||
| return; | |||||
| } | |||||
| if (! target.deleteFile()) | |||||
| { | |||||
| error = "Couldn't delete the destination file..."; | |||||
| return; | |||||
| } | |||||
| ScopedPointer<OutputStream> output (target.createOutputStream (32768)); | |||||
| if (output == 0) | |||||
| { | |||||
| error = "Couldn't write to the destination file..."; | |||||
| return; | |||||
| } | |||||
| setStatusMessage ("Downloading..."); | |||||
| int totalBytes = (int) input->getTotalLength(); | |||||
| int bytesSoFar = 0; | |||||
| while (! (input->isExhausted() || threadShouldExit())) | |||||
| { | |||||
| HeapBlock<char> buffer (8192); | |||||
| const int num = input->read (buffer, 8192); | |||||
| if (num == 0) | |||||
| break; | |||||
| output->write (buffer, num); | |||||
| bytesSoFar += num; | |||||
| setProgress (totalBytes > 0 ? bytesSoFar / (double) totalBytes : -1.0); | |||||
| } | |||||
| } | |||||
| String error; | |||||
| private: | |||||
| URL url; | |||||
| File target; | |||||
| }; | |||||
| //============================================================================== | |||||
| class Unzipper : public ThreadWithProgressWindow | |||||
| { | |||||
| public: | |||||
| Unzipper (ZipFile& zipFile_, const File& targetDir_) | |||||
| : ThreadWithProgressWindow ("Unzipping...", true, true), | |||||
| zipFile (zipFile_), targetDir (targetDir_), worked (true) | |||||
| { | |||||
| } | |||||
| void run() | |||||
| { | |||||
| for (int i = 0; i < zipFile.getNumEntries(); ++i) | |||||
| { | |||||
| if (threadShouldExit()) | |||||
| break; | |||||
| const ZipFile::ZipEntry* e = zipFile.getEntry (i); | |||||
| setStatusMessage ("Unzipping " + e->filename + "..."); | |||||
| setProgress (i / (double) zipFile.getNumEntries()); | |||||
| worked = zipFile.uncompressEntry (i, targetDir, true) && worked; | |||||
| } | |||||
| } | |||||
| bool worked; | |||||
| private: | |||||
| ZipFile& zipFile; | |||||
| File targetDir; | |||||
| }; | |||||
| //============================================================================== | |||||
| void JuceUpdater::applyVersion (VersionInfo* version) | |||||
| { | |||||
| File destDir (filenameComp.getCurrentFile()); | |||||
| const bool destDirExisted = destDir.isDirectory(); | |||||
| if (destDirExisted && destDir.getNumberOfChildFiles (File::findFilesAndDirectories, "*") > 0) | |||||
| { | |||||
| int r = AlertWindow::showYesNoCancelBox (AlertWindow::WarningIcon, "Folder already exists", | |||||
| "The folder " + destDir.getFullPathName() + "\nalready contains some files...\n\n" | |||||
| "Do you want to delete everything in the folder and replace it entirely, or just merge the new files into the existing folder?", | |||||
| "Delete and replace entire folder", | |||||
| "Add and overwrite existing files", | |||||
| "Cancel"); | |||||
| if (r == 0) | |||||
| return; | |||||
| if (r == 1) | |||||
| { | |||||
| if (! destDir.deleteRecursively()) | |||||
| { | |||||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "Problems...", | |||||
| "Couldn't delete the existing folder!"); | |||||
| return; | |||||
| } | |||||
| } | |||||
| } | |||||
| if (! (destDir.isDirectory() || destDir.createDirectory())) | |||||
| { | |||||
| AlertWindow::showMessageBox (AlertWindow::WarningIcon, "Problems...", | |||||
| "Couldn't create that target folder.."); | |||||
| return; | |||||
| } | |||||
| File zipFile (destDir.getNonexistentChildFile ("juce_download", ".tar.gz", false)); | |||||
| bool worked = false; | |||||
| { | |||||
| NewVersionDownloader downloader ("Downloading Version " + version->version + "...", | |||||
| version->url, zipFile); | |||||
| worked = downloader.runThread(); | |||||
| } | |||||
| if (worked) | |||||
| { | |||||
| ZipFile zip (zipFile); | |||||
| Unzipper unzipper (zip, destDir); | |||||
| worked = unzipper.runThread() && unzipper.worked; | |||||
| } | |||||
| zipFile.deleteFile(); | |||||
| if ((! destDirExisted) && (destDir.getNumberOfChildFiles (File::findFilesAndDirectories, "*") == 0 || ! worked)) | |||||
| destDir.deleteRecursively(); | |||||
| filenameComponentChanged (&filenameComp); | |||||
| } | |||||
| void JuceUpdater::filenameComponentChanged (FilenameComponent*) | |||||
| { | |||||
| const String version (getCurrentVersion()); | |||||
| if (version.isEmpty()) | |||||
| currentVersionLabel.setText ("(Not a Juce folder)", false); | |||||
| else | |||||
| currentVersionLabel.setText ("(Current version in this folder: " + version + ")", false); | |||||
| } | |||||
| //============================================================================== | |||||
| int JuceUpdater::getNumRows() | |||||
| { | |||||
| return availableVersions.size(); | |||||
| } | |||||
| void JuceUpdater::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) | |||||
| { | |||||
| if (rowIsSelected) | |||||
| g.fillAll (findColour (TextEditor::highlightColourId)); | |||||
| } | |||||
| Component* JuceUpdater::refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate) | |||||
| { | |||||
| class UpdateListComponent : public Component, | |||||
| public ButtonListener | |||||
| { | |||||
| public: | |||||
| UpdateListComponent (JuceUpdater& updater_) | |||||
| : updater (updater_), version (0), applyButton ("Install this version...") | |||||
| { | |||||
| addAndMakeVisible (&applyButton); | |||||
| applyButton.addButtonListener (this); | |||||
| setInterceptsMouseClicks (false, true); | |||||
| } | |||||
| ~UpdateListComponent() | |||||
| { | |||||
| applyButton.removeButtonListener (this); | |||||
| } | |||||
| void setVersion (VersionInfo* v) | |||||
| { | |||||
| if (version != v) | |||||
| { | |||||
| version = v; | |||||
| repaint(); | |||||
| resized(); | |||||
| } | |||||
| } | |||||
| void paint (Graphics& g) | |||||
| { | |||||
| if (version != 0) | |||||
| { | |||||
| g.setColour (Colours::green.withAlpha (0.12f)); | |||||
| g.fillRect (0, 1, getWidth(), getHeight() - 2); | |||||
| g.setColour (Colours::black); | |||||
| g.setFont (getHeight() * 0.7f); | |||||
| String s; | |||||
| s << "Version " << version->version << " - " << version->desc << " - " << version->date; | |||||
| g.drawText (s, 4, 0, applyButton.getX() - 4, getHeight(), Justification::centredLeft, true); | |||||
| } | |||||
| } | |||||
| void resized() | |||||
| { | |||||
| applyButton.changeWidthToFitText (getHeight() - 4); | |||||
| applyButton.setTopRightPosition (getWidth(), 2); | |||||
| applyButton.setVisible (version != 0); | |||||
| } | |||||
| void buttonClicked (Button*) | |||||
| { | |||||
| updater.applyVersion (version); | |||||
| } | |||||
| private: | |||||
| JuceUpdater& updater; | |||||
| TextButton applyButton; | |||||
| VersionInfo* version; | |||||
| }; | |||||
| UpdateListComponent* c = dynamic_cast <UpdateListComponent*> (existingComponentToUpdate); | |||||
| if (c == 0) | |||||
| c = new UpdateListComponent (*this); | |||||
| c->setVersion (availableVersions [rowNumber]); | |||||
| return c; | |||||
| } | |||||
| @@ -0,0 +1,77 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-10 by Raw Material Software Ltd. | |||||
| ------------------------------------------------------------------------------ | |||||
| JUCE can be redistributed and/or modified under the terms of the GNU General | |||||
| Public License (Version 2), as published by the Free Software Foundation. | |||||
| A copy of the license is included in the JUCE distribution, or can be found | |||||
| online at www.gnu.org/licenses. | |||||
| JUCE is distributed in the hope that it will be useful, but WITHOUT ANY | |||||
| WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||||
| A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.rawmaterialsoftware.com/juce for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| #ifndef __JUCER_JUCEUPDATER_H_81537815__ | |||||
| #define __JUCER_JUCEUPDATER_H_81537815__ | |||||
| //============================================================================== | |||||
| class JuceUpdater : public Component, | |||||
| public ButtonListener, | |||||
| public FilenameComponentListener, | |||||
| public ListBoxModel | |||||
| { | |||||
| public: | |||||
| JuceUpdater(); | |||||
| ~JuceUpdater(); | |||||
| static void show (Component* mainWindow); | |||||
| //============================================================================== | |||||
| void resized(); | |||||
| void paint (Graphics& g); | |||||
| void buttonClicked (Button*); | |||||
| void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged); | |||||
| int getNumRows(); | |||||
| void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected); | |||||
| Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); | |||||
| private: | |||||
| Label label, currentVersionLabel; | |||||
| FilenameComponent filenameComp; | |||||
| TextButton checkNowButton; | |||||
| ListBox availableVersionsList; | |||||
| XmlElement* downloadVersionList(); | |||||
| const String getCurrentVersion(); | |||||
| bool isAlreadyUpToDate(); | |||||
| struct VersionInfo | |||||
| { | |||||
| URL url; | |||||
| String desc; | |||||
| String version; | |||||
| String date; | |||||
| }; | |||||
| OwnedArray<VersionInfo> availableVersions; | |||||
| void updateVersions (const XmlElement& xml); | |||||
| void applyVersion (VersionInfo* version); | |||||
| }; | |||||
| #endif // __JUCER_JUCEUPDATER_H_81537815__ | |||||
| @@ -11,9 +11,9 @@ | |||||
| #ifndef __PLUGINCHARACTERISTICS_D4EFFF1A__ | #ifndef __PLUGINCHARACTERISTICS_D4EFFF1A__ | ||||
| #define __PLUGINCHARACTERISTICS_D4EFFF1A__ | #define __PLUGINCHARACTERISTICS_D4EFFF1A__ | ||||
| #define JucePlugin_Build_VST 1 // (If you change this you'll also need to re-export the projects using the Jucer) | |||||
| #define JucePlugin_Build_AU 1 // (If you change this you'll also need to re-export the projects using the Jucer) | |||||
| #define JucePlugin_Build_RTAS 0 // (If you change this you'll also need to re-export the projects using the Jucer) | |||||
| #define JucePlugin_Build_VST 1 // (If you change this value, you'll also need to re-export the projects using the Jucer) | |||||
| #define JucePlugin_Build_AU 1 // (If you change this value, you'll also need to re-export the projects using the Jucer) | |||||
| #define JucePlugin_Build_RTAS 0 // (If you change this value, you'll also need to re-export the projects using the Jucer) | |||||
| #define JucePlugin_Name "Juce Demo Plugin" | #define JucePlugin_Name "Juce Demo Plugin" | ||||
| #define JucePlugin_Desc "Juce Demo Plugin" | #define JucePlugin_Desc "Juce Demo Plugin" | ||||
| @@ -7464,97 +7464,40 @@ const String File::loadFileAsString() const | |||||
| return in.readEntireStreamAsString(); | return in.readEntireStreamAsString(); | ||||
| } | } | ||||
| bool File::fileTypeMatches (const int whatToLookFor, const bool isDir, const bool isHidden) | |||||
| { | |||||
| return (whatToLookFor & (isDir ? findDirectories | |||||
| : findFiles)) != 0 | |||||
| && ((! isHidden) || (whatToLookFor & File::ignoreHiddenFiles) == 0); | |||||
| } | |||||
| int File::findChildFiles (Array<File>& results, | int File::findChildFiles (Array<File>& results, | ||||
| const int whatToLookFor, | const int whatToLookFor, | ||||
| const bool searchRecursively, | const bool searchRecursively, | ||||
| const String& wildCardPattern) const | const String& wildCardPattern) const | ||||
| { | { | ||||
| // you have to specify the type of files you're looking for! | |||||
| jassert ((whatToLookFor & (findFiles | findDirectories)) != 0); | |||||
| DirectoryIterator di (*this, searchRecursively, wildCardPattern, whatToLookFor); | |||||
| int total = 0; | int total = 0; | ||||
| if (isDirectory()) | |||||
| while (di.next()) | |||||
| { | { | ||||
| // find child files or directories in this directory first.. | |||||
| String path (addTrailingSeparator (fullPath)), filename; | |||||
| bool itemIsDirectory, itemIsHidden; | |||||
| DirectoryIterator::NativeIterator i (path, wildCardPattern); | |||||
| while (i.next (filename, &itemIsDirectory, &itemIsHidden, 0, 0, 0, 0)) | |||||
| { | |||||
| if (! filename.containsOnly (".")) | |||||
| { | |||||
| const File fileFound (path + filename, 0); | |||||
| if (fileTypeMatches (whatToLookFor, itemIsDirectory, itemIsHidden)) | |||||
| { | |||||
| results.add (fileFound); | |||||
| ++total; | |||||
| } | |||||
| if (searchRecursively && itemIsDirectory | |||||
| && ((! itemIsHidden) || (whatToLookFor & File::ignoreHiddenFiles) == 0)) | |||||
| { | |||||
| total += fileFound.findChildFiles (results, whatToLookFor, true, wildCardPattern); | |||||
| } | |||||
| } | |||||
| } | |||||
| results.add (di.getFile()); | |||||
| ++total; | |||||
| } | } | ||||
| return total; | return total; | ||||
| } | } | ||||
| int File::getNumberOfChildFiles (const int whatToLookFor, | |||||
| const String& wildCardPattern) const | |||||
| int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const | |||||
| { | { | ||||
| // you have to specify the type of files you're looking for! | |||||
| jassert (whatToLookFor > 0 && whatToLookFor <= 3); | |||||
| DirectoryIterator di (*this, false, "*", whatToLookFor); | |||||
| int count = 0; | |||||
| if (isDirectory()) | |||||
| { | |||||
| String filename; | |||||
| bool itemIsDirectory, itemIsHidden; | |||||
| DirectoryIterator::NativeIterator i (*this, wildCardPattern); | |||||
| while (i.next (filename, &itemIsDirectory, &itemIsHidden, 0, 0, 0, 0)) | |||||
| if (fileTypeMatches (whatToLookFor, itemIsDirectory, itemIsHidden) | |||||
| && ! filename.containsOnly (".")) | |||||
| ++count; | |||||
| } | |||||
| else | |||||
| { | |||||
| // trying to search for files inside a non-directory? | |||||
| jassertfalse; | |||||
| } | |||||
| int total = 0; | |||||
| while (di.next()) | |||||
| ++total; | |||||
| return count; | |||||
| return total; | |||||
| } | } | ||||
| bool File::containsSubDirectories() const | bool File::containsSubDirectories() const | ||||
| { | { | ||||
| if (isDirectory()) | if (isDirectory()) | ||||
| { | { | ||||
| String filename; | |||||
| bool itemIsDirectory; | |||||
| DirectoryIterator::NativeIterator i (*this, "*"); | |||||
| while (i.next (filename, &itemIsDirectory, 0, 0, 0, 0, 0)) | |||||
| if (itemIsDirectory) | |||||
| return true; | |||||
| DirectoryIterator di (*this, false, "*", findDirectories); | |||||
| return di.next(); | |||||
| } | } | ||||
| return false; | return false; | ||||
| @@ -10498,46 +10441,60 @@ int ZipFile::findEndOfZipEntryTable (InputStream* input, int& numEntries) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| void ZipFile::uncompressTo (const File& targetDirectory, | |||||
| bool ZipFile::uncompressTo (const File& targetDirectory, | |||||
| const bool shouldOverwriteFiles) | const bool shouldOverwriteFiles) | ||||
| { | { | ||||
| for (int i = 0; i < entries.size(); ++i) | for (int i = 0; i < entries.size(); ++i) | ||||
| { | |||||
| const ZipEntry& zei = entries.getUnchecked(i)->entry; | |||||
| if (! uncompressEntry (i, targetDirectory, shouldOverwriteFiles)) | |||||
| return false; | |||||
| return true; | |||||
| } | |||||
| bool ZipFile::uncompressEntry (const int index, | |||||
| const File& targetDirectory, | |||||
| bool shouldOverwriteFiles) | |||||
| { | |||||
| const ZipEntryInfo* zei = entries [index]; | |||||
| const File targetFile (targetDirectory.getChildFile (zei.filename)); | |||||
| if (zei != 0) | |||||
| { | |||||
| const File targetFile (targetDirectory.getChildFile (zei->entry.filename)); | |||||
| if (zei.filename.endsWithChar ('/')) | |||||
| if (zei->entry.filename.endsWithChar ('/')) | |||||
| { | { | ||||
| targetFile.createDirectory(); // (entry is a directory, not a file) | targetFile.createDirectory(); // (entry is a directory, not a file) | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| ScopedPointer <InputStream> in (createStreamForEntry (i)); | |||||
| ScopedPointer<InputStream> in (createStreamForEntry (index)); | |||||
| if (in != 0) | if (in != 0) | ||||
| { | { | ||||
| if (shouldOverwriteFiles) | |||||
| targetFile.deleteFile(); | |||||
| if (shouldOverwriteFiles && ! targetFile.deleteFile()) | |||||
| return false; | |||||
| if ((! targetFile.exists()) | |||||
| && targetFile.getParentDirectory().createDirectory()) | |||||
| if ((! targetFile.exists()) && targetFile.getParentDirectory().createDirectory()) | |||||
| { | { | ||||
| ScopedPointer <FileOutputStream> out (targetFile.createOutputStream()); | |||||
| ScopedPointer<FileOutputStream> out (targetFile.createOutputStream()); | |||||
| if (out != 0) | if (out != 0) | ||||
| { | { | ||||
| out->writeFromInputStream (*in, -1); | out->writeFromInputStream (*in, -1); | ||||
| out = 0; | out = 0; | ||||
| targetFile.setCreationTime (zei.fileTime); | |||||
| targetFile.setLastModificationTime (zei.fileTime); | |||||
| targetFile.setLastAccessTime (zei.fileTime); | |||||
| targetFile.setCreationTime (zei->entry.fileTime); | |||||
| targetFile.setLastModificationTime (zei->entry.fileTime); | |||||
| targetFile.setLastAccessTime (zei->entry.fileTime); | |||||
| return true; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -29276,8 +29233,6 @@ const MidiMessage MidiMessage::noteOff (const int channel, | |||||
| const MidiMessage MidiMessage::allNotesOff (const int channel) throw() | const MidiMessage MidiMessage::allNotesOff (const int channel) throw() | ||||
| { | { | ||||
| jassert (channel > 0 && channel <= 16); | |||||
| return controllerEvent (channel, 123, 0); | return controllerEvent (channel, 123, 0); | ||||
| } | } | ||||
| @@ -33121,6 +33076,21 @@ static float vst_swapFloat (const float x) throw() | |||||
| #endif | #endif | ||||
| } | } | ||||
| static double getVSTHostTimeNanoseconds() | |||||
| { | |||||
| #if JUCE_WINDOWS | |||||
| return timeGetTime() * 1000000.0; | |||||
| #elif JUCE_LINUX | |||||
| timeval micro; | |||||
| gettimeofday (µ, 0); | |||||
| return micro.tv_usec * 1000.0; | |||||
| #elif JUCE_MAC | |||||
| UnsignedWide micro; | |||||
| Microseconds (µ); | |||||
| return micro.lo * 1000.0; | |||||
| #endif | |||||
| } | |||||
| typedef AEffect* (*MainCall) (audioMasterCallback); | typedef AEffect* (*MainCall) (audioMasterCallback); | ||||
| static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt); | static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt); | ||||
| @@ -33227,22 +33197,16 @@ static void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) th | |||||
| static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) throw() | static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) throw() | ||||
| { | { | ||||
| if (e.mods.isLeftButtonDown()) | |||||
| ev.xmotion.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) | |||||
| ev.xmotion.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) | |||||
| ev.xmotion.state |= Button2Mask; | |||||
| if (e.mods.isLeftButtonDown()) ev.xmotion.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) ev.xmotion.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) ev.xmotion.state |= Button2Mask; | |||||
| } | } | ||||
| static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) throw() | static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) throw() | ||||
| { | { | ||||
| if (e.mods.isLeftButtonDown()) | |||||
| ev.xcrossing.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) | |||||
| ev.xcrossing.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) | |||||
| ev.xcrossing.state |= Button2Mask; | |||||
| if (e.mods.isLeftButtonDown()) ev.xcrossing.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) ev.xcrossing.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) ev.xcrossing.state |= Button2Mask; | |||||
| } | } | ||||
| static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) throw() | static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) throw() | ||||
| @@ -33328,7 +33292,6 @@ public: | |||||
| ~ModuleHandle() | ~ModuleHandle() | ||||
| { | { | ||||
| getActiveModules().removeValue (this); | getActiveModules().removeValue (this); | ||||
| close(); | close(); | ||||
| } | } | ||||
| @@ -33626,7 +33589,7 @@ public: | |||||
| } | } | ||||
| const String getName() const { return name; } | const String getName() const { return name; } | ||||
| int getUID() const throw(); | |||||
| int getUID() const; | |||||
| bool acceptsMidi() const { return wantsMidiMessages; } | bool acceptsMidi() const { return wantsMidiMessages; } | ||||
| bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } | bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } | ||||
| @@ -33683,14 +33646,13 @@ private: | |||||
| MidiBuffer incomingMidi; | MidiBuffer incomingMidi; | ||||
| VSTMidiEventList midiEventsToSend; | VSTMidiEventList midiEventsToSend; | ||||
| VstTimeInfo vstHostTime; | VstTimeInfo vstHostTime; | ||||
| HeapBlock <float*> channels; | |||||
| ReferenceCountedObjectPtr <ModuleHandle> module; | ReferenceCountedObjectPtr <ModuleHandle> module; | ||||
| int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const; | int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const; | ||||
| bool restoreProgramSettings (const fxProgram* const prog); | bool restoreProgramSettings (const fxProgram* const prog); | ||||
| const String getCurrentProgramName(); | const String getCurrentProgramName(); | ||||
| void setParamsInProgramBlock (fxProgram* const prog) throw(); | |||||
| void setParamsInProgramBlock (fxProgram* const prog); | |||||
| void updateStoredProgramNames(); | void updateStoredProgramNames(); | ||||
| void initialise(); | void initialise(); | ||||
| void handleMidiFromPlugin (const VstEvents* const events); | void handleMidiFromPlugin (const VstEvents* const events); | ||||
| @@ -33705,8 +33667,8 @@ private: | |||||
| bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB); | bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB); | ||||
| int getVersionNumber() const throw() { return effect != 0 ? effect->version : 0; } | int getVersionNumber() const throw() { return effect != 0 ? effect->version : 0; } | ||||
| const String getVersion() const throw(); | |||||
| const String getCategory() const throw(); | |||||
| const String getVersion() const; | |||||
| const String getCategory() const; | |||||
| bool hasEditor() const throw() { return effect != 0 && (effect->flags & effFlagsHasEditor) != 0; } | bool hasEditor() const throw() { return effect != 0 && (effect->flags & effFlagsHasEditor) != 0; } | ||||
| void setPower (const bool on); | void setPower (const bool on); | ||||
| @@ -33777,34 +33739,32 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHan | |||||
| VSTPluginInstance::~VSTPluginInstance() | VSTPluginInstance::~VSTPluginInstance() | ||||
| { | { | ||||
| { | |||||
| const ScopedLock sl (lock); | |||||
| const ScopedLock sl (lock); | |||||
| jassert (insideVSTCallback == 0); | |||||
| jassert (insideVSTCallback == 0); | |||||
| if (effect != 0 && effect->magic == kEffectMagic) | |||||
| if (effect != 0 && effect->magic == kEffectMagic) | |||||
| { | |||||
| try | |||||
| { | { | ||||
| try | |||||
| { | |||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| if (module->resFileId != 0) | |||||
| UseResFile (module->resFileId); | |||||
| if (module->resFileId != 0) | |||||
| UseResFile (module->resFileId); | |||||
| #endif | #endif | ||||
| // Must delete any editors before deleting the plugin instance! | |||||
| jassert (getActiveEditor() == 0); | |||||
| // Must delete any editors before deleting the plugin instance! | |||||
| jassert (getActiveEditor() == 0); | |||||
| _fpreset(); // some dodgy plugs fuck around with this | |||||
| _fpreset(); // some dodgy plugs fuck around with this | |||||
| module->closeEffect (effect); | |||||
| } | |||||
| catch (...) | |||||
| {} | |||||
| module->closeEffect (effect); | |||||
| } | } | ||||
| module = 0; | |||||
| effect = 0; | |||||
| catch (...) | |||||
| {} | |||||
| } | } | ||||
| module = 0; | |||||
| effect = 0; | |||||
| } | } | ||||
| void VSTPluginInstance::initialise() | void VSTPluginInstance::initialise() | ||||
| @@ -33869,8 +33829,6 @@ void VSTPluginInstance::prepareToPlay (double sampleRate_, | |||||
| setLatencySamples (effect->initialDelay); | setLatencySamples (effect->initialDelay); | ||||
| channels.calloc (jmax (16, getNumOutputChannels(), getNumInputChannels()) + 2); | |||||
| vstHostTime.tempo = 120.0; | vstHostTime.tempo = 120.0; | ||||
| vstHostTime.timeSigNumerator = 4; | vstHostTime.timeSigNumerator = 4; | ||||
| vstHostTime.timeSigDenominator = 4; | vstHostTime.timeSigDenominator = 4; | ||||
| @@ -33924,7 +33882,6 @@ void VSTPluginInstance::releaseResources() | |||||
| incomingMidi.clear(); | incomingMidi.clear(); | ||||
| midiEventsToSend.freeEvents(); | midiEventsToSend.freeEvents(); | ||||
| channels.free(); | |||||
| } | } | ||||
| void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | ||||
| @@ -33954,17 +33911,7 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| vstHostTime.flags &= ~kVstTransportPlaying; | vstHostTime.flags &= ~kVstTransportPlaying; | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| vstHostTime.nanoSeconds = timeGetTime() * 1000000.0; | |||||
| #elif JUCE_LINUX | |||||
| timeval micro; | |||||
| gettimeofday (µ, 0); | |||||
| vstHostTime.nanoSeconds = micro.tv_usec * 1000.0; | |||||
| #elif JUCE_MAC | |||||
| UnsignedWide micro; | |||||
| Microseconds (µ); | |||||
| vstHostTime.nanoSeconds = micro.lo * 1000.0; | |||||
| #endif | |||||
| vstHostTime.nanoSeconds = getVSTHostTimeNanoseconds(); | |||||
| if (wantsMidiMessages) | if (wantsMidiMessages) | ||||
| { | { | ||||
| @@ -33989,21 +33936,13 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| {} | {} | ||||
| } | } | ||||
| int i; | |||||
| const int maxChans = jmax (effect->numInputs, effect->numOutputs); | |||||
| for (i = 0; i < maxChans; ++i) | |||||
| channels[i] = buffer.getSampleData (i); | |||||
| channels [maxChans] = 0; | |||||
| _clearfp(); | _clearfp(); | ||||
| if ((effect->flags & effFlagsCanReplacing) != 0) | if ((effect->flags & effFlagsCanReplacing) != 0) | ||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| effect->processReplacing (effect, channels, channels, numSamples); | |||||
| effect->processReplacing (effect, buffer.getArrayOfChannels(), buffer.getArrayOfChannels(), numSamples); | |||||
| } | } | ||||
| catch (...) | catch (...) | ||||
| {} | {} | ||||
| @@ -34013,22 +33952,15 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| tempBuffer.setSize (effect->numOutputs, numSamples); | tempBuffer.setSize (effect->numOutputs, numSamples); | ||||
| tempBuffer.clear(); | tempBuffer.clear(); | ||||
| float* outs [64]; | |||||
| for (i = effect->numOutputs; --i >= 0;) | |||||
| outs[i] = tempBuffer.getSampleData (i); | |||||
| outs [effect->numOutputs] = 0; | |||||
| try | try | ||||
| { | { | ||||
| effect->process (effect, channels, outs, numSamples); | |||||
| effect->process (effect, buffer.getArrayOfChannels(), tempBuffer.getArrayOfChannels(), numSamples); | |||||
| } | } | ||||
| catch (...) | catch (...) | ||||
| {} | {} | ||||
| for (i = effect->numOutputs; --i >= 0;) | |||||
| buffer.copyFrom (i, 0, outs[i], numSamples); | |||||
| for (int i = effect->numOutputs; --i >= 0;) | |||||
| buffer.copyFrom (i, 0, tempBuffer.getSampleData (i), numSamples); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -34496,7 +34428,7 @@ private: | |||||
| } | } | ||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| void checkPluginWindowSize() throw() | |||||
| void checkPluginWindowSize() | |||||
| { | { | ||||
| RECT r; | RECT r; | ||||
| GetWindowRect (pluginHWND, &r); | GetWindowRect (pluginHWND, &r); | ||||
| @@ -34517,7 +34449,7 @@ private: | |||||
| { | { | ||||
| for (int i = activeVSTWindows.size(); --i >= 0;) | for (int i = activeVSTWindows.size(); --i >= 0;) | ||||
| { | { | ||||
| const VSTPluginWindow* const w = (const VSTPluginWindow*) activeVSTWindows.getUnchecked (i); | |||||
| const VSTPluginWindow* const w = activeVSTWindows.getUnchecked (i); | |||||
| if (w->pluginHWND == hW) | if (w->pluginHWND == hW) | ||||
| { | { | ||||
| @@ -34913,7 +34845,7 @@ bool VSTPluginInstance::loadFromFXBFile (const void* const data, | |||||
| return true; | return true; | ||||
| } | } | ||||
| void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) throw() | |||||
| void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) | |||||
| { | { | ||||
| const int numParams = getNumParameters(); | const int numParams = getNumParameters(); | ||||
| @@ -35070,30 +35002,16 @@ int VSTPluginInstance::dispatch (const int opcode, const int index, const int va | |||||
| { | { | ||||
| if (effect != 0) | if (effect != 0) | ||||
| { | { | ||||
| #if JUCE_MAC | |||||
| #if JUCE_MAC | |||||
| if (module->resFileId != 0) | if (module->resFileId != 0) | ||||
| UseResFile (module->resFileId); | UseResFile (module->resFileId); | ||||
| CGrafPtr oldPort; | |||||
| if (getActiveEditor() != 0) | |||||
| { | |||||
| const Point<int> pos (getActiveEditor()->relativePositionToOtherComponent (getActiveEditor()->getTopLevelComponent(), Point<int>())); | |||||
| GetPort (&oldPort); | |||||
| SetPortWindowPort ((WindowRef) getActiveEditor()->getWindowHandle()); | |||||
| SetOrigin (-pos.getX(), -pos.getY()); | |||||
| } | |||||
| #endif | |||||
| #endif | |||||
| result = effect->dispatcher (effect, opcode, index, value, ptr, opt); | result = effect->dispatcher (effect, opcode, index, value, ptr, opt); | ||||
| #if JUCE_MAC | |||||
| if (getActiveEditor() != 0) | |||||
| SetPort (oldPort); | |||||
| #if JUCE_MAC | |||||
| module->resFileId = CurResFile(); | module->resFileId = CurResFile(); | ||||
| #endif | |||||
| #endif | |||||
| --insideVSTCallback; | --insideVSTCallback; | ||||
| return result; | return result; | ||||
| @@ -35120,7 +35038,7 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||||
| switch (opcode) | switch (opcode) | ||||
| { | { | ||||
| case audioMasterCanDo: | |||||
| case audioMasterCanDo: | |||||
| { | { | ||||
| static const char* canDos[] = { "supplyIdle", | static const char* canDos[] = { "supplyIdle", | ||||
| "sendVstEvents", | "sendVstEvents", | ||||
| @@ -35138,19 +35056,14 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| case audioMasterVersion: | |||||
| return 0x2400; | |||||
| case audioMasterCurrentId: | |||||
| return shellUIDToCreate; | |||||
| case audioMasterGetNumAutomatableParameters: | |||||
| return 0; | |||||
| case audioMasterGetAutomationState: | |||||
| return 1; | |||||
| case audioMasterVersion: return 0x2400; | |||||
| case audioMasterCurrentId: return shellUIDToCreate; | |||||
| case audioMasterGetNumAutomatableParameters: return 0; | |||||
| case audioMasterGetAutomationState: return 1; | |||||
| case audioMasterGetVendorVersion: return 0x0101; | |||||
| case audioMasterGetVendorVersion: | |||||
| return 0x0101; | |||||
| case audioMasterGetVendorString: | |||||
| case audioMasterGetProductString: | |||||
| case audioMasterGetVendorString: | |||||
| case audioMasterGetProductString: | |||||
| { | { | ||||
| String hostName ("Juce VST Host"); | String hostName ("Juce VST Host"); | ||||
| @@ -35158,21 +35071,16 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||||
| hostName = JUCEApplication::getInstance()->getApplicationName(); | hostName = JUCEApplication::getInstance()->getApplicationName(); | ||||
| hostName.copyToCString ((char*) ptr, jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | hostName.copyToCString ((char*) ptr, jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | ||||
| break; | |||||
| } | } | ||||
| break; | |||||
| case audioMasterGetSampleRate: | |||||
| return (VstIntPtr) defaultVSTSampleRateValue; | |||||
| case audioMasterGetSampleRate: return (VstIntPtr) defaultVSTSampleRateValue; | |||||
| case audioMasterGetBlockSize: return (VstIntPtr) defaultVSTBlockSizeValue; | |||||
| case audioMasterSetOutputSampleRate: return 0; | |||||
| case audioMasterGetBlockSize: | |||||
| return (VstIntPtr) defaultVSTBlockSizeValue; | |||||
| case audioMasterSetOutputSampleRate: | |||||
| return 0; | |||||
| default: | |||||
| DBG ("*** Unhandled VST Callback: " + String ((int) opcode)); | |||||
| break; | |||||
| default: | |||||
| DBG ("*** Unhandled VST Callback: " + String ((int) opcode)); | |||||
| break; | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -35313,7 +35221,7 @@ static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstI | |||||
| } | } | ||||
| } | } | ||||
| const String VSTPluginInstance::getVersion() const throw() | |||||
| const String VSTPluginInstance::getVersion() const | |||||
| { | { | ||||
| unsigned int v = dispatch (effGetVendorVersion, 0, 0, 0, 0); | unsigned int v = dispatch (effGetVendorVersion, 0, 0, 0, 0); | ||||
| @@ -35347,7 +35255,7 @@ const String VSTPluginInstance::getVersion() const throw() | |||||
| return s; | return s; | ||||
| } | } | ||||
| int VSTPluginInstance::getUID() const throw() | |||||
| int VSTPluginInstance::getUID() const | |||||
| { | { | ||||
| int uid = effect != 0 ? effect->uniqueID : 0; | int uid = effect != 0 ? effect->uniqueID : 0; | ||||
| @@ -35357,50 +35265,22 @@ int VSTPluginInstance::getUID() const throw() | |||||
| return uid; | return uid; | ||||
| } | } | ||||
| const String VSTPluginInstance::getCategory() const throw() | |||||
| const String VSTPluginInstance::getCategory() const | |||||
| { | { | ||||
| const char* result = 0; | const char* result = 0; | ||||
| switch (dispatch (effGetPlugCategory, 0, 0, 0, 0)) | switch (dispatch (effGetPlugCategory, 0, 0, 0, 0)) | ||||
| { | { | ||||
| case kPlugCategEffect: | |||||
| result = "Effect"; | |||||
| break; | |||||
| case kPlugCategSynth: | |||||
| result = "Synth"; | |||||
| break; | |||||
| case kPlugCategAnalysis: | |||||
| result = "Anaylsis"; | |||||
| break; | |||||
| case kPlugCategMastering: | |||||
| result = "Mastering"; | |||||
| break; | |||||
| case kPlugCategSpacializer: | |||||
| result = "Spacial"; | |||||
| break; | |||||
| case kPlugCategRoomFx: | |||||
| result = "Reverb"; | |||||
| break; | |||||
| case kPlugSurroundFx: | |||||
| result = "Surround"; | |||||
| break; | |||||
| case kPlugCategRestoration: | |||||
| result = "Restoration"; | |||||
| break; | |||||
| case kPlugCategGenerator: | |||||
| result = "Tone generation"; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| case kPlugCategEffect: result = "Effect"; break; | |||||
| case kPlugCategSynth: result = "Synth"; break; | |||||
| case kPlugCategAnalysis: result = "Anaylsis"; break; | |||||
| case kPlugCategMastering: result = "Mastering"; break; | |||||
| case kPlugCategSpacializer: result = "Spacial"; break; | |||||
| case kPlugCategRoomFx: result = "Reverb"; break; | |||||
| case kPlugSurroundFx: result = "Surround"; break; | |||||
| case kPlugCategRestoration: result = "Restoration"; break; | |||||
| case kPlugCategGenerator: result = "Tone generation"; break; | |||||
| default: break; | |||||
| } | } | ||||
| return result; | return result; | ||||
| @@ -35833,11 +35713,9 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdenti | |||||
| return false; | return false; | ||||
| #elif JUCE_WINDOWS | #elif JUCE_WINDOWS | ||||
| return f.existsAsFile() | |||||
| && f.hasFileExtension (".dll"); | |||||
| return f.existsAsFile() && f.hasFileExtension (".dll"); | |||||
| #elif JUCE_LINUX | #elif JUCE_LINUX | ||||
| return f.existsAsFile() | |||||
| && f.hasFileExtension (".so"); | |||||
| return f.existsAsFile() && f.hasFileExtension (".so"); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -262076,6 +261954,42 @@ public: | |||||
| outputNames.clear(); | outputNames.clear(); | ||||
| outputIds.clear(); | outputIds.clear(); | ||||
| /* void** hints = 0; | |||||
| if (snd_device_name_hint (-1, "pcm", &hints) >= 0) | |||||
| { | |||||
| for (void** hint = hints; *hint != 0; ++hint) | |||||
| { | |||||
| const String name (getHint (*hint, "NAME")); | |||||
| if (name.isNotEmpty()) | |||||
| { | |||||
| const String ioid (getHint (*hint, "IOID")); | |||||
| String desc (getHint (*hint, "DESC")); | |||||
| if (desc.isEmpty()) | |||||
| desc = name; | |||||
| desc = desc.replaceCharacters ("\n\r", " "); | |||||
| DBG ("name: " << name << "\ndesc: " << desc << "\nIO: " << ioid); | |||||
| if (ioid.isEmpty() || ioid == "Input") | |||||
| { | |||||
| inputNames.add (desc); | |||||
| inputIds.add (name); | |||||
| } | |||||
| if (ioid.isEmpty() || ioid == "Output") | |||||
| { | |||||
| outputNames.add (desc); | |||||
| outputIds.add (name); | |||||
| } | |||||
| } | |||||
| } | |||||
| snd_device_name_free_hint (hints); | |||||
| } | |||||
| */ | |||||
| snd_ctl_t* handle = 0; | snd_ctl_t* handle = 0; | ||||
| snd_ctl_card_info_t* info = 0; | snd_ctl_card_info_t* info = 0; | ||||
| snd_ctl_card_info_alloca (&info); | snd_ctl_card_info_alloca (&info); | ||||
| @@ -262211,6 +262125,14 @@ private: | |||||
| return (isInput || isOutput) && rates.size() > 0; | return (isInput || isOutput) && rates.size() > 0; | ||||
| } | } | ||||
| /*static const String getHint (void* hint, const char* type) | |||||
| { | |||||
| char* const n = snd_device_name_get_hint (hint, type); | |||||
| const String s ((const char*) n); | |||||
| free (n); | |||||
| return s; | |||||
| }*/ | |||||
| ALSAAudioIODeviceType (const ALSAAudioIODeviceType&); | ALSAAudioIODeviceType (const ALSAAudioIODeviceType&); | ||||
| ALSAAudioIODeviceType& operator= (const ALSAAudioIODeviceType&); | ALSAAudioIODeviceType& operator= (const ALSAAudioIODeviceType&); | ||||
| }; | }; | ||||
| @@ -64,7 +64,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 60 | |||||
| #define JUCE_BUILDNUMBER 61 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -9433,7 +9433,6 @@ private: | |||||
| bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | ||||
| static const String parseAbsolutePath (const String& path); | static const String parseAbsolutePath (const String& path); | ||||
| static bool fileTypeMatches (int whatToLookFor, bool isDir, bool isHidden); | |||||
| }; | }; | ||||
| @@ -15461,7 +15460,6 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| friend class File; | |||||
| class NativeIterator | class NativeIterator | ||||
| { | { | ||||
| @@ -16145,17 +16143,42 @@ public: | |||||
| */ | */ | ||||
| InputStream* createStreamForEntry (int index); | InputStream* createStreamForEntry (int index); | ||||
| /** Creates a stream that can read from one of the zip file's entries. | |||||
| The stream that is returned must be deleted by the caller (and | |||||
| zero might be returned if a stream can't be opened for some reason). | |||||
| The stream must not be used after the ZipFile object that created | |||||
| has been deleted. | |||||
| */ | |||||
| InputStream* createStreamForEntry (ZipEntry& entry); | |||||
| /** Uncompresses all of the files in the zip file. | /** Uncompresses all of the files in the zip file. | ||||
| This will expand all the entires into a target directory. The relative | |||||
| This will expand all the entries into a target directory. The relative | |||||
| paths of the entries are used. | paths of the entries are used. | ||||
| @param targetDirectory the root folder to uncompress to | @param targetDirectory the root folder to uncompress to | ||||
| @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones | @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones | ||||
| @returns true if all the files are successfully unzipped | |||||
| */ | */ | ||||
| void uncompressTo (const File& targetDirectory, | |||||
| bool uncompressTo (const File& targetDirectory, | |||||
| bool shouldOverwriteFiles = true); | bool shouldOverwriteFiles = true); | ||||
| /** Uncompresses one of the entries from the zip file. | |||||
| This will expand the entry and write it in a target directory. The entry's path is used to | |||||
| determine which subfolder of the target should contain the new file. | |||||
| @param index the index of the entry to uncompress | |||||
| @param targetDirectory the root folder to uncompress into | |||||
| @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones | |||||
| @returns true if the files is successfully unzipped | |||||
| */ | |||||
| bool uncompressEntry (int index, | |||||
| const File& targetDirectory, | |||||
| bool shouldOverwriteFiles = true); | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| @@ -40269,8 +40292,8 @@ public: | |||||
| The model pointer passed-in can be null, in which case you can set it later | The model pointer passed-in can be null, in which case you can set it later | ||||
| with setModel(). | with setModel(). | ||||
| */ | */ | ||||
| ListBox (const String& componentName, | |||||
| ListBoxModel* model); | |||||
| ListBox (const String& componentName = String::empty, | |||||
| ListBoxModel* model = 0); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~ListBox(); | ~ListBox(); | ||||
| @@ -494,8 +494,6 @@ const MidiMessage MidiMessage::noteOff (const int channel, | |||||
| const MidiMessage MidiMessage::allNotesOff (const int channel) throw() | const MidiMessage MidiMessage::allNotesOff (const int channel) throw() | ||||
| { | { | ||||
| jassert (channel > 0 && channel <= 16); | |||||
| return controllerEvent (channel, 123, 0); | return controllerEvent (channel, 123, 0); | ||||
| } | } | ||||
| @@ -172,7 +172,6 @@ struct fxProgramSet | |||||
| char chunk[8]; // variable | char chunk[8]; // variable | ||||
| }; | }; | ||||
| static long vst_swap (const long x) throw() | static long vst_swap (const long x) throw() | ||||
| { | { | ||||
| #ifdef JUCE_LITTLE_ENDIAN | #ifdef JUCE_LITTLE_ENDIAN | ||||
| @@ -194,6 +193,21 @@ static float vst_swapFloat (const float x) throw() | |||||
| #endif | #endif | ||||
| } | } | ||||
| static double getVSTHostTimeNanoseconds() | |||||
| { | |||||
| #if JUCE_WINDOWS | |||||
| return timeGetTime() * 1000000.0; | |||||
| #elif JUCE_LINUX | |||||
| timeval micro; | |||||
| gettimeofday (µ, 0); | |||||
| return micro.tv_usec * 1000.0; | |||||
| #elif JUCE_MAC | |||||
| UnsignedWide micro; | |||||
| Microseconds (µ); | |||||
| return micro.lo * 1000.0; | |||||
| #endif | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| typedef AEffect* (*MainCall) (audioMasterCallback); | typedef AEffect* (*MainCall) (audioMasterCallback); | ||||
| @@ -304,22 +318,16 @@ static void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) th | |||||
| static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) throw() | static void translateJuceToXMotionModifiers (const MouseEvent& e, XEvent& ev) throw() | ||||
| { | { | ||||
| if (e.mods.isLeftButtonDown()) | |||||
| ev.xmotion.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) | |||||
| ev.xmotion.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) | |||||
| ev.xmotion.state |= Button2Mask; | |||||
| if (e.mods.isLeftButtonDown()) ev.xmotion.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) ev.xmotion.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) ev.xmotion.state |= Button2Mask; | |||||
| } | } | ||||
| static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) throw() | static void translateJuceToXCrossingModifiers (const MouseEvent& e, XEvent& ev) throw() | ||||
| { | { | ||||
| if (e.mods.isLeftButtonDown()) | |||||
| ev.xcrossing.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) | |||||
| ev.xcrossing.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) | |||||
| ev.xcrossing.state |= Button2Mask; | |||||
| if (e.mods.isLeftButtonDown()) ev.xcrossing.state |= Button1Mask; | |||||
| else if (e.mods.isRightButtonDown()) ev.xcrossing.state |= Button3Mask; | |||||
| else if (e.mods.isMiddleButtonDown()) ev.xcrossing.state |= Button2Mask; | |||||
| } | } | ||||
| static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) throw() | static void translateJuceToXMouseWheelModifiers (const MouseEvent& e, const float increment, XEvent& ev) throw() | ||||
| @@ -408,7 +416,6 @@ public: | |||||
| ~ModuleHandle() | ~ModuleHandle() | ||||
| { | { | ||||
| getActiveModules().removeValue (this); | getActiveModules().removeValue (this); | ||||
| close(); | close(); | ||||
| } | } | ||||
| @@ -710,7 +717,7 @@ public: | |||||
| } | } | ||||
| const String getName() const { return name; } | const String getName() const { return name; } | ||||
| int getUID() const throw(); | |||||
| int getUID() const; | |||||
| bool acceptsMidi() const { return wantsMidiMessages; } | bool acceptsMidi() const { return wantsMidiMessages; } | ||||
| bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } | bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } | ||||
| @@ -773,7 +780,6 @@ private: | |||||
| MidiBuffer incomingMidi; | MidiBuffer incomingMidi; | ||||
| VSTMidiEventList midiEventsToSend; | VSTMidiEventList midiEventsToSend; | ||||
| VstTimeInfo vstHostTime; | VstTimeInfo vstHostTime; | ||||
| HeapBlock <float*> channels; | |||||
| ReferenceCountedObjectPtr <ModuleHandle> module; | ReferenceCountedObjectPtr <ModuleHandle> module; | ||||
| @@ -781,7 +787,7 @@ private: | |||||
| int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const; | int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const; | ||||
| bool restoreProgramSettings (const fxProgram* const prog); | bool restoreProgramSettings (const fxProgram* const prog); | ||||
| const String getCurrentProgramName(); | const String getCurrentProgramName(); | ||||
| void setParamsInProgramBlock (fxProgram* const prog) throw(); | |||||
| void setParamsInProgramBlock (fxProgram* const prog); | |||||
| void updateStoredProgramNames(); | void updateStoredProgramNames(); | ||||
| void initialise(); | void initialise(); | ||||
| void handleMidiFromPlugin (const VstEvents* const events); | void handleMidiFromPlugin (const VstEvents* const events); | ||||
| @@ -796,8 +802,8 @@ private: | |||||
| bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB); | bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB); | ||||
| int getVersionNumber() const throw() { return effect != 0 ? effect->version : 0; } | int getVersionNumber() const throw() { return effect != 0 ? effect->version : 0; } | ||||
| const String getVersion() const throw(); | |||||
| const String getCategory() const throw(); | |||||
| const String getVersion() const; | |||||
| const String getCategory() const; | |||||
| bool hasEditor() const throw() { return effect != 0 && (effect->flags & effFlagsHasEditor) != 0; } | bool hasEditor() const throw() { return effect != 0 && (effect->flags & effFlagsHasEditor) != 0; } | ||||
| void setPower (const bool on); | void setPower (const bool on); | ||||
| @@ -869,34 +875,32 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHan | |||||
| VSTPluginInstance::~VSTPluginInstance() | VSTPluginInstance::~VSTPluginInstance() | ||||
| { | { | ||||
| { | |||||
| const ScopedLock sl (lock); | |||||
| const ScopedLock sl (lock); | |||||
| jassert (insideVSTCallback == 0); | |||||
| jassert (insideVSTCallback == 0); | |||||
| if (effect != 0 && effect->magic == kEffectMagic) | |||||
| if (effect != 0 && effect->magic == kEffectMagic) | |||||
| { | |||||
| try | |||||
| { | { | ||||
| try | |||||
| { | |||||
| #if JUCE_MAC | #if JUCE_MAC | ||||
| if (module->resFileId != 0) | |||||
| UseResFile (module->resFileId); | |||||
| if (module->resFileId != 0) | |||||
| UseResFile (module->resFileId); | |||||
| #endif | #endif | ||||
| // Must delete any editors before deleting the plugin instance! | |||||
| jassert (getActiveEditor() == 0); | |||||
| // Must delete any editors before deleting the plugin instance! | |||||
| jassert (getActiveEditor() == 0); | |||||
| _fpreset(); // some dodgy plugs fuck around with this | |||||
| _fpreset(); // some dodgy plugs fuck around with this | |||||
| module->closeEffect (effect); | |||||
| } | |||||
| catch (...) | |||||
| {} | |||||
| module->closeEffect (effect); | |||||
| } | } | ||||
| module = 0; | |||||
| effect = 0; | |||||
| catch (...) | |||||
| {} | |||||
| } | } | ||||
| module = 0; | |||||
| effect = 0; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -964,8 +968,6 @@ void VSTPluginInstance::prepareToPlay (double sampleRate_, | |||||
| setLatencySamples (effect->initialDelay); | setLatencySamples (effect->initialDelay); | ||||
| channels.calloc (jmax (16, getNumOutputChannels(), getNumInputChannels()) + 2); | |||||
| vstHostTime.tempo = 120.0; | vstHostTime.tempo = 120.0; | ||||
| vstHostTime.timeSigNumerator = 4; | vstHostTime.timeSigNumerator = 4; | ||||
| vstHostTime.timeSigDenominator = 4; | vstHostTime.timeSigDenominator = 4; | ||||
| @@ -1019,7 +1021,6 @@ void VSTPluginInstance::releaseResources() | |||||
| incomingMidi.clear(); | incomingMidi.clear(); | ||||
| midiEventsToSend.freeEvents(); | midiEventsToSend.freeEvents(); | ||||
| channels.free(); | |||||
| } | } | ||||
| void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | ||||
| @@ -1049,17 +1050,7 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| vstHostTime.flags &= ~kVstTransportPlaying; | vstHostTime.flags &= ~kVstTransportPlaying; | ||||
| } | } | ||||
| #if JUCE_WINDOWS | |||||
| vstHostTime.nanoSeconds = timeGetTime() * 1000000.0; | |||||
| #elif JUCE_LINUX | |||||
| timeval micro; | |||||
| gettimeofday (µ, 0); | |||||
| vstHostTime.nanoSeconds = micro.tv_usec * 1000.0; | |||||
| #elif JUCE_MAC | |||||
| UnsignedWide micro; | |||||
| Microseconds (µ); | |||||
| vstHostTime.nanoSeconds = micro.lo * 1000.0; | |||||
| #endif | |||||
| vstHostTime.nanoSeconds = getVSTHostTimeNanoseconds(); | |||||
| if (wantsMidiMessages) | if (wantsMidiMessages) | ||||
| { | { | ||||
| @@ -1084,21 +1075,13 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| {} | {} | ||||
| } | } | ||||
| int i; | |||||
| const int maxChans = jmax (effect->numInputs, effect->numOutputs); | |||||
| for (i = 0; i < maxChans; ++i) | |||||
| channels[i] = buffer.getSampleData (i); | |||||
| channels [maxChans] = 0; | |||||
| _clearfp(); | _clearfp(); | ||||
| if ((effect->flags & effFlagsCanReplacing) != 0) | if ((effect->flags & effFlagsCanReplacing) != 0) | ||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| effect->processReplacing (effect, channels, channels, numSamples); | |||||
| effect->processReplacing (effect, buffer.getArrayOfChannels(), buffer.getArrayOfChannels(), numSamples); | |||||
| } | } | ||||
| catch (...) | catch (...) | ||||
| {} | {} | ||||
| @@ -1108,22 +1091,15 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||||
| tempBuffer.setSize (effect->numOutputs, numSamples); | tempBuffer.setSize (effect->numOutputs, numSamples); | ||||
| tempBuffer.clear(); | tempBuffer.clear(); | ||||
| float* outs [64]; | |||||
| for (i = effect->numOutputs; --i >= 0;) | |||||
| outs[i] = tempBuffer.getSampleData (i); | |||||
| outs [effect->numOutputs] = 0; | |||||
| try | try | ||||
| { | { | ||||
| effect->process (effect, channels, outs, numSamples); | |||||
| effect->process (effect, buffer.getArrayOfChannels(), tempBuffer.getArrayOfChannels(), numSamples); | |||||
| } | } | ||||
| catch (...) | catch (...) | ||||
| {} | {} | ||||
| for (i = effect->numOutputs; --i >= 0;) | |||||
| buffer.copyFrom (i, 0, outs[i], numSamples); | |||||
| for (int i = effect->numOutputs; --i >= 0;) | |||||
| buffer.copyFrom (i, 0, tempBuffer.getSampleData (i), numSamples); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -1604,7 +1580,7 @@ private: | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_WINDOWS | #if JUCE_WINDOWS | ||||
| void checkPluginWindowSize() throw() | |||||
| void checkPluginWindowSize() | |||||
| { | { | ||||
| RECT r; | RECT r; | ||||
| GetWindowRect (pluginHWND, &r); | GetWindowRect (pluginHWND, &r); | ||||
| @@ -1625,7 +1601,7 @@ private: | |||||
| { | { | ||||
| for (int i = activeVSTWindows.size(); --i >= 0;) | for (int i = activeVSTWindows.size(); --i >= 0;) | ||||
| { | { | ||||
| const VSTPluginWindow* const w = (const VSTPluginWindow*) activeVSTWindows.getUnchecked (i); | |||||
| const VSTPluginWindow* const w = activeVSTWindows.getUnchecked (i); | |||||
| if (w->pluginHWND == hW) | if (w->pluginHWND == hW) | ||||
| { | { | ||||
| @@ -2026,7 +2002,7 @@ bool VSTPluginInstance::loadFromFXBFile (const void* const data, | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) throw() | |||||
| void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) | |||||
| { | { | ||||
| const int numParams = getNumParameters(); | const int numParams = getNumParameters(); | ||||
| @@ -2184,30 +2160,16 @@ int VSTPluginInstance::dispatch (const int opcode, const int index, const int va | |||||
| { | { | ||||
| if (effect != 0) | if (effect != 0) | ||||
| { | { | ||||
| #if JUCE_MAC | |||||
| #if JUCE_MAC | |||||
| if (module->resFileId != 0) | if (module->resFileId != 0) | ||||
| UseResFile (module->resFileId); | UseResFile (module->resFileId); | ||||
| CGrafPtr oldPort; | |||||
| if (getActiveEditor() != 0) | |||||
| { | |||||
| const Point<int> pos (getActiveEditor()->relativePositionToOtherComponent (getActiveEditor()->getTopLevelComponent(), Point<int>())); | |||||
| GetPort (&oldPort); | |||||
| SetPortWindowPort ((WindowRef) getActiveEditor()->getWindowHandle()); | |||||
| SetOrigin (-pos.getX(), -pos.getY()); | |||||
| } | |||||
| #endif | |||||
| #endif | |||||
| result = effect->dispatcher (effect, opcode, index, value, ptr, opt); | result = effect->dispatcher (effect, opcode, index, value, ptr, opt); | ||||
| #if JUCE_MAC | |||||
| if (getActiveEditor() != 0) | |||||
| SetPort (oldPort); | |||||
| #if JUCE_MAC | |||||
| module->resFileId = CurResFile(); | module->resFileId = CurResFile(); | ||||
| #endif | |||||
| #endif | |||||
| --insideVSTCallback; | --insideVSTCallback; | ||||
| return result; | return result; | ||||
| @@ -2236,7 +2198,7 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||||
| switch (opcode) | switch (opcode) | ||||
| { | { | ||||
| case audioMasterCanDo: | |||||
| case audioMasterCanDo: | |||||
| { | { | ||||
| static const char* canDos[] = { "supplyIdle", | static const char* canDos[] = { "supplyIdle", | ||||
| "sendVstEvents", | "sendVstEvents", | ||||
| @@ -2254,19 +2216,14 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| case audioMasterVersion: | |||||
| return 0x2400; | |||||
| case audioMasterCurrentId: | |||||
| return shellUIDToCreate; | |||||
| case audioMasterGetNumAutomatableParameters: | |||||
| return 0; | |||||
| case audioMasterGetAutomationState: | |||||
| return 1; | |||||
| case audioMasterVersion: return 0x2400; | |||||
| case audioMasterCurrentId: return shellUIDToCreate; | |||||
| case audioMasterGetNumAutomatableParameters: return 0; | |||||
| case audioMasterGetAutomationState: return 1; | |||||
| case audioMasterGetVendorVersion: return 0x0101; | |||||
| case audioMasterGetVendorVersion: | |||||
| return 0x0101; | |||||
| case audioMasterGetVendorString: | |||||
| case audioMasterGetProductString: | |||||
| case audioMasterGetVendorString: | |||||
| case audioMasterGetProductString: | |||||
| { | { | ||||
| String hostName ("Juce VST Host"); | String hostName ("Juce VST Host"); | ||||
| @@ -2274,21 +2231,16 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||||
| hostName = JUCEApplication::getInstance()->getApplicationName(); | hostName = JUCEApplication::getInstance()->getApplicationName(); | ||||
| hostName.copyToCString ((char*) ptr, jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | hostName.copyToCString ((char*) ptr, jmin (kVstMaxVendorStrLen, kVstMaxProductStrLen) - 1); | ||||
| break; | |||||
| } | } | ||||
| break; | |||||
| case audioMasterGetSampleRate: | |||||
| return (VstIntPtr) defaultVSTSampleRateValue; | |||||
| case audioMasterGetBlockSize: | |||||
| return (VstIntPtr) defaultVSTBlockSizeValue; | |||||
| case audioMasterSetOutputSampleRate: | |||||
| return 0; | |||||
| case audioMasterGetSampleRate: return (VstIntPtr) defaultVSTSampleRateValue; | |||||
| case audioMasterGetBlockSize: return (VstIntPtr) defaultVSTBlockSizeValue; | |||||
| case audioMasterSetOutputSampleRate: return 0; | |||||
| default: | |||||
| DBG ("*** Unhandled VST Callback: " + String ((int) opcode)); | |||||
| break; | |||||
| default: | |||||
| DBG ("*** Unhandled VST Callback: " + String ((int) opcode)); | |||||
| break; | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -2430,7 +2382,7 @@ static VstIntPtr VSTCALLBACK audioMaster (AEffect* effect, VstInt32 opcode, VstI | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| const String VSTPluginInstance::getVersion() const throw() | |||||
| const String VSTPluginInstance::getVersion() const | |||||
| { | { | ||||
| unsigned int v = dispatch (effGetVendorVersion, 0, 0, 0, 0); | unsigned int v = dispatch (effGetVendorVersion, 0, 0, 0, 0); | ||||
| @@ -2464,7 +2416,7 @@ const String VSTPluginInstance::getVersion() const throw() | |||||
| return s; | return s; | ||||
| } | } | ||||
| int VSTPluginInstance::getUID() const throw() | |||||
| int VSTPluginInstance::getUID() const | |||||
| { | { | ||||
| int uid = effect != 0 ? effect->uniqueID : 0; | int uid = effect != 0 ? effect->uniqueID : 0; | ||||
| @@ -2474,50 +2426,22 @@ int VSTPluginInstance::getUID() const throw() | |||||
| return uid; | return uid; | ||||
| } | } | ||||
| const String VSTPluginInstance::getCategory() const throw() | |||||
| const String VSTPluginInstance::getCategory() const | |||||
| { | { | ||||
| const char* result = 0; | const char* result = 0; | ||||
| switch (dispatch (effGetPlugCategory, 0, 0, 0, 0)) | switch (dispatch (effGetPlugCategory, 0, 0, 0, 0)) | ||||
| { | { | ||||
| case kPlugCategEffect: | |||||
| result = "Effect"; | |||||
| break; | |||||
| case kPlugCategSynth: | |||||
| result = "Synth"; | |||||
| break; | |||||
| case kPlugCategAnalysis: | |||||
| result = "Anaylsis"; | |||||
| break; | |||||
| case kPlugCategMastering: | |||||
| result = "Mastering"; | |||||
| break; | |||||
| case kPlugCategSpacializer: | |||||
| result = "Spacial"; | |||||
| break; | |||||
| case kPlugCategRoomFx: | |||||
| result = "Reverb"; | |||||
| break; | |||||
| case kPlugSurroundFx: | |||||
| result = "Surround"; | |||||
| break; | |||||
| case kPlugCategRestoration: | |||||
| result = "Restoration"; | |||||
| break; | |||||
| case kPlugCategGenerator: | |||||
| result = "Tone generation"; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| case kPlugCategEffect: result = "Effect"; break; | |||||
| case kPlugCategSynth: result = "Synth"; break; | |||||
| case kPlugCategAnalysis: result = "Anaylsis"; break; | |||||
| case kPlugCategMastering: result = "Mastering"; break; | |||||
| case kPlugCategSpacializer: result = "Spacial"; break; | |||||
| case kPlugCategRoomFx: result = "Reverb"; break; | |||||
| case kPlugSurroundFx: result = "Surround"; break; | |||||
| case kPlugCategRestoration: result = "Restoration"; break; | |||||
| case kPlugCategGenerator: result = "Tone generation"; break; | |||||
| default: break; | |||||
| } | } | ||||
| return result; | return result; | ||||
| @@ -2957,11 +2881,9 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdenti | |||||
| return false; | return false; | ||||
| #elif JUCE_WINDOWS | #elif JUCE_WINDOWS | ||||
| return f.existsAsFile() | |||||
| && f.hasFileExtension (".dll"); | |||||
| return f.existsAsFile() && f.hasFileExtension (".dll"); | |||||
| #elif JUCE_LINUX | #elif JUCE_LINUX | ||||
| return f.existsAsFile() | |||||
| && f.hasFileExtension (".so"); | |||||
| return f.existsAsFile() && f.hasFileExtension (".so"); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 60 | |||||
| #define JUCE_BUILDNUMBER 61 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -175,8 +175,8 @@ public: | |||||
| The model pointer passed-in can be null, in which case you can set it later | The model pointer passed-in can be null, in which case you can set it later | ||||
| with setModel(). | with setModel(). | ||||
| */ | */ | ||||
| ListBox (const String& componentName, | |||||
| ListBoxModel* model); | |||||
| ListBox (const String& componentName = String::empty, | |||||
| ListBoxModel* model = 0); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~ListBox(); | ~ListBox(); | ||||
| @@ -115,8 +115,6 @@ public: | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| friend class File; | |||||
| //============================================================================== | //============================================================================== | ||||
| class NativeIterator | class NativeIterator | ||||
| { | { | ||||
| @@ -532,97 +532,40 @@ const String File::loadFileAsString() const | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| bool File::fileTypeMatches (const int whatToLookFor, const bool isDir, const bool isHidden) | |||||
| { | |||||
| return (whatToLookFor & (isDir ? findDirectories | |||||
| : findFiles)) != 0 | |||||
| && ((! isHidden) || (whatToLookFor & File::ignoreHiddenFiles) == 0); | |||||
| } | |||||
| int File::findChildFiles (Array<File>& results, | int File::findChildFiles (Array<File>& results, | ||||
| const int whatToLookFor, | const int whatToLookFor, | ||||
| const bool searchRecursively, | const bool searchRecursively, | ||||
| const String& wildCardPattern) const | const String& wildCardPattern) const | ||||
| { | { | ||||
| // you have to specify the type of files you're looking for! | |||||
| jassert ((whatToLookFor & (findFiles | findDirectories)) != 0); | |||||
| DirectoryIterator di (*this, searchRecursively, wildCardPattern, whatToLookFor); | |||||
| int total = 0; | int total = 0; | ||||
| if (isDirectory()) | |||||
| while (di.next()) | |||||
| { | { | ||||
| // find child files or directories in this directory first.. | |||||
| String path (addTrailingSeparator (fullPath)), filename; | |||||
| bool itemIsDirectory, itemIsHidden; | |||||
| DirectoryIterator::NativeIterator i (path, wildCardPattern); | |||||
| while (i.next (filename, &itemIsDirectory, &itemIsHidden, 0, 0, 0, 0)) | |||||
| { | |||||
| if (! filename.containsOnly (".")) | |||||
| { | |||||
| const File fileFound (path + filename, 0); | |||||
| if (fileTypeMatches (whatToLookFor, itemIsDirectory, itemIsHidden)) | |||||
| { | |||||
| results.add (fileFound); | |||||
| ++total; | |||||
| } | |||||
| if (searchRecursively && itemIsDirectory | |||||
| && ((! itemIsHidden) || (whatToLookFor & File::ignoreHiddenFiles) == 0)) | |||||
| { | |||||
| total += fileFound.findChildFiles (results, whatToLookFor, true, wildCardPattern); | |||||
| } | |||||
| } | |||||
| } | |||||
| results.add (di.getFile()); | |||||
| ++total; | |||||
| } | } | ||||
| return total; | return total; | ||||
| } | } | ||||
| int File::getNumberOfChildFiles (const int whatToLookFor, | |||||
| const String& wildCardPattern) const | |||||
| int File::getNumberOfChildFiles (const int whatToLookFor, const String& wildCardPattern) const | |||||
| { | { | ||||
| // you have to specify the type of files you're looking for! | |||||
| jassert (whatToLookFor > 0 && whatToLookFor <= 3); | |||||
| int count = 0; | |||||
| if (isDirectory()) | |||||
| { | |||||
| String filename; | |||||
| bool itemIsDirectory, itemIsHidden; | |||||
| DirectoryIterator::NativeIterator i (*this, wildCardPattern); | |||||
| DirectoryIterator di (*this, false, "*", whatToLookFor); | |||||
| while (i.next (filename, &itemIsDirectory, &itemIsHidden, 0, 0, 0, 0)) | |||||
| if (fileTypeMatches (whatToLookFor, itemIsDirectory, itemIsHidden) | |||||
| && ! filename.containsOnly (".")) | |||||
| ++count; | |||||
| } | |||||
| else | |||||
| { | |||||
| // trying to search for files inside a non-directory? | |||||
| jassertfalse; | |||||
| } | |||||
| int total = 0; | |||||
| while (di.next()) | |||||
| ++total; | |||||
| return count; | |||||
| return total; | |||||
| } | } | ||||
| bool File::containsSubDirectories() const | bool File::containsSubDirectories() const | ||||
| { | { | ||||
| if (isDirectory()) | if (isDirectory()) | ||||
| { | { | ||||
| String filename; | |||||
| bool itemIsDirectory; | |||||
| DirectoryIterator::NativeIterator i (*this, "*"); | |||||
| while (i.next (filename, &itemIsDirectory, 0, 0, 0, 0, 0)) | |||||
| if (itemIsDirectory) | |||||
| return true; | |||||
| DirectoryIterator di (*this, false, "*", findDirectories); | |||||
| return di.next(); | |||||
| } | } | ||||
| return false; | return false; | ||||
| @@ -939,7 +939,6 @@ private: | |||||
| bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | ||||
| static const String parseAbsolutePath (const String& path); | static const String parseAbsolutePath (const String& path); | ||||
| static bool fileTypeMatches (int whatToLookFor, bool isDir, bool isHidden); | |||||
| }; | }; | ||||
| @@ -374,46 +374,61 @@ int ZipFile::findEndOfZipEntryTable (InputStream* input, int& numEntries) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| void ZipFile::uncompressTo (const File& targetDirectory, | |||||
| bool ZipFile::uncompressTo (const File& targetDirectory, | |||||
| const bool shouldOverwriteFiles) | const bool shouldOverwriteFiles) | ||||
| { | { | ||||
| for (int i = 0; i < entries.size(); ++i) | for (int i = 0; i < entries.size(); ++i) | ||||
| { | |||||
| const ZipEntry& zei = entries.getUnchecked(i)->entry; | |||||
| if (! uncompressEntry (i, targetDirectory, shouldOverwriteFiles)) | |||||
| return false; | |||||
| return true; | |||||
| } | |||||
| bool ZipFile::uncompressEntry (const int index, | |||||
| const File& targetDirectory, | |||||
| bool shouldOverwriteFiles) | |||||
| { | |||||
| const ZipEntryInfo* zei = entries [index]; | |||||
| const File targetFile (targetDirectory.getChildFile (zei.filename)); | |||||
| if (zei != 0) | |||||
| { | |||||
| const File targetFile (targetDirectory.getChildFile (zei->entry.filename)); | |||||
| if (zei.filename.endsWithChar ('/')) | |||||
| if (zei->entry.filename.endsWithChar ('/')) | |||||
| { | { | ||||
| targetFile.createDirectory(); // (entry is a directory, not a file) | targetFile.createDirectory(); // (entry is a directory, not a file) | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| ScopedPointer <InputStream> in (createStreamForEntry (i)); | |||||
| ScopedPointer<InputStream> in (createStreamForEntry (index)); | |||||
| if (in != 0) | if (in != 0) | ||||
| { | { | ||||
| if (shouldOverwriteFiles) | |||||
| targetFile.deleteFile(); | |||||
| if (shouldOverwriteFiles && ! targetFile.deleteFile()) | |||||
| return false; | |||||
| if ((! targetFile.exists()) | |||||
| && targetFile.getParentDirectory().createDirectory()) | |||||
| if ((! targetFile.exists()) && targetFile.getParentDirectory().createDirectory()) | |||||
| { | { | ||||
| ScopedPointer <FileOutputStream> out (targetFile.createOutputStream()); | |||||
| ScopedPointer<FileOutputStream> out (targetFile.createOutputStream()); | |||||
| if (out != 0) | if (out != 0) | ||||
| { | { | ||||
| out->writeFromInputStream (*in, -1); | out->writeFromInputStream (*in, -1); | ||||
| out = 0; | out = 0; | ||||
| targetFile.setCreationTime (zei.fileTime); | |||||
| targetFile.setLastModificationTime (zei.fileTime); | |||||
| targetFile.setLastAccessTime (zei.fileTime); | |||||
| targetFile.setCreationTime (zei->entry.fileTime); | |||||
| targetFile.setLastModificationTime (zei->entry.fileTime); | |||||
| targetFile.setLastAccessTime (zei->entry.fileTime); | |||||
| return true; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -128,18 +128,42 @@ public: | |||||
| */ | */ | ||||
| InputStream* createStreamForEntry (int index); | InputStream* createStreamForEntry (int index); | ||||
| /** Creates a stream that can read from one of the zip file's entries. | |||||
| The stream that is returned must be deleted by the caller (and | |||||
| zero might be returned if a stream can't be opened for some reason). | |||||
| The stream must not be used after the ZipFile object that created | |||||
| has been deleted. | |||||
| */ | |||||
| InputStream* createStreamForEntry (ZipEntry& entry); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Uncompresses all of the files in the zip file. | /** Uncompresses all of the files in the zip file. | ||||
| This will expand all the entires into a target directory. The relative | |||||
| This will expand all the entries into a target directory. The relative | |||||
| paths of the entries are used. | paths of the entries are used. | ||||
| @param targetDirectory the root folder to uncompress to | @param targetDirectory the root folder to uncompress to | ||||
| @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones | @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones | ||||
| @returns true if all the files are successfully unzipped | |||||
| */ | */ | ||||
| void uncompressTo (const File& targetDirectory, | |||||
| bool uncompressTo (const File& targetDirectory, | |||||
| bool shouldOverwriteFiles = true); | bool shouldOverwriteFiles = true); | ||||
| /** Uncompresses one of the entries from the zip file. | |||||
| This will expand the entry and write it in a target directory. The entry's path is used to | |||||
| determine which subfolder of the target should contain the new file. | |||||
| @param index the index of the entry to uncompress | |||||
| @param targetDirectory the root folder to uncompress into | |||||
| @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones | |||||
| @returns true if the files is successfully unzipped | |||||
| */ | |||||
| bool uncompressEntry (int index, | |||||
| const File& targetDirectory, | |||||
| bool shouldOverwriteFiles = true); | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -789,6 +789,42 @@ public: | |||||
| outputNames.clear(); | outputNames.clear(); | ||||
| outputIds.clear(); | outputIds.clear(); | ||||
| /* void** hints = 0; | |||||
| if (snd_device_name_hint (-1, "pcm", &hints) >= 0) | |||||
| { | |||||
| for (void** hint = hints; *hint != 0; ++hint) | |||||
| { | |||||
| const String name (getHint (*hint, "NAME")); | |||||
| if (name.isNotEmpty()) | |||||
| { | |||||
| const String ioid (getHint (*hint, "IOID")); | |||||
| String desc (getHint (*hint, "DESC")); | |||||
| if (desc.isEmpty()) | |||||
| desc = name; | |||||
| desc = desc.replaceCharacters ("\n\r", " "); | |||||
| DBG ("name: " << name << "\ndesc: " << desc << "\nIO: " << ioid); | |||||
| if (ioid.isEmpty() || ioid == "Input") | |||||
| { | |||||
| inputNames.add (desc); | |||||
| inputIds.add (name); | |||||
| } | |||||
| if (ioid.isEmpty() || ioid == "Output") | |||||
| { | |||||
| outputNames.add (desc); | |||||
| outputIds.add (name); | |||||
| } | |||||
| } | |||||
| } | |||||
| snd_device_name_free_hint (hints); | |||||
| } | |||||
| */ | |||||
| snd_ctl_t* handle = 0; | snd_ctl_t* handle = 0; | ||||
| snd_ctl_card_info_t* info = 0; | snd_ctl_card_info_t* info = 0; | ||||
| snd_ctl_card_info_alloca (&info); | snd_ctl_card_info_alloca (&info); | ||||
| @@ -925,6 +961,14 @@ private: | |||||
| return (isInput || isOutput) && rates.size() > 0; | return (isInput || isOutput) && rates.size() > 0; | ||||
| } | } | ||||
| /*static const String getHint (void* hint, const char* type) | |||||
| { | |||||
| char* const n = snd_device_name_get_hint (hint, type); | |||||
| const String s ((const char*) n); | |||||
| free (n); | |||||
| return s; | |||||
| }*/ | |||||
| ALSAAudioIODeviceType (const ALSAAudioIODeviceType&); | ALSAAudioIODeviceType (const ALSAAudioIODeviceType&); | ||||
| ALSAAudioIODeviceType& operator= (const ALSAAudioIODeviceType&); | ALSAAudioIODeviceType& operator= (const ALSAAudioIODeviceType&); | ||||
| }; | }; | ||||