Sophie

Sophie

distrib > Mageia > 5 > i586 > by-pkgid > cf746698214707f972e669b661d0ae59 > files > 35

kdepim4-4.14.10-1.3.mga5.src.rpm

From d9d5d6de3e50e3efb2584120015bf43e59a1f649 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= <daniel.vratil@kdab.com>
Date: Wed, 3 Feb 2016 13:50:59 +0100
Subject: [PATCH 35/74] Add "Copy Decrypted Message To..." action to
 messagelist context menu

REVIEW: 126971
---
 kmail/kmail_part.rc    |  4 ++-
 kmail/kmcommands.cpp   | 82 +++++++++++++++++++++++++++++++++++++++++++++-----
 kmail/kmcommands.h     | 17 +++++++++--
 kmail/kmmainwidget.cpp | 61 ++++++++++++++++++++++++++++++++++---
 kmail/kmmainwidget.h   | 13 ++++++--
 kmail/kmmainwin.rc     |  4 ++-
 6 files changed, 163 insertions(+), 18 deletions(-)

diff --git a/kmail/kmail_part.rc b/kmail/kmail_part.rc
index db3c27b082..d349990573 100644
--- a/kmail/kmail_part.rc
+++ b/kmail/kmail_part.rc
@@ -2,7 +2,7 @@
      the same menu entries at the same place in KMail and Kontact  -->
 
 <!DOCTYPE kpartgui>
-<kpartgui version="502" name="kmmainwin" >
+<kpartgui version="503" name="kmmainwin" >
  <MenuBar>
   <Menu noMerge="1" name="file" >
    <text>&amp;File</text>
@@ -157,6 +157,7 @@
    <Action name="mailing_list"/>
    <Separator/>
    <Action name="akonadi_item_copy_to_menu" />
+   <Action name="copy_decrypted_message_to" />
    <Action name="akonadi_item_move_to_menu" />
    <Separator/>
    <Action name="set_status" />
@@ -280,6 +281,7 @@
   <Action name="move_thread_to_trash"/>
   <Separator/>
   <Action name="akonadi_item_move_to_menu"/>
+  <Action name="copy_decrypted_message_to" />
   <Action name="akonadi_item_copy_to_menu"/>
   <Separator/>
   <Action name="create_todo"/>
diff --git a/kmail/kmcommands.cpp b/kmail/kmcommands.cpp
index f7f06e92fb..59367b70c4 100644
--- a/kmail/kmcommands.cpp
+++ b/kmail/kmcommands.cpp
@@ -83,6 +83,7 @@
 #ifndef QT_NO_CURSOR
 #include "messageviewer/utils/kcursorsaver.h"
 #endif
+#include "messageviewer/viewer/objecttreeemptysource.h"
 #include "messageviewer/viewer/objecttreeparser.h"
 #include "messageviewer/viewer/csshelper.h"
 #include "messageviewer/utils/util.h"
@@ -105,6 +106,7 @@ using KMail::SecondaryWindow;
 #include <akonadi/itemmovejob.h>
 #include <akonadi/itemcopyjob.h>
 #include <akonadi/itemdeletejob.h>
+#include <akonadi/itemcreatejob.h>
 #include <akonadi/tag.h>
 #include <akonadi/tagcreatejob.h>
 #include <mailtransport/transportattribute.h>
@@ -1379,13 +1381,15 @@ KMCommand::Result KMMailingListFilterCommand::execute()
 }
 
 KMCopyCommand::KMCopyCommand( const Akonadi::Collection& destFolder,
-                              const QList<Akonadi::Item> &msgList)
-    :KMCommand( 0, msgList ), mDestFolder( destFolder )
+                              const QList<Akonadi::Item> &msgList,
+                              CopyOptions options )
+    :KMCommand( 0, msgList ), mDestFolder( destFolder ), mJobCount( 0 ), mOptions( options )
 {
 }
 
-KMCopyCommand::KMCopyCommand( const Akonadi::Collection& destFolder, const Akonadi::Item& msg)
-    :KMCommand( 0,msg ), mDestFolder( destFolder )
+KMCopyCommand::KMCopyCommand( const Akonadi::Collection& destFolder, const Akonadi::Item& msg,
+                              CopyOptions options )
+    :KMCommand( 0,msg ), mDestFolder( destFolder ), mJobCount( 0 ), mOptions( options )
 {
 }
 
@@ -1394,20 +1398,84 @@ KMCommand::Result KMCopyCommand::execute()
     setDeletesItself( true );
 
     QList<Akonadi::Item> listItem = retrievedMsgs();
-    Akonadi::ItemCopyJob *job = new Akonadi::ItemCopyJob( listItem, Akonadi::Collection(mDestFolder.id()),this );
-    connect( job, SIGNAL(result(KJob*)), this, SLOT(slotCopyResult(KJob*)) );
+    if ( mOptions & Decrypt ) {
+        Akonadi::ItemFetchJob *fetch = createFetchJob( listItem );
+        fetch->fetchScope().fetchFullPayload(true);
+        fetch->fetchScope().fetchAllAttributes(true);
+        fetch->fetchScope().setFetchRemoteIdentification(false);
+        connect(fetch, SIGNAL(result(KJob*)), this, SLOT(slotFetchResult(KJob*)) );
+    } else {
+        Akonadi::ItemCopyJob *job = new Akonadi::ItemCopyJob( listItem, Akonadi::Collection(mDestFolder.id()),this );
+        connect( job, SIGNAL(result(KJob*)), this, SLOT(slotCopyResult(KJob*)) );
+        ++mJobCount;
+    }
 
     return OK;
 }
 
+void KMCopyCommand::slotFetchResult( KJob * job )
+{
+    if ( job->error() ) {
+        showJobError(job);
+        setResult( Failed );
+        deleteLater();
+        return;
+    }
+
+    const QList<Akonadi::Item> items = qobject_cast<Akonadi::ItemFetchJob*>(job)->items();
+    Q_FOREACH ( Akonadi::Item item, items ) {
+        KMime::Message::Ptr msg = MessageCore::Util::message( item );
+        if ( !msg ) {
+            // Error handling?
+            continue;
+        }
+
+        Akonadi::Job *job = 0;
+        if ( decrypt( msg ) ) {
+            item.setPayload( msg );
+            job = new Akonadi::ItemCreateJob( item, Akonadi::Collection(mDestFolder.id()), this );
+        } else {
+            job = new Akonadi::ItemCopyJob( item, Akonadi::Collection(mDestFolder.id()), this );
+        }
+        connect( job, SIGNAL(result(KJob*)), this, SLOT(slotCopyResult(KJob*)) );
+        ++mJobCount;
+    }
+
+    if (mJobCount == 0) {
+        slotCopyResult( job );
+    }
+}
+
 void KMCopyCommand::slotCopyResult( KJob * job )
 {
     if ( job->error() ) {
         // handle errors
         showJobError(job);
         setResult( Failed );
+        mJobCount = 0;
     }
-    deleteLater();
+
+    --mJobCount;
+    if ( mJobCount <= 0 ) {
+        deleteLater();
+    }
+}
+
+bool KMCopyCommand::decrypt( KMime::Message::Ptr &msg ) const
+{
+    if ( !KMime::isEncrypted( msg.get() ) ) {
+        return false;
+    }
+
+    MessageViewer::EmptySource source;
+    source.setAllowDecryption(true);
+    MessageViewer::NodeHelper nodeHelper;
+
+    MessageViewer::ObjectTreeParser otp( &source, &nodeHelper, 0 , true, false, true );
+    otp.parseObjectTree( msg->topLevel() );
+
+    msg = nodeHelper.unencryptedMessage( msg );
+    return true;
 }
 
 KMMoveCommand::KMMoveCommand( const Akonadi::Collection& destFolder,
diff --git a/kmail/kmcommands.h b/kmail/kmcommands.h
index 1208da1259..3b0115dc1e 100644
--- a/kmail/kmcommands.h
+++ b/kmail/kmcommands.h
@@ -506,17 +506,30 @@ class KMAIL_EXPORT KMCopyCommand : public KMCommand
     Q_OBJECT
 
 public:
-    KMCopyCommand( const Akonadi::Collection &destFolder, const QList<Akonadi::Item> &msgList );
-    KMCopyCommand( const Akonadi::Collection& destFolder, const Akonadi::Item &msg );
+    enum CopyOptions {
+      NoOptions = 0x0,
+      Decrypt = 0x1
+    };
+
+    KMCopyCommand( const Akonadi::Collection &destFolder, const QList<Akonadi::Item> &msgList,
+                   CopyOptions options = NoOptions );
+    KMCopyCommand( const Akonadi::Collection& destFolder, const Akonadi::Item &msg,
+                   CopyOptions options = NoOptions );
 
 protected slots:
+    void slotFetchResult( KJob * job);
     void slotCopyResult( KJob * job );
+
 private:
     virtual Result execute();
+    bool decrypt( KMime::Message::Ptr &message ) const;
 
     Akonadi::Collection mDestFolder;
+    int mJobCount;
+    CopyOptions mOptions;
 };
 
+
 namespace KPIM {
 class ProgressItem;
 }
diff --git a/kmail/kmmainwidget.cpp b/kmail/kmmainwidget.cpp
index 02bedaa522..3d518f7667 100644
--- a/kmail/kmmainwidget.cpp
+++ b/kmail/kmmainwidget.cpp
@@ -1786,12 +1786,13 @@ void KMMainWidget::moveSelectedMessagesToFolder( const Akonadi::Collection & des
 }
 
 
-void KMMainWidget::copyMessageSelected( const QList<Akonadi::Item> &selectMsg, const Akonadi::Collection &dest )
+void KMMainWidget::copyMessageSelected( const QList<Akonadi::Item> &selectMsg, const Akonadi::Collection &dest,
+                                        KMCopyCommand::CopyOptions options )
 {
     if ( selectMsg.isEmpty() )
         return;
     // And stuff them into a KMCopyCommand :)
-    KMCommand *command = new KMCopyCommand( dest, selectMsg );
+    KMCommand *command = new KMCopyCommand( dest, selectMsg, options );
     QObject::connect(
                 command, SIGNAL(completed(KMCommand*)),
                 this, SLOT(slotCopyMessagesCompleted(KMCommand*))
@@ -1817,6 +1818,16 @@ void KMMainWidget::slotCopyMessagesCompleted( KMCommand *command )
 }
 
 void KMMainWidget::slotCopySelectedMessagesToFolder()
+{
+    copySelectedMessagesToFolder( KMCopyCommand::NoOptions );
+}
+
+void KMMainWidget::slotCopyDecryptedSelectedMessagesToFolder()
+{
+    copySelectedMessagesToFolder( KMCopyCommand::Decrypt );
+}
+
+void KMMainWidget::copySelectedMessagesToFolder( KMCopyCommand::CopyOptions options )
 {
     QPointer<MailCommon::FolderSelectionDialog> dialog( moveOrCopyToDialog() );
     dialog->setCaption( i18n( "Copy Messages to Folder" ) );
@@ -1824,16 +1835,17 @@ void KMMainWidget::slotCopySelectedMessagesToFolder()
     if ( dialog->exec() && dialog ) {
         const Akonadi::Collection dest = dialog->selectedCollection();
         if ( dest.isValid() ) {
-            copySelectedMessagesToFolder( dest );
+            copySelectedMessagesToFolder( dest, options );
         }
     }
 }
 
-void KMMainWidget::copySelectedMessagesToFolder( const Akonadi::Collection& dest )
+void KMMainWidget::copySelectedMessagesToFolder( const Akonadi::Collection& dest,
+                                                 KMCopyCommand::CopyOptions options )
 {
     const QList<Akonadi::Item > lstMsg = mMessagePane->selectionAsMessageItemList();
     if ( !lstMsg.isEmpty() ) {
-        copyMessageSelected( lstMsg, dest );
+        copyMessageSelected( lstMsg, dest, options );
     }
 }
 
@@ -2715,6 +2727,7 @@ void KMMainWidget::showMessagePopup(const Akonadi::Item&msg ,const KUrl&url,cons
         menu->addSeparator();
 
         menu->addAction( mCopyActionMenu );
+        menu->addAction( mCopyDecryptActionMenu );
         menu->addAction( mMoveActionMenu );
 
         menu->addSeparator();
@@ -3045,6 +3058,15 @@ void KMMainWidget::setupActions()
     {
         KAction *action = mAkonadiStandardActionManager->action( Akonadi::StandardActionManager::CopyItemToMenu );
         action->setText(i18n("Copy Message To...") );
+
+        mCopyDecryptActionMenu = new KActionMenu( i18n("Copy Decrypted Mesage To..."), actionCollection() );
+        mCopyDecryptActionMenu->setDelayed( true );
+        mCopyDecryptActionMenu->menu()->setProperty( "actionType", Akonadi::StandardActionManager::CopyItemToMenu );
+        connect(mAkonadiStandardActionManager->standardActionManager(), SIGNAL(actionStateUpdated()),
+                this, SLOT(slotUpdateCopyDecryptedActionMenu()));
+        actionCollection()->addAction( QLatin1String("copy_decrypted_message_to"), mCopyDecryptActionMenu );
+        slotUpdateCopyDecryptedActionMenu();
+
         action = mAkonadiStandardActionManager->action( Akonadi::StandardActionManager::MoveItemToMenu );
         action->setText(i18n("Move Message To...") );
     }
@@ -3381,6 +3403,12 @@ void KMMainWidget::setupActions()
                  SLOT(slotCopySelectedMessagesToFolder()) );
         action->setShortcut( QKeySequence( Qt::Key_C ) );
     }
+    {
+        KAction *action = new KAction( i18n("Copy Decrypted Message to Folder"), this );
+        actionCollection()->addAction(QLatin1String( "copy_decrypted_message_to_folder" ), action );
+        connect( action, SIGNAL(triggered(bool)),
+                 SLOT(slotCopyDecryptedSelectedMessagesToFolder()) );
+    }
     {
         KAction *action = new KAction( i18n("Jump to Folder..."), this );
         actionCollection()->addAction( QLatin1String("jump_to_folder"), action );
@@ -3521,6 +3549,29 @@ void KMMainWidget::slotAddFavoriteFolder()
     }
 }
 
+void KMMainWidget::slotUpdateCopyDecryptedActionMenu()
+{
+    KMenu *menu = mCopyDecryptActionMenu->menu();
+    delete menu;
+    menu = new KMenu();
+    // Will populate our menu with folders
+    connect(menu, SIGNAL(aboutToShow()),
+            mAkonadiStandardActionManager->standardActionManager(), SLOT(aboutToShowMenu()));
+    connect(menu, SIGNAL(triggered(QAction*)),
+            this, SLOT(slotCopyDecryptedActionTriggered(QAction*)));
+    mCopyDecryptActionMenu->setMenu(menu);
+}
+
+void KMMainWidget::slotCopyDecryptedActionTriggered(QAction *action)
+{
+    const QModelIndex index = action->data().value<QModelIndex>();
+    Q_ASSERT(index.isValid());
+
+    const Collection collection = index.data(EntityTreeModel::CollectionRole).value<Collection>();
+
+    copySelectedMessagesToFolder( collection, KMCopyCommand::Decrypt );
+}
+
 //-----------------------------------------------------------------------------
 void KMMainWidget::slotEditNotifications()
 {
diff --git a/kmail/kmmainwidget.h b/kmail/kmmainwidget.h
index 68f57a1bb3..a2d195418a 100644
--- a/kmail/kmmainwidget.h
+++ b/kmail/kmmainwidget.h
@@ -24,6 +24,7 @@
 #include "kmail_export.h"
 #include "kmreaderwin.h" //for inline actions
 #include "kmkernel.h" // for access to config
+#include "kmcommands.h"
 
 #include "foldertreewidget.h"
 
@@ -180,6 +181,7 @@ public slots:
      * messages (in MessageListView) into it.
      */
     void slotCopySelectedMessagesToFolder();
+    void slotCopyDecryptedSelectedMessagesToFolder();
 
     /**
      * Implements the "move to trash" action
@@ -275,7 +277,9 @@ protected:
     void layoutSplitters();
     void newFromTemplate( const Akonadi::Item& );
     void moveSelectedMessagesToFolder( const Akonadi::Collection & dest );
-    void copySelectedMessagesToFolder( const Akonadi::Collection& dest );
+    void copySelectedMessagesToFolder( KMCopyCommand::CopyOptions options );
+    void copySelectedMessagesToFolder( const Akonadi::Collection& dest,
+                                       KMCopyCommand::CopyOptions options );
 
 
     virtual void showEvent( QShowEvent *event );
@@ -428,7 +432,8 @@ private:
 
     void moveMessageSelected( MessageList::Core::MessageItemSetReference ref, const Akonadi::Collection &dest, bool confirmOnDeletion = true );
 
-    void copyMessageSelected( const QList<Akonadi::Item> &selectMsg, const Akonadi::Collection &dest );
+    void copyMessageSelected( const QList<Akonadi::Item> &selectMsg, const Akonadi::Collection &dest,
+                              KMCopyCommand::CopyOptions options );
 
 
     /**
@@ -513,6 +518,9 @@ private slots:
     void slotChangeDisplayMessageFormat(MessageViewer::Viewer::DisplayFormatMessage format);
 
     void slotCollectionRemoved(const Akonadi::Collection &col);
+
+    void slotUpdateCopyDecryptedActionMenu();
+    void slotCopyDecryptedActionTriggered(QAction *action);
 private:
     // Message actions
     KAction *mDeleteAction, *mTrashThreadAction,
@@ -531,6 +539,7 @@ private:
 
     KActionMenu *mThreadStatusMenu, *mApplyFilterActionsMenu;
     KAction *mCopyActionMenu;
+    KActionMenu *mCopyDecryptActionMenu;
     KAction *mMoveActionMenu;
     KAction *mMarkThreadAsReadAction;
     KAction *mMarkThreadAsUnreadAction;
diff --git a/kmail/kmmainwin.rc b/kmail/kmmainwin.rc
index db3c27b082..4fc7aab72c 100644
--- a/kmail/kmmainwin.rc
+++ b/kmail/kmmainwin.rc
@@ -2,7 +2,7 @@
      the same menu entries at the same place in KMail and Kontact  -->
 
 <!DOCTYPE kpartgui>
-<kpartgui version="502" name="kmmainwin" >
+<kpartgui version="503" name="kmmainwin" >
  <MenuBar>
   <Menu noMerge="1" name="file" >
    <text>&amp;File</text>
@@ -157,6 +157,7 @@
    <Action name="mailing_list"/>
    <Separator/>
    <Action name="akonadi_item_copy_to_menu" />
+   <Action name="copy_decrypted_message_to" />
    <Action name="akonadi_item_move_to_menu" />
    <Separator/>
    <Action name="set_status" />
@@ -280,6 +281,7 @@
   <Action name="move_thread_to_trash"/>
   <Separator/>
   <Action name="akonadi_item_move_to_menu"/>
+  <Action name="copy_decrypted_message_to"/>
   <Action name="akonadi_item_copy_to_menu"/>
   <Separator/>
   <Action name="create_todo"/>
-- 
2.14.1