File indexing completed on 2024-05-05 05:50:39
0001 /* 0002 SPDX-FileCopyrightText: 2007 Henrique Pinto <henrique.pinto@kdemail.net> 0003 SPDX-FileCopyrightText: 2008 Harald Hvaal <haraldhv@stud.ntnu.no> 0004 SPDX-FileCopyrightText: 2011 Raphael Kubo da Costa <rakuco@FreeBSD.org> 0005 0006 SPDX-License-Identifier: BSD-2-Clause 0007 */ 0008 0009 #ifndef ARCHIVE_H 0010 #define ARCHIVE_H 0011 0012 #include "kerfuffle_export.h" 0013 #include "metadatabackup.h" 0014 #include "options.h" 0015 0016 #include <KJob> 0017 0018 #include <QHash> 0019 #include <QMimeType> 0020 0021 namespace Kerfuffle 0022 { 0023 class LoadJob; 0024 class BatchExtractJob; 0025 class CreateJob; 0026 class ExtractJob; 0027 class DeleteJob; 0028 class AddJob; 0029 class MoveJob; 0030 class CopyJob; 0031 class CommentJob; 0032 class TestJob; 0033 class OpenJob; 0034 class OpenWithJob; 0035 class Plugin; 0036 class PreviewJob; 0037 class Query; 0038 class ReadOnlyArchiveInterface; 0039 0040 enum ArchiveError { NoError = 0, NoPlugin, FailedPlugin }; 0041 0042 class KERFUFFLE_EXPORT Archive : public QObject 0043 { 0044 Q_OBJECT 0045 0046 /** 0047 * Complete base name, without the "tar" extension (if any). 0048 */ 0049 Q_PROPERTY(QString completeBaseName READ completeBaseName CONSTANT) 0050 Q_PROPERTY(QString fileName READ fileName CONSTANT) 0051 Q_PROPERTY(QString comment READ comment CONSTANT) 0052 Q_PROPERTY(QMimeType mimeType READ mimeType CONSTANT) 0053 Q_PROPERTY(bool isEmpty READ isEmpty) 0054 Q_PROPERTY(bool isReadOnly READ isReadOnly CONSTANT) 0055 Q_PROPERTY(bool isSingleFile READ isSingleFile) 0056 Q_PROPERTY(bool isSingleFolder MEMBER m_isSingleFolder READ isSingleFolder) 0057 Q_PROPERTY(bool isMultiVolume READ isMultiVolume WRITE setMultiVolume) 0058 Q_PROPERTY(bool numberOfVolumes READ numberOfVolumes) 0059 Q_PROPERTY(EncryptionType encryptionType MEMBER m_encryptionType READ encryptionType) 0060 Q_PROPERTY(uint numberOfEntries READ numberOfEntries) 0061 Q_PROPERTY(qulonglong unpackedSize MEMBER m_extractedFilesSize READ unpackedSize) 0062 Q_PROPERTY(qulonglong packedSize READ packedSize) 0063 Q_PROPERTY(QString subfolderName MEMBER m_subfolderName READ subfolderName) 0064 Q_PROPERTY(QString password READ password) 0065 Q_PROPERTY(QStringList compressionMethods MEMBER m_compressionMethods) 0066 Q_PROPERTY(QStringList encryptionMethods MEMBER m_encryptionMethods) 0067 0068 public: 0069 enum EncryptionType { Unencrypted, Encrypted, HeaderEncrypted }; 0070 Q_ENUM(EncryptionType) 0071 0072 class Entry; 0073 0074 QString completeBaseName() const; 0075 QString fileName() const; 0076 QString comment() const; 0077 QMimeType mimeType(); 0078 bool isEmpty() const; 0079 bool isReadOnly() const; 0080 bool isSingleFile() const; 0081 bool isSingleFolder() const; 0082 bool isMultiVolume() const; 0083 void setMultiVolume(bool value); 0084 bool hasComment() const; 0085 int numberOfVolumes() const; 0086 EncryptionType encryptionType() const; 0087 QString password() const; 0088 uint numberOfEntries() const; 0089 qulonglong unpackedSize() const; 0090 qulonglong packedSize() const; 0091 QString subfolderName() const; 0092 QString multiVolumeName() const; 0093 ReadOnlyArchiveInterface *interface(); 0094 0095 /** 0096 * @return Whether the archive has more than one top-level entry. 0097 */ 0098 bool hasMultipleTopLevelEntries() const; 0099 0100 /** 0101 * @return Batch extraction job for @p filename to @p destination. 0102 * @param autoSubfolder Whether the job will extract into a subfolder. 0103 * @param preservePaths Whether the job will preserve paths. 0104 * @param parent The parent for the archive. 0105 */ 0106 static BatchExtractJob * 0107 batchExtract(const QString &fileName, const QString &destination, bool autoSubfolder, bool preservePaths, QObject *parent = nullptr); 0108 0109 /** 0110 * @return Job to create an archive for the given @p entries. 0111 * @param fileName The name of the new archive. 0112 * @param mimeType The mimetype of the new archive. 0113 */ 0114 static CreateJob *create(const QString &fileName, 0115 const QString &mimeType, 0116 const QVector<Archive::Entry *> &entries, 0117 const CompressionOptions &options, 0118 QObject *parent = nullptr); 0119 0120 /** 0121 * @return An empty archive with name @p fileName, mimetype @p mimeType and @p parent as parent. 0122 */ 0123 static Archive *createEmpty(const QString &fileName, const QString &mimeType, QObject *parent = nullptr); 0124 0125 /** 0126 * @return Job to load the archive @p fileName. 0127 * @param parent The parent of the archive that will be loaded. 0128 */ 0129 static LoadJob *load(const QString &fileName, QObject *parent = nullptr); 0130 0131 /** 0132 * @return Job to load the archive @p fileName with mimetype @p mimeType. 0133 * @param parent The parent of the archive that will be loaded. 0134 */ 0135 static LoadJob *load(const QString &fileName, const QString &mimeType, QObject *parent = nullptr); 0136 0137 /** 0138 * @return Job to load the archive @p fileName by using @p plugin. 0139 * @param parent The parent of the archive that will be loaded. 0140 */ 0141 static LoadJob *load(const QString &fileName, Plugin *plugin, QObject *parent = nullptr); 0142 0143 ~Archive() override; 0144 0145 ArchiveError error() const; 0146 bool isValid() const; 0147 0148 DeleteJob *deleteFiles(QVector<Archive::Entry *> &entries); 0149 CommentJob *addComment(const QString &comment); 0150 TestJob *testArchive(); 0151 0152 AddJob *addFiles(const QVector<Archive::Entry *> &files, const Archive::Entry *destination, const CompressionOptions &options = CompressionOptions()); 0153 0154 /** 0155 * Renames or moves entries within the archive. 0156 * 0157 * @param files All the renamed or moved files and their child entries (for renaming a directory too). 0158 * @param destination New entry name (for renaming) or destination folder (for moving). 0159 * If ReadOnlyArchiveInterface::entriesWithoutChildren(files).count() returns 1, then it's renaming, 0160 * so you must specify the resulted entry name, even if it's not going to be changed. 0161 * Otherwise (if count is more than 1) it's moving, so destination must contain only targeted folder path 0162 * or be empty, if moving to the root. 0163 */ 0164 MoveJob *moveFiles(const QVector<Archive::Entry *> &files, Archive::Entry *destination, const CompressionOptions &options = CompressionOptions()); 0165 0166 /** 0167 * Copies entries within the archive. 0168 * 0169 * @param files All the renamed or moved files and their child entries (for renaming a directory too). 0170 * @param destination Destination path. It must contain only targeted folder path or be empty, 0171 * if copying to the root. 0172 */ 0173 CopyJob *copyFiles(const QVector<Archive::Entry *> &files, Archive::Entry *destination, const CompressionOptions &options = CompressionOptions()); 0174 0175 ExtractJob *extractFiles(const QVector<Archive::Entry *> &files, const QString &destinationDir, ExtractionOptions options = ExtractionOptions()); 0176 0177 PreviewJob *preview(Archive::Entry *entry); 0178 OpenJob *open(Archive::Entry *entry); 0179 OpenWithJob *openWith(Archive::Entry *entry); 0180 0181 /** 0182 * @param password The password to encrypt the archive with. 0183 * @param encryptHeader Whether to encrypt also the list of files. 0184 */ 0185 void encrypt(const QString &password, bool encryptHeader); 0186 0187 private Q_SLOTS: 0188 void onAddFinished(KJob *); 0189 void onUserQuery(Kerfuffle::Query *); 0190 void onCompressionMethodFound(const QString &method); 0191 void onEncryptionMethodFound(const QString &method); 0192 0193 private: 0194 Archive(ReadOnlyArchiveInterface *archiveInterface, bool isReadOnly, QObject *parent = nullptr); 0195 Archive(ArchiveError errorCode, QObject *parent = nullptr); 0196 0197 static Archive *create(const QString &fileName, QObject *parent = nullptr); 0198 static Archive *create(const QString &fileName, const QString &fixedMimeType, QObject *parent = nullptr); 0199 0200 /** 0201 * Create an archive instance from a given @p plugin. 0202 * @param fileName The name of the archive. 0203 * @return A valid archive if the plugin could be loaded, an invalid one otherwise (with the FailedPlugin error set). 0204 */ 0205 static Archive *create(const QString &fileName, Plugin *plugin, QObject *parent = nullptr); 0206 ReadOnlyArchiveInterface *m_iface; 0207 bool m_isReadOnly; 0208 bool m_isSingleFolder; 0209 bool m_isMultiVolume; 0210 0211 QString m_subfolderName; 0212 qulonglong m_extractedFilesSize; 0213 ArchiveError m_error; 0214 EncryptionType m_encryptionType; 0215 QMimeType m_mimeType; 0216 QStringList m_compressionMethods; 0217 QStringList m_encryptionMethods; 0218 0219 /** 0220 * @brief The user metadata for this archive. 0221 * 0222 * We keep track of the user metadata for the archive so that we can restore 0223 * it after the archive has been modified. 0224 */ 0225 std::optional<MetadataBackup> m_userMetaData; 0226 0227 /** 0228 * @brief Restore the user metadata for this archive. 0229 */ 0230 void restoreUserMetadata(); 0231 }; 0232 0233 } // namespace Kerfuffle 0234 0235 #endif // ARCHIVE_H