File indexing completed on 2024-05-19 04:56:28
0001 /** 0002 * \file checkablelistmodel.h 0003 * Proxy model to use QAbstractItemModel with QML. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 23 Sep 2014 0008 * 0009 * Copyright (C) 2014-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #pragma once 0028 0029 #include <QAbstractProxyModel> 0030 #include <QItemSelectionModel> 0031 0032 /** 0033 * Proxy model to map a hierarchical item model to a list model suitable for 0034 * QML. 0035 * 0036 * Compared with VisualDataModel, this model has a selectionModel property, 0037 * which can be used to have multi selection and queried from delegates using 0038 * the checkState role. Other functions help to improve the support of 0039 * QAbstractItemModel in QML. 0040 */ 0041 class CheckableListModel : public QAbstractProxyModel { 0042 Q_OBJECT 0043 /** Source model, equivalent to the model property of VisualDataModel. */ 0044 Q_PROPERTY(QObject* sourceModel 0045 READ sourceModel WRITE setSourceModelObject 0046 NOTIFY sourceModelChanged) 0047 /** Selection model used to store the selections with the checkState role. */ 0048 Q_PROPERTY(QObject* selectionModel 0049 READ selectionModel WRITE setSelectionModelObject 0050 NOTIFY selectionModelChanged) 0051 /** Root node in the hierarchical source model. */ 0052 Q_PROPERTY(QModelIndex rootIndex READ rootIndex WRITE setRootIndex 0053 NOTIFY rootIndexChanged) 0054 /** Current row. */ 0055 Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow 0056 NOTIFY currentRowChanged) 0057 public: 0058 /** 0059 * Constructor. 0060 * @param parent parent object 0061 */ 0062 explicit CheckableListModel(QObject* parent = nullptr); 0063 0064 /** 0065 * Destructor. 0066 */ 0067 ~CheckableListModel() override = default; 0068 0069 /** 0070 * Get selection model. 0071 * @return selection model. 0072 */ 0073 QItemSelectionModel* selectionModel() const; 0074 0075 /** 0076 * Set selection model. 0077 * @param selModel selection model to use 0078 */ 0079 void setSelectionModel(QItemSelectionModel* selModel); 0080 0081 /** 0082 * Get root node in hierarchical source model. 0083 * @return root model index. 0084 */ 0085 QModelIndex rootIndex() const; 0086 0087 /** 0088 * Set root node in hierarchical source model. 0089 * @param rootIndex root model index 0090 */ 0091 void setRootIndex(const QModelIndex& rootIndex); 0092 0093 /** 0094 * Get data for @a roleName and @a row from model. 0095 * @param row model row 0096 * @param roleName role name as used in scripting languages 0097 * @return model data. 0098 */ 0099 Q_INVOKABLE QVariant getDataValue(int row, const QByteArray& roleName) const; 0100 0101 /** 0102 * Set data for @a roleName and @a row in model. 0103 * This method can be used to assign values in the model because this is not 0104 * supported by the role properties available in the delegate. 0105 * 0106 * @param row model row 0107 * @param roleName role name as used in scripting languages 0108 * @param value model data 0109 * @return true if ok. 0110 */ 0111 Q_INVOKABLE bool setDataValue(int row, const QByteArray& roleName, 0112 const QVariant& value); 0113 0114 /** 0115 * Get model index in the source model. 0116 * @param row model row 0117 * @return model index. 0118 */ 0119 Q_INVOKABLE QModelIndex modelIndex(int row) const; 0120 0121 /** 0122 * Get parent of the current root index. 0123 * This can be used to go up in the hierarchy. 0124 * @return model index of parent. 0125 */ 0126 Q_INVOKABLE QModelIndex parentModelIndex() const; 0127 0128 /** 0129 * Check if a row has children in the source model. 0130 * This can be used to go down in the hierarchy using modelIndex(). 0131 * @param row model row 0132 * @return true if the node has children. 0133 */ 0134 Q_INVOKABLE bool hasModelChildren(int row) const; 0135 0136 /** 0137 * Get the current row. 0138 * @return model row. 0139 */ 0140 int currentRow() const; 0141 0142 /** 0143 * Clear the selection and select @a row as the current index. 0144 * @param row row to select 0145 */ 0146 void setCurrentRow(int row); 0147 0148 /** Set item flags. */ 0149 Qt::ItemFlags flags(const QModelIndex& index) const override; 0150 0151 /** Get data for a given role. */ 0152 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; 0153 0154 /** Set data for a given role. */ 0155 bool setData(const QModelIndex& index, const QVariant& value, 0156 int role = Qt::EditRole) override; 0157 0158 /** Set source model. */ 0159 void setSourceModel(QAbstractItemModel* srcModel) override; 0160 0161 /** Get index in model. */ 0162 QModelIndex index(int row, int column, 0163 const QModelIndex& parent = QModelIndex()) const override; 0164 0165 /** Get parent model index. */ 0166 QModelIndex parent(const QModelIndex& child) const override; 0167 0168 /** Get number of rows under given @a parent. */ 0169 int rowCount(const QModelIndex& parent = QModelIndex()) const override; 0170 0171 /** Get number of columns under given @a parent. */ 0172 int columnCount(const QModelIndex& parent = QModelIndex()) const override; 0173 0174 /** Map proxy index to index of source model. */ 0175 QModelIndex mapToSource(const QModelIndex& proxyIndex) const override; 0176 0177 /** Map index of source model to proxy index. */ 0178 QModelIndex mapFromSource(const QModelIndex& srcIndex) const override; 0179 0180 signals: 0181 /** Emitted when source model is changed. */ 0182 void sourceModelChanged(); 0183 0184 /** Emitted when selection model is changed. */ 0185 void selectionModelChanged(); 0186 0187 /** Emitted when root index is changed. */ 0188 void rootIndexChanged(); 0189 0190 /** Emitted when the current row is changed. */ 0191 void currentRowChanged(int row); 0192 0193 private slots: 0194 void onModelAboutToBeReset(); 0195 void onModelReset(); 0196 void onDataChanged(const QModelIndex& topLeft, 0197 const QModelIndex& bottomRight); 0198 void onRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last); 0199 void onRowsRemoved(const QModelIndex &parent, int first, int last); 0200 void onRowsAboutToBeInserted(const QModelIndex& parent, int first, int last); 0201 void onRowsInserted(const QModelIndex& parent, int first, int last); 0202 void onSelectionChanged(const QItemSelection& selected, 0203 const QItemSelection& deselected); 0204 void onCurrentChanged(const QModelIndex& current, 0205 const QModelIndex& previous); 0206 0207 private: 0208 void setSourceModelObject(QObject* obj); 0209 void setSelectionModelObject(QObject* obj); 0210 0211 QItemSelectionModel* m_selModel; 0212 QPersistentModelIndex m_rootIndex; 0213 };