File indexing completed on 2024-04-14 14:20:01

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