KService

kservice.h
1 /*
2  This file is part of the KDE project
3  SPDX-FileCopyrightText: 1998, 1999 Torben Weis <[email protected]>
4  SPDX-FileCopyrightText: 1999-2006 David Faure <[email protected]>
5  SPDX-FileCopyrightText: 2022 Harald Sitter <[email protected]>
6 
7  SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #ifndef KSERVICE_H
11 #define KSERVICE_H
12 
13 #include "kserviceaction.h"
14 #include <QCoreApplication>
15 #include <QStringList>
16 #include <QVariant>
17 #include <ksycocaentry.h>
18 
19 // Exclude includes that are not needed when deprecations are disabled
20 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 94)
21 #include <KPluginFactory>
22 #include <KPluginLoader>
23 #endif
24 
25 class KServiceType;
26 class QDataStream;
27 class KDesktopFile;
28 class QWidget;
29 
30 class KServicePrivate;
31 
32 /**
33  * @class KService kservice.h <KService>
34  *
35  * Represent a service, like an application or plugin
36  * bound to one or several MIME types (or servicetypes) as written
37  * in its desktop entry file.
38  *
39  * The starting point you need is often the static methods, like createInstance().
40  * The types of service a plugin provides is taken from the accompanying desktop file
41  * where the 'X-KDE-ServiceTypes=' field is used.
42  *
43  * For a tutorial on how to build a plugin-loading mechanism and how to write plugins
44  * in general, see http://techbase.kde.org/Development/Tutorials#Services:_Applications_and_Plugins
45  *
46  * @see KServiceType
47  * @see KServiceGroup
48  * @author Torben Weis
49  */
50 class KSERVICE_EXPORT KService : public KSycocaEntry
51 {
52 public:
53  /**
54  * A shared data pointer for KService.
55  */
57  /**
58  * A list of shared data pointers for KService.
59  */
60  typedef QList<Ptr> List;
61 
62  /**
63  * Construct a temporary service with a given name, exec-line and icon.
64  * @param name the name of the service
65  * @param exec the executable
66  * @param icon the name of the icon
67  */
68  KService(const QString &name, const QString &exec, const QString &icon);
69 
70  /**
71  * Construct a service and take all information from a config file.
72  *
73  * @param fullpath Full path to the config file.
74  */
75  explicit KService(const QString &fullpath);
76 
77  /**
78  * Construct a service and take all information from a desktop file.
79  * @param config the desktop file to read
80  * @param optional relative path to store for findByName
81  */
82  explicit KService(const KDesktopFile *config, const QString &entryPath = QString());
83 
84  KService(const KService &other);
85 
86  ~KService() override;
87 
88  /**
89  * Services are either applications (executables) or dlopened libraries (plugins).
90  * @return true if this service is an application, i.e. it has Type=Application in its
91  * .desktop file and exec() will not be empty.
92  */
93  bool isApplication() const;
94 
95  /**
96  * Returns the executable.
97  * @return the command that the service executes,
98  * or QString() if not set
99  */
100  QString exec() const;
101  /**
102  * Returns the name of the service's library.
103  * @return the name of the library that contains the service's
104  * implementation, or QString() if not set
105  */
106  QString library() const;
107 
108  /**
109  * Returns the name of the icon.
110  * @return the icon associated with the service,
111  * or QString() if not set
112  */
113  QString icon() const;
114  /**
115  * Checks whether the service should be run in a terminal.
116  * @return true if the service is to be run in a terminal.
117  */
118  bool terminal() const;
119 
120  /**
121  * Returns any options associated with the terminal the service
122  * runs in, if it requires a terminal.
123  *
124  * The service must be a tty-oriented program.
125  * @return the terminal options,
126  * or QString() if not set
127  */
128  QString terminalOptions() const;
129 
130  /**
131  * Returns @c true if the service inidicates that it's preferred to run
132  * the application on a discrete graphics card, otherwise return @c false.
133  *
134  * In releases older than 5.86 this methoed checked for the @c X-KDE-RunOnDiscreteGpu
135  * key in the .desktop file represented by this service; starting from 5.86 this method
136  * now also checks for @c PrefersNonDefaultGPU key (added to the Freedesktop.org desktop
137  * entry spec in version 1.4 of the spec).
138  *
139  * @since 5.30
140  */
141  bool runOnDiscreteGpu() const;
142 
143  /**
144  * Checks whether the service runs with a different user id.
145  * @return true if the service has to be run under a different uid.
146  * @see username()
147  */
148  bool substituteUid() const;
149  /**
150  * Returns the user name, if the service runs with a
151  * different user id.
152  * @return the username under which the service has to be run,
153  * or QString() if not set
154  * @see substituteUid()
155  */
156  QString username() const;
157 
158  /**
159  * Returns the filename of the service desktop entry without any
160  * extension. E.g. "kppp"
161  * @return the name of the desktop entry without path or extension,
162  * or QString() if not set
163  */
164  QString desktopEntryName() const;
165 
166  /**
167  * Returns the menu ID of the service desktop entry.
168  * The menu ID is used to add or remove the entry to a menu.
169  * @return the menu ID
170  */
171  QString menuId() const;
172 
173  /**
174  * Returns a normalized ID suitable for storing in configuration files.
175  * It will be based on the menu-id when available and otherwise falls
176  * back to entryPath()
177  * @return the storage ID
178  */
179  QString storageId() const;
180 
181 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 102)
182  /**
183  * Describes the D-Bus Startup type of the service.
184  * @li None - This service has no D-Bus support
185  * @li Unique - This service provides a unique D-Bus service.
186  * The service name is equal to the desktopEntryName.
187  * @li Multi - This service provides a D-Bus service which can be run
188  * with multiple instances in parallel. The service name of
189  * an instance is equal to the desktopEntryName + "-" +
190  * the PID of the process.
191  */
192  enum DBusStartupType { DBusNone = 0, DBusUnique, DBusMulti };
193 #endif
194 
195 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 102)
196  /**
197  * Returns the DBUSStartupType supported by this service.
198  * @return the DBUSStartupType supported by this service
199  *
200  * @deprecated since 5.102, no known users.
201  */
202  KSERVICE_DEPRECATED_VERSION(5, 102, "No known users")
203  DBusStartupType dbusStartupType() const;
204 #endif
205 
206 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 63)
207  /**
208  * @return the working directory to run the program in,
209  * or QString() if not set
210  * @deprecated since 5.63, use workingDirectory() instead
211  */
212  KSERVICE_DEPRECATED_VERSION(5, 63, "Use KService::workingDirectory()")
213  QString path() const;
214 #endif
215 
216  /**
217  * @return the working directory to run the program in,
218  * or QString() if not set
219  * @since 5.63
220  */
221  QString workingDirectory() const;
222 
223  /**
224  * Returns the descriptive comment for the service, if there is one.
225  * @return the descriptive comment for the service, or QString()
226  * if not set
227  */
228  QString comment() const;
229 
230  /**
231  * Returns the generic name for the service, if there is one
232  * (e.g. "Mail Client").
233  * @return the generic name,
234  * or QString() if not set
235  */
236  QString genericName() const;
237 
238  /**
239  * Returns the untranslated (US English) generic name
240  * for the service, if there is one
241  * (e.g. "Mail Client").
242  * @return the generic name,
243  * or QString() if not set
244  */
245  QString untranslatedGenericName() const;
246 
247  /**
248  * Returns a list of descriptive keywords the service, if there are any.
249  * @return the list of keywords
250  */
251  QStringList keywords() const;
252 
253  /**
254  * Returns a list of VFolder categories.
255  * @return the list of VFolder categories
256  */
257  QStringList categories() const;
258 
259  /**
260  * Returns the list of MIME types that this service supports.
261  * Note that this doesn't include inherited MIME types,
262  * only the MIME types listed in the .desktop file.
263  * @since 4.8.3
264  */
265  QStringList mimeTypes() const;
266 
267  /**
268  * Returns the service types that this service supports.
269  * @return the list of service types that are supported
270  * Note that this doesn't include inherited servicetypes or MIME types,
271  * only the service types listed in the .desktop file.
272  */
273  QStringList serviceTypes() const;
274 
275  /**
276  * Checks whether the service supports this service type
277  * @param serviceTypePtr The name of the service type you are
278  * interested in determining whether this service supports.
279  *
280  * @return true if the service type you specified is supported, otherwise false.
281  */
282  bool hasServiceType(const QString &serviceTypePtr) const;
283 
284  /**
285  * Checks whether the service supports this MIME type
286  * @param mimeType The name of the MIME type you are
287  * interested in determining whether this service supports.
288  * @since 4.6
289  */
290  bool hasMimeType(const QString &mimeType) const;
291 
292 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 67)
293  /**
294  * Set to true if it is allowed to use this service as the default (main)
295  * action for the files it supports (e.g. Left Click in a file manager, or KRun in general).
296  *
297  * If not, then this service is only available in RMB popups, so it must
298  * be selected explicitly by the user in order to be used.
299  * Note that servicemenus supersede this functionality though, at least in konqueror.
300  *
301  * @return true if the service may be used as the default (main) handler
302  * @deprecated since 5.67 due to no known use case
303  */
304  KSERVICE_DEPRECATED_VERSION(5, 67, "No known use case")
305  bool allowAsDefault() const;
306 #endif
307 
308  /**
309  * Returns the actions defined in this desktop file
310  */
311  QList<KServiceAction> actions() const;
312 
313  /**
314  * Checks whether this service can handle several files as
315  * startup arguments.
316  * @return true if multiple files may be passed to this service at
317  * startup. False if only one file at a time may be passed.
318  */
319  bool allowMultipleFiles() const;
320 
321  /**
322  * What preference to associate with this service initially (before
323  * the user has had any chance to define a profile for it).
324  * The bigger the value, the most preferred the service is.
325  * @return the service preference level of the service
326  */
327  int initialPreference() const;
328 
329  /**
330  * Whether the entry should be suppressed in the K menu.
331  * @return true to suppress this service
332  *
333  * Such services still appear in trader queries, i.e. in
334  * "Open With" popup menus for instance.
335  */
336  bool noDisplay() const;
337 
338 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 0)
339  /**
340  * Whether the service should be shown in KDE at all
341  * (including in context menus).
342  * @return true if the service should be shown.
343  *
344  * KMimeTypeTrader honors this and removes such services
345  * from its results.
346  *
347  * @since 4.5
348  * @deprecated since 5.0, use showInCurrentDesktop()
349  */
350  KSERVICE_DEPRECATED_VERSION(5, 0, "Use KService::showInCurrentDesktop()")
351  bool showInKDE() const
352  {
353  return showInCurrentDesktop();
354  }
355 #endif
356 
357  /**
358  * Whether the service should be shown in the current desktop
359  * (including in context menus).
360  * @return true if the service should be shown.
361  *
362  * KApplicationTrader honors this and removes such services
363  * from its results.
364  *
365  * @since 5.0
366  */
367  bool showInCurrentDesktop() const;
368 
369  /**
370  * Whether the service should be shown on the current
371  * platform (e.g. on xcb or on wayland).
372  * @return true if the service should be shown
373  *
374  * @since 5.0
375  */
376  bool showOnCurrentPlatform() const;
377 
378 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 87)
379  /**
380  * Name of the application this service belongs to.
381  * (Useful for e.g. plugins)
382  * @return the parent application, or QString() if not set
383  * @deprecated Since 5.87, the concept of parent apps is deprecated. Plugins should use KPluginMetaData instead of
384  * KService and a dedicated namespace if the plugins are only for one app relevant.
385  */
386  KSERVICE_DEPRECATED_VERSION(5, 87, "See API docs")
387  QString parentApp() const;
388 #endif
389 
390 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 87)
391  /**
392  * The keyword to be used when constructing the plugin using KPluginFactory. The keyword is
393  * defined with X-KDE-PluginKeyword in the .desktop file and with registerPlugin<T>(keyword)
394  * in the K_PLUGIN_FACTORY macro when implementing the plugin.
395  * @deprecated Since 5.87, the metadata should be embedded in the actual plugin. Consequently
396  * this property is obsolete. In case there is only one plugin in the library the usage is not needed.
397  * In case there are different base classes registered the keyword is not needed too.
398  * If there are multiple classes of a common base class registered they should be split up
399  * in separate libs.
400  */
401  KSERVICE_DEPRECATED_VERSION(5, 87, "See API docs")
402  QString pluginKeyword() const;
403 #endif
404 
405  /**
406  * The path to the documentation for this service.
407  * @since 4.2
408  * @return the documentation path, or QString() if not set
409  */
410  QString docPath() const;
411 
412 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 102)
413  /**
414  * Returns the requested property.
415  *
416  * @param _name the name of the property
417  * @param t the assumed type of the property
418  * @return the property, or invalid if not found
419  * @see KServiceType
420  *
421  * @deprecated since 5.102, use property(QString, QMetaType::Type) instead.
422  */
423  KSERVICE_DEPRECATED_VERSION(5, 102, "Use property(QString, QMetaType::Type) instead")
424  QVariant property(const QString &_name, QVariant::Type t) const;
425 #endif
426 
427  /**
428  * Returns the requested property.
429  *
430  * @param _name the name of the property
431  * @param t the assumed type of the property
432  * @return the property, or invalid if not found
433  * @see KServiceType
434  *
435  * @since 5.102
436  */
437  QVariant property(const QString &_name, QMetaType::Type t) const;
438 
440 
441  /**
442  * Returns a path that can be used for saving changes to this
443  * service
444  * @return path that can be used for saving changes to this service
445  */
446  QString locateLocal() const;
447 
448  /**
449  * @internal
450  * Set the menu id
451  */
452  void setMenuId(const QString &menuId);
453  /**
454  * @internal
455  * Sets whether to use a terminal or not
456  */
457  void setTerminal(bool b);
458  /**
459  * @internal
460  * Sets the terminal options to use
461  */
462  void setTerminalOptions(const QString &options);
463 
464  /**
465  * Overrides the "Exec=" line of the service.
466  *
467  * If @ref exec is not empty, its value will override the one
468  * the one set when this service was created.
469  *
470  * Please note that @ref entryPath is also cleared so the service
471  * will no longer be associated with a specific config file.
472  *
473  * @internal
474  * @since 4.11
475  */
476  void setExec(const QString &exec);
477 
478  /**
479  * Overrides the "Path=" line of the service.
480  *
481  * If @ref workingDir is not empty, its value will override the one
482  * the one set when this service was created.
483  *
484  * Please note that @ref entryPath is also cleared so the service
485  * will no longer be associated with a specific config file.
486  *
487  * @internal
488  * @param workingDir
489  * @since 5.79
490  */
491  void setWorkingDirectory(const QString &workingDir);
492 
493  /**
494  * Find a service based on its path as returned by entryPath().
495  * It's usually better to use serviceByStorageId() instead.
496  *
497  * @param _path the path of the configuration file
498  * @return a pointer to the requested service or @c nullptr if the service is
499  * unknown.
500  * @em Very @em important: Don't store the result in a KService* !
501  */
502  static Ptr serviceByDesktopPath(const QString &_path);
503 
504  /**
505  * Find a service by the name of its desktop file, not depending on
506  * its actual location (as long as it's under the applications or service
507  * directories). For instance "konqbrowser" or "kcookiejar". Note that
508  * the ".desktop" extension is implicit.
509  *
510  * This is the recommended method (safe even if the user moves stuff)
511  * but note that it assumes that no two entries have the same filename.
512  *
513  * @param _name the name of the configuration file
514  * @return a pointer to the requested service or @c nullptr if the service is
515  * unknown.
516  * @em Very @em important: Don't store the result in a KService* !
517  */
518  static Ptr serviceByDesktopName(const QString &_name);
519 
520  /**
521  * Find a service by its menu-id
522  *
523  * @param _menuId the menu id of the service
524  * @return a pointer to the requested service or @c nullptr if the service is
525  * unknown.
526  * @em Very @em important: Don't store the result in a KService* !
527  */
528  static Ptr serviceByMenuId(const QString &_menuId);
529 
530  /**
531  * Find a service by its storage-id or desktop-file path. This
532  * function will try very hard to find a matching service.
533  *
534  * @param _storageId the storage id or desktop-file path of the service
535  * @return a pointer to the requested service or @c nullptr if the service is
536  * unknown.
537  * @em Very @em important: Don't store the result in a KService* !
538  */
539  static Ptr serviceByStorageId(const QString &_storageId);
540 
541  /**
542  * Returns the whole list of services.
543  *
544  * Useful for being able to
545  * to display them in a list box, for example.
546  * More memory consuming than the ones above, don't use unless
547  * really necessary.
548  * @return the list of all services
549  */
550  static List allServices();
551 
552  /**
553  * Returns a path that can be used to create a new KService based
554  * on @p suggestedName.
555  * @param showInMenu true, if the service should be shown in the KDE menu
556  * false, if the service should be hidden from the menu
557  * This argument isn't used anymore, use NoDisplay=true to hide the service.
558  * @param suggestedName name to base the file on, if a service with such a
559  * name already exists, a suffix will be added to make it unique
560  * (e.g. foo.desktop, foo-1.desktop, foo-2.desktop).
561  * @param menuId If provided, menuId will be set to the menu id to use for
562  * the KService
563  * @param reservedMenuIds If provided, the path and menu id will be chosen
564  * in such a way that the new menu id does not conflict with any
565  * of the reservedMenuIds
566  * @return The path to use for the new KService.
567  */
568  static QString newServicePath(bool showInMenu, const QString &suggestedName, QString *menuId = nullptr, const QStringList *reservedMenuIds = nullptr);
569 
570 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 86)
571 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 86)
572  /**
573  * This template allows to load the library for the specified service and ask the
574  * factory to create an instance of the given template type.
575  *
576  * @param parent The parent object (see QObject constructor)
577  * @param args A list of arguments, passed to the factory and possibly
578  * to the component (see KPluginFactory)
579  * @param error A pointer to QString which should receive the error description or @c nullptr
580  *
581  * @return A pointer to the newly created object or a null pointer if the
582  * factory was unable to create an object of the given type.
583  *
584  * @see KPluginFactory::instantiatePlugin
585  * @deprecated Since 5.86, Use KPluginMetaData/KPluginFactory or QPluginloader instead
586  */
587  template<class T>
588  KSERVICE_DEPRECATED_VERSION(5, 86, "Use KPluginMetaData/KPluginFactory or QPluginloader instead")
589  T *createInstance(QObject *parent = nullptr, const QVariantList &args = QVariantList(), QString *error = nullptr) const
590  {
591  return createInstance<T>(nullptr, parent, args, error);
592  }
593 #endif
594 #endif
595 
596 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 86)
597 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 86)
598  /**
599  * This template allows to load the library for the specified service and ask the
600  * factory to create an instance of the given template type.
601  *
602  * @param parentWidget A parent widget for the service. This is used e. g. for parts
603  * @param parent The parent object (see QObject constructor)
604  * @param args A list of arguments, passed to the factory and possibly
605  * to the component (see KPluginFactory)
606  * @param error A pointer to QString which should receive the error description or @c nullptr
607  *
608  * @return A pointer to the newly created object or a null pointer if the
609  * factory was unable to create an object of the given type.
610  *
611  * @see KPluginFactory::instantiatePlugin
612  * @deprecated Since 5.86, Use KPluginMetaData/KPluginFactory or QPluginloader instead
613  */
614  template<class T>
615  KSERVICE_DEPRECATED_VERSION(5, 86, "Use KPluginMetaData/KPluginFactory or QPluginloader instead")
616  T *createInstance(QWidget *parentWidget, QObject *parent, const QVariantList &args = QVariantList(), QString *error = nullptr) const
617  {
618  QT_WARNING_PUSH
619  QT_WARNING_DISABLE_DEPRECATED
620  KPluginLoader pluginLoader(*this);
621  KPluginFactory *factory = pluginLoader.factory();
622  if (factory) {
623  QVariantList argsWithMetaData = args;
624  argsWithMetaData << pluginLoader.metaData().toVariantMap();
625  T *o = factory->template create<T>(parentWidget, parent, pluginKeyword(), argsWithMetaData);
626  if (!o && error)
627  *error = QCoreApplication::translate("", "The service '%1' does not provide an interface '%2' with keyword '%3'")
628  .arg(name(), QString::fromLatin1(T::staticMetaObject.className()), pluginKeyword());
629  return o;
630  } else if (error) {
631  *error = pluginLoader.errorString();
632  pluginLoader.unload();
633  }
634  QT_WARNING_POP
635  return nullptr;
636  }
637 #endif
638 #endif
639 
640 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 86)
641 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 86)
642  /**
643  * Convert this KService to a KPluginName.
644  *
645  * This allows expressions like
646  * @code
647  * KPluginLoader(service);
648  * @endcode
649  * which will use library() as the name of the plugin. If the service
650  * is not valid or does not have a library, KPluginLoader::errorString()
651  * will be set appropriately.
652  */
653  operator KPluginName() const;
654 #endif
655 #endif
656 
657  /**
658  * @brief A desktop file name that this service is an alias for.
659  *
660  * This is used when a NoDisplay service is used to enforce specific handling
661  * for an application. In that case the NoDisplay service is an AliasFor another
662  * service and be considered roughly equal to the AliasFor service (which should
663  * not be NoDisplay=true)
664  * For example okular supplies a desktop file for each supported format (e.g. PDF), all
665  * of which NoDisplay and merely there to selectively support specific file formats.
666  * A UI may choose to display the aliased entry org.kde.okular instead of the NoDisplay entries.
667  *
668  * @since 5.96
669  *
670  * @return QString desktopName of the aliased service (excluding .desktop suffix)
671  */
672  QString aliasFor() const;
673 
674 private:
675  friend class KBuildServiceFactory;
676 
677  /// @internal for KBuildSycoca only
678  struct ServiceTypeAndPreference {
679  ServiceTypeAndPreference()
680  : preference(-1)
681  , serviceType()
682  {
683  }
684  ServiceTypeAndPreference(int pref, const QString &servType)
685  : preference(pref)
686  , serviceType(servType)
687  {
688  }
689  int preference;
690  QString serviceType; // or MIME type
691  };
692  /// @internal for KBuildSycoca only
693  QVector<ServiceTypeAndPreference> &_k_accessServiceTypes();
694 
695  friend QDataStream &operator>>(QDataStream &, ServiceTypeAndPreference &);
696  friend QDataStream &operator<<(QDataStream &, const ServiceTypeAndPreference &);
697 
698  Q_DECLARE_PRIVATE(KService)
699 
700  friend class KServiceFactory;
701 
702  /**
703  * @internal
704  * Construct a service from a stream.
705  * The stream must already be positioned at the correct offset.
706  */
707  KService(QDataStream &str, int offset);
708 };
709 #endif
QString storageId() const
QVariant property(const QString &name) const
Returns the requested property.
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
Base class for all Sycoca entries.
Definition: ksycocaentry.h:32
QList< Ptr > List
A list of shared data pointers for KService.
Definition: kservice.h:60
QDataStream & operator<<(QDataStream &out, const KDateTime &dateTime)
QExplicitlySharedDataPointer< KService > Ptr
A shared data pointer for KService.
Definition: kservice.h:56
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString name() const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
DBusStartupType
Describes the D-Bus Startup type of the service.
Definition: kservice.h:192
QDataStream & operator>>(QDataStream &in, KDateTime &dateTime)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:00:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.