File indexing completed on 2024-04-14 14:19:52

0001 /*
0002  * This file is part of the KDE Libraries
0003  * Copyright (C) 2000 Espen Sand (espen@kde.org)
0004  * Copyright (C) 2006 Nicolas GOUTTE <goutte@kde.org>
0005  * Copyright (C) 2008 Friedrich W. H. Kossebau <kossebau@kde.org>
0006  * Copyright (C) 2010 Teo Mrnjavac <teo@kde.org>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  *
0023  */
0024 
0025 #include "k4aboutdata.h"
0026 #include "kaboutdata.h"
0027 
0028 #include <QStandardPaths>
0029 #include <QFile>
0030 #include <QTextStream>
0031 #include <QSharedData>
0032 #include <QVariant>
0033 #include <QList>
0034 #include <QHash>
0035 
0036 // -----------------------------------------------------------------------------
0037 // Design notes:
0038 //
0039 // These classes deal with a lot of text, some of which needs to be
0040 // marked for translation. Since at the time when these object and calls are
0041 // made the translation catalogs are usually still not initialized, the
0042 // translation has to be delayed. This is achieved by using KLocalizedString
0043 // for translatable strings. KLocalizedStrings are produced by ki18n* calls,
0044 // instead of the more usuall i18n* calls which produce QString by trying to
0045 // translate immediately.
0046 //
0047 // All the non-translatable string arguments to methods are taken QByteArray,
0048 // all the translatable are KLocalizedString. The getter methods always return
0049 // proper QString: the non-translatable strings supplied by the code are
0050 // treated with QString::fromUtf8(), those coming from the outside with
0051 // QTextCodec::toUnicode(), and translatable strings are finalized to QStrings
0052 // at the point of getter calls (i.e. delayed translation).
0053 // -----------------------------------------------------------------------------
0054 
0055 class Q_DECL_HIDDEN K4AboutPerson::Private
0056 {
0057 public:
0058     KLocalizedString _name;
0059     KLocalizedString _task;
0060     QString _emailAddress;
0061     QString _webAddress;
0062     QString _ocsUsername;
0063 
0064     QString _nameNoop;
0065 };
0066 
0067 K4AboutPerson::K4AboutPerson(const KLocalizedString &_name,
0068                              const KLocalizedString &_task,
0069                              const QByteArray &_emailAddress,
0070                              const QByteArray &_webAddress)
0071     : d(new Private)
0072 {
0073     d->_name = _name;
0074     d->_task = _task;
0075     d->_emailAddress = QString::fromUtf8(_emailAddress.data());
0076     d->_webAddress = QString::fromUtf8(_webAddress.data());
0077 }
0078 
0079 K4AboutPerson::K4AboutPerson(const KLocalizedString &_name,
0080                              const KLocalizedString &_task,
0081                              const QByteArray &_emailAddress,
0082                              const QByteArray &_webAddress,
0083                              const QByteArray &_ocsUsername)
0084     : d(new Private)
0085 {
0086     d->_name = _name;
0087     d->_task = _task;
0088     d->_emailAddress = QString::fromUtf8(_emailAddress.data());
0089     d->_webAddress = QString::fromUtf8(_webAddress.data());
0090     d->_ocsUsername = QString::fromUtf8(_ocsUsername.data());
0091 }
0092 
0093 K4AboutPerson::K4AboutPerson(const QString &_name, const QString &_email)
0094     : d(new Private)
0095 {
0096     d->_nameNoop = _name;
0097     d->_emailAddress = _email;
0098 }
0099 
0100 K4AboutPerson::K4AboutPerson(const K4AboutPerson &other): d(new Private)
0101 {
0102     *d = *other.d;
0103 }
0104 
0105 K4AboutPerson::~K4AboutPerson()
0106 {
0107     delete d;
0108 }
0109 
0110 QString K4AboutPerson::name() const
0111 {
0112     if (!d->_nameNoop.isEmpty()) {
0113         return d->_nameNoop;
0114     }
0115     return d->_name.toString();
0116 }
0117 
0118 QString K4AboutPerson::task() const
0119 {
0120     if (!d->_task.isEmpty()) {
0121         return d->_task.toString();
0122     }
0123     return QString();
0124 }
0125 
0126 QString K4AboutPerson::emailAddress() const
0127 {
0128     return d->_emailAddress;
0129 }
0130 
0131 QString K4AboutPerson::webAddress() const
0132 {
0133     return d->_webAddress;
0134 }
0135 
0136 QString K4AboutPerson::ocsUsername() const
0137 {
0138     return d->_ocsUsername;
0139 }
0140 
0141 K4AboutPerson &K4AboutPerson::operator=(const K4AboutPerson &other)
0142 {
0143     *d = *other.d;
0144     return *this;
0145 }
0146 
0147 class Q_DECL_HIDDEN K4AboutLicense::Private : public QSharedData
0148 {
0149 public:
0150     Private(enum K4AboutData::LicenseKey licenseType, const K4AboutData *aboutData);
0151     Private(const QString &pathToFile, const K4AboutData *aboutData);
0152     Private(const KLocalizedString &licenseText, const K4AboutData *aboutData);
0153     Private(const Private &other);
0154 public:
0155     enum K4AboutData::LicenseKey  _licenseKey;
0156     KLocalizedString             _licenseText;
0157     QString                      _pathToLicenseTextFile;
0158     // needed for access to the possibly changing copyrightStatement()
0159     const K4AboutData            *_aboutData;
0160 };
0161 
0162 K4AboutLicense::Private::Private(enum K4AboutData::LicenseKey licenseType, const K4AboutData *aboutData)
0163     : QSharedData(),
0164       _licenseKey(licenseType),
0165       _aboutData(aboutData)
0166 {
0167 }
0168 
0169 K4AboutLicense::Private::Private(const QString &pathToFile, const K4AboutData *aboutData)
0170     : QSharedData(),
0171       _licenseKey(K4AboutData::License_File),
0172       _pathToLicenseTextFile(pathToFile),
0173       _aboutData(aboutData)
0174 {
0175 }
0176 
0177 K4AboutLicense::Private::Private(const KLocalizedString &licenseText, const K4AboutData *aboutData)
0178     : QSharedData(),
0179       _licenseKey(K4AboutData::License_Custom),
0180       _licenseText(licenseText),
0181       _aboutData(aboutData)
0182 {
0183 }
0184 
0185 K4AboutLicense::Private::Private(const K4AboutLicense::Private &other)
0186     : QSharedData(other),
0187       _licenseKey(other._licenseKey),
0188       _licenseText(other._licenseText),
0189       _pathToLicenseTextFile(other._pathToLicenseTextFile),
0190       _aboutData(other._aboutData)
0191 {}
0192 
0193 K4AboutLicense::K4AboutLicense(enum K4AboutData::LicenseKey licenseType, const K4AboutData *aboutData)
0194     : d(new Private(licenseType, aboutData))
0195 {
0196 }
0197 
0198 K4AboutLicense::K4AboutLicense(const QString &pathToFile, const K4AboutData *aboutData)
0199     : d(new Private(pathToFile, aboutData))
0200 {
0201 }
0202 
0203 K4AboutLicense::K4AboutLicense(const KLocalizedString &licenseText, const K4AboutData *aboutData)
0204     : d(new Private(licenseText, aboutData))
0205 {
0206 }
0207 
0208 K4AboutLicense::K4AboutLicense(const K4AboutLicense &other)
0209     : d(other.d)
0210 {
0211 }
0212 
0213 K4AboutLicense::~K4AboutLicense()
0214 {}
0215 
0216 QString K4AboutLicense::text() const
0217 {
0218     QString result;
0219 
0220     const QString lineFeed = QString::fromLatin1("\n\n");
0221 
0222     if (d->_aboutData && !d->_aboutData->copyrightStatement().isEmpty()) {
0223         result = d->_aboutData->copyrightStatement() + lineFeed;
0224     }
0225 
0226     bool knownLicense = false;
0227     QString pathToFile;
0228     switch (d->_licenseKey) {
0229     case K4AboutData::License_File:
0230         pathToFile = d->_pathToLicenseTextFile;
0231         break;
0232     case K4AboutData::License_GPL_V2:
0233         knownLicense = true;
0234         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/GPL_V2"));
0235         break;
0236     case K4AboutData::License_LGPL_V2:
0237         knownLicense = true;
0238         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/LGPL_V2"));
0239         break;
0240     case K4AboutData::License_BSD:
0241         knownLicense = true;
0242         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/BSD"));
0243         break;
0244     case K4AboutData::License_Artistic:
0245         knownLicense = true;
0246         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/ARTISTIC"));
0247         break;
0248     case K4AboutData::License_QPL_V1_0:
0249         knownLicense = true;
0250         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/QPL_V1.0"));
0251         break;
0252     case K4AboutData::License_GPL_V3:
0253         knownLicense = true;
0254         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/GPL_V3"));
0255         break;
0256     case K4AboutData::License_LGPL_V3:
0257         knownLicense = true;
0258         pathToFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QString::fromLatin1("LICENSES/LGPL_V3"));
0259         break;
0260     case K4AboutData::License_Custom:
0261         if (!d->_licenseText.isEmpty()) {
0262             result = d->_licenseText.toString();
0263             break;
0264         }
0265     // fall through
0266     default:
0267         result += i18n("No licensing terms for this program have been specified.\n"
0268                               "Please check the documentation or the source for any\n"
0269                               "licensing terms.\n");
0270     }
0271 
0272     if (knownLicense) {
0273         result += i18n("This program is distributed under the terms of the %1.", name(K4AboutData::ShortName));
0274         if (!pathToFile.isEmpty()) {
0275             result += lineFeed;
0276         }
0277     }
0278 
0279     if (!pathToFile.isEmpty()) {
0280         QFile file(pathToFile);
0281         if (file.open(QIODevice::ReadOnly)) {
0282             QTextStream str(&file);
0283             result += str.readAll();
0284         }
0285     }
0286 
0287     return result;
0288 }
0289 
0290 QString K4AboutLicense::name(K4AboutData::NameFormat formatName) const
0291 {
0292     QString licenseShort;
0293     QString licenseFull;
0294 
0295     switch (d->_licenseKey) {
0296     case K4AboutData::License_GPL_V2:
0297         licenseShort = i18nc("@item license (short name)", "GPL v2");
0298         licenseFull = i18nc("@item license", "GNU General Public License Version 2");
0299         break;
0300     case K4AboutData::License_LGPL_V2:
0301         licenseShort = i18nc("@item license (short name)", "LGPL v2");
0302         licenseFull = i18nc("@item license", "GNU Lesser General Public License Version 2");
0303         break;
0304     case K4AboutData::License_BSD:
0305         licenseShort = i18nc("@item license (short name)", "BSD License");
0306         licenseFull = i18nc("@item license", "BSD License");
0307         break;
0308     case K4AboutData::License_Artistic:
0309         licenseShort = i18nc("@item license (short name)", "Artistic License");
0310         licenseFull = i18nc("@item license", "Artistic License");
0311         break;
0312     case K4AboutData::License_QPL_V1_0:
0313         licenseShort = i18nc("@item license (short name)", "QPL v1.0");
0314         licenseFull = i18nc("@item license", "Q Public License");
0315         break;
0316     case K4AboutData::License_GPL_V3:
0317         licenseShort = i18nc("@item license (short name)", "GPL v3");
0318         licenseFull = i18nc("@item license", "GNU General Public License Version 3");
0319         break;
0320     case K4AboutData::License_LGPL_V3:
0321         licenseShort = i18nc("@item license (short name)", "LGPL v3");
0322         licenseFull = i18nc("@item license", "GNU Lesser General Public License Version 3");
0323         break;
0324     case K4AboutData::License_Custom:
0325     case K4AboutData::License_File:
0326         licenseShort = licenseFull = i18nc("@item license", "Custom");
0327         break;
0328     default:
0329         licenseShort = licenseFull = i18nc("@item license", "Not specified");
0330     }
0331 
0332     const QString result =
0333         (formatName == K4AboutData::ShortName) ? licenseShort :
0334         (formatName == K4AboutData::FullName) ?  licenseFull :
0335         QString();
0336 
0337     return result;
0338 }
0339 
0340 K4AboutLicense &K4AboutLicense::operator=(const K4AboutLicense &other)
0341 {
0342     d = other.d;
0343     return *this;
0344 }
0345 
0346 K4AboutData::LicenseKey K4AboutLicense::key() const
0347 {
0348     return d->_licenseKey;
0349 }
0350 
0351 K4AboutLicense K4AboutLicense::byKeyword(const QString &rawKeyword)
0352 {
0353     // Setup keyword->enum dictionary on first call.
0354     // Use normalized keywords, by the algorithm below.
0355     static QHash<QByteArray, K4AboutData::LicenseKey> ldict;
0356     if (ldict.isEmpty()) {
0357         ldict.insert("gpl", K4AboutData::License_GPL);
0358         ldict.insert("gplv2", K4AboutData::License_GPL_V2);
0359         ldict.insert("gplv2+", K4AboutData::License_GPL_V2);
0360         ldict.insert("lgpl", K4AboutData::License_LGPL);
0361         ldict.insert("lgplv2", K4AboutData::License_LGPL_V2);
0362         ldict.insert("lgplv2+", K4AboutData::License_LGPL_V2);
0363         ldict.insert("bsd", K4AboutData::License_BSD);
0364         ldict.insert("artistic", K4AboutData::License_Artistic);
0365         ldict.insert("qpl", K4AboutData::License_QPL);
0366         ldict.insert("qplv1", K4AboutData::License_QPL_V1_0);
0367         ldict.insert("qplv10", K4AboutData::License_QPL_V1_0);
0368         ldict.insert("gplv3", K4AboutData::License_GPL_V3);
0369         ldict.insert("gplv3+", K4AboutData::License_GPL_V3);
0370         ldict.insert("lgplv3", K4AboutData::License_LGPL_V3);
0371         ldict.insert("lgplv3+", K4AboutData::License_LGPL_V3);
0372     }
0373 
0374     // Normalize keyword.
0375     QString keyword = rawKeyword;
0376     keyword = keyword.toLower();
0377     keyword.remove(QLatin1Char(' '));
0378     keyword.remove(QLatin1Char('.'));
0379 
0380     K4AboutData::LicenseKey license = ldict.value(keyword.toLatin1(),
0381                                       K4AboutData::License_Custom);
0382     return K4AboutLicense(license, nullptr);
0383 }
0384 
0385 class Q_DECL_HIDDEN K4AboutData::Private
0386 {
0387 public:
0388     Private()
0389         : customAuthorTextEnabled(false)
0390     {}
0391     QByteArray _appName;
0392     KLocalizedString _programName;
0393     KLocalizedString _shortDescription;
0394     QByteArray _catalogName;
0395     KLocalizedString _copyrightStatement;
0396     KLocalizedString _otherText;
0397     QString _homepageAddress;
0398     QList<K4AboutPerson> _authorList;
0399     QList<K4AboutPerson> _creditList;
0400     QList<K4AboutLicense> _licenseList;
0401     KLocalizedString translatorName;
0402     KLocalizedString translatorEmail;
0403     QString productName;
0404     QString programIconName;
0405     QVariant programLogo;
0406     KLocalizedString customAuthorPlainText, customAuthorRichText;
0407     bool customAuthorTextEnabled;
0408 
0409     QString organizationDomain;
0410     QByteArray _ocsProviderUrl;
0411 
0412     // Everything dr.konqi needs, we store as utf-8, so we
0413     // can just give it a pointer, w/o any allocations.
0414     QByteArray _translatedProgramName; // ### I don't see it ever being translated, and I did not change that
0415     QByteArray _version;
0416     QByteArray _bugEmailAddress;
0417 };
0418 
0419 K4AboutData::K4AboutData(const QByteArray &_appName,
0420                          const QByteArray &_catalogName,
0421                          const KLocalizedString &_programName,
0422                          const QByteArray &_version,
0423                          const KLocalizedString &_shortDescription,
0424                          enum LicenseKey licenseType,
0425                          const KLocalizedString &_copyrightStatement,
0426                          const KLocalizedString &text,
0427                          const QByteArray &homePageAddress,
0428                          const QByteArray &bugsEmailAddress
0429                         )
0430     : d(new Private)
0431 {
0432     d->_appName = _appName;
0433     int p = d->_appName.indexOf('/');
0434     if (p >= 0) {
0435         d->_appName = d->_appName.mid(p + 1);
0436     }
0437 
0438     d->_catalogName = _catalogName;
0439     d->_programName = _programName;
0440     if (!d->_programName.isEmpty()) { // KComponentData("klauncher") gives empty program name
0441         d->_translatedProgramName = _programName.toString().toUtf8();
0442     }
0443     d->_version = _version;
0444     d->_shortDescription = _shortDescription;
0445     d->_licenseList.append(K4AboutLicense(licenseType, this));
0446     d->_copyrightStatement = _copyrightStatement;
0447     d->_otherText = text;
0448     d->_homepageAddress = QString::fromLatin1(homePageAddress.data());
0449     d->_bugEmailAddress = bugsEmailAddress;
0450 
0451     if (d->_homepageAddress.contains(QLatin1String("http://"))) {
0452         const int dot = d->_homepageAddress.indexOf(QLatin1Char('.'));
0453         if (dot >= 0) {
0454             d->organizationDomain = d->_homepageAddress.mid(dot + 1);
0455             const int slash = d->organizationDomain.indexOf(QLatin1Char('/'));
0456             if (slash >= 0) {
0457                 d->organizationDomain.truncate(slash);
0458             }
0459         } else {
0460             d->organizationDomain = QString::fromLatin1("kde.org");
0461         }
0462     } else {
0463         d->organizationDomain = QString::fromLatin1("kde.org");
0464     }
0465 }
0466 
0467 K4AboutData::~K4AboutData()
0468 {
0469     delete d;
0470 }
0471 
0472 K4AboutData::K4AboutData(const K4AboutData &other): d(new Private)
0473 {
0474     *d = *other.d;
0475     QList<K4AboutLicense>::iterator it = d->_licenseList.begin(), itEnd = d->_licenseList.end();
0476     for (; it != itEnd; ++it) {
0477         K4AboutLicense &al = *it;
0478         al.d.detach();
0479         al.d->_aboutData = this;
0480     }
0481 }
0482 
0483 K4AboutData &K4AboutData::operator=(const K4AboutData &other)
0484 {
0485     if (this != &other) {
0486         *d = *other.d;
0487         QList<K4AboutLicense>::iterator it = d->_licenseList.begin(), itEnd = d->_licenseList.end();
0488         for (; it != itEnd; ++it) {
0489             K4AboutLicense &al = *it;
0490             al.d.detach();
0491             al.d->_aboutData = this;
0492         }
0493     }
0494     return *this;
0495 }
0496 
0497 K4AboutData::operator KAboutData() const
0498 {
0499     // catalogName() is not used by KF5 KAboutData
0500     KAboutData aboutData(appName(), programName(), version(), shortDescription(),
0501                          KAboutLicense::Unknown, copyrightStatement(),
0502                          otherText(), d->_homepageAddress, bugAddress());
0503     for (auto it = d->_licenseList.constBegin(); it != d->_licenseList.constEnd(); ++it) {
0504         if (it->key() == K4AboutData::License_Custom) {
0505             aboutData.addLicenseText(it->text());
0506         } else if (it->key() == K4AboutData::License_File) {
0507             aboutData.addLicenseTextFile(it->d->_pathToLicenseTextFile);
0508         } else {
0509             aboutData.addLicense(static_cast<KAboutLicense::LicenseKey>(it->key()));
0510         }
0511     }
0512     return aboutData;
0513 }
0514 
0515 K4AboutData &K4AboutData::addAuthor(const KLocalizedString &name,
0516                                     const KLocalizedString &task,
0517                                     const QByteArray &emailAddress,
0518                                     const QByteArray &webAddress)
0519 {
0520     d->_authorList.append(K4AboutPerson(name, task, emailAddress, webAddress));
0521     return *this;
0522 }
0523 
0524 K4AboutData &K4AboutData::addAuthor(const KLocalizedString &name,
0525                                     const KLocalizedString &task,
0526                                     const QByteArray &emailAddress,
0527                                     const QByteArray &webAddress,
0528                                     const QByteArray &ocsUsername)
0529 {
0530     d->_authorList.append(K4AboutPerson(name, task, emailAddress, webAddress, ocsUsername));
0531     return *this;
0532 }
0533 
0534 K4AboutData &K4AboutData::addCredit(const KLocalizedString &name,
0535                                     const KLocalizedString &task,
0536                                     const QByteArray &emailAddress,
0537                                     const QByteArray &webAddress)
0538 {
0539     d->_creditList.append(K4AboutPerson(name, task, emailAddress, webAddress));
0540     return *this;
0541 }
0542 
0543 K4AboutData &K4AboutData::addCredit(const KLocalizedString &name,
0544                                     const KLocalizedString &task,
0545                                     const QByteArray &emailAddress,
0546                                     const QByteArray &webAddress,
0547                                     const QByteArray &ocsUsername)
0548 {
0549     d->_creditList.append(K4AboutPerson(name, task, emailAddress, webAddress, ocsUsername));
0550     return *this;
0551 }
0552 
0553 K4AboutData &K4AboutData::setTranslator(const KLocalizedString &name,
0554                                         const KLocalizedString &emailAddress)
0555 {
0556     d->translatorName = name;
0557     d->translatorEmail = emailAddress;
0558     return *this;
0559 }
0560 
0561 K4AboutData &K4AboutData::setLicenseText(const KLocalizedString &licenseText)
0562 {
0563     d->_licenseList[0] = K4AboutLicense(licenseText, this);
0564     return *this;
0565 }
0566 
0567 K4AboutData &K4AboutData::addLicenseText(const KLocalizedString &licenseText)
0568 {
0569     // if the default license is unknown, overwrite instead of append
0570     K4AboutLicense &firstLicense = d->_licenseList[0];
0571     if (d->_licenseList.count() == 1 && firstLicense.d->_licenseKey == License_Unknown) {
0572         firstLicense = K4AboutLicense(licenseText, this);
0573     } else {
0574         d->_licenseList.append(K4AboutLicense(licenseText, this));
0575     }
0576     return *this;
0577 }
0578 
0579 K4AboutData &K4AboutData::setLicenseTextFile(const QString &pathToFile)
0580 {
0581     d->_licenseList[0] = K4AboutLicense(pathToFile, this);
0582     return *this;
0583 }
0584 
0585 K4AboutData &K4AboutData::addLicenseTextFile(const QString &pathToFile)
0586 {
0587     // if the default license is unknown, overwrite instead of append
0588     K4AboutLicense &firstLicense = d->_licenseList[0];
0589     if (d->_licenseList.count() == 1 && firstLicense.d->_licenseKey == License_Unknown) {
0590         firstLicense = K4AboutLicense(pathToFile, this);
0591     } else {
0592         d->_licenseList.append(K4AboutLicense(pathToFile, this));
0593     }
0594     return *this;
0595 }
0596 
0597 K4AboutData &K4AboutData::setAppName(const QByteArray &_appName)
0598 {
0599     d->_appName = _appName;
0600     return *this;
0601 }
0602 
0603 K4AboutData &K4AboutData::setProgramName(const KLocalizedString &_programName)
0604 {
0605     d->_programName = _programName;
0606     translateInternalProgramName();
0607     return *this;
0608 }
0609 
0610 K4AboutData &K4AboutData::setOcsProvider(const QByteArray &_ocsProviderUrl)
0611 {
0612     d->_ocsProviderUrl = _ocsProviderUrl;
0613     return *this;
0614 }
0615 
0616 K4AboutData &K4AboutData::setVersion(const QByteArray &_version)
0617 {
0618     d->_version = _version;
0619     return *this;
0620 }
0621 
0622 K4AboutData &K4AboutData::setShortDescription(const KLocalizedString &_shortDescription)
0623 {
0624     d->_shortDescription = _shortDescription;
0625     return *this;
0626 }
0627 
0628 K4AboutData &K4AboutData::setCatalogName(const QByteArray &_catalogName)
0629 {
0630     d->_catalogName = _catalogName;
0631     return *this;
0632 }
0633 
0634 K4AboutData &K4AboutData::setLicense(LicenseKey licenseKey)
0635 {
0636     d->_licenseList[0] = K4AboutLicense(licenseKey, this);
0637     return *this;
0638 }
0639 
0640 K4AboutData &K4AboutData::addLicense(LicenseKey licenseKey)
0641 {
0642     // if the default license is unknown, overwrite instead of append
0643     K4AboutLicense &firstLicense = d->_licenseList[0];
0644     if (d->_licenseList.count() == 1 && firstLicense.d->_licenseKey == License_Unknown) {
0645         firstLicense = K4AboutLicense(licenseKey, this);
0646     } else {
0647         d->_licenseList.append(K4AboutLicense(licenseKey, this));
0648     }
0649     return *this;
0650 }
0651 
0652 K4AboutData &K4AboutData::setCopyrightStatement(const KLocalizedString &_copyrightStatement)
0653 {
0654     d->_copyrightStatement = _copyrightStatement;
0655     return *this;
0656 }
0657 
0658 K4AboutData &K4AboutData::setOtherText(const KLocalizedString &_otherText)
0659 {
0660     d->_otherText = _otherText;
0661     return *this;
0662 }
0663 
0664 K4AboutData &K4AboutData::setHomepage(const QByteArray &_homepage)
0665 {
0666     d->_homepageAddress = QString::fromLatin1(_homepage.data());
0667     return *this;
0668 }
0669 
0670 K4AboutData &K4AboutData::setBugAddress(const QByteArray &_bugAddress)
0671 {
0672     d->_bugEmailAddress = _bugAddress;
0673     return *this;
0674 }
0675 
0676 K4AboutData &K4AboutData::setOrganizationDomain(const QByteArray &domain)
0677 {
0678     d->organizationDomain = QString::fromLatin1(domain.data());
0679     return *this;
0680 }
0681 
0682 K4AboutData &K4AboutData::setProductName(const QByteArray &_productName)
0683 {
0684     d->productName = QString::fromUtf8(_productName.data());
0685     return *this;
0686 }
0687 
0688 QString K4AboutData::appName() const
0689 {
0690     return QString::fromUtf8(d->_appName.data());
0691 }
0692 
0693 QString K4AboutData::productName() const
0694 {
0695     if (!d->productName.isEmpty()) {
0696         return d->productName;
0697     }
0698     return appName();
0699 }
0700 
0701 QString K4AboutData::programName() const
0702 {
0703     if (!d->_programName.isEmpty()) {
0704         return d->_programName.toString();
0705     }
0706     return QString();
0707 }
0708 
0709 /// @internal
0710 /// Return the program name. It is always pre-allocated.
0711 /// Needed for KCrash in particular.
0712 const char *K4AboutData::internalProgramName() const
0713 {
0714     return d->_translatedProgramName.constData();
0715 }
0716 
0717 /// @internal
0718 /// KCrash should call as few things as possible and should avoid e.g. malloc()
0719 /// because it may deadlock. Since i18n() needs it, when KLocale is available
0720 /// the i18n() call will be done here in advance.
0721 void K4AboutData::translateInternalProgramName() const
0722 {
0723     d->_translatedProgramName.clear();
0724 #pragma message("KDE5 FIXME: This code must be replaced by something with KLocalizedString")
0725 #if 0
0726     if (KLocale::global()) {
0727         d->_translatedProgramName = programName().toUtf8();
0728     }
0729 #endif
0730 }
0731 
0732 QString K4AboutData::programIconName() const
0733 {
0734     return d->programIconName.isEmpty() ? appName() : d->programIconName;
0735 }
0736 
0737 K4AboutData &K4AboutData::setProgramIconName(const QString &iconName)
0738 {
0739     d->programIconName = iconName;
0740     return *this;
0741 }
0742 
0743 QVariant K4AboutData::programLogo() const
0744 {
0745     return d->programLogo;
0746 }
0747 
0748 K4AboutData &K4AboutData::setProgramLogo(const QVariant &image)
0749 {
0750     d->programLogo = image;
0751     return *this;
0752 }
0753 
0754 QString K4AboutData::ocsProviderUrl() const
0755 {
0756     if (!d->_ocsProviderUrl.isEmpty()) {
0757         return QString::fromUtf8(d->_ocsProviderUrl.data());
0758     }
0759     return QString();
0760 }
0761 
0762 QString K4AboutData::version() const
0763 {
0764     return QString::fromUtf8(d->_version.data());
0765 }
0766 
0767 /// @internal
0768 /// Return the untranslated and uninterpreted (to UTF8) string
0769 /// for the version information. Used in particular for KCrash.
0770 const char *K4AboutData::internalVersion() const
0771 {
0772     return d->_version.constData();
0773 }
0774 
0775 QString K4AboutData::shortDescription() const
0776 {
0777     if (!d->_shortDescription.isEmpty()) {
0778         return d->_shortDescription.toString();
0779     }
0780     return QString();
0781 }
0782 
0783 QString K4AboutData::catalogName() const
0784 {
0785     if (!d->_catalogName.isEmpty()) {
0786         return QString::fromUtf8(d->_catalogName.data());
0787     }
0788     // Fallback to appname for catalog name if empty.
0789     return QString::fromUtf8(d->_appName.data());
0790 }
0791 
0792 QString K4AboutData::homepage() const
0793 {
0794     return d->_homepageAddress;
0795 }
0796 
0797 QString K4AboutData::bugAddress() const
0798 {
0799     return QString::fromUtf8(d->_bugEmailAddress.data());
0800 }
0801 
0802 QString K4AboutData::organizationDomain() const
0803 {
0804     return d->organizationDomain;
0805 }
0806 
0807 /// @internal
0808 /// Return the untranslated and uninterpreted (to UTF8) string
0809 /// for the bug mail address. Used in particular for KCrash.
0810 const char *K4AboutData::internalBugAddress() const
0811 {
0812     if (d->_bugEmailAddress.isEmpty()) {
0813         return nullptr;
0814     }
0815     return d->_bugEmailAddress.constData();
0816 }
0817 
0818 QList<K4AboutPerson> K4AboutData::authors() const
0819 {
0820     return d->_authorList;
0821 }
0822 
0823 QList<K4AboutPerson> K4AboutData::credits() const
0824 {
0825     return d->_creditList;
0826 }
0827 
0828 #define NAME_OF_TRANSLATORS "Your names"
0829 #define EMAIL_OF_TRANSLATORS "Your emails"
0830 QList<K4AboutPerson> K4AboutData::translators() const
0831 {
0832     QList<K4AboutPerson> personList;
0833 #pragma message("KDE5 TODO: What about this code ?")
0834 #if 0
0835     KLocale *tmpLocale = NULL;
0836     if (KLocale::global()) {
0837         // There could be many catalogs loaded into the global locale,
0838         // e.g. in systemsettings. The tmp locale is needed to make sure we
0839         // use the translators name from this aboutdata's catalog, rather than
0840         // from any other loaded catalog.
0841         tmpLocale = new KLocale(*KLocale::global());
0842         tmpLocale->setActiveCatalog(catalogName());
0843     }
0844 #endif
0845     QString translatorName;
0846     if (!d->translatorName.isEmpty()) {
0847         translatorName = d->translatorName.toString();
0848     } else {
0849         translatorName = ki18nc("NAME OF TRANSLATORS", NAME_OF_TRANSLATORS).toString(); //toString(tmpLocale);
0850     }
0851 
0852     QString translatorEmail;
0853     if (!d->translatorEmail.isEmpty()) {
0854         translatorEmail = d->translatorEmail.toString();
0855     } else {
0856         translatorEmail = ki18nc("EMAIL OF TRANSLATORS", EMAIL_OF_TRANSLATORS).toString(); //toString(tmpLocale);
0857     }
0858 #if 0
0859     delete tmpLocale;
0860 #endif
0861     if (translatorName.isEmpty() || translatorName == QString::fromUtf8(NAME_OF_TRANSLATORS)) {
0862         return personList;
0863     }
0864 
0865     const QStringList nameList(translatorName.split(QString(QLatin1Char(','))));
0866 
0867     QStringList emailList;
0868     if (!translatorEmail.isEmpty() && translatorEmail != QString::fromUtf8(EMAIL_OF_TRANSLATORS)) {
0869         emailList = translatorEmail.split(QString(QLatin1Char(',')), QString::KeepEmptyParts);
0870     }
0871 
0872     QStringList::const_iterator nit;
0873     QStringList::const_iterator eit = emailList.constBegin();
0874 
0875     for (nit = nameList.constBegin(); nit != nameList.constEnd(); ++nit) {
0876         QString email;
0877         if (eit != emailList.constEnd()) {
0878             email = *eit;
0879             ++eit;
0880         }
0881 
0882         personList.append(K4AboutPerson((*nit).trimmed(), email.trimmed()));
0883     }
0884 
0885     return personList;
0886 }
0887 
0888 QString K4AboutData::aboutTranslationTeam()
0889 {
0890     return i18nc("replace this with information about your translation team",
0891                  "<p>KDE is translated into many languages thanks to the work "
0892                  "of the translation teams all over the world.</p>"
0893                  "<p>For more information on KDE internationalization "
0894                  "visit <a href=\"http://l10n.kde.org\">http://l10n.kde.org</a></p>"
0895                 );
0896 }
0897 
0898 QString K4AboutData::otherText() const
0899 {
0900     if (!d->_otherText.isEmpty()) {
0901         return d->_otherText.toString();
0902     }
0903     return QString();
0904 }
0905 
0906 QString K4AboutData::license() const
0907 {
0908     return d->_licenseList.at(0).text();
0909 }
0910 
0911 QString K4AboutData::licenseName(NameFormat formatName) const
0912 {
0913     return d->_licenseList.at(0).name(formatName);
0914 }
0915 
0916 QList<K4AboutLicense> K4AboutData::licenses() const
0917 {
0918     return d->_licenseList;
0919 }
0920 
0921 QString K4AboutData::copyrightStatement() const
0922 {
0923     if (!d->_copyrightStatement.isEmpty()) {
0924         return d->_copyrightStatement.toString();
0925     }
0926     return QString();
0927 }
0928 
0929 QString K4AboutData::customAuthorPlainText() const
0930 {
0931     if (!d->customAuthorPlainText.isEmpty()) {
0932         return d->customAuthorPlainText.toString();
0933     }
0934     return QString();
0935 }
0936 
0937 QString K4AboutData::customAuthorRichText() const
0938 {
0939     if (!d->customAuthorRichText.isEmpty()) {
0940         return d->customAuthorRichText.toString();
0941     }
0942     return QString();
0943 }
0944 
0945 bool K4AboutData::customAuthorTextEnabled() const
0946 {
0947     return d->customAuthorTextEnabled;
0948 }
0949 
0950 K4AboutData &K4AboutData::setCustomAuthorText(const KLocalizedString &plainText,
0951         const KLocalizedString &richText)
0952 {
0953     d->customAuthorPlainText = plainText;
0954     d->customAuthorRichText = richText;
0955 
0956     d->customAuthorTextEnabled = true;
0957 
0958     return *this;
0959 }
0960 
0961 K4AboutData &K4AboutData::unsetCustomAuthorText()
0962 {
0963     d->customAuthorPlainText = KLocalizedString();
0964     d->customAuthorRichText = KLocalizedString();
0965 
0966     d->customAuthorTextEnabled = false;
0967 
0968     return *this;
0969 }
0970