diff --git a/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h b/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h index 12da6958ae..18d165388e 100644 --- a/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h +++ b/extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h @@ -50,6 +50,7 @@ public: osSelector.onChange = [this] { addLabelsAndSetProperties(); + updateValues(); updateFilePathPropertyComponents(); }; @@ -65,6 +66,7 @@ public: addChildComponent (rescanUserPathButton); rescanUserPathButton.onClick = [] { ProjucerApplication::getApp().rescanUserPathModules(); }; + updateValues(); updateFilePathPropertyComponents(); } @@ -154,6 +156,9 @@ private: float flashAlpha = 0.0f; bool hasFlashed = false; + ValueWithDefault jucePathValue, juceModulePathValue, userModulePathValue, vst3PathValue, rtasPathValue, aaxPathValue, + androidSDKPathValue, androidNDKPathValue, clionExePathValue, androidStudioExePathValue; + //============================================================================== void timerCallback() override { @@ -196,46 +201,38 @@ private: { pathPropertyComponents.clear(); - auto& settings = getAppSettings(); + auto isThisOS = isSelectedOSThisOS(); - if (isSelectedOSThisOS()) + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (jucePathValue, "Path to JUCE", true, isThisOS))); + + pathPropertyComponents.add (nullptr); + + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (juceModulePathValue, "JUCE Modules", true, isThisOS))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (userModulePathValue, "User Modules", true, isThisOS, {}, {}, true))); + + pathPropertyComponents.add (nullptr); + + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (vst3PathValue, "Custom VST3 SDK", true, isThisOS))); + + if (getSelectedOS() == TargetOS::linux) { - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::jucePath), - "Path to JUCE", true))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (Value(), "AAX SDK", true, isThisOS))); + pathPropertyComponents.getLast()->setEnabled (false); - pathPropertyComponents.add (nullptr); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (Value(), "RTAS SDK", true, isThisOS))); + pathPropertyComponents.getLast()->setEnabled (false); + } + else + { + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (aaxPathValue, "AAX SDK", true, isThisOS))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (rtasPathValue, "RTAS SDK", true, isThisOS))); + } - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::defaultJuceModulePath), - "JUCE Modules", true))); - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::defaultUserModulePath), - "User Modules", true, {}, {}, true))); - - pathPropertyComponents.add (nullptr); - - if (getSelectedOS() == TargetOS::linux) - { - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent ({}, "RTAS SDK", true))); - pathPropertyComponents.getLast()->setEnabled (false); - - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent ({}, "AAX SDK", true))); - pathPropertyComponents.getLast()->setEnabled (false); - } - else - { - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::rtasPath), - "RTAS SDK", true))); - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::aaxPath), - "AAX SDK", true))); - } - - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::androidSDKPath), - "Android SDK", true))); - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::androidNDKPath), - "Android NDK", true))); - - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::vst3Path), - "Custom VST3 SDK", true))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (androidSDKPathValue, "Android SDK", true, isThisOS))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (androidNDKPathValue, "Android NDK", true, isThisOS))); + if (isThisOS) + { pathPropertyComponents.add (nullptr); #if JUCE_MAC @@ -245,54 +242,15 @@ private: #else String exeLabel ("startup script"); #endif - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::clionExePath), - "CLion " + exeLabel, false))); - addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (settings.getStoredPath (Ids::androidStudioExePath), - "Android Studio " + exeLabel, false))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (clionExePathValue, "CLion " + exeLabel, false, isThisOS))); + addAndMakeVisible (pathPropertyComponents.add (new FilePathPropertyComponent (androidStudioExePathValue, "Android Studio " + exeLabel, false, isThisOS))); rescanJUCEPathButton.setVisible (true); rescanUserPathButton.setVisible (true); } else { - auto selectedOS = getSelectedOS(); - auto maxChars = 1024; - - pathPropertyComponents.add (nullptr); - - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::defaultJuceModulePath, selectedOS), - "JUCE Modules", maxChars, false))); - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::defaultUserModulePath, selectedOS), - "User Modules", maxChars, false))); - - pathPropertyComponents.add (nullptr); - - if (selectedOS == TargetOS::linux) - { - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (Value(), "RTAS SDK", maxChars, false))); - pathPropertyComponents.getLast()->setEnabled (false); - - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (Value(), "AAX SDK", maxChars, false))); - pathPropertyComponents.getLast()->setEnabled (false); - } - else - { - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::rtasPath, selectedOS), - "RTAS SDK", maxChars, false))); - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::aaxPath, selectedOS), - "AAX SDK", maxChars, false))); - } - - - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::androidSDKPath, selectedOS), - "Android SDK", maxChars, false))); - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::androidNDKPath, selectedOS), - "Android NDK", maxChars, false))); - - addAndMakeVisible (pathPropertyComponents.add (new TextPropertyComponent (settings.getFallbackPathForOS (Ids::vst3Path, selectedOS), - "Custom VST3 SDK", maxChars, false))); - rescanJUCEPathButton.setVisible (false); rescanUserPathButton.setVisible (false); } @@ -300,6 +258,23 @@ private: resized(); } + void updateValues() + { + auto& settings = getAppSettings(); + auto os = getSelectedOS(); + + jucePathValue = settings.getStoredPath (Ids::jucePath, os); + juceModulePathValue = settings.getStoredPath (Ids::defaultJuceModulePath, os); + userModulePathValue = settings.getStoredPath (Ids::defaultUserModulePath, os); + vst3PathValue = settings.getStoredPath (Ids::vst3Path, os); + rtasPathValue = settings.getStoredPath (Ids::rtasPath, os); + aaxPathValue = settings.getStoredPath (Ids::aaxPath, os); + androidSDKPathValue = settings.getStoredPath (Ids::androidSDKPath, os); + androidNDKPathValue = settings.getStoredPath (Ids::androidNDKPath, os); + clionExePathValue = settings.getStoredPath (Ids::clionExePath, os); + androidStudioExePathValue = settings.getStoredPath (Ids::androidStudioExePath, os); + } + void addLabelsAndSetProperties() { pathPropertyLabels.clear(); @@ -316,5 +291,6 @@ private: } } + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlobalPathsWindowComponent) }; diff --git a/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp b/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp index ca57338a32..30f26af5a3 100644 --- a/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp +++ b/extras/Projucer/Source/Application/jucer_AutoUpdater.cpp @@ -751,10 +751,10 @@ void LatestVersionChecker::modalStateFinished (int result, void LatestVersionChecker::askUserForLocationToDownload (URL& newVersionToDownload, const String& extraHeaders) { - File targetFolder (getAppSettings().getStoredPath (Ids::jucePath).toString()); + File targetFolder (getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get()); FileChooser chooser (TRANS("Please select the location into which you'd like to install the new version"), - targetFolder); + targetFolder); if (chooser.browseForDirectory()) { diff --git a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp index 93e0e55df6..c253f39cf6 100644 --- a/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp +++ b/extras/Projucer/Source/LiveBuildEngine/jucer_CompileEngineClient.cpp @@ -462,7 +462,7 @@ private: && (project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST3") || project.isConfigFlagEnabled ("JUCE_PLUGINHOST_VST")); - auto customVst3Path = getAppSettings().getStoredPath (Ids::vst3Path).toString(); + auto customVst3Path = getAppSettings().getStoredPath (Ids::vst3Path, TargetOS::getThisOS()).get().toString(); if (customVst3Path.isNotEmpty() && (project.getProjectType().isAudioPlugin() || isVSTHost)) paths.add (customVst3Path); diff --git a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h index 546aa54106..29c0d101ef 100644 --- a/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h +++ b/extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h @@ -133,7 +133,8 @@ private: //============================================================================== class ModuleSettingsPanel : public Component, - private Value::Listener + private Value::Listener, + private Timer { public: ModuleSettingsPanel (Project& p, const String& modID, TreeView* tree) @@ -163,21 +164,21 @@ private: if (modules.doesModuleHaveHigherCppStandardThanProject (moduleID)) props.add (new CppStandardWarningComponent()); - modulePathValueSources.clear(); + exporterModulePathValues.clear(); for (Project::ExporterIterator exporter (project); exporter.next();) { if (exporter->isCLion()) continue; - auto key = isJUCEModule (moduleID) ? Ids::defaultJuceModulePath - : Ids::defaultUserModulePath; + exporterModulePathValues.add (exporter->getPathForModuleValue (moduleID)); - Value src (modulePathValueSources.add (new DependencyPathValueSource (exporter->getPathForModuleValue (moduleID), - key, exporter->getTargetOSForExporter()))); + auto& value = exporterModulePathValues.getReference (exporterModulePathValues.size() - 1); + value.onDefaultChange = [this] { startTimer (50); }; - auto* pathComponent = new DependencyFilePathPropertyComponent (src, "Path for " + exporter->getName().quoted(), - true, "*", project.getProjectFolder()); + auto* pathComponent = new FilePathPropertyComponent (value, "Path for " + exporter->getName().quoted(), true, + exporter->getTargetOSForExporter() == TargetOS::getThisOS(), + "*", project.getProjectFolder()); props.add (pathComponent, "A path to the folder that contains the " + moduleID + " module when compiling the " @@ -187,10 +188,11 @@ private: "is empty then the global path will be used."); pathComponent->setEnabled (! modules.shouldUseGlobalPath (moduleID)); - pathComponent->getValue().addListener (this); } + globalPathValue.removeListener (this); globalPathValue.referTo (modules.getShouldUseGlobalPathValue (moduleID)); + globalPathValue.addListener (this); auto menuItemString = (TargetOS::getThisOS() == TargetOS::osx ? "\"Projucer->Global Paths...\"" : "\"File->Global Paths...\""); @@ -200,7 +202,6 @@ private: String ("If this is enabled, then the locally-stored global path (set in the ") + menuItemString + " menu item) " "will be used as the path to this module. " "This means that if this Projucer project is opened on another machine it will use that machine's global path as the path to this module."); - globalPathValue.addListener (this); props.add (new BooleanPropertyComponent (modules.shouldCopyModuleFilesLocally (moduleID), "Create local copy", "Copy the module into the project folder"), @@ -239,33 +240,19 @@ private: String getModuleID() const noexcept { return moduleID; } private: + void valueChanged (Value&) override { startTimer (50); } + void timerCallback() override { stopTimer(); refresh(); } + + //============================================================================== PropertyGroupComponent group; Project& project; SafePointer modulesTree; String moduleID; - Value globalPathValue; - Value defaultJuceModulePathValue, defaultUserModulePathValue; + OwnedArray configFlags; - ReferenceCountedArray modulePathValueSources; - - //============================================================================== - void valueChanged (Value& v) override - { - if (v == globalPathValue) - { - auto useGlobalPath = globalPathValue.getValue(); - - for (auto prop : group.properties) - { - if (auto* pathPropertyComponent = dynamic_cast (prop)) - pathPropertyComponent->setEnabled (! useGlobalPath); - } - } - - if (auto* infoComponent = dynamic_cast (group.properties.getUnchecked (0))) - infoComponent->refresh(); - } + Array exporterModulePathValues; + Value globalPathValue; //============================================================================== class ModuleInfoComponent : public PropertyComponent, @@ -276,8 +263,7 @@ private: : PropertyComponent ("Module", 150), project (p), moduleID (modID) { for (Project::ExporterIterator exporter (project); exporter.next();) - listeningValues.add (new Value (exporter->getPathForModuleValue (moduleID))) - ->addListener (this); + listeningValues.add (new Value (exporter->getPathForModuleValue (moduleID).getPropertyAsValue()))->addListener (this); refresh(); } diff --git a/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h b/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h index 17e357ec48..d5fa108f31 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h +++ b/extras/Projucer/Source/Project/UI/jucer_ModulesInformationComponent.h @@ -292,7 +292,7 @@ private: auto modID = moduleList.getModuleID (i); if (modID != moduleToCopy) - exporter->getPathForModuleValue (modID) = exporter->getPathForModuleValue (moduleToCopy).getValue(); + exporter->getPathForModuleValue (modID) = exporter->getPathForModuleValue (moduleToCopy).get(); } } } @@ -301,7 +301,7 @@ private: modulePathClipboard.clear(); for (Project::ExporterIterator exporter (project); exporter.next();) - modulePathClipboard[exporter->getName()] = exporter->getPathForModuleValue (moduleToCopy).getValue(); + modulePathClipboard[exporter->getName()] = exporter->getPathForModuleValue (moduleToCopy).get(); } else if (res == pastePathsID) { diff --git a/extras/Projucer/Source/Project/jucer_Module.cpp b/extras/Projucer/Source/Project/jucer_Module.cpp index d9b65ea4e7..fa85fd0cf9 100644 --- a/extras/Projucer/Source/Project/jucer_Module.cpp +++ b/extras/Projucer/Source/Project/jucer_Module.cpp @@ -747,9 +747,9 @@ void EnabledModuleList::setLocalCopyModeForAllModules (bool copyLocally) File EnabledModuleList::findDefaultModulesFolder (Project& project) { - File globalPath (getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString()); + File globalPath (getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString()); - if (globalPath != File()) + if (globalPath.exists()) return globalPath; for (auto& exporterPathModule : project.getExporterPathsModuleList().getAllModules()) diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index 76156155e9..fded6d2871 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -139,7 +139,7 @@ public: gradleToolchain (settings, Ids::gradleToolchain, getUndoManager(), "clang"), androidPluginVersion (settings, Ids::androidPluginVersion, getUndoManager(), "3.1.3"), buildToolsVersion (settings, Ids::buildToolsVersion, getUndoManager(), "28.0.0"), - AndroidExecutable (getAppSettings().getStoredPath (Ids::androidStudioExePath).toString()) + AndroidExecutable (getAppSettings().getStoredPath (Ids::androidStudioExePath, TargetOS::getThisOS()).get().toString()) { name = getName(); @@ -816,8 +816,8 @@ private: { String props; - props << "ndk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidNDKPath).toString()) << newLine - << "sdk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidSDKPath).toString()) << newLine; + props << "ndk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidNDKPath, TargetOS::getThisOS()).get().toString()) << newLine + << "sdk.dir=" << sanitisePath (getAppSettings().getStoredPath (Ids::androidSDKPath, TargetOS::getThisOS()).get().toString()) << newLine; return props; } diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h index 9e56c8fdd2..1c5136952d 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_CLion.h @@ -231,7 +231,7 @@ private: static File getCLionExecutableOrApp() { File clionExeOrApp (getAppSettings() - .getStoredPath (Ids::clionExePath) + .getStoredPath (Ids::clionExePath, TargetOS::getThisOS()).get() .toString() .replace ("${user.home}", File::getSpecialLocation (File::userHomeDirectory).getFullPathName())); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h index a0feb777d7..02314c6ae7 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h @@ -136,9 +136,9 @@ public: //============================================================================== void initialiseDependencyPathValues() override { - vst3Path.referTo (Value (new DependencyPathValueSource (getSetting (Ids::vst3Folder), Ids::vst3Path, TargetOS::windows))); - aaxPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::aaxFolder), Ids::aaxPath, TargetOS::windows))); - rtasPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::rtasFolder), Ids::rtasPath, TargetOS::windows))); + vst3PathValueWrapper.init (Ids::vst3Path, TargetOS::windows); + aaxPathValueWrapper .init (Ids::aaxPath, TargetOS::windows); + rtasPathValueWrapper.init (Ids::rtasPath, TargetOS::windows); } //============================================================================== @@ -1068,7 +1068,7 @@ public: //============================================================================== RelativePath getAAXIconFile() const { - RelativePath aaxSDK (owner.getAAXPathValue().toString(), RelativePath::projectFolder); + RelativePath aaxSDK (owner.getAAXPathString(), RelativePath::projectFolder); RelativePath projectIcon ("icon.ico", RelativePath::buildTargetFolder); if (getOwner().getTargetFolder().getChildFile ("icon.ico").existsAsFile()) @@ -1083,7 +1083,7 @@ public: { if (type == AAXPlugIn) { - RelativePath aaxSDK (owner.getAAXPathValue().toString(), RelativePath::projectFolder); + RelativePath aaxSDK (owner.getAAXPathString(), RelativePath::projectFolder); RelativePath aaxLibsFolder = aaxSDK.getChildFile ("Libs"); RelativePath bundleScript = aaxSDK.getChildFile ("Utilities").getChildFile ("CreatePackage.bat"); RelativePath iconFilePath = getAAXIconFile(); @@ -1174,13 +1174,13 @@ public: { case AAXPlugIn: { - auto aaxLibsFolder = RelativePath (owner.getAAXPathValue().toString(), RelativePath::projectFolder).getChildFile ("Libs"); + auto aaxLibsFolder = RelativePath (owner.getAAXPathString(), RelativePath::projectFolder).getChildFile ("Libs"); defines.set ("JucePlugin_AAXLibs_path", createRebasedPath (aaxLibsFolder)); } break; case RTASPlugIn: { - RelativePath rtasFolder (owner.getRTASPathValue().toString(), RelativePath::projectFolder); + RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); defines.set ("JucePlugin_WinBag_path", createRebasedPath (rtasFolder.getChildFile ("WinBag"))); } break; @@ -1202,7 +1202,7 @@ public: StringArray searchPaths; if (type == RTASPlugIn) { - RelativePath rtasFolder (owner.getRTASPathValue().toString(), RelativePath::projectFolder); + RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); static const char* p[] = { "AlturaPorts/TDMPlugins/PluginLibrary/EffectClasses", "AlturaPorts/TDMPlugins/PluginLibrary/ProcessClasses", diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h index e55b444d5c..4821de2925 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h @@ -445,9 +445,9 @@ public: //============================================================================== void initialiseDependencyPathValues() override { - vst3Path.referTo (Value (new DependencyPathValueSource (getSetting (Ids::vst3Folder), Ids::vst3Path, TargetOS::osx))); - aaxPath. referTo (Value (new DependencyPathValueSource (getSetting (Ids::aaxFolder), Ids::aaxPath, TargetOS::osx))); - rtasPath.referTo (Value (new DependencyPathValueSource (getSetting (Ids::rtasFolder), Ids::rtasPath, TargetOS::osx))); + vst3PathValueWrapper.init (Ids::vst3Path, TargetOS::osx); + aaxPathValueWrapper .init (Ids::aaxPath, TargetOS::osx); + rtasPathValueWrapper.init (Ids::rtasPath, TargetOS::osx); } protected: @@ -1667,7 +1667,7 @@ public: { if (type == AAXPlugIn) { - auto aaxLibsFolder = RelativePath (owner.getAAXPathValue().toString(), RelativePath::projectFolder).getChildFile ("Libs"); + auto aaxLibsFolder = RelativePath (owner.getAAXPathString(), RelativePath::projectFolder).getChildFile ("Libs"); String libraryPath (config.isDebug() ? "Debug" : "Release"); libraryPath += "/libAAXLibrary_libcpp.a"; @@ -1676,7 +1676,7 @@ public: } else if (type == RTASPlugIn) { - RelativePath rtasFolder (owner.getRTASPathValue().toString(), RelativePath::projectFolder); + RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); extraLibs.add (rtasFolder.getChildFile ("MacBag/Libs/Debug/libPluginLibrary.a")); extraLibs.add (rtasFolder.getChildFile ("MacBag/Libs/Release/libPluginLibrary.a")); @@ -1689,7 +1689,7 @@ public: if (type == RTASPlugIn) { - RelativePath rtasFolder (owner.getRTASPathValue().toString(), RelativePath::projectFolder); + RelativePath rtasFolder (owner.getRTASPathString(), RelativePath::projectFolder); targetExtraSearchPaths.add ("$(DEVELOPER_DIR)/Headers/FlatCarbon"); targetExtraSearchPaths.add ("$(SDKROOT)/Developer/Headers/FlatCarbon"); diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp index a75a02e810..b676e6c3e8 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.cpp @@ -36,6 +36,8 @@ #include "jucer_ProjectExport_CLion.h" +#include "../Utility/UI/PropertyComponents/jucer_FilePathPropertyComponent.h" + //============================================================================== static void addType (Array& list, const char* name, const void* iconData, int iconDataSize) @@ -296,7 +298,24 @@ void ProjectExporter::createPropertyEditors (PropertyListBuilder& props) "The location of the folder in which the " + name + " project will be created. " "This path can be absolute, but it's much more sensible to make it relative to the jucer project directory."); - createDependencyPathProperties (props); + if (shouldBuildTargetType (ProjectType::Target::VST3PlugIn) && project.shouldBuildVST3()) + { + props.add (new FilePathPropertyComponent (vst3PathValueWrapper.wrappedValue, "VST3 SDK Folder", true, getTargetOSForExporter() == TargetOS::getThisOS()), + "If you're building a VST3 plug-in, you can use this field to override the global VST3 SDK path with a project-specific path. " + "This can be an absolute path, or a path relative to the Projucer project file."); + } + + if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn) && project.shouldBuildAAX()) + { + props.add (new FilePathPropertyComponent (aaxPathValueWrapper.wrappedValue, "AAX SDK Folder", true, getTargetOSForExporter() == TargetOS::getThisOS()), + "If you're building an AAX plug-in, this must be the folder containing the AAX SDK. This can be an absolute path, or a path relative to the Projucer project file."); + } + + if (shouldBuildTargetType (ProjectType::Target::RTASPlugIn) && project.shouldBuildRTAS()) + { + props.add (new FilePathPropertyComponent (rtasPathValueWrapper.wrappedValue, "RTAS SDK Folder", true, getTargetOSForExporter() == TargetOS::getThisOS()), + "If you're building an RTAS plug-in, this must be the folder containing the RTAS SDK. This can be an absolute path, or a path relative to the Projucer project file."); + } props.add (new TextPropertyComponent (extraPPDefsValue, "Extra Preprocessor Definitions", 32768, true), "Extra preprocessor definitions. Use the form \"NAME1=value NAME2=value\", using whitespace, commas, " @@ -327,31 +346,6 @@ void ProjectExporter::createPropertyEditors (PropertyListBuilder& props) "Extra comments: This field is not used for code or project generation, it's just a space where you can express your thoughts."); } -void ProjectExporter::createDependencyPathProperties (PropertyListBuilder& props) -{ - if (shouldBuildTargetType (ProjectType::Target::VST3PlugIn) && project.shouldBuildVST3()) - { - if (dynamic_cast (&getAAXPathValue().getValueSource()) != nullptr) - props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getVST3PathValue(), "VST3 SDK Folder"), - "If you're building a VST3 plug-in, you can use this field to override the global VST3 SDK path with a project-specific path. " - "This can be an absolute path, or a path relative to the Projucer project file."); - } - - if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn) && project.shouldBuildAAX()) - { - if (dynamic_cast (&getAAXPathValue().getValueSource()) != nullptr) - props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getAAXPathValue(), "AAX SDK Folder"), - "If you're building an AAX plug-in, this must be the folder containing the AAX SDK. This can be an absolute path, or a path relative to the Projucer project file."); - } - - if (shouldBuildTargetType (ProjectType::Target::RTASPlugIn) && project.shouldBuildRTAS()) - { - if (dynamic_cast (&getRTASPathValue().getValueSource()) != nullptr) - props.add (new DependencyPathPropertyComponent (project.getFile().getParentDirectory(), getRTASPathValue(), "RTAS SDK Folder"), - "If you're building an RTAS plug-in, this must be the folder containing the RTAS SDK. This can be an absolute path, or a path relative to the Projucer project file."); - } -} - void ProjectExporter::createIconProperties (PropertyListBuilder& props) { OwnedArray images; @@ -411,7 +405,7 @@ RelativePath ProjectExporter::getInternalVST3SDKPath() void ProjectExporter::addVST3FolderToPath() { - auto vst3Folder = getVST3PathValue().toString(); + auto vst3Folder = getVST3PathString(); if (vst3Folder.isNotEmpty()) addToExtraSearchPaths (RelativePath (vst3Folder, RelativePath::projectFolder), 0); @@ -421,7 +415,7 @@ void ProjectExporter::addVST3FolderToPath() void ProjectExporter::addAAXFoldersToPath() { - auto aaxFolder = getAAXPathValue().toString(); + auto aaxFolder = getAAXPathString(); if (aaxFolder.isNotEmpty()) { @@ -530,7 +524,13 @@ void ProjectExporter::addToExtraSearchPaths (const RelativePath& pathFromProject addProjectPathToBuildPathList (extraSearchPaths, pathFromProjectFolder, index); } -Value ProjectExporter::getPathForModuleValue (const String& moduleID) +static var getStoredPathForModule (const String& id, const ProjectExporter& exp) +{ + return getAppSettings().getStoredPath (isJUCEModule (id) ? Ids::defaultJuceModulePath : Ids::defaultUserModulePath, + exp.getTargetOSForExporter()).get(); +} + +ValueWithDefault ProjectExporter::getPathForModuleValue (const String& moduleID) { auto* um = getUndoManager(); @@ -544,7 +544,7 @@ Value ProjectExporter::getPathForModuleValue (const String& moduleID) paths.appendChild (m, um); } - return m.getPropertyAsValue (Ids::path, um); + return { m, Ids::path, um, getStoredPathForModule (moduleID, *this) }; } String ProjectExporter::getPathForModuleString (const String& moduleID) const @@ -553,18 +553,7 @@ String ProjectExporter::getPathForModuleString (const String& moduleID) const .getChildWithProperty (Ids::ID, moduleID) [Ids::path].toString(); if (exporterPath.isEmpty() || project.getEnabledModules().shouldUseGlobalPath (moduleID)) - { - auto id = isJUCEModule (moduleID) ? Ids::defaultJuceModulePath - : Ids::defaultUserModulePath; - - if (TargetOS::getThisOS() != getTargetOSForExporter()) - return getAppSettings().getFallbackPathForOS (id, getTargetOSForExporter()).toString(); - - if (id == Ids::defaultJuceModulePath) - return getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString(); - - return getAppSettings().getStoredPath (Ids::defaultUserModulePath).toString(); - } + return getStoredPathForModule (moduleID, *this); return exporterPath; } @@ -635,7 +624,7 @@ void ProjectExporter::updateOldModulePaths() { for (int i = project.getEnabledModules().getNumModules(); --i >= 0;) { - auto modID = project.getEnabledModules().getModuleID(i); + auto modID = project.getEnabledModules().getModuleID (i); getPathForModuleValue (modID) = getLegacyModulePath (modID).getParentDirectory().toUnixStyle(); } @@ -661,7 +650,7 @@ void ProjectExporter::createDefaultModulePaths() for (int i = project.getEnabledModules().getNumModules(); --i >= 0;) { auto modID = project.getEnabledModules().getModuleID (i); - getPathForModuleValue (modID) = exporter->getPathForModuleValue (modID).getValue(); + getPathForModuleValue (modID) = exporter->getPathForModuleValue (modID); } return; @@ -675,7 +664,7 @@ void ProjectExporter::createDefaultModulePaths() for (int i = project.getEnabledModules().getNumModules(); --i >= 0;) { auto modID = project.getEnabledModules().getModuleID (i); - getPathForModuleValue (modID) = exporter->getPathForModuleValue (modID).getValue(); + getPathForModuleValue (modID) = exporter->getPathForModuleValue (modID); } return; diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h index 33e0134435..f50a9b4106 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExporter.h @@ -27,7 +27,6 @@ #pragma once #include "../Project/jucer_Project.h" -#include "../Utility/UI/PropertyComponents/jucer_DependencyPathPropertyComponent.h" #include "../Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h" class ProjectSaver; @@ -152,15 +151,15 @@ public: String getExternalLibrariesString() const { return getSearchPathsFromString (externalLibrariesValue.get().toString()).joinIntoString (";"); } - bool shouldUseGNUExtensions() const { return gnuExtensionsValue.get();} + bool shouldUseGNUExtensions() const { return gnuExtensionsValue.get(); } - Value getVST3PathValue() const { return vst3Path; } - Value getRTASPathValue() const { return rtasPath; } - Value getAAXPathValue() const { return aaxPath; } + String getVST3PathString() const { return vst3PathValueWrapper.wrappedValue.get(); } + String getAAXPathString() const { return aaxPathValueWrapper.wrappedValue.get(); } + String getRTASPathString() const { return rtasPathValueWrapper.wrappedValue.get(); } // NB: this is the path to the parent "modules" folder that contains the named module, not the // module folder itself. - Value getPathForModuleValue (const String& moduleID); + ValueWithDefault getPathForModuleValue (const String& moduleID); String getPathForModuleString (const String& moduleID) const; void removePathForModule (const String& moduleID); @@ -370,7 +369,37 @@ protected: const String projectName; const File projectFolder; - Value vst3Path, rtasPath, aaxPath; // these must be initialised in the specific exporter c'tors! + //============================================================================== + // Wraps a ValueWithDefault object that has a default which depends on a global value. + // Used for the VST3, RTAS and AAX project-specific path options. + struct ValueWithDefaultWrapper : public Value::Listener + { + void init (const Identifier& identifierToUse, TargetOS::OS targetOS) + { + identifier = identifierToUse; + os = targetOS; + + globalValue = getAppSettings().getStoredPath (identifier, os).getPropertyAsValue(); + globalValue.addListener (this); + + wrappedValue.referTo (tree, identifier, nullptr, getAppSettings().getStoredPath (identifier, os).get()); + } + + void valueChanged (Value&) override + { + wrappedValue.setDefault (getAppSettings().getStoredPath (identifier, os).get()); + } + + ValueWithDefault wrappedValue; + + Identifier identifier; + TargetOS::OS os; + + ValueTree tree { "tree" }; + Value globalValue; + }; + + ValueWithDefaultWrapper vst3PathValueWrapper, rtasPathValueWrapper, aaxPathValueWrapper; ValueWithDefault targetLocationValue, extraCompilerFlagsValue, extraLinkerFlagsValue, externalLibrariesValue, userNotesValue, gnuExtensionsValue, bigIconValue, smallIconValue, extraPPDefsValue; diff --git a/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp b/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp index 47cd907b07..6ad6eedbaf 100644 --- a/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp +++ b/extras/Projucer/Source/Settings/jucer_StoredSettings.cpp @@ -211,34 +211,6 @@ void StoredSettings::updateOldProjectSettingsFiles() } } -void StoredSettings::checkJUCEPaths() -{ - auto moduleFolder = projectDefaults.getProperty (Ids::defaultJuceModulePath).toString(); - auto juceFolder = projectDefaults.getProperty (Ids::jucePath).toString(); - - auto validModuleFolder = moduleFolder.isNotEmpty() && isGlobalPathValid ({}, Ids::defaultJuceModulePath, moduleFolder); - auto validJuceFolder = juceFolder.isNotEmpty() && isGlobalPathValid ({}, Ids::jucePath, juceFolder); - - if (validModuleFolder && ! validJuceFolder) - projectDefaults.getPropertyAsValue (Ids::jucePath, nullptr) = File (moduleFolder).getParentDirectory().getFullPathName(); - else if (! validModuleFolder && validJuceFolder) - projectDefaults.getPropertyAsValue (Ids::defaultJuceModulePath, nullptr) = File (juceFolder).getChildFile ("modules").getFullPathName(); -} - -bool StoredSettings::shouldAskUserToSetJUCEPath() noexcept -{ - if (! isGlobalPathValid ({}, Ids::jucePath, projectDefaults.getProperty (Ids::jucePath).toString()) - && getGlobalProperties().getValue ("dontAskAboutJUCEPath", {}).isEmpty()) - return true; - - return false; -} - -void StoredSettings::setDontAskAboutJUCEPathAgain() noexcept -{ - getGlobalProperties().setValue ("dontAskAboutJUCEPath", 1); -} - //============================================================================== void StoredSettings::loadSwatchColours() { @@ -289,130 +261,23 @@ void StoredSettings::ColourSelectorWithSwatches::setSwatchColour (int index, con } //============================================================================== -Value StoredSettings::getStoredPath (const Identifier& key) +void StoredSettings::changed (bool isProjectDefaults) { - auto v = projectDefaults.getPropertyAsValue (key, nullptr); + std::unique_ptr data (isProjectDefaults ? projectDefaults.createXml() + : fallbackPaths.createXml()); - if (v.toString().isEmpty()) - v = getFallbackPathForOS (key, TargetOS::getThisOS()).toString(); - - return v; -} - -Value StoredSettings::getFallbackPathForOS (const Identifier& key, DependencyPathOS os) -{ - auto id = identifierForOS (os); - auto osFallback = fallbackPaths.getOrCreateChildWithName (id, nullptr); - auto v = osFallback.getPropertyAsValue (key, nullptr); - - if (v.toString().isEmpty()) - { - if (key == Ids::jucePath) - { - v = (os == TargetOS::windows ? "C:\\JUCE" - : "~/JUCE"); - } - else if (key == Ids::defaultJuceModulePath) - { - v = (os == TargetOS::windows ? "C:\\JUCE\\modules" - : "~/JUCE/modules"); - } - else if (key == Ids::defaultUserModulePath) - { - v = (os == TargetOS::windows ? "C:\\modules" - : "~/modules"); - } - else if (key == Ids::vst3Path) - { - v = ""; - } - else if (key == Ids::rtasPath) - { - if (os == TargetOS::windows) v = "C:\\SDKs\\PT_90_SDK"; - else if (os == TargetOS::osx) v = "~/SDKs/PT_90_SDK"; - else return {}; // no RTAS on this OS! - } - else if (key == Ids::aaxPath) - { - if (os == TargetOS::windows) v = "C:\\SDKs\\AAX"; - else if (os == TargetOS::osx) v = "~/SDKs/AAX"; - else return {}; // no AAX on this OS! - } - else if (key == Ids::androidSDKPath) - { - v = "${user.home}/Library/Android/sdk"; - } - else if (key == Ids::androidNDKPath) - { - v = "${user.home}/Library/Android/sdk/ndk-bundle"; - } - else if (key == Ids::clionExePath) - { - if (os == TargetOS::windows) - { - #if JUCE_WINDOWS - auto regValue = WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Applications\\clion64.exe\\shell\\open\\command\\", {}, {}); - auto openCmd = StringArray::fromTokens (regValue, true); - - if (! openCmd.isEmpty()) - return Value (openCmd[0].unquoted()); - #endif - - v = "C:\\Program Files\\JetBrains\\CLion YYYY.MM.DD\\bin\\clion64.exe"; - } - else if (os == TargetOS::osx) - { - v = "/Applications/CLion.app"; - } - else - { - v = "${user.home}/clion/bin/clion.sh"; - } - } - else if (key == Ids::androidStudioExePath) - { - if (os == TargetOS::windows) - { - #if JUCE_WINDOWS - auto path = WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Android Studio\\Path", {}, {}); - - if (! path.isEmpty()) - return Value (path.unquoted() + "\\bin\\studio64.exe"); - #endif - - v = "C:\\Program Files\\Android\\Android Studio\\bin\\studio64.exe"; - } - else if (os == TargetOS::osx) - { - v = "/Applications/Android Studio.app"; - } - else - { - return {}; // no Android Studio on this OS! - } - } - } - - return v; -} - -Identifier StoredSettings::identifierForOS (DependencyPathOS os) noexcept -{ - if (os == TargetOS::osx) return Ids::osxFallback; - else if (os == TargetOS::windows) return Ids::windowsFallback; - else if (os == TargetOS::linux) return Ids::linuxFallback; - - jassertfalse; - return {}; + propertyFiles.getUnchecked (0)->setValue (isProjectDefaults ? "PROJECT_DEFAULT_SETTINGS" : "FALLBACK_PATHS", + data.get()); } +//============================================================================== static bool doesSDKPathContainFile (const File& relativeTo, const String& path, const String& fileToCheckFor) noexcept { auto actualPath = path.replace ("${user.home}", File::getSpecialLocation (File::userHomeDirectory).getFullPathName()); return relativeTo.getChildFile (actualPath + "/" + fileToCheckFor).exists(); } -bool StoredSettings::isGlobalPathValid (const File& relativeTo, const Identifier& key, const String& path) const noexcept +static bool isGlobalPathValid (const File& relativeTo, const Identifier& key, const String& path) { String fileToCheckFor; @@ -483,3 +348,138 @@ bool StoredSettings::isGlobalPathValid (const File& relativeTo, const Identifier return doesSDKPathContainFile (relativeTo, path, fileToCheckFor); } + +void StoredSettings::checkJUCEPaths() +{ + auto moduleFolder = getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString(); + auto juceFolder = getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString(); + + auto validModuleFolder = isGlobalPathValid ({}, Ids::defaultJuceModulePath, moduleFolder); + auto validJuceFolder = isGlobalPathValid ({}, Ids::jucePath, juceFolder); + + if (validModuleFolder && ! validJuceFolder) + projectDefaults.getPropertyAsValue (Ids::jucePath, nullptr) = File (moduleFolder).getParentDirectory().getFullPathName(); + else if (! validModuleFolder && validJuceFolder) + projectDefaults.getPropertyAsValue (Ids::defaultJuceModulePath, nullptr) = File (juceFolder).getChildFile ("modules").getFullPathName(); +} + +bool StoredSettings::shouldAskUserToSetJUCEPath() noexcept +{ + if (! isGlobalPathValid ({}, Ids::jucePath, getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString()) + && getGlobalProperties().getValue ("dontAskAboutJUCEPath", {}).isEmpty()) + return true; + + return false; +} + +void StoredSettings::setDontAskAboutJUCEPathAgain() noexcept +{ + getGlobalProperties().setValue ("dontAskAboutJUCEPath", 1); +} + +static String getFallbackPathForOS (const Identifier& key, DependencyPathOS os) +{ + if (key == Ids::jucePath) + { + return (os == TargetOS::windows ? "C:\\JUCE" : "~/JUCE"); + } + else if (key == Ids::defaultJuceModulePath) + { + return (os == TargetOS::windows ? "C:\\JUCE\\modules" : "~/JUCE/modules"); + } + else if (key == Ids::defaultUserModulePath) + { + return (os == TargetOS::windows ? "C:\\modules" : "~/modules"); + } + else if (key == Ids::vst3Path) + { + return {}; + } + else if (key == Ids::rtasPath) + { + if (os == TargetOS::windows) return "C:\\SDKs\\PT_90_SDK"; + else if (os == TargetOS::osx) return "~/SDKs/PT_90_SDK"; + else return {}; // no RTAS on this OS! + } + else if (key == Ids::aaxPath) + { + if (os == TargetOS::windows) return "C:\\SDKs\\AAX"; + else if (os == TargetOS::osx) return "~/SDKs/AAX"; + else return {}; // no AAX on this OS! + } + else if (key == Ids::androidSDKPath) + { + return "${user.home}/Library/Android/sdk"; + } + else if (key == Ids::androidNDKPath) + { + return "${user.home}/Library/Android/sdk/ndk-bundle"; + } + else if (key == Ids::clionExePath) + { + if (os == TargetOS::windows) + { + #if JUCE_WINDOWS + auto regValue = WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\Applications\\clion64.exe\\shell\\open\\command\\", {}, {}); + auto openCmd = StringArray::fromTokens (regValue, true); + + if (! openCmd.isEmpty()) + return openCmd[0].unquoted(); + #endif + + return "C:\\Program Files\\JetBrains\\CLion YYYY.MM.DD\\bin\\clion64.exe"; + } + else if (os == TargetOS::osx) + { + return "/Applications/CLion.app"; + } + else + { + return "${user.home}/clion/bin/clion.sh"; + } + } + else if (key == Ids::androidStudioExePath) + { + if (os == TargetOS::windows) + { + #if JUCE_WINDOWS + auto path = WindowsRegistry::getValue ("HKEY_LOCAL_MACHINE\\SOFTWARE\\Android Studio\\Path", {}, {}); + + if (! path.isEmpty()) + return path.unquoted() + "\\bin\\studio64.exe"; + #endif + + return "C:\\Program Files\\Android\\Android Studio\\bin\\studio64.exe"; + } + else if (os == TargetOS::osx) + { + return "/Applications/Android Studio.app"; + } + else + { + return {}; // no Android Studio on this OS! + } + } + + // unknown key! + jassertfalse; + return {}; +} + +static Identifier identifierForOS (DependencyPathOS os) noexcept +{ + if (os == TargetOS::osx) return Ids::osxFallback; + else if (os == TargetOS::windows) return Ids::windowsFallback; + else if (os == TargetOS::linux) return Ids::linuxFallback; + + jassertfalse; + return {}; +} + +ValueWithDefault StoredSettings::getStoredPath (const Identifier& key, DependencyPathOS os) +{ + auto tree = (os == TargetOS::getThisOS() ? projectDefaults + : fallbackPaths.getOrCreateChildWithName (identifierForOS (os), nullptr)); + + return { tree, key, nullptr, getFallbackPathForOS (key, os) }; +} diff --git a/extras/Projucer/Source/Settings/jucer_StoredSettings.h b/extras/Projucer/Source/Settings/jucer_StoredSettings.h index e174c2550f..0871b470e1 100644 --- a/extras/Projucer/Source/Settings/jucer_StoredSettings.h +++ b/extras/Projucer/Source/Settings/jucer_StoredSettings.h @@ -61,53 +61,19 @@ public: void setSwatchColour (int index, const Colour& newColour) override; }; + //============================================================================== + ValueWithDefault getStoredPath (const Identifier& key, DependencyPathOS os); + + bool shouldAskUserToSetJUCEPath() noexcept; + void setDontAskAboutJUCEPathAgain() noexcept; + //============================================================================== AppearanceSettings appearance; StringArray monospacedFontNames; File lastWizardFolder; - //============================================================================== - Value getStoredPath (const Identifier& key); - Value getFallbackPathForOS (const Identifier& key, DependencyPathOS); - - bool isGlobalPathValid (const File& relativeTo, const Identifier& key, const String& path) const noexcept; - - //============================================================================== - bool shouldAskUserToSetJUCEPath() noexcept; - void setDontAskAboutJUCEPathAgain() noexcept; - private: - OwnedArray propertyFiles; - ValueTree projectDefaults; - ValueTree fallbackPaths; - - void changed (bool isProjectDefaults) - { - std::unique_ptr data (isProjectDefaults ? projectDefaults.createXml() - : fallbackPaths.createXml()); - - propertyFiles.getUnchecked (0)->setValue (isProjectDefaults ? "PROJECT_DEFAULT_SETTINGS" - : "FALLBACK_PATHS", - data.get()); - - // also override the fallback settings if we are editing the project defaults - if (isProjectDefaults) - { - auto v = fallbackPaths.getOrCreateChildWithName (identifierForOS (TargetOS::getThisOS()), nullptr); - auto n = projectDefaults.getNumProperties(); - - for (int i = 0; i < n; ++i) - { - auto name = projectDefaults.getPropertyName (i); - v.setProperty (name, projectDefaults.getProperty(name), nullptr); - } - - changed (false); - } - } - - static Identifier identifierForOS (DependencyPathOS os) noexcept; - + //============================================================================== void updateGlobalPreferences(); void updateRecentFiles(); void updateLastWizardFolder(); @@ -120,12 +86,20 @@ private: void checkJUCEPaths(); //============================================================================== + void changed (bool); + void valueTreePropertyChanged (ValueTree& vt, const Identifier&) override { changed (vt == projectDefaults); } void valueTreeChildAdded (ValueTree& vt, ValueTree&) override { changed (vt == projectDefaults); } void valueTreeChildRemoved (ValueTree& vt, ValueTree&, int) override { changed (vt == projectDefaults); } void valueTreeChildOrderChanged (ValueTree& vt, int, int) override { changed (vt == projectDefaults); } void valueTreeParentChanged (ValueTree& vt) override { changed (vt == projectDefaults); } + //============================================================================== + OwnedArray propertyFiles; + ValueTree projectDefaults; + ValueTree fallbackPaths; + + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (StoredSettings) }; diff --git a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp index 3a5c29496b..09b1be78cd 100644 --- a/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp +++ b/extras/Projucer/Source/Utility/PIPs/jucer_PIPGenerator.cpp @@ -255,9 +255,9 @@ ValueTree PIPGenerator::createExporterChild (const String& exporterName) if (isMobileExporter (exporterName) || (metadata[Ids::name] == "AUv3SynthPlugin" && exporterName == "XCODE_MAC")) { - auto juceDir = getAppSettings().getStoredPath (Ids::jucePath).toString(); + auto juceDir = getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString(); - if (juceDir.isNotEmpty() && isValidJUCEExamplesDirectory (File (juceDir).getChildFile ("examples"))) + if (isValidJUCEExamplesDirectory (File (juceDir).getChildFile ("examples"))) { auto assetsDirectoryPath = File (juceDir).getChildFile ("examples").getChildFile ("Assets").getFullPathName(); @@ -358,9 +358,9 @@ Result PIPGenerator::setProjectSettings (ValueTree& jucerTree) if (useLocalCopy && isJUCEExample (pipFile)) { - auto juceDir = getAppSettings().getStoredPath (Ids::jucePath).toString(); + auto juceDir = getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString(); - if (juceDir.isNotEmpty() && isValidJUCEExamplesDirectory (File (juceDir).getChildFile ("examples"))) + if (isValidJUCEExamplesDirectory (File (juceDir).getChildFile ("examples"))) { defines += ((defines.isEmpty() ? "" : " ") + String ("PIP_JUCE_EXAMPLES_DIRECTORY=") + Base64::toBase64 (File (juceDir).getChildFile ("examples").getFullPathName())); diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h index a6cbe1118d..9df1483705 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h +++ b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h @@ -38,7 +38,7 @@ public: useGlobalPathsToggle ("Use global module path") { if (initialFileOrDirectory.isEmpty()) - initialFileOrDirectory = getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString(); + initialFileOrDirectory = getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString(); setModulesFolder (initialFileOrDirectory); @@ -85,7 +85,7 @@ public: for (;;) { FileChooser fc ("Select your JUCE modules folder...", - { getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString() }, + { getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString() }, "*"); if (! fc.browseForDirectory()) @@ -286,7 +286,7 @@ public: WizardComp() : platformTargets(), projectName (TRANS("Project name")), - modulesPathBox (getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString()) + modulesPathBox (getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString()) { setOpaque (false); @@ -405,7 +405,7 @@ public: } - wizard->modulesFolder = modulesPathBox.isUsingGlobalPaths ? File (getAppSettings().getStoredPath (Ids::defaultJuceModulePath).toString()) + wizard->modulesFolder = modulesPathBox.isUsingGlobalPaths ? File (getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).get().toString()) : modulesPathBox.modulesFolder; if (! isJUCEModulesFolder (wizard->modulesFolder)) @@ -419,7 +419,7 @@ public: return; if (modulesPathBox.isUsingGlobalPaths) - getAppSettings().getStoredPath (Ids::defaultJuceModulePath).setValue (wizard->modulesFolder.getFullPathName()); + getAppSettings().getStoredPath (Ids::defaultJuceModulePath, TargetOS::getThisOS()).setValue (wizard->modulesFolder.getFullPathName(), nullptr); } auto projectDir = fileBrowser.getSelectedFile (0);