File indexing completed on 2024-05-19 04:56:08

0001 /**
0002  * \file taggedfilesystemmodel.h
0003  * Filesystem model which additional columns.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 08-Aug-2021
0008  *
0009  * Copyright (C) 2021-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 "filesystemmodel.h"
0030 #include "taggedfile.h"
0031 #include "kid3api.h"
0032 
0033 class CoreTaggedFileIconProvider;
0034 class ITaggedFileFactory;
0035 
0036 class KID3_CORE_EXPORT TaggedFileSystemModel : public FileSystemModel {
0037   Q_OBJECT
0038 public:
0039   /** Number of columns in FileSystemModel. */
0040   static const int NUM_FILESYSTEM_COLUMNS = 4;
0041 
0042   /** Custom role, extending FileSystemModel::Roles. */
0043   enum Roles {
0044     TaggedFileRole = Qt::UserRole + 4,
0045     IconIdRole = Qt::UserRole + 5,
0046     TruncatedRole =  Qt::UserRole + 6,
0047     IsDirRole = Qt::UserRole + 7
0048   };
0049 
0050   /**
0051    * Constructor.
0052    * @param iconProvider icon provider
0053    * @param parent parent object
0054    */
0055   explicit TaggedFileSystemModel(CoreTaggedFileIconProvider* iconProvider,
0056                                  QObject* parent = nullptr);
0057 
0058   /**
0059    * Destructor.
0060    */
0061   ~TaggedFileSystemModel() override;
0062 
0063   /**
0064    * Get data for a given role.
0065    * @param index model index
0066    * @param role item data role
0067    * @return data for role
0068    */
0069   QVariant data(const QModelIndex& index,
0070                 int role = Qt::DisplayRole) const override;
0071 
0072   /**
0073    * Set data for a given role.
0074    * @param index model index
0075    * @param value data value
0076    * @param role item data role
0077    * @return true if successful
0078    */
0079   bool setData(const QModelIndex& index, const QVariant& value,
0080                int role = Qt::EditRole) override;
0081 
0082   /**
0083    * Get data for header section.
0084    * @param section column or row
0085    * @param orientation horizontal or vertical
0086    * @param role item data role
0087    * @return header data for role
0088    */
0089   QVariant headerData(int section, Qt::Orientation orientation,
0090                       int role = Qt::DisplayRole) const override;
0091 
0092   QModelIndex sibling(int row, int column,
0093                       const QModelIndex& idx) const override;
0094   int columnCount(
0095       const QModelIndex& parent = QModelIndex()) const override;
0096 
0097   /**
0098    * Rename file or directory of @a index to @a newName.
0099    * @return true if ok
0100    */
0101   bool rename(const QModelIndex& index, const QString& newName);
0102 
0103   /**
0104    * Get icon provider.
0105    * @return icon provider.
0106    */
0107   CoreTaggedFileIconProvider* getIconProvider() const { return m_iconProvider; }
0108 
0109   /**
0110    * Called from tagged file to notify modification state changes.
0111    * @param index model index
0112    * @param modified true if file is modified
0113    */
0114   void notifyModificationChanged(const QModelIndex& index, bool modified);
0115 
0116   /**
0117    * Called from tagged file to notify changes in extra model data, e.g. the
0118    * information on which the CoreTaggedFileIconProvider depends.
0119    * @param index model index
0120    */
0121   void notifyModelDataChanged(const QModelIndex& index);
0122 
0123   /**
0124    * Access to tagged file factories.
0125    * @return reference to tagged file factories.
0126    */
0127   static QList<ITaggedFileFactory*>& taggedFileFactories() {
0128     return s_taggedFileFactories;
0129   }
0130 
0131   /**
0132    * Create a tagged file with a given feature.
0133    *
0134    * @param feature tagged file feature
0135    * @param fileName filename
0136    * @param idx model index
0137    *
0138    * @return tagged file, 0 if feature not found or type not supported.
0139    */
0140   static TaggedFile* createTaggedFile(
0141       TaggedFile::Feature feature,
0142       const QString& fileName,
0143       const QPersistentModelIndex& idx);
0144 
0145   /**
0146    * Create a tagged file.
0147    *
0148    * @param fileName filename
0149    * @param idx model index
0150    *
0151    * @return tagged file, 0 if not found or type not supported.
0152    */
0153   static TaggedFile* createTaggedFile(
0154       const QString& fileName,
0155       const QPersistentModelIndex& idx);
0156 
0157   /**
0158    * Get tagged file data of model index.
0159    *
0160    * @param index model index
0161    * @param taggedFile a TaggedFile pointer is returned here
0162    *
0163    * @return true if index has a tagged file, *taggedFile is set to the pointer.
0164    */
0165   static bool getTaggedFileOfIndex(const QModelIndex& index,
0166                                    TaggedFile** taggedFile);
0167 
0168   /**
0169    * Get tagged file of model index.
0170    *
0171    * @param index model index
0172    *
0173    * @return tagged file, 0 is returned if the index does not contain a
0174    * TaggedFile or if has a TaggedFile which is null.
0175    */
0176   static TaggedFile* getTaggedFileOfIndex(const QModelIndex& index);
0177 
0178 signals:
0179   /**
0180    * Emitted when the modification state of a file changes.
0181    * @param index model index
0182    * @param modified true if file is modified
0183    */
0184   void fileModificationChanged(const QModelIndex& index, bool modified);
0185 
0186 protected slots:
0187   /**
0188    * Reset internal data of the model.
0189    * Is called from endResetModel().
0190    */
0191 #if QT_VERSION >= 0x060000
0192   void resetInternalData() override;
0193 #else
0194   void resetInternalData();
0195 #endif
0196 
0197 private slots:
0198   /**
0199    * Update the TaggedFile contents for rows inserted into the model.
0200    * @param parent parent model index
0201    * @param start starting row
0202    * @param end ending row
0203    */
0204   void updateInsertedRows(const QModelIndex& parent, int start, int end);
0205 
0206 private:
0207   /**
0208    * Retrieve tagged file for an index.
0209    * @param index model index
0210    * @return QVariant with tagged file, invalid QVariant if not found.
0211    */
0212   QVariant retrieveTaggedFileVariant(const QPersistentModelIndex& index) const;
0213 
0214   /**
0215    * Store tagged file from variant with index.
0216    * @param index model index
0217    * @param value QVariant containing tagged file
0218    * @return true if index and value valid
0219    */
0220   bool storeTaggedFileVariant(const QPersistentModelIndex& index,
0221                               const QVariant& value);
0222 
0223   /**
0224    * Clear store with tagged files.
0225    */
0226   void clearTaggedFileStore();
0227 
0228   /**
0229    * Initialize tagged file for model index.
0230    * @param index model index
0231    */
0232   void initTaggedFileData(const QModelIndex& index);
0233 
0234   QHash<QPersistentModelIndex, TaggedFile*> m_taggedFiles;
0235   QList<Frame::Type> m_tagFrameColumnTypes;
0236   CoreTaggedFileIconProvider* m_iconProvider;
0237 
0238   static QList<ITaggedFileFactory*> s_taggedFileFactories;
0239 };
0240 
0241 Q_DECLARE_METATYPE(TaggedFile*)