File indexing completed on 2024-05-12 05:10:47

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-FileCopyrightText: 2012 SĂ©rgio Martins <iamsergio@gmail.com>
0009 
0010   SPDX-License-Identifier: LGPL-2.0-or-later
0011 */
0012 
0013 #pragma once
0014 
0015 #include "akonadi-calendar_export.h"
0016 #include "etmcalendar.h"
0017 
0018 #include <KCalendarCore/Incidence>
0019 #include <KCalendarCore/ScheduleMessage>
0020 
0021 #include <KGuiItem>
0022 #include <KLocalizedString>
0023 #include <KStandardGuiItem>
0024 
0025 #include <QObject>
0026 #include <QString>
0027 #include <QWidget>
0028 
0029 #include <memory>
0030 
0031 namespace Akonadi
0032 {
0033 class MessageQueueJob;
0034 }
0035 
0036 namespace KIdentityManagementCore
0037 {
0038 class Identity;
0039 }
0040 
0041 namespace Akonadi
0042 {
0043 class ITIPHandlerPrivate;
0044 
0045 /**
0046  * @short Ui delegate for editing counter proposals.
0047  * @since 4.11
0048  */
0049 class AKONADI_CALENDAR_EXPORT GroupwareUiDelegate : public QObject
0050 {
0051     Q_OBJECT
0052 public:
0053     explicit GroupwareUiDelegate(QObject *parent = nullptr);
0054     ~GroupwareUiDelegate() override;
0055 
0056     virtual void requestIncidenceEditor(const Akonadi::Item &item) = 0;
0057     virtual void setCalendar(const Akonadi::ETMCalendar::Ptr &calendar) = 0;
0058     virtual void createCalendar() = 0;
0059 };
0060 
0061 /**
0062  * @short Ui delegate for dialogs raised by the ITIPHandler and IncidenceChanger.
0063  * @since 4.15
0064  */
0065 class AKONADI_CALENDAR_EXPORT ITIPHandlerDialogDelegate : public QObject
0066 {
0067     Q_OBJECT
0068 public:
0069     // Possible default actions
0070     enum Action {
0071         ActionAsk, /**< Ask the user for a decision */
0072         ActionSendMessage, /**< Answer with Yes */
0073         ActionDontSendMessage /**< Answer with No */
0074     };
0075 
0076     // How will receive the mail afterwards
0077     enum Recipient {
0078         Organizer, /**< the organizer of the incidence */
0079         Attendees /**< the attendees of the incidence */
0080     };
0081 
0082     enum DialogAction { OkAction = 1, CancelAction = 2, PrimaryAction = 3, SecondaryAction = 4, ContinueAction = 5 };
0083 
0084     /**
0085      * Creates a new AskDelegator
0086      */
0087     explicit ITIPHandlerDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent = nullptr);
0088 
0089     /*
0090      * Opens a Dialog, when an incidence is created
0091      * The function must emit a dialogClosed signal with the user's answer
0092      *
0093      * @param recipient: to who the mail will be sent afterwards
0094      * @param question: dialog's question
0095      * @param action: Should the dialog been shown or should a default answer be returned
0096      * @param buttonYes: dialog's yes answer
0097      * @param buttonNo: dialog's no answer
0098      */
0099     virtual void openDialogIncidenceCreated(Recipient recipient,
0100                                             const QString &question,
0101                                             Action action = ActionAsk,
0102                                             const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
0103                                             const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
0104 
0105     /*
0106      * Opens a Dialog, when an incidence is modified
0107      * The function must emit a dialogClosed signal with the user's answer
0108      *
0109      * @param attendeeStatusChanged: Only the status of the own attendeeStatus is changed
0110      * @param recipient: to who the mail will be sent afterwards
0111      * @param question: dialog's question
0112      * @param action: Should the dialog been shown or should a default answer be returned
0113      * @param buttonYes: dialog's yes answer
0114      * @param buttonNo: dialog's no answer
0115      */
0116     virtual void openDialogIncidenceModified(bool attendeeStatusChanged,
0117                                              Recipient recipient,
0118                                              const QString &question,
0119                                              Action action = ActionAsk,
0120                                              const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
0121                                              const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
0122 
0123     /*
0124      * Opens a Dialog, when an incidence is deleted
0125      * The function must emit a dialogClosed signal with the user's answer
0126      *
0127      * @param recipient: to who the mail will be sent afterwards
0128      * @param question: dialog's question
0129      * @param action: Should the dialog been shown or should a default answer be returned
0130      * @param buttonYes: dialog's yes answer
0131      * @param buttonNo: dialog's no answer
0132      */
0133     virtual void openDialogIncidenceDeleted(Recipient recipient,
0134                                             const QString &question,
0135                                             Action action = ActionAsk,
0136                                             const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
0137                                             const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
0138     /*
0139      * Opens a Dialog, when mail was sended
0140      * The function must emit a dialogClosed signal with the user's answer
0141      *
0142      * @param question: dialog's question
0143      * @param action: Should the dialog been shown or should a default answer be returned
0144      * @param buttonYes: dialog's yes answer
0145      * @param buttonNo: dialog's no answer
0146      */
0147     virtual void openDialogSchedulerFinished(const QString &question,
0148                                              Action action = ActionAsk,
0149                                              const KGuiItem &buttonYes = KGuiItem(i18nc("@action:button dialog positive answer", "Send Email")),
0150                                              const KGuiItem &buttonNo = KGuiItem(i18nc("@action:button dialog negative answer", "Do Not Send")));
0151 
0152     /**
0153      * Opens a warning message box with two accept actions and cancel action.
0154      * @param text: dialog's text
0155      * @param title: dialog's title
0156      * @param primaryAction: dialog's primary action
0157      * @param secondaryAction: dialog's secondary action
0158      * @param cancelAction: dialog's cancel action
0159      * @returns The button clicked by the user (KMessageBox::ButtonCode)
0160      */
0161     virtual int warningTwoActionsCancel(const QString &text,
0162                                         const QString &title,
0163                                         const KGuiItem &primaryAction,
0164                                         const KGuiItem &secondaryAction,
0165                                         const KGuiItem &cancelAction = KStandardGuiItem::cancel());
0166     /**
0167      * Opens a warning message box with a Continue and Cancel actions
0168      * @param text: dialog's text
0169      * @param title: dialog's title
0170      * @param buttonContinue: dialog's continue answer
0171      * @param buttonCancel: dialog's cancel answer.
0172      * @returns The button clicked by the user (KMessageBox::ButtonCode)
0173      */
0174     virtual int warningContinueCancel(const QString &text,
0175                                       const QString &title,
0176                                       const KGuiItem &buttonContinue = KStandardGuiItem::cont(),
0177                                       const KGuiItem &buttonCancel = KStandardGuiItem::cancel());
0178 
0179 Q_SIGNALS:
0180     /*
0181      * Signal is emitted, when the user has answered the dialog or the defaultAction is used
0182      * @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
0183      * KMessageBox::No
0184      * @param method: itip method
0185      * @param incidence: purpose of the dialog
0186      */
0187     void dialogClosed(int answer, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0188 
0189 protected:
0190     /*
0191      * Opens a KMessageBox::questionYesNo with the question
0192      *
0193      * @return KMessageBox::Yes or KMessageBox::No
0194      *
0195      * @param question: dialog's question
0196      * @param action: Should the dialog been shown or should a default answer be returned
0197      * @param buttonYes: dialog's yes answer
0198      * @param buttonNo: dialog's no answer
0199      */
0200     int askUserIfNeeded(const QString &question, Action action, const KGuiItem &buttonYes, const KGuiItem &buttonNo) const;
0201 
0202     // parent of the dialog
0203     QWidget *mParent = nullptr;
0204 
0205     // Incidence related to the dialog
0206     KCalendarCore::Incidence::Ptr mIncidence;
0207 
0208     // ITIPMethod related to the dialog
0209     KCalendarCore::iTIPMethod mMethod;
0210 };
0211 
0212 /**
0213  * @short Factory to create Akonadi::MessageQueueJob jobs or ITIPHandlerDialogDelegate objects.
0214  * @since 4.15
0215  */
0216 class AKONADI_CALENDAR_EXPORT ITIPHandlerComponentFactory : public QObject
0217 {
0218     Q_OBJECT
0219 public:
0220     /*
0221      * Created a new ITIPHandlerComponentFactory object.
0222      */
0223     explicit ITIPHandlerComponentFactory(QObject *parent = nullptr);
0224 
0225     /*
0226      * deletes the object.
0227      */
0228     ~ITIPHandlerComponentFactory() override;
0229 
0230     /*
0231      * @return A new Akonadi::MessageQueueJob object
0232      * @param incidence related to the mail
0233      * @param identity that is the mail sender
0234      * @param parent of the Akonadi::MessageQueueJob object
0235      */
0236     virtual Akonadi::MessageQueueJob *
0237     createMessageQueueJob(const KCalendarCore::IncidenceBase::Ptr &incidence, const KIdentityManagementCore::Identity &identity, QObject *parent = nullptr);
0238 
0239     /*
0240      * @return A new ITIPHandlerDialogDelegate object
0241      * @param incidence the purpose of the dialogs
0242      * @param method the ITIPMethod
0243      * @parent parent of the AskDelegator
0244      *
0245      */
0246     virtual ITIPHandlerDialogDelegate *
0247     createITIPHanderDialogDelegate(const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, QWidget *parent = nullptr);
0248 };
0249 
0250 /**
0251  * @short Handles sending of iTip messages as well as processing incoming ones.
0252  * @since 4.11
0253  */
0254 class AKONADI_CALENDAR_EXPORT ITIPHandler : public QObject
0255 {
0256     Q_OBJECT
0257 public:
0258     enum Result {
0259         ResultError, /**< An unexpected error occurred */
0260         ResultSuccess, /**< The invitation was successfully handled. */
0261         ResultCancelled /**< User cancelled the operation. @since 4.12 */
0262     };
0263 
0264     /**
0265      * Creates a new ITIPHandler instance.
0266      * creates a default ITIPHandlerComponentFactory object.
0267      */
0268     explicit ITIPHandler(QObject *parent = nullptr);
0269 
0270     /**
0271      * Create a new ITIPHandler instance.
0272      * @param factory is set to 0 a new factory is created.
0273      * @since 4.15
0274      */
0275     explicit ITIPHandler(ITIPHandlerComponentFactory *factory, QObject *parent);
0276     /**
0277      * Destroys this instance.
0278      */
0279     ~ITIPHandler() override;
0280 
0281     /**
0282      * Processes a received iTip message.
0283      *
0284      * @param receiver
0285      * @param iCal
0286      * @param type
0287      *
0288      * @see iTipMessageProcessed()
0289      */
0290     void processiTIPMessage(const QString &receiver, const QString &iCal, const QString &type);
0291 
0292     /**
0293      * Sends an iTip message.
0294      *
0295      * @param method iTip method
0296      * @param incidence Incidence for which we're sending the iTip message.
0297      *                  Should contain a list of attendees.
0298      * @param parentWidget
0299      */
0300     void sendiTIPMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence, QWidget *parentWidget = nullptr);
0301 
0302     /**
0303      * Publishes incidence @p incidence.
0304      * A publish dialog will prompt the user to input recipients.
0305      * @see rfc2446 3.2.1
0306      */
0307     void publishInformation(const KCalendarCore::Incidence::Ptr &incidence, QWidget *parentWidget = nullptr);
0308 
0309     /**
0310      * Sends an e-mail with the incidence attached as iCalendar source.
0311      * A dialog will prompt the user to input recipients.
0312      */
0313     void sendAsICalendar(const KCalendarCore::Incidence::Ptr &incidence, QWidget *parentWidget = nullptr);
0314 
0315     /**
0316      * Sets the UI delegate to edit counter proposals.
0317      */
0318     void setGroupwareUiDelegate(GroupwareUiDelegate *delegate);
0319 
0320     /**
0321      * Sets the calendar that the itip handler should use.
0322      * The calendar should already be loaded.
0323      *
0324      * If none is set, a FetchJobCalendar will be created internally.
0325      */
0326     void setCalendar(const Akonadi::CalendarBase::Ptr &calendar);
0327 
0328     /**
0329      * Sets if the ITIP handler should show dialogs on error.
0330      * Default is true, for compatibility reasons, but this will change in KDE5.
0331      * TODO_KDE5: use message delegates
0332      *
0333      * @since 4.12
0334      */
0335     void setShowDialogsOnError(bool enable);
0336 
0337     /**
0338      * Returns the calendar used by this itip handler.
0339      */
0340     Akonadi::CalendarBase::Ptr calendar() const;
0341 
0342 Q_SIGNALS:
0343     /**
0344      * Sent after processing an incoming iTip message.
0345      *
0346      * @param result success of the operation.
0347      * @param errorMessage translated error message suitable for user dialogs.
0348      *                     Empty if the operation was successful
0349      */
0350     void iTipMessageProcessed(Akonadi::ITIPHandler::Result result, const QString &errorMessage);
0351 
0352     /**
0353      * Signal emitted after an iTip message was sent through sendiTIPMessage()
0354      */
0355     void iTipMessageSent(Akonadi::ITIPHandler::Result, const QString &errorMessage);
0356 
0357     /**
0358      * Signal emitted after an incidence was published with publishInformation()
0359      */
0360     void informationPublished(Akonadi::ITIPHandler::Result, const QString &errorMessage);
0361 
0362     /**
0363      * Signal emitted after an incidence was sent with sendAsICalendar()
0364      */
0365     void sentAsICalendar(Akonadi::ITIPHandler::Result, const QString &errorMessage);
0366 
0367 private:
0368     Q_DISABLE_COPY(ITIPHandler)
0369     std::unique_ptr<ITIPHandlerPrivate> const d;
0370 };
0371 }