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