File indexing completed on 2024-05-19 04:56:04
0001 /** 0002 * \file frametablemodel.h 0003 * Model for table with frames. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 01 May 2011 0008 * 0009 * Copyright (C) 2011-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 #pragma once 0028 0029 #include <QAbstractTableModel> 0030 #include <QVector> 0031 #include <QSet> 0032 #include <QBitArray> 0033 #include "frame.h" 0034 #include "kid3api.h" 0035 0036 class CoreTaggedFileIconProvider; 0037 0038 /** 0039 * Model for table with frames. 0040 */ 0041 class KID3_CORE_EXPORT FrameTableModel : public QAbstractTableModel { 0042 Q_OBJECT 0043 public: 0044 /** Custom role. */ 0045 enum Roles { 0046 FrameTypeRole = Qt::UserRole + 1, 0047 NameRole = Qt::UserRole + 2, 0048 ValueRole = Qt::UserRole + 3, 0049 ModifiedRole = Qt::UserRole + 4, 0050 TruncatedRole = Qt::UserRole + 5, 0051 InternalNameRole = Qt::UserRole + 6, 0052 FieldIdsRole = Qt::UserRole + 7, 0053 FieldValuesRole = Qt::UserRole + 8, 0054 CompletionsRole = Qt::UserRole + 9, 0055 NoticeRole = Qt::UserRole + 10, 0056 NoticeWarningRole = Qt::UserRole + 11 0057 }; 0058 0059 /** Column indices. */ 0060 enum ColumnIndex { 0061 CI_Enable, 0062 CI_Value, 0063 CI_NumColumns 0064 }; 0065 0066 /** 0067 * Constructor. 0068 * @param id3v1 true if model for ID3v1 frames 0069 * @param colorProvider colorProvider 0070 * @param parent parent widget 0071 */ 0072 FrameTableModel(bool id3v1, CoreTaggedFileIconProvider* colorProvider, 0073 QObject* parent = nullptr); 0074 0075 /** 0076 * Destructor. 0077 */ 0078 ~FrameTableModel() override = default; 0079 0080 /** 0081 * Get item flags for index. 0082 * @param index model index 0083 * @return item flags 0084 */ 0085 Qt::ItemFlags flags(const QModelIndex& index) const override; 0086 0087 /** 0088 * Get data for a given role. 0089 * @param index model index 0090 * @param role item data role 0091 * @return data for role 0092 */ 0093 QVariant data(const QModelIndex& index, 0094 int role = Qt::DisplayRole) const override; 0095 0096 /** 0097 * Set data for a given role. 0098 * @param index model index 0099 * @param value data value 0100 * @param role item data role 0101 * @return true if successful 0102 */ 0103 bool setData(const QModelIndex& index, const QVariant& value, 0104 int role = Qt::EditRole) override; 0105 0106 /** 0107 * Get data for header section. 0108 * @param section column or row 0109 * @param orientation horizontal or vertical 0110 * @param role item data role 0111 * @return header data for role 0112 */ 0113 QVariant headerData(int section, Qt::Orientation orientation, 0114 int role = Qt::DisplayRole) const override; 0115 0116 /** 0117 * Set data for header section. 0118 * Not supported. 0119 * @return false 0120 */ 0121 bool setHeaderData(int, Qt::Orientation, const QVariant&, 0122 int = Qt::EditRole) override { return false; } 0123 0124 /** 0125 * Get number of rows. 0126 * @param parent parent model index, invalid for table models 0127 * @return number of rows, 0128 * if parent is valid number of children (0 for table models) 0129 */ 0130 int rowCount(const QModelIndex& parent = QModelIndex()) const override; 0131 0132 /** 0133 * Get number of columns. 0134 * @param parent parent model index, invalid for table models 0135 * @return number of columns, 0136 * if parent is valid number of children (0 for table models) 0137 */ 0138 int columnCount(const QModelIndex& parent = QModelIndex()) const override; 0139 0140 /** 0141 * Remove rows. 0142 * @param row rows are removed starting with this row 0143 * @param count number of rows to remove 0144 * @param parent parent model index, invalid for table models 0145 * @return true if successful 0146 */ 0147 bool removeRows(int row, int count, 0148 const QModelIndex& parent = QModelIndex()) override; 0149 0150 /** 0151 * Insert rows. 0152 * @param row rows are inserted before this row, if 0 at the begin, 0153 * if rowCount() at the end 0154 * @param count number of rows to insert 0155 * @param parent parent model index, invalid for table models 0156 * @return true if successful 0157 */ 0158 bool insertRows(int row, int count, 0159 const QModelIndex& parent = QModelIndex()) override; 0160 0161 /** 0162 * Map role identifiers to role property names in scripting languages. 0163 * @return hash mapping role identifiers to names. 0164 */ 0165 QHash<int,QByteArray> roleNames() const override; 0166 0167 /** 0168 * Insert a frame. 0169 * @param frame frame to insert 0170 */ 0171 void insertFrame(const Frame& frame); 0172 0173 /** 0174 * Check if model is for ID3v1 frames. 0175 * @return true if for ID3v1. 0176 */ 0177 bool isId3v1() const { return m_id3v1; } 0178 0179 /** 0180 * Mark rows. 0181 * @param rowMask mask with bits of rows to mark 0182 */ 0183 void markRows(quint64 rowMask); 0184 0185 0186 /** 0187 * Mark changed frames. 0188 * @param types frame types to mark 0189 */ 0190 void markChangedFrames(const QList<Frame::ExtendedType>& types); 0191 0192 /** 0193 * Get frame for index. 0194 * @param index model index 0195 * @return frame, 0 if no frame. 0196 */ 0197 const Frame* getFrameOfIndex(const QModelIndex& index) const; 0198 0199 /** 0200 * Get row with frame with a specific frame index. 0201 * @param index frame index 0202 * @return row number, -1 if not found. 0203 */ 0204 int getRowWithFrameIndex(int index) const; 0205 0206 /** 0207 * Get row with frame with a specific frame name. 0208 * @param name name of frame 0209 * @return row number, -1 if not found. 0210 */ 0211 int getRowWithFrameName(const QString& name) const; 0212 0213 /** 0214 * Get filter with enabled frames. 0215 * 0216 * @param allDisabledToAllEnabled true to enable all if all are disabled 0217 * 0218 * @return filter with enabled frames. 0219 */ 0220 FrameFilter getEnabledFrameFilter(bool allDisabledToAllEnabled = false) const; 0221 0222 /** 0223 * Set the check state of all frames in the table. 0224 * 0225 * @param checked true to check the frames 0226 */ 0227 void setAllCheckStates(bool checked); 0228 0229 /** 0230 * Get reference to frame collection. 0231 * @return frame collection. 0232 */ 0233 const FrameCollection& frames() const { return m_frames; } 0234 0235 /** 0236 * Get enabled frames. 0237 * @return frame collection with enabled frames. 0238 */ 0239 FrameCollection getEnabledFrames() const; 0240 0241 /** 0242 * Clear frame collection. 0243 */ 0244 void clearFrames(); 0245 0246 /** 0247 * Transfer frames to frame collection. 0248 * @param src frames to move into frame collection, will be cleared 0249 */ 0250 void transferFrames(FrameCollection& src); 0251 0252 /** 0253 * Start filtering different values. 0254 */ 0255 void beginFilterDifferent(); 0256 0257 /** 0258 * Set values which are different inactive. 0259 * 0260 * @param others frames to compare, will be modified 0261 */ 0262 void filterDifferent(FrameCollection& others); 0263 0264 /** 0265 * End filtering different values. 0266 */ 0267 void endFilterDifferent(); 0268 0269 /** 0270 * Get the different values which have been filtered for a frame type. 0271 * @param type frame type 0272 * @return different values. 0273 */ 0274 QSet<QString> getCompletionsForType(Frame::ExtendedType type) const; 0275 0276 /** 0277 * Set if headerData() shall return empty values. 0278 * This can be used to avoid having text fragments visible in the header of 0279 * frame table columns. 0280 * @param empty true to use empty values, default is false 0281 */ 0282 void setHeadersEmpty(bool empty) { m_emptyHeaders = empty; } 0283 bool headersEmpty() const { return m_emptyHeaders; } 0284 0285 public slots: 0286 /** 0287 * Select all frames in the table. 0288 */ 0289 void selectAllFrames(); 0290 0291 /** 0292 * Deselect all frames in the table. 0293 */ 0294 void deselectAllFrames(); 0295 0296 /** 0297 * Select changed frames in the table. 0298 */ 0299 void selectChangedFrames(); 0300 0301 /** 0302 * Set order of frames in frame table. 0303 * @param frameTypes ordered sequence of frame types 0304 * @see TagConfig::quickAccessFrameOrder(). 0305 */ 0306 void setFrameOrder(const QList<int>& frameTypes); 0307 0308 private: 0309 /** 0310 * Get the frame at a specific position in the collection. 0311 * @param row position of frame 0312 * @return iterator to frame 0313 */ 0314 FrameCollection::iterator frameAt(int row) const; 0315 0316 /** 0317 * Get the row corresponding to a frame iterator. 0318 * @param frameIt frame iterator 0319 * @return row number, number of rows if not found. 0320 */ 0321 int rowOf(FrameCollection::iterator frameIt) const; 0322 0323 /** 0324 * Resize the bit array with the frame selection to match the frames size. 0325 */ 0326 void resizeFrameSelected(); 0327 0328 /** 0329 * Update the frame to row mapping. 0330 */ 0331 void updateFrameRowMapping(); 0332 0333 QBitArray m_frameSelected; 0334 quint64 m_markedRows; 0335 quint64 m_changedFrames; 0336 QSet<QString> m_changedOtherFrameNames; 0337 FrameCollection m_frames; 0338 QVector<FrameCollection::iterator> m_frameOfRow; 0339 QHash<Frame::ExtendedType, QSet<QString>> m_differentValues; 0340 QVector<int> m_frameTypeSeqNr; 0341 CoreTaggedFileIconProvider* m_colorProvider; 0342 bool m_id3v1; 0343 bool m_emptyHeaders; 0344 };