[kde-doc-english] [ark] /: Add support for editing/adding archive comments

Ragnar Thomsen rthomsen6 at gmail.com
Sat Apr 30 17:24:29 UTC 2016


Git commit 04d56afacf191feaaebf93bc9c4c53c068ba8a9a by Ragnar Thomsen.
Committed on 30/04/2016 at 17:24.
Pushed by rthomsen into branch 'master'.

Add support for editing/adding archive comments

Support was added for editing comments in supported archive types
(currently only RAR). A new bool was added to plugin json files
("SupportsWriteComment") to indicate support. A new action was added and
is found in Archive menu. The editing of comment is done in the same
QPlainTextEdit used to display comments before. When user modifies
comment, a KMessageWidget pops up with a "Save" button. Actual saving of
comment to archive is achieved by a new job type: CommentJob.

FEATURE: 357594
FIXED-IN: 16.08.0
GUI:
Differential Revision: D1493

M  +5    -1    autotests/kerfuffle/jsonarchiveinterface.cpp
M  +1    -0    autotests/kerfuffle/jsonarchiveinterface.h
M  +12   -0    kerfuffle/archive_kerfuffle.cpp
M  +2    -0    kerfuffle/archive_kerfuffle.h
M  +12   -3    kerfuffle/archiveformat.cpp
M  +4    -1    kerfuffle/archiveformat.h
M  +1    -0    kerfuffle/archiveinterface.h
M  +62   -2    kerfuffle/cliinterface.cpp
M  +21   -1    kerfuffle/cliinterface.h
M  +23   -0    kerfuffle/jobs.cpp
M  +16   -0    kerfuffle/jobs.h
M  +3    -2    part/ark_part.rc
M  +71   -2    part/part.cpp
M  +5    -0    part/part.h
M  +4    -0    plugins/clirarplugin/cliplugin.cpp
M  +3    -2    plugins/clirarplugin/kerfuffle_clirar.json
M  +6    -0    plugins/libarchive/libarchiveplugin.cpp
M  +1    -0    plugins/libarchive/libarchiveplugin.h

http://commits.kde.org/ark/04d56afacf191feaaebf93bc9c4c53c068ba8a9a

diff --git a/autotests/kerfuffle/jsonarchiveinterface.cpp b/autotests/kerfuffle/jsonarchiveinterface.cpp
index a6d74a0..6ce548b 100644
--- a/autotests/kerfuffle/jsonarchiveinterface.cpp
+++ b/autotests/kerfuffle/jsonarchiveinterface.cpp
@@ -103,4 +103,8 @@ bool JSONArchiveInterface::deleteFiles(const QList<QVariant>& files)
     return true;
 }
 
-
+bool JSONArchiveInterface::addComment(const QString& comment)
+{
+    Q_UNUSED(comment)
+    return true;
+}
diff --git a/autotests/kerfuffle/jsonarchiveinterface.h b/autotests/kerfuffle/jsonarchiveinterface.h
index 86a57a2..b7d9f88 100644
--- a/autotests/kerfuffle/jsonarchiveinterface.h
+++ b/autotests/kerfuffle/jsonarchiveinterface.h
@@ -58,6 +58,7 @@ public:
     virtual bool addFiles(const QStringList& files, const Kerfuffle::CompressionOptions& options) Q_DECL_OVERRIDE;
     virtual bool copyFiles(const QList<QVariant>& files, const QString& destinationDirectory, const Kerfuffle::ExtractionOptions& options) Q_DECL_OVERRIDE;
     virtual bool deleteFiles(const QList<QVariant>& files) Q_DECL_OVERRIDE;
+    virtual bool addComment(const QString& comment) Q_DECL_OVERRIDE;
 
 private:
     JSONParser::JSONArchive m_archive;
diff --git a/kerfuffle/archive_kerfuffle.cpp b/kerfuffle/archive_kerfuffle.cpp
index cc4bf07..9e38044 100644
--- a/kerfuffle/archive_kerfuffle.cpp
+++ b/kerfuffle/archive_kerfuffle.cpp
@@ -169,6 +169,18 @@ QString Archive::comment() const
     return isValid() ? m_iface->comment() : QString();
 }
 
+CommentJob* Archive::addComment(const QString &comment)
+{
+    if (!isValid()) {
+        return Q_NULLPTR;
+    }
+
+    qCDebug(ARK) << "Going to add comment:" << comment;
+    Q_ASSERT(!isReadOnly());
+    CommentJob *job = new CommentJob(comment, static_cast<ReadWriteArchiveInterface*>(m_iface), this);
+    return job;
+}
+
 QMimeType Archive::mimeType() const
 {
     return isValid() ? determineMimeType(fileName()) : QMimeType();
diff --git a/kerfuffle/archive_kerfuffle.h b/kerfuffle/archive_kerfuffle.h
index 36acef8..6ec4454 100644
--- a/kerfuffle/archive_kerfuffle.h
+++ b/kerfuffle/archive_kerfuffle.h
@@ -45,6 +45,7 @@ class ListJob;
 class ExtractJob;
 class DeleteJob;
 class AddJob;
+class CommentJob;
 class Plugin;
 class Query;
 class ReadOnlyArchiveInterface;
@@ -198,6 +199,7 @@ public:
     ListJob* list();
 
     DeleteJob* deleteFiles(const QList<QVariant> & files);
+    CommentJob* addComment(const QString &comment);
 
     /**
      * Compression options that should be handled by all interfaces:
diff --git a/kerfuffle/archiveformat.cpp b/kerfuffle/archiveformat.cpp
index 1d207ea..cea0858 100644
--- a/kerfuffle/archiveformat.cpp
+++ b/kerfuffle/archiveformat.cpp
@@ -37,12 +37,14 @@ ArchiveFormat::ArchiveFormat(const QMimeType& mimeType,
                              Archive::EncryptionType encryptionType,
                              int minCompLevel,
                              int maxCompLevel,
-                             int defaultCompLevel) :
+                             int defaultCompLevel,
+                             bool supportsWriteComment) :
     m_mimeType(mimeType),
     m_encryptionType(encryptionType),
     m_minCompressionLevel(minCompLevel),
     m_maxCompressionLevel(maxCompLevel),
-    m_defaultCompressionLevel(defaultCompLevel)
+    m_defaultCompressionLevel(defaultCompLevel),
+    m_supportsWriteComment(supportsWriteComment)
 {
 }
 
@@ -60,6 +62,8 @@ ArchiveFormat ArchiveFormat::fromMetadata(const QMimeType& mimeType, const KPlug
         int maxCompLevel = formatProps[QStringLiteral("CompressionLevelMax")].toInt();
         int defaultCompLevel = formatProps[QStringLiteral("CompressionLevelDefault")].toInt();
 
+        bool supportsWriteComment = formatProps[QStringLiteral("SupportsWriteComment")].toBool();
+
         Archive::EncryptionType encType = Archive::Unencrypted;
         if (formatProps[QStringLiteral("HeaderEncryption")].toBool()) {
             encType = Archive::HeaderEncrypted;
@@ -67,7 +71,7 @@ ArchiveFormat ArchiveFormat::fromMetadata(const QMimeType& mimeType, const KPlug
             encType = Archive::Encrypted;
         }
 
-        return ArchiveFormat(mimeType, encType, minCompLevel, maxCompLevel, defaultCompLevel);
+        return ArchiveFormat(mimeType, encType, minCompLevel, maxCompLevel, defaultCompLevel, supportsWriteComment);
     }
 
     return ArchiveFormat();
@@ -98,4 +102,9 @@ int ArchiveFormat::defaultCompressionLevel() const
     return m_defaultCompressionLevel;
 }
 
+bool ArchiveFormat::supportsWriteComment() const
+{
+    return m_supportsWriteComment;
+}
+
 }
diff --git a/kerfuffle/archiveformat.h b/kerfuffle/archiveformat.h
index fb7587f..856590d 100644
--- a/kerfuffle/archiveformat.h
+++ b/kerfuffle/archiveformat.h
@@ -41,7 +41,8 @@ public:
                            Kerfuffle::Archive::EncryptionType encryptionType,
                            int minCompLevel,
                            int maxCompLevel,
-                           int defaultCompLevel);
+                           int defaultCompLevel,
+                           bool supportsWriteComment);
 
     /**
      * @return The archive format of the given @p mimeType, according to the given @p metadata.
@@ -61,6 +62,7 @@ public:
     int minCompressionLevel() const;
     int maxCompressionLevel() const;
     int defaultCompressionLevel() const;
+    bool supportsWriteComment() const;
 
 private:
     QMimeType m_mimeType;
@@ -68,6 +70,7 @@ private:
     int m_minCompressionLevel;
     int m_maxCompressionLevel;
     int m_defaultCompressionLevel;
+    bool m_supportsWriteComment;
 };
 
 }
diff --git a/kerfuffle/archiveinterface.h b/kerfuffle/archiveinterface.h
index 141c117..37c449e 100644
--- a/kerfuffle/archiveinterface.h
+++ b/kerfuffle/archiveinterface.h
@@ -148,6 +148,7 @@ public:
     //contain
     virtual bool addFiles(const QStringList & files, const CompressionOptions& options) = 0;
     virtual bool deleteFiles(const QList<QVariant> & files) = 0;
+    virtual bool addComment(const QString &comment) = 0;
 };
 
 } // namespace Kerfuffle
diff --git a/kerfuffle/cliinterface.cpp b/kerfuffle/cliinterface.cpp
index 1acc63f..c2d18dc 100644
--- a/kerfuffle/cliinterface.cpp
+++ b/kerfuffle/cliinterface.cpp
@@ -50,6 +50,7 @@
 #include <QRegularExpression>
 #include <QStandardPaths>
 #include <QTemporaryDir>
+#include <QTemporaryFile>
 #include <QThread>
 #include <QTimer>
 #include <QUrl>
@@ -61,7 +62,8 @@ CliInterface::CliInterface(QObject *parent, const QVariantList & args)
         m_process(0),
         m_listEmptyLines(false),
         m_abortingOperation(false),
-        m_extractTempDir(Q_NULLPTR)
+        m_extractTempDir(Q_NULLPTR),
+        m_commentTempFile(Q_NULLPTR)
 {
     //because this interface uses the event loop
     setWaitForFinishedSignal(true);
@@ -84,6 +86,7 @@ void CliInterface::cacheParameterList()
 CliInterface::~CliInterface()
 {
     Q_ASSERT(!m_process);
+    delete m_commentTempFile;
 }
 
 bool CliInterface::isCliBased() const
@@ -676,6 +679,36 @@ QStringList CliInterface::substituteAddVariables(const QStringList &addArgs, con
     return args;
 }
 
+QStringList CliInterface::substituteCommentVariables(const QStringList &commentArgs, const QString &commentFile)
+{
+    // Required if we call this function from unit tests.
+    cacheParameterList();
+
+    QStringList args;
+    foreach (const QString& arg, commentArgs) {
+        qCDebug(ARK) << "Processing argument " << arg;
+
+        if (arg == QLatin1String("$Archive")) {
+            args << filename();
+            continue;
+        }
+
+        if (arg == QLatin1String("$CommentSwitch")) {
+            QString commentSwitch = m_param.value(CommentSwitch).toString();
+            commentSwitch.replace(QStringLiteral("$CommentFile"), commentFile);
+            args << commentSwitch;
+            continue;
+        }
+
+        args << arg;
+    }
+
+    // Remove empty strings, if any.
+    args.removeAll(QString());
+
+    return args;
+}
+
 QString CliInterface::preservePathSwitch(bool preservePaths) const
 {
     Q_ASSERT(m_param.contains(PreservePathSwitch));
@@ -1138,6 +1171,33 @@ void CliInterface::writeToProcess(const QByteArray& data)
 #endif
 }
 
-}
+bool CliInterface::addComment(const QString &comment)
+{
+    cacheParameterList();
 
+    m_operationMode = Comment;
+
+    m_commentTempFile = new QTemporaryFile;
+    if (!m_commentTempFile->open()) {
+        qCWarning(ARK) << "Failed to create temporary file for comment";
+        failOperation();
+        emit finished(false);
+        return false;
+    }
 
+    QTextStream stream(m_commentTempFile);
+    stream << comment << endl;
+    m_commentTempFile->close();
+
+    const auto args = substituteCommentVariables(m_param.value(CommentArgs).toStringList(),
+                                                 m_commentTempFile->fileName());
+
+    if (!runProcess(m_param.value(AddProgram).toStringList(), args)) {
+        failOperation();
+        return false;
+    }
+    m_comment = comment;
+    return true;
+}
+
+}
diff --git a/kerfuffle/cliinterface.h b/kerfuffle/cliinterface.h
index 7e9d0ae..d83681c 100644
--- a/kerfuffle/cliinterface.h
+++ b/kerfuffle/cliinterface.h
@@ -39,6 +39,7 @@ class KPtyProcess;
 
 class QDir;
 class QTemporaryDir;
+class QTemporaryFile;
 
 namespace Kerfuffle
 {
@@ -255,6 +256,22 @@ enum CliInterfaceParameters {
      * Example (rar plugin): ("-hp$Password")
      */
     PasswordHeaderSwitch,
+
+    ///////////////[ COMMENT ]/////////////
+
+    /**
+     * QStringList
+     * The arguments that are passed to AddProgram when adding
+     * a comment.
+     */
+    CommentArgs,
+    /**
+     * QString
+     * The variable $CommentFile will be substituted for the file
+     * containing the comment.
+     * Example (rar plugin): -z$CommentFile
+     */
+    CommentSwitch
 };
 
 typedef QHash<int, QVariant> ParameterList;
@@ -265,7 +282,7 @@ class KERFUFFLE_EXPORT CliInterface : public ReadWriteArchiveInterface
 
 public:
     enum OperationMode  {
-        List, Copy, Add, Delete
+        List, Copy, Add, Delete, Comment
     };
     OperationMode m_operationMode;
 
@@ -276,6 +293,7 @@ public:
     virtual bool copyFiles(const QList<QVariant>& files, const QString& destinationDirectory, const ExtractionOptions& options) Q_DECL_OVERRIDE;
     virtual bool addFiles(const QStringList & files, const CompressionOptions& options) Q_DECL_OVERRIDE;
     virtual bool deleteFiles(const QList<QVariant> & files) Q_DECL_OVERRIDE;
+    virtual bool addComment(const QString &comment) Q_DECL_OVERRIDE;
 
     virtual void resetParsing() = 0;
     virtual ParameterList parameterList() const = 0;
@@ -318,6 +336,7 @@ public:
     QStringList substituteListVariables(const QStringList &listArgs, const QString &password);
     QStringList substituteCopyVariables(const QStringList &extractArgs, const QVariantList &files, bool preservePaths, const QString &password, const QString &rootNode);
     QStringList substituteAddVariables(const QStringList &addArgs, const QStringList &files, const QString &password, bool encryptHeader, int compLevel);
+    QStringList substituteCommentVariables(const QStringList &commentArgs, const QString &commentFile);
 
     /**
      * @return The preserve path switch, according to the @p preservePaths extraction option.
@@ -442,6 +461,7 @@ private:
     QString m_oldWorkingDir;
     QString m_extractDestDir;
     QTemporaryDir *m_extractTempDir;
+    QTemporaryFile *m_commentTempFile;
     QVariantList m_copiedFiles;
 
 private slots:
diff --git a/kerfuffle/jobs.cpp b/kerfuffle/jobs.cpp
index 748085d..b4d14af 100644
--- a/kerfuffle/jobs.cpp
+++ b/kerfuffle/jobs.cpp
@@ -417,6 +417,29 @@ void DeleteJob::doWork()
     }
 }
 
+CommentJob::CommentJob(const QString& comment, ReadWriteArchiveInterface *interface, QObject *parent)
+    : Job(interface, parent)
+    , m_comment(comment)
+{
+}
+
+void CommentJob::doWork()
+{
+    emit description(this, i18n("Adding comment"));
+
+    ReadWriteArchiveInterface *m_writeInterface =
+        qobject_cast<ReadWriteArchiveInterface*>(archiveInterface());
+
+    Q_ASSERT(m_writeInterface);
+
+    connectToArchiveInterfaceSignals();
+    bool ret = m_writeInterface->addComment(m_comment);
+
+    if (!archiveInterface()->waitForFinishedSignal()) {
+        onFinished(ret);
+    }
+}
+
 } // namespace Kerfuffle
 
 
diff --git a/kerfuffle/jobs.h b/kerfuffle/jobs.h
index d98a312..5cbf83a 100644
--- a/kerfuffle/jobs.h
+++ b/kerfuffle/jobs.h
@@ -173,6 +173,22 @@ private:
     QVariantList m_files;
 };
 
+class KERFUFFLE_EXPORT CommentJob : public Job
+{
+    Q_OBJECT
+
+public:
+    CommentJob(const QString& comment, ReadWriteArchiveInterface *interface, QObject *parent = 0);
+
+public slots:
+    virtual void doWork() Q_DECL_OVERRIDE;
+
+private:
+    QString m_comment;
+};
+
+
+
 } // namespace Kerfuffle
 
 #endif // JOBS_H
diff --git a/part/ark_part.rc b/part/ark_part.rc
index eb9c711..1b2b823 100644
--- a/part/ark_part.rc
+++ b/part/ark_part.rc
@@ -1,12 +1,13 @@
 <!DOCTYPE kpartgui>
-<kpartgui name="ark_part" version="12">
+<kpartgui name="ark_part" version="13">
 <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="extract_all" group="archive_extract"/>
+		<Action name="edit_comment" group="archive_edit"/>
+                <Action name="extract_all" group="archive_extract"/>
 		<Action name="properties" group="archive_props"/>
 	</Menu>
 	<Menu name="ark_file">
diff --git a/part/part.cpp b/part/part.cpp
index 6e1063e..cd6b4f7 100644
--- a/part/part.cpp
+++ b/part/part.cpp
@@ -23,6 +23,7 @@
 
 #include "part.h"
 #include "ark_debug.h"
+#include "archiveformat.h"
 #include "archivemodel.h"
 #include "archiveview.h"
 #include "arkviewer.h"
@@ -36,6 +37,7 @@
 #include "kerfuffle/settings.h"
 #include "kerfuffle/previewsettingspage.h"
 #include "kerfuffle/propertiesdialog.h"
+#include "pluginmanager.h"
 
 #include <KAboutData>
 #include <KActionCollection>
@@ -114,6 +116,20 @@ Part::Part(QWidget *parentWidget, QObject *parent, const QVariantList& args)
     vbox->addWidget(m_commentView);
     m_commentBox->setLayout(vbox);
 
+    m_commentMsgWidget = new KMessageWidget();
+    m_commentMsgWidget->setText(i18n("Comment has been modified."));
+    m_commentMsgWidget->setMessageType(KMessageWidget::Information);
+    m_commentMsgWidget->setCloseButtonVisible(false);
+    m_commentMsgWidget->hide();
+
+    QAction *saveAction = new QAction(i18n("Save"), m_commentMsgWidget);
+    m_commentMsgWidget->addAction(saveAction);
+    connect(saveAction, &QAction::triggered, this, &Part::slotAddComment);
+
+    m_commentBox->layout()->addWidget(m_commentMsgWidget);
+
+    connect(m_commentView, &QPlainTextEdit::textChanged, this, &Part::slotCommentChanged);
+
     setWidget(mainWidget);
     mainWidget->setLayout(m_vlayout);
 
@@ -179,6 +195,15 @@ Part::~Part()
     m_extractAction->menu()->deleteLater();
 }
 
+void Part::slotCommentChanged()
+{
+    if (m_commentMsgWidget->isHidden() && m_commentView->toPlainText() != m_model->archive()->comment()) {
+        m_commentMsgWidget->animatedShow();
+    } else if (m_commentMsgWidget->isVisible() && m_commentView->toPlainText() == m_model->archive()->comment()) {
+        m_commentMsgWidget->hide();
+    }
+}
+
 KAboutData *Part::createAboutData()
 {
     return new KAboutData(QStringLiteral("ark"),
@@ -359,6 +384,13 @@ void Part::setupActions()
     connect(m_propertiesAction, &QAction::triggered,
             this, &Part::slotShowProperties);
 
+    m_editCommentAction = actionCollection()->addAction(QStringLiteral("edit_comment"));
+    m_editCommentAction->setIcon(QIcon::fromTheme(QStringLiteral("document-edit")));
+    m_editCommentAction->setText(i18nc("@action:inmenu", "&Edit Comment"));
+    actionCollection()->setDefaultShortcut(m_editCommentAction, Qt::ALT + Qt::Key_C);
+    m_editCommentAction->setToolTip(i18nc("@info:tooltip", "Click to add or edit comment"));
+    connect(m_editCommentAction, &QAction::triggered, this, &Part::slotShowComment);
+
     connect(m_signalMapper, SIGNAL(mapped(int)), this, SLOT(slotOpenEntry(int)));
 
     updateActions();
@@ -405,6 +437,44 @@ void Part::updateActions()
                                      (selectedEntriesCount == 1));
     m_propertiesAction->setEnabled(!isBusy() &&
                                    m_model->archive());
+
+    m_commentView->setEnabled(!isBusy());
+    m_commentMsgWidget->setEnabled(!isBusy());
+
+    if (m_model->archive()) {
+        const KPluginMetaData metadata = PluginManager().preferredPluginFor(m_model->archive()->mimeType())->metaData();
+        bool supportsWriteComment = ArchiveFormat::fromMetadata(m_model->archive()->mimeType(), metadata).supportsWriteComment();
+        m_editCommentAction->setEnabled(!isBusy() &&
+                                        supportsWriteComment);
+        m_commentView->setReadOnly(!supportsWriteComment);
+        m_model->archive()->comment().isEmpty() ? m_editCommentAction->setText(i18nc("@action:inmenu", "Add &Comment")) : m_editCommentAction->setText(i18nc("@action:inmenu", "Edit &Comment"));
+    } else {
+        m_editCommentAction->setEnabled(false);
+        m_commentView->setReadOnly(true);
+    }
+}
+
+void Part::slotShowComment()
+{
+    if (!m_commentBox->isVisible()) {
+        m_commentBox->show();
+        m_commentSplitter->setSizes(QList<int>() << m_view->height() * 0.6 << 1);
+    }
+    m_commentView->setFocus();
+}
+
+void Part::slotAddComment()
+{
+    CommentJob *job = m_model->archive()->addComment(m_commentView->toPlainText());
+    if (!job) {
+        return;
+    }
+    registerJob(job);
+    job->start();
+    m_commentMsgWidget->hide();
+    if (m_commentView->toPlainText().isEmpty()) {
+        m_commentBox->hide();
+    }
 }
 
 void Part::updateQuickExtractMenu(QAction *extractAction)
@@ -675,8 +745,7 @@ void Part::slotLoadingFinished(KJob *job)
 
     if (!m_model->archive()->comment().isEmpty()) {
         m_commentView->setPlainText(m_model->archive()->comment());
-        m_commentBox->show();
-        m_commentSplitter->setSizes(QList<int>() << m_view->height() * 0.6 << 1);
+        slotShowComment();
     } else {
         m_commentView->clear();
         m_commentBox->hide();
diff --git a/part/part.h b/part/part.h
index a8267a2..8f42bff 100644
--- a/part/part.h
+++ b/part/part.h
@@ -121,6 +121,9 @@ private slots:
     void setReadyGui();
     void setFileNameFromArchive();
     void slotWatchedFileModified(const QString& file);
+    void slotShowComment();
+    void slotAddComment();
+    void slotCommentChanged();
 
 signals:
     void busy();
@@ -150,6 +153,7 @@ private:
     QAction *m_deleteFilesAction;
     QAction *m_saveAsAction;
     QAction *m_propertiesAction;
+    QAction *m_editCommentAction;
     KToggleAction *m_showInfoPanelAction;
     InfoPanel            *m_infoPanel;
     QSplitter            *m_splitter;
@@ -165,6 +169,7 @@ private:
     QSplitter *m_commentSplitter;
     QGroupBox *m_commentBox;
     QPlainTextEdit *m_commentView;
+    KMessageWidget *m_commentMsgWidget;
 };
 
 } // namespace Ark
diff --git a/plugins/clirarplugin/cliplugin.cpp b/plugins/clirarplugin/cliplugin.cpp
index e1390bb..7e75353 100644
--- a/plugins/clirarplugin/cliplugin.cpp
+++ b/plugins/clirarplugin/cliplugin.cpp
@@ -122,6 +122,10 @@ ParameterList CliPlugin::parameterList() const
         p[CorruptArchivePatterns] = QStringList() << QStringLiteral("Unexpected end of archive")
                                                   << QStringLiteral("the file header is corrupt");
         p[DiskFullPatterns] = QStringList() << QStringLiteral("No space left on device");
+        p[CommentArgs] = QStringList() << QStringLiteral("c")
+                                       << QStringLiteral("$CommentSwitch")
+                                       << QStringLiteral("$Archive");
+        p[CommentSwitch] = QStringLiteral("-z$CommentFile");
     }
 
     return p;
diff --git a/plugins/clirarplugin/kerfuffle_clirar.json b/plugins/clirarplugin/kerfuffle_clirar.json
index 671d575..744be89 100644
--- a/plugins/clirarplugin/kerfuffle_clirar.json
+++ b/plugins/clirarplugin/kerfuffle_clirar.json
@@ -62,7 +62,8 @@
     "application/x-rar": {
         "CompressionLevelDefault": 3, 
         "CompressionLevelMax": 5, 
-        "CompressionLevelMin": 0, 
+        "CompressionLevelMin": 0,
+        "SupportsWriteComment": true,
         "HeaderEncryption": true
     }
-}
\ No newline at end of file
+}
diff --git a/plugins/libarchive/libarchiveplugin.cpp b/plugins/libarchive/libarchiveplugin.cpp
index 5c4e391..25246f2 100644
--- a/plugins/libarchive/libarchiveplugin.cpp
+++ b/plugins/libarchive/libarchiveplugin.cpp
@@ -129,6 +129,12 @@ bool LibarchivePlugin::deleteFiles(const QList<QVariant> &files)
     return false;
 }
 
+bool LibarchivePlugin::addComment(const QString& comment)
+{
+    Q_UNUSED(comment)
+    return false;
+}
+
 bool LibarchivePlugin::doKill()
 {
     m_abortOperation = true;
diff --git a/plugins/libarchive/libarchiveplugin.h b/plugins/libarchive/libarchiveplugin.h
index 91d66e9..94849e4 100644
--- a/plugins/libarchive/libarchiveplugin.h
+++ b/plugins/libarchive/libarchiveplugin.h
@@ -49,6 +49,7 @@ public:
 
     virtual bool addFiles(const QStringList& files, const CompressionOptions& options) Q_DECL_OVERRIDE;
     virtual bool deleteFiles(const QList<QVariant>& files) Q_DECL_OVERRIDE;
+    virtual bool addComment(const QString& comment) Q_DECL_OVERRIDE;
 
 protected:
     void emitEntryFromArchiveEntry(struct archive_entry *entry);


More information about the kde-doc-english mailing list