1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qcoreapplication.h"
42#include "qcoreapplication_p.h"
43
44#ifndef QT_NO_QOBJECT
45#include "qabstracteventdispatcher.h"
46#include "qcoreevent.h"
47#include "qeventloop.h"
48#endif
49#include "qcorecmdlineargs_p.h"
50#include <qdatastream.h>
51#include <qdebug.h>
52#include <qdir.h>
53#include <qfile.h>
54#include <qfileinfo.h>
55#include <qmutex.h>
56#include <private/qloggingregistry_p.h>
57#include <qstandardpaths.h>
58#include <qtextcodec.h>
59#ifndef QT_NO_QOBJECT
60#include <qthread.h>
61#include <qthreadpool.h>
62#include <qthreadstorage.h>
63#include <private/qthread_p.h>
64#endif
65#include <qelapsedtimer.h>
66#include <qlibraryinfo.h>
67#include <qvarlengtharray.h>
68#include <private/qfactoryloader_p.h>
69#include <private/qfunctions_p.h>
70#include <private/qlocale_p.h>
71#include <private/qhooks_p.h>
72
73#ifndef QT_NO_QOBJECT
74#if defined(Q_OS_UNIX)
75# if defined(Q_OS_DARWIN)
76# include "qeventdispatcher_cf_p.h"
77# else
78# if !defined(QT_NO_GLIB)
79# include "qeventdispatcher_glib_p.h"
80# endif
81# endif
82# include "qeventdispatcher_unix_p.h"
83#endif
84#ifdef Q_OS_WIN
85# ifdef Q_OS_WINRT
86# include "qeventdispatcher_winrt_p.h"
87# include "qfunctions_winrt.h"
88# include <wrl.h>
89# include <Windows.ApplicationModel.core.h>
90 using namespace ABI::Windows::ApplicationModel::Core;
91 using namespace Microsoft::WRL;
92# else
93# include "qeventdispatcher_win_p.h"
94# endif
95#endif
96#endif // QT_NO_QOBJECT
97
98#if defined(Q_OS_ANDROID)
99# include <private/qjni_p.h>
100# include <private/qjnihelpers_p.h>
101#endif
102
103#ifdef Q_OS_MAC
104# include "qcore_mac_p.h"
105#endif
106
107#include <stdlib.h>
108
109#ifdef Q_OS_UNIX
110# include <locale.h>
111# include <unistd.h>
112# include <sys/types.h>
113#endif
114
115#ifdef Q_OS_VXWORKS
116# include <taskLib.h>
117#endif
118
119#include <algorithm>
120
121QT_BEGIN_NAMESPACE
122
123#ifndef QT_NO_QOBJECT
124class QMutexUnlocker
125{
126public:
127 inline explicit QMutexUnlocker(QMutex *m)
128 : mtx(m)
129 { }
130 inline ~QMutexUnlocker() { unlock(); }
131 inline void unlock() { if (mtx) mtx->unlock(); mtx = 0; }
132
133private:
134 Q_DISABLE_COPY(QMutexUnlocker)
135
136 QMutex *mtx;
137};
138#endif
139
140#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
141extern QString qAppFileName();
142#endif
143
144#if QT_VERSION >= 0x060000
145# error "Bump QCoreApplicatoinPrivate::app_compile_version to 0x060000"
146#endif
147int QCoreApplicationPrivate::app_compile_version = 0x050000; //we don't know exactly, but it's at least 5.0.0
148
149bool QCoreApplicationPrivate::setuidAllowed = false;
150
151#if !defined(Q_OS_WIN)
152#ifdef Q_OS_DARWIN
153QString QCoreApplicationPrivate::infoDictionaryStringProperty(const QString &propertyName)
154{
155 QString bundleName;
156 QCFString cfPropertyName = propertyName.toCFString();
157 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
158 cfPropertyName);
159 if (string)
160 bundleName = QString::fromCFString(static_cast<CFStringRef>(string));
161 return bundleName;
162}
163#endif
164QString QCoreApplicationPrivate::appName() const
165{
166 QString applicationName;
167#ifdef Q_OS_DARWIN
168 applicationName = infoDictionaryStringProperty(QStringLiteral("CFBundleName"));
169#endif
170 if (applicationName.isEmpty() && argv[0]) {
171 char *p = strrchr(argv[0], '/');
172 applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
173 }
174
175 return applicationName;
176}
177QString QCoreApplicationPrivate::appVersion() const
178{
179 QString applicationVersion;
180#ifndef QT_BOOTSTRAPPED
181# ifdef Q_OS_DARWIN
182 applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
183# elif defined(Q_OS_ANDROID)
184 QJNIObjectPrivate context(QtAndroidPrivate::context());
185 if (context.isValid()) {
186 QJNIObjectPrivate pm = context.callObjectMethod(
187 "getPackageManager", "()Landroid/content/pm/PackageManager;");
188 QJNIObjectPrivate pn = context.callObjectMethod<jstring>("getPackageName");
189 if (pm.isValid() && pn.isValid()) {
190 QJNIObjectPrivate packageInfo = pm.callObjectMethod(
191 "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
192 pn.object(), 0);
193 if (packageInfo.isValid()) {
194 QJNIObjectPrivate versionName = packageInfo.getObjectField(
195 "versionName", "Ljava/lang/String;");
196 if (versionName.isValid())
197 return versionName.toString();
198 }
199 }
200 }
201# endif
202#endif
203 return applicationVersion;
204}
205#endif
206
207QString *QCoreApplicationPrivate::cachedApplicationFilePath = 0;
208
209bool QCoreApplicationPrivate::checkInstance(const char *function)
210{
211 bool b = (QCoreApplication::self != 0);
212 if (!b)
213 qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
214 return b;
215}
216
217void QCoreApplicationPrivate::processCommandLineArguments()
218{
219 int j = argc ? 1 : 0;
220 for (int i = 1; i < argc; ++i) {
221 if (!argv[i])
222 continue;
223 if (*argv[i] != '-') {
224 argv[j++] = argv[i];
225 continue;
226 }
227 const char *arg = argv[i];
228 if (arg[1] == '-') // startsWith("--")
229 ++arg;
230 if (strncmp(arg, "-qmljsdebugger=", 15) == 0) {
231 qmljs_debug_arguments = QString::fromLocal8Bit(arg + 15);
232 } else if (strcmp(arg, "-qmljsdebugger") == 0 && i < argc - 1) {
233 ++i;
234 qmljs_debug_arguments = QString::fromLocal8Bit(argv[i]);
235 } else {
236 argv[j++] = argv[i];
237 }
238 }
239
240 if (j < argc) {
241 argv[j] = 0;
242 argc = j;
243 }
244}
245
246// Support for introspection
247
248#ifndef QT_NO_QOBJECT
249QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
250
251void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
252{
253 qt_signal_spy_callback_set = callback_set;
254}
255#endif
256
257extern "C" void Q_CORE_EXPORT qt_startup_hook()
258{
259}
260
261typedef QList<QtStartUpFunction> QStartUpFuncList;
262Q_GLOBAL_STATIC(QStartUpFuncList, preRList)
263typedef QList<QtCleanUpFunction> QVFuncList;
264Q_GLOBAL_STATIC(QVFuncList, postRList)
265#ifndef QT_NO_QOBJECT
266static QBasicMutex globalPreRoutinesMutex;
267#endif
268
269/*!
270 \internal
271
272 Adds a global routine that will be called from the QCoreApplication
273 constructor. The public API is Q_COREAPP_STARTUP_FUNCTION.
274*/
275void qAddPreRoutine(QtStartUpFunction p)
276{
277 QStartUpFuncList *list = preRList();
278 if (!list)
279 return;
280 // Due to C++11 parallel dynamic initialization, this can be called
281 // from multiple threads.
282#ifndef QT_NO_THREAD
283 QMutexLocker locker(&globalPreRoutinesMutex);
284#endif
285 if (QCoreApplication::instance())
286 p();
287 list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines
288}
289
290void qAddPostRoutine(QtCleanUpFunction p)
291{
292 QVFuncList *list = postRList();
293 if (!list)
294 return;
295 list->prepend(p);
296}
297
298void qRemovePostRoutine(QtCleanUpFunction p)
299{
300 QVFuncList *list = postRList();
301 if (!list)
302 return;
303 list->removeAll(p);
304}
305
306static void qt_call_pre_routines()
307{
308 QStartUpFuncList *list = preRList();
309 if (!list)
310 return;
311#ifndef QT_NO_THREAD
312 QMutexLocker locker(&globalPreRoutinesMutex);
313#endif
314 // Unlike qt_call_post_routines, we don't empty the list, because
315 // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects
316 // the function to be executed every time QCoreApplication is created.
317 for (int i = 0; i < list->count(); ++i)
318 list->at(i)();
319}
320
321void Q_CORE_EXPORT qt_call_post_routines()
322{
323 QVFuncList *list = 0;
324 QT_TRY {
325 list = postRList();
326 } QT_CATCH(const std::bad_alloc &) {
327 // ignore - if we can't allocate a post routine list,
328 // there's a high probability that there's no post
329 // routine to be executed :)
330 }
331 if (!list)
332 return;
333 while (!list->isEmpty())
334 (list->takeFirst())();
335}
336
337
338// initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
339static bool qt_locale_initialized = false;
340
341#ifndef QT_NO_QOBJECT
342
343// app starting up if false
344bool QCoreApplicationPrivate::is_app_running = false;
345 // app closing down if true
346bool QCoreApplicationPrivate::is_app_closing = false;
347
348Q_CORE_EXPORT uint qGlobalPostedEventsCount()
349{
350 QThreadData *currentThreadData = QThreadData::current();
351 return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
352}
353
354QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
355
356#endif // QT_NO_QOBJECT
357
358QCoreApplication *QCoreApplication::self = 0;
359uint QCoreApplicationPrivate::attribs =
360 (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
361 (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
362
363struct QCoreApplicationData {
364 QCoreApplicationData() Q_DECL_NOTHROW {
365 applicationNameSet = false;
366 applicationVersionSet = false;
367 }
368 ~QCoreApplicationData() {
369#ifndef QT_NO_QOBJECT
370 // cleanup the QAdoptedThread created for the main() thread
371 if (QCoreApplicationPrivate::theMainThread) {
372 QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
373 data->deref(); // deletes the data and the adopted thread
374 }
375#endif
376 }
377
378 QString orgName, orgDomain;
379 QString application; // application name, initially from argv[0], can then be modified.
380 QString applicationVersion;
381 bool applicationNameSet; // true if setApplicationName was called
382 bool applicationVersionSet; // true if setApplicationVersion was called
383
384#ifndef QT_NO_LIBRARY
385 QScopedPointer<QStringList> app_libpaths;
386 QScopedPointer<QStringList> manual_libpaths;
387#endif
388
389};
390
391Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
392
393#ifndef QT_NO_QOBJECT
394static bool quitLockRefEnabled = true;
395#endif
396
397#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
398// Check whether the command line arguments match those passed to main()
399// by comparing to the global __argv/__argc (MS extension).
400// Deep comparison is required since argv/argc is rebuilt by WinMain for
401// GUI apps or when using MinGW due to its globbing.
402static inline bool isArgvModified(int argc, char **argv)
403{
404 if (__argc != argc || !__argv /* wmain() */)
405 return true;
406 if (__argv == argv)
407 return false;
408 for (int a = 0; a < argc; ++a) {
409 if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
410 return true;
411 }
412 return false;
413}
414
415static inline bool contains(int argc, char **argv, const char *needle)
416{
417 for (int a = 0; a < argc; ++a) {
418 if (!strcmp(argv[a], needle))
419 return true;
420 }
421 return false;
422}
423#endif // Q_OS_WIN && !Q_OS_WINRT
424
425QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
426 :
427#ifndef QT_NO_QOBJECT
428 QObjectPrivate(),
429#endif
430 argc(aargc)
431 , argv(aargv)
432#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
433 , origArgc(0)
434 , origArgv(Q_NULLPTR)
435#endif
436 , application_type(QCoreApplicationPrivate::Tty)
437#ifndef QT_NO_QOBJECT
438 , in_exec(false)
439 , aboutToQuitEmitted(false)
440 , threadData_clean(false)
441#else
442 , q_ptr(0)
443#endif
444{
445 app_compile_version = flags & 0xffffff;
446 static const char *const empty = "";
447 if (argc == 0 || argv == 0) {
448 argc = 0;
449 argv = const_cast<char **>(&empty);
450 }
451#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
452 if (!isArgvModified(argc, argv)) {
453 origArgc = argc;
454 origArgv = new char *[argc];
455 std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
456 }
457#endif // Q_OS_WIN && !Q_OS_WINRT
458
459#ifndef QT_NO_QOBJECT
460 QCoreApplicationPrivate::is_app_closing = false;
461
462# if defined(Q_OS_UNIX)
463 if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
464 qFatal("FATAL: The application binary appears to be running setuid, this is a security hole.");
465# endif // Q_OS_UNIX
466
467 QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread!
468 if (cur != theMainThread)
469 qWarning("WARNING: QApplication was not created in the main() thread.");
470#endif
471}
472
473QCoreApplicationPrivate::~QCoreApplicationPrivate()
474{
475#ifndef QT_NO_QOBJECT
476 cleanupThreadData();
477#endif
478#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
479 delete [] origArgv;
480#endif
481 QCoreApplicationPrivate::clearApplicationFilePath();
482}
483
484#ifndef QT_NO_QOBJECT
485
486void QCoreApplicationPrivate::cleanupThreadData()
487{
488 if (threadData && !threadData_clean) {
489#ifndef QT_NO_THREAD
490 void *data = &threadData->tls;
491 QThreadStorageData::finish((void **)data);
492#endif
493
494 // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
495 QMutexLocker locker(&threadData->postEventList.mutex);
496 for (int i = 0; i < threadData->postEventList.size(); ++i) {
497 const QPostEvent &pe = threadData->postEventList.at(i);
498 if (pe.event) {
499 --pe.receiver->d_func()->postedEvents;
500 pe.event->posted = false;
501 delete pe.event;
502 }
503 }
504 threadData->postEventList.clear();
505 threadData->postEventList.recursion = 0;
506 threadData->quitNow = false;
507 threadData_clean = true;
508 }
509}
510
511void QCoreApplicationPrivate::createEventDispatcher()
512{
513 Q_Q(QCoreApplication);
514#if defined(Q_OS_UNIX)
515# if defined(Q_OS_DARWIN)
516 bool ok = false;
517 int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
518 if (ok && value > 0)
519 eventDispatcher = new QEventDispatcherCoreFoundation(q);
520 else
521 eventDispatcher = new QEventDispatcherUNIX(q);
522# elif !defined(QT_NO_GLIB)
523 if (qEnvironmentVariableIsEmpty("QT_NO_GLIB") && QEventDispatcherGlib::versionSupported())
524 eventDispatcher = new QEventDispatcherGlib(q);
525 else
526 eventDispatcher = new QEventDispatcherUNIX(q);
527# else
528 eventDispatcher = new QEventDispatcherUNIX(q);
529# endif
530#elif defined(Q_OS_WINRT)
531 eventDispatcher = new QEventDispatcherWinRT(q);
532#elif defined(Q_OS_WIN)
533 eventDispatcher = new QEventDispatcherWin32(q);
534#else
535# error "QEventDispatcher not yet ported to this platform"
536#endif
537}
538
539void QCoreApplicationPrivate::eventDispatcherReady()
540{
541}
542
543QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0);
544QThread *QCoreApplicationPrivate::mainThread()
545{
546 Q_ASSERT(theMainThread.load() != 0);
547 return theMainThread.load();
548}
549
550bool QCoreApplicationPrivate::threadRequiresCoreApplication()
551{
552 QThreadData *data = QThreadData::current(false);
553 if (!data)
554 return true; // default setting
555 return data->requiresCoreApplication;
556}
557
558void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
559{
560 QThread *currentThread = QThread::currentThread();
561 QThread *thr = receiver->thread();
562 Q_ASSERT_X(currentThread == thr || !thr,
563 "QCoreApplication::sendEvent",
564 QString::asprintf("Cannot send events to objects owned by a different thread. "
565 "Current thread 0x%p. Receiver '%ls' (of type '%s') was created in thread 0x%p",
566 currentThread, qUtf16Printable(receiver->objectName()),
567 receiver->metaObject()->className(), thr)
568 .toLocal8Bit().data());
569 Q_UNUSED(currentThread);
570 Q_UNUSED(thr);
571}
572
573#endif // QT_NO_QOBJECT
574
575void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
576{
577#ifndef QT_NO_LIBRARY
578 QStringList *app_libpaths = coreappdata()->app_libpaths.data();
579 if (!app_libpaths)
580 coreappdata()->app_libpaths.reset(app_libpaths = new QStringList);
581 QString app_location = QCoreApplication::applicationFilePath();
582 app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
583#ifdef Q_OS_WINRT
584 if (app_location.isEmpty())
585 app_location.append(QLatin1Char('/'));
586#endif
587 app_location = QDir(app_location).canonicalPath();
588 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
589 app_libpaths->append(app_location);
590#endif
591}
592
593QString qAppName()
594{
595 if (!QCoreApplicationPrivate::checkInstance("qAppName"))
596 return QString();
597 return QCoreApplication::instance()->d_func()->appName();
598}
599
600void QCoreApplicationPrivate::initLocale()
601{
602 if (qt_locale_initialized)
603 return;
604 qt_locale_initialized = true;
605#if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
606 setlocale(LC_ALL, "");
607#endif
608}
609
610
611/*!
612 \class QCoreApplication
613 \inmodule QtCore
614 \brief The QCoreApplication class provides an event loop for Qt
615 applications without UI.
616
617 This class is used by non-GUI applications to provide their event
618 loop. For non-GUI application that uses Qt, there should be exactly
619 one QCoreApplication object. For GUI applications, see
620 QGuiApplication. For applications that use the Qt Widgets module,
621 see QApplication.
622
623 QCoreApplication contains the main event loop, where all events
624 from the operating system (e.g., timer and network events) and
625 other sources are processed and dispatched. It also handles the
626 application's initialization and finalization, as well as
627 system-wide and application-wide settings.
628
629 \section1 The Event Loop and Event Handling
630
631 The event loop is started with a call to exec(). Long-running
632 operations can call processEvents() to keep the application
633 responsive.
634
635 In general, we recommend that you create a QCoreApplication,
636 QGuiApplication or a QApplication object in your \c main()
637 function as early as possible. exec() will not return until
638 the event loop exits; e.g., when quit() is called.
639
640 Several static convenience functions are also provided. The
641 QCoreApplication object is available from instance(). Events can
642 be sent or posted using sendEvent(), postEvent(), and
643 sendPostedEvents(). Pending events can be removed with
644 removePostedEvents() or flushed with flush().
645
646 The class provides a quit() slot and an aboutToQuit() signal.
647
648 \section1 Application and Library Paths
649
650 An application has an applicationDirPath() and an
651 applicationFilePath(). Library paths (see QLibrary) can be retrieved
652 with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
653 and removeLibraryPath().
654
655 \section1 Internationalization and Translations
656
657 Translation files can be added or removed
658 using installTranslator() and removeTranslator(). Application
659 strings can be translated using translate(). The QObject::tr()
660 and QObject::trUtf8() functions are implemented in terms of
661 translate().
662
663 \section1 Accessing Command Line Arguments
664
665 The command line arguments which are passed to QCoreApplication's
666 constructor should be accessed using the arguments() function.
667
668 \note QCoreApplication removes option \c -qmljsdebugger="...". It parses the
669 argument of \c qmljsdebugger, and then removes this option plus its argument.
670
671 For more advanced command line option handling, create a QCommandLineParser.
672
673 \section1 Locale Settings
674
675 On Unix/Linux Qt is configured to use the system locale settings by
676 default. This can cause a conflict when using POSIX functions, for
677 instance, when converting between data types such as floats and
678 strings, since the notation may differ between locales. To get
679 around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
680 right after initializing QApplication, QGuiApplication or QCoreApplication
681 to reset the locale that is used for number formatting to "C"-locale.
682
683 \sa QGuiApplication, QAbstractEventDispatcher, QEventLoop,
684 {Semaphores Example}, {Wait Conditions Example}
685*/
686
687/*!
688 \fn static QCoreApplication *QCoreApplication::instance()
689
690 Returns a pointer to the application's QCoreApplication (or
691 QGuiApplication/QApplication) instance.
692
693 If no instance has been allocated, \c null is returned.
694*/
695
696/*!
697 \internal
698 */
699QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
700#ifdef QT_NO_QOBJECT
701 : d_ptr(&p)
702#else
703 : QObject(p, 0)
704#endif
705{
706 d_func()->q_ptr = this;
707 // note: it is the subclasses' job to call
708 // QCoreApplicationPrivate::eventDispatcher->startingUp();
709}
710
711#ifndef QT_NO_QOBJECT
712/*!
713 Flushes the platform-specific event queues.
714
715 If you are doing graphical changes inside a loop that does not
716 return to the event loop on asynchronous window systems like X11
717 or double buffered window systems like Quartz (\macos and iOS), and you want to
718 visualize these changes immediately (e.g. Splash Screens), call
719 this function.
720
721 \sa sendPostedEvents()
722*/
723void QCoreApplication::flush()
724{
725 if (self && self->d_func()->eventDispatcher)
726 self->d_func()->eventDispatcher->flush();
727}
728#endif
729
730/*!
731 Constructs a Qt core application. Core applications are applications without
732 a graphical user interface. Such applications are used at the console or as
733 server processes.
734
735 The \a argc and \a argv arguments are processed by the application,
736 and made available in a more convenient form by the arguments()
737 function.
738
739 \warning The data referred to by \a argc and \a argv must stay valid
740 for the entire lifetime of the QCoreApplication object. In addition,
741 \a argc must be greater than zero and \a argv must contain at least
742 one valid character string.
743*/
744QCoreApplication::QCoreApplication(int &argc, char **argv
745#ifndef Q_QDOC
746 , int _internal
747#endif
748 )
749#ifdef QT_NO_QOBJECT
750 : d_ptr(new QCoreApplicationPrivate(argc, argv, _internal))
751#else
752 : QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
753#endif
754{
755 d_func()->q_ptr = this;
756 d_func()->init();
757#ifndef QT_NO_QOBJECT
758 QCoreApplicationPrivate::eventDispatcher->startingUp();
759#endif
760}
761
762
763void QCoreApplicationPrivate::init()
764{
765 Q_Q(QCoreApplication);
766
767 initLocale();
768
769 Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
770 QCoreApplication::self = q;
771
772 // Store app name/version (so they're still available after QCoreApplication is destroyed)
773 if (!coreappdata()->applicationNameSet)
774 coreappdata()->application = appName();
775
776 if (!coreappdata()->applicationVersionSet)
777 coreappdata()->applicationVersion = appVersion();
778
779 QLoggingRegistry::instance()->init();
780
781#ifndef QT_NO_LIBRARY
782 // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
783 // into account. If necessary, recompute right away and replay the manual changes on top of the
784 // new lib paths.
785 QStringList *appPaths = coreappdata()->app_libpaths.take();
786 QStringList *manualPaths = coreappdata()->manual_libpaths.take();
787 if (appPaths) {
788 if (manualPaths) {
789 // Replay the delta. As paths can only be prepended to the front or removed from
790 // anywhere in the list, we can just linearly scan the lists and find the items that
791 // have been removed. Once the original list is exhausted we know all the remaining
792 // items have been added.
793 QStringList newPaths(q->libraryPaths());
794 for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) {
795 if (--j < 0) {
796 newPaths.prepend((*manualPaths)[--i]);
797 } else if (--i < 0) {
798 newPaths.removeAll((*appPaths)[j]);
799 } else if ((*manualPaths)[i] != (*appPaths)[j]) {
800 newPaths.removeAll((*appPaths)[j]);
801 ++i; // try again with next item.
802 }
803 }
804 delete manualPaths;
805 coreappdata()->manual_libpaths.reset(new QStringList(newPaths));
806 }
807 delete appPaths;
808 }
809#endif
810
811#ifndef QT_NO_QOBJECT
812 // use the event dispatcher created by the app programmer (if any)
813 if (!eventDispatcher)
814 eventDispatcher = threadData->eventDispatcher.load();
815 // otherwise we create one
816 if (!eventDispatcher)
817 createEventDispatcher();
818 Q_ASSERT(eventDispatcher);
819
820 if (!eventDispatcher->parent()) {
821 eventDispatcher->moveToThread(threadData->thread);
822 eventDispatcher->setParent(q);
823 }
824
825 threadData->eventDispatcher = eventDispatcher;
826 eventDispatcherReady();
827#endif
828
829#ifdef QT_EVAL
830 extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
831 qt_core_eval_init(application_type);
832#endif
833
834 processCommandLineArguments();
835
836 qt_call_pre_routines();
837 qt_startup_hook();
838#ifndef QT_BOOTSTRAPPED
839 if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
840 reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
841#endif
842
843#ifndef QT_NO_QOBJECT
844 is_app_running = true; // No longer starting up.
845#endif
846}
847
848/*!
849 Destroys the QCoreApplication object.
850*/
851QCoreApplication::~QCoreApplication()
852{
853 qt_call_post_routines();
854
855 self = 0;
856#ifndef QT_NO_QOBJECT
857 QCoreApplicationPrivate::is_app_closing = true;
858 QCoreApplicationPrivate::is_app_running = false;
859#endif
860
861#if !defined(QT_NO_THREAD)
862 // Synchronize and stop the global thread pool threads.
863 QThreadPool *globalThreadPool = 0;
864 QT_TRY {
865 globalThreadPool = QThreadPool::globalInstance();
866 } QT_CATCH (...) {
867 // swallow the exception, since destructors shouldn't throw
868 }
869 if (globalThreadPool)
870 globalThreadPool->waitForDone();
871#endif
872
873#ifndef QT_NO_QOBJECT
874 d_func()->threadData->eventDispatcher = 0;
875 if (QCoreApplicationPrivate::eventDispatcher)
876 QCoreApplicationPrivate::eventDispatcher->closingDown();
877 QCoreApplicationPrivate::eventDispatcher = 0;
878#endif
879
880#ifndef QT_NO_LIBRARY
881 coreappdata()->app_libpaths.reset();
882 coreappdata()->manual_libpaths.reset();
883#endif
884}
885
886/*!
887 \since 5.3
888
889 Allows the application to run setuid on UNIX platforms if \a allow
890 is true.
891
892 If \a allow is false (the default) and Qt detects the application is
893 running with an effective user id different than the real user id,
894 the application will be aborted when a QCoreApplication instance is
895 created.
896
897 Qt is not an appropriate solution for setuid programs due to its
898 large attack surface. However some applications may be required
899 to run in this manner for historical reasons. This flag will
900 prevent Qt from aborting the application when this is detected,
901 and must be set before a QCoreApplication instance is created.
902
903 \note It is strongly recommended not to enable this option since
904 it introduces security risks.
905*/
906void QCoreApplication::setSetuidAllowed(bool allow)
907{
908 QCoreApplicationPrivate::setuidAllowed = allow;
909}
910
911/*!
912 \since 5.3
913
914 Returns true if the application is allowed to run setuid on UNIX
915 platforms.
916
917 \sa QCoreApplication::setSetuidAllowed()
918*/
919bool QCoreApplication::isSetuidAllowed()
920{
921 return QCoreApplicationPrivate::setuidAllowed;
922}
923
924
925/*!
926 Sets the attribute \a attribute if \a on is true;
927 otherwise clears the attribute.
928
929 \sa testAttribute()
930*/
931void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
932{
933 if (on)
934 QCoreApplicationPrivate::attribs |= 1 << attribute;
935 else
936 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
937}
938
939/*!
940 Returns \c true if attribute \a attribute is set;
941 otherwise returns \c false.
942
943 \sa setAttribute()
944 */
945bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
946{
947 return QCoreApplicationPrivate::testAttribute(attribute);
948}
949
950
951#ifndef QT_NO_QOBJECT
952
953/*!
954 \property QCoreApplication::quitLockEnabled
955
956 \brief Whether the use of the QEventLoopLocker feature can cause the
957 application to quit.
958
959 The default is \c true.
960
961 \sa QEventLoopLocker
962*/
963
964bool QCoreApplication::isQuitLockEnabled()
965{
966 return quitLockRefEnabled;
967}
968
969static bool doNotify(QObject *, QEvent *);
970
971void QCoreApplication::setQuitLockEnabled(bool enabled)
972{
973 quitLockRefEnabled = enabled;
974}
975
976/*!
977 \internal
978 \deprecated
979
980 This function is here to make it possible for Qt extensions to
981 hook into event notification without subclassing QApplication
982*/
983bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
984{
985 return notifyInternal2(receiver, event);
986}
987
988/*!
989 \internal
990 \since 5.6
991
992 This function is here to make it possible for Qt extensions to
993 hook into event notification without subclassing QApplication.
994*/
995bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
996{
997 bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
998 if (!self && selfRequired)
999 return false;
1000
1001 // Make it possible for Qt Script to hook into events even
1002 // though QApplication is subclassed...
1003 bool result = false;
1004 void *cbdata[] = { receiver, event, &result };
1005 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
1006 return result;
1007 }
1008
1009 // Qt enforces the rule that events can only be sent to objects in
1010 // the current thread, so receiver->d_func()->threadData is
1011 // equivalent to QThreadData::current(), just without the function
1012 // call overhead.
1013 QObjectPrivate *d = receiver->d_func();
1014 QThreadData *threadData = d->threadData;
1015 QScopedScopeLevelCounter scopeLevelCounter(threadData);
1016 if (!selfRequired)
1017 return doNotify(receiver, event);
1018 return self->notify(receiver, event);
1019}
1020
1021/*!
1022 Sends \a event to \a receiver: \a {receiver}->event(\a event).
1023 Returns the value that is returned from the receiver's event
1024 handler. Note that this function is called for all events sent to
1025 any object in any thread.
1026
1027 For certain types of events (e.g. mouse and key events),
1028 the event will be propagated to the receiver's parent and so on up to
1029 the top-level object if the receiver is not interested in the event
1030 (i.e., it returns \c false).
1031
1032 There are five different ways that events can be processed;
1033 reimplementing this virtual function is just one of them. All five
1034 approaches are listed below:
1035 \list 1
1036 \li Reimplementing \l {QWidget::}{paintEvent()}, \l {QWidget::}{mousePressEvent()} and so
1037 on. This is the most common, easiest, and least powerful way.
1038
1039 \li Reimplementing this function. This is very powerful, providing
1040 complete control; but only one subclass can be active at a time.
1041
1042 \li Installing an event filter on QCoreApplication::instance(). Such
1043 an event filter is able to process all events for all widgets, so
1044 it's just as powerful as reimplementing notify(); furthermore, it's
1045 possible to have more than one application-global event filter.
1046 Global event filters even see mouse events for
1047 \l{QWidget::isEnabled()}{disabled widgets}. Note that application
1048 event filters are only called for objects that live in the main
1049 thread.
1050
1051 \li Reimplementing QObject::event() (as QWidget does). If you do
1052 this you get Tab key presses, and you get to see the events before
1053 any widget-specific event filters.
1054
1055 \li Installing an event filter on the object. Such an event filter gets all
1056 the events, including Tab and Shift+Tab key press events, as long as they
1057 do not change the focus widget.
1058 \endlist
1059
1060 \b{Future direction:} This function will not be called for objects that live
1061 outside the main thread in Qt 6. Applications that need that functionality
1062 should find other solutions for their event inspection needs in the meantime.
1063 The change may be extended to the main thread, causing this function to be
1064 deprecated.
1065
1066 \warning If you override this function, you must ensure all threads that
1067 process events stop doing so before your application object begins
1068 destruction. This includes threads started by other libraries that you may be
1069 using, but does not apply to Qt's own threads.
1070
1071 \sa QObject::event(), installNativeEventFilter()
1072*/
1073
1074bool QCoreApplication::notify(QObject *receiver, QEvent *event)
1075{
1076 // no events are delivered after ~QCoreApplication() has started
1077 if (QCoreApplicationPrivate::is_app_closing)
1078 return true;
1079 return doNotify(receiver, event);
1080}
1081
1082static bool doNotify(QObject *receiver, QEvent *event)
1083{
1084 if (receiver == 0) { // serious error
1085 qWarning("QCoreApplication::notify: Unexpected null receiver");
1086 return true;
1087 }
1088
1089#ifndef QT_NO_DEBUG
1090 QCoreApplicationPrivate::checkReceiverThread(receiver);
1091#endif
1092
1093 return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event);
1094}
1095
1096bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
1097{
1098 // We can't access the application event filters outside of the main thread (race conditions)
1099 Q_ASSERT(receiver->d_func()->threadData->thread == mainThread());
1100
1101 if (extraData) {
1102 // application event filters are only called for objects in the GUI thread
1103 for (int i = 0; i < extraData->eventFilters.size(); ++i) {
1104 QObject *obj = extraData->eventFilters.at(i);
1105 if (!obj)
1106 continue;
1107 if (obj->d_func()->threadData != threadData) {
1108 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
1109 continue;
1110 }
1111 if (obj->eventFilter(receiver, event))
1112 return true;
1113 }
1114 }
1115 return false;
1116}
1117
1118bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
1119{
1120 if (receiver != QCoreApplication::instance() && receiver->d_func()->extraData) {
1121 for (int i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
1122 QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
1123 if (!obj)
1124 continue;
1125 if (obj->d_func()->threadData != receiver->d_func()->threadData) {
1126 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
1127 continue;
1128 }
1129 if (obj->eventFilter(receiver, event))
1130 return true;
1131 }
1132 }
1133 return false;
1134}
1135
1136/*!
1137 \internal
1138
1139 Helper function called by QCoreApplicationPrivate::notify() and qapplication.cpp
1140 */
1141bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
1142{
1143 // send to all application event filters (only does anything in the main thread)
1144 if (QCoreApplication::self
1145 && receiver->d_func()->threadData->thread == mainThread()
1146 && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event))
1147 return true;
1148 // send to all receiver event filters
1149 if (sendThroughObjectEventFilters(receiver, event))
1150 return true;
1151 // deliver the event
1152 return receiver->event(event);
1153}
1154
1155/*!
1156 Returns \c true if an application object has not been created yet;
1157 otherwise returns \c false.
1158
1159 \sa closingDown()
1160*/
1161
1162bool QCoreApplication::startingUp()
1163{
1164 return !QCoreApplicationPrivate::is_app_running;
1165}
1166
1167/*!
1168 Returns \c true if the application objects are being destroyed;
1169 otherwise returns \c false.
1170
1171 \sa startingUp()
1172*/
1173
1174bool QCoreApplication::closingDown()
1175{
1176 return QCoreApplicationPrivate::is_app_closing;
1177}
1178
1179
1180/*!
1181 Processes all pending events for the calling thread according to
1182 the specified \a flags until there are no more events to process.
1183
1184 You can call this function occasionally when your program is busy
1185 performing a long operation (e.g. copying a file).
1186
1187 In the event that you are running a local loop which calls this function
1188 continuously, without an event loop, the
1189 \l{QEvent::DeferredDelete}{DeferredDelete} events will
1190 not be processed. This can affect the behaviour of widgets,
1191 e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
1192 events to function properly. An alternative would be to call
1193 \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
1194 within that local loop.
1195
1196 Calling this function processes events only for the calling thread.
1197
1198 \threadsafe
1199
1200 \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
1201*/
1202void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1203{
1204 QThreadData *data = QThreadData::current();
1205 if (!data->hasEventDispatcher())
1206 return;
1207 data->eventDispatcher.load()->processEvents(flags);
1208}
1209
1210/*!
1211 \overload processEvents()
1212
1213 Processes pending events for the calling thread for \a maxtime
1214 milliseconds or until there are no more events to process,
1215 whichever is shorter.
1216
1217 You can call this function occasionally when your program is busy
1218 doing a long operation (e.g. copying a file).
1219
1220 Calling this function processes events only for the calling thread.
1221
1222 \threadsafe
1223
1224 \sa exec(), QTimer, QEventLoop::processEvents()
1225*/
1226void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
1227{
1228 // ### Qt 6: consider splitting this method into a public and a private
1229 // one, so that a user-invoked processEvents can be detected
1230 // and handled properly.
1231 QThreadData *data = QThreadData::current();
1232 if (!data->hasEventDispatcher())
1233 return;
1234 QElapsedTimer start;
1235 start.start();
1236 while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1237 if (start.elapsed() > maxtime)
1238 break;
1239 }
1240}
1241
1242/*****************************************************************************
1243 Main event loop wrappers
1244 *****************************************************************************/
1245
1246/*!
1247 Enters the main event loop and waits until exit() is called. Returns
1248 the value that was passed to exit() (which is 0 if exit() is called via
1249 quit()).
1250
1251 It is necessary to call this function to start event handling. The
1252 main event loop receives events from the window system and
1253 dispatches these to the application widgets.
1254
1255 To make your application perform idle processing (by executing a
1256 special function whenever there are no pending events), use a
1257 QTimer with 0 timeout. More advanced idle processing schemes can
1258 be achieved using processEvents().
1259
1260 We recommend that you connect clean-up code to the
1261 \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1262 your application's \c{main()} function because on some platforms the
1263 exec() call may not return. For example, on Windows
1264 when the user logs off, the system terminates the process after Qt
1265 closes all top-level windows. Hence, there is no guarantee that the
1266 application will have time to exit its event loop and execute code at
1267 the end of the \c{main()} function after the exec()
1268 call.
1269
1270 \sa quit(), exit(), processEvents(), QApplication::exec()
1271*/
1272int QCoreApplication::exec()
1273{
1274 if (!QCoreApplicationPrivate::checkInstance("exec"))
1275 return -1;
1276
1277 QThreadData *threadData = self->d_func()->threadData;
1278 if (threadData != QThreadData::current()) {
1279 qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1280 return -1;
1281 }
1282 if (!threadData->eventLoops.isEmpty()) {
1283 qWarning("QCoreApplication::exec: The event loop is already running");
1284 return -1;
1285 }
1286
1287 threadData->quitNow = false;
1288 QEventLoop eventLoop;
1289 self->d_func()->in_exec = true;
1290 self->d_func()->aboutToQuitEmitted = false;
1291 int returnCode = eventLoop.exec();
1292 threadData->quitNow = false;
1293
1294 if (self)
1295 self->d_func()->execCleanup();
1296
1297 return returnCode;
1298}
1299
1300
1301// Cleanup after eventLoop is done executing in QCoreApplication::exec().
1302// This is for use cases in which QCoreApplication is instantiated by a
1303// library and not by an application executable, for example, Active X
1304// servers.
1305
1306void QCoreApplicationPrivate::execCleanup()
1307{
1308 threadData->quitNow = false;
1309 in_exec = false;
1310 if (!aboutToQuitEmitted)
1311 emit q_func()->aboutToQuit(QCoreApplication::QPrivateSignal());
1312 aboutToQuitEmitted = true;
1313 QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1314}
1315
1316
1317/*!
1318 Tells the application to exit with a return code.
1319
1320 After this function has been called, the application leaves the
1321 main event loop and returns from the call to exec(). The exec()
1322 function returns \a returnCode. If the event loop is not running,
1323 this function does nothing.
1324
1325 By convention, a \a returnCode of 0 means success, and any non-zero
1326 value indicates an error.
1327
1328 Note that unlike the C library function of the same name, this
1329 function \e does return to the caller -- it is event processing that
1330 stops.
1331
1332 \sa quit(), exec()
1333*/
1334void QCoreApplication::exit(int returnCode)
1335{
1336 if (!self)
1337 return;
1338 QThreadData *data = self->d_func()->threadData;
1339 data->quitNow = true;
1340 for (int i = 0; i < data->eventLoops.size(); ++i) {
1341 QEventLoop *eventLoop = data->eventLoops.at(i);
1342 eventLoop->exit(returnCode);
1343 }
1344}
1345
1346/*****************************************************************************
1347 QCoreApplication management of posted events
1348 *****************************************************************************/
1349
1350/*!
1351 \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1352
1353 Sends event \a event directly to receiver \a receiver, using the
1354 notify() function. Returns the value that was returned from the
1355 event handler.
1356
1357 The event is \e not deleted when the event has been sent. The normal
1358 approach is to create the event on the stack, for example:
1359
1360 \snippet code/src_corelib_kernel_qcoreapplication.cpp 0
1361
1362 \sa postEvent(), notify()
1363*/
1364
1365/*!
1366 \since 4.3
1367
1368 Adds the event \a event, with the object \a receiver as the
1369 receiver of the event, to an event queue and returns immediately.
1370
1371 The event must be allocated on the heap since the post event queue
1372 will take ownership of the event and delete it once it has been
1373 posted. It is \e {not safe} to access the event after
1374 it has been posted.
1375
1376 When control returns to the main event loop, all events that are
1377 stored in the queue will be sent using the notify() function.
1378
1379 Events are sorted in descending \a priority order, i.e. events
1380 with a high \a priority are queued before events with a lower \a
1381 priority. The \a priority can be any integer value, i.e. between
1382 INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1383 details. Events with equal \a priority will be processed in the
1384 order posted.
1385
1386 \threadsafe
1387
1388 \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1389*/
1390void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1391{
1392 if (receiver == 0) {
1393 qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1394 delete event;
1395 return;
1396 }
1397
1398 QThreadData * volatile * pdata = &receiver->d_func()->threadData;
1399 QThreadData *data = *pdata;
1400 if (!data) {
1401 // posting during destruction? just delete the event to prevent a leak
1402 delete event;
1403 return;
1404 }
1405
1406 // lock the post event mutex
1407 data->postEventList.mutex.lock();
1408
1409 // if object has moved to another thread, follow it
1410 while (data != *pdata) {
1411 data->postEventList.mutex.unlock();
1412
1413 data = *pdata;
1414 if (!data) {
1415 // posting during destruction? just delete the event to prevent a leak
1416 delete event;
1417 return;
1418 }
1419
1420 data->postEventList.mutex.lock();
1421 }
1422
1423 QMutexUnlocker locker(&data->postEventList.mutex);
1424
1425 // if this is one of the compressible events, do compression
1426 if (receiver->d_func()->postedEvents
1427 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1428 return;
1429 }
1430
1431 if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1432 // remember the current running eventloop for DeferredDelete
1433 // events posted in the receiver's thread.
1434
1435 // Events sent by non-Qt event handlers (such as glib) may not
1436 // have the scopeLevel set correctly. The scope level makes sure that
1437 // code like this:
1438 // foo->deleteLater();
1439 // qApp->processEvents(); // without passing QEvent::DeferredDelete
1440 // will not cause "foo" to be deleted before returning to the event loop.
1441
1442 // If the scope level is 0 while loopLevel != 0, we are called from a
1443 // non-conformant code path, and our best guess is that the scope level
1444 // should be 1. (Loop level 0 is special: it means that no event loops
1445 // are running.)
1446 int loopLevel = data->loopLevel;
1447 int scopeLevel = data->scopeLevel;
1448 if (scopeLevel == 0 && loopLevel != 0)
1449 scopeLevel = 1;
1450 static_cast<QDeferredDeleteEvent *>(event)->level = loopLevel + scopeLevel;
1451 }
1452
1453 // delete the event on exceptions to protect against memory leaks till the event is
1454 // properly owned in the postEventList
1455 QScopedPointer<QEvent> eventDeleter(event);
1456 data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1457 eventDeleter.take();
1458 event->posted = true;
1459 ++receiver->d_func()->postedEvents;
1460 data->canWait = false;
1461 locker.unlock();
1462
1463 QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
1464 if (dispatcher)
1465 dispatcher->wakeUp();
1466}
1467
1468/*!
1469 \internal
1470 Returns \c true if \a event was compressed away (possibly deleted) and should not be added to the list.
1471*/
1472bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1473{
1474#ifdef Q_OS_WIN
1475 Q_ASSERT(event);
1476 Q_ASSERT(receiver);
1477 Q_ASSERT(postedEvents);
1478
1479 // compress posted timers to this object.
1480 if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1481 int timerId = ((QTimerEvent *) event)->timerId();
1482 for (int i=0; i<postedEvents->size(); ++i) {
1483 const QPostEvent &e = postedEvents->at(i);
1484 if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1485 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1486 delete event;
1487 return true;
1488 }
1489 }
1490 } else
1491#endif
1492 if ((event->type() == QEvent::DeferredDelete
1493 || event->type() == QEvent::Quit)
1494 && receiver->d_func()->postedEvents > 0) {
1495 for (int i = 0; i < postedEvents->size(); ++i) {
1496 const QPostEvent &cur = postedEvents->at(i);
1497 if (cur.receiver != receiver
1498 || cur.event == 0
1499 || cur.event->type() != event->type())
1500 continue;
1501 // found an event for this receiver
1502 delete event;
1503 return true;
1504 }
1505 }
1506 return false;
1507}
1508
1509/*!
1510 Immediately dispatches all events which have been previously queued
1511 with QCoreApplication::postEvent() and which are for the object \a receiver
1512 and have the event type \a event_type.
1513
1514 Events from the window system are \e not dispatched by this
1515 function, but by processEvents().
1516
1517 If \a receiver is null, the events of \a event_type are sent for all
1518 objects. If \a event_type is 0, all the events are sent for \a receiver.
1519
1520 \note This method must be called from the thread in which its QObject
1521 parameter, \a receiver, lives.
1522
1523 \sa flush(), postEvent()
1524*/
1525void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1526{
1527 // ### Qt 6: consider splitting this method into a public and a private
1528 // one, so that a user-invoked sendPostedEvents can be detected
1529 // and handled properly.
1530 QThreadData *data = QThreadData::current();
1531
1532 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1533}
1534
1535void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1536 QThreadData *data)
1537{
1538 if (event_type == -1) {
1539 // we were called by an obsolete event dispatcher.
1540 event_type = 0;
1541 }
1542
1543 if (receiver && receiver->d_func()->threadData != data) {
1544 qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1545 "posted events for objects in another thread");
1546 return;
1547 }
1548
1549 ++data->postEventList.recursion;
1550
1551 QMutexLocker locker(&data->postEventList.mutex);
1552
1553 // by default, we assume that the event dispatcher can go to sleep after
1554 // processing all events. if any new events are posted while we send
1555 // events, canWait will be set to false.
1556 data->canWait = (data->postEventList.size() == 0);
1557
1558 if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1559 --data->postEventList.recursion;
1560 return;
1561 }
1562
1563 data->canWait = true;
1564
1565 // okay. here is the tricky loop. be careful about optimizing
1566 // this, it looks the way it does for good reasons.
1567 int startOffset = data->postEventList.startOffset;
1568 int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1569 data->postEventList.insertionOffset = data->postEventList.size();
1570
1571 // Exception-safe cleaning up without the need for a try/catch block
1572 struct CleanUp {
1573 QObject *receiver;
1574 int event_type;
1575 QThreadData *data;
1576 bool exceptionCaught;
1577
1578 inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
1579 receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
1580 {}
1581 inline ~CleanUp()
1582 {
1583 if (exceptionCaught) {
1584 // since we were interrupted, we need another pass to make sure we clean everything up
1585 data->canWait = false;
1586 }
1587
1588 --data->postEventList.recursion;
1589 if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
1590 data->eventDispatcher.load()->wakeUp();
1591
1592 // clear the global list, i.e. remove everything that was
1593 // delivered.
1594 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1595 const QPostEventList::iterator it = data->postEventList.begin();
1596 data->postEventList.erase(it, it + data->postEventList.startOffset);
1597 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1598 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1599 data->postEventList.startOffset = 0;
1600 }
1601 }
1602 };
1603 CleanUp cleanup(receiver, event_type, data);
1604
1605 while (i < data->postEventList.size()) {
1606 // avoid live-lock
1607 if (i >= data->postEventList.insertionOffset)
1608 break;
1609
1610 const QPostEvent &pe = data->postEventList.at(i);
1611 ++i;
1612
1613 if (!pe.event)
1614 continue;
1615 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1616 data->canWait = false;
1617 continue;
1618 }
1619
1620 if (pe.event->type() == QEvent::DeferredDelete) {
1621 // DeferredDelete events are sent either
1622 // 1) when the event loop that posted the event has returned; or
1623 // 2) if explicitly requested (with QEvent::DeferredDelete) for
1624 // events posted by the current event loop; or
1625 // 3) if the event was posted before the outermost event loop.
1626
1627 int eventLevel = static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel();
1628 int loopLevel = data->loopLevel + data->scopeLevel;
1629 const bool allowDeferredDelete =
1630 (eventLevel > loopLevel
1631 || (!eventLevel && loopLevel > 0)
1632 || (event_type == QEvent::DeferredDelete
1633 && eventLevel == loopLevel));
1634 if (!allowDeferredDelete) {
1635 // cannot send deferred delete
1636 if (!event_type && !receiver) {
1637 // we must copy it first; we want to re-post the event
1638 // with the event pointer intact, but we can't delay
1639 // nulling the event ptr until after re-posting, as
1640 // addEvent may invalidate pe.
1641 QPostEvent pe_copy = pe;
1642
1643 // null out the event so if sendPostedEvents recurses, it
1644 // will ignore this one, as it's been re-posted.
1645 const_cast<QPostEvent &>(pe).event = 0;
1646
1647 // re-post the copied event so it isn't lost
1648 data->postEventList.addEvent(pe_copy);
1649 }
1650 continue;
1651 }
1652 }
1653
1654 // first, we diddle the event so that we can deliver
1655 // it, and that no one will try to touch it later.
1656 pe.event->posted = false;
1657 QEvent *e = pe.event;
1658 QObject * r = pe.receiver;
1659
1660 --r->d_func()->postedEvents;
1661 Q_ASSERT(r->d_func()->postedEvents >= 0);
1662
1663 // next, update the data structure so that we're ready
1664 // for the next event.
1665 const_cast<QPostEvent &>(pe).event = 0;
1666
1667 struct MutexUnlocker
1668 {
1669 QMutexLocker &m;
1670 MutexUnlocker(QMutexLocker &m) : m(m) { m.unlock(); }
1671 ~MutexUnlocker() { m.relock(); }
1672 };
1673 MutexUnlocker unlocker(locker);
1674
1675 QScopedPointer<QEvent> event_deleter(e); // will delete the event (with the mutex unlocked)
1676
1677 // after all that work, it's time to deliver the event.
1678 QCoreApplication::sendEvent(r, e);
1679
1680 // careful when adding anything below this point - the
1681 // sendEvent() call might invalidate any invariants this
1682 // function depends on.
1683 }
1684
1685 cleanup.exceptionCaught = false;
1686}
1687
1688/*!
1689 \since 4.3
1690
1691 Removes all events of the given \a eventType that were posted
1692 using postEvent() for \a receiver.
1693
1694 The events are \e not dispatched, instead they are removed from
1695 the queue. You should never need to call this function. If you do
1696 call it, be aware that killing events may cause \a receiver to
1697 break one or more invariants.
1698
1699 If \a receiver is null, the events of \a eventType are removed for
1700 all objects. If \a eventType is 0, all the events are removed for
1701 \a receiver. You should never call this function with \a eventType
1702 of 0. If you do call it in this way, be aware that killing events
1703 may cause \a receiver to break one or more invariants.
1704
1705 \threadsafe
1706*/
1707
1708void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1709{
1710 QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
1711 QMutexLocker locker(&data->postEventList.mutex);
1712
1713 // the QObject destructor calls this function directly. this can
1714 // happen while the event loop is in the middle of posting events,
1715 // and when we get here, we may not have any more posted events
1716 // for this object.
1717 if (receiver && !receiver->d_func()->postedEvents)
1718 return;
1719
1720 //we will collect all the posted events for the QObject
1721 //and we'll delete after the mutex was unlocked
1722 QVarLengthArray<QEvent*> events;
1723 int n = data->postEventList.size();
1724 int j = 0;
1725
1726 for (int i = 0; i < n; ++i) {
1727 const QPostEvent &pe = data->postEventList.at(i);
1728
1729 if ((!receiver || pe.receiver == receiver)
1730 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1731 --pe.receiver->d_func()->postedEvents;
1732 pe.event->posted = false;
1733 events.append(pe.event);
1734 const_cast<QPostEvent &>(pe).event = 0;
1735 } else if (!data->postEventList.recursion) {
1736 if (i != j)
1737 qSwap(data->postEventList[i], data->postEventList[j]);
1738 ++j;
1739 }
1740 }
1741
1742#ifdef QT_DEBUG
1743 if (receiver && eventType == 0) {
1744 Q_ASSERT(!receiver->d_func()->postedEvents);
1745 }
1746#endif
1747
1748 if (!data->postEventList.recursion) {
1749 // truncate list
1750 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1751 }
1752
1753 locker.unlock();
1754 for (int i = 0; i < events.count(); ++i) {
1755 delete events[i];
1756 }
1757}
1758
1759/*!
1760 Removes \a event from the queue of posted events, and emits a
1761 warning message if appropriate.
1762
1763 \warning This function can be \e really slow. Avoid using it, if
1764 possible.
1765
1766 \threadsafe
1767*/
1768
1769void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1770{
1771 if (!event || !event->posted)
1772 return;
1773
1774 QThreadData *data = QThreadData::current();
1775
1776 QMutexLocker locker(&data->postEventList.mutex);
1777
1778 if (data->postEventList.size() == 0) {
1779#if defined(QT_DEBUG)
1780 qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1781 (void*)event, event->type());
1782 return;
1783#endif
1784 }
1785
1786 for (int i = 0; i < data->postEventList.size(); ++i) {
1787 const QPostEvent & pe = data->postEventList.at(i);
1788 if (pe.event == event) {
1789#ifndef QT_NO_DEBUG
1790 qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1791 event->type(),
1792 pe.receiver->metaObject()->className(),
1793 pe.receiver->objectName().toLocal8Bit().data());
1794#endif
1795 --pe.receiver->d_func()->postedEvents;
1796 pe.event->posted = false;
1797 delete pe.event;
1798 const_cast<QPostEvent &>(pe).event = 0;
1799 return;
1800 }
1801 }
1802}
1803
1804/*!\reimp
1805
1806*/
1807bool QCoreApplication::event(QEvent *e)
1808{
1809 if (e->type() == QEvent::Quit) {
1810 quit();
1811 return true;
1812 }
1813 return QObject::event(e);
1814}
1815
1816/*! \enum QCoreApplication::Encoding
1817 \obsolete
1818
1819 This enum type used to define the 8-bit encoding of character string
1820 arguments to translate(). This enum is now obsolete and UTF-8 will be
1821 used in all cases.
1822
1823 \value UnicodeUTF8 UTF-8.
1824 \omitvalue Latin1
1825 \omitvalue DefaultCodec UTF-8.
1826 \omitvalue CodecForTr
1827
1828 \sa QObject::tr(), QString::fromUtf8()
1829*/
1830
1831void QCoreApplicationPrivate::ref()
1832{
1833 quitLockRef.ref();
1834}
1835
1836void QCoreApplicationPrivate::deref()
1837{
1838 if (!quitLockRef.deref())
1839 maybeQuit();
1840}
1841
1842void QCoreApplicationPrivate::maybeQuit()
1843{
1844 if (quitLockRef.load() == 0 && in_exec && quitLockRefEnabled && shouldQuit())
1845 QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit));
1846}
1847
1848/*!
1849 Tells the application to exit with return code 0 (success).
1850 Equivalent to calling QCoreApplication::exit(0).
1851
1852 It's common to connect the QGuiApplication::lastWindowClosed() signal
1853 to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1854 signals in QAction, QMenu, or QMenuBar to it.
1855
1856 Example:
1857
1858 \snippet code/src_corelib_kernel_qcoreapplication.cpp 1
1859
1860 \sa exit(), aboutToQuit(), QGuiApplication::lastWindowClosed()
1861*/
1862
1863void QCoreApplication::quit()
1864{
1865 exit(0);
1866}
1867
1868/*!
1869 \fn void QCoreApplication::aboutToQuit()
1870
1871 This signal is emitted when the application is about to quit the
1872 main event loop, e.g. when the event loop level drops to zero.
1873 This may happen either after a call to quit() from inside the
1874 application or when the user shuts down the entire desktop session.
1875
1876 The signal is particularly useful if your application has to do some
1877 last-second cleanup. Note that no user interaction is possible in
1878 this state.
1879
1880 \sa quit()
1881*/
1882
1883#endif // QT_NO_QOBJECT
1884
1885#ifndef QT_NO_TRANSLATION
1886/*!
1887 Adds the translation file \a translationFile to the list of
1888 translation files to be used for translations.
1889
1890 Multiple translation files can be installed. Translations are
1891 searched for in the reverse order in which they were installed,
1892 so the most recently installed translation file is searched first
1893 and the first translation file installed is searched last.
1894 The search stops as soon as a translation containing a matching
1895 string is found.
1896
1897 Installing or removing a QTranslator, or changing an installed QTranslator
1898 generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
1899 QCoreApplication instance. A QGuiApplication instance will propagate the event
1900 to all toplevel windows, where a reimplementation of changeEvent can
1901 re-translate the user interface by passing user-visible strings via the
1902 tr() function to the respective property setters. User-interface classes
1903 generated by Qt Designer provide a \c retranslateUi() function that can be
1904 called.
1905
1906 The function returns \c true on success and false on failure.
1907
1908 \sa removeTranslator(), translate(), QTranslator::load(), {Dynamic Translation}
1909*/
1910
1911bool QCoreApplication::installTranslator(QTranslator *translationFile)
1912{
1913 if (!translationFile)
1914 return false;
1915
1916 if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
1917 return false;
1918 QCoreApplicationPrivate *d = self->d_func();
1919 d->translators.prepend(translationFile);
1920
1921#ifndef QT_NO_TRANSLATION_BUILDER
1922 if (translationFile->isEmpty())
1923 return false;
1924#endif
1925
1926#ifndef QT_NO_QOBJECT
1927 QEvent ev(QEvent::LanguageChange);
1928 QCoreApplication::sendEvent(self, &ev);
1929#endif
1930
1931 return true;
1932}
1933
1934/*!
1935 Removes the translation file \a translationFile from the list of
1936 translation files used by this application. (It does not delete the
1937 translation file from the file system.)
1938
1939 The function returns \c true on success and false on failure.
1940
1941 \sa installTranslator(), translate(), QObject::tr()
1942*/
1943
1944bool QCoreApplication::removeTranslator(QTranslator *translationFile)
1945{
1946 if (!translationFile)
1947 return false;
1948 if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
1949 return false;
1950 QCoreApplicationPrivate *d = self->d_func();
1951 if (d->translators.removeAll(translationFile)) {
1952#ifndef QT_NO_QOBJECT
1953 if (!self->closingDown()) {
1954 QEvent ev(QEvent::LanguageChange);
1955 QCoreApplication::sendEvent(self, &ev);
1956 }
1957#endif
1958 return true;
1959 }
1960 return false;
1961}
1962
1963static void replacePercentN(QString *result, int n)
1964{
1965 if (n >= 0) {
1966 int percentPos = 0;
1967 int len = 0;
1968 while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
1969 len = 1;
1970 QString fmt;
1971 if (result->at(percentPos + len) == QLatin1Char('L')) {
1972 ++len;
1973 fmt = QLatin1String("%L1");
1974 } else {
1975 fmt = QLatin1String("%1");
1976 }
1977 if (result->at(percentPos + len) == QLatin1Char('n')) {
1978 fmt = fmt.arg(n);
1979 ++len;
1980 result->replace(percentPos, len, fmt);
1981 len = fmt.length();
1982 }
1983 }
1984 }
1985}
1986
1987/*!
1988 \reentrant
1989
1990 Returns the translation text for \a sourceText, by querying the
1991 installed translation files. The translation files are searched
1992 from the most recently installed file back to the first
1993 installed file.
1994
1995 QObject::tr() provides this functionality more conveniently.
1996
1997 \a context is typically a class name (e.g., "MyDialog") and \a
1998 sourceText is either English text or a short identifying text.
1999
2000 \a disambiguation is an identifying string, for when the same \a
2001 sourceText is used in different roles within the same context. By
2002 default, it is null.
2003
2004 See the \l QTranslator and \l QObject::tr() documentation for
2005 more information about contexts, disambiguations and comments.
2006
2007 \a n is used in conjunction with \c %n to support plural forms.
2008 See QObject::tr() for details.
2009
2010 If none of the translation files contain a translation for \a
2011 sourceText in \a context, this function returns a QString
2012 equivalent of \a sourceText.
2013
2014 This function is not virtual. You can use alternative translation
2015 techniques by subclassing \l QTranslator.
2016
2017 \warning This method is reentrant only if all translators are
2018 installed \e before calling this method. Installing or removing
2019 translators while performing translations is not supported. Doing
2020 so will most likely result in crashes or other undesirable
2021 behavior.
2022
2023 \sa QObject::tr(), installTranslator()
2024*/
2025QString QCoreApplication::translate(const char *context, const char *sourceText,
2026 const char *disambiguation, int n)
2027{
2028 QString result;
2029
2030 if (!sourceText)
2031 return result;
2032
2033 if (self && !self->d_func()->translators.isEmpty()) {
2034 QList<QTranslator*>::ConstIterator it;
2035 QTranslator *translationFile;
2036 for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
2037 translationFile = *it;
2038 result = translationFile->translate(context, sourceText, disambiguation, n);
2039 if (!result.isNull())
2040 break;
2041 }
2042 }
2043
2044 if (result.isNull())
2045 result = QString::fromUtf8(sourceText);
2046
2047 replacePercentN(&result, n);
2048 return result;
2049}
2050
2051/*! \fn static QString QCoreApplication::translate(const char *context, const char *key, const char *disambiguation, Encoding encoding, int n = -1)
2052
2053 \obsolete
2054*/
2055
2056// Declared in qglobal.h
2057QString qtTrId(const char *id, int n)
2058{
2059 return QCoreApplication::translate(0, id, 0, n);
2060}
2061
2062bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
2063{
2064 return QCoreApplication::self
2065 && QCoreApplication::self->d_func()->translators.contains(translator);
2066}
2067
2068#else
2069
2070QString QCoreApplication::translate(const char *context, const char *sourceText,
2071 const char *disambiguation, int n)
2072{
2073 Q_UNUSED(context)
2074 Q_UNUSED(disambiguation)
2075 QString ret = QString::fromUtf8(sourceText);
2076 if (n >= 0)
2077 ret.replace(QLatin1String("%n"), QString::number(n));
2078 return ret;
2079}
2080
2081#endif //QT_NO_TRANSLATION
2082
2083// Makes it possible to point QCoreApplication to a custom location to ensure
2084// the directory is added to the patch, and qt.conf and deployed plugins are
2085// found from there. This is for use cases in which QGuiApplication is
2086// instantiated by a library and not by an application executable, for example,
2087// Active X servers.
2088
2089void QCoreApplicationPrivate::setApplicationFilePath(const QString &path)
2090{
2091 if (QCoreApplicationPrivate::cachedApplicationFilePath)
2092 *QCoreApplicationPrivate::cachedApplicationFilePath = path;
2093 else
2094 QCoreApplicationPrivate::cachedApplicationFilePath = new QString(path);
2095}
2096
2097/*!
2098 Returns the directory that contains the application executable.
2099
2100 For example, if you have installed Qt in the \c{C:\Qt}
2101 directory, and you run the \c{regexp} example, this function will
2102 return "C:/Qt/examples/tools/regexp".
2103
2104 On \macos and iOS this will point to the directory actually containing
2105 the executable, which may be inside an application bundle (if the
2106 application is bundled).
2107
2108 \warning On Linux, this function will try to get the path from the
2109 \c {/proc} file system. If that fails, it assumes that \c
2110 {argv[0]} contains the absolute file name of the executable. The
2111 function also assumes that the current directory has not been
2112 changed by the application.
2113
2114 \sa applicationFilePath()
2115*/
2116QString QCoreApplication::applicationDirPath()
2117{
2118 if (!self) {
2119 qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
2120 return QString();
2121 }
2122
2123 QCoreApplicationPrivate *d = self->d_func();
2124 if (d->cachedApplicationDirPath.isNull())
2125 d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
2126 return d->cachedApplicationDirPath;
2127}
2128
2129/*!
2130 Returns the file path of the application executable.
2131
2132 For example, if you have installed Qt in the \c{/usr/local/qt}
2133 directory, and you run the \c{regexp} example, this function will
2134 return "/usr/local/qt/examples/tools/regexp/regexp".
2135
2136 \warning On Linux, this function will try to get the path from the
2137 \c {/proc} file system. If that fails, it assumes that \c
2138 {argv[0]} contains the absolute file name of the executable. The
2139 function also assumes that the current directory has not been
2140 changed by the application.
2141
2142 \sa applicationDirPath()
2143*/
2144QString QCoreApplication::applicationFilePath()
2145{
2146 if (!self) {
2147 qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2148 return QString();
2149 }
2150
2151 QCoreApplicationPrivate *d = self->d_func();
2152
2153 if (d->argc) {
2154 static const char *procName = d->argv[0];
2155 if (qstrcmp(procName, d->argv[0]) != 0) {
2156 // clear the cache if the procname changes, so we reprocess it.
2157 QCoreApplicationPrivate::clearApplicationFilePath();
2158 procName = d->argv[0];
2159 }
2160 }
2161
2162 if (QCoreApplicationPrivate::cachedApplicationFilePath)
2163 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2164
2165#if defined(Q_OS_WIN)
2166 QCoreApplicationPrivate::setApplicationFilePath(QFileInfo(qAppFileName()).filePath());
2167 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2168#elif defined(Q_OS_MAC)
2169 QString qAppFileName_str = qAppFileName();
2170 if(!qAppFileName_str.isEmpty()) {
2171 QFileInfo fi(qAppFileName_str);
2172 if (fi.exists()) {
2173 QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
2174 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2175 }
2176 }
2177#endif
2178#if defined( Q_OS_UNIX )
2179# if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
2180 // Try looking for a /proc/<pid>/exe symlink first which points to
2181 // the absolute path of the executable
2182 QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
2183 if (pfi.exists() && pfi.isSymLink()) {
2184 QCoreApplicationPrivate::setApplicationFilePath(pfi.canonicalFilePath());
2185 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2186 }
2187# endif
2188 if (!arguments().isEmpty()) {
2189 QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
2190 QString absPath;
2191
2192 if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
2193 /*
2194 If argv0 starts with a slash, it is already an absolute
2195 file path.
2196 */
2197 absPath = argv0;
2198 } else if (argv0.contains(QLatin1Char('/'))) {
2199 /*
2200 If argv0 contains one or more slashes, it is a file path
2201 relative to the current directory.
2202 */
2203 absPath = QDir::current().absoluteFilePath(argv0);
2204 } else {
2205 /*
2206 Otherwise, the file path has to be determined using the
2207 PATH environment variable.
2208 */
2209 absPath = QStandardPaths::findExecutable(argv0);
2210 }
2211
2212 absPath = QDir::cleanPath(absPath);
2213
2214 QFileInfo fi(absPath);
2215 if (fi.exists()) {
2216 QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
2217 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2218 }
2219 }
2220
2221#endif
2222 return QString();
2223}
2224
2225/*!
2226 \since 4.4
2227
2228 Returns the current process ID for the application.
2229*/
2230qint64 QCoreApplication::applicationPid()
2231{
2232#if defined(Q_OS_WIN)
2233 return GetCurrentProcessId();
2234#elif defined(Q_OS_VXWORKS)
2235 return (pid_t) taskIdCurrent;
2236#else
2237 return getpid();
2238#endif
2239}
2240
2241/*!
2242 \since 4.1
2243
2244 Returns the list of command-line arguments.
2245
2246 Usually arguments().at(0) is the program name, arguments().at(1)
2247 is the first argument, and arguments().last() is the last
2248 argument. See the note below about Windows.
2249
2250 Calling this function is slow - you should store the result in a variable
2251 when parsing the command line.
2252
2253 \warning On Unix, this list is built from the argc and argv parameters passed
2254 to the constructor in the main() function. The string-data in argv is
2255 interpreted using QString::fromLocal8Bit(); hence it is not possible to
2256 pass, for example, Japanese command line arguments on a system that runs in a
2257 Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2258 Unicode-based.
2259
2260 On Windows, the list is built from the argc and argv parameters only if
2261 modified argv/argc parameters are passed to the constructor. In that case,
2262 encoding problems might occur.
2263
2264 Otherwise, the arguments() are constructed from the return value of
2265 \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2266 As a result of this, the string given by arguments().at(0) might not be
2267 the program name on Windows, depending on how the application was started.
2268
2269 \sa applicationFilePath(), QCommandLineParser
2270*/
2271
2272QStringList QCoreApplication::arguments()
2273{
2274 QStringList list;
2275
2276 if (!self) {
2277 qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2278 return list;
2279 }
2280 const int ac = self->d_func()->argc;
2281 char ** const av = self->d_func()->argv;
2282 list.reserve(ac);
2283
2284#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
2285 // On Windows, it is possible to pass Unicode arguments on
2286 // the command line. To restore those, we split the command line
2287 // and filter out arguments that were deleted by derived application
2288 // classes by index.
2289 QString cmdline = QString::fromWCharArray(GetCommandLine());
2290
2291 const QCoreApplicationPrivate *d = self->d_func();
2292 if (d->origArgv) {
2293 const QStringList allArguments = qWinCmdArgs(cmdline);
2294 Q_ASSERT(allArguments.size() == d->origArgc);
2295 for (int i = 0; i < d->origArgc; ++i) {
2296 if (contains(ac, av, d->origArgv[i]))
2297 list.append(allArguments.at(i));
2298 }
2299 return list;
2300 } // Fall back to rebuilding from argv/argc when a modified argv was passed.
2301#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
2302
2303 for (int a = 0; a < ac; ++a) {
2304 list << QString::fromLocal8Bit(av[a]);
2305 }
2306
2307 return list;
2308}
2309
2310/*!
2311 \property QCoreApplication::organizationName
2312 \brief the name of the organization that wrote this application
2313
2314 The value is used by the QSettings class when it is constructed
2315 using the empty constructor. This saves having to repeat this
2316 information each time a QSettings object is created.
2317
2318 On Mac, QSettings uses \l {QCoreApplication::}{organizationDomain()} as the organization
2319 if it's not an empty string; otherwise it uses
2320 organizationName(). On all other platforms, QSettings uses
2321 organizationName() as the organization.
2322
2323 \sa organizationDomain, applicationName
2324*/
2325
2326/*!
2327 \fn void QCoreApplication::organizationNameChanged()
2328 \internal
2329
2330 While not useful from C++ due to how organizationName is normally set once on
2331 startup, this is still needed for QML so that bindings are reevaluated after
2332 that initial change.
2333*/
2334void QCoreApplication::setOrganizationName(const QString &orgName)
2335{
2336 if (coreappdata()->orgName == orgName)
2337 return;
2338 coreappdata()->orgName = orgName;
2339#ifndef QT_NO_QOBJECT
2340 if (QCoreApplication::self)
2341 emit QCoreApplication::self->organizationNameChanged();
2342#endif
2343}
2344
2345QString QCoreApplication::organizationName()
2346{
2347 return coreappdata()->orgName;
2348}
2349
2350/*!
2351 \property QCoreApplication::organizationDomain
2352 \brief the Internet domain of the organization that wrote this application
2353
2354 The value is used by the QSettings class when it is constructed
2355 using the empty constructor. This saves having to repeat this
2356 information each time a QSettings object is created.
2357
2358 On Mac, QSettings uses organizationDomain() as the organization
2359 if it's not an empty string; otherwise it uses organizationName().
2360 On all other platforms, QSettings uses organizationName() as the
2361 organization.
2362
2363 \sa organizationName, applicationName, applicationVersion
2364*/
2365/*!
2366 \fn void QCoreApplication::organizationDomainChanged()
2367 \internal
2368
2369 Primarily for QML, see organizationNameChanged.
2370*/
2371void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2372{
2373 if (coreappdata()->orgDomain == orgDomain)
2374 return;
2375 coreappdata()->orgDomain = orgDomain;
2376#ifndef QT_NO_QOBJECT
2377 if (QCoreApplication::self)
2378 emit QCoreApplication::self->organizationDomainChanged();
2379#endif
2380}
2381
2382QString QCoreApplication::organizationDomain()
2383{
2384 return coreappdata()->orgDomain;
2385}
2386
2387/*!
2388 \property QCoreApplication::applicationName
2389 \brief the name of this application
2390
2391 The value is used by the QSettings class when it is constructed
2392 using the empty constructor. This saves having to repeat this
2393 information each time a QSettings object is created.
2394
2395 If not set, the application name defaults to the executable name (since 5.0).
2396
2397 \sa organizationName, organizationDomain, applicationVersion, applicationFilePath()
2398*/
2399/*!
2400 \fn void QCoreApplication::applicationNameChanged()
2401 \internal
2402
2403 Primarily for QML, see organizationNameChanged.
2404*/
2405void QCoreApplication::setApplicationName(const QString &application)
2406{
2407 coreappdata()->applicationNameSet = !application.isEmpty();
2408 QString newAppName = application;
2409 if (newAppName.isEmpty() && QCoreApplication::self)
2410 newAppName = QCoreApplication::self->d_func()->appName();
2411 if (coreappdata()->application == newAppName)
2412 return;
2413 coreappdata()->application = newAppName;
2414#ifndef QT_NO_QOBJECT
2415 if (QCoreApplication::self)
2416 emit QCoreApplication::self->applicationNameChanged();
2417#endif
2418}
2419
2420QString QCoreApplication::applicationName()
2421{
2422 return coreappdata() ? coreappdata()->application : QString();
2423}
2424
2425// Exported for QDesktopServices (Qt4 behavior compatibility)
2426Q_CORE_EXPORT QString qt_applicationName_noFallback()
2427{
2428 return coreappdata()->applicationNameSet ? coreappdata()->application : QString();
2429}
2430
2431/*!
2432 \property QCoreApplication::applicationVersion
2433 \since 4.4
2434 \brief the version of this application
2435
2436 If not set, the application version defaults to a platform-specific value
2437 determined from the main application executable or package (since Qt 5.9):
2438
2439 \table
2440 \header
2441 \li Platform
2442 \li Source
2443 \row
2444 \li Windows (classic desktop)
2445 \li PRODUCTVERSION parameter of the VERSIONINFO resource
2446 \row
2447 \li Universal Windows Platform
2448 \li version attribute of the application package manifest
2449 \row
2450 \li macOS, iOS, tvOS, watchOS
2451 \li CFBundleVersion property of the information property list
2452 \row
2453 \li Android
2454 \li android:versionName property of the AndroidManifest.xml manifest element
2455 \endtable
2456
2457 On other platforms, the default is the empty string.
2458
2459 \sa applicationName, organizationName, organizationDomain
2460*/
2461/*!
2462 \fn void QCoreApplication::applicationVersionChanged()
2463 \internal
2464
2465 Primarily for QML, see organizationNameChanged.
2466*/
2467void QCoreApplication::setApplicationVersion(const QString &version)
2468{
2469 coreappdata()->applicationVersionSet = !version.isEmpty();
2470 QString newVersion = version;
2471 if (newVersion.isEmpty() && QCoreApplication::self)
2472 newVersion = QCoreApplication::self->d_func()->appVersion();
2473 if (coreappdata()->applicationVersion == newVersion)
2474 return;
2475 coreappdata()->applicationVersion = newVersion;
2476#ifndef QT_NO_QOBJECT
2477 if (QCoreApplication::self)
2478 emit QCoreApplication::self->applicationVersionChanged();
2479#endif
2480}
2481
2482QString QCoreApplication::applicationVersion()
2483{
2484 return coreappdata() ? coreappdata()->applicationVersion : QString();
2485}
2486
2487#ifndef QT_NO_LIBRARY
2488
2489Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
2490
2491/*!
2492 Returns a list of paths that the application will search when
2493 dynamically loading libraries.
2494
2495 The return value of this function may change when a QCoreApplication
2496 is created. It is not recommended to call it before creating a
2497 QCoreApplication. The directory of the application executable (\b not
2498 the working directory) is part of the list if it is known. In order
2499 to make it known a QCoreApplication has to be constructed as it will
2500 use \c {argv[0]} to find it.
2501
2502 Qt provides default library paths, but they can also be set using
2503 a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2504 will override default values. Note that if the qt.conf file is in
2505 the directory of the application executable, it may not be found
2506 until a QCoreApplication is created. If it is not found when calling
2507 this function, the default library paths will be used.
2508
2509 The list will include the installation directory for plugins if
2510 it exists (the default installation directory for plugins is \c
2511 INSTALL/plugins, where \c INSTALL is the directory where Qt was
2512 installed). The colon separated entries of the \c QT_PLUGIN_PATH
2513 environment variable are always added. The plugin installation
2514 directory (and its existence) may change when the directory of
2515 the application executable becomes known.
2516
2517 If you want to iterate over the list, you can use the \l foreach
2518 pseudo-keyword:
2519
2520 \snippet code/src_corelib_kernel_qcoreapplication.cpp 2
2521
2522 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2523 {How to Create Qt Plugins}
2524*/
2525QStringList QCoreApplication::libraryPaths()
2526{
2527 QMutexLocker locker(libraryPathMutex());
2528
2529 if (coreappdata()->manual_libpaths)
2530 return *(coreappdata()->manual_libpaths);
2531
2532 if (!coreappdata()->app_libpaths) {
2533 QStringList *app_libpaths = new QStringList;
2534 coreappdata()->app_libpaths.reset(app_libpaths);
2535
2536 const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
2537 if (!libPathEnv.isEmpty()) {
2538 QStringList paths = QFile::decodeName(libPathEnv).split(QDir::listSeparator(), QString::SkipEmptyParts);
2539 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2540 QString canonicalPath = QDir(*it).canonicalPath();
2541 if (!canonicalPath.isEmpty()
2542 && !app_libpaths->contains(canonicalPath)) {
2543 app_libpaths->append(canonicalPath);
2544 }
2545 }
2546 }
2547
2548#ifdef Q_OS_DARWIN
2549 // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes.
2550 // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value
2551 // but with a different casing, so it can't be relied upon when the underlying filesystem
2552 // is case sensitive (and this is always the case on newer OSes like iOS).
2553 if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
2554 if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) {
2555 if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
2556 if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
2557 if (QFile::exists(path)) {
2558 path = QDir(path).canonicalPath();
2559 if (!app_libpaths->contains(path))
2560 app_libpaths->append(path);
2561 }
2562 }
2563 }
2564 }
2565 }
2566#endif // Q_OS_DARWIN
2567
2568 QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
2569 if (QFile::exists(installPathPlugins)) {
2570 // Make sure we convert from backslashes to slashes.
2571 installPathPlugins = QDir(installPathPlugins).canonicalPath();
2572 if (!app_libpaths->contains(installPathPlugins))
2573 app_libpaths->append(installPathPlugins);
2574 }
2575
2576 // If QCoreApplication is not yet instantiated,
2577 // make sure we add the application path when we construct the QCoreApplication
2578 if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2579 }
2580 return *(coreappdata()->app_libpaths);
2581}
2582
2583
2584
2585/*!
2586
2587 Sets the list of directories to search when loading libraries to
2588 \a paths. All existing paths will be deleted and the path list
2589 will consist of the paths given in \a paths.
2590
2591 The library paths are reset to the default when an instance of
2592 QCoreApplication is destructed.
2593
2594 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2595 */
2596void QCoreApplication::setLibraryPaths(const QStringList &paths)
2597{
2598 QMutexLocker locker(libraryPathMutex());
2599
2600 // setLibraryPaths() is considered a "remove everything and then add some new ones" operation.
2601 // When the application is constructed it should still amend the paths. So we keep the originals
2602 // around, and even create them if they don't exist, yet.
2603 if (!coreappdata()->app_libpaths)
2604 libraryPaths();
2605
2606 if (coreappdata()->manual_libpaths)
2607 *(coreappdata()->manual_libpaths) = paths;
2608 else
2609 coreappdata()->manual_libpaths.reset(new QStringList(paths));
2610
2611 locker.unlock();
2612 QFactoryLoader::refreshAll();
2613}
2614
2615/*!
2616 Prepends \a path to the beginning of the library path list, ensuring that
2617 it is searched for libraries first. If \a path is empty or already in the
2618 path list, the path list is not changed.
2619
2620 The default path list consists of a single entry, the installation
2621 directory for plugins. The default installation directory for plugins
2622 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2623 installed.
2624
2625 The library paths are reset to the default when an instance of
2626 QCoreApplication is destructed.
2627
2628 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2629 */
2630void QCoreApplication::addLibraryPath(const QString &path)
2631{
2632 if (path.isEmpty())
2633 return;
2634
2635 QString canonicalPath = QDir(path).canonicalPath();
2636 if (canonicalPath.isEmpty())
2637 return;
2638
2639 QMutexLocker locker(libraryPathMutex());
2640
2641 QStringList *libpaths = coreappdata()->manual_libpaths.data();
2642 if (libpaths) {
2643 if (libpaths->contains(canonicalPath))
2644 return;
2645 } else {
2646 // make sure that library paths are initialized
2647 libraryPaths();
2648 QStringList *app_libpaths = coreappdata()->app_libpaths.data();
2649 if (app_libpaths->contains(canonicalPath))
2650 return;
2651
2652 coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
2653 }
2654
2655 libpaths->prepend(canonicalPath);
2656 locker.unlock();
2657 QFactoryLoader::refreshAll();
2658}
2659
2660/*!
2661 Removes \a path from the library path list. If \a path is empty or not
2662 in the path list, the list is not changed.
2663
2664 The library paths are reset to the default when an instance of
2665 QCoreApplication is destructed.
2666
2667 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2668*/
2669void QCoreApplication::removeLibraryPath(const QString &path)
2670{
2671 if (path.isEmpty())
2672 return;
2673
2674 QString canonicalPath = QDir(path).canonicalPath();
2675 if (canonicalPath.isEmpty())
2676 return;
2677
2678 QMutexLocker locker(libraryPathMutex());
2679
2680 QStringList *libpaths = coreappdata()->manual_libpaths.data();
2681 if (libpaths) {
2682 if (libpaths->removeAll(canonicalPath) == 0)
2683 return;
2684 } else {
2685 // make sure that library paths is initialized
2686 libraryPaths();
2687 QStringList *app_libpaths = coreappdata()->app_libpaths.data();
2688 if (!app_libpaths->contains(canonicalPath))
2689 return;
2690
2691 coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
2692 libpaths->removeAll(canonicalPath);
2693 }
2694
2695 locker.unlock();
2696 QFactoryLoader::refreshAll();
2697}
2698
2699#endif //QT_NO_LIBRARY
2700
2701#ifndef QT_NO_QOBJECT
2702
2703/*!
2704 Installs an event filter \a filterObj for all native events
2705 received by the application in the main thread.
2706
2707 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
2708 function, which is called for all native events received in the main thread.
2709
2710 The QAbstractNativeEventFilter::nativeEventFilter() function should
2711 return true if the event should be filtered, i.e. stopped. It should
2712 return false to allow normal Qt processing to continue: the native
2713 event can then be translated into a QEvent and handled by the standard
2714 Qt \l{QEvent} {event} filtering, e.g. QObject::installEventFilter().
2715
2716 If multiple event filters are installed, the filter that was
2717 installed last is activated first.
2718
2719 \note The filter function set here receives native messages,
2720 i.e. MSG or XCB event structs.
2721
2722 \note Native event filters will be disabled in the application when the
2723 Qt::AA_PluginApplication attribute is set.
2724
2725 For maximum portability, you should always try to use QEvent
2726 and QObject::installEventFilter() whenever possible.
2727
2728 \sa QObject::installEventFilter()
2729
2730 \since 5.0
2731*/
2732void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
2733{
2734 if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
2735 qWarning("Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
2736 return;
2737 }
2738
2739 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread);
2740 if (!filterObj || !eventDispatcher)
2741 return;
2742 eventDispatcher->installNativeEventFilter(filterObj);
2743}
2744
2745/*!
2746 Removes an event \a filterObject from this object. The
2747 request is ignored if such an event filter has not been installed.
2748
2749 All event filters for this object are automatically removed when
2750 this object is destroyed.
2751
2752 It is always safe to remove an event filter, even during event
2753 filter activation (i.e. from the nativeEventFilter() function).
2754
2755 \sa installNativeEventFilter()
2756 \since 5.0
2757*/
2758void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
2759{
2760 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2761 if (!filterObject || !eventDispatcher)
2762 return;
2763 eventDispatcher->removeNativeEventFilter(filterObject);
2764}
2765
2766/*!
2767 \deprecated
2768
2769 This function returns \c true if there are pending events; otherwise
2770 returns \c false. Pending events can be either from the window
2771 system or posted events using postEvent().
2772
2773 \note this function is not thread-safe. It may only be called in the main
2774 thread and only if there are no other threads running in the application
2775 (including threads Qt starts for its own purposes).
2776
2777 \sa QAbstractEventDispatcher::hasPendingEvents()
2778*/
2779#if QT_DEPRECATED_SINCE(5, 3)
2780bool QCoreApplication::hasPendingEvents()
2781{
2782 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2783 if (eventDispatcher)
2784 return eventDispatcher->hasPendingEvents();
2785 return false;
2786}
2787#endif
2788
2789/*!
2790 Returns a pointer to the event dispatcher object for the main thread. If no
2791 event dispatcher exists for the thread, this function returns 0.
2792*/
2793QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
2794{
2795 if (QCoreApplicationPrivate::theMainThread)
2796 return QCoreApplicationPrivate::theMainThread.load()->eventDispatcher();
2797 return 0;
2798}
2799
2800/*!
2801 Sets the event dispatcher for the main thread to \a eventDispatcher. This
2802 is only possible as long as there is no event dispatcher installed yet. That
2803 is, before QCoreApplication has been instantiated. This method takes
2804 ownership of the object.
2805*/
2806void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
2807{
2808 QThread *mainThread = QCoreApplicationPrivate::theMainThread;
2809 if (!mainThread)
2810 mainThread = QThread::currentThread(); // will also setup theMainThread
2811 mainThread->setEventDispatcher(eventDispatcher);
2812}
2813
2814#endif // QT_NO_QOBJECT
2815
2816/*!
2817 \macro Q_COREAPP_STARTUP_FUNCTION(QtStartUpFunction ptr)
2818 \since 5.1
2819 \relates QCoreApplication
2820 \reentrant
2821
2822 Adds a global function that will be called from the QCoreApplication
2823 constructor. This macro is normally used to initialize libraries
2824 for program-wide functionality, without requiring the application to
2825 call into the library for initialization.
2826
2827 The function specified by \a ptr should take no arguments and should
2828 return nothing. For example:
2829
2830 \snippet code/src_corelib_kernel_qcoreapplication.cpp 3
2831
2832 Note that the startup function will run at the end of the QCoreApplication constructor,
2833 before any GUI initialization. If GUI code is required in the function,
2834 use a timer (or a queued invocation) to perform the initialization later on,
2835 from the event loop.
2836
2837 If QCoreApplication is deleted and another QCoreApplication is created,
2838 the startup function will be invoked again.
2839*/
2840
2841/*!
2842 \fn void qAddPostRoutine(QtCleanUpFunction ptr)
2843 \relates QCoreApplication
2844
2845 Adds a global routine that will be called from the QCoreApplication
2846 destructor. This function is normally used to add cleanup routines
2847 for program-wide functionality.
2848
2849 The cleanup routines are called in the reverse order of their addition.
2850
2851 The function specified by \a ptr should take no arguments and should
2852 return nothing. For example:
2853
2854 \snippet code/src_corelib_kernel_qcoreapplication.cpp 4
2855
2856 Note that for an application- or module-wide cleanup, qaddPostRoutine()
2857 is often not suitable. For example, if the program is split into dynamically
2858 loaded modules, the relevant module may be unloaded long before the
2859 QCoreApplication destructor is called. In such cases, if using qaddPostRoutine()
2860 is still desirable, qRemovePostRoutine() can be used to prevent a routine
2861 from being called by the QCoreApplication destructor. For example, if that
2862 routine was called before the module was unloaded.
2863
2864 For modules and libraries, using a reference-counted
2865 initialization manager or Qt's parent-child deletion mechanism may
2866 be better. Here is an example of a private class that uses the
2867 parent-child mechanism to call a cleanup function at the right
2868 time:
2869
2870 \snippet code/src_corelib_kernel_qcoreapplication.cpp 5
2871
2872 By selecting the right parent object, this can often be made to
2873 clean up the module's data at the right moment.
2874
2875 \sa qRemovePostRoutine()
2876*/
2877
2878/*!
2879 \fn void qRemovePostRoutine(QtCleanUpFunction ptr)
2880 \relates QCoreApplication
2881 \since 5.3
2882
2883 Removes the cleanup routine specified by \a ptr from the list of
2884 routines called by the QCoreApplication destructor. The routine
2885 must have been previously added to the list by a call to
2886 qAddPostRoutine(), otherwise this function has no effect.
2887
2888 \sa qAddPostRoutine()
2889*/
2890
2891/*!
2892 \macro Q_DECLARE_TR_FUNCTIONS(context)
2893 \relates QCoreApplication
2894
2895 The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
2896 translation functions, \c tr() and \c trUtf8(), with these
2897 signatures:
2898
2899 \snippet code/src_corelib_kernel_qcoreapplication.cpp 6
2900
2901 This macro is useful if you want to use QObject::tr() or
2902 QObject::trUtf8() in classes that don't inherit from QObject.
2903
2904 Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
2905 class definition (before the first \c{public:} or \c{protected:}).
2906 For example:
2907
2908 \snippet code/src_corelib_kernel_qcoreapplication.cpp 7
2909
2910 The \a context parameter is normally the class name, but it can
2911 be any text.
2912
2913 \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
2914*/
2915
2916QT_END_NAMESPACE
2917