1 /*
2 SPDX-FileCopyrightText: 2002-2004 Klarälvdalens Datakonsult AB,
3 <info@klaralvdalens-datakonsult.se>
4
5 SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org>
6 SPDX-FileCopyrightText: 2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9 */
10
11 #include "itiphandlerhelper_p.h"
12 #include "calendarsettings.h"
13 #include "utils_p.h"
14
15 #include "akonadicalendar_debug.h"
16 #include <KCalUtils/IncidenceFormatter>
17 #include <KCalUtils/Stringify>
18 #include <KCalendarCore/Calendar>
19 #include <KCalendarCore/ICalFormat>
20 #include <KLocalizedString>
21 #include <KMessageBox>
22
23 #include <QWidget>
24
25 using namespace Akonadi;
26
proposalComment(const KCalendarCore::Incidence::Ptr & incidence)27 QString proposalComment(const KCalendarCore::Incidence::Ptr &incidence)
28 {
29 QString comment;
30
31 // TODO: doesn't KCalUtils/IncidenceFormater already provide this?
32 // if not, it should go there.
33
34 switch (incidence->type()) {
35 case KCalendarCore::IncidenceBase::TypeEvent: {
36 const QDateTime dtEnd = incidence->dateTime(KCalendarCore::Incidence::RoleDisplayEnd);
37 comment = i18n("Proposed new meeting time: %1 - %2",
38 KCalUtils::IncidenceFormatter::dateToString(incidence->dtStart().toLocalTime().date()),
39 KCalUtils::IncidenceFormatter::dateToString(dtEnd.toLocalTime().date()));
40 break;
41 }
42 case KCalendarCore::IncidenceBase::TypeTodo:
43 qCWarning(AKONADICALENDAR_LOG) << "NOT IMPLEMENTED: proposalComment called for to-do.";
44 break;
45 default:
46 qCWarning(AKONADICALENDAR_LOG) << "NOT IMPLEMENTED: proposalComment called for " << incidence->typeStr();
47 }
48
49 return comment;
50 }
51
ITIPHandlerDialogDelegate(const KCalendarCore::Incidence::Ptr & incidence,KCalendarCore::iTIPMethod method,QWidget * parent)52 ITIPHandlerDialogDelegate::ITIPHandlerDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent)
53 : mParent(parent)
54 , mIncidence(incidence)
55 , mMethod(method)
56 {
57 }
58
askUserIfNeeded(const QString & question,Action action,const KGuiItem & buttonYes,const KGuiItem & buttonNo) const59 int ITIPHandlerDialogDelegate::askUserIfNeeded(const QString &question, Action action, const KGuiItem &buttonYes, const KGuiItem &buttonNo) const
60 {
61 Q_ASSERT_X(!question.isEmpty(), "ITIPHandlerHelper::askUser", "ask what?");
62
63 switch (action) {
64 case ActionSendMessage:
65 return KMessageBox::Yes;
66 case ActionDontSendMessage:
67 return KMessageBox::No;
68 default:
69 return KMessageBox::questionYesNo(mParent, question, i18n("Group Scheduling Email"), buttonYes, buttonNo);
70 }
71 }
72
openDialogIncidenceCreated(Recipient recipient,const QString & question,Action action,const KGuiItem & buttonYes,const KGuiItem & buttonNo)73 void ITIPHandlerDialogDelegate::openDialogIncidenceCreated(Recipient recipient,
74 const QString &question,
75 Action action,
76 const KGuiItem &buttonYes,
77 const KGuiItem &buttonNo)
78 {
79 Q_UNUSED(recipient)
80 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
81 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
82 }
83
openDialogIncidenceModified(bool attendeeStatusChanged,Recipient recipient,const QString & question,Action action,const KGuiItem & buttonYes,const KGuiItem & buttonNo)84 void ITIPHandlerDialogDelegate::openDialogIncidenceModified(bool attendeeStatusChanged,
85 Recipient recipient,
86 const QString &question,
87 Action action,
88 const KGuiItem &buttonYes,
89 const KGuiItem &buttonNo)
90 {
91 Q_UNUSED(attendeeStatusChanged)
92 Q_UNUSED(recipient)
93 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
94 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
95 }
96
openDialogIncidenceDeleted(Recipient recipient,const QString & question,Action action,const KGuiItem & buttonYes,const KGuiItem & buttonNo)97 void ITIPHandlerDialogDelegate::openDialogIncidenceDeleted(Recipient recipient,
98 const QString &question,
99 Action action,
100 const KGuiItem &buttonYes,
101 const KGuiItem &buttonNo)
102 {
103 Q_UNUSED(recipient)
104 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
105 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
106 }
107
openDialogSchedulerFinished(const QString & question,Action action,const KGuiItem & buttonYes,const KGuiItem & buttonNo)108 void ITIPHandlerDialogDelegate::openDialogSchedulerFinished(const QString &question, Action action, const KGuiItem &buttonYes, const KGuiItem &buttonNo)
109 {
110 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo);
111 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence);
112 }
113
114 ITIPHandlerHelper::SendResult
sentInvitation(int messageBoxReturnCode,const KCalendarCore::Incidence::Ptr & incidence,KCalendarCore::iTIPMethod method)115 ITIPHandlerHelper::sentInvitation(int messageBoxReturnCode, const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method)
116 {
117 // The value represented by messageBoxReturnCode is the answer on a question
118 // which is a variant of: Do you want to send an email to the attendees?
119 //
120 // Where the email contains an invitation, modification notification or
121 // deletion notification.
122
123 if (messageBoxReturnCode == KMessageBox::Yes) {
124 // We will be sending out a message here. Now make sure there is some summary
125 // Yes, we do modify the incidence here, but we still keep the Ptr
126 // semantics, because this change is only for sending and not stored int the
127 // local calendar.
128 KCalendarCore::Incidence::Ptr _incidence(incidence->clone());
129 if (_incidence->summary().isEmpty()) {
130 _incidence->setSummary(xi18n("<placeholder>No summary given</placeholder>"));
131 }
132
133 // Send the mail
134 m_status = StatusSendingInvitation;
135 m_scheduler->performTransaction(_incidence, method);
136 return ITIPHandlerHelper::ResultSuccess;
137 } else if (messageBoxReturnCode == KMessageBox::No) {
138 Q_EMIT finished(ITIPHandlerHelper::ResultCanceled, QString());
139 return ITIPHandlerHelper::ResultCanceled;
140 } else {
141 Q_ASSERT(false); // TODO: Figure out if/how this can happen (by closing the dialog with x??)
142 Q_EMIT finished(ITIPHandlerHelper::ResultCanceled, QString());
143 return ITIPHandlerHelper::ResultCanceled;
144 }
145 }
146
weAreOrganizerOf(const KCalendarCore::Incidence::Ptr & incidence)147 bool ITIPHandlerHelper::weAreOrganizerOf(const KCalendarCore::Incidence::Ptr &incidence)
148 {
149 const QString email = incidence->organizer().email();
150 return Akonadi::CalendarUtils::thatIsMe(email) || email.isEmpty() || email == QLatin1String("invalid@email.address");
151 }
152
weNeedToSendMailFor(const KCalendarCore::Incidence::Ptr & incidence)153 bool ITIPHandlerHelper::weNeedToSendMailFor(const KCalendarCore::Incidence::Ptr &incidence)
154 {
155 if (!weAreOrganizerOf(incidence)) {
156 qCritical() << "We should be the organizer of this incidence."
157 << "; email= " << incidence->organizer().email() << "; thatIsMe() = " << Akonadi::CalendarUtils::thatIsMe(incidence->organizer().email());
158 Q_ASSERT(false);
159 return false;
160 }
161
162 if (incidence->attendees().isEmpty()) {
163 return false;
164 }
165
166 // At least one attendee
167 return incidence->attendees().count() > 1 || incidence->attendees().at(0).email() != incidence->organizer().email();
168 }
169
ITIPHandlerHelper(ITIPHandlerComponentFactory * factory,QWidget * parent)170 ITIPHandlerHelper::ITIPHandlerHelper(ITIPHandlerComponentFactory *factory, QWidget *parent)
171 : QObject(parent)
172 , mDefaultAction(ITIPHandlerDialogDelegate::ActionAsk)
173 , mParent(parent)
174 , m_factory(factory ? factory : new ITIPHandlerComponentFactory(this))
175 , m_scheduler(new MailScheduler(m_factory, this))
176 , m_status(StatusNone)
177 {
178 connect(m_scheduler, &MailScheduler::transactionFinished, this, &ITIPHandlerHelper::onSchedulerFinished);
179 }
180
~ITIPHandlerHelper()181 ITIPHandlerHelper::~ITIPHandlerHelper()
182 {
183 }
184
setDialogParent(QWidget * parent)185 void ITIPHandlerHelper::setDialogParent(QWidget *parent)
186 {
187 mParent = parent;
188 }
189
setDefaultAction(ITIPHandlerDialogDelegate::Action action)190 void ITIPHandlerHelper::setDefaultAction(ITIPHandlerDialogDelegate::Action action)
191 {
192 mDefaultAction = action;
193 }
194
sendIncidenceCreatedMessage(KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence)195 void ITIPHandlerHelper::sendIncidenceCreatedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence)
196 {
197 /// When we created the incidence, we *must* be the organizer.
198
199 if (!weAreOrganizerOf(incidence)) {
200 qCWarning(AKONADICALENDAR_LOG) << "Creating incidence which has another organizer! Will skip sending invitations."
201 << "; email= " << incidence->organizer().email()
202 << "; thatIsMe() = " << Akonadi::CalendarUtils::thatIsMe(incidence->organizer().email());
203 Q_EMIT sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::ResultFailAbortUpdate, method, incidence);
204 Q_EMIT finished(ITIPHandlerHelper::ResultFailAbortUpdate, QString());
205 return;
206 }
207
208 if (!weNeedToSendMailFor(incidence)) {
209 Q_EMIT sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
210 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
211 return;
212 }
213
214 QString question;
215 if (incidence->type() == KCalendarCore::Incidence::TypeEvent) {
216 question = i18n(
217 "The event \"%1\" includes other people.\n"
218 "Do you want to email the invitation to the attendees?",
219 incidence->summary());
220 } else if (incidence->type() == KCalendarCore::Incidence::TypeTodo) {
221 question = i18n(
222 "The todo \"%1\" includes other people.\n"
223 "Do you want to email the invitation to the attendees?",
224 incidence->summary());
225 } else {
226 question = i18n(
227 "This incidence includes other people. "
228 "Should an email be sent to the attendees?");
229 }
230
231 ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent);
232 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotIncidenceCreatedDialogClosed);
233 askDelegator->openDialogIncidenceCreated(ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction);
234 }
235
slotIncidenceCreatedDialogClosed(int messageBoxReturnCode,KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence)236 void ITIPHandlerHelper::slotIncidenceCreatedDialogClosed(int messageBoxReturnCode,
237 KCalendarCore::iTIPMethod method,
238 const KCalendarCore::Incidence::Ptr &incidence)
239 {
240 ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method);
241 Q_EMIT sendIncidenceCreatedMessageFinished(status, method, incidence);
242 }
243
handleIncidenceAboutToBeModified(const KCalendarCore::Incidence::Ptr & incidence)244 bool ITIPHandlerHelper::handleIncidenceAboutToBeModified(const KCalendarCore::Incidence::Ptr &incidence)
245 {
246 Q_ASSERT(incidence);
247 if (!weAreOrganizerOf(incidence)) {
248 switch (incidence->type()) {
249 case KCalendarCore::Incidence::TypeEvent: {
250 const QString question = i18n(
251 "You are not the organizer of this event. Editing it will "
252 "bring your calendar out of sync with the organizer's calendar. "
253 "Do you really want to edit it?");
254 const int messageBoxReturnCode = KMessageBox::warningYesNo(mParent, question);
255 return messageBoxReturnCode != KMessageBox::No;
256 break;
257 }
258 case KCalendarCore::Incidence::TypeJournal:
259 case KCalendarCore::Incidence::TypeTodo:
260 // Not sure why we handle to-dos differently regarding this
261 return true;
262 break;
263 default:
264 qCritical() << "Unknown incidence type: " << incidence->type() << incidence->typeStr();
265 Q_ASSERT_X(false, "ITIPHandlerHelper::handleIncidenceAboutToBeModified()", "Unknown incidence type");
266 return false;
267 }
268 } else {
269 return true;
270 }
271 }
272
sendIncidenceModifiedMessage(KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence,bool attendeeStatusChanged)273 void ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalendarCore::iTIPMethod method,
274 const KCalendarCore::Incidence::Ptr &incidence,
275 bool attendeeStatusChanged)
276 {
277 ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent);
278
279 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotIncidenceModifiedDialogClosed);
280 // For a modified incidence, either we are the organizer or someone else.
281 if (weAreOrganizerOf(incidence)) {
282 if (weNeedToSendMailFor(incidence)) {
283 const QString question = i18n(
284 "You changed the invitation \"%1\".\n"
285 "Do you want to email the attendees an update message?",
286 incidence->summary());
287
288 askDelegator->openDialogIncidenceModified(attendeeStatusChanged,
289 ITIPHandlerDialogDelegate::Attendees,
290 question,
291 mDefaultAction,
292 KGuiItem(i18n("Send Update")));
293 return;
294 } else {
295 Q_EMIT sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
296 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
297 delete askDelegator;
298 return;
299 }
300 } else if (incidence->type() == KCalendarCore::Incidence::TypeTodo) {
301 if (method == KCalendarCore::iTIPRequest) {
302 // This is an update to be sent to the organizer
303 method = KCalendarCore::iTIPReply;
304 }
305
306 const QString question = i18n(
307 "Do you want to send a status update to the "
308 "organizer of this task?");
309 askDelegator->openDialogIncidenceModified(attendeeStatusChanged,
310 ITIPHandlerDialogDelegate::Organizer,
311 question,
312 mDefaultAction,
313 KGuiItem(i18n("Send Update")));
314 return;
315 } else if (incidence->type() == KCalendarCore::Incidence::TypeEvent) {
316 if (attendeeStatusChanged && method == KCalendarCore::iTIPRequest) {
317 method = KCalendarCore::iTIPReply;
318 const QString question = i18n(
319 "Your status as an attendee of this event changed. "
320 "Do you want to send a status update to the event organizer?");
321
322 askDelegator->openDialogIncidenceModified(attendeeStatusChanged,
323 ITIPHandlerDialogDelegate::Organizer,
324 question,
325 mDefaultAction,
326 KGuiItem(i18n("Send Update")));
327 return;
328 } else {
329 slotIncidenceModifiedDialogClosed(KMessageBox::Yes, method, incidence);
330 delete askDelegator;
331 return;
332 }
333 }
334 Q_ASSERT(false); // Shouldn't happen.
335 Q_EMIT sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
336 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
337 delete askDelegator;
338 }
339
slotIncidenceModifiedDialogClosed(int messageBoxReturnCode,KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence)340 void ITIPHandlerHelper::slotIncidenceModifiedDialogClosed(int messageBoxReturnCode,
341 KCalendarCore::iTIPMethod method,
342 const KCalendarCore::Incidence::Ptr &incidence)
343 {
344 ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method);
345 Q_EMIT sendIncidenceModifiedMessageFinished(status, method, incidence);
346 }
347
sendIncidenceDeletedMessage(KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence)348 void ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence)
349 {
350 Q_ASSERT(incidence);
351
352 ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent);
353
354 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotIncidenceDeletedDialogClosed);
355
356 // For a modified incidence, either we are the organizer or someone else.
357 if (weAreOrganizerOf(incidence)) {
358 if (weNeedToSendMailFor(incidence)) {
359 QString question;
360 if (incidence->type() == KCalendarCore::Incidence::TypeEvent) {
361 question = i18n(
362 "You removed the invitation \"%1\".\n"
363 "Do you want to email the attendees that the event is canceled?",
364 incidence->summary());
365 } else if (incidence->type() == KCalendarCore::Incidence::TypeTodo) {
366 question = i18n(
367 "You removed the invitation \"%1\".\n"
368 "Do you want to email the attendees that the todo is canceled?",
369 incidence->summary());
370 } else if (incidence->type() == KCalendarCore::Incidence::TypeJournal) {
371 question = i18n(
372 "You removed the invitation \"%1\".\n"
373 "Do you want to email the attendees that the journal is canceled?",
374 incidence->summary());
375 }
376 askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction);
377 return;
378 } else {
379 Q_EMIT sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
380 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
381 delete askDelegator;
382 return;
383 }
384 } else if (incidence->type() != KCalendarCore::Incidence::TypeEvent) {
385 if (method == KCalendarCore::iTIPRequest) {
386 // This is an update to be sent to the organizer
387 method = KCalendarCore::iTIPReply;
388 }
389
390 const QString question = (incidence->type() == KCalendarCore::Incidence::TypeTodo) ? i18n(
391 "Do you want to send a status update to the "
392 "organizer of this task?")
393 : i18n(
394 "Do you want to send a status update to the "
395 "organizer of this journal?");
396 askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Organizer,
397 question,
398 mDefaultAction,
399 KGuiItem(i18nc("@action:button dialog positive answer", "Send Update")));
400 return;
401 } else {
402 const QStringList myEmails = Akonadi::CalendarUtils::allEmails();
403 bool incidenceAcceptedBefore = false;
404 for (const QString &email : myEmails) {
405 const KCalendarCore::Attendee me = incidence->attendeeByMail(email);
406 if (!me.isNull() && (me.status() == KCalendarCore::Attendee::Accepted || me.status() == KCalendarCore::Attendee::Delegated)) {
407 incidenceAcceptedBefore = true;
408 break;
409 }
410 }
411
412 if (incidenceAcceptedBefore) {
413 QString question = i18n(
414 "You had previously accepted an invitation to this event. "
415 "Do you want to send an updated response to the organizer "
416 "declining the invitation?");
417 askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Organizer,
418 question,
419 mDefaultAction,
420 KGuiItem(i18nc("@action:button dialog positive answer", "Send Update")));
421 return;
422 } else {
423 // We did not accept the event before and delete it from our calendar again,
424 // so there is no need to notify people.
425 Q_EMIT sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
426 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
427 delete askDelegator;
428 return;
429 }
430 }
431
432 Q_ASSERT(false); // Shouldn't happen.
433 Q_EMIT sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence);
434 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString());
435 delete askDelegator;
436 }
437
slotIncidenceDeletedDialogClosed(const int messageBoxReturnCode,KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence)438 void ITIPHandlerHelper::slotIncidenceDeletedDialogClosed(const int messageBoxReturnCode,
439 KCalendarCore::iTIPMethod method,
440 const KCalendarCore::Incidence::Ptr &incidence)
441 {
442 ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method);
443 Q_EMIT sendIncidenceDeletedMessageFinished(status, method, incidence);
444 }
445
sendCounterProposal(const KCalendarCore::Incidence::Ptr & oldEvent,const KCalendarCore::Incidence::Ptr & newEvent)446 ITIPHandlerHelper::SendResult ITIPHandlerHelper::sendCounterProposal(const KCalendarCore::Incidence::Ptr &oldEvent,
447 const KCalendarCore::Incidence::Ptr &newEvent)
448 {
449 Q_ASSERT(oldEvent);
450 Q_ASSERT(newEvent);
451
452 if (!oldEvent || !newEvent || *oldEvent == *newEvent) {
453 return ITIPHandlerHelper::ResultNoSendingNeeded;
454 }
455
456 if (CalendarSettings::self()->outlookCompatCounterProposals()) {
457 KCalendarCore::Incidence::Ptr tmp(oldEvent->clone());
458 tmp->setSummary(i18n("Counter proposal: %1", newEvent->summary()));
459 tmp->setDescription(newEvent->description());
460 tmp->addComment(proposalComment(newEvent));
461
462 return sentInvitation(KMessageBox::Yes, tmp, KCalendarCore::iTIPReply);
463 } else {
464 return sentInvitation(KMessageBox::Yes, newEvent, KCalendarCore::iTIPCounter);
465 }
466 }
467
onSchedulerFinished(Akonadi::Scheduler::Result result,const QString & errorMsg)468 void ITIPHandlerHelper::onSchedulerFinished(Akonadi::Scheduler::Result result, const QString &errorMsg)
469 {
470 const bool success = result == MailScheduler::ResultSuccess;
471
472 if (m_status == StatusSendingInvitation) {
473 m_status = StatusNone;
474 if (!success) {
475 const QString question(i18n("Sending group scheduling email failed."));
476
477 ITIPHandlerDialogDelegate *askDelegator =
478 m_factory->createITIPHanderDialogDelegate(KCalendarCore::Incidence::Ptr(), KCalendarCore::iTIPNoMethod, mParent);
479
480 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotSchedulerFinishDialog);
481 askDelegator->openDialogSchedulerFinished(question,
482 ITIPHandlerDialogDelegate::ActionAsk,
483 KGuiItem(i18nc("@action:button dialog positive answer to abort question", "Abort Update")));
484 return;
485 } else {
486 // fall through
487 }
488 }
489
490 Q_EMIT finished(success ? ResultSuccess : ResultError, success ? QString() : i18n("Error: %1", errorMsg));
491 }
492
slotSchedulerFinishDialog(const int result,KCalendarCore::iTIPMethod method,const KCalendarCore::Incidence::Ptr & incidence)493 void ITIPHandlerHelper::slotSchedulerFinishDialog(const int result, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence)
494 {
495 Q_UNUSED(method)
496 Q_UNUSED(incidence)
497 if (result == KMessageBox::Yes) {
498 Q_EMIT finished(ResultFailAbortUpdate, QString());
499 } else {
500 Q_EMIT finished(ResultFailKeepUpdate, QString());
501 }
502 }
503