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