File indexing completed on 2024-05-12 16:46:10
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 } 0051 0052 void EntrySelectionModel::selectedEntriesChanged(const QItemSelection& selected_, const QItemSelection& deselected_) { 0053 // when clearSelection() is called on the other models, then there's a cascading series of calls to 0054 // selectedEntriesChanged(). But we only care about the first one 0055 if(m_processing) { 0056 return; 0057 } 0058 m_processing = true; 0059 0060 QItemSelectionModel* selectionModel = qobject_cast<QItemSelectionModel*>(sender()); 0061 Q_ASSERT(selectionModel); 0062 if(!selectionModel) { 0063 m_processing = false; 0064 return; 0065 } 0066 0067 if(m_recentSelectionModel != selectionModel) { 0068 m_selectedEntries.clear(); 0069 } 0070 m_recentSelectionModel = selectionModel; 0071 0072 // clearing the selection in the other models will have cascading calls to selectionChanged() 0073 // now, add and remove selected entries from the list 0074 // the selection will include an index for every column, need to check for duplicates 0075 // can't use a QSet of entries since we want to retain the selection ordering 0076 QSet<Data::ID> IDlist; 0077 foreach(const QModelIndex& index, deselected_.indexes()) { 0078 Data::EntryPtr entry = index.data(EntryPtrRole).value<Data::EntryPtr>(); 0079 if(entry && !IDlist.contains(entry->id())) { 0080 m_selectedEntries.removeOne(entry); 0081 IDlist += entry->id(); 0082 } 0083 } 0084 IDlist.clear(); 0085 foreach(const QModelIndex& index, selected_.indexes()) { 0086 Data::EntryPtr entry = index.data(EntryPtrRole).value<Data::EntryPtr>(); 0087 if(entry && !IDlist.contains(entry->id())) { 0088 m_selectedEntries += entry; 0089 IDlist += entry->id(); 0090 } 0091 } 0092 0093 emit entriesSelected(m_selectedEntries); 0094 // for every selection model which did not call this function, clear the selection 0095 foreach(const QPointer<QItemSelectionModel>& ptr, m_modelList) { //krazy:exclude=foreach 0096 QItemSelectionModel* const otherModel = ptr.data(); 0097 if(otherModel && otherModel != selectionModel) { 0098 otherModel->clearSelection(); 0099 } else if(!otherModel) { 0100 // since the filter or loan view could be created multiple times 0101 // the selection model might be added multiple times 0102 // since foreach() creates a copy of the list, it's ok to remove this here 0103 m_modelList.removeOne(ptr); 0104 } 0105 } 0106 m_processing = false; 0107 }