File indexing completed on 2024-04-28 05:47:43
0001 /* 0002 SPDX-FileCopyrightText: 2007 Henrique Pinto <henrique.pinto@kdemail.net> 0003 SPDX-FileCopyrightText: 2008-2009 Harald Hvaal <haraldhv@stud.ntnu.no> 0004 SPDX-FileCopyrightText: 2016 Vladyslav Batyrenko <mvlabat@gmail.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 #ifndef ARCHIVEMODEL_H 0009 #define ARCHIVEMODEL_H 0010 0011 #include "archiveentry.h" 0012 0013 #include <KMessageWidget> 0014 0015 #include <QAbstractItemModel> 0016 #include <QScopedPointer> 0017 0018 using Kerfuffle::Archive; 0019 0020 namespace Kerfuffle 0021 { 0022 class Query; 0023 } 0024 0025 /** 0026 * Meta data related to one entry in a compressed archive. 0027 * 0028 * This is used for indexing entry properties as numbers 0029 * and for determining data displaying order in part's view. 0030 */ 0031 enum EntryMetaDataType { 0032 DisplayName, /**< The entry's name that will be displayed in the view */ 0033 Size, /**< The entry's original size */ 0034 CompressedSize, /**< The compressed size for the entry */ 0035 Permissions, /**< The entry's permissions */ 0036 Owner, /**< The user the entry belongs to */ 0037 Group, /**< The user group the entry belongs to */ 0038 Ratio, /**< The compression ratio for the entry */ 0039 CRC, /**< The entry's CRC */ 0040 BLAKE2, /**< The entry's BLAKE2 */ 0041 Method, /**< The compression method used on the entry */ 0042 Version, /**< The archiver version needed to extract the entry */ 0043 Timestamp /**< The timestamp for the current entry */ 0044 }; 0045 0046 class ArchiveModel : public QAbstractItemModel 0047 { 0048 Q_OBJECT 0049 public: 0050 explicit ArchiveModel(const QString &dbusPathName, QObject *parent = nullptr); 0051 ~ArchiveModel() override; 0052 0053 QVariant data(const QModelIndex &index, int role) const override; 0054 Qt::ItemFlags flags(const QModelIndex &index) const override; 0055 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; 0056 QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; 0057 QModelIndex parent(const QModelIndex &index) const override; 0058 int rowCount(const QModelIndex &parent = QModelIndex()) const override; 0059 int columnCount(const QModelIndex &parent = QModelIndex()) const override; 0060 0061 // drag and drop related 0062 Qt::DropActions supportedDropActions() const override; 0063 QStringList mimeTypes() const override; 0064 QMimeData *mimeData(const QModelIndexList &indexes) const override; 0065 bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; 0066 0067 void reset(); 0068 void createEmptyArchive(const QString &path, const QString &mimeType, QObject *parent); 0069 Kerfuffle::LoadJob *loadArchive(const QString &path, const QString &mimeType, QObject *parent); 0070 Kerfuffle::Archive *archive() const; 0071 0072 QList<int> shownColumns() const; 0073 QMap<int, QByteArray> propertiesMap() const; 0074 0075 Archive::Entry *entryForIndex(const QModelIndex &index); 0076 0077 Kerfuffle::ExtractJob * 0078 extractFile(Archive::Entry *file, const QString &destinationDir, Kerfuffle::ExtractionOptions options = Kerfuffle::ExtractionOptions()) const; 0079 Kerfuffle::ExtractJob *extractFiles(const QVector<Archive::Entry *> &files, 0080 const QString &destinationDir, 0081 Kerfuffle::ExtractionOptions options = Kerfuffle::ExtractionOptions()) const; 0082 0083 Kerfuffle::PreviewJob *preview(Archive::Entry *file) const; 0084 Kerfuffle::OpenJob *open(Archive::Entry *file) const; 0085 Kerfuffle::OpenWithJob *openWith(Archive::Entry *file) const; 0086 0087 Kerfuffle::AddJob *addFiles(QVector<Archive::Entry *> &entries, 0088 const Archive::Entry *destination, 0089 const Kerfuffle::CompressionOptions &options = Kerfuffle::CompressionOptions()); 0090 Kerfuffle::MoveJob * 0091 moveFiles(QVector<Archive::Entry *> &entries, Archive::Entry *destination, const Kerfuffle::CompressionOptions &options = Kerfuffle::CompressionOptions()); 0092 Kerfuffle::CopyJob * 0093 copyFiles(QVector<Archive::Entry *> &entries, Archive::Entry *destination, const Kerfuffle::CompressionOptions &options = Kerfuffle::CompressionOptions()); 0094 Kerfuffle::DeleteJob *deleteFiles(QVector<Archive::Entry *> entries); 0095 0096 /** 0097 * @param password The password to encrypt the archive with. 0098 * @param encryptHeader Whether to encrypt also the list of files. 0099 */ 0100 void encryptArchive(const QString &password, bool encryptHeader); 0101 0102 void countEntriesAndSize(); 0103 qulonglong numberOfFiles() const; 0104 qulonglong numberOfFolders() const; 0105 qulonglong uncompressedSize() const; 0106 0107 /** 0108 * Constructs a list of conflicting entries. 0109 * 0110 * @param conflictingEntries Reference to the empty mutable entries list, which will be constructed. 0111 * If the method returns false, this list will contain only entries which produce a critical conflict. 0112 * @param entries New entries paths list. 0113 * @param allowMerging Boolean variable indicating whether merging is permitted. 0114 * If true, existing entries won't generate an error. 0115 * 0116 * @return Boolean variable indicating whether conflicts are not critical (true for not critical, 0117 * false for critical). For example, if there are both "some/file" (not a directory) and "some/file/" (a directory) 0118 * entries for both new and existing paths, the method will return false. Also, if merging is not allowed, 0119 * this method will return false for entries with the same path and types. 0120 */ 0121 bool conflictingEntries(QList<const Archive::Entry *> &conflictingEntries, const QStringList &entries, bool allowMerging) const; 0122 0123 static bool hasDuplicatedEntries(const QStringList &entries); 0124 0125 static QMap<QString, Archive::Entry *> entryMap(const QVector<Archive::Entry *> &entries); 0126 0127 QMap<QString, Kerfuffle::Archive::Entry *> filesToMove; 0128 QMap<QString, Kerfuffle::Archive::Entry *> filesToCopy; 0129 0130 Q_SIGNALS: 0131 void loadingStarted(); 0132 void loadingFinished(KJob *); 0133 void error(const QString &error, const QString &details); 0134 void droppedFiles(const QStringList &files, const Archive::Entry *); 0135 void messageWidget(KMessageWidget::MessageType type, const QString &msg); 0136 0137 private Q_SLOTS: 0138 void slotNewEntry(Archive::Entry *entry); 0139 void slotListEntry(Archive::Entry *entry); 0140 void slotLoadingFinished(KJob *job); 0141 void slotEntryRemoved(const QString &path); 0142 void slotUserQuery(Kerfuffle::Query *query); 0143 void slotCleanupEmptyDirs(); 0144 0145 private: 0146 /** 0147 * Strips file names that start with './'. 0148 * 0149 * For more information, see bug 194241. 0150 * 0151 * @param fileName The file name that will be stripped. 0152 * 0153 * @return @p fileName without the leading './' 0154 */ 0155 QString cleanFileName(const QString &fileName); 0156 0157 void initRootEntry(); 0158 0159 enum InsertBehaviour { NotifyViews, DoNotNotifyViews }; 0160 Archive::Entry *parentFor(const Kerfuffle::Archive::Entry *entry, InsertBehaviour behaviour = NotifyViews); 0161 QModelIndex indexForEntry(Archive::Entry *entry); 0162 /** 0163 * Insert the node @p node into the model, ensuring all views are notified 0164 * of the change. 0165 */ 0166 0167 void insertEntry(Archive::Entry *entry, InsertBehaviour behaviour = NotifyViews); 0168 void newEntry(Kerfuffle::Archive::Entry *receivedEntry, InsertBehaviour behaviour); 0169 0170 qulonglong traverseAndComputeDirSizes(Archive::Entry *dir); 0171 0172 QList<int> m_showColumns; 0173 QScopedPointer<Kerfuffle::Archive> m_archive; 0174 QScopedPointer<Archive::Entry> m_rootEntry; 0175 QHash<QString, QIcon> m_entryIcons; 0176 QMap<int, QByteArray> m_propertiesMap; 0177 0178 QString m_dbusPathName; 0179 0180 qulonglong m_numberOfFiles; 0181 qulonglong m_numberOfFolders; 0182 0183 // Whether a file entry has been listed. Used to ensure all relevant columns are shown, 0184 // since directories might have fewer columns than files. 0185 bool m_fileEntryListed; 0186 }; 0187 0188 #endif // ARCHIVEMODEL_H