KMoreTools

kmoretools.h
1/*
2 SPDX-FileCopyrightText: 2015 Gregor Mi <codestruct@posteo.org>
3
4 SPDX-License-Identifier: LGPL-2.1-or-later
5*/
6
7#ifndef KMORETOOLS_H
8#define KMORETOOLS_H
9
10#include <QMenu>
11#include <QString>
12#include <QUrl>
13
14#include <KService>
15
16#include <memory>
17
18#include <kmoretools_export.h>
19
22class KMoreToolsPrivate;
23
24/**
25 * Helps to create user-configurable menus with tools which are potentially not yet installed.
26 *
27 * This class is one entry point of the KMoreTools API.
28 * See also KMoreToolsMenuFactory.
29 *
30 * @note This is a new API (published within KNewStuff since April 2015). Its current
31 * target are KDE applications which are part of the kdesrcbuild infrastructure.
32 * Here, it is possible to find all usages and to adapt to API changes when needed.
33 * So, if you use this in your own application, beware that there might be API
34 * changes when more use cases are developed.
35 *
36 *
37 * Introduction
38 * ------------
39 * KMoreTools helps to build user-configurable menus with tools which
40 * might not installed yet. These tools may also take URL arguments supplied
41 * by the application.
42 *
43 * The user will see a menu item for a tool even if it is not installed (in the
44 * 'More' section). Furthermore, it makes long menus shorter by providing a
45 * main and more section.
46 * It provides a 'Configure menu' dialog to make the menu user-configurable.
47 *
48 * It does this in the following ways:
49 * - Provide an API to define external applications for a given context.
50 * - If a defined application is not installed (yet) the application is (optionally)
51 * still presented to the user with a hint that it is not installed and a link
52 * to the homepage (later with integration to package management).
53 * This increases the discoverability of useful applications the user never
54 * heard about yet.
55 * - In case of many applications for a given context, it provides a GUI to the
56 * user to hand-pick favorite tools.
57 * This makes it easier for application developers to add alternative
58 * application/tool suggestions without worrying about cluttered menus.
59 * - Menu items can be (automatically) moved to the "More" submenu.
60 * - Reduce translation effort by re-using .desktop files of the services added
61 * to the menu.
62 *
63 *
64 * Details
65 * -------
66 * The term "kmt-desktopfile" refers to a 1:1 copy of a .desktop file. The
67 * kmt-desktopfile is provided by the application that uses KMoreTools
68 * and must be installed to subdirectories of /usr/share/kf5/kmoretools/
69 * - e.g. /usr/share/kf5/kmoretools/dolphin/statusbar-diskspace-menu/
70 * - e.g. /usr/share/kf5/kmoretools/kate/addons/project/git-tools/
71 * - generally, 'QStandardPaths::GenericDataLocation'/kf5/kmoretools/'uniqueId'
72 *
73 * See KMoreTools::KMoreTools for hints of how to install this correctly
74 * using cmake.
75 *
76 * The kmt-desktopfiles are used to get ready-made translations for application
77 * name and description even if the application is not installed. You can
78 * also provide an icon which is used in the not-installed section when the
79 * application is not installed yet.
80 *
81 * For details about the resulting menu structure, see KMoreToolsMenuBuilder.
82 *
83 * See also https://community.kde.org/Scratchpad/KMoreToolsFramework (outdated)
84 *
85 *
86 * Rationale for the "Not installed" section
87 * -----------------------------------------
88 * - Increase discoverability and visibility of useful free software that have
89 * inherently low budget for marketing.
90 * - Make interconnection of different free software packages as effortless as
91 * possible (in terms of creating and maintaining the menu).
92 * - Provide expert (i.e. your) knowledge to useful free software alternatives
93 * to solve a certain task.
94 * - Give novice users hints about tools that are useful in a particular
95 * context even if they are not installed.
96 * - Improve self-documentation of applications.
97 *
98 *
99 * Presets
100 * -------
101 * Before installing desktop files in your application you might take a look
102 * at KMoreToolsPresets or KMoreToolsMenuFactory which might already contain
103 * the needed tools.
104 *
105 *
106 * Screenshots
107 * -----------
108 * This section shows screenshots of usage examples.
109 *
110 * ### KSnapshot's Send To... menu
111 *
112 * Last updated: 2015-04-17, uncommitted demo, source code:
113 * src/kde/kdegraphics/ksnapshot/ksnapshotsendtoactions.cpp
114 *
115 * Note, that the last item in the 'More' menu in the following screenshot was
116 * added by KSnapshot's code.
117 *
118 * \image html kmoretools-ksnapshot-sendto-1.png "Send To menu" width=100px
119 *
120 * ### Dolphins's Space info menu
121 *
122 * Last updated: 2015-04-17, uncommitted demo, source code: src/kde/applications/dolphin/src/statusbar/spaceinfotoolsmenu.cpp
123 *
124 * \image html kmoretools-dolphin-spaceinfo-1.png "Space info menu" width=100px
125 *
126 * ### Kate's Project plugin git menu
127 *
128 * Last updated: 2015-03-25, uncommitted demo, source code:
129 * src/kde/applications/kate/addons/project/kateprojecttreeviewcontextmenu.cpp
130 *
131 * \image html kmoretools-kate-project-1-all-installed.png "All git tools installed" width=100px
132 *
133 * \image html kmoretools-kate-project-2-two-not-installed.png "Not all git tools installed" width=100px
134 *
135 * \image html kmoretools-kate-project-3-config-dialog-all-installed.png "'Configure menu' dialog" width=100px
136 *
137 * ### Kate's Project plugin git menu
138 *
139 * Last updated: 2015-04-17, source code: src/frameworks/knewstuff/tests/kmoretools/kmoretoolstest.cpp
140 *
141 * \image html kmoretools-tests-configure-dialog-notinstalledapps.png "Configure dialog when there are non-installed apps" width=100px
142 *
143 *
144 * FAQ
145 * ---
146 * ### Why is everything based on desktopfiles?
147 *
148 * - With desktopfiles translation can be reused.
149 * - Definition of application icon can be reused.
150 * - They provide a unified interface for dealing with program arguments.
151 *
152 *
153 * todo later
154 * ----------
155 * - question: KMoreTools::registerServiceByDesktopEntryName():
156 * - warn if service is not of Type=Application (KService::isApplication()) or just leave it?
157 * Add support for package managers to install software (e.g. muon discover)
158 * - maybe: kmt-desktopfiles: add a config file that can configure the homepage URLs
159 * and e.g. the package name if needed for package manager support
160 *
161 */
162class KMORETOOLS_EXPORT KMoreTools
163{
164 friend class KMoreToolsService;
165 friend class KMoreToolsServicePrivate;
166
167public:
168 /**
169 * Specify how should be determined if a service is installed or not
170 */
172 /**
173 * by existence of desktop file (discoverable by KService)
174 */
176
177 /**
178 * by existence of executable defined in the TryExec or Exec line of
179 * the provided kmt-desktopfile
180 */
182 };
183
184 /**
185 * Specify where a menu item be placed by default
186 */
188 /**
189 * The item is placed in the main section (default)
190 */
192
193 /**
194 * The item is placed in the "More" submenu.
195 */
197 };
198
199 // /* *
200 // * todo/later: introduce when needed
201 // */
202 // enum NotInstalledSectionOption
203 // {
204 // /* *
205 // * default
206 // */
207 // NotInstalledSection_Show,
208 //
209 // /* *
210 // * Even if there are non-installed apps the Not-Installed section will
211 // * not be shown
212 // */
213 // NotInstalledSection_Hide
214 // };
215
216 /**
217 * Specify if the Configure dialog be accessible from the menu
218 * (via a "Configure..." menu item)
219 */
221 /**
222 * Always show the "Configure..." menu item
223 * (default)
224 */
226
227 /**
228 * Defensively show the "Configure..." menu item
229 *
230 * The "Configure..." menu item will only be shown if there are non-installed
231 * apps.
232 * Rationale (suggestion): Do not clutter menu more than needed in standard
233 * cases. But when there are not-installed apps the configure dialog can
234 * be used to find out more about these apps.
235 *
236 * Note, that the "Configure..." menu item still becomes visible when the
237 * user holds the Ctrl key while opening the menu.
238 */
240 };
241
242public:
243 /**
244 * @param uniqueId defines two things
245 * 1) the config section name where the user settings done by the Configure
246 * dialog will be stored.
247 * 2) the location where the kmt-desktopfiles should be installed because
248 * there they will be searched by default.
249 * If @p uniqueId contains slashes they will result in subdirectories.
250 * The default location can be overridden by
251 * registerServiceByDesktopEntryName's kmtDesktopfileSubdir parameter.
252 * This is currently used in KMoreToolsPresets implementation to
253 * separate the kmt-desktopfiles location from the user's config section
254 * name.
255 *
256 * Install Desktopfiles
257 * --------------------
258 * Example 1 (CMakeLists.txt if uniqueId = "dolphin/statusbar-diskspace-menu"):
259 * \verbatim
260 # note the trailing slash ------------. (it makes sure only the contents of the directory is copied)
261 # | ----fix---
262 # v ------ uniqueId-----------------
263 install(DIRECTORY statusbar/kmt-desktopfiles/ DESTINATION ${KDE_INSTALL_DATADIR_KF5}/kmoretools/dolphin/statusbar-diskspace-menu)
264 \endverbatim
265
266 Example 2:
267 \verbatim
268 ------ uniqueId--------------
269 install(DIRECTORY kmt-desktopfiles/ DESTINATION ${KDE_INSTALL_DATADIR_KF5}/kmoretools/kate/addons/project/git-tools)
270 \endverbatim
271 *
272 * ### About ${KDE_INSTALL_DATADIR_KF5}
273 *
274 * In general, ${KDE_INSTALL_DATADIR_KF5}/kmoretools/hallo ends up in /usr/share/kf5/kmoretools/hallo.
275 *
276 * To use it, you need to add \verbatim include(KDEInstallDirs) \endverbatim to your CMakeLists.txt.
277 */
278 explicit KMoreTools(const QString &uniqueId);
279
280 ~KMoreTools();
281
282 KMoreTools(const KMoreTools &) = delete;
283 KMoreTools &operator=(const KMoreTools &) = delete;
284
285 /**
286 * Registers a service with KMoreTools.
287 *
288 * If the method is called more than once for the same desktopEntryName
289 * the service is located again and the old service is replaced with the
290 * new one.
291 *
292 * @param desktopEntryName is the name of the desktopfile (without the
293 * .desktop extension)
294 * The desktop file is
295 * 1. either already installed. Then the information of the installed file
296 * is used.
297 * 2. or not installed and kmt-desktopfile is present. Then the information
298 * of the app-local copy of desktopfile located in the kmt-desktopfiles
299 * directory is used
300 * 3. or not installed and no kmt-desktopfile provided. In this case
301 * KMoreToolsService::setHomepageUrl should be used so that at least a
302 * website link can be displayed.
303 *
304 * @param kmtDesktopfileSubdir when not empty overrides the @p uniqueId
305 * parameter from the ctor when it comes to searching a kmt-desktopfile.
306 * Default value is the empty string.
307 *
308 * @param serviceLocatingMode == ServiceLocatingMode_ByProvidedExecLine:
309 * Some programs don't install a desktop file of their own (e.g. gitk).
310 * If set to true then installed desktop files are not searched
311 * but the provided in kmt-desktopfiles will be used to extract exec line.
312 * The exec line will be used to determine if the executable is installed.
313 *
314 * @return a KMoreToolsService pointer which lives as long as KMoreTools, so
315 * do not store it for later use.
316 * @return nullptr if the kmt provided desktop file is faulty.
317 * This kind of error must be fixed before you ship your application.
318 * This case is only used for unit tests.
319 */
320 KMoreToolsService *registerServiceByDesktopEntryName(const QString &desktopEntryName,
321 const QString &kmtDesktopfileSubdir = QString(),
322 ServiceLocatingMode serviceLocatingMode = ServiceLocatingMode_Default);
323
324 /**
325 * @returns the interface to build the menu. It is a singleton instance
326 * for each different @p userConfigPostfix (which is "" by default).
327 * So repeated calls with same parameter will return the same object.
328 *
329 * The pointer lives as long as KMoreTools.
330 *
331 * @param userConfigPostfix is empty by default. You can use it to specify
332 * a postfix for the user config section. So you can build different menus
333 * which can be configured separately. (This is used in unit tests to
334 * separated test cases.)
335 *
336 * @sa KMoreToolsMenuBuilder::clear()
337 */
338 KMoreToolsMenuBuilder *menuBuilder(const QString &userConfigPostfix = QString()) const;
339
340private:
341 const std::unique_ptr<KMoreToolsPrivate> d;
342};
343
344// --------------------------------------------------------------------------------------
345// --------------------------------------------------------------------------------------
346
347class KMoreToolsServicePrivate;
348
349/**
350 * A service described in a .desktop file (kmt-desktopfile) which will be
351 * called "registered service".
352 *
353 * A registered service can either be installed (isInstalled() == true)
354 * or - if not found on the system - not installed (isInstalled() == false).
355 */
356class KMORETOOLS_EXPORT KMoreToolsService
357{
358 friend class KMoreTools;
359 friend class KMoreToolsPrivate;
360
361public:
363
364 KMoreToolsService(const KMoreToolsService &) = delete;
365 KMoreToolsService &operator=(const KMoreToolsService &) = delete;
366
367 /**
368 * @return the desktop entry name which the service is identified by and with which
369 * it was registered (see registerServiceByDesktopEntryName).
370 *
371 * Filename without .desktop: e.g. if the desktop file is named
372 * "org.kde.ksnapshot.desktop" then the desktop entry name is
373 * "org.kde.ksnapshot".
374 */
375 QString desktopEntryName() const;
376
377 /**
378 * @returns true if the desktopfile with the given
379 * desktopname (name of the .desktop file without the .desktop)
380 * is installed on the system
381 */
382 bool isInstalled() const;
383
384 /**
385 * @returns the KService represented by an installed desktop file.
386 *
387 * @note that this might be nullptr even if isInstalled() is true.
388 * This can only happen when ServiceLocatingMode::ServiceLocatingMode_ByProvidedExecLine
389 * is used in registerServiceByDesktopEntryName. (Then the kmt-desktopfile's
390 * Exec line is used to determine if a program is installed)
391 */
392 KService::Ptr installedService() const;
393
394 /**
395 * @returns a non-null KService::Ptr if app-local kmt-desktopfile is
396 * found and valid
397 */
398 KService::Ptr kmtProvidedService() const;
399
400 /**
401 * @return the icon provided by the KMoreTools' user and not the installed one.
402 * (e.g. QGit currently has got a blank icon installed)
403 */
404 QIcon kmtProvidedIcon() const;
405
406 /**
407 * @see setHomepageUrl()
408 */
409 QUrl homepageUrl() const;
410
411 /**
412 * Sets the homepage url the user is shown when a service is not installed.
413 * This way the user gets some information of how to install the
414 * application.
415 */
416 void setHomepageUrl(const QUrl &url);
417
418 /**
419 * @see setMaxUrlArgCount()
420 */
421 int maxUrlArgCount() const;
422
423 /**
424 * In KMoreToolsMenuFactory some minor magic is done. In the context of
425 * connecting the action trigger signal we need to know the maximum number
426 * of URL arguments a given service can accept. Usually a number between
427 * 0 and 1. Sometimes 2.
428 * E.g. kdf must not be called with any positional argument.
429 * E.g. gitg can be called with zero or one arguments.
430 */
431 void setMaxUrlArgCount(int maxUrlArgCount);
432
433 /**
434 * @param formatString supports the following placeholders:
435 *
436 * 1. $GenericName
437 * 2. $Name
438 * 3. $DesktopEntryName
439 *
440 * which are replaced by the corresponding desktop file entries.
441 *
442 * If a value for a placeholder is not available (or empty)
443 * (e.g. if no desktop file is available (not installed or not provided
444 * via kmt-desktopfiles)) then the next one is used until 3. is reached which
445 * is always available. Example: the formatString is "$GenericName", but
446 * the GenericName field is not available. So $Name is used. If this is
447 * also not available, $DesktopEntryName is used.
448 *
449 * @sa KMoreToolsMenuItem::setInitialItemText
450 * @sa KMoreToolsMenuBuilder::setInitialItemTextTemplate
451 */
452 QString formatString(const QString &formatString) const;
453
454 /**
455 * 1. Icon from installed desktop file
456 * If 1. is not found not found then...
457 * 2. icon from kmt desktop file (which is then searched in the kmt-desktopfiles
458 * directory, must have extension .svg or .png)
459 * If 2. is not not found then...
460 * 3. no icon
461 */
462 QIcon icon() const;
463
464 /**
465 * Will override the "Exec=" line of the service. Will only apply if the
466 * service is installed.
467 *
468 * @see KService::setExec(...)
469 */
470 void setExec(const QString &exec);
471
472 /**
473 * Returns the associated appstream id that was previously set with setAppstreamId().
474 * If no appstream id was set, an empty string is returned.
475 *
476 * @return The service's appstream id.
477 */
478 QString appstreamId() const;
479
480 /**
481 * Sets the appstream id of the service. This is used to create a
482 * appstream url for installing the service via a software store
483 * (e.g. Discover). For instance, the appstream id for filelight is
484 * "org.kde.filelight.desktop".
485 *
486 * @param id the appstream id
487 */
488 void setAppstreamId(const QString &);
489
490private:
491 /**
492 * @param kmtDesktopfileSubdir where to find kmt-desktopfiles
493 * @param desktopEntryName name of the desktopfile without the .desktop extension
494 * @param isInstalled true if desktop file is installed
495 * @param installedService not nullptr if @p isInstalled is true
496 * @param kmtDesktopfile not null if app-local kmt-desktopfile is found and valid
497 */
498 KMoreToolsService(const QString &kmtDesktopfileSubdir,
499 const QString &desktopEntryName,
500 bool isInstalled,
501 KService::Ptr installedService,
502 KService::Ptr kmtDesktopfile);
503
504 /**
505 * No copy semantic => private and no implementation
506 */
508
509 const std::unique_ptr<KMoreToolsServicePrivate> d;
510};
511
512// --------------------------------------------------------------------------------------
513// --------------------------------------------------------------------------------------
514
516class KMoreToolsMenuBuilderPrivate;
517
518/**
519 * Define how the default structure of the menu should look like.
520 *
521 * Depending on if the added service is installed or not a "Not installed" section
522 * will be automatically added to the generated menu.
523 */
524class KMORETOOLS_EXPORT KMoreToolsMenuBuilder
525{
526 friend class KMoreToolsPrivate;
527 friend class KMoreTools;
528 friend class KMoreToolsTest;
529 friend class KMoreToolsTest2;
530 friend class KMoreToolsTestInteractive;
531
532public:
534
536 KMoreToolsMenuBuilder &operator=(const KMoreToolsMenuBuilder &) = delete;
537
538 /**
539 * Affects addMenuItem() if called before it.
540 *
541 * see KMoreToolsService::formatString, see KMoreToolsMenuItem::setInitialItemText
542 *
543 * The default template text is "$GenericName".
544 */
545 void setInitialItemTextTemplate(const QString &templateText);
546
547 /**
548 * Adds a registered service (which can installed or not) to the menu.
549 * If the service is not installed it will be shown in the "Not installed"
550 * section.
551 *
552 * @param registeredService will be added to a the menu. A unique menu
553 * itemId will be generated automatically from the desktopEntryName.
554 * See also KMoreToolsMenuItem::id().
555 *
556 * @param defaultLocation is KMoreTools::MenuSection_Main by default.
557 *
558 * The registeredService->isInstalled() result will be respected. E.g. if the service
559 * is not installed it will be placed in the "Not installed" section in the more
560 * location of the menu even if @p defaultLocation was main location.
561 *
562 * See also KMoreToolsMenuItem ctor
563 *
564 * @sa KMoreToolsMenuItem::action()
565 */
566 KMoreToolsMenuItem *addMenuItem(KMoreToolsService *registeredService, KMoreTools::MenuSection defaultLocation = KMoreTools::MenuSection_Main);
567
568 /**
569 * Adds an action to the menu which is created and managed by the caller.
570 *
571 * @param action to be added to the menu.
572 *
573 * @param itemId is a unique (for this menu) id for the item. The itemId
574 * _may_ be not unique. Then a unique id is generated automatically by
575 * using some postfix. But it is better if you specify something sensible
576 * because the itemId is used to find the items in the user config.
577 * Otherwise the user config can be messed up if the order or number
578 * of default menu items changes. NOTE, that the QAction::text is NOT
579 * used to generate the unique id because the text is translated and
580 * therefore not stable.
581 *
582 * @sa KMoreToolsMenuItem::action()
583 */
584 KMoreToolsMenuItem *addMenuItem(QAction *action, const QString &itemId, KMoreTools::MenuSection defaultLocation = KMoreTools::MenuSection_Main);
585
586 /**
587 * Clears all added menu items. This can be useful if the menuBuilder is reused more than once.
588 *
589 * @sa KMoreToolsService::menuBuilder
590 */
591 void clear();
592
593 /**
594 * Builds the actual menu and appends all items (main items,
595 * more submenu with a potential "not installed" section) to the @p menu.
596 *
597 * @param menu the menu where the items should be appended to
598 *
599 * @param configureDialogAccessibleSetting determines when the
600 * "Configure..." menu item should be added to the menu
601 *
602 * @param moreMenu if not nullptr then it will be set to the pointer to the
603 * "More" menu in case it was created.
604 * Otherwise the pointer will set to nullptr.
605 * This can be used to add some custom items to the @p menu.
606 */
607 void buildByAppendingToMenu(QMenu *menu,
609 QMenu **outMoreMenu = nullptr);
610
611private:
612 /**
613 * for unit testing / get as debug string
614 */
615 QString menuStructureAsString(bool mergeWithUserConfig) const;
616
617 /**
618 * for unit testing
619 */
620 void showConfigDialog(const QString &title);
621
622 /**
623 * (needed because QMap needs a default ctor)
624 */
626
627 /**
628 * internal usage
629 */
630 KMoreToolsMenuBuilder(const QString &uniqueId, const QString &userConfigPostfix);
631
632 /**
633 * No copy semantic => private and no implementation
634 */
636
637 const std::unique_ptr<KMoreToolsMenuBuilderPrivate> d;
638};
639
640// --------------------------------------------------------------------------------------
641// --------------------------------------------------------------------------------------
642
643class KMoreToolsMenuItemPrivate;
644
645/**
646 * Represents a menu item of a service (application, tool or variant of the same
647 * service with different parameters).
648 *
649 * The service might be installed or not.
650 *
651 * The corresponding QAction will be created for installed services.
652 *
653 * @note that for not-installed services action() returns nullptr.
654 */
655class KMORETOOLS_EXPORT KMoreToolsMenuItem
656{
657 friend class KMoreToolsMenuBuilderPrivate;
658 friend class KMoreToolsMenuBuilder;
659
660public:
661 KMoreToolsMenuItem(const KMoreToolsMenuItem &) = delete;
662 KMoreToolsMenuItem &operator=(const KMoreToolsMenuItem &) = delete;
663
664 /**
665 * Auto-generated unique id that tries to be as stable as possible even if the
666 * menu gets restructured after the user did some customization that was
667 * persisted in a config file.
668 *
669 * @note It is possible to add the same service more than once (and then
670 * hopefully change the action text). When the order of those are changed,
671 * the id will not be consistent (because internally an increasing number is used)
672 * If you have issues with this you can solve this by manually
673 * calling setId (e.g. 'desktopEntryName' + 'x').
674 */
675 QString id() const;
676
677 /**
678 * (Optional) to help with stable ids (see id())
679 *
680 * todo: make sure that if this is called, uniqueness of ids will be assured.
681 * todo: make sure to show error if the id contains characters other than
682 * alphanumerica, dashes and underscores etc.
683 */
684 void setId(const QString &id);
685
686 /**
687 * @return the underlying KMoreToolsService instance,
688 * see KMoreToolsMenuBuilder::addMenuItem (with KKmoreToolsService* argument).
689 * Or nullptr when KMoreToolsMenuBuilder::addMenuItem (with QAction* argument
690 * was used).
691 */
692 KMoreToolsService *registeredService() const;
693
694 /**
695 * see KMoreToolsMenuBuilder::addMenuItem
696 */
697 KMoreTools::MenuSection defaultLocation() const;
698
699 /**
700 * see setInitialItemText()
701 */
702 QString initialItemText() const;
703
704 /**
705 * Sets the initial text of a menu item.
706 *
707 * Menu items of a non-installed service will get this text.
708 * If the service is installed and you would like to change the item text,
709 * you can retrieve the created QAction (action())
710 * and modify the text using QAction's methods (QAction::setText()).
711 *
712 * @see
713 * - initialItemText()
714 * - action()
715 * - You can use the static method KMoreToolsService::formatString here.
716 */
717 void setInitialItemText(const QString &itemText);
718
719 /**
720 * Case 1
721 * ------
722 * KMoreToolsMenuBuilder::addMenuItem was called with KKmoreToolsService* argument.
723 *
724 * the corresponding QAction which will be added to the actual menu when
725 * underlying service is installed or else - if not installed - nullptr.
726 *
727 * So you can change the created action as you desire.
728 *
729 * We return nullptr because not-installed services will get a submenu with
730 * other items like opening a website instead of an single action.
731 *
732 * To change the item's text even for not-installed services use initialItemText()
733 *
734 * Note, that once the method was invoked the first time the action is created
735 * an then reused.
736 *
737 * Case 2
738 * ------
739 * KMoreToolsMenuBuilder::addMenuItem was called with QAction* argument.
740 * The added action will be returned.
741 *
742 * @see KMoreToolsService::isInstalled
743 */
744 QAction *action() const;
745
746private: // internal usage
747 /**
748 * Sets the initial item text.
749 */
750 KMoreToolsMenuItem(KMoreToolsService *registeredService, KMoreTools::MenuSection defaultLocation, const QString &initialItemTextTemplate);
751
752 KMoreToolsMenuItem(QAction *action, const QString &itemId, KMoreTools::MenuSection defaultLocation);
753
755
756private:
757 const std::unique_ptr<KMoreToolsMenuItemPrivate> d;
758};
759
760#endif // KMORETOOLS_H
Define how the default structure of the menu should look like.
Definition kmoretools.h:525
Represents a menu item of a service (application, tool or variant of the same service with different ...
Definition kmoretools.h:656
A service described in a .desktop file (kmt-desktopfile) which will be called "registered service".
Definition kmoretools.h:357
Helps to create user-configurable menus with tools which are potentially not yet installed.
Definition kmoretools.h:163
MenuSection
Specify where a menu item be placed by default.
Definition kmoretools.h:187
@ MenuSection_More
The item is placed in the "More" submenu.
Definition kmoretools.h:196
@ MenuSection_Main
The item is placed in the main section (default)
Definition kmoretools.h:191
ConfigureDialogAccessibleSetting
Specify if the Configure dialog be accessible from the menu (via a "Configure..." menu item)
Definition kmoretools.h:220
@ ConfigureDialogAccessible_Always
Always show the "Configure..." menu item (default)
Definition kmoretools.h:225
@ ConfigureDialogAccessible_Defensive
Defensively show the "Configure..." menu item.
Definition kmoretools.h:239
ServiceLocatingMode
Specify how should be determined if a service is installed or not.
Definition kmoretools.h:171
@ ServiceLocatingMode_Default
by existence of desktop file (discoverable by KService)
Definition kmoretools.h:175
@ ServiceLocatingMode_ByProvidedExecLine
by existence of executable defined in the TryExec or Exec line of the provided kmt-desktopfile
Definition kmoretools.h:181
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:15:34 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.