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.

204 lines
6.2KB

  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. class GroupItem : public ProjectTreeItemBase
  20. {
  21. public:
  22. GroupItem (const Project::Item& projectItem)
  23. : ProjectTreeItemBase (projectItem)
  24. {
  25. }
  26. bool isRoot() const override { return item.isMainGroup(); }
  27. bool acceptsFileDrop (const StringArray&) const override { return true; }
  28. void addNewGroup()
  29. {
  30. Project::Item newGroup (item.addNewSubGroup ("New Group", 0));
  31. triggerAsyncRename (newGroup);
  32. }
  33. bool acceptsDragItems (const OwnedArray<Project::Item>& selectedNodes) override
  34. {
  35. for (int i = selectedNodes.size(); --i >= 0;)
  36. if (item.canContain (*selectedNodes.getUnchecked(i)))
  37. return true;
  38. return false;
  39. }
  40. void addFilesAtIndex (const StringArray& files, int insertIndex) override
  41. {
  42. for (int i = 0; i < files.size(); ++i)
  43. {
  44. const File file (files[i]);
  45. if (item.addFileAtIndex (file, insertIndex, true))
  46. ++insertIndex;
  47. }
  48. }
  49. void addFilesRetainingSortOrder (const StringArray& files) override
  50. {
  51. for (int i = files.size(); --i >= 0;)
  52. item.addFileRetainingSortOrder (files[i], true);
  53. }
  54. void moveSelectedItemsTo (OwnedArray<Project::Item>& selectedNodes, int insertIndex) override
  55. {
  56. moveItems (selectedNodes, item, insertIndex);
  57. }
  58. void checkFileStatus() override
  59. {
  60. for (int i = 0; i < getNumSubItems(); ++i)
  61. if (ProjectTreeItemBase* p = dynamic_cast<ProjectTreeItemBase*> (getSubItem(i)))
  62. p->checkFileStatus();
  63. }
  64. ProjectTreeItemBase* createSubItem (const Project::Item& child) override
  65. {
  66. if (child.isGroup()) return new GroupItem (child);
  67. if (child.isFile()) return new SourceFileItem (child);
  68. jassertfalse;
  69. return nullptr;
  70. }
  71. void showDocument() override
  72. {
  73. if (ProjectContentComponent* pcc = getProjectContentComponent())
  74. pcc->setEditorComponent (new GroupInformationComponent (item), nullptr);
  75. }
  76. static void openOrCloseAllSubGroups (TreeViewItem& item, bool shouldOpen)
  77. {
  78. item.setOpen (shouldOpen);
  79. for (int i = item.getNumSubItems(); --i >= 0;)
  80. if (TreeViewItem* sub = item.getSubItem(i))
  81. openOrCloseAllSubGroups (*sub, shouldOpen);
  82. }
  83. static void setFilesToCompile (Project::Item item, const bool shouldCompile)
  84. {
  85. if (item.isFile())
  86. item.getShouldCompileValue() = shouldCompile;
  87. for (int i = item.getNumChildren(); --i >= 0;)
  88. setFilesToCompile (item.getChild (i), shouldCompile);
  89. }
  90. void showPopupMenu() override
  91. {
  92. PopupMenu m;
  93. addCreateFileMenuItems (m);
  94. m.addSeparator();
  95. if (! isRoot())
  96. {
  97. if (isOpen())
  98. m.addItem (1, "Collapse all Sub-groups");
  99. else
  100. m.addItem (2, "Expand all Sub-groups");
  101. }
  102. m.addSeparator();
  103. m.addItem (3, "Enable compiling of all enclosed files");
  104. m.addItem (4, "Disable compiling of all enclosed files");
  105. m.addSeparator();
  106. m.addItem (5, "Sort Items Alphabetically");
  107. m.addItem (6, "Sort Items Alphabetically (Groups first)");
  108. m.addSeparator();
  109. if (! isRoot())
  110. {
  111. m.addItem (7, "Rename...");
  112. m.addItem (8, "Delete");
  113. }
  114. launchPopupMenu (m);
  115. }
  116. void showPlusMenu() override
  117. {
  118. PopupMenu m;
  119. addCreateFileMenuItems (m);
  120. launchPopupMenu (m);
  121. }
  122. void handlePopupMenuResult (int resultCode) override
  123. {
  124. switch (resultCode)
  125. {
  126. case 1: openOrCloseAllSubGroups (*this, false); break;
  127. case 2: openOrCloseAllSubGroups (*this, true); break;
  128. case 3: setFilesToCompile (item, true); break;
  129. case 4: setFilesToCompile (item, false); break;
  130. case 5: item.sortAlphabetically (false, false); break;
  131. case 6: item.sortAlphabetically (true, false); break;
  132. case 7: triggerAsyncRename (item); break;
  133. case 8: deleteAllSelectedItems(); break;
  134. default: processCreateFileMenuItem (resultCode); break;
  135. }
  136. }
  137. void addCreateFileMenuItems (PopupMenu& m)
  138. {
  139. m.addItem (1001, "Add New Group");
  140. m.addItem (1002, "Add Existing Files...");
  141. m.addSeparator();
  142. NewFileWizard().addWizardsToMenu (m);
  143. }
  144. void processCreateFileMenuItem (int menuID)
  145. {
  146. switch (menuID)
  147. {
  148. case 1001: addNewGroup(); break;
  149. case 1002: browseToAddExistingFiles(); break;
  150. default:
  151. jassert (getProject() != nullptr);
  152. NewFileWizard().runWizardFromMenu (menuID, *getProject(), item);
  153. break;
  154. }
  155. }
  156. Project* getProject()
  157. {
  158. if (TreeView* tv = getOwnerView())
  159. if (ProjectContentComponent* pcc = tv->findParentComponentOfClass<ProjectContentComponent>())
  160. return pcc->getProject();
  161. return nullptr;
  162. }
  163. };