File indexing completed on 2024-04-14 04:36:55
0001 /*************************************************************************** 0002 * Copyright (C) 2018 by Emmanuel Lepage Vallee * 0003 * Author : Emmanuel Lepage Vallee <emmanuel.lepage@kde.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 3 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0017 **************************************************************************/ 0018 #include "qmodelindexwatcher.h" 0019 0020 // Qt 0021 #include <QQmlEngine> 0022 #include <QQmlContext> 0023 0024 // KQuickItemViews 0025 #include <contextadapterfactory.h> 0026 #include <adapters/contextadapter.h> 0027 0028 class QModelIndexWatcherPrivate : public QObject 0029 { 0030 Q_OBJECT 0031 public: 0032 QAbstractItemModel *m_pModel {nullptr}; 0033 QPersistentModelIndex m_Index { }; 0034 0035 QModelIndexWatcher *q_ptr; 0036 0037 public Q_SLOTS: 0038 void slotDismiss(); 0039 void slotDataChanged(const QModelIndex &tl, const QModelIndex &br, const QVector<int> &roles); 0040 void slotRemoved(const QModelIndex &parent, int first, int last); 0041 void slotRowsMoved(const QModelIndex &p, int start, int end, 0042 const QModelIndex &dest, int row); 0043 }; 0044 0045 QModelIndexWatcher::QModelIndexWatcher(QObject *parent) : QObject(parent), 0046 d_ptr(new QModelIndexWatcherPrivate()) 0047 { 0048 d_ptr->q_ptr = this; 0049 } 0050 0051 QModelIndexWatcher::~QModelIndexWatcher() 0052 { 0053 delete d_ptr; 0054 } 0055 0056 QModelIndex QModelIndexWatcher::modelIndex() const 0057 { 0058 return d_ptr->m_Index; 0059 } 0060 0061 QAbstractItemModel *QModelIndexWatcher::model() const 0062 { 0063 return d_ptr->m_pModel; 0064 } 0065 0066 bool QModelIndexWatcher::isValid() const 0067 { 0068 return d_ptr->m_Index.isValid(); 0069 } 0070 0071 void QModelIndexWatcher::setModelIndex(const QModelIndex &index) 0072 { 0073 if (index == d_ptr->m_Index) 0074 return; 0075 0076 // Disconnect old models 0077 if (d_ptr->m_pModel && d_ptr->m_pModel != index.model()) 0078 d_ptr->slotDismiss(); 0079 0080 0081 if (d_ptr->m_pModel != index.model()) { 0082 0083 d_ptr->m_pModel = const_cast<QAbstractItemModel*>(index.model()); 0084 0085 connect(d_ptr->m_pModel, &QAbstractItemModel::destroyed, 0086 d_ptr, &QModelIndexWatcherPrivate::slotDismiss); 0087 connect(d_ptr->m_pModel, &QAbstractItemModel::dataChanged, 0088 d_ptr, &QModelIndexWatcherPrivate::slotDataChanged); 0089 connect(d_ptr->m_pModel, &QAbstractItemModel::rowsAboutToBeRemoved, 0090 d_ptr, &QModelIndexWatcherPrivate::slotRemoved); 0091 connect(d_ptr->m_pModel, &QAbstractItemModel::rowsMoved, 0092 d_ptr, &QModelIndexWatcherPrivate::slotRowsMoved); 0093 } 0094 0095 d_ptr->m_Index = index; 0096 0097 emit indexChanged(); 0098 emit validChanged(); 0099 } 0100 0101 void QModelIndexWatcherPrivate::slotDismiss() 0102 { 0103 disconnect(m_pModel, &QAbstractItemModel::destroyed, 0104 this, &QModelIndexWatcherPrivate::slotDismiss); 0105 disconnect(m_pModel, &QAbstractItemModel::dataChanged, 0106 this, &QModelIndexWatcherPrivate::slotDataChanged); 0107 disconnect(m_pModel, &QAbstractItemModel::rowsAboutToBeRemoved, 0108 this, &QModelIndexWatcherPrivate::slotRemoved); 0109 disconnect(m_pModel, &QAbstractItemModel::rowsMoved, 0110 this, &QModelIndexWatcherPrivate::slotRowsMoved); 0111 0112 m_pModel = nullptr; 0113 m_Index = QModelIndex(); 0114 emit q_ptr->indexChanged(); 0115 emit q_ptr->removed(); 0116 } 0117 0118 void QModelIndexWatcherPrivate::slotDataChanged(const QModelIndex &tl, const QModelIndex &br, const QVector<int> &roles) 0119 { 0120 if (tl.parent() != m_Index.parent()) 0121 return; 0122 0123 if (tl.row() > m_Index.row() || br.row() < m_Index.row()) 0124 return; 0125 0126 if (tl.column() > m_Index.column() || br.column() < m_Index.column()) 0127 return; 0128 0129 emit q_ptr->dataChanged(roles); 0130 } 0131 0132 void QModelIndexWatcherPrivate::slotRemoved(const QModelIndex &parent, int first, int last) 0133 { 0134 if (parent != m_Index.parent() || !(m_Index.row() >= first && m_Index.row() <= last)) 0135 return; 0136 0137 emit q_ptr->removed(); 0138 emit q_ptr->validChanged(); 0139 0140 slotDismiss(); 0141 } 0142 0143 void QModelIndexWatcherPrivate::slotRowsMoved(const QModelIndex &p, int start, int end, const QModelIndex &dest, int row) 0144 { 0145 Q_UNUSED(p) 0146 Q_UNUSED(start) 0147 Q_UNUSED(end) 0148 Q_UNUSED(dest) 0149 Q_UNUSED(row) 0150 //TODO 0151 } 0152 0153 #include <qmodelindexwatcher.moc>