File indexing completed on 2024-05-05 04:38:47

0001 /*
0002     SPDX-FileCopyrightText: 2013 Kevin Funk <kfunk@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #ifndef KDEVPLATFORM_PLACEHOLDERITEMPROXYMODEL_H
0008 #define KDEVPLATFORM_PLACEHOLDERITEMPROXYMODEL_H
0009 
0010 #include "utilexport.h"
0011 
0012 #include <QIdentityProxyModel>
0013 #include <QScopedPointer>
0014 
0015 namespace KDevelop {
0016 class PlaceholderItemProxyModelPrivate;
0017 
0018 /**
0019  * Proxy model adding a placeholder item for new entries
0020  *
0021  * This is mostly a QIdentityProxyModel, with one additional row added at the end
0022  *
0023  * Example use:
0024  *
0025  * @code
0026  * PlaceholderItemProxyModel* proxyModel = new PlaceholderItemProxyModel;
0027  * proxyModel->setSourceModel(new MyItemModel);
0028  * proxyModel->setColumnHint(0, "(Add new entry)");
0029  * connect(proxyModel, SIGNAL(dataInserted(...), SLOT(handleDataInserted(...));
0030  * @endcode
0031  *
0032  * In this case MyItemModel has exactly two entries, "Item1" and "Item2"
0033  *
0034  * This will end up in PlaceholderItemProxyModel holding the following indices:
0035  * - "Item1" (from source model)
0036  * - "Item2" (from source model)
0037  * - "(Add new entry)" (from PlaceholderItemProxyModel)
0038  *
0039  * In case the last entry is edited, and a non-empty value is supplied,
0040  * dataInserted() is emitted to notify the user about newly created rows.
0041  * The user then has to make sure the signal is handled accordingly and
0042  * new items are added to the source model.
0043  *
0044  * @see dataInserted
0045  *
0046  * @note WARNING: This implementation is only suitable for flat models
0047  * It will fall apart when you use a tree model as source
0048  */
0049 class KDEVPLATFORMUTIL_EXPORT PlaceholderItemProxyModel : public QIdentityProxyModel
0050 {
0051     Q_OBJECT
0052 
0053 public:
0054     explicit PlaceholderItemProxyModel(QObject* parent = nullptr);
0055     ~PlaceholderItemProxyModel() override;
0056 
0057     QVariant columnHint(int column) const;
0058 
0059     /**
0060      * Set the hint value for @p column to @p hint
0061      *
0062      * This text is going to be displayed in the place holder item row
0063      *
0064      * Only columns with non-empty hints are clickable and editable and
0065      * eventually cause the dataInserted() signal to be triggered
0066      */
0067     void setColumnHint(int column, const QVariant& hint);
0068 
0069     void setSourceModel(QAbstractItemModel* sourceModel) override;
0070 
0071     Qt::ItemFlags flags(const QModelIndex& index) const override;
0072     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
0073     bool hasChildren(const QModelIndex& parent = QModelIndex()) const override;
0074     QVariant data(const QModelIndex& proxyIndex, int role = Qt::DisplayRole) const override;
0075     bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
0076     QModelIndex parent(const QModelIndex& child) const override;
0077     QModelIndex sibling(int row, int column, const QModelIndex& idx) const override;
0078     QModelIndex buddy(const QModelIndex& index) const override;
0079     QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
0080 
0081     QModelIndex mapToSource(const QModelIndex& proxyIndex) const override;
0082 
0083     /**
0084      * Implement in subclass.
0085      *
0086      * @return True in case the input was valid, and the filter should notify
0087      *   external observers via the dataInserted signal.
0088      *
0089      * By default, this method returns true only in case @p value is non-empty
0090      *
0091      * @sa dataInserted()
0092      */
0093     virtual bool validateRow(const QModelIndex& index, const QVariant& value) const;
0094 
0095 Q_SIGNALS:
0096     void dataInserted(int column, const QVariant& values);
0097 
0098 private:
0099     const QScopedPointer<class PlaceholderItemProxyModelPrivate> d_ptr;
0100     Q_DECLARE_PRIVATE(PlaceholderItemProxyModel)
0101 };
0102 
0103 }
0104 
0105 #endif // KDEVPLATFORM_PLACEHOLDERITEMPROXYMODEL_H