mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
477 lines
17 KiB
C++
477 lines
17 KiB
C++
/* This file is part of the KDE libraries
|
|
Copyright (C) 1999 Sirtaj Singh Kanq <taj@kde.org>
|
|
Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License version 2 as published by the Free Software Foundation.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
#ifndef KGLOBAL_H
|
|
#define KGLOBAL_H
|
|
|
|
#include <kdecore_export.h>
|
|
#include <QtCore/qobject.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
//
|
|
// WARNING!!
|
|
// This code uses undocumented Qt API
|
|
// Do not copy it to your application! Use only the functions that are here!
|
|
// Otherwise, it could break when a new version of Qt ships.
|
|
//
|
|
|
|
class KComponentData;
|
|
class KCharsets;
|
|
class KConfig;
|
|
class KLocale;
|
|
class KStandardDirs;
|
|
class KSharedConfig;
|
|
template <typename T>
|
|
class KSharedPtr;
|
|
typedef KSharedPtr<KSharedConfig> KSharedConfigPtr;
|
|
|
|
/// @cond InternalDocs
|
|
|
|
/**
|
|
* @internal
|
|
*/
|
|
typedef void (*KdeCleanUpFunction)();
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application
|
|
* shutdown.
|
|
*/
|
|
class KCleanUpGlobalStatic
|
|
{
|
|
public:
|
|
KdeCleanUpFunction func;
|
|
|
|
inline ~KCleanUpGlobalStatic() { func(); }
|
|
};
|
|
|
|
/// @endcond
|
|
|
|
/**
|
|
* This macro makes it easy to use non-POD types as global statics.
|
|
* The object is created on first use and creation is threadsafe.
|
|
*
|
|
* The object is destructed on library unload or application exit.
|
|
* Be careful with calling other objects in the destructor of the class
|
|
* as you have to be sure that they (or objects they depend on) are not already destructed.
|
|
*
|
|
* @param TYPE The type of the global static object. Do not add a *.
|
|
* @param NAME The name of the function to get a pointer to the global static object.
|
|
*
|
|
* If you have code that might be called after the global object has been destroyed you can check
|
|
* for that using the isDestroyed() function.
|
|
*
|
|
* If needed (If the destructor of the global object calls other functions that depend on other
|
|
* global statics (e.g. KConfig::sync) your destructor has to be called before those global statics
|
|
* are destroyed. A Qt post routine does that.) you can also install a post routine (qAddPostRoutine) to clean up the object
|
|
* using the destroy() method. If you registered a post routine and the object is destroyed because
|
|
* of a lib unload you have to call qRemovePostRoutine!
|
|
*
|
|
* Example:
|
|
* @code
|
|
* class A {
|
|
* public:
|
|
* ~A();
|
|
* ...
|
|
* };
|
|
*
|
|
* K_GLOBAL_STATIC(A, globalA)
|
|
* // The above creates a new globally static variable named 'globalA' which you
|
|
* // can use as a pointer to an instance of A.
|
|
*
|
|
* void doSomething()
|
|
* {
|
|
* // The first time you access globalA a new instance of A will be created automatically.
|
|
* A *a = globalA;
|
|
* ...
|
|
* }
|
|
*
|
|
* void doSomethingElse()
|
|
* {
|
|
* if (globalA.isDestroyed()) {
|
|
* return;
|
|
* }
|
|
* A *a = globalA;
|
|
* ...
|
|
* }
|
|
*
|
|
* void installPostRoutine()
|
|
* {
|
|
* // A post routine can be used to delete the object when QCoreApplication destructs,
|
|
* // not adding such a post routine will delete the object normally at program unload
|
|
* qAddPostRoutine(globalA.destroy);
|
|
* }
|
|
*
|
|
* A::~A()
|
|
* {
|
|
* // When you install a post routine you have to remove the post routine from the destructor of
|
|
* // the class used as global static!
|
|
* qRemovePostRoutine(globalA.destroy);
|
|
* }
|
|
* @endcode
|
|
*
|
|
* A common case for the need of deletion on lib unload/app shutdown are Singleton classes. Here's
|
|
* an example how to do it:
|
|
* @code
|
|
* class MySingletonPrivate;
|
|
* class EXPORT_MACRO MySingleton
|
|
* {
|
|
* friend class MySingletonPrivate;
|
|
* public:
|
|
* static MySingleton *self();
|
|
* QString someFunction();
|
|
*
|
|
* private:
|
|
* MySingleton();
|
|
* ~MySingleton();
|
|
* };
|
|
* @endcode
|
|
* in the .cpp file:
|
|
* @code
|
|
* // This class will be instantiated and referenced as a singleton in this example
|
|
* class MySingletonPrivate
|
|
* {
|
|
* public:
|
|
* QString foo;
|
|
* MySingleton instance;
|
|
* };
|
|
*
|
|
* K_GLOBAL_STATIC(MySingletonPrivate, mySingletonPrivate)
|
|
*
|
|
* MySingleton *MySingleton::self()
|
|
* {
|
|
* // returns the singleton; automatically creates a new instance if that has not happened yet.
|
|
* return &mySingletonPrivate->instance;
|
|
* }
|
|
* QString MySingleton::someFunction()
|
|
* {
|
|
* // Refencing the singleton directly is possible for your convenience
|
|
* return mySingletonPrivate->foo;
|
|
* }
|
|
* @endcode
|
|
*
|
|
* Instead of the above you can use also the following pattern (ignore the name of the namespace):
|
|
* @code
|
|
* namespace MySingleton
|
|
* {
|
|
* EXPORT_MACRO QString someFunction();
|
|
* }
|
|
* @endcode
|
|
* in the .cpp file:
|
|
* @code
|
|
* class MySingletonPrivate
|
|
* {
|
|
* public:
|
|
* QString foo;
|
|
* };
|
|
*
|
|
* K_GLOBAL_STATIC(MySingletonPrivate, mySingletonPrivate)
|
|
*
|
|
* QString MySingleton::someFunction()
|
|
* {
|
|
* return mySingletonPrivate->foo;
|
|
* }
|
|
* @endcode
|
|
*
|
|
* Now code that wants to call someFunction() doesn't have to do
|
|
* @code
|
|
* MySingleton::self()->someFunction();
|
|
* @endcode
|
|
* anymore but instead:
|
|
* @code
|
|
* MySingleton::someFunction();
|
|
* @endcode
|
|
*
|
|
* @ingroup KDEMacros
|
|
*/
|
|
#define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
|
|
|
|
/**
|
|
* @overload
|
|
* This is the same as K_GLOBAL_STATIC, but can take arguments that are passed
|
|
* to the object's constructor
|
|
*
|
|
* @param TYPE The type of the global static object. Do not add a *.
|
|
* @param NAME The name of the function to get a pointer to the global static object.
|
|
* @param ARGS the list of arguments, between brackets
|
|
*
|
|
* Example:
|
|
* @code
|
|
* class A
|
|
* {
|
|
* public:
|
|
* A(const char *s, int i);
|
|
* ...
|
|
* };
|
|
*
|
|
* K_GLOBAL_STATIC_WITH_ARGS(A, globalA, ("foo", 0))
|
|
* // The above creates a new globally static variable named 'globalA' which you
|
|
* // can use as a pointer to an instance of A.
|
|
*
|
|
* void doSomething()
|
|
* {
|
|
* // The first time you access globalA a new instance of A will be created automatically.
|
|
* A *a = globalA;
|
|
* ...
|
|
* }
|
|
* @endcode
|
|
*
|
|
* @ingroup KDEMacros
|
|
*/
|
|
#define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
|
|
static QAtomicPointer<TYPE > _k_static_##NAME (0); \
|
|
static bool _k_static_##NAME##_destroyed; \
|
|
static struct \
|
|
{ \
|
|
inline bool isDestroyed() const \
|
|
{ \
|
|
return _k_static_##NAME##_destroyed; \
|
|
} \
|
|
inline bool exists() const \
|
|
{ \
|
|
return _k_static_##NAME != 0; \
|
|
} \
|
|
inline operator TYPE*() \
|
|
{ \
|
|
return operator->(); \
|
|
} \
|
|
inline TYPE *operator->() \
|
|
{ \
|
|
if (!_k_static_##NAME) { \
|
|
if (isDestroyed()) { \
|
|
qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \
|
|
"Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__); \
|
|
} \
|
|
TYPE *x = new TYPE ARGS; \
|
|
if (!_k_static_##NAME.testAndSetOrdered(0, x) \
|
|
&& _k_static_##NAME != x ) { \
|
|
delete x; \
|
|
} else { \
|
|
static KCleanUpGlobalStatic cleanUpObject = { destroy }; \
|
|
} \
|
|
} \
|
|
return _k_static_##NAME; \
|
|
} \
|
|
inline TYPE &operator*() \
|
|
{ \
|
|
return *operator->(); \
|
|
} \
|
|
static void destroy() \
|
|
{ \
|
|
_k_static_##NAME##_destroyed = true; \
|
|
TYPE *x = _k_static_##NAME; \
|
|
_k_static_##NAME = 0; \
|
|
delete x; \
|
|
} \
|
|
} NAME;
|
|
|
|
/**
|
|
* This class is useful in libraries where you want to make sure that
|
|
* anyone that uses your library will get the correct catalog loaded.
|
|
* Just declare a static KCatalogLoader in the global namespace of one of
|
|
* your cpp files and that will load your catalog once
|
|
* the global klocale is created
|
|
*
|
|
* @param catalogName The name of your catalog
|
|
*
|
|
* @since 4.6.2
|
|
*
|
|
* Example:
|
|
* @code
|
|
* static const KCatalogLoader loader("libkdepim");
|
|
* @endcode
|
|
*/
|
|
class KDECORE_EXPORT KCatalogLoader
|
|
{
|
|
public:
|
|
KCatalogLoader(const QString &catalogName);
|
|
};
|
|
|
|
/**
|
|
* Access to the KDE global objects.
|
|
* KGlobal provides you with pointers of many central
|
|
* objects that exist only once in the process. It is also
|
|
* responsible for managing instances of KStaticDeleterBase.
|
|
*
|
|
* @see KStaticDeleterBase
|
|
* @author Sirtaj Singh Kang (taj@kde.org)
|
|
*/
|
|
namespace KGlobal
|
|
{
|
|
|
|
/**
|
|
* Returns the global component data. There is always at least
|
|
* one instance of a component in one application (in most
|
|
* cases the application itself).
|
|
* @return the global component data
|
|
*/
|
|
KDECORE_EXPORT const KComponentData &mainComponent(); //krazy:exclude=constref (don't mess up ref-counting)
|
|
|
|
/**
|
|
* @internal
|
|
* Returns whether a main KComponentData is available.
|
|
*/
|
|
KDECORE_EXPORT bool hasMainComponent();
|
|
|
|
/**
|
|
* Returns the application standard dirs object.
|
|
* @return the global standard dir object
|
|
*/
|
|
KDECORE_EXPORT KStandardDirs *dirs();
|
|
|
|
/**
|
|
* Returns the general config object.
|
|
* @return the global configuration object.
|
|
*/
|
|
KDECORE_EXPORT KSharedConfigPtr config();
|
|
|
|
/**
|
|
* Inserts the catalog in the main locale object if it exists.
|
|
* Otherwise the catalog name is stored and added once the main locale gets created
|
|
*
|
|
* @since 4.6
|
|
*/
|
|
KDECORE_EXPORT void insertCatalog(const QString& catalog);
|
|
|
|
/**
|
|
* Returns the global locale object.
|
|
* @return the global locale object
|
|
*
|
|
* Note: in multi-threaded programs, you should call KGlobal::locale()
|
|
* in the main thread (e.g. in main(), after creating the QCoreApplication
|
|
* and setting the main component), to ensure that the initialization is
|
|
* done in the main thread. However KApplication takes care of this, so this
|
|
* is only needed when not using KApplication.
|
|
*/
|
|
KDECORE_EXPORT KLocale *locale();
|
|
/**
|
|
* @internal
|
|
* Returns whether KGlobal has a valid KLocale object
|
|
*/
|
|
KDECORE_EXPORT bool hasLocale();
|
|
|
|
/**
|
|
* The global charset manager.
|
|
* @return the global charset manager
|
|
*/
|
|
KDECORE_EXPORT KCharsets *charsets();
|
|
|
|
/**
|
|
* Returns the umask of the process.
|
|
* @return the umask of the process
|
|
*/
|
|
KDECORE_EXPORT mode_t umask();
|
|
|
|
/**
|
|
* Tells KGlobal about one more operations that should be finished
|
|
* before the application exits. The standard behavior is to exit on the
|
|
* "last window closed" event, but some events should outlive the last window closed
|
|
* (e.g. a file copy for a file manager, or 'compacting folders on exit' for a mail client),
|
|
* or simply any application with a system tray icon.
|
|
*
|
|
* We have some use cases that we want to take care of (the format is "action refcount"):
|
|
* - open window -> setAllowQuit(true) 1 ; close window 0 => EXIT
|
|
* - job start 1; job end 0 [don't exit yet]; open window -> setAllowQuit(true) 1 ; close window 0 => EXIT
|
|
* - job start 1; open window -> setAllowQuit(true) 2; close window 1; job end 0 => EXIT
|
|
* - job start 1; open window -> setAllowQuit(true) 2; job end 1; close window 0 => EXIT
|
|
* - open dialog 0; close dialog 0; => DO NOT EXIT
|
|
* - job start 1; job end 0; create two main objects 2; delete both main objects 0 => EXIT
|
|
* - open window -> setAllowQuit(true) 1; add systray icon 2; close window 1 => DO NOT EXIT
|
|
* - open window -> setAllowQuit(true) 1; add systray icon 2; remove systray icon 1; close window 0 => EXIT
|
|
* - unit test which opens and closes many windows: should call ref() to avoid subevent-loops quitting too early.
|
|
*
|
|
* Note that for this to happen you must call qApp->setQuitOnLastWindowClosed(false),
|
|
* in main() for instance.
|
|
*/
|
|
KDECORE_EXPORT void ref();
|
|
|
|
/**
|
|
* Tells KGlobal that one operation such as those described in ref() just finished.
|
|
* This call makes the QApplication quit if the counter is back to 0.
|
|
*/
|
|
KDECORE_EXPORT void deref();
|
|
|
|
/**
|
|
* If refcounting reaches 0 (or less), and @p allowQuit is true, the instance of the application
|
|
* will automatically be exited. Otherwise, the application will not exit automatically.
|
|
*
|
|
* This is used by KMainWindow to allow quitting after the first mainwindow is created,
|
|
* and is used by special applications like kioclient, to allow quitting even though
|
|
* no mainwindow was created.
|
|
*
|
|
* However, don't try to call setAllowQuit(false) in applications, it doesn't make sense.
|
|
* If you find that the application quits too early when closing a window, then consider
|
|
* _what_ is making your application still alive to the user (like a systray icon or a D-Bus object)
|
|
* and use KGlobal::ref() + KGlobal::deref() in that object.
|
|
*
|
|
* @since 4.1.1
|
|
*/
|
|
KDECORE_EXPORT void setAllowQuit(bool allowQuit);
|
|
|
|
/**
|
|
* The component currently active (useful in a multi-component
|
|
* application, such as a KParts application).
|
|
* Don't use this - it's mainly for KAboutDialog
|
|
* @internal
|
|
*/
|
|
KDECORE_EXPORT KComponentData activeComponent();
|
|
|
|
/**
|
|
* Set the active component for use by KAboutDialog.
|
|
* To be used only by a multi-component (KParts) application.
|
|
*
|
|
* @see activeComponent()
|
|
*/
|
|
KDECORE_EXPORT void setActiveComponent(const KComponentData &d);
|
|
|
|
/**
|
|
* Returns a text for the window caption.
|
|
*
|
|
* This may be set by
|
|
* "--caption", otherwise it will be equivalent to the name of the
|
|
* executable.
|
|
* @return the text for the window caption
|
|
*/
|
|
KDECORE_EXPORT QString caption();
|
|
|
|
/// @internal
|
|
KDECORE_EXPORT QObject* findDirectChild_helper(const QObject* parent, const QMetaObject& mo);
|
|
|
|
/**
|
|
* Returns the child of the given object that can be cast into type T, or 0 if there is no such object.
|
|
* Unlike QObject::findChild, the search is NOT performed recursively.
|
|
* @since 4.4
|
|
*/
|
|
template<typename T>
|
|
inline T findDirectChild(const QObject* object) {
|
|
return static_cast<T>(findDirectChild_helper(object, (static_cast<T>(0))->staticMetaObject));
|
|
}
|
|
|
|
/**
|
|
* For setLocale
|
|
*/
|
|
enum CopyCatalogs { DoCopyCatalogs, DontCopyCatalogs};
|
|
|
|
///@internal
|
|
KDECORE_EXPORT void setLocale(KLocale *, CopyCatalogs copy = DoCopyCatalogs);
|
|
}
|
|
|
|
#endif // KGLOBAL_H
|
|
|