| @@ -45,6 +45,7 @@ endif | |||
| OBJECTS := \ | |||
| $(OBJDIR)/jucer_DocumentEditorComponent_695dff1d.o \ | |||
| $(OBJDIR)/jucer_FilePreviewComponent_55512f53.o \ | |||
| $(OBJDIR)/jucer_JuceUpdater_cf7865c4.o \ | |||
| $(OBJDIR)/jucer_Main_f8488f5b.o \ | |||
| $(OBJDIR)/jucer_MainWindow_1e163aeb.o \ | |||
| $(OBJDIR)/jucer_OpenDocumentManager_4c72d210.o \ | |||
| @@ -95,6 +96,11 @@ $(OBJDIR)/jucer_FilePreviewComponent_55512f53.o: ../../Source/Application/jucer_ | |||
| @echo "Compiling jucer_FilePreviewComponent.cpp" | |||
| @$(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 | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling jucer_Main.cpp" | |||
| @@ -19,6 +19,7 @@ | |||
| 2E6836738CE7EB452FDC7E9A = { isa = PBXBuildFile; fileRef = D9FB1A5365FEEB854A0FF7BF; }; | |||
| D6D0659F3F3504012246F13D = { isa = PBXBuildFile; fileRef = AA3CBE4A2AC3E9411426F630; }; | |||
| 8BAE4D8EA7F247DA0A4D3A5C = { isa = PBXBuildFile; fileRef = F617CE0630ADB0628A34D6BF; }; | |||
| 280FE650B3F02AD9E821EA37 = { isa = PBXBuildFile; fileRef = 832701705EC0EC9484F9D9C2; }; | |||
| 9950893AA82F86F1EEE55BED = { isa = PBXBuildFile; fileRef = D77EAC704C96F798B1C69A0D; }; | |||
| C2F198C7058FC1A88A600645 = { isa = PBXBuildFile; fileRef = B06694E3C7EB89E3DDEFCBD0; }; | |||
| 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; }; | |||
| 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; }; | |||
| 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; }; | |||
| 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; }; | |||
| @@ -139,6 +142,8 @@ | |||
| F617CE0630ADB0628A34D6BF, | |||
| 330CB15608DEAF19D28C18DD, | |||
| 0CA0CCCEBFA0AC8C577FC915, | |||
| 832701705EC0EC9484F9D9C2, | |||
| AFC2F9A887CDBF7A0051CD09, | |||
| D77EAC704C96F798B1C69A0D, | |||
| B06694E3C7EB89E3DDEFCBD0, | |||
| 24378294003DC2D038D0534D, | |||
| @@ -304,6 +309,7 @@ | |||
| 5362E03ADF975A126C1F2F7B = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( | |||
| D6D0659F3F3504012246F13D, | |||
| 8BAE4D8EA7F247DA0A4D3A5C, | |||
| 280FE650B3F02AD9E821EA37, | |||
| 9950893AA82F86F1EEE55BED, | |||
| C2F198C7058FC1A88A600645, | |||
| A7C05B907BBCB4288FBC6428, | |||
| @@ -137,6 +137,8 @@ | |||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | |||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.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_MainWindow.cpp"/> | |||
| <File RelativePath="..\..\Source\Application\jucer_MainWindow.h"/> | |||
| @@ -137,6 +137,8 @@ | |||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.cpp"/> | |||
| <File RelativePath="..\..\Source\Application\jucer_FilePreviewComponent.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_MainWindow.cpp"/> | |||
| <File RelativePath="..\..\Source\Application\jucer_MainWindow.h"/> | |||
| @@ -124,6 +124,7 @@ | |||
| <ItemGroup> | |||
| <ClCompile Include="..\..\Source\Application\jucer_DocumentEditorComponent.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_MainWindow.cpp"/> | |||
| <ClCompile Include="..\..\Source\Application\jucer_OpenDocumentManager.cpp"/> | |||
| @@ -156,6 +157,7 @@ | |||
| <ClInclude Include="..\..\Source\Application\jucer_DocumentEditorComponent.h"/> | |||
| <ClInclude Include="..\..\Source\Application\jucer_FilePreviewComponent.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_OpenDocumentManager.h"/> | |||
| <ClInclude Include="..\..\Source\Code Editor\jucer_SourceCodeEditor.h"/> | |||
| @@ -31,6 +31,9 @@ | |||
| <ClCompile Include="..\..\Source\Application\jucer_FilePreviewComponent.cpp"> | |||
| <Filter>The Jucer\Application</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\Application\jucer_JuceUpdater.cpp"> | |||
| <Filter>The Jucer\Application</Filter> | |||
| </ClCompile> | |||
| <ClCompile Include="..\..\Source\Application\jucer_Main.cpp"> | |||
| <Filter>The Jucer\Application</Filter> | |||
| </ClCompile> | |||
| @@ -150,6 +153,9 @@ | |||
| <ClInclude Include="..\..\Source\jucer_Headers.h"> | |||
| <Filter>The Jucer\Application</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\Application\jucer_JuceUpdater.h"> | |||
| <Filter>The Jucer\Application</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="..\..\Source\Application\jucer_MainWindow.h"> | |||
| <Filter>The Jucer\Application</Filter> | |||
| </ClInclude> | |||
| @@ -45,6 +45,10 @@ | |||
| resource="0" file="Source/Application/jucer_FilePreviewComponent.h"/> | |||
| <FILE id="qXOJtpg" name="jucer_Headers.h" compile="0" resource="0" | |||
| 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="Glk9Bg" name="jucer_MainWindow.cpp" compile="1" resource="0" | |||
| file="Source/Application/jucer_MainWindow.cpp"/> | |||
| @@ -28,6 +28,7 @@ | |||
| #include "../jucer_Headers.h" | |||
| #include "jucer_MainWindow.h" | |||
| #include "jucer_JuceUpdater.h" | |||
| #include "../Project/jucer_NewProjectWizard.h" | |||
| @@ -161,7 +162,7 @@ public: | |||
| 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); | |||
| } | |||
| @@ -251,6 +252,10 @@ public: | |||
| menu.addSeparator(); | |||
| menu.addCommandItem (commandManager, CommandIDs::closeAllDocuments); | |||
| } | |||
| else if (topLevelMenuIndex == 4) // "Juce" menu | |||
| { | |||
| menu.addCommandItem (commandManager, CommandIDs::showJuceVersion); | |||
| } | |||
| return menu; | |||
| } | |||
| @@ -287,7 +292,8 @@ public: | |||
| CommandIDs::open, | |||
| CommandIDs::showPrefs, | |||
| CommandIDs::closeAllDocuments, | |||
| CommandIDs::saveAll }; | |||
| CommandIDs::saveAll, | |||
| CommandIDs::showJuceVersion }; | |||
| commands.addArray (ids, numElementsInArray (ids)); | |||
| } | |||
| @@ -321,6 +327,10 @@ public: | |||
| result.setActive (OpenDocumentManager::getInstance()->anyFilesNeedSaving()); | |||
| break; | |||
| case CommandIDs::showJuceVersion: | |||
| result.setInfo ("Download the latest JUCE version", "Checks online for any Juce updates", CommandCategories::general, 0); | |||
| break; | |||
| default: | |||
| JUCEApplication::getCommandInfo (commandID, result); | |||
| break; | |||
| @@ -336,6 +346,7 @@ public: | |||
| case CommandIDs::showPrefs: showPrefsPanel(); break; | |||
| case CommandIDs::saveAll: OpenDocumentManager::getInstance()->saveAll(); break; | |||
| case CommandIDs::closeAllDocuments: closeAllDocuments (true); break; | |||
| case CommandIDs::showJuceVersion: JuceUpdater::show (mainWindows[0]); break; | |||
| default: return JUCEApplication::perform (info); | |||
| } | |||
| @@ -39,6 +39,7 @@ namespace CommandIDs | |||
| static const int saveProjectAs = 0x200070; | |||
| static const int openProjectInIDE = 0x200071; | |||
| static const int showProjectSettings = 0x200072; | |||
| static const int showJuceVersion = 0x200073; | |||
| static const int saveAll = 0x200080; | |||
| 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__ | |||
| #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_Desc "Juce Demo Plugin" | |||
| @@ -7464,97 +7464,40 @@ const String File::loadFileAsString() const | |||
| 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, | |||
| const int whatToLookFor, | |||
| const bool searchRecursively, | |||
| 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; | |||
| 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; | |||
| } | |||
| 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 | |||
| { | |||
| 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; | |||
| @@ -10498,46 +10441,60 @@ int ZipFile::findEndOfZipEntryTable (InputStream* input, int& numEntries) | |||
| return 0; | |||
| } | |||
| void ZipFile::uncompressTo (const File& targetDirectory, | |||
| bool ZipFile::uncompressTo (const File& targetDirectory, | |||
| const bool shouldOverwriteFiles) | |||
| { | |||
| 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) | |||
| } | |||
| else | |||
| { | |||
| ScopedPointer <InputStream> in (createStreamForEntry (i)); | |||
| ScopedPointer<InputStream> in (createStreamForEntry (index)); | |||
| 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) | |||
| { | |||
| out->writeFromInputStream (*in, -1); | |||
| 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 | |||
| @@ -29276,8 +29233,6 @@ const MidiMessage MidiMessage::noteOff (const int channel, | |||
| const MidiMessage MidiMessage::allNotesOff (const int channel) throw() | |||
| { | |||
| jassert (channel > 0 && channel <= 16); | |||
| return controllerEvent (channel, 123, 0); | |||
| } | |||
| @@ -33121,6 +33076,21 @@ static float vst_swapFloat (const float x) throw() | |||
| #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); | |||
| 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() | |||
| { | |||
| 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() | |||
| { | |||
| 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() | |||
| @@ -33328,7 +33292,6 @@ public: | |||
| ~ModuleHandle() | |||
| { | |||
| getActiveModules().removeValue (this); | |||
| close(); | |||
| } | |||
| @@ -33626,7 +33589,7 @@ public: | |||
| } | |||
| const String getName() const { return name; } | |||
| int getUID() const throw(); | |||
| int getUID() const; | |||
| bool acceptsMidi() const { return wantsMidiMessages; } | |||
| bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } | |||
| @@ -33683,14 +33646,13 @@ private: | |||
| MidiBuffer incomingMidi; | |||
| VSTMidiEventList midiEventsToSend; | |||
| VstTimeInfo vstHostTime; | |||
| HeapBlock <float*> channels; | |||
| ReferenceCountedObjectPtr <ModuleHandle> module; | |||
| int dispatch (const int opcode, const int index, const int value, void* const ptr, float opt) const; | |||
| bool restoreProgramSettings (const fxProgram* const prog); | |||
| const String getCurrentProgramName(); | |||
| void setParamsInProgramBlock (fxProgram* const prog) throw(); | |||
| void setParamsInProgramBlock (fxProgram* const prog); | |||
| void updateStoredProgramNames(); | |||
| void initialise(); | |||
| void handleMidiFromPlugin (const VstEvents* const events); | |||
| @@ -33705,8 +33667,8 @@ private: | |||
| bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB); | |||
| 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; } | |||
| void setPower (const bool on); | |||
| @@ -33777,34 +33739,32 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHan | |||
| 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 (module->resFileId != 0) | |||
| UseResFile (module->resFileId); | |||
| if (module->resFileId != 0) | |||
| UseResFile (module->resFileId); | |||
| #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() | |||
| @@ -33869,8 +33829,6 @@ void VSTPluginInstance::prepareToPlay (double sampleRate_, | |||
| setLatencySamples (effect->initialDelay); | |||
| channels.calloc (jmax (16, getNumOutputChannels(), getNumInputChannels()) + 2); | |||
| vstHostTime.tempo = 120.0; | |||
| vstHostTime.timeSigNumerator = 4; | |||
| vstHostTime.timeSigDenominator = 4; | |||
| @@ -33924,7 +33882,6 @@ void VSTPluginInstance::releaseResources() | |||
| incomingMidi.clear(); | |||
| midiEventsToSend.freeEvents(); | |||
| channels.free(); | |||
| } | |||
| void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||
| @@ -33954,17 +33911,7 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||
| 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) | |||
| { | |||
| @@ -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(); | |||
| if ((effect->flags & effFlagsCanReplacing) != 0) | |||
| { | |||
| try | |||
| { | |||
| effect->processReplacing (effect, channels, channels, numSamples); | |||
| effect->processReplacing (effect, buffer.getArrayOfChannels(), buffer.getArrayOfChannels(), numSamples); | |||
| } | |||
| catch (...) | |||
| {} | |||
| @@ -34013,22 +33952,15 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||
| tempBuffer.setSize (effect->numOutputs, numSamples); | |||
| tempBuffer.clear(); | |||
| float* outs [64]; | |||
| for (i = effect->numOutputs; --i >= 0;) | |||
| outs[i] = tempBuffer.getSampleData (i); | |||
| outs [effect->numOutputs] = 0; | |||
| try | |||
| { | |||
| effect->process (effect, channels, outs, numSamples); | |||
| effect->process (effect, buffer.getArrayOfChannels(), tempBuffer.getArrayOfChannels(), numSamples); | |||
| } | |||
| 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 | |||
| @@ -34496,7 +34428,7 @@ private: | |||
| } | |||
| #if JUCE_WINDOWS | |||
| void checkPluginWindowSize() throw() | |||
| void checkPluginWindowSize() | |||
| { | |||
| RECT r; | |||
| GetWindowRect (pluginHWND, &r); | |||
| @@ -34517,7 +34449,7 @@ private: | |||
| { | |||
| 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) | |||
| { | |||
| @@ -34913,7 +34845,7 @@ bool VSTPluginInstance::loadFromFXBFile (const void* const data, | |||
| return true; | |||
| } | |||
| void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) throw() | |||
| void VSTPluginInstance::setParamsInProgramBlock (fxProgram* const prog) | |||
| { | |||
| const int numParams = getNumParameters(); | |||
| @@ -35070,30 +35002,16 @@ int VSTPluginInstance::dispatch (const int opcode, const int index, const int va | |||
| { | |||
| if (effect != 0) | |||
| { | |||
| #if JUCE_MAC | |||
| #if JUCE_MAC | |||
| if (module->resFileId != 0) | |||
| 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); | |||
| #if JUCE_MAC | |||
| if (getActiveEditor() != 0) | |||
| SetPort (oldPort); | |||
| #if JUCE_MAC | |||
| module->resFileId = CurResFile(); | |||
| #endif | |||
| #endif | |||
| --insideVSTCallback; | |||
| return result; | |||
| @@ -35120,7 +35038,7 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||
| switch (opcode) | |||
| { | |||
| case audioMasterCanDo: | |||
| case audioMasterCanDo: | |||
| { | |||
| static const char* canDos[] = { "supplyIdle", | |||
| "sendVstEvents", | |||
| @@ -35138,19 +35056,14 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||
| 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"); | |||
| @@ -35158,21 +35071,16 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||
| hostName = JUCEApplication::getInstance()->getApplicationName(); | |||
| 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; | |||
| @@ -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); | |||
| @@ -35347,7 +35255,7 @@ const String VSTPluginInstance::getVersion() const throw() | |||
| return s; | |||
| } | |||
| int VSTPluginInstance::getUID() const throw() | |||
| int VSTPluginInstance::getUID() const | |||
| { | |||
| int uid = effect != 0 ? effect->uniqueID : 0; | |||
| @@ -35357,50 +35265,22 @@ int VSTPluginInstance::getUID() const throw() | |||
| return uid; | |||
| } | |||
| const String VSTPluginInstance::getCategory() const throw() | |||
| const String VSTPluginInstance::getCategory() const | |||
| { | |||
| const char* result = 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; | |||
| @@ -35833,11 +35713,9 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdenti | |||
| return false; | |||
| #elif JUCE_WINDOWS | |||
| return f.existsAsFile() | |||
| && f.hasFileExtension (".dll"); | |||
| return f.existsAsFile() && f.hasFileExtension (".dll"); | |||
| #elif JUCE_LINUX | |||
| return f.existsAsFile() | |||
| && f.hasFileExtension (".so"); | |||
| return f.existsAsFile() && f.hasFileExtension (".so"); | |||
| #endif | |||
| } | |||
| @@ -262076,6 +261954,42 @@ public: | |||
| outputNames.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_card_info_t* info = 0; | |||
| snd_ctl_card_info_alloca (&info); | |||
| @@ -262211,6 +262125,14 @@ private: | |||
| 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& operator= (const ALSAAudioIODeviceType&); | |||
| }; | |||
| @@ -64,7 +64,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 60 | |||
| #define JUCE_BUILDNUMBER 61 | |||
| /** Current Juce version number. | |||
| @@ -9433,7 +9433,6 @@ private: | |||
| bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | |||
| static const String parseAbsolutePath (const String& path); | |||
| static bool fileTypeMatches (int whatToLookFor, bool isDir, bool isHidden); | |||
| }; | |||
| @@ -15461,7 +15460,6 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| friend class File; | |||
| class NativeIterator | |||
| { | |||
| @@ -16145,17 +16143,42 @@ public: | |||
| */ | |||
| 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. | |||
| 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. | |||
| @param targetDirectory the root folder to uncompress to | |||
| @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); | |||
| /** 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 | |||
| private: | |||
| @@ -40269,8 +40292,8 @@ public: | |||
| The model pointer passed-in can be null, in which case you can set it later | |||
| with setModel(). | |||
| */ | |||
| ListBox (const String& componentName, | |||
| ListBoxModel* model); | |||
| ListBox (const String& componentName = String::empty, | |||
| ListBoxModel* model = 0); | |||
| /** Destructor. */ | |||
| ~ListBox(); | |||
| @@ -494,8 +494,6 @@ const MidiMessage MidiMessage::noteOff (const int channel, | |||
| const MidiMessage MidiMessage::allNotesOff (const int channel) throw() | |||
| { | |||
| jassert (channel > 0 && channel <= 16); | |||
| return controllerEvent (channel, 123, 0); | |||
| } | |||
| @@ -172,7 +172,6 @@ struct fxProgramSet | |||
| char chunk[8]; // variable | |||
| }; | |||
| static long vst_swap (const long x) throw() | |||
| { | |||
| #ifdef JUCE_LITTLE_ENDIAN | |||
| @@ -194,6 +193,21 @@ static float vst_swapFloat (const float x) throw() | |||
| #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); | |||
| @@ -304,22 +318,16 @@ static void translateJuceToXButtonModifiers (const MouseEvent& e, XEvent& ev) th | |||
| 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() | |||
| { | |||
| 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() | |||
| @@ -408,7 +416,6 @@ public: | |||
| ~ModuleHandle() | |||
| { | |||
| getActiveModules().removeValue (this); | |||
| close(); | |||
| } | |||
| @@ -710,7 +717,7 @@ public: | |||
| } | |||
| const String getName() const { return name; } | |||
| int getUID() const throw(); | |||
| int getUID() const; | |||
| bool acceptsMidi() const { return wantsMidiMessages; } | |||
| bool producesMidi() const { return dispatch (effCanDo, 0, 0, (void*) "sendVstMidiEvent", 0) > 0; } | |||
| @@ -773,7 +780,6 @@ private: | |||
| MidiBuffer incomingMidi; | |||
| VSTMidiEventList midiEventsToSend; | |||
| VstTimeInfo vstHostTime; | |||
| HeapBlock <float*> channels; | |||
| 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; | |||
| bool restoreProgramSettings (const fxProgram* const prog); | |||
| const String getCurrentProgramName(); | |||
| void setParamsInProgramBlock (fxProgram* const prog) throw(); | |||
| void setParamsInProgramBlock (fxProgram* const prog); | |||
| void updateStoredProgramNames(); | |||
| void initialise(); | |||
| void handleMidiFromPlugin (const VstEvents* const events); | |||
| @@ -796,8 +802,8 @@ private: | |||
| bool saveToFXBFile (MemoryBlock& dest, bool isFXB, int maxSizeMB); | |||
| 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; } | |||
| void setPower (const bool on); | |||
| @@ -869,34 +875,32 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr <ModuleHan | |||
| 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 (module->resFileId != 0) | |||
| UseResFile (module->resFileId); | |||
| if (module->resFileId != 0) | |||
| UseResFile (module->resFileId); | |||
| #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); | |||
| channels.calloc (jmax (16, getNumOutputChannels(), getNumInputChannels()) + 2); | |||
| vstHostTime.tempo = 120.0; | |||
| vstHostTime.timeSigNumerator = 4; | |||
| vstHostTime.timeSigDenominator = 4; | |||
| @@ -1019,7 +1021,6 @@ void VSTPluginInstance::releaseResources() | |||
| incomingMidi.clear(); | |||
| midiEventsToSend.freeEvents(); | |||
| channels.free(); | |||
| } | |||
| void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||
| @@ -1049,17 +1050,7 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||
| 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) | |||
| { | |||
| @@ -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(); | |||
| if ((effect->flags & effFlagsCanReplacing) != 0) | |||
| { | |||
| try | |||
| { | |||
| effect->processReplacing (effect, channels, channels, numSamples); | |||
| effect->processReplacing (effect, buffer.getArrayOfChannels(), buffer.getArrayOfChannels(), numSamples); | |||
| } | |||
| catch (...) | |||
| {} | |||
| @@ -1108,22 +1091,15 @@ void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, | |||
| tempBuffer.setSize (effect->numOutputs, numSamples); | |||
| tempBuffer.clear(); | |||
| float* outs [64]; | |||
| for (i = effect->numOutputs; --i >= 0;) | |||
| outs[i] = tempBuffer.getSampleData (i); | |||
| outs [effect->numOutputs] = 0; | |||
| try | |||
| { | |||
| effect->process (effect, channels, outs, numSamples); | |||
| effect->process (effect, buffer.getArrayOfChannels(), tempBuffer.getArrayOfChannels(), numSamples); | |||
| } | |||
| 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 | |||
| @@ -1604,7 +1580,7 @@ private: | |||
| //============================================================================== | |||
| #if JUCE_WINDOWS | |||
| void checkPluginWindowSize() throw() | |||
| void checkPluginWindowSize() | |||
| { | |||
| RECT r; | |||
| GetWindowRect (pluginHWND, &r); | |||
| @@ -1625,7 +1601,7 @@ private: | |||
| { | |||
| 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) | |||
| { | |||
| @@ -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(); | |||
| @@ -2184,30 +2160,16 @@ int VSTPluginInstance::dispatch (const int opcode, const int index, const int va | |||
| { | |||
| if (effect != 0) | |||
| { | |||
| #if JUCE_MAC | |||
| #if JUCE_MAC | |||
| if (module->resFileId != 0) | |||
| 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); | |||
| #if JUCE_MAC | |||
| if (getActiveEditor() != 0) | |||
| SetPort (oldPort); | |||
| #if JUCE_MAC | |||
| module->resFileId = CurResFile(); | |||
| #endif | |||
| #endif | |||
| --insideVSTCallback; | |||
| return result; | |||
| @@ -2236,7 +2198,7 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||
| switch (opcode) | |||
| { | |||
| case audioMasterCanDo: | |||
| case audioMasterCanDo: | |||
| { | |||
| static const char* canDos[] = { "supplyIdle", | |||
| "sendVstEvents", | |||
| @@ -2254,19 +2216,14 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||
| 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"); | |||
| @@ -2274,21 +2231,16 @@ static VstIntPtr handleGeneralCallback (VstInt32 opcode, VstInt32 index, VstInt3 | |||
| hostName = JUCEApplication::getInstance()->getApplicationName(); | |||
| 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; | |||
| @@ -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); | |||
| @@ -2464,7 +2416,7 @@ const String VSTPluginInstance::getVersion() const throw() | |||
| return s; | |||
| } | |||
| int VSTPluginInstance::getUID() const throw() | |||
| int VSTPluginInstance::getUID() const | |||
| { | |||
| int uid = effect != 0 ? effect->uniqueID : 0; | |||
| @@ -2474,50 +2426,22 @@ int VSTPluginInstance::getUID() const throw() | |||
| return uid; | |||
| } | |||
| const String VSTPluginInstance::getCategory() const throw() | |||
| const String VSTPluginInstance::getCategory() const | |||
| { | |||
| const char* result = 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; | |||
| @@ -2957,11 +2881,9 @@ bool VSTPluginFormat::fileMightContainThisPluginType (const String& fileOrIdenti | |||
| return false; | |||
| #elif JUCE_WINDOWS | |||
| return f.existsAsFile() | |||
| && f.hasFileExtension (".dll"); | |||
| return f.existsAsFile() && f.hasFileExtension (".dll"); | |||
| #elif JUCE_LINUX | |||
| return f.existsAsFile() | |||
| && f.hasFileExtension (".so"); | |||
| return f.existsAsFile() && f.hasFileExtension (".so"); | |||
| #endif | |||
| } | |||
| @@ -33,7 +33,7 @@ | |||
| */ | |||
| #define JUCE_MAJOR_VERSION 1 | |||
| #define JUCE_MINOR_VERSION 52 | |||
| #define JUCE_BUILDNUMBER 60 | |||
| #define JUCE_BUILDNUMBER 61 | |||
| /** 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 | |||
| with setModel(). | |||
| */ | |||
| ListBox (const String& componentName, | |||
| ListBoxModel* model); | |||
| ListBox (const String& componentName = String::empty, | |||
| ListBoxModel* model = 0); | |||
| /** Destructor. */ | |||
| ~ListBox(); | |||
| @@ -115,8 +115,6 @@ public: | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| friend class File; | |||
| //============================================================================== | |||
| 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, | |||
| const int whatToLookFor, | |||
| const bool searchRecursively, | |||
| 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; | |||
| 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; | |||
| } | |||
| 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 | |||
| { | |||
| 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; | |||
| @@ -939,7 +939,6 @@ private: | |||
| bool setFileReadOnlyInternal (bool shouldBeReadOnly) const; | |||
| 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; | |||
| } | |||
| void ZipFile::uncompressTo (const File& targetDirectory, | |||
| bool ZipFile::uncompressTo (const File& targetDirectory, | |||
| const bool shouldOverwriteFiles) | |||
| { | |||
| 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) | |||
| } | |||
| else | |||
| { | |||
| ScopedPointer <InputStream> in (createStreamForEntry (i)); | |||
| ScopedPointer<InputStream> in (createStreamForEntry (index)); | |||
| 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) | |||
| { | |||
| out->writeFromInputStream (*in, -1); | |||
| 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 | |||
| @@ -128,18 +128,42 @@ public: | |||
| */ | |||
| 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. | |||
| 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. | |||
| @param targetDirectory the root folder to uncompress to | |||
| @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); | |||
| /** 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 | |||
| @@ -789,6 +789,42 @@ public: | |||
| outputNames.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_card_info_t* info = 0; | |||
| snd_ctl_card_info_alloca (&info); | |||
| @@ -925,6 +961,14 @@ private: | |||
| 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& operator= (const ALSAAudioIODeviceType&); | |||
| }; | |||