Branch 'kolab/integration/4.13.0' - 2 commits - akonadi/calendar
Sandro Knauß
knauss at kolabsys.com
Sun Aug 10 15:10:07 CEST 2014
akonadi/calendar/freebusymanager.cpp | 2
akonadi/calendar/incidencechanger.cpp | 340 +++++++++++++++++++----------
akonadi/calendar/incidencechanger.h | 12 +
akonadi/calendar/incidencechanger_p.cpp | 10
akonadi/calendar/incidencechanger_p.h | 26 +-
akonadi/calendar/itiphandler.cpp | 33 ++
akonadi/calendar/itiphandler.h | 178 +++++++++++++++
akonadi/calendar/itiphandler_p.cpp | 32 +-
akonadi/calendar/itiphandler_p.h | 5
akonadi/calendar/itiphandlerhelper_p.cpp | 207 +++++++++++++----
akonadi/calendar/itiphandlerhelper_p.h | 36 +--
akonadi/calendar/mailclient_p.cpp | 43 ---
akonadi/calendar/mailclient_p.h | 23 +
akonadi/calendar/mailscheduler_p.cpp | 6
akonadi/calendar/mailscheduler_p.h | 3
akonadi/calendar/tests/itiphandlertest.cpp | 74 +++++-
akonadi/calendar/tests/mailclienttest.cpp | 62 ++++-
17 files changed, 819 insertions(+), 273 deletions(-)
New commits:
commit aebd3e86aaee5d2c42ae7d488c6575a587be6ef8
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Thu Jul 24 15:25:19 2014 +0200
DialogInterception for IncienceChanger.
REVIEW: 119434
diff --git a/akonadi/calendar/incidencechanger.cpp b/akonadi/calendar/incidencechanger.cpp
index 79d0f49..0d0bddd 100644
--- a/akonadi/calendar/incidencechanger.cpp
+++ b/akonadi/calendar/incidencechanger.cpp
@@ -43,7 +43,7 @@ using namespace KCalCore;
# define RUNNING_UNIT_TESTS false
#endif
-ITIPHandlerHelper::Action actionFromStatus(ITIPHandlerHelper::SendResult result)
+ITIPHandlerDialogDelegate::Action actionFromStatus(ITIPHandlerHelper::SendResult result)
{
//enum SendResult {
// Canceled, /**< Sending was canceled by the user, meaning there are
@@ -55,11 +55,11 @@ ITIPHandlerHelper::Action actionFromStatus(ITIPHandlerHelper::SendResult result)
// Success
switch (result) {
case ITIPHandlerHelper::ResultCanceled:
- return ITIPHandlerHelper::ActionDontSendMessage;
+ return ITIPHandlerDialogDelegate::ActionDontSendMessage;
case ITIPHandlerHelper::ResultSuccess:
- return ITIPHandlerHelper::ActionSendMessage;
+ return ITIPHandlerDialogDelegate::ActionSendMessage;
default:
- return ITIPHandlerHelper::ActionAsk;
+ return ITIPHandlerDialogDelegate::ActionAsk;
}
}
@@ -153,6 +153,7 @@ IncidenceChanger::Private::Private(bool enableHistory, ITIPHandlerComponentFacto
qRegisterMetaType<Akonadi::Item>("Akonadi::Item");
qRegisterMetaType<Akonadi::IncidenceChanger::ResultCode>(
"Akonadi::IncidenceChanger::ResultCode");
+ qRegisterMetaType<ITIPHandlerHelper::SendResult>("ITIPHandlerHelper::SendResult");
}
IncidenceChanger::Private::~Private()
@@ -228,7 +229,6 @@ void IncidenceChanger::Private::performNextModification(Akonadi::Item::Id id)
void IncidenceChanger::Private::handleTransactionJobResult(KJob *job)
{
- //kDebug();
TransactionSequence *transaction = qobject_cast<TransactionSequence*>(job);
Q_ASSERT(transaction);
Q_ASSERT(mAtomicOperationByTransaction.contains(transaction));
@@ -259,59 +259,80 @@ void IncidenceChanger::Private::handleTransactionJobResult(KJob *job)
void IncidenceChanger::Private::handleCreateJobResult(KJob *job)
{
- //kDebug();
- QString errorString;
- ResultCode resultCode = ResultCodeSuccess;
-
Change::Ptr change = mChangeForJob.take(job);
- mChangeById.remove(change->id);
const ItemCreateJob *j = qobject_cast<const ItemCreateJob*>(job);
Q_ASSERT(j);
Akonadi::Item item = j->item();
- QString description;
- if (change->atomicOperationId != 0) {
- AtomicOperation *a = mAtomicOperations[change->atomicOperationId];
- a->m_numCompletedChanges++;
- change->completed = true;
- description = a->m_description;
- }
if (j->error()) {
+ const QString errorString = j->errorString();
+ ResultCode resultCode = ResultCodeJobError;
item = change->newItem;
- resultCode = ResultCodeJobError;
- errorString = j->errorString();
+
kError() << errorString;
if (mShowDialogsOnError) {
KMessageBox::sorry(change->parentWidget,
i18n("Error while trying to create calendar item. Error was: %1",
errorString));
}
+ mChangeById.remove(change->id);
+ change->errorString = errorString;
+ change->resultCode = resultCode;
+ // puff, change finally goes out of scope, and emits the incidenceCreated signal.
} else {
Q_ASSERT(item.isValid());
Q_ASSERT(item.hasPayload<KCalCore::Incidence::Ptr>());
change->newItem = item;
- handleInvitationsAfterChange(change);
- // for user undo/redo
- if (change->recordToHistory) {
- mHistory->recordCreation(item, description, change->atomicOperationId);
+
+ if (change->useGroupwareCommunication) {
+ connect(change.data(),SIGNAL(dialogClosedAfterChange(int,ITIPHandlerHelper::SendResult)),
+ SLOT(handleCreateJobResult2(int,ITIPHandlerHelper::SendResult)));
+ handleInvitationsAfterChange(change);
+ } else {
+ handleCreateJobResult2(change->id, ITIPHandlerHelper::ResultSuccess);
}
}
+}
+
+void IncidenceChanger::Private::handleCreateJobResult2(int changeId, ITIPHandlerHelper::SendResult status)
+{
+ Change::Ptr change = mChangeById[changeId];
+ Akonadi::Item item = change->newItem;
+
+ mChangeById.remove(changeId);
+
+ if (status == ITIPHandlerHelper::ResultFailAbortUpdate) {
+ kError() << "Sending invitations failed, but did not delete the incidence";
+ }
+
+ const uint atomicOperationId = change->atomicOperationId;
+ if (atomicOperationId != 0) {
+ mInvitationStatusByAtomicOperation.insert(atomicOperationId, status);
+ }
+
+ QString description;
+ if (change->atomicOperationId != 0) {
+ AtomicOperation *a = mAtomicOperations[change->atomicOperationId];
+ ++a->m_numCompletedChanges;
+ change->completed = true;
+ description = a->m_description;
+ }
- change->errorString = errorString;
- change->resultCode = resultCode;
+ // for user undo/redo
+ if (change->recordToHistory) {
+ mHistory->recordCreation(item, description, change->atomicOperationId);
+ }
+
+ change->errorString = QString();
+ change->resultCode = ResultCodeSuccess;
// puff, change finally goes out of scope, and emits the incidenceCreated signal.
}
void IncidenceChanger::Private::handleDeleteJobResult(KJob *job)
{
- //kDebug();
- QString errorString;
- ResultCode resultCode = ResultCodeSuccess;
-
Change::Ptr change = mChangeForJob.take(job);
- mChangeById.remove(change->id);
const ItemDeleteJob *j = qobject_cast<const ItemDeleteJob*>(job);
const Item::List items = j->deletedItems();
@@ -329,8 +350,7 @@ void IncidenceChanger::Private::handleDeleteJobResult(KJob *job)
description = a->m_description;
}
if (j->error()) {
- resultCode = ResultCodeJobError;
- errorString = j->errorString();
+ const QString errorString = j->errorString();
kError() << errorString;
if (mShowDialogsOnError) {
KMessageBox::sorry(change->parentWidget,
@@ -342,26 +362,48 @@ void IncidenceChanger::Private::handleDeleteJobResult(KJob *job)
// Werent deleted due to error
mDeletedItemIds.remove(mDeletedItemIds.indexOf(item.id()));
}
+ mChangeById.remove(change->id);
+ change->resultCode = ResultCodeJobError;
+ change->errorString = errorString;
+ change->emitCompletionSignal();
+
} else { // success
if (change->recordToHistory) {
Q_ASSERT(mHistory);
mHistory->recordDeletions(items, description, change->atomicOperationId);
}
- handleInvitationsAfterChange(change);
+ if (change->useGroupwareCommunication) {
+ connect(change.data(),SIGNAL(dialogClosedAfterChange(int,ITIPHandlerHelper::SendResult)),
+ SLOT(handleDeleteJobResult2(int,ITIPHandlerHelper::SendResult)));
+ handleInvitationsAfterChange(change);
+ } else {
+ handleDeleteJobResult2(change->id, ITIPHandlerHelper::ResultSuccess);
+ }
+ }
+}
+
+void IncidenceChanger::Private::handleDeleteJobResult2(int changeId, ITIPHandlerHelper::SendResult status)
+{
+ Change::Ptr change = mChangeById[changeId];
+ mChangeById.remove(change->id);
+
+ if (status == ITIPHandlerHelper::ResultSuccess) {
+ change->errorString = QString();
+ change->resultCode = ResultCodeSuccess;
+ } else {
+ change->errorString = i18nc("errormessage for a job ended with an unexpected result", "An unknown error occurred");
+ change->resultCode = ResultCodeJobError;
}
- change->errorString = errorString;
- change->resultCode = resultCode;
// puff, change finally goes out of scope, and emits the incidenceDeleted signal.
}
+
+
void IncidenceChanger::Private::handleModifyJobResult(KJob *job)
{
- QString errorString;
- ResultCode resultCode = ResultCodeSuccess;
Change::Ptr change = mChangeForJob.take(job);
- mChangeById.remove(change->id);
const ItemModifyJob *j = qobject_cast<const ItemModifyJob*>(job);
const Item item = j->item();
@@ -377,16 +419,15 @@ void IncidenceChanger::Private::handleModifyJobResult(KJob *job)
description = a->m_description;
}
if (j->error()) {
+ const QString errorString = j->errorString();
+ ResultCode resultCode = ResultCodeJobError;
if (deleteAlreadyCalled(item.id())) {
// User deleted the item almost at the same time he changed it. We could just return success
// but the delete is probably already recorded to History, and that would make undo not work
// in the proper order.
resultCode = ResultCodeAlreadyDeleted;
- errorString = j->errorString();
kWarning() << "Trying to change item " << item.id() << " while deletion is in progress.";
} else {
- resultCode = ResultCodeJobError;
- errorString = j->errorString();
kError() << errorString;
}
if (mShowDialogsOnError) {
@@ -394,6 +435,16 @@ void IncidenceChanger::Private::handleModifyJobResult(KJob *job)
i18n("Error while trying to modify calendar item. Error was: %1",
errorString));
}
+ mChangeById.remove(change->id);
+ change->errorString = errorString;
+ change->resultCode = resultCode;
+ // puff, change finally goes out of scope, and emits the incidenceModified signal.
+
+
+ QMetaObject::invokeMethod(this, "performNextModification",
+ Qt::QueuedConnection,
+ Q_ARG(Akonadi::Item::Id, item.id()));
+
} else { // success
ConflictPreventer::self()->mLatestRevisionByItemId[item.id()] = item.revision();
change->newItem = item;
@@ -403,16 +454,31 @@ void IncidenceChanger::Private::handleModifyJobResult(KJob *job)
description, change->atomicOperationId);
}
- handleInvitationsAfterChange(change);
+ if (change->useGroupwareCommunication) {
+ connect(change.data(),SIGNAL(dialogClosedAfterChange(int,ITIPHandlerHelper::SendResult)),
+ SLOT(handleModifyJobResult2(int,ITIPHandlerHelper::SendResult)));
+ handleInvitationsAfterChange(change);
+ } else {
+ handleModifyJobResult2(change->id, ITIPHandlerHelper::ResultSuccess);
+ }
}
+}
+
+void IncidenceChanger::Private::handleModifyJobResult2(int changeId, ITIPHandlerHelper::SendResult status)
+{
+ Change::Ptr change = mChangeById[changeId];
- change->errorString = errorString;
- change->resultCode = resultCode;
+ mChangeById.remove(changeId);
+ if (change->atomicOperationId != 0) {
+ mInvitationStatusByAtomicOperation.insert(change->atomicOperationId, status);
+ }
+ change->errorString = QString();
+ change->resultCode = ResultCodeSuccess;
// puff, change finally goes out of scope, and emits the incidenceModified signal.
QMetaObject::invokeMethod(this, "performNextModification",
Qt::QueuedConnection,
- Q_ARG(Akonadi::Item::Id, item.id()));
+ Q_ARG(Akonadi::Item::Id, change->newItem.id()));
}
bool IncidenceChanger::Private::deleteAlreadyCalled(Akonadi::Item::Id id) const
@@ -420,20 +486,10 @@ bool IncidenceChanger::Private::deleteAlreadyCalled(Akonadi::Item::Id id) const
return mDeletedItemIds.contains(id);
}
-bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr &change)
+void IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr &change)
{
- bool result = true;
if (mGroupwareCommunication) {
- ITIPHandlerHelper handler(mFactory, change->parentWidget); // TODO make async
-
- if (m_invitationPolicy == InvitationPolicySend) {
- handler.setDefaultAction(ITIPHandlerHelper::ActionSendMessage);
- } else if (m_invitationPolicy == InvitationPolicyDontSend) {
- handler.setDefaultAction(ITIPHandlerHelper::ActionDontSendMessage);
- } else if (mInvitationStatusByAtomicOperation.contains(change->atomicOperationId)) {
- handler.setDefaultAction(actionFromStatus(mInvitationStatusByAtomicOperation.value(change->atomicOperationId)));
- }
-
+ ITIPHandlerHelper::SendResult result = ITIPHandlerHelper::ResultSuccess;
switch (change->type) {
case IncidenceChanger::ChangeTypeCreate:
// nothing needs to be done
@@ -441,7 +497,23 @@ bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr
case IncidenceChanger::ChangeTypeDelete:
{
ITIPHandlerHelper::SendResult status;
+ bool sendOk = true;
Q_ASSERT(!change->originalItems.isEmpty());
+
+ ITIPHandlerHelper *handler = new ITIPHandlerHelper(mFactory, change->parentWidget);
+ handler->setParent(this);
+
+ if (m_invitationPolicy == InvitationPolicySend) {
+ handler->setDefaultAction(ITIPHandlerDialogDelegate::ActionSendMessage);
+ } else if (m_invitationPolicy == InvitationPolicyDontSend) {
+ handler->setDefaultAction(ITIPHandlerDialogDelegate::ActionDontSendMessage);
+ } else if (mInvitationStatusByAtomicOperation.contains(change->atomicOperationId)) {
+ handler->setDefaultAction(actionFromStatus(mInvitationStatusByAtomicOperation.value(change->atomicOperationId)));
+ }
+
+ connect(handler, SIGNAL(finished(Akonadi::ITIPHandlerHelper::SendResult,QString)),
+ change.data(), SLOT(emitUserDialogClosedBeforeChange(Akonadi::ITIPHandlerHelper::SendResult)));
+
foreach(const Akonadi::Item &item, change->originalItems) {
Q_ASSERT(item.hasPayload<KCalCore::Incidence::Ptr>());
Incidence::Ptr incidence = CalendarUtils::incidence(item);
@@ -451,16 +523,21 @@ bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr
// We only send CANCEL if we're the organizer.
// If we're not, then we send REPLY with PartStat=Declined in handleInvitationsAfterChange()
if (Akonadi::CalendarUtils::thatIsMe(incidence->organizer()->email())) {
- status = handler.sendIncidenceDeletedMessage(KCalCore::iTIPCancel, incidence);
+ //TODO: not to popup all delete message dialogs at once :(
+ sendOk = false;
+ handler->sendIncidenceDeletedMessage(KCalCore::iTIPCancel, incidence);
if (change->atomicOperationId) {
mInvitationStatusByAtomicOperation.insert(change->atomicOperationId, status);
}
- result = status != ITIPHandlerHelper::ResultFailAbortUpdate;
//TODO: with some status we want to break immediately
}
}
+
+ if (sendOk) {
+ change->emitUserDialogClosedBeforeChange(result);
+ }
}
- break;
+ return;
case IncidenceChanger::ChangeTypeModify:
{
if (change->originalItems.isEmpty()) {
@@ -481,15 +558,20 @@ bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr
// "You're not organizer, do you want to modify event?" dialog in unit-tests, but want
// to emulate a "yes" and a "no" press.
if (m_invitationPolicy == InvitationPolicySend) {
- return true;
+ change->emitUserDialogClosedBeforeChange(ITIPHandlerHelper::ResultSuccess);
+ return;
} else if (m_invitationPolicy == InvitationPolicyDontSend) {
- return false;
+ change->emitUserDialogClosedBeforeChange(ITIPHandlerHelper::ResultCanceled);
+ return;
}
}
+ ITIPHandlerHelper handler(mFactory, change->parentWidget);
const bool modify = handler.handleIncidenceAboutToBeModified(newIncidence);
if (modify) {
break;
+ } else {
+ result = ITIPHandlerHelper::ResultCanceled;
}
if (newIncidence->type() == oldIncidence->type()) {
@@ -497,30 +579,34 @@ bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr
IncidenceBase *i2 = oldIncidence.data();
*i1 = *i2;
}
- result = false;
}
break;
default:
Q_ASSERT(false);
- result = false;
+ result = ITIPHandlerHelper::ResultCanceled;
}
+ change->emitUserDialogClosedBeforeChange(result);
+ } else {
+ change->emitUserDialogClosedBeforeChange(ITIPHandlerHelper::ResultSuccess);
}
- return result;
}
-bool IncidenceChanger::Private::handleInvitationsAfterChange(const Change::Ptr &change)
+void IncidenceChanger::Private::handleInvitationsAfterChange(const Change::Ptr &change)
{
if (change->useGroupwareCommunication) {
- ITIPHandlerHelper handler(mFactory, change->parentWidget); // TODO make async
+ ITIPHandlerHelper *handler = new ITIPHandlerHelper(mFactory, change->parentWidget);
+ connect(handler, SIGNAL(finished(Akonadi::ITIPHandlerHelper::SendResult,QString)),
+ change.data(), SLOT(emitUserDialogClosedAfterChange(Akonadi::ITIPHandlerHelper::SendResult)));
+ handler->setParent(this);
const bool alwaysSend = m_invitationPolicy == InvitationPolicySend;
const bool neverSend = m_invitationPolicy == InvitationPolicyDontSend;
if (alwaysSend) {
- handler.setDefaultAction(ITIPHandlerHelper::ActionSendMessage);
+ handler->setDefaultAction(ITIPHandlerDialogDelegate::ActionSendMessage);
}
if (neverSend) {
- handler.setDefaultAction(ITIPHandlerHelper::ActionDontSendMessage);
+ handler->setDefaultAction(ITIPHandlerDialogDelegate::ActionDontSendMessage);
}
switch (change->type) {
@@ -528,22 +614,15 @@ bool IncidenceChanger::Private::handleInvitationsAfterChange(const Change::Ptr &
{
Incidence::Ptr incidence = CalendarUtils::incidence(change->newItem);
if (incidence->supportsGroupwareCommunication()) {
- const ITIPHandlerHelper::SendResult status =
- handler.sendIncidenceCreatedMessage(KCalCore::iTIPRequest, incidence);
-
- if (status == ITIPHandlerHelper::ResultFailAbortUpdate) {
- kError() << "Sending invitations failed, but did not delete the incidence";
- }
-
- const uint atomicOperationId = change->atomicOperationId;
- if (atomicOperationId != 0) {
- mInvitationStatusByAtomicOperation.insert(atomicOperationId, status);
- }
+ handler->sendIncidenceCreatedMessage(KCalCore::iTIPRequest, incidence);
+ return;
}
}
break;
case IncidenceChanger::ChangeTypeDelete:
{
+ handler->deleteLater();
+ handler = 0;
Q_ASSERT(!change->originalItems.isEmpty());
foreach(const Akonadi::Item &item, change->originalItems) {
Q_ASSERT(item.hasPayload());
@@ -596,28 +675,31 @@ bool IncidenceChanger::Private::handleInvitationsAfterChange(const Change::Ptr &
}
if (!neverSend && !alwaysSend && mInvitationStatusByAtomicOperation.contains(change->atomicOperationId)) {
- handler.setDefaultAction(actionFromStatus(mInvitationStatusByAtomicOperation.value(change->atomicOperationId)));
+ handler->setDefaultAction(actionFromStatus(mInvitationStatusByAtomicOperation.value(change->atomicOperationId)));
}
const bool attendeeStatusChanged = myAttendeeStatusChanged(newIncidence,
oldIncidence,
Akonadi::CalendarUtils::allEmails());
- ITIPHandlerHelper::SendResult status = handler.sendIncidenceModifiedMessage(KCalCore::iTIPRequest,
- newIncidence,
- attendeeStatusChanged);
+ handler->sendIncidenceModifiedMessage(KCalCore::iTIPRequest, newIncidence, attendeeStatusChanged);
+ return;
- if (change->atomicOperationId != 0) {
- mInvitationStatusByAtomicOperation.insert(change->atomicOperationId, status);
- }
}
break;
default:
+ handler->deleteLater();
+ handler = 0;
Q_ASSERT(false);
- return false;
+ change->emitUserDialogClosedAfterChange(ITIPHandlerHelper::ResultCanceled);
+ return;
}
+ handler->deleteLater();
+ handler = 0;
+ change->emitUserDialogClosedAfterChange(ITIPHandlerHelper::ResultSuccess);
+ } else {
+ change->emitUserDialogClosedAfterChange(ITIPHandlerHelper::ResultSuccess);
}
- return true;
}
/** static */
@@ -658,7 +740,6 @@ int IncidenceChanger::createIncidence(const Incidence::Ptr &incidence,
const Collection &collection,
QWidget *parent)
{
- //kDebug();
if (!incidence) {
kWarning() << "An invalid payload is not allowed.";
d->cancelTransaction();
@@ -702,7 +783,6 @@ int IncidenceChanger::deleteIncidence(const Item &item, QWidget *parent)
int IncidenceChanger::deleteIncidences(const Item::List &items, QWidget *parent)
{
- //kDebug();
if (items.isEmpty()) {
kError() << "Delete what?";
d->cancelTransaction();
@@ -774,31 +854,44 @@ int IncidenceChanger::deleteIncidences(const Item::List &items, QWidget *parent)
return changeId;
}
change->originalItems = itemsToDelete;
- d->handleInvitationsBeforeChange(change);
- ItemDeleteJob *deleteJob = new ItemDeleteJob(itemsToDelete, d->parentJob(change));
- d->mChangeForJob.insert(deleteJob, change);
d->mChangeById.insert(changeId, change);
- if (d->mBatchOperationInProgress) {
- AtomicOperation *atomic = d->mAtomicOperations[atomicOperationId];
+ if (d->mGroupwareCommunication) {
+ connect(change.data(), SIGNAL(dialogClosedBeforeChange(int,ITIPHandlerHelper::SendResult)),
+ d, SLOT(deleteIncidences2(int,ITIPHandlerHelper::SendResult)));
+ d->handleInvitationsBeforeChange(change);
+ } else {
+ d->deleteIncidences2(changeId, ITIPHandlerHelper::ResultSuccess);
+ }
+ return changeId;
+}
+
+void IncidenceChanger::Private::deleteIncidences2(int changeId, ITIPHandlerHelper::SendResult status)
+{
+ Q_UNUSED(status);
+ Change::Ptr change = mChangeById[changeId];
+ const uint atomicOperationId = change->atomicOperationId;
+ ItemDeleteJob *deleteJob = new ItemDeleteJob(change->originalItems, parentJob(change));
+ mChangeForJob.insert(deleteJob, change);
+
+ if (mBatchOperationInProgress) {
+ AtomicOperation *atomic = mAtomicOperations[atomicOperationId];
Q_ASSERT(atomic);
atomic->addChange(change);
}
- foreach(const Item &item, itemsToDelete) {
- d->mDeletedItemIds << item.id();
+ foreach(const Item &item, change->originalItems) {
+ mDeletedItemIds << item.id();
}
// Do some cleanup
- if (d->mDeletedItemIds.count() > 100)
- d->mDeletedItemIds.remove(0, 50);
+ if (mDeletedItemIds.count() > 100)
+ mDeletedItemIds.remove(0, 50);
// QueuedConnection because of possible sync exec calls.
connect(deleteJob, SIGNAL(result(KJob*)),
- d, SLOT(handleDeleteJobResult(KJob*)), Qt::QueuedConnection);
-
- return changeId;
+ SLOT(handleDeleteJobResult(KJob*)), Qt::QueuedConnection);
}
int IncidenceChanger::modifyIncidence(const Item &changedItem,
@@ -840,6 +933,7 @@ int IncidenceChanger::modifyIncidence(const Item &changedItem,
if (!d->allowAtomicOperation(atomicOperationId, change)) {
const QString errorString = d->showErrorDialog(ResultCodeDuplicateId, parent);
+
change->resultCode = ResultCodeDuplicateId;
change->errorString = errorString;
d->cancelTransaction();
@@ -888,15 +982,32 @@ void IncidenceChanger::Private::performModification(Change::Ptr change)
emitModifyFinished(q, changeId, newItem, ResultCodeRolledback, errorMessage);
return;
}
+ if (mGroupwareCommunication) {
+ connect(change.data(), SIGNAL(dialogClosedBeforeChange(int,ITIPHandlerHelper::SendResult)),
+ SLOT(performModification2(int,ITIPHandlerHelper::SendResult)));
+ handleInvitationsBeforeChange(change);
+ } else {
+ performModification2(change->id, ITIPHandlerHelper::ResultSuccess);
+ }
+}
- const bool userCancelled = !handleInvitationsBeforeChange(change);
- if (userCancelled) {
+void IncidenceChanger::Private::performModification2(int changeId, ITIPHandlerHelper::SendResult status)
+{
+ Change::Ptr change = mChangeById[changeId];
+ const Item::Id id = change->newItem.id();
+ Akonadi::Item &newItem = change->newItem;
+ Q_ASSERT(newItem.isValid());
+ Q_ASSERT(newItem.hasPayload<Incidence::Ptr>());
+ if (status == ITIPHandlerHelper::ResultCanceled) { //TODO:fireout what is right here:)
// User got a "You're not the organizer, do you really want to send" dialog, and said "no"
kDebug() << "User cancelled, giving up";
- emitModifyFinished(q, changeId, newItem, ResultCodeUserCanceled, QString());
+ emitModifyFinished(q, change->id, newItem, ResultCodeUserCanceled, QString());
return;
}
+ const uint atomicOperationId = change->atomicOperationId;
+ const bool hasAtomicOperationId = atomicOperationId != 0;
+
QHash<Akonadi::Item::Id, int> &latestRevisionByItemId =
ConflictPreventer::self()->mLatestRevisionByItemId;
if (latestRevisionByItemId.contains(id) &&
diff --git a/akonadi/calendar/incidencechanger_p.cpp b/akonadi/calendar/incidencechanger_p.cpp
index 74cf138..063eb2b 100644
--- a/akonadi/calendar/incidencechanger_p.cpp
+++ b/akonadi/calendar/incidencechanger_p.cpp
@@ -30,6 +30,16 @@
using namespace Akonadi;
+void Change::emitUserDialogClosedAfterChange(Akonadi::ITIPHandlerHelper::SendResult status)
+{
+ emit dialogClosedAfterChange(id, status);
+}
+
+void Change::emitUserDialogClosedBeforeChange(Akonadi::ITIPHandlerHelper::SendResult status)
+{
+ emit dialogClosedBeforeChange(id , status);
+}
+
void IncidenceChanger::Private::loadCollections()
{
if (isLoadingCollections()) {
diff --git a/akonadi/calendar/incidencechanger_p.h b/akonadi/calendar/incidencechanger_p.h
index eb08eb1..f600970 100644
--- a/akonadi/calendar/incidencechanger_p.h
+++ b/akonadi/calendar/incidencechanger_p.h
@@ -45,8 +45,8 @@ namespace Akonadi {
class TransactionSequence;
class CollectionFetchJob;
-class Change {
-
+class Change : public QObject {
+ Q_OBJECT
public:
typedef QSharedPointer<Change> Ptr;
typedef QList<Ptr> List;
@@ -97,6 +97,15 @@ public:
bool completed;
bool queuedModification;
bool useGroupwareCommunication;
+
+signals:
+ void dialogClosedBeforeChange(int id, ITIPHandlerHelper::SendResult status);
+ void dialogClosedAfterChange(int id, ITIPHandlerHelper::SendResult status);
+
+public slots:
+ void emitUserDialogClosedAfterChange(Akonadi::ITIPHandlerHelper::SendResult status);
+ void emitUserDialogClosedBeforeChange(Akonadi::ITIPHandlerHelper::SendResult status);
+
protected:
IncidenceChanger *const changer;
};
@@ -285,8 +294,8 @@ public:
void cleanupTransaction();
bool allowAtomicOperation(int atomicOperationId, const Change::Ptr &change) const;
- bool handleInvitationsBeforeChange(const Change::Ptr &change);
- bool handleInvitationsAfterChange(const Change::Ptr &change);
+ void handleInvitationsBeforeChange(const Change::Ptr &change);
+ void handleInvitationsAfterChange(const Change::Ptr &change);
static bool myAttendeeStatusChanged(const KCalCore::Incidence::Ptr &newIncidence,
const KCalCore::Incidence::Ptr &oldIncidence,
const QStringList &myEmails);
@@ -299,6 +308,12 @@ public Q_SLOTS:
void performNextModification(Akonadi::Item::Id id);
void onCollectionsLoaded(KJob*);
+ void handleCreateJobResult2(int changeId, ITIPHandlerHelper::SendResult);
+ void handleDeleteJobResult2(int changeId, ITIPHandlerHelper::SendResult);
+ void handleModifyJobResult2(int changeId, ITIPHandlerHelper::SendResult);
+ void performModification2(int changeId, ITIPHandlerHelper::SendResult);
+ void deleteIncidences2(int changeId, ITIPHandlerHelper::SendResult);
+
public:
int mLatestChangeId;
QHash<const KJob*,Change::Ptr> mChangeForJob;
diff --git a/akonadi/calendar/itiphandler.cpp b/akonadi/calendar/itiphandler.cpp
index a4bc9f1..ffaccf5 100644
--- a/akonadi/calendar/itiphandler.cpp
+++ b/akonadi/calendar/itiphandler.cpp
@@ -76,6 +76,11 @@ MailTransport::MessageQueueJob *ITIPHandlerComponentFactory::createMessageQueueJ
return new MailTransport::MessageQueueJob(parent);
}
+ITIPHandlerDialogDelegate *ITIPHandlerComponentFactory::createITIPHanderDialogDelegate(const KCalCore::Incidence::Ptr &incidence, KCalCore::iTIPMethod method, QWidget *parent)
+{
+ return new ITIPHandlerDialogDelegate(incidence, method, parent);
+}
+
ITIPHandler::ITIPHandler(QObject *parent) : QObject(parent)
, d(new Private(/*factory=*/0, this))
{
diff --git a/akonadi/calendar/itiphandler.h b/akonadi/calendar/itiphandler.h
index dcbc6b6..2182dbe 100644
--- a/akonadi/calendar/itiphandler.h
+++ b/akonadi/calendar/itiphandler.h
@@ -32,6 +32,10 @@
#include <kcalcore/incidence.h>
#include <kcalcore/schedulemessage.h>
+#include <KGuiItem>
+#include <KLocalizedString>
+
+#include <QObject>
#include <QString>
#include <QWidget>
@@ -60,7 +64,130 @@ public:
};
/**
- * @short Factory to create MailTransport::MessageQueueJob jobs.
+ * @short Ui delegate for dialogs raised by the ITIPHandler and IncidenceChanger.
+ * @since 4.15
+ */
+class AKONADI_CALENDAR_EXPORT ITIPHandlerDialogDelegate : public QObject {
+ Q_OBJECT
+public:
+ // Posible default actions
+ enum Action {
+ ActionAsk, /**< Ask the user for a descision */
+ ActionSendMessage, /**< Answer with Yes */
+ ActionDontSendMessage /**< Answer with No */
+ };
+
+ // How will reveive the mail afterwards
+ enum Recipient {
+ Organizer, /**< the organizer of the incidence */
+ Attendees /**< the attendees of the incidence */
+ };
+
+ /**
+ * Creates a new AskDelegator
+ */
+ explicit ITIPHandlerDialogDelegate(const KCalCore::Incidence::Ptr &incidence, KCalCore::iTIPMethod method, QWidget *parent = 0);
+
+ /*
+ * Opens a Dialog, when an incidence is created
+ * The function must emit a dialogClosed signal with the user's answer
+ *
+ * @param recipient: to who the mail will be sent afterwards
+ * @param question: dialog's question
+ * @param action: Should the dialog been shown or should a default answer be returned
+ * @param buttonYes: dialog's yes answer
+ * @param buttonNo: dialog's no answer
+ */
+ virtual void openDialogIncidenceCreated(Recipient recipient,
+ const QString &question,
+ Action action = ActionAsk,
+ const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
+ const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
+
+ /*
+ * Opens a Dialog, when an incidence is modified
+ * The function must emit a dialogClosed signal with the user's answer
+ *
+ * @param attendeeStatusChanged: Only the status of the own attendeeStatus is changed
+ * @param recipient: to who the mail will be sent afterwards
+ * @param question: dialog's question
+ * @param action: Should the dialog been shown or should a default answer be returned
+ * @param buttonYes: dialog's yes answer
+ * @param buttonNo: dialog's no answer
+ */
+ virtual void openDialogIncidenceModified(bool attendeeStatusChanged,
+ Recipient recipient,
+ const QString &question,
+ Action action = ActionAsk,
+ const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
+ const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
+
+ /*
+ * Opens a Dialog, when an incidence is deleted
+ * The function must emit a dialogClosed signal with the user's answer
+ *
+ * @param recipient: to who the mail will be sent afterwards
+ * @param question: dialog's question
+ * @param action: Should the dialog been shown or should a default answer be returned
+ * @param buttonYes: dialog's yes answer
+ * @param buttonNo: dialog's no answer
+ */
+ virtual void openDialogIncidenceDeleted(Recipient recipient,
+ const QString &question,
+ Action action = ActionAsk,
+ const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
+ const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
+ /*
+ * Opens a Dialog, when mail was sended
+ * The function must emit a dialogClosed signal with the user's answer
+ *
+ * @param question: dialog's question
+ * @param action: Should the dialog been shown or should a default answer be returned
+ * @param buttonYes: dialog's yes answer
+ * @param buttonNo: dialog's no answer
+ */
+ virtual void openDialogSchedulerFinished(const QString &question,
+ Action action = ActionAsk,
+ const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
+ const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
+
+Q_SIGNALS:
+ /*
+ * Signal is emited, when the user has answered the dialog or the defaultAction is used
+ * @param answer: answer should be part of KMessageBox:ButtonCode, keep in mind that it is a YesNoDialog so normally it should be KMessageBox::Yes or KMessageBox::No
+ * @param method: itip method
+ * @param incidence: purpose of the dialog
+ */
+ void dialogClosed(int answer, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+
+protected:
+ /*
+ * Opens a KMessageBox::questionYesNo with the question
+ *
+ * @return KMessageBox::Yes or KMessageBox::No
+ *
+ * @param question: dialog's question
+ * @param action: Should the dialog been shown or should a default answer be returned
+ * @param buttonYes: dialog's yes answer
+ * @param buttonNo: dialog's no answer
+ */
+ int askUserIfNeeded(const QString &question,
+ Action action,
+ const KGuiItem &buttonYes,
+ const KGuiItem &buttonNo) const;
+
+ // parent of the dialog
+ QWidget *mParent;
+
+ // Incidence related to the dialog
+ KCalCore::Incidence::Ptr mIncidence;
+
+ // ITIPMethod related to the dialog
+ KCalCore::iTIPMethod mMethod;
+};
+
+/**
+ * @short Factory to create MailTransport::MessageQueueJob jobs or ITIPHandlerDialogDelegate objects.
* @since 4.15
*/
class AKONADI_CALENDAR_EXPORT ITIPHandlerComponentFactory : public QObject
@@ -84,6 +211,15 @@ public:
* @param parent of the MailTransport::MessageQueueJob object
*/
virtual MailTransport::MessageQueueJob* createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity, QObject *parent = 0);
+
+ /*
+ * @return A new ITIPHandlerDialogDelegate object
+ * @param incidence the purpose of the dialogs
+ * @param method the ITIPMethod
+ * @parent parent of the AskDelegator
+ *
+ */
+ virtual ITIPHandlerDialogDelegate* createITIPHanderDialogDelegate(const KCalCore::Incidence::Ptr &incidence, KCalCore::iTIPMethod method, QWidget *parent = 0);
};
/**
diff --git a/akonadi/calendar/itiphandler_p.cpp b/akonadi/calendar/itiphandler_p.cpp
index db1de2f..c8736a3 100644
--- a/akonadi/calendar/itiphandler_p.cpp
+++ b/akonadi/calendar/itiphandler_p.cpp
@@ -41,6 +41,9 @@ ITIPHandler::Private::Private(ITIPHandlerComponentFactory *factory, ITIPHandler
connect(m_helper, SIGNAL(finished(Akonadi::ITIPHandlerHelper::SendResult,QString)),
SLOT(onHelperFinished(Akonadi::ITIPHandlerHelper::SendResult,QString)));
+
+ connect(m_helper, SIGNAL(sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::SendResult,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)),
+ SLOT(onHelperModifyDialogClosed(ITIPHandlerHelper::SendResult,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)));
}
void ITIPHandler::Private::onSchedulerFinished(Akonadi::Scheduler::Result result,
@@ -127,18 +130,12 @@ void ITIPHandler::Private::finishProcessiTIPMessage(Akonadi::MailScheduler::Resu
if (success) {
// send update to all attendees
Q_ASSERT(m_incidence);
- ITIPHandlerHelper::SendResult sendResult
- = m_helper->sendIncidenceModifiedMessage(KCalCore::iTIPRequest,
+ m_helper->setDialogParent(m_parentWidget);
+ m_helper->sendIncidenceModifiedMessage(KCalCore::iTIPRequest,
KCalCore::Incidence::Ptr(m_incidence->clone()),
false);
m_incidence.clear();
- if (sendResult == ITIPHandlerHelper::ResultNoSendingNeeded ||
- sendResult == ITIPHandlerHelper::ResultCanceled) {
- emit q->iTipMessageSent(ResultSuccess, QString());
- } else {
- // ITIPHandlerHelper is working hard and slot onHelperFinished will be called soon
- return;
- }
+ return;
} else {
//fall through
}
@@ -148,6 +145,15 @@ void ITIPHandler::Private::finishProcessiTIPMessage(Akonadi::MailScheduler::Resu
success ? QString() : i18n("Error: %1", errorMessage));
}
+void ITIPHandler::Private::onHelperModifyDialogClosed(ITIPHandlerHelper::SendResult sendResult, KCalCore::iTIPMethod /*method*/, const KCalCore::Incidence::Ptr &incidence)
+{
+ if (sendResult == ITIPHandlerHelper::ResultNoSendingNeeded ||
+ sendResult == ITIPHandlerHelper::ResultCanceled) {
+ emit q->iTipMessageSent(ResultSuccess, QString());
+ }
+}
+
+
void ITIPHandler::Private::finishSendiTIPMessage(Akonadi::MailScheduler::Result result,
const QString &errorMessage)
{
diff --git a/akonadi/calendar/itiphandler_p.h b/akonadi/calendar/itiphandler_p.h
index 63040b2..aaae4fd 100644
--- a/akonadi/calendar/itiphandler_p.h
+++ b/akonadi/calendar/itiphandler_p.h
@@ -92,6 +92,8 @@ private Q_SLOTS:
void onHelperFinished(Akonadi::ITIPHandlerHelper::SendResult result,
const QString &errorMessage);
+ void onHelperModifyDialogClosed(ITIPHandlerHelper::SendResult result, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+
void onCounterProposalDelegateFinished(bool success, const QString &errorMessage);
};
diff --git a/akonadi/calendar/itiphandlerhelper_p.cpp b/akonadi/calendar/itiphandlerhelper_p.cpp
index d72e89a..2af8f3f 100644
--- a/akonadi/calendar/itiphandlerhelper_p.cpp
+++ b/akonadi/calendar/itiphandlerhelper_p.cpp
@@ -65,28 +65,65 @@ QString proposalComment(const KCalCore::Incidence::Ptr &incidence)
return comment;
}
-int ITIPHandlerHelper::askUserIfNeeded(const QString &question,
- bool ignoreDefaultAction,
- const KGuiItem &buttonYes,
- const KGuiItem &buttonNo) const
+ITIPHandlerDialogDelegate::ITIPHandlerDialogDelegate(const KCalCore::Incidence::Ptr &incidence, KCalCore::iTIPMethod method, QWidget *parent)
+ : mParent(parent)
+ , mIncidence(incidence)
+ , mMethod(method)
{
- Q_ASSERT_X(!question.isEmpty(), "ITIPHandlerHelper::askUser", "ask what?");
+}
- if (ignoreDefaultAction || mDefaultAction == ITIPHandlerHelper::ActionAsk)
- return KMessageBox::questionYesNo(mParent, question, i18n("Group Scheduling Email"),
- buttonYes, buttonNo);
- switch (mDefaultAction) {
- case ITIPHandlerHelper::ActionSendMessage:
+int ITIPHandlerDialogDelegate::askUserIfNeeded(const QString &question, Action action,
+ const KGuiItem &buttonYes, const KGuiItem &buttonNo) const
+{
+ Q_ASSERT_X(!question.isEmpty(), "ITIPHandlerHelper::askUser", "ask what?");
+
+ switch (action) {
+ case ActionSendMessage:
return KMessageBox::Yes;
- case ITIPHandlerHelper::ActionDontSendMessage:
+ case ActionDontSendMessage:
return KMessageBox::No;
default:
- Q_ASSERT(false);
- return 0;
+ return KMessageBox::questionYesNo(mParent, question, i18n("Group Scheduling Email"),
+ buttonYes, buttonNo);
}
}
+void ITIPHandlerDialogDelegate::openDialogIncidenceCreated(Recipient recipient,
+ const QString &question, Action action,
+ const KGuiItem &buttonYes, const KGuiItem &buttonNo)
+{
+ Q_UNUSED(recipient);
+ const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
+ emit dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
+}
+
+void ITIPHandlerDialogDelegate::openDialogIncidenceModified(bool attendeeStatusChanged, Recipient recipient,
+ const QString &question, Action action,
+ const KGuiItem &buttonYes, const KGuiItem &buttonNo)
+{
+ Q_UNUSED(attendeeStatusChanged);
+ Q_UNUSED(recipient);
+ const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
+ emit dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
+}
+
+void ITIPHandlerDialogDelegate::openDialogIncidenceDeleted(Recipient recipient,
+ const QString &question, Action action,
+ const KGuiItem &buttonYes, const KGuiItem &buttonNo)
+{
+ Q_UNUSED(recipient);
+ const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
+ emit dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
+}
+
+void ITIPHandlerDialogDelegate::openDialogSchedulerFinished(const QString &question, Action action,
+ const KGuiItem &buttonYes, const KGuiItem &buttonNo)
+{
+ const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
+ emit dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
+}
+
ITIPHandlerHelper::SendResult
ITIPHandlerHelper::sentInvitation(int messageBoxReturnCode,
const KCalCore::Incidence::Ptr &incidence,
@@ -114,9 +151,11 @@ ITIPHandlerHelper::sentInvitation(int messageBoxReturnCode,
return ITIPHandlerHelper::ResultSuccess;
} else if (messageBoxReturnCode == KMessageBox::No) {
+ emit finished(ITIPHandlerHelper::ResultCanceled, QString());
return ITIPHandlerHelper::ResultCanceled;
} else {
Q_ASSERT(false); // TODO: Figure out if/how this can happen (by closing the dialog with x??)
+ emit finished(ITIPHandlerHelper::ResultCanceled, QString());
return ITIPHandlerHelper::ResultCanceled;
}
}
@@ -149,9 +188,11 @@ bool ITIPHandlerHelper::weNeedToSendMailFor(const KCalCore::Incidence::Ptr &inci
}
ITIPHandlerHelper::ITIPHandlerHelper(ITIPHandlerComponentFactory *factory, QWidget *parent)
- : mDefaultAction(ITIPHandlerHelper::ActionAsk)
+ : QObject(parent)
+ , mDefaultAction(ITIPHandlerDialogDelegate::ActionAsk)
, mParent(parent)
- , m_scheduler(new MailScheduler(factory, parent))
+ , m_factory(factory ? factory : new ITIPHandlerComponentFactory(this))
+ , m_scheduler(new MailScheduler(m_factory, this))
, m_status(StatusNone)
{
connect(m_scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString)),
@@ -167,13 +208,12 @@ void ITIPHandlerHelper::setDialogParent(QWidget *parent)
mParent = parent;
}
-void ITIPHandlerHelper::setDefaultAction(Action action)
+void ITIPHandlerHelper::setDefaultAction(ITIPHandlerDialogDelegate::Action action)
{
mDefaultAction = action;
}
-ITIPHandlerHelper::SendResult
-ITIPHandlerHelper::sendIncidenceCreatedMessage(KCalCore::iTIPMethod method,
+void ITIPHandlerHelper::sendIncidenceCreatedMessage(KCalCore::iTIPMethod method,
const KCalCore::Incidence::Ptr &incidence)
{
/// When we created the incidence, we *must* be the organizer.
@@ -182,12 +222,15 @@ ITIPHandlerHelper::sendIncidenceCreatedMessage(KCalCore::iTIPMethod method,
kError() << "We should be the organizer of this incidence!"
<< "; email= " << incidence->organizer()->email()
<< "; thatIsMe() = " << Akonadi::CalendarUtils::thatIsMe(incidence->organizer()->email());
- Q_ASSERT(false);
- return ITIPHandlerHelper::ResultFailAbortUpdate;
+ emit sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::ResultFailAbortUpdate, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultFailAbortUpdate, QString());
+ return;
}
if (!weNeedToSendMailFor(incidence)) {
- return ITIPHandlerHelper::ResultNoSendingNeeded;
+ emit sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
+ return;
}
QString question;
@@ -204,8 +247,16 @@ ITIPHandlerHelper::sendIncidenceCreatedMessage(KCalCore::iTIPMethod method,
"Should an email be sent to the attendees?");
}
- const int messageBoxReturnCode = askUserIfNeeded(question, false);
- return sentInvitation(messageBoxReturnCode, incidence, method);
+ ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent);
+ connect(askDelegator, SIGNAL(dialogClosed(int, KCalCore::iTIPMethod, KCalCore::Incidence::Ptr)),
+ SLOT(slotIncidenceCreatedDialogClosed(int, KCalCore::iTIPMethod, KCalCore::Incidence::Ptr)));
+ askDelegator->openDialogIncidenceCreated(ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction);
+}
+
+void ITIPHandlerHelper::slotIncidenceCreatedDialogClosed(int messageBoxReturnCode, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence)
+{
+ ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method);
+ emit sendIncidenceCreatedMessageFinished(status, method, incidence);
}
bool ITIPHandlerHelper::handleIncidenceAboutToBeModified(const KCalCore::Incidence::Ptr &incidence)
@@ -239,11 +290,14 @@ bool ITIPHandlerHelper::handleIncidenceAboutToBeModified(const KCalCore::Inciden
}
}
-ITIPHandlerHelper::SendResult
-ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
+void ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
const KCalCore::Incidence::Ptr &incidence,
bool attendeeStatusChanged)
{
+ ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent);
+
+ connect(askDelegator, SIGNAL(dialogClosed(int,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)),
+ SLOT(slotIncidenceModifiedDialogClosed(int,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)));
// For a modified incidence, either we are the organizer or someone else.
if (weAreOrganizerOf(incidence)) {
if (weNeedToSendMailFor(incidence)) {
@@ -251,10 +305,13 @@ ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
"Do you want to email the attendees an update message?",
incidence->summary());
- const int messageBoxReturnCode = askUserIfNeeded(question, false, KGuiItem(i18n("Send Update")));
- return sentInvitation(messageBoxReturnCode, incidence, method);
+ askDelegator->openDialogIncidenceModified(attendeeStatusChanged, ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction, KGuiItem(i18n("Send Update")));
+ return;
} else {
- return ResultNoSendingNeeded;
+ emit sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
+ delete askDelegator;
+ return;
}
} else if (incidence->type() == KCalCore::Incidence::TypeTodo) {
@@ -266,8 +323,8 @@ ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
const QString question = i18n("Do you want to send a status update to the "
"organizer of this task?");
- const int messageBoxReturnCode = askUserIfNeeded(question, false, KGuiItem(i18n("Send Update")));
- return sentInvitation(messageBoxReturnCode, incidence, method);
+ askDelegator->openDialogIncidenceModified(attendeeStatusChanged, ITIPHandlerDialogDelegate::Organizer, question, mDefaultAction, KGuiItem(i18n("Send Update")));
+ return;
} else if (incidence->type() == KCalCore::Incidence::TypeEvent) {
if (attendeeStatusChanged && method == KCalCore::iTIPRequest) {
@@ -275,21 +332,37 @@ ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
const QString question =
i18n("Your status as an attendee of this event changed. "
"Do you want to send a status update to the event organizer?");
- const int messageBoxReturnCode = askUserIfNeeded(question, false, KGuiItem(i18n("Send Update")));
- return sentInvitation(messageBoxReturnCode, incidence, method);
+
+ askDelegator->openDialogIncidenceModified(attendeeStatusChanged, ITIPHandlerDialogDelegate::Organizer, question, mDefaultAction, KGuiItem(i18n("Send Update")));
+ return;
} else {
- return sentInvitation(KMessageBox::Yes, incidence, method);
+ slotIncidenceModifiedDialogClosed(KMessageBox::Yes, method, incidence);
+ delete askDelegator;
+ return;
}
}
Q_ASSERT(false); // Shouldn't happen.
- return ResultNoSendingNeeded;
+ emit sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
+ delete askDelegator;
}
-ITIPHandlerHelper::SendResult
-ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
+void ITIPHandlerHelper::slotIncidenceModifiedDialogClosed(int messageBoxReturnCode, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence)
+{
+ ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method);
+ emit sendIncidenceModifiedMessageFinished(status, method, incidence);
+}
+
+void ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
const KCalCore::Incidence::Ptr &incidence)
{
Q_ASSERT(incidence);
+
+ ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent);
+
+ connect(askDelegator, SIGNAL(dialogClosed(int,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)),
+ SLOT(slotIncidenceDeletedDialogClosed(int,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)));
+
// For a modified incidence, either we are the organizer or someone else.
if (weAreOrganizerOf(incidence)) {
if (weNeedToSendMailFor(incidence)) {
@@ -307,11 +380,13 @@ ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
"Do you want to email the attendees that the journal is canceled?",
incidence->summary());
}
-
- const int messageBoxReturnCode = askUserIfNeeded(question, false);
- return sentInvitation(messageBoxReturnCode, incidence, method);
+ askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction);
+ return;
} else {
- return ResultNoSendingNeeded;
+ emit sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
+ delete askDelegator;
+ return;
}
} else if (incidence->type() != KCalCore::Incidence::TypeEvent) {
@@ -326,9 +401,9 @@ ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
"organizer of this task?") :
i18n("Do you want to send a status update to the "
"organizer of this journal?");
-
- const int messageBoxReturnCode = askUserIfNeeded(question, false, KGuiItem(i18n("Send Update")));
- return sentInvitation(messageBoxReturnCode, incidence, method);
+ askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Organizer, question, mDefaultAction,
+ KGuiItem(i18nc("@action:button dialog positive answer","Send Update")));
+ return;
} else if (incidence->type() == KCalCore::Incidence::TypeEvent) {
const QStringList myEmails = Akonadi::CalendarUtils::allEmails();
@@ -347,17 +422,29 @@ ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
QString question = i18n("You had previously accepted an invitation to this event. "
"Do you want to send an updated response to the organizer "
"declining the invitation?");
- int messageBoxReturnCode = askUserIfNeeded(question, false, KGuiItem(i18n("Send Update")));
- return sentInvitation(messageBoxReturnCode, incidence, method);
+ askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Organizer, question, mDefaultAction,
+ KGuiItem(i18nc("@action:button dialog positive answer","Send Update")));
+ return;
} else {
// We did not accept the event before and delete it from our calendar agian,
// so there is no need to notify people.
- return ITIPHandlerHelper::ResultNoSendingNeeded;
+ emit sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
+ delete askDelegator;
+ return;
}
}
Q_ASSERT(false); // Shouldn't happen.
- return ResultNoSendingNeeded;
+ emit sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
+ emit finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
+ delete askDelegator;
+}
+
+void ITIPHandlerHelper::slotIncidenceDeletedDialogClosed(const int messageBoxReturnCode, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence)
+{
+ ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method);
+ emit sendIncidenceDeletedMessageFinished(status, method, incidence);
}
ITIPHandlerHelper::SendResult
@@ -391,12 +478,13 @@ void ITIPHandlerHelper::onSchedulerFinished(Akonadi::Scheduler::Result result,
m_status = StatusNone;
if (!success) {
const QString question(i18n("Sending group scheduling email failed."));
- const int code = askUserIfNeeded(question, true, KGuiItem(i18n("Abort Update")));
- if (code == KMessageBox::Yes) {
- emit finished(ResultFailAbortUpdate, QString());
- } else {
- emit finished(ResultFailKeepUpdate, QString());
- }
+
+ ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(KCalCore::Incidence::Ptr(), KCalCore::iTIPNoMethod, mParent);
+
+ connect(askDelegator, SIGNAL(dialogClosed(int,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)),
+ SLOT(slotSchedulerFinishDialog(int,KCalCore::iTIPMethod,KCalCore::Incidence::Ptr)));
+ askDelegator->openDialogSchedulerFinished(question, ITIPHandlerDialogDelegate::ActionAsk,
+ KGuiItem(i18nc("@action:button dialog positive answer to abort question","Abort Update")));
return;
} else {
//fall through
@@ -407,3 +495,14 @@ void ITIPHandlerHelper::onSchedulerFinished(Akonadi::Scheduler::Result result,
success ? QString() : i18n("Error: %1", errorMsg));
}
+void ITIPHandlerHelper::slotSchedulerFinishDialog(const int result, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence)
+{
+ Q_UNUSED(method);
+ Q_UNUSED(incidence);
+ if (result == KMessageBox::Yes) {
+ emit finished(ResultFailAbortUpdate, QString());
+ } else {
+ emit finished(ResultFailKeepUpdate, QString());
+ }
+}
+
diff --git a/akonadi/calendar/itiphandlerhelper_p.h b/akonadi/calendar/itiphandlerhelper_p.h
index 6b8ee6d..152f46c 100644
--- a/akonadi/calendar/itiphandlerhelper_p.h
+++ b/akonadi/calendar/itiphandlerhelper_p.h
@@ -78,14 +78,10 @@ public:
ResultNoSendingNeeded, /**< In some cases it is not needed to send an invitation
(e.g. when we are the only attendee) */
ResultError, /**< An unexpected error occurred */
- ResultSuccess /**< The invitation was sent to all attendees. */
+ ResultSuccess, /**< The invitation was sent to all attendees. */
+ ResultPending /**< The user has been asked about one detail, waiting for him to anwser it */
};
- enum Action {
- ActionAsk,
- ActionSendMessage,
- ActionDontSendMessage
- };
/**
When an Incidence is created/modified/deleted the user can choose to send
@@ -96,7 +92,7 @@ public:
sendIncidence*Message() methods.
@param action the action to set as default
*/
- void setDefaultAction(Action action);
+ void setDefaultAction(ITIPHandlerDialogDelegate::Action action);
/**
Before an invitation is sent the user is asked for confirmation by means of
@@ -111,7 +107,7 @@ public:
Kontact/PIM) are the organizer.
@param incidence The new incidence.
*/
- ITIPHandlerHelper::SendResult sendIncidenceCreatedMessage(KCalCore::iTIPMethod method,
+ void sendIncidenceCreatedMessage(KCalCore::iTIPMethod method,
const KCalCore::Incidence::Ptr &incidence);
/**
@@ -131,7 +127,7 @@ public:
@param incidence The modified incidence.
@param attendeeStatusChanged if @c true and @p method is #iTIPRequest ask the user whether to send a status update as well
*/
- ITIPHandlerHelper::SendResult sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
+ void sendIncidenceModifiedMessage(KCalCore::iTIPMethod method,
const KCalCore::Incidence::Ptr &incidence,
bool attendeeStatusChanged);
@@ -139,7 +135,7 @@ public:
Handles sending of ivitations for deleted incidences.
@param incidence The deleted incidence.
*/
- ITIPHandlerHelper::SendResult sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
+ void sendIncidenceDeletedMessage(KCalCore::iTIPMethod method,
const KCalCore::Incidence::Ptr &incidence);
/**
@@ -157,19 +153,24 @@ Q_SIGNALS:
void finished(Akonadi::ITIPHandlerHelper::SendResult result,
const QString &errorMessage);
+ void sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::SendResult, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+ void sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::SendResult, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+ void sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::SendResult, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+
private Q_SLOTS:
void onSchedulerFinished(Akonadi::Scheduler::Result result, const QString &errorMsg);
+ void slotIncidenceDeletedDialogClosed(const int, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+ void slotIncidenceModifiedDialogClosed(const int, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+ void slotIncidenceCreatedDialogClosed(const int, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+
+ void slotSchedulerFinishDialog(const int result, KCalCore::iTIPMethod method, const KCalCore::Incidence::Ptr &incidence);
+
private:
ITIPHandlerHelper::SendResult sentInvitation(int messageBoxReturnCode,
const KCalCore::Incidence::Ptr &incidence,
KCalCore::iTIPMethod method);
- int askUserIfNeeded(const QString &question,
- bool ignoreDefaultAction = true,
- const KGuiItem &buttonYes = KGuiItem(i18n("Send Email")),
- const KGuiItem &buttonNo = KGuiItem(i18n("Do Not Send"))) const;
-
/**
We are the organizer. If there is more than one attendee, or if there is
only one, and it's not the same as the organizer, ask the user to send
@@ -184,8 +185,9 @@ private:
*/
bool weNeedToSendMailFor(const KCalCore::Incidence::Ptr &incidence);
- ITIPHandlerHelper::Action mDefaultAction;
+ ITIPHandlerDialogDelegate::Action mDefaultAction;
QWidget *mParent;
+ ITIPHandlerComponentFactory *m_factory;
MailScheduler *m_scheduler;
Status m_status;
};
commit eafe617ed73a296e55a94e9b84de7975ea98f48a
Author: Sandro Knauà <knauss at kolabsys.com>
Date: Tue Jul 1 16:36:02 2014 +0200
Make MailClient interceptable
REVIEW: 119432
diff --git a/akonadi/calendar/freebusymanager.cpp b/akonadi/calendar/freebusymanager.cpp
index bf64dab..28359ac 100644
--- a/akonadi/calendar/freebusymanager.cpp
+++ b/akonadi/calendar/freebusymanager.cpp
@@ -913,7 +913,7 @@ void FreeBusyManager::mailFreeBusy(int daysToPublish, QWidget *parentWidget)
QPointer<PublishDialog> publishdlg = new PublishDialog();
if (publishdlg->exec() == QDialog::Accepted) {
// Send the mail
- MailScheduler *scheduler = new MailScheduler();
+ MailScheduler *scheduler = new MailScheduler(/*factory=*/0, this);
connect(scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString))
, d, SLOT(processMailSchedulerResult(Akonadi::Scheduler::Result,QString)));
d->mParentWidgetForMailling = parentWidget;
diff --git a/akonadi/calendar/incidencechanger.cpp b/akonadi/calendar/incidencechanger.cpp
index aafa8d5..79d0f49 100644
--- a/akonadi/calendar/incidencechanger.cpp
+++ b/akonadi/calendar/incidencechanger.cpp
@@ -132,10 +132,11 @@ ConflictPreventer* ConflictPreventer::self()
return &sConflictPreventerPrivate->instance;
}
-IncidenceChanger::Private::Private(bool enableHistory, IncidenceChanger *qq) : q(qq)
+IncidenceChanger::Private::Private(bool enableHistory, ITIPHandlerComponentFactory *factory, IncidenceChanger *qq) : q(qq)
{
mLatestChangeId = 0;
mShowDialogsOnError = true;
+ mFactory = factory ? factory : new ITIPHandlerComponentFactory(this);
mHistory = enableHistory ? new History(this) : 0;
mUseHistory = enableHistory;
mDestinationPolicy = DestinationPolicyDefault;
@@ -423,7 +424,7 @@ bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr
{
bool result = true;
if (mGroupwareCommunication) {
- ITIPHandlerHelper handler(change->parentWidget); // TODO make async
+ ITIPHandlerHelper handler(mFactory, change->parentWidget); // TODO make async
if (m_invitationPolicy == InvitationPolicySend) {
handler.setDefaultAction(ITIPHandlerHelper::ActionSendMessage);
@@ -510,7 +511,7 @@ bool IncidenceChanger::Private::handleInvitationsBeforeChange(const Change::Ptr
bool IncidenceChanger::Private::handleInvitationsAfterChange(const Change::Ptr &change)
{
if (change->useGroupwareCommunication) {
- ITIPHandlerHelper handler(change->parentWidget); // TODO make async
+ ITIPHandlerHelper handler(mFactory, change->parentWidget); // TODO make async
const bool alwaysSend = m_invitationPolicy == InvitationPolicySend;
const bool neverSend = m_invitationPolicy == InvitationPolicyDontSend;
@@ -571,7 +572,7 @@ bool IncidenceChanger::Private::handleInvitationsAfterChange(const Change::Ptr &
}
if (notifyOrganizer) {
- MailScheduler scheduler; // TODO make async
+ MailScheduler scheduler(mFactory, change->parentWidget); // TODO make async
scheduler.performTransaction(incidence, KCalCore::iTIPReply);
}
}
@@ -633,12 +634,18 @@ bool IncidenceChanger::Private::myAttendeeStatusChanged(const Incidence::Ptr &ne
}
IncidenceChanger::IncidenceChanger(QObject *parent) : QObject(parent)
- , d(new Private(/**history=*/true, this))
+ , d(new Private(/**history=*/true, /*factory=*/0, this))
+{
+}
+
+
+IncidenceChanger::IncidenceChanger(ITIPHandlerComponentFactory *factory, QObject *parent) : QObject(parent)
+ , d(new Private(/**history=*/true, factory, this))
{
}
IncidenceChanger::IncidenceChanger(bool enableHistory, QObject *parent) : QObject(parent)
- , d(new Private(enableHistory, this))
+ , d(new Private(enableHistory, /*factory=*/0, this))
{
}
@@ -1030,7 +1037,7 @@ void IncidenceChanger::setHistoryEnabled(bool enable)
if (d->mUseHistory != enable) {
d->mUseHistory = enable;
if (enable && !d->mHistory)
- d->mHistory = new History(this);
+ d->mHistory = new History(d);
}
}
diff --git a/akonadi/calendar/incidencechanger.h b/akonadi/calendar/incidencechanger.h
index 858e487..da1a8e7 100644
--- a/akonadi/calendar/incidencechanger.h
+++ b/akonadi/calendar/incidencechanger.h
@@ -22,6 +22,8 @@
#include "akonadi-calendar_export.h"
+#include "itiphandler.h"
+
#include <akonadi/item.h>
#include <akonadi/collection.h>
#include <kcalcore/incidence.h>
@@ -134,11 +136,21 @@ public:
/**
* Creates a new IncidenceChanger instance.
+ * creates a default ITIPHandlerComponentFactory object.
* @param parent parent QObject
*/
explicit IncidenceChanger(QObject *parent = 0);
/**
+ * Creates a new IncidenceChanger instance.
+ * @param factory factory for creating dialogs and the mail transport job. To create a default
+ * factory set factory == 0
+ * @param parent parent QObject
+ * @since 4.15
+ */
+ explicit IncidenceChanger(ITIPHandlerComponentFactory *factory, QObject *parent);
+
+ /**
* Destroys this IncidenceChanger instance.
*/
~IncidenceChanger();
diff --git a/akonadi/calendar/incidencechanger_p.h b/akonadi/calendar/incidencechanger_p.h
index 82bdfa1..eb08eb1 100644
--- a/akonadi/calendar/incidencechanger_p.h
+++ b/akonadi/calendar/incidencechanger_p.h
@@ -250,7 +250,7 @@ class IncidenceChanger::Private : public QObject
{
Q_OBJECT
public:
- explicit Private(bool enableHistory, IncidenceChanger *mIncidenceChanger);
+ explicit Private(bool enableHistory, ITIPHandlerComponentFactory *factory, IncidenceChanger *mIncidenceChanger);
~Private();
void loadCollections(); // async-loading of list of writable collections
@@ -350,6 +350,7 @@ public:
IncidenceChanger::InvitationPolicy m_invitationPolicy;
+ ITIPHandlerComponentFactory *mFactory;
private:
IncidenceChanger *q;
};
diff --git a/akonadi/calendar/itiphandler.cpp b/akonadi/calendar/itiphandler.cpp
index 2b72199..a4bc9f1 100644
--- a/akonadi/calendar/itiphandler.cpp
+++ b/akonadi/calendar/itiphandler.cpp
@@ -38,6 +38,7 @@
#include <kcalutils/stringify.h>
#include <kpimidentities/identitymanager.h>
+#include <mailtransport/messagequeuejob.h>
#include <mailtransport/transportmanager.h>
#include <KMessageBox>
@@ -59,8 +60,31 @@ GroupwareUiDelegate::~GroupwareUiDelegate()
{
}
+ITIPHandlerComponentFactory::ITIPHandlerComponentFactory(QObject *parent)
+ : QObject(parent)
+{
+}
+
+ITIPHandlerComponentFactory::~ITIPHandlerComponentFactory()
+{
+}
+
+MailTransport::MessageQueueJob *ITIPHandlerComponentFactory::createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity, QObject *parent)
+{
+ Q_UNUSED(incidence);
+ Q_UNUSED(identity);
+ return new MailTransport::MessageQueueJob(parent);
+}
+
ITIPHandler::ITIPHandler(QObject *parent) : QObject(parent)
- , d(new Private(this))
+ , d(new Private(/*factory=*/0, this))
+{
+ qRegisterMetaType<Akonadi::ITIPHandler::Result>("Akonadi::ITIPHandler::Result");
+}
+
+
+ITIPHandler::ITIPHandler(ITIPHandlerComponentFactory *factory, QObject *parent) : QObject(parent)
+ , d(new Private(factory, this))
{
qRegisterMetaType<Akonadi::ITIPHandler::Result>("Akonadi::ITIPHandler::Result");
}
@@ -347,7 +371,7 @@ void ITIPHandler::sendAsICalendar(const KCalCore::Incidence::Ptr &originalIncide
const QString from = Akonadi::CalendarUtils::email();
const bool bccMe = Akonadi::CalendarSettings::self()->bcc();
const QString messageText = format.createScheduleMessage(incidence, KCalCore::iTIPRequest);
- MailClient *mailer = new MailClient();
+ MailClient *mailer = new MailClient(d->m_factory);
d->m_queuedInvitation.incidence = incidence;
connect(mailer, SIGNAL(finished(Akonadi::MailClient::Result,QString)),
d, SLOT(finishSendAsICalendar(Akonadi::MailScheduler::Result,QString)));
diff --git a/akonadi/calendar/itiphandler.h b/akonadi/calendar/itiphandler.h
index 5c581e7..dcbc6b6 100644
--- a/akonadi/calendar/itiphandler.h
+++ b/akonadi/calendar/itiphandler.h
@@ -35,6 +35,14 @@
#include <QString>
#include <QWidget>
+namespace MailTransport {
+ class MessageQueueJob;
+}
+
+namespace KPIMIdentities {
+ class Identity;
+}
+
namespace Akonadi {
/**
@@ -52,6 +60,33 @@ public:
};
/**
+ * @short Factory to create MailTransport::MessageQueueJob jobs.
+ * @since 4.15
+ */
+class AKONADI_CALENDAR_EXPORT ITIPHandlerComponentFactory : public QObject
+{
+ Q_OBJECT
+public:
+ /*
+ * Created a new ITIPHandlerComponentFactory object.
+ */
+ explicit ITIPHandlerComponentFactory(QObject *parent = 0);
+
+ /*
+ * deletes the object.
+ */
+ virtual ~ITIPHandlerComponentFactory();
+
+ /*
+ * @return A new MailTransport::MessageQueueJob object
+ * @param incidence related to the mail
+ * @param identity that is the mail sender
+ * @param parent of the MailTransport::MessageQueueJob object
+ */
+ virtual MailTransport::MessageQueueJob* createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity, QObject *parent = 0);
+};
+
+/**
* @short Handles sending of iTip messages aswell as processing incoming ones.
* @since 4.11
*/
@@ -67,10 +102,17 @@ public:
/**
* Creates a new ITIPHandler instance.
+ * creates a default ITIPHandlerComponentFactory object.
*/
explicit ITIPHandler(QObject *parent = 0);
/**
+ * Create a new ITIPHandler instance.
+ * @param factory is set to 0 a new factory is created.
+ * @since 4.15
+ */
+ explicit ITIPHandler(ITIPHandlerComponentFactory *factory, QObject *parent);
+ /**
* Destroys this instance.
*/
~ITIPHandler();
diff --git a/akonadi/calendar/itiphandler_p.cpp b/akonadi/calendar/itiphandler_p.cpp
index e62b72b..db1de2f 100644
--- a/akonadi/calendar/itiphandler_p.cpp
+++ b/akonadi/calendar/itiphandler_p.cpp
@@ -25,15 +25,17 @@
using namespace Akonadi;
-ITIPHandler::Private::Private(ITIPHandler *qq) : m_calendarLoadError(false)
- , m_scheduler(new MailScheduler(qq))
+ITIPHandler::Private::Private(ITIPHandlerComponentFactory *factory, ITIPHandler *qq) : m_calendarLoadError(false)
+ , m_factory(factory ? factory : new ITIPHandlerComponentFactory(this))
+ , m_scheduler(new MailScheduler(m_factory, qq))
, m_method(KCalCore::iTIPNoMethod)
- , m_helper(new ITIPHandlerHelper()) //TODO parent
+ , m_helper(new ITIPHandlerHelper(m_factory))
, m_currentOperation(OperationNone)
, m_uiDelegate(0)
, m_showDialogsOnError(true)
, q(qq)
{
+ m_helper->setParent(this);
connect(m_scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString)),
SLOT(onSchedulerFinished(Akonadi::Scheduler::Result,QString)));
diff --git a/akonadi/calendar/itiphandler_p.h b/akonadi/calendar/itiphandler_p.h
index 35e895a..63040b2 100644
--- a/akonadi/calendar/itiphandler_p.h
+++ b/akonadi/calendar/itiphandler_p.h
@@ -58,7 +58,7 @@ class ITIPHandler::Private : public QObject
{
Q_OBJECT
public:
- Private(ITIPHandler *q);
+ Private(ITIPHandlerComponentFactory *factory, ITIPHandler *q);
void finishProcessiTIPMessage(Akonadi::MailScheduler::Result, const QString &errorMessage);
void finishSendiTIPMessage(Akonadi::MailScheduler::Result, const QString &errorMessage);
@@ -74,6 +74,7 @@ public:
Invitation m_queuedInvitation;
bool m_calendarLoadError;
CalendarBase::Ptr m_calendar;
+ ITIPHandlerComponentFactory *m_factory;
MailScheduler *m_scheduler;
KCalCore::Incidence::Ptr m_incidence;
KCalCore::iTIPMethod m_method; // METHOD field of ical rfc of incoming invitation
diff --git a/akonadi/calendar/itiphandlerhelper_p.cpp b/akonadi/calendar/itiphandlerhelper_p.cpp
index 6eaf5f5..d72e89a 100644
--- a/akonadi/calendar/itiphandlerhelper_p.cpp
+++ b/akonadi/calendar/itiphandlerhelper_p.cpp
@@ -148,10 +148,10 @@ bool ITIPHandlerHelper::weNeedToSendMailFor(const KCalCore::Incidence::Ptr &inci
incidence->attendees().first()->email() != incidence->organizer()->email();
}
-ITIPHandlerHelper::ITIPHandlerHelper(QWidget *parent)
+ITIPHandlerHelper::ITIPHandlerHelper(ITIPHandlerComponentFactory *factory, QWidget *parent)
: mDefaultAction(ITIPHandlerHelper::ActionAsk)
, mParent(parent)
- , m_scheduler(new MailScheduler(parent))
+ , m_scheduler(new MailScheduler(factory, parent))
, m_status(StatusNone)
{
connect(m_scheduler, SIGNAL(transactionFinished(Akonadi::Scheduler::Result,QString)),
diff --git a/akonadi/calendar/itiphandlerhelper_p.h b/akonadi/calendar/itiphandlerhelper_p.h
index 11bc6de..6b8ee6d 100644
--- a/akonadi/calendar/itiphandlerhelper_p.h
+++ b/akonadi/calendar/itiphandlerhelper_p.h
@@ -67,7 +67,7 @@ class ITIPHandlerHelper : public QObject
{
Q_OBJECT
public:
- explicit ITIPHandlerHelper(QWidget *parent = 0); // TODO
+ explicit ITIPHandlerHelper(ITIPHandlerComponentFactory *factory, QWidget *parent = 0);
~ITIPHandlerHelper();
enum SendResult {
diff --git a/akonadi/calendar/mailclient_p.cpp b/akonadi/calendar/mailclient_p.cpp
index 94accce..fc8466f 100644
--- a/akonadi/calendar/mailclient_p.cpp
+++ b/akonadi/calendar/mailclient_p.cpp
@@ -45,10 +45,9 @@
using namespace Akonadi;
-bool Akonadi::MailClient::sRunningUnitTests = false;
-UnitTestResult::List MailClient::sUnitTestResults;
-MailClient::MailClient(QObject *parent) : QObject(parent)
+MailClient::MailClient(ITIPHandlerComponentFactory *factory, QObject *parent) : QObject(parent)
+ , mFactory(factory ? factory : new ITIPHandlerComponentFactory(this))
{
}
@@ -132,7 +131,7 @@ void MailClient::mailAttendees(const KCalCore::IncidenceBase::Ptr &incidence,
const QString body = KCalUtils::IncidenceFormatter::mailBodyStr(incidence,
KSystemTimeZones::local());
- send(identity, from, to, cc, subject, body, false, bccMe, attachment, mailTransport);
+ send(incidence, identity, from, to, cc, subject, body, false, bccMe, attachment, mailTransport);
}
void MailClient::mailOrganizer(const KCalCore::IncidenceBase::Ptr &incidence,
@@ -156,7 +155,7 @@ void MailClient::mailOrganizer(const KCalCore::IncidenceBase::Ptr &incidence,
const QString body = KCalUtils::IncidenceFormatter::mailBodyStr(incidence,
KSystemTimeZones::local());
- send(identity, from, to, QString(), subject, body, false, bccMe, attachment, mailTransport);
+ send(incidence, identity, from, to, QString(), subject, body, false, bccMe, attachment, mailTransport);
}
void MailClient::mailTo(const KCalCore::IncidenceBase::Ptr &incidence,
@@ -177,7 +176,7 @@ void MailClient::mailTo(const KCalCore::IncidenceBase::Ptr &incidence,
const QString body = KCalUtils::IncidenceFormatter::mailBodyStr(incidence,
KSystemTimeZones::local());
- send(identity, from, recipients, QString(), subject, body, false,
+ send(incidence, identity, from, recipients, QString(), subject, body, false,
bccMe, attachment, mailTransport);
}
@@ -192,13 +191,13 @@ static QStringList extractEmailAndNormalize(const QString &email)
return normalizedEmail;
}
-void MailClient::send(const KPIMIdentities::Identity &identity,
+void MailClient::send(const KCalCore::IncidenceBase::Ptr &incidence,
+ const KPIMIdentities::Identity &identity,
const QString &from, const QString &_to,
const QString &cc, const QString &subject,
const QString &body, bool hidden, bool bccMe,
const QString &attachment, const QString &mailTransport)
{
- Q_UNUSED(identity);
Q_UNUSED(hidden);
UnitTestResult unitTestResult;
@@ -223,9 +222,6 @@ void MailClient::send(const KPIMIdentities::Identity &identity,
<< "\nAttachment:\n" << attachment
<< "\nmailTransport: " << mailTransport;
- QTime timer;
- timer.start();
-
MailTransport::Transport *transport =
MailTransport::TransportManager::self()->transportByName(mailTransport);
@@ -335,7 +331,7 @@ void MailClient::send(const KPIMIdentities::Identity &identity,
message->assemble();
// Put the newly created item in the MessageQueueJob.
- MailTransport::MessageQueueJob *qjob = new MailTransport::MessageQueueJob(this);
+ MailTransport::MessageQueueJob *qjob = mFactory->createMessageQueueJob(incidence, identity, this);
qjob->transportAttribute().setTransportId(transportId);
qjob->sentBehaviourAttribute().setSentBehaviour(
MailTransport::SentBehaviourAttribute::MoveToDefaultSentCollection);
@@ -367,25 +363,9 @@ void MailClient::send(const KPIMIdentities::Identity &identity,
qjob->addressAttribute().setBcc(bccStringList);
}
- if (sRunningUnitTests) {
- unitTestResult.message = message;
- unitTestResult.from = finalFrom;
- unitTestResult.to = toStringList;
- unitTestResult.cc = ccStringList;
- unitTestResult.bcc = bccStringList;
- unitTestResult.transportId = transportId;
- sUnitTestResults << unitTestResult;
- qjob->deleteLater();
-
- QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection,
- Q_ARG(Akonadi::MailClient::Result, ResultSuccess),
- Q_ARG(QString, QString()));
-
- } else {
- qjob->setMessage(message);
- connect(qjob, SIGNAL(finished(KJob*)), SLOT(handleQueueJobFinished(KJob*)));
- qjob->start();
- }
+ qjob->setMessage(message);
+ connect(qjob, SIGNAL(finished(KJob*)), SLOT(handleQueueJobFinished(KJob*)));
+ qjob->start();
}
void MailClient::handleQueueJobFinished(KJob *job)
@@ -395,7 +375,6 @@ void MailClient::handleQueueJobFinished(KJob *job)
emit finished(ResultQueueJobError, i18n("Error queuing message in outbox: %1",
job->errorText()));
} else {
- kDebug() << "Mail queued";
emit finished(ResultSuccess, QString());
}
}
diff --git a/akonadi/calendar/mailclient_p.h b/akonadi/calendar/mailclient_p.h
index c284806..702a0e0 100644
--- a/akonadi/calendar/mailclient_p.h
+++ b/akonadi/calendar/mailclient_p.h
@@ -23,6 +23,7 @@
#define AKONADI_MAILCLIENT_P_H
#include "akonadi-calendar_export.h"
+#include "itiphandler.h"
#include <kcalcore/incidencebase.h>
#include <kmime/kmime_message.h>
#include <QObject>
@@ -45,19 +46,19 @@ class Identity;
class KJob;
namespace Akonadi {
-
#ifdef PLEASE_TEST_INVITATIONS
#define EXPORT_MAILCLIENT AKONADI_CALENDAR_EXPORT
#else
#define EXPORT_MAILCLIENT
#endif
+class ITIPHandlerComponentFactory;
+
class EXPORT_MAILCLIENT MailClient : public QObject
{
Q_OBJECT
public:
-
enum Result {
ResultSuccess,
ResultNoAttendees,
@@ -67,29 +68,30 @@ public:
ResultQueueJobError
};
- explicit MailClient(QObject *parent = 0);
+ explicit MailClient(ITIPHandlerComponentFactory *factory, QObject *parent = 0);
~MailClient();
- void mailAttendees(const KCalCore::IncidenceBase::Ptr &,
+ void mailAttendees(const KCalCore::IncidenceBase::Ptr &incidence,
const KPIMIdentities::Identity &identity,
bool bccMe, const QString &attachment=QString(),
const QString &mailTransport = QString());
- void mailOrganizer(const KCalCore::IncidenceBase::Ptr &,
+ void mailOrganizer(const KCalCore::IncidenceBase::Ptr &incidence,
const KPIMIdentities::Identity &identity,
const QString &from, bool bccMe,
const QString &attachment=QString(),
const QString &sub=QString(),
const QString &mailTransport = QString());
- void mailTo(const KCalCore::IncidenceBase::Ptr &, const KPIMIdentities::Identity &identity,
+ void mailTo(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity,
const QString &from, bool bccMe, const QString &recipients,
- const QString &attachment=QString(), const QString &mailTransport = QString());
+ const QString &attachment = QString(), const QString &mailTransport = QString());
/**
Sends mail with specified from, to and subject field and body as text.
If bcc is set, send a blind carbon copy to the sender
+ @param incidence is the incidence, that is sended
@param identity is the Identity of the sender
@param from is the address of the sender of the message
@param to a list of addresses to receive the message
@@ -103,7 +105,7 @@ public:
@param mailTransport defines the mail transport method. See here the
kdepimlibs/mailtransport library.
*/
- void send(const KPIMIdentities::Identity &identity, const QString &from, const QString &to,
+ void send(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity, const QString &from, const QString &to,
const QString &cc, const QString &subject, const QString &body,
bool hidden=false, bool bccMe=false, const QString &attachment=QString(),
const QString &mailTransport = QString());
@@ -116,12 +118,11 @@ Q_SIGNALS:
public:
// For unit-test usage, since we can't depend on kdepim-runtime on jenkins
- static UnitTestResult::List sUnitTestResults;
- static bool sRunningUnitTests;
+ ITIPHandlerComponentFactory *mFactory;
};
}
Q_DECLARE_METATYPE(Akonadi::MailClient::Result)
-#endif
+#endif
\ No newline at end of file
diff --git a/akonadi/calendar/mailscheduler_p.cpp b/akonadi/calendar/mailscheduler_p.cpp
index cfeebd0..907a11a 100644
--- a/akonadi/calendar/mailscheduler_p.cpp
+++ b/akonadi/calendar/mailscheduler_p.cpp
@@ -44,12 +44,12 @@ public:
MailClient *m_mailer;
};
-MailScheduler::MailScheduler(QObject *parent) : Scheduler(parent)
+MailScheduler::MailScheduler(ITIPHandlerComponentFactory *factory, QObject *parent) : Scheduler(parent)
, d(new Private())
-
{
d->m_identityManager = new IdentityManager(/*ro=*/true, this);
- d->m_mailer = new MailClient();
+ d->m_mailer = new MailClient(factory, parent);
+
connect(d->m_mailer, SIGNAL(finished(Akonadi::MailClient::Result,QString)),
SLOT(onMailerFinished(Akonadi::MailClient::Result,QString)));
}
diff --git a/akonadi/calendar/mailscheduler_p.h b/akonadi/calendar/mailscheduler_p.h
index cdbdd87..58c8c4f 100644
--- a/akonadi/calendar/mailscheduler_p.h
+++ b/akonadi/calendar/mailscheduler_p.h
@@ -47,7 +47,7 @@ public:
/**
* @param calendar Must be a valid and loaded calendar.
*/
- explicit MailScheduler(QObject *parent = 0);
+ explicit MailScheduler(ITIPHandlerComponentFactory *factory, QObject *parent = 0);
~MailScheduler();
/** reimp */
@@ -63,6 +63,7 @@ public:
KCalCore::iTIPMethod method,
const QString &recipients);
+
/** Returns the directory where the free-busy information is stored */
/** reimp*/ QString freeBusyDir() const;
diff --git a/akonadi/calendar/tests/itiphandlertest.cpp b/akonadi/calendar/tests/itiphandlertest.cpp
index f1167e1..92c9e37 100644
--- a/akonadi/calendar/tests/itiphandlertest.cpp
+++ b/akonadi/calendar/tests/itiphandlertest.cpp
@@ -30,6 +30,7 @@
#include <akonadi/collectionfetchscope.h>
#include <akonadi/itemfetchscope.h>
#include <akonadi/qtest_akonadi.h>
+#include <mailtransport/messagequeuejob.h>
#include <kcalcore/event.h>
@@ -47,15 +48,61 @@ Q_DECLARE_METATYPE(QList<int>)
static const char *s_ourEmail = "unittests at dev.nul"; // change also in kdepimlibs/akonadi/calendar/tests/unittestenv/kdehome/share/config
static const char *s_outEmail2 = "identity2 at kde.org";
+class FakeMessageQueueJob : public MailTransport::MessageQueueJob
+{
+public:
+ explicit FakeMessageQueueJob(QObject *parent = 0) : MailTransport::MessageQueueJob(parent)
+ {
+ }
+
+ virtual void start()
+ {
+ UnitTestResult unitTestResult;
+ unitTestResult.message = message();
+ unitTestResult.from = addressAttribute().from();
+ unitTestResult.to = addressAttribute().to();
+ unitTestResult.cc = addressAttribute().cc();
+ unitTestResult.bcc = addressAttribute().bcc();
+ unitTestResult.transportId = transportAttribute().transportId();
+ FakeMessageQueueJob::sUnitTestResults << unitTestResult;
+
+ setError(Akonadi::MailClient::ResultSuccess);
+ setErrorText(QString());
+
+ emitResult();
+ }
+
+ static UnitTestResult::List sUnitTestResults;
+};
+
+
+UnitTestResult::List FakeMessageQueueJob::sUnitTestResults;
+
+class FakeITIPHandlerComponentFactory : public ITIPHandlerComponentFactory
+{
+public:
+ FakeITIPHandlerComponentFactory(QObject *parent = 0) : ITIPHandlerComponentFactory(parent)
+ {
+ }
+
+ virtual MailTransport::MessageQueueJob *createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity, QObject *parent = 0)
+ {
+ Q_UNUSED(incidence);
+ Q_UNUSED(identity);
+ return new FakeMessageQueueJob(parent);
+ }
+};
+
+
+
void ITIPHandlerTest::initTestCase()
{
AkonadiTest::checkTestIsIsolated();
m_pendingItipMessageSignal = 0;
m_pendingIncidenceChangerSignal = 0;
- MailClient::sRunningUnitTests = true;
m_itipHandler = 0;
m_cancelExpected = false;
- m_changer = new IncidenceChanger(this);
+ m_changer = new IncidenceChanger(new FakeITIPHandlerComponentFactory(this), this);
m_changer->setHistoryEnabled(false);
m_changer->setGroupwareCommunication(true);
m_changer->setInvitationPolicy(IncidenceChanger::InvitationPolicySend); // don't show dialogs
@@ -190,7 +237,7 @@ void ITIPHandlerTest::testProcessITIPMessage()
QFETCH(int, expectedNumIncidences);
QFETCH(KCalCore::Attendee::PartStat, expectedPartStat);
- MailClient::sUnitTestResults.clear();
+ FakeMessageQueueJob::sUnitTestResults.clear();
createITIPHandler();
m_expectedResult = expectedResult;
@@ -262,7 +309,7 @@ void ITIPHandlerTest::testProcessITIPMessages()
const QString receiver = QLatin1String(s_ourEmail);
- MailClient::sUnitTestResults.clear();
+ FakeMessageQueueJob::sUnitTestResults.clear();
createITIPHandler();
m_expectedResult = Akonadi::ITIPHandler::ResultSuccess;
@@ -319,7 +366,7 @@ void ITIPHandlerTest::testProcessITIPMessageCancel()
QFETCH(QString, incidenceUid);
const QString receiver = QLatin1String(s_ourEmail);
- MailClient::sUnitTestResults.clear();
+ FakeMessageQueueJob::sUnitTestResults.clear();
createITIPHandler();
m_expectedResult = Akonadi::ITIPHandler::ResultSuccess;
@@ -476,7 +523,7 @@ void ITIPHandlerTest::testOutgoingInvitations()
KCalCore::Incidence::Ptr incidence = item.payload<KCalCore::Incidence::Ptr>();
m_pendingIncidenceChangerSignal = 1;
- MailClient::sUnitTestResults.clear();
+ FakeMessageQueueJob::sUnitTestResults.clear();
m_changer->setInvitationPolicy(invitationPolicy);
m_cancelExpected = userCancels;
@@ -485,7 +532,7 @@ void ITIPHandlerTest::testOutgoingInvitations()
case IncidenceChanger::ChangeTypeCreate:
m_changer->createIncidence(incidence, mCollection);
waitForIt();
- QCOMPARE(MailClient::sUnitTestResults.count(), expectedEmailCount);
+ QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), expectedEmailCount);
break;
case IncidenceChanger::ChangeTypeModify: {
// Create if first, so we have something to modify
@@ -493,7 +540,7 @@ void ITIPHandlerTest::testOutgoingInvitations()
m_changer->createIncidence(incidence, mCollection);
waitForIt();
m_changer->setGroupwareCommunication(true);
- QCOMPARE(MailClient::sUnitTestResults.count(), 0);
+ QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), 0);
QVERIFY(mLastInsertedItem.isValid());
m_pendingIncidenceChangerSignal = 1;
@@ -502,7 +549,7 @@ void ITIPHandlerTest::testOutgoingInvitations()
int changeId = m_changer->modifyIncidence(mLastInsertedItem, oldIncidence);
QVERIFY(changeId != 1);
waitForIt();
- QCOMPARE(MailClient::sUnitTestResults.count(), expectedEmailCount);
+ QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), expectedEmailCount);
}
break;
case IncidenceChanger::ChangeTypeDelete:
@@ -511,13 +558,13 @@ void ITIPHandlerTest::testOutgoingInvitations()
m_changer->createIncidence(incidence, mCollection);
waitForIt();
m_changer->setGroupwareCommunication(true);
- QCOMPARE(MailClient::sUnitTestResults.count(), 0);
+ QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), 0);
QVERIFY(mLastInsertedItem.isValid());
m_pendingIncidenceChangerSignal = 1;
m_changer->deleteIncidence(mLastInsertedItem);
waitForIt();
- QCOMPARE(MailClient::sUnitTestResults.count(), expectedEmailCount);
+ QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), expectedEmailCount);
break;
default:
Q_ASSERT(false);
@@ -571,7 +618,7 @@ void ITIPHandlerTest::cleanup()
void ITIPHandlerTest::createITIPHandler()
{
- m_itipHandler = new Akonadi::ITIPHandler();
+ m_itipHandler = new Akonadi::ITIPHandler(new FakeITIPHandlerComponentFactory(this), this);
m_itipHandler->setShowDialogsOnError(false);
connect(m_itipHandler, SIGNAL(iTipMessageProcessed(Akonadi::ITIPHandler::Result,QString)),
SLOT(oniTipMessageProcessed(Akonadi::ITIPHandler::Result,QString)));
@@ -594,7 +641,7 @@ void ITIPHandlerTest::processItip(const QString &icaldata, const QString &receiv
// 0 e-mails are sent because the status update e-mail is sent by
// kmail's text_calendar.cpp.
- QCOMPARE(MailClient::sUnitTestResults.count(), 0);
+ QCOMPARE(FakeMessageQueueJob::sUnitTestResults.count(), 0);
items = calendarItems();
@@ -676,7 +723,6 @@ void ITIPHandlerTest::onModifyFinished(int changeId, const Item &item,
if (m_pendingIncidenceChangerSignal == 0) {
stopWaiting();
}
- kDebug() << "Got result " << resultCode << m_cancelExpected;
QCOMPARE(resultCode, m_cancelExpected ? IncidenceChanger::ResultCodeUserCanceled
: IncidenceChanger::ResultCodeSuccess);
}
diff --git a/akonadi/calendar/tests/mailclienttest.cpp b/akonadi/calendar/tests/mailclienttest.cpp
index 8235b31..4417bfa 100644
--- a/akonadi/calendar/tests/mailclienttest.cpp
+++ b/akonadi/calendar/tests/mailclienttest.cpp
@@ -38,6 +38,50 @@ using namespace Akonadi;
Q_DECLARE_METATYPE(KPIMIdentities::Identity)
Q_DECLARE_METATYPE(KCalCore::Incidence::Ptr)
+class FakeMessageQueueJob : public MailTransport::MessageQueueJob
+{
+public:
+ explicit FakeMessageQueueJob(QObject *parent = 0) : MailTransport::MessageQueueJob(parent)
+ {
+ }
+
+ virtual void start()
+ {
+ UnitTestResult unitTestResult;
+ unitTestResult.message = message();
+ unitTestResult.from = addressAttribute().from();
+ unitTestResult.to = addressAttribute().to();
+ unitTestResult.cc = addressAttribute().cc();
+ unitTestResult.bcc = addressAttribute().bcc();
+ unitTestResult.transportId = transportAttribute().transportId();
+ FakeMessageQueueJob::sUnitTestResults << unitTestResult;
+
+ setError(Akonadi::MailClient::ResultSuccess);
+ setErrorText(QString());
+
+ emitResult();
+ }
+
+ static UnitTestResult::List sUnitTestResults;
+};
+
+UnitTestResult::List FakeMessageQueueJob::sUnitTestResults;
+
+class FakeITIPHandlerComponentFactory : public ITIPHandlerComponentFactory
+{
+public:
+ explicit FakeITIPHandlerComponentFactory(QObject *parent = 0) : ITIPHandlerComponentFactory(parent)
+ {
+ }
+
+ virtual MailTransport::MessageQueueJob *createMessageQueueJob(const KCalCore::IncidenceBase::Ptr &incidence, const KPIMIdentities::Identity &identity, QObject *parent = 0)
+ {
+ Q_UNUSED(incidence);
+ Q_UNUSED(identity);
+ return new FakeMessageQueueJob(parent);
+ }
+};
+
class MailClientTest : public QObject
{
Q_OBJECT
@@ -55,8 +99,7 @@ private Q_SLOTS:
AkonadiTest::checkTestIsIsolated();
mPendingSignals = 0;
- mMailClient = new MailClient(this);
- mMailClient->sRunningUnitTests = true;
+ mMailClient = new MailClient(new FakeITIPHandlerComponentFactory(this), this);
mLastResult = MailClient::ResultSuccess;
connect(mMailClient, SIGNAL(finished(Akonadi::MailClient::Result,QString)),
SLOT(handleFinished(Akonadi::MailClient::Result,QString)));
@@ -193,7 +236,8 @@ private Q_SLOTS:
QFETCH(QStringList, expectedToList);
QFETCH(QStringList, expectedCcList);
QFETCH(QStringList, expectedBccList);
- mMailClient->sUnitTestResults.clear();
+
+ FakeMessageQueueJob::sUnitTestResults.clear();
mPendingSignals = 1;
mMailClient->mailAttendees(incidence, identity, bccMe, attachment, transport);
@@ -206,10 +250,10 @@ private Q_SLOTS:
}
UnitTestResult unitTestResult;
- if (mMailClient->sUnitTestResults.isEmpty()) {
+ if (FakeMessageQueueJob::sUnitTestResults.isEmpty()) {
qDebug() << "mail results are empty";
} else {
- unitTestResult = mMailClient->sUnitTestResults.first();
+ unitTestResult = FakeMessageQueueJob::sUnitTestResults.first();
}
if (expectedTransportId != -1 && unitTestResult.transportId != expectedTransportId) {
@@ -287,14 +331,14 @@ private Q_SLOTS:
QFETCH(QStringList, expectedToList);
QFETCH(QStringList, expectedBccList);
QFETCH(QString, expectedSubject);
- mMailClient->sUnitTestResults.clear();
+ FakeMessageQueueJob::sUnitTestResults.clear();
mPendingSignals = 1;
mMailClient->mailOrganizer(incidence, identity, from, bccMe, attachment, subject, transport);
waitForSignals();
QCOMPARE(mLastResult, expectedResult);
- UnitTestResult unitTestResult = mMailClient->sUnitTestResults.first();
+ UnitTestResult unitTestResult = FakeMessageQueueJob::sUnitTestResults.first();
if (expectedTransportId != -1)
QCOMPARE(unitTestResult.transportId, expectedTransportId);
@@ -354,13 +398,13 @@ private Q_SLOTS:
QFETCH(QString, expectedFrom);
QFETCH(QStringList, expectedToList);
QFETCH(QStringList, expectedBccList);
- mMailClient->sUnitTestResults.clear();
+ FakeMessageQueueJob::sUnitTestResults.clear();
mPendingSignals = 1;
mMailClient->mailTo(incidence, identity, from, bccMe, recipients, attachment, transport);
waitForSignals();
QCOMPARE(mLastResult, expectedResult);
- UnitTestResult unitTestResult = mMailClient->sUnitTestResults.first();
+ UnitTestResult unitTestResult = FakeMessageQueueJob::sUnitTestResults.first();
if (expectedTransportId != -1)
QCOMPARE(unitTestResult.transportId, expectedTransportId);
More information about the commits
mailing list