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-FileCopyrightText: 2012 Sérgio Martins <iamsergio@gmail.com> 9 10 SPDX-License-Identifier: LGPL-2.0-or-later 11 */ 12 13 #pragma once 14 15 #include "akonadi-calendar_export.h" 16 #include "etmcalendar.h" 17 18 #include <KCalendarCore/Incidence> 19 #include <KCalendarCore/ScheduleMessage> 20 21 #include <KGuiItem> 22 #include <KLocalizedString> 23 24 #include <QObject> 25 #include <QString> 26 #include <QWidget> 27 28 #include <memory> 29 30 namespace MailTransport 31 { 32 class MessageQueueJob; 33 } 34 35 namespace KIdentityManagement 36 { 37 class Identity; 38 } 39 40 namespace Akonadi 41 { 42 class ITIPHandlerPrivate; 43 44 /** 45 * @short Ui delegate for editing counter proposals. 46 * @since 4.11 47 */ 48 class AKONADI_CALENDAR_EXPORT GroupwareUiDelegate : public QObject 49 { 50 Q_OBJECT 51 public: 52 explicit GroupwareUiDelegate(QObject *parent = nullptr); 53 ~GroupwareUiDelegate() override; 54 55 virtual void requestIncidenceEditor(const Akonadi::Item &item) = 0; 56 virtual void setCalendar(const Akonadi::ETMCalendar::Ptr &calendar) = 0; 57 virtual void createCalendar() = 0; 58 }; 59 60 /** 61 * @short Ui delegate for dialogs raised by the ITIPHandler and IncidenceChanger. 62 * @since 4.15 63 */ 64 class AKONADI_CALENDAR_EXPORT ITIPHandlerDialogDelegate : public QObject 65 { 66 Q_OBJECT 67 public: 68 // Possible default actions 69 enum Action { 70 ActionAsk, /**< Ask the user for a decision */ 71 ActionSendMessage, /**< Answer with Yes */ 72 ActionDontSendMessage /**< Answer with No */ 73 }; 74 75 // How will receive the mail afterwards 76 enum Recipient { 77 Organizer, /**< the organizer of the incidence */ 78 Attendees /**< the attendees of the incidence */ 79 }; 80 81 /** 82 * Creates a new AskDelegator 83 */ 84 explicit ITIPHandlerDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent = nullptr); 85 86 /* 87 * Opens a Dialog, when an incidence is created 88 * The function must emit a dialogClosed signal with the user's answer 89 * 90 * @param recipient: to who the mail will be sent afterwards 91 * @param question: dialog's question 92 * @param action: Should the dialog been shown or should a default answer be returned 93 * @param buttonYes: dialog's yes answer 94 * @param buttonNo: dialog's no answer 95 */ 96 virtual void openDialogIncidenceCreated(Recipient recipient, 97 const QString &question, 98 Action action = ActionAsk, 99 const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")), 100 const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send"))); 101 102 /* 103 * Opens a Dialog, when an incidence is modified 104 * The function must emit a dialogClosed signal with the user's answer 105 * 106 * @param attendeeStatusChanged: Only the status of the own attendeeStatus is changed 107 * @param recipient: to who the mail will be sent afterwards 108 * @param question: dialog's question 109 * @param action: Should the dialog been shown or should a default answer be returned 110 * @param buttonYes: dialog's yes answer 111 * @param buttonNo: dialog's no answer 112 */ 113 virtual void openDialogIncidenceModified(bool attendeeStatusChanged, 114 Recipient recipient, 115 const QString &question, 116 Action action = ActionAsk, 117 const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")), 118 const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send"))); 119 120 /* 121 * Opens a Dialog, when an incidence is deleted 122 * The function must emit a dialogClosed signal with the user's answer 123 * 124 * @param recipient: to who the mail will be sent afterwards 125 * @param question: dialog's question 126 * @param action: Should the dialog been shown or should a default answer be returned 127 * @param buttonYes: dialog's yes answer 128 * @param buttonNo: dialog's no answer 129 */ 130 virtual void openDialogIncidenceDeleted(Recipient recipient, 131 const QString &question, 132 Action action = ActionAsk, 133 const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")), 134 const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send"))); 135 /* 136 * Opens a Dialog, when mail was sended 137 * The function must emit a dialogClosed signal with the user's answer 138 * 139 * @param question: dialog's question 140 * @param action: Should the dialog been shown or should a default answer be returned 141 * @param buttonYes: dialog's yes answer 142 * @param buttonNo: dialog's no answer 143 */ 144 virtual void openDialogSchedulerFinished(const QString &question, 145 Action action = ActionAsk, 146 const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")), 147 const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send"))); 148 149 Q_SIGNALS: 150 /* 151 * Signal is emitted, when the user has answered the dialog or the defaultAction is used 152 * @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 153 * KMessageBox::No 154 * @param method: itip method 155 * @param incidence: purpose of the dialog 156 */ 157 void dialogClosed(int answer, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence); 158 159 protected: 160 /* 161 * Opens a KMessageBox::questionYesNo with the question 162 * 163 * @return KMessageBox::Yes or KMessageBox::No 164 * 165 * @param question: dialog's question 166 * @param action: Should the dialog been shown or should a default answer be returned 167 * @param buttonYes: dialog's yes answer 168 * @param buttonNo: dialog's no answer 169 */ 170 int askUserIfNeeded(const QString &question, Action action, const KGuiItem &buttonYes, const KGuiItem &buttonNo) const; 171 172 // parent of the dialog 173 QWidget *mParent = nullptr; 174 175 // Incidence related to the dialog 176 KCalendarCore::Incidence::Ptr mIncidence; 177 178 // ITIPMethod related to the dialog 179 KCalendarCore::iTIPMethod mMethod; 180 }; 181 182 /** 183 * @short Factory to create MailTransport::MessageQueueJob jobs or ITIPHandlerDialogDelegate objects. 184 * @since 4.15 185 */ 186 class AKONADI_CALENDAR_EXPORT ITIPHandlerComponentFactory : public QObject 187 { 188 Q_OBJECT 189 public: 190 /* 191 * Created a new ITIPHandlerComponentFactory object. 192 */ 193 explicit ITIPHandlerComponentFactory(QObject *parent = nullptr); 194 195 /* 196 * deletes the object. 197 */ 198 ~ITIPHandlerComponentFactory() override; 199 200 /* 201 * @return A new MailTransport::MessageQueueJob object 202 * @param incidence related to the mail 203 * @param identity that is the mail sender 204 * @param parent of the MailTransport::MessageQueueJob object 205 */ 206 virtual MailTransport::MessageQueueJob * 207 createMessageQueueJob(const KCalendarCore::IncidenceBase::Ptr &incidence, const KIdentityManagement::Identity &identity, QObject *parent = nullptr); 208 209 /* 210 * @return A new ITIPHandlerDialogDelegate object 211 * @param incidence the purpose of the dialogs 212 * @param method the ITIPMethod 213 * @parent parent of the AskDelegator 214 * 215 */ 216 virtual ITIPHandlerDialogDelegate * 217 createITIPHanderDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent = nullptr); 218 }; 219 220 /** 221 * @short Handles sending of iTip messages as well as processing incoming ones. 222 * @since 4.11 223 */ 224 class AKONADI_CALENDAR_EXPORT ITIPHandler : public QObject 225 { 226 Q_OBJECT 227 public: 228 enum Result { 229 ResultError, /**< An unexpected error occurred */ 230 ResultSuccess, /**< The invitation was successfully handled. */ 231 ResultCancelled /**< User cancelled the operation. @since 4.12 */ 232 }; 233 234 /** 235 * Creates a new ITIPHandler instance. 236 * creates a default ITIPHandlerComponentFactory object. 237 */ 238 explicit ITIPHandler(QObject *parent = nullptr); 239 240 /** 241 * Create a new ITIPHandler instance. 242 * @param factory is set to 0 a new factory is created. 243 * @since 4.15 244 */ 245 explicit ITIPHandler(ITIPHandlerComponentFactory *factory, QObject *parent); 246 /** 247 * Destroys this instance. 248 */ 249 ~ITIPHandler() override; 250 251 /** 252 * Processes a received iTip message. 253 * 254 * @param receiver 255 * @param iCal 256 * @param type 257 * 258 * @see iTipMessageProcessed() 259 */ 260 void processiTIPMessage(const QString &receiver, const QString &iCal, const QString &type); 261 262 /** 263 * Sends an iTip message. 264 * 265 * @param method iTip method 266 * @param incidence Incidence for which we're sending the iTip message. 267 * Should contain a list of attendees. 268 * @param parentWidget 269 */ 270 void sendiTIPMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence, QWidget *parentWidget = nullptr); 271 272 /** 273 * Publishes incidence @p incidence. 274 * A publish dialog will prompt the user to input recipients. 275 * @see rfc2446 3.2.1 276 */ 277 void publishInformation(const KCalendarCore::Incidence::Ptr &incidence, QWidget *parentWidget = nullptr); 278 279 /** 280 * Sends an e-mail with the incidence attached as iCalendar source. 281 * A dialog will prompt the user to input recipients. 282 */ 283 void sendAsICalendar(const KCalendarCore::Incidence::Ptr &incidence, QWidget *parentWidget = nullptr); 284 285 /** 286 * Sets the UI delegate to edit counter proposals. 287 */ 288 void setGroupwareUiDelegate(GroupwareUiDelegate *delegate); 289 290 /** 291 * Sets the calendar that the itip handler should use. 292 * The calendar should already be loaded. 293 * 294 * If none is set, a FetchJobCalendar will be created internally. 295 */ 296 void setCalendar(const Akonadi::CalendarBase::Ptr &calendar); 297 298 /** 299 * Sets if the ITIP handler should show dialogs on error. 300 * Default is true, for compatibility reasons, but this will change in KDE5. 301 * TODO_KDE5: use message delegates 302 * 303 * @since 4.12 304 */ 305 void setShowDialogsOnError(bool enable); 306 307 /** 308 * Returns the calendar used by this itip handler. 309 */ 310 Akonadi::CalendarBase::Ptr calendar() const; 311 312 Q_SIGNALS: 313 /** 314 * Sent after processing an incoming iTip message. 315 * 316 * @param result success of the operation. 317 * @param errorMessage translated error message suitable for user dialogs. 318 * Empty if the operation was successful 319 */ 320 void iTipMessageProcessed(Akonadi::ITIPHandler::Result result, const QString &errorMessage); 321 322 /** 323 * Signal emitted after an iTip message was sent through sendiTIPMessage() 324 */ 325 void iTipMessageSent(Akonadi::ITIPHandler::Result, const QString &errorMessage); 326 327 /** 328 * Signal emitted after an incidence was published with publishInformation() 329 */ 330 void informationPublished(Akonadi::ITIPHandler::Result, const QString &errorMessage); 331 332 /** 333 * Signal emitted after an incidence was sent with sendAsICalendar() 334 */ 335 void sentAsICalendar(Akonadi::ITIPHandler::Result, const QString &errorMessage); 336 337 private: 338 Q_DISABLE_COPY(ITIPHandler) 339 std::unique_ptr<ITIPHandlerPrivate> const d; 340 }; 341 } 342 343