diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-07-10 15:24:15 -0500 |
commit | bd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch) | |
tree | 7a520322212d48ebcb9fbe1087e7fca28b76185c /src/kernel/qapplication.cpp | |
download | qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip |
Add Qt3 development HEAD version
Diffstat (limited to 'src/kernel/qapplication.cpp')
-rw-r--r-- | src/kernel/qapplication.cpp | 4602 |
1 files changed, 4602 insertions, 0 deletions
diff --git a/src/kernel/qapplication.cpp b/src/kernel/qapplication.cpp new file mode 100644 index 0000000..7296f4c --- /dev/null +++ b/src/kernel/qapplication.cpp @@ -0,0 +1,4602 @@ +/**************************************************************************** +** +** Implementation of QApplication class +** +** Created : 931107 +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "qobjectlist.h" +#include "qapplication.h" +#include "qeventloop.h" +#include "qeventloop_p.h" +#include "qwidget.h" +#include "qwidgetlist.h" +#include "qwidgetintdict.h" +#include "qptrdict.h" +#include "qcleanuphandler.h" + +#include "qtranslator.h" +#include "qtextcodec.h" +#include "qsessionmanager.h" +#include "qdragobject.h" +#include "qclipboard.h" +#include "qcursor.h" +#include "qstyle.h" +#include "qstylefactory.h" +#include "qfile.h" +#include "qmessagebox.h" +#include "qdir.h" +#include "qfileinfo.h" +#ifdef Q_WS_WIN +#include "qinputcontext_p.h" +#endif +#include "qfontdata_p.h" + +#if defined(QT_THREAD_SUPPORT) +# include "qmutex.h" +# include "qthread.h" +#endif // QT_THREAD_SUPPORT + +#include <stdlib.h> + +#ifdef truncate +# undef truncate +#endif + +/*! + \class QApplication qapplication.h + \brief The QApplication class manages the GUI application's control + flow and main settings. + + \ingroup application + \mainclass + + It contains the main event loop, where all events from the window + system and other sources are processed and dispatched. It also + handles the application's initialization and finalization, and + provides session management. It also handles most system-wide and + application-wide settings. + + For any GUI application that uses Qt, there is precisely one + QApplication object, no matter whether the application has 0, 1, 2 + or more windows at any time. + + The QApplication object is accessible through the global pointer \c + qApp. Its main areas of responsibility are: + \list + + \i It initializes the application with the user's desktop settings + such as palette(), font() and doubleClickInterval(). It keeps track + of these properties in case the user changes the desktop globally, for + example through some kind of control panel. + + \i It performs event handling, meaning that it receives events + from the underlying window system and dispatches them to the relevant + widgets. By using sendEvent() and postEvent() you can send your own + events to widgets. + + \i It parses common command line arguments and sets its internal + state accordingly. See the \link QApplication::QApplication() + constructor documentation\endlink below for more details about this. + + \i It defines the application's look and feel, which is + encapsulated in a QStyle object. This can be changed at runtime + with setStyle(). + + \i It specifies how the application is to allocate colors. + See setColorSpec() for details. + + \i It provides localization of strings that are visible to the user + via translate(). + + \i It provides some magical objects like the desktop() and the + clipboard(). + + \i It knows about the application's windows. You can ask which + widget is at a certain position using widgetAt(), get a list of + topLevelWidgets() and closeAllWindows(), etc. + + \i It manages the application's mouse cursor handling, + see setOverrideCursor() and setGlobalMouseTracking(). + + \i On the X window system, it provides functions to flush and sync + the communication stream, see flushX() and syncX(). + + \i It provides support for sophisticated \link + session.html session management \endlink. This makes it possible + for applications to terminate gracefully when the user logs out, to + cancel a shutdown process if termination isn't possible and even to + preserve the entire application's state for a future session. See + isSessionRestored(), sessionId() and commitData() and saveState() + for details. + + \endlist + + The <a href="simple-application.html">Application walk-through + example</a> contains a typical complete main() that does the usual + things with QApplication. + + Since the QApplication object does so much initialization, it + <b>must</b> be created before any other objects related to the user + interface are created. + + Since it also deals with common command line arguments, it is + usually a good idea to create it \e before any interpretation or + modification of \c argv is done in the application itself. (Note + also that for X11, setMainWidget() may change the main widget + according to the \c -geometry option. To preserve this + functionality, you must set your defaults before setMainWidget() and + any overrides after.) + + \table + \header \i21 Groups of functions + \row + \i System settings + \i + desktopSettingsAware(), + setDesktopSettingsAware(), + cursorFlashTime(), + setCursorFlashTime(), + doubleClickInterval(), + setDoubleClickInterval(), + wheelScrollLines(), + setWheelScrollLines(), + palette(), + setPalette(), + font(), + setFont(), + fontMetrics(). + + \row + \i Event handling + \i + exec(), + processEvents(), + enter_loop(), + exit_loop(), + exit(), + quit(). + sendEvent(), + postEvent(), + sendPostedEvents(), + removePostedEvents(), + hasPendingEvents(), + notify(), + macEventFilter(), + qwsEventFilter(), + x11EventFilter(), + x11ProcessEvent(), + winEventFilter(). + + \row + \i GUI Styles + \i + style(), + setStyle(), + polish(). + + \row + \i Color usage + \i + colorSpec(), + setColorSpec(), + qwsSetCustomColors(). + + \row + \i Text handling + \i + installTranslator(), + removeTranslator() + translate(). + + \row + \i Widgets + \i + mainWidget(), + setMainWidget(), + allWidgets(), + topLevelWidgets(), + desktop(), + activePopupWidget(), + activeModalWidget(), + clipboard(), + focusWidget(), + winFocus(), + activeWindow(), + widgetAt(). + + \row + \i Advanced cursor handling + \i + hasGlobalMouseTracking(), + setGlobalMouseTracking(), + overrideCursor(), + setOverrideCursor(), + restoreOverrideCursor(). + + \row + \i X Window System synchronization + \i + flushX(), + syncX(). + + \row + \i Session management + \i + isSessionRestored(), + sessionId(), + commitData(), + saveState(). + + \row + \i Threading + \i + lock(), unlock(), locked(), tryLock(), + wakeUpGuiThread() + + \row + \i Miscellaneous + \i + closeAllWindows(), + startingUp(), + closingDown(), + type(). + \endtable + + \e {Non-GUI programs:} While Qt is not optimized or + designed for writing non-GUI programs, it's possible to use + \link tools.html some of its classes \endlink without creating a + QApplication. This can be useful if you wish to share code between + a non-GUI server and a GUI client. + + \headerfile qnamespace.h + \headerfile qwindowdefs.h + \headerfile qglobal.h +*/ + +/*! \enum Qt::HANDLE + \internal +*/ + +/*! + \enum QApplication::Type + + \value Tty a console application + \value GuiClient a GUI client application + \value GuiServer a GUI server application +*/ + +/*! + \enum QApplication::ColorSpec + + \value NormalColor the default color allocation policy + \value CustomColor the same as NormalColor for X11; allocates colors + to a palette on demand under Windows + \value ManyColor the right choice for applications that use thousands of + colors + + See setColorSpec() for full details. +*/ + +/* + The qt_init() and qt_cleanup() functions are implemented in the + qapplication_xyz.cpp file. +*/ + +void qt_init( int *, char **, QApplication::Type ); +void qt_cleanup(); +#if defined(Q_WS_X11) +void qt_init( Display* dpy, Qt::HANDLE, Qt::HANDLE ); +#endif +Q_EXPORT bool qt_tryModalHelper( QWidget *widget, QWidget **rettop ); + +QApplication *qApp = 0; // global application object + +QStyle *QApplication::app_style = 0; // default application style +bool qt_explicit_app_style = FALSE; // style explicitly set by programmer + +int QApplication::app_cspec = QApplication::NormalColor; +#ifndef QT_NO_PALETTE +QPalette *QApplication::app_pal = 0; // default application palette +#endif +QFont *QApplication::app_font = 0; // default application font +bool qt_app_has_font = FALSE; +#ifndef QT_NO_CURSOR +QCursor *QApplication::app_cursor = 0; // default application cursor +#endif +int QApplication::app_tracking = 0; // global mouse tracking +bool QApplication::is_app_running = FALSE; // app starting up if FALSE +bool QApplication::is_app_closing = FALSE; // app closing down if TRUE +int QApplication::loop_level = 0; // event loop level +QWidget *QApplication::main_widget = 0; // main application widget +QWidget *QApplication::focus_widget = 0; // has keyboard input focus +QWidget *QApplication::active_window = 0; // toplevel with keyboard focus +bool QApplication::obey_desktop_settings = TRUE; // use winsys resources +int QApplication::cursor_flash_time = 1000; // text caret flash time +int QApplication::mouse_double_click_time = 400; // mouse dbl click limit +#ifndef QT_NO_WHEELEVENT +int QApplication::wheel_scroll_lines = 3; // number of lines to scroll +#endif +bool qt_is_gui_used; +bool Q_EXPORT qt_resolve_symlinks = TRUE; +bool Q_EXPORT qt_tab_all_widgets = TRUE; +QRect qt_maxWindowRect; +static int drag_time = 500; +static int drag_distance = 4; +static bool reverse_layout = FALSE; +QSize QApplication::app_strut = QSize( 0,0 ); // no default application strut +bool QApplication::animate_ui = TRUE; +bool QApplication::animate_menu = FALSE; +bool QApplication::fade_menu = FALSE; +bool QApplication::animate_combo = FALSE; +bool QApplication::animate_tooltip = FALSE; +bool QApplication::fade_tooltip = FALSE; +bool QApplication::animate_toolbox = FALSE; +bool QApplication::widgetCount = FALSE; +QApplication::Type qt_appType=QApplication::Tty; +#ifndef QT_NO_COMPONENT +QStringList *QApplication::app_libpaths = 0; +#endif +bool QApplication::metaComposeUnicode = FALSE; +int QApplication::composedUnicode = 0; + +#ifdef QT_THREAD_SUPPORT +QMutex *QApplication::qt_mutex = 0; +static QMutex *postevent_mutex = 0; +static Qt::HANDLE qt_application_thread_id = 0; +Q_EXPORT Qt::HANDLE qt_get_application_thread_id() +{ + return qt_application_thread_id; +} +#endif // QT_THREAD_SUPPORT + +QEventLoop *QApplication::eventloop = 0; // application event loop + +#ifndef QT_NO_ACCEL +extern bool qt_dispatchAccelEvent( QWidget*, QKeyEvent* ); // def in qaccel.cpp +extern bool qt_tryComposeUnicode( QWidget*, QKeyEvent* ); // def in qaccel.cpp +#endif + +#if defined(QT_TABLET_SUPPORT) +bool chokeMouse = FALSE; +#endif + +void qt_setMaxWindowRect(const QRect& r) +{ + qt_maxWindowRect = r; + // Re-resize any maximized windows + QWidgetList* l = QApplication::topLevelWidgets(); + if ( l ) { + QWidget *w = l->first(); + while ( w ) { + if ( w->isVisible() && w->isMaximized() ) + { + w->showNormal(); //#### flicker + w->showMaximized(); + } + w = l->next(); + } + delete l; + } +} + +typedef void (*VFPTR)(); +typedef QValueList<VFPTR> QVFuncList; +static QVFuncList *postRList = 0; // list of post routines + +/*! + \relates QApplication + + Adds a global routine that will be called from the QApplication + destructor. This function is normally used to add cleanup routines + for program-wide functionality. + + The function given by \a p should take no arguments and return + nothing, like this: + \code + static int *global_ptr = 0; + + static void cleanup_ptr() + { + delete [] global_ptr; + global_ptr = 0; + } + + void init_ptr() + { + global_ptr = new int[100]; // allocate data + qAddPostRoutine( cleanup_ptr ); // delete later + } + \endcode + + Note that for an application- or module-wide cleanup, + qAddPostRoutine() is often not suitable. People have a tendency to + make such modules dynamically loaded, and then unload those modules + long before the QApplication destructor is called, for example. + + For modules and libraries, using a reference-counted initialization + manager or Qt' parent-child delete mechanism may be better. Here is + an example of a private class which uses the parent-child mechanism + to call a cleanup function at the right time: + + \code + class MyPrivateInitStuff: public QObject { + private: + MyPrivateInitStuff( QObject * parent ): QObject( parent) { + // initialization goes here + } + MyPrivateInitStuff * p; + + public: + static MyPrivateInitStuff * initStuff( QObject * parent ) { + if ( !p ) + p = new MyPrivateInitStuff( parent ); + return p; + } + + ~MyPrivateInitStuff() { + // cleanup (the "post routine") goes here + } + } + \endcode + + By selecting the right parent widget/object, this can often be made + to clean up the module's data at the exact right moment. +*/ + +Q_EXPORT void qAddPostRoutine( QtCleanUpFunction p) +{ + if ( !postRList ) { + postRList = new QVFuncList; + Q_CHECK_PTR( postRList ); + } + postRList->prepend( p ); +} + + +Q_EXPORT void qRemovePostRoutine( QtCleanUpFunction p ) +{ + if ( !postRList ) return; + QVFuncList::Iterator it = postRList->begin(); + while ( it != postRList->end() ) { + if ( *it == p ) { + postRList->remove( it ); + it = postRList->begin(); + } else { + ++it; + } + } +} + +// Default application palettes and fonts (per widget type) +QAsciiDict<QPalette> *QApplication::app_palettes = 0; +QAsciiDict<QFont> *QApplication::app_fonts = 0; + +#ifndef QT_NO_SESSIONMANAGER +QString *QApplication::session_key = 0; // ## session key. Should be a member in 4.0 +#endif +QWidgetList *QApplication::popupWidgets = 0; // has keyboard input focus + +QDesktopWidget *qt_desktopWidget = 0; // root window widgets +#ifndef QT_NO_CLIPBOARD +QClipboard *qt_clipboard = 0; // global clipboard object +#endif +QWidgetList * qt_modal_stack=0; // stack of modal widgets + +// Definitions for posted events +struct QPostEvent { + QPostEvent( QObject *r, QEvent *e ): receiver( r ), event( e ) {} + ~QPostEvent() { delete event; } + QObject *receiver; + QEvent *event; +}; + +class Q_EXPORT QPostEventList : public QPtrList<QPostEvent> +{ +public: + QPostEventList() : QPtrList<QPostEvent>() {} + QPostEventList( const QPostEventList &list ) : QPtrList<QPostEvent>(list) {} + ~QPostEventList() { clear(); } + QPostEventList &operator=(const QPostEventList &list) + { return (QPostEventList&)QPtrList<QPostEvent>::operator=(list); } +}; +class Q_EXPORT QPostEventListIt : public QPtrListIterator<QPostEvent> +{ +public: + QPostEventListIt( const QPostEventList &l ) : QPtrListIterator<QPostEvent>(l) {} + QPostEventListIt &operator=(const QPostEventListIt &i) +{ return (QPostEventListIt&)QPtrListIterator<QPostEvent>::operator=(i); } +}; + +static QPostEventList *globalPostedEvents = 0; // list of posted events + +uint qGlobalPostedEventsCount() +{ + if (!globalPostedEvents) + return 0; + return globalPostedEvents->count(); +} + +static QSingleCleanupHandler<QPostEventList> qapp_cleanup_events; + +#ifndef QT_NO_PALETTE +QPalette *qt_std_pal = 0; + +void qt_create_std_palette() +{ + if ( qt_std_pal ) + delete qt_std_pal; + + QColor standardLightGray( 192, 192, 192 ); + QColor light( 255, 255, 255 ); + QColor dark( standardLightGray.dark( 150 ) ); + QColorGroup std_act( Qt::black, standardLightGray, + light, dark, Qt::gray, + Qt::black, Qt::white ); + QColorGroup std_dis( Qt::darkGray, standardLightGray, + light, dark, Qt::gray, + Qt::darkGray, std_act.background() ); + QColorGroup std_inact( Qt::black, standardLightGray, + light, dark, Qt::gray, + Qt::black, Qt::white ); + qt_std_pal = new QPalette( std_act, std_dis, std_inact ); +} + +static void qt_fix_tooltips() +{ + // No resources for this yet (unlike on Windows). + QColorGroup cg( Qt::black, QColor(255,255,220), + QColor(96,96,96), Qt::black, Qt::black, + Qt::black, QColor(255,255,220) ); + QPalette pal( cg, cg, cg ); + QApplication::setPalette( pal, TRUE, "QTipLabel"); +} +#endif + +void QApplication::process_cmdline( int* argcptr, char ** argv ) +{ + // process platform-indep command line + if ( !qt_is_gui_used || !*argcptr) + return; + + int argc = *argcptr; + int i, j; + + j = 1; + for ( i=1; i<argc; i++ ) { + if ( argv[i] && *argv[i] != '-' ) { + argv[j++] = argv[i]; + continue; + } + QCString arg = argv[i]; + QCString s; + if ( arg == "-qdevel" || arg == "-qdebug") { + // obsolete argument + } else if ( arg.find( "-style=", 0, FALSE ) != -1 ) { + s = arg.right( arg.length() - 7 ); + } else if ( qstrcmp(arg,"-style") == 0 && i < argc-1 ) { + s = argv[++i]; + s = s.lower(); +#ifndef QT_NO_SESSIONMANAGER + } else if ( qstrcmp(arg,"-session") == 0 && i < argc-1 ) { + QCString s = argv[++i]; + if ( !s.isEmpty() ) { + session_id = QString::fromLatin1( s ); + int p = session_id.find( '_' ); + if ( p >= 0 ) { + if ( !session_key ) + session_key = new QString; + *session_key = session_id.mid( p +1 ); + session_id = session_id.left( p ); + } + is_session_restored = TRUE; + } +#endif + } else if ( qstrcmp(arg, "-reverse") == 0 ) { + setReverseLayout( TRUE ); + } else if ( qstrcmp(arg, "-widgetcount") == 0 ) { + widgetCount = TRUE;; + } else { + argv[j++] = argv[i]; + } +#ifndef QT_NO_STYLE + if ( !s.isEmpty() ) { + setStyle( s ); + } +#endif + } + + if(j < argc) { +#ifdef Q_WS_MACX + static char* empty = "\0"; + argv[j] = empty; +#else + argv[j] = 0; +#endif + *argcptr = j; + } +} + +/*! + Initializes the window system and constructs an application object + with \a argc command line arguments in \a argv. + + The global \c qApp pointer refers to this application object. Only + one application object should be created. + + This application object must be constructed before any \link + QPaintDevice paint devices\endlink (including widgets, pixmaps, bitmaps + etc.). + + Note that \a argc and \a argv might be changed. Qt removes command + line arguments that it recognizes. The modified \a argc and \a argv + can also be accessed later with \c qApp->argc() and \c qApp->argv(). + The documentation for argv() contains a detailed description of how + to process command line arguments. + + Qt debugging options (not available if Qt was compiled with the + QT_NO_DEBUG flag defined): + \list + \i -nograb, tells Qt that it must never grab the mouse or the keyboard. + \i -dograb (only under X11), running under a debugger can cause + an implicit -nograb, use -dograb to override. + \i -sync (only under X11), switches to synchronous mode for + debugging. + \endlist + + See \link debug.html Debugging Techniques \endlink for a more + detailed explanation. + + All Qt programs automatically support the following command line options: + \list + \i -reverse causes text to be formatted for right-to-left languages + rather than in the usual left-to-right direction. + \i -style= \e style, sets the application GUI style. Possible values + are \c motif, \c windows, and \c platinum. If you compiled Qt + with additional styles or have additional styles as plugins these + will be available to the \c -style command line option. + \i -style \e style, is the same as listed above. + \i -session= \e session, restores the application from an earlier + \link session.html session \endlink. + \i -session \e session, is the same as listed above. + \i -widgetcount, prints debug message at the end about number of widgets left + undestroyed and maximum number of widgets existed at the same time + \endlist + + The X11 version of Qt also supports some traditional X11 + command line options: + \list + \i -display \e display, sets the X display (default is $DISPLAY). + \i -geometry \e geometry, sets the client geometry of the + \link setMainWidget() main widget\endlink. + \i -fn or \c -font \e font, defines the application font. The + font should be specified using an X logical font description. + \i -bg or \c -background \e color, sets the default background color + and an application palette (light and dark shades are calculated). + \i -fg or \c -foreground \e color, sets the default foreground color. + \i -btn or \c -button \e color, sets the default button color. + \i -name \e name, sets the application name. + \i -title \e title, sets the application title (caption). + \i -visual \c TrueColor, forces the application to use a TrueColor visual + on an 8-bit display. + \i -ncols \e count, limits the number of colors allocated in the + color cube on an 8-bit display, if the application is using the + \c QApplication::ManyColor color specification. If \e count is + 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green, + and 6 of blue); for other values, a cube + approximately proportional to a 2x3x1 cube is used. + \i -cmap, causes the application to install a private color map + on an 8-bit display. + \endlist + + \sa argc(), argv() +*/ + +//######### BINARY COMPATIBILITY constructor +QApplication::QApplication( int &argc, char **argv ) +{ + construct( argc, argv, GuiClient ); +} + + +/*! + Constructs an application object with \a argc command line arguments + in \a argv. If \a GUIenabled is TRUE, a GUI application is + constructed, otherwise a non-GUI (console) application is created. + + Set \a GUIenabled to FALSE for programs without a graphical user + interface that should be able to run without a window system. + + On X11, the window system is initialized if \a GUIenabled is TRUE. + If \a GUIenabled is FALSE, the application does not connect to the + X-server. + On Windows and Macintosh, currently the window system is always + initialized, regardless of the value of GUIenabled. This may change in + future versions of Qt. + + The following example shows how to create an application that + uses a graphical interface when available. + \code + int main( int argc, char **argv ) + { +#ifdef Q_WS_X11 + bool useGUI = getenv( "DISPLAY" ) != 0; +#else + bool useGUI = TRUE; +#endif + QApplication app(argc, argv, useGUI); + + if ( useGUI ) { + //start GUI version + ... + } else { + //start non-GUI version + ... + } + return app.exec(); + } +\endcode +*/ + +QApplication::QApplication( int &argc, char **argv, bool GUIenabled ) +{ + construct( argc, argv, GUIenabled ? GuiClient : Tty ); +} + +/*! + Constructs an application object with \a argc command line arguments + in \a argv. + + For Qt/Embedded, passing \c QApplication::GuiServer for \a type + makes this application the server (equivalent to running with the + -qws option). +*/ +QApplication::QApplication( int &argc, char **argv, Type type ) +{ + construct( argc, argv, type ); +} + +Q_EXPORT void qt_ucm_initialize( QApplication *theApp ) +{ + if ( qApp ) + return; + int argc = theApp->argc(); + char **argv = theApp->argv(); + theApp->construct( argc, argv, qApp->type() ); + + Q_ASSERT( qApp == theApp ); +} + +void QApplication::construct( int &argc, char **argv, Type type ) +{ + qt_appType = type; + qt_is_gui_used = (type != Tty); + init_precmdline(); + static const char *empty = ""; + if ( argc == 0 || argv == 0 ) { + argc = 0; + argv = (char **)∅ // ouch! careful with QApplication::argv()! + } + app_argc = argc; + app_argv = argv; + + qt_init( &argc, argv, type ); // Must be called before initialize() + process_cmdline( &argc, argv ); + initialize( argc, argv ); + if ( qt_is_gui_used ) + qt_maxWindowRect = desktop()->rect(); + if ( eventloop ) + eventloop->appStartingUp(); +} + +/*! + Returns the type of application, Tty, GuiClient or GuiServer. +*/ + +QApplication::Type QApplication::type() const +{ + return qt_appType; +} + +#if defined(Q_WS_X11) +/*! + Create an application, given an already open display \a dpy. If \a + visual and \a colormap are non-zero, the application will use those as + the default Visual and Colormap contexts. + + \warning Qt only supports TrueColor visuals at depths higher than 8 + bits-per-pixel. + + This is available only on X11. +*/ + +QApplication::QApplication( Display* dpy, HANDLE visual, HANDLE colormap ) +{ + static int aargc = 1; + // ### a string literal is a cont char* + // ### using it as a char* is wrong and could lead to segfaults + // ### if aargv is modified someday + static char *aargv[] = { (char*)"unknown", 0 }; + + app_argc = aargc; + app_argv = aargv; + + qt_appType = GuiClient; + qt_is_gui_used = TRUE; + qt_appType = GuiClient; + init_precmdline(); + // ... no command line. + + if ( ! dpy ) { +#ifdef QT_CHECK_STATE + qWarning( "QApplication: invalid Display* argument." ); +#endif // QT_CHECK_STATE + + qt_init( &aargc, aargv, GuiClient ); + } else { + qt_init( dpy, visual, colormap ); + } + + initialize( aargc, aargv ); + + if ( qt_is_gui_used ) + qt_maxWindowRect = desktop()->rect(); + if ( eventloop ) + eventloop->appStartingUp(); +} + +/*! + Create an application, given an already open display \a dpy and using + \a argc command line arguments in \a argv. If \a + visual and \a colormap are non-zero, the application will use those as + the default Visual and Colormap contexts. + + \warning Qt only supports TrueColor visuals at depths higher than 8 + bits-per-pixel. + + This is available only on X11. + +*/ +QApplication::QApplication(Display *dpy, int argc, char **argv, + HANDLE visual, HANDLE colormap) +{ + qt_appType = GuiClient; + qt_is_gui_used = TRUE; + qt_appType = GuiClient; + init_precmdline(); + + app_argc = argc; + app_argv = argv; + + if ( ! dpy ) { +#ifdef QT_CHECK_STATE + qWarning( "QApplication: invalid Display* argument." ); +#endif // QT_CHECK_STATE + + qt_init( &argc, argv, GuiClient ); + } else { + qt_init(dpy, visual, colormap); + } + + process_cmdline( &argc, argv ); + initialize(argc, argv); + + if ( qt_is_gui_used ) + qt_maxWindowRect = desktop()->rect(); + if ( eventloop ) + eventloop->appStartingUp(); +} + + +#endif // Q_WS_X11 + + +void QApplication::init_precmdline() +{ + translators = 0; + is_app_closing = FALSE; +#ifndef QT_NO_SESSIONMANAGER + is_session_restored = FALSE; +#endif +#if defined(QT_CHECK_STATE) + if ( qApp ) + qWarning( "QApplication: There should be max one application object" ); +#endif + qApp = (QApplication*)this; +} + +/*! + Initializes the QApplication object, called from the constructors. +*/ + +void QApplication::initialize( int argc, char **argv ) +{ +#ifdef QT_THREAD_SUPPORT + qt_mutex = new QMutex( TRUE ); + postevent_mutex = new QMutex( TRUE ); + qt_application_thread_id = QThread::currentThread(); +#endif // QT_THREAD_SUPPORT + + app_argc = argc; + app_argv = argv; + quit_now = FALSE; + quit_code = 0; + QWidget::createMapper(); // create widget mapper +#ifndef QT_NO_PALETTE + (void) palette(); // trigger creation of application palette +#endif + is_app_running = TRUE; // no longer starting up + +#ifndef QT_NO_SESSIONMANAGER + // connect to the session manager + if ( !session_key ) + session_key = new QString; + session_manager = new QSessionManager( qApp, session_id, *session_key ); +#endif + +} + + +/***************************************************************************** + Functions returning the active popup and modal widgets. + *****************************************************************************/ + +/*! + Returns the active popup widget. + + A popup widget is a special top level widget that sets the \c + WType_Popup widget flag, e.g. the QPopupMenu widget. When the + application opens a popup widget, all events are sent to the popup. + Normal widgets and modal widgets cannot be accessed before the popup + widget is closed. + + Only other popup widgets may be opened when a popup widget is shown. + The popup widgets are organized in a stack. This function returns + the active popup widget at the top of the stack. + + \sa activeModalWidget(), topLevelWidgets() +*/ + +QWidget *QApplication::activePopupWidget() +{ + return popupWidgets ? popupWidgets->getLast() : 0; +} + + +/*! + Returns the active modal widget. + + A modal widget is a special top level widget which is a subclass of + QDialog that specifies the modal parameter of the constructor as + TRUE. A modal widget must be closed before the user can continue + with other parts of the program. + + Modal widgets are organized in a stack. This function returns + the active modal widget at the top of the stack. + + \sa activePopupWidget(), topLevelWidgets() +*/ + +QWidget *QApplication::activeModalWidget() +{ + return qt_modal_stack ? qt_modal_stack->getFirst() : 0; +} + +/*! + Cleans up any window system resources that were allocated by this + application. Sets the global variable \c qApp to 0. +*/ + +QApplication::~QApplication() +{ +#ifndef QT_NO_CLIPBOARD + // flush clipboard contents + if ( qt_clipboard ) { + QCustomEvent event( QEvent::Clipboard ); + QApplication::sendEvent( qt_clipboard, &event ); + } +#endif + + if ( eventloop ) + eventloop->appClosingDown(); + if ( postRList ) { + QVFuncList::Iterator it = postRList->begin(); + while ( it != postRList->end() ) { // call post routines + (**it)(); + postRList->remove( it ); + it = postRList->begin(); + } + delete postRList; + postRList = 0; + } + + QObject *tipmanager = child( "toolTipManager", "QTipManager", FALSE ); + delete tipmanager; + + delete qt_desktopWidget; + qt_desktopWidget = 0; + is_app_closing = TRUE; + +#ifndef QT_NO_CLIPBOARD + delete qt_clipboard; + qt_clipboard = 0; +#endif + QWidget::destroyMapper(); +#ifndef QT_NO_PALETTE + delete qt_std_pal; + qt_std_pal = 0; + delete app_pal; + app_pal = 0; + delete app_palettes; + app_palettes = 0; +#endif + delete app_font; + app_font = 0; + delete app_fonts; + app_fonts = 0; +#ifndef QT_NO_STYLE + delete app_style; + app_style = 0; +#endif +#ifndef QT_NO_CURSOR + delete app_cursor; + app_cursor = 0; +#endif +#ifndef QT_NO_TRANSLATION + delete translators; +#endif + +#ifndef QT_NO_DRAGANDDROP + extern QDragManager *qt_dnd_manager; + delete qt_dnd_manager; +#endif + + qt_cleanup(); + +#ifndef QT_NO_COMPONENT + delete app_libpaths; + app_libpaths = 0; +#endif + +#ifdef QT_THREAD_SUPPORT + delete qt_mutex; + qt_mutex = 0; + delete postevent_mutex; + postevent_mutex = 0; +#endif // QT_THREAD_SUPPORT + + if( qApp == this ) { + if ( postedEvents ) + removePostedEvents( this ); + qApp = 0; + } + is_app_running = FALSE; + + if ( widgetCount ) { + qDebug( "Widgets left: %i Max widgets: %i \n", QWidget::instanceCounter, QWidget::maxInstances ); + } +#ifndef QT_NO_SESSIONMANAGER + delete session_manager; + session_manager = 0; + delete session_key; + session_key = 0; +#endif //QT_NO_SESSIONMANAGER + + qt_explicit_app_style = FALSE; + qt_app_has_font = FALSE; + app_tracking = 0; + obey_desktop_settings = TRUE; + cursor_flash_time = 1000; + mouse_double_click_time = 400; +#ifndef QT_NO_WHEELEVENT + wheel_scroll_lines = 3; +#endif + drag_time = 500; + drag_distance = 4; + reverse_layout = FALSE; + app_strut = QSize( 0, 0 ); + animate_ui = TRUE; + animate_menu = FALSE; + fade_menu = FALSE; + animate_combo = FALSE; + animate_tooltip = FALSE; + fade_tooltip = FALSE; + widgetCount = FALSE; +} + + +/*! + \fn int QApplication::argc() const + + Returns the number of command line arguments. + + The documentation for argv() describes how to process command line + arguments. + + \sa argv(), QApplication::QApplication() +*/ + +/*! + \fn char **QApplication::argv() const + + Returns the command line argument vector. + + \c argv()[0] is the program name, \c argv()[1] is the first + argument and \c argv()[argc()-1] is the last argument. + + A QApplication object is constructed by passing \e argc and \e + argv from the \c main() function. Some of the arguments may be + recognized as Qt options and removed from the argument vector. For + example, the X11 version of Qt knows about \c -display, \c -font + and a few more options. + + Example: + \code + // showargs.cpp - displays program arguments in a list box + + #include <qapplication.h> + #include <qlistbox.h> + + int main( int argc, char **argv ) + { + QApplication a( argc, argv ); + QListBox b; + a.setMainWidget( &b ); + for ( int i = 0; i < a.argc(); i++ ) // a.argc() == argc + b.insertItem( a.argv()[i] ); // a.argv()[i] == argv[i] + b.show(); + return a.exec(); + } + \endcode + + If you run \c{showargs -display unix:0 -font 9x15bold hello world} + under X11, the list box contains the three strings "showargs", + "hello" and "world". + + Qt provides a global pointer, \c qApp, that points to the + QApplication object, and through which you can access argc() and + argv() in functions other than main(). + + \sa argc(), QApplication::QApplication() +*/ + +/*! + \fn void QApplication::setArgs( int argc, char **argv ) + \internal +*/ + + +#ifndef QT_NO_STYLE + +static QString *qt_style_override = 0; + +/*! + Returns the application's style object. + + \sa setStyle(), QStyle +*/ +QStyle& QApplication::style() +{ +#ifndef QT_NO_STYLE + if ( app_style ) + return *app_style; + if ( !qt_is_gui_used ) + qFatal( "No style available in non-gui applications!" ); + +#if defined(Q_WS_X11) + if(!qt_style_override) + x11_initialize_style(); // run-time search for default style +#endif + if ( !app_style ) { + // Compile-time search for default style + // + QString style; + if ( qt_style_override ) { + style = *qt_style_override; + delete qt_style_override; + qt_style_override = 0; + } else { +# if defined(Q_WS_WIN) && defined(Q_OS_TEMP) + style = "PocketPC"; +#elif defined(Q_WS_WIN) + if ( qWinVersion() >= Qt::WV_XP && qWinVersion() < Qt::WV_NT_based ) + style = "WindowsXP"; + else + style = "Windows"; // default styles for Windows +#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS) + style = "CDE"; // default style for X11 on Solaris +#elif defined(Q_WS_X11) && defined(Q_OS_IRIX) + style = "SGI"; // default style for X11 on IRIX +#elif defined(Q_WS_X11) + style = "Motif"; // default style for X11 +#elif defined(Q_WS_MAC) + style = "Macintosh"; // default style for all Mac's +#elif defined(Q_WS_QWS) + style = "Compact"; // default style for small devices +#endif + } + app_style = QStyleFactory::create( style ); + if ( !app_style && // platform default style not available, try alternatives + !(app_style = QStyleFactory::create( "Windows" ) ) && + !(app_style = QStyleFactory::create( "Platinum" ) ) && + !(app_style = QStyleFactory::create( "MotifPlus" ) ) && + !(app_style = QStyleFactory::create( "Motif" ) ) && + !(app_style = QStyleFactory::create( "CDE" ) ) && + !(app_style = QStyleFactory::create( "Aqua" ) ) && + !(app_style = QStyleFactory::create( "SGI" ) ) && + !(app_style = QStyleFactory::create( "Compact" ) ) +#ifndef QT_NO_STRINGLIST + && !(app_style = QStyleFactory::create( QStyleFactory::keys()[0] ) ) +#endif + ) + qFatal( "No %s style available!", style.latin1() ); + } + + QPalette app_pal_copy ( *app_pal ); + app_style->polish( *app_pal ); + + if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) { + QEvent e( QEvent::ApplicationPaletteChange ); + QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) ); + register QWidget *w; + while ( (w=it.current()) ) { // for all widgets... + ++it; + sendEvent( w, &e ); + } + } + + app_style->polish( qApp ); +#endif + return *app_style; +} + +/*! + Sets the application's GUI style to \a style. Ownership of the style + object is transferred to QApplication, so QApplication will delete + the style object on application exit or when a new style is set. + + Example usage: + \code + QApplication::setStyle( new QWindowsStyle ); + \endcode + + When switching application styles, the color palette is set back to + the initial colors or the system defaults. This is necessary since + certain styles have to adapt the color palette to be fully + style-guide compliant. + + \sa style(), QStyle, setPalette(), desktopSettingsAware() +*/ +void QApplication::setStyle( QStyle *style ) +{ + QStyle* old = app_style; + app_style = style; +#ifdef Q_WS_X11 + qt_explicit_app_style = TRUE; +#endif // Q_WS_X11 + + if ( startingUp() ) { + delete old; + return; + } + + // clean up the old style + if (old) { + if ( is_app_running && !is_app_closing ) { + QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) ); + register QWidget *w; + while ( (w=it.current()) ) { // for all widgets... + ++it; + if ( !w->testWFlags(WType_Desktop) && // except desktop + w->testWState(WState_Polished) ) { // has been polished + old->unPolish(w); + } + } + } + old->unPolish( qApp ); + } + + // take care of possible palette requirements of certain gui + // styles. Do it before polishing the application since the style + // might call QApplication::setStyle() itself + if ( !qt_std_pal ) + qt_create_std_palette(); + QPalette tmpPal = *qt_std_pal; + setPalette( tmpPal, TRUE ); + + // initialize the application with the new style + app_style->polish( qApp ); + + // re-polish existing widgets if necessary + if (old) { + if ( is_app_running && !is_app_closing ) { + QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) ); + register QWidget *w; + while ( (w=it.current()) ) { // for all widgets... + ++it; + if ( !w->testWFlags(WType_Desktop) ) { // except desktop + if ( w->testWState(WState_Polished) ) + app_style->polish(w); // repolish + w->styleChange( *old ); + if ( w->isVisible() ){ + w->update(); + } + } + } + } + delete old; + } +} + +/*! + \overload + + Requests a QStyle object for \a style from the QStyleFactory. + + The string must be one of the QStyleFactory::keys(), typically one + of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and + "compact". Depending on the platform, "windowsxp", "aqua" or + "macintosh" may be available. + + A later call to the QApplication constructor will override the + requested style when a "-style" option is passed in as a commandline + parameter. + + Returns 0 if an unknown \a style is passed, otherwise the QStyle object + returned is set as the application's GUI style. +*/ +QStyle* QApplication::setStyle( const QString& style ) +{ +#ifdef Q_WS_X11 + qt_explicit_app_style = TRUE; +#endif // Q_WS_X11 + + if ( startingUp() ) { + if(qt_style_override) + *qt_style_override = style; + else + qt_style_override = new QString(style); + return 0; + } + QStyle *s = QStyleFactory::create( style ); + if ( !s ) + return 0; + + setStyle( s ); + return s; +} + +#endif + + +#if 1 /* OBSOLETE */ + +QApplication::ColorMode QApplication::colorMode() +{ + return (QApplication::ColorMode)app_cspec; +} + +void QApplication::setColorMode( QApplication::ColorMode mode ) +{ + app_cspec = mode; +} +#endif + + +/*! + Returns the color specification. + \sa QApplication::setColorSpec() + */ + +int QApplication::colorSpec() +{ + return app_cspec; +} + +/*! + Sets the color specification for the application to \a spec. + + The color specification controls how the application allocates colors + when run on a display with a limited amount of colors, e.g. 8 bit / 256 + color displays. + + The color specification must be set before you create the QApplication + object. + + The options are: + \list + \i QApplication::NormalColor. + This is the default color allocation strategy. Use this option if + your application uses buttons, menus, texts and pixmaps with few + colors. With this option, the application uses system global + colors. This works fine for most applications under X11, but on + Windows machines it may cause dithering of non-standard colors. + \i QApplication::CustomColor. + Use this option if your application needs a small number of custom + colors. On X11, this option is the same as NormalColor. On Windows, Qt + creates a Windows palette, and allocates colors to it on demand. + \i QApplication::ManyColor. + Use this option if your application is very color hungry + (e.g. it requires thousands of colors). + Under X11 the effect is: + \list + \i For 256-color displays which have at best a 256 color true color + visual, the default visual is used, and colors are allocated + from a color cube. The color cube is the 6x6x6 (216 color) "Web + palette"<sup>*</sup>, but the number of colors can be changed + by the \e -ncols option. The user can force the application to + use the true color visual with the \link + QApplication::QApplication() -visual \endlink option. + \i For 256-color displays which have a true color visual with more + than 256 colors, use that visual. Silicon Graphics X servers + have this feature, for example. They provide an 8 bit visual + by default but can deliver true color when asked. + \endlist + On Windows, Qt creates a Windows palette, and fills it with a color cube. + \endlist + + Be aware that the CustomColor and ManyColor choices may lead to colormap + flashing: The foreground application gets (most) of the available + colors, while the background windows will look less attractive. + + Example: + \code + int main( int argc, char **argv ) + { + QApplication::setColorSpec( QApplication::ManyColor ); + QApplication a( argc, argv ); + ... + } + \endcode + + QColor provides more functionality for controlling color allocation and + freeing up certain colors. See QColor::enterAllocContext() for more + information. + + To check what mode you end up with, call QColor::numBitPlanes() once + the QApplication object exists. A value greater than 8 (typically + 16, 24 or 32) means true color. + + <sup>*</sup> The color cube used by Qt has 216 colors whose red, + green, and blue components always have one of the following values: + 0x00, 0x33, 0x66, 0x99, 0xCC, or 0xFF. + + \sa colorSpec(), QColor::numBitPlanes(), QColor::enterAllocContext() */ + +void QApplication::setColorSpec( int spec ) +{ +#if defined(QT_CHECK_STATE) + if ( qApp ) { + qWarning( "QApplication::setColorSpec: This function must be " + "called before the QApplication object is created" ); + } +#endif + app_cspec = spec; +} + +/*! + \fn QSize QApplication::globalStrut() + + Returns the application's global strut. + + The strut is a size object whose dimensions are the minimum that any + GUI element that the user can interact with should have. For example + no button should be resized to be smaller than the global strut size. + + \sa setGlobalStrut() +*/ + +/*! + Sets the application's global strut to \a strut. + + The strut is a size object whose dimensions are the minimum that any + GUI element that the user can interact with should have. For example + no button should be resized to be smaller than the global strut size. + + The strut size should be considered when reimplementing GUI controls + that may be used on touch-screens or similar IO-devices. + + Example: + \code + QSize& WidgetClass::sizeHint() const + { + return QSize( 80, 25 ).expandedTo( QApplication::globalStrut() ); + } + \endcode + + \sa globalStrut() +*/ + +void QApplication::setGlobalStrut( const QSize& strut ) +{ + app_strut = strut; +} + +#if defined( Q_WS_WIN ) || defined( Q_WS_MAC ) +extern const char *qAppFileName(); +#endif + +#ifndef QT_NO_DIR +#ifndef Q_WS_WIN +static QString resolveSymlinks( const QString& path, int depth = 0 ) +{ + bool foundLink = FALSE; + QString linkTarget; + QString part = path; + int slashPos = path.length(); + + // too deep; we give up + if ( depth == 128 ) + return QString::null; + + do { + part = part.left( slashPos ); + QFileInfo fileInfo( part ); + if ( fileInfo.isSymLink() ) { + foundLink = TRUE; + linkTarget = fileInfo.readLink(); + break; + } + } while ( (slashPos = part.findRev('/')) != -1 ); + + if ( foundLink ) { + QString path2; + if ( linkTarget[0] == '/' ) { + path2 = linkTarget; + if ( slashPos < (int) path.length() ) + path2 += "/" + path.right( path.length() - slashPos - 1 ); + } else { + QString relPath; + relPath = part.left( part.findRev('/') + 1 ) + linkTarget; + if ( slashPos < (int) path.length() ) { + if ( !linkTarget.endsWith( "/" ) ) + relPath += "/"; + relPath += path.right( path.length() - slashPos - 1 ); + } + path2 = QDir::current().absFilePath( relPath ); + } + path2 = QDir::cleanDirPath( path2 ); + return resolveSymlinks( path2, depth + 1 ); + } else { + return path; + } +} +#endif // Q_WS_WIN + +/*! + Returns the directory that contains the application executable. + + For example, if you have installed Qt in the \c{C:\Trolltech\Qt} + directory, and you run the \c{demo} example, this function will + return "C:/Trolltech/Qt/examples/demo". + + On Mac OS X this will point to the directory actually containing the + executable, which may be inside of an application bundle (if the + application is bundled). + + \warning On Unix, this function assumes that argv[0] contains the file + name of the executable (which it normally does). It also assumes that + the current directory hasn't been changed by the application. + + \sa applicationFilePath() +*/ +QString QApplication::applicationDirPath() +{ + return QFileInfo( applicationFilePath() ).dirPath(); +} + +/*! + Returns the file path of the application executable. + + For example, if you have installed Qt in the \c{C:\Trolltech\Qt} + directory, and you run the \c{demo} example, this function will + return "C:/Trolltech/Qt/examples/demo/demo.exe". + + \warning On Unix, this function assumes that argv[0] contains the file + name of the executable (which it normally does). It also assumes that + the current directory hasn't been changed by the application. + + \sa applicationDirPath() +*/ +QString QApplication::applicationFilePath() +{ +#if defined( Q_WS_WIN ) + QFileInfo filePath; + QT_WA({ + WCHAR module_name[256]; + GetModuleFileNameW(0, module_name, sizeof(module_name)); + filePath = QString::fromUcs2((const unsigned short *)module_name); + }, { + char module_name[256]; + GetModuleFileNameA(0, module_name, sizeof(module_name)); + filePath = QString::fromLocal8Bit(module_name); + }); + + return filePath.filePath(); +#elif defined( Q_WS_MAC ) + return QDir::cleanDirPath( QFile::decodeName( qAppFileName() ) ); +#else + QString argv0 = QFile::decodeName( argv()[0] ); + QString absPath; + + if ( argv0[0] == '/' ) { + /* + If argv0 starts with a slash, it is already an absolute + file path. + */ + absPath = argv0; + } else if ( argv0.find('/') != -1 ) { + /* + If argv0 contains one or more slashes, it is a file path + relative to the current directory. + */ + absPath = QDir::current().absFilePath( argv0 ); + } else { + /* + Otherwise, the file path has to be determined using the + PATH environment variable. + */ + char *pEnv = getenv( "PATH" ); + QStringList paths( QStringList::split(QChar(':'), pEnv) ); + QStringList::const_iterator p = paths.begin(); + while ( p != paths.end() ) { + QString candidate = QDir::current().absFilePath( *p + "/" + argv0 ); + if ( QFile::exists(candidate) ) { + absPath = candidate; + break; + } + ++p; + } + } + + absPath = QDir::cleanDirPath( absPath ); + if ( QFile::exists(absPath) ) { + return resolveSymlinks( absPath ); + } else { + return QString::null; + } +#endif +} +#endif // QT_NO_DIR + +#ifndef QT_NO_COMPONENT + +/*! + Returns a list of paths that the application will search when + dynamically loading libraries. + The installation directory for plugins is the only entry if no + paths have been set. The default installation directory for plugins + is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was + installed. The directory of the application executable (NOT the + working directory) is also added to the plugin paths. + + If you want to iterate over the list, you should iterate over a + copy, e.g. + \code + QStringList list = app.libraryPaths(); + QStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + See the \link plugins-howto.html plugins documentation\endlink for a + description of how the library paths are used. + + \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary +*/ +QStringList QApplication::libraryPaths() +{ + if ( !app_libpaths ) { + app_libpaths = new QStringList; + QString installPathPlugins = QString::fromLocal8Bit(qInstallPathPlugins()); + if ( QFile::exists(installPathPlugins) ) { +#ifdef Q_WS_WIN + installPathPlugins.replace('\\', '/'); +#endif + app_libpaths->append(installPathPlugins); + } + + QString app_location; + if (qApp) + app_location = qApp->applicationFilePath(); +#ifdef Q_WS_WIN + else { + app_location = QString(qAppFileName()); + app_location.replace('\\', '/'); + } +#endif + if (!app_location.isEmpty()) { + app_location.truncate( app_location.findRev( '/' ) ); + if ( app_location != qInstallPathPlugins() && QFile::exists( app_location ) ) + app_libpaths->append( app_location ); + } + } + return *app_libpaths; +} + + +/*! + Sets the list of directories to search when loading libraries to \a paths. + All existing paths will be deleted and the path list will consist of the + paths given in \a paths. + + \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary + */ +void QApplication::setLibraryPaths( const QStringList &paths ) +{ + delete app_libpaths; + app_libpaths = new QStringList( paths ); +} + +/*! + Append \a path to the end of the library path list. If \a path is + empty or already in the path list, the path list is not changed. + + The default path list consists of a single entry, the installation + directory for plugins. The default installation directory for plugins + is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was + installed. + + \sa removeLibraryPath(), libraryPaths(), setLibraryPaths() + */ +void QApplication::addLibraryPath( const QString &path ) +{ + if ( path.isEmpty() ) + return; + + // make sure that library paths is initialized + libraryPaths(); + + if ( !app_libpaths->contains( path ) ) + app_libpaths->prepend( path ); +} + +/*! + Removes \a path from the library path list. If \a path is empty or not + in the path list, the list is not changed. + + \sa addLibraryPath(), libraryPaths(), setLibraryPaths() +*/ +void QApplication::removeLibraryPath( const QString &path ) +{ + if ( path.isEmpty() ) + return; + + // make sure that library paths is initialized + libraryPaths(); + + if ( app_libpaths->contains( path ) ) + app_libpaths->remove( path ); +} +#endif //QT_NO_COMPONENT + +/*! + Returns the application palette. + + If a widget is passed in \a w, the default palette for the + widget's class is returned. This may or may not be the application + palette. In most cases there isn't a special palette for certain + types of widgets, but one notable exception is the popup menu under + Windows, if the user has defined a special background color for + menus in the display settings. + + \sa setPalette(), QWidget::palette() +*/ +#ifndef QT_NO_PALETTE +QPalette QApplication::palette(const QWidget* w) +{ +#if defined(QT_CHECK_STATE) + if ( !qApp ) + qWarning( "QApplication::palette: This function can only be " + "called after the QApplication object has been created" ); +#endif + if ( !app_pal ) { + if ( !qt_std_pal ) + qt_create_std_palette(); + app_pal = new QPalette( *qt_std_pal ); + qt_fix_tooltips(); + } + + if ( w && app_palettes ) { + QPalette* wp = app_palettes->find( w->className() ); + if ( wp ) + return *wp; + QAsciiDictIterator<QPalette> it( *app_palettes ); + const char* name; + while ( (name=it.currentKey()) != 0 ) { + if ( w->inherits( name ) ) + return *it.current(); + ++it; + } + } + return *app_pal; +} + +/*! + Changes the default application palette to \a palette. If \a + informWidgets is TRUE, then existing widgets are informed about the + change and may adjust themselves to the new application + setting. If \a informWidgets is FALSE, the change only affects newly + created widgets. + + If \a className is passed, the change applies only to widgets that + inherit \a className (as reported by QObject::inherits()). If + \a className is left 0, the change affects all widgets, thus overriding + any previously set class specific palettes. + + The palette may be changed according to the current GUI style in + QStyle::polish(). + + \sa QWidget::setPalette(), palette(), QStyle::polish() +*/ + +void QApplication::setPalette( const QPalette &palette, bool informWidgets, + const char* className ) +{ + QPalette pal = palette; + QPalette *oldpal = 0; +#ifndef QT_NO_STYLE + if ( !startingUp() ) // on startup this has been done already + qApp->style().polish( pal ); // NB: non-const reference +#endif + bool all = FALSE; + if ( !className ) { + if ( !app_pal ) { + app_pal = new QPalette( pal ); + Q_CHECK_PTR( app_pal ); + } else { + *app_pal = pal; + } + all = app_palettes != 0; + delete app_palettes; + app_palettes = 0; + qt_fix_tooltips(); + } else { + if ( !app_palettes ) { + app_palettes = new QAsciiDict<QPalette>; + Q_CHECK_PTR( app_palettes ); + app_palettes->setAutoDelete( TRUE ); + } + oldpal = app_palettes->find( className ); + app_palettes->insert( className, new QPalette( pal ) ); + } + if ( informWidgets && is_app_running && !is_app_closing ) { + if ( !oldpal || ( *oldpal != pal ) ) { + QEvent e( QEvent::ApplicationPaletteChange ); + QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) ); + register QWidget *w; + while ( (w=it.current()) ) { // for all widgets... + ++it; + if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class + sendEvent( w, &e ); + } + } + } +} + +#endif // QT_NO_PALETTE + +/*! + Returns the default font for the widget \a w, or the default + application font if \a w is 0. + + \sa setFont(), fontMetrics(), QWidget::font() +*/ + +QFont QApplication::font( const QWidget *w ) +{ + if ( w && app_fonts ) { + QFont* wf = app_fonts->find( w->className() ); + if ( wf ) + return *wf; + QAsciiDictIterator<QFont> it( *app_fonts ); + const char* name; + while ( (name=it.currentKey()) != 0 ) { + if ( w->inherits( name ) ) + return *it.current(); + ++it; + } + } + if ( !app_font ) { + app_font = new QFont( "Helvetica" ); + Q_CHECK_PTR( app_font ); + } + return *app_font; +} + +/*! Changes the default application font to \a font. If \a + informWidgets is TRUE, then existing widgets are informed about the + change and may adjust themselves to the new application + setting. If \a informWidgets is FALSE, the change only affects newly + created widgets. If \a className is passed, the change applies only + to classes that inherit \a className (as reported by + QObject::inherits()). + + On application start-up, the default font depends on the window + system. It can vary depending on both the window system version and + the locale. This function lets you override the default font; but + overriding may be a bad idea because, for example, some locales need + extra-large fonts to support their special characters. + + \sa font(), fontMetrics(), QWidget::setFont() +*/ + +void QApplication::setFont( const QFont &font, bool informWidgets, + const char* className ) +{ + bool all = FALSE; + if ( !className ) { + qt_app_has_font = TRUE; + if ( !app_font ) { + app_font = new QFont( font ); + Q_CHECK_PTR( app_font ); + } else { + *app_font = font; + } + + // make sure the application font is complete + app_font->detach(); + app_font->d->mask = QFontPrivate::Complete; + + all = app_fonts != 0; + delete app_fonts; + app_fonts = 0; + } else { + if (!app_fonts){ + app_fonts = new QAsciiDict<QFont>; + Q_CHECK_PTR( app_fonts ); + app_fonts->setAutoDelete( TRUE ); + } + QFont* fnt = new QFont(font); + Q_CHECK_PTR( fnt ); + app_fonts->insert(className, fnt); + } + if ( informWidgets && is_app_running && !is_app_closing ) { + QEvent e( QEvent::ApplicationFontChange ); + QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) ); + register QWidget *w; + while ( (w=it.current()) ) { // for all widgets... + ++it; + if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class + sendEvent( w, &e ); + } + } +} + + +/*! + Initialization of the appearance of the widget \a w \e before it is first + shown. + + Usually widgets call this automatically when they are polished. It + may be used to do some style-based central customization of widgets. + + Note that you are not limited to the public functions of QWidget. + Instead, based on meta information like QObject::className() you are + able to customize any kind of widget. + + \sa QStyle::polish(), QWidget::polish(), setPalette(), setFont() +*/ + +void QApplication::polish( QWidget *w ) +{ +#ifndef QT_NO_STYLE + w->style().polish( w ); +#endif +} + + +/*! + Returns a list of the top level widgets in the application. + + The list is created using \c new and must be deleted by the caller. + + The list is empty (QPtrList::isEmpty()) if there are no top level + widgets. + + Note that some of the top level widgets may be hidden, for example + the tooltip if no tooltip is currently shown. + + Example: + \code + // Show all hidden top level widgets. + QWidgetList *list = QApplication::topLevelWidgets(); + QWidgetListIt it( *list ); // iterate over the widgets + QWidget * w; + while ( (w=it.current()) != 0 ) { // for each top level widget... + ++it; + if ( !w->isVisible() ) + w->show(); + } + delete list; // delete the list, not the widgets + \endcode + + \warning Delete the list as soon you have finished using it. + The widgets in the list may be deleted by someone else at any time. + + \sa allWidgets(), QWidget::isTopLevel(), QWidget::isVisible(), + QPtrList::isEmpty() +*/ + +QWidgetList *QApplication::topLevelWidgets() +{ + return QWidget::tlwList(); +} + +/*! + Returns a list of all the widgets in the application. + + The list is created using \c new and must be deleted by the caller. + + The list is empty (QPtrList::isEmpty()) if there are no widgets. + + Note that some of the widgets may be hidden. + + Example that updates all widgets: + \code + QWidgetList *list = QApplication::allWidgets(); + QWidgetListIt it( *list ); // iterate over the widgets + QWidget * w; + while ( (w=it.current()) != 0 ) { // for each widget... + ++it; + w->update(); + } + delete list; // delete the list, not the widgets + \endcode + + The QWidgetList class is defined in the \c qwidgetlist.h header + file. + + \warning Delete the list as soon as you have finished using it. + The widgets in the list may be deleted by someone else at any time. + + \sa topLevelWidgets(), QWidget::isVisible(), QPtrList::isEmpty(), +*/ + +QWidgetList *QApplication::allWidgets() +{ + return QWidget::wList(); +} + +/*! + \fn QWidget *QApplication::focusWidget() const + + Returns the application widget that has the keyboard input focus, or + 0 if no widget in this application has the focus. + + \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow() +*/ + +/*! + \fn QWidget *QApplication::activeWindow() const + + Returns the application top-level window that has the keyboard input + focus, or 0 if no application window has the focus. Note that + there might be an activeWindow() even if there is no focusWidget(), + for example if no widget in that window accepts key events. + + \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget() +*/ + +/*! + Returns display (screen) font metrics for the application font. + + \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics() +*/ + +QFontMetrics QApplication::fontMetrics() +{ + return desktop()->fontMetrics(); +} + + + +/*! + Tells the application to exit with return code 0 (success). + Equivalent to calling QApplication::exit( 0 ). + + It's common to connect the lastWindowClosed() signal to quit(), and + you also often connect e.g. QButton::clicked() or signals in + QAction, QPopupMenu or QMenuBar to it. + + Example: + \code + QPushButton *quitButton = new QPushButton( "Quit" ); + connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) ); + \endcode + + \sa exit() aboutToQuit() lastWindowClosed() QAction +*/ + +void QApplication::quit() +{ + QApplication::exit( 0 ); +} + + +/*! + Closes all top-level windows. + + This function is particularly useful for applications with many + top-level windows. It could, for example, be connected to a "Quit" + entry in the file menu as shown in the following code example: + + \code + // the "Quit" menu entry should try to close all windows + QPopupMenu* file = new QPopupMenu( this ); + file->insertItem( "&Quit", qApp, SLOT(closeAllWindows()), CTRL+Key_Q ); + + // when the last window is closed, the application should quit + connect( qApp, SIGNAL( lastWindowClosed() ), qApp, SLOT( quit() ) ); + \endcode + + The windows are closed in random order, until one window does not + accept the close event. + + \sa QWidget::close(), QWidget::closeEvent(), lastWindowClosed(), + quit(), topLevelWidgets(), QWidget::isTopLevel() + + */ +void QApplication::closeAllWindows() +{ + bool did_close = TRUE; + QWidget *w; + while((w = activeModalWidget()) && did_close) { + if(w->isHidden()) + break; + did_close = w->close(); + } + QWidgetList *list = QApplication::topLevelWidgets(); + for ( w = list->first(); did_close && w; ) { + if ( !w->isHidden() ) { + did_close = w->close(); + delete list; + list = QApplication::topLevelWidgets(); + w = list->first(); + } else { + w = list->next(); + } + } + delete list; +} + +/*! + Displays a simple message box about Qt. The message includes the + version number of Qt being used by the application. + + This is useful for inclusion in the Help menu of an application. + See the examples/menu/menu.cpp example. + + This function is a convenience slot for QMessageBox::aboutQt(). +*/ +void QApplication::aboutQt() +{ +#ifndef QT_NO_MESSAGEBOX + QMessageBox::aboutQt( mainWidget() ); +#endif // QT_NO_MESSAGEBOX +} + + +/*! + \fn void QApplication::lastWindowClosed() + + This signal is emitted when the user has closed the last + top level window. + + The signal is very useful when your application has many top level + widgets but no main widget. You can then connect it to the quit() + slot. + + For convenience, this signal is \e not emitted for transient top level + widgets such as popup menus and dialogs. + + \sa mainWidget(), topLevelWidgets(), QWidget::isTopLevel(), QWidget::close() +*/ + +/*! + \fn void QApplication::aboutToQuit() + + This signal is emitted when the application is about to quit the + main event loop, e.g. when the event loop level drops to zero. + This may happen either after a call to quit() from inside the + application or when the users shuts down the entire desktop session. + + The signal is particularly useful if your application has to do some + last-second cleanup. Note that no user interaction is possible in + this state. + + \sa quit() +*/ + + +/*! + \fn void QApplication::guiThreadAwake() + + This signal is emitted after the event loop returns from a function + that could block. + + \sa wakeUpGuiThread() +*/ + + +/*! + \fn bool QApplication::sendEvent( QObject *receiver, QEvent *event ) + + Sends event \a event directly to receiver \a receiver, using the + notify() function. Returns the value that was returned from the event + handler. + + The event is \e not deleted when the event has been sent. The normal + approach is to create the event on the stack, e.g. + \code + QMouseEvent me( QEvent::MouseButtonPress, pos, 0, 0 ); + QApplication::sendEvent( mainWindow, &me ); + \endcode + If you create the event on the heap you must delete it. + + \sa postEvent(), notify() +*/ + +/*! + Sends event \a e to \a receiver: \a {receiver}->event(\a e). + Returns the value that is returned from the receiver's event handler. + + For certain types of events (e.g. mouse and key events), + the event will be propagated to the receiver's parent and so on up to + the top-level object if the receiver is not interested in the event + (i.e., it returns FALSE). + + There are five different ways that events can be processed; + reimplementing this virtual function is just one of them. All five + approaches are listed below: + \list 1 + \i Reimplementing this function. This is very powerful, providing + complete control; but only one subclass can be qApp. + + \i Installing an event filter on qApp. Such an event filter is able + to process all events for all widgets, so it's just as powerful as + reimplementing notify(); furthermore, it's possible to have more + than one application-global event filter. Global event filters even + see mouse events for \link QWidget::isEnabled() disabled + widgets, \endlink and if \link setGlobalMouseTracking() global mouse + tracking \endlink is enabled, as well as mouse move events for all + widgets. + + \i Reimplementing QObject::event() (as QWidget does). If you do + this you get Tab key presses, and you get to see the events before + any widget-specific event filters. + + \i Installing an event filter on the object. Such an event filter + gets all the events except Tab and Shift-Tab key presses. + + \i Reimplementing paintEvent(), mousePressEvent() and so + on. This is the commonest, easiest and least powerful way. + \endlist + + \sa QObject::event(), installEventFilter() +*/ + +bool QApplication::notify( QObject *receiver, QEvent *e ) +{ + // no events are delivered after ~QApplication() has started + if ( is_app_closing ) + return FALSE; + + if ( receiver == 0 ) { // serious error +#if defined(QT_CHECK_NULL) + qWarning( "QApplication::notify: Unexpected null receiver" ); +#endif + return FALSE; + } + + if ( e->type() == QEvent::ChildRemoved && receiver->postedEvents && globalPostedEvents) { + +#ifdef QT_THREAD_SUPPORT + QMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT + + // the QObject destructor calls QObject::removeChild, which calls + // QApplication::sendEvent() directly. this can happen while the event + // loop is in the middle of posting events, and when we get here, we may + // not have any more posted events for this object. + if ( receiver->postedEvents ) { + // if this is a child remove event and the child insert + // hasn't been dispatched yet, kill that insert + QPostEventList * l = receiver->postedEvents; + QObject * c = ((QChildEvent*)e)->child(); + QPostEvent * pe; + l->first(); + while( ( pe = l->current()) != 0 ) { + if ( pe->event && pe->receiver == receiver && + pe->event->type() == QEvent::ChildInserted && + ((QChildEvent*)pe->event)->child() == c ) { + pe->event->posted = FALSE; + delete pe->event; + pe->event = 0; + l->remove(); + continue; + } + l->next(); + } + } + } + + bool res = FALSE; + if ( !receiver->isWidgetType() ) + res = internalNotify( receiver, e ); + else switch ( e->type() ) { +#ifndef QT_NO_ACCEL + case QEvent::Accel: + { + QKeyEvent* key = (QKeyEvent*) e; + res = internalNotify( receiver, e ); + + if ( !res && !key->isAccepted() ) + res = qt_dispatchAccelEvent( (QWidget*)receiver, key ); + + // next lines are for compatibility with Qt <= 3.0.x: old + // QAccel was listening on toplevel widgets + if ( !res && !key->isAccepted() && !((QWidget*)receiver)->isTopLevel() ) + res = internalNotify( ((QWidget*)receiver)->topLevelWidget(), e ); + } + break; +#endif //QT_NO_ACCEL + case QEvent::KeyPress: + case QEvent::KeyRelease: + case QEvent::AccelOverride: + { + QWidget* w = (QWidget*)receiver; + QKeyEvent* key = (QKeyEvent*) e; +#ifndef QT_NO_ACCEL + if ( qt_tryComposeUnicode( w, key ) ) + break; +#endif + bool def = key->isAccepted(); + while ( w ) { + if ( def ) + key->accept(); + else + key->ignore(); + res = internalNotify( w, e ); + if ( res || key->isAccepted() ) + break; + w = w->parentWidget( TRUE ); + } + } + break; + case QEvent::MouseButtonPress: + if ( e->spontaneous() ) { + QWidget* fw = (QWidget*)receiver; + while ( fw->focusProxy() ) + fw = fw->focusProxy(); + if ( fw->isEnabled() && fw->focusPolicy() & QWidget::ClickFocus ) { + QFocusEvent::setReason( QFocusEvent::Mouse); + fw->setFocus(); + QFocusEvent::resetReason(); + } + } + // fall through intended + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + { + QWidget* w = (QWidget*)receiver; + QMouseEvent* mouse = (QMouseEvent*) e; + QPoint relpos = mouse->pos(); + while ( w ) { + QMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->state()); + me.spont = mouse->spontaneous(); + res = internalNotify( w, w == receiver ? mouse : &me ); + e->spont = FALSE; + if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation)) + break; + + relpos += w->pos(); + w = w->parentWidget(); + } + if ( res ) + mouse->accept(); + else + mouse->ignore(); + } + break; +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: + { + if ( e->spontaneous() ) { + QWidget* fw = (QWidget*)receiver; + while ( fw->focusProxy() ) + fw = fw->focusProxy(); + if ( fw->isEnabled() && (fw->focusPolicy() & QWidget::WheelFocus) == QWidget::WheelFocus ) { + QFocusEvent::setReason( QFocusEvent::Mouse); + fw->setFocus(); + QFocusEvent::resetReason(); + } + } + + QWidget* w = (QWidget*)receiver; + QWheelEvent* wheel = (QWheelEvent*) e; + QPoint relpos = wheel->pos(); + while ( w ) { + QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->state(), wheel->orientation()); + we.spont = wheel->spontaneous(); + res = internalNotify( w, w == receiver ? wheel : &we ); + e->spont = FALSE; + if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation)) + break; + + relpos += w->pos(); + w = w->parentWidget(); + } + if ( res ) + wheel->accept(); + else + wheel->ignore(); + } + break; +#endif + case QEvent::ContextMenu: + { + QWidget* w = (QWidget*)receiver; + QContextMenuEvent *context = (QContextMenuEvent*) e; + QPoint relpos = context->pos(); + while ( w ) { + QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->state()); + ce.spont = e->spontaneous(); + res = internalNotify( w, w == receiver ? context : &ce ); + e->spont = FALSE; + + if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation)) + break; + + relpos += w->pos(); + w = w->parentWidget(); + } + if ( res ) + context->accept(); + else + context->ignore(); + } + break; +#if defined (QT_TABLET_SUPPORT) + case QEvent::TabletMove: + case QEvent::TabletPress: + case QEvent::TabletRelease: + { + QWidget *w = (QWidget*)receiver; + QTabletEvent *tablet = (QTabletEvent*)e; + QPoint relpos = tablet->pos(); + while ( w ) { + QTabletEvent te(tablet->pos(), tablet->globalPos(), tablet->device(), + tablet->pressure(), tablet->xTilt(), tablet->yTilt(), + tablet->uniqueId()); + te.spont = e->spontaneous(); + res = internalNotify( w, w == receiver ? tablet : &te ); + e->spont = FALSE; + if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation)) + break; + + relpos += w->pos(); + w = w->parentWidget(); + } + if ( res ) + tablet->accept(); + else + tablet->ignore(); + chokeMouse = tablet->isAccepted(); + } + break; +#endif + default: + res = internalNotify( receiver, e ); + break; + } + + return res; +} + +/*!\reimp + +*/ +bool QApplication::event( QEvent *e ) +{ + if(e->type() == QEvent::Close) { + QCloseEvent *ce = (QCloseEvent*)e; + ce->accept(); + closeAllWindows(); + + QWidgetList *list = topLevelWidgets(); + for(QWidget *w = list->first(); w; w = list->next()) { + if ( !w->isHidden() && !w->isDesktop() && !w->isPopup() && + (!w->isDialog() || !w->parentWidget())) { + ce->ignore(); + break; + } + } + if(ce->isAccepted()) + return TRUE; + } else if (e->type() == QEvent::Quit) { + quit(); + return TRUE; + } + return QObject::event(e); +} + +/*!\internal + + Helper function called by notify() + */ +bool QApplication::internalNotify( QObject *receiver, QEvent * e) +{ + if ( eventFilters ) { + QObjectListIt it( *eventFilters ); + register QObject *obj; + while ( (obj=it.current()) != 0 ) { // send to all filters + ++it; // until one returns TRUE + if ( obj->eventFilter(receiver,e) ) + return TRUE; + } + } + + bool consumed = FALSE; + bool handled = FALSE; + if ( receiver->isWidgetType() ) { + QWidget *widget = (QWidget*)receiver; + + // toggle HasMouse widget state on enter and leave + if ( e->type() == QEvent::Enter || e->type() == QEvent::DragEnter ) + widget->setWState( WState_HasMouse ); + else if ( e->type() == QEvent::Leave || e->type() == QEvent::DragLeave ) + widget->clearWState( WState_HasMouse ); + + // throw away any mouse-tracking-only mouse events + if ( e->type() == QEvent::MouseMove && + (((QMouseEvent*)e)->state()&QMouseEvent::MouseButtonMask) == 0 && + !widget->hasMouseTracking() ) { + handled = TRUE; + consumed = TRUE; + } else if ( !widget->isEnabled() ) { // throw away mouse events to disabled widgets + switch(e->type()) { + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + ( (QMouseEvent*) e)->ignore(); + handled = TRUE; + consumed = TRUE; + break; +#ifndef QT_NO_DRAGANDDROP + case QEvent::DragEnter: + case QEvent::DragMove: + ( (QDragMoveEvent*) e)->ignore(); + handled = TRUE; + break; + + case QEvent::DragLeave: + case QEvent::DragResponse: + handled = TRUE; + break; + + case QEvent::Drop: + ( (QDropEvent*) e)->ignore(); + handled = TRUE; + break; +#endif +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: + ( (QWheelEvent*) e)->ignore(); + handled = TRUE; + break; +#endif + case QEvent::ContextMenu: + ( (QContextMenuEvent*) e)->ignore(); + handled = TRUE; + break; + default: + break; + } + } + + } + + if (!handled) + consumed = receiver->event( e ); + e->spont = FALSE; + return consumed; +} + +/*! + Returns TRUE if an application object has not been created yet; + otherwise returns FALSE. + + \sa closingDown() +*/ + +bool QApplication::startingUp() +{ + return !is_app_running; +} + +/*! + Returns TRUE if the application objects are being destroyed; + otherwise returns FALSE. + + \sa startingUp() +*/ + +bool QApplication::closingDown() +{ + return is_app_closing; +} + + +/*! + Processes pending events, for 3 seconds or until there are no more + events to process, whichever is shorter. + + You can call this function occasionally when your program is busy + performing a long operation (e.g. copying a file). + + \sa exec(), QTimer, QEventLoop::processEvents() +*/ + +void QApplication::processEvents() +{ + processEvents( 3000 ); +} + +/*! + \overload + + Processes pending events for \a maxtime milliseconds or until + there are no more events to process, whichever is shorter. + + You can call this function occasionally when you program is busy + doing a long operation (e.g. copying a file). + + \sa exec(), QTimer, QEventLoop::processEvents() +*/ +void QApplication::processEvents( int maxtime ) +{ + eventLoop()->processEvents( QEventLoop::AllEvents, maxtime ); +} + +/*! \obsolete + Waits for an event to occur, processes it, then returns. + + This function is useful for adapting Qt to situations where the + event processing must be grafted onto existing program loops. + + Using this function in new applications may be an indication of design + problems. + + \sa processEvents(), exec(), QTimer +*/ + +void QApplication::processOneEvent() +{ + eventLoop()->processEvents( QEventLoop::AllEvents | + QEventLoop::WaitForMore ); +} + +/***************************************************************************** + Main event loop wrappers + *****************************************************************************/ + +/*! + Returns the application event loop. This function will return + zero if called during and after destroying QApplication. + + To create your own instance of QEventLoop or QEventLoop subclass create + it before you create the QApplication object. + + \sa QEventLoop +*/ +QEventLoop *QApplication::eventLoop() +{ + if ( !eventloop && !is_app_closing ) + (void) new QEventLoop( qApp, "default event loop" ); + return eventloop; +} + + +/*! + Enters the main event loop and waits until exit() is called or the + main widget is destroyed, and returns the value that was set to + exit() (which is 0 if exit() is called via quit()). + + It is necessary to call this function to start event handling. The + main event loop receives events from the window system and + dispatches these to the application widgets. + + Generally speaking, no user interaction can take place before + calling exec(). As a special case, modal widgets like QMessageBox + can be used before calling exec(), because modal widgets call + exec() to start a local event loop. + + To make your application perform idle processing, i.e. executing a + special function whenever there are no pending events, use a + QTimer with 0 timeout. More advanced idle processing schemes can + be achieved using processEvents(). + + \sa quit(), exit(), processEvents(), setMainWidget() +*/ +int QApplication::exec() +{ + return eventLoop()->exec(); +} + +/*! + Tells the application to exit with a return code. + + After this function has been called, the application leaves the main + event loop and returns from the call to exec(). The exec() function + returns \a retcode. + + By convention, a \a retcode of 0 means success, and any non-zero + value indicates an error. + + Note that unlike the C library function of the same name, this + function \e does return to the caller -- it is event processing that + stops. + + \sa quit(), exec() +*/ +void QApplication::exit( int retcode ) +{ + qApp->eventLoop()->exit( retcode ); +} + +/*! + \obsolete + + This function enters the main event loop (recursively). Do not call + it unless you really know what you are doing. + + Use QApplication::eventLoop()->enterLoop() instead. + +*/ +int QApplication::enter_loop() +{ + return eventLoop()->enterLoop(); +} + +/*! + \obsolete + + This function exits from a recursive call to the main event loop. + Do not call it unless you are an expert. + + Use QApplication::eventLoop()->exitLoop() instead. + +*/ +void QApplication::exit_loop() +{ + eventLoop()->exitLoop(); +} + +/*! + \obsolete + + Returns the current loop level. + + Use QApplication::eventLoop()->loopLevel() instead. + +*/ +int QApplication::loopLevel() const +{ + return eventLoop()->loopLevel(); +} + +/*! + + Wakes up the GUI thread. + + \sa guiThreadAwake() \link threads.html Thread Support in Qt\endlink +*/ +void QApplication::wakeUpGuiThread() +{ + eventLoop()->wakeUp(); +} + +/*! + This function returns TRUE if there are pending events; otherwise + returns FALSE. Pending events can be either from the window system + or posted events using QApplication::postEvent(). +*/ +bool QApplication::hasPendingEvents() +{ + return eventLoop()->hasPendingEvents(); +} + +#if !defined(Q_WS_X11) + +// The doc and X implementation of these functions is in qapplication_x11.cpp + +void QApplication::flushX() {} // do nothing + +void QApplication::syncX() {} // do nothing + +#endif + +/*! + \fn void QApplication::setWinStyleHighlightColor( const QColor & ) + \obsolete + + Sets the color used to mark selections in windows style for all widgets + in the application. Will repaint all widgets if the color is changed. + + The default color is \c darkBlue. + \sa winStyleHighlightColor() +*/ + +/*! + \fn const QColor& QApplication::winStyleHighlightColor() + \obsolete + + Returns the color used to mark selections in windows style. + + \sa setWinStyleHighlightColor() +*/ + +/*! + Returns the version of the Windows operating system that is running: + + \list + \i Qt::WV_95 - Windows 95 + \i Qt::WV_98 - Windows 98 + \i Qt::WV_Me - Windows Me + \i Qt::WV_NT - Windows NT 4.x + \i Qt::WV_2000 - Windows 2000 (NT5) + \i Qt::WV_XP - Windows XP + \i Qt::WV_2003 - Windows Server 2003 family + \i Qt::WV_CE - Windows CE + \i Qt::WV_CENET - Windows CE.NET + \endlist + + Note that this function is implemented for the Windows version + of Qt only. +*/ + +#if defined(Q_OS_CYGWIN) +Qt::WindowsVersion QApplication::winVersion() +{ + return qt_winver; +} +#endif + +#ifndef QT_NO_TRANSLATION + +bool qt_detectRTLLanguage() +{ + return QApplication::tr( "QT_LAYOUT_DIRECTION", + "Translate this string to the string 'LTR' in left-to-right" + " languages or to 'RTL' in right-to-left languages (such as Hebrew" + " and Arabic) to get proper widget layout." ) == "RTL"; +} + +/*! + Adds the message file \a mf to the list of message files to be used + for translations. + + Multiple message files can be installed. Translations are searched + for in the last installed message file, then the one from last, and + so on, back to the first installed message file. The search stops as + soon as a matching translation is found. + + \sa removeTranslator() translate() QTranslator::load() +*/ + +void QApplication::installTranslator( QTranslator * mf ) +{ + if ( !mf ) + return; + if ( !translators ) + translators = new QValueList<QTranslator*>; + + translators->prepend( mf ); + +#ifndef QT_NO_TRANSLATION_BUILDER + if ( mf->isEmpty() ) + return; +#endif + + // hook to set the layout direction of dialogs + setReverseLayout( qt_detectRTLLanguage() ); + + QWidgetList *list = topLevelWidgets(); + QWidgetListIt it( *list ); + QWidget *w; + while ( ( w=it.current() ) != 0 ) { + ++it; + if (!w->isDesktop()) + postEvent( w, new QEvent( QEvent::LanguageChange ) ); + } + delete list; +} + +/*! + Removes the message file \a mf from the list of message files used by + this application. (It does not delete the message file from the file + system.) + + \sa installTranslator() translate(), QObject::tr() +*/ + +void QApplication::removeTranslator( QTranslator * mf ) +{ + if ( !translators || !mf ) + return; + + if ( translators->remove( mf ) && ! qApp->closingDown() ) { + setReverseLayout( qt_detectRTLLanguage() ); + + QWidgetList *list = topLevelWidgets(); + QWidgetListIt it( *list ); + QWidget *w; + while ( ( w=it.current() ) != 0 ) { + ++it; + postEvent( w, new QEvent( QEvent::LanguageChange ) ); + } + delete list; + } +} + +#ifndef QT_NO_TEXTCODEC +/*! \obsolete + This is the same as QTextCodec::setCodecForTr(). +*/ +void QApplication::setDefaultCodec( QTextCodec* codec ) +{ + QTextCodec::setCodecForTr( codec ); +} + +/*! \obsolete + Returns QTextCodec::codecForTr(). +*/ +QTextCodec* QApplication::defaultCodec() const +{ + return QTextCodec::codecForTr(); +} +#endif //QT_NO_TEXTCODEC + +/*! \enum QApplication::Encoding + + This enum type defines the 8-bit encoding of character string + arguments to translate(): + + \value DefaultCodec - the encoding specified by + QTextCodec::codecForTr() (Latin-1 if none has been set) + \value UnicodeUTF8 - UTF-8 + + \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8() +*/ + +/*! \reentrant + Returns the translation text for \a sourceText, by querying the + installed messages files. The message files are searched from the most + recently installed message file back to the first installed message + file. + + QObject::tr() and QObject::trUtf8() provide this functionality more + conveniently. + + \a context is typically a class name (e.g., "MyDialog") and + \a sourceText is either English text or a short identifying text, if + the output text will be very long (as for help texts). + + \a comment is a disambiguating comment, for when the same \a + sourceText is used in different roles within the same context. By + default, it is null. \a encoding indicates the 8-bit encoding of + character stings + + See the \l QTranslator documentation for more information about + contexts and comments. + + If none of the message files contain a translation for \a + sourceText in \a context, this function returns a QString + equivalent of \a sourceText. The encoding of \a sourceText is + specified by \e encoding; it defaults to \c DefaultCodec. + + This function is not virtual. You can use alternative translation + techniques by subclassing \l QTranslator. + + \warning This method is reentrant only if all translators are + installed \e before calling this method. Installing or removing + translators while performing translations is not supported. Doing + so will most likely result in crashes or other undesirable behavior. + + \sa QObject::tr() installTranslator() defaultCodec() +*/ + +QString QApplication::translate( const char * context, const char * sourceText, + const char * comment, Encoding encoding ) const +{ + if ( !sourceText ) + return QString::null; + + if ( translators ) { + QValueList<QTranslator*>::iterator it; + QTranslator * mf; + QString result; + for ( it = translators->begin(); it != translators->end(); ++it ) { + mf = *it; + result = mf->findMessage( context, sourceText, comment ).translation(); + if ( !result.isNull() ) + return result; + } + } +#ifndef QT_NO_TEXTCODEC + if ( encoding == UnicodeUTF8 ) + return QString::fromUtf8( sourceText ); + else if ( QTextCodec::codecForTr() != 0 ) + return QTextCodec::codecForTr()->toUnicode( sourceText ); + else +#endif + return QString::fromLatin1( sourceText ); +} + +#endif + +/***************************************************************************** + QApplication management of posted events + *****************************************************************************/ + +//see also notify(), which does the removal of ChildInserted when ChildRemoved. + +/*! + Adds the event \a event with the object \a receiver as the receiver of the + event, to an event queue and returns immediately. + + The event must be allocated on the heap since the post event queue + will take ownership of the event and delete it once it has been posted. + + When control returns to the main event loop, all events that are + stored in the queue will be sent using the notify() function. + + \threadsafe + + \sa sendEvent(), notify() +*/ + +void QApplication::postEvent( QObject *receiver, QEvent *event ) +{ + if ( receiver == 0 ) { +#if defined(QT_CHECK_NULL) + qWarning( "QApplication::postEvent: Unexpected null receiver" ); +#endif + delete event; + return; + } + +#ifdef QT_THREAD_SUPPORT + QMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT + + if ( !globalPostedEvents ) { // create list + globalPostedEvents = new QPostEventList; + Q_CHECK_PTR( globalPostedEvents ); + globalPostedEvents->setAutoDelete( TRUE ); + qapp_cleanup_events.set( &globalPostedEvents ); + } + + if ( !receiver->postedEvents ) + receiver->postedEvents = new QPostEventList; + QPostEventList * l = receiver->postedEvents; + + // if this is one of the compressible events, do compression + if ( event->type() == QEvent::Paint || + event->type() == QEvent::LayoutHint || + event->type() == QEvent::Resize || + event->type() == QEvent::Move || + event->type() == QEvent::LanguageChange ) { + l->first(); + QPostEvent * cur = 0; + for ( ;; ) { + while ( (cur=l->current()) != 0 && + ( cur->receiver != receiver || + cur->event == 0 || + cur->event->type() != event->type() ) ) + l->next(); + if ( l->current() != 0 ) { + if ( cur->event->type() == QEvent::Paint ) { + QPaintEvent * p = (QPaintEvent*)(cur->event); + if ( p->erase != ((QPaintEvent*)event)->erase ) { + l->next(); + continue; + } + p->reg = p->reg.unite( ((QPaintEvent *)event)->reg ); + p->rec = p->rec.unite( ((QPaintEvent *)event)->rec ); + delete event; + return; + } else if ( cur->event->type() == QEvent::LayoutHint ) { + delete event; + return; + } else if ( cur->event->type() == QEvent::Resize ) { + ((QResizeEvent *)(cur->event))->s = ((QResizeEvent *)event)->s; + delete event; + return; + } else if ( cur->event->type() == QEvent::Move ) { + ((QMoveEvent *)(cur->event))->p = ((QMoveEvent *)event)->p; + delete event; + return; + } else if ( cur->event->type() == QEvent::LanguageChange ) { + delete event; + return; + } + } + break; + }; + } + +#if !defined(QT_NO_IM) + // if this is one of the compressible IM events, do compression + else if ( event->type() == QEvent::IMCompose ) { + l->last(); + QPostEvent * cur = 0; + for ( ;; ) { + while ( (cur=l->current()) != 0 && + ( cur->receiver != receiver || + cur->event == 0 || + cur->event->type() != event->type() || + cur->event->type() != QEvent::IMStart ) ) + l->prev(); + if ( l->current() != 0 ) { + // IMCompose must not be compressed with another one + // beyond its IMStart boundary + if ( cur->event->type() == QEvent::IMStart ) { + break; + } else if ( cur->event->type() == QEvent::IMCompose ) { + QIMComposeEvent * e = (QIMComposeEvent *)(cur->event); + *e = *(QIMComposeEvent *)event; + delete event; + return; + } + } + break; + }; + } +#endif + + // if no compression could be done, just append something + event->posted = TRUE; + QPostEvent * pe = new QPostEvent( receiver, event ); + l->append( pe ); + globalPostedEvents->append( pe ); + + if (eventloop) + eventloop->wakeUp(); +} + + +/*! \overload + + Dispatches all posted events, i.e. empties the event queue. +*/ +void QApplication::sendPostedEvents() +{ + sendPostedEvents( 0, 0 ); +} + + + +/*! + Immediately dispatches all events which have been previously queued + with QApplication::postEvent() and which are for the object \a receiver + and have the event type \a event_type. + + Note that events from the window system are \e not dispatched by this + function, but by processEvents(). + + If \a receiver is null, the events of \a event_type are sent for all + objects. If \a event_type is 0, all the events are sent for \a receiver. +*/ + +void QApplication::sendPostedEvents( QObject *receiver, int event_type ) +{ + // Make sure the object hierarchy is stable before processing events + // to avoid endless loops + if ( receiver == 0 && event_type == 0 ) + sendPostedEvents( 0, QEvent::ChildInserted ); + + if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) + return; + +#ifdef QT_THREAD_SUPPORT + QMutexLocker locker( postevent_mutex ); +#endif + + bool sent = TRUE; + while ( sent ) { + sent = FALSE; + + if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) ) + return; + + // if we have a receiver, use the local list. Otherwise, use the + // global list + QPostEventList * l = receiver ? receiver->postedEvents : globalPostedEvents; + + // okay. here is the tricky loop. be careful about optimizing + // this, it looks the way it does for good reasons. + QPostEventListIt it( *l ); + QPostEvent *pe; + while ( (pe=it.current()) != 0 ) { + ++it; + if ( pe->event // hasn't been sent yet + && ( receiver == 0 // we send to all receivers + || receiver == pe->receiver ) // we send to THAT receiver + && ( event_type == 0 // we send all types + || event_type == pe->event->type() ) ) { // we send THAT type + // first, we diddle the event so that we can deliver + // it, and that noone will try to touch it later. + pe->event->posted = FALSE; + QEvent * e = pe->event; + QObject * r = pe->receiver; + pe->event = 0; + + // next, update the data structure so that we're ready + // for the next event. + + // look for the local list, and take whatever we're + // delivering out of it. r->postedEvents maybe *l + if ( r->postedEvents ) { + r->postedEvents->removeRef( pe ); + // if possible, get rid of that list. this is not + // ideal - we will create and delete a list for + // each update() call. it would be better if we'd + // leave the list empty here, and delete it + // somewhere else if it isn't being used. + if ( r->postedEvents->isEmpty() ) { + delete r->postedEvents; + r->postedEvents = 0; + } + } + +#ifdef QT_THREAD_SUPPORT + if ( locker.mutex() ) locker.mutex()->unlock(); +#endif // QT_THREAD_SUPPORT + // after all that work, it's time to deliver the event. + if ( e->type() == QEvent::Paint && r->isWidgetType() ) { + QWidget * w = (QWidget*)r; + QPaintEvent * p = (QPaintEvent*)e; + if ( w->isVisible() ) + w->repaint( p->reg, p->erase ); + } else { + sent = TRUE; + QApplication::sendEvent( r, e ); + } +#ifdef QT_THREAD_SUPPORT + if ( locker.mutex() ) locker.mutex()->lock(); +#endif // QT_THREAD_SUPPORT + + delete e; + // careful when adding anything below this point - the + // sendEvent() call might invalidate any invariants this + // function depends on. + } + } + + // clear the global list, i.e. remove everything that was + // delivered. + if ( l == globalPostedEvents ) { + globalPostedEvents->first(); + while( (pe=globalPostedEvents->current()) != 0 ) { + if ( pe->event ) + globalPostedEvents->next(); + else + globalPostedEvents->remove(); + } + } + } +} + +/*! + Removes all events posted using postEvent() for \a receiver. + + The events are \e not dispatched, instead they are removed from the + queue. You should never need to call this function. If you do call it, + be aware that killing events may cause \a receiver to break one or + more invariants. + + \threadsafe +*/ + +void QApplication::removePostedEvents( QObject *receiver ) +{ + removePostedEvents( receiver, 0 ); +} + +/*! + Removes all events that have the event type \a event_type posted + using postEvent() for \a receiver. + + The events are \e not dispatched, instead they are removed from the + queue. + + If \a event_type is 0, all the events are removed from the queue. + + \threadsafe +*/ + +void QApplication::removePostedEvents( QObject *receiver, int event_type ) +{ + if ( !receiver ) + return; + +#ifdef QT_THREAD_SUPPORT + QMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT + + // the QObject destructor calls this function directly. this can + // happen while the event loop is in the middle of posting events, + // and when we get here, we may not have any more posted events + // for this object. + if ( !receiver->postedEvents ) + return; + + // iterate over the object-specifc list and delete the events. + // leave the QPostEvent objects; they'll be deleted by + // sendPostedEvents(). + QPostEventList * l = receiver->postedEvents; + l->first(); + QPostEvent * pe; + while( (pe=l->current()) != 0 ) { + if ( !event_type || pe->event->type() == event_type ) { + if ( pe->event ) { + pe->event->posted = FALSE; + delete pe->event; + pe->event = 0; + } + l->remove(); + } else { + l->next(); + } + } + if ( !event_type || !l->count() ) { + receiver->postedEvents = 0; + delete l; + } +} + + +/*! + Removes \a event from the queue of posted events, and emits a + warning message if appropriate. + + \warning This function can be \e really slow. Avoid using it, if + possible. + + \threadsafe +*/ + +void QApplication::removePostedEvent( QEvent * event ) +{ + if ( !event || !event->posted ) + return; + + if ( !globalPostedEvents ) { +#if defined(QT_DEBUG) + qDebug( "QApplication::removePostedEvent: %p %d is posted: impossible", + (void*)event, event->type() ); + return; +#endif + } + +#ifdef QT_THREAD_SUPPORT + QMutexLocker locker( postevent_mutex ); +#endif // QT_THREAD_SUPPORT + + QPostEventListIt it( *globalPostedEvents ); + QPostEvent * pe; + while( (pe = it.current()) != 0 ) { + ++it; + if ( pe->event == event ) { +#if defined(QT_DEBUG) + const char *n; + switch ( event->type() ) { + case QEvent::Timer: + n = "Timer"; + break; + case QEvent::MouseButtonPress: + n = "MouseButtonPress"; + break; + case QEvent::MouseButtonRelease: + n = "MouseButtonRelease"; + break; + case QEvent::MouseButtonDblClick: + n = "MouseButtonDblClick"; + break; + case QEvent::MouseMove: + n = "MouseMove"; + break; +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: + n = "Wheel"; + break; +#endif + case QEvent::KeyPress: + n = "KeyPress"; + break; + case QEvent::KeyRelease: + n = "KeyRelease"; + break; + case QEvent::FocusIn: + n = "FocusIn"; + break; + case QEvent::FocusOut: + n = "FocusOut"; + break; + case QEvent::Enter: + n = "Enter"; + break; + case QEvent::Leave: + n = "Leave"; + break; + case QEvent::Paint: + n = "Paint"; + break; + case QEvent::Move: + n = "Move"; + break; + case QEvent::Resize: + n = "Resize"; + break; + case QEvent::Create: + n = "Create"; + break; + case QEvent::Destroy: + n = "Destroy"; + break; + case QEvent::Close: + n = "Close"; + break; + case QEvent::Quit: + n = "Quit"; + break; + default: + n = "<other>"; + break; + } + qWarning("QEvent: Warning: %s event deleted while posted to %s %s", + n, + pe->receiver ? pe->receiver->className() : "null", + pe->receiver ? pe->receiver->name() : "object" ); + // note the beautiful uglehack if !pe->receiver :) +#endif + event->posted = FALSE; + delete pe->event; + pe->event = 0; + return; + } + } +} + +/*!\internal + + Sets the active window in reaction to a system event. Call this + from the platform specific event handlers. + + It sets the activeWindow() and focusWidget() attributes and sends + proper WindowActivate/WindowDeactivate and FocusIn/FocusOut events + to all appropriate widgets. + + \sa activeWindow() + */ +void QApplication::setActiveWindow( QWidget* act ) +{ + QWidget* window = act?act->topLevelWidget():0; + + if ( active_window == window ) + return; + + // first the activation/deactivation events + if ( active_window ) { + QWidgetList deacts; +#ifndef QT_NO_STYLE + if ( style().styleHint(QStyle::SH_Widget_ShareActivation, active_window ) ) { + QWidgetList *list = topLevelWidgets(); + if ( list ) { + for ( QWidget *w = list->first(); w; w = list->next() ) { + if ( w->isVisible() && w->isActiveWindow() ) + deacts.append(w); + } + delete list; + } + } else +#endif + deacts.append(active_window); + active_window = 0; + QEvent e( QEvent::WindowDeactivate ); + for(QWidget *w = deacts.first(); w; w = deacts.next()) + QApplication::sendSpontaneousEvent( w, &e ); + } + + active_window = window; + if ( active_window ) { + QEvent e( QEvent::WindowActivate ); + QWidgetList acts; +#ifndef QT_NO_STYLE + if ( style().styleHint(QStyle::SH_Widget_ShareActivation, active_window ) ) { + QWidgetList *list = topLevelWidgets(); + if ( list ) { + for ( QWidget *w = list->first(); w; w = list->next() ) { + if ( w->isVisible() && w->isActiveWindow() ) + acts.append(w); + } + delete list; + } + } else +#endif + acts.append(active_window); + for(QWidget *w = acts.first(); w; w = acts.next()) + QApplication::sendSpontaneousEvent( w, &e ); + } + + // then focus events + QFocusEvent::setReason( QFocusEvent::ActiveWindow ); + if ( !active_window && focus_widget ) { + QFocusEvent out( QEvent::FocusOut ); + QWidget *tmp = focus_widget; + focus_widget = 0; +#ifdef Q_WS_WIN + QInputContext::accept( tmp ); +#elif defined(Q_WS_X11) + tmp->unfocusInputContext(); +#endif + QApplication::sendSpontaneousEvent( tmp, &out ); + } else if ( active_window ) { + QWidget *w = active_window->focusWidget(); + if ( w && w->focusPolicy() != QWidget::NoFocus ) + w->setFocus(); + else + active_window->focusNextPrevChild( TRUE ); + } + QFocusEvent::resetReason(); +} + + +/*!\internal + + Creates the proper Enter/Leave event when widget \a enter is entered + and widget \a leave is left. + */ +Q_EXPORT void qt_dispatchEnterLeave( QWidget* enter, QWidget* leave ) { +#if 0 + if ( leave ) { + QEvent e( QEvent::Leave ); + QApplication::sendEvent( leave, & e ); + } + if ( enter ) { + QEvent e( QEvent::Enter ); + QApplication::sendEvent( enter, & e ); + } + return; +#endif + + QWidget* w ; + if ( !enter && !leave ) + return; + QWidgetList leaveList; + QWidgetList enterList; + + bool sameWindow = leave && enter && leave->topLevelWidget() == enter->topLevelWidget(); + if ( leave && !sameWindow ) { + w = leave; + do { + leaveList.append( w ); + } while ( (w = w->parentWidget( TRUE ) ) ); + } + if ( enter && !sameWindow ) { + w = enter; + do { + enterList.prepend( w ); + } while ( (w = w->parentWidget(TRUE) ) ); + } + if ( sameWindow ) { + int enterDepth = 0; + int leaveDepth = 0; + w = enter; + while ( ( w = w->parentWidget( TRUE ) ) ) + enterDepth++; + w = leave; + while ( ( w = w->parentWidget( TRUE ) ) ) + leaveDepth++; + QWidget* wenter = enter; + QWidget* wleave = leave; + while ( enterDepth > leaveDepth ) { + wenter = wenter->parentWidget(); + enterDepth--; + } + while ( leaveDepth > enterDepth ) { + wleave = wleave->parentWidget(); + leaveDepth--; + } + while ( !wenter->isTopLevel() && wenter != wleave ) { + wenter = wenter->parentWidget(); + wleave = wleave->parentWidget(); + } + + w = leave; + while ( w != wleave ) { + leaveList.append( w ); + w = w->parentWidget(); + } + w = enter; + while ( w != wenter ) { + enterList.prepend( w ); + w = w->parentWidget(); + } + } + + QEvent leaveEvent( QEvent::Leave ); + for ( w = leaveList.first(); w; w = leaveList.next() ) { + if ( !qApp->activeModalWidget() || qt_tryModalHelper( w, 0 )) + QApplication::sendEvent( w, &leaveEvent ); + } + QEvent enterEvent( QEvent::Enter ); + for ( w = enterList.first(); w; w = enterList.next() ) { + if ( !qApp->activeModalWidget() || qt_tryModalHelper( w, 0 )) + QApplication::sendEvent( w, &enterEvent ); + } +} + + +#ifdef Q_WS_MACX +extern QWidget *qt_tryModalHelperMac( QWidget * top ); //qapplication_mac.cpp +#endif + + +/*!\internal + + Called from qapplication_<platform>.cpp, returns TRUE + if the widget should accept the event. + */ +Q_EXPORT bool qt_tryModalHelper( QWidget *widget, QWidget **rettop ) { + QWidget *modal=0, *top=QApplication::activeModalWidget(); + if ( rettop ) *rettop = top; + + if ( qApp->activePopupWidget() ) + return TRUE; + +#ifdef Q_WS_MACX + top = qt_tryModalHelperMac( top ); + if ( rettop ) *rettop = top; +#endif + + QWidget* groupLeader = widget; + widget = widget->topLevelWidget(); + + if ( widget->testWFlags(Qt::WShowModal) ) // widget is modal + modal = widget; + if ( !top || modal == top ) // don't block event + return TRUE; + + QWidget * p = widget->parentWidget(); // Check if the active modal widget is a parent of our widget + while ( p ) { + if ( p == top ) + return TRUE; + p = p->parentWidget(); + } + + while ( groupLeader && !groupLeader->testWFlags( Qt::WGroupLeader ) ) + groupLeader = groupLeader->parentWidget(); + + if ( groupLeader ) { + // Does groupLeader have a child in qt_modal_stack? + bool unrelated = TRUE; + modal = qt_modal_stack->first(); + while (modal && unrelated) { + QWidget* p = modal->parentWidget(); + while ( p && p != groupLeader && !p->testWFlags( Qt::WGroupLeader) ) { + p = p->parentWidget(); + } + modal = qt_modal_stack->next(); + if ( p == groupLeader ) unrelated = FALSE; + } + + if ( unrelated ) + return TRUE; // don't block event + } + return FALSE; +} + + +/*! + Returns the desktop widget (also called the root window). + + The desktop widget is useful for obtaining the size of the screen. + It may also be possible to draw on the desktop. We recommend against + assuming that it's possible to draw on the desktop, since this does + not work on all operating systems. + + \code + QDesktopWidget *d = QApplication::desktop(); + int w = d->width(); // returns desktop width + int h = d->height(); // returns desktop height + \endcode +*/ + +QDesktopWidget *QApplication::desktop() +{ + if ( !qt_desktopWidget || // not created yet + !qt_desktopWidget->isDesktop() ) { // reparented away + qt_desktopWidget = new QDesktopWidget(); + Q_CHECK_PTR( qt_desktopWidget ); + } + return qt_desktopWidget; +} + +#ifndef QT_NO_CLIPBOARD +/*! + Returns a pointer to the application global clipboard. +*/ +QClipboard *QApplication::clipboard() +{ + if ( qt_clipboard == 0 ) { + qt_clipboard = new QClipboard; + Q_CHECK_PTR( qt_clipboard ); + } + return qt_clipboard; +} +#endif // QT_NO_CLIPBOARD + +/*! + By default, Qt will try to use the current standard colors, fonts + etc., from the underlying window system's desktop settings, + and use them for all relevant widgets. This behavior can be switched off + by calling this function with \a on set to FALSE. + + This static function must be called before creating the QApplication + object, like this: + + \code + int main( int argc, char** argv ) { + QApplication::setDesktopSettingsAware( FALSE ); // I know better than the user + QApplication myApp( argc, argv ); // Use default fonts & colors + ... + } + \endcode + + \sa desktopSettingsAware() +*/ + +void QApplication::setDesktopSettingsAware( bool on ) +{ + obey_desktop_settings = on; +} + +/*! + Returns the value set by setDesktopSettingsAware(); by default TRUE. + + \sa setDesktopSettingsAware() +*/ + +bool QApplication::desktopSettingsAware() +{ + return obey_desktop_settings; +} + +/*! \fn void QApplication::lock() + + Lock the Qt Library Mutex. If another thread has already locked the + mutex, the calling thread will block until the other thread has + unlocked the mutex. + + \sa unlock() locked() \link threads.html Thread Support in Qt\endlink +*/ + + +/*! \fn void QApplication::unlock(bool wakeUpGui) + + Unlock the Qt Library Mutex. If \a wakeUpGui is TRUE (the default), + then the GUI thread will be woken with QApplication::wakeUpGuiThread(). + + \sa lock(), locked() \link threads.html Thread Support in Qt\endlink +*/ + + +/*! \fn bool QApplication::locked() + + Returns TRUE if the Qt Library Mutex is locked by a different thread; + otherwise returns FALSE. + + \warning Due to different implementations of recursive mutexes on + the supported platforms, calling this function from the same thread + that previously locked the mutex will give undefined results. + + \sa lock() unlock() \link threads.html Thread Support in Qt\endlink +*/ + +/*! \fn bool QApplication::tryLock() + + Attempts to lock the Qt Library Mutex, and returns immediately. If + the lock was obtained, this function returns TRUE. If another thread + has locked the mutex, this function returns FALSE, instead of + waiting for the lock to become available. + + The mutex must be unlocked with unlock() before another thread can + successfully lock it. + + \sa lock(), unlock() \link threads.html Thread Support in Qt\endlink +*/ + +#if defined(QT_THREAD_SUPPORT) +void QApplication::lock() +{ + qt_mutex->lock(); +} + +void QApplication::unlock(bool wakeUpGui) +{ + qt_mutex->unlock(); + + if (wakeUpGui) + wakeUpGuiThread(); +} + +bool QApplication::locked() +{ + return qt_mutex->locked(); +} + +bool QApplication::tryLock() +{ + return qt_mutex->tryLock(); +} +#endif + + +/*! + \fn bool QApplication::isSessionRestored() const + + Returns TRUE if the application has been restored from an earlier + \link session.html session\endlink; otherwise returns FALSE. + + \sa sessionId(), commitData(), saveState() +*/ + + +/*! + \fn QString QApplication::sessionId() const + + Returns the current \link session.html session's\endlink identifier. + + If the application has been restored from an earlier session, this + identifier is the same as it was in that previous session. + + The session identifier is guaranteed to be unique both for different + applications and for different instances of the same application. + + \sa isSessionRestored(), sessionKey(), commitData(), saveState() + */ + +/*! + \fn QString QApplication::sessionKey() const + + Returns the session key in the current \link session.html + session\endlink. + + If the application has been restored from an earlier session, this + key is the same as it was when the previous session ended. + + The session key changes with every call of commitData() or + saveState(). + + \sa isSessionRestored(), sessionId(), commitData(), saveState() + */ + + +/*! + \fn void QApplication::commitData( QSessionManager& sm ) + + This function deals with \link session.html session + management\endlink. It is invoked when the QSessionManager wants the + application to commit all its data. + + Usually this means saving all open files, after getting + permission from the user. Furthermore you may want to provide a means + by which the user can cancel the shutdown. + + Note that you should not exit the application within this function. + Instead, the session manager may or may not do this afterwards, + depending on the context. + + \warning Within this function, no user interaction is possible, \e + unless you ask the session manager \a sm for explicit permission. + See QSessionManager::allowsInteraction() and + QSessionManager::allowsErrorInteraction() for details and example + usage. + + The default implementation requests interaction and sends a close + event to all visible top level widgets. If any event was + rejected, the shutdown is canceled. + + \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink +*/ +#ifndef QT_NO_SESSIONMANAGER +void QApplication::commitData( QSessionManager& sm ) +{ + + if ( sm.allowsInteraction() ) { + QWidgetList done; + QWidgetList *list = QApplication::topLevelWidgets(); + bool cancelled = FALSE; + QWidget* w = list->first(); + while ( !cancelled && w ) { + if ( !w->isHidden() ) { + QCloseEvent e; + sendEvent( w, &e ); + cancelled = !e.isAccepted(); + if ( !cancelled ) + done.append( w ); + delete list; // one never knows... + list = QApplication::topLevelWidgets(); + w = list->first(); + } else { + w = list->next(); + } + while ( w && done.containsRef( w ) ) + w = list->next(); + } + delete list; + if ( cancelled ) + sm.cancel(); + } +} + + +/*! + \fn void QApplication::saveState( QSessionManager& sm ) + + This function deals with \link session.html session + management\endlink. It is invoked when the + \link QSessionManager session manager \endlink wants the application + to preserve its state for a future session. + + For example, a text editor would create a temporary file that + includes the current contents of its edit buffers, the location of + the cursor and other aspects of the current editing session. + + Note that you should never exit the application within this + function. Instead, the session manager may or may not do this + afterwards, depending on the context. Futhermore, most session + managers will very likely request a saved state immediately after + the application has been started. This permits the session manager + to learn about the application's restart policy. + + \warning Within this function, no user interaction is possible, \e + unless you ask the session manager \a sm for explicit permission. + See QSessionManager::allowsInteraction() and + QSessionManager::allowsErrorInteraction() for details. + + \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink +*/ + +void QApplication::saveState( QSessionManager& /* sm */ ) +{ +} +#endif //QT_NO_SESSIONMANAGER +/*! + Sets the time after which a drag should start to \a ms ms. + + \sa startDragTime() +*/ + +void QApplication::setStartDragTime( int ms ) +{ + drag_time = ms; +} + +/*! + If you support drag and drop in you application and a drag should + start after a mouse click and after a certain time elapsed, you + should use the value which this method returns as the delay (in ms). + + Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, + for starting a drag. + + The default value is 500 ms. + + \sa setStartDragTime(), startDragDistance() +*/ + +int QApplication::startDragTime() +{ + return drag_time; +} + +/*! + Sets the distance after which a drag should start to \a l pixels. + + \sa startDragDistance() +*/ + +void QApplication::setStartDragDistance( int l ) +{ + drag_distance = l; +} + +/*! + If you support drag and drop in you application and a drag should + start after a mouse click and after moving the mouse a certain + distance, you should use the value which this method returns as the + distance. + + For example, if the mouse position of the click is stored in \c + startPos and the current position (e.g. in the mouse move event) is + \c currPos, you can find out if a drag should be started with code + like this: + \code + if ( ( startPos - currPos ).manhattanLength() > + QApplication::startDragDistance() ) + startTheDrag(); + \endcode + + Qt uses this value internally, e.g. in QFileDialog. + + The default value is 4 pixels. + + \sa setStartDragDistance(), startDragTime(), QPoint::manhattanLength() +*/ + +int QApplication::startDragDistance() +{ + return drag_distance; +} + +/*! + If \a b is TRUE, all dialogs and widgets will be laid out in a + mirrored fashion, as required by right to left languages such as + Arabic and Hebrew. If \a b is FALSE, dialogs and widgets are laid + out left to right. + + Changing this flag in runtime does not cause a relayout of already + instantiated widgets. + + \sa reverseLayout() +*/ +void QApplication::setReverseLayout( bool b ) +{ + if ( reverse_layout == b ) + return; + + reverse_layout = b; + + QWidgetList *list = topLevelWidgets(); + QWidgetListIt it( *list ); + QWidget *w; + while ( ( w=it.current() ) != 0 ) { + ++it; + postEvent( w, new QEvent( QEvent::LayoutDirectionChange ) ); + } + delete list; +} + +/*! + Returns TRUE if all dialogs and widgets will be laid out in a + mirrored (right to left) fashion. Returns FALSE if dialogs and + widgets will be laid out left to right. + + \sa setReverseLayout() +*/ +bool QApplication::reverseLayout() +{ + return reverse_layout; +} + + +/*! + \class QSessionManager qsessionmanager.h + \brief The QSessionManager class provides access to the session manager. + + \ingroup application + \ingroup environment + + The session manager is responsible for session management, most + importantly for interruption and resumption. A "session" is a kind + of record of the state of the system, e.g. which applications were + run at start up and which applications are currently running. The + session manager is used to save the session, e.g. when the machine + is shut down; and to restore a session, e.g. when the machine is + started up. Use QSettings to save and restore an individual + application's settings, e.g. window positions, recently used files, + etc. + + QSessionManager provides an interface between the application and + the session manager so that the program can work well with the + session manager. In Qt, session management requests for action + are handled by the two virtual functions QApplication::commitData() + and QApplication::saveState(). Both provide a reference to + a session manager object as argument, to allow the application + to communicate with the session manager. + + During a session management action (i.e. within commitData() and + saveState()), no user interaction is possible \e unless the + application got explicit permission from the session manager. You + ask for permission by calling allowsInteraction() or, if it's really + urgent, allowsErrorInteraction(). Qt does not enforce this, but the + session manager may. + + You can try to abort the shutdown process by calling cancel(). The + default commitData() function does this if some top-level window + rejected its closeEvent(). + + For sophisticated session managers provided on Unix/X11, QSessionManager + offers further possibilites to fine-tune an application's session + management behavior: setRestartCommand(), setDiscardCommand(), + setRestartHint(), setProperty(), requestPhase2(). See the respective + function descriptions for further details. +*/ + +/*! \enum QSessionManager::RestartHint + + This enum type defines the circumstances under which this + application wants to be restarted by the session manager. The + current values are + + \value RestartIfRunning if the application is still running when + the session is shut down, it wants to be restarted at the start of + the next session. + + \value RestartAnyway the application wants to be started at the + start of the next session, no matter what. (This is useful for + utilities that run just after startup and then quit.) + + \value RestartImmediately the application wants to be started + immediately whenever it is not running. + + \value RestartNever the application does not want to be restarted + automatically. + + The default hint is \c RestartIfRunning. +*/ + + +/*! + \fn QString QSessionManager::sessionId() const + + Returns the identifier of the current session. + + If the application has been restored from an earlier session, this + identifier is the same as it was in that earlier session. + + \sa sessionKey(), QApplication::sessionId() + */ + +/*! + \fn QString QSessionManager::sessionKey() const + + Returns the session key in the current session. + + If the application has been restored from an earlier session, this + key is the same as it was when the previous session ended. + + The session key changes with every call of commitData() or + saveState(). + + \sa sessionId(), QApplication::sessionKey() + */ + +// ### Note: This function is undocumented, since it is #ifdef'd. + +/*! + \fn void* QSessionManager::handle() const + + X11 only: returns a handle to the current \c SmcConnection. +*/ + + +/*! + \fn bool QSessionManager::allowsInteraction() + + Asks the session manager for permission to interact with the + user. Returns TRUE if interaction is permitted; otherwise + returns FALSE. + + The rationale behind this mechanism is to make it possible to + synchronize user interaction during a shutdown. Advanced session + managers may ask all applications simultaneously to commit their + data, resulting in a much faster shutdown. + + When the interaction is completed we strongly recommend releasing the + user interaction semaphore with a call to release(). This way, other + applications may get the chance to interact with the user while your + application is still busy saving data. (The semaphore is implicitly + released when the application exits.) + + If the user decides to cancel the shutdown process during the + interaction phase, you must tell the session manager that this has + happened by calling cancel(). + + Here's an example of how an application's QApplication::commitData() + might be implemented: + +\code +void MyApplication::commitData( QSessionManager& sm ) { + if ( sm.allowsInteraction() ) { + switch ( QMessageBox::warning( + yourMainWindow, + tr("Application Name"), + tr("Save changes to document Foo?"), + tr("&Yes"), + tr("&No"), + tr("Cancel"), + 0, 2) ) { + case 0: // yes + sm.release(); + // save document here; if saving fails, call sm.cancel() + break; + case 1: // continue without saving + break; + default: // cancel + sm.cancel(); + break; + } + } else { + // we did not get permission to interact, then + // do something reasonable instead. + } +} +\endcode + + If an error occurred within the application while saving its data, + you may want to try allowsErrorInteraction() instead. + + \sa QApplication::commitData(), release(), cancel() +*/ + + +/*! + \fn bool QSessionManager::allowsErrorInteraction() + + This is similar to allowsInteraction(), but also tells the session + manager that an error occurred. Session managers may give error + interaction request higher priority, which means that it is more likely + that an error interaction is permitted. However, you are still not + guaranteed that the session manager will allow interaction. + + \sa allowsInteraction(), release(), cancel() +*/ + +/*! + \fn void QSessionManager::release() + + Releases the session manager's interaction semaphore after an + interaction phase. + + \sa allowsInteraction(), allowsErrorInteraction() +*/ + +/*! + \fn void QSessionManager::cancel() + + Tells the session manager to cancel the shutdown process. Applications + should not call this function without first asking the user. + + \sa allowsInteraction(), allowsErrorInteraction() + +*/ + +/*! + \fn void QSessionManager::setRestartHint( RestartHint hint ) + + Sets the application's restart hint to \a hint. On application + startup the hint is set to \c RestartIfRunning. + + Note that these flags are only hints, a session manager may or may + not respect them. + + We recommend setting the restart hint in QApplication::saveState() + because most session managers perform a checkpoint shortly after an + application's startup. + + \sa restartHint() +*/ + +/*! + \fn QSessionManager::RestartHint QSessionManager::restartHint() const + + Returns the application's current restart hint. The default is + \c RestartIfRunning. + + \sa setRestartHint() +*/ + +/*! + \fn void QSessionManager::setRestartCommand( const QStringList& command ) + + If the session manager is capable of restoring sessions it will + execute \a command in order to restore the application. The command + defaults to + + \code + appname -session id + \endcode + + The \c -session option is mandatory; otherwise QApplication cannot + tell whether it has been restored or what the current session + identifier is. See QApplication::isSessionRestored() and + QApplication::sessionId() for details. + + If your application is very simple, it may be possible to store the + entire application state in additional command line options. This + is usually a very bad idea because command lines are often limited + to a few hundred bytes. Instead, use QSettings, or temporary files + or a database for this purpose. By marking the data with the unique + sessionId(), you will be able to restore the application in a future + session. + + \sa restartCommand(), setDiscardCommand(), setRestartHint() +*/ + +/*! + \fn QStringList QSessionManager::restartCommand() const + + Returns the currently set restart command. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QStringList list = mySession.restartCommand(); + QStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa setRestartCommand(), restartHint() +*/ + +/*! + \fn void QSessionManager::setDiscardCommand( const QStringList& ) + + \sa discardCommand(), setRestartCommand() +*/ + + +/*! + \fn QStringList QSessionManager::discardCommand() const + + Returns the currently set discard command. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QStringList list = mySession.discardCommand(); + QStringList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa setDiscardCommand(), restartCommand(), setRestartCommand() +*/ + +/*! + \overload void QSessionManager::setManagerProperty( const QString& name, + const QString& value ) + + Low-level write access to the application's identification and state + records are kept in the session manager. + + The property called \a name has its value set to the string \a value. +*/ + +/*! + \fn void QSessionManager::setManagerProperty( const QString& name, + const QStringList& value ) + + Low-level write access to the application's identification and state + record are kept in the session manager. + + The property called \a name has its value set to the string list \a value. +*/ + +/*! + \fn bool QSessionManager::isPhase2() const + + Returns TRUE if the session manager is currently performing a second + session management phase; otherwise returns FALSE. + + \sa requestPhase2() +*/ + +/*! + \fn void QSessionManager::requestPhase2() + + Requests a second session management phase for the application. The + application may then return immediately from the + QApplication::commitData() or QApplication::saveState() function, + and they will be called again once most or all other applications have + finished their session management. + + The two phases are useful for applications such as the X11 window manager + that need to store information about another application's windows + and therefore have to wait until these applications have completed their + respective session management tasks. + + Note that if another application has requested a second phase it + may get called before, simultaneously with, or after your + application's second phase. + + \sa isPhase2() +*/ + +/*! + \fn int QApplication::horizontalAlignment( int align ) + + Strips out vertical alignment flags and transforms an + alignment \a align of AlignAuto into AlignLeft or + AlignRight according to the language used. The other horizontal + alignment flags are left untouched. +*/ + + +/***************************************************************************** + Stubbed session management support + *****************************************************************************/ +#ifndef QT_NO_SESSIONMANAGER +#if defined( QT_NO_SM_SUPPORT ) || defined( Q_WS_WIN ) || defined( Q_WS_MAC ) || defined( Q_WS_QWS ) + +class QSessionManagerData +{ +public: + QStringList restartCommand; + QStringList discardCommand; + QString sessionId; + QString sessionKey; + QSessionManager::RestartHint restartHint; +}; + +QSessionManager* qt_session_manager_self = 0; +QSessionManager::QSessionManager( QApplication * app, QString &id, QString &key ) + : QObject( app, "qt_sessionmanager" ) +{ + qt_session_manager_self = this; + d = new QSessionManagerData; +#if defined(Q_WS_WIN) && !defined(Q_OS_TEMP) + wchar_t guidstr[40]; + GUID guid; + CoCreateGuid( &guid ); + StringFromGUID2(guid, guidstr, 40); + id = QString::fromUcs2((ushort*)guidstr); + CoCreateGuid( &guid ); + StringFromGUID2(guid, guidstr, 40); + key = QString::fromUcs2((ushort*)guidstr); +#endif + d->sessionId = id; + d->sessionKey = key; + d->restartHint = RestartIfRunning; +} + +QSessionManager::~QSessionManager() +{ + delete d; + qt_session_manager_self = 0; +} + +QString QSessionManager::sessionId() const +{ + return d->sessionId; +} + +QString QSessionManager::sessionKey() const +{ + return d->sessionKey; +} + + +#if defined(Q_WS_X11) || defined(Q_WS_MAC) +void* QSessionManager::handle() const +{ + return 0; +} +#endif + +#if !defined(Q_WS_WIN) +bool QSessionManager::allowsInteraction() +{ + return TRUE; +} + +bool QSessionManager::allowsErrorInteraction() +{ + return TRUE; +} +void QSessionManager::release() +{ +} + +void QSessionManager::cancel() +{ +} +#endif + + +void QSessionManager::setRestartHint( QSessionManager::RestartHint hint) +{ + d->restartHint = hint; +} + +QSessionManager::RestartHint QSessionManager::restartHint() const +{ + return d->restartHint; +} + +void QSessionManager::setRestartCommand( const QStringList& command) +{ + d->restartCommand = command; +} + +QStringList QSessionManager::restartCommand() const +{ + return d->restartCommand; +} + +void QSessionManager::setDiscardCommand( const QStringList& command) +{ + d->discardCommand = command; +} + +QStringList QSessionManager::discardCommand() const +{ + return d->discardCommand; +} + +void QSessionManager::setManagerProperty( const QString&, const QString&) +{ +} + +void QSessionManager::setManagerProperty( const QString&, const QStringList& ) +{ +} + +bool QSessionManager::isPhase2() const +{ + return FALSE; +} + +void QSessionManager::requestPhase2() +{ +} + +#endif // QT_NO_SM_SUPPORT +#endif //QT_NO_SESSIONMANAGER |