File indexing completed on 2024-05-19 04:55:57
0001 /** 0002 * \file starratingmappingsmodel.cpp 0003 * Star rating mappings configuration table model. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 2 Jan 2018 0008 * 0009 * Copyright (C) 2018-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #include "starratingmappingsmodel.h" 0028 0029 /** Column indices. */ 0030 enum ColumnIndex { 0031 CI_Name = 0, 0032 CI_NumColumns = 6 0033 }; 0034 0035 /** 0036 * Constructor. 0037 * @param parent parent widget 0038 */ 0039 StarRatingMappingsModel::StarRatingMappingsModel(QObject* parent) 0040 : QAbstractTableModel(parent) 0041 { 0042 setObjectName(QLatin1String("StarRatingMappingsModel")); 0043 } 0044 0045 /** 0046 * Get item flags for index. 0047 * @param index model index 0048 * @return item flags 0049 */ 0050 Qt::ItemFlags StarRatingMappingsModel::flags(const QModelIndex& index) const 0051 { 0052 Qt::ItemFlags theFlags = QAbstractTableModel::flags(index); 0053 if (index.isValid()) { 0054 theFlags |= Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; 0055 } 0056 return theFlags; 0057 } 0058 0059 /** 0060 * Get data for a given role. 0061 * @param index model index 0062 * @param role item data role 0063 * @return data for role 0064 */ 0065 QVariant StarRatingMappingsModel::data(const QModelIndex& index, int role) const 0066 { 0067 if (!index.isValid() || 0068 index.row() < 0 || index.row() >= m_maps.size() || 0069 index.column() < 0 || index.column() >= CI_NumColumns) 0070 return QVariant(); 0071 const QPair<QString, QVector<int> >& item = m_maps.at(index.row()); 0072 if (role == Qt::DisplayRole || role == Qt::EditRole) { 0073 if (index.column() == CI_Name) { 0074 return item.first; 0075 } 0076 if (item.second.size() >= index.column()) { 0077 return item.second.at(index.column() - 1); 0078 } 0079 } 0080 return QVariant(); 0081 } 0082 0083 /** 0084 * Set data for a given role. 0085 * @param index model index 0086 * @param value data value 0087 * @param role item data role 0088 * @return true if successful 0089 */ 0090 bool StarRatingMappingsModel::setData(const QModelIndex& index, 0091 const QVariant& value, int role) 0092 { 0093 if (!index.isValid() || 0094 index.row() < 0 || index.row() >= m_maps.size() || 0095 index.column() < 0 || index.column() >= CI_NumColumns) 0096 return false; 0097 QPair<QString, QVector<int> >& item = m_maps[index.row()]; // clazy:exclude=detaching-member 0098 bool changed = false; 0099 if (role == Qt::EditRole) { 0100 if (index.column() == CI_Name) { 0101 item.first = value.toString(); 0102 changed = true; 0103 } else if (item.second.size() >= index.column()) { 0104 item.second[index.column() - 1] = value.toInt(); 0105 changed = true; 0106 } 0107 if (changed) { 0108 makeRowValid(index.row()); 0109 emit dataChanged(index, index); 0110 } 0111 } 0112 return changed; 0113 } 0114 0115 /** 0116 * Get data for header section. 0117 * @param section column or row 0118 * @param orientation horizontal or vertical 0119 * @param role item data role 0120 * @return header data for role 0121 */ 0122 QVariant StarRatingMappingsModel::headerData( 0123 int section, Qt::Orientation orientation, int role) const 0124 { 0125 if (role != Qt::DisplayRole) 0126 return QVariant(); 0127 if (orientation == Qt::Horizontal) { 0128 if (section == CI_Name) { 0129 return tr("Name"); 0130 } 0131 if (section < CI_NumColumns) { 0132 return section; 0133 } 0134 } 0135 return section + 1; 0136 } 0137 0138 /** 0139 * Get number of rows. 0140 * @param parent parent model index, invalid for table models 0141 * @return number of rows, 0142 * if parent is valid number of children (0 for table models) 0143 */ 0144 int StarRatingMappingsModel::rowCount(const QModelIndex& parent) const 0145 { 0146 return parent.isValid() ? 0 : m_maps.size(); 0147 } 0148 0149 /** 0150 * Get number of columns. 0151 * @param parent parent model index, invalid for table models 0152 * @return number of columns, 0153 * if parent is valid number of children (0 for table models) 0154 */ 0155 int StarRatingMappingsModel::columnCount(const QModelIndex& parent) const 0156 { 0157 return parent.isValid() ? 0 : CI_NumColumns; 0158 } 0159 0160 /** 0161 * Insert rows. 0162 * @param row rows are inserted before this row, if 0 at the begin, 0163 * if rowCount() at the end 0164 * @param count number of rows to insert 0165 * @return true if successful 0166 */ 0167 bool StarRatingMappingsModel::insertRows(int row, int count, 0168 const QModelIndex&) 0169 { 0170 if (count > 0) { 0171 beginInsertRows(QModelIndex(), row, row + count - 1); 0172 for (int i = 0; i < count; ++i) { 0173 m_maps.insert(row, qMakePair(QString(), QVector<int>(CI_NumColumns - 1))); 0174 makeRowValid(row); 0175 } 0176 endInsertRows(); 0177 } 0178 return true; 0179 } 0180 0181 /** 0182 * Remove rows. 0183 * @param row rows are removed starting with this row 0184 * @param count number of rows to remove 0185 * @return true if successful 0186 */ 0187 bool StarRatingMappingsModel::removeRows(int row, int count, 0188 const QModelIndex&) 0189 { 0190 if (count > 0) { 0191 beginRemoveRows(QModelIndex(), row, row + count - 1); 0192 for (int i = 0; i < count; ++i) 0193 m_maps.removeAt(row); 0194 endRemoveRows(); 0195 } 0196 return true; 0197 } 0198 0199 /** 0200 * Set the model from the star count mappings. 0201 * @param maps star count mappings 0202 */ 0203 void StarRatingMappingsModel::setMappings( 0204 const QList<QPair<QString, QVector<int> > >& maps) 0205 { 0206 beginResetModel(); 0207 m_maps = maps; 0208 endResetModel(); 0209 } 0210 0211 /** 0212 * Get the start count mappings from the model. 0213 * @return star count mappings 0214 */ 0215 QList<QPair<QString, QVector<int> > > StarRatingMappingsModel::getMappings() const 0216 { 0217 return m_maps; 0218 } 0219 0220 /** 0221 * Make sure that @a row contains valid values. 0222 */ 0223 void StarRatingMappingsModel::makeRowValid(int row) 0224 { 0225 QString& type = m_maps[row].first; // clazy:exclude=detaching-member 0226 type = type.trimmed(); 0227 if (type == QLatin1String("POPM.")) { 0228 type.truncate(4); 0229 } 0230 QVector<int>& values = m_maps[row].second; // clazy:exclude=detaching-member 0231 int previousValue = 0; 0232 for (auto it = values.begin(); it != values.end(); ++it) { 0233 if (*it <= previousValue) { 0234 *it = previousValue + 1; 0235 } 0236 previousValue = *it; 0237 } 0238 }