File indexing completed on 2024-04-28 04:37:21

0001 /*
0002     SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org>
0003     SPDX-FileCopyrightText: 2015 Laszlo Kis-Adam <laszlo.kis-adam@kdemail.net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef PROBLEMMODEL_H
0009 #define PROBLEMMODEL_H
0010 
0011 #include <shell/shellexport.h>
0012 #include <QAbstractItemModel>
0013 #include <shell/problem.h>
0014 #include <language/editor/documentrange.h>
0015 
0016 #include "problemconstants.h"
0017 
0018 class QUrl;
0019 
0020 namespace KDevelop {
0021 class IDocument;
0022 class IndexedString;
0023 class ProblemStore;
0024 class ProblemModelPrivate;
0025 
0026 /**
0027  * @brief Wraps a ProblemStore and adds the QAbstractItemModel interface, so the it can be used in a model/view architecture.
0028  *
0029  * By default ProblemModel instantiates a FilteredProblemStore, with the following features on:
0030  * \li ScopeFilter
0031  * \li SeverityFilter
0032  * \li Grouping
0033  * \li CanByPassScopeFilter
0034  *
0035  * Has to following columns:
0036  * \li Error
0037  * \li Source
0038  * \li File
0039  * \li Line
0040  * \li Column
0041  * \li LastColumn
0042  *
0043  * Possible ProblemModel features
0044  * \li NoFeatures
0045  * \li CanDoFullUpdate
0046  * \li CanShowImports
0047  * \li ScopeFilter
0048  * \li SeverityFilter
0049  * \li Grouping
0050  * \li CanByPassScopeFilter
0051  *
0052  * Scope, severity, grouping, imports can be set using the slots named after these features.
0053  *
0054  * Usage example:
0055  * @code
0056  * IProblem::Ptr problem(new DetectedProblem);
0057  * problem->setDescription(QStringLiteral("Problem"));
0058  * ProblemModel *model = new ProblemModel(nullptr);
0059  * model->addProblem(problem);
0060  * model->rowCount(); // returns 1
0061  * QModelIndex idx = model->index(0, 0);
0062  * model->data(index); // "Problem"
0063  * @endcode
0064  *
0065  */
0066 class KDEVPLATFORMSHELL_EXPORT ProblemModel : public QAbstractItemModel
0067 {
0068     Q_OBJECT
0069 
0070 public:
0071     /// List of supportable features
0072     enum FeatureCode
0073     {
0074         NoFeatures                 = 0,  /// No features :(
0075         CanDoFullUpdate            = 1,  /// Reload/Reparse problems
0076         CanShowImports             = 2,  /// Show problems from imported files. E.g.: Header files in C/C++
0077         ScopeFilter                = 4,  /// Filter problems by scope. E.g.: current document, open documents, etc
0078         SeverityFilter             = 8,  /// Filter problems by severity. E.g.: hint, warning, error, etc
0079         Grouping                   = 16, /// Can group problems
0080         CanByPassScopeFilter       = 32, /// Can bypass scope filter
0081         ShowSource                 = 64  /// Show problem's source. Set if problems can have different sources.
0082     };
0083 
0084     Q_DECLARE_FLAGS(Features, FeatureCode)
0085 
0086     explicit ProblemModel(QObject *parent, ProblemStore *store = nullptr);
0087     ~ProblemModel() override;
0088 
0089     // NOTE: keep the enumerators of Columns in sync with the sizePolicy array in ProblemTreeView::resizeColumns().
0090     enum Columns {
0091         Error,
0092         Source,
0093         File,
0094         Line,
0095         Column,
0096         LastColumn
0097     };
0098 
0099     enum Roles {
0100         ProblemRole = Qt::UserRole + 1,
0101         SeverityRole
0102     };
0103 
0104     int columnCount(const QModelIndex & parent = QModelIndex()) const override;
0105     QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const override;
0106     QModelIndex parent(const QModelIndex & index) const override;
0107     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
0108     int rowCount(const QModelIndex & parent = QModelIndex()) const override;
0109     QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
0110 
0111     IProblem::Ptr problemForIndex(const QModelIndex& index) const;
0112 
0113     /// Adds a new problem to the model
0114     void addProblem(const IProblem::Ptr &problem);
0115 
0116     /// Clears the problems, then adds a new set of them
0117     void setProblems(const QVector<IProblem::Ptr> &problems);
0118 
0119     /// Clears the problems
0120     void clearProblems();
0121 
0122     /// Retrieve problems for selected document
0123     QVector<IProblem::Ptr> problems(const KDevelop::IndexedString& document) const;
0124 
0125     /**
0126      * Add new "placeholder" item (problem). The item will be displayed whenever the model is empty.
0127      *
0128      * The method should be used to notify user about some events. For example, analyzer plugin
0129      * can set placeholders at analysis state changes - started/finished without errors/etc.
0130      *
0131      * \param[in] text Sets problem description.
0132      * \param[in] location Sets problem final location.
0133      * \param[in] source Sets problem source string.
0134     */
0135     void setPlaceholderText(const QString& text,
0136                             const KDevelop::DocumentRange& location = KDevelop::DocumentRange::invalid(),
0137                             const QString& source = QString());
0138 
0139     /// Retrieve the supported features
0140     Features features() const;
0141 
0142     /// Retrieve 'show imports' filter setting
0143     bool showImports() const;
0144 
0145     /// Set the supported features
0146     void setFeatures(Features features);
0147 
0148     /// Tooltip for "Force Full Update" action in the Problems View when the model
0149     /// is active (correspondent tab is selected)
0150     QString fullUpdateTooltip() const;
0151 
0152     /// Set the "Force Full Update" action tooltip
0153     void setFullUpdateTooltip(const QString& tooltip);
0154 
0155 Q_SIGNALS:
0156     /// Emitted when the stored problems are changed with addProblem(), setProblems() and
0157     /// clearProblems() methods. This signal emitted only when internal problems storage is
0158     /// really changed: for example, it is not emitted when we call clearProblems() method
0159     /// for empty model.
0160     void problemsChanged();
0161 
0162     /// Emitted when the "Force Full Update" action tooltip is changed with setFullUpdateTooltip().
0163     /// This signal emitted only when tooltip is really changed.
0164     void fullUpdateTooltipChanged();
0165 
0166 public Q_SLOTS:
0167     /// Show imports
0168     void setShowImports(bool showImports);
0169 
0170     /// Sets the scope filter
0171     void setScope(ProblemScope scope);
0172 
0173     /// Sets the path filter for the DocumentsInPath scope
0174     void setPathForDocumentsInPathScope(const QString& path);
0175 
0176     /// Sets the severity filter
0177     void setSeverity(int severity);///old-style severity filtering
0178 
0179     void setSeverities(KDevelop::IProblem::Severities severities);///new-style severity filtering
0180 
0181     void setGrouping(int grouping);
0182 
0183     /**
0184      * Force a full problem update.
0185      * E.g.: Reparse the source code.
0186      * Obviously it doesn't make sense for run-time problem checkers.
0187      */
0188     virtual void forceFullUpdate(){}
0189 
0190 protected Q_SLOTS:
0191     /// Triggered when problems change
0192     virtual void onProblemsChanged(){}
0193 
0194 private Q_SLOTS:
0195     /// Triggered when the current document changes
0196     virtual void setCurrentDocument(IDocument* doc);
0197 
0198     virtual void closedDocument(IDocument* doc);
0199 
0200     void documentUrlChanged(IDocument* document, const QUrl& previousUrl);
0201 
0202     /// Triggered before the problems are rebuilt
0203     void onBeginRebuild();
0204 
0205     /// Triggered once the problems have been rebuilt
0206     void onEndRebuild();
0207 
0208 protected:
0209     ProblemStore *store() const;
0210 
0211 private:
0212     const QScopedPointer<class ProblemModelPrivate> d_ptr;
0213     Q_DECLARE_PRIVATE(ProblemModel)
0214 };
0215 
0216 Q_DECLARE_OPERATORS_FOR_FLAGS(ProblemModel::Features)
0217 
0218 }
0219 
0220 #endif // PROBLEMMODEL_H