Git commit beb910b8431d69ef322bd61b70f8e5d12fcfd82c by Daniel Vr=C3=A1til. Committed on 31/07/2017 at 19:40. Pushed by dvratil into branch 'master'. MessageViewer: use custom Akonadi::Session Have MessageViewer use a custom Akonadi::Session instead of the shared default one. This way the MessageViewer will still be able to show message, even if the default session is currently busy. This addresses the issue when a long-running operations (like large moves) block the default session, so that user has to stare at the "Retrieving folder contents" screen until the operation finishes. This is not as good as a generic "session pool" solution, but that introduced various issues in behaviour and consumed more resources. M +4 -2 messageviewer/src/job/attachmenteditjob.cpp M +5 -1 messageviewer/src/job/attachmenteditjob.h M +5 -3 messageviewer/src/job/modifymessagedisplayformatjob.cpp M +5 -1 messageviewer/src/job/modifymessagedisplayformatjob.h M +2 -1 messageviewer/src/utils/markmessagereadhandler.cpp M +1 -0 messageviewer/src/utils/markmessagereadhandler.h M +32 -1 messageviewer/src/viewer/viewer.cpp M +14 -5 messageviewer/src/viewer/viewer.h M +11 -8 messageviewer/src/viewer/viewer_p.cpp M +2 -0 messageviewer/src/viewer/viewer_p.h https://commits.kde.org/messagelib/beb910b8431d69ef322bd61b70f8e5d12fcfd82c diff --git a/messageviewer/src/job/attachmenteditjob.cpp b/messageviewer/sr= c/job/attachmenteditjob.cpp index e1d65853..40591e20 100644 --- a/messageviewer/src/job/attachmenteditjob.cpp +++ b/messageviewer/src/job/attachmenteditjob.cpp @@ -25,14 +25,16 @@ #include #include #include +#include #include = using namespace MessageViewer; = -AttachmentEditJob::AttachmentEditJob(QObject *parent) +AttachmentEditJob::AttachmentEditJob(Akonadi::Session *session, QObject *p= arent) : QObject(parent) , mShowWarning(true) , mMainWindow(nullptr) + , mSession(session) { } = @@ -97,7 +99,7 @@ void AttachmentEditJob::slotAttachmentEditDone(MessageVie= wer::EditorWatcher *edi file.close(); = mMessageItem.setPayloadFromData(mMessage->encodedContent()); - Akonadi::ItemModifyJob *job =3D new Akonadi::ItemModifyJob(mMe= ssageItem); + Akonadi::ItemModifyJob *job =3D new Akonadi::ItemModifyJob(mMe= ssageItem, mSession); connect(job, &KJob::result, this, &AttachmentEditJob::slotItem= ModifiedResult); removeEditorWatcher(editorWatcher, name); } diff --git a/messageviewer/src/job/attachmenteditjob.h b/messageviewer/src/= job/attachmenteditjob.h index 6323fcef..f4d4e9a1 100644 --- a/messageviewer/src/job/attachmenteditjob.h +++ b/messageviewer/src/job/attachmenteditjob.h @@ -27,13 +27,16 @@ namespace KMime { class Content; } +namespace Akonadi { +class Session; +} namespace MessageViewer { class EditorWatcher; class AttachmentEditJob : public QObject { Q_OBJECT public: - explicit AttachmentEditJob(QObject *parent =3D nullptr); + explicit AttachmentEditJob(Akonadi::Session *session, QObject *parent = =3D nullptr); ~AttachmentEditJob(); = void setMainWindow(QWidget *mainWindow); @@ -57,6 +60,7 @@ private: KMime::Message::Ptr mMessage; bool mShowWarning; QWidget *mMainWindow; + Akonadi::Session *mSession; }; } = diff --git a/messageviewer/src/job/modifymessagedisplayformatjob.cpp b/mess= ageviewer/src/job/modifymessagedisplayformatjob.cpp index f4aea99a..e1870a45 100644 --- a/messageviewer/src/job/modifymessagedisplayformatjob.cpp +++ b/messageviewer/src/job/modifymessagedisplayformatjob.cpp @@ -21,12 +21,14 @@ #include "messageviewer_debug.h" = #include +#include = #include "viewer/messagedisplayformatattribute.h" = using namespace MessageViewer; -ModifyMessageDisplayFormatJob::ModifyMessageDisplayFormatJob(QObject *pare= nt) +ModifyMessageDisplayFormatJob::ModifyMessageDisplayFormatJob(Akonadi::Sess= ion *session, QObject *parent) : QObject(parent) + , mSession(session) , mMessageFormat(Viewer::UseGlobalSetting) , mRemoteContent(false) , mResetFormat(false) @@ -74,7 +76,7 @@ void ModifyMessageDisplayFormatJob::setMessageItem(const = Akonadi::Item &messageI void ModifyMessageDisplayFormatJob::resetDisplayFormat() { mMessageItem.removeAttribute(); - Akonadi::ItemModifyJob *modify =3D new Akonadi::ItemModifyJob(mMessage= Item); + Akonadi::ItemModifyJob *modify =3D new Akonadi::ItemModifyJob(mMessage= Item, mSession); modify->setIgnorePayload(true); modify->disableRevisionCheck(); connect(modify, &KJob::result, this, &ModifyMessageDisplayFormatJob::s= lotModifyItemDone); @@ -87,7 +89,7 @@ void ModifyMessageDisplayFormatJob::modifyDisplayFormat() Akonadi::Item::AddIfMissing); attr->setRemoteContent(mRemoteContent); attr->setMessageFormat(mMessageFormat); - Akonadi::ItemModifyJob *modify =3D new Akonadi::ItemModifyJob(mMessage= Item); + Akonadi::ItemModifyJob *modify =3D new Akonadi::ItemModifyJob(mMessage= Item, mSession); modify->setIgnorePayload(true); modify->disableRevisionCheck(); connect(modify, &KJob::result, this, &ModifyMessageDisplayFormatJob::s= lotModifyItemDone); diff --git a/messageviewer/src/job/modifymessagedisplayformatjob.h b/messag= eviewer/src/job/modifymessagedisplayformatjob.h index 1f2f07bd..a14e7d5f 100644 --- a/messageviewer/src/job/modifymessagedisplayformatjob.h +++ b/messageviewer/src/job/modifymessagedisplayformatjob.h @@ -22,12 +22,15 @@ = #include #include "viewer/viewer_p.h" +namespace Akonadi { +class Session; +} namespace MessageViewer { class ModifyMessageDisplayFormatJob : public QObject { Q_OBJECT public: - explicit ModifyMessageDisplayFormatJob(QObject *parent =3D nullptr); + explicit ModifyMessageDisplayFormatJob(Akonadi::Session *session, QObj= ect *parent =3D nullptr); ~ModifyMessageDisplayFormatJob(); = void setRemoteContent(bool remote); @@ -41,6 +44,7 @@ private: void slotModifyItemDone(KJob *job); void resetDisplayFormat(); void modifyDisplayFormat(); + Akonadi::Session *mSession; Akonadi::Item mMessageItem; Viewer::DisplayFormatMessage mMessageFormat; bool mRemoteContent; diff --git a/messageviewer/src/utils/markmessagereadhandler.cpp b/messagevi= ewer/src/utils/markmessagereadhandler.cpp index ab287077..7b4624b6 100644 --- a/messageviewer/src/utils/markmessagereadhandler.cpp +++ b/messageviewer/src/utils/markmessagereadhandler.cpp @@ -24,6 +24,7 @@ #include "settings/messageviewersettings.h" = #include +#include #include = #include @@ -52,7 +53,7 @@ void MarkMessageReadHandler::Private::handleMessages() // mark as read item.setFlag(Akonadi::MessageFlags::Seen); = - Akonadi::ItemModifyJob *modifyJob =3D new Akonadi::ItemModifyJob(item,= q); + Akonadi::ItemModifyJob *modifyJob =3D new Akonadi::ItemModifyJob(item,= q->session()); modifyJob->disableRevisionCheck(); modifyJob->setIgnorePayload(true); sListItem->removeAll(item); diff --git a/messageviewer/src/utils/markmessagereadhandler.h b/messageview= er/src/utils/markmessagereadhandler.h index 36a5bb31..33ec0e2f 100644 --- a/messageviewer/src/utils/markmessagereadhandler.h +++ b/messageviewer/src/utils/markmessagereadhandler.h @@ -58,6 +58,7 @@ public: private: //@cond PRIVATE class Private; + friend class Private; Private *const d; = Q_PRIVATE_SLOT(d, void handleMessages()) diff --git a/messageviewer/src/viewer/viewer.cpp b/messageviewer/src/viewer= /viewer.cpp index e4f7e723..8429e749 100644 --- a/messageviewer/src/viewer/viewer.cpp +++ b/messageviewer/src/viewer/viewer.cpp @@ -48,6 +48,35 @@ #include = namespace MessageViewer { + +class AbstractMessageLoadedHandler::Private +{ +public: + Akonadi::Session *mSession =3D nullptr; +}; + +AbstractMessageLoadedHandler::AbstractMessageLoadedHandler() + : d(new Private) +{ +} + +AbstractMessageLoadedHandler::~AbstractMessageLoadedHandler() +{ + delete d; +} + +void AbstractMessageLoadedHandler::setSession(Akonadi::Session *session) +{ + d->mSession =3D session; +} + +Akonadi::Session *AbstractMessageLoadedHandler::session() const +{ + return d->mSession; +} + + = + Viewer::Viewer(QWidget *aParent, QWidget *mainWindow, KActionCollection *a= ctionCollection) : QWidget(aParent) , d_ptr(new ViewerPrivate(this, mainWindow, actionCollection)) @@ -507,7 +536,8 @@ QAbstractItemModel *Viewer::messageTreeModel() const = Akonadi::ItemFetchJob *Viewer::createFetchJob(const Akonadi::Item &item) { - Akonadi::ItemFetchJob *job =3D new Akonadi::ItemFetchJob(item); + Q_D(Viewer); + Akonadi::ItemFetchJob *job =3D new Akonadi::ItemFetchJob(item, d->mSes= sion); job->fetchScope().fetchAllAttributes(); job->fetchScope().setAncestorRetrieval(Akonadi::ItemFetchScope::Parent= ); job->fetchScope().fetchFullPayload(true); @@ -524,6 +554,7 @@ void Viewer::addMessageLoadedHandler(AbstractMessageLoa= dedHandler *handler) return; } = + handler->setSession(d->mSession); d->mMessageLoadedHandlers.insert(handler); } = diff --git a/messageviewer/src/viewer/viewer.h b/messageviewer/src/viewer/v= iewer.h index 69d60968..a933acc8 100644 --- a/messageviewer/src/viewer/viewer.h +++ b/messageviewer/src/viewer/viewer.h @@ -65,13 +65,12 @@ class ViewerPrivate; * An interface to plug in a handler that is called when * an message item has been loaded into the view. */ +class Viewer; class AbstractMessageLoadedHandler { public: - - virtual ~AbstractMessageLoadedHandler() - { - } + AbstractMessageLoadedHandler(); + virtual ~AbstractMessageLoadedHandler(); = /** * This method is called whenever a message item has been loaded @@ -80,6 +79,16 @@ public: * @param item The message item that has been loaded. */ virtual void setItem(const Akonadi::Item &item) =3D 0; + +protected: + Akonadi::Session *session() const; + +private: + void setSession(Akonadi::Session *session); + + friend class Viewer; + class Private; + Private * const d; }; = //TODO(Andras) once only those methods are public that really need to be p= ublic, probably export the whole class instead of just some methods @@ -301,7 +310,7 @@ public: * It will set the correct fetch scope. * You still need to connect to the job's result signal. */ - static Akonadi::ItemFetchJob *createFetchJob(const Akonadi::Item &item= ); + Akonadi::ItemFetchJob *createFetchJob(const Akonadi::Item &item); = /** * Adds a @p handler for actions that will be executed when the message diff --git a/messageviewer/src/viewer/viewer_p.cpp b/messageviewer/src/view= er/viewer_p.cpp index 24788dbd..af48a2d2 100644 --- a/messageviewer/src/viewer/viewer_p.cpp +++ b/messageviewer/src/viewer/viewer_p.cpp @@ -219,6 +219,7 @@ ViewerPrivate::ViewerPrivate(Viewer *aParent, QWidget *= mainWindow, , mCurrentContent(nullptr) , mMessagePartNode(nullptr) , q(aParent) + , mSession(new Akonadi::Session("MessageViewer-" + QByteArray::number(= reinterpret_cast(this)), this)) , mPreviouslyViewedItem(-1) , mScamDetectionWarning(nullptr) , mOpenAttachmentFolderWidget(nullptr) @@ -280,6 +281,7 @@ ViewerPrivate::ViewerPrivate(Viewer *aParent, QWidget *= mainWindow, = // FIXME: Don't use the full payload here when attachment loading on d= emand is used, just // like in KMMainWidget::slotMessageActivated(). + mMonitor.setSession(mSession); Akonadi::ItemFetchScope fs; fs.fetchFullPayload(); fs.fetchAttribute(); @@ -464,7 +466,7 @@ bool ViewerPrivate::deleteAttachment(KMime::Content *no= de, bool showWarning) mMimePartTree->mimePartModel()->setRoot(modifiedMessage); #endif mMessageItem.setPayloadFromData(modifiedMessage->encodedContent()); - Akonadi::ItemModifyJob *job =3D new Akonadi::ItemModifyJob(mMessageIte= m); + Akonadi::ItemModifyJob *job =3D new Akonadi::ItemModifyJob(mMessageIte= m, mSession); job->disableRevisionCheck(); connect(job, &KJob::result, this, &ViewerPrivate::itemModifiedResult); return true; @@ -481,7 +483,7 @@ void ViewerPrivate::itemModifiedResult(KJob *job) = void ViewerPrivate::editAttachment(KMime::Content *node, bool showWarning) { - MessageViewer::AttachmentEditJob *job =3D new MessageViewer::Attachmen= tEditJob(this); + MessageViewer::AttachmentEditJob *job =3D new MessageViewer::Attachmen= tEditJob(mSession, this); connect(job, &AttachmentEditJob::refreshMessage, this, &ViewerPrivate:= :slotRefreshMessage); job->setMainWindow(mMainWindow); job->setMessageItem(mMessageItem); @@ -1006,7 +1008,7 @@ void ViewerPrivate::collectionFetchedForStoringDecryp= tedMessage(KJob *job) KMime::Message::Ptr unencryptedMessage =3D mNodeHelper->unencrypte= dMessage(mMessage); if (unencryptedMessage) { mMessageItem.setPayload(unencryptedMessag= e); - Akonadi::ItemModifyJob *job =3D new Akonadi::ItemModifyJob(mMe= ssageItem); + Akonadi::ItemModifyJob *job =3D new Akonadi::ItemModifyJob(mMe= ssageItem, mSession); connect(job, &KJob::result, this, &ViewerPrivate::itemModified= Result); } } @@ -1044,7 +1046,8 @@ void ViewerPrivate::postProcessMessage(MimeTreeParser= ::ObjectTreeParser *otp, // on the wrong item! Akonadi::CollectionFetchJob *job =3D new Akonadi::CollectionFe= tchJob( Akonadi::Collection::root(), - Akonadi::CollectionFetchJob::Recursive); + Akonadi::CollectionFetchJob::Recursive, + mSession); connect(job, &KJob::result, this, &ViewerPrivate::collectionFetchedForStoringDecry= ptedMessage); } @@ -2788,7 +2791,7 @@ void ViewerPrivate::slotAttachmentEdit() return; } = - MessageViewer::AttachmentEditJob *job =3D new MessageViewer::Attachmen= tEditJob(this); + MessageViewer::AttachmentEditJob *job =3D new MessageViewer::Attachmen= tEditJob(mSession, this); connect(job, &AttachmentEditJob::refreshMessage, this, &ViewerPrivate:= :slotRefreshMessage); job->setMainWindow(mMainWindow); job->setMessageItem(mMessageItem); @@ -3198,7 +3201,7 @@ void ViewerPrivate::slotSaveMessageDisplayFormat() { if (mMessageItem.isValid()) { MessageViewer::ModifyMessageDisplayFormatJob *job - =3D new MessageViewer::ModifyMessageDisplayFormatJob(this); + =3D new MessageViewer::ModifyMessageDisplayFormatJob(mSession,= this); job->setMessageFormat(displayFormatMessageOverwrite()); job->setMessageItem(mMessageItem); job->setRemoteContent(htmlLoadExtOverride()); @@ -3211,7 +3214,7 @@ void ViewerPrivate::slotResetMessageDisplayFormat() if (mMessageItem.isValid()) { if (mMessageItem.hasAttribute()) { MessageViewer::ModifyMessageDisplayFormatJob *job - =3D new MessageViewer::ModifyMessageDisplayFormatJob(this); + =3D new MessageViewer::ModifyMessageDisplayFormatJob(mSess= ion, this); job->setMessageItem(mMessageItem); job->setResetFormat(true); job->start(); @@ -3250,7 +3253,7 @@ void ViewerPrivate::slotMessageIsNotAScam() MessageViewer::ScamAttribute *attr =3D mMessageItem.attribute( Akonadi::Item::AddIfMissing); attr->setIsAScam(false); - Akonadi::ItemModifyJob *modify =3D new Akonadi::ItemModifyJob(mMes= sageItem); + Akonadi::ItemModifyJob *modify =3D new Akonadi::ItemModifyJob(mMes= sageItem, mSession); modify->setIgnorePayload(true); modify->disableRevisionCheck(); connect(modify, &KJob::result, this, &ViewerPrivate::slotModifyIte= mDone); diff --git a/messageviewer/src/viewer/viewer_p.h b/messageviewer/src/viewer= /viewer_p.h index b38f9740..8d6ed80a 100644 --- a/messageviewer/src/viewer/viewer_p.h +++ b/messageviewer/src/viewer/viewer_p.h @@ -30,6 +30,7 @@ = #include #include +#include #include #include #include @@ -682,6 +683,7 @@ public: QColor mBackgroundError; = Viewer *const q; + Akonadi::Session *mSession; Akonadi::Monitor mMonitor; QSet mMessageLoadedHandlers; Akonadi::Item::Id mPreviouslyViewedItem;