Browse Source

New feature in the (new) jucer: automatic download of the latest source code version. Fix for File::findChildFiles. VST host channels fix.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
0ca53b3098
29 changed files with 918 additions and 511 deletions
  1. +6
    -0
      extras/Jucer (experimental)/Builds/Linux/Makefile
  2. +6
    -0
      extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj
  3. +2
    -0
      extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
  4. +2
    -0
      extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
  5. +2
    -0
      extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj
  6. +6
    -0
      extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters
  7. +4
    -0
      extras/Jucer (experimental)/Jucer.jucer
  8. +13
    -2
      extras/Jucer (experimental)/Source/Application/jucer_Application.h
  9. +1
    -0
      extras/Jucer (experimental)/Source/Application/jucer_CommandIDs.h
  10. +402
    -0
      extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.cpp
  11. +77
    -0
      extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.h
  12. +3
    -3
      extras/audio plugins/demo/JuceLibraryCode/JucePluginCharacteristics.h
  13. BIN
      extras/juce demo/Builds/MacOSX/Icon.icns
  14. BIN
      extras/juce demo/Builds/VisualStudio2005/icon.ico
  15. BIN
      extras/juce demo/Builds/VisualStudio2008/icon.ico
  16. BIN
      extras/juce demo/Builds/VisualStudio2010/icon.ico
  17. BIN
      extras/juce demo/Builds/iPhone/Icon.icns
  18. +167
    -245
      juce_amalgamated.cpp
  19. +30
    -7
      juce_amalgamated.h
  20. +0
    -2
      src/audio/midi/juce_MidiMessage.cpp
  21. +83
    -161
      src/audio/plugins/formats/juce_VSTPluginFormat.cpp
  22. +1
    -1
      src/core/juce_StandardHeader.h
  23. +2
    -2
      src/gui/components/controls/juce_ListBox.h
  24. +0
    -2
      src/io/files/juce_DirectoryIterator.h
  25. +12
    -69
      src/io/files/juce_File.cpp
  26. +0
    -1
      src/io/files/juce_File.h
  27. +29
    -14
      src/io/files/juce_ZipFile.cpp
  28. +26
    -2
      src/io/files/juce_ZipFile.h
  29. +44
    -0
      src/native/linux/juce_linux_Audio.cpp

+ 6
- 0
extras/Jucer (experimental)/Builds/Linux/Makefile View File

@@ -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"


+ 6
- 0
extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj View File

@@ -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,


+ 2
- 0
extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj View File

@@ -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"/>


+ 2
- 0
extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj View File

@@ -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"/>


+ 2
- 0
extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj View File

@@ -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"/>


+ 6
- 0
extras/Jucer (experimental)/Builds/VisualStudio2010/The Jucer.vcxproj.filters View File

@@ -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>


+ 4
- 0
extras/Jucer (experimental)/Jucer.jucer View File

@@ -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"/>


+ 13
- 2
extras/Jucer (experimental)/Source/Application/jucer_Application.h View File

@@ -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);
}


+ 1
- 0
extras/Jucer (experimental)/Source/Application/jucer_CommandIDs.h View File

@@ -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;


+ 402
- 0
extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.cpp View File

@@ -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 (&currentVersionLabel);
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;
}

+ 77
- 0
extras/Jucer (experimental)/Source/Application/jucer_JuceUpdater.h View File

@@ -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__

+ 3
- 3
extras/audio plugins/demo/JuceLibraryCode/JucePluginCharacteristics.h View File

@@ -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"


BIN
extras/juce demo/Builds/MacOSX/Icon.icns View File


BIN
extras/juce demo/Builds/VisualStudio2005/icon.ico View File

Before After

BIN
extras/juce demo/Builds/VisualStudio2008/icon.ico View File

Before After

BIN
extras/juce demo/Builds/VisualStudio2010/icon.ico View File

Before After

BIN
extras/juce demo/Builds/iPhone/Icon.icns View File


+ 167
- 245
juce_amalgamated.cpp View File

@@ -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 (&micro, 0);
return micro.tv_usec * 1000.0;
#elif JUCE_MAC
UnsignedWide micro;
Microseconds (&micro);
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 (&micro, 0);
vstHostTime.nanoSeconds = micro.tv_usec * 1000.0;
#elif JUCE_MAC
UnsignedWide micro;
Microseconds (&micro);
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&);
};


+ 30
- 7
juce_amalgamated.h View File

@@ -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();


+ 0
- 2
src/audio/midi/juce_MidiMessage.cpp View File

@@ -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);
}


+ 83
- 161
src/audio/plugins/formats/juce_VSTPluginFormat.cpp View File

@@ -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 (&micro, 0);
return micro.tv_usec * 1000.0;
#elif JUCE_MAC
UnsignedWide micro;
Microseconds (&micro);
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 (&micro, 0);
vstHostTime.nanoSeconds = micro.tv_usec * 1000.0;
#elif JUCE_MAC
UnsignedWide micro;
Microseconds (&micro);
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
}


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -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.


+ 2
- 2
src/gui/components/controls/juce_ListBox.h View File

@@ -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();


+ 0
- 2
src/io/files/juce_DirectoryIterator.h View File

@@ -115,8 +115,6 @@ public:
juce_UseDebuggingNewOperator
private:
friend class File;
//==============================================================================
class NativeIterator
{


+ 12
- 69
src/io/files/juce_File.cpp View File

@@ -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;


+ 0
- 1
src/io/files/juce_File.h View File

@@ -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);
};


+ 29
- 14
src/io/files/juce_ZipFile.cpp View File

@@ -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

+ 26
- 2
src/io/files/juce_ZipFile.h View File

@@ -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


+ 44
- 0
src/native/linux/juce_linux_Audio.cpp View File

@@ -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&);
};


Loading…
Cancel
Save