diff --git a/extras/Jucer (experimental)/Builds/Linux/Makefile b/extras/Jucer (experimental)/Builds/Linux/Makefile
index e9fe579416..522443f489 100644
--- a/extras/Jucer (experimental)/Builds/Linux/Makefile
+++ b/extras/Jucer (experimental)/Builds/Linux/Makefile
@@ -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"
diff --git a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj
index 7878f237aa..f530ef56d3 100644
--- a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj
+++ b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj
@@ -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,
diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
index 3a7e47847c..cced041554 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
@@ -137,6 +137,8 @@
+
+
diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
index 7c66c03ab2..6558ce1a29 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
@@ -137,6 +137,8 @@
+
+
diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj
index 71ddd84911..1d06fb7029 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj
@@ -124,6 +124,7 @@
+
@@ -156,6 +157,7 @@
+
diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters
index 4c0e921e7d..e077948cb6 100644
--- a/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters
+++ b/extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters
@@ -31,6 +31,9 @@
The Jucer\Application
+
+ The Jucer\Application
+
The Jucer\Application
@@ -150,6 +153,9 @@
The Jucer\Application
+
+ The Jucer\Application
+
The Jucer\Application
diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer
index 963b44bb2d..e8d53e8e5e 100644
--- a/extras/Jucer (experimental)/Jucer.jucer
+++ b/extras/Jucer (experimental)/Jucer.jucer
@@ -45,6 +45,10 @@
resource="0" file="Source/Application/jucer_FilePreviewComponent.h"/>
+
+
diff --git a/extras/Jucer (experimental)/Source/Application/jucer_Application.h b/extras/Jucer (experimental)/Source/Application/jucer_Application.h
index 3236bbde09..18a27e776e 100644
--- a/extras/Jucer (experimental)/Source/Application/jucer_Application.h
+++ b/extras/Jucer (experimental)/Source/Application/jucer_Application.h
@@ -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);
}
diff --git a/extras/Jucer (experimental)/Source/Application/jucer_CommandIDs.h b/extras/Jucer (experimental)/Source/Application/jucer_CommandIDs.h
index a74b834af2..a10af1dc36 100644
--- a/extras/Jucer (experimental)/Source/Application/jucer_CommandIDs.h
+++ b/extras/Jucer (experimental)/Source/Application/jucer_CommandIDs.h
@@ -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;
diff --git a/extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.cpp b/extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.cpp
new file mode 100644
index 0000000000..7de8f5fb6a
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.cpp
@@ -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 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 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 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 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 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 (existingComponentToUpdate);
+ if (c == 0)
+ c = new UpdateListComponent (*this);
+
+ c->setVersion (availableVersions [rowNumber]);
+ return c;
+}
diff --git a/extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.h b/extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.h
new file mode 100644
index 0000000000..47aabe952a
--- /dev/null
+++ b/extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.h
@@ -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 availableVersions;
+
+ void updateVersions (const XmlElement& xml);
+ void applyVersion (VersionInfo* version);
+};
+
+
+#endif // __JUCER_JUCEUPDATER_H_81537815__
diff --git a/extras/audio plugins/demo/JuceLibraryCode/JucePluginCharacteristics.h b/extras/audio plugins/demo/JuceLibraryCode/JucePluginCharacteristics.h
index 1b044bce19..5d836bbcbd 100644
--- a/extras/audio plugins/demo/JuceLibraryCode/JucePluginCharacteristics.h
+++ b/extras/audio plugins/demo/JuceLibraryCode/JucePluginCharacteristics.h
@@ -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"
diff --git a/extras/juce demo/Builds/MacOSX/Icon.icns b/extras/juce demo/Builds/MacOSX/Icon.icns
index a1d2ba8423..fea3a04779 100644
Binary files a/extras/juce demo/Builds/MacOSX/Icon.icns and b/extras/juce demo/Builds/MacOSX/Icon.icns differ
diff --git a/extras/juce demo/Builds/VisualStudio2005/icon.ico b/extras/juce demo/Builds/VisualStudio2005/icon.ico
index 853e63debc..9dfea84c64 100644
Binary files a/extras/juce demo/Builds/VisualStudio2005/icon.ico and b/extras/juce demo/Builds/VisualStudio2005/icon.ico differ
diff --git a/extras/juce demo/Builds/VisualStudio2008/icon.ico b/extras/juce demo/Builds/VisualStudio2008/icon.ico
index 853e63debc..9dfea84c64 100644
Binary files a/extras/juce demo/Builds/VisualStudio2008/icon.ico and b/extras/juce demo/Builds/VisualStudio2008/icon.ico differ
diff --git a/extras/juce demo/Builds/VisualStudio2010/icon.ico b/extras/juce demo/Builds/VisualStudio2010/icon.ico
index 853e63debc..9dfea84c64 100644
Binary files a/extras/juce demo/Builds/VisualStudio2010/icon.ico and b/extras/juce demo/Builds/VisualStudio2010/icon.ico differ
diff --git a/extras/juce demo/Builds/iPhone/Icon.icns b/extras/juce demo/Builds/iPhone/Icon.icns
index a1d2ba8423..fea3a04779 100644
Binary files a/extras/juce demo/Builds/iPhone/Icon.icns and b/extras/juce demo/Builds/iPhone/Icon.icns differ
diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp
index 1bc39b284a..3848a1459f 100644
--- a/juce_amalgamated.cpp
+++ b/juce_amalgamated.cpp
@@ -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& 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 in (createStreamForEntry (i));
+ ScopedPointer 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 out (targetFile.createOutputStream());
+ ScopedPointer 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 channels;
ReferenceCountedObjectPtr 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 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 pos (getActiveEditor()->relativePositionToOtherComponent (getActiveEditor()->getTopLevelComponent(), Point()));
-
- 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&);
};
diff --git a/juce_amalgamated.h b/juce_amalgamated.h
index a4737b4a59..2ae7a610dc 100644
--- a/juce_amalgamated.h
+++ b/juce_amalgamated.h
@@ -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();
diff --git a/src/audio/midi/juce_MidiMessage.cpp b/src/audio/midi/juce_MidiMessage.cpp
index b000a6e5da..ff002b8a40 100644
--- a/src/audio/midi/juce_MidiMessage.cpp
+++ b/src/audio/midi/juce_MidiMessage.cpp
@@ -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);
}
diff --git a/src/audio/plugins/formats/juce_VSTPluginFormat.cpp b/src/audio/plugins/formats/juce_VSTPluginFormat.cpp
index 2c7f8cc3af..489961b0e9 100644
--- a/src/audio/plugins/formats/juce_VSTPluginFormat.cpp
+++ b/src/audio/plugins/formats/juce_VSTPluginFormat.cpp
@@ -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 channels;
ReferenceCountedObjectPtr 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 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 pos (getActiveEditor()->relativePositionToOtherComponent (getActiveEditor()->getTopLevelComponent(), Point()));
-
- 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
}
diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h
index 0f73be32ad..468edfa80a 100644
--- a/src/core/juce_StandardHeader.h
+++ b/src/core/juce_StandardHeader.h
@@ -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.
diff --git a/src/gui/components/controls/juce_ListBox.h b/src/gui/components/controls/juce_ListBox.h
index b880c5eb84..b288063d34 100644
--- a/src/gui/components/controls/juce_ListBox.h
+++ b/src/gui/components/controls/juce_ListBox.h
@@ -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();
diff --git a/src/io/files/juce_DirectoryIterator.h b/src/io/files/juce_DirectoryIterator.h
index 75f57a7db5..133a1f190d 100644
--- a/src/io/files/juce_DirectoryIterator.h
+++ b/src/io/files/juce_DirectoryIterator.h
@@ -115,8 +115,6 @@ public:
juce_UseDebuggingNewOperator
private:
- friend class File;
-
//==============================================================================
class NativeIterator
{
diff --git a/src/io/files/juce_File.cpp b/src/io/files/juce_File.cpp
index 86ad8d2d14..bb321af780 100644
--- a/src/io/files/juce_File.cpp
+++ b/src/io/files/juce_File.cpp
@@ -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& 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;
diff --git a/src/io/files/juce_File.h b/src/io/files/juce_File.h
index 435639b71c..fcd69e3b57 100644
--- a/src/io/files/juce_File.h
+++ b/src/io/files/juce_File.h
@@ -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);
};
diff --git a/src/io/files/juce_ZipFile.cpp b/src/io/files/juce_ZipFile.cpp
index a8685dbd45..7eea5e68bb 100644
--- a/src/io/files/juce_ZipFile.cpp
+++ b/src/io/files/juce_ZipFile.cpp
@@ -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 in (createStreamForEntry (i));
+ ScopedPointer 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 out (targetFile.createOutputStream());
+ ScopedPointer 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
diff --git a/src/io/files/juce_ZipFile.h b/src/io/files/juce_ZipFile.h
index 48e6c648c3..52f1a83697 100644
--- a/src/io/files/juce_ZipFile.h
+++ b/src/io/files/juce_ZipFile.h
@@ -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
diff --git a/src/native/linux/juce_linux_Audio.cpp b/src/native/linux/juce_linux_Audio.cpp
index 97f6502dd3..72d8218752 100644
--- a/src/native/linux/juce_linux_Audio.cpp
+++ b/src/native/linux/juce_linux_Audio.cpp
@@ -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&);
};