File indexing completed on 2023-10-03 03:16:24
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 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License version 2 as published by the Free Software Foundation. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 #ifndef _KGLOBAL_H 0020 #define _KGLOBAL_H 0021 0022 #include <kdelibs4support_export.h> 0023 0024 #ifdef KDELIBS4SUPPORT_NO_DEPRECATED_NOISE 0025 #warning "This file is deprecated." 0026 #endif 0027 0028 /** @file */ // Trigger doxygen coverage of global objects in the file, like macros 0029 0030 #include <QAtomicPointer> 0031 #include <sys/types.h> 0032 #include <QDebug> 0033 // To simplify Qt5 porting in KDE code not yet ported to frameworks. 0034 #include <QMimeData> 0035 #include <klocale.h> 0036 0037 // TODO: Re-add for source compat: #include <kdemacros.h> 0038 0039 // 0040 // WARNING!! 0041 // This code uses undocumented Qt API 0042 // Do not copy it to your application! Use only the functions that are here! 0043 // Otherwise, it could break when a new version of Qt ships. 0044 // 0045 0046 class KComponentData; 0047 class KCharsets; 0048 class KConfig; 0049 class KStandardDirs; 0050 class KSharedConfig; 0051 template <typename T> 0052 class QExplicitlySharedDataPointer; 0053 typedef QExplicitlySharedDataPointer<KSharedConfig> KSharedConfigPtr; 0054 0055 /// @cond InternalDocs 0056 0057 /** 0058 * @internal 0059 */ 0060 typedef void (*KdeCleanUpFunction)(); 0061 0062 /** 0063 * @internal 0064 * 0065 * Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application 0066 * shutdown. 0067 */ 0068 class KCleanUpGlobalStatic 0069 { 0070 public: 0071 KdeCleanUpFunction func; 0072 0073 inline ~KCleanUpGlobalStatic() 0074 { 0075 func(); 0076 } 0077 }; 0078 0079 #ifdef Q_CC_MSVC 0080 /** 0081 * @internal 0082 * 0083 * MSVC seems to give anonymous structs the same name which fails at link time. So instead we name 0084 * the struct and hope that by adding the line number to the name it's unique enough to never clash. 0085 */ 0086 # define K_GLOBAL_STATIC_STRUCT_NAME(NAME) _k_##NAME##__LINE__ 0087 #else 0088 /** 0089 * @internal 0090 * 0091 * Make the struct of the K_GLOBAL_STATIC anonymous. 0092 */ 0093 # define K_GLOBAL_STATIC_STRUCT_NAME(NAME) 0094 #endif 0095 0096 /// @endcond 0097 0098 /** 0099 * This macro makes it easy to use non-POD types as global statics. 0100 * The object is created on first use and creation is threadsafe. 0101 * 0102 * The object is destructed on library unload or application exit. 0103 * Be careful with calling other objects in the destructor of the class 0104 * as you have to be sure that they (or objects they depend on) are not already destructed. 0105 * 0106 * @param TYPE The type of the global static object. Do not add a *. 0107 * @param NAME The name of the function to get a pointer to the global static object. 0108 * 0109 * If you have code that might be called after the global object has been destroyed you can check 0110 * for that using the isDestroyed() function. 0111 * 0112 * If needed (If the destructor of the global object calls other functions that depend on other 0113 * global statics (e.g. KConfig::sync) your destructor has to be called before those global statics 0114 * are destroyed. A Qt post routine does that.) you can also install a post routine (qAddPostRoutine) to clean up the object 0115 * using the destroy() method. If you registered a post routine and the object is destroyed because 0116 * of a lib unload you have to call qRemovePostRoutine! 0117 * 0118 * Example: 0119 * @code 0120 * class A { 0121 * public: 0122 * ~A(); 0123 * ... 0124 * }; 0125 * 0126 * K_GLOBAL_STATIC(A, globalA) 0127 * // The above creates a new globally static variable named 'globalA' which you 0128 * // can use as a pointer to an instance of A. 0129 * 0130 * void doSomething() 0131 * { 0132 * // The first time you access globalA a new instance of A will be created automatically. 0133 * A *a = globalA; 0134 * ... 0135 * } 0136 * 0137 * void doSomethingElse() 0138 * { 0139 * if (globalA.isDestroyed()) { 0140 * return; 0141 * } 0142 * A *a = globalA; 0143 * ... 0144 * } 0145 * 0146 * void installPostRoutine() 0147 * { 0148 * // A post routine can be used to delete the object when QCoreApplication destructs, 0149 * // not adding such a post routine will delete the object normally at program unload 0150 * qAddPostRoutine(globalA.destroy); 0151 * } 0152 * 0153 * A::~A() 0154 * { 0155 * // When you install a post routine you have to remove the post routine from the destructor of 0156 * // the class used as global static! 0157 * qRemovePostRoutine(globalA.destroy); 0158 * } 0159 * @endcode 0160 * 0161 * A common case for the need of deletion on lib unload/app shutdown are Singleton classes. Here's 0162 * an example how to do it: 0163 * @code 0164 * class MySingletonPrivate; 0165 * class EXPORT_MACRO MySingleton 0166 * { 0167 * friend class MySingletonPrivate; 0168 * public: 0169 * static MySingleton *self(); 0170 * QString someFunction(); 0171 * 0172 * private: 0173 * MySingleton(); 0174 * ~MySingleton(); 0175 * }; 0176 * @endcode 0177 * in the .cpp file: 0178 * @code 0179 * // This class will be instantiated and referenced as a singleton in this example 0180 * class MySingletonPrivate 0181 * { 0182 * public: 0183 * QString foo; 0184 * MySingleton instance; 0185 * }; 0186 * 0187 * K_GLOBAL_STATIC(MySingletonPrivate, mySingletonPrivate) 0188 * 0189 * MySingleton *MySingleton::self() 0190 * { 0191 * // returns the singleton; automatically creates a new instance if that has not happened yet. 0192 * return &mySingletonPrivate->instance; 0193 * } 0194 * QString MySingleton::someFunction() 0195 * { 0196 * // Refencing the singleton directly is possible for your convenience 0197 * return mySingletonPrivate->foo; 0198 * } 0199 * @endcode 0200 * 0201 * Instead of the above you can use also the following pattern (ignore the name of the namespace): 0202 * @code 0203 * namespace MySingleton 0204 * { 0205 * EXPORT_MACRO QString someFunction(); 0206 * } 0207 * @endcode 0208 * in the .cpp file: 0209 * @code 0210 * class MySingletonPrivate 0211 * { 0212 * public: 0213 * QString foo; 0214 * }; 0215 * 0216 * K_GLOBAL_STATIC(MySingletonPrivate, mySingletonPrivate) 0217 * 0218 * QString MySingleton::someFunction() 0219 * { 0220 * return mySingletonPrivate->foo; 0221 * } 0222 * @endcode 0223 * 0224 * Now code that wants to call someFunction() doesn't have to do 0225 * @code 0226 * MySingleton::self()->someFunction(); 0227 * @endcode 0228 * anymore but instead: 0229 * @code 0230 * MySingleton::someFunction(); 0231 * @endcode 0232 * 0233 * @ingroup KDEMacros 0234 */ 0235 #define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ()) 0236 0237 /** 0238 * @overload 0239 * This is the same as K_GLOBAL_STATIC, but can take arguments that are passed 0240 * to the object's constructor 0241 * 0242 * @param TYPE The type of the global static object. Do not add a *. 0243 * @param NAME The name of the function to get a pointer to the global static object. 0244 * @param ARGS the list of arguments, between brackets 0245 * 0246 * Example: 0247 * @code 0248 * class A 0249 * { 0250 * public: 0251 * A(const char *s, int i); 0252 * ... 0253 * }; 0254 * 0255 * K_GLOBAL_STATIC_WITH_ARGS(A, globalA, ("foo", 0)) 0256 * // The above creates a new globally static variable named 'globalA' which you 0257 * // can use as a pointer to an instance of A. 0258 * 0259 * void doSomething() 0260 * { 0261 * // The first time you access globalA a new instance of A will be created automatically. 0262 * A *a = globalA; 0263 * ... 0264 * } 0265 * @endcode 0266 * 0267 * @ingroup KDEMacros 0268 */ 0269 0270 // In Qt5 QBasicAtomicPointer<T> no longer implicit casts to T* 0271 // Instead it has load() and store() methods which do not exist in Qt4. 0272 // In practice, we should be porting frameworks to the new Q_GLOBAL_STATIC 0273 // which isn't in Qt5 yet, so duplicate for now. 0274 0275 #define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ 0276 static QBasicAtomicPointer<TYPE > _k_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(nullptr); \ 0277 static bool _k_static_##NAME##_destroyed; \ 0278 static struct K_GLOBAL_STATIC_STRUCT_NAME(NAME) \ 0279 { \ 0280 inline bool isDestroyed() const \ 0281 { \ 0282 return _k_static_##NAME##_destroyed; \ 0283 } \ 0284 inline bool exists() const \ 0285 { \ 0286 return _k_static_##NAME.load() != nullptr; \ 0287 } \ 0288 inline operator TYPE*() \ 0289 { \ 0290 return operator->(); \ 0291 } \ 0292 inline TYPE *operator->() \ 0293 { \ 0294 if (!_k_static_##NAME.load()) { \ 0295 if (isDestroyed()) { \ 0296 qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \ 0297 "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__); \ 0298 } \ 0299 TYPE *x = new TYPE ARGS; \ 0300 if (!_k_static_##NAME.testAndSetOrdered(nullptr, x) \ 0301 && _k_static_##NAME.load() != x ) { \ 0302 delete x; \ 0303 } else { \ 0304 static KCleanUpGlobalStatic cleanUpObject = { destroy }; \ 0305 } \ 0306 } \ 0307 return _k_static_##NAME.load(); \ 0308 } \ 0309 inline TYPE &operator*() \ 0310 { \ 0311 return *operator->(); \ 0312 } \ 0313 static void destroy() \ 0314 { \ 0315 _k_static_##NAME##_destroyed = true; \ 0316 TYPE *x = _k_static_##NAME.load(); \ 0317 _k_static_##NAME.store(nullptr); \ 0318 delete x; \ 0319 } \ 0320 } NAME; 0321 0322 /** 0323 * Access to the KDE global objects. 0324 * KGlobal provides you with pointers of many central 0325 * objects that exist only once in the process. It is also 0326 * responsible for managing instances of KStaticDeleterBase. 0327 * 0328 * @see KStaticDeleterBase 0329 * @author Sirtaj Singh Kang (taj@kde.org) 0330 */ 0331 namespace KGlobal 0332 { 0333 0334 struct KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE LocaleWrapper : public KLocale { 0335 KDELIBS4SUPPORT_DEPRECATED explicit LocaleWrapper(KLocale *locale) 0336 : KLocale(*locale) 0337 { 0338 0339 } 0340 0341 KDELIBS4SUPPORT_DEPRECATED static void insertCatalog(const QString &) 0342 { 0343 qWarning() << "Your code needs to be ported in KF5. See the Ki18n programmers guide."; 0344 } 0345 0346 LocaleWrapper *operator->() 0347 { 0348 return this; 0349 } 0350 0351 operator KLocale *() 0352 { 0353 return this; 0354 } 0355 }; 0356 0357 /** 0358 * Returns the global component data. There is always at least 0359 * one instance of a component in one application (in most 0360 * cases the application itself). 0361 * @return the global component data 0362 * @deprecated since 5.0 use KComponentData::mainComponent() if you really need a KComponentData 0363 */ 0364 KDELIBS4SUPPORT_DEPRECATED_EXPORT const KComponentData &mainComponent(); //krazy:exclude=constref (don't mess up ref-counting) 0365 0366 /** 0367 * @internal 0368 * Returns whether a main KComponentData is available. 0369 * @deprecated since 5.0, use KComponentData::hasMainComponent() if you really need a KComponentData 0370 */ 0371 KDELIBS4SUPPORT_DEPRECATED_EXPORT bool hasMainComponent(); 0372 0373 /** 0374 * Returns the application standard dirs object. 0375 * @return the global standard dir object 0376 */ 0377 KDELIBS4SUPPORT_DEPRECATED_EXPORT KStandardDirs *dirs(); 0378 0379 /** 0380 * Returns the general config object. 0381 * @return the global configuration object. 0382 * @deprecated since 5.0, use KSharedConfig::openConfig() 0383 */ 0384 KDELIBS4SUPPORT_DEPRECATED_EXPORT KSharedConfigPtr config(); 0385 0386 /** 0387 * Returns the global locale object. 0388 * @return the global locale object 0389 * 0390 * Note: in multi-threaded programs, you should call KLocale::global() 0391 * in the main thread (e.g. in main(), after creating the QCoreApplication 0392 * and setting the main component), to ensure that the initialization is 0393 * done in the main thread. However KApplication takes care of this, so this 0394 * is only needed when not using KApplication. 0395 * 0396 * @deprecated since 5.0, use KLocale::global() 0397 */ 0398 KDELIBS4SUPPORT_DEPRECATED_EXPORT LocaleWrapper locale(); 0399 /** 0400 * @internal 0401 * Returns whether KGlobal has a valid KLocale object 0402 * @deprecated since 5.0, port to if (qApp) because KLocale::global() can be called, as soon as a qApp exists. 0403 */ 0404 KDELIBS4SUPPORT_DEPRECATED_EXPORT bool hasLocale(); 0405 0406 /** 0407 * The global charset manager. 0408 * @return the global charset manager 0409 * @deprecated since 5.0, use KCharsets::charsets() 0410 */ 0411 KDELIBS4SUPPORT_DEPRECATED_EXPORT KCharsets *charsets(); 0412 0413 /** 0414 * Returns the umask of the process. 0415 * @return the umask of the process 0416 */ 0417 KDELIBS4SUPPORT_DEPRECATED_EXPORT mode_t umask(); 0418 0419 /** 0420 * Creates a static QString. 0421 * 0422 * To be used inside functions(!) like: 0423 * @code 0424 * static const QString &myString = KGlobal::staticQString("myText"); 0425 * @endcode 0426 * 0427 * @attention Do @b NOT use code such as: 0428 * @code 0429 * static QString myString = KGlobal::staticQString("myText"); 0430 * @endcode 0431 * This creates a static object (instead of a static reference) 0432 * and as you know static objects are EVIL. 0433 * @param str the string to create 0434 * @return the static string 0435 * @deprecated since 5.0, use QLatin1String() or QStringLiteral() 0436 */ 0437 KDELIBS4SUPPORT_DEPRECATED_EXPORT const QString &staticQString(const char *str); //krazy:exclude=constref (doesn't make sense otherwise) 0438 0439 /** 0440 * Creates a static QString. 0441 * 0442 * To be used inside functions(!) like: 0443 * @code 0444 * static const QString &myString = KGlobal::staticQString(i18n("My Text")); 0445 * @endcode 0446 * 0447 * @attention Do @b NOT use code such as: 0448 * @code 0449 * static QString myString = KGlobal::staticQString(i18n("myText")); 0450 * @endcode 0451 * This creates a static object (instead of a static reference) 0452 * and as you know static objects are EVIL. 0453 * @param str the string to create 0454 * @return the static string 0455 * @deprecated since 5.0 don't make the string static 0456 */ 0457 KDELIBS4SUPPORT_DEPRECATED_EXPORT const QString &staticQString(const QString &str); //krazy:exclude=constref (doesn't make sense otherwise) 0458 0459 /** 0460 * Tells KGlobal about one more operations that should be finished 0461 * before the application exits. The standard behavior is to exit on the 0462 * "last window closed" event, but some events should outlive the last window closed 0463 * (e.g. a file copy for a file manager, or 'compacting folders on exit' for a mail client), 0464 * or simply any application with a system tray icon. 0465 * 0466 * We have some use cases that we want to take care of (the format is "action refcount"): 0467 * - open window -> setAllowQuit(true) 1 ; close window 0 => EXIT 0468 * - job start 1; job end 0 [don't exit yet]; open window -> setAllowQuit(true) 1 ; close window 0 => EXIT 0469 * - job start 1; open window -> setAllowQuit(true) 2; close window 1; job end 0 => EXIT 0470 * - job start 1; open window -> setAllowQuit(true) 2; job end 1; close window 0 => EXIT 0471 * - open dialog 0; close dialog 0; => DO NOT EXIT 0472 * - job start 1; job end 0; create two main objects 2; delete both main objects 0 => EXIT 0473 * - open window -> setAllowQuit(true) 1; add systray icon 2; close window 1 => DO NOT EXIT 0474 * - open window -> setAllowQuit(true) 1; add systray icon 2; remove systray icon 1; close window 0 => EXIT 0475 * - unit test which opens and closes many windows: should call ref() to avoid subevent-loops quitting too early. 0476 * 0477 * Note that for this to happen you must call qApp->setQuitOnLastWindowClosed(false), 0478 * in main() for instance. 0479 * 0480 * @deprecated since 5.0, use QEventLoopLocker, its constructor does the equivalent of ref 0481 */ 0482 KDELIBS4SUPPORT_DEPRECATED_EXPORT void ref(); 0483 0484 /** 0485 * Tells KGlobal that one operation such as those described in ref() just finished. 0486 * This call makes the QApplication quit if the counter is back to 0. 0487 * 0488 * @deprecated since 5.0, use QEventLoopLocker, its destructor does the equivalent of unref 0489 */ 0490 KDELIBS4SUPPORT_DEPRECATED_EXPORT void deref(); 0491 0492 /** 0493 * If refcounting reaches 0 (or less), and @p allowQuit is true, the instance of the application 0494 * will automatically be exited. Otherwise, the application will not exit automatically. 0495 * 0496 * This is used by KMainWindow to allow quitting after the first mainwindow is created, 0497 * and is used by special applications like kfmclient, to allow quitting even though 0498 * no mainwindow was created. 0499 * 0500 * However, don't try to call setAllowQuit(false) in applications, it doesn't make sense. 0501 * If you find that the application quits too early when closing a window, then consider 0502 * _what_ is making your application still alive to the user (like a systray icon or a D-Bus object) 0503 * and use KGlobal::ref() + KGlobal::deref() in that object. 0504 * 0505 * @since 4.1.1 0506 * @deprecated since 5.0, not necessary anymore, with QCoreApplication and QEventLoopLocker 0507 */ 0508 KDELIBS4SUPPORT_DEPRECATED_EXPORT void setAllowQuit(bool allowQuit); 0509 0510 /** 0511 * The component currently active (useful in a multi-component 0512 * application, such as a KParts application). 0513 * Don't use this - it's mainly for KAboutDialog and KBugReport. 0514 * @internal 0515 * @deprecated since 5.0 see KComponentData::activeComponent() about 0516 * why you should do without this concept (or let your app remember the active 0517 * part/plugin if it cares) 0518 */ 0519 KDELIBS4SUPPORT_DEPRECATED_EXPORT KComponentData activeComponent(); 0520 0521 /** 0522 * Set the active component for use by KAboutDialog and KBugReport. 0523 * To be used only by a multi-component (KParts) application. 0524 * 0525 * @see activeComponent() 0526 * @deprecated since 5.0 see KComponentData::setActiveComponent about 0527 * why you can probably just remove the call. 0528 */ 0529 KDELIBS4SUPPORT_DEPRECATED_EXPORT void setActiveComponent(const KComponentData &d); 0530 0531 /** 0532 * Returns a text for the window caption. 0533 * 0534 * This may be set by 0535 * "-caption", otherwise it will be equivalent to the name of the 0536 * executable. 0537 * @return the text for the window caption 0538 * @deprecated since 5.0. Don't use in window titles anymore, Qt takes care of it. 0539 * If you really need this, use QGuiApplication::applicationDisplayName(), and if that's empty, QCoreApplication::applicationName(). 0540 */ 0541 KDELIBS4SUPPORT_DEPRECATED_EXPORT QString caption(); 0542 0543 /// @internal 0544 KDELIBS4SUPPORT_DEPRECATED_EXPORT QObject *findDirectChild_helper(const QObject *parent, const QMetaObject &mo); 0545 0546 /** 0547 * Returns the child of the given object that can be cast into type T, or 0 if there is no such object. 0548 * Unlike QObject::findChild, the search is NOT performed recursively. 0549 * @since 4.4 0550 * @deprecated since Qt 5, use QObject::findChild(FindDirectChildrenOnly) 0551 */ 0552 template<typename T> 0553 KDELIBS4SUPPORT_DEPRECATED inline T findDirectChild(const QObject *object) 0554 { 0555 return static_cast<T>(findDirectChild_helper(object, (static_cast<T>(nullptr))->staticMetaObject)); 0556 } 0557 } 0558 0559 struct KCatalogLoader { 0560 KDELIBS4SUPPORT_DEPRECATED KCatalogLoader(const QString &) 0561 { 0562 qWarning() << "Your code needs to be ported in KF5. See the Ki18n programmers guide."; 0563 } 0564 }; 0565 0566 #endif // _KGLOBAL_H 0567