File indexing completed on 2024-04-21 14:55:34

0001 /* This file is part of the KDE libraries
0002    Copyright (C) 1999 Sirtaj Singh Kanq <taj@kde.org>
0003    Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
0004    Copyright (C) 2009 Olivier Goffart <ogoffart@kde.org>
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 /*
0022  * kglobal.cpp -- Implementation of namespace KGlobal.
0023  * Author:  Sirtaj Singh Kang
0024  * Generated:   Sat May  1 02:08:43 EST 1999
0025  */
0026 
0027 #undef KDE3_SUPPORT
0028 
0029 #include "kglobal.h"
0030 #include <QThread>
0031 
0032 #include <config-kdelibs4support.h>
0033 
0034 #if HAVE_SYS_STAT_H
0035 #include <sys/stat.h>
0036 #endif
0037 
0038 #include <QList>
0039 #include <QSet>
0040 
0041 #include <k4aboutdata.h>
0042 #include <kconfig.h>
0043 #include <klocalizedstring.h>
0044 #include <kcharsets.h>
0045 #include "kstandarddirs.h"
0046 #include <kcomponentdata.h>
0047 #undef QT_NO_TRANSLATION
0048 #include <QCoreApplication>
0049 #define QT_NO_TRANSLATION
0050 #include <QTextCodec>
0051 #include <unistd.h> // umask
0052 
0053 // ~KConfig needs qrand(). qrand() depends on a Q_GLOBAL_STATIC. With this Q_CONSTRUCTOR_FUNCTION we
0054 // try to make qrand() live longer than any KConfig object.
0055 Q_CONSTRUCTOR_FUNCTION(qrand)
0056 
0057 typedef QSet<QString> KStringDict;
0058 mode_t s_umsk;
0059 
0060 class KGlobalPrivate
0061 {
0062 public:
0063     inline KGlobalPrivate()
0064         : dirs(nullptr),
0065           stringDict(nullptr)
0066     {
0067         // the umask is read here before any threads are created to avoid race conditions
0068         mode_t tmp = 0;
0069         s_umsk = umask(tmp);
0070         umask(s_umsk);
0071     }
0072 
0073     inline ~KGlobalPrivate()
0074     {
0075         delete dirs;
0076         dirs = nullptr;
0077         delete stringDict;
0078         stringDict = nullptr;
0079     }
0080 
0081     KStandardDirs *dirs;
0082     KStringDict *stringDict;
0083 };
0084 
0085 K_GLOBAL_STATIC(KGlobalPrivate, globalData)
0086 
0087 #define PRIVATE_DATA KGlobalPrivate *d = globalData
0088 
0089 KStandardDirs *KGlobal::dirs()
0090 {
0091     PRIVATE_DATA;
0092     if (!d->dirs) {
0093         d->dirs = new KStandardDirs;
0094         KSharedConfig::Ptr config = KSharedConfig::openConfig();
0095         if (d->dirs->addCustomized(config.data())) {
0096             config->reparseConfiguration();
0097         }
0098     }
0099     return d->dirs;
0100 }
0101 
0102 KSharedConfig::Ptr KGlobal::config()
0103 {
0104     return KComponentData::mainComponent().config();
0105 }
0106 
0107 const KComponentData &KGlobal::mainComponent()
0108 {
0109     return KComponentData::mainComponent();
0110 }
0111 
0112 bool KGlobal::hasMainComponent()
0113 {
0114     return KComponentData::hasMainComponent();
0115 }
0116 
0117 KGlobal::LocaleWrapper KGlobal::locale()
0118 {
0119     return KGlobal::LocaleWrapper(KLocale::global());
0120 }
0121 
0122 bool KGlobal::hasLocale()
0123 {
0124     return QCoreApplication::instance() != nullptr;
0125 }
0126 
0127 KCharsets *KGlobal::charsets()
0128 {
0129     return KCharsets::charsets();
0130 }
0131 
0132 mode_t KGlobal::umask()
0133 {
0134     // Don't use PRIVATE_DATA here. This is called by ~KGlobalPrivate -> ~KConfig -> sync -> KSaveFile, so there's no KGlobalPrivate anymore.
0135     return s_umsk;
0136 }
0137 
0138 KComponentData KGlobal::activeComponent()
0139 {
0140     return KComponentData::activeComponent();
0141 }
0142 
0143 void KGlobal::setActiveComponent(const KComponentData &c)
0144 {
0145     KComponentData::setActiveComponent(c);
0146 }
0147 
0148 /**
0149  * Create a static QString
0150  *
0151  * To be used inside functions(!) like:
0152  * static const QString &myString = KGlobal::staticQString("myText");
0153  */
0154 const QString &KGlobal::staticQString(const char *str)
0155 {
0156     return staticQString(QLatin1String(str));
0157 }
0158 
0159 /**
0160  * Create a static QString
0161  *
0162  * To be used inside functions(!) like:
0163  * static const QString &myString = KGlobal::staticQString(i18n("My Text"));
0164  */
0165 const QString &KGlobal::staticQString(const QString &str)
0166 {
0167     PRIVATE_DATA;
0168     if (!d->stringDict) {
0169         d->stringDict = new KStringDict;
0170     }
0171 
0172     return *d->stringDict->insert(str);
0173 }
0174 
0175 QString KGlobal::caption()
0176 {
0177 #if 0 // Should move to Qt if wanted
0178     // Caption set from command line ?
0179     KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
0180     if (args && args->isSet("caption")) {
0181         return args->getOption("caption");
0182     } else
0183 #endif
0184     {
0185         // We have some about data ?
0186         const KComponentData &cData = KComponentData::mainComponent();
0187         if (cData.isValid() && cData.aboutData()) {
0188             return cData.aboutData()->programName();
0189         } else {
0190             // Last resort : application name
0191             return QCoreApplication::instance()->applicationName();
0192         }
0193     }
0194 }
0195 
0196 /**
0197  * This counter indicates when to quit the application.
0198  * It starts at 0, is incremented by KMainWindow, systray icons, running jobs, etc.
0199  * and decremented again when those things are destroyed.
0200  * This mechanism allows dialogs and jobs to outlive the last window closed
0201  * e.g. a file copy for a file manager, or 'compacting folders on exit' for a mail client,
0202  * the job progress widget with "keep open" checked, etc.
0203  */
0204 static int s_refCount = 0;
0205 static bool s_allowQuit = false;
0206 
0207 void KGlobal::ref()
0208 {
0209     ++s_refCount;
0210     //kDebug() << "KGlobal::ref() : refCount = " << s_refCount;
0211 }
0212 
0213 void KGlobal::deref()
0214 {
0215     --s_refCount;
0216     //kDebug() << "KGlobal::deref() : refCount = " << s_refCount;
0217     if (s_refCount <= 0 && s_allowQuit) {
0218         QCoreApplication::instance()->quit();
0219     }
0220 }
0221 
0222 void KGlobal::setAllowQuit(bool allowQuit)
0223 {
0224     s_allowQuit = allowQuit;
0225 }
0226 
0227 #undef PRIVATE_DATA
0228 
0229 QObject *KGlobal::findDirectChild_helper(const QObject *parent, const QMetaObject &mo)
0230 {
0231     if (!parent) {
0232         return nullptr;
0233     }
0234 
0235     const QObjectList &children = parent->children();
0236     for (int i = 0; i < children.size(); ++i) {
0237         QObject *obj = children.at(i);
0238         if (mo.cast(obj)) {
0239             return obj;
0240         }
0241     }
0242     return nullptr;
0243 
0244 }