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.

277 lines
8.1KB

  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_Headers.h"
  19. #include "jucer_Application.h"
  20. #include "jucer_MainWindow.h"
  21. #include "jucer_OpenDocumentManager.h"
  22. #include "../Code Editor/jucer_SourceCodeEditor.h"
  23. #include "../Project/jucer_NewProjectWizard.h"
  24. ApplicationCommandManager* commandManager = 0;
  25. //==============================================================================
  26. MainWindow::MainWindow()
  27. : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(),
  28. Colour::greyLevel (0.6f),
  29. DocumentWindow::allButtons)
  30. {
  31. setUsingNativeTitleBar (true);
  32. setContentOwned (new ProjectContentComponent(), false);
  33. #if ! JUCE_MAC
  34. JucerApplication* app = static_cast<JucerApplication*> (JUCEApplication::getInstance());
  35. setMenuBar (app->menuModel);
  36. #endif
  37. setResizable (true, false);
  38. centreWithSize (700, 600);
  39. // Register all the app commands..
  40. {
  41. commandManager->registerAllCommandsForTarget (this);
  42. // use a temporary one of these to harvest its commands..
  43. ProjectContentComponent pcc;
  44. commandManager->registerAllCommandsForTarget (&pcc);
  45. DocumentEditorComponent dec (0);
  46. commandManager->registerAllCommandsForTarget (&dec);
  47. }
  48. commandManager->getKeyMappings()->resetToDefaultMappings();
  49. ScopedPointer <XmlElement> keys (StoredSettings::getInstance()->getProps().getXmlValue ("keyMappings"));
  50. if (keys != 0)
  51. commandManager->getKeyMappings()->restoreFromXml (*keys);
  52. addKeyListener (commandManager->getKeyMappings());
  53. // don't want the window to take focus when the title-bar is clicked..
  54. setWantsKeyboardFocus (false);
  55. //getPeer()->setCurrentRenderingEngine (0);
  56. getLookAndFeel().setColour (ColourSelector::backgroundColourId, Colours::transparentBlack);
  57. }
  58. MainWindow::~MainWindow()
  59. {
  60. #if ! JUCE_MAC
  61. setMenuBar (0);
  62. #endif
  63. removeKeyListener (commandManager->getKeyMappings());
  64. // save the current size and position to our settings file..
  65. StoredSettings::getInstance()->getProps()
  66. .setValue ("lastMainWindowPos", getWindowStateAsString());
  67. clearContentComponent();
  68. currentProject = 0;
  69. }
  70. ProjectContentComponent* MainWindow::getProjectContentComponent() const
  71. {
  72. return dynamic_cast <ProjectContentComponent*> (getContentComponent());
  73. }
  74. void MainWindow::closeButtonPressed()
  75. {
  76. if (! closeCurrentProject())
  77. return;
  78. JucerApplication* jucer = static_cast<JucerApplication*> (JUCEApplication::getInstance());
  79. jucer->closeWindow (this);
  80. }
  81. bool MainWindow::closeProject (Project* project)
  82. {
  83. jassert (project == currentProject && project != 0);
  84. if (project == 0)
  85. return true;
  86. StoredSettings::getInstance()->getProps()
  87. .setValue (getProjectWindowPosName(), getWindowStateAsString());
  88. if (! OpenDocumentManager::getInstance()->closeAllDocumentsUsingProject (*project, true))
  89. return false;
  90. FileBasedDocument::SaveResult r = project->saveIfNeededAndUserAgrees();
  91. if (r == FileBasedDocument::savedOk)
  92. {
  93. setProject (0);
  94. return true;
  95. }
  96. return false;
  97. }
  98. bool MainWindow::closeCurrentProject()
  99. {
  100. return currentProject == 0 || closeProject (currentProject);
  101. }
  102. void MainWindow::setProject (Project* newProject)
  103. {
  104. getProjectContentComponent()->setProject (newProject);
  105. currentProject = newProject;
  106. commandManager->commandStatusChanged();
  107. // (mustn't do this when the project is 0, because that'll happen on shutdown,
  108. // which will erase the list of recent projects)
  109. if (newProject != 0)
  110. static_cast<JucerApplication*> (JUCEApplication::getInstance())->updateRecentProjectList();
  111. }
  112. void MainWindow::restoreWindowPosition()
  113. {
  114. String windowState;
  115. if (currentProject != 0)
  116. windowState = StoredSettings::getInstance()->getProps().getValue (getProjectWindowPosName());
  117. if (windowState.isEmpty())
  118. windowState = StoredSettings::getInstance()->getProps().getValue ("lastMainWindowPos");
  119. restoreWindowStateFromString (windowState);
  120. }
  121. bool MainWindow::canOpenFile (const File& file) const
  122. {
  123. return file.hasFileExtension (Project::projectFileExtension)
  124. || OpenDocumentManager::getInstance()->canOpenFile (file);
  125. }
  126. bool MainWindow::openFile (const File& file)
  127. {
  128. if (file.hasFileExtension (Project::projectFileExtension))
  129. {
  130. ScopedPointer <Project> newDoc (new Project (file));
  131. if (file == File::nonexistent ? newDoc->loadFromUserSpecifiedFile (true)
  132. : newDoc->loadFrom (file, true))
  133. {
  134. if (closeCurrentProject())
  135. {
  136. setProject (newDoc.release());
  137. return true;
  138. }
  139. }
  140. }
  141. else if (file.exists())
  142. {
  143. return getProjectContentComponent()->showEditorForFile (file);
  144. }
  145. return false;
  146. }
  147. bool MainWindow::isInterestedInFileDrag (const StringArray& filenames)
  148. {
  149. for (int i = filenames.size(); --i >= 0;)
  150. if (canOpenFile (filenames[i]))
  151. return true;
  152. return false;
  153. }
  154. void MainWindow::filesDropped (const StringArray& filenames, int mouseX, int mouseY)
  155. {
  156. for (int i = filenames.size(); --i >= 0;)
  157. {
  158. const File f (filenames[i]);
  159. if (canOpenFile (f) && openFile (f))
  160. break;
  161. }
  162. }
  163. void MainWindow::activeWindowStatusChanged()
  164. {
  165. DocumentWindow::activeWindowStatusChanged();
  166. if (getProjectContentComponent() != 0)
  167. getProjectContentComponent()->updateMissingFileStatuses();
  168. OpenDocumentManager::getInstance()->reloadModifiedFiles();
  169. }
  170. void MainWindow::updateTitle (const String& documentName)
  171. {
  172. String name (JUCEApplication::getInstance()->getApplicationName());
  173. if (documentName.isNotEmpty())
  174. name = documentName + " - " + name;
  175. setName (name);
  176. }
  177. //==============================================================================
  178. ApplicationCommandTarget* MainWindow::getNextCommandTarget()
  179. {
  180. return 0;
  181. }
  182. void MainWindow::getAllCommands (Array <CommandID>& commands)
  183. {
  184. const CommandID ids[] = { CommandIDs::closeWindow };
  185. commands.addArray (ids, numElementsInArray (ids));
  186. }
  187. void MainWindow::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
  188. {
  189. switch (commandID)
  190. {
  191. case CommandIDs::closeWindow:
  192. result.setInfo ("Close Window", "Closes the current window", CommandCategories::general, 0);
  193. result.defaultKeypresses.add (KeyPress ('w', ModifierKeys::commandModifier, 0));
  194. break;
  195. default:
  196. break;
  197. }
  198. }
  199. bool MainWindow::perform (const InvocationInfo& info)
  200. {
  201. switch (info.commandID)
  202. {
  203. case CommandIDs::closeWindow:
  204. closeButtonPressed();
  205. break;
  206. default:
  207. return false;
  208. }
  209. return true;
  210. }