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