KCoreAddons

kaboutdata.cpp
1 /*
2  This file is part of the KDE Libraries
3 
4  SPDX-FileCopyrightText: 2000 Espen Sand <[email protected]>
5  SPDX-FileCopyrightText: 2006 Nicolas GOUTTE <[email protected]>
6  SPDX-FileCopyrightText: 2008 Friedrich W. H. Kossebau <[email protected]>
7  SPDX-FileCopyrightText: 2010 Teo Mrnjavac <[email protected]>
8  SPDX-FileCopyrightText: 2017 Harald Sitter <[email protected]>
9 
10  SPDX-License-Identifier: LGPL-2.0-or-later
11 */
12 
13 #include "kaboutdata.h"
14 #include "kpluginmetadata.h"
15 
16 #include <QCommandLineOption>
17 #include <QCommandLineParser>
18 #include <QCoreApplication>
19 #include <QFile>
20 #include <QHash>
21 #include <QJsonObject>
22 #include <QList>
23 #include <QLoggingCategory>
24 #include <QSharedData>
25 #include <QStandardPaths>
26 #include <QTextStream>
27 #include <QUrl>
28 
29 #include <algorithm>
30 
31 Q_DECLARE_LOGGING_CATEGORY(KABOUTDATA)
32 // logging category for this framework, default: log stuff >= warning
33 Q_LOGGING_CATEGORY(KABOUTDATA, "kf.coreaddons.kaboutdata", QtWarningMsg)
34 
35 class KAboutPersonPrivate : public QSharedData
36 {
37 public:
38  QString _name;
39  QString _task;
40  QString _emailAddress;
41  QString _webAddress;
42  QString _ocsUsername;
43 };
44 
45 KAboutPerson::KAboutPerson(const QString &_name, const QString &_task, const QString &_emailAddress, const QString &_webAddress, const QString &_ocsUsername)
46  : d(new KAboutPersonPrivate)
47 {
48  d->_name = _name;
49  d->_task = _task;
50  d->_emailAddress = _emailAddress;
51  d->_webAddress = _webAddress;
52  d->_ocsUsername = _ocsUsername;
53 }
54 
55 KAboutPerson::KAboutPerson(const QString &_name, const QString &_email, bool)
56  : d(new KAboutPersonPrivate)
57 {
58  d->_name = _name;
59  d->_emailAddress = _email;
60 }
61 
62 KAboutPerson::KAboutPerson(const KAboutPerson &other) = default;
63 
64 KAboutPerson::~KAboutPerson() = default;
65 
67 {
68  return d->_name;
69 }
70 
72 {
73  return d->_task;
74 }
75 
77 {
78  return d->_emailAddress;
79 }
80 
82 {
83  return d->_webAddress;
84 }
85 
87 {
88  return d->_ocsUsername;
89 }
90 
91 KAboutPerson &KAboutPerson::operator=(const KAboutPerson &other) = default;
92 
94 {
95  const QString name = KPluginMetaData::readTranslatedString(obj, QStringLiteral("Name"));
96  const QString task = KPluginMetaData::readTranslatedString(obj, QStringLiteral("Task"));
97  const QString email = obj[QStringLiteral("Email")].toString();
98  const QString website = obj[QStringLiteral("Website")].toString();
99  const QString userName = obj[QStringLiteral("UserName")].toString();
100  return KAboutPerson(name, task, email, website, userName);
101 }
102 
103 class KAboutLicensePrivate : public QSharedData
104 {
105 public:
106  KAboutLicensePrivate(KAboutLicense::LicenseKey licenseType, KAboutLicense::VersionRestriction versionRestriction, const KAboutData *aboutData);
107  KAboutLicensePrivate(const KAboutLicensePrivate &other);
108 
109  QString spdxID() const;
110 
111  KAboutLicense::LicenseKey _licenseKey;
112  QString _licenseText;
113  QString _pathToLicenseTextFile;
114  KAboutLicense::VersionRestriction _versionRestriction;
115  // needed for access to the possibly changing copyrightStatement()
116  const KAboutData *_aboutData;
117 };
118 
119 KAboutLicensePrivate::KAboutLicensePrivate(KAboutLicense::LicenseKey licenseType,
120  KAboutLicense::VersionRestriction versionRestriction,
121  const KAboutData *aboutData)
122  : QSharedData()
123  , _licenseKey(licenseType)
124  , _versionRestriction(versionRestriction)
125  , _aboutData(aboutData)
126 {
127 }
128 
129 KAboutLicensePrivate::KAboutLicensePrivate(const KAboutLicensePrivate &other)
130  : QSharedData(other)
131  , _licenseKey(other._licenseKey)
132  , _licenseText(other._licenseText)
133  , _pathToLicenseTextFile(other._pathToLicenseTextFile)
134  , _versionRestriction(other._versionRestriction)
135  , _aboutData(other._aboutData)
136 {
137 }
138 
139 QString KAboutLicensePrivate::spdxID() const
140 {
141  switch (_licenseKey) {
142  case KAboutLicense::GPL_V2:
143  return QStringLiteral("GPL-2.0");
144  case KAboutLicense::LGPL_V2:
145  return QStringLiteral("LGPL-2.0");
146  case KAboutLicense::BSDL:
147  return QStringLiteral("BSD-2-Clause");
148  case KAboutLicense::Artistic:
149  return QStringLiteral("Artistic-1.0");
150  case KAboutLicense::QPL_V1_0:
151  return QStringLiteral("QPL-1.0");
152  case KAboutLicense::GPL_V3:
153  return QStringLiteral("GPL-3.0");
154  case KAboutLicense::LGPL_V3:
155  return QStringLiteral("LGPL-3.0");
157  return QStringLiteral("LGPL-2.1");
158  case KAboutLicense::Custom:
159  case KAboutLicense::File:
160  case KAboutLicense::Unknown:
161  return QString();
162  }
163  return QString();
164 }
165 
167  : d(new KAboutLicensePrivate(Unknown, {}, nullptr))
168 {
169 }
170 
171 KAboutLicense::KAboutLicense(LicenseKey licenseType, VersionRestriction versionRestriction, const KAboutData *aboutData)
172  : d(new KAboutLicensePrivate(licenseType, versionRestriction, aboutData))
173 {
174 }
175 
176 KAboutLicense::KAboutLicense(LicenseKey licenseType, const KAboutData *aboutData)
177  : d(new KAboutLicensePrivate(licenseType, OnlyThisVersion, aboutData))
178 {
179 }
180 
182  : d(new KAboutLicensePrivate(Unknown, OnlyThisVersion, aboutData))
183 {
184 }
185 
187  : d(other.d)
188 {
189 }
190 
191 KAboutLicense::~KAboutLicense()
192 {
193 }
194 
195 void KAboutLicense::setLicenseFromPath(const QString &pathToFile)
196 {
197  d->_licenseKey = KAboutLicense::File;
198  d->_pathToLicenseTextFile = pathToFile;
199 }
200 
201 void KAboutLicense::setLicenseFromText(const QString &licenseText)
202 {
203  d->_licenseKey = KAboutLicense::Custom;
204  d->_licenseText = licenseText;
205 }
206 
208 {
209  QString result;
210 
211  const QString lineFeed = QStringLiteral("\n\n");
212 
213  if (d->_aboutData && !d->_aboutData->copyrightStatement().isEmpty()) {
214  result = d->_aboutData->copyrightStatement() + lineFeed;
215  }
216 
217  bool knownLicense = false;
218  QString pathToFile; // rel path if known license
219  switch (d->_licenseKey) {
220  case KAboutLicense::File:
221  pathToFile = d->_pathToLicenseTextFile;
222  break;
223  case KAboutLicense::GPL_V2:
224  knownLicense = true;
225  pathToFile = QStringLiteral("GPL_V2");
226  break;
227  case KAboutLicense::LGPL_V2:
228  knownLicense = true;
229  pathToFile = QStringLiteral("LGPL_V2");
230  break;
231  case KAboutLicense::BSDL:
232  knownLicense = true;
233  pathToFile = QStringLiteral("BSD");
234  break;
235  case KAboutLicense::Artistic:
236  knownLicense = true;
237  pathToFile = QStringLiteral("ARTISTIC");
238  break;
239  case KAboutLicense::QPL_V1_0:
240  knownLicense = true;
241  pathToFile = QStringLiteral("QPL_V1.0");
242  break;
243  case KAboutLicense::GPL_V3:
244  knownLicense = true;
245  pathToFile = QStringLiteral("GPL_V3");
246  break;
247  case KAboutLicense::LGPL_V3:
248  knownLicense = true;
249  pathToFile = QStringLiteral("LGPL_V3");
250  break;
252  knownLicense = true;
253  pathToFile = QStringLiteral("LGPL_V21");
254  break;
255  case KAboutLicense::Custom:
256  if (!d->_licenseText.isEmpty()) {
257  result = d->_licenseText;
258  break;
259  }
260  Q_FALLTHROUGH();
261  // fall through
262  default:
263  result += QCoreApplication::translate("KAboutLicense",
264  "No licensing terms for this program have been specified.\n"
265  "Please check the documentation or the source for any\n"
266  "licensing terms.\n");
267  }
268 
269  if (knownLicense) {
270  pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("kf5/licenses/") + pathToFile);
271  result += QCoreApplication::translate("KAboutLicense", "This program is distributed under the terms of the %1.").arg(name(KAboutLicense::ShortName));
272  if (!pathToFile.isEmpty()) {
273  result += lineFeed;
274  }
275  }
276 
277  if (!pathToFile.isEmpty()) {
278  QFile file(pathToFile);
279  if (file.open(QIODevice::ReadOnly)) {
280  QTextStream str(&file);
281  result += str.readAll();
282  }
283  }
284 
285  return result;
286 }
287 
289 {
290  // SPDX licenses are comprised of an identifier (e.g. GPL-2.0), an optional + to denote 'or
291  // later versions' and optional ' WITH $exception' to denote standardized exceptions from the
292  // core license. As we do not offer exceptions we effectively only return GPL-2.0 or GPL-2.0+,
293  // this may change in the future. To that end the documentation makes no assertations about the
294  // actual content of the SPDX license expression we return.
295  // Expressions can in theory also contain AND, OR and () to build constructs involving more than
296  // one license. As this is outside the scope of a single license object we'll ignore this here
297  // for now.
298  // The expecation is that the return value is only run through spec-compliant parsers, so this
299  // can potentially be changed.
300 
301  auto id = d->spdxID();
302  if (id.isNull()) { // Guard against potential future changes which would allow 'Foo+' as input.
303  return id;
304  }
305  return d->_versionRestriction == OrLaterVersions ? id.append(QLatin1Char('+')) : id;
306 }
307 
308 QString KAboutLicense::name(KAboutLicense::NameFormat formatName) const
309 {
310  QString licenseShort;
311  QString licenseFull;
312 
313  switch (d->_licenseKey) {
314  case KAboutLicense::GPL_V2:
315  licenseShort = QCoreApplication::translate("KAboutLicense", "GPL v2", "@item license (short name)");
316  licenseFull = QCoreApplication::translate("KAboutLicense", "GNU General Public License Version 2", "@item license");
317  break;
318  case KAboutLicense::LGPL_V2:
319  licenseShort = QCoreApplication::translate("KAboutLicense", "LGPL v2", "@item license (short name)");
320  licenseFull = QCoreApplication::translate("KAboutLicense", "GNU Lesser General Public License Version 2", "@item license");
321  break;
322  case KAboutLicense::BSDL:
323  licenseShort = QCoreApplication::translate("KAboutLicense", "BSD License", "@item license (short name)");
324  licenseFull = QCoreApplication::translate("KAboutLicense", "BSD License", "@item license");
325  break;
326  case KAboutLicense::Artistic:
327  licenseShort = QCoreApplication::translate("KAboutLicense", "Artistic License", "@item license (short name)");
328  licenseFull = QCoreApplication::translate("KAboutLicense", "Artistic License", "@item license");
329  break;
330  case KAboutLicense::QPL_V1_0:
331  licenseShort = QCoreApplication::translate("KAboutLicense", "QPL v1.0", "@item license (short name)");
332  licenseFull = QCoreApplication::translate("KAboutLicense", "Q Public License", "@item license");
333  break;
334  case KAboutLicense::GPL_V3:
335  licenseShort = QCoreApplication::translate("KAboutLicense", "GPL v3", "@item license (short name)");
336  licenseFull = QCoreApplication::translate("KAboutLicense", "GNU General Public License Version 3", "@item license");
337  break;
338  case KAboutLicense::LGPL_V3:
339  licenseShort = QCoreApplication::translate("KAboutLicense", "LGPL v3", "@item license (short name)");
340  licenseFull = QCoreApplication::translate("KAboutLicense", "GNU Lesser General Public License Version 3", "@item license");
341  break;
343  licenseShort = QCoreApplication::translate("KAboutLicense", "LGPL v2.1", "@item license (short name)");
344  licenseFull = QCoreApplication::translate("KAboutLicense", "GNU Lesser General Public License Version 2.1", "@item license");
345  break;
346  case KAboutLicense::Custom:
347  case KAboutLicense::File:
348  licenseShort = licenseFull = QCoreApplication::translate("KAboutLicense", "Custom", "@item license");
349  break;
350  default:
351  licenseShort = licenseFull = QCoreApplication::translate("KAboutLicense", "Not specified", "@item license");
352  }
353 
354  const QString result = (formatName == KAboutLicense::ShortName) ? licenseShort : (formatName == KAboutLicense::FullName) ? licenseFull : QString();
355 
356  return result;
357 }
358 
360 {
361  d = other.d;
362  return *this;
363 }
364 
366 {
367  return d->_licenseKey;
368 }
369 
371 {
372  // Setup keyword->enum dictionary on first call.
373  // Use normalized keywords, by the algorithm below.
374  static const QHash<QByteArray, KAboutLicense::LicenseKey> licenseDict{
375  {"gpl", KAboutLicense::GPL}, {"gplv2", KAboutLicense::GPL_V2},
376  {"gplv2+", KAboutLicense::GPL_V2}, {"gpl20", KAboutLicense::GPL_V2},
377  {"gpl20+", KAboutLicense::GPL_V2}, {"lgpl", KAboutLicense::LGPL},
378  {"lgplv2", KAboutLicense::LGPL_V2}, {"lgplv2+", KAboutLicense::LGPL_V2},
379  {"lgpl20", KAboutLicense::LGPL_V2}, {"lgpl20+", KAboutLicense::LGPL_V2},
380  {"bsd", KAboutLicense::BSDL}, {"bsd2clause", KAboutLicense::BSDL},
381  {"artistic", KAboutLicense::Artistic}, {"artistic10", KAboutLicense::Artistic},
382  {"qpl", KAboutLicense::QPL}, {"qplv1", KAboutLicense::QPL_V1_0},
383  {"qplv10", KAboutLicense::QPL_V1_0}, {"qpl10", KAboutLicense::QPL_V1_0},
384  {"gplv3", KAboutLicense::GPL_V3}, {"gplv3+", KAboutLicense::GPL_V3},
385  {"gpl30", KAboutLicense::GPL_V3}, {"gpl30+", KAboutLicense::GPL_V3},
386  {"lgplv3", KAboutLicense::LGPL_V3}, {"lgplv3+", KAboutLicense::LGPL_V3},
387  {"lgpl30", KAboutLicense::LGPL_V3}, {"lgpl30+", KAboutLicense::LGPL_V3},
388  {"lgplv21", KAboutLicense::LGPL_V2_1}, {"lgplv21+", KAboutLicense::LGPL_V2_1},
389  {"lgpl21", KAboutLicense::LGPL_V2_1}, {"lgpl21+", KAboutLicense::LGPL_V2_1},
390  };
391 
392  // Normalize keyword.
393  QString keyword = rawKeyword;
394  keyword = keyword.toLower();
395  keyword.remove(QLatin1Char(' '));
396  keyword.remove(QLatin1Char('.'));
397  keyword.remove(QLatin1Char('-'));
398 
399  LicenseKey license = licenseDict.value(keyword.toLatin1(), KAboutLicense::Custom);
400  auto restriction = keyword.endsWith(QLatin1Char('+')) ? OrLaterVersions : OnlyThisVersion;
401  return KAboutLicense(license, restriction, nullptr);
402 }
403 
404 class KAboutDataPrivate
405 {
406 public:
407  KAboutDataPrivate()
408  : customAuthorTextEnabled(false)
409  {
410  }
411  QString _componentName;
412  QString _displayName;
413  QString _shortDescription;
414  QString _copyrightStatement;
415  QString _otherText;
416  QString _homepageAddress;
417  QList<KAboutPerson> _authorList;
418  QList<KAboutPerson> _creditList;
419  QList<KAboutPerson> _translatorList;
420  QList<KAboutLicense> _licenseList;
421  QString productName;
422 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 2)
423  QString programIconName;
424 #endif
425  QVariant programLogo;
426  QString customAuthorPlainText, customAuthorRichText;
427  bool customAuthorTextEnabled;
428 
429  QString organizationDomain;
430  QString _ocsProviderUrl;
431  QString desktopFileName;
432 
433  // Everything dr.konqi needs, we store as utf-8, so we
434  // can just give it a pointer, w/o any allocations.
435  QByteArray _internalProgramName;
436  QByteArray _version;
437  QByteArray _bugAddress;
438 
439  static QList<KAboutPerson> parseTranslators(const QString &translatorName, const QString &translatorEmail);
440 };
441 
442 KAboutData::KAboutData(const QString &_componentName,
443  const QString &_displayName,
444  const QString &_version,
445  const QString &_shortDescription,
446  enum KAboutLicense::LicenseKey licenseType,
447  const QString &_copyrightStatement,
448  const QString &text,
449  const QString &homePageAddress,
450  const QString &bugAddress)
451  : d(new KAboutDataPrivate)
452 {
453  d->_componentName = _componentName;
454  int p = d->_componentName.indexOf(QLatin1Char('/'));
455  if (p >= 0) {
456  d->_componentName = d->_componentName.mid(p + 1);
457  }
458 
459  d->_displayName = _displayName;
460  if (!d->_displayName.isEmpty()) { // KComponentData("klauncher") gives empty program name
461  d->_internalProgramName = _displayName.toUtf8();
462  }
463  d->_version = _version.toUtf8();
464  d->_shortDescription = _shortDescription;
465  d->_licenseList.append(KAboutLicense(licenseType, this));
466  d->_copyrightStatement = _copyrightStatement;
467  d->_otherText = text;
468  d->_homepageAddress = homePageAddress;
469  d->_bugAddress = bugAddress.toUtf8();
470 
471  QUrl homePageUrl(homePageAddress);
472  if (!homePageUrl.isValid() || homePageUrl.scheme().isEmpty()) {
473  // Default domain if nothing else is better
474  homePageUrl.setUrl(QStringLiteral("https://kde.org/"));
475  }
476 
477  const QChar dotChar(QLatin1Char('.'));
478  QStringList hostComponents = homePageUrl.host().split(dotChar);
479 
480  // Remove leading component unless 2 (or less) components are present
481  if (hostComponents.size() > 2) {
482  hostComponents.removeFirst();
483  }
484 
485  d->organizationDomain = hostComponents.join(dotChar);
486 
487  // KF6: do not set a default desktopFileName value here, but remove this code and leave it empty
488  // see KAboutData::desktopFileName() for details
489 
490  // desktop file name is reverse domain name
491  std::reverse(hostComponents.begin(), hostComponents.end());
492  hostComponents.append(_componentName);
493 
494  d->desktopFileName = hostComponents.join(dotChar);
495 }
496 
497 KAboutData::KAboutData(const QString &_componentName, const QString &_displayName, const QString &_version)
498  : d(new KAboutDataPrivate)
499 {
500  d->_componentName = _componentName;
501  int p = d->_componentName.indexOf(QLatin1Char('/'));
502  if (p >= 0) {
503  d->_componentName = d->_componentName.mid(p + 1);
504  }
505 
506  d->_displayName = _displayName;
507  if (!d->_displayName.isEmpty()) { // KComponentData("klauncher") gives empty program name
508  d->_internalProgramName = _displayName.toUtf8();
509  }
510  d->_version = _version.toUtf8();
511 
512  // match behaviour of other constructors
513  d->_licenseList.append(KAboutLicense(KAboutLicense::Unknown, this));
514  d->_bugAddress = "[email protected]";
515  d->organizationDomain = QStringLiteral("kde.org");
516  // KF6: do not set a default desktopFileName value here, but remove this code and leave it empty
517  // see KAboutData::desktopFileName() for details
518  d->desktopFileName = QLatin1String("org.kde.") + d->_componentName;
519 }
520 
521 KAboutData::~KAboutData() = default;
522 
524  : d(new KAboutDataPrivate)
525 {
526  *d = *other.d;
527  QList<KAboutLicense>::iterator it = d->_licenseList.begin(), itEnd = d->_licenseList.end();
528  for (; it != itEnd; ++it) {
529  KAboutLicense &al = *it;
530  al.d.detach();
531  al.d->_aboutData = this;
532  }
533 }
534 
536 {
537  if (this != &other) {
538  *d = *other.d;
539  QList<KAboutLicense>::iterator it = d->_licenseList.begin(), itEnd = d->_licenseList.end();
540  for (; it != itEnd; ++it) {
541  KAboutLicense &al = *it;
542  al.d.detach();
543  al.d->_aboutData = this;
544  }
545  }
546  return *this;
547 }
548 
549 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 65)
551 {
552  KAboutData ret(plugin.pluginId(),
553  plugin.name(),
554  plugin.version(),
555  plugin.description(),
556  KAboutLicense::byKeyword(plugin.license()).key(),
557  plugin.copyrightText(),
558  plugin.extraInformation(),
559  plugin.website());
560 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 2)
561  ret.d->programIconName = plugin.iconName();
562 #endif
563  ret.d->_authorList = plugin.authors();
564  ret.d->_translatorList = plugin.translators();
565  ret.d->_creditList = plugin.otherContributors();
566  return ret;
567 }
568 #endif
569 
570 KAboutData &KAboutData::addAuthor(const QString &name, const QString &task, const QString &emailAddress, const QString &webAddress, const QString &ocsUsername)
571 {
572  d->_authorList.append(KAboutPerson(name, task, emailAddress, webAddress, ocsUsername));
573  return *this;
574 }
575 
576 KAboutData &KAboutData::addCredit(const QString &name, const QString &task, const QString &emailAddress, const QString &webAddress, const QString &ocsUsername)
577 {
578  d->_creditList.append(KAboutPerson(name, task, emailAddress, webAddress, ocsUsername));
579  return *this;
580 }
581 
582 KAboutData &KAboutData::setTranslator(const QString &name, const QString &emailAddress)
583 {
584  d->_translatorList = KAboutDataPrivate::parseTranslators(name, emailAddress);
585  return *this;
586 }
587 
589 {
590  d->_licenseList[0] = KAboutLicense(this);
591  d->_licenseList[0].setLicenseFromText(licenseText);
592  return *this;
593 }
594 
596 {
597  // if the default license is unknown, overwrite instead of append
598  KAboutLicense &firstLicense = d->_licenseList[0];
599  KAboutLicense newLicense(this);
600  newLicense.setLicenseFromText(licenseText);
601  if (d->_licenseList.count() == 1 && firstLicense.d->_licenseKey == KAboutLicense::Unknown) {
602  firstLicense = newLicense;
603  } else {
604  d->_licenseList.append(newLicense);
605  }
606 
607  return *this;
608 }
609 
611 {
612  d->_licenseList[0] = KAboutLicense(this);
613  d->_licenseList[0].setLicenseFromPath(pathToFile);
614  return *this;
615 }
616 
618 {
619  // if the default license is unknown, overwrite instead of append
620  KAboutLicense &firstLicense = d->_licenseList[0];
621  KAboutLicense newLicense(this);
622  newLicense.setLicenseFromPath(pathToFile);
623  if (d->_licenseList.count() == 1 && firstLicense.d->_licenseKey == KAboutLicense::Unknown) {
624  firstLicense = newLicense;
625  } else {
626  d->_licenseList.append(newLicense);
627  }
628  return *this;
629 }
630 
632 {
633  d->_componentName = componentName;
634  return *this;
635 }
636 
638 {
639  d->_displayName = _displayName;
640  d->_internalProgramName = _displayName.toUtf8();
641  return *this;
642 }
643 
645 {
646  d->_ocsProviderUrl = _ocsProviderUrl;
647  return *this;
648 }
649 
651 {
652  d->_version = _version;
653  return *this;
654 }
655 
657 {
658  d->_shortDescription = _shortDescription;
659  return *this;
660 }
661 
663 {
664  return setLicense(licenseKey, KAboutLicense::OnlyThisVersion);
665 }
666 
668 {
669  d->_licenseList[0] = KAboutLicense(licenseKey, versionRestriction, this);
670  return *this;
671 }
672 
674 {
675  return addLicense(licenseKey, KAboutLicense::OnlyThisVersion);
676 }
677 
679 {
680  // if the default license is unknown, overwrite instead of append
681  KAboutLicense &firstLicense = d->_licenseList[0];
682  if (d->_licenseList.count() == 1 && firstLicense.d->_licenseKey == KAboutLicense::Unknown) {
683  firstLicense = KAboutLicense(licenseKey, versionRestriction, this);
684  } else {
685  d->_licenseList.append(KAboutLicense(licenseKey, versionRestriction, this));
686  }
687  return *this;
688 }
689 
691 {
692  d->_copyrightStatement = _copyrightStatement;
693  return *this;
694 }
695 
697 {
698  d->_otherText = _otherText;
699  return *this;
700 }
701 
703 {
704  d->_homepageAddress = homepage;
705  return *this;
706 }
707 
709 {
710  d->_bugAddress = _bugAddress;
711  return *this;
712 }
713 
715 {
716  d->organizationDomain = QString::fromLatin1(domain.data());
717  return *this;
718 }
719 
721 {
722  d->productName = QString::fromUtf8(_productName.data());
723  return *this;
724 }
725 
727 {
728  return d->_componentName;
729 }
730 
732 {
733  if (!d->productName.isEmpty()) {
734  return d->productName;
735  }
736  return componentName();
737 }
738 
740 {
741  if (!d->_displayName.isEmpty()) {
742  return d->_displayName;
743  }
744  return componentName();
745 }
746 
747 /// @internal
748 /// Return the program name. It is always pre-allocated.
749 /// Needed for KCrash in particular.
751 {
752  return d->_internalProgramName.constData();
753 }
754 
755 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 2)
757 {
758  return d->programIconName.isEmpty() ? componentName() : d->programIconName;
759 }
760 
762 {
763  d->programIconName = iconName;
764  return *this;
765 }
766 #endif
767 
769 {
770  return d->programLogo;
771 }
772 
774 {
775  d->programLogo = image;
776  return *this;
777 }
778 
780 {
781  return d->_ocsProviderUrl;
782 }
783 
785 {
786  return QString::fromUtf8(d->_version.data());
787 }
788 
789 /// @internal
790 /// Return the untranslated and uninterpreted (to UTF8) string
791 /// for the version information. Used in particular for KCrash.
792 const char *KAboutData::internalVersion() const
793 {
794  return d->_version.constData();
795 }
796 
798 {
799  return d->_shortDescription;
800 }
801 
803 {
804  return d->_homepageAddress;
805 }
806 
808 {
809  return QString::fromUtf8(d->_bugAddress.constData());
810 }
811 
813 {
814  return d->organizationDomain;
815 }
816 
817 /// @internal
818 /// Return the untranslated and uninterpreted (to UTF8) string
819 /// for the bug mail address. Used in particular for KCrash.
821 {
822  if (d->_bugAddress.isEmpty()) {
823  return nullptr;
824  }
825  return d->_bugAddress.constData();
826 }
827 
829 {
830  return d->_authorList;
831 }
832 
834 {
835  return d->_creditList;
836 }
837 
838 QList<KAboutPerson> KAboutDataPrivate::parseTranslators(const QString &translatorName, const QString &translatorEmail)
839 {
840  QList<KAboutPerson> personList;
841  if (translatorName.isEmpty() || translatorName == QLatin1String("Your names")) {
842  return personList;
843  }
844 
845  const QStringList nameList(translatorName.split(QLatin1Char(',')));
846 
847  QStringList emailList;
848  if (!translatorEmail.isEmpty() && translatorEmail != QLatin1String("Your emails")) {
849  emailList = translatorEmail.split(QLatin1Char(','), Qt::KeepEmptyParts);
850  }
851 
853  QStringList::const_iterator eit = emailList.constBegin();
854 
855  for (nit = nameList.constBegin(); nit != nameList.constEnd(); ++nit) {
856  QString email;
857  if (eit != emailList.constEnd()) {
858  email = *eit;
859  ++eit;
860  }
861 
862  personList.append(KAboutPerson((*nit).trimmed(), email.trimmed(), true));
863  }
864 
865  return personList;
866 }
867 
869 {
870  return d->_translatorList;
871 }
872 
874 {
875  return QCoreApplication::translate("KAboutData",
876  "<p>KDE is translated into many languages thanks to the work "
877  "of the translation teams all over the world.</p>"
878  "<p>For more information on KDE internationalization "
879  "visit <a href=\"https://l10n.kde.org\">https://l10n.kde.org</a></p>",
880  "replace this with information about your translation team");
881 }
882 
884 {
885  return d->_otherText;
886 }
887 
889 {
890  return d->_licenseList;
891 }
892 
894 {
895  return d->_copyrightStatement;
896 }
897 
899 {
900  return d->customAuthorPlainText;
901 }
902 
904 {
905  return d->customAuthorRichText;
906 }
907 
909 {
910  return d->customAuthorTextEnabled;
911 }
912 
913 KAboutData &KAboutData::setCustomAuthorText(const QString &plainText, const QString &richText)
914 {
915  d->customAuthorPlainText = plainText;
916  d->customAuthorRichText = richText;
917 
918  d->customAuthorTextEnabled = true;
919 
920  return *this;
921 }
922 
924 {
925  d->customAuthorPlainText = QString();
926  d->customAuthorRichText = QString();
927 
928  d->customAuthorTextEnabled = false;
929 
930  return *this;
931 }
932 
934 {
935  d->desktopFileName = desktopFileName;
936 
937  return *this;
938 }
939 
941 {
942  return d->desktopFileName;
943  // KF6: switch to this code and adapt API dox
944 #if 0
945  // if desktopFileName has been explicitly set, use that value
946  if (!d->desktopFileName.isEmpty()) {
947  return d->desktopFileName;
948  }
949 
950  // return a string calculated on-the-fly from the current org domain & component name
951  const QChar dotChar(QLatin1Char('.'));
952  QStringList hostComponents = d->organizationDomain.split(dotChar);
953 
954  // desktop file name is reverse domain name
955  std::reverse(hostComponents.begin(), hostComponents.end());
956  hostComponents.append(componentName());
957 
958  return hostComponents.join(dotChar);
959 #endif
960 }
961 
962 class KAboutDataRegistry
963 {
964 public:
965  KAboutDataRegistry()
966  : m_appData(nullptr)
967  {
968  }
969  ~KAboutDataRegistry()
970  {
971  delete m_appData;
972 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 76)
973  qDeleteAll(m_pluginData);
974 #endif
975  }
976  KAboutDataRegistry(const KAboutDataRegistry &) = delete;
977  KAboutDataRegistry &operator=(const KAboutDataRegistry &) = delete;
978 
979  KAboutData *m_appData;
980 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 76)
981  QHash<QString, KAboutData *> m_pluginData;
982 #endif
983 };
984 
985 Q_GLOBAL_STATIC(KAboutDataRegistry, s_registry)
986 
987 namespace
988 {
989 void warnIfOutOfSync(const char *aboutDataString, const QString &aboutDataValue, const char *appDataString, const QString &appDataValue)
990 {
991  if (aboutDataValue != appDataValue) {
992  qCWarning(KABOUTDATA) << appDataString << appDataValue << "is out-of-sync with" << aboutDataString << aboutDataValue;
993  }
994 }
995 
996 }
997 
999 {
1001 
1002  KAboutData *aboutData = s_registry->m_appData;
1003 
1004  // not yet existing
1005  if (!aboutData) {
1006  // init from current Q*Application data
1008  // For applicationDisplayName & desktopFileName, which are only properties of QGuiApplication,
1009  // we have to try to get them via the property system, as the static getter methods are
1010  // part of QtGui only. Disadvantage: requires an app instance.
1011  // Either get all or none of the properties & warn about it
1012  if (app) {
1014  aboutData->setVersion(QCoreApplication::applicationVersion().toUtf8());
1015  aboutData->setDisplayName(app->property("applicationDisplayName").toString());
1016  aboutData->setDesktopFileName(app->property("desktopFileName").toString());
1017  } else {
1018  qCWarning(KABOUTDATA) << "Could not initialize the properties of KAboutData::applicationData by the equivalent properties from Q*Application: no "
1019  "app instance (yet) existing.";
1020  }
1021 
1022  s_registry->m_appData = aboutData;
1023  } else {
1024  // check if in-sync with Q*Application metadata, as their setters could have been called
1025  // after the last KAboutData::setApplicationData, with different values
1026  warnIfOutOfSync("KAboutData::applicationData().componentName",
1027  aboutData->componentName(),
1028  "QCoreApplication::applicationName",
1030  warnIfOutOfSync("KAboutData::applicationData().version",
1031  aboutData->version(),
1032  "QCoreApplication::applicationVersion",
1034  warnIfOutOfSync("KAboutData::applicationData().organizationDomain",
1035  aboutData->organizationDomain(),
1036  "QCoreApplication::organizationDomain",
1038  if (app) {
1039  warnIfOutOfSync("KAboutData::applicationData().displayName",
1040  aboutData->displayName(),
1041  "QGuiApplication::applicationDisplayName",
1042  app->property("applicationDisplayName").toString());
1043  warnIfOutOfSync("KAboutData::applicationData().desktopFileName",
1044  aboutData->desktopFileName(),
1045  "QGuiApplication::desktopFileName",
1046  app->property("desktopFileName").toString());
1047  }
1048  }
1049 
1050  return *aboutData;
1051 }
1052 
1054 {
1055  if (s_registry->m_appData) {
1056  *s_registry->m_appData = aboutData;
1057  } else {
1058  s_registry->m_appData = new KAboutData(aboutData);
1059  }
1060 
1061  // For applicationDisplayName & desktopFileName, which are only properties of QGuiApplication,
1062  // we have to try to set them via the property system, as the static getter methods are
1063  // part of QtGui only. Disadvantage: requires an app instance.
1064  // So set either all or none of the properties & warn about it
1066  if (app) {
1067  app->setApplicationVersion(aboutData.version());
1068  app->setApplicationName(aboutData.componentName());
1069  app->setOrganizationDomain(aboutData.organizationDomain());
1070  app->setProperty("applicationDisplayName", aboutData.displayName());
1071  app->setProperty("desktopFileName", aboutData.desktopFileName());
1072  } else {
1073  qCWarning(KABOUTDATA) << "Could not initialize the equivalent properties of Q*Application: no instance (yet) existing.";
1074  }
1075 
1076  // KF6: Rethink the current relation between KAboutData::applicationData and the Q*Application metadata
1077  // Always overwriting the Q*Application metadata here, but not updating back the KAboutData
1078  // in applicationData() is unbalanced and can result in out-of-sync data if the Q*Application
1079  // setters have been called meanwhile
1080  // Options are to remove the overlapping properties of KAboutData for cleancode, or making the
1081  // overlapping properties official shadow properties of their Q*Application countparts, though
1082  // that increases behavioural complexity a little.
1083 }
1084 
1085 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 76)
1087 {
1088  auto &data = s_registry->m_pluginData[aboutData.componentName()];
1089  if (data) {
1090  // silently ignore double registration, assuming it's for the same plugin
1091  // all of this is getting deprecated anyways, we just don't want to leak anything
1092  return;
1093  }
1094  data = new KAboutData(aboutData);
1095 }
1096 #endif
1097 
1098 #if KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 76)
1100 {
1101  KAboutData *ad = s_registry->m_pluginData.value(componentName);
1102  return ad;
1103 }
1104 #endif
1105 
1106 // only for KCrash (no memory allocation allowed)
1107 const KAboutData *KAboutData::applicationDataPointer()
1108 {
1109  if (s_registry.exists()) {
1110  return s_registry->m_appData;
1111  }
1112  return nullptr;
1113 }
1114 
1116 {
1117  if (!d->_shortDescription.isEmpty()) {
1118  parser->setApplicationDescription(d->_shortDescription);
1119  }
1120 
1121  parser->addHelpOption();
1122 
1124  if (app && !app->applicationVersion().isEmpty()) {
1125  parser->addVersionOption();
1126  }
1127 
1128  return parser->addOption(QCommandLineOption(QStringLiteral("author"), QCoreApplication::translate("KAboutData CLI", "Show author information.")))
1129  && parser->addOption(QCommandLineOption(QStringLiteral("license"), QCoreApplication::translate("KAboutData CLI", "Show license information.")))
1130  && parser->addOption(QCommandLineOption(QStringLiteral("desktopfile"),
1131  QCoreApplication::translate("KAboutData CLI", "The base file name of the desktop entry for this application."),
1132  QCoreApplication::translate("KAboutData CLI", "file name")));
1133 }
1134 
1136 {
1137  bool foundArgument = false;
1138  if (parser->isSet(QStringLiteral("author"))) {
1139  foundArgument = true;
1140  if (d->_authorList.isEmpty()) {
1141  printf("%s\n",
1142  qPrintable(QCoreApplication::translate("KAboutData CLI", "This application was written by somebody who wants to remain anonymous.")));
1143  } else {
1144  printf("%s\n", qPrintable(QCoreApplication::translate("KAboutData CLI", "%1 was written by:").arg(qAppName())));
1145  for (const KAboutPerson &person : qAsConst(d->_authorList)) {
1146  QString authorData = QLatin1String(" ") + person.name();
1147  if (!person.emailAddress().isEmpty()) {
1148  authorData.append(QLatin1String(" <") + person.emailAddress() + QLatin1Char('>'));
1149  }
1150  printf("%s\n", qPrintable(authorData));
1151  }
1152  }
1153  if (!customAuthorTextEnabled()) {
1155  printf("%s\n", qPrintable(QCoreApplication::translate("KAboutData CLI", "Please use https://bugs.kde.org to report bugs.")));
1156  } else if (!bugAddress().isEmpty()) {
1157  printf("%s\n", qPrintable(QCoreApplication::translate("KAboutData CLI", "Please report bugs to %1.").arg(bugAddress())));
1158  }
1159  } else {
1160  printf("%s\n", qPrintable(customAuthorPlainText()));
1161  }
1162  } else if (parser->isSet(QStringLiteral("license"))) {
1163  foundArgument = true;
1164  for (const KAboutLicense &license : qAsConst(d->_licenseList)) {
1165  printf("%s\n", qPrintable(license.text()));
1166  }
1167  }
1168 
1169  const QString desktopFileName = parser->value(QStringLiteral("desktopfile"));
1170  if (!desktopFileName.isEmpty()) {
1171  d->desktopFileName = desktopFileName;
1172  }
1173 
1174  if (foundArgument) {
1175  ::exit(EXIT_SUCCESS);
1176  }
1177 }
1178 
1179 template<class T>
1180 QVariantList listToVariant(const QList<T> &values)
1181 {
1182  QVariantList ret;
1183  ret.reserve(values.count());
1184  for (const auto &license : values) {
1185  ret << QVariant::fromValue(license);
1186  }
1187  return ret;
1188 }
1189 
1190 QVariantList KAboutData::licensesVariant() const
1191 {
1192  return listToVariant(d->_licenseList);
1193 }
1194 
1195 QVariantList KAboutData::authorsVariant() const
1196 {
1197  return listToVariant(d->_authorList);
1198 }
1199 
1200 QVariantList KAboutData::creditsVariant() const
1201 {
1202  return listToVariant(d->_creditList);
1203 }
1204 
1205 QVariantList KAboutData::translatorsVariant() const
1206 {
1207  return listToVariant(d->_translatorList);
1208 }
This class is used to store information about a license.
Definition: kaboutdata.h:175
KAboutData & setCopyrightStatement(const QString &copyrightStatement)
Defines the copyright statement to show when displaying the license.
Definition: kaboutdata.cpp:690
const char * internalVersion() const
Definition: kaboutdata.cpp:792
QString homepage() const
Returns the application homepage.
KAboutData & setBugAddress(const QByteArray &bugAddress)
Defines the address where bug reports should be sent.
Definition: kaboutdata.cpp:708
QString & append(QChar ch)
QString organizationDomain() const
Returns the domain name of the organization that wrote this application.
Definition: kaboutdata.cpp:812
KAboutLicense::LicenseKey key() const
Returns the license key.
void processCommandLine(QCommandLineParser *parser)
Reads the processed parser and sees if any of the arguments are the ones set up from setupCommandLine...
QString componentName() const
Returns the application&#39;s internal name.
static KAboutData applicationData()
Returns the KAboutData for the application.
Definition: kaboutdata.cpp:998
KAboutData & setLicense(KAboutLicense::LicenseKey licenseKey)
Defines the license identifier.
Definition: kaboutdata.cpp:662
QString task() const
The person&#39;s task.
QString spdx() const
Returns the SPDX license expression of this license.
KAboutData & setOtherText(const QString &otherText)
Defines the additional text to show in the about dialog.
Definition: kaboutdata.cpp:696
void removeFirst()
QString otherText() const
Returns a translated, free form text.
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
QString host(QUrl::ComponentFormattingOptions options) const const
KAboutData & setDesktopFileName(const QString &desktopFileName)
Sets the base name of the desktop entry for this application.
Definition: kaboutdata.cpp:933
QString ocsProviderUrl() const
Returns the chosen Open Collaboration Services provider URL.
Definition: kaboutdata.cpp:779
KAboutData & setDisplayName(const QString &displayName)
Defines the displayable component name string.
Definition: kaboutdata.cpp:637
const char * internalBugAddress() const
Definition: kaboutdata.cpp:820
QCommandLineOption addVersionOption()
QList< KAboutPerson > translators() const
Returns a list of translators.
KAboutData & setHomepage(const QString &homepage)
Defines the program homepage.
Definition: kaboutdata.cpp:702
QString desktopFileName() const
KAboutLicense & operator=(const KAboutLicense &other)
Assignment operator.
Definition: kaboutdata.cpp:359
QString organizationDomain()
QString join(const QString &separator) const const
QString & remove(int position, int n)
static KAboutData * pluginData(const QString &componentName)
Return the KAboutData for the given plugin identified by componentName.
KAboutData & addAuthor(const QString &name, const QString &task=QString(), const QString &emailAddress=QString(), const QString &webAddress=QString(), const QString &ocsUsername=QString())
Defines an author.
Definition: kaboutdata.cpp:570
int size() const const
KAboutData & setVersion(const QByteArray &version)
Defines the program version string.
Definition: kaboutdata.cpp:650
QString bugAddress() const
Returns the email address or URL for bugs.
KAboutData & setLicenseText(const QString &license)
Defines a license text, which is translated.
Definition: kaboutdata.cpp:588
KAboutData & setOcsProvider(const QString &providerUrl)
Specifies an Open Collaboration Services provider by URL.
Definition: kaboutdata.cpp:644
QList< KAboutPerson > authors() const
Returns a list of authors.
static void registerPluginData(const KAboutData &aboutData)
Register the KAboutData information for a plugin.
KAboutPerson & operator=(const KAboutPerson &other)
Assignment operator.
QVector< V > values(const QMultiHash< K, V > &c)
KAboutData & setCustomAuthorText(const QString &plainText, const QString &richText)
Sets the custom text displayed around the list of authors instead of the default message telling user...
Definition: kaboutdata.cpp:913
bool customAuthorTextEnabled() const
Returns whether custom text should be displayed around the list of authors.
Definition: kaboutdata.cpp:908
QList< KAboutLicense > licenses() const
Returns a list of licenses.
QString emailAddress() const
The person&#39;s email address.
int count(const T &value) const const
QString applicationVersion()
void append(const T &value)
QString fromUtf8(const char *str, int size)
QVariant property(const char *name) const const
KAboutData & addLicenseTextFile(const QString &file)
Adds a license text by pointing to a file where it resides.
Definition: kaboutdata.cpp:617
KAboutData & addCredit(const QString &name, const QString &task=QString(), const QString &emailAddress=QString(), const QString &webAddress=QString(), const QString &ocsUsername=QString())
Defines a person that deserves credit.
Definition: kaboutdata.cpp:576
void setUrl(const QString &url, QUrl::ParsingMode parsingMode)
static QString readTranslatedString(const QJsonObject &jo, const QString &key, const QString &defaultValue=QString())
bool isEmpty() const const
QString trimmed() const const
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QCommandLineOption addHelpOption()
QString text() const
Returns the full license text.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
This class is used to store information about a program or plugin.
Definition: kaboutdata.h:395
void setApplicationDescription(const QString &description)
QCoreApplication * instance()
KAboutData & setProductName(const QByteArray &name)
Defines the product name which will be used in the KBugReport dialog.
Definition: kaboutdata.cpp:720
KAboutData & addLicense(KAboutLicense::LicenseKey licenseKey)
Adds a license identifier.
Definition: kaboutdata.cpp:673
KAboutData & setShortDescription(const QString &shortDescription)
Defines a short description of what the program does.
Definition: kaboutdata.cpp:656
bool isSet(const QString &name) const const
virtual bool open(QIODevice::OpenMode mode) override
QString scheme() const const
QVariant programLogo() const
Returns the program logo image.
LicenseKey
Describes the license of the software.
Definition: kaboutdata.h:188
QList::iterator end()
QString toLower() const const
QList< KAboutPerson > credits() const
Returns a list of persons who contributed.
static void setApplicationData(const KAboutData &aboutData)
Sets the application data for this application.
KeepEmptyParts
KAboutData & setOrganizationDomain(const QByteArray &domain)
Defines the domain of the organization that wrote this application.
Definition: kaboutdata.cpp:714
QVariant fromValue(const T &value)
This class is used to store information about a person or developer.
Definition: kaboutdata.h:56
static KAboutData fromPluginMetaData(const KPluginMetaData &plugin)
Creates a KAboutData from the given plugin metadata.
Definition: kaboutdata.cpp:550
static KAboutPerson fromJSON(const QJsonObject &obj)
Creates a KAboutPerson from a JSON object with the following structure:
Definition: kaboutdata.cpp:93
QString ocsUsername() const
The person&#39;s Open Collaboration Services username.
KAboutData & addLicenseText(const QString &license)
Adds a license text, which is translated.
Definition: kaboutdata.cpp:595
QString customAuthorPlainText() const
Returns the plain text displayed around the list of authors instead of the default message telling us...
Definition: kaboutdata.cpp:898
bool isValid() const const
QString displayName() const
Returns the translated program name.
QByteArray toLatin1() const const
QString productName() const
Returns the application&#39;s product name, which will be used in KBugReport dialog.
KAboutData & unsetCustomAuthorText()
Clears any custom text displayed around the list of authors and falls back to the default message tel...
Definition: kaboutdata.cpp:923
bool setupCommandLine(QCommandLineParser *parser)
Configures the parser command line parser to provide an authors entry with information about the deve...
NameFormat
Format of the license name.
Definition: kaboutdata.h:209
KAboutData & setLicenseTextFile(const QString &file)
Defines a license text by pointing to a file where it resides.
Definition: kaboutdata.cpp:610
static KAboutLicense byKeyword(const QString &keyword)
Fetch a known license by a keyword/spdx ID.
Definition: kaboutdata.cpp:370
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
static QString aboutTranslationTeam()
Returns a message about the translation team.
Definition: kaboutdata.cpp:873
This class allows easily accessing some standardized values from the JSON metadata that can be embedd...
KAboutPerson(const QString &name=QString(), const QString &task=QString(), const QString &emailAddress=QString(), const QString &webAddress=QString(), const QString &ocsUsername=QString())
Convenience constructor.
Definition: kaboutdata.cpp:45
QString copyrightStatement() const
Returns the copyright statement.
KAboutData & setComponentName(const QString &componentName)
Defines the component name used internally.
Definition: kaboutdata.cpp:631
QString webAddress() const
The home page or a relevant link.
bool addOption(const QCommandLineOption &option)
char * data()
KAboutData & setProgramLogo(const QVariant &image)
Defines the program logo.
Definition: kaboutdata.cpp:773
QString fromLatin1(const char *str, int size)
const char * internalProgramName() const
Definition: kaboutdata.cpp:750
KAboutData & setProgramIconName(const QString &iconName)
Obsolete method.
Definition: kaboutdata.cpp:761
QString version() const
Returns the program&#39;s version.
bool setProperty(const char *name, const QVariant &value)
KAboutData & operator=(const KAboutData &other)
Assignment operator.
Definition: kaboutdata.cpp:535
KAboutData(const QString &componentName, const QString &displayName, const QString &version, const QString &shortDescription, enum KAboutLicense::LicenseKey licenseType, const QString &copyrightStatement=QString(), const QString &otherText=QString(), const QString &homePageAddress=QString(), const QString &bugAddress=QStringLiteral("[email protected]"))
Constructor.
Definition: kaboutdata.cpp:442
QString customAuthorRichText() const
Returns the rich text displayed around the list of authors instead of the default message telling use...
Definition: kaboutdata.cpp:903
QString programIconName() const
Returns the program&#39;s icon name.
Definition: kaboutdata.cpp:756
QString readAll()
QString toString() const const
QString value(const QString &optionName) const const
QString shortDescription() const
Returns a short, translated description.
QString name() const
The person&#39;s name.
QList::iterator begin()
QString applicationName()
VersionRestriction
Whether later versions of the license are allowed.
Definition: kaboutdata.h:218
QString locate(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
KAboutData & setTranslator(const QString &name, const QString &emailAddress)
Sets the name(s) of the translator(s) of the GUI.
Definition: kaboutdata.cpp:582
QByteArray toUtf8() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Apr 13 2021 23:01:32 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.