1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Minor URL additions and introjucer work.

This commit is contained in:
Julian Storer 2011-08-18 12:43:49 +01:00
parent 64ee6d54d9
commit 8aa60b9361
27 changed files with 279 additions and 91 deletions

View file

@ -24,6 +24,7 @@
*/ */
#include "../Project/jucer_Project.h" #include "../Project/jucer_Project.h"
#include "../Project/jucer_Module.h"
#include "jucer_CommandLine.h" #include "jucer_CommandLine.h"
@ -74,8 +75,108 @@ namespace
} }
//============================================================================== //==============================================================================
int buildModule (const StringArray& tokens) String getModulePackageName (const LibraryModule& module)
{ {
return module.getID() + ".jucemodule";
}
int zipModule (const File& targetFolder, const File& moduleFolder)
{
jassert (targetFolder.isDirectory());
const File moduleFolderParent (moduleFolder.getParentDirectory());
LibraryModule module (moduleFolder.getChildFile (LibraryModule::getInfoFileName()));
if (! module.isValid())
{
std::cout << moduleFolder.getFullPathName() << " is not a valid module folder!" << std::endl;
return 1;
}
const File targetFile (targetFolder.getChildFile (getModulePackageName (module)));
ZipFile::Builder zip;
{
DirectoryIterator i (moduleFolder, true, "*", File::findFiles);
while (i.next())
if (! i.getFile().isHidden())
zip.addFile (i.getFile(), 9, i.getFile().getRelativePathFrom (moduleFolderParent));
}
std::cout << "Writing: " << targetFile.getFullPathName() << std::endl;
TemporaryFile temp (targetFile);
ScopedPointer<FileOutputStream> out (temp.getFile().createOutputStream());
bool ok = out != nullptr && zip.writeToStream (*out);
out = nullptr;
ok = ok && temp.overwriteTargetFileWithTemporary();
if (! ok)
{
std::cout << "Failed to write to the target file: " << targetFile.getFullPathName() << std::endl;
return 1;
}
return 0;
}
int buildModules (const StringArray& tokens, const bool buildAllWithIndex)
{
if (tokens.size() < 3)
{
std::cout << "Not enough arguments!" << std::endl;
return 1;
}
const File targetFolder (getFile (tokens[1]));
if (! targetFolder.isDirectory())
{
std::cout << "The first argument must be the directory to put the result." << std::endl;
return 1;
}
if (buildAllWithIndex)
{
const File folderToSearch (getFile (tokens[2]));
DirectoryIterator i (folderToSearch, false, "*", File::findDirectories);
var infoList;
while (i.next())
{
LibraryModule module (i.getFile().getChildFile (LibraryModule::getInfoFileName()));
if (module.isValid())
{
const int result = zipModule (targetFolder, i.getFile());
if (result != 0)
return result;
var moduleInfo (new DynamicObject());
moduleInfo.getDynamicObject()->setProperty ("file", getModulePackageName (module));
moduleInfo.getDynamicObject()->setProperty ("info", module.moduleInfo);
infoList.append (moduleInfo);
}
}
const File indexFile (targetFolder.getChildFile ("modulelist"));
std::cout << "Writing: " << indexFile.getFullPathName() << std::endl;
indexFile.replaceWithText (JSON::toString (infoList), false, false);
}
else
{
for (int i = 2; i < tokens.size(); ++i)
{
const int result = zipModule (targetFolder, getFile (tokens[i]));
if (result != 0)
return result;
}
}
return 0; return 0;
} }
@ -92,7 +193,10 @@ int performCommandLine (const String& commandLine)
return resaveProject (getFile (tokens[1])); return resaveProject (getFile (tokens[1]));
if (tokens[0] == "buildmodule") if (tokens[0] == "buildmodule")
return buildModule (tokens); return buildModules (tokens, false);
if (tokens[0] == "buildallmodules")
return buildModules (tokens, true);
return commandLineNotPerformed; return commandLineNotPerformed;
} }

View file

@ -92,7 +92,7 @@ protected:
return getIntermediatesPath (config); return getIntermediatesPath (config);
RelativePath binaryRelPath (binaryPath, RelativePath::projectFolder); RelativePath binaryRelPath (binaryPath, RelativePath::projectFolder);
if (binaryRelPath.isAbsolute()) if (binaryRelPath.isAbsolute())
return binaryRelPath.toWindowsStyle(); return binaryRelPath.toWindowsStyle();

View file

@ -210,7 +210,8 @@ void ProjectExporter::createPropertyEditors (Array <PropertyComponent*>& props)
props.getLast()->setTooltip ("The location of the Juce library folder that the " + name + " project will use to when compiling. This can be an absolute path, or relative to the jucer project folder, but it must be valid on the filesystem of the machine you use to actually do the compiling."); props.getLast()->setTooltip ("The location of the Juce library folder that the " + name + " project will use to when compiling. This can be an absolute path, or relative to the jucer project folder, but it must be valid on the filesystem of the machine you use to actually do the compiling.");
OwnedArray<LibraryModule> modules; OwnedArray<LibraryModule> modules;
project.createRequiredModules (ModuleList::getInstance(), modules); ModuleList moduleList;
project.createRequiredModules (moduleList, modules);
for (int i = 0; i < modules.size(); ++i) for (int i = 0; i < modules.size(); ++i)
modules.getUnchecked(i)->createPropertyEditors (*this, props); modules.getUnchecked(i)->createPropertyEditors (*this, props);

View file

@ -65,7 +65,11 @@ public:
writeMainProjectFile(); writeMainProjectFile();
OwnedArray<LibraryModule> modules; OwnedArray<LibraryModule> modules;
project.createRequiredModules (ModuleList::getInstance(), modules);
{
ModuleList moduleList;
project.createRequiredModules (moduleList, modules);
}
if (errors.size() == 0) if (errors.size() == 0)
writeAppConfigFile (modules); writeAppConfigFile (modules);

View file

@ -36,12 +36,6 @@ ModuleList::ModuleList()
rescan(); rescan();
} }
ModuleList& ModuleList::getInstance()
{
static ModuleList list;
return list;
}
struct ModuleSorter struct ModuleSorter
{ {
static int compareElements (const ModuleList::Module* m1, const ModuleList::Module* m2) static int compareElements (const ModuleList::Module* m1, const ModuleList::Module* m2)
@ -50,38 +44,84 @@ struct ModuleSorter
} }
}; };
void ModuleList::sort()
{
ModuleSorter sorter;
modules.sort (sorter);
}
void ModuleList::rescan() void ModuleList::rescan()
{ {
modules.clear(); modules.clear();
moduleFolder = StoredSettings::getInstance()->getLastKnownJuceFolder().getChildFile ("modules"); moduleFolder = StoredSettings::getInstance()->getLastKnownJuceFolder().getChildFile ("modules");
DirectoryIterator iter (moduleFolder, false, "*", File::findDirectories); DirectoryIterator iter (moduleFolder, false, "*", File::findDirectories);
while (iter.next()) while (iter.next())
{ {
const File moduleDef (iter.getFile().getChildFile ("juce_module_info")); const File moduleDef (iter.getFile().getChildFile (LibraryModule::getInfoFileName()));
if (moduleDef.exists()) if (moduleDef.exists())
{ {
ScopedPointer<LibraryModule> m (new LibraryModule (moduleDef)); LibraryModule m (moduleDef);
jassert (m->isValid()); jassert (m.isValid());
if (m->isValid()) if (m.isValid())
{ {
Module* info = new Module(); Module* info = new Module();
modules.add (info); modules.add (info);
info->uid = m->getID(); info->uid = m.getID();
info->name = m->moduleInfo ["name"]; info->version = m.getVersion();
info->description = m->moduleInfo ["description"]; info->name = m.moduleInfo ["name"];
info->description = m.moduleInfo ["description"];
info->file = moduleDef; info->file = moduleDef;
} }
} }
} }
ModuleSorter sorter; sort();
modules.sort (sorter); }
void ModuleList::loadFromWebsite()
{
modules.clear();
URL baseURL ("http://www.rawmaterialsoftware.com/juce/modules");
URL url (baseURL.getChildURL ("modulelist"));
var infoList (JSON::parse (url.readEntireTextStream (false)));
if (infoList.isArray())
{
const Array<var>* moduleList = infoList.getArray();
for (int i = 0; i < moduleList->size(); ++i)
{
const var& m = moduleList->getReference(i);
const String file (m ["file"].toString());
if (file.isNotEmpty())
{
var moduleInfo (m ["info"]);
LibraryModule lm (moduleInfo);
if (lm.isValid())
{
Module* info = new Module();
modules.add (info);
info->uid = lm.getID();
info->version = lm.getVersion();
info->name = lm.getName();
info->description = lm.getDescription();
info->url = baseURL.getChildURL (file);
}
}
}
}
sort();
} }
LibraryModule* ModuleList::Module::create() const LibraryModule* ModuleList::Module::create() const
@ -162,8 +202,12 @@ LibraryModule::LibraryModule (const File& file)
jassert (isValid()); jassert (isValid());
} }
String LibraryModule::getID() const { return moduleInfo ["id"].toString(); }; LibraryModule::LibraryModule (const var& moduleInfo_)
bool LibraryModule::isValid() const { return getID().isNotEmpty(); } : moduleInfo (moduleInfo_)
{
}
bool LibraryModule::isValid() const { return getID().isNotEmpty(); }
bool LibraryModule::isPluginClient() const { return getID() == "juce_audio_plugin_client"; } bool LibraryModule::isPluginClient() const { return getID() == "juce_audio_plugin_client"; }
bool LibraryModule::isAUPluginHost (const Project& project) const { return getID() == "juce_audio_processors" && project.isConfigFlagEnabled ("JUCE_PLUGINHOST_AU"); } bool LibraryModule::isAUPluginHost (const Project& project) const { return getID() == "juce_audio_processors" && project.isConfigFlagEnabled ("JUCE_PLUGINHOST_AU"); }

View file

@ -36,15 +36,22 @@ class LibraryModule
{ {
public: public:
LibraryModule (const File& file); LibraryModule (const File& file);
LibraryModule (const var& moduleInfo);
String getID() const;
bool isValid() const; bool isValid() const;
String getID() const { return moduleInfo ["id"].toString(); }
String getVersion() const { return moduleInfo ["version"].toString(); }
String getName() const { return moduleInfo ["name"].toString(); }
String getDescription() const { return moduleInfo ["description"].toString(); }
void writeIncludes (ProjectSaver& projectSaver, OutputStream& out); void writeIncludes (ProjectSaver& projectSaver, OutputStream& out);
void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) const; void prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) const;
void createPropertyEditors (const ProjectExporter& exporter, Array <PropertyComponent*>& props) const; void createPropertyEditors (const ProjectExporter& exporter, Array <PropertyComponent*>& props) const;
void getConfigFlags (Project& project, OwnedArray<Project::ConfigFlag>& flags) const; void getConfigFlags (Project& project, OwnedArray<Project::ConfigFlag>& flags) const;
static String getInfoFileName() { return "juce_module_info"; }
var moduleInfo; var moduleInfo;
private: private:
@ -81,10 +88,10 @@ class ModuleList
public: public:
ModuleList(); ModuleList();
static ModuleList& getInstance();
//============================================================================== //==============================================================================
void rescan(); void rescan();
void loadFromWebsite();
LibraryModule* loadModule (const String& uid) const; LibraryModule* loadModule (const String& uid) const;
void getDependencies (const String& moduleID, StringArray& dependencies) const; void getDependencies (const String& moduleID, StringArray& dependencies) const;
@ -95,8 +102,9 @@ public:
{ {
LibraryModule* create() const; LibraryModule* create() const;
String uid, name, description; String uid, version, name, description;
File file; File file;
URL url;
}; };
const Module* findModuleInfo (const String& uid) const; const Module* findModuleInfo (const String& uid) const;
@ -105,6 +113,8 @@ public:
private: private:
File moduleFolder; File moduleFolder;
void sort();
}; };

View file

@ -107,10 +107,10 @@ private:
}; };
//============================================================================== //==============================================================================
static StringArray getExtraDependenciesNeeded (Project& project, const ModuleList::Module& m) static StringArray getExtraDependenciesNeeded (Project& project, ModuleList& moduleList, const ModuleList::Module& m)
{ {
StringArray dependencies, extraDepsNeeded; StringArray dependencies, extraDepsNeeded;
ModuleList::getInstance().getDependencies (m.uid, dependencies); moduleList.getDependencies (m.uid, dependencies);
for (int i = 0; i < dependencies.size(); ++i) for (int i = 0; i < dependencies.size(); ++i)
if ((! project.isModuleEnabled (dependencies[i])) && dependencies[i] != m.uid) if ((! project.isModuleEnabled (dependencies[i])) && dependencies[i] != m.uid)
@ -123,25 +123,25 @@ static StringArray getExtraDependenciesNeeded (Project& project, const ModuleLis
class ModuleSettingsPanel : public PanelBase class ModuleSettingsPanel : public PanelBase
{ {
public: public:
ModuleSettingsPanel (Project& project_, const String& moduleID_) ModuleSettingsPanel (Project& project_, ModuleList& moduleList_, const String& moduleID_)
: PanelBase (project_), moduleID (moduleID_) : PanelBase (project_), moduleList (moduleList_), moduleID (moduleID_)
{ {
setBounds ("parent.width / 2 + 1, 3, parent.width - 3, parent.height - 3"); setBounds ("parent.width / 2 + 1, 3, parent.width - 3, parent.height - 3");
} }
void rebuildProperties (Array <PropertyComponent*>& props) void rebuildProperties (Array <PropertyComponent*>& props)
{ {
ScopedPointer<LibraryModule> module (ModuleList::getInstance().loadModule (moduleID)); ScopedPointer<LibraryModule> module (moduleList.loadModule (moduleID));
if (module != nullptr) if (module != nullptr)
{ {
props.add (new ModuleInfoComponent (project, moduleID)); props.add (new ModuleInfoComponent (project, moduleList, moduleID));
if (project.isModuleEnabled (moduleID)) if (project.isModuleEnabled (moduleID))
{ {
const ModuleList::Module* m = ModuleList::getInstance().findModuleInfo (moduleID); const ModuleList::Module* m = moduleList.findModuleInfo (moduleID);
if (m != nullptr && getExtraDependenciesNeeded (project, *m).size() > 0) if (m != nullptr && getExtraDependenciesNeeded (project, moduleList, *m).size() > 0)
props.add (new MissingDependenciesComponent (project, moduleID)); props.add (new MissingDependenciesComponent (project, moduleList, moduleID));
} }
props.add (new BooleanPropertyComponent (project.shouldShowAllModuleFilesInProject (moduleID), props.add (new BooleanPropertyComponent (project.shouldShowAllModuleFilesInProject (moduleID),
@ -182,15 +182,16 @@ public:
} }
private: private:
ModuleList& moduleList;
String moduleID; String moduleID;
//============================================================================== //==============================================================================
class ModuleInfoComponent : public PropertyComponent class ModuleInfoComponent : public PropertyComponent
{ {
public: public:
ModuleInfoComponent (Project& project_, const String& moduleID_) ModuleInfoComponent (Project& project_, ModuleList& moduleList_, const String& moduleID_)
: PropertyComponent ("Module", 100), : PropertyComponent ("Module", 100),
project (project_), moduleID (moduleID_) project (project_), moduleList (moduleList_), moduleID (moduleID_)
{ {
} }
@ -201,7 +202,7 @@ private:
g.setColour (Colours::white.withAlpha (0.4f)); g.setColour (Colours::white.withAlpha (0.4f));
g.fillRect (0, 0, getWidth(), getHeight() - 1); g.fillRect (0, 0, getWidth(), getHeight() - 1);
const ModuleList::Module* module = ModuleList::getInstance().findModuleInfo (moduleID); const ModuleList::Module* module = moduleList.findModuleInfo (moduleID);
if (module != nullptr) if (module != nullptr)
{ {
@ -218,6 +219,7 @@ private:
private: private:
Project& project; Project& project;
ModuleList& moduleList;
String moduleID; String moduleID;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleInfoComponent); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleInfoComponent);
@ -228,15 +230,15 @@ private:
public Button::Listener public Button::Listener
{ {
public: public:
MissingDependenciesComponent (Project& project_, const String& moduleID_) MissingDependenciesComponent (Project& project_, ModuleList& moduleList_, const String& moduleID_)
: PropertyComponent ("Dependencies", 100), : PropertyComponent ("Dependencies", 100),
project (project_), moduleID (moduleID_), project (project_), moduleList (moduleList), moduleID (moduleID_),
fixButton ("Enable Required Modules") fixButton ("Enable Required Modules")
{ {
const ModuleList::Module* module = ModuleList::getInstance().findModuleInfo (moduleID); const ModuleList::Module* module = moduleList.findModuleInfo (moduleID);
if (module != nullptr) if (module != nullptr)
missingDependencies = getExtraDependenciesNeeded (project, *module); missingDependencies = getExtraDependenciesNeeded (project, moduleList, *module);
addAndMakeVisible (&fixButton); addAndMakeVisible (&fixButton);
fixButton.setColour (TextButton::buttonColourId, Colours::red); fixButton.setColour (TextButton::buttonColourId, Colours::red);
@ -265,6 +267,7 @@ private:
private: private:
Project& project; Project& project;
ModuleList& moduleList;
String moduleID; String moduleID;
StringArray missingDependencies; StringArray missingDependencies;
TextButton fixButton; TextButton fixButton;
@ -290,7 +293,7 @@ public:
int getNumRows() int getNumRows()
{ {
return ModuleList::getInstance().modules.size(); return moduleList.modules.size();
} }
void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
@ -298,7 +301,7 @@ public:
if (rowIsSelected) if (rowIsSelected)
g.fillAll (findColour (TextEditor::highlightColourId)); g.fillAll (findColour (TextEditor::highlightColourId));
const ModuleList::Module* const m = ModuleList::getInstance().modules [rowNumber]; const ModuleList::Module* const m = moduleList.modules [rowNumber];
if (m != nullptr) if (m != nullptr)
{ {
@ -307,7 +310,7 @@ public:
getLookAndFeel().drawTickBox (g, *this, (height - tickSize) / 2, (height - tickSize) / 2, tickSize, tickSize, getLookAndFeel().drawTickBox (g, *this, (height - tickSize) / 2, (height - tickSize) / 2, tickSize, tickSize,
project.isModuleEnabled (m->uid), true, false, false); project.isModuleEnabled (m->uid), true, false, false);
if (project.isModuleEnabled (m->uid) && getExtraDependenciesNeeded (project, *m).size() > 0) if (project.isModuleEnabled (m->uid) && getExtraDependenciesNeeded (project, moduleList, *m).size() > 0)
g.setColour (Colours::red); g.setColour (Colours::red);
else else
g.setColour (Colours::black); g.setColour (Colours::black);
@ -322,7 +325,7 @@ public:
void flipRow (int row) void flipRow (int row)
{ {
const ModuleList::Module* const m = ModuleList::getInstance().modules [row]; const ModuleList::Module* const m = moduleList.modules [row];
if (m != nullptr) if (m != nullptr)
{ {
@ -332,7 +335,7 @@ public:
} }
else else
{ {
const StringArray extraDepsNeeded (getExtraDependenciesNeeded (project, *m)); const StringArray extraDepsNeeded (getExtraDependenciesNeeded (project, moduleList, *m));
/* if (extraDepsNeeded.size() > 0) /* if (extraDepsNeeded.size() > 0)
{ {
@ -375,12 +378,12 @@ public:
void selectedRowsChanged (int lastRowSelected) void selectedRowsChanged (int lastRowSelected)
{ {
const ModuleList::Module* const m = ModuleList::getInstance().modules [lastRowSelected]; const ModuleList::Module* const m = moduleList.modules [lastRowSelected];
settings = nullptr; settings = nullptr;
if (m != nullptr) if (m != nullptr)
addAndMakeVisible (settings = new ModuleSettingsPanel (project, m->uid)); addAndMakeVisible (settings = new ModuleSettingsPanel (project, moduleList, m->uid));
} }
void refresh() void refresh()
@ -393,6 +396,7 @@ public:
private: private:
Project& project; Project& project;
ModuleList moduleList;
ListBox modulesList; ListBox modulesList;
ScopedPointer<ModuleSettingsPanel> settings; ScopedPointer<ModuleSettingsPanel> settings;
}; };

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_audio_basics", "id": "juce_audio_basics",
"name": "JUCE audio and midi data classes", "name": "JUCE audio and midi data classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc", "description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_audio_devices", "id": "juce_audio_devices",
"name": "JUCE audio and midi I/O device classes", "name": "JUCE audio and midi I/O device classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes to play and record from audio and midi i/o devices.", "description": "Classes to play and record from audio and midi i/o devices.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_audio_formats", "id": "juce_audio_formats",
"name": "JUCE audio file format codecs", "name": "JUCE audio file format codecs",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for reading and writing various audio file formats.", "description": "Classes for reading and writing various audio file formats.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_audio_plugin_client", "id": "juce_audio_plugin_client",
"name": "JUCE audio plugin wrapper classes", "name": "JUCE audio plugin wrapper classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for building VST, RTAS and AU plugins.", "description": "Classes for building VST, RTAS and AU plugins.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_audio_processors", "id": "juce_audio_processors",
"name": "JUCE audio plugin hosting classes", "name": "JUCE audio plugin hosting classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for loading and playing VST, AU, or internally-generated audio processors.", "description": "Classes for loading and playing VST, AU, or internally-generated audio processors.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_audio_utils", "id": "juce_audio_utils",
"name": "JUCE extra audio utility classes", "name": "JUCE extra audio utility classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for audio-related GUI and miscellaneous tasks.", "description": "Classes for audio-related GUI and miscellaneous tasks.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_browser_plugin_client", "id": "juce_browser_plugin_client",
"name": "JUCE browser plugin wrapper classes", "name": "JUCE browser plugin wrapper classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for building NPAPI and ActiveX browser plugins.", "description": "Classes for building NPAPI and ActiveX browser plugins.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_core", "id": "juce_core",
"name": "JUCE core classes", "name": "JUCE core classes",
"version": "2.0.1", "version": "2.0.2",
"description": "The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.", "description": "The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -173,6 +173,17 @@ namespace URLHelpers
<< (int) postData.getSize() << "\r\n"; << (int) postData.getSize() << "\r\n";
} }
} }
void concatenatePaths (String& path, const String& suffix)
{
if (! path.endsWithChar ('/'))
path << '/';
if (suffix.startsWithChar ('/'))
path += suffix.substring (1);
else
path += suffix;
}
} }
String URL::toString (const bool includeGetParameters) const String URL::toString (const bool includeGetParameters) const
@ -221,7 +232,7 @@ String URL::getScheme() const
return url.substring (0, URLHelpers::findStartOfDomain (url) - 1); return url.substring (0, URLHelpers::findStartOfDomain (url) - 1);
} }
const URL URL::withNewSubPath (const String& newPath) const URL URL::withNewSubPath (const String& newPath) const
{ {
int start = URLHelpers::findStartOfDomain (url); int start = URLHelpers::findStartOfDomain (url);
while (url[start] == '/') while (url[start] == '/')
@ -234,14 +245,14 @@ const URL URL::withNewSubPath (const String& newPath) const
if (startOfPath > 0) if (startOfPath > 0)
u.url = url.substring (0, startOfPath); u.url = url.substring (0, startOfPath);
if (! u.url.endsWithChar ('/')) URLHelpers::concatenatePaths (u.url, newPath);
u.url << '/'; return u;
}
if (newPath.startsWithChar ('/'))
u.url << newPath.substring (1);
else
u.url << newPath;
URL URL::getChildURL (const String& subPath) const
{
URL u (*this);
URLHelpers::concatenatePaths (u.url, subPath);
return u; return u;
} }
@ -328,17 +339,17 @@ XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const
} }
//============================================================================== //==============================================================================
const URL URL::withParameter (const String& parameterName, URL URL::withParameter (const String& parameterName,
const String& parameterValue) const const String& parameterValue) const
{ {
URL u (*this); URL u (*this);
u.parameters.set (parameterName, parameterValue); u.parameters.set (parameterName, parameterValue);
return u; return u;
} }
const URL URL::withFileToUpload (const String& parameterName, URL URL::withFileToUpload (const String& parameterName,
const File& fileToUpload, const File& fileToUpload,
const String& mimeType) const const String& mimeType) const
{ {
jassert (mimeType.isNotEmpty()); // You need to supply a mime type! jassert (mimeType.isNotEmpty()); // You need to supply a mime type!
@ -348,7 +359,7 @@ const URL URL::withFileToUpload (const String& parameterName,
return u; return u;
} }
const URL URL::withPOSTData (const String& postData_) const URL URL::withPOSTData (const String& postData_) const
{ {
URL u (*this); URL u (*this);
u.postData = postData_; u.postData = postData_;

View file

@ -94,7 +94,20 @@ public:
E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
"bar", it'll return "http://www.xyz.com/bar?x=1". "bar", it'll return "http://www.xyz.com/bar?x=1".
*/ */
const URL withNewSubPath (const String& newPath) const; URL withNewSubPath (const String& newPath) const;
/** Returns a new URL that refers to a sub-path relative to this one.
E.g. if the URL is "http://www.xyz.com/foo" and you call this with
"bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for
this method to know whether the original URL is a file or directory, so it's
up to you to make sure it's a directory. It also won't attempt to be smart about
the content of the childPath string, so if this string is an absolute URL, it'll
still just get bolted onto the end of the path.
@see File::getChildFile
*/
URL getChildURL (const String& subPath) const;
//============================================================================== //==============================================================================
/** Returns a copy of this URL, with a GET or POST parameter added to the end. /** Returns a copy of this URL, with a GET or POST parameter added to the end.
@ -105,8 +118,8 @@ public:
would produce a new url whose toString(true) method would return would produce a new url whose toString(true) method would return
"www.fish.com?amount=some+fish". "www.fish.com?amount=some+fish".
*/ */
const URL withParameter (const String& parameterName, URL withParameter (const String& parameterName,
const String& parameterValue) const; const String& parameterValue) const;
/** Returns a copy of this URl, with a file-upload type parameter added to it. /** Returns a copy of this URl, with a file-upload type parameter added to it.
@ -116,9 +129,9 @@ public:
Note that the filename is stored, but the file itself won't actually be read Note that the filename is stored, but the file itself won't actually be read
until this URL is later used to create a network input stream. until this URL is later used to create a network input stream.
*/ */
const URL withFileToUpload (const String& parameterName, URL withFileToUpload (const String& parameterName,
const File& fileToUpload, const File& fileToUpload,
const String& mimeType) const; const String& mimeType) const;
/** Returns a set of all the parameters encoded into the url. /** Returns a set of all the parameters encoded into the url.
@ -154,7 +167,7 @@ public:
This data will only be used if you specify a post operation when you call This data will only be used if you specify a post operation when you call
createInputStream(). createInputStream().
*/ */
const URL withPOSTData (const String& postData) const; URL withPOSTData (const String& postData) const;
/** Returns the data that was set using withPOSTData(). /** Returns the data that was set using withPOSTData().
*/ */

View file

@ -33,7 +33,7 @@
*/ */
#define JUCE_MAJOR_VERSION 2 #define JUCE_MAJOR_VERSION 2
#define JUCE_MINOR_VERSION 0 #define JUCE_MINOR_VERSION 0
#define JUCE_BUILDNUMBER 1 #define JUCE_BUILDNUMBER 2
/** Current Juce version number. /** Current Juce version number.

View file

@ -39,7 +39,6 @@ public:
class ZipFile::ZipInputStream : public InputStream class ZipFile::ZipInputStream : public InputStream
{ {
public: public:
//==============================================================================
ZipInputStream (ZipFile& file_, ZipFile::ZipEntryInfo& zei) ZipInputStream (ZipFile& file_, ZipFile::ZipEntryInfo& zei)
: file (file_), : file (file_),
zipEntryInfo (zei), zipEntryInfo (zei),
@ -127,9 +126,7 @@ public:
return true; return true;
} }
private: private:
//==============================================================================
ZipFile& file; ZipFile& file;
ZipEntryInfo zipEntryInfo; ZipEntryInfo zipEntryInfo;
int64 pos; int64 pos;

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_cryptography", "id": "juce_cryptography",
"name": "JUCE cryptography classes", "name": "JUCE cryptography classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.", "description": "Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_data_structures", "id": "juce_data_structures",
"name": "JUCE data model helper classes", "name": "JUCE data model helper classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for undo/redo management, and smart data structures.", "description": "Classes for undo/redo management, and smart data structures.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_events", "id": "juce_events",
"name": "JUCE message and event handling classes", "name": "JUCE message and event handling classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for running an application's main event loop and sending/receiving messages, timers, etc.", "description": "Classes for running an application's main event loop and sending/receiving messages, timers, etc.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_graphics", "id": "juce_graphics",
"name": "JUCE graphics classes", "name": "JUCE graphics classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for 2D vector graphics, image loading/saving, font handling, etc.", "description": "Classes for 2D vector graphics, image loading/saving, font handling, etc.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_gui_basics", "id": "juce_gui_basics",
"name": "JUCE GUI core classes", "name": "JUCE GUI core classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Basic user-interface components and related classes.", "description": "Basic user-interface components and related classes.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_gui_extra", "id": "juce_gui_extra",
"name": "JUCE extended GUI classes", "name": "JUCE extended GUI classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Miscellaneous GUI classes for specialised tasks.", "description": "Miscellaneous GUI classes for specialised tasks.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_opengl", "id": "juce_opengl",
"name": "JUCE OpenGL classes", "name": "JUCE OpenGL classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for rendering OpenGL in a JUCE window.", "description": "Classes for rendering OpenGL in a JUCE window.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",

View file

@ -1,7 +1,7 @@
{ {
"id": "juce_video", "id": "juce_video",
"name": "JUCE video playback and capture classes", "name": "JUCE video playback and capture classes",
"version": "2.0.1", "version": "2.0.2",
"description": "Classes for playing video and capturing camera input.", "description": "Classes for playing video and capturing camera input.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",