KDELibs4Support

kglobal.h
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 1999 Sirtaj Singh Kanq <[email protected]>
3  Copyright (C) 2007 Matthias Kretz <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 #ifndef _KGLOBAL_H
20 #define _KGLOBAL_H
21 
22 #include <kdelibs4support_export.h>
23 
24 #ifdef KDELIBS4SUPPORT_NO_DEPRECATED_NOISE
25 #warning "This file is deprecated."
26 #endif
27 
28 /** @file */ // Trigger doxygen coverage of global objects in the file, like macros
29 
30 #include <QAtomicPointer>
31 #include <sys/types.h>
32 #include <QDebug>
33 // To simplify Qt5 porting in KDE code not yet ported to frameworks.
34 #include <QMimeData>
35 #include <klocale.h>
36 
37 // TODO: Re-add for source compat: #include <kdemacros.h>
38 
39 //
40 // WARNING!!
41 // This code uses undocumented Qt API
42 // Do not copy it to your application! Use only the functions that are here!
43 // Otherwise, it could break when a new version of Qt ships.
44 //
45 
46 class KComponentData;
47 class KCharsets;
48 class KConfig;
49 class KStandardDirs;
50 class KSharedConfig;
51 template <typename T>
54 
55 /// @cond InternalDocs
56 
57 /**
58  * @internal
59  */
60 typedef void (*KdeCleanUpFunction)();
61 
62 /**
63  * @internal
64  *
65  * Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application
66  * shutdown.
67  */
68 class KCleanUpGlobalStatic
69 {
70 public:
71  KdeCleanUpFunction func;
72 
73  inline ~KCleanUpGlobalStatic()
74  {
75  func();
76  }
77 };
78 
79 #ifdef Q_CC_MSVC
80 /**
81  * @internal
82  *
83  * MSVC seems to give anonymous structs the same name which fails at link time. So instead we name
84  * the struct and hope that by adding the line number to the name it's unique enough to never clash.
85  */
86 # define K_GLOBAL_STATIC_STRUCT_NAME(NAME) _k_##NAME##__LINE__
87 #else
88 /**
89  * @internal
90  *
91  * Make the struct of the K_GLOBAL_STATIC anonymous.
92  */
93 # define K_GLOBAL_STATIC_STRUCT_NAME(NAME)
94 #endif
95 
96 /// @endcond
97 
98 /**
99  * This macro makes it easy to use non-POD types as global statics.
100  * The object is created on first use and creation is threadsafe.
101  *
102  * The object is destructed on library unload or application exit.
103  * Be careful with calling other objects in the destructor of the class
104  * as you have to be sure that they (or objects they depend on) are not already destructed.
105  *
106  * @param TYPE The type of the global static object. Do not add a *.
107  * @param NAME The name of the function to get a pointer to the global static object.
108  *
109  * If you have code that might be called after the global object has been destroyed you can check
110  * for that using the isDestroyed() function.
111  *
112  * If needed (If the destructor of the global object calls other functions that depend on other
113  * global statics (e.g. KConfig::sync) your destructor has to be called before those global statics
114  * are destroyed. A Qt post routine does that.) you can also install a post routine (qAddPostRoutine) to clean up the object
115  * using the destroy() method. If you registered a post routine and the object is destroyed because
116  * of a lib unload you have to call qRemovePostRoutine!
117  *
118  * Example:
119  * @code
120  * class A {
121  * public:
122  * ~A();
123  * ...
124  * };
125  *
126  * K_GLOBAL_STATIC(A, globalA)
127  * // The above creates a new globally static variable named 'globalA' which you
128  * // can use as a pointer to an instance of A.
129  *
130  * void doSomething()
131  * {
132  * // The first time you access globalA a new instance of A will be created automatically.
133  * A *a = globalA;
134  * ...
135  * }
136  *
137  * void doSomethingElse()
138  * {
139  * if (globalA.isDestroyed()) {
140  * return;
141  * }
142  * A *a = globalA;
143  * ...
144  * }
145  *
146  * void installPostRoutine()
147  * {
148  * // A post routine can be used to delete the object when QCoreApplication destructs,
149  * // not adding such a post routine will delete the object normally at program unload
150  * qAddPostRoutine(globalA.destroy);
151  * }
152  *
153  * A::~A()
154  * {
155  * // When you install a post routine you have to remove the post routine from the destructor of
156  * // the class used as global static!
157  * qRemovePostRoutine(globalA.destroy);
158  * }
159  * @endcode
160  *
161  * A common case for the need of deletion on lib unload/app shutdown are Singleton classes. Here's
162  * an example how to do it:
163  * @code
164  * class MySingletonPrivate;
165  * class EXPORT_MACRO MySingleton
166  * {
167  * friend class MySingletonPrivate;
168  * public:
169  * static MySingleton *self();
170  * QString someFunction();
171  *
172  * private:
173  * MySingleton();
174  * ~MySingleton();
175  * };
176  * @endcode
177  * in the .cpp file:
178  * @code
179  * // This class will be instantiated and referenced as a singleton in this example
180  * class MySingletonPrivate
181  * {
182  * public:
183  * QString foo;
184  * MySingleton instance;
185  * };
186  *
187  * K_GLOBAL_STATIC(MySingletonPrivate, mySingletonPrivate)
188  *
189  * MySingleton *MySingleton::self()
190  * {
191  * // returns the singleton; automatically creates a new instance if that has not happened yet.
192  * return &mySingletonPrivate->instance;
193  * }
194  * QString MySingleton::someFunction()
195  * {
196  * // Refencing the singleton directly is possible for your convenience
197  * return mySingletonPrivate->foo;
198  * }
199  * @endcode
200  *
201  * Instead of the above you can use also the following pattern (ignore the name of the namespace):
202  * @code
203  * namespace MySingleton
204  * {
205  * EXPORT_MACRO QString someFunction();
206  * }
207  * @endcode
208  * in the .cpp file:
209  * @code
210  * class MySingletonPrivate
211  * {
212  * public:
213  * QString foo;
214  * };
215  *
216  * K_GLOBAL_STATIC(MySingletonPrivate, mySingletonPrivate)
217  *
218  * QString MySingleton::someFunction()
219  * {
220  * return mySingletonPrivate->foo;
221  * }
222  * @endcode
223  *
224  * Now code that wants to call someFunction() doesn't have to do
225  * @code
226  * MySingleton::self()->someFunction();
227  * @endcode
228  * anymore but instead:
229  * @code
230  * MySingleton::someFunction();
231  * @endcode
232  *
233  * @ingroup KDEMacros
234  */
235 #define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ())
236 
237 /**
238  * @overload
239  * This is the same as K_GLOBAL_STATIC, but can take arguments that are passed
240  * to the object's constructor
241  *
242  * @param TYPE The type of the global static object. Do not add a *.
243  * @param NAME The name of the function to get a pointer to the global static object.
244  * @param ARGS the list of arguments, between brackets
245  *
246  * Example:
247  * @code
248  * class A
249  * {
250  * public:
251  * A(const char *s, int i);
252  * ...
253  * };
254  *
255  * K_GLOBAL_STATIC_WITH_ARGS(A, globalA, ("foo", 0))
256  * // The above creates a new globally static variable named 'globalA' which you
257  * // can use as a pointer to an instance of A.
258  *
259  * void doSomething()
260  * {
261  * // The first time you access globalA a new instance of A will be created automatically.
262  * A *a = globalA;
263  * ...
264  * }
265  * @endcode
266  *
267  * @ingroup KDEMacros
268  */
269 
270 // In Qt5 QBasicAtomicPointer<T> no longer implicit casts to T*
271 // Instead it has load() and store() methods which do not exist in Qt4.
272 // In practice, we should be porting frameworks to the new Q_GLOBAL_STATIC
273 // which isn't in Qt5 yet, so duplicate for now.
274 
275 #define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \
276  static QBasicAtomicPointer<TYPE > _k_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(nullptr); \
277  static bool _k_static_##NAME##_destroyed; \
278  static struct K_GLOBAL_STATIC_STRUCT_NAME(NAME) \
279  { \
280  inline bool isDestroyed() const \
281  { \
282  return _k_static_##NAME##_destroyed; \
283  } \
284  inline bool exists() const \
285  { \
286  return _k_static_##NAME.load() != nullptr; \
287  } \
288  inline operator TYPE*() \
289  { \
290  return operator->(); \
291  } \
292  inline TYPE *operator->() \
293  { \
294  if (!_k_static_##NAME.load()) { \
295  if (isDestroyed()) { \
296  qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \
297  "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__); \
298  } \
299  TYPE *x = new TYPE ARGS; \
300  if (!_k_static_##NAME.testAndSetOrdered(nullptr, x) \
301  && _k_static_##NAME.load() != x ) { \
302  delete x; \
303  } else { \
304  static KCleanUpGlobalStatic cleanUpObject = { destroy }; \
305  } \
306  } \
307  return _k_static_##NAME.load(); \
308  } \
309  inline TYPE &operator*() \
310  { \
311  return *operator->(); \
312  } \
313  static void destroy() \
314  { \
315  _k_static_##NAME##_destroyed = true; \
316  TYPE *x = _k_static_##NAME.load(); \
317  _k_static_##NAME.store(nullptr); \
318  delete x; \
319  } \
320  } NAME;
321 
322 /**
323  * Access to the KDE global objects.
324  * KGlobal provides you with pointers of many central
325  * objects that exist only once in the process. It is also
326  * responsible for managing instances of KStaticDeleterBase.
327  *
328  * @see KStaticDeleterBase
329  * @author Sirtaj Singh Kang ([email protected])
330  */
331 namespace KGlobal
332 {
333 
334 struct KDELIBS4SUPPORT_DEPRECATED_EXPORT_NOISE LocaleWrapper : public KLocale {
335  KDELIBS4SUPPORT_DEPRECATED explicit LocaleWrapper(KLocale *locale)
336  : KLocale(*locale)
337  {
338 
339  }
340 
341  KDELIBS4SUPPORT_DEPRECATED static void insertCatalog(const QString &)
342  {
343  qWarning() << "Your code needs to be ported in KF5. See the Ki18n programmers guide.";
344  }
345 
346  LocaleWrapper *operator->()
347  {
348  return this;
349  }
350 
351  operator KLocale *()
352  {
353  return this;
354  }
355 };
356 
357 /**
358  * Returns the global component data. There is always at least
359  * one instance of a component in one application (in most
360  * cases the application itself).
361  * @return the global component data
362  * @deprecated since 5.0 use KComponentData::mainComponent() if you really need a KComponentData
363  */
364 KDELIBS4SUPPORT_DEPRECATED_EXPORT const KComponentData &mainComponent(); //krazy:exclude=constref (don't mess up ref-counting)
365 
366 /**
367  * @internal
368  * Returns whether a main KComponentData is available.
369  * @deprecated since 5.0, use KComponentData::hasMainComponent() if you really need a KComponentData
370  */
371 KDELIBS4SUPPORT_DEPRECATED_EXPORT bool hasMainComponent();
372 
373 /**
374  * Returns the application standard dirs object.
375  * @return the global standard dir object
376  */
377 KDELIBS4SUPPORT_DEPRECATED_EXPORT KStandardDirs *dirs();
378 
379 /**
380  * Returns the general config object.
381  * @return the global configuration object.
382  * @deprecated since 5.0, use KSharedConfig::openConfig()
383  */
384 KDELIBS4SUPPORT_DEPRECATED_EXPORT KSharedConfigPtr config();
385 
386 /**
387  * Returns the global locale object.
388  * @return the global locale object
389  *
390  * Note: in multi-threaded programs, you should call KLocale::global()
391  * in the main thread (e.g. in main(), after creating the QCoreApplication
392  * and setting the main component), to ensure that the initialization is
393  * done in the main thread. However KApplication takes care of this, so this
394  * is only needed when not using KApplication.
395  *
396  * @deprecated since 5.0, use KLocale::global()
397  */
398 KDELIBS4SUPPORT_DEPRECATED_EXPORT LocaleWrapper locale();
399 /**
400  * @internal
401  * Returns whether KGlobal has a valid KLocale object
402  * @deprecated since 5.0, port to if (qApp) because KLocale::global() can be called, as soon as a qApp exists.
403  */
404 KDELIBS4SUPPORT_DEPRECATED_EXPORT bool hasLocale();
405 
406 /**
407  * The global charset manager.
408  * @return the global charset manager
409  * @deprecated since 5.0, use KCharsets::charsets()
410  */
411 KDELIBS4SUPPORT_DEPRECATED_EXPORT KCharsets *charsets();
412 
413 /**
414  * Returns the umask of the process.
415  * @return the umask of the process
416  */
417 KDELIBS4SUPPORT_DEPRECATED_EXPORT mode_t umask();
418 
419 /**
420  * Creates a static QString.
421  *
422  * To be used inside functions(!) like:
423  * @code
424  * static const QString &myString = KGlobal::staticQString("myText");
425  * @endcode
426  *
427  * @attention Do @b NOT use code such as:
428  * @code
429  * static QString myString = KGlobal::staticQString("myText");
430  * @endcode
431  * This creates a static object (instead of a static reference)
432  * and as you know static objects are EVIL.
433  * @param str the string to create
434  * @return the static string
435  * @deprecated since 5.0, use QLatin1String() or QStringLiteral()
436  */
437 KDELIBS4SUPPORT_DEPRECATED_EXPORT const QString &staticQString(const char *str); //krazy:exclude=constref (doesn't make sense otherwise)
438 
439 /**
440  * Creates a static QString.
441  *
442  * To be used inside functions(!) like:
443  * @code
444  * static const QString &myString = KGlobal::staticQString(i18n("My Text"));
445  * @endcode
446  *
447  * @attention Do @b NOT use code such as:
448  * @code
449  * static QString myString = KGlobal::staticQString(i18n("myText"));
450  * @endcode
451  * This creates a static object (instead of a static reference)
452  * and as you know static objects are EVIL.
453  * @param str the string to create
454  * @return the static string
455  * @deprecated since 5.0 don't make the string static
456  */
457 KDELIBS4SUPPORT_DEPRECATED_EXPORT const QString &staticQString(const QString &str); //krazy:exclude=constref (doesn't make sense otherwise)
458 
459 /**
460  * Tells KGlobal about one more operations that should be finished
461  * before the application exits. The standard behavior is to exit on the
462  * "last window closed" event, but some events should outlive the last window closed
463  * (e.g. a file copy for a file manager, or 'compacting folders on exit' for a mail client),
464  * or simply any application with a system tray icon.
465  *
466  * We have some use cases that we want to take care of (the format is "action refcount"):
467  * - open window -> setAllowQuit(true) 1 ; close window 0 => EXIT
468  * - job start 1; job end 0 [don't exit yet]; open window -> setAllowQuit(true) 1 ; close window 0 => EXIT
469  * - job start 1; open window -> setAllowQuit(true) 2; close window 1; job end 0 => EXIT
470  * - job start 1; open window -> setAllowQuit(true) 2; job end 1; close window 0 => EXIT
471  * - open dialog 0; close dialog 0; => DO NOT EXIT
472  * - job start 1; job end 0; create two main objects 2; delete both main objects 0 => EXIT
473  * - open window -> setAllowQuit(true) 1; add systray icon 2; close window 1 => DO NOT EXIT
474  * - open window -> setAllowQuit(true) 1; add systray icon 2; remove systray icon 1; close window 0 => EXIT
475  * - unit test which opens and closes many windows: should call ref() to avoid subevent-loops quitting too early.
476  *
477  * Note that for this to happen you must call qApp->setQuitOnLastWindowClosed(false),
478  * in main() for instance.
479  *
480  * @deprecated since 5.0, use QEventLoopLocker, its constructor does the equivalent of ref
481  */
482 KDELIBS4SUPPORT_DEPRECATED_EXPORT void ref();
483 
484 /**
485  * Tells KGlobal that one operation such as those described in ref() just finished.
486  * This call makes the QApplication quit if the counter is back to 0.
487  *
488  * @deprecated since 5.0, use QEventLoopLocker, its destructor does the equivalent of unref
489  */
490 KDELIBS4SUPPORT_DEPRECATED_EXPORT void deref();
491 
492 /**
493  * If refcounting reaches 0 (or less), and @p allowQuit is true, the instance of the application
494  * will automatically be exited. Otherwise, the application will not exit automatically.
495  *
496  * This is used by KMainWindow to allow quitting after the first mainwindow is created,
497  * and is used by special applications like kfmclient, to allow quitting even though
498  * no mainwindow was created.
499  *
500  * However, don't try to call setAllowQuit(false) in applications, it doesn't make sense.
501  * If you find that the application quits too early when closing a window, then consider
502  * _what_ is making your application still alive to the user (like a systray icon or a D-Bus object)
503  * and use KGlobal::ref() + KGlobal::deref() in that object.
504  *
505  * @since 4.1.1
506  * @deprecated since 5.0, not necessary anymore, with QCoreApplication and QEventLoopLocker
507  */
508 KDELIBS4SUPPORT_DEPRECATED_EXPORT void setAllowQuit(bool allowQuit);
509 
510 /**
511  * The component currently active (useful in a multi-component
512  * application, such as a KParts application).
513  * Don't use this - it's mainly for KAboutDialog and KBugReport.
514  * @internal
515  * @deprecated since 5.0 see KComponentData::activeComponent() about
516  * why you should do without this concept (or let your app remember the active
517  * part/plugin if it cares)
518  */
519 KDELIBS4SUPPORT_DEPRECATED_EXPORT KComponentData activeComponent();
520 
521 /**
522  * Set the active component for use by KAboutDialog and KBugReport.
523  * To be used only by a multi-component (KParts) application.
524  *
525  * @see activeComponent()
526  * @deprecated since 5.0 see KComponentData::setActiveComponent about
527  * why you can probably just remove the call.
528  */
529 KDELIBS4SUPPORT_DEPRECATED_EXPORT void setActiveComponent(const KComponentData &d);
530 
531 /**
532  * Returns a text for the window caption.
533  *
534  * This may be set by
535  * "-caption", otherwise it will be equivalent to the name of the
536  * executable.
537  * @return the text for the window caption
538  * @deprecated since 5.0. Don't use in window titles anymore, Qt takes care of it.
539  * If you really need this, use QGuiApplication::applicationDisplayName(), and if that's empty, QCoreApplication::applicationName().
540  */
541 KDELIBS4SUPPORT_DEPRECATED_EXPORT QString caption();
542 
543 /// @internal
544 KDELIBS4SUPPORT_DEPRECATED_EXPORT QObject *findDirectChild_helper(const QObject *parent, const QMetaObject &mo);
545 
546 /**
547  * Returns the child of the given object that can be cast into type T, or 0 if there is no such object.
548  * Unlike QObject::findChild, the search is NOT performed recursively.
549  * @since 4.4
550  * @deprecated since Qt 5, use QObject::findChild(FindDirectChildrenOnly)
551  */
552 template<typename T>
553 KDELIBS4SUPPORT_DEPRECATED inline T findDirectChild(const QObject *object)
554 {
555  return static_cast<T>(findDirectChild_helper(object, (static_cast<T>(nullptr))->staticMetaObject));
556 }
557 }
558 
559 struct KCatalogLoader {
560  KDELIBS4SUPPORT_DEPRECATED KCatalogLoader(const QString &)
561  {
562  qWarning() << "Your code needs to be ported in KF5. See the Ki18n programmers guide.";
563  }
564 };
565 
566 #endif // _KGLOBAL_H
567 
const QString & staticQString(const char *str)
Creates a static QString.
Definition: kglobal.cpp:154
Access to the KDE global objects.
Definition: kglobal.h:331
T findDirectChild(const QObject *object)
Returns the child of the given object that can be cast into type T, or 0 if there is no such object.
Definition: kglobal.h:553
void ref()
Tells KGlobal about one more operations that should be finished before the application exits.
Definition: kglobal.cpp:207
KComponentData activeComponent()
The component currently active (useful in a multi-component application, such as a KParts application...
Definition: kglobal.cpp:138
void deref()
Tells KGlobal that one operation such as those described in ref() just finished.
Definition: kglobal.cpp:213
QString caption()
Returns a text for the window caption.
Definition: kglobal.cpp:175
void setAllowQuit(bool allowQuit)
If refcounting reaches 0 (or less), and allowQuit is true, the instance of the application will autom...
Definition: kglobal.cpp:222
KCharsets * charsets()
The global charset manager.
Definition: kglobal.cpp:127
void setActiveComponent(const KComponentData &d)
Set the active component for use by KAboutDialog and KBugReport.
Definition: kglobal.cpp:143
bool hasMainComponent()
Definition: kglobal.cpp:112
KSharedConfigPtr config()
Returns the general config object.
Definition: kglobal.cpp:102
Per component data.
LocaleWrapper locale()
Returns the global locale object.
Definition: kglobal.cpp:117
const KComponentData & mainComponent()
Returns the global component data.
Definition: kglobal.cpp:107
bool hasLocale()
Definition: kglobal.cpp:122
mode_t umask()
Returns the umask of the process.
Definition: kglobal.cpp:132
KStandardDirs * dirs()
Returns the application standard dirs object.
Definition: kglobal.cpp:89
Site-independent access to standard KDE directories.
QObject * findDirectChild_helper(const QObject *parent, const QMetaObject &mo)
Definition: kglobal.cpp:229
KLocale provides support for language and country specific stuff.
Definition: klocale.h:75
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Dec 1 2023 03:59:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.