[kde-doc-english] [ark] /: Implement a custom AddDialog

Ragnar Thomsen rthomsen6 at gmail.com
Sat Jul 16 10:29:12 UTC 2016


Git commit 07269ec72e0f83fb6c2804f2640c78f07973cbeb by Ragnar Thomsen.
Committed on 16/07/2016 at 10:24.
Pushed by rthomsen into branch 'master'.

Implement a custom AddDialog

This diff implements an AddDialog class that is used instead of
QFileDialogs for adding files/folders to an archive. Now both folders
and files are added to an archive with a single action in Part, instead
of two separate actions (Add File/Add Folder).

AddDialog has a button which opens a new dialog that allows setting
advanced compression settings (currently only compression level). Since
compression options are used both when creating a new archive and adding
files to an existing archive, a new class called
CompressionOptionsWidget was created which is used by both AddDialog and
CreateDialog.

Differential Revision: D2120
GUI:

M  +5    -0    autotests/kerfuffle/CMakeLists.txt
A  +164  -0    autotests/kerfuffle/adddialogtest.cpp     [License: BSD]
M  +3    -0    kerfuffle/CMakeLists.txt
A  +123  -0    kerfuffle/adddialog.cpp     [License: BSD]
A  +68   -0    kerfuffle/adddialog.h     [License: BSD]
M  +10   -0    kerfuffle/archive_kerfuffle.cpp
M  +3    -0    kerfuffle/archive_kerfuffle.h
A  +158  -0    kerfuffle/compressionoptionswidget.cpp     [License: BSD]
C  +16   -52   kerfuffle/compressionoptionswidget.h [from: kerfuffle/createdialog.h - 053% similarity]
C  +50   -147  kerfuffle/compressionoptionswidget.ui [from: kerfuffle/createdialog.ui - 056% similarity]
M  +10   -64   kerfuffle/createdialog.cpp
M  +2    -1    kerfuffle/createdialog.h
M  +83   -197  kerfuffle/createdialog.ui
M  +1    -2    part/ark_part.rc
M  +28   -25   part/part.cpp
M  +1    -2    part/part.h

http://commits.kde.org/ark/07269ec72e0f83fb6c2804f2640c78f07973cbeb

diff --git a/autotests/kerfuffle/CMakeLists.txt b/autotests/kerfuffle/CMakeLists.txt
index d90cdfd..b99a526 100644
--- a/autotests/kerfuffle/CMakeLists.txt
+++ b/autotests/kerfuffle/CMakeLists.txt
@@ -16,6 +16,11 @@ ecm_add_tests(
     LINK_LIBRARIES kerfuffle Qt5::Test
     NAME_PREFIX kerfuffle-)
 
+ecm_add_test(
+    adddialogtest.cpp
+    LINK_LIBRARIES kerfuffle Qt5::Test KF5::KIOFileWidgets
+    NAME_PREFIX kerfuffle-)
+
 ecm_add_tests(
     jobstest.cpp
     LINK_LIBRARIES jsoninterface Qt5::Test
diff --git a/autotests/kerfuffle/adddialogtest.cpp b/autotests/kerfuffle/adddialogtest.cpp
new file mode 100644
index 0000000..8b32702
--- /dev/null
+++ b/autotests/kerfuffle/adddialogtest.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2016 Ragnar Thomsen <rthomsen6 at gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "adddialog.h"
+#include "archiveformat.h"
+#include "pluginmanager.h"
+
+#include <KCollapsibleGroupBox>
+
+#include <QCheckBox>
+#include <QComboBox>
+#include <QLineEdit>
+#include <QMimeDatabase>
+#include <QTest>
+
+using namespace Kerfuffle;
+
+class AddDialogTest : public QObject
+{
+    Q_OBJECT
+
+private Q_SLOTS:
+    void testBasicWidgets_data();
+    void testBasicWidgets();
+
+private:
+    PluginManager m_pluginManager;
+};
+
+void AddDialogTest::testBasicWidgets_data()
+{
+    QTest::addColumn<QString>("mimeType");
+    QTest::addColumn<bool>("supportsCompLevel");
+    QTest::addColumn<int>("initialCompLevel");
+    QTest::addColumn<int>("changeToCompLevel");
+
+    QTest::newRow("tar") << QStringLiteral("application/x-tar") << false << -1 << -1;
+    QTest::newRow("targzip") << QStringLiteral("application/x-compressed-tar") << true << 3 << 7;
+    QTest::newRow("tarbzip") << QStringLiteral("application/x-bzip-compressed-tar") << true << 3 << 7;
+    QTest::newRow("tarZ") << QStringLiteral("application/x-tarz") << false << -1 << -1;
+    QTest::newRow("tarxz") << QStringLiteral("application/x-xz-compressed-tar") << true << 3 << 7;
+    QTest::newRow("tarlzma") << QStringLiteral("application/x-lzma-compressed-tar") << true << 3 << 7;
+    QTest::newRow("tarlzop") << QStringLiteral("application/x-tzo") << true << 3 << 7;
+    QTest::newRow("tarlzip") << QStringLiteral("application/x-lzip-compressed-tar") << true << 3 << 7;
+
+    const auto writeMimeTypes = m_pluginManager.supportedWriteMimeTypes();
+
+    if (writeMimeTypes.contains(QStringLiteral("application/zip"))) {
+        QTest::newRow("zip") << QStringLiteral("application/zip") << true << 3 << 7;
+    } else {
+        qDebug() << "zip format not available, skipping test.";
+    }
+
+    if (writeMimeTypes.contains(QStringLiteral("application/x-7z-compressed"))) {
+        QTest::newRow("7z") << QStringLiteral("application/x-7z-compressed") << true << 3 << 7;
+    } else {
+        qDebug() << "7z format not available, skipping test.";
+    }
+
+    if (writeMimeTypes.contains(QStringLiteral("application/x-rar"))) {
+        QTest::newRow("rar") << QStringLiteral("application/x-rar") << true << 2 << 5;
+    } else {
+        qDebug() << "rar format not available, skipping test.";
+    }
+
+    if (writeMimeTypes.contains(QStringLiteral("application/x-lrzip-compressed-tar"))) {
+        QTest::newRow("tarlrzip") << QStringLiteral("application/x-lrzip-compressed-tar") << true << 3 << 7;
+    } else {
+        qDebug() << "tar.lrzip format not available, skipping test.";
+    }
+}
+
+void AddDialogTest::testBasicWidgets()
+{
+    QFETCH(QString, mimeType);
+    const QMimeType mime = QMimeDatabase().mimeTypeForName(mimeType);
+    QFETCH(bool, supportsCompLevel);
+    QFETCH(int, initialCompLevel);
+    QFETCH(int, changeToCompLevel);
+
+    AddDialog *dialog = new AddDialog(Q_NULLPTR, QString(), QUrl(), mime);
+
+    dialog->slotOpenOptions();
+
+    auto collapsibleCompression = dialog->optionsDialog->findChild<KCollapsibleGroupBox*>(QStringLiteral("collapsibleCompression"));
+    QVERIFY(collapsibleCompression);
+
+    if (supportsCompLevel) {
+        // Test that collapsiblegroupbox is enabled for mimetypes that support compression levels.
+        QVERIFY(collapsibleCompression->isEnabled());
+
+        auto compLevelSlider = dialog->optionsDialog->findChild<QSlider*>(QStringLiteral("compLevelSlider"));
+        QVERIFY(compLevelSlider);
+
+        const KPluginMetaData metadata = PluginManager().preferredPluginFor(mime)->metaData();
+        const ArchiveFormat archiveFormat = ArchiveFormat::fromMetadata(mime, metadata);
+        QVERIFY(archiveFormat.isValid());
+
+        // Test that min/max of slider are correct.
+        QCOMPARE(compLevelSlider->minimum(), archiveFormat.minCompressionLevel());
+        QCOMPARE(compLevelSlider->maximum(), archiveFormat.maxCompressionLevel());
+
+        // Test that the slider is set to default compression level.
+        QCOMPARE(compLevelSlider->value(), archiveFormat.defaultCompressionLevel());
+
+        // Set the compression level slider.
+        compLevelSlider->setValue(changeToCompLevel);
+    } else {
+        // Test that collapsiblegroupbox is disabled for mimetypes that don't support compression levels.
+        QVERIFY(!collapsibleCompression->isEnabled());
+    }
+
+    dialog->optionsDialog->accept();
+    dialog->accept();
+
+    if (supportsCompLevel) {
+        // Test that the value set by slider is exported from AddDialog.
+        QCOMPARE(dialog->compressionOptions()[QStringLiteral("CompressionLevel")].toInt(), changeToCompLevel);
+    }
+
+    // Test that passing a compression level in ctor works.
+    CompressionOptions opts;
+    opts[QStringLiteral("CompressionLevel")] = initialCompLevel;
+
+    dialog = new AddDialog(Q_NULLPTR, QString(), QUrl(), mime, opts);
+    dialog->slotOpenOptions();
+
+    if (supportsCompLevel) {
+
+        auto compLevelSlider = dialog->optionsDialog->findChild<QSlider*>(QStringLiteral("compLevelSlider"));
+        QVERIFY(compLevelSlider);
+
+        // Test that slider is set to the compression level supplied in ctor.
+        QCOMPARE(compLevelSlider->value(), initialCompLevel);
+    }
+    dialog->optionsDialog->accept();
+    dialog->accept();
+}
+
+QTEST_MAIN(AddDialogTest)
+
+#include "adddialogtest.moc"
diff --git a/kerfuffle/CMakeLists.txt b/kerfuffle/CMakeLists.txt
index 4eaabaa..a14d25c 100644
--- a/kerfuffle/CMakeLists.txt
+++ b/kerfuffle/CMakeLists.txt
@@ -8,6 +8,8 @@ set(kerfuffle_SRCS
     previewsettingspage.cpp
     settingspage.cpp
     jobs.cpp
+    adddialog.cpp
+    compressionoptionswidget.cpp
     createdialog.cpp
     extractiondialog.cpp
     propertiesdialog.cpp
@@ -27,6 +29,7 @@ ki18n_wrap_ui(kerfuffle_SRCS
     extractionsettings.ui
     previewsettings.ui
     propertiesdialog.ui
+    compressionoptionswidget.ui
 )
 
 ecm_qt_declare_logging_category(kerfuffle_SRCS
diff --git a/kerfuffle/adddialog.cpp b/kerfuffle/adddialog.cpp
new file mode 100644
index 0000000..882f145
--- /dev/null
+++ b/kerfuffle/adddialog.cpp
@@ -0,0 +1,123 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Ragnar Thomsen <rthomsen6 at gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "adddialog.h"
+#include "ark_debug.h"
+#include "archiveformat.h"
+#include "compressionoptionswidget.h"
+#include "mimetypes.h"
+
+#include <QDialogButtonBox>
+#include <QPointer>
+#include <QPushButton>
+#include <QUrl>
+#include <QVBoxLayout>
+
+namespace Kerfuffle
+{
+
+AddDialog::AddDialog(QWidget *parent,
+                     const QString &title,
+                     const QUrl &startDir,
+                     const QMimeType &mimeType,
+                     const CompressionOptions &opts)
+        : QDialog(parent, Qt::Dialog)
+        , m_mimeType(mimeType)
+        , m_compOptions(opts)
+{
+    qCDebug(ARK) << "AddDialog loaded with options:" << m_compOptions;
+
+    setWindowTitle(title);
+
+    QVBoxLayout *vlayout = new QVBoxLayout(this);
+    m_fileWidget = new KFileWidget(startDir, this);
+    vlayout->addWidget(m_fileWidget);
+
+    QPushButton *optionsButton = new QPushButton(QIcon::fromTheme(QStringLiteral("settings-configure")),
+                                                 i18n("Advanced Options"));
+    optionsButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+    m_fileWidget->setCustomWidget(optionsButton);
+
+    connect(optionsButton, &QPushButton::clicked, this, &AddDialog::slotOpenOptions);
+
+    m_fileWidget->setMode(KFile::Files | KFile::Directory | KFile::LocalOnly | KFile::ExistingOnly);
+    m_fileWidget->setOperationMode(KFileWidget::Opening);
+
+    m_fileWidget->okButton()->setText(i18nc("@action:button", "Add"));
+    m_fileWidget->okButton()->show();
+    connect(m_fileWidget->okButton(), &QPushButton::clicked, m_fileWidget, &KFileWidget::slotOk);
+    connect(m_fileWidget, &KFileWidget::accepted, m_fileWidget, &KFileWidget::accept);
+    connect(m_fileWidget, &KFileWidget::accepted, this, &QDialog::accept);
+
+    m_fileWidget->cancelButton()->show();
+    connect(m_fileWidget->cancelButton(), &QPushButton::clicked, this, &QDialog::reject);
+}
+
+AddDialog::~AddDialog()
+{
+}
+
+QStringList AddDialog::selectedFiles() const
+{
+    return m_fileWidget->selectedFiles();
+}
+
+CompressionOptions AddDialog::compressionOptions() const
+{
+    return m_compOptions;
+}
+
+void AddDialog::slotOpenOptions()
+{
+    optionsDialog = new QDialog(this);
+    QVBoxLayout *vlayout = new QVBoxLayout(optionsDialog);
+    optionsDialog->setWindowTitle(i18n("Advanced Options"));
+
+    CompressionOptionsWidget *optionsWidget = new CompressionOptionsWidget(optionsDialog, m_compOptions);
+    optionsWidget->setMimeType(m_mimeType);
+    optionsWidget->setEncryptionVisible(false);
+    optionsWidget->collapsibleCompression->expand();
+    vlayout->addWidget(optionsWidget);
+
+    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, optionsDialog);
+    vlayout->addWidget(buttonBox);
+    connect(buttonBox, &QDialogButtonBox::accepted, optionsDialog, &QDialog::accept);
+    connect(buttonBox, &QDialogButtonBox::rejected, optionsDialog, &QDialog::reject);
+
+    optionsDialog->layout()->setSizeConstraint(QLayout::SetFixedSize);
+
+    connect(optionsDialog, &QDialog::finished, this, [this, optionsWidget](int result) {
+        if (result == QDialog::Accepted) {
+            m_compOptions = optionsWidget->commpressionOptions();
+        }
+        optionsDialog->deleteLater();
+    });
+
+    optionsDialog->open();
+}
+
+}
diff --git a/kerfuffle/adddialog.h b/kerfuffle/adddialog.h
new file mode 100644
index 0000000..013b93d
--- /dev/null
+++ b/kerfuffle/adddialog.h
@@ -0,0 +1,68 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Ragnar Thomsen <rthomsen6 at gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ADDDIALOG_H
+#define ADDDIALOG_H
+
+#include "kerfuffle_export.h"
+#include "archive_kerfuffle.h"
+#include "compressionoptionswidget.h"
+
+#include <KFileWidget>
+
+#include <QDialog>
+#include <QMimeType>
+
+class QUrl;
+
+namespace Kerfuffle
+{
+class KERFUFFLE_EXPORT AddDialog : public QDialog
+{
+    Q_OBJECT
+public:
+    explicit AddDialog(QWidget *parent,
+                       const QString &title,
+                       const QUrl &startDir,
+                       const QMimeType &mimeType,
+                       const CompressionOptions &opts = QHash<QString, QVariant>());
+    virtual ~AddDialog();
+    QStringList selectedFiles() const;
+    CompressionOptions compressionOptions() const;
+    QDialog *optionsDialog;
+
+private:
+    KFileWidget *m_fileWidget;
+    QMimeType m_mimeType;
+    CompressionOptions m_compOptions;
+
+public slots:
+    void slotOpenOptions();
+};
+}
+
+#endif
diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp
index 6f81c10..01cb8b1 100644
--- a/kerfuffle/archive_kerfuffle.cpp
+++ b/kerfuffle/archive_kerfuffle.cpp
@@ -470,4 +470,14 @@ void Archive::onUserQuery(Query* query)
     query->execute();
 }
 
+void Archive::setCompressionOptions(const CompressionOptions &opts)
+{
+    m_compOptions = opts;
+}
+
+CompressionOptions Archive::compressionOptions() const
+{
+    return m_compOptions;
+}
+
 } // namespace Kerfuffle
diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h
index 8fcf2dc..a510a03 100644
--- a/kerfuffle/archive_kerfuffle.h
+++ b/kerfuffle/archive_kerfuffle.h
@@ -180,6 +180,8 @@ public:
     qulonglong unpackedSize();
     qulonglong packedSize() const;
     QString subfolderName();
+    void setCompressionOptions(const CompressionOptions &opts);
+    CompressionOptions compressionOptions() const;
 
     static Archive *create(const QString &fileName, QObject *parent = 0);
     static Archive *create(const QString &fileName, const QString &fixedMimeType, QObject *parent = 0);
@@ -256,6 +258,7 @@ private:
     EncryptionType m_encryptionType;
     qulonglong m_numberOfFiles;
     qulonglong m_numberOfFolders;
+    CompressionOptions m_compOptions;
     QMimeType m_mimeType;
 };
 
diff --git a/kerfuffle/compressionoptionswidget.cpp b/kerfuffle/compressionoptionswidget.cpp
new file mode 100644
index 0000000..4340009
--- /dev/null
+++ b/kerfuffle/compressionoptionswidget.cpp
@@ -0,0 +1,158 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2016 Ragnar Thomsen <rthomsen6 at gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "compressionoptionswidget.h"
+#include "ark_debug.h"
+#include "archiveformat.h"
+#include "pluginmanager.h"
+
+#include <KColorScheme>
+#include <KPluginMetaData>
+
+#include <QMimeDatabase>
+
+namespace Kerfuffle
+{
+CompressionOptionsWidget::CompressionOptionsWidget(QWidget *parent,
+                                                   const CompressionOptions &opts)
+    : QWidget(parent)
+    , m_opts(opts)
+{
+    setupUi(this);
+
+    KColorScheme colorScheme(QPalette::Active, KColorScheme::View);
+    pwdWidget->setBackgroundWarningColor(colorScheme.background(KColorScheme::NegativeBackground).color());
+    pwdWidget->setPasswordStrengthMeterVisible(false);
+}
+
+CompressionOptions CompressionOptionsWidget::commpressionOptions() const
+{
+    CompressionOptions opts;
+    opts[QStringLiteral("CompressionLevel")] = compLevelSlider->value();
+
+    return opts;
+}
+
+int CompressionOptionsWidget::compressionLevel() const
+{
+    return compLevelSlider->value();
+}
+
+void CompressionOptionsWidget::setEncryptionVisible(bool visible)
+{
+    collapsibleEncryption->setVisible(visible);
+}
+
+QString CompressionOptionsWidget::password() const
+{
+    return pwdWidget->password();
+}
+
+void CompressionOptionsWidget::updateWidgets()
+{
+    const KPluginMetaData metadata = PluginManager().preferredPluginFor(m_mimetype)->metaData();
+    const ArchiveFormat archiveFormat = ArchiveFormat::fromMetadata(m_mimetype, metadata);
+    Q_ASSERT(archiveFormat.isValid());
+
+    if (archiveFormat.encryptionType() != Archive::Unencrypted) {
+        collapsibleEncryption->setEnabled(true);
+        collapsibleEncryption->setToolTip(QString());
+        pwdWidget->setEnabled(true);
+
+        if (archiveFormat.encryptionType() == Archive::HeaderEncrypted) {
+            encryptHeaderCheckBox->setEnabled(true);
+            encryptHeaderCheckBox->setToolTip(QString());
+        } else {
+            encryptHeaderCheckBox->setEnabled(false);
+            // Show the tooltip only if the encryption is still enabled.
+            // This is needed because if the new filter is e.g. tar, the whole encryption group gets disabled.
+            if (collapsibleEncryption->isEnabled() && collapsibleEncryption->isExpanded()) {
+                encryptHeaderCheckBox->setToolTip(i18n("Protection of the list of files is not possible with the %1 format.",
+                                                       m_mimetype.comment()));
+            } else {
+                encryptHeaderCheckBox->setToolTip(QString());
+            }
+        }
+
+    } else {
+        collapsibleEncryption->setEnabled(false);
+        collapsibleEncryption->setToolTip(i18n("Protection of the archive with password is not possible with the %1 format.",
+                                               m_mimetype.comment()));
+        pwdWidget->setEnabled(false);
+        encryptHeaderCheckBox->setToolTip(QString());
+    }
+
+
+    if (archiveFormat.maxCompressionLevel() == 0) {
+        collapsibleCompression->setEnabled(false);
+        collapsibleCompression->setToolTip(i18n("It is not possible to set compression level for the %1 format.",
+                                                m_mimetype.comment()));
+    } else {
+        collapsibleCompression->setEnabled(true);
+        collapsibleCompression->setToolTip(QString());
+        compLevelSlider->setMinimum(archiveFormat.minCompressionLevel());
+        compLevelSlider->setMaximum(archiveFormat.maxCompressionLevel());
+        if (m_opts.contains(QStringLiteral("CompressionLevel"))) {
+            compLevelSlider->setValue(m_opts.value(QStringLiteral("CompressionLevel")).toInt());
+        } else {
+            compLevelSlider->setValue(archiveFormat.defaultCompressionLevel());
+        }
+    }
+}
+
+void CompressionOptionsWidget::setMimeType(const QMimeType &mimeType)
+{
+    m_mimetype = mimeType;
+    updateWidgets();
+}
+
+bool CompressionOptionsWidget::isEncryptionAvailable() const
+{
+    return collapsibleEncryption->isEnabled();
+}
+
+bool CompressionOptionsWidget::isEncryptionEnabled() const
+{
+    return isEncryptionAvailable() && collapsibleEncryption->isExpanded();
+}
+
+bool CompressionOptionsWidget::isHeaderEncryptionAvailable() const
+{
+    return isEncryptionEnabled() && encryptHeaderCheckBox->isEnabled();
+}
+
+bool CompressionOptionsWidget::isHeaderEncryptionEnabled() const
+{
+    return isHeaderEncryptionAvailable() && encryptHeaderCheckBox->isChecked();
+}
+
+KNewPasswordWidget::PasswordStatus CompressionOptionsWidget::passwordStatus() const
+{
+    return pwdWidget->passwordStatus();
+}
+
+}
diff --git a/kerfuffle/createdialog.h b/kerfuffle/compressionoptionswidget.h
similarity index 53%
copy from kerfuffle/createdialog.h
copy to kerfuffle/compressionoptionswidget.h
index f3fe49d..350aa7a 100644
--- a/kerfuffle/createdialog.h
+++ b/kerfuffle/compressionoptionswidget.h
@@ -1,9 +1,6 @@
 /*
  * ark -- archiver for the KDE project
  *
- * Copyright (C) 2008 Harald Hvaal <haraldhv at stud.ntnu.no>
- * Copyright (C) 2009 Raphael Kubo da Costa <rakuco at FreeBSD.org>
- * Copyright (C) 2015 Elvis Angelaccio <elvis.angelaccio at kdemail.net>
  * Copyright (C) 2016 Ragnar Thomsen <rthomsen6 at gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,75 +25,42 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef CREATEDIALOG_H
-#define CREATEDIALOG_H
+#ifndef COMPRESSIONOPTIONSWIDGET_H
+#define COMPRESSIONOPTIONSWIDGET_H
 
 #include "kerfuffle_export.h"
-#include "pluginmanager.h"
+#include "archive_kerfuffle.h"
+#include "ui_compressionoptionswidget.h"
 
-#include <KConfigGroup>
-
-#include <QDialog>
 #include <QMimeType>
-
-class QUrl;
-class QVBoxLayout;
+#include <QWidget>
 
 namespace Kerfuffle
 {
-
-class KERFUFFLE_EXPORT CreateDialog : public QDialog
+class KERFUFFLE_EXPORT CompressionOptionsWidget : public QWidget, public Ui::CompressionOptionsWidget
 {
     Q_OBJECT
 
 public:
-    explicit CreateDialog(QWidget *parent,
-                          const QString &caption,
-                          const QUrl &startDir);
-    QUrl selectedUrl() const;
-    QString password() const;
-    QMimeType currentMimeType() const;
-    bool setMimeType(const QString &mimeTypeName);
+    explicit CompressionOptionsWidget(QWidget *parent = Q_NULLPTR,
+                                      const CompressionOptions &opts = QHash<QString, QVariant>());
     int compressionLevel() const;
-
-    /**
-     * @return Whether the user can encrypt the new archive.
-     */
+    QString password() const;
+    CompressionOptions commpressionOptions() const;
     bool isEncryptionAvailable() const;
-
-    /**
-     * @return Whether the user has chosen to encrypt the new archive.
-     */
     bool isEncryptionEnabled() const;
-
-    /**
-     * @return Whether the user can encrypt the list of files in the new archive.
-     */
     bool isHeaderEncryptionAvailable() const;
-
-    /**
-     * @return Whether the user has chosen to encrypt the list of files in the new archive.
-     */
     bool isHeaderEncryptionEnabled() const;
+    KNewPasswordWidget::PasswordStatus passwordStatus() const;
 
-public slots:
-    virtual void accept() Q_DECL_OVERRIDE;
+    void setEncryptionVisible(bool visible);
+    void setMimeType(const QMimeType &mimeType);
 
 private:
-    void loadConfiguration();
-
-    class CreateDialogUI *m_ui;
-    QVBoxLayout *m_vlayout;
-    KConfigGroup m_config;
-    QStringList m_supportedMimeTypes;
-    PluginManager m_pluginManger;
+    void updateWidgets();
 
-private slots:
-    void slotFileNameEdited(const QString &text);
-    void slotUpdateWidgets(int index);
-    void slotEncryptionToggled();
-    void slotUpdateDefaultMimeType();
-    void slotUpdateFilenameExtension(int index);
+    QMimeType m_mimetype;
+    CompressionOptions m_opts;
 };
 }
 
diff --git a/kerfuffle/createdialog.ui b/kerfuffle/compressionoptionswidget.ui
similarity index 56%
copy from kerfuffle/createdialog.ui
copy to kerfuffle/compressionoptionswidget.ui
index addf276..b0a36f4 100644
--- a/kerfuffle/createdialog.ui
+++ b/kerfuffle/compressionoptionswidget.ui
@@ -1,142 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <class>CreateDialog</class>
- <widget class="QWidget" name="CreateDialog">
+ <class>CompressionOptionsWidget</class>
+ <widget class="QWidget" name="CompressionOptionsWidget">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>502</width>
-    <height>369</height>
+    <width>384</width>
+    <height>62</height>
    </rect>
   </property>
-  <property name="minimumSize">
-   <size>
-    <width>400</width>
-    <height>0</height>
-   </size>
-  </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QFormLayout" name="formLayout">
-     <property name="sizeConstraint">
-      <enum>QLayout::SetFixedSize</enum>
-     </property>
-     <item row="0" column="0">
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>Folder:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <widget class="KUrlRequester" name="destFolderUrlRequester">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="label_3">
-       <property name="text">
-        <string>Filename:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1">
-      <widget class="QLineEdit" name="filenameLineEdit">
-       <property name="placeholderText">
-        <string>Type archive name...</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="label_2">
-       <property name="text">
-        <string>Type:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="1">
-      <widget class="QComboBox" name="mimeComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item row="4" column="0">
-      <widget class="QLabel" name="label_4">
-       <property name="text">
-        <string>Extension:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="4" column="1">
-      <widget class="QCheckBox" name="chkAddExtension">
-       <property name="text">
-        <string notr="true">Automatically add filename extension (extension)</string>
-       </property>
-       <property name="checked">
-        <bool>true</bool>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="KCollapsibleGroupBox" name="collapsibleEncryption">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title">
-      <string>Password Protection</string>
-     </property>
-     <property name="expanded">
-      <bool>false</bool>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_3">
-      <item>
-       <widget class="KNewPasswordWidget" name="pwdWidget" native="true">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QCheckBox" name="encryptHeaderCheckBox">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="layoutDirection">
-         <enum>Qt::LeftToRight</enum>
-        </property>
-        <property name="text">
-         <string>Ask for password before showing the list of files in the archive</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
     <widget class="KCollapsibleGroupBox" name="collapsibleCompression">
      <property name="enabled">
-      <bool>false</bool>
+      <bool>true</bool>
      </property>
      <property name="title">
       <string>Compression</string>
@@ -183,6 +61,12 @@
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
+        <property name="minimumSize">
+         <size>
+          <width>300</width>
+          <height>0</height>
+         </size>
+        </property>
         <property name="maximum">
          <number>9</number>
         </property>
@@ -204,28 +88,53 @@
     </widget>
    </item>
    <item>
-    <widget class="Line" name="line_2">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+    <widget class="KCollapsibleGroupBox" name="collapsibleEncryption">
+     <property name="enabled">
+      <bool>true</bool>
      </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="title">
+      <string>Password Protection</string>
+     </property>
+     <property name="expanded">
+      <bool>false</bool>
      </property>
+     <layout class="QVBoxLayout" name="verticalLayout_3">
+      <item>
+       <widget class="KNewPasswordWidget" name="pwdWidget" native="true">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QCheckBox" name="encryptHeaderCheckBox">
+        <property name="enabled">
+         <bool>false</bool>
+        </property>
+        <property name="layoutDirection">
+         <enum>Qt::LeftToRight</enum>
+        </property>
+        <property name="text">
+         <string>Ask for password before showing the list of files in the archive</string>
+        </property>
+        <property name="checked">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+     </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <customwidgets>
   <customwidget>
-   <class>KUrlRequester</class>
-   <extends>QWidget</extends>
-   <header>kurlrequester.h</header>
-  </customwidget>
-  <customwidget>
    <class>KCollapsibleGroupBox</class>
    <extends>QWidget</extends>
    <header>kcollapsiblegroupbox.h</header>
@@ -238,12 +147,6 @@
    <container>1</container>
   </customwidget>
  </customwidgets>
- <tabstops>
-  <tabstop>destFolderUrlRequester</tabstop>
-  <tabstop>filenameLineEdit</tabstop>
-  <tabstop>mimeComboBox</tabstop>
-  <tabstop>collapsibleEncryption</tabstop>
- </tabstops>
  <resources/>
  <connections/>
 </ui>
diff --git a/kerfuffle/createdialog.cpp b/kerfuffle/createdialog.cpp
index ba6a475..dd21d88 100644
--- a/kerfuffle/createdialog.cpp
+++ b/kerfuffle/createdialog.cpp
@@ -35,7 +35,6 @@
 #include "kerfuffle/archive_kerfuffle.h"
 #include "mimetypes.h"
 
-#include <KColorScheme>
 #include <KMessageBox>
 #include <KSharedConfig>
 #include <KUrlRequester>
@@ -80,17 +79,12 @@ CreateDialog::CreateDialog(QWidget *parent,
         m_ui->destFolderUrlRequester->setUrl(startDir);
     }
 
-    KColorScheme colorScheme(QPalette::Active, KColorScheme::View);
-    m_ui->pwdWidget->setBackgroundWarningColor(colorScheme.background(KColorScheme::NegativeBackground).color());
-    m_ui->pwdWidget->setPasswordStrengthMeterVisible(false);
-
     // Populate combobox with mimetypes.
     foreach (const QString &type, m_supportedMimeTypes) {
         m_ui->mimeComboBox->addItem(QMimeDatabase().mimeTypeForName(type).comment());
     }
 
     connect(m_ui->filenameLineEdit, &QLineEdit::textChanged, this, &CreateDialog::slotFileNameEdited);
-    connect(m_ui->collapsibleEncryption, &KCollapsibleGroupBox::expandedChanged, this, &CreateDialog::slotEncryptionToggled);
     connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
     connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
     connect(this, &QDialog::accepted, this, &CreateDialog::slotUpdateDefaultMimeType);
@@ -99,6 +93,8 @@ CreateDialog::CreateDialog(QWidget *parent,
 
     m_vlayout->addWidget(m_ui);
 
+    m_ui->optionsWidget->setMimeType(currentMimeType());
+
     loadConfiguration();
 
     layout()->setSizeConstraint(QLayout::SetFixedSize);
@@ -119,30 +115,7 @@ void CreateDialog::slotFileNameEdited(const QString &fileName)
 
 void CreateDialog::slotUpdateWidgets(int index)
 {
-    const QMimeType mimeType = QMimeDatabase().mimeTypeForName(m_supportedMimeTypes.at(index));
-    const KPluginMetaData metadata = m_pluginManger.preferredPluginFor(mimeType)->metaData();
-    const ArchiveFormat archiveFormat = ArchiveFormat::fromMetadata(mimeType, metadata);
-    Q_ASSERT(archiveFormat.isValid());
-
-    if (archiveFormat.encryptionType() != Archive::Unencrypted) {
-        m_ui->collapsibleEncryption->setEnabled(true);
-        m_ui->collapsibleEncryption->setToolTip(QString());
-    } else {
-        m_ui->collapsibleEncryption->setEnabled(false);
-        m_ui->collapsibleEncryption->setToolTip(i18n("Protection of the archive with password is not possible with the %1 format.",
-                                                mimeType.comment()));
-    }
-
-    if (archiveFormat.maxCompressionLevel() == 0) {
-        m_ui->collapsibleCompression->setEnabled(false);
-    } else {
-        m_ui->collapsibleCompression->setEnabled(true);
-        m_ui->compLevelSlider->setMinimum(archiveFormat.minCompressionLevel());
-        m_ui->compLevelSlider->setMaximum(archiveFormat.maxCompressionLevel());
-        m_ui->compLevelSlider->setValue(archiveFormat.defaultCompressionLevel());
-    }
-
-    slotEncryptionToggled();
+    m_ui->optionsWidget->setMimeType(QMimeDatabase().mimeTypeForName(m_supportedMimeTypes.at(index)));
 }
 
 void CreateDialog::slotUpdateFilenameExtension(int index)
@@ -175,35 +148,32 @@ QUrl CreateDialog::selectedUrl() const
 
 int CreateDialog::compressionLevel() const
 {
-    if (m_ui->compLevelSlider->isEnabled()) {
-        return m_ui->compLevelSlider->value();
-    }
-    return -1;
+    return m_ui->optionsWidget->compressionLevel();
 }
 
 QString CreateDialog::password() const
 {
-    return m_ui->pwdWidget->password();
+    return m_ui->optionsWidget->password();
 }
 
 bool CreateDialog::isEncryptionAvailable() const
 {
-    return m_ui->collapsibleEncryption->isEnabled();
+    return m_ui->optionsWidget->isEncryptionAvailable();
 }
 
 bool CreateDialog::isEncryptionEnabled() const
 {
-    return isEncryptionAvailable() && m_ui->collapsibleEncryption->isExpanded();
+    return m_ui->optionsWidget->isEncryptionEnabled();
 }
 
 bool CreateDialog::isHeaderEncryptionAvailable() const
 {
-    return isEncryptionEnabled() && m_ui->encryptHeaderCheckBox->isEnabled();
+    return m_ui->optionsWidget->isHeaderEncryptionAvailable();
 }
 
 bool CreateDialog::isHeaderEncryptionEnabled() const
 {
-    return isHeaderEncryptionAvailable() && m_ui->encryptHeaderCheckBox->isChecked();
+    return m_ui->optionsWidget->isHeaderEncryptionEnabled();
 }
 
 void CreateDialog::accept()
@@ -213,7 +183,7 @@ void CreateDialog::accept()
         return;
     }
 
-    switch (m_ui->pwdWidget->passwordStatus()) {
+    switch (m_ui->optionsWidget->passwordStatus()) {
     case KNewPasswordWidget::WeakPassword:
     case KNewPasswordWidget::StrongPassword:
         QDialog::accept();
@@ -226,30 +196,6 @@ void CreateDialog::accept()
     }
 }
 
-void CreateDialog::slotEncryptionToggled()
-{
-    const KPluginMetaData metadata = m_pluginManger.preferredPluginFor(currentMimeType())->metaData();
-    const ArchiveFormat archiveFormat = ArchiveFormat::fromMetadata(currentMimeType(), metadata);
-    Q_ASSERT(archiveFormat.isValid());
-
-    const bool isExpanded = m_ui->collapsibleEncryption->isExpanded();
-    if (isExpanded && (archiveFormat.encryptionType() == Archive::HeaderEncrypted)) {
-        m_ui->encryptHeaderCheckBox->setEnabled(true);
-        m_ui->encryptHeaderCheckBox->setToolTip(QString());
-    } else {
-        m_ui->encryptHeaderCheckBox->setEnabled(false);
-        // Show the tooltip only if the encryption is still enabled.
-        // This is needed because if the new filter is e.g. tar, the whole encryption group gets disabled.
-        if (isEncryptionEnabled()) {
-            m_ui->encryptHeaderCheckBox->setToolTip(i18n("Protection of the list of files is not possible with the %1 format.",
-                                                         currentMimeType().comment()));
-        } else {
-            m_ui->encryptHeaderCheckBox->setToolTip(QString());
-        }
-    }
-    m_ui->pwdWidget->setEnabled(isExpanded);
-}
-
 void CreateDialog::slotUpdateDefaultMimeType()
 {
     m_config.writeEntry("LastMimeType", currentMimeType().name());
diff --git a/kerfuffle/createdialog.h b/kerfuffle/createdialog.h
index f3fe49d..4ba3d40 100644
--- a/kerfuffle/createdialog.h
+++ b/kerfuffle/createdialog.h
@@ -31,6 +31,7 @@
 #ifndef CREATEDIALOG_H
 #define CREATEDIALOG_H
 
+#include "archive_kerfuffle.h"
 #include "kerfuffle_export.h"
 #include "pluginmanager.h"
 
@@ -90,11 +91,11 @@ private:
     KConfigGroup m_config;
     QStringList m_supportedMimeTypes;
     PluginManager m_pluginManger;
+    CompressionOptions m_compOptions;
 
 private slots:
     void slotFileNameEdited(const QString &text);
     void slotUpdateWidgets(int index);
-    void slotEncryptionToggled();
     void slotUpdateDefaultMimeType();
     void slotUpdateFilenameExtension(int index);
 };
diff --git a/kerfuffle/createdialog.ui b/kerfuffle/createdialog.ui
index addf276..e0eb481 100644
--- a/kerfuffle/createdialog.ui
+++ b/kerfuffle/createdialog.ui
@@ -18,205 +18,98 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <layout class="QFormLayout" name="formLayout">
-     <property name="sizeConstraint">
-      <enum>QLayout::SetFixedSize</enum>
-     </property>
-     <item row="0" column="0">
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>Folder:</string>
+    <layout class="QVBoxLayout" name="vlayout">
+     <item>
+      <layout class="QFormLayout" name="formLayout">
+       <property name="sizeConstraint">
+        <enum>QLayout::SetFixedSize</enum>
        </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <widget class="KUrlRequester" name="destFolderUrlRequester">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="0">
-      <widget class="QLabel" name="label_3">
-       <property name="text">
-        <string>Filename:</string>
-       </property>
-      </widget>
+       <item row="0" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Folder:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1">
+        <widget class="KUrlRequester" name="destFolderUrlRequester">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label_3">
+         <property name="text">
+          <string>Filename:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLineEdit" name="filenameLineEdit">
+         <property name="placeholderText">
+          <string>Type archive name...</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="0">
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string>Type:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QComboBox" name="mimeComboBox">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="0">
+        <widget class="QLabel" name="label_4">
+         <property name="text">
+          <string>Extension:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1">
+        <widget class="QCheckBox" name="chkAddExtension">
+         <property name="text">
+          <string notr="true">Automatically add filename extension (extension)</string>
+         </property>
+         <property name="checked">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+      </layout>
      </item>
-     <item row="1" column="1">
-      <widget class="QLineEdit" name="filenameLineEdit">
-       <property name="placeholderText">
-        <string>Type archive name...</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="0">
-      <widget class="QLabel" name="label_2">
-       <property name="text">
-        <string>Type:</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="1">
-      <widget class="QComboBox" name="mimeComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
+     <item>
+      <widget class="Kerfuffle::CompressionOptionsWidget" name="optionsWidget" native="true"/>
      </item>
-     <item row="4" column="0">
-      <widget class="QLabel" name="label_4">
-       <property name="text">
-        <string>Extension:</string>
+     <item>
+      <widget class="Line" name="line">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
        </property>
       </widget>
      </item>
-     <item row="4" column="1">
-      <widget class="QCheckBox" name="chkAddExtension">
-       <property name="text">
-        <string notr="true">Automatically add filename extension (extension)</string>
-       </property>
-       <property name="checked">
-        <bool>true</bool>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
        </property>
       </widget>
      </item>
     </layout>
    </item>
-   <item>
-    <widget class="KCollapsibleGroupBox" name="collapsibleEncryption">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title">
-      <string>Password Protection</string>
-     </property>
-     <property name="expanded">
-      <bool>false</bool>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout_3">
-      <item>
-       <widget class="KNewPasswordWidget" name="pwdWidget" native="true">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QCheckBox" name="encryptHeaderCheckBox">
-        <property name="enabled">
-         <bool>false</bool>
-        </property>
-        <property name="layoutDirection">
-         <enum>Qt::LeftToRight</enum>
-        </property>
-        <property name="text">
-         <string>Ask for password before showing the list of files in the archive</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="KCollapsibleGroupBox" name="collapsibleCompression">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
-     <property name="title">
-      <string>Compression</string>
-     </property>
-     <property name="expanded">
-      <bool>false</bool>
-     </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="1">
-       <widget class="QLabel" name="label_6">
-        <property name="text">
-         <string>Min</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QLabel" name="label_7">
-        <property name="text">
-         <string>Max</string>
-        </property>
-        <property name="alignment">
-         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_5">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-          <horstretch>1</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="text">
-         <string>Level:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1" colspan="2">
-       <widget class="QSlider" name="compLevelSlider">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-          <horstretch>3</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-        <property name="maximum">
-         <number>9</number>
-        </property>
-        <property name="pageStep">
-         <number>1</number>
-        </property>
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="tickPosition">
-         <enum>QSlider::TicksBothSides</enum>
-        </property>
-        <property name="tickInterval">
-         <number>1</number>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="Line" name="line_2">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
-     </property>
-    </widget>
-   </item>
   </layout>
  </widget>
  <customwidgets>
@@ -226,15 +119,9 @@
    <header>kurlrequester.h</header>
   </customwidget>
   <customwidget>
-   <class>KCollapsibleGroupBox</class>
-   <extends>QWidget</extends>
-   <header>kcollapsiblegroupbox.h</header>
-   <container>1</container>
-  </customwidget>
-  <customwidget>
-   <class>KNewPasswordWidget</class>
+   <class>Kerfuffle::CompressionOptionsWidget</class>
    <extends>QWidget</extends>
-   <header location="global">KNewPasswordWidget</header>
+   <header location="global">compressionoptionswidget.h</header>
    <container>1</container>
   </customwidget>
  </customwidgets>
@@ -242,7 +129,6 @@
   <tabstop>destFolderUrlRequester</tabstop>
   <tabstop>filenameLineEdit</tabstop>
   <tabstop>mimeComboBox</tabstop>
-  <tabstop>collapsibleEncryption</tabstop>
  </tabstops>
  <resources/>
  <connections/>
diff --git a/part/ark_part.rc b/part/ark_part.rc
index 62c0e68..628fb98 100644
--- a/part/ark_part.rc
+++ b/part/ark_part.rc
@@ -1,11 +1,10 @@
 <!DOCTYPE kpartgui>
-<kpartgui name="ark_part" version="14">
+<kpartgui name="ark_part" version="15">
 <MenuBar>
 	<Menu name="archive">
 		<text>&Archive</text>
 		<Action name="ark_file_save_as" group="file_save"/>
 		<Action name="add" group="archive_edit"/>
-		<Action name="add-dir" group="archive_edit"/>
 		<Action name="edit_comment" group="archive_edit"/>
 		<Action name="extract_all" group="archive_extract"/>
 		<Action name="properties" group="archive_props"/>
diff --git a/part/part.cpp b/part/part.cpp
index 7614646..435cb9b 100644
--- a/part/part.cpp
+++ b/part/part.cpp
@@ -23,6 +23,7 @@
 
 #include "part.h"
 #include "ark_debug.h"
+#include "adddialog.h"
 #include "archiveformat.h"
 #include "archivemodel.h"
 #include "archiveview.h"
@@ -364,18 +365,11 @@ void Part::setupActions()
 
     m_addFilesAction = actionCollection()->addAction(QStringLiteral("add"));
     m_addFilesAction->setIcon(QIcon::fromTheme(QStringLiteral("archive-insert")));
-    m_addFilesAction->setText(i18n("Add &File..."));
+    m_addFilesAction->setText(i18n("Add &Files..."));
     m_addFilesAction->setToolTip(i18nc("@info:tooltip", "Click to add files to the archive"));
     connect(m_addFilesAction, SIGNAL(triggered(bool)),
             this, SLOT(slotAddFiles()));
 
-    m_addDirAction = actionCollection()->addAction(QStringLiteral("add-dir"));
-    m_addDirAction->setIcon(QIcon::fromTheme(QStringLiteral("archive-insert-directory")));
-    m_addDirAction->setText(i18n("Add Fo&lder..."));
-    m_addDirAction->setToolTip(i18nc("@info:tooltip", "Click to add a folder to the archive"));
-    connect(m_addDirAction, &QAction::triggered,
-            this, &Part::slotAddDir);
-
     m_deleteFilesAction = actionCollection()->addAction(QStringLiteral("delete"));
     m_deleteFilesAction->setIcon(QIcon::fromTheme(QStringLiteral("archive-remove")));
     m_deleteFilesAction->setText(i18n("De&lete"));
@@ -437,8 +431,6 @@ void Part::updateActions()
                                m_model->rowCount() > 0);
     m_addFilesAction->setEnabled(!isBusy() &&
                                  isWritable);
-    m_addDirAction->setEnabled(!isBusy() &&
-                               isWritable);
     m_deleteFilesAction->setEnabled(!isBusy() &&
                                     isWritable &&
                                     (selectedEntriesCount > 0));
@@ -1214,17 +1206,14 @@ void Part::slotAddFiles(const QStringList& filesToAdd, const QString& path)
         globalWorkDir.chop(1);
     }
 
+    CompressionOptions options(m_model->archive()->compressionOptions());
+
     // Now take the absolute path of the parent directory.
     globalWorkDir = QFileInfo(globalWorkDir).dir().absolutePath();
 
     qCDebug(ARK) << "Detected GlobalWorkDir to be " << globalWorkDir;
-    CompressionOptions options;
     options[QStringLiteral("GlobalWorkDir")] = globalWorkDir;
 
-    if (arguments().metaData().contains(QStringLiteral("compressionLevel"))) {
-        options[QStringLiteral("CompressionLevel")] = arguments().metaData()[QStringLiteral("compressionLevel")];
-    }
-
     AddJob *job = m_model->addFiles(cleanFilesToAdd, options);
     if (!job) {
         return;
@@ -1238,6 +1227,19 @@ void Part::slotAddFiles(const QStringList& filesToAdd, const QString& path)
 
 void Part::slotAddFiles()
 {
+    // If compression options are already set, we dont use the values from CreateDialog.
+    CompressionOptions opts;
+    if (m_model->archive()->compressionOptions().isEmpty()) {
+        if (arguments().metaData().contains(QStringLiteral("compressionLevel"))) {
+            opts[QStringLiteral("CompressionLevel")] = arguments().metaData()[QStringLiteral("compressionLevel")];
+        }
+        m_model->archive()->setCompressionOptions(opts);
+    } else {
+        opts = m_model->archive()->compressionOptions();
+    }
+
+    qCDebug(ARK) << "Opening AddDialog with opts:" << opts;
+
     // #264819: passing widget() as the parent will not work as expected.
     //          KFileDialog will create a KFileWidget, which runs an internal
     //          event loop to stat the given directory. This, in turn, leads to
@@ -1248,18 +1250,19 @@ void Part::slotAddFiles()
     //          When KFileDialog::exec() is called, the widget is already shown
     //          and nothing happens.
 
-    const QStringList filesToAdd = QFileDialog::getOpenFileNames(widget(), i18nc("@title:window", "Add Files"));
-
-    slotAddFiles(filesToAdd);
-}
-
-void Part::slotAddDir()
-{
-    const QString dirToAdd = QFileDialog::getExistingDirectory(widget(), i18nc("@title:window", "Add Folder"));
+    QPointer<AddDialog> dlg = new AddDialog(widget(),
+                                            i18nc("@title:window", "Add Files"),
+                                            m_lastUsedAddPath,
+                                            m_model->archive()->mimeType(),
+                                            opts);
 
-    if (!dirToAdd.isEmpty()) {
-        slotAddFiles(QStringList() << dirToAdd);
+    if (dlg->exec() == QDialog::Accepted) {
+        qCDebug(ARK) << "Selected files:" << dlg->selectedFiles();
+        qCDebug(ARK) << "Options:" << dlg->compressionOptions();
+        m_model->archive()->setCompressionOptions(dlg->compressionOptions());
+        slotAddFiles(dlg->selectedFiles(), QString());
     }
+    delete dlg;
 }
 
 void Part::slotAddFilesDone(KJob* job)
diff --git a/part/part.h b/part/part.h
index df9a895..ba75065 100644
--- a/part/part.h
+++ b/part/part.h
@@ -105,7 +105,6 @@ private slots:
     void slotQuickExtractFiles(QAction*);
     void slotAddFiles();
     void slotAddFiles(const QStringList& files, const QString& path = QString());
-    void slotAddDir();
     void slotAddFilesDone(KJob*);
     void slotTestingDone(KJob*);
     void slotDeleteFiles();
@@ -153,7 +152,6 @@ private:
     QAction *m_extractArchiveAction;
     QAction *m_extractAction;
     QAction *m_addFilesAction;
-    QAction *m_addDirAction;
     QAction *m_deleteFilesAction;
     QAction *m_saveAsAction;
     QAction *m_propertiesAction;
@@ -165,6 +163,7 @@ private:
     QList<QTemporaryDir*>      m_tmpOpenDirList;
     bool                  m_busy;
     OpenFileMode m_openFileMode;
+    QUrl m_lastUsedAddPath;
 
     KAbstractWidgetJobTracker  *m_jobTracker;
     KParts::StatusBarExtension *m_statusBarExtension;


More information about the kde-doc-english mailing list