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 #pragma once
0012 
0013 #include "itiphandler.h"
0014 #include "mailscheduler_p.h"
0015 
0016 #include <KCalendarCore/Incidence>
0017 #include <KCalendarCore/ScheduleMessage>
0018 
0019 #include <QObject>
0020 
0021 class QWidget;
0022 
0023 namespace Akonadi
0024 {
0025 enum Status { StatusNone, StatusSendingInvitation };
0026 
0027 /**
0028   This class handles sending of invitations to attendees when Incidences (e.g.
0029   events or todos) are created/modified/deleted.
0030 
0031   There are two scenarios:
0032   o "we" are the organizer, where "we" means any of the identities or mail
0033     addresses known to Kontact/PIM. If there are attendees, we need to mail
0034     them all, even if one or more of them are also "us". Otherwise there
0035     would be no way to invite a resource or our boss, other identities we
0036     also manage.
0037   o "we: are not the organizer, which means we changed the completion status
0038     of a todo, or we changed our attendee status from, say, tentative to
0039     accepted. In both cases we only mail the organizer. All other changes
0040     bring us out of sync with the organizer, so we won't mail, if the user
0041     insists on applying them.
0042 
0043   NOTE: Currently only events and todos are support, meaning Incidence::type()
0044         should either return "Event" or "Todo"
0045  */
0046 class ITIPHandlerHelper : public QObject
0047 {
0048     Q_OBJECT
0049 public:
0050     explicit ITIPHandlerHelper(ITIPHandlerComponentFactory *factory, QWidget *parent = nullptr);
0051     ~ITIPHandlerHelper() override;
0052 
0053     enum SendResult {
0054         ResultCanceled, /**< Sending was canceled by the user, meaning there are
0055                            local changes of which other attendees are not aware. */
0056         ResultFailKeepUpdate, /**< Sending failed, the changes to the incidence must be kept. */
0057         ResultFailAbortUpdate, /**< Sending failed, the changes to the incidence must be undone. */
0058         ResultNoSendingNeeded, /**< In some cases it is not needed to send an invitation
0059                                 (e.g. when we are the only attendee) */
0060         ResultError, /**< An unexpected error occurred */
0061         ResultSuccess, /**< The invitation was sent to all attendees. */
0062         ResultPending /**< The user has been asked about one detail, waiting for the answer */
0063     };
0064 
0065     enum MessagePrivacy { MessagePrivacyPlain = 0, MessagePrivacySign = 1, MessagePrivacyEncrypt = 2 };
0066     Q_DECLARE_FLAGS(MessagePrivacyFlags, MessagePrivacy)
0067 
0068     /**
0069       When an Incidence is created/modified/deleted the user can choose to send
0070       an ICal message to the other participants. By default the user will be asked
0071       if he wants to send a message to other participants. In some cases it is
0072       preferably though to not bother the user with this question. This method
0073       allows to change the default behavior. This method applies to the
0074       sendIncidence*Message() methods.
0075       @param action the action to set as default
0076      */
0077     void setDefaultAction(ITIPHandlerDialogDelegate::Action action);
0078 
0079     /**
0080      * Sets the default privacy rules for the message.
0081      */
0082     void setMessagePrivacy(MessagePrivacyFlags messagePrivacy);
0083 
0084     /**
0085       Before an invitation is sent the user is asked for confirmation by means of
0086       an dialog.
0087       @param parent The parent widget used for the dialogs.
0088      */
0089     void setDialogParent(QWidget *parent);
0090 
0091     /**
0092       Handles sending of invitations for newly created incidences. This method
0093       asserts that we (as in any of the identities or mail addresses known to
0094       Kontact/PIM) are the organizer.
0095       @param incidence The new incidence.
0096      */
0097     void sendIncidenceCreatedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0098 
0099     /**
0100        Checks if the incidence should really be modified.
0101 
0102        If the user is not the organizer of this incidence, he will be asked if he really
0103        wants to proceed.
0104 
0105        Only create the ItemModifyJob if this method returns true.
0106 
0107        @param incidence The modified incidence. It may not be null.
0108      */
0109     bool handleIncidenceAboutToBeModified(const KCalendarCore::Incidence::Ptr &incidence);
0110 
0111     /**
0112       Handles sending of invitations for modified incidences.
0113       @param incidence The modified incidence.
0114       @param attendeeStatusChanged if @c true and @p method is #iTIPRequest ask the user whether to send a status update as well
0115      */
0116     void sendIncidenceModifiedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence, bool attendeeStatusChanged);
0117 
0118     /**
0119       Handles sending of ivitations for deleted incidences.
0120       @param incidence The deleted incidence.
0121      */
0122     void sendIncidenceDeletedMessage(KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0123 
0124     /**
0125       Send counter proposal message.
0126       @param receiver Recipient email of the original invitation.
0127       @param oldIncidence The original event provided in the invitations.
0128       @param newIncidence The new event as edited by the user.
0129     */
0130     ITIPHandlerHelper::SendResult
0131     sendCounterProposal(const QString &receiver, const KCalendarCore::Incidence::Ptr &oldIncidence, const KCalendarCore::Incidence::Ptr &newIncidence);
0132 
0133 Q_SIGNALS:
0134     void finished(Akonadi::ITIPHandlerHelper::SendResult result, const QString &errorMessage);
0135 
0136     void sendIncidenceDeletedMessageFinished(ITIPHandlerHelper::SendResult, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0137     void sendIncidenceModifiedMessageFinished(ITIPHandlerHelper::SendResult, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0138     void sendIncidenceCreatedMessageFinished(ITIPHandlerHelper::SendResult, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0139 
0140 private Q_SLOTS:
0141     void onSchedulerFinished(Akonadi::Scheduler::Result result, const QString &errorMsg);
0142 
0143     void slotIncidenceDeletedDialogClosed(const int, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0144     void slotIncidenceModifiedDialogClosed(const int, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0145     void slotIncidenceCreatedDialogClosed(const int, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0146 
0147     void slotSchedulerFinishDialog(const int result, KCalendarCore::iTIPMethod method, const KCalendarCore::Incidence::Ptr &incidence);
0148 
0149 private:
0150     ITIPHandlerHelper::SendResult
0151     sentInvitation(int messageBoxReturnCode, const KCalendarCore::Incidence::Ptr &incidence, KCalendarCore::iTIPMethod method, const QString &sender = {});
0152 
0153     /**
0154       We are the organizer. If there is more than one attendee, or if there is
0155       only one, and it's not the same as the organizer, ask the user to send
0156       mail.
0157     */
0158     bool weAreOrganizerOf(const KCalendarCore::Incidence::Ptr &incidence);
0159 
0160     /**
0161       Assumes that we are the organizer. If there is more than one attendee, or if
0162       there is only one, and it's not the same as the organizer, ask the user to send
0163       mail.
0164      */
0165     bool weNeedToSendMailFor(const KCalendarCore::Incidence::Ptr &incidence);
0166 
0167     ITIPHandlerDialogDelegate::Action mDefaultAction;
0168     QWidget *mParent = nullptr;
0169     ITIPHandlerComponentFactory *m_factory = nullptr;
0170     MailScheduler *m_scheduler = nullptr;
0171     Status m_status;
0172     MessagePrivacyFlags m_messagePrivacy = MessagePrivacyPlain;
0173 };
0174 }
0175 
0176 Q_DECLARE_OPERATORS_FOR_FLAGS(Akonadi::ITIPHandlerHelper::MessagePrivacyFlags)