File indexing completed on 2024-05-12 05:09:52
0001 /*************************************************************************** 0002 Copyright (C) 2011 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "entryselectionmodel.h" 0026 #include "models.h" 0027 #include "../tellico_debug.h" 0028 0029 #include <QSet> 0030 0031 using Tellico::EntrySelectionModel; 0032 0033 EntrySelectionModel::EntrySelectionModel(QAbstractItemModel* targetModel_, 0034 QItemSelectionModel* selModel_, 0035 QObject* parent_) 0036 : KLinkItemSelectionModel(targetModel_, selModel_, parent_) 0037 , m_processing(false) { 0038 addSelectionProxy(selModel_); 0039 // when the entry model is reset, the selection signal is not triggered 0040 // using the modelReset signal does not work 0041 connect(targetModel_, &QAbstractItemModel::modelAboutToBeReset, 0042 this, &QItemSelectionModel::clear); 0043 } 0044 0045 void EntrySelectionModel::addSelectionProxy(QItemSelectionModel* selModel_) { 0046 Q_ASSERT(selModel_); 0047 m_modelList += selModel_; 0048 connect(selModel_, &QItemSelectionModel::selectionChanged, 0049 this, &EntrySelectionModel::selectedEntriesChanged); 0050 connect(selModel_->model(), &QAbstractItemModel::modelAboutToBeReset, 0051 this, [this]() { m_selectedEntries.clear();}); 0052 } 0053 0054 void EntrySelectionModel::selectedEntriesChanged(const QItemSelection& selected_, const QItemSelection& deselected_) { 0055 // when clearSelection() is called on the other models, then there's a cascading series of calls to 0056 // selectedEntriesChanged(). But we only care about the first one 0057 if(m_processing) { 0058 return; 0059 } 0060 m_processing = true; 0061 0062 QItemSelectionModel* selectionModel = qobject_cast<QItemSelectionModel*>(sender()); 0063 Q_ASSERT(selectionModel); 0064 if(!selectionModel) { 0065 m_processing = false; 0066 return; 0067 } 0068 0069 if(m_recentSelectionModel != selectionModel) { 0070 m_selectedEntries.clear(); 0071 } 0072 m_recentSelectionModel = selectionModel; 0073 0074 // clearing the selection in the other models will have cascading calls to selectionChanged() 0075 // now, add and remove selected entries from the list 0076 // the selection will include an index for every column, need to check for duplicates 0077 // can't use a QSet of entries since we want to retain the selection ordering 0078 QSet<Data::ID> IDlist; 0079 foreach(const QModelIndex& index, deselected_.indexes()) { 0080 Data::EntryPtr entry = index.data(EntryPtrRole).value<Data::EntryPtr>(); 0081 if(entry && !IDlist.contains(entry->id())) { 0082 m_selectedEntries.removeOne(entry); 0083 IDlist += entry->id(); 0084 } 0085 } 0086 IDlist.clear(); 0087 foreach(const QModelIndex& index, selected_.indexes()) { 0088 Data::EntryPtr entry = index.data(EntryPtrRole).value<Data::EntryPtr>(); 0089 if(entry && !IDlist.contains(entry->id())) { 0090 m_selectedEntries += entry; 0091 IDlist += entry->id(); 0092 } 0093 } 0094 0095 emit entriesSelected(m_selectedEntries); 0096 // for every selection model which did not call this function, clear the selection 0097 foreach(const QPointer<QItemSelectionModel>& ptr, m_modelList) { //krazy:exclude=foreach 0098 QItemSelectionModel* const otherModel = ptr.data(); 0099 if(otherModel && otherModel != selectionModel) { 0100 otherModel->clearSelection(); 0101 } else if(!otherModel) { 0102 // since the filter or loan view could be created multiple times 0103 // the selection model might be added multiple times 0104 // since foreach() creates a copy of the list, it's ok to remove this here 0105 m_modelList.removeOne(ptr); 0106 } 0107 } 0108 m_processing = false; 0109 }