File indexing completed on 2024-04-28 15:27:22

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 1998-2009 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #ifndef KFILEITEMACTIONS_H
0009 #define KFILEITEMACTIONS_H
0010 
0011 #include "kiowidgets_export.h"
0012 #include <KService>
0013 #include <kfileitem.h>
0014 
0015 #include <memory>
0016 
0017 class KFileItemListProperties;
0018 class QAction;
0019 class QMenu;
0020 class KFileItemActionsPrivate;
0021 
0022 /**
0023  * @class KFileItemActions kfileitemactions.h <KFileItemActions>
0024  *
0025  * This class creates and handles the actions for a url (or urls) in a popupmenu.
0026  *
0027  * This includes:
0028  * @li "open with <application>" actions, but also
0029  * @li user-defined actions for a .desktop file, defined in the file itself (see the desktop entry standard)
0030  * @li servicemenus actions, defined in .desktop files and selected based on the MIME type of the url
0031  *
0032  * KFileItemActions respects Kiosk-based restrictions (see the KAuthorized
0033  * namespace in the KConfig framework). In particular, the "action/openwith"
0034  * action is checked when determining actions for opening files (see
0035  * addOpenWithActionsTo()) and service-specific actions are checked before
0036  * adding service actions to a menu (see addServiceActionsTo()).
0037  *
0038  * For user-defined actions in a .desktop file, the "X-KDE-AuthorizeAction" key
0039  * can be used to determine which actions are checked before the user-defined
0040  * action is allowed.  The action is ignored if any of the listed actions are
0041  * not authorized.
0042  *
0043  * @note: The builtin services like mount/unmount for old-style device desktop
0044  * files (which mainly concerns CDROM and Floppy drives) have been deprecated
0045  * since 5.82; those menu entries were hidden long before that, since the FSDevice
0046  * .desktop template file hadn't been installed for quite a while.
0047  *
0048  * @since 4.3
0049  */
0050 class KIOWIDGETS_EXPORT KFileItemActions : public QObject
0051 {
0052     Q_OBJECT
0053 public:
0054     /**
0055      * Creates a KFileItemActions instance.
0056      * Note that this instance must stay alive for at least as long as the popupmenu;
0057      * it has the slots for the actions created by addOpenWithActionsTo/addServiceActionsTo.
0058      */
0059     KFileItemActions(QObject *parent = nullptr);
0060 
0061     /**
0062      * Destructor
0063      */
0064     ~KFileItemActions() override;
0065 
0066     /**
0067      * Sets all the data for the next instance of the popupmenu.
0068      * @see KFileItemListProperties
0069      */
0070     void setItemListProperties(const KFileItemListProperties &itemList);
0071 
0072     /**
0073      * Set the parent widget for any dialogs being shown.
0074      *
0075      * This should normally be your mainwindow, not a popup menu,
0076      * so that it still exists even after the popup is closed
0077      * (e.g. error message from KRun) and so that QAction::setStatusTip
0078      * can find a statusbar, too.
0079      */
0080     void setParentWidget(QWidget *widget);
0081 
0082 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 82)
0083     /**
0084      * Generates the "Open With <Application>" actions, and appends them to @p menu.
0085      * All actions are created as children of the menu.
0086      *
0087      * No actions will be added if the "openwith" Kiosk action is not authorized
0088      * (see KAuthorized::authorize()).
0089      *
0090      * @param menu the QMenu where the actions will be added
0091      * @param traderConstraint this constraint allows to exclude the current application
0092      * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'".
0093      *
0094      * @sa insertOpenWithActionsTo()
0095      * @deprecated Since 5.82, use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead and pass in a
0096      * nullptr for the @c before parameter
0097      */
0098     KIOWIDGETS_DEPRECATED_VERSION(5,
0099                                   82,
0100                                   "use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead and pass "
0101                                   "in a nullptr for the before parameter")
0102     void addOpenWithActionsTo(QMenu *menu, const QString &traderConstraint = QString());
0103 #endif
0104 
0105 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 82)
0106     /**
0107      * Generates the "Open With <Application>" actions, and inserts them in @p menu,
0108      * before action @p before. If @p before is nullptr or doesn't exist in the menu
0109      * the actions will be appended to the menu.
0110      *
0111      * All actions are created as children of the menu.
0112      *
0113      * No actions will be added if the "openwith" Kiosk action is not authorized
0114      * (see KAuthorized::authorize()).
0115      *
0116      * @param before the "open with" actions will be inserted before this action; if this action
0117      * is nullptr or isn't available in @p topMenu, the "open with" actions will be appended
0118      * @param menu the QMenu where the actions will be added
0119      * @param traderConstraint this constraint allows to exclude the current application
0120      * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'".
0121      *
0122      * @since 5.78
0123      * @deprecated Since 5.82, use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead
0124      */
0125     KIOWIDGETS_DEPRECATED_VERSION(5, 82, "use insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames) instead")
0126     void insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QString &traderConstraint);
0127 #endif
0128 
0129     /**
0130      * Generates the "Open With <Application>" actions, and inserts them in @p menu,
0131      * before action @p before. If @p before is nullptr or doesn't exist in the menu
0132      * the actions will be appended to the menu.
0133      *
0134      * All actions are created as children of the menu.
0135      *
0136      * No actions will be added if the "openwith" Kiosk action is not authorized
0137      * (see KAuthorized::authorize()).
0138      *
0139      * @param before the "open with" actions will be inserted before this action; if this action
0140      * is nullptr or isn't available in @p topMenu, the "open with" actions will be appended
0141      * @param menu the QMenu where the actions will be added
0142      * @param excludedDesktopEntryNames list of desktop entry names that will not be shown
0143      *
0144      * @since 5.82
0145      */
0146     void insertOpenWithActionsTo(QAction *before, QMenu *topMenu, const QStringList &excludedDesktopEntryNames);
0147 
0148 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 82)
0149     /**
0150      * Returns an action for the preferred application only.
0151      * @param traderConstraint this constraint allows to exclude the current application
0152      * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'".
0153      * @return the action - or @c nullptr if no application was found.
0154      * @deprecated Since 5.82, use the first use first entry of @c associatedApplications() to create the action instead
0155      */
0156     KIOWIDGETS_DEPRECATED_VERSION(5, 82, "use first entry of associatedApplications to create the action instead")
0157     QAction *preferredOpenWithAction(const QString &traderConstraint);
0158 #endif
0159 
0160 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 83)
0161     /**
0162      * Returns the applications associated with all the given MIME types.
0163      *
0164      * Helper method used internally, can also be used for similar GUIs that
0165      * show the list of associated applications.
0166      * Used in KParts::BrowserOpenOrSaveQuestion for example.
0167      *
0168      * This is basically a KMimeTypeTrader::query, but it supports multiple MIME types, and
0169      * also cleans up "apparent" duplicates, such as different versions of the same
0170      * application installed in parallel.
0171      *
0172      * The list is sorted according to the user preferences for the given MIME type(s).
0173      * In case multiple MIME types appear in the URL list, the logic is:
0174      * applications that on average appear earlier on the associated applications
0175      * list for the given MIME types also appear earlier on the final applications list.
0176      *
0177      * Note that for a single MIME type there is no need to use this, you should use
0178      * KMimeTypeTrader instead, e.g. query() or preferredService().
0179      *
0180      * This will return an empty list if the "openwith" Kiosk action is not
0181      * authorized (see KAuthorized::authorize()).
0182      *
0183      * @param mimeTypeList the MIME types
0184      * @param traderConstraint this optional constraint allows to exclude the current application
0185      * from the "open with" list. Example: "DesktopEntryName != 'kfmclient'".
0186      * @return the sorted list of services.
0187      * @since 4.4
0188      * @deprecated Since 5.83, use associatedApplications(const QStringList &) instead
0189      */
0190     KIOWIDGETS_DEPRECATED_VERSION(5, 83, "use associatedApplications(const QStringList &) instead")
0191     static KService::List associatedApplications(const QStringList &mimeTypeList, const QString &traderConstraint);
0192 #endif
0193 
0194     /**
0195      * Returns the applications associated with all the given MIME types.
0196      *
0197      * This is basically a KApplicationTrader::query, but it supports multiple MIME types, and
0198      * also cleans up "apparent" duplicates, such as different versions of the same
0199      * application installed in parallel.
0200      *
0201      * The list is sorted according to the user preferences for the given MIME type(s).
0202      * In case multiple MIME types appear in the URL list, the logic is:
0203      * applications that on average appear earlier on the associated applications
0204      * list for the given MIME types also appear earlier on the final applications list.
0205      *
0206      * Note that for a single MIME type there is no need to use this, you should use
0207      * KApplicationTrader instead, e.g. query() or preferredService().
0208      *
0209      * This will return an empty list if the "openwith" Kiosk action is not
0210      * authorized (see @c KAuthorized::authorize()).
0211      *
0212      * @param mimeTypeList the MIME types
0213      * @return the sorted list of services.
0214      * @since 5.83
0215      */
0216     static KService::List associatedApplications(const QStringList &mimeTypeList);
0217 
0218 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79)
0219     /**
0220      * Generate the user-defined actions and submenus, and adds them to the @p menu.
0221      * User-defined actions include:
0222      * - builtin services like mount/unmount for old-style device desktop files
0223      * - user-defined actions for a .desktop file, defined in the file itself (see the desktop entry standard)
0224      * - servicemenus actions, defined in .desktop files and selected based on the MIME type of the URL
0225      *
0226      * When KFileItemListProperties::supportsWriting() is false, actions that modify the files are not shown.
0227      * This is controlled by Require=Write in the servicemenu desktop files.
0228      *
0229      * Service actions that are not authorized (see KAuthorized::authorize())
0230      * are not added.  For user-defined actions in a .desktop file, the
0231      * "X-KDE-AuthorizeAction" key determines the Kiosk actions that are
0232      * checked.
0233      *
0234      * All actions are created as children of the menu.
0235      * @return the number of actions added
0236      * @deprecated since 5.79, use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead
0237      */
0238     KIOWIDGETS_DEPRECATED_VERSION(5, 79, "Use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead")
0239     int addServiceActionsTo(QMenu *menu);
0240 #endif
0241 
0242 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79)
0243     /**
0244      * Add actions implemented by plugins.
0245      * These are defined in .desktop files or JSON in plugins using the KFileItemAction/Plugin service type,
0246      * and the KAbstractFileItemActionPlugin base class.
0247      *
0248      * All actions are created as children of the menu.
0249      * @return the number of actions added
0250      *
0251      * @since 5.27
0252      * @deprecated since 5.79, use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead
0253      */
0254     KIOWIDGETS_DEPRECATED_VERSION(5, 79, "Use addActionsTo(QMenu *menu, MenuActionSources, QList<QAction *> &, const QStringList &) instead")
0255     int addPluginActionsTo(QMenu *menu);
0256 #endif
0257 
0258     enum class MenuActionSource {
0259         Services = 0x1, ///< Add user defined actions and servicemenu actions (this used to include builtin
0260                         ///< actions, which have been deprecated since 5.82 see class API documentation)
0261         Plugins = 0x2, ///< Add actions implemented by plugins. See KAbstractFileItemActionPlugin base class.
0262         All = Services | Plugins,
0263     };
0264     Q_DECLARE_FLAGS(MenuActionSources, MenuActionSource)
0265 
0266     /**
0267      * This methods adds additional actions to the menu.
0268      * @param menu Menu to which the actions/submenus will be added.
0269      * @param sources sources from which the actions should be fetched. By default all sources are used.
0270      * @param additionalActions additional actions that should be added to the "Actions" submenu or
0271      * top level menu if there are less than three entries in total.
0272      * @param excludeList list of action names or plugin ids that should be excluded
0273      * @since 5.77
0274      */
0275     void addActionsTo(QMenu *menu,
0276                       MenuActionSources sources = MenuActionSource::All,
0277                       const QList<QAction *> &additionalActions = {},
0278                       const QStringList &excludeList = {});
0279 
0280 Q_SIGNALS:
0281     /**
0282      * Emitted before the "Open With" dialog is shown
0283      * This is used e.g in folderview to close the folder peek popups on invoking the "Open With" menu action
0284      * @since 4.8.2
0285      */
0286     void openWithDialogAboutToBeShown();
0287 
0288     /**
0289      * Forwards the errors from the KAbstractFileItemActionPlugin instances
0290      * @since 5.82
0291      */
0292     void error(const QString &errorMessage);
0293 
0294 public Q_SLOTS:
0295 #if KIOWIDGETS_ENABLE_DEPRECATED_SINCE(5, 79)
0296     /**
0297      * Slot used to execute a list of files in their respective preferred application.
0298      * @param fileOpenList the list of KFileItems to open.
0299      * @param traderConstraint this optional constraint allows to exclude the current application
0300      * @since 4.5
0301      * @deprecated Since 5.83, use use runPreferredApplications(const KFileItemList &) instead
0302      */
0303     KIOWIDGETS_DEPRECATED_VERSION(5, 83, "use runPreferredApplications(const KFileItemList &) instead")
0304     void runPreferredApplications(const KFileItemList &fileOpenList, const QString &traderConstraint);
0305 #endif
0306 
0307     /**
0308      * Slot used to execute a list of files in their respective preferred application.
0309      * @param fileOpenList the list of KFileItems to open.
0310      * @since 5.83
0311      */
0312     void runPreferredApplications(const KFileItemList &fileOpenList);
0313 
0314 private:
0315     std::unique_ptr<KFileItemActionsPrivate> const d;
0316     friend class KFileItemActionsPrivate;
0317 };
0318 Q_DECLARE_OPERATORS_FOR_FLAGS(KFileItemActions::MenuActionSources)
0319 
0320 #endif /* KFILEITEMACTIONS_H */