1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
26 #pragma once
27 
28 #include "projectexplorer_export.h"
29 
30 #include <coreplugin/icontext.h>
31 
32 #include <functional>
33 
34 namespace Utils { class FilePath; }
35 
36 namespace ProjectExplorer {
37 class BuildSystem;
38 class FileNode;
39 class FolderNode;
40 class Node;
41 class Project;
42 class ProjectNode;
43 class SessionNode;
44 class Target;
45 
46 namespace Internal { class ProjectTreeWidget; }
47 
48 class PROJECTEXPLORER_EXPORT ProjectTree : public QObject
49 {
50     Q_OBJECT
51 public:
52     explicit ProjectTree(QObject *parent = nullptr);
53     ~ProjectTree() override;
54 
55     static ProjectTree *instance();
56 
57     static Project *currentProject();
58     static Target *currentTarget();
59     static BuildSystem *currentBuildSystem();
60     static Node *currentNode();
61     static Utils::FilePath currentFilePath();
62 
63     class CurrentNodeKeeper {
64     public:
65         CurrentNodeKeeper();
66         ~CurrentNodeKeeper();
67     private:
68         const bool m_active = false;
69     };
70 
71     // Integration with ProjectTreeWidget
72     static void registerWidget(Internal::ProjectTreeWidget *widget);
73     static void unregisterWidget(Internal::ProjectTreeWidget *widget);
74     static void nodeChanged(Internal::ProjectTreeWidget *widget);
75 
76     static void aboutToShutDown();
77 
78     static void showContextMenu(Internal::ProjectTreeWidget *focus, const QPoint &globalPos, Node *node);
79 
80     static void highlightProject(Project *project, const QString &message);
81 
82     using TreeManagerFunction = std::function<void(FolderNode *)>;
83     static void registerTreeManager(const TreeManagerFunction &treeChange);
84     static void applyTreeManager(FolderNode *folder);
85 
86     // Nodes:
87     static bool hasNode(const Node *node);
88     static void forEachNode(const std::function<void(Node *)> &task);
89 
90     static Project *projectForNode(const Node *node);
91     static Node *nodeForFile(const Utils::FilePath &fileName);
92 
93     static const QList<Node *> siblingsWithSameBaseName(const Node *fileNode);
94 
95     void expandCurrentNodeRecursively();
96 
97     void collapseAll();
98     void expandAll();
99 
100     void changeProjectRootDirectory();
101 
102     // for nodes to emit signals, do not call unless you are a node
103     static void emitSubtreeChanged(FolderNode *node);
104 
105 signals:
106     void currentProjectChanged(ProjectExplorer::Project *project);
107     void currentNodeChanged(Node *node);
108     void nodeActionsChanged();
109 
110     // Emitted whenever the model needs to send a update signal.
111     void subtreeChanged(ProjectExplorer::FolderNode *node);
112 
113     void aboutToShowContextMenu(ProjectExplorer::Node *node);
114 
115     // Emitted on any change to the tree
116     void treeChanged();
117 
118 private:
119     void sessionAndTreeChanged();
120     void sessionChanged();
121     void update();
122     void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
123     void updateFromDocumentManager();
124     void updateFromNode(Node *node);
125     void setCurrent(Node *node, Project *project);
126     void updateContext();
127 
128     void updateFromFocus();
129 
130     void updateExternalFileWarning();
131     static bool hasFocus(Internal::ProjectTreeWidget *widget);
132     Internal::ProjectTreeWidget *currentWidget() const;
133     void hideContextMenu();
134 
135 private:
136     static ProjectTree *s_instance;
137     QList<QPointer<Internal::ProjectTreeWidget>> m_projectTreeWidgets;
138     QVector<TreeManagerFunction> m_treeManagers;
139     Node *m_currentNode = nullptr;
140     Project *m_currentProject = nullptr;
141     Internal::ProjectTreeWidget *m_focusForContextMenu = nullptr;
142     int m_keepCurrentNodeRequests = 0;
143     Core::Context m_lastProjectContext;
144 };
145 
146 } // namespace ProjectExplorer
147