8f427b2 by axis at 2009-04-24 1
/****************************************************************************
2
**
89c08c0 by Jason McDonald at 2012-01-11 3
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
04e3b30 by Jason McDonald at 2009-09-09 4
** All rights reserved.
858c70f by Jason McDonald at 2009-06-16 5
** Contact: Nokia Corporation (qt-info@nokia.com)
8f427b2 by axis at 2009-04-24 6
**
7
** This file is part of the QtCore module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** GNU Lesser General Public License Usage
1eea52e by Jyri Tahtela at 2011-05-13 11
** This file may be used under the terms of the GNU Lesser General Public
12
** License version 2.1 as published by the Free Software Foundation and
13
** appearing in the file LICENSE.LGPL included in the packaging of this
14
** file. Please review the following information to ensure the GNU Lesser
15
** General Public License version 2.1 requirements will be met:
16
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
8f427b2 by axis at 2009-04-24 17
**
04e3b30 by Jason McDonald at 2009-09-09 18
** In addition, as a special exception, Nokia gives you certain additional
1eea52e by Jyri Tahtela at 2011-05-13 19
** rights. These rights are described in the Nokia Qt LGPL Exception
04e3b30 by Jason McDonald at 2009-09-09 20
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
8f427b2 by axis at 2009-04-24 21
**
1eea52e by Jyri Tahtela at 2011-05-13 22
** GNU General Public License Usage
23
** Alternatively, this file may be used under the terms of the GNU General
24
** Public License version 3.0 as published by the Free Software Foundation
25
** and appearing in the file LICENSE.GPL included in the packaging of this
26
** file. Please review the following information to ensure the GNU General
27
** Public License version 3.0 requirements will be met:
28
** http://www.gnu.org/copyleft/gpl.html.
309db73 by Jason McDonald at 2009-08-31 29
**
1eea52e by Jyri Tahtela at 2011-05-13 30
** Other Usage
31
** Alternatively, this file may be used in accordance with the terms and
32
** conditions contained in a signed written agreement between you and Nokia.
309db73 by Jason McDonald at 2009-08-31 33
**
34
**
35
**
36
**
8f427b2 by axis at 2009-04-24 37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#include "qcoreapplication.h"
43
#include "qcoreapplication_p.h"
44
45
#include "qabstracteventdispatcher.h"
46
#include "qcoreevent.h"
47
#include "qeventloop.h"
48
#include "qcorecmdlineargs_p.h"
49
#include <qdatastream.h>
50
#include <qdebug.h>
51
#include <qdir.h>
52
#include <qfile.h>
53
#include <qfileinfo.h>
54
#include <qhash.h>
55
#include <private/qprocess_p.h>
56
#include <qtextcodec.h>
57
#include <qthread.h>
58
#include <qthreadpool.h>
59
#include <qthreadstorage.h>
60
#include <private/qthread_p.h>
21983be by Thiago Macieira at 2010-03-17 61
#include <qelapsedtimer.h>
8f427b2 by axis at 2009-04-24 62
#include <qlibraryinfo.h>
b3b2bc3 by Thierry Bastian at 2009-08-12 63
#include <qvarlengtharray.h>
8f427b2 by axis at 2009-04-24 64
#include <private/qfactoryloader_p.h>
d7b6888 by Robert Griebl at 2009-07-29 65
#include <private/qfunctions_p.h>
e4c60e6 by Denis Dzyubenko at 2010-05-03 66
#include <private/qlocale_p.h>
8f427b2 by axis at 2009-04-24 67
68
#ifdef Q_OS_SYMBIAN
7604f80 by Robert Griebl at 2009-06-10 69
#  include <exception>
8f427b2 by axis at 2009-04-24 70
#  include <f32file.h>
0ef1365 by Frans Englich at 2010-04-08 71
#  include <e32ldr.h>
8f427b2 by axis at 2009-04-24 72
#  include "qeventdispatcher_symbian_p.h"
7604f80 by Robert Griebl at 2009-06-10 73
#  include "private/qcore_symbian_p.h"
63d50fd by Shane Kearns at 2010-09-20 74
#  include "private/qfilesystemengine_p.h"
a601a45 by Miikka Heikkinen at 2011-01-11 75
#  include <apacmdln.h>
8f427b2 by axis at 2009-04-24 76
#elif defined(Q_OS_UNIX)
77
#  if !defined(QT_NO_GLIB)
78
#    include "qeventdispatcher_glib_p.h"
79
#  endif
80
#  include "qeventdispatcher_unix_p.h"
81
#endif
82
83
#ifdef Q_OS_WIN
84
#  include "qeventdispatcher_win_p.h"
85
#endif
86
87
#ifdef Q_OS_MAC
88
#  include "qcore_mac_p.h"
89
#endif
90
91
#include <stdlib.h>
92
93
#ifdef Q_OS_UNIX
94
#  include <locale.h>
95
#endif
96
d7b6888 by Robert Griebl at 2009-07-29 97
#ifdef Q_OS_VXWORKS
98
#  include <taskLib.h>
99
#endif
100
648bf77 by Ritt Konstantin at 2011-06-21 101
#ifdef Q_OS_QNX
09cd27d by Ritt Konstantin at 2011-06-21 102
#  include <sys/neutrino.h>
648bf77 by Ritt Konstantin at 2011-06-21 103
#  include <pthread.h>
104
#  include <sched.h>
105
#endif
106
8f427b2 by axis at 2009-04-24 107
QT_BEGIN_NAMESPACE
108
d24029e by Harald Fernengel at 2009-08-17 109
class QMutexUnlocker
7604f80 by Robert Griebl at 2009-06-10 110
{
111
public:
d24029e by Harald Fernengel at 2009-08-17 112
    inline explicit QMutexUnlocker(QMutex *m)
7604f80 by Robert Griebl at 2009-06-10 113
        : mtx(m)
114
    { }
d24029e by Harald Fernengel at 2009-08-17 115
    inline ~QMutexUnlocker() { unlock(); }
7604f80 by Robert Griebl at 2009-06-10 116
    inline void unlock() { if (mtx) mtx->unlock(); mtx = 0; }
117
118
private:
d24029e by Harald Fernengel at 2009-08-17 119
    Q_DISABLE_COPY(QMutexUnlocker)
7604f80 by Robert Griebl at 2009-06-10 120
121
    QMutex *mtx;
122
};
123
b3f3ab7 by Shane Kearns at 2009-09-23 124
#ifdef Q_OS_SYMBIAN
a601a45 by Miikka Heikkinen at 2011-01-11 125
static CApaCommandLine* apaCommandLine = 0;
126
static char *apaTail = 0;
127
static QVector<char *> *apaArgv = 0;
128
129
static void qt_cleanup_apa_cmd_line()
130
{
131
    delete apaCommandLine;
132
    apaCommandLine = 0;
133
    delete apaArgv;
134
    apaArgv = 0;
135
    delete apaTail;
136
    apaTail = 0;
137
}
138
139
static inline void qt_init_symbian_apa_arguments(int &argc, char **&argv)
140
{
141
    // If app is launched via CApaCommandLine::StartApp(), normal arguments only contain
142
    // application name.
143
    if (argc == 1) {
144
        CApaCommandLine* commandLine = QCoreApplicationPrivate::symbianCommandLine();
145
        if(commandLine) {
146
            TPtrC8 apaCmdLine = commandLine->TailEnd();
147
            int tailLen = apaCmdLine.Length();
148
            if (tailLen) {
149
                apaTail = reinterpret_cast<char *>(qMalloc(tailLen + 1));
150
                qMemCopy(apaTail, reinterpret_cast<const char *>(apaCmdLine.Ptr()), tailLen);
151
                apaTail[tailLen] = '\0';
152
                apaArgv = new QVector<char *>(8);
153
                // Reuse windows command line parsing
154
                *apaArgv = qWinCmdLine<char>(apaTail, tailLen, argc);
155
                apaArgv->insert(0, argv[0]);
156
                argc++;
157
                argv = apaArgv->data();
158
            }
159
        }
160
    }
161
}
162
163
CApaCommandLine* QCoreApplicationPrivate::symbianCommandLine()
164
{
165
    // Getting of Apa command line needs to be static as it can only be called successfully
166
	// once per process.
167
    if (!apaCommandLine) {
168
        TInt err = CApaCommandLine::GetCommandLineFromProcessEnvironment(apaCommandLine);
169
        if (err == KErrNone) {
170
            qAddPostRoutine(qt_cleanup_apa_cmd_line);
171
        }
172
    }
173
    return apaCommandLine;
174
}
175
b3f3ab7 by Shane Kearns at 2009-09-23 176
#endif
177
8f427b2 by axis at 2009-04-24 178
#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
179
extern QString qAppFileName();
180
#endif
181
0b61f3e by Olivier Goffart at 2010-05-28 182
int QCoreApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0
183
#if defined(QT3_SUPPORT)
184
bool QCoreApplicationPrivate::useQt3Support = true;
185
#endif
186
8f427b2 by axis at 2009-04-24 187
#if !defined(Q_OS_WIN)
188
#ifdef Q_OS_MAC
189
QString QCoreApplicationPrivate::macMenuBarName()
190
{
191
    QString bundleName;
192
    CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleName"));
193
    if (string)
194
        bundleName = QCFString::toQString(static_cast<CFStringRef>(string));
195
    return bundleName;
196
}
197
#endif
198
QString QCoreApplicationPrivate::appName() const
199
{
200
    static QString applName;
201
#ifdef Q_OS_MAC
202
    applName = macMenuBarName();
203
#endif
204
    if (applName.isEmpty() && argv[0]) {
205
        char *p = strrchr(argv[0], '/');
206
        applName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
207
    }
208
    return applName;
209
}
210
#endif
211
212
bool QCoreApplicationPrivate::checkInstance(const char *function)
213
{
214
    bool b = (QCoreApplication::self != 0);
215
    if (!b)
216
        qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
217
    return b;
218
}
219
220
// Support for introspection
221
222
QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
223
224
void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
225
{
226
    qt_signal_spy_callback_set = callback_set;
227
}
228
229
extern "C" void Q_CORE_EXPORT qt_startup_hook()
230
{
231
}
232
233
typedef QList<QtCleanUpFunction> QVFuncList;
234
Q_GLOBAL_STATIC(QVFuncList, postRList)
235
236
void qAddPostRoutine(QtCleanUpFunction p)
237
{
238
    QVFuncList *list = postRList();
239
    if (!list)
240
        return;
241
    list->prepend(p);
242
}
243
244
void qRemovePostRoutine(QtCleanUpFunction p)
245
{
246
    QVFuncList *list = postRList();
247
    if (!list)
248
        return;
249
    list->removeAll(p);
250
}
251
252
void Q_CORE_EXPORT qt_call_post_routines()
253
{
7604f80 by Robert Griebl at 2009-06-10 254
    QVFuncList *list = 0;
255
    QT_TRY {
256
        list = postRList();
257
    } QT_CATCH(const std::bad_alloc &) {
258
        // ignore - if we can't allocate a post routine list,
259
        // there's a high probability that there's no post
260
        // routine to be executed :)
261
    }
8f427b2 by axis at 2009-04-24 262
    if (!list)
263
        return;
264
    while (!list->isEmpty())
265
        (list->takeFirst())();
266
}
267
268
269
// app starting up if false
270
bool QCoreApplicationPrivate::is_app_running = false;
271
 // app closing down if true
272
bool QCoreApplicationPrivate::is_app_closing = false;
273
// initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
274
Q_CORE_EXPORT bool qt_locale_initialized = false;
275
acfa201 by Miikka Heikkinen at 2011-09-13 276
#ifdef Q_OS_SYMBIAN
277
// The global QSettings needs to be cleaned where cleanup stack is available, which is not
278
// normally the case when global static destructors are run.
279
// Declare a custom QGlobalStaticDeleter for QSettings to handle that case.
280
template<>
281
class QGlobalStaticDeleter<QSettings>
282
{
283
public:
284
    QGlobalStatic<QSettings> &globalStatic;
285
    QGlobalStaticDeleter(QGlobalStatic<QSettings> &_globalStatic)
286
        : globalStatic(_globalStatic)
287
    { }
288
289
    inline ~QGlobalStaticDeleter()
290
    {
291
        CTrapCleanup *cleanup = CTrapCleanup::New();
292
        delete globalStatic.pointer;
293
        delete cleanup;
294
        globalStatic.pointer = 0;
295
        globalStatic.destroyed = true;
296
    }
297
};
298
#endif
8f427b2 by axis at 2009-04-24 299
988871d by mae at 2011-05-02 300
/*
301
  Create an instance of Trolltech.conf. This ensures that the settings will not
302
  be thrown out of QSetting's cache for unused settings.
303
  */
c99be6b by mae at 2011-05-02 304
Q_GLOBAL_STATIC_WITH_ARGS(QSettings, staticTrolltechConf, (QSettings::UserScope, QLatin1String("Trolltech")))
988871d by mae at 2011-05-02 305
306
QSettings *QCoreApplicationPrivate::trolltechConf()
307
{
c99be6b by mae at 2011-05-02 308
    return staticTrolltechConf();
988871d by mae at 2011-05-02 309
}
31ef8fa by mae at 2011-04-29 310
8f427b2 by axis at 2009-04-24 311
Q_CORE_EXPORT uint qGlobalPostedEventsCount()
312
{
313
    QThreadData *currentThreadData = QThreadData::current();
314
    return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
315
}
316
317
318
void qt_set_current_thread_to_main_thread()
319
{
320
    QCoreApplicationPrivate::theMainThread = QThread::currentThread();
321
}
322
323
324
325
QCoreApplication *QCoreApplication::self = 0;
326
QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0;
327
uint QCoreApplicationPrivate::attribs;
328
329
#ifdef Q_OS_UNIX
330
Qt::HANDLE qt_application_thread_id = 0;
331
#endif
332
333
struct QCoreApplicationData {
334
    QCoreApplicationData() {
335
#ifndef QT_NO_LIBRARY
336
        app_libpaths = 0;
337
#endif
338
    }
339
    ~QCoreApplicationData() {
340
#ifndef QT_NO_LIBRARY
341
        delete app_libpaths;
342
#endif
343
344
        // cleanup the QAdoptedThread created for the main() thread
345
       if (QCoreApplicationPrivate::theMainThread) {
346
           QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread);
347
           QCoreApplicationPrivate::theMainThread = 0;
348
           data->deref(); // deletes the data and the adopted thread
349
       }
350
    }
351
    QString orgName, orgDomain, application;
352
    QString applicationVersion;
353
354
#ifndef QT_NO_LIBRARY
355
    QStringList *app_libpaths;
356
#endif
357
358
};
359
360
Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
361
0b61f3e by Olivier Goffart at 2010-05-28 362
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
8f427b2 by axis at 2009-04-24 363
    : QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
364
      in_exec(false), aboutToQuitEmitted(false)
365
{
0b61f3e by Olivier Goffart at 2010-05-28 366
    app_compile_version = flags & 0xffffff;
367
#if defined(QT3_SUPPORT)
368
    useQt3Support = !(flags & 0x01000000);
369
#endif
8f427b2 by axis at 2009-04-24 370
    static const char *const empty = "";
371
    if (argc == 0 || argv == 0) {
372
        argc = 0;
373
        argv = (char **)&empty; // ouch! careful with QCoreApplication::argv()!
374
    }
375
    QCoreApplicationPrivate::is_app_closing = false;
376
a601a45 by Miikka Heikkinen at 2011-01-11 377
#ifdef Q_OS_SYMBIAN
378
    qt_init_symbian_apa_arguments(argc, argv);
379
#endif
380
8f427b2 by axis at 2009-04-24 381
#ifdef Q_OS_UNIX
382
    qt_application_thread_id = QThread::currentThreadId();
383
#endif
384
648bf77 by Ritt Konstantin at 2011-06-21 385
#ifdef Q_OS_QNX
09cd27d by Ritt Konstantin at 2011-06-21 386
    // make the kernel attempt to emulate an instruction with a misaligned access
387
    // if the attempt fails, it faults with a SIGBUS
388
    int tv = -1;
389
    ThreadCtl(_NTO_TCTL_ALIGN_FAULT, &tv);
390
648bf77 by Ritt Konstantin at 2011-06-21 391
    // without Round Robin drawn intensive apps will hog the cpu
392
    // and make the system appear frozen
393
    int sched_policy;
394
    sched_param param;
395
    if (pthread_getschedparam(0, &sched_policy, &param) == 0 && sched_policy != SCHED_RR) {
396
        sched_policy = SCHED_RR;
397
        pthread_setschedparam(0, sched_policy, &param);
398
    }
399
#endif
400
8f427b2 by axis at 2009-04-24 401
    // note: this call to QThread::currentThread() may end up setting theMainThread!
402
    if (QThread::currentThread() != theMainThread)
403
        qWarning("WARNING: QApplication was not created in the main() thread.");
404
}
405
406
QCoreApplicationPrivate::~QCoreApplicationPrivate()
407
{
7604f80 by Robert Griebl at 2009-06-10 408
    if (threadData) {
8f427b2 by axis at 2009-04-24 409
#ifndef QT_NO_THREAD
7604f80 by Robert Griebl at 2009-06-10 410
        void *data = &threadData->tls;
411
        QThreadStorageData::finish((void **)data);
8f427b2 by axis at 2009-04-24 412
#endif
413
7604f80 by Robert Griebl at 2009-06-10 414
        // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
415
        QMutexLocker locker(&threadData->postEventList.mutex);
416
        for (int i = 0; i < threadData->postEventList.size(); ++i) {
417
            const QPostEvent &pe = threadData->postEventList.at(i);
418
            if (pe.event) {
419
                --pe.receiver->d_func()->postedEvents;
420
                pe.event->posted = false;
421
                delete pe.event;
422
            }
8f427b2 by axis at 2009-04-24 423
        }
7604f80 by Robert Griebl at 2009-06-10 424
        threadData->postEventList.clear();
425
        threadData->postEventList.recursion = 0;
426
        threadData->quitNow = false;
8f427b2 by axis at 2009-04-24 427
    }
428
}
429
430
void QCoreApplicationPrivate::createEventDispatcher()
431
{
432
    Q_Q(QCoreApplication);
433
#if defined(Q_OS_SYMBIAN)
434
    eventDispatcher = new QEventDispatcherSymbian(q);
435
#elif defined(Q_OS_UNIX)
436
#  if !defined(QT_NO_GLIB)
437
    if (qgetenv("QT_NO_GLIB").isEmpty() && QEventDispatcherGlib::versionSupported())
438
        eventDispatcher = new QEventDispatcherGlib(q);
439
    else
440
#  endif
441
        eventDispatcher = new QEventDispatcherUNIX(q);
442
#elif defined(Q_OS_WIN)
443
    eventDispatcher = new QEventDispatcherWin32(q);
444
#else
445
#  error "QEventDispatcher not yet ported to this platform"
446
#endif
447
}
448
449
QThread *QCoreApplicationPrivate::theMainThread = 0;
450
QThread *QCoreApplicationPrivate::mainThread()
451
{
452
    Q_ASSERT(theMainThread != 0);
453
    return theMainThread;
454
}
455
456
#if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
457
void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
458
{
459
    QThread *currentThread = QThread::currentThread();
460
    QThread *thr = receiver->thread();
461
    Q_ASSERT_X(currentThread == thr || !thr,
462
               "QCoreApplication::sendEvent",
463
               QString::fromLatin1("Cannot send events to objects owned by a different thread. "
464
                                   "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4")
465
               .arg(QString::number((quintptr) currentThread, 16))
466
               .arg(receiver->objectName())
467
               .arg(QLatin1String(receiver->metaObject()->className()))
468
               .arg(QString::number((quintptr) thr, 16))
469
               .toLocal8Bit().data());
470
    Q_UNUSED(currentThread);
471
    Q_UNUSED(thr);
472
}
fca64a0 by Iain at 2009-05-26 473
#elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG)
474
// no implementation in release builds, but keep the symbol present
2e27c5a by Jason Barron at 2009-09-23 475
void QCoreApplicationPrivate::checkReceiverThread(QObject * /* receiver */)
fca64a0 by Iain at 2009-05-26 476
{
477
}
8f427b2 by axis at 2009-04-24 478
#endif
479
480
void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
481
{
482
#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
483
    QStringList *app_libpaths = coreappdata()->app_libpaths;
484
    Q_ASSERT(app_libpaths);
485
# if defined(Q_OS_SYMBIAN)
486
    QString app_location( QCoreApplication::applicationDirPath() );
487
    // File existence check for application's private dir requires additional '\' or
488
    // platform security will not allow it.
489
    if (app_location !=  QLibraryInfo::location(QLibraryInfo::PluginsPath) && QFile::exists(app_location + QLatin1Char('\\')) && !app_libpaths->contains(app_location))
490
# else
491
    QString app_location( QCoreApplication::applicationFilePath() );
492
    app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
493
    app_location = QDir(app_location).canonicalPath();
c8816c6 by Joerg Bornemann at 2009-09-21 494
    if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
8f427b2 by axis at 2009-04-24 495
# endif
496
        app_libpaths->append(app_location);
497
#endif
498
}
499
500
QString qAppName()
501
{
502
    if (!QCoreApplicationPrivate::checkInstance("qAppName"))
503
        return QString();
504
    return QCoreApplication::instance()->d_func()->appName();
505
}
506
507
/*!
508
    \class QCoreApplication
509
    \brief The QCoreApplication class provides an event loop for console Qt
510
    applications.
511
512
    This class is used by non-GUI applications to provide their event
513
    loop. For non-GUI application that uses Qt, there should be exactly
514
    one QCoreApplication object. For GUI applications, see
515
    QApplication.
516
517
    QCoreApplication contains the main event loop, where all events
518
    from the operating system (e.g., timer and network events) and
519
    other sources are processed and dispatched. It also handles the
520
    application's initialization and finalization, as well as
521
    system-wide and application-wide settings.
522
34d66c9 by David Boddie at 2009-08-27 523
    \section1 The Event Loop and Event Handling
524
525
    The event loop is started with a call to exec(). Long running
8f427b2 by axis at 2009-04-24 526
    operations can call processEvents() to keep the application
527
    responsive.
528
bbd87cf by Geir Vattekar at 2011-01-27 529
    In general, we recommend that you create a QCoreApplication or a
530
    QApplication object in your \c main() function as early as
531
    possible. exec() will not return until the event loop exits; e.g.,
532
    when quit() is called.
34d66c9 by David Boddie at 2009-08-27 533
534
    Several static convenience functions are also provided. The
535
    QCoreApplication object is available from instance(). Events can
536
    be sent or posted using sendEvent(), postEvent(), and
537
    sendPostedEvents(). Pending events can be removed with
538
    removePostedEvents() or flushed with flush().
539
540
    The class provides a quit() slot and an aboutToQuit() signal.
541
542
    \section1 Application and Library Paths
8f427b2 by axis at 2009-04-24 543
544
    An application has an applicationDirPath() and an
34d66c9 by David Boddie at 2009-08-27 545
    applicationFilePath(). Library paths (see QLibrary) can be retrieved
546
    with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
547
    and removeLibraryPath().
548
549
    \section1 Internationalization and Translations
550
551
    Translation files can be added or removed
8f427b2 by axis at 2009-04-24 552
    using installTranslator() and removeTranslator(). Application
553
    strings can be translated using translate(). The QObject::tr()
554
    and QObject::trUtf8() functions are implemented in terms of
555
    translate().
556
34d66c9 by David Boddie at 2009-08-27 557
    \section1 Accessing Command Line Arguments
8f427b2 by axis at 2009-04-24 558
34d66c9 by David Boddie at 2009-08-27 559
    The command line arguments which are passed to QCoreApplication's
560
    constructor should be accessed using the arguments() function.
561
    Note that some arguments supplied by the user may have been
562
    processed and removed by QCoreApplication.
563
564
    In cases where command line arguments need to be obtained using the
565
    argv() function, you must convert them from the local string encoding
566
    using QString::fromLocal8Bit().
567
568
    \section1 Locale Settings
569
570
    On Unix/Linux Qt is configured to use the system locale settings by
571
    default. This can cause a conflict when using POSIX functions, for
572
    instance, when converting between data types such as floats and
573
    strings, since the notation may differ between locales. To get
574
    around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
575
    right after initializing QApplication or QCoreApplication to reset
576
    the locale that is used for number formatting to "C"-locale.
9969f53 by Morten Engvoldsen at 2009-04-01 577
8f427b2 by axis at 2009-04-24 578
    \sa QApplication, QAbstractEventDispatcher, QEventLoop,
579
    {Semaphores Example}, {Wait Conditions Example}
580
*/
581
582
/*!
583
    \fn static QCoreApplication *QCoreApplication::instance()
584
585
    Returns a pointer to the application's QCoreApplication (or
586
    QApplication) instance.
587
588
    If no instance has been allocated, \c null is returned.
589
*/
590
591
/*!\internal
592
 */
593
QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
594
    : QObject(p, 0)
595
{
596
    init();
597
    // note: it is the subclasses' job to call
598
    // QCoreApplicationPrivate::eventDispatcher->startingUp();
599
}
600
601
/*!
602
    Flushes the platform specific event queues.
603
604
    If you are doing graphical changes inside a loop that does not
605
    return to the event loop on asynchronous window systems like X11
606
    or double buffered window systems like Mac OS X, and you want to
607
    visualize these changes immediately (e.g. Splash Screens), call
608
    this function.
609
610
    \sa sendPostedEvents()
611
*/
612
void QCoreApplication::flush()
613
{
614
    if (self && self->d_func()->eventDispatcher)
615
        self->d_func()->eventDispatcher->flush();
616
}
617
618
/*!
619
    Constructs a Qt kernel application. Kernel applications are
620
    applications without a graphical user interface. These type of
621
    applications are used at the console or as server processes.
622
623
    The \a argc and \a argv arguments are processed by the application,
624
    and made available in a more convenient form by the arguments()
625
    function.
626
627
    \warning The data referred to by \a argc and \a argv must stay valid
628
    for the entire lifetime of the QCoreApplication object. In addition,
629
    \a argc must be greater than zero and \a argv must contain at least
630
    one valid character string.
631
*/
632
QCoreApplication::QCoreApplication(int &argc, char **argv)
0b61f3e by Olivier Goffart at 2010-05-28 633
    : QObject(*new QCoreApplicationPrivate(argc, argv, 0x040000))
8f427b2 by axis at 2009-04-24 634
{
635
    init();
636
    QCoreApplicationPrivate::eventDispatcher->startingUp();
e709077 by Tasuku Suzuki at 2010-04-29 637
#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY)
8f427b2 by axis at 2009-04-24 638
    // Refresh factoryloader, as text codecs are requested during lib path
639
    // resolving process and won't be therefore properly loaded.
640
    // Unknown if this is symbian specific issue.
641
    QFactoryLoader::refreshAll();
642
#endif
643
e4c60e6 by Denis Dzyubenko at 2010-05-03 644
#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
645
    d_func()->symbianInit();
646
#endif
8f427b2 by axis at 2009-04-24 647
}
648
0b61f3e by Olivier Goffart at 2010-05-28 649
QCoreApplication::QCoreApplication(int &argc, char **argv, int _internal)
650
: QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
651
{
652
    init();
653
    QCoreApplicationPrivate::eventDispatcher->startingUp();
654
#if defined(Q_OS_SYMBIAN)
655
#ifndef QT_NO_LIBRARY
656
    // Refresh factoryloader, as text codecs are requested during lib path
657
    // resolving process and won't be therefore properly loaded.
658
    // Unknown if this is symbian specific issue.
659
    QFactoryLoader::refreshAll();
660
#endif
661
#ifndef QT_NO_SYSTEMLOCALE
662
    d_func()->symbianInit();
663
#endif
664
#endif //Q_OS_SYMBIAN
665
}
666
667
8f427b2 by axis at 2009-04-24 668
// ### move to QCoreApplicationPrivate constructor?
669
void QCoreApplication::init()
670
{
671
    Q_D(QCoreApplication);
672
673
#ifdef Q_OS_UNIX
674
    setlocale(LC_ALL, "");                // use correct char set mapping
675
    qt_locale_initialized = true;
676
#endif
677
678
    Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
679
    QCoreApplication::self = this;
680
63d50fd by Shane Kearns at 2010-09-20 681
#ifdef Q_OS_SYMBIAN
682
    //ensure temp and working directories exist
683
    QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::tempPath()), true);
684
    QFileSystemEngine::createDirectory(QFileSystemEntry(QFileSystemEngine::currentPath()), true);
685
#endif
686
8f427b2 by axis at 2009-04-24 687
#ifndef QT_NO_THREAD
688
    QThread::initialize();
689
#endif
690
691
    // use the event dispatcher created by the app programmer (if any)
692
    if (!QCoreApplicationPrivate::eventDispatcher)
693
        QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
694
    // otherwise we create one
695
    if (!QCoreApplicationPrivate::eventDispatcher)
696
        d->createEventDispatcher();
697
    Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
698
699
    if (!QCoreApplicationPrivate::eventDispatcher->parent())
700
        QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
701
702
    d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
703
704
#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
705
    if (!coreappdata()->app_libpaths) {
706
        // make sure that library paths is initialized
707
        libraryPaths();
708
    } else {
709
        d->appendApplicationPathToLibraryPaths();
710
    }
711
#endif
712
d9c06bf by Harald Fernengel at 2011-02-04 713
#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
714
    // Make sure the process manager thread object is created in the main
715
    // thread.
716
    QProcessPrivate::initializeProcessManager();
717
#endif
718
8f427b2 by axis at 2009-04-24 719
#ifdef QT_EVAL
720
    extern void qt_core_eval_init(uint);
721
    qt_core_eval_init(d->application_type);
722
#endif
723
0ef1365 by Frans Englich at 2010-04-08 724
#if    defined(Q_OS_SYMBIAN)  \
725
    && defined(Q_CC_NOKIAX86) \
726
    && defined(QT_DEBUG)
727
    /**
728
     * Prevent the executable from being locked in the Symbian emulator. The
729
     * code dramatically simplifies debugging on Symbian, but beyond that has
730
     * no impact.
731
     *
732
     * Force the ZLazyUnloadTimer to fire and therefore unload code segments
733
     * immediately. The code affects Symbian's file server and on the other
734
     * hand needs only to be run once in each emulator run.
735
     */
736
    {
737
        RLoader loader;
738
        CleanupClosePushL(loader);
739
        User::LeaveIfError(loader.Connect());
740
        User::LeaveIfError(loader.CancelLazyDllUnload());
741
        CleanupStack::PopAndDestroy(&loader);
742
    }
743
#endif
744
8f427b2 by axis at 2009-04-24 745
    qt_startup_hook();
746
}
747
e4c60e6 by Denis Dzyubenko at 2010-05-03 748
#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
749
void QCoreApplicationPrivate::symbianInit()
750
{
751
    if (!environmentChangeNotifier)
752
        environmentChangeNotifier.reset(new QEnvironmentChangeNotifier);
753
}
754
#endif
755
756
8f427b2 by axis at 2009-04-24 757
/*!
758
    Destroys the QCoreApplication object.
759
*/
760
QCoreApplication::~QCoreApplication()
761
{
762
    qt_call_post_routines();
763
764
    self = 0;
765
    QCoreApplicationPrivate::is_app_closing = true;
766
    QCoreApplicationPrivate::is_app_running = false;
767
768
#if !defined(QT_NO_THREAD)
769
#if !defined(QT_NO_CONCURRENT)
770
    // Synchronize and stop the global thread pool threads.
7604f80 by Robert Griebl at 2009-06-10 771
    QThreadPool *globalThreadPool = 0;
772
    QT_TRY {
773
        globalThreadPool = QThreadPool::globalInstance();
774
    } QT_CATCH (...) {
775
        // swallow the exception, since destructors shouldn't throw
776
    }
777
    if (globalThreadPool)
778
        globalThreadPool->waitForDone();
8f427b2 by axis at 2009-04-24 779
#endif
780
    QThread::cleanup();
781
#endif
782
783
    d_func()->threadData->eventDispatcher = 0;
784
    if (QCoreApplicationPrivate::eventDispatcher)
785
        QCoreApplicationPrivate::eventDispatcher->closingDown();
786
    QCoreApplicationPrivate::eventDispatcher = 0;
787
788
#ifndef QT_NO_LIBRARY
789
    delete coreappdata()->app_libpaths;
790
    coreappdata()->app_libpaths = 0;
791
#endif
792
}
793
794
795
/*!
796
    Sets the attribute \a attribute if \a on is true;
797
    otherwise clears the attribute.
798
799
    One of the attributes that can be set with this method is
800
    Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel
801
    windows immediately. Normally, resources for widgets are allocated
802
    on demand to improve efficiency and minimize resource usage.
803
    Therefore, if it is important to minimize resource consumption, do
804
    not set this attribute.
805
806
    \sa testAttribute()
807
*/
808
void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
809
{
810
    if (on)
811
        QCoreApplicationPrivate::attribs |= 1 << attribute;
812
    else
813
        QCoreApplicationPrivate::attribs &= ~(1 << attribute);
1e0e674 by Norwegian Rock Cat at 2009-05-04 814
#ifdef Q_OS_MAC
815
    // Turn on the no native menubar here, since we used to
816
    // do this implicitly. We DO NOT flip it off if someone sets
817
    // it to false.
818
    // Ideally, we'd have magic that would be something along the lines of
819
    // "follow MacPluginApplication" unless explicitly set.
820
    // Considering this attribute isn't only at the beginning
821
    // it's unlikely it will ever be a problem, but I want
822
    // to have the behavior documented here.
823
    if (attribute == Qt::AA_MacPluginApplication && on
824
          && !testAttribute(Qt::AA_DontUseNativeMenuBar)) {
825
        setAttribute(Qt::AA_DontUseNativeMenuBar, true);
826
    }
827
#endif
8f427b2 by axis at 2009-04-24 828
}
829
830
/*!
831
  Returns true if attribute \a attribute is set;
832
  otherwise returns false.
833
834
  \sa setAttribute()
835
 */
836
bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
837
{
838
    return QCoreApplicationPrivate::testAttribute(attribute);
839
}
840
841
842
/*!
843
  \internal
844
845
  This function is here to make it possible for Qt extensions to
846
  hook into event notification without subclassing QApplication
847
*/
848
bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
849
{
850
    // Make it possible for Qt Jambi and QSA to hook into events even
851
    // though QApplication is subclassed...
852
    bool result = false;
853
    void *cbdata[] = { receiver, event, &result };
854
    if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
855
        return result;
856
    }
857
858
    // Qt enforces the rule that events can only be sent to objects in
859
    // the current thread, so receiver->d_func()->threadData is
860
    // equivalent to QThreadData::current(), just without the function
861
    // call overhead.
862
    QObjectPrivate *d = receiver->d_func();
863
    QThreadData *threadData = d->threadData;
864
    ++threadData->loopLevel;
865
866
#ifdef QT_JAMBI_BUILD
867
    int deleteWatch = 0;
868
    int *oldDeleteWatch = QObjectPrivate::setDeleteWatch(d, &deleteWatch);
869
870
    bool inEvent = d->inEventHandler;
871
    d->inEventHandler = true;
872
#endif
873
874
    bool returnValue;
7604f80 by Robert Griebl at 2009-06-10 875
    QT_TRY {
8f427b2 by axis at 2009-04-24 876
        returnValue = notify(receiver, event);
7604f80 by Robert Griebl at 2009-06-10 877
    } QT_CATCH (...) {
8f427b2 by axis at 2009-04-24 878
        --threadData->loopLevel;
7604f80 by Robert Griebl at 2009-06-10 879
        QT_RETHROW;
8f427b2 by axis at 2009-04-24 880
    }
881
882
#ifdef QT_JAMBI_BUILD
883
    // Restore the previous state if the object was not deleted..
884
    if (!deleteWatch) {
885
        d->inEventHandler = inEvent;
886
    }
887
    QObjectPrivate::resetDeleteWatch(d, oldDeleteWatch, deleteWatch);
888
#endif
889
    --threadData->loopLevel;
890
    return returnValue;
891
}
892
893
894
/*!
895
  Sends \a event to \a receiver: \a {receiver}->event(\a event).
896
  Returns the value that is returned from the receiver's event
2c96aeb by Martin Smith at 2009-06-23 897
  handler. Note that this function is called for all events sent to
898
  any object in any thread.
8f427b2 by axis at 2009-04-24 899
900
  For certain types of events (e.g. mouse and key events),
901
  the event will be propagated to the receiver's parent and so on up to
902
  the top-level object if the receiver is not interested in the event
903
  (i.e., it returns false).
904
905
  There are five different ways that events can be processed;
906
  reimplementing this virtual function is just one of them. All five
907
  approaches are listed below:
908
  \list 1
909
  \i Reimplementing paintEvent(), mousePressEvent() and so
910
  on. This is the commonest, easiest and least powerful way.
911
912
  \i Reimplementing this function. This is very powerful, providing
913
  complete control; but only one subclass can be active at a time.
914
915
  \i Installing an event filter on QCoreApplication::instance(). Such
916
  an event filter is able to process all events for all widgets, so
917
  it's just as powerful as reimplementing notify(); furthermore, it's
918
  possible to have more than one application-global event filter.
919
  Global event filters even see mouse events for
920
  \l{QWidget::isEnabled()}{disabled widgets}. Note that application
921
  event filters are only called for objects that live in the main
922
  thread.
923
924
  \i Reimplementing QObject::event() (as QWidget does). If you do
925
  this you get Tab key presses, and you get to see the events before
926
  any widget-specific event filters.
927
928
  \i Installing an event filter on the object. Such an event filter gets all
929
  the events, including Tab and Shift+Tab key press events, as long as they
930
  do not change the focus widget.
931
  \endlist
932
933
  \sa QObject::event(), installEventFilter()
934
*/
935
936
bool QCoreApplication::notify(QObject *receiver, QEvent *event)
937
{
938
    Q_D(QCoreApplication);
939
    // no events are delivered after ~QCoreApplication() has started
940
    if (QCoreApplicationPrivate::is_app_closing)
941
        return true;
942
943
    if (receiver == 0) {                        // serious error
944
        qWarning("QCoreApplication::notify: Unexpected null receiver");
945
        return true;
946
    }
947
948
#ifndef QT_NO_DEBUG
949
    d->checkReceiverThread(receiver);
950
#endif
951
952
    return receiver->isWidgetType() ? false : d->notify_helper(receiver, event);
953
}
954
955
bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
956
{
957
    if (receiver->d_func()->threadData == this->threadData) {
958
        // application event filters are only called for objects in the GUI thread
959
        for (int i = 0; i < eventFilters.size(); ++i) {
960
            register QObject *obj = eventFilters.at(i);
961
            if (!obj)
962
                continue;
963
            if (obj->d_func()->threadData != threadData) {
964
                qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
965
                continue;
966
            }
967
            if (obj->eventFilter(receiver, event))
968
                return true;
969
        }
970
    }
971
    return false;
972
}
973
974
bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
975
{
976
    Q_Q(QCoreApplication);
977
    if (receiver != q) {
978
        for (int i = 0; i < receiver->d_func()->eventFilters.size(); ++i) {
979
            register QObject *obj = receiver->d_func()->eventFilters.at(i);
980
            if (!obj)
981
                continue;
982
            if (obj->d_func()->threadData != receiver->d_func()->threadData) {
983
                qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
984
                continue;
985
            }
986
            if (obj->eventFilter(receiver, event))
987
                return true;
988
        }
989
    }
990
    return false;
991
}
992
993
/*!\internal
994
995
  Helper function called by notify()
996
 */
997
bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
998
{
999
    // send to all application event filters
1000
    if (sendThroughApplicationEventFilters(receiver, event))
1001
        return true;
1002
    // send to all receiver event filters
1003
    if (sendThroughObjectEventFilters(receiver, event))
1004
        return true;
1005
    // deliver the event
1006
    return receiver->event(event);
1007
}
1008
1009
/*!
1010
  Returns true if an application object has not been created yet;
1011
  otherwise returns false.
1012
1013
  \sa closingDown()
1014
*/
1015
1016
bool QCoreApplication::startingUp()
1017
{
1018
    return !QCoreApplicationPrivate::is_app_running;
1019
}
1020
1021
/*!
1022
  Returns true if the application objects are being destroyed;
1023
  otherwise returns false.
1024
1025
  \sa startingUp()
1026
*/
1027
1028
bool QCoreApplication::closingDown()
1029
{
1030
    return QCoreApplicationPrivate::is_app_closing;
1031
}
1032
1033
1034
/*!
1035
    Processes all pending events for the calling thread according to
1036
    the specified \a flags until there are no more events to process.
1037
1038
    You can call this function occasionally when your program is busy
1039
    performing a long operation (e.g. copying a file).
1040
1041
    In event you are running a local loop which calls this function
1042
    continuously, without an event loop, the
1043
    \l{QEvent::DeferredDelete}{DeferredDelete} events will
1044
    not be processed. This can affect the behaviour of widgets,
1045
    e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
1046
    events to function properly. An alternative would be to call
1047
    \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
1048
    within that local loop.
1049
1050
    Calling this function processes events only for the calling thread.
1051
1052
    \threadsafe
1053
1054
    \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
1055
*/
1056
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1057
{
1058
    QThreadData *data = QThreadData::current();
1059
    if (!data->eventDispatcher)
1060
        return;
1061
    if (flags & QEventLoop::DeferredDeletion)
1062
        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1063
    data->eventDispatcher->processEvents(flags);
1064
}
1065
1066
/*!
1067
    \overload processEvents()
1068
1069
    Processes pending events for the calling thread for \a maxtime
1070
    milliseconds or until there are no more events to process,
1071
    whichever is shorter.
1072
1073
    You can call this function occasionally when you program is busy
1074
    doing a long operation (e.g. copying a file).
1075
1076
    Calling this function processes events only for the calling thread.
1077
1078
    \threadsafe
1079
1080
    \sa exec(), QTimer, QEventLoop::processEvents()
1081
*/
1082
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime)
1083
{
1084
    QThreadData *data = QThreadData::current();
1085
    if (!data->eventDispatcher)
1086
        return;
21983be by Thiago Macieira at 2010-03-17 1087
    QElapsedTimer start;
8f427b2 by axis at 2009-04-24 1088
    start.start();
1089
    if (flags & QEventLoop::DeferredDeletion)
1090
        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1091
    while (data->eventDispatcher->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1092
        if (start.elapsed() > maxtime)
1093
            break;
1094
        if (flags & QEventLoop::DeferredDeletion)
1095
            QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
1096
    }
1097
}
1098
1099
/*****************************************************************************
1100
  Main event loop wrappers
1101
 *****************************************************************************/
1102
1103
/*!
1104
    Enters the main event loop and waits until exit() is called.
1105
    Returns the value that was set to exit() (which is 0 if exit() is
1106
    called via quit()).
1107
1108
    It is necessary to call this function to start event handling. The
1109
    main event loop receives events from the window system and
1110
    dispatches these to the application widgets.
1111
1112
    To make your application perform idle processing (i.e. executing a
1113
    special function whenever there are no pending events), use a
1114
    QTimer with 0 timeout. More advanced idle processing schemes can
1115
    be achieved using processEvents().
1116
1117
    We recommend that you connect clean-up code to the
1118
    \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1119
    your application's \c{main()} function because on some platforms the
1120
    QCoreApplication::exec() call may not return. For example, on Windows
1121
    when the user logs off, the system terminates the process after Qt
1122
    closes all top-level windows. Hence, there is no guarantee that the
1123
    application will have time to exit its event loop and execute code at
1124
    the end of the \c{main()} function after the QCoreApplication::exec()
1125
    call.
1126
1127
    \sa quit(), exit(), processEvents(), QApplication::exec()
1128
*/
1129
int QCoreApplication::exec()
1130
{
1131
    if (!QCoreApplicationPrivate::checkInstance("exec"))
1132
        return -1;
1133
1134
    QThreadData *threadData = self->d_func()->threadData;
1135
    if (threadData != QThreadData::current()) {
1136
        qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1137
        return -1;
1138
    }
1139
    if (!threadData->eventLoops.isEmpty()) {
1140
        qWarning("QCoreApplication::exec: The event loop is already running");
1141
        return -1;
1142
    }
1143
1144
    threadData->quitNow = false;
1145
    QEventLoop eventLoop;
1146
    self->d_func()->in_exec = true;
1147
    self->d_func()->aboutToQuitEmitted = false;
1148
    int returnCode = eventLoop.exec();
1149
    threadData->quitNow = false;
1150
    if (self) {
1151
        self->d_func()->in_exec = false;
1152
        if (!self->d_func()->aboutToQuitEmitted)
1153
            emit self->aboutToQuit();
1154
        self->d_func()->aboutToQuitEmitted = true;
1155
        sendPostedEvents(0, QEvent::DeferredDelete);
1156
    }
1157
1158
    return returnCode;
1159
}
1160
0b61f3e by Olivier Goffart at 2010-05-28 1161
8f427b2 by axis at 2009-04-24 1162
/*!
1163
  Tells the application to exit with a return code.
1164
1165
    After this function has been called, the application leaves the
1166
    main event loop and returns from the call to exec(). The exec()
1167
    function returns \a returnCode. If the event loop is not running,
1168
    this function does nothing.
1169
1170
  By convention, a \a returnCode of 0 means success, and any non-zero
1171
  value indicates an error.
1172
1173
  Note that unlike the C library function of the same name, this
1174
  function \e does return to the caller -- it is event processing that
1175
  stops.
1176
1177
  \sa quit(), exec()
1178
*/
1179
void QCoreApplication::exit(int returnCode)
1180
{
1181
    if (!self)
1182
        return;
1183
    QThreadData *data = self->d_func()->threadData;
1184
    data->quitNow = true;
1185
    for (int i = 0; i < data->eventLoops.size(); ++i) {
1186
        QEventLoop *eventLoop = data->eventLoops.at(i);
1187
        eventLoop->exit(returnCode);
1188
    }
1189
}
1190
1191
/*****************************************************************************
1192
  QCoreApplication management of posted events
1193
 *****************************************************************************/
1194
1195
/*!
1196
    \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1197
1198
    Sends event \a event directly to receiver \a receiver, using the
1199
    notify() function. Returns the value that was returned from the
1200
    event handler.
1201
1202
    The event is \e not deleted when the event has been sent. The normal
1203
    approach is to create the event on the stack, for example:
1204
66fc16b by Martin Smith at 2009-08-28 1205
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 0
8f427b2 by axis at 2009-04-24 1206
1207
    \sa postEvent(), notify()
1208
*/
1209
1210
/*!
1211
    Adds the event \a event, with the object \a receiver as the
1212
    receiver of the event, to an event queue and returns immediately.
1213
1214
    The event must be allocated on the heap since the post event queue
1215
    will take ownership of the event and delete it once it has been
7ffb1c2 by Geir Vattekar at 2010-06-04 1216
    posted.  It is \e {not safe} to access the event after
8f427b2 by axis at 2009-04-24 1217
    it has been posted.
1218
1219
    When control returns to the main event loop, all events that are
1220
    stored in the queue will be sent using the notify() function.
1221
1222
    Events are processed in the order posted. For more control over
1223
    the processing order, use the postEvent() overload below, which
1224
    takes a priority argument. This function posts all event with a
1225
    Qt::NormalEventPriority.
1226
1227
    \threadsafe
1228
1229
    \sa sendEvent(), notify(), sendPostedEvents()
1230
*/
1231
1232
void QCoreApplication::postEvent(QObject *receiver, QEvent *event)
1233
{
1234
    postEvent(receiver, event, Qt::NormalEventPriority);
1235
}
1236
1237
1238
/*!
1239
    \overload postEvent()
1240
    \since 4.3
1241
1242
    Adds the event \a event, with the object \a receiver as the
1243
    receiver of the event, to an event queue and returns immediately.
1244
1245
    The event must be allocated on the heap since the post event queue
1246
    will take ownership of the event and delete it once it has been
7ffb1c2 by Geir Vattekar at 2010-06-04 1247
    posted.  It is \e {not safe} to access the event after
8f427b2 by axis at 2009-04-24 1248
    it has been posted.
1249
1250
    When control returns to the main event loop, all events that are
1251
    stored in the queue will be sent using the notify() function.
1252
1253
    Events are sorted in descending \a priority order, i.e. events
1254
    with a high \a priority are queued before events with a lower \a
1255
    priority. The \a priority can be any integer value, i.e. between
1256
    INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1257
    details. Events with equal \a priority will be processed in the
1258
    order posted.
1259
1260
    \threadsafe
1261
1262
    \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1263
*/
1264
void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1265
{
1266
    if (receiver == 0) {
1267
        qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1268
        delete event;
1269
        return;
1270
    }
1271
1272
    QThreadData * volatile * pdata = &receiver->d_func()->threadData;
1273
    QThreadData *data = *pdata;
1274
    if (!data) {
1275
        // posting during destruction? just delete the event to prevent a leak
1276
        delete event;
1277
        return;
1278
    }
1279
1280
    // lock the post event mutex
1281
    data->postEventList.mutex.lock();
1282
1283
    // if object has moved to another thread, follow it
1284
    while (data != *pdata) {
1285
        data->postEventList.mutex.unlock();
1286
1287
        data = *pdata;
1288
        if (!data) {
1289
            // posting during destruction? just delete the event to prevent a leak
1290
            delete event;
1291
            return;
1292
        }
1293
1294
        data->postEventList.mutex.lock();
1295
    }
1296
d24029e by Harald Fernengel at 2009-08-17 1297
    QMutexUnlocker locker(&data->postEventList.mutex);
7604f80 by Robert Griebl at 2009-06-10 1298
8f427b2 by axis at 2009-04-24 1299
    // if this is one of the compressible events, do compression
1300
    if (receiver->d_func()->postedEvents
1301
        && self && self->compressEvent(event, receiver, &data->postEventList)) {
1302
        return;
1303
    }
1304
1305
    if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1306
        // remember the current running eventloop for DeferredDelete
1307
        // events posted in the receiver's thread
1308
        event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel));
1309
    }
1310
d4c0be3 by Shane Kearns at 2009-08-20 1311
    // delete the event on exceptions to protect against memory leaks till the event is
41a83e1 by Harald Fernengel at 2009-08-03 1312
    // properly owned in the postEventList
1313
    QScopedPointer<QEvent> eventDeleter(event);
2ff9617 by Olivier Goffart at 2011-06-27 1314
    data->postEventList.addEvent(QPostEvent(receiver, event, priority));
41a83e1 by Harald Fernengel at 2009-08-03 1315
    eventDeleter.take();
7604f80 by Robert Griebl at 2009-06-10 1316
    event->posted = true;
1317
    ++receiver->d_func()->postedEvents;
8f427b2 by axis at 2009-04-24 1318
    data->canWait = false;
7604f80 by Robert Griebl at 2009-06-10 1319
    locker.unlock();
8f427b2 by axis at 2009-04-24 1320
1321
    if (data->eventDispatcher)
1322
        data->eventDispatcher->wakeUp();
1323
}
1324
1325
/*!
1326
  \internal
1327
  Returns true if \a event was compressed away (possibly deleted) and should not be added to the list.
1328
*/
1329
bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1330
{
1331
#ifdef Q_WS_WIN
1332
    Q_ASSERT(event);
1333
    Q_ASSERT(receiver);
1334
    Q_ASSERT(postedEvents);
1335
1336
    // compress posted timers to this object.
1337
    if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1338
        int timerId = ((QTimerEvent *) event)->timerId();
1339
        for (int i=0; i<postedEvents->size(); ++i) {
1340
            const QPostEvent &e = postedEvents->at(i);
1341
            if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1342
                && ((QTimerEvent *) e.event)->timerId() == timerId) {
1343
                delete event;
1344
                return true;
1345
            }
1346
        }
1347
    } else
1348
#endif
1349
        if ((event->type() == QEvent::DeferredDelete
1350
             || event->type() == QEvent::Quit)
1351
            && receiver->d_func()->postedEvents > 0) {
1352
            for (int i = 0; i < postedEvents->size(); ++i) {
1353
                const QPostEvent &cur = postedEvents->at(i);
1354
                if (cur.receiver != receiver
1355
                    || cur.event == 0
1356
                    || cur.event->type() != event->type())
1357
                    continue;
1358
                // found an event for this receiver
1359
                delete event;
1360
                return true;
1361
            }
1362
        }
1363
    return false;
1364
}
1365
1366
/*!
1367
  \fn void QCoreApplication::sendPostedEvents()
1368
  \overload sendPostedEvents()
1369
1370
    Dispatches all posted events, i.e. empties the event queue.
1371
*/
1372
1373
/*!
1374
  Immediately dispatches all events which have been previously queued
1375
  with QCoreApplication::postEvent() and which are for the object \a receiver
1376
  and have the event type \a event_type.
1377
1378
  Events from the window system are \e not dispatched by this
1379
  function, but by processEvents().
1380
1381
  If \a receiver is null, the events of \a event_type are sent for all
1382
  objects. If \a event_type is 0, all the events are sent for \a receiver.
1383
1384
  \note This method must be called from the same thread as its QObject parameter, \a receiver.
1385
1386
  \sa flush(), postEvent()
1387
*/
1388
1389
void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1390
{
1391
    QThreadData *data = QThreadData::current();
1392
1393
    QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1394
}
1395
1396
void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1397
                                               QThreadData *data)
1398
{
1399
    if (event_type == -1) {
1400
        // we were called by an obsolete event dispatcher.
1401
        event_type = 0;
1402
    }
1403
1404
    if (receiver && receiver->d_func()->threadData != data) {
1405
        qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1406
                 "posted events for objects in another thread");
1407
        return;
1408
    }
1409
1410
    ++data->postEventList.recursion;
1411
1412
#ifdef QT3_SUPPORT
1413
    if (event_type == QEvent::ChildInserted) {
1414
        if (receiver) {
1415
            // optimize sendPostedEvents(w, QEvent::ChildInserted) calls away
1416
            receiver->d_func()->sendPendingChildInsertedEvents();
1417
            --data->postEventList.recursion;
1418
            return;
1419
        }
1420
1421
        // ChildInserted events are sent in response to *Request
1422
        event_type = QEvent::ChildInsertedRequest;
1423
    }
1424
#endif
1425
1426
    QMutexLocker locker(&data->postEventList.mutex);
1427
1428
    // by default, we assume that the event dispatcher can go to sleep after
1429
    // processing all events. if any new events are posted while we send
1430
    // events, canWait will be set to false.
1431
    data->canWait = (data->postEventList.size() == 0);
1432
1433
    if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1434
        --data->postEventList.recursion;
1435
        return;
1436
    }
1437
1438
    data->canWait = true;
1439
1440
    // okay. here is the tricky loop. be careful about optimizing
1441
    // this, it looks the way it does for good reasons.
1442
    int startOffset = data->postEventList.startOffset;
1443
    int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1444
    data->postEventList.insertionOffset = data->postEventList.size();
1445
1446
    while (i < data->postEventList.size()) {
1447
        // avoid live-lock
1448
        if (i >= data->postEventList.insertionOffset)
1449
            break;
1450
1451
        const QPostEvent &pe = data->postEventList.at(i);
1452
        ++i;
1453
1454
        if (!pe.event)
1455
            continue;
1456
        if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1457
            data->canWait = false;
1458
            continue;
1459
        }
1460
1461
        if (pe.event->type() == QEvent::DeferredDelete) {
1462
            // DeferredDelete events are only sent when we are explicitly asked to
1463
            // (s.a. QEvent::DeferredDelete), and then only if the event loop that
1464
            // posted the event has returned.
1465
            const bool allowDeferredDelete =
1466
                (quintptr(pe.event->d) > unsigned(data->loopLevel)
1467
                 || (!quintptr(pe.event->d) && data->loopLevel > 0)
1468
                 || (event_type == QEvent::DeferredDelete
1469
                     && quintptr(pe.event->d) == unsigned(data->loopLevel)));
1470
            if (!allowDeferredDelete) {
1471
                // cannot send deferred delete
1472
                if (!event_type && !receiver) {
1473
                    // don't lose the event
2ff9617 by Olivier Goffart at 2011-06-27 1474
                    data->postEventList.addEvent(pe);
8f427b2 by axis at 2009-04-24 1475
                    const_cast<QPostEvent &>(pe).event = 0;
1476
                }
1477
                continue;
1478
            }
1479
        }
1480
1481
        // first, we diddle the event so that we can deliver
1482
        // it, and that no one will try to touch it later.
1483
        pe.event->posted = false;
1484
        QEvent * e = pe.event;
1485
        QObject * r = pe.receiver;
1486
1487
        --r->d_func()->postedEvents;
1488
        Q_ASSERT(r->d_func()->postedEvents >= 0);
1489
1490
        // next, update the data structure so that we're ready
1491
        // for the next event.
1492
        const_cast<QPostEvent &>(pe).event = 0;
1493
1494
        locker.unlock();
1495
        // after all that work, it's time to deliver the event.
1496
#ifdef QT_NO_EXCEPTIONS
1497
        QCoreApplication::sendEvent(r, e);
1498
#else
1499
        try {
1500
            QCoreApplication::sendEvent(r, e);
1501
        } catch (...) {
1502
            delete e;
1503
            locker.relock();
1504
1505
            // since we were interrupted, we need another pass to make sure we clean everything up
1506
            data->canWait = false;
1507
1508
            // uglehack: copied from below
1509
            --data->postEventList.recursion;
1510
            if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1511
                data->eventDispatcher->wakeUp();
1512
            throw;              // rethrow
1513
        }
1514
#endif
1515
1516
        delete e;
1517
        locker.relock();
1518
1519
        // careful when adding anything below this point - the
1520
        // sendEvent() call might invalidate any invariants this
1521
        // function depends on.
1522
    }
1523
1524
    --data->postEventList.recursion;
1525
    if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
1526
        data->eventDispatcher->wakeUp();
1527
1528
    // clear the global list, i.e. remove everything that was
1529
    // delivered.
1530
    if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1531
        const QPostEventList::iterator it = data->postEventList.begin();
1532
        data->postEventList.erase(it, it + data->postEventList.startOffset);
1533
        data->postEventList.insertionOffset -= data->postEventList.startOffset;
1534
        Q_ASSERT(data->postEventList.insertionOffset >= 0);
1535
        data->postEventList.startOffset = 0;
1536
    }
1537
}
1538
1539
/*!
1540
  Removes all events posted using postEvent() for \a receiver.
1541
1542
  The events are \e not dispatched, instead they are removed from the
1543
  queue. You should never need to call this function. If you do call it,
1544
  be aware that killing events may cause \a receiver to break one or
1545
  more invariants.
1546
1547
  \threadsafe
1548
*/
1549
1550
void QCoreApplication::removePostedEvents(QObject *receiver)
1551
{
1552
    removePostedEvents(receiver, 0);
1553
}
1554
1555
/*!
1556
    \overload removePostedEvents()
1557
    \since 4.3
1558
1559
    Removes all events of the given \a eventType that were posted
1560
    using postEvent() for \a receiver.
1561
1562
    The events are \e not dispatched, instead they are removed from
1563
    the queue. You should never need to call this function. If you do
1564
    call it, be aware that killing events may cause \a receiver to
1565
    break one or more invariants.
1566
1567
    If \a receiver is null, the events of \a eventType are removed for
1568
    all objects. If \a eventType is 0, all the events are removed for
1569
    \a receiver.
1570
1571
    \threadsafe
1572
*/
1573
1574
void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1575
{
1576
#ifdef QT3_SUPPORT
1577
    if (eventType == QEvent::ChildInserted)
1578
        eventType = QEvent::ChildInsertedRequest;
1579
#endif
1580
1581
    QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current();
1582
    QMutexLocker locker(&data->postEventList.mutex);
1583
1584
    // the QObject destructor calls this function directly.  this can
1585
    // happen while the event loop is in the middle of posting events,
1586
    // and when we get here, we may not have any more posted events
1587
    // for this object.
1588
    if (receiver && !receiver->d_func()->postedEvents)
1589
        return;
1590
b3b2bc3 by Thierry Bastian at 2009-08-12 1591
    //we will collect all the posted events for the QObject
1592
    //and we'll delete after the mutex was unlocked
1593
    QVarLengthArray<QEvent*> events;
8f427b2 by axis at 2009-04-24 1594
    int n = data->postEventList.size();
1595
    int j = 0;
1596
1597
    for (int i = 0; i < n; ++i) {
1598
        const QPostEvent &pe = data->postEventList.at(i);
1599
1600
        if ((!receiver || pe.receiver == receiver)
1601
            && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1602
            --pe.receiver->d_func()->postedEvents;
1603
#ifdef QT3_SUPPORT
1604
            if (pe.event->type() == QEvent::ChildInsertedRequest)
66d6813 by Olivier Goffart at 2010-05-28 1605
                pe.receiver->d_func()->pendingChildInsertedEvents.clear();
8f427b2 by axis at 2009-04-24 1606
#endif
1607
            pe.event->posted = false;
b3b2bc3 by Thierry Bastian at 2009-08-12 1608
            events.append(pe.event);
8f427b2 by axis at 2009-04-24 1609
            const_cast<QPostEvent &>(pe).event = 0;
1610
        } else if (!data->postEventList.recursion) {
1611
            if (i != j)
1612
                data->postEventList.swap(i, j);
1613
            ++j;
1614
        }
1615
    }
1616
1617
#ifdef QT_DEBUG
1618
    if (receiver && eventType == 0) {
1619
        Q_ASSERT(!receiver->d_func()->postedEvents);
1620
    }
1621
#endif
1622
1623
    if (!data->postEventList.recursion) {
1624
        // truncate list
1625
        data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1626
    }
1627
b3b2bc3 by Thierry Bastian at 2009-08-12 1628
    locker.unlock();
1629
    for (int i = 0; i < events.count(); ++i) {
1630
        delete events[i];
1631
    }
1632
}
8f427b2 by axis at 2009-04-24 1633
1634
/*!
1635
  Removes \a event from the queue of posted events, and emits a
1636
  warning message if appropriate.
1637
1638
  \warning This function can be \e really slow. Avoid using it, if
1639
  possible.
1640
1641
  \threadsafe
1642
*/
1643
1644
void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1645
{
1646
    if (!event || !event->posted)
1647
        return;
1648
1649
    QThreadData *data = QThreadData::current();
1650
1651
    QMutexLocker locker(&data->postEventList.mutex);
1652
1653
    if (data->postEventList.size() == 0) {
1654
#if defined(QT_DEBUG)
1655
        qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1656
                (void*)event, event->type());
1657
        return;
1658
#endif
1659
    }
1660
1661
    for (int i = 0; i < data->postEventList.size(); ++i) {
1662
        const QPostEvent & pe = data->postEventList.at(i);
1663
        if (pe.event == event) {
1664
#ifndef QT_NO_DEBUG
1665
            qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1666
                     event->type(),
1667
                     pe.receiver->metaObject()->className(),
1668
                     pe.receiver->objectName().toLocal8Bit().data());
1669
#endif
1670
            --pe.receiver->d_func()->postedEvents;
1671
            pe.event->posted = false;
1672
            delete pe.event;
1673
            const_cast<QPostEvent &>(pe).event = 0;
1674
            return;
1675
        }
1676
    }
1677
}
1678
1679
/*!\reimp
1680
1681
*/
1682
bool QCoreApplication::event(QEvent *e)
1683
{
1684
    if (e->type() == QEvent::Quit) {
1685
        quit();
1686
        return true;
1687
    }
1688
    return QObject::event(e);
1689
}
1690
1691
/*! \enum QCoreApplication::Encoding
1692
1693
    This enum type defines the 8-bit encoding of character string
1694
    arguments to translate():
1695
1696
    \value CodecForTr  The encoding specified by
1697
                       QTextCodec::codecForTr() (Latin-1 if none has
1698
                       been set).
1699
    \value UnicodeUTF8  UTF-8.
1700
    \value DefaultCodec  (Obsolete) Use CodecForTr instead.
1701
1702
    \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
1703
*/
1704
1705
/*!
1706
    Tells the application to exit with return code 0 (success).
1707
    Equivalent to calling QCoreApplication::exit(0).
1708
1709
    It's common to connect the QApplication::lastWindowClosed() signal
1710
    to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1711
    signals in QAction, QMenu, or QMenuBar to it.
1712
1713
    Example:
1714
66fc16b by Martin Smith at 2009-08-28 1715
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 1
8f427b2 by axis at 2009-04-24 1716
1717
    \sa exit(), aboutToQuit(), QApplication::lastWindowClosed()
1718
*/
1719
1720
void QCoreApplication::quit()
1721
{
1722
    exit(0);
1723
}
1724
1725
/*!
1726
  \fn void QCoreApplication::aboutToQuit()
1727
1728
  This signal is emitted when the application is about to quit the
1729
  main event loop, e.g. when the event loop level drops to zero.
1730
  This may happen either after a call to quit() from inside the
1731
  application or when the users shuts down the entire desktop session.
1732
1733
  The signal is particularly useful if your application has to do some
1734
  last-second cleanup. Note that no user interaction is possible in
1735
  this state.
1736
1737
  \sa quit()
1738
*/
1739
1740
#ifndef QT_NO_TRANSLATION
1741
/*!
1742
    Adds the translation file \a translationFile to the list of
1743
    translation files to be used for translations.
1744
1745
    Multiple translation files can be installed. Translations are
1746
    searched for in the reverse order in which they were installed,
1747
    so the most recently installed translation file is searched first
1748
    and the first translation file installed is searched last.
1749
    The search stops as soon as a translation containing a matching
1750
    string is found.
1751
1752
    Installing or removing a QTranslator, or changing an installed QTranslator
1753
    generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
1754
    QCoreApplication instance. A QApplication instance will propagate the event
1755
    to all toplevel windows, where a reimplementation of changeEvent can
1756
    re-translate the user interface by passing user-visible strings via the
1757
    tr() function to the respective property setters. User-interface classes
1758
    generated by \l{Qt Designer} provide a \c retranslateUi() function that can be
1759
    called.
1760
1761
    \sa removeTranslator() translate() QTranslator::load() {Dynamic Translation}
1762
*/
1763
1764
void QCoreApplication::installTranslator(QTranslator *translationFile)
1765
{
1766
    if (!translationFile)
1767
        return;
1768
1769
    if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
1770
        return;
1771
    QCoreApplicationPrivate *d = self->d_func();
1772
    d->translators.prepend(translationFile);
1773
1774
#ifndef QT_NO_TRANSLATION_BUILDER
1775
    if (translationFile->isEmpty())
1776
        return;
1777
#endif
1778
1779
    QEvent ev(QEvent::LanguageChange);
1780
    QCoreApplication::sendEvent(self, &ev);
1781
}
1782
1783
/*!
1784
    Removes the translation file \a translationFile from the list of
1785
    translation files used by this application. (It does not delete the
1786
    translation file from the file system.)
1787
1788
    \sa installTranslator() translate(), QObject::tr()
1789
*/
1790
1791
void QCoreApplication::removeTranslator(QTranslator *translationFile)
1792
{
1793
    if (!translationFile)
1794
        return;
1795
    if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
1796
        return;
1797
    QCoreApplicationPrivate *d = self->d_func();
1798
    if (d->translators.removeAll(translationFile) && !self->closingDown()) {
1799
        QEvent ev(QEvent::LanguageChange);
1800
        QCoreApplication::sendEvent(self, &ev);
1801
    }
1802
}
1803
1804
/*!
1805
    \overload translate()
1806
*/
1807
QString QCoreApplication::translate(const char *context, const char *sourceText,
1808
                                    const char *disambiguation, Encoding encoding)
1809
{
1810
    return translate(context, sourceText, disambiguation, encoding, -1);
1811
}
1812
1813
static void replacePercentN(QString *result, int n)
1814
{
1815
    if (n >= 0) {
1816
        int percentPos = 0;
1817
        int len = 0;
1818
        while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
1819
            len = 1;
1820
            QString fmt;
1821
            if (result->at(percentPos + len) == QLatin1Char('L')) {
1822
                ++len;
1823
                fmt = QLatin1String("%L1");
1824
            } else {
1825
                fmt = QLatin1String("%1");
1826
            }
1827
            if (result->at(percentPos + len) == QLatin1Char('n')) {
1828
                fmt = fmt.arg(n);
1829
                ++len;
1830
                result->replace(percentPos, len, fmt);
1831
                len = fmt.length();
1832
            }
1833
        }
1834
    }
1835
}
1836
1837
/*!
1838
    \reentrant
1839
    \since 4.5
1840
1841
    Returns the translation text for \a sourceText, by querying the
1842
    installed translation files. The translation files are searched
1843
    from the most recently installed file back to the first
1844
    installed file.
1845
1846
    QObject::tr() and QObject::trUtf8() provide this functionality
1847
    more conveniently.
1848
1849
    \a context is typically a class name (e.g., "MyDialog") and \a
1850
    sourceText is either English text or a short identifying text.
1851
1852
    \a disambiguation is an identifying string, for when the same \a
1853
    sourceText is used in different roles within the same context. By
1854
    default, it is null.
1855
1856
    See the \l QTranslator and \l QObject::tr() documentation for
1857
    more information about contexts, disambiguations and comments.
1858
1859
    \a encoding indicates the 8-bit encoding of character strings.
1860
1861
    \a n is used in conjunction with \c %n to support plural forms.
1862
    See QObject::tr() for details.
1863
1864
    If none of the translation files contain a translation for \a
1865
    sourceText in \a context, this function returns a QString
1866
    equivalent of \a sourceText. The encoding of \a sourceText is
1867
    specified by \e encoding; it defaults to CodecForTr.
1868
1869
    This function is not virtual. You can use alternative translation
1870
    techniques by subclassing \l QTranslator.
1871
1872
    \warning This method is reentrant only if all translators are
1873
    installed \e before calling this method. Installing or removing
1874
    translators while performing translations is not supported. Doing
1875
    so will most likely result in crashes or other undesirable
1876
    behavior.
1877
1878
    \sa QObject::tr() installTranslator() QTextCodec::codecForTr()
1879
*/
1880
1881
1882
QString QCoreApplication::translate(const char *context, const char *sourceText,
1883
                                    const char *disambiguation, Encoding encoding, int n)
1884
{
1885
    QString result;
1886
1887
    if (!sourceText)
1888
        return result;
1889
1890
    if (self && !self->d_func()->translators.isEmpty()) {
1891
        QList<QTranslator*>::ConstIterator it;
1892
        QTranslator *translationFile;
1893
        for (it = self->d_func()->translators.constBegin(); it != self->d_func()->translators.constEnd(); ++it) {
1894
            translationFile = *it;
1895
            result = translationFile->translate(context, sourceText, disambiguation, n);
1896
            if (!result.isEmpty())
1897
                break;
1898
        }
1899
    }
1900
1901
    if (result.isEmpty()) {
1902
#ifdef QT_NO_TEXTCODEC
1903
        Q_UNUSED(encoding)
1904
#else
1905
        if (encoding == UnicodeUTF8)
1906
            result = QString::fromUtf8(sourceText);
1907
        else if (QTextCodec::codecForTr() != 0)
1908
            result = QTextCodec::codecForTr()->toUnicode(sourceText);
1909
        else
1910
#endif
1911
            result = QString::fromLatin1(sourceText);
1912
    }
1913
1914
    replacePercentN(&result, n);
1915
    return result;
1916
}
1917
20d73ef by Oswald Buddenhagen at 2009-07-06 1918
// Declared in qglobal.h
1919
QString qtTrId(const char *id, int n)
1920
{
1921
    return QCoreApplication::translate(0, id, 0, QCoreApplication::UnicodeUTF8, n);
1922
}
1923
8f427b2 by axis at 2009-04-24 1924
bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
1925
{
1926
    return QCoreApplication::self
1927
           && QCoreApplication::self->d_func()->translators.contains(translator);
1928
}
1929
1930
#endif //QT_NO_TRANSLATE
1931
1932
/*!
1933
    Returns the directory that contains the application executable.
1934
1935
    For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1936
    directory, and you run the \c{regexp} example, this function will
1937
    return "C:/Trolltech/Qt/examples/tools/regexp".
1938
1939
    On Mac OS X this will point to the directory actually containing the
1940
    executable, which may be inside of an application bundle (if the
1941
    application is bundled).
1942
1943
    \warning On Linux, this function will try to get the path from the
1944
    \c {/proc} file system. If that fails, it assumes that \c
1945
    {argv[0]} contains the absolute file name of the executable. The
1946
    function also assumes that the current directory has not been
1947
    changed by the application.
1948
0179bc8 by axis at 2009-08-21 1949
    In Symbian this function will return the application private directory,
1950
    not the path to executable itself, as those are always in \c {/sys/bin}.
b85f6a4 by Shane Kearns at 2009-09-22 1951
    If the application is in a read only drive, i.e. ROM, then the private path
1952
    on the system drive will be returned.
8f427b2 by axis at 2009-04-24 1953
1954
    \sa applicationFilePath()
1955
*/
1956
QString QCoreApplication::applicationDirPath()
1957
{
1958
    if (!self) {
1959
        qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
1960
        return QString();
1961
    }
1962
1963
    QCoreApplicationPrivate *d = self->d_func();
8e9b041 by Jesper Thomschütz at 2009-05-14 1964
    if (d->cachedApplicationDirPath.isNull())
8f427b2 by axis at 2009-04-24 1965
#if defined(Q_OS_SYMBIAN)
1966
    {
1967
        QString appPath;
b85f6a4 by Shane Kearns at 2009-09-22 1968
        RFs& fs = qt_s60GetRFs();
1969
        TChar driveChar;
1970
        QChar qDriveChar;
1971
        driveChar = (RProcess().FileName())[0];
1972
1973
        //Check if the process is installed in a read only drive (typically ROM),
1974
        //and use the system drive (typically C:) if so.
1975
        TInt drive;
1976
        TDriveInfo driveInfo;
1977
        TInt err = fs.CharToDrive(driveChar, drive);
8f427b2 by axis at 2009-04-24 1978
        if (err == KErrNone) {
b85f6a4 by Shane Kearns at 2009-09-22 1979
            err = fs.Drive(driveInfo, drive);
1980
        }
1981
        if (err != KErrNone || (driveInfo.iDriveAtt & KDriveAttRom) || (driveInfo.iMediaAtt
1982
            & KMediaAttWriteProtected)) {
358d5b2 by Miikka Heikkinen at 2011-05-20 1983
            drive = fs.GetSystemDrive();
b3f3ab7 by Shane Kearns at 2009-09-23 1984
            fs.DriveToChar(drive, driveChar);
8f427b2 by axis at 2009-04-24 1985
        }
1986
b85f6a4 by Shane Kearns at 2009-09-22 1987
        qDriveChar = QChar(QLatin1Char(driveChar)).toUpper();
1988
1989
        TFileName privatePath;
1990
        fs.PrivatePath(privatePath);
1991
        appPath = qt_TDesC2QString(privatePath);
1992
        appPath.prepend(QLatin1Char(':')).prepend(qDriveChar);
1993
1994
        d->cachedApplicationDirPath = QFileInfo(appPath).path();
8f427b2 by axis at 2009-04-24 1995
    }
1996
#else
1997
        d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
1998
#endif
1999
    return d->cachedApplicationDirPath;
2000
}
2001
2002
/*!
2003
    Returns the file path of the application executable.
2004
2005
    For example, if you have installed Qt in the \c{/usr/local/qt}
2006
    directory, and you run the \c{regexp} example, this function will
2007
    return "/usr/local/qt/examples/tools/regexp/regexp".
2008
2009
    \warning On Linux, this function will try to get the path from the
2010
    \c {/proc} file system. If that fails, it assumes that \c
2011
    {argv[0]} contains the absolute file name of the executable. The
2012
    function also assumes that the current directory has not been
2013
    changed by the application.
2014
2015
    \sa applicationDirPath()
2016
*/
2017
QString QCoreApplication::applicationFilePath()
2018
{
2019
    if (!self) {
2020
        qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2021
        return QString();
2022
    }
2023
2024
    QCoreApplicationPrivate *d = self->d_func();
8e9b041 by Jesper Thomschütz at 2009-05-14 2025
    if (!d->cachedApplicationFilePath.isNull())
8f427b2 by axis at 2009-04-24 2026
        return d->cachedApplicationFilePath;
2027
cfadf08 by Marius Storm-Olsen at 2009-07-01 2028
#if defined(Q_WS_WIN)
2029
    d->cachedApplicationFilePath = QFileInfo(qAppFileName()).filePath();
8f427b2 by axis at 2009-04-24 2030
    return d->cachedApplicationFilePath;
2031
#elif defined(Q_WS_MAC)
2032
    QString qAppFileName_str = qAppFileName();
2033
    if(!qAppFileName_str.isEmpty()) {
2034
        QFileInfo fi(qAppFileName_str);
2035
        d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
2036
        return d->cachedApplicationFilePath;
2037
    }
2038
#endif
2039
#if defined(Q_OS_SYMBIAN)
2040
    QString appPath;
2041
    RProcess proc;
2042
    TInt err = proc.Open(proc.Id());
2043
    if (err == KErrNone) {
2044
        TFileName procName = proc.FileName();
2045
        appPath.append(QString(reinterpret_cast<const QChar*>(procName.Ptr()), procName.Length()));
2046
        proc.Close();
2047
    }
2048
2049
    d->cachedApplicationFilePath = appPath;
2050
    return d->cachedApplicationFilePath;
2051
2052
#elif defined( Q_OS_UNIX )
2053
#  ifdef Q_OS_LINUX
2054
    // Try looking for a /proc/<pid>/exe symlink first which points to
2055
    // the absolute path of the executable
2056
    QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
2057
    if (pfi.exists() && pfi.isSymLink()) {
2058
        d->cachedApplicationFilePath = pfi.canonicalFilePath();
2059
        return d->cachedApplicationFilePath;
2060
    }
2061
#  endif
2062
2063
    QString argv0 = QFile::decodeName(QByteArray(argv()[0]));
2064
    QString absPath;
2065
2066
    if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
2067
        /*
2068
          If argv0 starts with a slash, it is already an absolute
2069
          file path.
2070
        */
2071
        absPath = argv0;
2072
    } else if (argv0.contains(QLatin1Char('/'))) {
2073
        /*
2074
          If argv0 contains one or more slashes, it is a file path
2075
          relative to the current directory.
2076
        */
2077
        absPath = QDir::current().absoluteFilePath(argv0);
2078
    } else {
2079
        /*
2080
          Otherwise, the file path has to be determined using the
2081
          PATH environment variable.
2082
        */
2083
        QByteArray pEnv = qgetenv("PATH");
2084
        QDir currentDir = QDir::current();
30ed4ee by Thierry Bastian at 2009-05-25 2085
        QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1Char(':'));
8f427b2 by axis at 2009-04-24 2086
        for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
2087
            if ((*p).isEmpty())
2088
                continue;
2089
            QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
2090
            QFileInfo candidate_fi(candidate);
2091
            if (candidate_fi.exists() && !candidate_fi.isDir()) {
2092
                absPath = candidate;
2093
                break;
2094
            }
2095
        }
2096
    }
2097
2098
    absPath = QDir::cleanPath(absPath);
2099
2100
    QFileInfo fi(absPath);
2101
    d->cachedApplicationFilePath = fi.exists() ? fi.canonicalFilePath() : QString();
2102
    return d->cachedApplicationFilePath;
2103
#endif
2104
}
2105
2106
/*!
2107
    \since 4.4
2108
2109
    Returns the current process ID for the application.
2110
*/
2111
qint64 QCoreApplication::applicationPid()
2112
{
2113
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
2114
    return GetCurrentProcessId();
d7b6888 by Robert Griebl at 2009-07-29 2115
#elif defined(Q_OS_VXWORKS)
2116
    return (pid_t) taskIdCurrent;
8f427b2 by axis at 2009-04-24 2117
#else
2118
    return getpid();
2119
#endif
2120
}
2121
2122
/*!
2123
    \obsolete
2124
2125
    Use arguments().size() instead.
2126
*/
2127
int QCoreApplication::argc()
2128
{
2129
    if (!self) {
2130
        qWarning("QCoreApplication::argc: Please instantiate the QApplication object first");
2131
        return 0;
2132
    }
2133
    return self->d_func()->argc;
2134
}
2135
2136
2137
/*!
2138
    \obsolete
2139
2140
    Use arguments() instead.
2141
*/
2142
char **QCoreApplication::argv()
2143
{
2144
    if (!self) {
2145
        qWarning("QCoreApplication::argv: Please instantiate the QApplication object first");
2146
        return 0;
2147
    }
2148
    return self->d_func()->argv;
2149
}
2150
2151
/*!
2152
    \since 4.1
2153
2154
    Returns the list of command-line arguments.
2155
2156
    Usually arguments().at(0) is the program name, arguments().at(1)
2157
    is the first argument, and arguments().last() is the last
2158
    argument. See the note below about Windows.
2159
2160
    Calling this function is slow - you should store the result in a variable
2161
    when parsing the command line.
2162
2163
    \warning On Unix, this list is built from the argc and argv parameters passed
2164
    to the constructor in the main() function. The string-data in argv is
2165
    interpreted using QString::fromLocal8Bit(); hence it is not possible to
34d66c9 by David Boddie at 2009-08-27 2166
    pass, for example, Japanese command line arguments on a system that runs in a
2167
    Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2168
    Unicode-based.
8f427b2 by axis at 2009-04-24 2169
2170
    On NT-based Windows, this limitation does not apply either.
2171
    On Windows, the arguments() are not built from the contents of argv/argc, as
2172
    the content does not support Unicode. Instead, the arguments() are constructed
2173
    from the return value of
2174
    \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2175
    As a result of this, the string given by arguments().at(0) might not be
2176
    the program name on Windows, depending on how the application was started.
2177
a601a45 by Miikka Heikkinen at 2011-01-11 2178
    For Symbian applications started with \c RApaLsSession::StartApp one can specify
2179
    arguments using \c CApaCommandLine::SetTailEndL function. Such arguments are only
2180
    available via this method; they will not be passed to \c main function. Also note
2181
    that only 8-bit string data set with \c CApaCommandLine::SetTailEndL is supported
2182
    by this function.
2183
8f427b2 by axis at 2009-04-24 2184
    \sa applicationFilePath()
2185
*/
2186
2187
QStringList QCoreApplication::arguments()
2188
{
2189
    QStringList list;
2190
2191
    if (!self) {
2192
        qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2193
        return list;
2194
    }
2195
#ifdef Q_OS_WIN
5ae330b by miniak at 2009-07-01 2196
    QString cmdline = QString::fromWCharArray(GetCommandLine());
8f427b2 by axis at 2009-04-24 2197
2198
#if defined(Q_OS_WINCE)
2199
    wchar_t tempFilename[MAX_PATH+1];
5ae330b by miniak at 2009-07-01 2200
    if (GetModuleFileName(0, tempFilename, MAX_PATH)) {
8f427b2 by axis at 2009-04-24 2201
        tempFilename[MAX_PATH] = 0;
5ae330b by miniak at 2009-07-01 2202
        cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" "));
8f427b2 by axis at 2009-04-24 2203
    }
2204
#endif // Q_OS_WINCE
2205
2206
    list = qWinCmdArgs(cmdline);
2207
    if (self->d_func()->application_type) { // GUI app? Skip known - see qapplication.cpp
2208
        QStringList stripped;
2209
        for (int a = 0; a < list.count(); ++a) {
2210
            QString arg = list.at(a);
2211
            QByteArray l1arg = arg.toLatin1();
2212
            if (l1arg == "-qdevel" ||
2213
                l1arg == "-qdebug" ||
2214
                l1arg == "-reverse" ||
2215
                l1arg == "-stylesheet" ||
3ab7dc5 by Gunnar Sletta at 2009-04-24 2216
                l1arg == "-widgetcount")
8f427b2 by axis at 2009-04-24 2217
                ;
a9e5329 by Lasse Holmstedt at 2010-09-17 2218
            else if (l1arg.startsWith("-style=") ||
2219
                     l1arg.startsWith("-qmljsdebugger="))
8f427b2 by axis at 2009-04-24 2220
                ;
2221
            else if (l1arg == "-style" ||
2222
                     l1arg == "-session" ||
d245961 by Petri Kiiskinen at 2009-09-29 2223
                     l1arg == "-graphicssystem" ||
2224
                     l1arg == "-testability")
8f427b2 by axis at 2009-04-24 2225
                ++a;
2226
            else
2227
                stripped += arg;
2228
        }
2229
        list = stripped;
2230
    }
2231
#else
2232
    const int ac = self->d_func()->argc;
2233
    char ** const av = self->d_func()->argv;
2234
    for (int a = 0; a < ac; ++a) {
2235
        list << QString::fromLocal8Bit(av[a]);
2236
    }
2237
#endif
2238
2239
    return list;
2240
}
2241
2242
/*!
2243
    \property QCoreApplication::organizationName
2244
    \brief the name of the organization that wrote this application
2245
2246
    The value is used by the QSettings class when it is constructed
2247
    using the empty constructor. This saves having to repeat this
2248
    information each time a QSettings object is created.
2249
2250
    On Mac, QSettings uses organizationDomain() as the organization
2251
    if it's not an empty string; otherwise it uses
2252
    organizationName(). On all other platforms, QSettings uses
2253
    organizationName() as the organization.
2254
2255
    \sa organizationDomain applicationName
2256
*/
2257
2258
void QCoreApplication::setOrganizationName(const QString &orgName)
2259
{
2260
    coreappdata()->orgName = orgName;
2261
}
2262
2263
QString QCoreApplication::organizationName()
2264
{
2265
    return coreappdata()->orgName;
2266
}
2267
2268
/*!
2269
    \property QCoreApplication::organizationDomain
2270
    \brief the Internet domain of the organization that wrote this application
2271
2272
    The value is used by the QSettings class when it is constructed
2273
    using the empty constructor. This saves having to repeat this
2274
    information each time a QSettings object is created.
2275
2276
    On Mac, QSettings uses organizationDomain() as the organization
2277
    if it's not an empty string; otherwise it uses organizationName().
2278
    On all other platforms, QSettings uses organizationName() as the
2279
    organization.
2280
2281
    \sa organizationName applicationName applicationVersion
2282
*/
2283
void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2284
{
2285
    coreappdata()->orgDomain = orgDomain;
2286
}
2287
2288
QString QCoreApplication::organizationDomain()
2289
{
2290
    return coreappdata()->orgDomain;
2291
}
2292
2293
/*!
2294
    \property QCoreApplication::applicationName
2295
    \brief the name of this application
2296
2297
    The value is used by the QSettings class when it is constructed
2298
    using the empty constructor. This saves having to repeat this
2299
    information each time a QSettings object is created.
2300
2301
    \sa organizationName organizationDomain applicationVersion
2302
*/
2303
void QCoreApplication::setApplicationName(const QString &application)
2304
{
2305
    coreappdata()->application = application;
2306
}
2307
2308
QString QCoreApplication::applicationName()
2309
{
2310
    return coreappdata()->application;
2311
}
2312
2313
/*!
2314
    \property QCoreApplication::applicationVersion
2315
    \since 4.4
2316
    \brief the version of this application
2317
2318
    \sa applicationName organizationName organizationDomain
2319
*/
2320
void QCoreApplication::setApplicationVersion(const QString &version)
2321
{
2322
    coreappdata()->applicationVersion = version;
2323
}
2324
2325
QString QCoreApplication::applicationVersion()
2326
{
2327
    return coreappdata()->applicationVersion;
2328
}
2329
e709077 by Tasuku Suzuki at 2010-04-29 2330
#ifndef QT_NO_LIBRARY
8f427b2 by axis at 2009-04-24 2331
820b508 by mread at 2011-09-28 2332
#if defined(Q_OS_SYMBIAN)
2333
void qt_symbian_installLibraryPaths(QString installPathPlugins, QStringList& libPaths)
2334
{
2335
    // Add existing path on all drives for relative PluginsPath in Symbian
2336
    QString tempPath = installPathPlugins;
2337
    if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
2338
        tempPath += QDir::separator();
2339
    }
2340
    RFs& fs = qt_s60GetRFs();
2341
    TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
2342
    // Symbian searches should start from Y:. Fix start drive otherwise TFindFile starts from the session drive
2343
    _LIT(KStartDir, "Y:");
2344
    TFileName dirPath(KStartDir);
2345
    dirPath.Append(tempPathPtr);
2346
    TFindFile finder(fs);
2347
    TInt err = finder.FindByDir(tempPathPtr, dirPath);
2348
    while (err == KErrNone) {
2349
        QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
2350
                         finder.File().Length());
2351
        foundDir = QDir(foundDir).canonicalPath();
2352
        if (!libPaths.contains(foundDir))
2353
            libPaths.append(foundDir);
2354
        err = finder.Find();
2355
    }
2356
}
2357
#endif
2358
8f427b2 by axis at 2009-04-24 2359
Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
2360
2361
/*!
2362
    Returns a list of paths that the application will search when
2363
    dynamically loading libraries.
2364
2365
    Qt provides default library paths, but they can also be set using
2366
    a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2367
    will override default values.
2368
2369
    This list will include the installation directory for plugins if
2370
    it exists (the default installation directory for plugins is \c
2371
    INSTALL/plugins, where \c INSTALL is the directory where Qt was
2372
    installed).  The directory of the application executable (NOT the
2373
    working directory) is always added, as well as the colon separated
2374
    entries of the QT_PLUGIN_PATH environment variable.
2375
2376
    If you want to iterate over the list, you can use the \l foreach
2377
    pseudo-keyword:
2378
66fc16b by Martin Smith at 2009-08-28 2379
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 2
8f427b2 by axis at 2009-04-24 2380
2381
    \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2382
        {How to Create Qt Plugins}
2383
*/
2384
QStringList QCoreApplication::libraryPaths()
2385
{
2386
    QMutexLocker locker(libraryPathMutex());
2387
    if (!coreappdata()->app_libpaths) {
2388
        QStringList *app_libpaths = coreappdata()->app_libpaths = new QStringList;
2389
        QString installPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
2390
#if defined(Q_OS_SYMBIAN)
fe24f53 by Janne Anttila at 2009-09-09 2391
        if (installPathPlugins.at(1) != QChar(QLatin1Char(':'))) {
820b508 by mread at 2011-09-28 2392
            qt_symbian_installLibraryPaths(installPathPlugins, *app_libpaths);
8f427b2 by axis at 2009-04-24 2393
        }
2394
#else
2395
        if (QFile::exists(installPathPlugins)) {
2396
            // Make sure we convert from backslashes to slashes.
2397
            installPathPlugins = QDir(installPathPlugins).canonicalPath();
2398
            if (!app_libpaths->contains(installPathPlugins))
2399
                app_libpaths->append(installPathPlugins);
2400
        }
2401
#endif
2402
2403
        // If QCoreApplication is not yet instantiated,
2404
        // make sure we add the application path when we construct the QCoreApplication
2405
        if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2406
2407
        const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH");
2408
        if (!libPathEnv.isEmpty()) {
2409
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
2410
            QLatin1Char pathSep(';');
2411
#else
2412
            QLatin1Char pathSep(':');
2413
#endif
2414
            QStringList paths = QString::fromLatin1(libPathEnv).split(pathSep, QString::SkipEmptyParts);
2415
            for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2416
                QString canonicalPath = QDir(*it).canonicalPath();
2417
                if (!canonicalPath.isEmpty()
2418
                    && !app_libpaths->contains(canonicalPath)) {
2419
                    app_libpaths->append(canonicalPath);
2420
                }
2421
            }
2422
        }
2423
    }
2424
    return *(coreappdata()->app_libpaths);
2425
}
2426
2427
2428
2429
/*!
2430
2431
    Sets the list of directories to search when loading libraries to
2432
    \a paths. All existing paths will be deleted and the path list
2433
    will consist of the paths given in \a paths.
2434
00c4f1d by Miikka Heikkinen at 2010-02-01 2435
    In Symbian this function is only useful for setting paths for
2436
    finding Qt extension plugin stubs, since the OS can only
2437
    load libraries from the \c{/sys/bin} directory.
2438
8f427b2 by axis at 2009-04-24 2439
    \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2440
 */
2441
void QCoreApplication::setLibraryPaths(const QStringList &paths)
2442
{
2443
    QMutexLocker locker(libraryPathMutex());
2444
    if (!coreappdata()->app_libpaths)
2445
        coreappdata()->app_libpaths = new QStringList;
2446
    *(coreappdata()->app_libpaths) = paths;
d32127a by Olivier Goffart at 2010-08-12 2447
    locker.unlock();
8f427b2 by axis at 2009-04-24 2448
    QFactoryLoader::refreshAll();
2449
}
2450
2451
/*!
2452
  Prepends \a path to the beginning of the library path list, ensuring that
2453
  it is searched for libraries first. If \a path is empty or already in the
2454
  path list, the path list is not changed.
2455
2456
  The default path list consists of a single entry, the installation
2457
  directory for plugins.  The default installation directory for plugins
2458
  is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2459
  installed.
2460
00c4f1d by Miikka Heikkinen at 2010-02-01 2461
  In Symbian this function is only useful for adding paths for
2462
  finding Qt extension plugin stubs, since the OS can only
2463
  load libraries from the \c{/sys/bin} directory.
2464
8f427b2 by axis at 2009-04-24 2465
  \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2466
 */
2467
void QCoreApplication::addLibraryPath(const QString &path)
2468
{
2469
    if (path.isEmpty())
2470
        return;
2471
2472
    QMutexLocker locker(libraryPathMutex());
2473
2474
    // make sure that library paths is initialized
2475
    libraryPaths();
2476
2477
    QString canonicalPath = QDir(path).canonicalPath();
2478
    if (!canonicalPath.isEmpty()
2479
        && !coreappdata()->app_libpaths->contains(canonicalPath)) {
2480
        coreappdata()->app_libpaths->prepend(canonicalPath);
d32127a by Olivier Goffart at 2010-08-12 2481
        locker.unlock();
8f427b2 by axis at 2009-04-24 2482
        QFactoryLoader::refreshAll();
2483
    }
2484
}
2485
2486
/*!
2487
    Removes \a path from the library path list. If \a path is empty or not
2488
    in the path list, the list is not changed.
2489
2490
    \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2491
*/
2492
void QCoreApplication::removeLibraryPath(const QString &path)
2493
{
2494
    if (path.isEmpty())
2495
        return;
2496
2497
    QMutexLocker locker(libraryPathMutex());
2498
2499
    // make sure that library paths is initialized
2500
    libraryPaths();
2501
2502
    QString canonicalPath = QDir(path).canonicalPath();
2503
    coreappdata()->app_libpaths->removeAll(canonicalPath);
2504
    QFactoryLoader::refreshAll();
2505
}
2506
820b508 by mread at 2011-09-28 2507
#if defined(Q_OS_SYMBIAN)
2508
void QCoreApplicationPrivate::rebuildInstallLibraryPaths()
2509
{
2510
    // check there is not a single fixed install path
2511
    QString nativeInstallPathPlugins =  QLibraryInfo::location(QLibraryInfo::PluginsPath);
2512
    if (nativeInstallPathPlugins.at(1) == QChar(QLatin1Char(':')))
2513
        return;
2514
    QString installPathPlugins = QDir::cleanPath(nativeInstallPathPlugins);
2515
    // look for the install path at the drive roots
2516
    installPathPlugins.prepend(QChar(QLatin1Char(':')));
2517
2518
    QMutexLocker locker(libraryPathMutex());
2519
    QStringList &app_libpaths = *coreappdata()->app_libpaths;
2520
    // Build a new library path, copying non-installPath components, and replacing existing install path with new
2521
    QStringList newPaths;
2522
    bool installPathFound = false;
2523
    foreach (QString path, app_libpaths) {
2524
        if (path.mid(1).compare(installPathPlugins, Qt::CaseInsensitive) == 0) {
2525
            // skip existing install paths, insert new install path when we find the first
2526
            if (!installPathFound)
2527
                qt_symbian_installLibraryPaths(nativeInstallPathPlugins, newPaths);
2528
            installPathFound = true;
2529
        } else {
2530
            newPaths.append(path);
2531
        }
2532
    }
2533
    app_libpaths = newPaths;
2534
}
2535
#endif
2536
8f427b2 by axis at 2009-04-24 2537
#endif //QT_NO_LIBRARY
2538
2539
/*!
2540
    \typedef QCoreApplication::EventFilter
2541
2542
    A function with the following signature that can be used as an
2543
    event filter:
2544
66fc16b by Martin Smith at 2009-08-28 2545
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 3
8f427b2 by axis at 2009-04-24 2546
2547
    \sa setEventFilter()
2548
*/
2549
2550
/*!
2551
    \fn EventFilter QCoreApplication::setEventFilter(EventFilter filter)
2552
b420385 by Martin Smith at 2009-07-10 2553
    Replaces the event filter function for the QCoreApplication with
2554
    \a filter and returns the pointer to the replaced event filter
2555
    function. Only the current event filter function is called. If you
2556
    want to use both filter functions, save the replaced EventFilter
2557
    in a place where yours can call it.
2558
2559
    The event filter function set here is called for all messages
2560
    received by all threads meant for all Qt objects. It is \e not
2561
    called for messages that are not meant for Qt objects.
2562
2563
    The event filter function should return true if the message should
2564
    be filtered, (i.e. stopped). It should return false to allow
2565
    processing the message to continue.
2566
2567
    By default, no event filter function is set (i.e., this function
2568
    returns a null EventFilter the first time it is called).
d4c0be3 by Shane Kearns at 2009-08-20 2569
b420385 by Martin Smith at 2009-07-10 2570
    \note The filter function set here receives native messages,
2571
    i.e. MSG or XEvent structs, that are going to Qt objects. It is
2572
    called by QCoreApplication::filterEvent(). If the filter function
2573
    returns false to indicate the message should be processed further,
2574
    the native message can then be translated into a QEvent and
2575
    handled by the standard Qt \l{QEvent} {event} filering, e.g.
2576
    QObject::installEventFilter().
2577
2578
    \note The filter function set here is different form the filter
2579
    function set via QAbstractEventDispatcher::setEventFilter(), which
2580
    gets all messages received by its thread, even messages meant for
8f427b2 by axis at 2009-04-24 2581
    objects that are not handled by Qt.
2582
b420385 by Martin Smith at 2009-07-10 2583
    \sa QObject::installEventFilter(), QAbstractEventDispatcher::setEventFilter()
8f427b2 by axis at 2009-04-24 2584
*/
2585
QCoreApplication::EventFilter
2586
QCoreApplication::setEventFilter(QCoreApplication::EventFilter filter)
2587
{
2588
    Q_D(QCoreApplication);
2589
    EventFilter old = d->eventFilter;
2590
    d->eventFilter = filter;
2591
    return old;
2592
}
2593
2594
/*!
2595
    Sends \a message through the event filter that was set by
2596
    setEventFilter(). If no event filter has been set, this function
2597
    returns false; otherwise, this function returns the result of the
2598
    event filter function in the \a result parameter.
2599
2600
    \sa setEventFilter()
2601
*/
2602
bool QCoreApplication::filterEvent(void *message, long *result)
2603
{
2604
    Q_D(QCoreApplication);
2605
    if (result)
2606
        *result = 0;
2607
    if (d->eventFilter)
2608
        return d->eventFilter(message, result);
2609
#ifdef Q_OS_WIN
2610
    return winEventFilter(reinterpret_cast<MSG *>(message), result);
2611
#else
2612
    return false;
2613
#endif
2614
}
2615
2616
/*!
2617
    This function returns true if there are pending events; otherwise
2618
    returns false. Pending events can be either from the window
2619
    system or posted events using postEvent().
2620
2621
    \sa QAbstractEventDispatcher::hasPendingEvents()
2622
*/
2623
bool QCoreApplication::hasPendingEvents()
2624
{
2625
    QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2626
    if (eventDispatcher)
2627
        return eventDispatcher->hasPendingEvents();
2628
    return false;
2629
}
2630
2631
#ifdef QT3_SUPPORT
2632
/*! \fn void QCoreApplication::lock()
2633
2634
    In Qt 3, this function locked the Qt library mutex, allowing
2635
    non-GUI threads to perform basic printing operations using
2636
    QPainter.
2637
2638
    In Qt 4, this is no longer supported, since painting is only
2639
    supported from within a paint event handler. This function does
2640
    nothing.
2641
2642
    \sa QWidget::paintEvent()
2643
*/
2644
2645
/*! \fn void QCoreApplication::unlock(bool wakeUpGui)
2646
2647
    In Qt 3, this function unlocked the Qt library mutex. The mutex
2648
    allowed non-GUI threads to perform basic printing operations
2649
    using QPainter.
2650
2651
    In Qt 4, this is no longer supported, since painting is only
2652
    supported from within a paint event handler. This function does
2653
    nothing.
2654
*/
2655
2656
/*! \fn bool QCoreApplication::locked()
2657
2658
    This function does nothing. It is there to keep old code working.
2659
    It always returns false.
2660
2661
    See lock() for details.
2662
*/
2663
2664
/*! \fn bool QCoreApplication::tryLock()
2665
2666
    This function does nothing. It is there to keep old code working.
2667
    It always returns false.
2668
2669
    See lock() for details.
2670
*/
2671
2672
/*! \fn void QCoreApplication::processOneEvent()
2673
    \obsolete
2674
2675
    Waits for an event to occur, processes it, then returns.
2676
2677
    This function is useful for adapting Qt to situations where the
2678
    event processing must be grafted onto existing program loops.
2679
2680
    Using this function in new applications may be an indication of design
2681
    problems.
2682
2683
    \sa processEvents(), exec(), QTimer
2684
*/
2685
2686
/*! \obsolete
2687
2688
    This function enters the main event loop (recursively). Do not call
2689
    it unless you really know what you are doing.
2690
*/
2691
int QCoreApplication::enter_loop()
2692
{
2693
    if (!QCoreApplicationPrivate::checkInstance("enter_loop"))
2694
        return -1;
2695
    if (QThreadData::current() != self->d_func()->threadData) {
2696
        qWarning("QCoreApplication::enter_loop: Must be called from the main thread");
2697
        return -1;
2698
    }
2699
    QEventLoop eventLoop;
2700
    int returnCode = eventLoop.exec();
2701
    return returnCode;
2702
}
2703
2704
/*! \obsolete
2705
2706
    This function exits from a recursive call to the main event loop.
2707
    Do not call it unless you are an expert.
2708
*/
2709
void QCoreApplication::exit_loop()
2710
{
2711
    if (!QCoreApplicationPrivate::checkInstance("exit_loop"))
2712
        return;
2713
    QThreadData *data = QThreadData::current();
2714
    if (data != self->d_func()->threadData) {
2715
        qWarning("QCoreApplication::exit_loop: Must be called from the main thread");
2716
        return;
2717
    }
2718
    if (!data->eventLoops.isEmpty())
2719
        data->eventLoops.top()->exit();
2720
}
2721
2722
/*! \obsolete
2723
2724
    Returns the current loop level.
2725
*/
2726
int QCoreApplication::loopLevel()
2727
{
2728
    if (!QCoreApplicationPrivate::checkInstance("loopLevel"))
2729
        return -1;
2730
    return self->d_func()->threadData->eventLoops.size();
2731
}
2732
#endif
2733
66fc16b by Martin Smith at 2009-08-28 2734
/*
8f427b2 by axis at 2009-04-24 2735
    \fn void QCoreApplication::watchUnixSignal(int signal, bool watch)
2736
    \internal
2737
*/
2738
2739
/*!
2740
    \fn void QCoreApplication::unixSignal(int number)
2741
    \internal
2742
2743
    This signal is emitted whenever a Unix signal is received by the
2744
    application. The Unix signal received is specified by its \a number.
2745
*/
2746
2747
/*!
2748
    \fn void qAddPostRoutine(QtCleanUpFunction ptr)
2749
    \relates QCoreApplication
2750
2751
    Adds a global routine that will be called from the QApplication
2752
    destructor. This function is normally used to add cleanup routines
2753
    for program-wide functionality.
2754
2755
    The function specified by \a ptr should take no arguments and should
2756
    return nothing. For example:
2757
66fc16b by Martin Smith at 2009-08-28 2758
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 4
8f427b2 by axis at 2009-04-24 2759
2760
    Note that for an application- or module-wide cleanup,
2761
    qAddPostRoutine() is often not suitable. For example, if the
2762
    program is split into dynamically loaded modules, the relevant
2763
    module may be unloaded long before the QApplication destructor is
2764
    called.
2765
2766
    For modules and libraries, using a reference-counted
2767
    initialization manager or Qt's parent-child deletion mechanism may
2768
    be better. Here is an example of a private class that uses the
2769
    parent-child mechanism to call a cleanup function at the right
2770
    time:
2771
66fc16b by Martin Smith at 2009-08-28 2772
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 5
8f427b2 by axis at 2009-04-24 2773
2774
    By selecting the right parent object, this can often be made to
2775
    clean up the module's data at the right moment.
2776
*/
2777
2778
/*!
2779
    \macro Q_DECLARE_TR_FUNCTIONS(context)
2780
    \relates QCoreApplication
2781
2782
    The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
2783
    translation functions, \c tr() and \c trUtf8(), with these
2784
    signatures:
2785
66fc16b by Martin Smith at 2009-08-28 2786
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 6
8f427b2 by axis at 2009-04-24 2787
2788
    This macro is useful if you want to use QObject::tr() or
2789
    QObject::trUtf8() in classes that don't inherit from QObject.
2790
2791
    Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
2792
    class definition (before the first \c{public:} or \c{protected:}).
2793
    For example:
2794
66fc16b by Martin Smith at 2009-08-28 2795
    \snippet doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp 7
8f427b2 by axis at 2009-04-24 2796
2797
    The \a context parameter is normally the class name, but it can
2798
    be any string.
2799
2800
    \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
2801
*/
2802
2803
QT_END_NAMESPACE