|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2017 - ROLI Ltd.
-
- JUCE is an open source library subject to commercial or open-source
- licensing.
-
- By using JUCE, you agree to the terms of both the JUCE 5 End-User License
- Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
- 27th April 2017).
-
- End User License Agreement: www.juce.com/juce-5-licence
- Privacy Policy: www.juce.com/juce-5-privacy-policy
-
- Or: You may also use this code under the terms of the GPL v3 (see
- www.gnu.org/licenses).
-
- JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
- EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
- DISCLAIMED.
-
- ==============================================================================
- */
-
- class GroupItem : public ProjectTreeItemBase
- {
- public:
- GroupItem (const Project::Item& projectItem, const String& filter = String())
- : ProjectTreeItemBase (projectItem),
- searchFilter (filter)
- {
- }
-
- bool isRoot() const override { return item.isMainGroup(); }
- bool acceptsFileDrop (const StringArray&) const override { return true; }
-
- void addNewGroup()
- {
- Project::Item newGroup (item.addNewSubGroup ("New Group", 0));
- triggerAsyncRename (newGroup);
- }
-
- bool acceptsDragItems (const OwnedArray<Project::Item>& selectedNodes) override
- {
- for (int i = selectedNodes.size(); --i >= 0;)
- if (item.canContain (*selectedNodes.getUnchecked(i)))
- return true;
-
- return false;
- }
-
- void addFilesAtIndex (const StringArray& files, int insertIndex) override
- {
- for (int i = 0; i < files.size(); ++i)
- {
- const File file (files[i]);
-
- if (item.addFileAtIndex (file, insertIndex, true))
- ++insertIndex;
- }
- }
-
- void addFilesRetainingSortOrder (const StringArray& files) override
- {
- for (int i = files.size(); --i >= 0;)
- item.addFileRetainingSortOrder (files[i], true);
- }
-
- void moveSelectedItemsTo (OwnedArray<Project::Item>& selectedNodes, int insertIndex) override
- {
- moveItems (selectedNodes, item, insertIndex);
- }
-
- void checkFileStatus() override
- {
- for (int i = 0; i < getNumSubItems(); ++i)
- if (ProjectTreeItemBase* p = dynamic_cast<ProjectTreeItemBase*> (getSubItem(i)))
- p->checkFileStatus();
- }
-
- bool isGroupEmpty (const Project::Item& group) // recursive
- {
- for (auto i = 0; i < group.getNumChildren(); ++i)
- {
- auto child = group.getChild (i);
-
- if ((child.isGroup() && ! isGroupEmpty (child))
- || (child.isFile() && child.getName().containsIgnoreCase (searchFilter)))
- return false;
- }
-
- return true;
- }
-
- ProjectTreeItemBase* createSubItem (const Project::Item& child) override
- {
- if (child.isGroup())
- {
- if (searchFilter.isNotEmpty() && isGroupEmpty (child))
- return nullptr;
-
- return new GroupItem (child, searchFilter);
- }
-
- if (child.isFile())
- {
- if (child.getName().containsIgnoreCase (searchFilter))
- return new SourceFileItem (child);
-
- return nullptr;
- }
-
- jassertfalse;
- return nullptr;
- }
-
- void showDocument() override
- {
- if (ProjectContentComponent* pcc = getProjectContentComponent())
- pcc->setEditorComponent (new GroupInformationComponent (item), nullptr);
- }
-
- static void openAllGroups (TreeViewItem* root)
- {
- for (auto i = 0; i < root->getNumSubItems(); ++i)
- if (auto* sub = root->getSubItem (i))
- openOrCloseAllSubGroups (*sub, true);
- }
-
- static void closeAllGroups (TreeViewItem* root)
- {
- for (auto i = 0; i < root->getNumSubItems(); ++i)
- if (auto* sub = root->getSubItem (i))
- openOrCloseAllSubGroups (*sub, false);
- }
-
- static void openOrCloseAllSubGroups (TreeViewItem& item, bool shouldOpen)
- {
- item.setOpen (shouldOpen);
-
- for (int i = item.getNumSubItems(); --i >= 0;)
- if (auto* sub = item.getSubItem (i))
- openOrCloseAllSubGroups (*sub, shouldOpen);
- }
-
- static void setFilesToCompile (Project::Item item, const bool shouldCompile)
- {
- if (item.isFile())
- item.getShouldCompileValue() = shouldCompile;
-
- for (int i = item.getNumChildren(); --i >= 0;)
- setFilesToCompile (item.getChild (i), shouldCompile);
- }
-
- void showPopupMenu() override
- {
- PopupMenu m;
- addCreateFileMenuItems (m);
-
- m.addSeparator();
-
- m.addItem (1, "Collapse all Groups");
- m.addItem (2, "Expand all Groups");
-
- if (! isRoot())
- {
- if (isOpen())
- m.addItem (3, "Collapse all Sub-groups");
- else
- m.addItem (4, "Expand all Sub-groups");
- }
-
- m.addSeparator();
- m.addItem (5, "Enable compiling of all enclosed files");
- m.addItem (6, "Disable compiling of all enclosed files");
-
- m.addSeparator();
- m.addItem (7, "Sort Items Alphabetically");
- m.addItem (8, "Sort Items Alphabetically (Groups first)");
- m.addSeparator();
-
- if (! isRoot())
- {
- m.addItem (9, "Rename...");
- m.addItem (10, "Delete");
- }
-
- launchPopupMenu (m);
- }
-
- void showPlusMenu() override
- {
- PopupMenu m;
- addCreateFileMenuItems (m);
-
- launchPopupMenu (m);
- }
-
- void handlePopupMenuResult (int resultCode) override
- {
- switch (resultCode)
- {
- case 1: closeAllGroups (getOwnerView()->getRootItem()); break;
- case 2: openAllGroups (getOwnerView()->getRootItem()); break;
- case 3: openOrCloseAllSubGroups (*this, false); break;
- case 4: openOrCloseAllSubGroups (*this, true); break;
- case 5: setFilesToCompile (item, true); break;
- case 6: setFilesToCompile (item, false); break;
- case 7: item.sortAlphabetically (false, false); break;
- case 8: item.sortAlphabetically (true, false); break;
- case 9: triggerAsyncRename (item); break;
- case 10: deleteAllSelectedItems(); break;
- default: processCreateFileMenuItem (resultCode); break;
- }
- }
-
- void addCreateFileMenuItems (PopupMenu& m)
- {
- m.addItem (1001, "Add New Group");
- m.addItem (1002, "Add Existing Files...");
-
- m.addSeparator();
- NewFileWizard().addWizardsToMenu (m);
- }
-
- void processCreateFileMenuItem (int menuID)
- {
- switch (menuID)
- {
- case 1001: addNewGroup(); break;
- case 1002: browseToAddExistingFiles(); break;
-
- default:
- jassert (getProject() != nullptr);
- NewFileWizard().runWizardFromMenu (menuID, *getProject(), item);
- break;
- }
- }
-
- Project* getProject()
- {
- if (TreeView* tv = getOwnerView())
- if (ProjectContentComponent* pcc = tv->findParentComponentOfClass<ProjectContentComponent>())
- return pcc->getProject();
-
- return nullptr;
- }
-
- void setSearchFilter (const String& filter)
- {
- searchFilter = filter;
- refreshSubItems();
- }
-
- String searchFilter;
- };
|