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.

768 lines
26KB

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