File indexing completed on 2024-05-12 05:10:48
0001 /* 0002 SPDX-FileCopyrightText: 2002-2004 Klarälvdalens Datakonsult AB, 0003 <info@klaralvdalens-datakonsult.se> 0004 0005 SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org> 0006 SPDX-FileCopyrightText: 2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "itiphandlerhelper_p.h" 0012 #include "calendarsettings.h" 0013 #include "utils_p.h" 0014 0015 #include "akonadicalendar_debug.h" 0016 #include <KCalUtils/IncidenceFormatter> 0017 #include <KCalendarCore/Calendar> 0018 #include <KLocalizedString> 0019 #include <KMessageBox> 0020 0021 #include <QWidget> 0022 0023 using namespace Akonadi; 0024 0025 QString proposalComment(const KCalendarCore::Incidence::Ptr &incidence) 0026 { 0027 QString comment; 0028 0029 // TODO: doesn't KCalUtils/IncidenceFormater already provide this? 0030 // if not, it should go there. 0031 0032 switch (incidence->type()) { 0033 case KCalendarCore::IncidenceBase::TypeEvent: { 0034 const QDateTime dtEnd = incidence->dateTime(KCalendarCore::Incidence::RoleDisplayEnd); 0035 comment = i18n("Proposed new meeting time: %1 - %2", 0036 KCalUtils::IncidenceFormatter::dateToString(incidence->dtStart().toLocalTime().date()), 0037 KCalUtils::IncidenceFormatter::dateToString(dtEnd.toLocalTime().date())); 0038 break; 0039 } 0040 case KCalendarCore::IncidenceBase::TypeTodo: 0041 qCWarning(AKONADICALENDAR_LOG) << "NOT IMPLEMENTED: proposalComment called for to-do."; 0042 break; 0043 default: 0044 qCWarning(AKONADICALENDAR_LOG) << "NOT IMPLEMENTED: proposalComment called for " << incidence->typeStr(); 0045 } 0046 0047 return comment; 0048 } 0049 0050 ITIPHandlerDialogDelegate::ITIPHandlerDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent) 0051 : mParent(parent) 0052 , mIncidence(incidence) 0053 , mMethod(method) 0054 { 0055 } 0056 0057 int ITIPHandlerDialogDelegate::askUserIfNeeded(const QString &question, Action action, const KGuiItem &buttonYes, const KGuiItem &buttonNo) const 0058 { 0059 Q_ASSERT_X(!question.isEmpty(), "ITIPHandlerHelper::askUser", "ask what?"); 0060 0061 switch (action) { 0062 case ActionSendMessage: 0063 return KMessageBox::ButtonCode::PrimaryAction; 0064 case ActionDontSendMessage: 0065 return KMessageBox::ButtonCode::SecondaryAction; 0066 default: 0067 return KMessageBox::questionTwoActionsCancel(mParent, question, i18nc("@title:window", "Group Scheduling Email"), buttonYes, buttonNo); 0068 } 0069 } 0070 0071 void ITIPHandlerDialogDelegate::openDialogIncidenceCreated(Recipient recipient, 0072 const QString &question, 0073 Action action, 0074 const KGuiItem &buttonYes, 0075 const KGuiItem &buttonNo) 0076 { 0077 Q_UNUSED(recipient) 0078 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo); 0079 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence); 0080 } 0081 0082 void ITIPHandlerDialogDelegate::openDialogIncidenceModified(bool attendeeStatusChanged, 0083 Recipient recipient, 0084 const QString &question, 0085 Action action, 0086 const KGuiItem &buttonYes, 0087 const KGuiItem &buttonNo) 0088 { 0089 Q_UNUSED(attendeeStatusChanged) 0090 Q_UNUSED(recipient) 0091 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo); 0092 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence); 0093 } 0094 0095 void ITIPHandlerDialogDelegate::openDialogIncidenceDeleted(Recipient recipient, 0096 const QString &question, 0097 Action action, 0098 const KGuiItem &buttonYes, 0099 const KGuiItem &buttonNo) 0100 { 0101 Q_UNUSED(recipient) 0102 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo); 0103 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence); 0104 } 0105 0106 void ITIPHandlerDialogDelegate::openDialogSchedulerFinished(const QString &question, Action action, const KGuiItem &buttonYes, const KGuiItem &buttonNo) 0107 { 0108 const int messageBoxReturnCode = askUserIfNeeded(question, action, buttonYes, buttonNo); 0109 Q_EMIT dialogClosed(messageBoxReturnCode, mMethod, mIncidence); 0110 } 0111 0112 int ITIPHandlerDialogDelegate::warningContinueCancel(const QString &text, const QString &title, const KGuiItem &buttonContinue, const KGuiItem &buttonCancel) 0113 { 0114 return KMessageBox::warningContinueCancel(mParent, text, title, buttonContinue, buttonCancel); 0115 } 0116 0117 int ITIPHandlerDialogDelegate::warningTwoActionsCancel(const QString &text, 0118 const QString &title, 0119 const KGuiItem &primaryAction, 0120 const KGuiItem &secondaryAction, 0121 const KGuiItem &cancelAction) 0122 { 0123 return KMessageBox::warningTwoActionsCancel(mParent, text, title, primaryAction, secondaryAction, cancelAction); 0124 } 0125 0126 ITIPHandlerHelper::SendResult ITIPHandlerHelper::sentInvitation(int messageBoxReturnCode, 0127 const KCalendarCore::Incidence::Ptr &incidence, 0128 KCalendarCore::iTIPMethod method, 0129 const QString &sender) 0130 { 0131 // The value represented by messageBoxReturnCode is the answer on a question 0132 // which is a variant of: Do you want to send an email to the attendees? 0133 // 0134 // Where the email contains an invitation, modification notification or 0135 // deletion notification. 0136 0137 if (messageBoxReturnCode == KMessageBox::ButtonCode::PrimaryAction) { 0138 // We will be sending out a message here. Now make sure there is some summary 0139 // Yes, we do modify the incidence here, but we still keep the Ptr 0140 // semantics, because this change is only for sending and not stored int the 0141 // local calendar. 0142 KCalendarCore::Incidence::Ptr _incidence(incidence->clone()); 0143 if (_incidence->summary().isEmpty()) { 0144 _incidence->setSummary(xi18n("<placeholder>No summary given</placeholder>")); 0145 } 0146 0147 // Send the mail 0148 m_status = StatusSendingInvitation; 0149 m_scheduler->performTransaction(_incidence, method, sender); 0150 return ITIPHandlerHelper::ResultSuccess; 0151 } else if (messageBoxReturnCode == KMessageBox::ButtonCode::SecondaryAction) { 0152 Q_EMIT finished(ITIPHandlerHelper::ResultCanceled, QString()); 0153 return ITIPHandlerHelper::ResultCanceled; 0154 } else { 0155 Q_ASSERT(false); // TODO: Figure out if/how this can happen (by closing the dialog with x??) 0156 Q_EMIT finished(ITIPHandlerHelper::ResultCanceled, QString()); 0157 return ITIPHandlerHelper::ResultCanceled; 0158 } 0159 } 0160 0161 bool ITIPHandlerHelper::weAreOrganizerOf(const KCalendarCore::Incidence::Ptr &incidence) 0162 { 0163 const QString email = incidence->organizer().email(); 0164 return Akonadi::CalendarUtils::thatIsMe(email) || email.isEmpty() || email == QLatin1StringView("invalid@email.address"); 0165 } 0166 0167 bool ITIPHandlerHelper::weNeedToSendMailFor(const KCalendarCore::Incidence::Ptr &incidence) 0168 { 0169 if (!weAreOrganizerOf(incidence)) { 0170 qCritical() << "We should be the organizer of this incidence." 0171 << "; email= " << incidence->organizer().email() << "; thatIsMe() = " << Akonadi::CalendarUtils::thatIsMe(incidence->organizer().email()); 0172 Q_ASSERT(false); 0173 return false; 0174 } 0175 0176 if (incidence->attendees().isEmpty()) { 0177 return false; 0178 } 0179 0180 // At least one attendee 0181 return incidence->attendees().count() > 1 || incidence->attendees().at(0).email() != incidence->organizer().email(); 0182 } 0183 0184 ITIPHandlerHelper::ITIPHandlerHelper(ITIPHandlerComponentFactory *factory, QWidget *parent) 0185 : QObject(parent) 0186 , mDefaultAction(ITIPHandlerDialogDelegate::ActionAsk) 0187 , mParent(parent) 0188 , m_factory(factory ? factory : new ITIPHandlerComponentFactory(this)) 0189 , m_scheduler(new MailScheduler(m_factory, this)) 0190 , m_status(StatusNone) 0191 { 0192 connect(m_scheduler, &MailScheduler::transactionFinished, this, &ITIPHandlerHelper::onSchedulerFinished); 0193 } 0194 0195 ITIPHandlerHelper::~ITIPHandlerHelper() = default; 0196 0197 void ITIPHandlerHelper::setDialogParent(QWidget *parent) 0198 { 0199 mParent = parent; 0200 } 0201 0202 void ITIPHandlerHelper::setDefaultAction(ITIPHandlerDialogDelegate::Action action) 0203 { 0204 mDefaultAction = action; 0205 } 0206 0207 void ITIPHandlerHelper::setMessagePrivacy(MessagePrivacyFlags messagePrivacy) 0208 { 0209 m_scheduler->setSign((messagePrivacy & ITIPHandlerHelper::MessagePrivacySign) == ITIPHandlerHelper::MessagePrivacySign); 0210 m_scheduler->setEncrypt((messagePrivacy & ITIPHandlerHelper::MessagePrivacyEncrypt) == ITIPHandlerHelper::MessagePrivacyEncrypt); 0211 } 0212 0213 void ITIPHandlerHelper::sendIncidenceCreatedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence) 0214 { 0215 /// When we created the incidence, we *must* be the organizer. 0216 0217 if (!weAreOrganizerOf(incidence)) { 0218 qCWarning(AKONADICALENDAR_LOG) << "Creating incidence which has another organizer! Will skip sending invitations." 0219 << "; email= " << incidence->organizer().email() 0220 << "; thatIsMe() = " << Akonadi::CalendarUtils::thatIsMe(incidence->organizer().email()); 0221 Q_EMIT sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::ResultFailAbortUpdate, method, incidence); 0222 Q_EMIT finished(ITIPHandlerHelper::ResultFailAbortUpdate, QString()); 0223 return; 0224 } 0225 0226 if (!weNeedToSendMailFor(incidence)) { 0227 Q_EMIT sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence); 0228 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString()); 0229 return; 0230 } 0231 0232 QString question; 0233 if (incidence->type() == KCalendarCore::Incidence::TypeEvent) { 0234 question = i18n( 0235 "The event \"%1\" includes other people.\n" 0236 "Do you want to email the invitation to the attendees?", 0237 incidence->summary()); 0238 } else if (incidence->type() == KCalendarCore::Incidence::TypeTodo) { 0239 question = i18n( 0240 "The todo \"%1\" includes other people.\n" 0241 "Do you want to email the invitation to the attendees?", 0242 incidence->summary()); 0243 } else { 0244 question = i18n( 0245 "This incidence includes other people. " 0246 "Should an email be sent to the attendees?"); 0247 } 0248 0249 ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent); 0250 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotIncidenceCreatedDialogClosed); 0251 askDelegator->openDialogIncidenceCreated(ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction); 0252 } 0253 0254 void ITIPHandlerHelper::slotIncidenceCreatedDialogClosed(int messageBoxReturnCode, 0255 KCalendarCore::iTIPMethod method, 0256 const KCalendarCore::Incidence::Ptr &incidence) 0257 { 0258 ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method); 0259 Q_EMIT sendIncidenceCreatedMessageFinished(status, method, incidence); 0260 } 0261 0262 bool ITIPHandlerHelper::handleIncidenceAboutToBeModified(const KCalendarCore::Incidence::Ptr &incidence) 0263 { 0264 Q_ASSERT(incidence); 0265 if (!weAreOrganizerOf(incidence)) { 0266 switch (incidence->type()) { 0267 case KCalendarCore::Incidence::TypeEvent: { 0268 const QString question = i18n( 0269 "You are not the organizer of this event. Editing it will " 0270 "bring your calendar out of sync with the organizer's calendar. " 0271 "Do you really want to edit it?"); 0272 const int messageBoxReturnCode = KMessageBox::warningTwoActions(mParent, question, {}, KStandardGuiItem::ok(), KStandardGuiItem::cancel()); 0273 return messageBoxReturnCode != KMessageBox::ButtonCode::SecondaryAction; 0274 break; 0275 } 0276 case KCalendarCore::Incidence::TypeJournal: 0277 case KCalendarCore::Incidence::TypeTodo: 0278 // Not sure why we handle to-dos differently regarding this 0279 return true; 0280 break; 0281 default: 0282 qCritical() << "Unknown incidence type: " << incidence->type() << incidence->typeStr(); 0283 Q_ASSERT_X(false, "ITIPHandlerHelper::handleIncidenceAboutToBeModified()", "Unknown incidence type"); 0284 return false; 0285 } 0286 } else { 0287 return true; 0288 } 0289 } 0290 0291 void ITIPHandlerHelper::sendIncidenceModifiedMessage(KCalendarCore::iTIPMethod method, 0292 const KCalendarCore::Incidence::Ptr &incidence, 0293 bool attendeeStatusChanged) 0294 { 0295 ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent); 0296 0297 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotIncidenceModifiedDialogClosed); 0298 // For a modified incidence, either we are the organizer or someone else. 0299 if (weAreOrganizerOf(incidence)) { 0300 if (weNeedToSendMailFor(incidence)) { 0301 const QString question = i18n( 0302 "You changed the invitation \"%1\".\n" 0303 "Do you want to email the attendees an update message?", 0304 incidence->summary()); 0305 0306 askDelegator->openDialogIncidenceModified(attendeeStatusChanged, 0307 ITIPHandlerDialogDelegate::Attendees, 0308 question, 0309 mDefaultAction, 0310 KGuiItem(i18n("Send Update"))); 0311 return; 0312 } else { 0313 Q_EMIT sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence); 0314 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString()); 0315 delete askDelegator; 0316 return; 0317 } 0318 } else if (incidence->type() == KCalendarCore::Incidence::TypeTodo) { 0319 if (method == KCalendarCore::iTIPRequest) { 0320 // This is an update to be sent to the organizer 0321 method = KCalendarCore::iTIPReply; 0322 } 0323 0324 const QString question = i18n( 0325 "Do you want to send a status update to the " 0326 "organizer of this task?"); 0327 askDelegator->openDialogIncidenceModified(attendeeStatusChanged, 0328 ITIPHandlerDialogDelegate::Organizer, 0329 question, 0330 mDefaultAction, 0331 KGuiItem(i18n("Send Update"))); 0332 return; 0333 } else if (incidence->type() == KCalendarCore::Incidence::TypeEvent) { 0334 if (attendeeStatusChanged && method == KCalendarCore::iTIPRequest) { 0335 method = KCalendarCore::iTIPReply; 0336 const QString question = i18n( 0337 "Your status as an attendee of this event changed. " 0338 "Do you want to send a status update to the event organizer?"); 0339 0340 askDelegator->openDialogIncidenceModified(attendeeStatusChanged, 0341 ITIPHandlerDialogDelegate::Organizer, 0342 question, 0343 mDefaultAction, 0344 KGuiItem(i18n("Send Update"))); 0345 return; 0346 } else { 0347 slotIncidenceModifiedDialogClosed(KMessageBox::ButtonCode::PrimaryAction, method, incidence); 0348 delete askDelegator; 0349 return; 0350 } 0351 } 0352 Q_ASSERT(false); // Shouldn't happen. 0353 Q_EMIT sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence); 0354 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString()); 0355 delete askDelegator; 0356 } 0357 0358 void ITIPHandlerHelper::slotIncidenceModifiedDialogClosed(int messageBoxReturnCode, 0359 KCalendarCore::iTIPMethod method, 0360 const KCalendarCore::Incidence::Ptr &incidence) 0361 { 0362 ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method); 0363 Q_EMIT sendIncidenceModifiedMessageFinished(status, method, incidence); 0364 } 0365 0366 void ITIPHandlerHelper::sendIncidenceDeletedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence) 0367 { 0368 Q_ASSERT(incidence); 0369 0370 ITIPHandlerDialogDelegate *askDelegator = m_factory->createITIPHanderDialogDelegate(incidence, method, mParent); 0371 0372 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotIncidenceDeletedDialogClosed); 0373 0374 // For a modified incidence, either we are the organizer or someone else. 0375 if (weAreOrganizerOf(incidence)) { 0376 if (weNeedToSendMailFor(incidence)) { 0377 QString question; 0378 if (incidence->type() == KCalendarCore::Incidence::TypeEvent) { 0379 question = i18n( 0380 "You removed the invitation \"%1\".\n" 0381 "Do you want to email the attendees that the event is canceled?", 0382 incidence->summary()); 0383 } else if (incidence->type() == KCalendarCore::Incidence::TypeTodo) { 0384 question = i18n( 0385 "You removed the invitation \"%1\".\n" 0386 "Do you want to email the attendees that the todo is canceled?", 0387 incidence->summary()); 0388 } else if (incidence->type() == KCalendarCore::Incidence::TypeJournal) { 0389 question = i18n( 0390 "You removed the invitation \"%1\".\n" 0391 "Do you want to email the attendees that the journal is canceled?", 0392 incidence->summary()); 0393 } 0394 askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Attendees, question, mDefaultAction); 0395 return; 0396 } else { 0397 Q_EMIT sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence); 0398 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString()); 0399 delete askDelegator; 0400 return; 0401 } 0402 } else if (incidence->type() != KCalendarCore::Incidence::TypeEvent) { 0403 if (method == KCalendarCore::iTIPRequest) { 0404 // This is an update to be sent to the organizer 0405 method = KCalendarCore::iTIPReply; 0406 } 0407 0408 const QString question = (incidence->type() == KCalendarCore::Incidence::TypeTodo) ? i18n( 0409 "Do you want to send a status update to the " 0410 "organizer of this task?") 0411 : i18n( 0412 "Do you want to send a status update to the " 0413 "organizer of this journal?"); 0414 askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Organizer, 0415 question, 0416 mDefaultAction, 0417 KGuiItem(i18nc("@action:button dialog positive answer", "Send Update"))); 0418 return; 0419 } else { 0420 const QStringList myEmails = Akonadi::CalendarUtils::allEmails(); 0421 bool incidenceAcceptedBefore = false; 0422 for (const QString &email : myEmails) { 0423 const KCalendarCore::Attendee me = incidence->attendeeByMail(email); 0424 if (!me.isNull() && (me.status() == KCalendarCore::Attendee::Accepted || me.status() == KCalendarCore::Attendee::Delegated)) { 0425 incidenceAcceptedBefore = true; 0426 break; 0427 } 0428 } 0429 0430 if (incidenceAcceptedBefore) { 0431 QString question = i18n( 0432 "You had previously accepted an invitation to this event. " 0433 "Do you want to send an updated response to the organizer " 0434 "declining the invitation?"); 0435 askDelegator->openDialogIncidenceDeleted(ITIPHandlerDialogDelegate::Organizer, 0436 question, 0437 mDefaultAction, 0438 KGuiItem(i18nc("@action:button dialog positive answer", "Send Update"))); 0439 return; 0440 } else { 0441 // We did not accept the event before and delete it from our calendar again, 0442 // so there is no need to notify people. 0443 Q_EMIT sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence); 0444 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString()); 0445 delete askDelegator; 0446 return; 0447 } 0448 } 0449 0450 Q_ASSERT(false); // Shouldn't happen. 0451 Q_EMIT sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::ResultNoSendingNeeded, method, incidence); 0452 Q_EMIT finished(ITIPHandlerHelper::ResultNoSendingNeeded, QString()); 0453 delete askDelegator; 0454 } 0455 0456 void ITIPHandlerHelper::slotIncidenceDeletedDialogClosed(const int messageBoxReturnCode, 0457 KCalendarCore::iTIPMethod method, 0458 const KCalendarCore::Incidence::Ptr &incidence) 0459 { 0460 ITIPHandlerHelper::SendResult status = sentInvitation(messageBoxReturnCode, incidence, method); 0461 Q_EMIT sendIncidenceDeletedMessageFinished(status, method, incidence); 0462 } 0463 0464 ITIPHandlerHelper::SendResult 0465 ITIPHandlerHelper::sendCounterProposal(const QString &receiver, const KCalendarCore::Incidence::Ptr &oldEvent, const KCalendarCore::Incidence::Ptr &newEvent) 0466 { 0467 Q_ASSERT(oldEvent); 0468 Q_ASSERT(newEvent); 0469 0470 if (!oldEvent || !newEvent || *oldEvent == *newEvent) { 0471 return ITIPHandlerHelper::ResultNoSendingNeeded; 0472 } 0473 0474 if (CalendarSettings::self()->outlookCompatCounterProposals()) { 0475 KCalendarCore::Incidence::Ptr tmp(oldEvent->clone()); 0476 tmp->setSummary(i18n("Counter proposal: %1", newEvent->summary())); 0477 tmp->setDescription(newEvent->description()); 0478 tmp->addComment(proposalComment(newEvent)); 0479 0480 return sentInvitation(KMessageBox::ButtonCode::PrimaryAction, tmp, KCalendarCore::iTIPReply, receiver); 0481 } else { 0482 return sentInvitation(KMessageBox::ButtonCode::PrimaryAction, newEvent, KCalendarCore::iTIPCounter, receiver); 0483 } 0484 } 0485 0486 void ITIPHandlerHelper::onSchedulerFinished(Akonadi::Scheduler::Result result, const QString &errorMsg) 0487 { 0488 const bool success = result == MailScheduler::ResultSuccess; 0489 0490 if (m_status == StatusSendingInvitation) { 0491 m_status = StatusNone; 0492 if (!success) { 0493 const QString question(i18n("Sending group scheduling email failed.")); 0494 0495 ITIPHandlerDialogDelegate *askDelegator = 0496 m_factory->createITIPHanderDialogDelegate(KCalendarCore::Incidence::Ptr(), KCalendarCore::iTIPNoMethod, mParent); 0497 0498 connect(askDelegator, &ITIPHandlerDialogDelegate::dialogClosed, this, &ITIPHandlerHelper::slotSchedulerFinishDialog); 0499 askDelegator->openDialogSchedulerFinished(question, 0500 ITIPHandlerDialogDelegate::ActionAsk, 0501 KGuiItem(i18nc("@action:button dialog positive answer to abort question", "Abort Update"))); 0502 return; 0503 } else { 0504 // fall through 0505 } 0506 } 0507 0508 Q_EMIT finished(success ? ResultSuccess : ResultError, success ? QString() : i18n("Error: %1", errorMsg)); 0509 } 0510 0511 void ITIPHandlerHelper::slotSchedulerFinishDialog(const int result, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence) 0512 { 0513 Q_UNUSED(method) 0514 Q_UNUSED(incidence) 0515 if (result == KMessageBox::ButtonCode::PrimaryAction) { 0516 Q_EMIT finished(ResultFailAbortUpdate, QString()); 0517 } else { 0518 Q_EMIT finished(ResultFailKeepUpdate, QString()); 0519 } 0520 } 0521 0522 #include "moc_itiphandlerhelper_p.cpp"