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.

770 lines
26KB

  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. void createGUIEditorMenu (PopupMenu&);
  20. void handleGUIEditorMenuCommand (int);
  21. void registerGUIEditorCommands();
  22. //==============================================================================
  23. struct ProjucerApplication::MainMenuModel : public MenuBarModel
  24. {
  25. MainMenuModel()
  26. {
  27. setApplicationCommandManagerToWatch (&getCommandManager());
  28. }
  29. StringArray getMenuBarNames() override
  30. {
  31. return getApp().getMenuNames();
  32. }
  33. PopupMenu getMenuForIndex (int /*topLevelMenuIndex*/, const String& menuName) override
  34. {
  35. PopupMenu menu;
  36. getApp().createMenu (menu, menuName);
  37. return menu;
  38. }
  39. void menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/) override
  40. {
  41. getApp().handleMainMenuCommand (menuItemID);
  42. }
  43. };
  44. //==============================================================================
  45. ProjucerApplication::ProjucerApplication() : isRunningCommandLine (false)
  46. {
  47. }
  48. void ProjucerApplication::initialise (const String& commandLine)
  49. {
  50. if (commandLine.trimStart().startsWith ("--server"))
  51. {
  52. initialiseLogger ("Compiler_Log_");
  53. LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);
  54. #if JUCE_MAC
  55. Process::setDockIconVisible (false);
  56. #endif
  57. server = createClangServer (commandLine);
  58. }
  59. else
  60. {
  61. initialiseLogger ("IDE_Log_");
  62. Logger::writeToLog (SystemStats::getOperatingSystemName());
  63. Logger::writeToLog ("CPU: " + String (SystemStats::getCpuSpeedInMegaherz())
  64. + "MHz Cores: " + String (SystemStats::getNumCpus())
  65. + " " + String (SystemStats::getMemorySizeInMegabytes()) + "MB");
  66. initialiseBasics();
  67. if (commandLine.isNotEmpty())
  68. {
  69. isRunningCommandLine = true;
  70. const int appReturnCode = performCommandLine (commandLine);
  71. if (appReturnCode != commandLineNotPerformed)
  72. {
  73. setApplicationReturnValue (appReturnCode);
  74. quit();
  75. return;
  76. }
  77. isRunningCommandLine = false;
  78. }
  79. if (sendCommandLineToPreexistingInstance())
  80. {
  81. DBG ("Another instance is running - quitting...");
  82. quit();
  83. return;
  84. }
  85. openDocumentManager.registerType (new ProjucerAppClasses::LiveBuildCodeEditorDocument::Type(), 2);
  86. childProcessCache = new ChildProcessCache();
  87. initCommandManager();
  88. menuModel = new MainMenuModel();
  89. settings->appearance.refreshPresetSchemeList();
  90. // do further initialisation in a moment when the message loop has started
  91. triggerAsyncUpdate();
  92. }
  93. }
  94. void ProjucerApplication::initialiseBasics()
  95. {
  96. LookAndFeel::setDefaultLookAndFeel (&lookAndFeel);
  97. settings = new StoredSettings();
  98. ImageCache::setCacheTimeout (30 * 1000);
  99. icons = new Icons();
  100. tooltipWindow.setMillisecondsBeforeTipAppears (1200);
  101. }
  102. bool ProjucerApplication::initialiseLogger (const char* filePrefix)
  103. {
  104. if (logger == nullptr)
  105. {
  106. #if JUCE_LINUX
  107. String folder = "~/.config/Projucer/Logs";
  108. #else
  109. String folder = "com.juce.projucer";
  110. #endif
  111. logger = FileLogger::createDateStampedLogger (folder, filePrefix, ".txt",
  112. getApplicationName() + " " + getApplicationVersion()
  113. + " --- Build date: " __DATE__);
  114. Logger::setCurrentLogger (logger);
  115. }
  116. return logger != nullptr;
  117. }
  118. void ProjucerApplication::handleAsyncUpdate()
  119. {
  120. licenseController = new LicenseController;
  121. licenseController->addLicenseStatusChangedCallback (this);
  122. licenseStateChanged (licenseController->getState());
  123. #if JUCE_MAC
  124. PopupMenu extraAppleMenuItems;
  125. createExtraAppleMenuItems (extraAppleMenuItems);
  126. // workaround broken "Open Recent" submenu: not passing the
  127. // submenu's title here avoids the defect in JuceMainMenuHandler::addMenuItem
  128. MenuBarModel::setMacMainMenu (menuModel, &extraAppleMenuItems); //, "Open Recent");
  129. #endif
  130. versionChecker = new LatestVersionChecker();
  131. }
  132. void ProjucerApplication::initialiseWindows (const String& commandLine)
  133. {
  134. const String commandLineWithoutNSDebug (commandLine.replace ("-NSDocumentRevisionsDebugMode YES", StringRef()));
  135. if (commandLineWithoutNSDebug.trim().isNotEmpty() && ! commandLineWithoutNSDebug.trim().startsWithChar ('-'))
  136. anotherInstanceStarted (commandLine);
  137. else
  138. mainWindowList.reopenLastProjects();
  139. mainWindowList.createWindowIfNoneAreOpen();
  140. }
  141. void ProjucerApplication::shutdown()
  142. {
  143. if (server != nullptr)
  144. {
  145. destroyClangServer (server);
  146. Logger::writeToLog ("Server shutdown cleanly");
  147. }
  148. versionChecker = nullptr;
  149. appearanceEditorWindow = nullptr;
  150. globalPreferencesWindow = nullptr;
  151. utf8Window = nullptr;
  152. svgPathWindow = nullptr;
  153. aboutWindow = nullptr;
  154. if (licenseController != nullptr)
  155. {
  156. licenseController->removeLicenseStatusChangedCallback (this);
  157. licenseController = nullptr;
  158. }
  159. mainWindowList.forceCloseAllWindows();
  160. openDocumentManager.clear();
  161. childProcessCache = nullptr;
  162. #if JUCE_MAC
  163. MenuBarModel::setMacMainMenu (nullptr);
  164. #endif
  165. menuModel = nullptr;
  166. commandManager = nullptr;
  167. settings = nullptr;
  168. LookAndFeel::setDefaultLookAndFeel (nullptr);
  169. if (! isRunningCommandLine)
  170. Logger::writeToLog ("Shutdown");
  171. deleteLogger();
  172. }
  173. struct AsyncQuitRetrier : private Timer
  174. {
  175. AsyncQuitRetrier() { startTimer (500); }
  176. void timerCallback() override
  177. {
  178. stopTimer();
  179. delete this;
  180. if (JUCEApplicationBase* app = JUCEApplicationBase::getInstance())
  181. app->systemRequestedQuit();
  182. }
  183. JUCE_DECLARE_NON_COPYABLE (AsyncQuitRetrier)
  184. };
  185. void ProjucerApplication::systemRequestedQuit()
  186. {
  187. if (server != nullptr)
  188. {
  189. sendQuitMessageToIDE (server);
  190. }
  191. else if (ModalComponentManager::getInstance()->cancelAllModalComponents())
  192. {
  193. new AsyncQuitRetrier();
  194. }
  195. else
  196. {
  197. if (closeAllMainWindows())
  198. quit();
  199. }
  200. }
  201. //==============================================================================
  202. void ProjucerApplication::licenseStateChanged (const LicenseState& state)
  203. {
  204. if (state.type != LicenseState::Type::notLoggedIn
  205. && state.type != LicenseState::Type::noLicenseChosenYet)
  206. {
  207. initialiseWindows (getCommandLineParameters());
  208. }
  209. }
  210. void ProjucerApplication::doLogout()
  211. {
  212. if (licenseController != nullptr)
  213. {
  214. const LicenseState& state = licenseController->getState();
  215. if (state.type != LicenseState::Type::notLoggedIn && closeAllMainWindows())
  216. licenseController->logout();
  217. }
  218. }
  219. //==============================================================================
  220. String ProjucerApplication::getVersionDescription() const
  221. {
  222. String s;
  223. const Time buildDate (Time::getCompilationDate());
  224. s << "Projucer " << ProjectInfo::versionString
  225. << newLine
  226. << "Build date: " << buildDate.getDayOfMonth()
  227. << " " << Time::getMonthName (buildDate.getMonth(), true)
  228. << " " << buildDate.getYear();
  229. return s;
  230. }
  231. void ProjucerApplication::anotherInstanceStarted (const String& commandLine)
  232. {
  233. if (server == nullptr && ! commandLine.trim().startsWithChar ('-'))
  234. openFile (File (commandLine.unquoted()));
  235. }
  236. ProjucerApplication& ProjucerApplication::getApp()
  237. {
  238. ProjucerApplication* const app = dynamic_cast<ProjucerApplication*> (JUCEApplication::getInstance());
  239. jassert (app != nullptr);
  240. return *app;
  241. }
  242. ApplicationCommandManager& ProjucerApplication::getCommandManager()
  243. {
  244. ApplicationCommandManager* cm = ProjucerApplication::getApp().commandManager;
  245. jassert (cm != nullptr);
  246. return *cm;
  247. }
  248. //==============================================================================
  249. enum
  250. {
  251. recentProjectsBaseID = 100,
  252. activeDocumentsBaseID = 300,
  253. colourSchemeBaseID = 1000
  254. };
  255. MenuBarModel* ProjucerApplication::getMenuModel()
  256. {
  257. return menuModel.get();
  258. }
  259. StringArray ProjucerApplication::getMenuNames()
  260. {
  261. const char* const names[] = { "File", "Edit", "View", "Build", "Window", "GUI Editor", "Tools", nullptr };
  262. return StringArray (names);
  263. }
  264. void ProjucerApplication::createMenu (PopupMenu& menu, const String& menuName)
  265. {
  266. if (menuName == "File") createFileMenu (menu);
  267. else if (menuName == "Edit") createEditMenu (menu);
  268. else if (menuName == "View") createViewMenu (menu);
  269. else if (menuName == "Build") createBuildMenu (menu);
  270. else if (menuName == "Window") createWindowMenu (menu);
  271. else if (menuName == "Tools") createToolsMenu (menu);
  272. else if (menuName == "GUI Editor") createGUIEditorMenu (menu);
  273. else jassertfalse; // names have changed?
  274. }
  275. void ProjucerApplication::createFileMenu (PopupMenu& menu)
  276. {
  277. menu.addCommandItem (commandManager, CommandIDs::newProject);
  278. menu.addSeparator();
  279. menu.addCommandItem (commandManager, CommandIDs::open);
  280. PopupMenu recentFiles;
  281. settings->recentFiles.createPopupMenuItems (recentFiles, recentProjectsBaseID, true, true);
  282. menu.addSubMenu ("Open Recent", recentFiles);
  283. menu.addSeparator();
  284. menu.addCommandItem (commandManager, CommandIDs::closeDocument);
  285. menu.addCommandItem (commandManager, CommandIDs::saveDocument);
  286. menu.addCommandItem (commandManager, CommandIDs::saveDocumentAs);
  287. menu.addCommandItem (commandManager, CommandIDs::saveAll);
  288. menu.addSeparator();
  289. menu.addCommandItem (commandManager, CommandIDs::closeProject);
  290. menu.addCommandItem (commandManager, CommandIDs::saveProject);
  291. menu.addSeparator();
  292. menu.addCommandItem (commandManager, CommandIDs::openInIDE);
  293. menu.addCommandItem (commandManager, CommandIDs::saveAndOpenInIDE);
  294. menu.addSeparator();
  295. #if ! JUCER_ENABLE_GPL_MODE
  296. menu.addCommandItem (commandManager, CommandIDs::loginLogout);
  297. #endif
  298. #if ! JUCE_MAC
  299. menu.addCommandItem (commandManager, CommandIDs::showAboutWindow);
  300. menu.addCommandItem (commandManager, CommandIDs::showGlobalPreferences);
  301. menu.addSeparator();
  302. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit);
  303. #endif
  304. }
  305. void ProjucerApplication::createEditMenu (PopupMenu& menu)
  306. {
  307. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::undo);
  308. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::redo);
  309. menu.addSeparator();
  310. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::cut);
  311. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::copy);
  312. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::paste);
  313. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::del);
  314. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::selectAll);
  315. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::deselectAll);
  316. menu.addSeparator();
  317. menu.addCommandItem (commandManager, CommandIDs::showFindPanel);
  318. menu.addCommandItem (commandManager, CommandIDs::findSelection);
  319. menu.addCommandItem (commandManager, CommandIDs::findNext);
  320. menu.addCommandItem (commandManager, CommandIDs::findPrevious);
  321. }
  322. void ProjucerApplication::createViewMenu (PopupMenu& menu)
  323. {
  324. menu.addCommandItem (commandManager, CommandIDs::showProjectSettings);
  325. menu.addCommandItem (commandManager, CommandIDs::showProjectTab);
  326. menu.addCommandItem (commandManager, CommandIDs::showBuildTab);
  327. menu.addCommandItem (commandManager, CommandIDs::showFileExplorerPanel);
  328. menu.addCommandItem (commandManager, CommandIDs::showModulesPanel);
  329. menu.addCommandItem (commandManager, CommandIDs::showExportersPanel);
  330. menu.addCommandItem (commandManager, CommandIDs::showExporterSettings);
  331. menu.addSeparator();
  332. createColourSchemeItems (menu);
  333. }
  334. void ProjucerApplication::createBuildMenu (PopupMenu& menu)
  335. {
  336. menu.addCommandItem (commandManager, CommandIDs::toggleBuildEnabled);
  337. menu.addCommandItem (commandManager, CommandIDs::toggleContinuousBuild);
  338. menu.addCommandItem (commandManager, CommandIDs::buildNow);
  339. menu.addSeparator();
  340. menu.addCommandItem (commandManager, CommandIDs::launchApp);
  341. menu.addCommandItem (commandManager, CommandIDs::killApp);
  342. menu.addCommandItem (commandManager, CommandIDs::cleanAll);
  343. menu.addSeparator();
  344. menu.addCommandItem (commandManager, CommandIDs::reinstantiateComp);
  345. menu.addCommandItem (commandManager, CommandIDs::showWarnings);
  346. menu.addSeparator();
  347. menu.addCommandItem (commandManager, CommandIDs::nextError);
  348. menu.addCommandItem (commandManager, CommandIDs::prevError);
  349. }
  350. void ProjucerApplication::createColourSchemeItems (PopupMenu& menu)
  351. {
  352. PopupMenu colourSchemes;
  353. colourSchemes.addItem (colourSchemeBaseID + 0, "Dark");
  354. colourSchemes.addItem (colourSchemeBaseID + 1, "Grey");
  355. colourSchemes.addItem (colourSchemeBaseID + 2, "Light");
  356. menu.addSubMenu ("Colour Scheme", colourSchemes);
  357. }
  358. void ProjucerApplication::createWindowMenu (PopupMenu& menu)
  359. {
  360. menu.addCommandItem (commandManager, CommandIDs::closeWindow);
  361. menu.addSeparator();
  362. menu.addCommandItem (commandManager, CommandIDs::goToPreviousDoc);
  363. menu.addCommandItem (commandManager, CommandIDs::goToNextDoc);
  364. menu.addCommandItem (commandManager, CommandIDs::goToCounterpart);
  365. menu.addSeparator();
  366. const int numDocs = jmin (50, openDocumentManager.getNumOpenDocuments());
  367. for (int i = 0; i < numDocs; ++i)
  368. {
  369. OpenDocumentManager::Document* doc = openDocumentManager.getOpenDocument(i);
  370. menu.addItem (activeDocumentsBaseID + i, doc->getName());
  371. }
  372. menu.addSeparator();
  373. menu.addCommandItem (commandManager, CommandIDs::closeAllDocuments);
  374. }
  375. void ProjucerApplication::createToolsMenu (PopupMenu& menu)
  376. {
  377. menu.addCommandItem (commandManager, CommandIDs::showUTF8Tool);
  378. menu.addCommandItem (commandManager, CommandIDs::showSVGPathTool);
  379. menu.addCommandItem (commandManager, CommandIDs::showTranslationTool);
  380. }
  381. void ProjucerApplication::createExtraAppleMenuItems (PopupMenu& menu)
  382. {
  383. menu.addCommandItem (commandManager, CommandIDs::showAboutWindow);
  384. menu.addSeparator();
  385. menu.addCommandItem (commandManager, CommandIDs::showGlobalPreferences);
  386. }
  387. void ProjucerApplication::handleMainMenuCommand (int menuItemID)
  388. {
  389. if (menuItemID >= recentProjectsBaseID && menuItemID < recentProjectsBaseID + 100)
  390. {
  391. // open a file from the "recent files" menu
  392. openFile (settings->recentFiles.getFile (menuItemID - recentProjectsBaseID));
  393. }
  394. else if (menuItemID >= activeDocumentsBaseID && menuItemID < activeDocumentsBaseID + 200)
  395. {
  396. if (OpenDocumentManager::Document* doc = openDocumentManager.getOpenDocument (menuItemID - activeDocumentsBaseID))
  397. mainWindowList.openDocument (doc, true);
  398. else
  399. jassertfalse;
  400. }
  401. else if (menuItemID >= colourSchemeBaseID && menuItemID < colourSchemeBaseID + 3)
  402. {
  403. auto& appearanceSettings = getAppSettings().appearance;
  404. if (menuItemID == colourSchemeBaseID)
  405. {
  406. lookAndFeel.setColourScheme (LookAndFeel_V4::getDarkColourScheme());
  407. appearanceSettings.selectPresetScheme (0);
  408. }
  409. else if (menuItemID == colourSchemeBaseID + 1)
  410. {
  411. lookAndFeel.setColourScheme (LookAndFeel_V4::getGreyColourScheme());
  412. appearanceSettings.selectPresetScheme (0);
  413. }
  414. else if (menuItemID == colourSchemeBaseID + 2)
  415. {
  416. lookAndFeel.setColourScheme (LookAndFeel_V4::getLightColourScheme());
  417. appearanceSettings.selectPresetScheme (1);
  418. }
  419. lookAndFeel.setupColours();
  420. mainWindowList.sendLookAndFeelChange();
  421. if (utf8Window != nullptr) utf8Window->sendLookAndFeelChange();
  422. if (svgPathWindow != nullptr) svgPathWindow->sendLookAndFeelChange();
  423. if (globalPreferencesWindow != nullptr) globalPreferencesWindow->sendLookAndFeelChange();
  424. if (aboutWindow != nullptr) aboutWindow->sendLookAndFeelChange();
  425. }
  426. else
  427. {
  428. handleGUIEditorMenuCommand (menuItemID);
  429. }
  430. }
  431. //==============================================================================
  432. void ProjucerApplication::getAllCommands (Array <CommandID>& commands)
  433. {
  434. JUCEApplication::getAllCommands (commands);
  435. const CommandID ids[] = { CommandIDs::newProject,
  436. CommandIDs::open,
  437. CommandIDs::closeAllDocuments,
  438. CommandIDs::saveAll,
  439. CommandIDs::showGlobalPreferences,
  440. CommandIDs::showUTF8Tool,
  441. CommandIDs::showSVGPathTool,
  442. CommandIDs::showAboutWindow,
  443. CommandIDs::loginLogout };
  444. commands.addArray (ids, numElementsInArray (ids));
  445. }
  446. void ProjucerApplication::getCommandInfo (CommandID commandID, ApplicationCommandInfo& result)
  447. {
  448. switch (commandID)
  449. {
  450. case CommandIDs::newProject:
  451. result.setInfo ("New Project...", "Creates a new Jucer project", CommandCategories::general, 0);
  452. result.defaultKeypresses.add (KeyPress ('n', ModifierKeys::commandModifier, 0));
  453. break;
  454. case CommandIDs::open:
  455. result.setInfo ("Open...", "Opens a Jucer project", CommandCategories::general, 0);
  456. result.defaultKeypresses.add (KeyPress ('o', ModifierKeys::commandModifier, 0));
  457. break;
  458. case CommandIDs::showGlobalPreferences:
  459. result.setInfo ("Preferences...", "Shows the preferences window.", CommandCategories::general, 0);
  460. result.defaultKeypresses.add (KeyPress (',', ModifierKeys::commandModifier, 0));
  461. break;
  462. case CommandIDs::closeAllDocuments:
  463. result.setInfo ("Close All Documents", "Closes all open documents", CommandCategories::general, 0);
  464. result.setActive (openDocumentManager.getNumOpenDocuments() > 0);
  465. break;
  466. case CommandIDs::saveAll:
  467. result.setInfo ("Save All", "Saves all open documents", CommandCategories::general, 0);
  468. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier | ModifierKeys::altModifier, 0));
  469. break;
  470. case CommandIDs::showUTF8Tool:
  471. result.setInfo ("UTF-8 String-Literal Helper", "Shows the UTF-8 string literal utility", CommandCategories::general, 0);
  472. break;
  473. case CommandIDs::showSVGPathTool:
  474. result.setInfo ("SVG Path Converter", "Shows the SVG->Path data conversion utility", CommandCategories::general, 0);
  475. break;
  476. case CommandIDs::showAboutWindow:
  477. result.setInfo ("About Projucer", "Shows the Projucer's 'About' page.", CommandCategories::general, 0);
  478. break;
  479. case CommandIDs::loginLogout:
  480. {
  481. bool isLoggedIn = false;
  482. String username;
  483. if (licenseController != nullptr)
  484. {
  485. const LicenseState state = licenseController->getState();
  486. isLoggedIn = (state.type != LicenseState::Type::notLoggedIn && state.type != LicenseState::Type::GPL);
  487. username = state.username;
  488. }
  489. result.setInfo (isLoggedIn
  490. ? String ("Sign out ") + username + "..."
  491. : String ("Sign in..."),
  492. "Log out of your JUCE account", CommandCategories::general, 0);
  493. }
  494. break;
  495. default:
  496. JUCEApplication::getCommandInfo (commandID, result);
  497. break;
  498. }
  499. }
  500. bool ProjucerApplication::perform (const InvocationInfo& info)
  501. {
  502. switch (info.commandID)
  503. {
  504. case CommandIDs::newProject: createNewProject(); break;
  505. case CommandIDs::open: askUserToOpenFile(); break;
  506. case CommandIDs::saveAll: openDocumentManager.saveAll(); break;
  507. case CommandIDs::closeAllDocuments: closeAllDocuments (true); break;
  508. case CommandIDs::showUTF8Tool: showUTF8ToolWindow(); break;
  509. case CommandIDs::showSVGPathTool: showSVGPathDataToolWindow(); break;
  510. case CommandIDs::showGlobalPreferences: AppearanceSettings::showGlobalPreferences (globalPreferencesWindow); break;
  511. case CommandIDs::showAboutWindow: showAboutWindow(); break;
  512. case CommandIDs::loginLogout: doLogout(); break;
  513. default: return JUCEApplication::perform (info);
  514. }
  515. return true;
  516. }
  517. //==============================================================================
  518. void ProjucerApplication::createNewProject()
  519. {
  520. MainWindow* mw = mainWindowList.getOrCreateEmptyWindow();
  521. mw->showNewProjectWizard();
  522. mainWindowList.avoidSuperimposedWindows (mw);
  523. }
  524. void ProjucerApplication::updateNewlyOpenedProject (Project& p)
  525. {
  526. LiveBuildProjectSettings::updateNewlyOpenedProject (p);
  527. }
  528. void ProjucerApplication::askUserToOpenFile()
  529. {
  530. FileChooser fc ("Open File");
  531. if (fc.browseForFileToOpen())
  532. openFile (fc.getResult());
  533. }
  534. bool ProjucerApplication::openFile (const File& file)
  535. {
  536. return mainWindowList.openFile (file);
  537. }
  538. bool ProjucerApplication::closeAllDocuments (bool askUserToSave)
  539. {
  540. return openDocumentManager.closeAll (askUserToSave);
  541. }
  542. bool ProjucerApplication::closeAllMainWindows()
  543. {
  544. return server != nullptr || mainWindowList.askAllWindowsToClose();
  545. }
  546. //==============================================================================
  547. void ProjucerApplication::showUTF8ToolWindow()
  548. {
  549. if (utf8Window != nullptr)
  550. utf8Window->toFront (true);
  551. else
  552. new FloatingToolWindow ("UTF-8 String Literal Converter",
  553. "utf8WindowPos",
  554. new UTF8Component(), utf8Window, true,
  555. 500, 500, 300, 300, 1000, 1000);
  556. }
  557. void ProjucerApplication::showSVGPathDataToolWindow()
  558. {
  559. if (svgPathWindow != nullptr)
  560. svgPathWindow->toFront (true);
  561. else
  562. new FloatingToolWindow ("SVG Path Converter",
  563. "svgPathWindowPos",
  564. new SVGPathDataComponent(), svgPathWindow, true,
  565. 500, 500, 300, 300, 1000, 1000);
  566. }
  567. void ProjucerApplication::showAboutWindow()
  568. {
  569. if (aboutWindow != nullptr)
  570. aboutWindow->toFront (true);
  571. else
  572. new FloatingToolWindow ("",
  573. "aboutWindowPos",
  574. new AboutWindowComponent(), aboutWindow, false,
  575. 500, 300, 500, 300, 500, 300);
  576. }
  577. //==============================================================================
  578. struct FileWithTime
  579. {
  580. FileWithTime (const File& f) : file (f), time (f.getLastModificationTime()) {}
  581. FileWithTime() {}
  582. bool operator< (const FileWithTime& other) const { return time < other.time; }
  583. bool operator== (const FileWithTime& other) const { return time == other.time; }
  584. File file;
  585. Time time;
  586. };
  587. void ProjucerApplication::deleteLogger()
  588. {
  589. const int maxNumLogFilesToKeep = 50;
  590. Logger::setCurrentLogger (nullptr);
  591. if (logger != nullptr)
  592. {
  593. Array<File> logFiles;
  594. logger->getLogFile().getParentDirectory().findChildFiles (logFiles, File::findFiles, false);
  595. if (logFiles.size() > maxNumLogFilesToKeep)
  596. {
  597. Array <FileWithTime> files;
  598. for (int i = 0; i < logFiles.size(); ++i)
  599. files.addUsingDefaultSort (logFiles.getReference(i));
  600. for (int i = 0; i < files.size() - maxNumLogFilesToKeep; ++i)
  601. files.getReference(i).file.deleteFile();
  602. }
  603. }
  604. logger = nullptr;
  605. }
  606. PropertiesFile::Options ProjucerApplication::getPropertyFileOptionsFor (const String& filename)
  607. {
  608. PropertiesFile::Options options;
  609. options.applicationName = filename;
  610. options.filenameSuffix = "settings";
  611. options.osxLibrarySubFolder = "Application Support";
  612. #if JUCE_LINUX
  613. options.folderName = "~/.config/Projucer";
  614. #else
  615. options.folderName = "Projucer";
  616. #endif
  617. return options;
  618. }
  619. void ProjucerApplication::updateAllBuildTabs()
  620. {
  621. for (int i = 0; i < mainWindowList.windows.size(); ++i)
  622. if (ProjectContentComponent* p = mainWindowList.windows.getUnchecked(i)->getProjectContentComponent())
  623. p->rebuildProjectTabs();
  624. }
  625. void ProjucerApplication::initCommandManager()
  626. {
  627. commandManager = new ApplicationCommandManager();
  628. commandManager->registerAllCommandsForTarget (this);
  629. {
  630. CodeDocument doc;
  631. CppCodeEditorComponent ed (File(), doc);
  632. commandManager->registerAllCommandsForTarget (&ed);
  633. }
  634. registerGUIEditorCommands();
  635. }