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.

273 lines
9.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #ifndef JUCER_NEWPROJECTWIZARD_H_INCLUDED
  18. #define JUCER_NEWPROJECTWIZARD_H_INCLUDED
  19. //==============================================================================
  20. static void createFileCreationOptionComboBox (Component& setupComp,
  21. OwnedArray<Component>& itemsCreated,
  22. const StringArray& fileOptions)
  23. {
  24. ComboBox* c = new ComboBox();
  25. itemsCreated.add (c);
  26. setupComp.addChildAndSetID (c, "filesToCreate");
  27. c->addItemList (fileOptions, 1);
  28. c->setSelectedId (1, dontSendNotification);
  29. Label* l = new Label (String::empty, TRANS("Files to Auto-Generate") + ":");
  30. l->attachToComponent (c, true);
  31. itemsCreated.add (l);
  32. c->setBounds ("parent.width / 2 + 160, 30, parent.width - 30, top + 22");
  33. }
  34. static int getFileCreationComboResult (WizardComp& setupComp)
  35. {
  36. if (ComboBox* cb = dynamic_cast<ComboBox*> (setupComp.findChildWithID ("filesToCreate")))
  37. return cb->getSelectedItemIndex();
  38. jassertfalse;
  39. return 0;
  40. }
  41. static void setExecutableNameForAllTargets (Project& project, const String& exeName)
  42. {
  43. for (Project::ExporterIterator exporter (project); exporter.next();)
  44. for (ProjectExporter::ConfigIterator config (*exporter); config.next();)
  45. config->getTargetBinaryName() = exeName;
  46. }
  47. static Project::Item createSourceGroup (Project& project)
  48. {
  49. return project.getMainGroup().addNewSubGroup ("Source", 0);
  50. }
  51. static File& getLastWizardFolder()
  52. {
  53. #if JUCE_WINDOWS
  54. static File lastFolder (File::getSpecialLocation (File::userDocumentsDirectory));
  55. #else
  56. static File lastFolder (File::getSpecialLocation (File::userHomeDirectory));
  57. #endif
  58. return lastFolder;
  59. }
  60. static bool isJuceModulesFolder (const File& f)
  61. {
  62. return f.isDirectory()
  63. && f.getChildFile ("juce_core").isDirectory();
  64. }
  65. static File findDefaultModulesFolder (bool mustContainJuceCoreModule = true)
  66. {
  67. const MainWindowList& windows = IntrojucerApp::getApp().mainWindowList;
  68. for (int i = windows.windows.size(); --i >= 0;)
  69. {
  70. if (Project* p = windows.windows.getUnchecked (i)->getProject())
  71. {
  72. const File f (EnabledModuleList::findDefaultModulesFolder (*p));
  73. if (isJuceModulesFolder (f) || (f.isDirectory() && ! mustContainJuceCoreModule))
  74. return f;
  75. }
  76. }
  77. if (mustContainJuceCoreModule)
  78. return findDefaultModulesFolder (false);
  79. return File::nonexistent;
  80. }
  81. //==============================================================================
  82. struct NewProjectWizard
  83. {
  84. NewProjectWizard() {}
  85. virtual ~NewProjectWizard() {}
  86. //==============================================================================
  87. virtual String getName() const = 0;
  88. virtual String getDescription() const = 0;
  89. virtual const char* getIcon() const = 0;
  90. virtual void addSetupItems (Component&, OwnedArray<Component>&) {}
  91. virtual Result processResultsFromSetupItems (WizardComp&) { return Result::ok(); }
  92. virtual bool initialiseProject (Project& project) = 0;
  93. virtual StringArray getDefaultModules()
  94. {
  95. static const char* mods[] =
  96. {
  97. "juce_core",
  98. "juce_events",
  99. "juce_graphics",
  100. "juce_data_structures",
  101. "juce_gui_basics",
  102. "juce_gui_extra",
  103. "juce_cryptography",
  104. "juce_video",
  105. "juce_opengl",
  106. "juce_audio_basics",
  107. "juce_audio_devices",
  108. "juce_audio_formats",
  109. "juce_audio_processors",
  110. nullptr
  111. };
  112. return StringArray (mods);
  113. }
  114. String appTitle;
  115. File targetFolder, projectFile, modulesFolder;
  116. WizardComp* ownerWizardComp;
  117. StringArray failedFiles;
  118. //==============================================================================
  119. Project* runWizard (WizardComp& wc,
  120. const String& projectName,
  121. const File& target)
  122. {
  123. ownerWizardComp = &wc;
  124. appTitle = projectName;
  125. targetFolder = target;
  126. if (! targetFolder.exists())
  127. {
  128. if (! targetFolder.createDirectory())
  129. failedFiles.add (targetFolder.getFullPathName());
  130. }
  131. else if (FileHelpers::containsAnyNonHiddenFiles (targetFolder))
  132. {
  133. if (! AlertWindow::showOkCancelBox (AlertWindow::InfoIcon,
  134. TRANS("New Juce Project"),
  135. TRANS("The folder you chose isn't empty - are you sure you want to create the project there?")
  136. + "\n\n"
  137. + TRANS("Any existing files with the same names may be overwritten by the new files.")))
  138. return nullptr;
  139. }
  140. projectFile = targetFolder.getChildFile (File::createLegalFileName (appTitle))
  141. .withFileExtension (Project::projectFileExtension);
  142. ScopedPointer<Project> project (new Project (projectFile));
  143. if (failedFiles.size() == 0)
  144. {
  145. project->setFile (projectFile);
  146. project->setTitle (appTitle);
  147. project->getBundleIdentifier() = project->getDefaultBundleIdentifier();
  148. if (! initialiseProject (*project))
  149. return nullptr;
  150. addExporters (*project, wc);
  151. addDefaultModules (*project, false);
  152. if (project->save (false, true) != FileBasedDocument::savedOk)
  153. return nullptr;
  154. project->setChangedFlag (false);
  155. }
  156. if (failedFiles.size() > 0)
  157. {
  158. AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
  159. TRANS("Errors in Creating Project!"),
  160. TRANS("The following files couldn't be written:")
  161. + "\n\n"
  162. + failedFiles.joinIntoString ("\n", 0, 10));
  163. return nullptr;
  164. }
  165. return project.release();
  166. }
  167. bool selectJuceFolder()
  168. {
  169. for (;;)
  170. {
  171. FileChooser fc ("Select your JUCE modules folder...",
  172. findDefaultModulesFolder(),
  173. "*");
  174. if (! fc.browseForDirectory())
  175. return false;
  176. if (isJuceModulesFolder (fc.getResult()))
  177. {
  178. modulesFolder = fc.getResult();
  179. return true;
  180. }
  181. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  182. "Not a valid JUCE modules folder!",
  183. "Please select the folder containing your juce_* modules!\n\n"
  184. "This is required so that the new project can be given some essential core modules.");
  185. }
  186. }
  187. //==============================================================================
  188. File getSourceFilesFolder() const
  189. {
  190. return projectFile.getSiblingFile ("Source");
  191. }
  192. void createSourceFolder()
  193. {
  194. if (! getSourceFilesFolder().createDirectory())
  195. failedFiles.add (getSourceFilesFolder().getFullPathName());
  196. }
  197. void addDefaultModules (Project& project, bool areModulesCopiedLocally)
  198. {
  199. StringArray mods (getDefaultModules());
  200. ModuleList list;
  201. list.addAllModulesInFolder (modulesFolder);
  202. for (int i = 0; i < mods.size(); ++i)
  203. if (const ModuleDescription* info = list.getModuleWithID (mods[i]))
  204. project.getModules().addModule (info->manifestFile, areModulesCopiedLocally);
  205. }
  206. void addExporters (Project& project, WizardComp& wizardComp)
  207. {
  208. StringArray types (wizardComp.platformTargets.getSelectedPlatforms());
  209. for (int i = 0; i < types.size(); ++i)
  210. project.addNewExporter (types[i]);
  211. if (project.getNumExporters() == 0)
  212. project.createExporterForCurrentPlatform();
  213. }
  214. };
  215. #endif // JUCER_NEWPROJECTWIZARD_H_INCLUDED