1 | /* |
2 | Copyright (c) 2008 Volker Krause <vkrause@kde.org> |
3 | |
4 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or (at your |
7 | option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
12 | License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to the |
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 02110-1301, USA. |
18 | */ |
19 | |
20 | #ifndef AKONADI_STANDARDACTIONMANAGER_H |
21 | #define AKONADI_STANDARDACTIONMANAGER_H |
22 | |
23 | #include "akonadi_export.h" |
24 | |
25 | #include <QtCore/QObject> |
26 | |
27 | #include <akonadi/collection.h> |
28 | #include <akonadi/item.h> |
29 | |
30 | class KAction; |
31 | class KActionCollection; |
32 | class KLocalizedString; |
33 | class QItemSelectionModel; |
34 | class QWidget; |
35 | class ; |
36 | |
37 | namespace Akonadi { |
38 | |
39 | class FavoriteCollectionsModel; |
40 | |
41 | /** |
42 | * @short Manages generic actions for collection and item views. |
43 | * |
44 | * Manages generic Akonadi actions common for all types. This covers |
45 | * creating of the actions with appropriate labels, icons, shortcuts |
46 | * etc., updating the action state depending on the current selection |
47 | * as well as default implementations for the actual operations. |
48 | * |
49 | * If the default implementation is not appropriate for your application |
50 | * you can still use the state tracking by disconnecting the triggered() |
51 | * signal and re-connecting it to your implementation. The actual KAction |
52 | * objects can be retrieved by calling createAction() or action() for that. |
53 | * |
54 | * If the default look and feel (labels, icons, shortcuts) of the actions |
55 | * is not appropriate for your application, you can access them as noted |
56 | * above and customize them to your needs. Additionally, you can set a |
57 | * KLocalizedString which should be used as a action label with correct |
58 | * plural handling for actions operating on multiple objects with |
59 | * setActionText(). |
60 | * |
61 | * Finally, if you have special needs for the action states, connect to |
62 | * the actionStateUpdated() signal and adjust the state accordingly. |
63 | * |
64 | * The following actions are provided (KAction name in parenthesis): |
65 | * - Creation of a new collection (@c akonadi_collection_create) |
66 | * - Copying of selected collections (@c akonadi_collection_copy) |
67 | * - Deletion of selected collections (@c akonadi_collection_delete) |
68 | * - Synchronization of selected collections (@c akonadi_collection_sync) |
69 | * - Showing the collection properties dialog for the current collection (@c akonadi_collection_properties) |
70 | * - Copying of selected items (@c akonadi_itemcopy) |
71 | * - Pasting collections, items or raw data (@c akonadi_paste) |
72 | * - Deleting of selected items (@c akonadi_item_delete) |
73 | * - Managing local subscriptions (@c akonadi_manage_local_subscriptions) |
74 | * |
75 | * The following example shows how to use standard actions in your application: |
76 | * |
77 | * @code |
78 | * |
79 | * Akonadi::StandardActionManager *actMgr = new Akonadi::StandardActionManager( actionCollection(), this ); |
80 | * actMgr->setCollectionSelectionModel( collectionView->collectionSelectionModel() ); |
81 | * actMgr->createAllActions(); |
82 | * |
83 | * @endcode |
84 | * |
85 | * Additionally you have to add the actions to the KXMLGUI file of your application, |
86 | * using the names listed above. |
87 | * |
88 | * If you only need a subset of the actions provided, you can call createAction() |
89 | * instead of createAllActions() for the action types you want. |
90 | * |
91 | * If you want to use your own implementation of the actual action operation and |
92 | * not the default implementation, you can call interceptAction() on the action type |
93 | * you want to handle yourself and connect the slot with your own implementation |
94 | * to the triggered() signal of the action: |
95 | * |
96 | * @code |
97 | * |
98 | * using namespace Akonadi; |
99 | * |
100 | * StandardActionManager *manager = new StandardActionManager( actionCollection(), this ); |
101 | * manager->setCollectionSelectionModel( collectionView->collectionSelectionModel() ); |
102 | * manager->createAllActions(); |
103 | * |
104 | * // disable default implementation |
105 | * manager->interceptAction( StandardActionManager::CopyCollections ); |
106 | * |
107 | * // connect your own implementation |
108 | * connect( manager->action( StandardActionManager::CopyCollections ), SIGNAL( triggered( bool ) ), |
109 | * this, SLOT( myCopyImplementation() ) ); |
110 | * ... |
111 | * |
112 | * void MyClass::myCopyImplementation() |
113 | * { |
114 | * const Collection::List collections = manager->selectedCollections(); |
115 | * foreach ( const Collection &collection, collections ) { |
116 | * // copy the collection manually... |
117 | * } |
118 | * } |
119 | * |
120 | * @endcode |
121 | * |
122 | * @todo collection deleting and sync do not support multi-selection yet |
123 | * |
124 | * @author Volker Krause <vkrause@kde.org> |
125 | */ |
126 | class AKONADI_EXPORT StandardActionManager : public QObject |
127 | { |
128 | Q_OBJECT |
129 | public: |
130 | /** |
131 | * Describes the supported actions. |
132 | */ |
133 | enum Type { |
134 | CreateCollection, ///< Creates an collection |
135 | CopyCollections, ///< Copies the selected collections |
136 | DeleteCollections, ///< Deletes the selected collections |
137 | SynchronizeCollections, ///< Synchronizes collections |
138 | CollectionProperties, ///< Provides collection properties |
139 | CopyItems, ///< Copies the selected items |
140 | Paste, ///< Paste collections or items |
141 | DeleteItems, ///< Deletes the selected items |
142 | ManageLocalSubscriptions, ///< Manages local subscriptions |
143 | AddToFavoriteCollections, ///< Add the collection to the favorite collections model @since 4.4 |
144 | RemoveFromFavoriteCollections, ///< Remove the collection from the favorite collections model @since 4.4 |
145 | RenameFavoriteCollection, ///< Rename the collection of the favorite collections model @since 4.4 |
146 | CopyCollectionToMenu, ///< Menu allowing to quickly copy a collection into another collection @since 4.4 |
147 | CopyItemToMenu, ///< Menu allowing to quickly copy an item into a collection @since 4.4 |
148 | MoveItemToMenu, ///< Menu allowing to move item into a collection @since 4.4 |
149 | MoveCollectionToMenu, ///< Menu allowing to move a collection into another collection @since 4.4 |
150 | CutItems, ///< Cuts the selected items @since 4.4 |
151 | CutCollections, ///< Cuts the selected collections @since 4.4 |
152 | CreateResource, ///< Creates a new resource @since 4.6 |
153 | DeleteResources, ///< Deletes the selected resources @since 4.6 |
154 | ResourceProperties, ///< Provides the resource properties @since 4.6 |
155 | SynchronizeResources, ///< Synchronizes the selected resources @since 4.6 |
156 | ToggleWorkOffline, ///< Toggles the work offline state of all resources @since 4.6 |
157 | CopyCollectionToDialog, ///< Copy a collection into another collection, select the target in a dialog @since 4.6 |
158 | MoveCollectionToDialog, ///< Move a collection into another collection, select the target in a dialog @since 4.6 |
159 | CopyItemToDialog, ///< Copy an item into a collection, select the target in a dialog @since 4.6 |
160 | MoveItemToDialog, ///< Move an item into a collection, select the target in a dialog @since 4.6 |
161 | SynchronizeCollectionsRecursive, ///< Synchronizes collections in a recursive way @since 4.6 |
162 | MoveCollectionsToTrash, ///< Moves the selected collection to trash and marks it as deleted, needs EntityDeletedAttribute @since 4.8 |
163 | MoveItemsToTrash, ///< Moves the selected items to trash and marks them as deleted, needs EntityDeletedAttribute @since 4.8 |
164 | RestoreCollectionsFromTrash, ///< Restores the selected collection from trash, needs EntityDeletedAttribute @since 4.8 |
165 | RestoreItemsFromTrash, ///< Restores the selected items from trash, needs EntityDeletedAttribute @since 4.8 |
166 | MoveToTrashRestoreCollection, ///< Move Collection to Trash or Restore it from Trash, needs EntityDeletedAttribute @since 4.8 |
167 | MoveToTrashRestoreCollectionAlternative, ///< Helper type for MoveToTrashRestoreCollection, do not create directly. Use this to override texts of the restore action. @since 4.8 |
168 | MoveToTrashRestoreItem, ///< Move Item to Trash or Restore it from Trash, needs EntityDeletedAttribute @since 4.8 |
169 | MoveToTrashRestoreItemAlternative, ///< Helper type for MoveToTrashRestoreItem, do not create directly. Use this to override texts of the restore action. @since 4.8 |
170 | SynchronizeFavoriteCollections, ///< Synchronize favorite collections @since 4.8 |
171 | LastType ///< Marks last action |
172 | }; |
173 | |
174 | /** |
175 | * Describes the text context that can be customized. |
176 | */ |
177 | enum TextContext { |
178 | DialogTitle, ///< The window title of a dialog |
179 | DialogText, ///< The text of a dialog |
180 | MessageBoxTitle, ///< The window title of a message box |
181 | MessageBoxText, ///< The text of a message box |
182 | MessageBoxAlternativeText, ///< An alternative text of a message box |
183 | ErrorMessageTitle, ///< The window title of an error message |
184 | ErrorMessageText ///< The text of an error message |
185 | }; |
186 | |
187 | /** |
188 | * Creates a new standard action manager. |
189 | * |
190 | * @param actionCollection The action collection to operate on. |
191 | * @param parent The parent widget. |
192 | */ |
193 | explicit StandardActionManager(KActionCollection *actionCollection, QWidget *parent = 0); |
194 | |
195 | /** |
196 | * Destroys the standard action manager. |
197 | */ |
198 | ~StandardActionManager(); |
199 | |
200 | /** |
201 | * Sets the collection selection model based on which the collection |
202 | * related actions should operate. If none is set, all collection actions |
203 | * will be disabled. |
204 | * |
205 | * @param selectionModel model to be set for collection |
206 | */ |
207 | void setCollectionSelectionModel(QItemSelectionModel *selectionModel); |
208 | |
209 | /** |
210 | * Sets the item selection model based on which the item related actions |
211 | * should operate. If none is set, all item actions will be disabled. |
212 | * |
213 | * @param selectionModel selection model for items |
214 | */ |
215 | void setItemSelectionModel(QItemSelectionModel *selectionModel); |
216 | |
217 | /** |
218 | * Sets the favorite collections model based on which the collection |
219 | * relatedactions should operate. If none is set, the "Add to Favorite Folders" action |
220 | * will be disabled. |
221 | * |
222 | * @param favoritesModel model for the user's favorite collections |
223 | * @since 4.4 |
224 | */ |
225 | void setFavoriteCollectionsModel(FavoriteCollectionsModel *favoritesModel); |
226 | |
227 | /** |
228 | * Sets the favorite collection selection model based on which the favorite |
229 | * collection related actions should operate. If none is set, all favorite modifications |
230 | * actions will be disabled. |
231 | * |
232 | * @param selectionModel selection model for favorite collections |
233 | * @since 4.4 |
234 | */ |
235 | void setFavoriteSelectionModel(QItemSelectionModel *selectionModel); |
236 | |
237 | /** |
238 | * Creates the action of the given type and adds it to the action collection |
239 | * specified in the constructor if it does not exist yet. The action is |
240 | * connected to its default implementation provided by this class. |
241 | * |
242 | * @param type action to be created |
243 | */ |
244 | KAction *createAction(Type type); |
245 | |
246 | /** |
247 | * Convenience method to create all standard actions. |
248 | * @see createAction() |
249 | */ |
250 | void createAllActions(); |
251 | |
252 | /** |
253 | * Returns the action of the given type, 0 if it has not been created (yet). |
254 | * @param type action type |
255 | */ |
256 | KAction *action(Type type) const; |
257 | |
258 | /** |
259 | * Sets the label of the action @p type to @p text, which is used during |
260 | * updating the action state and substituted according to the number of |
261 | * selected objects. This is mainly useful to customize the label of actions |
262 | * that can operate on multiple objects. |
263 | * @param type the action to set a text for |
264 | * @param text the text to display for the given action |
265 | * Example: |
266 | * @code |
267 | * acctMgr->setActionText( Akonadi::StandardActionManager::CopyItems, |
268 | * ki18np( "Copy Mail", "Copy %1 Mails" ) ); |
269 | * @endcode |
270 | */ |
271 | void setActionText(Type type, const KLocalizedString &text); |
272 | |
273 | /** |
274 | * Sets whether the default implementation for the given action @p type |
275 | * shall be executed when the action is triggered. |
276 | * |
277 | * @param type action type |
278 | * @param intercept If @c false, the default implementation will be executed, |
279 | * if @c true no action is taken. |
280 | * |
281 | * @since 4.6 |
282 | */ |
283 | void interceptAction(Type type, bool intercept = true); |
284 | |
285 | /** |
286 | * Returns the list of collections that are currently selected. |
287 | * The list is empty if no collection is currently selected. |
288 | * |
289 | * @since 4.6 |
290 | */ |
291 | Akonadi::Collection::List selectedCollections() const; |
292 | |
293 | /** |
294 | * Returns the list of items that are currently selected. |
295 | * The list is empty if no item is currently selected. |
296 | * |
297 | * @since 4.6 |
298 | */ |
299 | Akonadi::Item::List selectedItems() const; |
300 | |
301 | /** |
302 | * Sets the @p text of the action @p type for the given @p context. |
303 | * |
304 | * @param type action type |
305 | * @param context context for action |
306 | * @param text content to set for the action |
307 | * @since 4.6 |
308 | */ |
309 | void setContextText(Type type, TextContext context, const QString &text); |
310 | |
311 | /** |
312 | * Sets the @p text of the action @p type for the given @p context. |
313 | * |
314 | * @param type action type |
315 | * @param context context for action |
316 | * @param text content to set for the action |
317 | * @since 4.6 |
318 | */ |
319 | void setContextText(Type type, TextContext context, const KLocalizedString &text); |
320 | |
321 | /** |
322 | * Sets the mime type filter that will be used when creating new resources. |
323 | * |
324 | * @param mimeTypes filter for creating new resources |
325 | * @since 4.6 |
326 | */ |
327 | void setMimeTypeFilter(const QStringList &mimeTypes); |
328 | |
329 | /** |
330 | * Sets the capability filter that will be used when creating new resources. |
331 | * |
332 | * @param capabilities filter for creating new resources |
333 | * @since 4.6 |
334 | */ |
335 | void setCapabilityFilter(const QStringList &capabilities); |
336 | |
337 | /** |
338 | * Sets the page @p names of the config pages that will be used by the |
339 | * built-in collection properties dialog. |
340 | * |
341 | * @param names list of names which will be used |
342 | * @since 4.6 |
343 | */ |
344 | void setCollectionPropertiesPageNames(const QStringList &names); |
345 | |
346 | /** |
347 | * Create a popup menu. |
348 | * |
349 | * @param menu parent menu for a popup |
350 | * @param type action type |
351 | * @since 4.8 |
352 | */ |
353 | void createActionFolderMenu(QMenu *, Type type); |
354 | |
355 | Q_SIGNALS: |
356 | /** |
357 | * This signal is emitted whenever the action state has been updated. |
358 | * In case you have special needs for changing the state of some actions, |
359 | * connect to this signal and adjust the action state. |
360 | */ |
361 | void actionStateUpdated(); |
362 | |
363 | private: |
364 | //@cond PRIVATE |
365 | class Private; |
366 | Private *const d; |
367 | |
368 | Q_PRIVATE_SLOT( d, void updateActions() ) |
369 | #ifndef QT_NO_CLIPBOARD |
370 | Q_PRIVATE_SLOT( d, void clipboardChanged(QClipboard::Mode) ) |
371 | #endif |
372 | Q_PRIVATE_SLOT( d, void collectionSelectionChanged() ) |
373 | Q_PRIVATE_SLOT( d, void favoriteSelectionChanged() ) |
374 | |
375 | Q_PRIVATE_SLOT( d, void slotCreateCollection() ) |
376 | Q_PRIVATE_SLOT( d, void slotCopyCollections() ) |
377 | Q_PRIVATE_SLOT( d, void slotCutCollections() ) |
378 | Q_PRIVATE_SLOT( d, void slotDeleteCollection() ) |
379 | Q_PRIVATE_SLOT( d, void slotMoveCollectionToTrash() ) |
380 | Q_PRIVATE_SLOT( d, void slotMoveItemToTrash() ) |
381 | Q_PRIVATE_SLOT( d, void slotRestoreCollectionFromTrash() ) |
382 | Q_PRIVATE_SLOT( d, void slotRestoreItemFromTrash() ) |
383 | Q_PRIVATE_SLOT( d, void slotTrashRestoreCollection() ) |
384 | Q_PRIVATE_SLOT( d, void slotTrashRestoreItem() ) |
385 | Q_PRIVATE_SLOT( d, void slotSynchronizeCollection() ) |
386 | Q_PRIVATE_SLOT( d, void slotSynchronizeCollectionRecursive() ) |
387 | Q_PRIVATE_SLOT( d, void slotSynchronizeFavoriteCollections() ) |
388 | Q_PRIVATE_SLOT( d, void slotCollectionProperties() ) |
389 | Q_PRIVATE_SLOT( d, void slotCopyItems() ) |
390 | Q_PRIVATE_SLOT( d, void slotCutItems() ) |
391 | Q_PRIVATE_SLOT( d, void slotPaste() ) |
392 | Q_PRIVATE_SLOT( d, void slotDeleteItems() ) |
393 | Q_PRIVATE_SLOT( d, void slotDeleteItemsDeferred(const Akonadi::Item::List &) ) |
394 | Q_PRIVATE_SLOT( d, void slotLocalSubscription() ) |
395 | Q_PRIVATE_SLOT( d, void slotAddToFavorites() ) |
396 | Q_PRIVATE_SLOT( d, void slotRemoveFromFavorites() ) |
397 | Q_PRIVATE_SLOT( d, void slotRenameFavorite() ) |
398 | Q_PRIVATE_SLOT( d, void slotCopyCollectionTo() ) |
399 | Q_PRIVATE_SLOT( d, void slotMoveCollectionTo() ) |
400 | Q_PRIVATE_SLOT( d, void slotCopyItemTo() ) |
401 | Q_PRIVATE_SLOT( d, void slotMoveItemTo() ) |
402 | Q_PRIVATE_SLOT( d, void slotCopyCollectionTo(QAction*) ) |
403 | Q_PRIVATE_SLOT( d, void slotMoveCollectionTo(QAction*) ) |
404 | Q_PRIVATE_SLOT( d, void slotCopyItemTo(QAction*) ) |
405 | Q_PRIVATE_SLOT( d, void slotMoveItemTo(QAction*) ) |
406 | Q_PRIVATE_SLOT( d, void slotCreateResource() ) |
407 | Q_PRIVATE_SLOT( d, void slotDeleteResource() ) |
408 | Q_PRIVATE_SLOT( d, void slotResourceProperties() ) |
409 | Q_PRIVATE_SLOT( d, void slotSynchronizeResource() ) |
410 | Q_PRIVATE_SLOT( d, void slotToggleWorkOffline(bool) ) |
411 | |
412 | Q_PRIVATE_SLOT( d, void collectionCreationResult(KJob*) ) |
413 | Q_PRIVATE_SLOT( d, void collectionDeletionResult(KJob*) ) |
414 | Q_PRIVATE_SLOT( d, void moveCollectionToTrashResult(KJob*) ) |
415 | Q_PRIVATE_SLOT( d, void moveItemToTrashResult(KJob*) ) |
416 | Q_PRIVATE_SLOT( d, void itemDeletionResult(KJob*) ) |
417 | Q_PRIVATE_SLOT( d, void resourceCreationResult(KJob*) ) |
418 | Q_PRIVATE_SLOT( d, void pasteResult(KJob*) ) |
419 | |
420 | Q_PRIVATE_SLOT( d, void enableAction(int, bool) ) |
421 | Q_PRIVATE_SLOT( d, void updatePluralLabel(int, int) ) |
422 | Q_PRIVATE_SLOT( d, void updateAlternatingAction(int) ) |
423 | Q_PRIVATE_SLOT( d, bool isFavoriteCollection(const Akonadi::Collection&) ) |
424 | |
425 | Q_PRIVATE_SLOT( d, void aboutToShowMenu() ) |
426 | //@endcond |
427 | }; |
428 | |
429 | } |
430 | |
431 | #endif |
432 | |