1 /* 2 This file is part of the KDE project 3 SPDX-FileCopyrightText: 1998-2009 David Faure <faure@kde.org> 4 5 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 6 */ 7 8 #ifndef KFILEITEMACTIONS_H 9 #define KFILEITEMACTIONS_H 10 11 #include "kiowidgets_export.h" 12 #include <KService> 13 #include <kfileitem.h> 14 15 class KFileItemListProperties; 16 class QAction; 17 class QMenu; 18 class KFileItemActionsPrivate; 19 20 /** 21 * @class KFileItemActions kfileitemactions.h <KFileItemActions> 22 * 23 * This class creates and handles the actions for a url (or urls) in a popupmenu. 24 * 25 * This includes: 26 * @li "open with <application>" actions, but also 27 * @li user-defined actions for a .desktop file, defined in the file itself (see the desktop entry standard) 28 * @li servicemenus actions, defined in .desktop files and selected based on the MIME type of the url 29 * 30 * KFileItemActions respects Kiosk-based restrictions (see the KAuthorized 31 * namespace in the KConfig framework). In particular, the "action/openwith" 32 * action is checked when determining actions for opening files (see 33 * addOpenWithActionsTo()) and service-specific actions are checked before 34 * adding service actions to a menu (see addServiceActionsTo()). 35 * 36 * For user-defined actions in a .desktop file, the "X-KDE-AuthorizeAction" key 37 * can be used to determine which actions are checked before the user-defined 38 * action is allowed. The action is ignored if any of the listed actions are 39 * not authorized. 40 * 41 * @note: The builtin services like mount/unmount for old-style device desktop 42 * files (which mainly concerns CDROM and Floppy drives) have been deprecated 43 * since 5.82; those menu entries were hidden long before that, since the FSDevice 44 * .desktop template file hadn't been installed for quite a while. 45 * 46 * @since 4.3 47 */ 48 class KIOWIDGETS_EXPORT KFileItemActions : public QObject 49 { 50 Q_OBJECT 51 public: 52 /** 53 * Creates a KFileItemActions instance. 54 * Note that this instance must stay alive for at least as long as the popupmenu; 55 * it has the slots for the actions created by addOpenWithActionsTo/addServiceActionsTo. 56 */ 57 KFileItemActions(QObject *parent = nullptr); 58 59 /** 60 * Destructor 61 */ 62 ~KFileItemActions() override; 63 64 /** 65 * Sets all the data for the next instance of the popupmenu. 66 * @see KFileItemListProperties 67 */ 68 void setItemListProperties(const KFileItemListProperties &itemList); 69 70 /** 71 * Set the parent widget for any dialogs being shown. 72 * 73 * This should normally be your mainwindow, not a popup menu, 74 * so that it still exists even after the popup is closed 75 * (e.g. error message from KRun) and so that QAction::setStatusTip 76 * can find a statusbar, too. 77 */ 78 void setParentWidget(QWidget *widget); 79 80 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 82) 81 /** 82 * Generates the "Open With <Application>" actions, and appends them to @p menu. 83 * All actions are created as children of the menu. 84 * 85 * No actions will be added if the "openwith" Kiosk action is not authorized 86 * (see KAuthorized::authorize()). 87 * 88 * @param menu the QMenu where the actions will be added 89 * @param traderConstraint this constraint allows to exclude the current application 90 * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'". 91 * 92 * @sa insertOpenWithActionsTo() 93 * @deprecated Since 5.82, use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead and pass in a 94 * nullptr for the @c before parameter 95 */ 96 KIOWIDGETS_DEPRECATED_VERSION(5, 97 82, 98 "use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead and pass " 99 "in a nullptr for the before parameter") 100 void addOpenWithActionsTo(QMenu *menu, const QString &traderConstraint = QString()); 101 #endif 102 103 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 82) 104 /** 105 * Generates the "Open With <Application>" actions, and inserts them in @p menu, 106 * before action @p before. If @p before is nullptr or doesn't exist in the menu 107 * the actions will be appended to the menu. 108 * 109 * All actions are created as children of the menu. 110 * 111 * No actions will be added if the "openwith" Kiosk action is not authorized 112 * (see KAuthorized::authorize()). 113 * 114 * @param before the "open with" actions will be inserted before this action; if this action 115 * is nullptr or isn't available in @p topMenu, the "open with" actions will be appended 116 * @param menu the QMenu where the actions will be added 117 * @param traderConstraint this constraint allows to exclude the current application 118 * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'". 119 * 120 * @since 5.78 121 * @deprecated Since 5.82, use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead 122 */ 123 KIOWIDGETS_DEPRECATED_VERSION(5, 82, "use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead") 124 void insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QString &traderConstraint); 125 #endif 126 127 /** 128 * Generates the "Open With <Application>" actions, and inserts them in @p menu, 129 * before action @p before. If @p before is nullptr or doesn't exist in the menu 130 * the actions will be appended to the menu. 131 * 132 * All actions are created as children of the menu. 133 * 134 * No actions will be added if the "openwith" Kiosk action is not authorized 135 * (see KAuthorized::authorize()). 136 * 137 * @param before the "open with" actions will be inserted before this action; if this action 138 * is nullptr or isn't available in @p topMenu, the "open with" actions will be appended 139 * @param menu the QMenu where the actions will be added 140 * @param excludedDesktopEntryNames list of desktop entry names that will not be shown 141 * 142 * @since 5.82 143 */ 144 void insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames); 145 146 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 82) 147 /** 148 * Returns an action for the preferred application only. 149 * @param traderConstraint this constraint allows to exclude the current application 150 * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'". 151 * @return the action - or @c nullptr if no application was found. 152 * @deprecated Since 5.82, use the first use first entry of @c associatedApplications() to create the action instead 153 */ 154 KIOWIDGETS_DEPRECATED_VERSION(5, 82, "use first entry of associatedApplications to create the action instead") 155 QAction *preferredOpenWithAction(const QString &traderConstraint); 156 #endif 157 158 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 83) 159 /** 160 * Returns the applications associated with all the given MIME types. 161 * 162 * Helper method used internally, can also be used for similar GUIs that 163 * show the list of associated applications. 164 * Used in KParts::BrowserOpenOrSaveQuestion for example. 165 * 166 * This is basically a KMimeTypeTrader::query, but it supports multiple MIME types, and 167 * also cleans up "apparent" duplicates, such as different versions of the same 168 * application installed in parallel. 169 * 170 * The list is sorted according to the user preferences for the given MIME type(s). 171 * In case multiple MIME types appear in the URL list, the logic is: 172 * applications that on average appear earlier on the associated applications 173 * list for the given MIME types also appear earlier on the final applications list. 174 * 175 * Note that for a single MIME type there is no need to use this, you should use 176 * KMimeTypeTrader instead, e.g. query() or preferredService(). 177 * 178 * This will return an empty list if the "openwith" Kiosk action is not 179 * authorized (see KAuthorized::authorize()). 180 * 181 * @param mimeTypeList the MIME types 182 * @param traderConstraint this optional constraint allows to exclude the current application 183 * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'". 184 * @return the sorted list of services. 185 * @since 4.4 186 * @deprecated Since 5.83, use associatedApplications(const QStringList &) instead 187 */ 188 KIOWIDGETS_DEPRECATED_VERSION(5, 83, "use associatedApplications(const QStringList &) instead") 189 static KService::List associatedApplications(const QStringList &mimeTypeList, const QString &traderConstraint); 190 #endif 191 192 /** 193 * Returns the applications associated with all the given MIME types. 194 * 195 * This is basically a KApplicationTrader::query, but it supports multiple MIME types, and 196 * also cleans up "apparent" duplicates, such as different versions of the same 197 * application installed in parallel. 198 * 199 * The list is sorted according to the user preferences for the given MIME type(s). 200 * In case multiple MIME types appear in the URL list, the logic is: 201 * applications that on average appear earlier on the associated applications 202 * list for the given MIME types also appear earlier on the final applications list. 203 * 204 * Note that for a single MIME type there is no need to use this, you should use 205 * KApplicationTrader instead, e.g. query() or preferredService(). 206 * 207 * This will return an empty list if the "openwith" Kiosk action is not 208 * authorized (see @c KAuthorized::authorize()). 209 * 210 * @param mimeTypeList the MIME types 211 * @return the sorted list of services. 212 * @since 5.83 213 */ 214 static KService::List associatedApplications(const QStringList &mimeTypeList); 215 216 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79) 217 /** 218 * Generate the user-defined actions and submenus, and adds them to the @p menu. 219 * User-defined actions include: 220 * - builtin services like mount/unmount for old-style device desktop files 221 * - user-defined actions for a .desktop file, defined in the file itself (see the desktop entry standard) 222 * - servicemenus actions, defined in .desktop files and selected based on the MIME type of the URL 223 * 224 * When KFileItemListProperties::supportsWriting() is false, actions that modify the files are not shown. 225 * This is controlled by Require=Write in the servicemenu desktop files. 226 * 227 * Service actions that are not authorized (see KAuthorized::authorize()) 228 * are not added. For user-defined actions in a .desktop file, the 229 * "X-KDE-AuthorizeAction" key determines the Kiosk actions that are 230 * checked. 231 * 232 * All actions are created as children of the menu. 233 * @return the number of actions added 234 * @deprecated since 5.79, use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead 235 */ 236 KIOWIDGETS_DEPRECATED_VERSION(5, 79, "Use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead") 237 int addServiceActionsTo(QMenu *menu); 238 #endif 239 240 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79) 241 /** 242 * Add actions implemented by plugins. 243 * These are defined in .desktop files or JSON in plugins using the KFileItemAction/Plugin service type, 244 * and the KAbstractFileItemActionPlugin base class. 245 * 246 * All actions are created as children of the menu. 247 * @return the number of actions added 248 * 249 * @since 5.27 250 * @deprecated since 5.79, use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead 251 */ 252 KIOWIDGETS_DEPRECATED_VERSION(5, 79, "Use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead") 253 int addPluginActionsTo(QMenu *menu); 254 #endif 255 256 enum class MenuActionSource { 257 Services = 0x1, ///< Add user defined actions and servicemenu actions (this used to include builtin 258 ///< actions, which have been deprecated since 5.82 see class API documentation) 259 Plugins = 0x2, ///< Add actions implemented by plugins. See KAbstractFileItemActionPlugin base class. 260 All = Services | Plugins, 261 }; 262 Q_DECLARE_FLAGS(MenuActionSources, MenuActionSource) 263 264 /** 265 * This methods adds additional actions to the menu. 266 * @param menu Menu to which the actions/submenus will be added. 267 * @param sources sources from which the actions should be fetched. By default all sources are used. 268 * @param additionalActions additional actions that should be added to the "Actions" submenu or 269 * top level menu if there are less than three entries in total. 270 * @param excludeList list of action names or plugin ids that should be excluded 271 * @since 5.77 272 */ 273 void addActionsTo(QMenu *menu, 274 MenuActionSources sources = MenuActionSource::All, 275 const QList<QAction *> &additionalActions = {}, 276 const QStringList &excludeList = {}); 277 278 Q_SIGNALS: 279 /** 280 * Emitted before the "Open With" dialog is shown 281 * This is used e.g in folderview to close the folder peek popups on invoking the "Open With" menu action 282 * @since 4.8.2 283 */ 284 void openWithDialogAboutToBeShown(); 285 286 /** 287 * Forwards the errors from the KAbstractFileItemActionPlugin instances 288 * @since 5.82 289 */ 290 void error(const QString &errorMessage); 291 292 public Q_SLOTS: 293 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79) 294 /** 295 * Slot used to execute a list of files in their respective preferred application. 296 * @param fileOpenList the list of KFileItems to open. 297 * @param traderConstraint this optional constraint allows to exclude the current application 298 * @since 4.5 299 * @deprecated Since 5.83, use use runPreferredApplications(const KFileItemList &) instead 300 */ 301 KIOWIDGETS_DEPRECATED_VERSION(5, 83, "use runPreferredApplications(const KFileItemList &) instead") 302 void runPreferredApplications(const KFileItemList &fileOpenList, const QString &traderConstraint); 303 #endif 304 305 /** 306 * Slot used to execute a list of files in their respective preferred application. 307 * @param fileOpenList the list of KFileItems to open. 308 * @since 5.83 309 */ 310 void runPreferredApplications(const KFileItemList &fileOpenList); 311 312 private: 313 KFileItemActionsPrivate *const d; 314 friend class KFileItemActionsPrivate; 315 }; 316 Q_DECLARE_OPERATORS_FOR_FLAGS(KFileItemActions::MenuActionSources) 317 318 #endif /* KFILEITEMACTIONS_H */ 319