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 00032 #include <config.h> 00033 00034 #ifdef HAVE_SYS_STAT_H 00035 #include <sys/stat.h> 00036 #endif 00037 00038 #include <QtCore/QList> 00039 #include <QtCore/QSet> 00040 00041 #include <kaboutdata.h> 00042 #include <kconfig.h> 00043 #include <klocale.h> 00044 #include <kcharsets.h> 00045 #include <kstandarddirs.h> 00046 #include <kcomponentdata.h> 00047 #undef QT_NO_TRANSLATION 00048 #include <QtCore/QCoreApplication> 00049 #define QT_NO_TRANSLATION 00050 #include <QtCore/QTextCodec> 00051 #include "kcmdlineargs.h" 00052 #include <unistd.h> // umask 00053 00054 #ifndef NDEBUG 00055 #define MYASSERT(x) if (!x) \ 00056 qFatal("Fatal error: you need to have a KComponentData object before\n" \ 00057 "you do anything that requires it! Examples of this are config\n" \ 00058 "objects, standard directories or translations."); 00059 #else 00060 #define MYASSERT(x) /* nope */ 00061 #endif 00062 00063 // ~KConfig needs qrand(). qrand() depends on a Q_GLOBAL_STATIC. With this Q_CONSTRUCTOR_FUNCTION we 00064 // try to make qrand() live longer than any KConfig object. 00065 Q_CONSTRUCTOR_FUNCTION(qrand) 00066 00067 typedef QSet<QString> KStringDict; 00068 mode_t s_umsk; 00069 00070 class KGlobalPrivate 00071 { 00072 public: 00073 inline KGlobalPrivate() 00074 : stringDict(0), 00075 locale(0), 00076 charsets(0) 00077 { 00078 // the umask is read here before any threads are created to avoid race conditions 00079 mode_t tmp = 0; 00080 s_umsk = umask(tmp); 00081 umask(s_umsk); 00082 } 00083 00084 inline ~KGlobalPrivate() 00085 { 00086 delete locale; 00087 locale = 0; 00088 delete charsets; 00089 charsets = 0; 00090 delete stringDict; 00091 stringDict = 0; 00092 } 00093 00094 KComponentData activeComponent; 00095 KComponentData mainComponent; // holds a refcount 00096 KStringDict *stringDict; 00097 KLocale *locale; 00098 KCharsets *charsets; 00099 00104 static KComponentData initFakeComponent() 00105 { 00106 QString name = QCoreApplication::applicationName(); 00107 if(name.isEmpty()) 00108 name = qAppName(); 00109 if(name.isEmpty()) 00110 name = QString::fromLatin1("kde"); 00111 return KComponentData(name.toLatin1(), name.toLatin1(), 00112 KComponentData::SkipMainComponentRegistration); 00113 } 00114 }; 00115 00116 K_GLOBAL_STATIC(KGlobalPrivate, globalData) 00117 K_GLOBAL_STATIC_WITH_ARGS(KComponentData, fakeComponent, (KGlobalPrivate::initFakeComponent())) 00118 00119 #define PRIVATE_DATA KGlobalPrivate *d = globalData 00120 00121 KStandardDirs *KGlobal::dirs() 00122 { 00123 PRIVATE_DATA; 00124 return d->mainComponent.isValid() ? d->mainComponent.dirs() : fakeComponent->dirs(); 00125 } 00126 00127 KSharedConfig::Ptr KGlobal::config() 00128 { 00129 PRIVATE_DATA; 00130 return d->mainComponent.isValid() ? d->mainComponent.config() : fakeComponent->config(); 00131 } 00132 00133 const KComponentData &KGlobal::mainComponent() 00134 { 00135 PRIVATE_DATA; 00136 return d->mainComponent.isValid() ? d->mainComponent : *fakeComponent; 00137 } 00138 00139 bool KGlobal::hasMainComponent() 00140 { 00141 if (globalData.isDestroyed()) { 00142 return false; 00143 } 00144 PRIVATE_DATA; 00145 return d->mainComponent.isValid(); 00146 } 00147 00148 KLocale *KGlobal::locale() 00149 { 00150 PRIVATE_DATA; 00151 if (d->locale == 0) { 00152 if (!d->mainComponent.isValid()) { 00153 return 0; 00154 } 00155 00156 d->locale = new KLocale(d->mainComponent.catalogName()); 00157 QTextCodec::setCodecForLocale(d->locale->codecForEncoding()); 00158 d->mainComponent.aboutData()->translateInternalProgramName(); 00159 QCoreApplication* coreApp = QCoreApplication::instance(); 00160 if (coreApp) // testcase: kwrite --help: no qcore app 00161 QCoreApplication::installTranslator(new KDETranslator(coreApp)); 00162 } 00163 return d->locale; 00164 } 00165 00166 bool KGlobal::hasLocale() 00167 { 00168 if (globalData.isDestroyed()) { 00169 return false; 00170 } 00171 PRIVATE_DATA; 00172 return (d->locale != 0); 00173 } 00174 00175 KCharsets *KGlobal::charsets() 00176 { 00177 PRIVATE_DATA; 00178 if (d->charsets == 0) { 00179 d->charsets = new KCharsets; 00180 } 00181 00182 return d->charsets; 00183 } 00184 00185 mode_t KGlobal::umask() 00186 { 00187 // Don't use PRIVATE_DATA here. This is called by ~KGlobalPrivate -> ~KConfig -> sync -> KSaveFile, so there's no KGlobalPrivate anymore. 00188 return s_umsk; 00189 } 00190 00191 KComponentData KGlobal::activeComponent() 00192 { 00193 PRIVATE_DATA; 00194 MYASSERT(d->activeComponent.isValid()); 00195 return d->activeComponent; 00196 } 00197 00198 void KGlobal::setActiveComponent(const KComponentData &c) 00199 { 00200 PRIVATE_DATA; 00201 d->activeComponent = c; 00202 if (c.isValid() && d->locale) { 00203 d->locale->setActiveCatalog(c.catalogName()); 00204 } 00205 } 00206 00207 void KGlobal::newComponentData(const KComponentData &c) 00208 { 00209 PRIVATE_DATA; 00210 if (d->mainComponent.isValid()) { 00211 return; 00212 } 00213 d->mainComponent = c; 00214 KGlobal::setActiveComponent(c); 00215 } 00216 00217 void KGlobal::setLocale(KLocale *locale, CopyCatalogs copy) 00218 { 00219 PRIVATE_DATA; 00220 if (copy == DoCopyCatalogs && d->locale) 00221 d->locale->copyCatalogsTo(locale); 00222 delete d->locale; 00223 d->locale = locale; 00224 } 00225 00232 const QString &KGlobal::staticQString(const char *str) 00233 { 00234 return staticQString(QLatin1String(str)); 00235 } 00236 00243 const QString &KGlobal::staticQString(const QString &str) 00244 { 00245 PRIVATE_DATA; 00246 if (!d->stringDict) { 00247 d->stringDict = new KStringDict; 00248 } 00249 00250 return *d->stringDict->insert(str); 00251 } 00252 00253 QString KGlobal::caption() 00254 { 00255 PRIVATE_DATA; 00256 // Caption set from command line ? 00257 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); 00258 if (args && args->isSet("caption")) { 00259 return args->getOption("caption"); 00260 } else { 00261 // We have some about data ? 00262 if (d->mainComponent.isValid() && d->mainComponent.aboutData()) { 00263 return d->mainComponent.aboutData()->programName(); 00264 } else { 00265 // Last resort : application name 00266 return QCoreApplication::instance()->applicationName(); 00267 } 00268 } 00269 } 00270 00279 static int s_refCount = 0; 00280 static bool s_allowQuit = false; 00281 00282 void KGlobal::ref() 00283 { 00284 ++s_refCount; 00285 //kDebug() << "KGlobal::ref() : refCount = " << s_refCount; 00286 } 00287 00288 void KGlobal::deref() 00289 { 00290 --s_refCount; 00291 //kDebug() << "KGlobal::deref() : refCount = " << s_refCount; 00292 if (s_refCount <= 0 && s_allowQuit) { 00293 QCoreApplication::instance()->quit(); 00294 } 00295 } 00296 00297 void KGlobal::setAllowQuit(bool allowQuit) 00298 { 00299 s_allowQuit = allowQuit; 00300 } 00301 00302 #undef PRIVATE_DATA