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

0001 /* This file is part of the KDE libraries
0002    Copyright (C) 1999 Torben Weis <weis@kde.org>
0003    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
0004    Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License version 2 as published by the Free Software Foundation.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "kcomponentdata.h"
0022 #include "kcomponentdata_p.h"
0023 
0024 #include <QCoreApplication>
0025 
0026 #include "kaboutdata.h"
0027 #include "k4aboutdata.h"
0028 #include "kconfig.h"
0029 #include "kconfiggroup.h"
0030 #include <QtDebug>
0031 
0032 #ifndef NDEBUG
0033 #define MYASSERT(x) if (!x) \
0034         qFatal("Fatal error: you need to have a KComponentData object before\n" \
0035                "you do anything that requires it! Examples of this are config\n" \
0036                "objects, standard directories or translations.");
0037 #else
0038 #define MYASSERT(x) /* nope */
0039 #endif
0040 
0041 KComponentData::KComponentData()
0042     : d(nullptr)
0043 {
0044 }
0045 
0046 KComponentData::KComponentData(const KComponentData &rhs)
0047     : d(rhs.d)
0048 {
0049     if (d) {
0050         d->ref();
0051     }
0052 }
0053 
0054 KComponentData &KComponentData::operator=(const KComponentData &rhs)
0055 {
0056     if (rhs.d != d) {
0057         if (rhs.d) {
0058             rhs.d->ref();
0059         }
0060         if (d) {
0061             d->deref();
0062         }
0063         d = rhs.d;
0064     }
0065     return *this;
0066 }
0067 
0068 bool KComponentData::operator==(const KComponentData &rhs) const
0069 {
0070     return d == rhs.d;
0071 }
0072 
0073 bool KComponentData::operator!=(const KComponentData &rhs) const
0074 {
0075     return !operator==(rhs);
0076 }
0077 
0078 enum KdeLibraryPathsAdded {
0079     NeedLazyInit,
0080     LazyInitDone,
0081     KdeLibraryPathsAddedDone
0082 };
0083 static KdeLibraryPathsAdded kdeLibraryPathsAdded = NeedLazyInit;
0084 
0085 class KComponentDataStatic
0086 {
0087 public:
0088     KComponentData mainComponent; // holds a refcount
0089     KComponentData activeComponent;
0090 
0091     void newComponentData(const KComponentData &c)
0092     {
0093         if (mainComponent.isValid()) {
0094             return;
0095         }
0096         mainComponent = c;
0097         KAboutData::setApplicationData(KAboutData(*c.aboutData()));
0098         KConfig::setMainConfigName(c.aboutData()->appName() + QLatin1String("rc"));
0099 #if 0 // no longer available in KF5
0100         KLocale::setMainCatalog(c.catalogName());
0101 #endif
0102         KComponentData::setActiveComponent(c);
0103     }
0104 };
0105 
0106 /**
0107  * This component may be used in applications that doesn't have a
0108  * main component (such as pure Qt applications).
0109  */
0110 static KComponentData initFakeComponent()
0111 {
0112     QString name = QCoreApplication::applicationName();
0113     if (name.isEmpty() && QCoreApplication::instance()) {
0114         name = qAppName();
0115     }
0116     if (name.isEmpty()) {
0117         name = QString::fromLatin1("kde");
0118     }
0119     return KComponentData(name.toLatin1(), name.toLatin1(),
0120                           KComponentData::SkipMainComponentRegistration);
0121 }
0122 
0123 Q_GLOBAL_STATIC(KComponentDataStatic, globalStatic)
0124 Q_GLOBAL_STATIC_WITH_ARGS(KComponentData, fakeComponent, (initFakeComponent()))
0125 
0126 KComponentData::KComponentData(const QByteArray &name, const QByteArray &catalog, MainComponentRegistration registerAsMain)
0127     : d(new KComponentDataPrivate(K4AboutData(name, catalog, KLocalizedString(), QByteArray())))
0128 {
0129     Q_ASSERT(!name.isEmpty());
0130 
0131     if (kdeLibraryPathsAdded == NeedLazyInit) {
0132         kdeLibraryPathsAdded = LazyInitDone;
0133         d->lazyInit();
0134     }
0135 
0136     if (registerAsMain == RegisterAsMainComponent) {
0137         globalStatic()->newComponentData(*this);
0138     }
0139 }
0140 
0141 KComponentData::KComponentData(const K4AboutData *aboutData, MainComponentRegistration registerAsMain)
0142     : d(new KComponentDataPrivate(*aboutData))
0143 {
0144     Q_ASSERT(!aboutData->appName().isEmpty());
0145 
0146     if (kdeLibraryPathsAdded == NeedLazyInit) {
0147         kdeLibraryPathsAdded = LazyInitDone;
0148         d->lazyInit();
0149     }
0150 
0151     if (registerAsMain == RegisterAsMainComponent) {
0152         globalStatic()->newComponentData(*this);
0153     }
0154 }
0155 
0156 KComponentData::KComponentData(const K4AboutData &aboutData, MainComponentRegistration registerAsMain)
0157     : d(new KComponentDataPrivate(aboutData))
0158 {
0159     Q_ASSERT(!aboutData.appName().isEmpty());
0160 
0161     if (kdeLibraryPathsAdded == NeedLazyInit) {
0162         kdeLibraryPathsAdded = LazyInitDone;
0163         d->lazyInit();
0164     }
0165 
0166     if (registerAsMain == RegisterAsMainComponent) {
0167         globalStatic()->newComponentData(*this);
0168     }
0169 }
0170 
0171 KComponentData::~KComponentData()
0172 {
0173     if (d) {
0174         d->deref();
0175         d = nullptr;
0176     }
0177 }
0178 
0179 bool KComponentData::isValid() const
0180 {
0181     return (d != nullptr);
0182 }
0183 
0184 void KComponentDataPrivate::lazyInit()
0185 {
0186     if (!sharedConfig) {
0187         configInit();
0188     }
0189 
0190 #if 0 // obsolete in KF5
0191 #ifdef Q_OS_WIN
0192     if (QCoreApplication::instance() && kdeLibraryPathsAdded != KdeLibraryPathsAddedDone) {
0193 #else
0194     // the first KComponentData sets the KDE Qt plugin paths
0195     if (kdeLibraryPathsAdded != KdeLibraryPathsAddedDone) {
0196 #endif
0197         kdeLibraryPathsAdded = KdeLibraryPathsAddedDone;
0198         const QStringList &plugins = dirs->resourceDirs("qtplugins");
0199         QStringList::ConstIterator it = plugins.begin();
0200         while (it != plugins.end()) {
0201             QCoreApplication::addLibraryPath(*it);
0202             ++it;
0203         }
0204     }
0205 #endif
0206 }
0207 
0208 extern KCONFIGCORE_EXPORT bool kde_kiosk_exception;
0209 bool kde_kiosk_admin = false;
0210 
0211 void KComponentDataPrivate::configInit()
0212 {
0213     Q_ASSERT(!sharedConfig);
0214 
0215     if (!configName.isEmpty()) {
0216         sharedConfig = KSharedConfig::openConfig(configName);
0217 
0218         //FIXME: this is broken and I don't know how to repair it
0219         // Check whether custom config files are allowed.
0220         KConfigGroup cg(sharedConfig, "KDE Action Restrictions");
0221         QString kioskException = cg.readEntry("kiosk_exception");
0222         if (!cg.readEntry("custom_config", true)) {
0223             sharedConfig = nullptr;
0224         }
0225     }
0226 
0227     if (!sharedConfig) {
0228         // was: KSharedConfig::openConfig(component)
0229         sharedConfig = KSharedConfig::openConfig(aboutData.appName() + QLatin1String("rc"));
0230     }
0231 
0232     // Check if we are excempt from kiosk restrictions
0233     if (kde_kiosk_admin && !kde_kiosk_exception && !qgetenv("KDE_KIOSK_NO_RESTRICTIONS").isEmpty()) {
0234         kde_kiosk_exception = true;
0235         sharedConfig = nullptr;
0236         configInit(); // Reread...
0237     }
0238 }
0239 
0240 const KSharedConfig::Ptr &KComponentData::config() const
0241 {
0242     Q_ASSERT(d);
0243     d->lazyInit();
0244 
0245     return d->sharedConfig;
0246 }
0247 
0248 void KComponentData::setConfigName(const QString &configName)
0249 {
0250     Q_ASSERT(d);
0251     d->configName = configName;
0252 }
0253 
0254 const K4AboutData *KComponentData::aboutData() const
0255 {
0256     Q_ASSERT(d);
0257     return &d->aboutData;
0258 }
0259 
0260 void KComponentData::setAboutData(const K4AboutData &aboutData)
0261 {
0262     d->aboutData = aboutData;
0263 }
0264 
0265 QString KComponentData::componentName() const
0266 {
0267     Q_ASSERT(d);
0268     return d->aboutData.appName();
0269 }
0270 
0271 QString KComponentData::catalogName() const
0272 {
0273     Q_ASSERT(d);
0274     return d->aboutData.catalogName();
0275 }
0276 
0277 bool KComponentData::hasMainComponent()
0278 {
0279     KComponentDataStatic *s = globalStatic();
0280     return s && s->mainComponent.isValid();
0281 }
0282 
0283 const KComponentData &KComponentData::mainComponent()
0284 {
0285     KComponentDataStatic *s = globalStatic();
0286     return s && s->mainComponent.isValid() ? s->mainComponent : *fakeComponent();
0287 }
0288 
0289 const KComponentData &KComponentData::activeComponent()
0290 {
0291     MYASSERT(globalStatic()->activeComponent.isValid());
0292     return globalStatic()->activeComponent;
0293 }
0294 
0295 void KComponentData::setActiveComponent(const KComponentData &c)
0296 {
0297     globalStatic()->activeComponent = c;
0298 #if 0 // no longer available in KF5
0299     if (c.isValid()) {
0300         KLocale::global()->setActiveCatalog(c.catalogName());
0301     }
0302 #endif
0303 }
0304 
0305 KComponentData::operator KAboutData() const
0306 {
0307     return KAboutData(*aboutData());
0308 }
0309 
0310 void KComponentData::virtual_hook(int, void *)
0311 {
0312     /*BASE::virtual_hook(id, data);*/
0313 }
0314