Kstars

kstarsdata.h
1 /*
2  SPDX-FileCopyrightText: 2001 Heiko Evermann <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "colorscheme.h"
10 #include "geolocation.h"
11 #include "ksnumbers.h"
12 #include "kstarsdatetime.h"
13 #include "ksuserdb.h"
14 #include "simclock.h"
15 #include "skyobjectuserdata.h"
16 #include <qobject.h>
17 #ifndef KSTARS_LITE
18 #include "oal/oal.h"
19 #include "oal/log.h"
20 #include "polyfills/qstring_hash.h"
21 #endif
22 
23 #include <QList>
24 #include <QMap>
25 #include <QKeySequence>
26 #include <QMutex>
27 
28 #include <iostream>
29 #include <memory>
30 #include <unordered_map>
31 
32 #define MINZOOM 250.
33 #define MAXZOOM 5000000.
34 #define DEFAULTZOOM 2000.
35 #define DZOOM 1.189207115 // 2^(1/4)
36 #define AU_KM 1.49605e8 //km in one AU
37 
38 class QFile;
39 
40 class Execute;
41 class FOV;
42 class ImageExporter;
43 class SkyMap;
44 class SkyMapComposite;
45 class SkyObject;
46 class ObservingList;
47 class TimeZoneRule;
48 
49 #ifdef KSTARS_LITE
50 //Will go away when details window will be implemented in KStars Lite
51 struct ADVTreeData
52 {
53  QString Name;
54  QString Link;
55  int Type;
56 };
57 #else
58 struct ADVTreeData;
59 #endif
60 
61 /**
62  * @class KStarsData
63  * KStarsData is the backbone of KStars. It contains all the data used by KStars,
64  * including the SkyMapComposite that contains all items in the skymap
65  * (stars, deep-sky objects, planets, constellations, etc). Other kinds of data
66  * are stored here as well: the geographic locations, the timezone rules, etc.
67  *
68  * @author Heiko Evermann
69  * @version 1.0
70  */
71 class KStarsData : public QObject
72 {
73  Q_OBJECT
74 
75  protected:
76  /** Constructor. */
77  KStarsData();
78 
79  public:
80  // FIXME: It uses temporary trail. There must be way to
81  // this better. And resumeKey in DBUS code
82  friend class KStars;
83  // FIXME: it uses temporary trail and resumeKey
84  friend class SkyMap;
85  // FIXME: uses geoList and changes it.
86  friend class LocationDialog;
87  friend class LocationDialogLite;
88 
89  static KStarsData *Create();
90 
91  static inline KStarsData *Instance()
92  {
93  return pinstance;
94  }
95 
96  /**
97  * Initialize KStarsData while running splash screen.
98  * @return true on success.
99  */
100  bool initialize();
101 
102  /** Destructor. Delete data objects. */
103  ~KStarsData() override;
104 
105  /**
106  * Set the NextDSTChange member.
107  * Need this accessor because I could not make KStars::privatedata a friend
108  * class for some reason...:/
109  */
111  {
112  NextDSTChange = dt;
113  }
114 
115  /**
116  * Returns true if time is running forward else false. Used by KStars to prevent
117  * double calculations of daylight saving change time.
118  */
119  bool isTimeRunningForward() const
120  {
121  return TimeRunsForward;
122  }
123 
124  /** @return pointer to the localization (KLocale) object */
125  //KLocale *getLocale() { return locale; }
126 
127  /**
128  * @short Find object by name.
129  * @param name Object name to find
130  * @return pointer to SkyObject matching this name
131  */
132  SkyObject *objectNamed(const QString &name);
133 
134  /**
135  * The Sky is updated more frequently than the moon, which is updated more frequently
136  * than the planets. The date of the last update for each category is recorded so we
137  * know when we need to do it again (see KStars::updateTime()).
138  * Initializing these to -1000000.0 ensures they will be updated immediately
139  * on the first call to KStars::updateTime().
140  */
141  void setFullTimeUpdate();
142 
143  /**
144  * Change the current simulation date/time to the KStarsDateTime argument.
145  * Specified DateTime is always universal time.
146  * @param newDate the DateTime to set.
147  */
148  void changeDateTime(const KStarsDateTime &newDate);
149 
150  /** @return pointer to the current simulation local time */
151  const KStarsDateTime &lt() const
152  {
153  return LTime;
154  }
155 
156  /** @return reference to the current simulation universal time */
157  const KStarsDateTime &ut() const
158  {
159  return Clock.utc();
160  }
161 
162  /** Sync the LST with the simulation clock. */
163  void syncLST();
164 
165  /** @return pointer to SkyComposite */
167  {
168  return m_SkyComposite.get();
169  }
170 
171  /** @return pointer to the ColorScheme object */
173  {
174  return &CScheme;
175  }
176 
177  /** @return file name of current color scheme **/
179 
180  /** @return file name of the color scheme with the name \p name **/
182  {
183  return m_color_schemes.count(name) > 0 ? m_color_schemes.at(name) : "";
184  }
185 
186  /** @return file name of the current color scheme **/
188  {
189  return colorSchemeName(CScheme.fileName());
190  }
191 
192  /** @return the name of the color scheme with the name \p name **/
193  QString colorSchemeName(const QString &fileName)
194  {
195  return m_color_scheme_names.count(fileName) > 0 ? m_color_scheme_names.at(fileName) : "";
196  }
197 
198  /** @return if the color scheme with the name or filename \p scheme is loaded **/
199  bool hasColorScheme(const QString &scheme)
200  {
201  return m_color_scheme_names.count(scheme) || m_color_schemes.count(scheme);
202  }
203 
204  /** Register a color scheme with \p filename and \p name. */
205  void add_color_scheme(const QString &filename, const QString &name)
206  {
207  m_color_schemes[name] = filename;
208  m_color_scheme_names[filename] = name;
209  };
210 
211  /** \return a map of color scheme names and filenames */
212  const std::map<QString, QString> color_schemes() { return m_color_schemes; };
213 
214  /** @return pointer to the KSUserDB object */
215  KSUserDB *userdb() { return &m_ksuserdb; }
216 
217  /** @return pointer to the simulation Clock object */
219  {
220  return &Clock;
221  }
222 
223  /** @return pointer to the local sidereal time: a dms object */
225  {
226  return &LST;
227  }
228 
229  /** @return pointer to the GeoLocation object*/
231  {
232  return &m_Geo;
233  }
234 
235  /** @return list of all geographic locations */
237  {
238  return geoList;
239  }
240 
241  GeoLocation *locationNamed(const QString &city, const QString &province = QString(),
242  const QString &country = QString());
243 
244  /**
245  * @brief nearestLocation Return nearest location to the given longitude and latitude coordinates
246  * @param longitude Longitude (-180 to +180)
247  * @param latitude Latitude (-90 to +90)
248  * @return nearest geographical location to the parameters above.
249  */
250  GeoLocation *nearestLocation(double longitude, double latitude);
251 
252  /**
253  * Set the GeoLocation according to the argument.
254  * @param l reference to the new GeoLocation
255  */
256  void setLocation(const GeoLocation &l);
257 
258  /** Set the GeoLocation according to the values stored in the configuration file. */
259  void setLocationFromOptions();
260 
261  /** Return map for daylight saving rules. */
263  {
264  return Rulebook;
265  }
266 
267  /** @return whether the next Focus change will omit the slewing animation. */
268  bool snapNextFocus() const
269  {
270  return snapToFocus;
271  }
272 
273  /**
274  * Disable or re-enable the slewing animation for the next Focus change.
275  * @note If the user has turned off all animated slewing, setSnapNextFocus(false)
276  * will *NOT* enable animation on the next slew. A false argument would only
277  * be used if you have previously called setSnapNextFocus(true), but then decided
278  * you didn't want that after all. In other words, it's extremely unlikely you'd
279  * ever want to use setSnapNextFocus(false).
280  * @param b when true (the default), the next Focus change will omit the slewing
281  * animation.
282  */
283  void setSnapNextFocus(bool b = true)
284  {
285  snapToFocus = b;
286  }
287 
288  /**
289  * Execute a script. This function actually duplicates the DCOP functionality
290  * for those cases when invoking DCOP is not practical (i.e., when preparing
291  * a sky image in command-line dump mode).
292  * @param name the filename of the script to "execute".
293  * @param map pointer to the SkyMap object.
294  * @return true if the script was successfully parsed.
295  */
296  bool executeScript(const QString &name, SkyMap *map);
297 
298  /** Synchronize list of visible FOVs and list of selected FOVs in Options */
299 #ifndef KSTARS_LITE
300  void syncFOV();
301 #endif
302 
303  /**
304  * @return the list of visible FOVs
305  */
306  inline const QList<FOV *> getVisibleFOVs() const
307  {
308  return visibleFOVs;
309  }
310 
311  /**
312  * @return the list of available FOVs
313  */
314  inline const QList<FOV *> getAvailableFOVs() const
315  {
316  return availFOVs;
317  }
318 
319  /**
320  * @brief addTransientFOV Adds a new FOV to the list.
321  * @param newFOV pointer to FOV object.
322  */
323  inline void addTransientFOV(std::shared_ptr<FOV> newFOV)
324  {
325  transientFOVs.append(newFOV);
326  }
327  inline void clearTransientFOVs()
328  {
329  transientFOVs.clear();
330  }
331 
332  /**
333  * @return the list of transient FOVs
334  */
336  {
337  return transientFOVs;
338  }
339 #ifndef KSTARS_LITE
340  /** Return log object */
341  OAL::Log *logObject()
342  {
343  return m_LogObject.get();
344  }
345 
346  /** Return ADV Tree */
348  {
349  return ADVtreeList;
350  }
351 
352  inline ObservingList *observingList() const
353  {
354  return m_ObservingList;
355  }
356 
357  ImageExporter *imageExporter();
358 
359  Execute *executeSession();
360 #endif
361  /*@short Increments the updateID, forcing a recomputation of star positions as well */
362  unsigned int incUpdateID();
363 
364  unsigned int updateID() const
365  {
366  return m_updateID;
367  }
368  unsigned int updateNumID() const
369  {
370  return m_updateNumID;
371  }
372  KSNumbers *updateNum()
373  {
374  return &m_updateNum;
375  }
376  void syncUpdateIDs();
377 
378  signals:
379  /** Signal that specifies the text that should be drawn in the KStarsSplash window. */
380  void progressText(const QString &text);
381 
382  /** Should be used to refresh skymap. */
383  void skyUpdate(bool);
384 
385  /** If data changed, emit clearCache signal. */
386  void clearCache();
387 
388  /** Emitted when geo location changed */
389  void geoChanged();
390 
391  public slots:
392  /** @short send a message to the console*/
394  {
395  std::cout << (const char *)(s.toLocal8Bit()) << std::endl;
396  }
397 
398  /**
399  * Update the Simulation Clock. Update positions of Planets. Update
400  * Alt/Az coordinates of objects. Update precession.
401  * emit the skyUpdate() signal so that SkyMap / whatever draws the sky can update itself
402  *
403  * This is ugly.
404  * It _will_ change!
405  * (JH:)hey, it's much less ugly now...can we lose the comment yet? :p
406  */
407  void updateTime(GeoLocation *geo, const bool automaticDSTchange = true);
408 
409  /**
410  * Sets the direction of time and stores it in bool TimeRunForwards. If scale >= 0
411  * time is running forward else time runs backward. We need this to calculate just
412  * one daylight saving change time (previous or next DST change).
413  */
414  void setTimeDirection(float scale);
415 
416  // What follows is mostly a port of Arkashs auxdata stuff to a
417  // more centralized approach that does not store the data in
418  // the skyobjects as they are ephemeral in the new DSO implementation
419  //
420  // I've tried to reuse as much code as possible and maintain
421  // compatibility with peoples data.
422  //
423  // -- Valentin Boettcher
424 
425  /**
426  * Get a reference to the user data of an object with the name \p name.
427  */
428  const SkyObjectUserdata::Data &getUserData(const QString &name);
429 
430  /**
431  * Adds a link \p data to the user data for the object with \p
432  * name, both in memory and on disk.
433  *
434  * @returns {success, error_message}
435  */
436  std::pair<bool, QString> addToUserData(const QString &name,
437  const SkyObjectUserdata::LinkData &data);
438 
439  /**
440  * Replace \p data in the user data at \p index for the object with \p
441  * name, both in memory and on disk.
442  *
443  * @returns {success, error_message}
444  */
445  std::pair<bool, QString> editUserData(const QString &name,
446  const unsigned int index,
447  const SkyObjectUserdata::LinkData &data);
448 
449  /**
450  * Remove data of \p type from the user data at \p index for
451  * the object with \p name, both in memory and on disk.
452  *
453  * @returns {success, error_message}
454  */
455  std::pair<bool, QString> deleteUserData(const QString &name,
456  const unsigned int index,
457  SkyObjectUserdata::Type type);
458  /**
459  * Update the user log of the object with the \p name to
460  * contain \p newLog (find and replace).
461  *
462  * @returns {success, error_message}
463  */
464  std::pair<bool, QString> updateUserLog(const QString &name,
465  const QString &newLog);
466 
467  private:
468  /**
469  * Populate list of geographic locations from "citydb.sqlite" database. Also check for custom
470  * locations file "mycitydb.sqlite" database, but don't require it. Each line in the file
471  * provides the information required to create one GeoLocation object.
472  * @short Fill list of geographic locations from file(s)
473  * @return true if at least one city read successfully.
474  * @see KStarsData::processCity()
475  */
476  bool readCityData();
477 
478  /** Read the data file that contains daylight savings time rules. */
479  bool readTimeZoneRulebook();
480 
481  //TODO JM: ADV tree should use XML instead
482  /**
483  * Read Advanced interface structure to be used later to construct the list view in
484  * the advanced tab in the Detail Dialog.
485  * @li KSLABEL designates a top-level parent label
486  * @li KSINTERFACE designates a common URL interface for several objects
487  * @li END designates the end of a sub tree structure
488  * @short read online database lookup structure.
489  * @return true if data is successfully read.
490  */
491  bool readADVTreeData();
492 
493  /** Read INDI hosts from an XML file */
494  bool readINDIHosts();
495 
496  //TODO JM: Use XML instead; The logger should have more features
497  // that allow users to enter details about their observation logs
498  // objects observed, eye pieces, telescope, conditions, mag..etc
499  /**
500  * @short read user logs.
501  *
502  * Read user logs. The log file is formatted as following:
503  * @li KSLABEL designates the beginning of a log
504  * @li KSLogEnd designates the end of a log.
505  *
506  * @return true if data is successfully read.
507  */
508  bool readUserLog();
509 
510  /**
511  * Read in URLs to be attached to a named object's right-click popup menu. At this
512  * point, there is no way to attach URLs to unnamed objects. There are two
513  * kinds of URLs, each with its own data file: image links and webpage links. In addition,
514  * there may be user-specific versions with custom URLs. Each line contains 3 fields
515  * separated by colons (":"). Note that the last field is the URL, and as such it will
516  * generally contain a colon itself. Only the first two colons encountered are treated
517  * as field separators. The fields are:
518  *
519  * @li Object name. This must be the "primary" name of the object (the name at the top of the popup menu).
520  * @li Menu text. The string that should appear in the popup menu to activate the link.
521  * @li URL.
522  * @short Read in image and information URLs.
523  * @return true if data files were successfully read.
524  */
525  bool readURLData(const QString &url,
526  SkyObjectUserdata::Type type = SkyObjectUserdata::Type::website);
527 
528  /**
529  * @short open a file containing URL links.
530  * @param urlfile string representation of the filename to open
531  * @param file reference to the QFile object which will be opened to this file.
532  * @return true if file successfully opened.
533  */
534  bool openUrlFile(const QString &urlfile, QFile &file);
535 
536  /**
537  * Reset local time to new daylight saving time. Use this function if DST has changed.
538  * Used by updateTime().
539  */
540  void resetToNewDST(GeoLocation *geo, const bool automaticDSTchange);
541 
542  /**
543  * As KStarsData::getUserData just non-const.
544  * @warning This method is not thread safe :) so take care of that when you use it.
545  */
546  SkyObjectUserdata::Data &findUserData(const QString &name);
547 
548  QList<ADVTreeData *> ADVtreeList;
549  std::unique_ptr<SkyMapComposite> m_SkyComposite;
550 
551  GeoLocation m_Geo;
552  SimClock Clock;
553  KStarsDateTime LTime;
554  KSUserDB m_ksuserdb;
555  ColorScheme CScheme;
556  std::map<QString, QString> m_color_schemes; // name: filename
557  std::map<QString, QString> m_color_scheme_names; // filename: name
558 
559 #ifndef KSTARS_LITE
560  ObservingList* m_ObservingList { nullptr };
561  std::unique_ptr<OAL::Log> m_LogObject;
562  std::unique_ptr<Execute> m_Execute;
563  std::unique_ptr<ImageExporter> m_ImageExporter;
564 #endif
565 
566  //EquipmentWriter *m_equipmentWriter;
567 
568  bool TimeRunsForward { false };
569  bool temporaryTrail { false };
570  // FIXME: Used in SkyMap only. Check!
571  bool snapToFocus { false };
572 
573  //KLocale *locale;
574 
575  CachingDms LST;
576 
577  QKeySequence resumeKey;
578 
579  QList<FOV *> availFOVs; // List of all available FOVs
580  QList<FOV *> visibleFOVs; // List of visible FOVs. Cached from Options::FOVNames
581  QList<std::shared_ptr<FOV>> transientFOVs; // List of non-permenant transient FOVs.
582 
583  KStarsDateTime LastNumUpdate, LastSkyUpdate, LastPlanetUpdate, LastMoonUpdate;
584  KStarsDateTime NextDSTChange;
585  // FIXME: Used in kstarsdcop.cpp only
586  KStarsDateTime StoredDate;
587 
588  QList<GeoLocation *> geoList;
590 
591  quint32 m_preUpdateID, m_updateID;
592  quint32 m_preUpdateNumID, m_updateNumID;
593  KSNumbers m_preUpdateNum, m_updateNum;
594 
595  static KStarsData *pinstance;
596 
597  std::unordered_map<QString, SkyObjectUserdata::Data> m_user_data;
598  QMutex m_user_data_mutex; // for m_user_data
599 };
bool hasColorScheme(const QString &scheme)
Definition: kstarsdata.h:199
Q_OBJECTQ_OBJECT
void append(const T &value)
const std::map< QString, QString > color_schemes()
Definition: kstarsdata.h:212
Definition: fov.h:27
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
Single class to delegate all User database I/O.
Definition: ksuserdb.h:38
LocationDialog(QWidget *parent)
Constructor.
QList< GeoLocation * > & getGeoList()
Definition: kstarsdata.h:236
void setLocation(const GeoLocation &l)
Set the GeoLocation according to the argument.
Definition: kstarsdata.cpp:403
const KStarsDateTime & lt() const
Definition: kstarsdata.h:151
void updateTime(GeoLocation *geo, const bool automaticDSTchange=true)
Update the Simulation Clock.
Definition: kstarsdata.cpp:234
void setLocationFromOptions()
Set the GeoLocation according to the values stored in the configuration file.
Definition: kstarsdata.cpp:396
std::pair< bool, QString > editUserData(const QString &name, const unsigned int index, const SkyObjectUserdata::LinkData &data)
Replace data in the user data at index for the object with name, both in memory and on disk.
const QList< FOV * > getVisibleFOVs() const
Definition: kstarsdata.h:306
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition: cachingdms.h:18
void setTimeDirection(float scale)
Sets the direction of time and stores it in bool TimeRunForwards.
Definition: kstarsdata.cpp:359
Execute()
Default constructor.
Definition: execute.cpp:21
Backends for exporting a sky image, either raster or vector, with a legend.
Definition: imageexporter.h:23
CachingDms * lst()
Definition: kstarsdata.h:224
SkyObject * objectNamed(const QString &name)
Find object by name.
Definition: kstarsdata.cpp:429
void addTransientFOV(std::shared_ptr< FOV > newFOV)
addTransientFOV Adds a new FOV to the list.
Definition: kstarsdata.h:323
const QList< std::shared_ptr< FOV > > getTransientFOVs() const
Definition: kstarsdata.h:335
KSUserDB * userdb()
Definition: kstarsdata.h:215
QList< ADVTreeData * > avdTree()
Return ADV Tree.
Definition: kstarsdata.h:347
std::pair< bool, QString > deleteUserData(const QString &name, const unsigned int index, SkyObjectUserdata::Type type)
Remove data of type from the user data at index for the object with name, both in memory and on disk.
void setFullTimeUpdate()
The Sky is updated more frequently than the moon, which is updated more frequently than the planets.
Definition: kstarsdata.cpp:313
QString colorSchemeName(const QString &fileName)
Definition: kstarsdata.h:193
const SkyObjectUserdata::Data & getUserData(const QString &name)
Get a reference to the user data of an object with the name name.
void progressText(const QString &text)
Signal that specifies the text that should be drawn in the KStarsSplash window.
Stores Users' Logs, Pictures and Websites regarding an object in the sky.
KStarsData()
Constructor.
Definition: kstarsdata.cpp:105
bool initialize()
Initialize KStarsData while running splash screen.
Definition: kstarsdata.cpp:131
void geoChanged()
Emitted when geo location changed.
void changeDateTime(const KStarsDateTime &newDate)
Change the current simulation date/time to the KStarsDateTime argument.
Definition: kstarsdata.cpp:327
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
const QList< FOV * > getAvailableFOVs() const
Definition: kstarsdata.h:314
ColorScheme * colorScheme()
Definition: kstarsdata.h:172
GeoLocation * geo()
Definition: kstarsdata.h:230
Q_INVOKABLE SimClock * clock()
Definition: kstarsdata.h:218
QString fileName() const
Definition: colorscheme.h:91
Q_INVOKABLE QString colorSchemeFileName()
Definition: kstarsdata.h:178
std::pair< bool, QString > updateUserLog(const QString &name, const QString &newLog)
Update the user log of the object with the name to contain newLog (find and replace).
bool executeScript(const QString &name, SkyMap *map)
Execute a script.
Definition: kstarsdata.cpp:912
std::pair< bool, QString > addToUserData(const QString &name, const SkyObjectUserdata::LinkData &data)
Adds a link data to the user data for the object with name, both in memory and on disk.
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:90
Q_INVOKABLEQ_INVOKABLE
kstars simulation clock
Definition: simclock.h:22
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:166
const QMap< QString, TimeZoneRule > & getRulebook() const
Return map for daylight saving rules.
Definition: kstarsdata.h:262
void setSnapNextFocus(bool b=true)
Disable or re-enable the slewing animation for the next Focus change.
Definition: kstarsdata.h:283
QString colorSchemeFileName(const QString &name)
Definition: kstarsdata.h:181
bool snapNextFocus() const
Definition: kstarsdata.h:268
const KStarsDateTime & ut() const
Definition: kstarsdata.h:157
OAL::Log * logObject()
Return log object.
Definition: kstarsdata.h:341
void skyUpdate(bool)
Should be used to refresh skymap.
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:53
bool isTimeRunningForward() const
Returns true if time is running forward else false.
Definition: kstarsdata.h:119
void slotConsoleMessage(QString s)
send a message to the console
Definition: kstarsdata.h:393
void clearCache()
If data changed, emit clearCache signal.
void clear()
void add_color_scheme(const QString &filename, const QString &name)
Register a color scheme with filename and name.
Definition: kstarsdata.h:205
~KStarsData() override
Destructor.
Definition: kstarsdata.cpp:118
void syncFOV()
Synchronize list of visible FOVs and list of selected FOVs in Options.
QByteArray toLocal8Bit() const const
void setNextDSTChange(const KStarsDateTime &dt)
Set the NextDSTChange member.
Definition: kstarsdata.h:110
Q_INVOKABLE QString colorSchemeName()
Definition: kstarsdata.h:187
const KStarsDateTime & utc() const
Definition: simclock.h:35
GeoLocation * nearestLocation(double longitude, double latitude)
nearestLocation Return nearest location to the given longitude and latitude coordinates
Definition: kstarsdata.cpp:377
Information about an object in the sky.
Definition: skyobject.h:41
void syncLST()
Sync the LST with the simulation clock.
Definition: kstarsdata.cpp:322
Stores the tite and URL of a webpage.
Relevant data about an observing location on Earth.
Definition: geolocation.h:27
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Nov 30 2023 04:05:12 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.