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