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>