1 /* 2 ============================================================================== 3 4 This file is part of the JUCE library. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 JUCE is an open source library subject to commercial or open-source 8 licensing. 9 10 By using JUCE, you agree to the terms of both the JUCE 6 End-User License 11 Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020). 12 13 End User License Agreement: www.juce.com/juce-6-licence 14 Privacy Policy: www.juce.com/juce-privacy-policy 15 16 Or: You may also use this code under the terms of the GPL v3 (see 17 www.gnu.org/licenses). 18 19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER 20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE 21 DISCLAIMED. 22 23 ============================================================================== 24 */ 25 26 #pragma once 27 28 #include "../Application/UserAccount/jucer_LicenseController.h" 29 #include "Modules/jucer_AvailableModulesList.h" 30 31 class ProjectExporter; 32 class LibraryModule; 33 class EnabledModulesList; 34 class CompileEngineSettings; 35 36 namespace ProjectMessages 37 { 38 namespace Ids 39 { 40 #define DECLARE_ID(name) static const Identifier name (#name) 41 42 DECLARE_ID (projectMessages); 43 44 DECLARE_ID (incompatibleLicense); 45 DECLARE_ID (cppStandard); 46 DECLARE_ID (moduleNotFound); 47 DECLARE_ID (jucePath); 48 DECLARE_ID (jucerFileModified); 49 DECLARE_ID (missingModuleDependencies); 50 DECLARE_ID (oldProjucer); 51 DECLARE_ID (cLion); 52 DECLARE_ID (newVersionAvailable); 53 54 DECLARE_ID (notification); 55 DECLARE_ID (warning); 56 57 DECLARE_ID (isVisible); 58 59 #undef DECLARE_ID 60 } 61 getTypeForMessage(const Identifier & message)62 inline Identifier getTypeForMessage (const Identifier& message) 63 { 64 static Identifier warnings[] = { Ids::incompatibleLicense, Ids::cppStandard, Ids::moduleNotFound, 65 Ids::jucePath, Ids::jucerFileModified, Ids::missingModuleDependencies, 66 Ids::oldProjucer, Ids::cLion }; 67 68 if (std::find (std::begin (warnings), std::end (warnings), message) != std::end (warnings)) 69 return Ids::warning; 70 71 if (message == Ids::newVersionAvailable) 72 return Ids::notification; 73 74 jassertfalse; 75 return {}; 76 } 77 getTitleForMessage(const Identifier & message)78 inline String getTitleForMessage (const Identifier& message) 79 { 80 if (message == Ids::incompatibleLicense) return "Incompatible License and Splash Screen Setting"; 81 if (message == Ids::cppStandard) return "C++ Standard"; 82 if (message == Ids::moduleNotFound) return "Module Not Found"; 83 if (message == Ids::jucePath) return "JUCE Path"; 84 if (message == Ids::jucerFileModified) return "Project File Modified"; 85 if (message == Ids::missingModuleDependencies) return "Missing Module Dependencies"; 86 if (message == Ids::oldProjucer) return "Projucer Out of Date"; 87 if (message == Ids::newVersionAvailable) return "New Version Available"; 88 if (message == Ids::cLion) return "Deprecated Exporter"; 89 90 jassertfalse; 91 return {}; 92 } 93 getDescriptionForMessage(const Identifier & message)94 inline String getDescriptionForMessage (const Identifier& message) 95 { 96 if (message == Ids::incompatibleLicense) return "Save and export is disabled."; 97 if (message == Ids::cppStandard) return "Module(s) have a higher C++ standard requirement than the project."; 98 if (message == Ids::moduleNotFound) return "Module(s) could not be found at the specified paths."; 99 if (message == Ids::jucePath) return "The path to your JUCE folder is incorrect."; 100 if (message == Ids::jucerFileModified) return "The .jucer file has been modified since the last save."; 101 if (message == Ids::missingModuleDependencies) return "Module(s) have missing dependencies."; 102 if (message == Ids::oldProjucer) return "The version of the Projucer you are using is out of date."; 103 if (message == Ids::newVersionAvailable) return "A new version of JUCE is available to download."; 104 if (message == Ids::cLion) return "The CLion exporter is deprecated. Use JUCE's CMake support instead."; 105 106 jassertfalse; 107 return {}; 108 } 109 110 using MessageAction = std::pair<String, std::function<void()>>; 111 } 112 113 //============================================================================== 114 class Project : public FileBasedDocument, 115 private ValueTree::Listener, 116 private LicenseController::LicenseStateListener, 117 private ChangeListener, 118 private AvailableModulesList::Listener 119 { 120 public: 121 //============================================================================== 122 Project (const File&); 123 ~Project() override; 124 125 //============================================================================== 126 String getDocumentTitle() override; 127 Result loadDocument (const File& file) override; 128 Result saveDocument (const File& file) override; 129 130 Result saveProject (ProjectExporter* exporterToSave = nullptr); 131 Result saveResourcesOnly(); 132 Result openProjectInIDE (ProjectExporter& exporterToOpen, bool saveFirst); 133 134 File getLastDocumentOpened() override; 135 void setLastDocumentOpened (const File& file) override; 136 137 void setTitle (const String& newTitle); 138 139 //============================================================================== getProjectFolder()140 File getProjectFolder() const { return getFile().getParentDirectory(); } getGeneratedCodeFolder()141 File getGeneratedCodeFolder() const { return getFile().getSiblingFile ("JuceLibraryCode"); } getSourceFilesFolder()142 File getSourceFilesFolder() const { return getProjectFolder().getChildFile ("Source"); } getLocalModulesFolder()143 File getLocalModulesFolder() const { return getGeneratedCodeFolder().getChildFile ("modules"); } getLocalModuleFolder(const String & moduleID)144 File getLocalModuleFolder (const String& moduleID) const { return getLocalModulesFolder().getChildFile (moduleID); } getAppIncludeFile()145 File getAppIncludeFile() const { return getGeneratedCodeFolder().getChildFile (getJuceSourceHFilename()); } 146 147 File getBinaryDataCppFile (int index) const; getBinaryDataHeaderFile()148 File getBinaryDataHeaderFile() const { return getBinaryDataCppFile (0).withFileExtension (".h"); } 149 getAppConfigFilename()150 static String getAppConfigFilename() { return "AppConfig.h"; } getPluginDefinesFilename()151 static String getPluginDefinesFilename() { return "JucePluginDefines.h"; } getJuceSourceHFilename()152 static String getJuceSourceHFilename() { return "JuceHeader.h"; } 153 154 //============================================================================== 155 template <class FileType> shouldBeAddedToBinaryResourcesByDefault(const FileType & file)156 bool shouldBeAddedToBinaryResourcesByDefault (const FileType& file) 157 { 158 return ! file.hasFileExtension (sourceOrHeaderFileExtensions); 159 } 160 161 File resolveFilename (String filename) const; 162 String getRelativePathForFile (const File& file) const; 163 164 //============================================================================== 165 // Creates editors for the project settings 166 void createPropertyEditors (PropertyListBuilder&); 167 168 //============================================================================== getProjectRoot()169 ValueTree getProjectRoot() const { return projectRoot; } getProjectValue(const Identifier & name)170 Value getProjectValue (const Identifier& name) { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); } getProjectVar(const Identifier & name)171 var getProjectVar (const Identifier& name) const { return projectRoot.getProperty (name); } 172 173 const build_tools::ProjectType& getProjectType() const; getProjectTypeString()174 String getProjectTypeString() const { return projectTypeValue.get(); } setProjectType(const String & newProjectType)175 void setProjectType (const String& newProjectType) { projectTypeValue = newProjectType; } 176 getProjectNameString()177 String getProjectNameString() const { return projectNameValue.get(); } getProjectFilenameRootString()178 String getProjectFilenameRootString() { return File::createLegalFileName (getDocumentTitle()); } getProjectUIDString()179 String getProjectUIDString() const { return projectUIDValue.get(); } 180 getProjectLineFeed()181 String getProjectLineFeed() const { return projectLineFeedValue.get(); } 182 getVersionString()183 String getVersionString() const { return versionValue.get(); } getVersionAsHex()184 String getVersionAsHex() const { return build_tools::getVersionAsHex (getVersionString()); } getVersionAsHexInteger()185 int getVersionAsHexInteger() const { return build_tools::getVersionAsHexInteger (getVersionString()); } setProjectVersion(const String & newVersion)186 void setProjectVersion (const String& newVersion) { versionValue = newVersion; } 187 getBundleIdentifierString()188 String getBundleIdentifierString() const { return bundleIdentifierValue.get(); } 189 String getDefaultBundleIdentifierString() const; getDefaultAAXIdentifierString()190 String getDefaultAAXIdentifierString() const { return getDefaultBundleIdentifierString(); } 191 String getDefaultPluginManufacturerString() const; 192 getCompanyNameString()193 String getCompanyNameString() const { return companyNameValue.get(); } getCompanyCopyrightString()194 String getCompanyCopyrightString() const { return companyCopyrightValue.get(); } getCompanyWebsiteString()195 String getCompanyWebsiteString() const { return companyWebsiteValue.get(); } getCompanyEmailString()196 String getCompanyEmailString() const { return companyEmailValue.get(); } 197 getHeaderSearchPathsString()198 String getHeaderSearchPathsString() const { return headerSearchPathsValue.get(); } 199 getPreprocessorDefs()200 StringPairArray getPreprocessorDefs() const { return parsedPreprocessorDefs; } 201 getMaxBinaryFileSize()202 int getMaxBinaryFileSize() const { return maxBinaryFileSizeValue.get(); } shouldIncludeBinaryInJuceHeader()203 bool shouldIncludeBinaryInJuceHeader() const { return includeBinaryDataInJuceHeaderValue.get(); } getBinaryDataNamespaceString()204 String getBinaryDataNamespaceString() const { return binaryDataNamespaceValue.get(); } 205 shouldDisplaySplashScreen()206 bool shouldDisplaySplashScreen() const { return displaySplashScreenValue.get(); } getSplashScreenColourString()207 String getSplashScreenColourString() const { return splashScreenColourValue.get(); } 208 getCppStandardStrings()209 static StringArray getCppStandardStrings() { return { "C++11", "C++14", "C++17", "Use Latest" }; } getCppStandardVars()210 static Array<var> getCppStandardVars() { return { "11", "14", "17", "latest" }; } 211 getCppStandardString()212 String getCppStandardString() const { return cppStandardValue.get(); } 213 214 StringArray getCompilerFlagSchemes() const; 215 void addCompilerFlagScheme (const String&); 216 void removeCompilerFlagScheme (const String&); 217 getPostExportShellCommandPosixString()218 String getPostExportShellCommandPosixString() const { return postExportShellCommandPosixValue.get(); } getPostExportShellCommandWinString()219 String getPostExportShellCommandWinString() const { return postExportShellCommandWinValue.get(); } 220 shouldUseAppConfig()221 bool shouldUseAppConfig() const { return useAppConfigValue.get(); } shouldAddUsingNamespaceToJuceHeader()222 bool shouldAddUsingNamespaceToJuceHeader() const { return addUsingNamespaceToJuceHeader.get(); } 223 224 //============================================================================== getPluginNameString()225 String getPluginNameString() const { return pluginNameValue.get(); } getPluginDescriptionString()226 String getPluginDescriptionString() const { return pluginDescriptionValue.get();} getPluginManufacturerString()227 String getPluginManufacturerString() const { return pluginManufacturerValue.get(); } getPluginManufacturerCodeString()228 String getPluginManufacturerCodeString() const { return pluginManufacturerCodeValue.get(); } getPluginCodeString()229 String getPluginCodeString() const { return pluginCodeValue.get(); } getPluginChannelConfigsString()230 String getPluginChannelConfigsString() const { return pluginChannelConfigsValue.get(); } getAAXIdentifierString()231 String getAAXIdentifierString() const { return pluginAAXIdentifierValue.get(); } getPluginAUExportPrefixString()232 String getPluginAUExportPrefixString() const { return pluginAUExportPrefixValue.get(); } getVSTNumMIDIInputsString()233 String getVSTNumMIDIInputsString() const { return pluginVSTNumMidiInputsValue.get(); } getVSTNumMIDIOutputsString()234 String getVSTNumMIDIOutputsString() const { return pluginVSTNumMidiOutputsValue.get(); } 235 checkMultiChoiceVar(const ValueWithDefault & valueToCheck,Identifier idToCheck)236 static bool checkMultiChoiceVar (const ValueWithDefault& valueToCheck, Identifier idToCheck) noexcept 237 { 238 if (! valueToCheck.get().isArray()) 239 return false; 240 241 auto v = valueToCheck.get(); 242 243 if (auto* varArray = v.getArray()) 244 return varArray->contains (idToCheck.toString()); 245 246 return false; 247 } 248 isAudioPluginProject()249 bool isAudioPluginProject() const { return getProjectType().isAudioPlugin(); } 250 shouldBuildVST()251 bool shouldBuildVST() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildVST); } shouldBuildVST3()252 bool shouldBuildVST3() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildVST3); } shouldBuildAU()253 bool shouldBuildAU() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildAU); } shouldBuildAUv3()254 bool shouldBuildAUv3() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildAUv3); } shouldBuildRTAS()255 bool shouldBuildRTAS() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildRTAS); } shouldBuildAAX()256 bool shouldBuildAAX() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildAAX); } shouldBuildStandalonePlugin()257 bool shouldBuildStandalonePlugin() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildStandalone); } shouldBuildUnityPlugin()258 bool shouldBuildUnityPlugin() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::buildUnity); } shouldEnableIAA()259 bool shouldEnableIAA() const { return isAudioPluginProject() && checkMultiChoiceVar (pluginFormatsValue, Ids::enableIAA); } 260 isPluginSynth()261 bool isPluginSynth() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginIsSynth); } pluginWantsMidiInput()262 bool pluginWantsMidiInput() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginWantsMidiIn); } pluginProducesMidiOutput()263 bool pluginProducesMidiOutput() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginProducesMidiOut); } isPluginMidiEffect()264 bool isPluginMidiEffect() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginIsMidiEffectPlugin); } pluginEditorNeedsKeyFocus()265 bool pluginEditorNeedsKeyFocus() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginEditorRequiresKeys); } isPluginRTASBypassDisabled()266 bool isPluginRTASBypassDisabled() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginRTASDisableBypass); } isPluginRTASMultiMonoDisabled()267 bool isPluginRTASMultiMonoDisabled() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginRTASDisableMultiMono); } isPluginAAXBypassDisabled()268 bool isPluginAAXBypassDisabled() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginAAXDisableBypass); } isPluginAAXMultiMonoDisabled()269 bool isPluginAAXMultiMonoDisabled() const { return checkMultiChoiceVar (pluginCharacteristicsValue, Ids::pluginAAXDisableMultiMono); } 270 271 static StringArray getAllAUMainTypeStrings() noexcept; 272 static Array<var> getAllAUMainTypeVars() noexcept; 273 Array<var> getDefaultAUMainTypes() const noexcept; 274 275 static StringArray getAllVSTCategoryStrings() noexcept; 276 Array<var> getDefaultVSTCategories() const noexcept; 277 278 static StringArray getAllVST3CategoryStrings() noexcept; 279 Array<var> getDefaultVST3Categories() const noexcept; 280 281 static StringArray getAllAAXCategoryStrings() noexcept; 282 static Array<var> getAllAAXCategoryVars() noexcept; 283 Array<var> getDefaultAAXCategories() const noexcept; 284 285 static StringArray getAllRTASCategoryStrings() noexcept; 286 static Array<var> getAllRTASCategoryVars() noexcept; 287 Array<var> getDefaultRTASCategories() const noexcept; 288 289 String getAUMainTypeString() const noexcept; 290 bool isAUSandBoxSafe() const noexcept; 291 String getVSTCategoryString() const noexcept; 292 String getVST3CategoryString() const noexcept; 293 int getAAXCategory() const noexcept; 294 int getRTASCategory() const noexcept; 295 296 String getIAATypeCode() const; 297 String getIAAPluginName() const; 298 getUnityScriptName()299 String getUnityScriptName() const { return addUnityPluginPrefixIfNecessary (getProjectNameString()) + "_UnityScript.cs"; } addUnityPluginPrefixIfNecessary(const String & name)300 static String addUnityPluginPrefixIfNecessary (const String& name) 301 { 302 if (! name.startsWithIgnoreCase ("audioplugin")) 303 return "audioplugin_" + name; 304 305 return name; 306 } 307 308 //============================================================================== 309 bool isAUPluginHost(); 310 bool isVSTPluginHost(); 311 bool isVST3PluginHost(); 312 313 //============================================================================== 314 bool shouldBuildTargetType (build_tools::ProjectType::Target::Type targetType) const noexcept; 315 static build_tools::ProjectType::Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix); 316 317 //============================================================================== 318 void updateDeprecatedProjectSettingsInteractively(); 319 320 StringPairArray getAppConfigDefs(); 321 StringPairArray getAudioPluginFlags() const; 322 323 //============================================================================== 324 class Item 325 { 326 public: 327 //============================================================================== 328 Item (Project& project, const ValueTree& itemNode, bool isModuleCode); 329 Item (const Item& other); 330 331 static Item createGroup (Project& project, const String& name, const String& uid, bool isModuleCode); 332 void initialiseMissingProperties(); 333 334 //============================================================================== isValid()335 bool isValid() const { return state.isValid(); } 336 bool operator== (const Item& other) const { return state == other.state && &project == &other.project; } 337 bool operator!= (const Item& other) const { return ! operator== (other); } 338 339 //============================================================================== 340 bool isFile() const; 341 bool isGroup() const; 342 bool isMainGroup() const; 343 bool isImageFile() const; 344 bool isSourceFile() const; 345 346 String getID() const; 347 void setID (const String& newID); 348 Item findItemWithID (const String& targetId) const; // (recursive search) 349 350 String getImageFileID() const; 351 std::unique_ptr<Drawable> loadAsImageFile() const; 352 353 //============================================================================== 354 Value getNameValue(); 355 String getName() const; 356 File getFile() const; 357 String getFilePath() const; 358 void setFile (const File& file); 359 void setFile (const build_tools::RelativePath& file); 360 File determineGroupFolder() const; 361 bool renameFile (const File& newFile); 362 363 bool shouldBeAddedToTargetProject() const; 364 bool shouldBeAddedToTargetExporter (const ProjectExporter&) const; 365 bool shouldBeCompiled() const; 366 Value getShouldCompileValue(); 367 368 bool shouldBeAddedToBinaryResources() const; 369 Value getShouldAddToBinaryResourcesValue(); 370 371 bool shouldBeAddedToXcodeResources() const; 372 Value getShouldAddToXcodeResourcesValue(); 373 374 Value getShouldInhibitWarningsValue(); 375 bool shouldInhibitWarnings() const; 376 377 bool isModuleCode() const; 378 379 Value getShouldSkipPCHValue(); 380 bool shouldSkipPCH() const; 381 382 Value getCompilerFlagSchemeValue(); 383 String getCompilerFlagSchemeString() const; 384 385 void setCompilerFlagScheme (const String&); 386 void clearCurrentCompilerFlagScheme(); 387 388 //============================================================================== 389 bool canContain (const Item& child) const; getNumChildren()390 int getNumChildren() const { return state.getNumChildren(); } getChild(int index)391 Item getChild (int index) const { return Item (project, state.getChild (index), belongsToModule); } 392 393 Item addNewSubGroup (const String& name, int insertIndex); 394 Item getOrCreateSubGroup (const String& name); 395 void addChild (const Item& newChild, int insertIndex); 396 bool addFileAtIndex (const File& file, int insertIndex, bool shouldCompile); 397 bool addFileRetainingSortOrder (const File& file, bool shouldCompile); 398 void addFileUnchecked (const File& file, int insertIndex, bool shouldCompile); 399 bool addRelativeFile (const build_tools::RelativePath& file, int insertIndex, bool shouldCompile); 400 void removeItemFromProject(); 401 void sortAlphabetically (bool keepGroupsAtStart, bool recursive); 402 Item findItemForFile (const File& file) const; 403 bool containsChildForFile (const build_tools::RelativePath& file) const; 404 405 Item getParent() const; 406 Item createCopy(); 407 getUndoManager()408 UndoManager* getUndoManager() const { return project.getUndoManagerFor (state); } 409 410 Icon getIcon (bool isOpen = false) const; 411 bool isIconCrossedOut() const; 412 413 bool needsSaving() const noexcept; 414 415 Project& project; 416 ValueTree state; 417 418 private: 419 Item& operator= (const Item&); 420 bool belongsToModule; 421 }; 422 423 Item getMainGroup(); 424 425 void findAllImageItems (OwnedArray<Item>& items); 426 427 //============================================================================== 428 ValueTree getExporters(); 429 int getNumExporters(); 430 std::unique_ptr<ProjectExporter> createExporter (int index); 431 void addNewExporter (const Identifier& exporterIdentifier); 432 void createExporterForCurrentPlatform(); 433 434 struct ExporterIterator 435 { 436 ExporterIterator (Project& project); 437 ~ExporterIterator(); 438 439 bool next(); 440 441 ProjectExporter& operator*() const { return *exporter; } 442 ProjectExporter* operator->() const { return exporter.get(); } 443 444 std::unique_ptr<ProjectExporter> exporter; 445 int index; 446 447 private: 448 Project& project; 449 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExporterIterator) 450 }; 451 452 //============================================================================== 453 struct ConfigFlag 454 { 455 String symbol, description, sourceModuleID; 456 ValueWithDefault value; 457 }; 458 459 ValueWithDefault getConfigFlag (const String& name); 460 bool isConfigFlagEnabled (const String& name, bool defaultIsEnabled = false) const; 461 462 //============================================================================== 463 EnabledModulesList& getEnabledModules(); 464 getExporterPathsModulesList()465 AvailableModulesList& getExporterPathsModulesList() { return exporterPathsModulesList; } 466 void rescanExporterPathModules (bool async = false); 467 468 std::pair<String, File> getModuleWithID (const String&); 469 470 //============================================================================== 471 PropertiesFile& getStoredProperties() const; 472 473 //============================================================================== getUndoManagerFor(const ValueTree &)474 UndoManager* getUndoManagerFor (const ValueTree&) const { return nullptr; } getUndoManager()475 UndoManager* getUndoManager() const { return nullptr; } 476 477 //============================================================================== 478 static const char* projectFileExtension; 479 480 //============================================================================== 481 bool updateCachedFileState(); getCachedFileStateContent()482 String getCachedFileStateContent() const noexcept { return cachedFileState.second; } 483 484 String serialiseProjectXml (std::unique_ptr<XmlElement>) const; 485 486 //============================================================================== 487 String getUniqueTargetFolderSuffixForExporter (const Identifier& exporterIdentifier, const String& baseTargetFolder); 488 489 //============================================================================== isCurrentlySaving()490 bool isCurrentlySaving() const noexcept { return isSaving; } 491 isTemporaryProject()492 bool isTemporaryProject() const noexcept { return tempDirectory != File(); } getTemporaryDirectory()493 File getTemporaryDirectory() const noexcept { return tempDirectory; } 494 void setTemporaryDirectory (const File&) noexcept; 495 496 //============================================================================== getCompileEngineSettings()497 CompileEngineSettings& getCompileEngineSettings() { return *compileEngineSettings; } 498 499 //============================================================================== getProjectMessages()500 ValueTree getProjectMessages() const { return projectMessages; } 501 502 void addProjectMessage (const Identifier& messageToAdd, std::vector<ProjectMessages::MessageAction>&& messageActions); 503 void removeProjectMessage (const Identifier& messageToRemove); 504 505 std::vector<ProjectMessages::MessageAction> getMessageActions (const Identifier& message); 506 507 //============================================================================== 508 bool hasIncompatibleLicenseTypeAndSplashScreenSetting() const; 509 bool isFileModificationCheckPending() const; 510 bool isSaveAndExportDisabled() const; 511 512 private: 513 //============================================================================== 514 void valueTreePropertyChanged (ValueTree&, const Identifier&) override; 515 void valueTreeChildAdded (ValueTree&, ValueTree&) override; 516 void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override; 517 void valueTreeChildOrderChanged (ValueTree&, int, int) override; 518 519 //============================================================================== 520 struct ProjectFileModificationPoller : private Timer 521 { 522 ProjectFileModificationPoller (Project& p); isCheckPendingProjectFileModificationPoller523 bool isCheckPending() const noexcept { return pending; } 524 525 private: 526 void timerCallback() override; 527 void reset(); 528 529 void resaveProject(); 530 void reloadProjectFromDisk(); 531 532 Project& project; 533 bool pending = false; 534 }; 535 536 //============================================================================== 537 ValueTree projectRoot { Ids::JUCERPROJECT }; 538 539 ValueWithDefault projectNameValue, projectUIDValue, projectLineFeedValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, 540 companyCopyrightValue, companyWebsiteValue, companyEmailValue, displaySplashScreenValue, splashScreenColourValue, cppStandardValue, 541 headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInJuceHeaderValue, binaryDataNamespaceValue, 542 compilerFlagSchemesValue, postExportShellCommandPosixValue, postExportShellCommandWinValue, useAppConfigValue, addUsingNamespaceToJuceHeader; 543 544 ValueWithDefault pluginFormatsValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue, 545 pluginCodeValue, pluginChannelConfigsValue, pluginCharacteristicsValue, pluginAUExportPrefixValue, pluginAAXIdentifierValue, 546 pluginAUMainTypeValue, pluginAUSandboxSafeValue, pluginRTASCategoryValue, pluginVSTCategoryValue, pluginVST3CategoryValue, pluginAAXCategoryValue, 547 pluginVSTNumMidiInputsValue, pluginVSTNumMidiOutputsValue; 548 549 //============================================================================== 550 std::unique_ptr<CompileEngineSettings> compileEngineSettings; 551 std::unique_ptr<EnabledModulesList> enabledModulesList; 552 553 AvailableModulesList exporterPathsModulesList; 554 555 //============================================================================== 556 void updateDeprecatedProjectSettings(); 557 558 //============================================================================== 559 bool shouldWriteLegacyPluginFormatSettings = false; 560 bool shouldWriteLegacyPluginCharacteristicsSettings = false; 561 562 static Array<Identifier> getLegacyPluginFormatIdentifiers() noexcept; 563 static Array<Identifier> getLegacyPluginCharacteristicsIdentifiers() noexcept; 564 565 void writeLegacyPluginFormatSettings(); 566 void writeLegacyPluginCharacteristicsSettings(); 567 568 void coalescePluginFormatValues(); 569 void coalescePluginCharacteristicsValues(); 570 void updatePluginCategories(); 571 572 //============================================================================== 573 File tempDirectory; 574 std::pair<Time, String> cachedFileState; 575 576 void saveAndMoveTemporaryProject (bool openInIDE); 577 578 //============================================================================== 579 friend class Item; 580 bool isSaving = false; 581 StringPairArray parsedPreprocessorDefs; 582 583 //============================================================================== 584 void initialiseProjectValues(); 585 void initialiseMainGroup(); 586 void initialiseAudioPluginValues(); 587 588 bool setCppVersionFromOldExporterSettings(); 589 590 void createAudioPluginPropertyEditors (PropertyListBuilder& props); 591 592 //============================================================================== 593 void updateTitleDependencies(); 594 void updateCompanyNameDependencies(); 595 void updateProjectSettings(); 596 ValueTree getConfigurations() const; 597 ValueTree getConfigNode(); 598 599 void updateOldStyleConfigList(); 600 void moveOldPropertyFromProjectToAllExporters (Identifier name); 601 void removeDefunctExporters(); 602 void updateOldModulePaths(); 603 604 //============================================================================== 605 void licenseStateChanged() override; 606 void changeListenerCallback (ChangeBroadcaster*) override; 607 void availableModulesChanged (AvailableModulesList*) override; 608 609 void updateLicenseWarning(); 610 void updateJUCEPathWarning(); 611 612 void updateModuleWarnings(); 613 void updateExporterWarnings(); 614 void updateCppStandardWarning (bool showWarning); 615 void updateMissingModuleDependenciesWarning (bool showWarning); 616 void updateOldProjucerWarning (bool showWarning); 617 void updateCLionWarning (bool showWarning); 618 void updateModuleNotFoundWarning (bool showWarning); 619 620 ValueTree projectMessages { ProjectMessages::Ids::projectMessages, {}, 621 { { ProjectMessages::Ids::notification, {} }, { ProjectMessages::Ids::warning, {} } } }; 622 std::map<Identifier, std::vector<ProjectMessages::MessageAction>> messageActions; 623 624 ProjectFileModificationPoller fileModificationPoller { *this }; 625 626 //============================================================================== 627 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Project) 628 }; 629