File indexing completed on 2024-05-12 04:37:44

0001 /*
0002     SPDX-FileCopyrightText: 2007-2009 Hamish Rodda <rodda@kde.org>
0003     SPDX-FileCopyrightText: 2009 Lior Mualem <lior.m.kde@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KDEVPLATFORM_CLASSMODELNODE_H
0009 #define KDEVPLATFORM_CLASSMODELNODE_H
0010 
0011 #include "classmodel.h"
0012 
0013 #include "../duchain/identifier.h"
0014 #include "../duchain/duchainpointer.h"
0015 #include "classmodelnodescontroller.h"
0016 
0017 #include <QIcon>
0018 
0019 class NodesModelInterface;
0020 
0021 namespace KDevelop {
0022 class ClassDeclaration;
0023 class ClassFunctionDeclaration;
0024 class ClassMemberDeclaration;
0025 class Declaration;
0026 }
0027 
0028 namespace ClassModelNodes {
0029 /// Base node class - provides basic functionality.
0030 class Node
0031 {
0032 public:
0033     Node(const QString& a_displayName, NodesModelInterface* a_model);
0034     virtual ~Node();
0035 
0036 public: // Operations
0037     /// Clear all the children from the node.
0038     void clear();
0039 
0040     /// Called by the model to collapse the node and remove sub-items if needed.
0041     virtual void collapse() {};
0042 
0043     /// Called by the model to expand the node and populate it with sub-nodes if needed.
0044     virtual void expand() {};
0045 
0046     /// Append a new child node to the list.
0047     void addNode(Node* a_child);
0048 
0049     /// Remove child node from the list and delete it.
0050     void removeNode(Node* a_child);
0051 
0052     /// Remove this node and delete it.
0053     void removeSelf() { m_parentNode->removeNode(this); }
0054 
0055     /// Called once the node has been populated to sort the entire tree / branch.
0056     void recursiveSort();
0057 
0058 public: // Info retrieval
0059     /// Return the parent associated with this node.
0060     Node* parent() const { return m_parentNode; }
0061 
0062     /// Get my index in the parent node
0063     int row();
0064 
0065     /// Return the display name for the node.
0066     QString displayName() const { return m_displayName; }
0067 
0068     /// Returns a list of child nodes
0069     const QList<Node*>& children() const { return m_children; }
0070 
0071     /// Return an icon representation for the node.
0072     /// @note It calls the internal getIcon and caches the result.
0073     QIcon cachedIcon();
0074 
0075 public: // overridables
0076     /// Return a score when sorting the nodes.
0077     virtual int score() const = 0;
0078 
0079     /// Return true if the node contains sub-nodes.
0080     virtual bool hasChildren() const { return !m_children.empty(); }
0081 
0082     /// We use this string when sorting items.
0083     virtual QString sortableString() const { return m_displayName; }
0084 
0085 protected:
0086     /// fill a_resultIcon with a display icon for the node.
0087     /// @param a_resultIcon returned icon.
0088     /// @return true if result was returned.
0089     virtual bool getIcon(QIcon& a_resultIcon) = 0;
0090 
0091 private:
0092     Node* m_parentNode;
0093 
0094     /// Called once the node has been populated to sort the entire tree / branch.
0095     void recursiveSortInternal();
0096 
0097 protected:
0098     using NodesList = QList<Node*>;
0099     NodesList m_children;
0100     QString m_displayName;
0101     QIcon m_cachedIcon;
0102     NodesModelInterface* m_model;
0103 };
0104 
0105 //////////////////////////////////////////////////////////////////////////////
0106 //////////////////////////////////////////////////////////////////////////////
0107 
0108 /// Base class for nodes that generate and populate their child nodes dynamically
0109 class DynamicNode
0110     : public Node
0111 {
0112 public:
0113     DynamicNode(const QString& a_displayName, NodesModelInterface* a_model);
0114 
0115     /// Return true if the node was populated already.
0116     bool isPopulated() const { return m_populated; }
0117 
0118     /// Populate the node and mark the flag - called from expand or can be used internally.
0119     void performPopulateNode(bool a_forceRepopulate = false);
0120 
0121 public: // Node overrides.
0122     void collapse() override;
0123     void expand() override;
0124     bool hasChildren() const override;
0125 
0126 protected: // overridables
0127     /// Called by the framework when the node is about to be expanded
0128     /// it should be populated with sub-nodes if applicable.
0129     virtual void populateNode() {}
0130 
0131     /// Called after the nodes have been removed.
0132     /// It's for derived classes to clean cached data.
0133     virtual void nodeCleared() {}
0134 
0135 private:
0136     bool m_populated;
0137 
0138     /// Clear all the child nodes and mark flag.
0139     void performNodeCleanup();
0140 };
0141 
0142 //////////////////////////////////////////////////////////////////////////////
0143 //////////////////////////////////////////////////////////////////////////////
0144 
0145 /// Base class for nodes associated with a @ref KDevelop::QualifiedIdentifier
0146 class IdentifierNode
0147     : public DynamicNode
0148 {
0149 public:
0150     IdentifierNode(KDevelop::Declaration* a_decl, NodesModelInterface* a_model,
0151                    const QString& a_displayName = QString());
0152 
0153 public:
0154     /// Returns the qualified identifier for this node by going through the tree
0155     const KDevelop::IndexedQualifiedIdentifier& identifier() const { return m_identifier; }
0156 
0157 public: // Node overrides
0158     bool getIcon(QIcon& a_resultIcon) override;
0159 
0160 public: // Overridables
0161     /// Return the associated declaration
0162     /// @note DU CHAIN MUST BE LOCKED FOR READ
0163     virtual KDevelop::Declaration* declaration();
0164 
0165 private:
0166     KDevelop::IndexedQualifiedIdentifier m_identifier;
0167     KDevelop::IndexedDeclaration m_indexedDeclaration;
0168     KDevelop::DeclarationPointer m_cachedDeclaration;
0169 };
0170 
0171 //////////////////////////////////////////////////////////////////////////////
0172 //////////////////////////////////////////////////////////////////////////////
0173 
0174 /// A node that represents an enum value.
0175 class EnumNode
0176     : public IdentifierNode
0177 {
0178 public:
0179     EnumNode(KDevelop::Declaration* a_decl, NodesModelInterface* a_model);
0180 
0181 public: // Node overrides
0182     int score() const override { return 102; }
0183     bool getIcon(QIcon& a_resultIcon) override;
0184     void populateNode() override;
0185 };
0186 
0187 //////////////////////////////////////////////////////////////////////////////
0188 //////////////////////////////////////////////////////////////////////////////
0189 
0190 /// Provides display for a single class.
0191 class ClassNode
0192     : public IdentifierNode
0193     , public ClassModelNodeDocumentChangedInterface
0194 {
0195 public:
0196     ClassNode(KDevelop::Declaration* a_decl, NodesModelInterface* a_model);
0197     ~ClassNode() override;
0198 
0199     /// Lookup a contained class and return the related node.
0200     /// @return the node pointer or 0 if non was found.
0201     ClassNode* findSubClass(const KDevelop::IndexedQualifiedIdentifier& a_id);
0202 
0203 public: // Node overrides
0204     int score() const override { return 300; }
0205     void populateNode() override;
0206     void nodeCleared() override;
0207     bool hasChildren() const override { return true; }
0208 
0209 protected: // ClassModelNodeDocumentChangedInterface overrides
0210     void documentChanged(const KDevelop::IndexedString& a_file) override;
0211 
0212 private:
0213     using SubIdentifiersMap = QMap<uint, Node*>;
0214     /// Set of known sub-identifiers. It's used for updates check.
0215     SubIdentifiersMap m_subIdentifiers;
0216 
0217     /// We use this variable to know if we've registered for change notification or not.
0218     KDevelop::IndexedString m_cachedUrl;
0219 
0220     /// Updates the node to reflect changes in the declaration.
0221     /// @note DU CHAIN MUST BE LOCKED FOR READ
0222     /// @return true if something was updated.
0223     bool updateClassDeclarations();
0224 
0225     /// Add "Base classes" and "Derived classes" folders, if needed
0226     /// @return true if one of the folders was added.
0227     bool addBaseAndDerived();
0228 };
0229 
0230 //////////////////////////////////////////////////////////////////////////////
0231 //////////////////////////////////////////////////////////////////////////////
0232 
0233 /// Provides a display for a single class function.
0234 class FunctionNode
0235     : public IdentifierNode
0236 {
0237 public:
0238     FunctionNode(KDevelop::Declaration* a_decl, NodesModelInterface* a_model);
0239 
0240 public: // Node overrides
0241     int score() const override { return 400; }
0242     QString sortableString() const override { return m_sortableString; }
0243 
0244 private:
0245     QString m_sortableString;
0246 };
0247 
0248 //////////////////////////////////////////////////////////////////////////////
0249 //////////////////////////////////////////////////////////////////////////////
0250 
0251 /// Provides display for a single class variable.
0252 class ClassMemberNode
0253     : public IdentifierNode
0254 {
0255 public:
0256     ClassMemberNode(KDevelop::ClassMemberDeclaration* a_decl, NodesModelInterface* a_model);
0257 
0258 public: // Node overrides
0259     int score() const override { return 500; }
0260     bool getIcon(QIcon& a_resultIcon) override;
0261 };
0262 
0263 //////////////////////////////////////////////////////////////////////////////
0264 //////////////////////////////////////////////////////////////////////////////
0265 
0266 /// Provides a folder node with a static list of nodes.
0267 class FolderNode
0268     : public Node
0269 {
0270 public:
0271     FolderNode(const QString& a_displayName, NodesModelInterface* a_model);
0272 
0273 public: // Node overrides
0274     bool getIcon(QIcon& a_resultIcon) override;
0275     int score() const override { return 100; }
0276 };
0277 
0278 //////////////////////////////////////////////////////////////////////////////
0279 //////////////////////////////////////////////////////////////////////////////
0280 
0281 /// Provides a folder node with a dynamic list of nodes.
0282 class DynamicFolderNode
0283     : public DynamicNode
0284 {
0285 public:
0286     DynamicFolderNode(const QString& a_displayName, NodesModelInterface* a_model);
0287 
0288 public: // Node overrides
0289     bool getIcon(QIcon& a_resultIcon) override;
0290     int score() const override { return 100; }
0291 };
0292 
0293 //////////////////////////////////////////////////////////////////////////////
0294 //////////////////////////////////////////////////////////////////////////////
0295 
0296 /// Special folder - the parent is assumed to be a ClassNode.
0297 /// It then displays the base classes for the class it sits in.
0298 class BaseClassesFolderNode
0299     : public DynamicFolderNode
0300 {
0301 public:
0302     explicit BaseClassesFolderNode(NodesModelInterface* a_model);
0303 
0304 public: // Node overrides
0305     void populateNode() override;
0306 };
0307 
0308 //////////////////////////////////////////////////////////////////////////////
0309 //////////////////////////////////////////////////////////////////////////////
0310 
0311 /// Special folder - the parent is assumed to be a ClassNode.
0312 /// It then displays list of derived classes from the parent class.
0313 class DerivedClassesFolderNode
0314     : public DynamicFolderNode
0315 {
0316 public:
0317     explicit DerivedClassesFolderNode(NodesModelInterface* a_model);
0318 
0319 public: // Node overrides
0320     void populateNode() override;
0321 };
0322 } // namespace classModelNodes
0323 
0324 #endif