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