File indexing completed on 2024-05-12 05:10:47
0001 /* 0002 SPDX-FileCopyrightText: 2012 Sérgio Martins <iamsergio@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "itiphandler_p.h" 0008 #include "fetchjobcalendar.h" 0009 #include <KCalendarCore/Incidence> 0010 #include <KLocalizedString> 0011 #include <KMessageBox> 0012 using namespace Akonadi; 0013 0014 ITIPHandlerPrivate::ITIPHandlerPrivate(ITIPHandlerComponentFactory *factory, ITIPHandler *qq) 0015 : m_factory(factory ? factory : new ITIPHandlerComponentFactory(this)) 0016 , m_scheduler(new MailScheduler(m_factory, qq)) 0017 , m_method(KCalendarCore::iTIPNoMethod) 0018 , m_helper(new ITIPHandlerHelper(m_factory)) 0019 , m_currentOperation(OperationNone) 0020 , m_uiDelegate(nullptr) 0021 , q(qq) 0022 { 0023 m_helper->setParent(this); 0024 connect(m_scheduler, &Scheduler::transactionFinished, this, &ITIPHandlerPrivate::onSchedulerFinished); 0025 0026 connect(m_helper, &ITIPHandlerHelper::finished, this, &ITIPHandlerPrivate::onHelperFinished); 0027 0028 connect(m_helper, &ITIPHandlerHelper::sendIncidenceModifiedMessageFinished, this, &ITIPHandlerPrivate::onHelperModifyDialogClosed); 0029 } 0030 0031 void ITIPHandlerPrivate::onSchedulerFinished(Akonadi::Scheduler::Result result, const QString &errorMessage) 0032 { 0033 if (m_currentOperation == OperationNone) { 0034 qCritical() << "Operation can't be none!" << result << errorMessage; 0035 return; 0036 } 0037 0038 if (m_currentOperation == OperationProcessiTIPMessage) { 0039 m_currentOperation = OperationNone; 0040 finishProcessiTIPMessage(result, errorMessage); 0041 } else if (m_currentOperation == OperationSendiTIPMessage) { 0042 m_currentOperation = OperationNone; 0043 finishSendiTIPMessage(result, errorMessage); 0044 } else if (m_currentOperation == OperationPublishInformation) { 0045 m_currentOperation = OperationNone; 0046 finishPublishInformation(result, errorMessage); 0047 } else { 0048 Q_ASSERT(false); 0049 qCritical() << "Unknown operation" << m_currentOperation; 0050 } 0051 } 0052 0053 void ITIPHandlerPrivate::onHelperFinished(Akonadi::ITIPHandlerHelper::SendResult result, const QString &errorMessage) 0054 { 0055 const bool success = result == ITIPHandlerHelper::ResultSuccess; 0056 0057 if (m_currentOperation == OperationProcessiTIPMessage) { 0058 MailScheduler::Result result2 = success ? MailScheduler::ResultSuccess : MailScheduler::ResultGenericError; 0059 finishProcessiTIPMessage(result2, i18n("Error: %1", errorMessage)); 0060 } else { 0061 Q_EMIT q->iTipMessageSent(success ? ITIPHandler::ResultSuccess : ITIPHandler::ResultError, success ? QString() : i18n("Error: %1", errorMessage)); 0062 } 0063 } 0064 0065 void ITIPHandlerPrivate::onCounterProposalDelegateFinished(bool success, const QString &errorMessage) 0066 { 0067 Q_UNUSED(success) 0068 Q_UNUSED(errorMessage) 0069 // This will be used when we make editing counter proposals async. 0070 } 0071 0072 void ITIPHandlerPrivate::onLoadFinished(bool success, const QString &errorMessage) 0073 { 0074 if (m_currentOperation == OperationProcessiTIPMessage) { 0075 if (success) { 0076 // Harmless hack, processiTIPMessage() asserts that there's not current operation running 0077 // to prevent users from calling it twice. 0078 m_currentOperation = OperationNone; 0079 q->processiTIPMessage(m_queuedInvitation.receiver, m_queuedInvitation.iCal, m_queuedInvitation.action); 0080 } else { 0081 Q_EMIT q->iTipMessageProcessed(ITIPHandler::ResultError, i18n("Error loading calendar: %1", errorMessage)); 0082 } 0083 } else if (m_currentOperation == OperationSendiTIPMessage) { 0084 q->sendiTIPMessage(m_queuedInvitation.method, m_queuedInvitation.incidence, m_parentWidget); 0085 } else if (!success) { // TODO 0086 m_calendarLoadError = true; 0087 } 0088 } 0089 0090 void ITIPHandlerPrivate::finishProcessiTIPMessage(Akonadi::MailScheduler::Result result, const QString &errorMessage) 0091 { 0092 // Handle when user cancels on the collection selection dialog 0093 if (result == MailScheduler::ResultUserCancelled) { 0094 Q_EMIT q->iTipMessageProcessed(ITIPHandler::ResultCancelled, QString()); 0095 return; 0096 } 0097 0098 const bool success = result == MailScheduler::ResultSuccess; 0099 0100 if (m_method == KCalendarCore::iTIPCounter) { 0101 // Here we're processing a counter-proposal that someone sent us and we're the organizer. 0102 // TODO: Shouldn't there be a test to see if we're the organizer? 0103 if (success) { 0104 // send update to all attendees 0105 Q_ASSERT(m_incidence); 0106 m_helper->setDialogParent(m_parentWidget); 0107 m_helper->sendIncidenceModifiedMessage(KCalendarCore::iTIPRequest, KCalendarCore::Incidence::Ptr(m_incidence->clone()), false); 0108 m_incidence.clear(); 0109 return; 0110 } else { 0111 // fall through 0112 } 0113 } 0114 0115 Q_EMIT q->iTipMessageProcessed(success ? ITIPHandler::ResultSuccess : ITIPHandler::ResultError, success ? QString() : i18n("Error: %1", errorMessage)); 0116 } 0117 0118 void ITIPHandlerPrivate::onHelperModifyDialogClosed(ITIPHandlerHelper::SendResult sendResult, 0119 KCalendarCore::iTIPMethod /*method*/, 0120 const KCalendarCore::Incidence::Ptr &) 0121 { 0122 if (sendResult == ITIPHandlerHelper::ResultNoSendingNeeded || sendResult == ITIPHandlerHelper::ResultCanceled) { 0123 Q_EMIT q->iTipMessageSent(ITIPHandler::ResultSuccess, QString()); 0124 } 0125 } 0126 0127 void ITIPHandlerPrivate::finishSendiTIPMessage(Akonadi::MailScheduler::Result result, const QString &errorMessage) 0128 { 0129 if (result == Scheduler::ResultSuccess) { 0130 if (m_parentWidget) { 0131 KMessageBox::information(m_parentWidget, 0132 i18n("The groupware message for item '%1' " 0133 "was successfully sent.\nMethod: %2", 0134 m_queuedInvitation.incidence->summary(), 0135 KCalendarCore::ScheduleMessage::methodName(m_queuedInvitation.method)), 0136 i18nc("@title:window", "Sending Free/Busy"), 0137 QStringLiteral("FreeBusyPublishSuccess")); 0138 } 0139 Q_EMIT q->iTipMessageSent(ITIPHandler::ResultSuccess, QString()); 0140 } else { 0141 const QString error = i18nc( 0142 "Groupware message sending failed. " 0143 "%2 is request/reply/add/cancel/counter/etc.", 0144 "Unable to send the item '%1'.\nMethod: %2", 0145 m_queuedInvitation.incidence->summary(), 0146 KCalendarCore::ScheduleMessage::methodName(m_queuedInvitation.method)); 0147 if (m_parentWidget) { 0148 KMessageBox::error(m_parentWidget, error); 0149 } 0150 qCritical() << "Groupware message sending failed." << error << errorMessage; 0151 Q_EMIT q->iTipMessageSent(ITIPHandler::ResultError, error + errorMessage); 0152 } 0153 } 0154 0155 void ITIPHandlerPrivate::finishPublishInformation(Akonadi::MailScheduler::Result result, const QString &errorMessage) 0156 { 0157 if (result == Scheduler::ResultSuccess) { 0158 if (m_parentWidget) { 0159 KMessageBox::information(m_parentWidget, 0160 i18n("The item information was successfully sent."), 0161 i18nc("@title:window", "Publishing"), 0162 QStringLiteral("IncidencePublishSuccess")); 0163 } 0164 Q_EMIT q->informationPublished(ITIPHandler::ResultSuccess, QString()); 0165 } else { 0166 const QString error = i18n("Unable to publish the item '%1'", m_queuedInvitation.incidence->summary()); 0167 if (m_parentWidget) { 0168 KMessageBox::error(m_parentWidget, error); 0169 } 0170 qCritical() << "Publish failed." << error << errorMessage; 0171 Q_EMIT q->informationPublished(ITIPHandler::ResultError, error + errorMessage); 0172 } 0173 } 0174 0175 void ITIPHandlerPrivate::finishSendAsICalendar(Akonadi::MailClient::Result result, const QString &errorMessage) 0176 { 0177 if (result == MailClient::ResultSuccess) { 0178 if (m_parentWidget) { 0179 KMessageBox::information(m_parentWidget, 0180 i18n("The item information was successfully sent."), 0181 i18nc("@title:window", "Forwarding"), 0182 QStringLiteral("IncidenceForwardSuccess")); 0183 } 0184 Q_EMIT q->sentAsICalendar(ITIPHandler::ResultSuccess, QString()); 0185 } else { 0186 if (m_parentWidget) { 0187 KMessageBox::error(m_parentWidget, 0188 i18n("Unable to forward the item '%1'", m_queuedInvitation.incidence->summary()), 0189 i18nc("@title:window", "Forwarding Error")); 0190 } 0191 qCritical() << "Sent as iCalendar failed." << errorMessage; 0192 Q_EMIT q->sentAsICalendar(ITIPHandler::ResultError, errorMessage); 0193 } 0194 0195 sender()->deleteLater(); // Delete the mailer 0196 } 0197 0198 CalendarBase::Ptr ITIPHandlerPrivate::calendar() 0199 { 0200 if (!m_calendar) { 0201 FetchJobCalendar::Ptr fetchJobCalendar = FetchJobCalendar::Ptr(new FetchJobCalendar()); 0202 connect(fetchJobCalendar.data(), &FetchJobCalendar::loadFinished, this, &ITIPHandlerPrivate::onLoadFinished); 0203 0204 m_calendar = fetchJobCalendar; 0205 } 0206 0207 return m_calendar; 0208 } 0209 0210 bool ITIPHandlerPrivate::isLoaded() 0211 { 0212 FetchJobCalendar::Ptr fetchJobCalendar = calendar().dynamicCast<Akonadi::FetchJobCalendar>(); 0213 if (fetchJobCalendar) { 0214 return !fetchJobCalendar->isLoading(); 0215 } 0216 0217 // If it's an ETMCalendar, set through setCalendar(), then it's already loaded, it's a requirement of setCalendar(). 0218 // ETM doesn't have any way to check if it's already populated, so we have to require loaded calendars. 0219 return true; 0220 } 0221 0222 #include "moc_itiphandler_p.cpp"