KDECore
kglobal.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Sirtaj Singh Kanq <taj@kde.org> 00003 Copyright (C) 2007 Matthias Kretz <kretz@kde.org> 00004 Copyright (C) 2009 Olivier Goffart <ogoffart@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 /* 00022 * kglobal.cpp -- Implementation of namespace KGlobal. 00023 * Author: Sirtaj Singh Kang 00024 * Generated: Sat May 1 02:08:43 EST 1999 00025 */ 00026 00027 #undef KDE3_SUPPORT 00028 00029 #include "kglobal.h" 00030 #include "kglobal_p.h" 00031 #include <QThread> 00032 00033 #include <config.h> 00034 00035 #ifdef HAVE_SYS_STAT_H 00036 #include <sys/stat.h> 00037 #endif 00038 00039 #include <QtCore/QList> 00040 #include <QtCore/QSet> 00041 00042 #include <kaboutdata.h> 00043 #include <kconfig.h> 00044 #include <klocale.h> 00045 #include <kcharsets.h> 00046 #include <kstandarddirs.h> 00047 #include <kcomponentdata.h> 00048 #undef QT_NO_TRANSLATION 00049 #include <QtCore/QCoreApplication> 00050 #define QT_NO_TRANSLATION 00051 #include <QtCore/QDebug> 00052 #include <QtCore/QTextCodec> 00053 #include "kcmdlineargs.h" 00054 #include <unistd.h> // umask 00055 00056 #ifndef NDEBUG 00057 #define MYASSERT(x) if (!x) \ 00058 qFatal("Fatal error: you need to have a KComponentData object before\n" \ 00059 "you do anything that requires it! Examples of this are config\n" \ 00060 "objects, standard directories or translations."); 00061 #else 00062 #define MYASSERT(x) /* nope */ 00063 #endif 00064 00065 // ~KConfig needs qrand(). qrand() depends on a Q_GLOBAL_STATIC. With this Q_CONSTRUCTOR_FUNCTION we 00066 // try to make qrand() live longer than any KConfig object. 00067 Q_CONSTRUCTOR_FUNCTION(qrand) 00068 00069 typedef QSet<QString> KStringDict; 00070 mode_t s_umsk; 00071 00072 class KGlobalPrivate 00073 { 00074 public: 00075 inline KGlobalPrivate() 00076 : stringDict(0), 00077 locale(0), 00078 charsets(0), 00079 localeIsFromFakeComponent(false) 00080 { 00081 // the umask is read here before any threads are created to avoid race conditions 00082 mode_t tmp = 0; 00083 s_umsk = umask(tmp); 00084 umask(s_umsk); 00085 } 00086 00087 inline ~KGlobalPrivate() 00088 { 00089 delete locale; 00090 locale = 0; 00091 delete charsets; 00092 charsets = 0; 00093 delete stringDict; 00094 stringDict = 0; 00095 } 00096 00097 KComponentData activeComponent; 00098 KComponentData mainComponent; // holds a refcount 00099 KStringDict *stringDict; 00100 KLocale *locale; 00101 KCharsets *charsets; 00102 bool localeIsFromFakeComponent; 00103 QStringList catalogsToInsert; 00104 00109 static KComponentData initFakeComponent() 00110 { 00111 QString name = QCoreApplication::applicationName(); 00112 if(name.isEmpty() && QCoreApplication::instance()) 00113 name = qAppName(); 00114 if(name.isEmpty()) 00115 name = QString::fromLatin1("kde"); 00116 return KComponentData(name.toLatin1(), name.toLatin1(), 00117 KComponentData::SkipMainComponentRegistration); 00118 } 00119 }; 00120 00121 KCatalogLoader::KCatalogLoader(const QString &catalogName) 00122 { 00123 KGlobal::insertCatalog(catalogName); 00124 } 00125 00126 00127 K_GLOBAL_STATIC(KGlobalPrivate, globalData) 00128 K_GLOBAL_STATIC_WITH_ARGS(KComponentData, fakeComponent, (KGlobalPrivate::initFakeComponent())) 00129 00130 #define PRIVATE_DATA KGlobalPrivate *d = globalData 00131 00132 KStandardDirs *KGlobal::dirs() 00133 { 00134 PRIVATE_DATA; 00135 return d->mainComponent.isValid() ? d->mainComponent.dirs() : fakeComponent->dirs(); 00136 } 00137 00138 KSharedConfig::Ptr KGlobal::config() 00139 { 00140 PRIVATE_DATA; 00141 return d->mainComponent.isValid() ? d->mainComponent.config() : fakeComponent->config(); 00142 } 00143 00144 const KComponentData &KGlobal::mainComponent() 00145 { 00146 PRIVATE_DATA; 00147 return d->mainComponent.isValid() ? d->mainComponent : *fakeComponent; 00148 } 00149 00150 bool KGlobal::hasMainComponent() 00151 { 00152 if (globalData.isDestroyed()) { 00153 return false; 00154 } 00155 PRIVATE_DATA; 00156 return d->mainComponent.isValid(); 00157 } 00158 00159 void KGlobal::insertCatalog(const QString& catalog) 00160 { 00161 PRIVATE_DATA; 00162 if (d->locale) { 00163 d->locale->insertCatalog(catalog); 00164 } else { 00165 d->catalogsToInsert.append(catalog); 00166 } 00167 } 00168 00169 KLocale *KGlobal::locale() 00170 { 00171 PRIVATE_DATA; 00172 if (d->locale == 0 || (d->localeIsFromFakeComponent && d->mainComponent.isValid() && d->mainComponent.config())) { 00173 if (d->locale != 0) qDebug() << "KGlobal::locale::Warning your global KLocale is being recreated with a valid main component instead of a fake component, this usually means you tried to call i18n related functions before your main component was created. You should not do that since it most likely will not work"; 00174 delete d->locale; 00175 d->locale = 0; 00176 d->locale = new KLocale(mainComponent().catalogName()); 00177 d->localeIsFromFakeComponent = !d->mainComponent.isValid(); 00178 QTextCodec::setCodecForLocale(d->locale->codecForEncoding()); 00179 mainComponent().aboutData()->translateInternalProgramName(); 00180 QCoreApplication* coreApp = QCoreApplication::instance(); 00181 if (coreApp) { // testcase: kwrite --help: no qcore app 00182 if (coreApp->thread() != QThread::currentThread()) { 00183 qFatal("KGlobal::locale() must be called from the main thread before using i18n() in threads. KApplication takes care of this. If not using KApplication, call KGlobal::locale() during initialization."); 00184 } else { 00185 QCoreApplication::installTranslator(new KDETranslator(coreApp)); 00186 } 00187 } 00188 foreach(const QString &catalog, d->catalogsToInsert) 00189 d->locale->insertCatalog(catalog); 00190 d->catalogsToInsert.clear(); 00191 } 00192 return d->locale; 00193 } 00194 00195 bool KGlobal::hasLocale() 00196 { 00197 if (globalData.isDestroyed()) { 00198 return false; 00199 } 00200 PRIVATE_DATA; 00201 return (d->locale != 0); 00202 } 00203 00204 KCharsets *KGlobal::charsets() 00205 { 00206 PRIVATE_DATA; 00207 if (d->charsets == 0) { 00208 d->charsets = new KCharsets; 00209 } 00210 00211 return d->charsets; 00212 } 00213 00214 mode_t KGlobal::umask() 00215 { 00216 // Don't use PRIVATE_DATA here. This is called by ~KGlobalPrivate -> ~KConfig -> sync -> KSaveFile, so there's no KGlobalPrivate anymore. 00217 return s_umsk; 00218 } 00219 00220 KComponentData KGlobal::activeComponent() 00221 { 00222 PRIVATE_DATA; 00223 MYASSERT(d->activeComponent.isValid()); 00224 return d->activeComponent; 00225 } 00226 00227 void KGlobal::setActiveComponent(const KComponentData &c) 00228 { 00229 PRIVATE_DATA; 00230 d->activeComponent = c; 00231 if (c.isValid() && d->locale) { 00232 d->locale->setActiveCatalog(c.catalogName()); 00233 } 00234 } 00235 00236 void KGlobal::newComponentData(const KComponentData &c) 00237 { 00238 PRIVATE_DATA; 00239 if (d->mainComponent.isValid()) { 00240 return; 00241 } 00242 d->mainComponent = c; 00243 KGlobal::setActiveComponent(c); 00244 } 00245 00246 void KGlobal::setLocale(KLocale *locale, CopyCatalogs copy) 00247 { 00248 PRIVATE_DATA; 00249 if (copy == DoCopyCatalogs && d->locale) 00250 d->locale->copyCatalogsTo(locale); 00251 delete d->locale; 00252 d->locale = locale; 00253 } 00254 00261 const QString &KGlobal::staticQString(const char *str) 00262 { 00263 return staticQString(QLatin1String(str)); 00264 } 00265 00272 const QString &KGlobal::staticQString(const QString &str) 00273 { 00274 PRIVATE_DATA; 00275 if (!d->stringDict) { 00276 d->stringDict = new KStringDict; 00277 } 00278 00279 return *d->stringDict->insert(str); 00280 } 00281 00282 QString KGlobal::caption() 00283 { 00284 PRIVATE_DATA; 00285 // Caption set from command line ? 00286 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); 00287 if (args && args->isSet("caption")) { 00288 return args->getOption("caption"); 00289 } else { 00290 // We have some about data ? 00291 if (d->mainComponent.isValid() && d->mainComponent.aboutData()) { 00292 return d->mainComponent.aboutData()->programName(); 00293 } else { 00294 // Last resort : application name 00295 return QCoreApplication::instance()->applicationName(); 00296 } 00297 } 00298 } 00299 00308 static int s_refCount = 0; 00309 static bool s_allowQuit = false; 00310 00311 void KGlobal::ref() 00312 { 00313 ++s_refCount; 00314 //kDebug() << "KGlobal::ref() : refCount = " << s_refCount; 00315 } 00316 00317 void KGlobal::deref() 00318 { 00319 --s_refCount; 00320 //kDebug() << "KGlobal::deref() : refCount = " << s_refCount; 00321 if (s_refCount <= 0 && s_allowQuit) { 00322 QCoreApplication::instance()->quit(); 00323 } 00324 } 00325 00326 void KGlobal::setAllowQuit(bool allowQuit) 00327 { 00328 s_allowQuit = allowQuit; 00329 } 00330 00331 #undef PRIVATE_DATA 00332 00333 QObject* KGlobal::findDirectChild_helper(const QObject* parent, const QMetaObject& mo) 00334 { 00335 if (!parent) 00336 return 0; 00337 00338 const QObjectList &children = parent->children(); 00339 for (int i = 0; i < children.size(); ++i) { 00340 QObject* obj = children.at(i); 00341 if (mo.cast(obj)) { 00342 return obj; 00343 } 00344 } 00345 return 0; 00346 00347 }
KDE 4.6 API Reference