From 8aa60b9361ec508d642f08a3c5a4cfd65002ed17 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Thu, 18 Aug 2011 12:43:49 +0100 Subject: [PATCH] Minor URL additions and introjucer work. --- .../Source/Application/jucer_CommandLine.cpp | 108 +++++++++++++++++- .../Project Saving/jucer_ProjectExport_MSVC.h | 2 +- .../Project Saving/jucer_ProjectExporter.cpp | 3 +- .../Project Saving/jucer_ProjectSaver.h | 6 +- .../Source/Project/jucer_Module.cpp | 80 ++++++++++--- .../Introjucer/Source/Project/jucer_Module.h | 18 ++- .../jucer_ProjectInformationComponent.cpp | 50 ++++---- modules/juce_audio_basics/juce_module_info | 2 +- modules/juce_audio_devices/juce_module_info | 2 +- modules/juce_audio_formats/juce_module_info | 2 +- .../juce_audio_plugin_client/juce_module_info | 2 +- .../juce_audio_processors/juce_module_info | 2 +- modules/juce_audio_utils/juce_module_info | 2 +- modules/juce_browser_plugin/juce_module_info | 2 +- modules/juce_core/juce_module_info | 2 +- modules/juce_core/network/juce_URL.cpp | 39 ++++--- modules/juce_core/network/juce_URL.h | 27 +++-- .../juce_core/system/juce_StandardHeader.h | 2 +- modules/juce_core/zip/juce_ZipFile.cpp | 3 - modules/juce_cryptography/juce_module_info | 2 +- modules/juce_data_structures/juce_module_info | 2 +- modules/juce_events/juce_module_info | 2 +- modules/juce_graphics/juce_module_info | 2 +- modules/juce_gui_basics/juce_module_info | 2 +- modules/juce_gui_extra/juce_module_info | 2 +- modules/juce_opengl/juce_module_info | 2 +- modules/juce_video/juce_module_info | 2 +- 27 files changed, 279 insertions(+), 91 deletions(-) diff --git a/extras/Introjucer/Source/Application/jucer_CommandLine.cpp b/extras/Introjucer/Source/Application/jucer_CommandLine.cpp index 9c73d42185..a84124dfe3 100644 --- a/extras/Introjucer/Source/Application/jucer_CommandLine.cpp +++ b/extras/Introjucer/Source/Application/jucer_CommandLine.cpp @@ -24,6 +24,7 @@ */ #include "../Project/jucer_Project.h" +#include "../Project/jucer_Module.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 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; } @@ -92,7 +193,10 @@ int performCommandLine (const String& commandLine) return resaveProject (getFile (tokens[1])); if (tokens[0] == "buildmodule") - return buildModule (tokens); + return buildModules (tokens, false); + + if (tokens[0] == "buildallmodules") + return buildModules (tokens, true); return commandLineNotPerformed; } diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h index 4fb2ccf1f1..514140d616 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExport_MSVC.h @@ -92,7 +92,7 @@ protected: return getIntermediatesPath (config); RelativePath binaryRelPath (binaryPath, RelativePath::projectFolder); - + if (binaryRelPath.isAbsolute()) return binaryRelPath.toWindowsStyle(); diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp b/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp index 50c4743f8e..33a17ca540 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectExporter.cpp @@ -210,7 +210,8 @@ void ProjectExporter::createPropertyEditors (Array & 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."); OwnedArray modules; - project.createRequiredModules (ModuleList::getInstance(), modules); + ModuleList moduleList; + project.createRequiredModules (moduleList, modules); for (int i = 0; i < modules.size(); ++i) modules.getUnchecked(i)->createPropertyEditors (*this, props); diff --git a/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h b/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h index f9df21b0e3..af24f1319a 100644 --- a/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h +++ b/extras/Introjucer/Source/Project Saving/jucer_ProjectSaver.h @@ -65,7 +65,11 @@ public: writeMainProjectFile(); OwnedArray modules; - project.createRequiredModules (ModuleList::getInstance(), modules); + + { + ModuleList moduleList; + project.createRequiredModules (moduleList, modules); + } if (errors.size() == 0) writeAppConfigFile (modules); diff --git a/extras/Introjucer/Source/Project/jucer_Module.cpp b/extras/Introjucer/Source/Project/jucer_Module.cpp index 0ae8365f5a..5b0ad6d57c 100644 --- a/extras/Introjucer/Source/Project/jucer_Module.cpp +++ b/extras/Introjucer/Source/Project/jucer_Module.cpp @@ -36,12 +36,6 @@ ModuleList::ModuleList() rescan(); } -ModuleList& ModuleList::getInstance() -{ - static ModuleList list; - return list; -} - struct ModuleSorter { 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() { modules.clear(); - moduleFolder = StoredSettings::getInstance()->getLastKnownJuceFolder().getChildFile ("modules"); DirectoryIterator iter (moduleFolder, false, "*", File::findDirectories); while (iter.next()) { - const File moduleDef (iter.getFile().getChildFile ("juce_module_info")); + const File moduleDef (iter.getFile().getChildFile (LibraryModule::getInfoFileName())); if (moduleDef.exists()) { - ScopedPointer m (new LibraryModule (moduleDef)); - jassert (m->isValid()); + LibraryModule m (moduleDef); + jassert (m.isValid()); - if (m->isValid()) + if (m.isValid()) { Module* info = new Module(); modules.add (info); - info->uid = m->getID(); - info->name = m->moduleInfo ["name"]; - info->description = m->moduleInfo ["description"]; + info->uid = m.getID(); + info->version = m.getVersion(); + info->name = m.moduleInfo ["name"]; + info->description = m.moduleInfo ["description"]; info->file = moduleDef; } } } - ModuleSorter sorter; - modules.sort (sorter); + sort(); +} + +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* 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 @@ -162,8 +202,12 @@ LibraryModule::LibraryModule (const File& file) jassert (isValid()); } -String LibraryModule::getID() const { return moduleInfo ["id"].toString(); }; -bool LibraryModule::isValid() const { return getID().isNotEmpty(); } +LibraryModule::LibraryModule (const var& moduleInfo_) + : moduleInfo (moduleInfo_) +{ +} + +bool LibraryModule::isValid() const { return getID().isNotEmpty(); } 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"); } diff --git a/extras/Introjucer/Source/Project/jucer_Module.h b/extras/Introjucer/Source/Project/jucer_Module.h index 78beb9165c..713a570452 100644 --- a/extras/Introjucer/Source/Project/jucer_Module.h +++ b/extras/Introjucer/Source/Project/jucer_Module.h @@ -36,15 +36,22 @@ class LibraryModule { public: LibraryModule (const File& file); + LibraryModule (const var& moduleInfo); - String getID() 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 prepareExporter (ProjectExporter& exporter, ProjectSaver& projectSaver) const; void createPropertyEditors (const ProjectExporter& exporter, Array & props) const; void getConfigFlags (Project& project, OwnedArray& flags) const; + static String getInfoFileName() { return "juce_module_info"; } + var moduleInfo; private: @@ -81,10 +88,10 @@ class ModuleList public: ModuleList(); - static ModuleList& getInstance(); - //============================================================================== void rescan(); + void loadFromWebsite(); + LibraryModule* loadModule (const String& uid) const; void getDependencies (const String& moduleID, StringArray& dependencies) const; @@ -95,8 +102,9 @@ public: { LibraryModule* create() const; - String uid, name, description; + String uid, version, name, description; File file; + URL url; }; const Module* findModuleInfo (const String& uid) const; @@ -105,6 +113,8 @@ public: private: File moduleFolder; + + void sort(); }; diff --git a/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp b/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp index 131624a298..0ae0940c52 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp +++ b/extras/Introjucer/Source/Project/jucer_ProjectInformationComponent.cpp @@ -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; - ModuleList::getInstance().getDependencies (m.uid, dependencies); + moduleList.getDependencies (m.uid, dependencies); for (int i = 0; i < dependencies.size(); ++i) if ((! project.isModuleEnabled (dependencies[i])) && dependencies[i] != m.uid) @@ -123,25 +123,25 @@ static StringArray getExtraDependenciesNeeded (Project& project, const ModuleLis class ModuleSettingsPanel : public PanelBase { public: - ModuleSettingsPanel (Project& project_, const String& moduleID_) - : PanelBase (project_), moduleID (moduleID_) + ModuleSettingsPanel (Project& project_, ModuleList& moduleList_, const String& moduleID_) + : PanelBase (project_), moduleList (moduleList_), moduleID (moduleID_) { setBounds ("parent.width / 2 + 1, 3, parent.width - 3, parent.height - 3"); } void rebuildProperties (Array & props) { - ScopedPointer module (ModuleList::getInstance().loadModule (moduleID)); + ScopedPointer module (moduleList.loadModule (moduleID)); if (module != nullptr) { - props.add (new ModuleInfoComponent (project, moduleID)); + props.add (new ModuleInfoComponent (project, moduleList, moduleID)); if (project.isModuleEnabled (moduleID)) { - const ModuleList::Module* m = ModuleList::getInstance().findModuleInfo (moduleID); - if (m != nullptr && getExtraDependenciesNeeded (project, *m).size() > 0) - props.add (new MissingDependenciesComponent (project, moduleID)); + const ModuleList::Module* m = moduleList.findModuleInfo (moduleID); + if (m != nullptr && getExtraDependenciesNeeded (project, moduleList, *m).size() > 0) + props.add (new MissingDependenciesComponent (project, moduleList, moduleID)); } props.add (new BooleanPropertyComponent (project.shouldShowAllModuleFilesInProject (moduleID), @@ -182,15 +182,16 @@ public: } private: + ModuleList& moduleList; String moduleID; //============================================================================== class ModuleInfoComponent : public PropertyComponent { public: - ModuleInfoComponent (Project& project_, const String& moduleID_) + ModuleInfoComponent (Project& project_, ModuleList& moduleList_, const String& moduleID_) : 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.fillRect (0, 0, getWidth(), getHeight() - 1); - const ModuleList::Module* module = ModuleList::getInstance().findModuleInfo (moduleID); + const ModuleList::Module* module = moduleList.findModuleInfo (moduleID); if (module != nullptr) { @@ -218,6 +219,7 @@ private: private: Project& project; + ModuleList& moduleList; String moduleID; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ModuleInfoComponent); @@ -228,15 +230,15 @@ private: public Button::Listener { public: - MissingDependenciesComponent (Project& project_, const String& moduleID_) + MissingDependenciesComponent (Project& project_, ModuleList& moduleList_, const String& moduleID_) : PropertyComponent ("Dependencies", 100), - project (project_), moduleID (moduleID_), + project (project_), moduleList (moduleList), moduleID (moduleID_), fixButton ("Enable Required Modules") { - const ModuleList::Module* module = ModuleList::getInstance().findModuleInfo (moduleID); + const ModuleList::Module* module = moduleList.findModuleInfo (moduleID); if (module != nullptr) - missingDependencies = getExtraDependenciesNeeded (project, *module); + missingDependencies = getExtraDependenciesNeeded (project, moduleList, *module); addAndMakeVisible (&fixButton); fixButton.setColour (TextButton::buttonColourId, Colours::red); @@ -265,6 +267,7 @@ private: private: Project& project; + ModuleList& moduleList; String moduleID; StringArray missingDependencies; TextButton fixButton; @@ -290,7 +293,7 @@ public: int getNumRows() { - return ModuleList::getInstance().modules.size(); + return moduleList.modules.size(); } void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected) @@ -298,7 +301,7 @@ public: if (rowIsSelected) 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) { @@ -307,7 +310,7 @@ public: getLookAndFeel().drawTickBox (g, *this, (height - tickSize) / 2, (height - tickSize) / 2, tickSize, tickSize, 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); else g.setColour (Colours::black); @@ -322,7 +325,7 @@ public: void flipRow (int row) { - const ModuleList::Module* const m = ModuleList::getInstance().modules [row]; + const ModuleList::Module* const m = moduleList.modules [row]; if (m != nullptr) { @@ -332,7 +335,7 @@ public: } else { - const StringArray extraDepsNeeded (getExtraDependenciesNeeded (project, *m)); + const StringArray extraDepsNeeded (getExtraDependenciesNeeded (project, moduleList, *m)); /* if (extraDepsNeeded.size() > 0) { @@ -375,12 +378,12 @@ public: void selectedRowsChanged (int lastRowSelected) { - const ModuleList::Module* const m = ModuleList::getInstance().modules [lastRowSelected]; + const ModuleList::Module* const m = moduleList.modules [lastRowSelected]; settings = nullptr; if (m != nullptr) - addAndMakeVisible (settings = new ModuleSettingsPanel (project, m->uid)); + addAndMakeVisible (settings = new ModuleSettingsPanel (project, moduleList, m->uid)); } void refresh() @@ -393,6 +396,7 @@ public: private: Project& project; + ModuleList moduleList; ListBox modulesList; ScopedPointer settings; }; diff --git a/modules/juce_audio_basics/juce_module_info b/modules/juce_audio_basics/juce_module_info index 1ff788f983..741fdc3b12 100644 --- a/modules/juce_audio_basics/juce_module_info +++ b/modules/juce_audio_basics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_basics", "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", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_devices/juce_module_info b/modules/juce_audio_devices/juce_module_info index d57622fb29..cb82614c7e 100644 --- a/modules/juce_audio_devices/juce_module_info +++ b/modules/juce_audio_devices/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_devices", "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.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_formats/juce_module_info b/modules/juce_audio_formats/juce_module_info index 3041643b63..33cbbbb60d 100644 --- a/modules/juce_audio_formats/juce_module_info +++ b/modules/juce_audio_formats/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_formats", "name": "JUCE audio file format codecs", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for reading and writing various audio file formats.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_plugin_client/juce_module_info b/modules/juce_audio_plugin_client/juce_module_info index d7b13671eb..0654544358 100644 --- a/modules/juce_audio_plugin_client/juce_module_info +++ b/modules/juce_audio_plugin_client/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_plugin_client", "name": "JUCE audio plugin wrapper classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for building VST, RTAS and AU plugins.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_processors/juce_module_info b/modules/juce_audio_processors/juce_module_info index 8b9d40c7ee..dd2498438b 100644 --- a/modules/juce_audio_processors/juce_module_info +++ b/modules/juce_audio_processors/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_processors", "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.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_audio_utils/juce_module_info b/modules/juce_audio_utils/juce_module_info index a021d8aa37..12caeb65f8 100644 --- a/modules/juce_audio_utils/juce_module_info +++ b/modules/juce_audio_utils/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_utils", "name": "JUCE extra audio utility classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for audio-related GUI and miscellaneous tasks.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_browser_plugin/juce_module_info b/modules/juce_browser_plugin/juce_module_info index 4886cc337b..7dce38101e 100644 --- a/modules/juce_browser_plugin/juce_module_info +++ b/modules/juce_browser_plugin/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_browser_plugin_client", "name": "JUCE browser plugin wrapper classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for building NPAPI and ActiveX browser plugins.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_core/juce_module_info b/modules/juce_core/juce_module_info index d709ec61f6..14de580182 100644 --- a/modules/juce_core/juce_module_info +++ b/modules/juce_core/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_core", "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.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_core/network/juce_URL.cpp b/modules/juce_core/network/juce_URL.cpp index e1c12d84d4..56875261a1 100644 --- a/modules/juce_core/network/juce_URL.cpp +++ b/modules/juce_core/network/juce_URL.cpp @@ -173,6 +173,17 @@ namespace URLHelpers << (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 @@ -221,7 +232,7 @@ String URL::getScheme() const 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); while (url[start] == '/') @@ -234,14 +245,14 @@ const URL URL::withNewSubPath (const String& newPath) const if (startOfPath > 0) u.url = url.substring (0, startOfPath); - if (! u.url.endsWithChar ('/')) - u.url << '/'; - - if (newPath.startsWithChar ('/')) - u.url << newPath.substring (1); - else - u.url << newPath; + URLHelpers::concatenatePaths (u.url, newPath); + return u; +} +URL URL::getChildURL (const String& subPath) const +{ + URL u (*this); + URLHelpers::concatenatePaths (u.url, subPath); return u; } @@ -328,17 +339,17 @@ XmlElement* URL::readEntireXmlStream (const bool usePostCommand) const } //============================================================================== -const URL URL::withParameter (const String& parameterName, - const String& parameterValue) const +URL URL::withParameter (const String& parameterName, + const String& parameterValue) const { URL u (*this); u.parameters.set (parameterName, parameterValue); return u; } -const URL URL::withFileToUpload (const String& parameterName, - const File& fileToUpload, - const String& mimeType) const +URL URL::withFileToUpload (const String& parameterName, + const File& fileToUpload, + const String& mimeType) const { jassert (mimeType.isNotEmpty()); // You need to supply a mime type! @@ -348,7 +359,7 @@ const URL URL::withFileToUpload (const String& parameterName, return u; } -const URL URL::withPOSTData (const String& postData_) const +URL URL::withPOSTData (const String& postData_) const { URL u (*this); u.postData = postData_; diff --git a/modules/juce_core/network/juce_URL.h b/modules/juce_core/network/juce_URL.h index 0ebee624d0..832d170122 100644 --- a/modules/juce_core/network/juce_URL.h +++ b/modules/juce_core/network/juce_URL.h @@ -94,7 +94,20 @@ public: 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". */ - 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. @@ -105,8 +118,8 @@ public: would produce a new url whose toString(true) method would return "www.fish.com?amount=some+fish". */ - const URL withParameter (const String& parameterName, - const String& parameterValue) const; + URL withParameter (const String& parameterName, + const String& parameterValue) const; /** 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 until this URL is later used to create a network input stream. */ - const URL withFileToUpload (const String& parameterName, - const File& fileToUpload, - const String& mimeType) const; + URL withFileToUpload (const String& parameterName, + const File& fileToUpload, + const String& mimeType) const; /** 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 createInputStream(). */ - const URL withPOSTData (const String& postData) const; + URL withPOSTData (const String& postData) const; /** Returns the data that was set using withPOSTData(). */ diff --git a/modules/juce_core/system/juce_StandardHeader.h b/modules/juce_core/system/juce_StandardHeader.h index 8c2f64187d..54d6dfe83a 100644 --- a/modules/juce_core/system/juce_StandardHeader.h +++ b/modules/juce_core/system/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 2 #define JUCE_MINOR_VERSION 0 -#define JUCE_BUILDNUMBER 1 +#define JUCE_BUILDNUMBER 2 /** Current Juce version number. diff --git a/modules/juce_core/zip/juce_ZipFile.cpp b/modules/juce_core/zip/juce_ZipFile.cpp index 1b6b626413..1909b952e3 100644 --- a/modules/juce_core/zip/juce_ZipFile.cpp +++ b/modules/juce_core/zip/juce_ZipFile.cpp @@ -39,7 +39,6 @@ public: class ZipFile::ZipInputStream : public InputStream { public: - //============================================================================== ZipInputStream (ZipFile& file_, ZipFile::ZipEntryInfo& zei) : file (file_), zipEntryInfo (zei), @@ -127,9 +126,7 @@ public: return true; } - private: - //============================================================================== ZipFile& file; ZipEntryInfo zipEntryInfo; int64 pos; diff --git a/modules/juce_cryptography/juce_module_info b/modules/juce_cryptography/juce_module_info index 3a80123048..abc5f77add 100644 --- a/modules/juce_cryptography/juce_module_info +++ b/modules/juce_cryptography/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_cryptography", "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.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_data_structures/juce_module_info b/modules/juce_data_structures/juce_module_info index 5e5d7b1022..bdf8bc3f5d 100644 --- a/modules/juce_data_structures/juce_module_info +++ b/modules/juce_data_structures/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_data_structures", "name": "JUCE data model helper classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for undo/redo management, and smart data structures.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_events/juce_module_info b/modules/juce_events/juce_module_info index ce7c1d8e52..2d2e9fc0a6 100644 --- a/modules/juce_events/juce_module_info +++ b/modules/juce_events/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_events", "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.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_graphics/juce_module_info b/modules/juce_graphics/juce_module_info index 294f0232c0..6ab57dc443 100644 --- a/modules/juce_graphics/juce_module_info +++ b/modules/juce_graphics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_graphics", "name": "JUCE graphics classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for 2D vector graphics, image loading/saving, font handling, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_gui_basics/juce_module_info b/modules/juce_gui_basics/juce_module_info index 4d23a8a57b..feafbed820 100644 --- a/modules/juce_gui_basics/juce_module_info +++ b/modules/juce_gui_basics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_gui_basics", "name": "JUCE GUI core classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Basic user-interface components and related classes.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_gui_extra/juce_module_info b/modules/juce_gui_extra/juce_module_info index 0619aaa9ec..0be56fb6cb 100644 --- a/modules/juce_gui_extra/juce_module_info +++ b/modules/juce_gui_extra/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_gui_extra", "name": "JUCE extended GUI classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Miscellaneous GUI classes for specialised tasks.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_opengl/juce_module_info b/modules/juce_opengl/juce_module_info index 0d732e318b..59dcff731a 100644 --- a/modules/juce_opengl/juce_module_info +++ b/modules/juce_opengl/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_opengl", "name": "JUCE OpenGL classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for rendering OpenGL in a JUCE window.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/modules/juce_video/juce_module_info b/modules/juce_video/juce_module_info index d687240944..9473707570 100644 --- a/modules/juce_video/juce_module_info +++ b/modules/juce_video/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_video", "name": "JUCE video playback and capture classes", - "version": "2.0.1", + "version": "2.0.2", "description": "Classes for playing video and capturing camera input.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial",