KDELibs4Support

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

KDE's Doxygen guidelines are available online.