File indexing completed on 2025-01-19 03:50:37
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-02-15 0007 * Description : contextmenu helper class 0008 * 0009 * SPDX-FileCopyrightText: 2009-2010 by Andi Clemens <andi dot clemens at gmail dot com> 0010 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * 0012 * SPDX-License-Identifier: GPL-2.0-or-later 0013 * 0014 * ============================================================ */ 0015 0016 #ifndef DIGIKAM_CONTEXT_MENU_HELPER_H 0017 #define DIGIKAM_CONTEXT_MENU_HELPER_H 0018 0019 // Qt includes 0020 0021 #include <QObject> 0022 #include <QList> 0023 #include <QUrl> 0024 0025 // Local includes 0026 0027 #include "digikam_export.h" 0028 #include "digikam_config.h" 0029 #include "coredbalbuminfo.h" 0030 0031 class QAction; 0032 class QMenu; 0033 class QPoint; 0034 class QString; 0035 0036 namespace Digikam 0037 { 0038 0039 class AbstractCheckableAlbumModel; 0040 class Album; 0041 class AlbumIconItem; 0042 class AlbumModificationHelper; 0043 class ItemInfo; 0044 class ItemFilterModel; 0045 class PAlbum; 0046 class TagModificationHelper; 0047 class TAlbum; 0048 0049 /** 0050 * @brief A helper class to add actions and special menus to the context menu. 0051 * 0052 * The %ContextMenuHelper class helps adding commonly used actions and menus. 0053 * Use this class to add 0054 * - actions from the actionCollection 0055 * - standard actions (copy, paste, delete) 0056 * - temporary actions 0057 * - predefined special actions 0058 * - predefined submenus 0059 * to the menu. 0060 * 0061 * All addAction() methods take a special parameter 'addDisabled'. This 0062 * parameter controls if disabled actions are added to the menu. Normally 0063 * adding disabled actions is turned off, to clean up the menu and make it 0064 * more readable. 0065 * 0066 * If the %ContextMenuHelper class is used, you need to call its own exec() method, 0067 * instead the one from the parent menu. This way signals from 0068 * special menus can be emitted and connected to the appropriate slots. 0069 */ 0070 class DIGIKAM_GUI_EXPORT ContextMenuHelper : public QObject // clazy:exclude=ctor-missing-parent-argument 0071 { 0072 Q_OBJECT 0073 0074 public: 0075 0076 typedef const QList<qlonglong> imageIds; 0077 0078 public: 0079 0080 /** 0081 * Constructs the helper class. 0082 * 0083 * @param parent the menu the helper class is linked to 0084 */ 0085 explicit ContextMenuHelper(QMenu* const parent); // clazy:exclude=ctor-missing-parent-argument 0086 ~ContextMenuHelper() override; 0087 0088 /** 0089 * Add an action from the actionCollection. 0090 * 0091 * This method adds actions from the actionCollection. The actionCollection can 0092 * be set in the constructor of the ContextMenuHelper class. 0093 * 0094 * @param name the name of the action in the actionCollection 0095 * @param addDisabled if set, disabled actions are added to the menu 0096 */ 0097 void addAction(const QString& name, bool addDisabled = false); 0098 0099 /** 0100 * Add a temporary action. 0101 * 0102 * Sometimes it is necessary to define actions that only exist in the current context menu content. 0103 * Use this method to add such an action. 0104 * 0105 * @param action the action to add 0106 * @param addDisabled if set, disabled actions are added to the menu 0107 */ 0108 void addAction(QAction* const action, bool addDisabled = false); 0109 0110 /** 0111 * Add a temporary action and assign it to a custom slot. 0112 * 0113 * Use this method if you want to add a temporary action and immediately connect it to the 0114 * receiving slot. 0115 * 0116 * @param action the action to add 0117 * @param recv the receiver of the triggered action 0118 * @param slot the slot to connect the triggered action to 0119 * @param addDisabled if set, disabled actions are added to the menu 0120 */ 0121 void addAction(QAction* const action, QObject* const recv, const char* const slot, bool addDisabled = false); 0122 0123 /** 0124 * Add the standard cut action and connect it to the appropriate slot 0125 * 0126 * @param recv the receiver of the triggered action 0127 * @param slot the slot to connect the triggered action to 0128 */ 0129 void addStandardActionCut(QObject* const recv, const char* const slot); 0130 0131 /** 0132 * Add the standard copy action and connect it to the appropriate slot 0133 * 0134 * @param recv the receiver of the triggered action 0135 * @param slot the slot to connect the triggered action to 0136 */ 0137 void addStandardActionCopy(QObject* const recv, const char* const slot); 0138 0139 /** 0140 * Add the standard paste action and connect it to the appropriate slot 0141 * 0142 * @param recv the receiver of the triggered action 0143 * @param slot the slot to connect the triggered action to 0144 */ 0145 void addStandardActionPaste(QObject* const recv, const char* const slot); 0146 0147 /** 0148 * Add the standard delete action and connect it to the appropriate slot 0149 * 0150 * @param recv the receiver of the triggered action 0151 * @param slot the slot to connect the triggered action to 0152 * @param quantity the number of the files that should be deleted. This parameter is used for 0153 * the action name and is normally used when deleting more then one item. 0154 */ 0155 void addStandardActionItemDelete(QObject* const recv, const char* const slot, int quantity = 1); 0156 0157 /** 0158 * Add the standard Image Quality Sorter action and connect it to the appropriate slot 0159 * 0160 * @param recv the receiver of the triggered action 0161 * @param slot the slot to connect the triggered action to 0162 */ 0163 void addIQSAction(QObject* const recv, const char* const slot); 0164 0165 /** 0166 * Add the lighttable action to the menu. 0167 * 0168 * Do not use addAction() to add the lighttable action, because we need 0169 * to handle special cases here. Depending on whether the lighttable window 0170 * has already been created and filled with items, we set different actions. 0171 */ 0172 void addStandardActionLightTable(); 0173 0174 /** 0175 * Add the thumbnail action to the menu. 0176 * 0177 * Do not use addAction() to add the thumbnail action, because we need 0178 * to handle special cases here. Depending on whether the current view is 0179 * album or icon view, we set different actions. 0180 * 0181 * @param ids the selected items in the current view 0182 * @param album the current album the AlbumIconView is displaying 0183 */ 0184 void addStandardActionThumbnail(const imageIds& ids, Album* const album); 0185 0186 /** 0187 * Add section for main views for opening and moving/going to albums. 0188 * 0189 * This is a convenience function to ensure consistent menus and reduce 0190 * code duplication. 0191 * 0192 * @param imageIds the list of selected items 0193 * @param lightTable for the light table 0194 */ 0195 void addOpenAndNavigateActions(const imageIds& ids, bool lightTable = false); 0196 0197 /** 0198 * Add the services menu to the menu. 0199 * 0200 * The services menu is used to open the selected items in a different application. 0201 * It will query the item for registered services and provide them in a submenu. 0202 * The menu will be titled "Open With...". 0203 * 0204 * @param selectedItems the list of selected items 0205 */ 0206 void addServicesMenu(const QList<QUrl>& selectedItems); 0207 0208 /** 0209 * Add the Goto menu. 0210 * 0211 * This menu will provide the following actions for the given item: 0212 * - Goto Album 0213 * - Goto Date 0214 * - Goto Tag 0215 * To make this menu work, you need to run exec() from this class, otherwise the signals 0216 * are not emitted and you will not be able to react on triggered actions from this menu. 0217 * Make sure to connect the signals to the appropriate slots in the context menu handling method. 0218 * 0219 * @param imageIds the list of selected items 0220 * @see exec() 0221 * @see signalGotoAlbum() signalGotoDate() signalGotoTag() 0222 */ 0223 void addGotoMenu(const imageIds& ids); 0224 0225 /** 0226 * Add Queue Manager actions menu. 0227 */ 0228 void addQueueManagerMenu(); 0229 0230 /** 0231 * Add actions to add, remove or edit a tag. 0232 * The tag modification helper is used to execute the action. 0233 * You must set the parent tag to use on modification helper. 0234 */ 0235 void addActionNewTag(TagModificationHelper* const helper, TAlbum* const parentTag = nullptr); 0236 void addActionDeleteTag(TagModificationHelper* const helper, TAlbum* const tag); 0237 void addActionDeleteTags(TagModificationHelper* const helper, const QList<TAlbum*>& tags); 0238 void addActionEditTag(TagModificationHelper* const helper, TAlbum* const tag); 0239 0240 /** 0241 * Add action to delete tags from people sidebar. 0242 */ 0243 void addActionDeleteFaceTag(TagModificationHelper* const helper, TAlbum* const tag); 0244 void addActionDeleteFaceTags(TagModificationHelper* const helper, const QList<TAlbum*>& tags); 0245 0246 /** 0247 * Add action to set tags as face tags. 0248 */ 0249 void addActionTagToFaceTag(TagModificationHelper* const helper, TAlbum* const tag); 0250 void addActionTagsToFaceTags(TagModificationHelper* const helper, const QList<TAlbum*>& tags); 0251 0252 /** 0253 * Add actions to add, remove or edit a tag. 0254 * The tag modification helper is used to execute the action. 0255 * You must set the parent tag to use on modification helper. 0256 */ 0257 void addActionNewAlbum(AlbumModificationHelper* const helper, PAlbum* const parentAlbum = nullptr); 0258 void addActionDeleteAlbum(AlbumModificationHelper* const helper, PAlbum* const album); 0259 void addActionEditAlbum(AlbumModificationHelper* const helper, PAlbum* const album); 0260 void addActionRenameAlbum(AlbumModificationHelper* const helper, PAlbum* const album); 0261 void addActionResetAlbumIcon(AlbumModificationHelper* const helper, PAlbum* const album); 0262 0263 /** 0264 * Add "Assign Tags" menu. 0265 * 0266 * This menu will provide a list of all tags available so that they can be assigned to the current 0267 * selected items. 0268 * 0269 * To make this menu work, you need to run exec() from this class, otherwise the signals 0270 * are not emitted and you will not be able to react on triggered actions from this menu. 0271 * Make sure to connect the signals to the appropriate slots in the context menu handling method. 0272 * 0273 * @param ids the selected items 0274 * @see exec() 0275 * @see signalAssignTag() 0276 */ 0277 void addAssignTagsMenu(const imageIds& ids); 0278 0279 /** 0280 * Add "Remove Tags" menu. 0281 * 0282 * This menu will provide a list of all tags assigned to the current items. Actions triggered in here 0283 * will remove the selected tag from the items. 0284 * 0285 * To make this menu work, you need to run exec() from this class, otherwise the signals 0286 * are not emitted and you will not be able to react on triggered actions from this menu. 0287 * Make sure to connect the signals to the appropriate slots in the context menu handling method. 0288 * 0289 * @param ids the selected items 0290 * @see exec() 0291 * @see signalRemoveTag() 0292 */ 0293 void addRemoveTagsMenu(const imageIds& ids); 0294 0295 /** 0296 * Add "Remove all Tags" action. 0297 * 0298 * Removes all tags from the selected item ids except face tags. 0299 * 0300 * @param ids the selected items 0301 */ 0302 void addRemoveAllTags(const imageIds& ids); 0303 0304 /** 0305 * Add a menu to create new tags from adressbook entries. 0306 */ 0307 void addCreateTagFromAddressbookMenu(); 0308 0309 /** 0310 * Add "Pick/Color/Rating Labels" action. 0311 * 0312 * This action will provide methods to assign pick/color/rating labels to the currently selected items. 0313 * 0314 * To make this menu work, you need to run exec() from this class, otherwise the signals 0315 * are not emitted and you will not be able to react on triggered actions from this menu. 0316 * Make sure to connect the signals to the appropriate slots in the context menu handling method. 0317 * 0318 * @see exec() 0319 * @see signalAssignPickLabel() 0320 * @see signalAssignColorLabel() 0321 * @see signalAssignRating() 0322 */ 0323 void addLabelsAction(); 0324 0325 /** 0326 * Add a "Group" menu. 0327 * This menu will provide actions open, close, add to, remove from, or split a group. 0328 * 0329 * addGroupActions will add the actions as a flat list, not in a submenu. 0330 * Note: Call setItemFilterModel before to have Open/Close group actions. 0331 */ 0332 void addGroupMenu(const imageIds& ids, const QList<QAction*>& extraMenuItems = QList<QAction*>()); 0333 void addGroupActions(const imageIds& ids); 0334 0335 /** 0336 * Set a filter model. 0337 * Some of the group actions will operate directly on the model. 0338 */ 0339 void setItemFilterModel(ItemFilterModel* const model); 0340 0341 /** 0342 * Add a Select and Deselect menu to check and uncheck albums. 0343 * Note: Call setAlbumModel before, or this will have no effect. 0344 */ 0345 void addAlbumCheckUncheckActions(Album* const album); 0346 0347 /** 0348 * Set an album model. 0349 * The check/uncheck actions will operate directly on the model. 0350 */ 0351 void setAlbumModel(AbstractCheckableAlbumModel* const model); 0352 0353 /** 0354 * Add Import Webservices actions menu. 0355 */ 0356 void addImportMenu(); 0357 0358 /** 0359 * Add Export Webservices actions menu. 0360 */ 0361 void addExportMenu(); 0362 0363 /** 0364 * Add a submenu to the parent context menu. 0365 * 0366 * @param subMenu the submenu to be added 0367 */ 0368 void addSubMenu(QMenu* subMenu); 0369 0370 /** 0371 * Add a separator to the context menu 0372 */ 0373 void addSeparator(); 0374 0375 /** 0376 * Execute the registered parent menu and evaluate the triggered actions. 0377 * 0378 * Always use this method instead the one from the parent menu. 0379 * It will ensure that the signals are emitted and special cases are handled. 0380 * 0381 * @param pos position of the triggered action in the registered menu 0382 * @param at the action that should be at the position pos 0383 * @return the triggered action 0384 */ 0385 QAction* exec(const QPoint& pos, QAction* const at = nullptr); 0386 0387 Q_SIGNALS: 0388 0389 void signalSetThumbnail(const ItemInfo&); 0390 void signalGotoAlbum(const ItemInfo&); 0391 void signalGotoDate(const ItemInfo&); 0392 void signalGotoTag(int); 0393 void signalAssignTag(int); 0394 void signalRemoveTag(int); 0395 void signalAssignPickLabel(int); 0396 void signalAssignColorLabel(int); 0397 void signalAssignRating(int); 0398 void signalAddToExistingQueue(int); 0399 void signalAddNewTagFromABCMenu(const QString&); 0400 void signalPopupTagsView(); 0401 void signalCreateGroup(); 0402 void signalCreateGroupByTime(); 0403 void signalCreateGroupByFilename(); 0404 void signalCreateGroupByTimelapse(); 0405 void signalUngroup(); 0406 void signalRemoveFromGroup(); 0407 0408 private Q_SLOTS: 0409 0410 void slotOpenWith(); 0411 void slotOpenWith(QAction* action); 0412 void slotOpenInFileManager(); 0413 void slotOpenImageFile(); 0414 void slotDeselectAllAlbumItems(); 0415 void slotOpenGroups(); 0416 void slotCloseGroups(); 0417 void slotOpenAllGroups(); 0418 void slotCloseAllGroups(); 0419 void slotSelectChildren(); 0420 void slotDeselectChildren(); 0421 void slotSelectParents(); 0422 void slotDeselectParents(); 0423 void slotRemoveAllTags(); 0424 0425 private: 0426 0427 void setGroupsOpen(bool open); 0428 void setSelectedIds(const imageIds& ids); 0429 void setSelectedItems(const QList<QUrl>& urls); 0430 0431 bool imageIdsHaveSameCategory(const imageIds& ids, DatabaseItem::Category category); 0432 QList<QAction*> groupMenuActions(const imageIds& ids); 0433 0434 private: 0435 0436 class Private; 0437 Private* const d; 0438 }; 0439 0440 } // namespace Digikam 0441 0442 #endif // DIGIKAM_CONTEXT_MENU_HELPER_H