File indexing completed on 2024-05-12 05:09:52
0001 /*************************************************************************** 0002 Copyright (C) 2008-2009 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 "entrysortmodel.h" 0026 #include "models.h" 0027 #include "fieldcomparison.h" 0028 #include "../field.h" 0029 #include "../entry.h" 0030 0031 using Tellico::EntrySortModel; 0032 0033 EntrySortModel::EntrySortModel(QObject* parent) : AbstractSortModel(parent) { 0034 setDynamicSortFilter(true); 0035 setSortLocaleAware(true); 0036 connect(this, &QAbstractItemModel::modelReset, this, &EntrySortModel::clearData); 0037 } 0038 0039 void EntrySortModel::setFilter(Tellico::FilterPtr filter_) { 0040 if(m_filter != filter_ || (m_filter && *m_filter != *filter_)) { 0041 m_filter = filter_; 0042 invalidateFilter(); 0043 } 0044 } 0045 0046 Tellico::FilterPtr EntrySortModel::filter() const { 0047 return m_filter; 0048 } 0049 0050 bool EntrySortModel::filterAcceptsRow(int row_, const QModelIndex& parent_) const { 0051 if(!m_filter) { 0052 return true; 0053 } 0054 QModelIndex index = sourceModel()->index(row_, 0, parent_); 0055 Q_ASSERT(index.isValid()); 0056 Data::EntryPtr entry = index.data(EntryPtrRole).value<Data::EntryPtr>(); 0057 Q_ASSERT(entry); 0058 return m_filter->matches(entry); 0059 } 0060 0061 bool EntrySortModel::lessThan(const QModelIndex& left_, const QModelIndex& right_) const { 0062 if(sortRole() != EntryPtrRole) { 0063 // for RowCount sorting, if there are no children, then sort by title 0064 if(sortRole() == RowCountRole) { 0065 const int leftCount = left_.data(RowCountRole).toInt(); 0066 const int rightCount = right_.data(RowCountRole).toInt(); 0067 if(leftCount == 0 && rightCount == 0) { 0068 // also, never sort descending by title when sorting parent by count 0069 const int res = left_.data().toString().localeAwareCompare(right_.data().toString()); 0070 return sortOrder() == Qt::DescendingOrder ? (res >= 0) : (res < 0); 0071 } 0072 } 0073 return AbstractSortModel::lessThan(left_, right_); 0074 } 0075 Data::EntryPtr leftEntry = left_.data(EntryPtrRole).value<Data::EntryPtr>(); 0076 Data::EntryPtr rightEntry = right_.data(EntryPtrRole).value<Data::EntryPtr>(); 0077 if(!leftEntry) { 0078 if(rightEntry) { 0079 return true; 0080 } else { 0081 return false; 0082 } 0083 } else if(leftEntry && !rightEntry) { 0084 return false; 0085 } 0086 0087 QModelIndex left = left_; 0088 QModelIndex right = right_; 0089 0090 for(int i = 0; i < 3; ++i) { 0091 FieldComparison* comp = getComparison(left); 0092 if(!comp || !left.isValid() || !right.isValid()) { 0093 return false; 0094 } 0095 0096 const int res = comp->compare(leftEntry, rightEntry); 0097 if(res == 0) { 0098 switch (i) { 0099 case 0: 0100 left = left.model()->index(left.row(), secondarySortColumn()); 0101 right = right.model()->index(right.row(), secondarySortColumn()); 0102 break; 0103 case 1: 0104 left = left.model()->index(left.row(), tertiarySortColumn()); 0105 right = right.model()->index(right.row(), tertiarySortColumn()); 0106 break; 0107 case 2: 0108 return false; 0109 } 0110 } else { 0111 return res < 0; 0112 } 0113 } 0114 return AbstractSortModel::lessThan(left_, right_); 0115 } 0116 0117 void EntrySortModel::clearData() { 0118 m_filter = FilterPtr(); 0119 qDeleteAll(m_comparisons); 0120 m_comparisons.clear(); 0121 } 0122 0123 Tellico::FieldComparison* EntrySortModel::getComparison(const QModelIndex& index_) const { 0124 if(m_comparisons.contains(index_.column())) { 0125 return m_comparisons.value(index_.column()); 0126 } 0127 FieldComparison* comp = nullptr; 0128 if(index_.isValid()) { 0129 Data::FieldPtr field = index_.model()->headerData(index_.column(), Qt::Horizontal, FieldPtrRole).value<Data::FieldPtr>(); 0130 if(field) { 0131 comp = FieldComparison::create(field); 0132 m_comparisons.insert(index_.column(), comp); 0133 } 0134 } 0135 return comp; 0136 }