aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer/projecttree.h
blob: 81140895e725131a606d7c06f8fe5d03a86f3307 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#pragma once

#include "projectexplorer_export.h"

#include <coreplugin/icontext.h>

#include <functional>

namespace Core { class IDocument; }
namespace Utils { class FilePath; }

namespace ProjectExplorer {
class BuildSystem;
class FileNode;
class FolderNode;
class Node;
class Project;
class ProjectNode;
class SessionNode;
class Target;

namespace Internal { class ProjectTreeWidget; }

class PROJECTEXPLORER_EXPORT ProjectTree : public QObject
{
    Q_OBJECT
public:
    explicit ProjectTree(QObject *parent = nullptr);
    ~ProjectTree() override;

    static ProjectTree *instance();

    static Project *currentProject();
    static Target *currentTarget();
    static BuildSystem *currentBuildSystem();
    static Node *currentNode();
    static Utils::FilePath currentFilePath();

    class CurrentNodeKeeper {
    public:
        CurrentNodeKeeper();
        ~CurrentNodeKeeper();
    private:
        const bool m_active = false;
    };

    enum ConstructionPhase {
        AsyncPhase,
        FinalPhase
    };

    // Integration with ProjectTreeWidget
    static void registerWidget(Internal::ProjectTreeWidget *widget);
    static void unregisterWidget(Internal::ProjectTreeWidget *widget);
    static void nodeChanged(Internal::ProjectTreeWidget *widget);

    static void aboutToShutDown();

    static void showContextMenu(Internal::ProjectTreeWidget *focus, const QPoint &globalPos, Node *node);

    static void highlightProject(Project *project, const QString &message);

    using TreeManagerFunction = std::function<void(FolderNode *, ConstructionPhase)>;
    static void registerTreeManager(const TreeManagerFunction &treeChange);
    static void applyTreeManager(FolderNode *folder, ConstructionPhase phase);

    // Nodes:
    static bool hasNode(const Node *node);
    static void forEachNode(const std::function<void(Node *)> &task);

    static Project *projectForNode(const Node *node);
    static Node *nodeForFile(const Utils::FilePath &fileName);

    static const QList<Node *> siblingsWithSameBaseName(const Node *fileNode);

    void expandCurrentNodeRecursively();

    void collapseAll();
    void expandAll();

    void changeProjectRootDirectory();

    // for nodes to emit signals, do not call unless you are a node
    static void emitSubtreeChanged(FolderNode *node);

signals:
    void currentProjectChanged(ProjectExplorer::Project *project);
    void currentNodeChanged(Node *node);
    void nodeActionsChanged();

    // Emitted whenever the model needs to send a update signal.
    void subtreeChanged(ProjectExplorer::FolderNode *node);

    void aboutToShowContextMenu(ProjectExplorer::Node *node);

    // Emitted on any change to the tree
    void treeChanged();

private:
    void sessionAndTreeChanged();
    void sessionChanged();
    void update();
    void updateFromProjectTreeWidget(Internal::ProjectTreeWidget *widget);
    void updateFromDocumentManager();
    void updateFromNode(Node *node);
    void setCurrent(Node *node, Project *project);
    void updateContext();

    void updateFromFocus();

    void updateFileWarning(Core::IDocument *document, const QString &text);
    static bool hasFocus(Internal::ProjectTreeWidget *widget);
    Internal::ProjectTreeWidget *currentWidget() const;
    void hideContextMenu();

private:
    static ProjectTree *s_instance;
    QList<QPointer<Internal::ProjectTreeWidget>> m_projectTreeWidgets;
    QVector<TreeManagerFunction> m_treeManagers;
    Node *m_currentNode = nullptr;
    Project *m_currentProject = nullptr;
    Internal::ProjectTreeWidget *m_focusForContextMenu = nullptr;
    int m_keepCurrentNodeRequests = 0;
    Core::Context m_lastProjectContext;
};

} // namespace ProjectExplorer