File indexing completed on 2024-04-28 05:47:34

0001 /*
0002     SPDX-FileCopyrightText: 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
0003     SPDX-FileCopyrightText: 2009-2010 Raphael Kubo da Costa <rakuco@FreeBSD.org>
0004 
0005     SPDX-License-Identifier: BSD-2-Clause
0006 */
0007 
0008 #ifndef BATCHEXTRACT_H
0009 #define BATCHEXTRACT_H
0010 
0011 #include <KCompositeJob>
0012 
0013 #include <QMap>
0014 #include <QVector>
0015 
0016 namespace Kerfuffle
0017 {
0018 class Archive;
0019 class Query;
0020 }
0021 
0022 /**
0023  * This class schedules the extraction of all given compressed archives.
0024  *
0025  * Like AddToArchive, this class does not need the GUI to be active, and
0026  * provides the functionality available from the --batch command-line option.
0027  *
0028  * @author Harald Hvaal <haraldhv@stud.ntnu.no>
0029  */
0030 class BatchExtract : public KCompositeJob
0031 {
0032     Q_OBJECT
0033 
0034 public:
0035     /**
0036      * Creates a new BatchExtract object.
0037      */
0038     explicit BatchExtract(QObject *parent = nullptr);
0039 
0040     /**
0041      * Destroys a BatchExtract object.
0042      */
0043     ~BatchExtract() override;
0044 
0045     /**
0046      * Creates a BatchExtractJob for the given @p url and puts it on the queue.
0047      *
0048      * If necessary, the destination directory for the archive is created by the job.
0049      *
0050      * @param url The url of the archive that will be extracted.
0051      *
0052      * @see setAutoSubfolder
0053      */
0054     void addExtraction(const QUrl &url);
0055 
0056     bool doKill() override;
0057 
0058     /**
0059      * A wrapper that calls slotStartJob() when the event loop has started.
0060      */
0061     void start() override;
0062 
0063     /**
0064      * Whether to automatically create a folder inside the destination
0065      * directory if the archive has more than one directory or file
0066      * at top level.
0067      *
0068      * @return @c true  Create the subdirectory automatically.
0069      * @return @c false Do not create the subdirectory automatically.
0070      */
0071     bool autoSubfolder() const;
0072 
0073     /**
0074      * Set whether a folder should be created when necessary so
0075      * the archive is extracted to it.
0076      *
0077      * If set to @c true, when the archive does not consist of a
0078      * single folder with the other files and directories inside,
0079      * a directory will be automatically created inside the destination
0080      * directory and the archive will be extracted there.
0081      *
0082      * @param value Whether to create this directory automatically
0083      *              when needed.
0084      */
0085     void setAutoSubfolder(bool value);
0086 
0087     /**
0088      * Adds a file to the list of files that will be extracted.
0089      *
0090      * @param url The file that will be added to the list.
0091      */
0092     void addInput(const QUrl &url);
0093 
0094     /**
0095      * Shows the extract options dialog before extracting the files.
0096      *
0097      * @return @c true  The user has set some options and clicked OK.
0098      * @return @c false The user has canceled extraction.
0099      */
0100     bool showExtractDialog();
0101 
0102     /**
0103      * Returns the destination directory where the archives
0104      * will be extracted to.
0105      *
0106      * @return The destination directory. If no directory has been manually
0107      *         set with setDestinationFolder, QDir::currentPath() will be
0108      *         returned.
0109      */
0110     QString destinationFolder() const;
0111 
0112     /**
0113      * Sets the directory the archives will be extracted to.
0114      *
0115      * If @c setSubfolder has been used, the final destination
0116      * directory will be the concatenation of both.
0117      *
0118      * If @p folder does not exist, the current destination
0119      * folder will not change.
0120      *
0121      * @param folder The directory that will be used.
0122      */
0123     void setDestinationFolder(const QString &folder);
0124 
0125     /**
0126      * Returns whether the destination folder should
0127      * be open after all archives are extracted.
0128      *
0129      * @return @c true  Open the destination folder.
0130      * @return @c false Do not open the destination folder.
0131      */
0132     bool openDestinationAfterExtraction() const;
0133 
0134     /**
0135      * Whether to open the destination folder after
0136      * all archives are extracted.
0137      *
0138      * @param value Whether to open the destination.
0139      */
0140     void setOpenDestinationAfterExtraction(bool value);
0141 
0142     /**
0143      * Whether all files should be extracted to the same directory,
0144      * even if they're in different directories in the archive.
0145      *
0146      * This is also known as "flat" extraction.
0147      *
0148      * @return @c true  Paths should be preserved.
0149      * @return @c false Paths should be ignored.
0150      */
0151     bool preservePaths() const;
0152 
0153     /**
0154      * Sets whether paths should be preserved during extraction.
0155      *
0156      * When it is set to false, all files are extracted to a single
0157      * directory, regardless of their hierarchy in the archive.
0158      *
0159      * @param value Whether to preserve paths.
0160      */
0161     void setPreservePaths(bool value);
0162 
0163 private Q_SLOTS:
0164     /**
0165      * Updates the percentage of the job that has been completed.
0166      */
0167     void forwardProgress(KJob *job, unsigned long percent);
0168 
0169     /**
0170      * Shows a dialog with a list of all the files that could not
0171      * be successfully extracted.
0172      */
0173     void showFailedFiles();
0174 
0175     /**
0176      * Shows an error message if the current job hasn't finished
0177      * successfully, and advances to the next extraction job if
0178      * there are more.
0179      */
0180     void slotResult(KJob *job) override;
0181 
0182     /**
0183      * Shows a query dialog, which may happen when a file already exists.
0184      */
0185     void slotUserQuery(Kerfuffle::Query *query);
0186 
0187     /**
0188      * Does the real work for start() and extracts all scheduled files.
0189      *
0190      * Each extraction job is started after the last one finishes.
0191      * The jobs are executed in the order they were added via addInput().
0192      */
0193     void slotStartJob();
0194 
0195 private:
0196     int m_initialJobCount;
0197     QMap<KJob *, QPair<QString, QString>> m_fileNames;
0198     bool m_autoSubfolder;
0199 
0200     QVector<QUrl> m_inputs;
0201     QString m_destinationFolder;
0202     QStringList m_failedFiles;
0203     bool m_preservePaths;
0204     bool m_openDestinationAfterExtraction;
0205 };
0206 
0207 #endif // BATCHEXTRACT_H