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.

321 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-10 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "jucer_ProjectContentComponent.h"
  19. #include "../jucer_MainWindow.h"
  20. #include "../Code Editor/jucer_SourceCodeEditor.h"
  21. #include "../Drawable Editor/jucer_DrawableEditor.h"
  22. #include "jucer_ProjectInformationComponent.h"
  23. #include "jucer_TreeViewTypes.h"
  24. #include "../../model/Project/jucer_ProjectExporter.h"
  25. //==============================================================================
  26. ProjectContentComponent::ProjectContentComponent()
  27. : projectTree (0), project (0),
  28. currentDocument (0), resizerBar (0)
  29. {
  30. setItemLayout (0, 100, 500, 300);
  31. setItemLayout (1, 4, 4, 4);
  32. setItemLayout (2, 100, 10000, 800);
  33. setOpaque (true);
  34. setWantsKeyboardFocus (true);
  35. }
  36. ProjectContentComponent::~ProjectContentComponent()
  37. {
  38. setProject (0);
  39. contentView = 0;
  40. deleteAllChildren();
  41. }
  42. void ProjectContentComponent::paint (Graphics& g)
  43. {
  44. g.fillAll (Colour::greyLevel (0.4f));
  45. }
  46. void ProjectContentComponent::hasBeenMoved()
  47. {
  48. resized();
  49. }
  50. void ProjectContentComponent::resized()
  51. {
  52. Component* comps[] = { projectTree, resizerBar, contentView };
  53. layOutComponents (comps, 3, 0, 0, getWidth(), getHeight(), false, true);
  54. }
  55. void ProjectContentComponent::setProject (Project* newProject)
  56. {
  57. if (project != newProject)
  58. {
  59. if (project != 0)
  60. project->removeChangeListener (this);
  61. if (projectTree != 0)
  62. projectTree->deleteRootItem();
  63. projectTree = 0;
  64. contentView = 0;
  65. resizerBar = 0;
  66. deleteAllChildren();
  67. project = newProject;
  68. if (project != 0)
  69. {
  70. addAndMakeVisible (projectTree = new TreeView());
  71. projectTree->setRootItemVisible (true);
  72. projectTree->setMultiSelectEnabled (true);
  73. projectTree->setDefaultOpenness (true);
  74. projectTree->setColour (TreeView::backgroundColourId, Colour::greyLevel (0.93f));
  75. projectTree->setIndentSize (14);
  76. addAndMakeVisible (resizerBar = new StretchableLayoutResizerBar (this, 1, true));
  77. resized();
  78. projectTree->setRootItem (new GroupTreeViewItem (project->getMainGroup()));
  79. projectTree->getRootItem()->setOpen (true);
  80. project->addChangeListener (this);
  81. if (currentDocument == 0)
  82. commandManager->invoke (CommandIDs::showProjectSettings, true);
  83. updateMissingFileStatuses();
  84. }
  85. }
  86. }
  87. void ProjectContentComponent::changeListenerCallback (void*)
  88. {
  89. updateMissingFileStatuses();
  90. }
  91. void ProjectContentComponent::updateMissingFileStatuses()
  92. {
  93. if (projectTree != 0)
  94. {
  95. ProjectTreeViewBase* p = dynamic_cast <ProjectTreeViewBase*> (projectTree->getRootItem());
  96. if (p != 0)
  97. p->checkFileStatus();
  98. }
  99. }
  100. bool ProjectContentComponent::showEditorForFile (const File& f)
  101. {
  102. return showDocument (OpenDocumentManager::getInstance()
  103. ->getDocumentForFile (project, f));
  104. }
  105. bool ProjectContentComponent::showDocument (OpenDocumentManager::Document* doc)
  106. {
  107. if (doc == 0)
  108. return false;
  109. OpenDocumentManager::getInstance()->moveDocumentToTopOfStack (doc);
  110. if (doc->hasFileBeenModifiedExternally())
  111. doc->reloadFromFile();
  112. return setEditorComponent (doc->createEditor(), doc);
  113. }
  114. void ProjectContentComponent::hideDocument (OpenDocumentManager::Document* doc)
  115. {
  116. if (doc == currentDocument)
  117. {
  118. currentDocument = 0;
  119. contentView = 0;
  120. updateMainWindowTitle();
  121. commandManager->commandStatusChanged();
  122. }
  123. }
  124. bool ProjectContentComponent::setEditorComponent (Component* editor, OpenDocumentManager::Document* doc)
  125. {
  126. if (editor != 0)
  127. {
  128. contentView = editor;
  129. currentDocument = doc;
  130. addAndMakeVisible (editor);
  131. resized();
  132. updateMainWindowTitle();
  133. commandManager->commandStatusChanged();
  134. return true;
  135. }
  136. updateMainWindowTitle();
  137. return false;
  138. }
  139. void ProjectContentComponent::updateMainWindowTitle()
  140. {
  141. MainWindow* mw = Component::findParentComponentOfClass ((MainWindow*) 0);
  142. if (mw != 0)
  143. mw->updateTitle (currentDocument != 0 ? currentDocument->getName() : String::empty);
  144. }
  145. ApplicationCommandTarget* ProjectContentComponent::getNextCommandTarget()
  146. {
  147. return findFirstTargetParentComponent();
  148. }
  149. void ProjectContentComponent::getAllCommands (Array <CommandID>& commands)
  150. {
  151. const CommandID ids[] = { CommandIDs::saveProject,
  152. CommandIDs::saveProjectAs,
  153. CommandIDs::closeProject,
  154. CommandIDs::openProjectInIDE,
  155. CommandIDs::showProjectSettings,
  156. StandardApplicationCommandIDs::del};
  157. commands.addArray (ids, numElementsInArray (ids));
  158. }
  159. void ProjectContentComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
  160. {
  161. switch (commandID)
  162. {
  163. case CommandIDs::saveProject:
  164. result.setInfo ("Save Project",
  165. "Saves the current project",
  166. CommandCategories::general, 0);
  167. result.setActive (project != 0);
  168. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0));
  169. break;
  170. case CommandIDs::saveProjectAs:
  171. result.setInfo ("Save Project As...",
  172. "Saves the current project to a different filename",
  173. CommandCategories::general, 0);
  174. result.setActive (project != 0);
  175. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
  176. break;
  177. case CommandIDs::closeProject:
  178. result.setInfo ("Close Project",
  179. "Closes the current project",
  180. CommandCategories::general, 0);
  181. result.setActive (project != 0);
  182. result.defaultKeypresses.add (KeyPress ('w', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
  183. break;
  184. case CommandIDs::openProjectInIDE:
  185. #if JUCE_MAC
  186. result.setInfo ("Save Project and Open in XCode...",
  187. #elif JUCE_WINDOWS
  188. result.setInfo ("Save Project and Open in Visual Studio...",
  189. #else
  190. result.setInfo ("Save Project and Open as a Makefile...",
  191. #endif
  192. "Saves the project and launches it in an external IDE",
  193. CommandCategories::general, 0);
  194. result.setActive (project != 0);
  195. result.defaultKeypresses.add (KeyPress ('l', ModifierKeys::commandModifier, 0));
  196. break;
  197. case CommandIDs::showProjectSettings:
  198. result.setInfo ("Show Project Build Settings",
  199. "Shows the build options for the project",
  200. CommandCategories::general, 0);
  201. result.setActive (project != 0);
  202. result.defaultKeypresses.add (KeyPress ('i', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
  203. break;
  204. case StandardApplicationCommandIDs::del:
  205. result.setInfo ("Delete", String::empty, CommandCategories::general, 0);
  206. result.defaultKeypresses.add (KeyPress (KeyPress::deleteKey, 0, 0));
  207. result.defaultKeypresses.add (KeyPress (KeyPress::backspaceKey, 0, 0));
  208. result.setActive (projectTree != 0);
  209. break;
  210. default:
  211. break;
  212. }
  213. }
  214. bool ProjectContentComponent::isCommandActive (const CommandID commandID)
  215. {
  216. return project != 0;
  217. }
  218. bool ProjectContentComponent::perform (const InvocationInfo& info)
  219. {
  220. switch (info.commandID)
  221. {
  222. case CommandIDs::saveProject:
  223. if (project != 0)
  224. project->save (true, true);
  225. break;
  226. case CommandIDs::saveProjectAs:
  227. if (project != 0)
  228. project->saveAsInteractive (true);
  229. break;
  230. case CommandIDs::closeProject:
  231. if (((MainWindow*) getParentComponent())->closeCurrentProject())
  232. StoredSettings::getInstance()->setLastProject (File::nonexistent);
  233. break;
  234. case CommandIDs::openProjectInIDE:
  235. if (project != 0 && project->save (true, true) == FileBasedDocument::savedOk)
  236. {
  237. ScopedPointer <ProjectExporter> exporter (ProjectExporter::createPlatformDefaultExporter (*project));
  238. exporter->launchProject();
  239. }
  240. break;
  241. case CommandIDs::showProjectSettings:
  242. if (projectTree != 0)
  243. projectTree->getRootItem()->setSelected (true, true);
  244. break;
  245. case StandardApplicationCommandIDs::del:
  246. if (projectTree != 0)
  247. {
  248. ProjectTreeViewBase* p = dynamic_cast <ProjectTreeViewBase*> (projectTree->getRootItem());
  249. if (p != 0)
  250. p->deleteAllSelectedItems();
  251. }
  252. break;
  253. default:
  254. return false;
  255. }
  256. return true;
  257. }