File indexing completed on 2025-01-05 04:47:11

0001 /*
0002     SPDX-FileCopyrightText: 2008 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "akonadiwidgets_export.h"
0010 
0011 // AkonadiCore
0012 #include "akonadi/collection.h"
0013 #include "akonadi/item.h"
0014 
0015 #include <QObject>
0016 
0017 #include <memory>
0018 
0019 class QAction;
0020 class KActionCollection;
0021 class KLocalizedString;
0022 class QItemSelectionModel;
0023 class QWidget;
0024 class QMenu;
0025 
0026 namespace Akonadi
0027 {
0028 class FavoriteCollectionsModel;
0029 class StandardActionManagerPrivate;
0030 
0031 /**
0032  * @short Manages generic actions for collection and item views.
0033  *
0034  * Manages generic Akonadi actions common for all types. This covers
0035  * creating of the actions with appropriate labels, icons, shortcuts
0036  * etc., updating the action state depending on the current selection
0037  * as well as default implementations for the actual operations.
0038  *
0039  * If the default implementation is not appropriate for your application
0040  * you can still use the state tracking by disconnecting the triggered()
0041  * signal and re-connecting it to your implementation. The actual KAction
0042  * objects can be retrieved by calling createAction() or action() for that.
0043  *
0044  * If the default look and feel (labels, icons, shortcuts) of the actions
0045  * is not appropriate for your application, you can access them as noted
0046  * above and customize them to your needs. Additionally, you can set a
0047  * KLocalizedString which should be used as a action label with correct
0048  * plural handling for actions operating on multiple objects with
0049  * setActionText().
0050  *
0051  * Finally, if you have special needs for the action states, connect to
0052  * the actionStateUpdated() signal and adjust the state accordingly.
0053  *
0054  * The following actions are provided (KAction name in parenthesis):
0055  * - Creation of a new collection (@c akonadi_collection_create)
0056  * - Copying of selected collections (@c akonadi_collection_copy)
0057  * - Deletion of selected collections (@c akonadi_collection_delete)
0058  * - Synchronization of selected collections (@c akonadi_collection_sync)
0059  * - Showing the collection properties dialog for the current collection (@c akonadi_collection_properties)
0060  * - Copying of selected items (@c akonadi_itemcopy)
0061  * - Pasting collections, items or raw data (@c akonadi_paste)
0062  * - Deleting of selected items (@c akonadi_item_delete)
0063  * - Managing local subscriptions (@c akonadi_manage_local_subscriptions)
0064  *
0065  * The following example shows how to use standard actions in your application:
0066  *
0067  * @code
0068  *
0069  * Akonadi::StandardActionManager *actMgr = new Akonadi::StandardActionManager( actionCollection(), this );
0070  * actMgr->setCollectionSelectionModel( collectionView->collectionSelectionModel() );
0071  * actMgr->createAllActions();
0072  *
0073  * @endcode
0074  *
0075  * Additionally you have to add the actions to the KXMLGUI file of your application,
0076  * using the names listed above.
0077  *
0078  * If you only need a subset of the actions provided, you can call createAction()
0079  * instead of createAllActions() for the action types you want.
0080  *
0081  * If you want to use your own implementation of the actual action operation and
0082  * not the default implementation, you can call interceptAction() on the action type
0083  * you want to handle yourself and connect the slot with your own implementation
0084  * to the triggered() signal of the action:
0085  *
0086  * @code
0087  *
0088  * using namespace Akonadi;
0089  *
0090  * StandardActionManager *manager = new StandardActionManager( actionCollection(), this );
0091  * manager->setCollectionSelectionModel( collectionView->collectionSelectionModel() );
0092  * manager->createAllActions();
0093  *
0094  * // disable default implementation
0095  * manager->interceptAction( StandardActionManager::CopyCollections );
0096  *
0097  * // connect your own implementation
0098  * connect( manager->action( StandardActionManager::CopyCollections ), SIGNAL(triggered(bool)),
0099  *          this, SLOT(myCopyImplementation()) );
0100  * ...
0101  *
0102  * void MyClass::myCopyImplementation()
0103  * {
0104  *   const Collection::List collections = manager->selectedCollections();
0105  *   for ( const Collection &collection : collections ) {
0106  *     // copy the collection manually...
0107  *   }
0108  * }
0109  *
0110  * @endcode
0111  *
0112  * @todo collection deleting and sync do not support multi-selection yet
0113  *
0114  * @author Volker Krause <vkrause@kde.org>
0115  */
0116 class AKONADIWIDGETS_EXPORT StandardActionManager : public QObject
0117 {
0118     Q_OBJECT
0119 public:
0120     /**
0121      * Describes the supported actions.
0122      */
0123     enum Type {
0124         CreateCollection, ///< Creates an collection
0125         CopyCollections, ///< Copies the selected collections
0126         DeleteCollections, ///< Deletes the selected collections
0127         SynchronizeCollections, ///< Synchronizes collections
0128         CollectionProperties, ///< Provides collection properties
0129         CopyItems, ///< Copies the selected items
0130         Paste, ///< Paste collections or items
0131         DeleteItems, ///< Deletes the selected items
0132         ManageLocalSubscriptions, ///< Manages local subscriptions
0133         AddToFavoriteCollections, ///< Add the collection to the favorite collections model @since 4.4
0134         RemoveFromFavoriteCollections, ///< Remove the collection from the favorite collections model @since 4.4
0135         RenameFavoriteCollection, ///< Rename the collection of the favorite collections model @since 4.4
0136         CopyCollectionToMenu, ///< Menu allowing to quickly copy a collection into another collection @since 4.4
0137         CopyItemToMenu, ///< Menu allowing to quickly copy an item into a collection @since 4.4
0138         MoveItemToMenu, ///< Menu allowing to move item into a collection @since 4.4
0139         MoveCollectionToMenu, ///< Menu allowing to move a collection into another collection @since 4.4
0140         CutItems, ///< Cuts the selected items @since 4.4
0141         CutCollections, ///< Cuts the selected collections @since 4.4
0142         CreateResource, ///< Creates a new resource @since 4.6
0143         DeleteResources, ///< Deletes the selected resources @since 4.6
0144         ResourceProperties, ///< Provides the resource properties @since 4.6
0145         SynchronizeResources, ///< Synchronizes the selected resources @since 4.6
0146         ToggleWorkOffline, ///< Toggles the work offline state of all resources @since 4.6
0147         CopyCollectionToDialog, ///< Copy a collection into another collection, select the target in a dialog @since 4.6
0148         MoveCollectionToDialog, ///< Move a collection into another collection, select the target in a dialog @since 4.6
0149         CopyItemToDialog, ///< Copy an item into a collection, select the target in a dialog @since 4.6
0150         MoveItemToDialog, ///< Move an item into a collection, select the target in a dialog @since 4.6
0151         SynchronizeCollectionsRecursive, ///< Synchronizes collections in a recursive way @since 4.6
0152         MoveCollectionsToTrash, ///< Moves the selected collection to trash and marks it as deleted, needs EntityDeletedAttribute @since 4.8
0153         MoveItemsToTrash, ///< Moves the selected items to trash and marks them as deleted, needs EntityDeletedAttribute @since 4.8
0154         RestoreCollectionsFromTrash, ///< Restores the selected collection from trash, needs EntityDeletedAttribute @since 4.8
0155         RestoreItemsFromTrash, ///< Restores the selected items from trash, needs EntityDeletedAttribute @since 4.8
0156         MoveToTrashRestoreCollection, ///< Move Collection to Trash or Restore it from Trash, needs EntityDeletedAttribute @since 4.8
0157         MoveToTrashRestoreCollectionAlternative, ///< Helper type for MoveToTrashRestoreCollection, do not create directly. Use this to override texts of the
0158                                                  ///< restore action. @since 4.8
0159         MoveToTrashRestoreItem, ///< Move Item to Trash or Restore it from Trash, needs EntityDeletedAttribute @since 4.8
0160         MoveToTrashRestoreItemAlternative, ///< Helper type for MoveToTrashRestoreItem, do not create directly. Use this to override texts of the restore
0161                                            ///< action. @since 4.8
0162         SynchronizeFavoriteCollections, ///< Synchronize favorite collections @since 4.8
0163         SynchronizeCollectionTree, ///< Synchronize collection tree @since 4.15
0164         LastType ///< Marks last action
0165     };
0166 
0167     /**
0168      * Describes the text context that can be customized.
0169      */
0170     enum TextContext {
0171         DialogTitle, ///< The window title of a dialog
0172         DialogText, ///< The text of a dialog
0173         MessageBoxTitle, ///< The window title of a message box
0174         MessageBoxText, ///< The text of a message box
0175         MessageBoxAlternativeText, ///< An alternative text of a message box
0176         ErrorMessageTitle, ///< The window title of an error message
0177         ErrorMessageText ///< The text of an error message
0178     };
0179 
0180     /**
0181      * Creates a new standard action manager.
0182      *
0183      * @param actionCollection The action collection to operate on.
0184      * @param parent The parent widget.
0185      */
0186     explicit StandardActionManager(KActionCollection *actionCollection, QWidget *parent = nullptr);
0187 
0188     /**
0189      * Destroys the standard action manager.
0190      */
0191     ~StandardActionManager() override;
0192 
0193     /**
0194      * Sets the collection selection model based on which the collection
0195      * related actions should operate. If none is set, all collection actions
0196      * will be disabled.
0197      *
0198      * @param selectionModel model to be set for collection
0199      */
0200     void setCollectionSelectionModel(QItemSelectionModel *selectionModel);
0201 
0202     /**
0203      * Sets the item selection model based on which the item related actions
0204      * should operate. If none is set, all item actions will be disabled.
0205      *
0206      * @param selectionModel selection model for items
0207      */
0208     void setItemSelectionModel(QItemSelectionModel *selectionModel);
0209 
0210     /**
0211      * Sets the favorite collections model based on which the collection
0212      * relatedactions should operate. If none is set, the "Add to Favorite Folders" action
0213      * will be disabled.
0214      *
0215      * @param favoritesModel model for the user's favorite collections
0216      * @since 4.4
0217      */
0218     void setFavoriteCollectionsModel(FavoriteCollectionsModel *favoritesModel);
0219 
0220     /**
0221      * Sets the favorite collection selection model based on which the favorite
0222      * collection related actions should operate. If none is set, all favorite modifications
0223      * actions will be disabled.
0224      *
0225      * @param selectionModel selection model for favorite collections
0226      * @since 4.4
0227      */
0228     void setFavoriteSelectionModel(QItemSelectionModel *selectionModel);
0229 
0230     /**
0231      * Creates the action of the given type and adds it to the action collection
0232      * specified in the constructor if it does not exist yet. The action is
0233      * connected to its default implementation provided by this class.
0234      *
0235      * @param type action to be created
0236      */
0237     QAction *createAction(Type type);
0238 
0239     /**
0240      * Convenience method to create all standard actions.
0241      * @see createAction()
0242      */
0243     void createAllActions();
0244 
0245     /**
0246      * Returns the action of the given type, 0 if it has not been created (yet).
0247      * @param type action type
0248      */
0249     QAction *action(Type type) const;
0250 
0251     /**
0252      * Sets the label of the action @p type to @p text, which is used during
0253      * updating the action state and substituted according to the number of
0254      * selected objects. This is mainly useful to customize the label of actions
0255      * that can operate on multiple objects.
0256      * @param type the action to set a text for
0257      * @param text the text to display for the given action
0258      * Example:
0259      * @code
0260      * acctMgr->setActionText( Akonadi::StandardActionManager::CopyItems,
0261      *                         ki18np( "Copy Mail", "Copy %1 Mails" ) );
0262      * @endcode
0263      */
0264     void setActionText(Type type, const KLocalizedString &text);
0265 
0266     /**
0267      * Sets whether the default implementation for the given action @p type
0268      * shall be executed when the action is triggered.
0269      *
0270      * @param type action type
0271      * @param intercept If @c false, the default implementation will be executed,
0272      *                  if @c true no action is taken.
0273      *
0274      * @since 4.6
0275      */
0276     void interceptAction(Type type, bool intercept = true);
0277 
0278     /**
0279      * Returns the list of collections that are currently selected.
0280      * The list is empty if no collection is currently selected.
0281      *
0282      * @since 4.6
0283      */
0284     Akonadi::Collection::List selectedCollections() const;
0285 
0286     /**
0287      * Returns the list of items that are currently selected.
0288      * The list is empty if no item is currently selected.
0289      *
0290      * @since 4.6
0291      */
0292     Akonadi::Item::List selectedItems() const;
0293 
0294     /**
0295      * Sets the @p text of the action @p type for the given @p context.
0296      *
0297      * @param type action type
0298      * @param context context for action
0299      * @param text content to set for the action
0300      * @since 4.6
0301      */
0302     void setContextText(Type type, TextContext context, const QString &text);
0303 
0304     /**
0305      * Sets the @p text of the action @p type for the given @p context.
0306      *
0307      * @param type action type
0308      * @param context context for action
0309      * @param text content to set for the action
0310      * @since 4.6
0311      */
0312     void setContextText(Type type, TextContext context, const KLocalizedString &text);
0313 
0314     /**
0315      * Sets the mime type filter that will be used when creating new resources.
0316      *
0317      * @param mimeTypes filter for creating new resources
0318      * @since 4.6
0319      */
0320     void setMimeTypeFilter(const QStringList &mimeTypes);
0321 
0322     /**
0323      * Sets the capability filter that will be used when creating new resources.
0324      *
0325      * @param capabilities filter for creating new resources
0326      * @since 4.6
0327      */
0328     void setCapabilityFilter(const QStringList &capabilities);
0329 
0330     /**
0331      * Sets the page @p names of the config pages that will be used by the
0332      * built-in collection properties dialog.
0333      *
0334      * @param names list of names which will be used
0335      * @since 4.6
0336      */
0337     void setCollectionPropertiesPageNames(const QStringList &names);
0338 
0339     /**
0340      * Create a popup menu.
0341      *
0342      * @param menu parent menu for a popup
0343      * @param type action type
0344      * @since 4.8
0345      */
0346     void createActionFolderMenu(QMenu *menu, Type type);
0347 
0348     /**
0349      * Add a collection to the global recent collection list.
0350      *
0351      * @param id the collection ID
0352      * @since 5.18
0353      */
0354     void addRecentCollection(Akonadi::Collection::Id id) const;
0355 
0356 Q_SIGNALS:
0357 
0358     /**
0359      * This signal is emitted whenever one of the selections has changed
0360      * (selected collections, selected favorites collections, selected items)
0361      * This allows other action managers to update their actions accordingly
0362      * (see e.g. StandardMailActionManager)
0363      */
0364     void selectionsChanged(const Collection::List &selectedCollectionsList,
0365                            const Collection::List &selectedFavoriteCollectionsList,
0366                            const Item::List &selectedItems);
0367 
0368     /**
0369      * This signal is emitted whenever the action state has been updated.
0370      * In case you have special needs for changing the state of some actions,
0371      * connect to this signal and adjust the action state.
0372      */
0373     void actionStateUpdated();
0374 
0375 private:
0376     /// @cond PRIVATE
0377     friend class StandardActionManagerPrivate;
0378     std::unique_ptr<StandardActionManagerPrivate> const d;
0379 
0380     Q_PRIVATE_SLOT(d, void updateActions())
0381 
0382     Q_PRIVATE_SLOT(d, void slotCreateCollection())
0383     Q_PRIVATE_SLOT(d, void slotCopyCollections())
0384     Q_PRIVATE_SLOT(d, void slotCutCollections())
0385     Q_PRIVATE_SLOT(d, void slotDeleteCollection())
0386     Q_PRIVATE_SLOT(d, void slotMoveCollectionToTrash())
0387     Q_PRIVATE_SLOT(d, void slotMoveItemToTrash())
0388     Q_PRIVATE_SLOT(d, void slotRestoreCollectionFromTrash())
0389     Q_PRIVATE_SLOT(d, void slotRestoreItemFromTrash())
0390     Q_PRIVATE_SLOT(d, void slotTrashRestoreCollection())
0391     Q_PRIVATE_SLOT(d, void slotTrashRestoreItem())
0392     Q_PRIVATE_SLOT(d, void slotSynchronizeCollection())
0393     Q_PRIVATE_SLOT(d, void slotSynchronizeCollectionRecursive())
0394     Q_PRIVATE_SLOT(d, void slotSynchronizeFavoriteCollections())
0395     Q_PRIVATE_SLOT(d, void slotCollectionProperties())
0396     Q_PRIVATE_SLOT(d, void slotCopyItems())
0397     Q_PRIVATE_SLOT(d, void slotCutItems())
0398     Q_PRIVATE_SLOT(d, void slotPaste())
0399     Q_PRIVATE_SLOT(d, void slotDeleteItems())
0400     Q_PRIVATE_SLOT(d, void slotDeleteItemsDeferred(const Akonadi::Item::List &))
0401     Q_PRIVATE_SLOT(d, void slotLocalSubscription())
0402     Q_PRIVATE_SLOT(d, void slotAddToFavorites())
0403     Q_PRIVATE_SLOT(d, void slotRemoveFromFavorites())
0404     Q_PRIVATE_SLOT(d, void slotRenameFavorite())
0405     Q_PRIVATE_SLOT(d, void slotCopyCollectionTo())
0406     Q_PRIVATE_SLOT(d, void slotMoveCollectionTo())
0407     Q_PRIVATE_SLOT(d, void slotCopyItemTo())
0408     Q_PRIVATE_SLOT(d, void slotMoveItemTo())
0409     Q_PRIVATE_SLOT(d, void slotCopyCollectionTo(QAction *))
0410     Q_PRIVATE_SLOT(d, void slotMoveCollectionTo(QAction *))
0411     Q_PRIVATE_SLOT(d, void slotCopyItemTo(QAction *))
0412     Q_PRIVATE_SLOT(d, void slotMoveItemTo(QAction *))
0413     Q_PRIVATE_SLOT(d, void slotCreateResource())
0414     Q_PRIVATE_SLOT(d, void slotDeleteResource())
0415     Q_PRIVATE_SLOT(d, void slotResourceProperties())
0416     Q_PRIVATE_SLOT(d, void slotSynchronizeResource())
0417     Q_PRIVATE_SLOT(d, void slotToggleWorkOffline(bool))
0418     Q_PRIVATE_SLOT(d, void slotSynchronizeCollectionTree())
0419     Q_PRIVATE_SLOT(d, void collectionCreationResult(KJob *))
0420     Q_PRIVATE_SLOT(d, void moveItemToTrashResult(KJob *))
0421     Q_PRIVATE_SLOT(d, void resourceCreationResult(KJob *))
0422     Q_PRIVATE_SLOT(d, void pasteResult(KJob *))
0423 
0424     Q_PRIVATE_SLOT(d, void enableAction(int, bool))
0425     Q_PRIVATE_SLOT(d, void updatePluralLabel(int, int))
0426     Q_PRIVATE_SLOT(d, void updateAlternatingAction(int))
0427     Q_PRIVATE_SLOT(d, bool isFavoriteCollection(const Akonadi::Collection &))
0428     /// @endcond
0429 };
0430 
0431 }