File indexing completed on 2023-11-26 10:45:34
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org> 0004 SPDX-FileCopyrightText: 1999-2006 David Faure <faure@kde.org> 0005 SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef KSERVICE_H 0011 #define KSERVICE_H 0012 0013 #include "kserviceaction.h" 0014 #include <QCoreApplication> 0015 #include <QStringList> 0016 #include <QVariant> 0017 #include <kserviceconversioncheck_p.h> 0018 #include <ksycocaentry.h> 0019 0020 #include <optional> 0021 0022 class QDataStream; 0023 class KDesktopFile; 0024 class QWidget; 0025 0026 class KServicePrivate; 0027 0028 /** 0029 * @class KService kservice.h <KService> 0030 * 0031 * Represents an installed application. 0032 * 0033 * To obtain a KService instance for a specific application you typically use serviceByDesktopName(), e.g.: 0034 * 0035 * @code 0036 * KService::Ptr service = KService::serviceByDesktopName("org.kde.kate"); 0037 * @endcode 0038 * 0039 * Other typical usage would be in combination with KApplicationTrader to obtain e.g. the default application for a given file type. 0040 * 0041 * @see <a href="https://specifications.freedesktop.org/desktop-entry-spec/latest/">Desktop Entry Specification</a> 0042 */ 0043 class KSERVICE_EXPORT KService : public KSycocaEntry 0044 { 0045 public: 0046 /** 0047 * A shared data pointer for KService. 0048 */ 0049 typedef QExplicitlySharedDataPointer<KService> Ptr; 0050 /** 0051 * A list of shared data pointers for KService. 0052 */ 0053 typedef QList<Ptr> List; 0054 0055 /** 0056 * Construct a temporary service with a given name, exec-line and icon. 0057 * @param name the name of the service 0058 * @param exec the executable 0059 * @param icon the name of the icon 0060 */ 0061 KService(const QString &name, const QString &exec, const QString &icon); 0062 0063 /** 0064 * Construct a service and take all information from a .desktop file. 0065 * 0066 * @param fullpath Full path to the .desktop file. 0067 */ 0068 explicit KService(const QString &fullpath); 0069 0070 /** 0071 * Construct a service and take all information from a desktop file. 0072 * @param config the desktop file to read 0073 * @param optional relative path to store for findByName 0074 */ 0075 explicit KService(const KDesktopFile *config, const QString &entryPath = QString()); 0076 0077 KService(const KService &other); 0078 0079 ~KService() override; 0080 0081 /** 0082 * Whether this service is an application 0083 * @return true if this service is an application, i.e. it has Type=Application in its 0084 * .desktop file and exec() will not be empty. 0085 */ 0086 bool isApplication() const; 0087 0088 /** 0089 * Returns the executable. 0090 * @return the command that the service executes, 0091 * or QString() if not set 0092 */ 0093 QString exec() const; 0094 0095 /** 0096 * Returns the name of the icon. 0097 * @return the icon associated with the service, 0098 * or QString() if not set 0099 */ 0100 QString icon() const; 0101 /** 0102 * Checks whether the application should be run in a terminal. 0103 * 0104 * This corresponds to `Terminal=true` in the .desktop file. 0105 * 0106 * @return @c true if the application should be run in a terminal. 0107 */ 0108 bool terminal() const; 0109 0110 /** 0111 * Returns any options associated with the terminal the application 0112 * runs in, if it requires a terminal. 0113 * 0114 * The application must be a TTY-oriented program. 0115 * @return the terminal options, 0116 * or QString() if not set 0117 */ 0118 QString terminalOptions() const; 0119 0120 /** 0121 * Returns @c true if the application indicates that it's preferred to run 0122 * on a discrete graphics card, otherwise return @c false. 0123 * 0124 * In releases older than 5.86, this method checked for the @c X-KDE-RunOnDiscreteGpu 0125 * key in the .desktop file represented by this service; starting from 5.86 this method 0126 * now also checks for @c PrefersNonDefaultGPU key (added to the Freedesktop.org desktop 0127 * entry spec in version 1.4 of the spec). 0128 * 0129 * @since 5.30 0130 */ 0131 bool runOnDiscreteGpu() const; 0132 0133 /** 0134 * @brief Checks whether the application needs to run under a different UID. 0135 * @return @c true if the application needs to run under a different UID. 0136 * @see username() 0137 */ 0138 bool substituteUid() const; 0139 /** 0140 * Returns the user name if the application runs with a 0141 * different user id. 0142 * @return the username under which the service has to be run, 0143 * or QString() if not set 0144 * @see substituteUid() 0145 */ 0146 QString username() const; 0147 0148 /** 0149 * Returns the filename of the desktop entry without any 0150 * extension, e.g. "org.kde.kate" 0151 * @return the name of the desktop entry without path or extension, 0152 * or QString() if not set 0153 */ 0154 QString desktopEntryName() const; 0155 0156 /** 0157 * Returns the menu ID of the application desktop entry. 0158 * The menu ID is used to add or remove the entry to a menu. 0159 * @return the menu ID 0160 */ 0161 QString menuId() const; 0162 0163 /** 0164 * Returns a normalized ID suitable for storing in configuration files. 0165 * It will be based on the menu-id when available and otherwise falls 0166 * back to entryPath() 0167 * @return the storage ID 0168 */ 0169 QString storageId() const; 0170 0171 /** 0172 * @return the working directory to run the program in, 0173 * or QString() if not set 0174 * @since 5.63 0175 */ 0176 QString workingDirectory() const; 0177 0178 /** 0179 * Returns the descriptive comment for the application, if there is one. 0180 * @return the descriptive comment for the application, or QString() 0181 * if not set 0182 */ 0183 QString comment() const; 0184 0185 /** 0186 * Returns the generic name for the application, if there is one 0187 * (e.g. "Mail Client"). 0188 * @return the generic name, 0189 * or QString() if not set 0190 */ 0191 QString genericName() const; 0192 0193 /** 0194 * Returns the untranslated (US English) generic name 0195 * for the application, if there is one 0196 * (e.g. "Mail Client"). 0197 * @return the generic name, 0198 * or QString() if not set 0199 */ 0200 QString untranslatedGenericName() const; 0201 0202 /** 0203 * @return untranslated name for the given service 0204 * 0205 * @since 6.0 0206 */ 0207 QString untranslatedName() const; 0208 /** 0209 * Returns a list of descriptive keywords for the application, if there are any. 0210 * @return the list of keywords 0211 */ 0212 QStringList keywords() const; 0213 0214 /** 0215 * Returns a list of VFolder categories. 0216 * @return the list of VFolder categories 0217 */ 0218 QStringList categories() const; 0219 0220 /** 0221 * Returns the list of MIME types that this application supports. 0222 * Note that this doesn't include inherited MIME types, 0223 * only the MIME types listed in the .desktop file. 0224 * @since 4.8.3 0225 */ 0226 QStringList mimeTypes() const; 0227 0228 /** 0229 * Returns the list of protocols this application supports. 0230 * 0231 * This is taken from the x-scheme-handler MIME types 0232 * listed in the .destkop file as well as the 'X-KDE-Protocols' 0233 * entry 0234 * 0235 * For example a web browser could return {"http", "https"}. 0236 * @since 6.0 0237 */ 0238 QStringList supportedProtocols() const; 0239 0240 /** 0241 * Checks whether the application supports this MIME type 0242 * @param mimeType The name of the MIME type you are 0243 * interested in determining whether this service supports. 0244 * @since 4.6 0245 */ 0246 bool hasMimeType(const QString &mimeType) const; 0247 0248 /** 0249 * Returns the actions defined in this desktop file 0250 */ 0251 QList<KServiceAction> actions() const; 0252 0253 /** 0254 * Checks whether this application can handle several files as 0255 * startup arguments. 0256 * @return true if multiple files may be passed to this service at 0257 * startup. False if only one file at a time may be passed. 0258 */ 0259 bool allowMultipleFiles() const; 0260 0261 /** 0262 * What preference to associate with this application initially (before 0263 * the user has had any chance to define a profile for it). 0264 * The bigger the value, the stronger the preference for the application. 0265 * @return the service preference level of the application 0266 */ 0267 int initialPreference() const; 0268 0269 /** 0270 * Whether the entry should be hidden from the menu. 0271 * @return @c true to hide this application from the menu 0272 * 0273 * Such services still appear in trader queries, i.e. in 0274 * "Open With" popup menus for instance. 0275 */ 0276 bool noDisplay() const; 0277 0278 /** 0279 * Whether the application should be shown in the current desktop 0280 * (including in context menus). 0281 * @return true if the application should be shown in the current desktop. 0282 * 0283 * KApplicationTrader honors this and removes such services 0284 * from its results. 0285 * 0286 * @since 5.0 0287 */ 0288 bool showInCurrentDesktop() const; 0289 0290 /** 0291 * Whether the application should be shown on the current 0292 * platform (e.g. on xcb or on wayland). 0293 * @return @c true if the application should be shown on the current platform. 0294 * 0295 * @since 5.0 0296 */ 0297 bool showOnCurrentPlatform() const; 0298 0299 /** 0300 * The path to the documentation for this application. 0301 * @since 4.2 0302 * @return the documentation path, or QString() if not set 0303 */ 0304 QString docPath() const; 0305 0306 /** 0307 * Returns the requested property. 0308 * 0309 * @param _name the name of the property 0310 * @param t the assumed type of the property 0311 * @return the property, or invalid if not found 0312 * 0313 * @since 5.102 0314 */ 0315 QVariant property(const QString &_name, QMetaType::Type t) const; 0316 0317 /** 0318 * Returns the requested property. 0319 * 0320 * @tparam T the type of the requested property. 0321 * 0322 * @param name the name of the property. 0323 * 0324 * @since 6.0 0325 */ 0326 template<typename T> 0327 T property(const QString &name) const 0328 { 0329 KServiceConversionCheck::to_QVariant<T>(); 0330 return property(name, static_cast<QMetaType::Type>(qMetaTypeId<T>())).value<T>(); 0331 } 0332 0333 /** 0334 * Returns a path that can be used for saving changes to this 0335 * application 0336 * @return path that can be used for saving changes to this application 0337 */ 0338 QString locateLocal() const; 0339 0340 /** 0341 * @internal 0342 * Set the menu id 0343 */ 0344 void setMenuId(const QString &menuId); 0345 /** 0346 * @internal 0347 * Sets whether to use a terminal or not 0348 */ 0349 void setTerminal(bool b); 0350 /** 0351 * @internal 0352 * Sets the terminal options to use 0353 */ 0354 void setTerminalOptions(const QString &options); 0355 0356 /** 0357 * Overrides the "Exec=" line of the service. 0358 * 0359 * If @ref exec is not empty, its value will override the one 0360 * the one set when this application was created. 0361 * 0362 * Please note that @ref entryPath is also cleared so the application 0363 * will no longer be associated with a specific config file. 0364 * 0365 * @internal 0366 * @since 4.11 0367 */ 0368 void setExec(const QString &exec); 0369 0370 /** 0371 * Overrides the "Path=" line of the application. 0372 * 0373 * If @ref workingDir is not empty, its value will override 0374 * the one set when this application was created. 0375 * 0376 * Please note that @ref entryPath is also cleared so the application 0377 * will no longer be associated with a specific config file. 0378 * 0379 * @internal 0380 * @param workingDir 0381 * @since 5.79 0382 */ 0383 void setWorkingDirectory(const QString &workingDir); 0384 0385 /** 0386 * Find a application based on its path as returned by entryPath(). 0387 * It's usually better to use serviceByStorageId() instead. 0388 * 0389 * @param _path the path of the configuration file 0390 * @return a pointer to the requested application or @c nullptr if the application is 0391 * unknown. 0392 * @em Very @em important: Don't store the result in a KService* ! 0393 */ 0394 static Ptr serviceByDesktopPath(const QString &_path); 0395 0396 /** 0397 * Find an application by the name of its desktop file, not depending on 0398 * its actual location (as long as it's under the applications or application 0399 * directories). For instance "konqbrowser" or "kcookiejar". Note that 0400 * the ".desktop" extension is implicit. 0401 * 0402 * This is the recommended method (safe even if the user moves stuff) 0403 * but note that it assumes that no two entries have the same filename. 0404 * 0405 * @param _name the name of the configuration file 0406 * @return a pointer to the requested application or @c nullptr if the application is 0407 * unknown. 0408 * @em Very @em important: Don't store the result in a KService* ! 0409 */ 0410 static Ptr serviceByDesktopName(const QString &_name); 0411 0412 /** 0413 * Find a application by its menu-id 0414 * 0415 * @param _menuId the menu id of the application 0416 * @return a pointer to the requested application or @c nullptr if the application is 0417 * unknown. 0418 * @em Very @em important: Don't store the result in a KService* ! 0419 */ 0420 static Ptr serviceByMenuId(const QString &_menuId); 0421 0422 /** 0423 * Find a application by its storage-id or desktop-file path. This 0424 * function will try very hard to find a matching application. 0425 * 0426 * @param _storageId the storage id or desktop-file path of the application 0427 * @return a pointer to the requested application or @c nullptr if the application is 0428 * unknown. 0429 * @em Very @em important: Don't store the result in a KService* ! 0430 */ 0431 static Ptr serviceByStorageId(const QString &_storageId); 0432 0433 /** 0434 * Returns the whole list of applications. 0435 * 0436 * Useful for being able to 0437 * to display them in a list box, for example. 0438 * More memory consuming than the ones above, don't use unless 0439 * really necessary. 0440 * @return the list of all applications 0441 */ 0442 static List allServices(); 0443 0444 /** 0445 * Returns a path that can be used to create a new KService based 0446 * on @p suggestedName. 0447 * @param showInMenu @c true, if the application should be shown in the KDE menu 0448 * @c false, if the application should be hidden from the menu 0449 * This argument isn't used anymore, use `NoDisplay=true` to hide the application. 0450 * @param suggestedName name to base the file on, if an application with such a 0451 * name already exists, a suffix will be added to make it unique 0452 * (e.g. foo.desktop, foo-1.desktop, foo-2.desktop). 0453 * @param menuId If provided, menuId will be set to the menu id to use for 0454 * the KService 0455 * @param reservedMenuIds If provided, the path and menu id will be chosen 0456 * in such a way that the new menu id does not conflict with any 0457 * of the reservedMenuIds 0458 * @return The path to use for the new KService. 0459 */ 0460 static QString newServicePath(bool showInMenu, const QString &suggestedName, QString *menuId = nullptr, const QStringList *reservedMenuIds = nullptr); 0461 0462 /** 0463 * @brief A desktop file name that this application is an alias for. 0464 * 0465 * This is used when a `NoDisplay` application is used to enforce specific handling 0466 * for an application. In that case the `NoDisplay` application is an `AliasFor` another 0467 * application and be considered roughly equal to the `AliasFor` application (which should 0468 * not be `NoDisplay=true`) 0469 * For example Okular supplies a desktop file for each supported format (e.g. PDF), all 0470 * of which `NoDisplay` and it is merely there to selectively support specific file formats. 0471 * A UI may choose to display the aliased entry org.kde.okular instead of the NoDisplay entries. 0472 * 0473 * @since 5.96 0474 * 0475 * @return QString desktopName of the aliased application (excluding .desktop suffix) 0476 */ 0477 QString aliasFor() const; 0478 0479 /** 0480 * Returns the value of StartupNotify for this service. 0481 * 0482 * If the service doesn't define a value nullopt is returned. 0483 * 0484 * See StartupNotify in the <a href="https://specifications.freedesktop.org/desktop-entry-spec/latest/">Desktop Entry Specification</a>. 0485 * 0486 * @since 6.0 0487 */ 0488 std::optional<bool> startupNotify() const; 0489 0490 private: 0491 friend class KBuildServiceFactory; 0492 0493 /// @internal for KBuildSycoca only 0494 struct KSERVICE_NO_EXPORT ServiceTypeAndPreference { 0495 ServiceTypeAndPreference() 0496 : preference(-1) 0497 , serviceType() 0498 { 0499 } 0500 ServiceTypeAndPreference(int pref, const QString &servType) 0501 : preference(pref) 0502 , serviceType(servType) 0503 { 0504 } 0505 int preference; 0506 QString serviceType; // or MIME type 0507 }; 0508 /// @internal for KBuildSycoca only 0509 QVector<ServiceTypeAndPreference> _k_accessServiceTypes(); 0510 0511 void setActions(const QList<KServiceAction> &actions); 0512 0513 friend QDataStream &operator>>(QDataStream &, ServiceTypeAndPreference &); 0514 friend QDataStream &operator<<(QDataStream &, const ServiceTypeAndPreference &); 0515 0516 Q_DECLARE_PRIVATE(KService) 0517 0518 friend class KServiceFactory; 0519 0520 /** 0521 * @internal 0522 * Construct a service from a stream. 0523 * The stream must already be positioned at the correct offset. 0524 */ 0525 KSERVICE_NO_EXPORT KService(QDataStream &str, int offset); 0526 }; 0527 #endif