The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
19KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. #include "jucer_ProjectType.h"
  21. class ProjectExporter;
  22. class LibraryModule;
  23. class EnabledModuleList;
  24. //==============================================================================
  25. class Project : public FileBasedDocument,
  26. public ValueTree::Listener
  27. {
  28. public:
  29. //==============================================================================
  30. Project (const File&);
  31. ~Project();
  32. //==============================================================================
  33. // FileBasedDocument stuff..
  34. String getDocumentTitle() override;
  35. Result loadDocument (const File& file) override;
  36. Result saveDocument (const File& file) override;
  37. Result saveProject (const File& file, bool isCommandLineApp);
  38. Result saveResourcesOnly (const File& file);
  39. File getLastDocumentOpened() override;
  40. void setLastDocumentOpened (const File& file) override;
  41. void setTitle (const String& newTitle);
  42. //==============================================================================
  43. File getProjectFolder() const { return getFile().getParentDirectory(); }
  44. File getGeneratedCodeFolder() const { return getFile().getSiblingFile ("JuceLibraryCode"); }
  45. File getSourceFilesFolder() const { return getProjectFolder().getChildFile ("Source"); }
  46. File getLocalModulesFolder() const { return getGeneratedCodeFolder().getChildFile ("modules"); }
  47. File getLocalModuleFolder (const String& moduleID) const { return getLocalModulesFolder().getChildFile (moduleID); }
  48. File getAppIncludeFile() const { return getGeneratedCodeFolder().getChildFile (getJuceSourceHFilename()); }
  49. File getBinaryDataCppFile (int index) const;
  50. File getBinaryDataHeaderFile() const { return getBinaryDataCppFile (0).withFileExtension (".h"); }
  51. String getAppConfigFilename() const { return "AppConfig.h"; }
  52. String getJuceSourceFilenameRoot() const { return "JuceLibraryCode"; }
  53. String getJuceSourceHFilename() const { return "JuceHeader.h"; }
  54. //==============================================================================
  55. template <class FileType>
  56. bool shouldBeAddedToBinaryResourcesByDefault (const FileType& file)
  57. {
  58. return ! file.hasFileExtension (sourceOrHeaderFileExtensions);
  59. }
  60. File resolveFilename (String filename) const;
  61. String getRelativePathForFile (const File& file) const;
  62. //==============================================================================
  63. // Creates editors for the project settings
  64. void createPropertyEditors (PropertyListBuilder&);
  65. //==============================================================================
  66. ValueTree getProjectRoot() const { return projectRoot; }
  67. Value getProjectValue (const Identifier& name) { return projectRoot.getPropertyAsValue (name, getUndoManagerFor (projectRoot)); }
  68. var getProjectVar (const Identifier& name) const { return projectRoot.getProperty (name); }
  69. const ProjectType& getProjectType() const;
  70. String getProjectTypeString() const { return projectTypeValue.get(); }
  71. void setProjectType (const String& newProjectType) { projectTypeValue = newProjectType; }
  72. String getProjectNameString() const { return projectNameValue.get(); }
  73. String getProjectFilenameRootString() { return File::createLegalFileName (getDocumentTitle()); }
  74. String getProjectUIDString() const { return projectUIDValue.get(); }
  75. String getVersionString() const { return versionValue.get(); }
  76. String getVersionAsHex() const;
  77. int getVersionAsHexInteger() const;
  78. void setProjectVersion (const String& newVersion) { versionValue = newVersion; }
  79. String getBundleIdentifierString() const { return bundleIdentifierValue.get(); }
  80. String getDefaultBundleIdentifierString() { return "com.yourcompany." + CodeHelpers::makeValidIdentifier (getProjectNameString(), false, true, false); }
  81. String getDefaultAAXIdentifierString() { return getDefaultBundleIdentifierString(); }
  82. String getCompanyNameString() const { return companyNameValue.get(); }
  83. String getCompanyCopyrightString() const { return companyCopyrightValue.get(); }
  84. String getCompanyWebsiteString() const { return companyWebsiteValue.get(); }
  85. String getCompanyEmailString() const { return companyEmailValue.get(); }
  86. String getHeaderSearchPathsString() const { return headerSearchPathsValue.get(); }
  87. StringPairArray getPreprocessorDefs() const;
  88. int getMaxBinaryFileSize() const { return maxBinaryFileSizeValue.get(); }
  89. bool shouldIncludeBinaryInAppConfig() const { return includeBinaryDataInAppConfigValue.get(); }
  90. String getBinaryDataNamespaceString() const { return binaryDataNamespaceValue.get(); }
  91. bool shouldDisplaySplashScreen() const { return displaySplashScreenValue.get(); }
  92. bool shouldReportAppUsage() const { return reportAppUsageValue.get(); }
  93. String getSplashScreenColourString() const { return splashScreenColourValue.get(); }
  94. String getCppStandardString() const { return cppStandardValue.get(); }
  95. //==============================================================================
  96. bool shouldBuildVST() const { return buildVSTValue.get(); }
  97. bool shouldBuildVST3() const { return buildVST3Value.get(); }
  98. bool shouldBuildAU() const { return buildAUValue.get(); }
  99. bool shouldBuildAUv3() const { return buildAUv3Value.get(); }
  100. bool shouldBuildRTAS() const { return buildRTASValue.get(); }
  101. bool shouldBuildAAX() const { return buildAAXValue.get(); }
  102. bool shouldBuildStandalonePlugin() const { return buildStandaloneValue.get(); }
  103. bool shouldEnableIAA() const { return enableIAAValue.get(); }
  104. //==============================================================================
  105. String getPluginNameString() const { return pluginNameValue.get(); }
  106. String getPluginDescriptionString() const { return pluginDescriptionValue.get();}
  107. String getPluginManufacturerString() const { return pluginManufacturerValue.get(); }
  108. String getPluginManufacturerCodeString() const { return pluginManufacturerCodeValue.get(); }
  109. String getPluginCodeString() const { return pluginCodeValue.get(); }
  110. String getPluginChannelConfigsString() const { return pluginChannelConfigsValue.get(); }
  111. String getPluginAUExportPrefixString() const { return pluginAUExportPrefixValue.get(); }
  112. String getPluginAUMainTypeString() const { return pluginAUMainTypeValue.get(); }
  113. String getPluginRTASCategoryString() const { return pluginRTASCategoryValue.get(); }
  114. String getAAXIdentifierString() const { return pluginAAXIdentifierValue.get(); }
  115. String getPluginAAXCategoryString() const { return pluginAAXCategoryValue.get(); }
  116. bool isPluginSynth() const { return pluginIsSynthValue.get(); }
  117. bool pluginWantsMidiInput() const { return pluginWantsMidiInputValue.get(); }
  118. bool pluginProducesMidiOutput() const { return pluginProducesMidiOutValue.get(); }
  119. bool isPluginMidiEffect() const { return pluginIsMidiEffectPluginValue.get(); }
  120. bool pluginEditorNeedsKeyFocus() const { return pluginEditorNeedsKeyFocusValue.get(); }
  121. bool isPluginRTASBypassDisabled() const { return pluginRTASBypassDisabledValue.get(); }
  122. bool isPluginRTASMultiMonoDisabled() const { return pluginRTASMultiMonoDisabledValue.get(); }
  123. bool isPluginAAXBypassDisabled() const { return pluginAAXBypassDisabledValue.get(); }
  124. bool isPluginAAXMultiMonoDisabled() const { return pluginAAXMultiMonoDisabledValue.get(); }
  125. String getPluginRTASCategoryCode();
  126. String getAUMainTypeString();
  127. String getAUMainTypeCode();
  128. String getIAATypeCode();
  129. String getIAAPluginName();
  130. String getPluginVSTCategoryString();
  131. bool isAUPluginHost();
  132. bool isVSTPluginHost();
  133. bool isVST3PluginHost();
  134. //==============================================================================
  135. bool shouldBuildTargetType (ProjectType::Target::Type targetType) const noexcept;
  136. static ProjectType::Target::Type getTargetTypeFromFilePath (const File& file, bool returnSharedTargetIfNoValidSuffix);
  137. //==============================================================================
  138. void updateDeprecatedProjectSettingsInteractively();
  139. //==============================================================================
  140. class Item
  141. {
  142. public:
  143. //==============================================================================
  144. Item (Project& project, const ValueTree& itemNode, bool isModuleCode);
  145. Item (const Item& other);
  146. static Item createGroup (Project& project, const String& name, const String& uid, bool isModuleCode);
  147. void initialiseMissingProperties();
  148. //==============================================================================
  149. bool isValid() const { return state.isValid(); }
  150. bool operator== (const Item& other) const { return state == other.state && &project == &other.project; }
  151. bool operator!= (const Item& other) const { return ! operator== (other); }
  152. //==============================================================================
  153. bool isFile() const;
  154. bool isGroup() const;
  155. bool isMainGroup() const;
  156. bool isImageFile() const;
  157. String getID() const;
  158. void setID (const String& newID);
  159. Item findItemWithID (const String& targetId) const; // (recursive search)
  160. String getImageFileID() const;
  161. Drawable* loadAsImageFile() const;
  162. //==============================================================================
  163. Value getNameValue();
  164. String getName() const;
  165. File getFile() const;
  166. String getFilePath() const;
  167. void setFile (const File& file);
  168. void setFile (const RelativePath& file);
  169. File determineGroupFolder() const;
  170. bool renameFile (const File& newFile);
  171. bool shouldBeAddedToTargetProject() const;
  172. bool shouldBeCompiled() const;
  173. Value getShouldCompileValue();
  174. bool shouldBeAddedToBinaryResources() const;
  175. Value getShouldAddToBinaryResourcesValue();
  176. bool shouldBeAddedToXcodeResources() const;
  177. Value getShouldAddToXcodeResourcesValue();
  178. Value getShouldInhibitWarningsValue();
  179. bool shouldInhibitWarnings() const;
  180. bool isModuleCode() const;
  181. //==============================================================================
  182. bool canContain (const Item& child) const;
  183. int getNumChildren() const { return state.getNumChildren(); }
  184. Item getChild (int index) const { return Item (project, state.getChild (index), belongsToModule); }
  185. Item addNewSubGroup (const String& name, int insertIndex);
  186. Item getOrCreateSubGroup (const String& name);
  187. void addChild (const Item& newChild, int insertIndex);
  188. bool addFileAtIndex (const File& file, int insertIndex, bool shouldCompile);
  189. bool addFileRetainingSortOrder (const File& file, bool shouldCompile);
  190. void addFileUnchecked (const File& file, int insertIndex, bool shouldCompile);
  191. bool addRelativeFile (const RelativePath& file, int insertIndex, bool shouldCompile);
  192. void removeItemFromProject();
  193. void sortAlphabetically (bool keepGroupsAtStart, bool recursive);
  194. Item findItemForFile (const File& file) const;
  195. bool containsChildForFile (const RelativePath& file) const;
  196. Item getParent() const;
  197. Item createCopy();
  198. UndoManager* getUndoManager() const { return project.getUndoManagerFor (state); }
  199. Icon getIcon (bool isOpen = false) const;
  200. bool isIconCrossedOut() const;
  201. Project& project;
  202. ValueTree state;
  203. private:
  204. Item& operator= (const Item&);
  205. bool belongsToModule;
  206. };
  207. Item getMainGroup();
  208. void findAllImageItems (OwnedArray<Item>& items);
  209. //==============================================================================
  210. ValueTree getExporters();
  211. int getNumExporters();
  212. ProjectExporter* createExporter (int index);
  213. void addNewExporter (const String& exporterName);
  214. void createExporterForCurrentPlatform();
  215. struct ExporterIterator
  216. {
  217. ExporterIterator (Project& project);
  218. ~ExporterIterator();
  219. bool next();
  220. ProjectExporter& operator*() const { return *exporter; }
  221. ProjectExporter* operator->() const { return exporter.get(); }
  222. ScopedPointer<ProjectExporter> exporter;
  223. int index;
  224. private:
  225. Project& project;
  226. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ExporterIterator)
  227. };
  228. //==============================================================================
  229. struct ConfigFlag
  230. {
  231. String symbol, description, sourceModuleID;
  232. ValueWithDefault value;
  233. };
  234. ValueWithDefault getConfigFlag (const String& name);
  235. bool isConfigFlagEnabled (const String& name, bool defaultIsEnabled = false) const;
  236. //==============================================================================
  237. EnabledModuleList& getModules();
  238. //==============================================================================
  239. String getFileTemplate (const String& templateName);
  240. //==============================================================================
  241. PropertiesFile& getStoredProperties() const;
  242. //==============================================================================
  243. void valueTreePropertyChanged (ValueTree&, const Identifier&) override;
  244. void valueTreeChildAdded (ValueTree&, ValueTree&) override;
  245. void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override;
  246. void valueTreeChildOrderChanged (ValueTree&, int, int) override;
  247. void valueTreeParentChanged (ValueTree&) override;
  248. //==============================================================================
  249. UndoManager* getUndoManagerFor (const ValueTree&) const { return nullptr; }
  250. //==============================================================================
  251. static const char* projectFileExtension;
  252. //==============================================================================
  253. bool hasProjectBeenModified();
  254. void updateModificationTime() { modificationTime = getFile().getLastModificationTime(); }
  255. //==============================================================================
  256. String getUniqueTargetFolderSuffixForExporter (const String& exporterName, const String& baseTargetFolder);
  257. //==============================================================================
  258. bool isCurrentlySaving() const noexcept { return isSaving; }
  259. bool shouldWaitAfterSaving = false;
  260. String specifiedExporterToSave = {};
  261. private:
  262. ValueTree projectRoot;
  263. ValueWithDefault projectNameValue, projectUIDValue, projectTypeValue, versionValue, bundleIdentifierValue, companyNameValue, companyCopyrightValue,
  264. companyWebsiteValue, companyEmailValue, displaySplashScreenValue, reportAppUsageValue, splashScreenColourValue, cppStandardValue,
  265. headerSearchPathsValue, preprocessorDefsValue, userNotesValue, maxBinaryFileSizeValue, includeBinaryDataInAppConfigValue, binaryDataNamespaceValue;
  266. ValueWithDefault buildVSTValue, buildVST3Value, buildAUValue, buildAUv3Value, buildRTASValue, buildAAXValue, buildStandaloneValue,
  267. enableIAAValue, pluginNameValue, pluginDescriptionValue, pluginManufacturerValue, pluginManufacturerCodeValue,
  268. pluginCodeValue, pluginChannelConfigsValue, pluginIsSynthValue, pluginWantsMidiInputValue, pluginProducesMidiOutValue,
  269. pluginIsMidiEffectPluginValue, pluginEditorNeedsKeyFocusValue, pluginVSTCategoryValue, pluginAUExportPrefixValue,
  270. pluginAUMainTypeValue, pluginRTASCategoryValue, pluginRTASBypassDisabledValue, pluginRTASMultiMonoDisabledValue,
  271. pluginAAXIdentifierValue, pluginAAXCategoryValue, pluginAAXBypassDisabledValue, pluginAAXMultiMonoDisabledValue;
  272. //==============================================================================
  273. friend class Item;
  274. ScopedPointer<EnabledModuleList> enabledModulesList;
  275. bool isSaving;
  276. Time modificationTime;
  277. //==============================================================================
  278. void intialiseProjectValues();
  279. void initialiseMainGroup();
  280. void initialiseAudioPluginValues();
  281. bool setCppVersionFromOldExporterSettings();
  282. void createAudioPluginPropertyEditors (PropertyListBuilder& props);
  283. //==============================================================================
  284. void updateProjectSettings();
  285. ValueTree getConfigurations() const;
  286. ValueTree getConfigNode();
  287. void updateOldStyleConfigList();
  288. void moveOldPropertyFromProjectToAllExporters (Identifier name);
  289. void removeDefunctExporters();
  290. void updateOldModulePaths();
  291. void warnAboutOldProjucerVersion();
  292. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Project)
  293. };