File indexing completed on 2024-04-28 05:11:32

0001 /*
0002   SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org>
0003   SPDX-FileCopyrightText: 2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
0004 
0005   SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include <Akonadi/Collection>
0011 #include <Akonadi/IncidenceChanger>
0012 #include <QObject>
0013 
0014 #include <memory>
0015 
0016 namespace Akonadi
0017 {
0018 class Item;
0019 }
0020 
0021 class KJob;
0022 
0023 namespace IncidenceEditorNG
0024 {
0025 class ItemEditorUi;
0026 class ItemEditorPrivate;
0027 
0028 /**
0029  * Helper class for creating dialogs that let the user create and edit the payload
0030  * of Akonadi items (e.g. events, contacts, etc). This class supports editing of
0031  * one item at a time and handles all Akonadi specific logic like Item creation,
0032  * Item modifying and monitoring of changes to the item during editing.
0033  */
0034 // template <typename PayloadT>
0035 class EditorItemManager : public QObject
0036 {
0037     Q_OBJECT
0038 public:
0039     enum ItipPrivacy { ItipPrivacyPlain = 0, ItipPrivacySign = 1, ItipPrivacyEncrypt = 2 };
0040     Q_DECLARE_FLAGS(ItipPrivacyFlags, ItipPrivacy)
0041 
0042     /**
0043      * Creates an ItemEditor for a new Item.
0044      * Receives an option IncidenceChanger, so you can share the undo/redo stack with your
0045      * application.
0046      */
0047     explicit EditorItemManager(ItemEditorUi *ui, Akonadi::IncidenceChanger *changer = nullptr);
0048 
0049     /**
0050      * Destructs the ItemEditor. Unsaved changes will get lost at this point.
0051      */
0052     ~EditorItemManager() override;
0053 
0054     enum ItemState {
0055         AfterSave, /**< Returns the last saved item */
0056         BeforeSave /**< Returns an item with the original payload before the last save call */
0057     };
0058 
0059     /**
0060      * Returns the last saved item with payload or an invalid item when save is
0061      * not called yet.
0062      */
0063     [[nodiscard]] Akonadi::Item item(ItemState state = AfterSave) const;
0064 
0065     /**
0066      * Loads the @param item into the editor. The item passed must be
0067      * a valid item.
0068      */
0069     void load(const Akonadi::Item &item);
0070 
0071     /**
0072      * Saves the new or modified item. This method does nothing when the
0073      * ui is not dirty.
0074      */
0075     void save(ItipPrivacyFlags itipPrivacy = ItipPrivacyPlain);
0076 
0077     enum SaveAction {
0078         Create, /**< A new item was created */
0079         Modify, /**< An existing item was modified */
0080         None, /**< Nothing happened. */
0081         Move, /**< An existing item was moved to another collection */
0082         MoveAndModify /**< An existing item was moved to another collection and modified */
0083     };
0084 
0085     void setIsCounterProposal(bool isCounterProposal);
0086 
0087 Q_SIGNALS:
0088     void itemSaveFinished(IncidenceEditorNG::EditorItemManager::SaveAction action);
0089 
0090     void itemSaveFailed(IncidenceEditorNG::EditorItemManager::SaveAction action, const QString &message);
0091 
0092     void revertFinished();
0093     void revertFailed(const QString &message);
0094 
0095 private:
0096     std::unique_ptr<ItemEditorPrivate> const d_ptr;
0097     Q_DECLARE_PRIVATE(ItemEditor)
0098     Q_DISABLE_COPY(EditorItemManager)
0099 };
0100 
0101 class ItemEditorUi
0102 {
0103 public:
0104     enum RejectReason {
0105         ItemFetchFailed, ///> Either the fetchjob failed or no items where returned
0106         ItemHasInvalidPayload, ///> The fetched item has an invalid payload
0107         ItemMoveFailed ///> Item move failed
0108     };
0109 
0110     virtual ~ItemEditorUi();
0111 
0112     /**
0113      * Returns whether or not the identifier set contains payload identifiers that
0114      * are displayed/editable in the Gui.
0115      */
0116     virtual bool containsPayloadIdentifiers(const QSet<QByteArray> &partIdentifiers) const = 0;
0117 
0118     /**
0119      * Returns whether or not @param item has a payload type that is supported by
0120      * the gui.
0121      */
0122     virtual bool hasSupportedPayload(const Akonadi::Item &item) const = 0;
0123 
0124     /**
0125      * Returns whether or not the values in the ui differ from the original (i.e.
0126      * either an empty or a loaded item). This method <em>only</em> involves
0127      * payload fields. I.e. if only the collection in which the item should be
0128      * stored has changed, this method should return false.
0129      */
0130     virtual bool isDirty() const = 0;
0131 
0132     /**
0133      * Returns whether or not the values in the ui are valid. This method can also
0134      * be used to update the ui if necessary. The default implementation returns
0135      * true, so if the ui doesn't need validation there is no need to reimplement
0136      * this method.
0137      */
0138     virtual bool isValid() const;
0139 
0140     /**
0141      * Fills the ui with the values of the payload of @param item. The item is
0142      * guaranteed to have a payload.
0143      */
0144     virtual void load(const Akonadi::Item &item) = 0;
0145 
0146     /**
0147      * Stores the values of the ui into the payload of @param item and returns the
0148      * item with an updated payload. The returned item must have a valid mimetype
0149      * too.
0150      */
0151     virtual Akonadi::Item save(const Akonadi::Item &item) = 0;
0152 
0153     /**
0154      * Returns the currently selected collection in which the item will be stored.
0155      */
0156     virtual Akonadi::Collection selectedCollection() const = 0;
0157 
0158     /**
0159      * This function is called if for some reason the creation or editing of the
0160      * item cannot be continued. The implementing class must abort editing at
0161      * this point.
0162      */
0163     virtual void reject(RejectReason reason, const QString &errorMessage = QString()) = 0;
0164 };
0165 }
0166 
0167 Q_DECLARE_OPERATORS_FOR_FLAGS(IncidenceEditorNG::EditorItemManager::ItipPrivacyFlags)