[kde-doc-english] [ark/Applications/15.08] /: Create password-protected archives with Ark

Elvis Angelaccio elvis.angelaccio at kdemail.net
Wed Jul 22 12:36:27 UTC 2015


Git commit 402bbe84bed878827664b849b8fb5e910bde1882 by Elvis Angelaccio.
Committed on 22/07/2015 at 12:26.
Pushed by elvisangelaccio into branch 'Applications/15.08'.

Create password-protected archives with Ark

This feature allows Ark to create a password-protected archive from
scratch.
The 7z and rar plugins support both header encryption and entries-only
encryption, while the zip one supports only the latter.

An encrypted archive can be created through the CreateDialog (within Ark) or
through the AddDialog (from e.g. Dolphin).

REVIEW: 120204
FEATURE: 253694
FIXED-IN: 15.08
GUI:

M  +30   -11   app/mainwindow.cpp
M  +13   -8    kerfuffle/CMakeLists.txt
M  +11   -133  kerfuffle/adddialog.cpp
M  +5    -24   kerfuffle/adddialog.h
M  +33   -52   kerfuffle/adddialog.ui
M  +19   -2    kerfuffle/addtoarchive.cpp
M  +4    -0    kerfuffle/addtoarchive.h
M  +51   -0    kerfuffle/archive_kerfuffle.cpp
M  +3    -0    kerfuffle/archive_kerfuffle.h
M  +10   -0    kerfuffle/archiveinterface.cpp
M  +4    -0    kerfuffle/archiveinterface.h
M  +85   -0    kerfuffle/cliinterface.cpp
M  +21   -1    kerfuffle/cliinterface.h
A  +256  -0    kerfuffle/createdialog.cpp     [License: BSD]
C  +32   -21   kerfuffle/createdialog.h [from: kerfuffle/adddialog.h - 070% similarity]
A  +122  -0    kerfuffle/createdialog.ui
M  +7    -0    kerfuffle/kerfufflePlugin.desktop
M  +12   -0    part/archivemodel.cpp
M  +3    -0    part/archivemodel.h
M  +9    -0    part/part.cpp
M  +3    -2    plugins/cli7zplugin/cliplugin.cpp
M  +2    -0    plugins/cli7zplugin/kerfuffle_cli7z.desktop.cmake
M  +3    -2    plugins/clirarplugin/cliplugin.cpp
M  +3    -1    plugins/clirarplugin/kerfuffle_clirar.desktop.cmake
M  +1    -1    plugins/clizipplugin/cliplugin.cpp
M  +3    -1    plugins/clizipplugin/kerfuffle_clizip.desktop.cmake

http://commits.kde.org/ark/402bbe84bed878827664b849b8fb5e910bde1882

diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp
index a71874e..172a125 100644
--- a/app/mainwindow.cpp
+++ b/app/mainwindow.cpp
@@ -24,6 +24,7 @@
 #include "logging.h"
 #include "mainwindow.h"
 #include "kerfuffle/archive_kerfuffle.h"
+#include "kerfuffle/createdialog.h"
 #include "kerfuffle/settingspage.h"
 #include "part/interface.h"
 
@@ -310,17 +311,35 @@ void MainWindow::newArchive()
 
     qCDebug(ARK) << "Supported mimetypes are" << mimeTypes.join(QLatin1String(" "));
 
-    QFileDialog dlg(this);
-    dlg.setMimeTypeFilters(mimeTypes);
-    QStringList filters = dlg.nameFilters();
-    filters.sort(Qt::CaseInsensitive);
-    dlg.setNameFilters(filters);
-    dlg.setFileMode(QFileDialog::AnyFile);
-    dlg.setAcceptMode(QFileDialog::AcceptSave);
-    if (dlg.exec() == QDialog::Accepted) {
+    QPointer<Kerfuffle::CreateDialog> dialog = new Kerfuffle::CreateDialog(
+        Q_NULLPTR, // parent
+        i18n("Create a new Archive"), // caption
+        QUrl()); // startDir
+
+    dialog.data()->show();
+    dialog.data()->restoreWindowSize();
+
+    if (dialog.data()->exec()) {
+        const QUrl saveFileUrl = dialog.data()->selectedUrls().first();
+        const QString password = dialog.data()->password();
+
+        qCDebug(ARK) << "CreateDialog returned URL:" << saveFileUrl.toString();
+        qCDebug(ARK) << "CreateDialog returned mime:" << dialog.data()->currentMimeFilter();
+
         m_openArgs.metaData()[QLatin1String( "createNewArchive" )] = QLatin1String( "true" );
-        openUrl(dlg.selectedUrls().first());
-        m_openArgs.metaData().remove(QLatin1String( "showExtractDialog" ));
-        m_openArgs.metaData().remove(QLatin1String( "createNewArchive" ));
+        m_openArgs.metaData()[QLatin1String("encryptionPassword")] = password;
+
+        if (dialog.data()->isHeaderEncryptionChecked()) {
+            m_openArgs.metaData()[QLatin1String("encryptHeader")] = QLatin1String("true");
+        }
+
+        openUrl(saveFileUrl);
+
+        m_openArgs.metaData().remove(QLatin1String("showExtractDialog"));
+        m_openArgs.metaData().remove(QLatin1String("createNewArchive"));
+        m_openArgs.metaData().remove(QLatin1String("encryptionPassword"));
+        m_openArgs.metaData().remove(QLatin1String("encryptHeader"));
     }
+
+    delete dialog.data();
 }
diff --git a/kerfuffle/CMakeLists.txt b/kerfuffle/CMakeLists.txt
index 1ef63bc..cde4c32 100644
--- a/kerfuffle/CMakeLists.txt
+++ b/kerfuffle/CMakeLists.txt
@@ -7,18 +7,23 @@ set(kerfuffle_SRCS
     previewsettingspage.cpp
     settingspage.cpp
     jobs.cpp
-	extractiondialog.cpp
-	adddialog.cpp
-	queries.cpp
-	addtoarchive.cpp
-	cliinterface.cpp
+    createdialog.cpp
+    extractiondialog.cpp
+    adddialog.cpp
+    queries.cpp
+    addtoarchive.cpp
+    cliinterface.cpp
    )
 
 kconfig_add_kcfg_files(kerfuffle_SRCS settings.kcfgc)
 
-ki18n_wrap_ui(kerfuffle_SRCS extractiondialog.ui adddialog.ui )
-ki18n_wrap_ui(kerfuffle_SRCS extractionsettings.ui)
-ki18n_wrap_ui(kerfuffle_SRCS previewsettings.ui)
+ki18n_wrap_ui(kerfuffle_SRCS
+    adddialog.ui
+    createdialog.ui
+    extractiondialog.ui
+    extractionsettings.ui
+    previewsettings.ui
+)
 
 add_library(kerfuffle SHARED ${kerfuffle_SRCS})
 generate_export_header(kerfuffle BASE_NAME kerfuffle)
diff --git a/kerfuffle/adddialog.cpp b/kerfuffle/adddialog.cpp
index 45aed46..ed1e015 100644
--- a/kerfuffle/adddialog.cpp
+++ b/kerfuffle/adddialog.cpp
@@ -26,26 +26,18 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "app/logging.h"
 #include "adddialog.h"
+#include "app/logging.h"
 #include "ui_adddialog.h"
 #include "kerfuffle/archive_kerfuffle.h"
 
-
 #include <KFilePlacesModel>
-#include <KSharedConfig>
-#include <KWindowConfig>
-#include <KUrlComboBox>
-#include <KMessageBox>
+#include <KFileWidget>
 
+#include <QDir>
 #include <QFileInfo>
-#include <QStandardItemModel>
-#include <QPushButton>
-#include <QIcon>
 #include <QMimeDatabase>
-#include <QDebug>
-#include <QWindow>
-#include <QScreen>
+#include <QStandardItemModel>
 
 namespace Kerfuffle
 {
@@ -58,95 +50,25 @@ public:
     }
 };
 
-AddDialog::AddDialog(const QStringList &itemsToAdd,
-                     QWidget *parent,
+AddDialog::AddDialog(QWidget *parent,
                      const QString &caption,
-                     const QUrl &startDir)
-        : QDialog(parent, Qt::Dialog)
+                     const QUrl &startDir,
+                     const QStringList &itemsToAdd)
+        : CreateDialog(parent, caption, startDir)
 {
     qCDebug(KERFUFFLE) << "AddDialog loaded";
 
-    this->setWindowTitle(caption);
-
-    QHBoxLayout *hlayout = new QHBoxLayout();
-    setLayout(hlayout);
-
-    fileWidget = new KFileWidget(startDir, this);
-    hlayout->addWidget(fileWidget);
-
-    fileWidget->setMode(KFile::File | KFile::LocalOnly);
-    fileWidget->setConfirmOverwrite(true);
-    fileWidget->setOperationMode(KFileWidget::Saving);
-
-    connect(fileWidget->okButton(), &QPushButton::clicked, this, &AddDialog::slotOkButtonClicked);
-    connect(fileWidget, &KFileWidget::accepted, fileWidget, &KFileWidget::accept);
-    connect(fileWidget, &KFileWidget::accepted, this, &QDialog::accept);
-    fileWidget->okButton()->show();
-
-    fileWidget->cancelButton()->show();
-    connect(fileWidget->cancelButton(), &QPushButton::clicked, this, &QDialog::reject);
-
-    loadConfiguration();
-
-    connect(this, &QDialog::accepted, this, &AddDialog::updateDefaultMimeType);
-    connect(this, &QDialog::finished, this, &AddDialog::slotSaveWindowSize);
-
-    // Sidepanel with extra options, disabled for now
-    /*
     m_ui = new AddDialogUI(this);
-    hlayout->addWidget(m_ui);
-    m_ui->groupExtraOptions->hide();
+    m_vlayout->addWidget(m_ui);
+
     setupIconList(itemsToAdd);
-    */
 
     // Set up a default name if there's only one file to compress
     if (itemsToAdd.size() == 1) {
         const QFileInfo fileInfo(itemsToAdd.first());
         const QString fileName =
             fileInfo.isDir() ? fileInfo.dir().dirName() : fileInfo.baseName();
-        fileWidget->setSelection(fileName);
-    }
-}
-
-QSize AddDialog::sizeHint() const
-{
-    // Used only when no previous window size has been stored
-    return QSize(750,450);
-}
-
-void AddDialog::loadConfiguration()
-{
-    m_config = KConfigGroup(KSharedConfig::openConfig()->group("AddDialog"));
-
-    const QString defaultMimeType = QLatin1String("application/x-compressed-tar");
-    const QString lastMimeType = m_config.readEntry("LastMimeType", defaultMimeType);
-    QStringList writeMimeTypes = Kerfuffle::supportedWriteMimeTypes();
-
-    // The filters need to be sorted by comment, so create a QMap with
-    // comment as key (QMaps are always sorted by key) and QMimeType
-    // as value. Then convert the QMap back to a QStringList. Mimetypes
-    // with empty comments are discarded.
-    QMimeDatabase db;
-    QMap<QString,QMimeType> mimeMap;
-    foreach (const QString &s, writeMimeTypes) {
-        QMimeType mime(db.mimeTypeForName(s));
-        if (!mime.comment().isEmpty()) {
-            mimeMap[mime.comment()] = mime;
-        }
-    }
-
-    writeMimeTypes.clear();
-
-    QMapIterator<QString,QMimeType> j(mimeMap);
-    while (j.hasNext()) {
-        j.next();
-        writeMimeTypes << j.value().name();
-    }
-
-    if (writeMimeTypes.contains(lastMimeType)) {
-        fileWidget->setMimeFilter(writeMimeTypes, lastMimeType);
-    } else {
-        fileWidget->setMimeFilter(writeMimeTypes, defaultMimeType);
+        m_fileWidget->setSelection(fileName);
     }
 }
 
@@ -175,48 +97,4 @@ void AddDialog::setupIconList(const QStringList& itemsToAdd)
     m_ui->compressList->setModel(listModel);
 }
 
-void AddDialog::updateDefaultMimeType()
-{
-    m_config.writeEntry("LastMimeType", fileWidget->currentFilterMimeType().name());
-}
-
-QList<QUrl> AddDialog::selectedUrls()
-{
-    return(fileWidget->selectedUrls());
-}
-
-QString AddDialog::currentMimeFilter()
-{
-    return(fileWidget->currentMimeFilter());
-}
-
-void AddDialog::slotSaveWindowSize()
-{
-    // Save dialog window size
-    KConfigGroup group(KSharedConfig::openConfig(), "AddDialog");
-    KWindowConfig::saveWindowSize(windowHandle(), group, KConfigBase::Persistent);
-}
-
-void AddDialog::slotOkButtonClicked()
-{
-    // In case the user tries to leave the lineEdit empty:
-    if (fileWidget->locationEdit()->urls().at(0) == fileWidget->baseUrl().path().left(fileWidget->baseUrl().path().size()-1))
-    {
-        KMessageBox::sorry(this, i18n("Please select a filename for the archive."), i18n("No file selected"));
-        return;
-    }
-    // This slot sets the url from text in the lineEdit, asks for overwrite etc, and emits signal accepted
-    fileWidget->slotOk();
-}
-
-void AddDialog::restoreWindowSize()
-{
-  // Restore window size from config file, needs a windowHandle so must be called after show()
-  KConfigGroup group(KSharedConfig::openConfig(), "AddDialog");
-  //KWindowConfig::restoreWindowSize(windowHandle(), group);
-  //KWindowConfig::restoreWindowSize is broken atm., so we need this hack:
-  const QRect desk = windowHandle()->screen()->geometry();
-  this->resize(QSize(group.readEntry(QString::fromLatin1("Width %1").arg(desk.width()), windowHandle()->size().width()),
-                     group.readEntry(QString::fromLatin1("Height %1").arg(desk.height()), windowHandle()->size().height())));
-}
 }
diff --git a/kerfuffle/adddialog.h b/kerfuffle/adddialog.h
index 217da1e..dfb7f78 100644
--- a/kerfuffle/adddialog.h
+++ b/kerfuffle/adddialog.h
@@ -29,44 +29,25 @@
 #ifndef ADDDIALOG_H
 #define ADDDIALOG_H
 
+#include "createdialog.h"
 #include "kerfuffle_export.h"
 
-#include <KConfigGroup>
-#include <KFileWidget>
-
-#include <QDialog>
-
 namespace Kerfuffle
 {
-class KERFUFFLE_EXPORT AddDialog : public QDialog
+class KERFUFFLE_EXPORT AddDialog : public CreateDialog
 {
     Q_OBJECT
 
 public:
-    AddDialog(const QStringList &itemsToAdd,
-              QWidget *parent,
+    AddDialog(QWidget *parent,
               const QString &caption,
-              const QUrl &startDir);
-    QSize sizeHint() const Q_DECL_OVERRIDE;
-
-    QList<QUrl> selectedUrls();
-    QString currentMimeFilter();
+              const QUrl &startDir,
+              const QStringList &itemsToAdd);
 
 private:
     class AddDialogUI *m_ui;
-    KConfigGroup m_config;
-    KFileWidget *fileWidget;
 
-    void loadConfiguration();
     void setupIconList(const QStringList& itemsToAdd);
-
-public slots:
-    void restoreWindowSize();
-
-private slots:
-    void updateDefaultMimeType();
-    void slotSaveWindowSize();
-    void slotOkButtonClicked();
 };
 }
 
diff --git a/kerfuffle/adddialog.ui b/kerfuffle/adddialog.ui
index a1c595b..be97db6 100644
--- a/kerfuffle/adddialog.ui
+++ b/kerfuffle/adddialog.ui
@@ -1,104 +1,85 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>AddDialog</class>
- <widget class="QWidget" name="AddDialog" >
-  <property name="geometry" >
+ <widget class="QWidget" name="AddDialog">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>565</width>
-    <height>113</height>
+    <height>181</height>
    </rect>
   </property>
-  <property name="minimumSize" >
+  <property name="minimumSize">
    <size>
     <width>0</width>
     <height>0</height>
    </size>
   </property>
-  <layout class="QHBoxLayout" name="horizontalLayout" >
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
    <item>
-    <widget class="QGroupBox" name="groupCompressFiles" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+    <widget class="QGroupBox" name="groupCompressFiles">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
-     <property name="title" >
+     <property name="title">
       <string>Files/Folders to Compress</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_2" >
+     <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
-       <widget class="QListView" name="compressList" >
-        <property name="sizePolicy" >
-         <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+       <widget class="QListView" name="compressList">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
         </property>
-        <property name="autoFillBackground" >
+        <property name="autoFillBackground">
          <bool>false</bool>
         </property>
-        <property name="frameShape" >
+        <property name="frameShape">
          <enum>QFrame::NoFrame</enum>
         </property>
-        <property name="frameShadow" >
+        <property name="frameShadow">
          <enum>QFrame::Plain</enum>
         </property>
-        <property name="lineWidth" >
+        <property name="lineWidth">
          <number>0</number>
         </property>
-        <property name="editTriggers" >
+        <property name="editTriggers">
          <set>QAbstractItemView::NoEditTriggers</set>
         </property>
-        <property name="selectionMode" >
+        <property name="selectionMode">
          <enum>QAbstractItemView::NoSelection</enum>
         </property>
-        <property name="iconSize" >
+        <property name="iconSize">
          <size>
           <width>32</width>
           <height>32</height>
          </size>
         </property>
-        <property name="textElideMode" >
+        <property name="textElideMode">
          <enum>Qt::ElideMiddle</enum>
         </property>
-        <property name="verticalScrollMode" >
+        <property name="verticalScrollMode">
          <enum>QAbstractItemView::ScrollPerPixel</enum>
         </property>
-        <property name="resizeMode" >
+        <property name="resizeMode">
          <enum>QListView::Adjust</enum>
         </property>
-        <property name="viewMode" >
+        <property name="viewMode">
          <enum>QListView::IconMode</enum>
         </property>
-        <property name="uniformItemSizes" >
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupExtraOptions" >
-     <property name="sizePolicy" >
-      <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="title" >
-      <string>Extra Compression Options</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout" >
-      <item>
-       <widget class="QLabel" name="label" >
-        <property name="text" >
-         <string>Easter egg for the developers:
-This is where future versions will have extra compression options for the various compression interfaces.</string>
-        </property>
-        <property name="wordWrap" >
+        <property name="uniformItemSizes">
          <bool>true</bool>
         </property>
        </widget>
diff --git a/kerfuffle/addtoarchive.cpp b/kerfuffle/addtoarchive.cpp
index 6a63839..cd6117c 100644
--- a/kerfuffle/addtoarchive.cpp
+++ b/kerfuffle/addtoarchive.cpp
@@ -75,15 +75,25 @@ void AddToArchive::setMimeType(const QString & mimeType)
     m_mimeType = mimeType;
 }
 
+void AddToArchive::setPassword(const QString &password)
+{
+    m_password = password;
+}
+
+void AddToArchive::setHeaderEncryptionEnabled(bool enabled)
+{
+    m_enableHeaderEncryption = enabled;
+}
+
 bool AddToArchive::showAddDialog()
 {
     qCDebug(KERFUFFLE) << "Opening add dialog";
 
     QPointer<Kerfuffle::AddDialog> dialog = new Kerfuffle::AddDialog(
-        m_inputs, // itemsToAdd
         Q_NULLPTR, // parent
         i18n("Compress to Archive"), // caption
-        QUrl::fromLocalFile(m_firstPath)); // startDir
+        QUrl::fromLocalFile(m_firstPath), // startDir
+        m_inputs); // itemsToAdd
 
     dialog.data()->show();
     dialog.data()->restoreWindowSize();
@@ -94,6 +104,8 @@ bool AddToArchive::showAddDialog()
         qCDebug(KERFUFFLE) << "AddDialog returned mime:" << dialog.data()->currentMimeFilter();
         setFilename(dialog.data()->selectedUrls().at(0));
         setMimeType(dialog.data()->currentMimeFilter());
+        setPassword(dialog.data()->password());
+        setHeaderEncryptionEnabled(dialog.data()->isHeaderEncryptionChecked());
     }
 
     delete dialog.data();
@@ -175,6 +187,11 @@ void AddToArchive::slotStartJob()
         return;
     }
 
+    if (!m_password.isEmpty()) {
+        archive->setPassword(m_password);
+        archive->enableHeaderEncryption(m_enableHeaderEncryption);
+    }
+
     if (m_changeToFirstPath) {
         if (m_firstPath.isEmpty()) {
             qCWarning(KERFUFFLE) << "Weird, this should not happen. no firstpath defined. aborting";
diff --git a/kerfuffle/addtoarchive.h b/kerfuffle/addtoarchive.h
index a5bdeba..d4ebb05 100644
--- a/kerfuffle/addtoarchive.h
+++ b/kerfuffle/addtoarchive.h
@@ -66,6 +66,8 @@ public slots:
     void setAutoFilenameSuffix(const QString& suffix);
     void setFilename(const QUrl &path);
     void setMimeType(const QString & mimeType);
+    void setPassword(const QString &password);
+    void setHeaderEncryptionEnabled(bool enabled);
     void start() Q_DECL_OVERRIDE;
 
 private slots:
@@ -78,8 +80,10 @@ private:
     QString m_autoFilenameSuffix;
     QString m_firstPath;
     QString m_mimeType;
+    QString m_password;
     QStringList m_inputs;
     bool m_changeToFirstPath;
+    bool m_enableHeaderEncryption;
 };
 }
 
diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp
index c22d61e..7b9990d 100644
--- a/kerfuffle/archive_kerfuffle.cpp
+++ b/kerfuffle/archive_kerfuffle.cpp
@@ -287,6 +287,11 @@ void Archive::setPassword(const QString &password)
     m_iface->setPassword(password);
 }
 
+void Archive::enableHeaderEncryption(bool enable)
+{
+    m_iface->setHeaderEncryptionEnabled(enable);
+}
+
 QStringList supportedMimeTypes()
 {
     const QLatin1String constraint("(exist Library)");
@@ -341,4 +346,50 @@ QStringList supportedWriteMimeTypes()
     return supported;
 }
 
+QSet<QString> supportedEncryptEntriesMimeTypes()
+{
+    const QLatin1String constraint("(exist Library) and ([X-KDE-Kerfuffle-EncryptEntries] == true)");
+    const QLatin1String basePartService("Kerfuffle/Plugin");
+
+    const KService::List offers = KServiceTypeTrader::self()->query(basePartService, constraint);
+    QSet<QString> supported;
+
+    foreach (const KService::Ptr& service, offers) {
+        QStringList mimeTypes = service->serviceTypes();
+
+        foreach (const QString& mimeType, mimeTypes) {
+            if (mimeType != basePartService) {
+                supported.insert(mimeType);
+            }
+        }
+    }
+
+    qCDebug(KERFUFFLE) << "Returning supported mimetypes" << supported;
+
+    return supported;
+}
+
+QSet<QString> supportedEncryptHeaderMimeTypes()
+{
+    const QLatin1String constraint("(exist Library) and ([X-KDE-Kerfuffle-EncryptHeader] == true)");
+    const QLatin1String basePartService("Kerfuffle/Plugin");
+
+    const KService::List offers = KServiceTypeTrader::self()->query(basePartService, constraint);
+    QSet<QString> supported;
+
+    foreach (const KService::Ptr& service, offers) {
+        QStringList mimeTypes = service->serviceTypes();
+
+        foreach (const QString& mimeType, mimeTypes) {
+            if (mimeType != basePartService) {
+                supported.insert(mimeType);
+            }
+        }
+    }
+
+    qCDebug(KERFUFFLE) << "Returning supported mimetypes" << supported;
+
+    return supported;
+}
+
 } // namespace Kerfuffle
diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h
index 886da3e..f6fbbd8 100644
--- a/kerfuffle/archive_kerfuffle.h
+++ b/kerfuffle/archive_kerfuffle.h
@@ -125,6 +125,7 @@ public:
     bool isPasswordProtected();
 
     void setPassword(const QString &password);
+    void enableHeaderEncryption(bool enable);
 
 private slots:
     void onListFinished(KJob*);
@@ -145,6 +146,8 @@ private:
 
 KERFUFFLE_EXPORT QStringList supportedMimeTypes();
 KERFUFFLE_EXPORT QStringList supportedWriteMimeTypes();
+KERFUFFLE_EXPORT QSet<QString> supportedEncryptEntriesMimeTypes();
+KERFUFFLE_EXPORT QSet<QString> supportedEncryptHeaderMimeTypes();
 } // namespace Kerfuffle
 
 
diff --git a/kerfuffle/archiveinterface.cpp b/kerfuffle/archiveinterface.cpp
index 686dc06..01c0547 100644
--- a/kerfuffle/archiveinterface.cpp
+++ b/kerfuffle/archiveinterface.cpp
@@ -66,6 +66,11 @@ void ReadOnlyArchiveInterface::setPassword(const QString &password)
     m_password = password;
 }
 
+void ReadOnlyArchiveInterface::setHeaderEncryptionEnabled(bool enabled)
+{
+    m_isHeaderEncryptionEnabled = enabled;
+}
+
 QString ReadOnlyArchiveInterface::password() const
 {
     return m_password;
@@ -109,6 +114,11 @@ void ReadOnlyArchiveInterface::setWaitForFinishedSignal(bool value)
     m_waitForFinishedSignal = value;
 }
 
+bool ReadOnlyArchiveInterface::isHeaderEncryptionEnabled() const
+{
+    return m_isHeaderEncryptionEnabled;
+}
+
 bool ReadWriteArchiveInterface::isReadOnly() const
 {
     QFileInfo fileInfo(filename());
diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h
index 968237d..1aac2a4 100644
--- a/kerfuffle/archiveinterface.h
+++ b/kerfuffle/archiveinterface.h
@@ -73,6 +73,7 @@ public:
      */
     virtual bool list() = 0;
     void setPassword(const QString &password);
+    void setHeaderEncryptionEnabled(bool enabled);
 
     /**
      * Extract files from archive.
@@ -113,10 +114,13 @@ protected:
      */
     void setWaitForFinishedSignal(bool value);
 
+    bool isHeaderEncryptionEnabled() const;
+
 private:
     QString m_filename;
     QString m_password;
     bool m_waitForFinishedSignal;
+    bool m_isHeaderEncryptionEnabled;
 };
 
 class KERFUFFLE_EXPORT ReadWriteArchiveInterface: public ReadOnlyArchiveInterface
diff --git a/kerfuffle/cliinterface.cpp b/kerfuffle/cliinterface.cpp
index 2718c11..2f5d607 100644
--- a/kerfuffle/cliinterface.cpp
+++ b/kerfuffle/cliinterface.cpp
@@ -272,6 +272,65 @@ bool CliInterface::addFiles(const QStringList & files, const CompressionOptions&
             args[i] = filename();
         }
 
+        if (argument == QLatin1String("$PasswordSwitch")) {
+            //if the PasswordSwitch argument has been added, we at least
+            //assume that the format of the switch has been added as well
+            Q_ASSERT(m_param.contains(PasswordSwitch));
+
+            //we will decrement i afterwards
+            args.removeAt(i);
+
+            QString pass = password();
+
+            if (!pass.isEmpty()) {
+                QStringList theSwitch = m_param.value(PasswordSwitch).toStringList();
+
+                // use the header encryption switch if needed and if provided by the plugin
+                if (isHeaderEncryptionEnabled() && !m_param.value(PasswordHeaderSwitch).toStringList().isEmpty()) {
+                    theSwitch = m_param.value(PasswordHeaderSwitch).toStringList();
+                }
+
+                for (int j = 0; j < theSwitch.size(); ++j) {
+                    //get the argument part
+                    QString newArg = theSwitch.at(j);
+
+                    //substitute the $Password
+                    newArg.replace(QLatin1String("$Password"), pass);
+
+                    //put it in the arg list
+                    args.insert(i + j, newArg);
+                    ++i;
+                }
+            }
+            --i; //decrement to compensate for the variable we replaced
+        }
+
+        if (argument == QLatin1String("$EncryptHeaderSwitch")) {
+            //if the EncryptHeaderSwitch argument has been added, we at least
+            //assume that the format of the switch has been added as well
+            Q_ASSERT(m_param.contains(EncryptHeaderSwitch));
+
+            //we will decrement i afterwards
+            args.removeAt(i);
+
+            QString enabled = isHeaderEncryptionEnabled() ? QLatin1String("on") : QLatin1String("off");
+
+            QStringList theSwitch = m_param.value(EncryptHeaderSwitch).toStringList();
+            for (int j = 0; j < theSwitch.size(); ++j) {
+                //get the argument part
+                QString newArg = theSwitch.at(j);
+
+                //substitute the $Password
+                newArg.replace(QLatin1String("$Enabled"), enabled);
+
+                //put it in the arg list
+                args.insert(i + j, newArg);
+                ++i;
+            }
+
+            --i; //decrement to compensate for the variable we replaced
+        }
+
         if (argument == QLatin1String( "$Files" )) {
             args.removeAt(i);
             for (int j = 0; j < files.count(); ++j) {
@@ -740,6 +799,32 @@ void CliInterface::substituteListVariables(QStringList& params)
         if (parameter == QLatin1String( "$Archive" )) {
             params[i] = filename();
         }
+
+        if (parameter == QLatin1String("$PasswordSwitch")) {
+            //if the PasswordSwitch argument has been added, we at least
+            //assume that the format of the switch has been added as well
+            Q_ASSERT(m_param.contains(PasswordSwitch));
+
+            //we will set it afterwards, if there is a password
+            params[i] = QString();
+
+            QString pass = password();
+
+            if (!pass.isEmpty()) {
+                QStringList theSwitch = m_param.value(PasswordSwitch).toStringList();
+
+                for (int j = 0; j < theSwitch.size(); ++j) {
+                    //get the argument part
+                    QString newArg = theSwitch.at(j);
+
+                    //substitute the $Password
+                    newArg.replace(QLatin1String("$Password"), pass);
+
+                    //put it in the arg list
+                    params[i] = newArg;
+                }
+            }
+        }
     }
 }
 
diff --git a/kerfuffle/cliinterface.h b/kerfuffle/cliinterface.h
index e93d443..50c9e36 100644
--- a/kerfuffle/cliinterface.h
+++ b/kerfuffle/cliinterface.h
@@ -216,7 +216,27 @@ enum CliInterfaceParameters {
      * $Archive - the path of the archive
      * $Files - the files selected to be added
      */
-    AddArgs
+    AddArgs,
+
+    ///////////////[ ENCRYPT ]/////////////
+
+    /**
+     * QStringList (default empty)
+     * The variable $Password will be
+     * substituted for the password string used to encrypt the header.
+     * Example (rar plugin): ("-hp$Password")
+     */
+    PasswordHeaderSwitch,
+
+    /**
+     * QStringList (default empty)
+     * Encrypt the archive header without providing a password string.
+     * It uses $Password from either PasswordSwitch or PasswordHeaderSwitch.
+     * However, there is the $Enabled variable
+     * which is substituted with either 'on' or 'off'.
+     * Example (7z plugin): ("-mhe=$Enabled")
+     */
+    EncryptHeaderSwitch
 };
 
 typedef QHash<int, QVariant> ParameterList;
diff --git a/kerfuffle/createdialog.cpp b/kerfuffle/createdialog.cpp
new file mode 100644
index 0000000..3a7528a
--- /dev/null
+++ b/kerfuffle/createdialog.cpp
@@ -0,0 +1,256 @@
+/*
+ * ark -- archiver for the KDE project
+ *
+ * Copyright (C) 2008 Harald Hvaal <haraldhv at stud.ntnu.no>
+ * Copyright (C) 2009,2011 Raphael Kubo da Costa <rakuco at FreeBSD.org>
+ * Copyright (C) 2015 Elvis Angelaccio <elvis.angelaccio at kdemail.net>
+ *
+ * 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 "app/logging.h"
+#include "createdialog.h"
+#include "ui_createdialog.h"
+#include "kerfuffle/archive_kerfuffle.h"
+
+#include <KFileWidget>
+#include <KMessageBox>
+#include <KSharedConfig>
+#include <KUrlComboBox>
+#include <KWindowConfig>
+
+#include <QDebug>
+#include <QMimeDatabase>
+#include <QPushButton>
+#include <QScreen>
+#include <QUrl>
+#include <QWindow>
+
+namespace Kerfuffle
+{
+class CreateDialogUI: public QWidget, public Ui::CreateDialog
+{
+public:
+    CreateDialogUI(QWidget *parent = 0)
+            : QWidget(parent) {
+        setupUi(this);
+    }
+};
+
+CreateDialog::CreateDialog(QWidget *parent,
+                           const QString &caption,
+                           const QUrl &startDir)
+        : QDialog(parent, Qt::Dialog)
+{
+    qCDebug(KERFUFFLE) << "CreateDialog loaded";
+
+    this->setWindowTitle(caption);
+
+    m_vlayout = new QVBoxLayout();
+    setLayout(m_vlayout);
+
+    m_fileWidget = new KFileWidget(startDir, this);
+    m_vlayout->addWidget(m_fileWidget);
+
+    m_fileWidget->setMode(KFile::File | KFile::LocalOnly);
+    m_fileWidget->setConfirmOverwrite(true);
+    m_fileWidget->setOperationMode(KFileWidget::Saving);
+    m_fileWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding);
+
+    connect(m_fileWidget->okButton(), &QPushButton::clicked, this, &CreateDialog::slotOkButtonClicked);
+    connect(m_fileWidget, &KFileWidget::accepted, m_fileWidget, &KFileWidget::accept);
+    connect(m_fileWidget, &KFileWidget::accepted, this, &CreateDialog::accept);
+    m_fileWidget->okButton()->show();
+
+    m_fileWidget->cancelButton()->show();
+    connect(m_fileWidget->cancelButton(), &QPushButton::clicked, this, &QDialog::reject);
+
+    loadConfiguration();
+
+    connect(this, &QDialog::accepted, this, &CreateDialog::updateDefaultMimeType);
+    connect(this, &QDialog::finished, this, &CreateDialog::slotSaveWindowSize);
+    connect(m_fileWidget, &KFileWidget::filterChanged, this, &CreateDialog::updateDisplayedOptions);
+
+    m_ui = new CreateDialogUI(this);
+    m_ui->groupEncryptionOptions->hide();
+    m_vlayout->addWidget(m_ui);
+
+    connect(m_ui->encryptCheckBox, &QCheckBox::toggled, this, &CreateDialog::encryptionToggled);
+    connect(m_ui->showPwdCheckbox, &QCheckBox::toggled, this, &CreateDialog::showPasswordToggled);
+}
+
+QSize CreateDialog::sizeHint() const
+{
+    // Used only when no previous window size has been stored
+    return QSize(750,450);
+}
+
+QList<QUrl> CreateDialog::selectedUrls() const
+{
+    return m_fileWidget->selectedUrls();
+}
+
+QString CreateDialog::currentMimeFilter() const
+{
+    return m_fileWidget->currentMimeFilter();
+}
+
+QString CreateDialog::password() const
+{
+    return m_ui->pwdInput->text();
+}
+
+bool CreateDialog::isHeaderEncryptionChecked() const
+{
+    return m_ui->encryptHeaderCheckBox->isChecked();
+}
+
+void CreateDialog::accept()
+{
+    if ((m_ui->pwdInput->text() == m_ui->pwdConfirmInput->text()) || m_ui->showPwdCheckbox->isChecked()) {
+        QDialog::accept();
+    } else {
+        KMessageBox::error(NULL, i18n("The chosen password does not match the given verification password."));
+        m_ui->pwdInput->clear();
+        m_ui->pwdConfirmInput->clear();
+    }
+}
+
+void CreateDialog::restoreWindowSize()
+{
+    // Restore window size from config file, needs a windowHandle so must be called after show()
+    KConfigGroup group(KSharedConfig::openConfig(), "AddDialog");
+    //KWindowConfig::restoreWindowSize(windowHandle(), group);
+    //KWindowConfig::restoreWindowSize is broken atm., so we need this hack:
+    const QRect desk = windowHandle()->screen()->geometry();
+    this->resize(QSize(group.readEntry(QString::fromLatin1("Width %1").arg(desk.width()), windowHandle()->size().width()),
+                     group.readEntry(QString::fromLatin1("Height %1").arg(desk.height()), windowHandle()->size().height())));
+}
+
+void CreateDialog::slotSaveWindowSize()
+{
+    // Save dialog window size
+    KConfigGroup group(KSharedConfig::openConfig(), "CreateDialog");
+    KWindowConfig::saveWindowSize(windowHandle(), group, KConfigBase::Persistent);
+}
+
+void CreateDialog::slotOkButtonClicked()
+{
+    // In case the user tries to leave the lineEdit empty:
+    if (m_fileWidget->locationEdit()->urls().at(0) == m_fileWidget->baseUrl().path().left(m_fileWidget->baseUrl().path().size()-1))
+    {
+        KMessageBox::sorry(this, i18n("Please select a filename for the archive."), i18n("No file selected"));
+        return;
+    }
+    // This slot sets the url from text in the lineEdit, asks for overwrite etc, and emits signal accepted
+    m_fileWidget->slotOk();
+}
+
+
+void CreateDialog::encryptionToggled(bool checked)
+{
+    m_ui->groupEncryptionOptions->setVisible(checked);
+}
+
+void CreateDialog::showPasswordToggled(bool checked)
+{
+    if (checked) {
+        m_ui->pwdConfirmInputLabel->hide();
+        m_ui->pwdConfirmInput->hide();
+        m_ui->pwdInput->setEchoMode(QLineEdit::Normal);
+    } else {
+        m_ui->pwdConfirmInputLabel->show();
+        m_ui->pwdConfirmInput->show();
+        m_ui->pwdInput->setEchoMode(QLineEdit::Password);
+    }
+}
+
+void CreateDialog::updateDefaultMimeType()
+{
+    m_config.writeEntry("LastMimeType", m_fileWidget->currentFilterMimeType().name());
+}
+
+void CreateDialog::updateDisplayedOptions(const QString &filter)
+{
+    qCDebug(KERFUFFLE) << "Current selected mime filter: " << filter;
+
+    if (Kerfuffle::supportedEncryptEntriesMimeTypes().contains(filter)) {
+        m_ui->encryptCheckBox->setEnabled(true);
+        m_ui->encryptCheckBox->setToolTip(QString());
+        m_ui->groupEncryptionOptions->setEnabled(true);
+    } else {
+        m_ui->encryptCheckBox->setEnabled(false);
+        m_ui->encryptCheckBox->setToolTip(i18n("Protection of the archive with password is not possible with the %1 format.",
+                                               QMimeDatabase().mimeTypeForName(filter).comment()));
+        m_ui->groupEncryptionOptions->setEnabled(false);
+    }
+
+    if (Kerfuffle::supportedEncryptHeaderMimeTypes().contains(filter)) {
+        m_ui->encryptHeaderCheckBox->setEnabled(true);
+        m_ui->encryptHeaderCheckBox->setToolTip(QString());
+    } else {
+        m_ui->encryptHeaderCheckBox->setEnabled(false);
+        // show the tooltip only if the whole group is enabled
+        if (m_ui->groupEncryptionOptions->isEnabled()) {
+            m_ui->encryptHeaderCheckBox->setToolTip(i18n("Protection of the list of files is not possible with the %1 format.",
+                                                         QMimeDatabase().mimeTypeForName(filter).comment()));
+        }
+    }
+}
+
+void CreateDialog::loadConfiguration()
+{
+    m_config = KConfigGroup(KSharedConfig::openConfig()->group("AddDialog"));
+
+    const QString defaultMimeType = QLatin1String("application/x-compressed-tar");
+    const QString lastMimeType = m_config.readEntry("LastMimeType", defaultMimeType);
+    QStringList writeMimeTypes = Kerfuffle::supportedWriteMimeTypes();
+
+    // The filters need to be sorted by comment, so create a QMap with
+    // comment as key (QMaps are always sorted by key) and QMimeType
+    // as value. Then convert the QMap back to a QStringList. Mimetypes
+    // with empty comments are discarded.
+    QMimeDatabase db;
+    QMap<QString,QMimeType> mimeMap;
+    foreach (const QString &s, writeMimeTypes) {
+        QMimeType mime(db.mimeTypeForName(s));
+        if (!mime.comment().isEmpty()) {
+            mimeMap[mime.comment()] = mime;
+        }
+    }
+
+    writeMimeTypes.clear();
+
+    QMapIterator<QString,QMimeType> j(mimeMap);
+    while (j.hasNext()) {
+        j.next();
+        writeMimeTypes << j.value().name();
+    }
+
+    if (writeMimeTypes.contains(lastMimeType)) {
+        m_fileWidget->setMimeFilter(writeMimeTypes, lastMimeType);
+    } else {
+        m_fileWidget->setMimeFilter(writeMimeTypes, defaultMimeType);
+    }
+}
+
+}
diff --git a/kerfuffle/adddialog.h b/kerfuffle/createdialog.h
similarity index 70%
copy from kerfuffle/adddialog.h
copy to kerfuffle/createdialog.h
index 217da1e..8d78962 100644
--- a/kerfuffle/adddialog.h
+++ b/kerfuffle/createdialog.h
@@ -3,6 +3,7 @@
  *
  * 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>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,47 +27,57 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ADDDIALOG_H
-#define ADDDIALOG_H
+#ifndef CREATEDIALOG_H
+#define CREATEDIALOG_H
 
 #include "kerfuffle_export.h"
 
 #include <KConfigGroup>
-#include <KFileWidget>
 
 #include <QDialog>
 
+class KFileWidget;
+
+class QVBoxLayout;
+
 namespace Kerfuffle
 {
-class KERFUFFLE_EXPORT AddDialog : public QDialog
+class KERFUFFLE_EXPORT CreateDialog : public QDialog
 {
     Q_OBJECT
 
 public:
-    AddDialog(const QStringList &itemsToAdd,
-              QWidget *parent,
-              const QString &caption,
-              const QUrl &startDir);
-    QSize sizeHint() const Q_DECL_OVERRIDE;
-
-    QList<QUrl> selectedUrls();
-    QString currentMimeFilter();
+    CreateDialog(
+        QWidget *parent,
+        const QString &caption,
+        const QUrl &startDir);
 
-private:
-    class AddDialogUI *m_ui;
-    KConfigGroup m_config;
-    KFileWidget *fileWidget;
-
-    void loadConfiguration();
-    void setupIconList(const QStringList& itemsToAdd);
+    QSize sizeHint() const Q_DECL_OVERRIDE;
+    QList<QUrl> selectedUrls() const;
+    QString currentMimeFilter() const;
+    QString password() const;
+    bool isHeaderEncryptionChecked() const;
 
 public slots:
+
+    virtual void accept() Q_DECL_OVERRIDE;
     void restoreWindowSize();
 
-private slots:
-    void updateDefaultMimeType();
+protected slots:
     void slotSaveWindowSize();
     void slotOkButtonClicked();
+    void encryptionToggled(bool checked);
+    void showPasswordToggled(bool checked);
+    void updateDefaultMimeType();
+    void updateDisplayedOptions(const QString &filter);
+
+protected:
+    class CreateDialogUI *m_ui;
+    QVBoxLayout *m_vlayout;
+    KConfigGroup m_config;
+    KFileWidget *m_fileWidget;
+
+    void loadConfiguration();
 };
 }
 
diff --git a/kerfuffle/createdialog.ui b/kerfuffle/createdialog.ui
new file mode 100644
index 0000000..a947345
--- /dev/null
+++ b/kerfuffle/createdialog.ui
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CreateDialog</class>
+ <widget class="QWidget" name="CreateDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>799</width>
+    <height>496</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>0</width>
+    <height>0</height>
+   </size>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QCheckBox" name="encryptCheckBox">
+     <property name="text">
+      <string>Protect the archive with a password</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupEncryptionOptions">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="layoutDirection">
+      <enum>Qt::LeftToRight</enum>
+     </property>
+     <property name="title">
+      <string>Encryption Options</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="1">
+       <widget class="QLineEdit" name="pwdInput">
+        <property name="echoMode">
+         <enum>QLineEdit::Password</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QLineEdit" name="pwdConfirmInput">
+        <property name="echoMode">
+         <enum>QLineEdit::Password</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="pwdConfirmInputLabel">
+        <property name="text">
+         <string>Confirm password:</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0">
+       <widget class="QLabel" name="pwdInputLabel">
+        <property name="text">
+         <string>Password:</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="QCheckBox" name="encryptHeaderCheckBox">
+        <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>
+      <item row="0" column="2">
+       <widget class="QCheckBox" name="showPwdCheckbox">
+        <property name="text">
+         <string>Show password</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <spacer name="verticalSpacer">
+        <property name="orientation">
+         <enum>Qt::Vertical</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>20</width>
+          <height>40</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
\ No newline at end of file
diff --git a/kerfuffle/kerfufflePlugin.desktop b/kerfuffle/kerfufflePlugin.desktop
index 7c194af..a5da4f6 100644
--- a/kerfuffle/kerfufflePlugin.desktop
+++ b/kerfuffle/kerfufflePlugin.desktop
@@ -71,4 +71,11 @@ Type=int
 [PropertyDef::X-KDE-Kerfuffle-ReadWrite]
 Type=bool
 
+# Whether the plugin can encrypt its archive entries
+[PropertyDef::X-KDE-Kerfuffle-EncryptEntries]
+Type=bool
+
+# Whether the plugin can encrypt its archive header
+[PropertyDef::X-KDE-Kerfuffle-EncryptHeader]
+Type=bool
 
diff --git a/part/archivemodel.cpp b/part/archivemodel.cpp
index fd70705..31bb936 100644
--- a/part/archivemodel.cpp
+++ b/part/archivemodel.cpp
@@ -944,6 +944,18 @@ DeleteJob* ArchiveModel::deleteFiles(const QList<QVariant> & files)
     return Q_NULLPTR;
 }
 
+void ArchiveModel::setPassword(const QString &password)
+{
+    Q_ASSERT(m_archive);
+    m_archive->setPassword(password);
+}
+
+void ArchiveModel::enableHeaderEncryption()
+{
+    Q_ASSERT(m_archive);
+    m_archive->enableHeaderEncryption(true);
+}
+
 void ArchiveModel::slotCleanupEmptyDirs()
 {
     QList<QPersistentModelIndex> queue;
diff --git a/part/archivemodel.h b/part/archivemodel.h
index 13e062d..02cc0af 100644
--- a/part/archivemodel.h
+++ b/part/archivemodel.h
@@ -75,6 +75,9 @@ public:
     Kerfuffle::AddJob* addFiles(const QStringList & paths, const Kerfuffle::CompressionOptions& options = Kerfuffle::CompressionOptions());
     Kerfuffle::DeleteJob* deleteFiles(const QList<QVariant> & files);
 
+    void setPassword(const QString &password);
+    void enableHeaderEncryption();
+
 signals:
     void loadingStarted();
     void loadingFinished(KJob *);
diff --git a/part/part.cpp b/part/part.cpp
index 5312bfc..ed61279 100644
--- a/part/part.cpp
+++ b/part/part.cpp
@@ -514,6 +514,15 @@ bool Part::openFile()
         QTimer::singleShot(0, this, SLOT(slotExtractFiles()));
     }
 
+    const QString password = arguments().metaData()[QLatin1String("encryptionPassword")];
+    if (!password.isEmpty()) {
+        m_model->setPassword(password);
+
+        if (arguments().metaData()[QLatin1String("encryptHeader")] == QLatin1String("true")) {
+            m_model->enableHeaderEncryption();
+        }
+    }
+
     return true;
 }
 
diff --git a/plugins/cli7zplugin/cliplugin.cpp b/plugins/cli7zplugin/cliplugin.cpp
index 1c1389f..51480bc 100644
--- a/plugins/cli7zplugin/cliplugin.cpp
+++ b/plugins/cli7zplugin/cliplugin.cpp
@@ -59,13 +59,14 @@ ParameterList CliPlugin::parameterList() const
         //p[CaptureProgress] = true;
         p[ListProgram] = p[ExtractProgram] = p[DeleteProgram] = p[AddProgram] = QStringList() << QLatin1String( "7z" ) << QLatin1String( "7za" ) << QLatin1String( "7zr" );
 
-        p[ListArgs] = QStringList() << QLatin1String( "l" ) << QLatin1String( "-slt" ) << QLatin1String( "$Archive" );
+        p[ListArgs] = QStringList() << QLatin1String( "l" ) << QLatin1String( "-slt" ) << QLatin1String("$PasswordSwitch") << QLatin1String( "$Archive" );
         p[ExtractArgs] = QStringList() << QLatin1String( "$PreservePathSwitch" ) << QLatin1String( "$PasswordSwitch" ) << QLatin1String( "$Archive" ) << QLatin1String( "$Files" );
         p[PreservePathSwitch] = QStringList() << QLatin1String( "x" ) << QLatin1String( "e" );
         p[PasswordSwitch] = QStringList() << QLatin1String( "-p$Password" );
+        p[EncryptHeaderSwitch] = QStringList() << QLatin1String("-mhe=$Enabled");
         p[FileExistsExpression] = QLatin1String( "already exists. Overwrite with" );
         p[WrongPasswordPatterns] = QStringList() << QLatin1String( "Wrong password" );
-        p[AddArgs] = QStringList() << QLatin1String( "a" ) << QLatin1String( "$Archive" ) << QLatin1String( "$Files" );
+        p[AddArgs] = QStringList() << QLatin1String( "a" ) << QLatin1String( "$Archive" ) << QLatin1String("$EncryptHeaderSwitch") << QLatin1String( "$PasswordSwitch" ) << QLatin1String( "$Files" );
         p[DeleteArgs] = QStringList() << QLatin1String( "d" ) << QLatin1String( "$Archive" ) << QLatin1String( "$Files" );
 
         p[FileExistsInput] = QStringList()
diff --git a/plugins/cli7zplugin/kerfuffle_cli7z.desktop.cmake b/plugins/cli7zplugin/kerfuffle_cli7z.desktop.cmake
index b9325f9..2b0cfce 100644
--- a/plugins/cli7zplugin/kerfuffle_cli7z.desktop.cmake
+++ b/plugins/cli7zplugin/kerfuffle_cli7z.desktop.cmake
@@ -11,6 +11,8 @@ X-KDE-PluginInfo-License=GPLv2+
 X-KDE-Priority=120
 X-KDE-Kerfuffle-APIRevision=1
 X-KDE-Kerfuffle-ReadWrite=true
+X-KDE-Kerfuffle-EncryptEntries=true
+X-KDE-Kerfuffle-EncryptHeader=true
 Name=7zip archive plugin
 Name[ar]=ملحق أرشيف 7zip
 Name[ast]=Complementu d'archivos 7zip
diff --git a/plugins/clirarplugin/cliplugin.cpp b/plugins/clirarplugin/cliplugin.cpp
index 489abd6..62d2078 100644
--- a/plugins/clirarplugin/cliplugin.cpp
+++ b/plugins/clirarplugin/cliplugin.cpp
@@ -73,7 +73,7 @@ ParameterList CliPlugin::parameterList() const
         p[ListProgram] = p[ExtractProgram] = QStringList() << QLatin1String( "unrar" );
         p[DeleteProgram] = p[AddProgram] = QStringList() << QLatin1String( "rar" );
 
-        p[ListArgs] = QStringList() << QLatin1String( "vt" ) << QLatin1String( "-c-" ) << QLatin1String( "-v" ) << QLatin1String( "$Archive" );
+        p[ListArgs] = QStringList() << QLatin1String( "vt" ) << QLatin1String( "-c-" ) << QLatin1String( "-v" ) << QLatin1String("$PasswordSwitch") << QLatin1String( "$Archive" );
         p[ExtractArgs] = QStringList() << QLatin1String( "-kb" ) << QLatin1String( "-p-" )
                                        << QLatin1String( "$PreservePathSwitch" )
                                        << QLatin1String( "$PasswordSwitch" )
@@ -83,6 +83,7 @@ ParameterList CliPlugin::parameterList() const
         p[PreservePathSwitch] = QStringList() << QLatin1String( "x" ) << QLatin1String( "e" );
         p[RootNodeSwitch] = QStringList() << QLatin1String( "-ap$Path" );
         p[PasswordSwitch] = QStringList() << QLatin1String( "-p$Password" );
+        p[PasswordHeaderSwitch] = QStringList() << QLatin1String("-hp$Password");
 
         p[DeleteArgs] = QStringList() << QLatin1String( "d" ) << QLatin1String( "$Archive" ) << QLatin1String( "$Files" );
 
@@ -95,7 +96,7 @@ ParameterList CliPlugin::parameterList() const
                              << QLatin1String( "Q" ) //cancel
                              ;
 
-        p[AddArgs] = QStringList() << QLatin1String( "a" ) << QLatin1String( "$Archive" ) << QLatin1String( "$Files" );
+        p[AddArgs] = QStringList() << QLatin1String( "a" ) << QLatin1String( "$Archive" ) << QLatin1String("$PasswordSwitch") << QLatin1String( "$Files" );
 
         p[PasswordPromptPattern] = QLatin1String("Enter password \\(will not be echoed\\) for");
 
diff --git a/plugins/clirarplugin/kerfuffle_clirar.desktop.cmake b/plugins/clirarplugin/kerfuffle_clirar.desktop.cmake
index 545dca9..9dcaa68 100644
--- a/plugins/clirarplugin/kerfuffle_clirar.desktop.cmake
+++ b/plugins/clirarplugin/kerfuffle_clirar.desktop.cmake
@@ -11,6 +11,8 @@ X-KDE-PluginInfo-License=GPLv2+
 X-KDE-Priority=120
 X-KDE-Kerfuffle-APIRevision=1
 X-KDE-Kerfuffle-ReadWrite=true
+X-KDE-Kerfuffle-EncryptEntries=true
+X-KDE-Kerfuffle-EncryptHeader=true
 Name=RAR archive plugin
 Name[ar]=ملحق أرشيف RAR
 Name[ast]=Complementu d'archivos RAR
@@ -27,7 +29,7 @@ Name[es]=Complemento de archivo comprimido RAR
 Name[et]=RAR-arhiivi plugin
 Name[eu]=RAR artxiboen plugina
 Name[fi]=RAR-pakkaustuki
-Name[fr]=Module externe d'archive « RAR »
+Name[fr]=Module externe d'archive « RAR »
 Name[ga]=Breiseán cartlainne RAR
 Name[gl]=Extensión de arquivo RAR
 Name[hr]=Arhivni priključak RAR
diff --git a/plugins/clizipplugin/cliplugin.cpp b/plugins/clizipplugin/cliplugin.cpp
index c927581..db8dcea 100644
--- a/plugins/clizipplugin/cliplugin.cpp
+++ b/plugins/clizipplugin/cliplugin.cpp
@@ -98,7 +98,7 @@ ParameterList CliPlugin::parameterList() const
                              << QLatin1String( "N" ) //autoskip
                              ;
 
-        p[AddArgs] = QStringList() << QLatin1String( "-r" ) << QLatin1String( "$Archive" ) << QLatin1String( "$Files" );
+        p[AddArgs] = QStringList() << QLatin1String( "-r" ) << QLatin1String( "$Archive" ) << QLatin1String( "$PasswordSwitch" ) << QLatin1String( "$Files" );
 
         p[PasswordPromptPattern] = QLatin1String(" password: ");
         p[WrongPasswordPatterns] = QStringList() << QLatin1String( "incorrect password" );
diff --git a/plugins/clizipplugin/kerfuffle_clizip.desktop.cmake b/plugins/clizipplugin/kerfuffle_clizip.desktop.cmake
index d7451c7..abb201c 100644
--- a/plugins/clizipplugin/kerfuffle_clizip.desktop.cmake
+++ b/plugins/clizipplugin/kerfuffle_clizip.desktop.cmake
@@ -11,6 +11,8 @@ X-KDE-PluginInfo-License=GPLv2+
 X-KDE-Priority=160
 X-KDE-Kerfuffle-APIRevision=1
 X-KDE-Kerfuffle-ReadWrite=true
+X-KDE-Kerfuffle-EncryptEntries=true
+X-KDE-Kerfuffle-EncryptHeader=false
 Name=ZIP archive plugin
 Name[ar]=ملحق أرشيف ZIP
 Name[ast]=Complementu d'archivos ZIP
@@ -27,7 +29,7 @@ Name[es]=Complemento de archivo comprimido ZIP
 Name[et]=ZIP-arhiivi plugin
 Name[eu]=ZIP artxiboen plugina
 Name[fi]=Zip-pakkaustuki
-Name[fr]=Module externe d'archive « ZIP »
+Name[fr]=Module externe d'archive « ZIP »
 Name[ga]=Breiseán cartlainne ZIP
 Name[gl]=Extensión de arquivo ZIP
 Name[hr]=Arhivni priključak ZIP


More information about the kde-doc-english mailing list