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.

787 lines
26KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 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 "../Application/jucer_MainWindow.h"
  20. #include "../Application/jucer_Application.h"
  21. #include "../Code Editor/jucer_SourceCodeEditor.h"
  22. #include "jucer_ConfigPage.h"
  23. #include "jucer_TreeViewTypes.h"
  24. #include "../Project Saving/jucer_ProjectExporter.h"
  25. #include "../Utility/jucer_TranslationTool.h"
  26. //==============================================================================
  27. class FileTreeTab : public TreePanelBase
  28. {
  29. public:
  30. FileTreeTab (Project& p)
  31. : TreePanelBase (&p, "fileTreeState")
  32. {
  33. tree.setMultiSelectEnabled (true);
  34. setRoot (new GroupTreeViewItem (p.getMainGroup()));
  35. }
  36. };
  37. //==============================================================================
  38. class ConfigTreeTab : public TreePanelBase
  39. {
  40. public:
  41. ConfigTreeTab (Project& p)
  42. : TreePanelBase (&p, "settingsTreeState")
  43. {
  44. tree.setMultiSelectEnabled (false);
  45. setRoot (createProjectConfigTreeViewRoot (p));
  46. if (tree.getNumSelectedItems() == 0)
  47. tree.getRootItem()->setSelected (true, true);
  48. #if JUCE_MAC || JUCE_WINDOWS
  49. addAndMakeVisible (&openProjectButton);
  50. openProjectButton.setCommandToTrigger (commandManager, CommandIDs::openInIDE, true);
  51. openProjectButton.setButtonText (commandManager->getNameOfCommand (CommandIDs::openInIDE));
  52. openProjectButton.setColour (TextButton::buttonColourId, Colours::white.withAlpha (0.5f));
  53. addAndMakeVisible (&saveAndOpenButton);
  54. saveAndOpenButton.setCommandToTrigger (commandManager, CommandIDs::saveAndOpenInIDE, true);
  55. saveAndOpenButton.setButtonText (commandManager->getNameOfCommand (CommandIDs::saveAndOpenInIDE));
  56. saveAndOpenButton.setColour (TextButton::buttonColourId, Colours::white.withAlpha (0.5f));
  57. #endif
  58. }
  59. void resized()
  60. {
  61. Rectangle<int> r (getAvailableBounds());
  62. r.removeFromBottom (6);
  63. if (saveAndOpenButton.isVisible())
  64. saveAndOpenButton.setBounds (r.removeFromBottom (30).reduced (16, 4));
  65. if (openProjectButton.isVisible())
  66. openProjectButton.setBounds (r.removeFromBottom (30).reduced (16, 4));
  67. tree.setBounds (r);
  68. }
  69. TextButton openProjectButton, saveAndOpenButton;
  70. };
  71. //==============================================================================
  72. class LogoComponent : public Component
  73. {
  74. public:
  75. LogoComponent() {}
  76. void paint (Graphics& g)
  77. {
  78. const Path& logo = getIcons().mainJuceLogo;
  79. const AffineTransform trans (RectanglePlacement (RectanglePlacement::centred)
  80. .getTransformToFit (logo.getBounds(),
  81. getLocalBounds().toFloat()));
  82. g.setColour (findColour (mainBackgroundColourId).contrasting (0.3f));
  83. g.fillPath (logo, trans);
  84. }
  85. };
  86. //==============================================================================
  87. ProjectContentComponent::ProjectContentComponent()
  88. : project (nullptr),
  89. currentDocument (nullptr),
  90. treeViewTabs (TabbedButtonBar::TabsAtTop)
  91. {
  92. setOpaque (true);
  93. setWantsKeyboardFocus (true);
  94. addAndMakeVisible (logo = new LogoComponent());
  95. treeSizeConstrainer.setMinimumWidth (200);
  96. treeSizeConstrainer.setMaximumWidth (500);
  97. treeViewTabs.setOutline (0);
  98. treeViewTabs.getTabbedButtonBar().setMinimumTabScaleFactor (0.3);
  99. IntrojucerApp::getApp().openDocumentManager.addListener (this);
  100. }
  101. ProjectContentComponent::~ProjectContentComponent()
  102. {
  103. IntrojucerApp::getApp().openDocumentManager.removeListener (this);
  104. logo = nullptr;
  105. setProject (nullptr);
  106. contentView = nullptr;
  107. removeChildComponent (&bubbleMessage);
  108. jassert (getNumChildComponents() <= 1);
  109. }
  110. void ProjectContentComponent::paint (Graphics& g)
  111. {
  112. IntrojucerLookAndFeel::fillWithBackgroundTexture (*this, g);
  113. }
  114. void ProjectContentComponent::paintOverChildren (Graphics& g)
  115. {
  116. if (resizerBar != nullptr)
  117. {
  118. const int shadowSize = 15;
  119. const int x = resizerBar->getX();
  120. ColourGradient cg (Colours::black.withAlpha (0.25f), (float) x, 0,
  121. Colours::transparentBlack, (float) (x - shadowSize), 0, false);
  122. cg.addColour (0.4, Colours::black.withAlpha (0.07f));
  123. cg.addColour (0.6, Colours::black.withAlpha (0.02f));
  124. g.setGradientFill (cg);
  125. g.fillRect (x - shadowSize, 0, shadowSize, getHeight());
  126. }
  127. }
  128. void ProjectContentComponent::resized()
  129. {
  130. Rectangle<int> r (getLocalBounds());
  131. if (treeViewTabs.isVisible())
  132. treeViewTabs.setBounds (r.removeFromLeft (treeViewTabs.getWidth()));
  133. if (resizerBar != nullptr)
  134. resizerBar->setBounds (r.withWidth (4));
  135. if (contentView != nullptr)
  136. contentView->setBounds (r);
  137. logo->setBounds (r.reduced (r.getWidth() / 4, r.getHeight() / 4));
  138. }
  139. void ProjectContentComponent::lookAndFeelChanged()
  140. {
  141. repaint();
  142. }
  143. void ProjectContentComponent::childBoundsChanged (Component* child)
  144. {
  145. if (child == &treeViewTabs)
  146. resized();
  147. }
  148. void ProjectContentComponent::setProject (Project* newProject)
  149. {
  150. if (project != newProject)
  151. {
  152. if (project != nullptr)
  153. project->removeChangeListener (this);
  154. contentView = nullptr;
  155. resizerBar = nullptr;
  156. deleteProjectTabs();
  157. project = newProject;
  158. rebuildProjectTabs();
  159. }
  160. }
  161. void ProjectContentComponent::rebuildProjectTabs()
  162. {
  163. deleteProjectTabs();
  164. if (project != nullptr)
  165. {
  166. addAndMakeVisible (&treeViewTabs);
  167. createProjectTabs();
  168. PropertiesFile& settings = project->getStoredProperties();
  169. const String lastTabName (settings.getValue ("lastTab"));
  170. int lastTabIndex = treeViewTabs.getTabNames().indexOf (lastTabName);
  171. if (lastTabIndex < 0 || lastTabIndex > treeViewTabs.getNumTabs())
  172. lastTabIndex = 1;
  173. treeViewTabs.setCurrentTabIndex (lastTabIndex);
  174. int lastTreeWidth = settings.getValue ("projectPanelWidth").getIntValue();
  175. if (lastTreeWidth < 150)
  176. lastTreeWidth = 240;
  177. treeViewTabs.setBounds (0, 0, lastTreeWidth, getHeight());
  178. addAndMakeVisible (resizerBar = new ResizableEdgeComponent (&treeViewTabs, &treeSizeConstrainer,
  179. ResizableEdgeComponent::rightEdge));
  180. resizerBar->setAlwaysOnTop (true);
  181. project->addChangeListener (this);
  182. updateMissingFileStatuses();
  183. }
  184. else
  185. {
  186. treeViewTabs.setVisible (false);
  187. }
  188. resized();
  189. }
  190. void ProjectContentComponent::createProjectTabs()
  191. {
  192. jassert (project != nullptr);
  193. const Colour tabColour (Colours::transparentBlack);
  194. treeViewTabs.addTab ("Files", tabColour, new FileTreeTab (*project), true);
  195. treeViewTabs.addTab ("Config", tabColour, new ConfigTreeTab (*project), true);
  196. }
  197. void ProjectContentComponent::deleteProjectTabs()
  198. {
  199. if (project != nullptr && treeViewTabs.isShowing())
  200. {
  201. PropertiesFile& settings = project->getStoredProperties();
  202. if (treeViewTabs.getWidth() > 0)
  203. settings.setValue ("projectPanelWidth", treeViewTabs.getWidth());
  204. if (treeViewTabs.getNumTabs() > 0)
  205. settings.setValue ("lastTab", treeViewTabs.getCurrentTabName());
  206. }
  207. treeViewTabs.clearTabs();
  208. }
  209. TreeView* ProjectContentComponent::getFilesTreeView() const
  210. {
  211. if (FileTreeTab* ft = dynamic_cast<FileTreeTab*> (treeViewTabs.getTabContentComponent (0)))
  212. return &(ft->tree);
  213. return nullptr;
  214. }
  215. ProjectTreeViewBase* ProjectContentComponent::getFilesTreeRoot() const
  216. {
  217. if (TreeView* tv = getFilesTreeView())
  218. return dynamic_cast <ProjectTreeViewBase*> (tv->getRootItem());
  219. return nullptr;
  220. }
  221. void ProjectContentComponent::saveTreeViewState()
  222. {
  223. for (int i = treeViewTabs.getNumTabs(); --i >= 0;)
  224. if (TreePanelBase* t = dynamic_cast<TreePanelBase*> (treeViewTabs.getTabContentComponent (i)))
  225. t->saveOpenness();
  226. }
  227. void ProjectContentComponent::saveOpenDocumentList()
  228. {
  229. if (project != nullptr)
  230. {
  231. ScopedPointer<XmlElement> xml (recentDocumentList.createXML());
  232. if (xml != nullptr)
  233. project->getStoredProperties().setValue ("lastDocs", xml);
  234. }
  235. }
  236. void ProjectContentComponent::reloadLastOpenDocuments()
  237. {
  238. if (project != nullptr)
  239. {
  240. ScopedPointer<XmlElement> xml (project->getStoredProperties().getXmlValue ("lastDocs"));
  241. if (xml != nullptr)
  242. {
  243. recentDocumentList.restoreFromXML (*project, *xml);
  244. showDocument (recentDocumentList.getCurrentDocument(), true);
  245. }
  246. }
  247. }
  248. void ProjectContentComponent::documentAboutToClose (OpenDocumentManager::Document* document)
  249. {
  250. hideDocument (document);
  251. }
  252. void ProjectContentComponent::changeListenerCallback (ChangeBroadcaster*)
  253. {
  254. updateMissingFileStatuses();
  255. }
  256. void ProjectContentComponent::updateMissingFileStatuses()
  257. {
  258. if (ProjectTreeViewBase* p = getFilesTreeRoot())
  259. p->checkFileStatus();
  260. }
  261. bool ProjectContentComponent::showEditorForFile (const File& f, bool grabFocus)
  262. {
  263. return getCurrentFile() == f
  264. || showDocument (IntrojucerApp::getApp().openDocumentManager.openFile (project, f), grabFocus);
  265. }
  266. File ProjectContentComponent::getCurrentFile() const
  267. {
  268. return currentDocument != nullptr ? currentDocument->getFile()
  269. : File::nonexistent;
  270. }
  271. bool ProjectContentComponent::showDocument (OpenDocumentManager::Document* doc, bool grabFocus)
  272. {
  273. if (doc == nullptr)
  274. return false;
  275. if (doc->hasFileBeenModifiedExternally())
  276. doc->reloadFromFile();
  277. if (doc == getCurrentDocument() && contentView != nullptr)
  278. {
  279. if (grabFocus)
  280. contentView->grabKeyboardFocus();
  281. return true;
  282. }
  283. recentDocumentList.newDocumentOpened (doc);
  284. bool opened = setEditorComponent (doc->createEditor(), doc);
  285. if (opened && grabFocus)
  286. contentView->grabKeyboardFocus();
  287. return opened;
  288. }
  289. void ProjectContentComponent::hideEditor()
  290. {
  291. currentDocument = nullptr;
  292. contentView = nullptr;
  293. updateMainWindowTitle();
  294. commandManager->commandStatusChanged();
  295. resized();
  296. }
  297. void ProjectContentComponent::hideDocument (OpenDocumentManager::Document* doc)
  298. {
  299. if (doc == currentDocument)
  300. {
  301. if (OpenDocumentManager::Document* replacement = recentDocumentList.getClosestPreviousDocOtherThan (doc))
  302. showDocument (replacement, true);
  303. else
  304. hideEditor();
  305. }
  306. }
  307. bool ProjectContentComponent::setEditorComponent (Component* editor,
  308. OpenDocumentManager::Document* doc)
  309. {
  310. if (editor != nullptr)
  311. {
  312. contentView = nullptr;
  313. contentView = editor;
  314. currentDocument = doc;
  315. addAndMakeVisible (editor);
  316. resized();
  317. updateMainWindowTitle();
  318. commandManager->commandStatusChanged();
  319. return true;
  320. }
  321. updateMainWindowTitle();
  322. return false;
  323. }
  324. void ProjectContentComponent::closeDocument()
  325. {
  326. if (currentDocument != nullptr)
  327. IntrojucerApp::getApp().openDocumentManager.closeDocument (currentDocument, true);
  328. else if (contentView != nullptr)
  329. if (! goToPreviousFile())
  330. hideEditor();
  331. }
  332. static void showSaveWarning (OpenDocumentManager::Document* currentDocument)
  333. {
  334. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  335. TRANS("Save failed!"),
  336. TRANS("Couldn't save the file:")
  337. + "\n" + currentDocument->getFile().getFullPathName());
  338. }
  339. void ProjectContentComponent::saveDocument()
  340. {
  341. if (currentDocument != nullptr)
  342. {
  343. if (! currentDocument->save())
  344. showSaveWarning (currentDocument);
  345. }
  346. else
  347. saveProject();
  348. updateMainWindowTitle();
  349. }
  350. void ProjectContentComponent::saveAs()
  351. {
  352. if (currentDocument != nullptr && ! currentDocument->saveAs())
  353. showSaveWarning (currentDocument);
  354. }
  355. bool ProjectContentComponent::goToPreviousFile()
  356. {
  357. OpenDocumentManager::Document* doc = recentDocumentList.getCurrentDocument();
  358. if (doc == nullptr || doc == getCurrentDocument())
  359. doc = recentDocumentList.getPrevious();
  360. return showDocument (doc, true);
  361. }
  362. bool ProjectContentComponent::goToNextFile()
  363. {
  364. return showDocument (recentDocumentList.getNext(), true);
  365. }
  366. bool ProjectContentComponent::canGoToCounterpart() const
  367. {
  368. return currentDocument != nullptr
  369. && currentDocument->getCounterpartFile().exists();
  370. }
  371. bool ProjectContentComponent::goToCounterpart()
  372. {
  373. if (currentDocument != nullptr)
  374. {
  375. const File file (currentDocument->getCounterpartFile());
  376. if (file.exists())
  377. return showEditorForFile (file, true);
  378. }
  379. return false;
  380. }
  381. bool ProjectContentComponent::saveProject()
  382. {
  383. return project != nullptr
  384. && project->save (true, true) == FileBasedDocument::savedOk;
  385. }
  386. void ProjectContentComponent::closeProject()
  387. {
  388. if (MainWindow* const mw = findParentComponentOfClass<MainWindow>())
  389. mw->closeCurrentProject();
  390. }
  391. void ProjectContentComponent::openInIDE()
  392. {
  393. if (project != nullptr)
  394. {
  395. for (Project::ExporterIterator exporter (*project); exporter.next();)
  396. if (exporter->launchProject())
  397. break;
  398. }
  399. }
  400. void ProjectContentComponent::deleteSelectedTreeItems()
  401. {
  402. if (TreePanelBase* const tree = dynamic_cast<TreePanelBase*> (treeViewTabs.getCurrentContentComponent()))
  403. tree->deleteSelectedItems();
  404. }
  405. void ProjectContentComponent::updateMainWindowTitle()
  406. {
  407. if (MainWindow* mw = findParentComponentOfClass<MainWindow>())
  408. {
  409. String title;
  410. File file;
  411. bool edited = false;
  412. if (currentDocument != nullptr)
  413. {
  414. title = currentDocument->getName();
  415. edited = currentDocument->needsSaving();
  416. file = currentDocument->getFile();
  417. }
  418. if (ComponentPeer* peer = mw->getPeer())
  419. {
  420. if (! peer->setDocumentEditedStatus (edited))
  421. if (edited)
  422. title << "*";
  423. peer->setRepresentedFile (file);
  424. }
  425. mw->updateTitle (title);
  426. }
  427. }
  428. void ProjectContentComponent::showBubbleMessage (const Rectangle<int>& pos, const String& text)
  429. {
  430. addChildComponent (&bubbleMessage);
  431. bubbleMessage.setColour (BubbleComponent::backgroundColourId, Colours::white.withAlpha (0.7f));
  432. bubbleMessage.setColour (BubbleComponent::outlineColourId, Colours::black.withAlpha (0.8f));
  433. bubbleMessage.setAlwaysOnTop (true);
  434. bubbleMessage.showAt (pos, AttributedString (text), 3000, true, false);
  435. }
  436. //==============================================================================
  437. void ProjectContentComponent::showTranslationTool()
  438. {
  439. if (translationTool != nullptr)
  440. {
  441. translationTool->toFront (true);
  442. }
  443. else if (project != nullptr)
  444. {
  445. TranslationToolComponent* ttc = new TranslationToolComponent();
  446. ttc->initialiseForProject (*project);
  447. new FloatingToolWindow ("Translation File Builder",
  448. "transToolWindowPos_" + project->getProjectUID(),
  449. ttc, translationTool,
  450. 600, 700,
  451. 500, 400, 10000, 10000);
  452. }
  453. }
  454. //==============================================================================
  455. ApplicationCommandTarget* ProjectContentComponent::getNextCommandTarget()
  456. {
  457. return findFirstTargetParentComponent();
  458. }
  459. void ProjectContentComponent::getAllCommands (Array <CommandID>& commands)
  460. {
  461. const CommandID ids[] = { CommandIDs::saveDocument,
  462. CommandIDs::saveDocumentAs,
  463. CommandIDs::closeDocument,
  464. CommandIDs::saveProject,
  465. CommandIDs::closeProject,
  466. CommandIDs::openInIDE,
  467. CommandIDs::saveAndOpenInIDE,
  468. CommandIDs::showFilePanel,
  469. CommandIDs::showConfigPanel,
  470. CommandIDs::goToPreviousDoc,
  471. CommandIDs::goToNextDoc,
  472. CommandIDs::goToCounterpart,
  473. CommandIDs::deleteSelectedItem,
  474. CommandIDs::showTranslationTool };
  475. commands.addArray (ids, numElementsInArray (ids));
  476. }
  477. void ProjectContentComponent::getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result)
  478. {
  479. String documentName;
  480. if (currentDocument != nullptr)
  481. documentName = " '" + currentDocument->getName().substring (0, 32) + "'";
  482. #if JUCE_MAC
  483. const ModifierKeys cmdCtrl (ModifierKeys::ctrlModifier | ModifierKeys::commandModifier);
  484. #else
  485. const ModifierKeys cmdCtrl (ModifierKeys::ctrlModifier | ModifierKeys::altModifier);
  486. #endif
  487. switch (commandID)
  488. {
  489. case CommandIDs::saveProject:
  490. result.setInfo ("Save Project",
  491. "Saves the current project",
  492. CommandCategories::general, 0);
  493. result.setActive (project != nullptr);
  494. break;
  495. case CommandIDs::closeProject:
  496. result.setInfo ("Close Project",
  497. "Closes the current project",
  498. CommandCategories::general, 0);
  499. result.setActive (project != nullptr);
  500. break;
  501. case CommandIDs::saveDocument:
  502. result.setInfo ("Save" + documentName,
  503. "Saves the current document",
  504. CommandCategories::general, 0);
  505. result.setActive (currentDocument != nullptr || project != nullptr);
  506. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier, 0));
  507. break;
  508. case CommandIDs::saveDocumentAs:
  509. result.setInfo ("Save As...",
  510. "Saves the current document to a new location",
  511. CommandCategories::general, 0);
  512. result.setActive (currentDocument != nullptr || project != nullptr);
  513. result.defaultKeypresses.add (KeyPress ('s', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
  514. break;
  515. case CommandIDs::closeDocument:
  516. result.setInfo ("Close" + documentName,
  517. "Closes the current document",
  518. CommandCategories::general, 0);
  519. result.setActive (contentView != nullptr);
  520. result.defaultKeypresses.add (KeyPress ('w', cmdCtrl, 0));
  521. break;
  522. case CommandIDs::goToPreviousDoc:
  523. result.setInfo ("Previous Document", "Go to previous document", CommandCategories::general, 0);
  524. result.setActive (recentDocumentList.canGoToPrevious());
  525. result.defaultKeypresses.add (KeyPress (KeyPress::leftKey, cmdCtrl, 0));
  526. break;
  527. case CommandIDs::goToNextDoc:
  528. result.setInfo ("Next Document", "Go to next document", CommandCategories::general, 0);
  529. result.setActive (recentDocumentList.canGoToNext());
  530. result.defaultKeypresses.add (KeyPress (KeyPress::rightKey, cmdCtrl, 0));
  531. break;
  532. case CommandIDs::goToCounterpart:
  533. result.setInfo ("Open corresponding header or cpp file", "Open counterpart file", CommandCategories::general, 0);
  534. result.setActive (canGoToCounterpart());
  535. result.defaultKeypresses.add (KeyPress (KeyPress::upKey, cmdCtrl, 0));
  536. break;
  537. case CommandIDs::openInIDE:
  538. #if JUCE_MAC
  539. result.setInfo ("Open in Xcode...",
  540. #elif JUCE_WINDOWS
  541. result.setInfo ("Open in Visual Studio...",
  542. #else
  543. result.setInfo ("Open as a Makefile...",
  544. #endif
  545. "Launches the project in an external IDE",
  546. CommandCategories::general, 0);
  547. result.setActive (ProjectExporter::canProjectBeLaunched (project));
  548. break;
  549. case CommandIDs::saveAndOpenInIDE:
  550. #if JUCE_MAC
  551. result.setInfo ("Save Project and Open in Xcode...",
  552. #elif JUCE_WINDOWS
  553. result.setInfo ("Save Project and Open in Visual Studio...",
  554. #else
  555. result.setInfo ("Save Project and Open as a Makefile...",
  556. #endif
  557. "Saves the project and launches it in an external IDE",
  558. CommandCategories::general, 0);
  559. result.setActive (ProjectExporter::canProjectBeLaunched (project));
  560. result.defaultKeypresses.add (KeyPress ('l', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
  561. break;
  562. case CommandIDs::showFilePanel:
  563. result.setInfo ("Show File Panel",
  564. "Shows the tree of files for this project",
  565. CommandCategories::general, 0);
  566. result.setActive (project != nullptr);
  567. result.defaultKeypresses.add (KeyPress ('p', ModifierKeys::commandModifier, 0));
  568. break;
  569. case CommandIDs::showConfigPanel:
  570. result.setInfo ("Show Config Panel",
  571. "Shows the build options for the project",
  572. CommandCategories::general, 0);
  573. result.setActive (project != nullptr);
  574. result.defaultKeypresses.add (KeyPress ('i', ModifierKeys::commandModifier, 0));
  575. break;
  576. case CommandIDs::deleteSelectedItem:
  577. result.setInfo ("Delete Selected File", String::empty, CommandCategories::general, 0);
  578. result.defaultKeypresses.add (KeyPress (KeyPress::deleteKey, 0, 0));
  579. result.defaultKeypresses.add (KeyPress (KeyPress::backspaceKey, 0, 0));
  580. result.setActive (dynamic_cast<TreePanelBase*> (treeViewTabs.getCurrentContentComponent()) != nullptr);
  581. break;
  582. case CommandIDs::showTranslationTool:
  583. result.setInfo ("Translation File Builder", "Shows the translation file helper tool", CommandCategories::general, 0);
  584. break;
  585. default:
  586. break;
  587. }
  588. }
  589. bool ProjectContentComponent::isCommandActive (const CommandID)
  590. {
  591. return project != nullptr;
  592. }
  593. bool ProjectContentComponent::perform (const InvocationInfo& info)
  594. {
  595. switch (info.commandID)
  596. {
  597. case CommandIDs::saveProject:
  598. case CommandIDs::closeProject:
  599. case CommandIDs::saveDocument:
  600. case CommandIDs::saveDocumentAs:
  601. case CommandIDs::closeDocument:
  602. case CommandIDs::goToPreviousDoc:
  603. case CommandIDs::goToNextDoc:
  604. case CommandIDs::goToCounterpart:
  605. case CommandIDs::saveAndOpenInIDE:
  606. if (reinvokeCommandAfterCancellingModalComps (info))
  607. {
  608. grabKeyboardFocus(); // to force any open labels to close their text editors
  609. return true;
  610. }
  611. break;
  612. default:
  613. break;
  614. }
  615. switch (info.commandID)
  616. {
  617. case CommandIDs::saveProject: saveProject(); break;
  618. case CommandIDs::closeProject: closeProject(); break;
  619. case CommandIDs::saveDocument: saveDocument(); break;
  620. case CommandIDs::saveDocumentAs: saveAs(); break;
  621. case CommandIDs::closeDocument: closeDocument(); break;
  622. case CommandIDs::goToPreviousDoc: goToPreviousFile(); break;
  623. case CommandIDs::goToNextDoc: goToNextFile(); break;
  624. case CommandIDs::goToCounterpart: goToCounterpart(); break;
  625. case CommandIDs::showFilePanel: treeViewTabs.setCurrentTabIndex (0); break;
  626. case CommandIDs::showConfigPanel: treeViewTabs.setCurrentTabIndex (1); break;
  627. case CommandIDs::openInIDE: openInIDE(); break;
  628. case CommandIDs::deleteSelectedItem: deleteSelectedTreeItems(); break;
  629. case CommandIDs::saveAndOpenInIDE:
  630. if (saveProject())
  631. openInIDE();
  632. break;
  633. case CommandIDs::showTranslationTool: showTranslationTool(); break;
  634. default:
  635. return false;
  636. }
  637. return true;
  638. }