Fix the qtranslator autotest
[profile/ivi/qtbase.git] / src / widgets / kernel / qapplication.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qplatformdefs.h"
43 #include "qabstracteventdispatcher.h"
44 #include "qaccessible.h"
45 #include "qapplication.h"
46 #include "qclipboard.h"
47 #include "qcursor.h"
48 #include "qdesktopwidget.h"
49 #include "qdir.h"
50 #include "qevent.h"
51 #include "qfile.h"
52 #include "qfileinfo.h"
53 #include "qgraphicsscene.h"
54 #include "qhash.h"
55 #include "qset.h"
56 #include "qlayout.h"
57 #include "qsessionmanager.h"
58 #include "qstyle.h"
59 #include "qstylefactory.h"
60 #include "qtextcodec.h"
61 #include "qtranslator.h"
62 #include "qvariant.h"
63 #include "qwidget.h"
64 #include "private/qdnd_p.h"
65 #include "qcolormap.h"
66 #include "qdebug.h"
67 #include "private/qstylesheetstyle_p.h"
68 #include "private/qstyle_p.h"
69 #include "qmessagebox.h"
70 #include <QtWidgets/qgraphicsproxywidget.h>
71 #include <QtGui/qstylehints.h>
72 #include <QtGui/qinputpanel.h>
73
74 #include "qinputcontext.h"
75 #include "private/qkeymapper_p.h"
76
77 #ifdef Q_WS_X11
78 #include <private/qt_x11_p.h>
79 #endif
80
81 #include "qguiplatformplugin_p.h"
82
83 #include <qthread.h>
84 #include <private/qthread_p.h>
85
86 #include <private/qfont_p.h>
87
88 #include <stdlib.h>
89
90 #if defined(Q_WS_X11) && !defined(QT_NO_EGL)
91 #include <link.h>
92 #endif
93
94 #include "qapplication_p.h"
95 #include "private/qevent_p.h"
96 #include "qwidget_p.h"
97
98 #include "qapplication.h"
99
100 #include "qgesture.h"
101 #include "private/qgesturemanager_p.h"
102 #include "private/qguiapplication_p.h"
103 #include "qplatformfontdatabase_qpa.h"
104 #ifndef QT_NO_LIBRARY
105 #include "qlibrary.h"
106 #endif
107
108 #ifdef Q_WS_WINCE
109 #include "qdatetime.h"
110 #include "qguifunctions_wince.h"
111 extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
112 extern bool qt_wince_is_mobile();     //qguifunctions_wince.cpp
113 extern bool qt_wince_is_pocket_pc();  //qguifunctions_wince.cpp
114 #endif
115
116 #include "qdatetime.h"
117
118 #ifdef QT_MAC_USE_COCOA
119 #include <private/qt_cocoa_helpers_mac_p.h>
120 #endif
121
122 //#define ALIEN_DEBUG
123
124 #if defined(Q_OS_SYMBIAN)
125 #include "qt_s60_p.h"
126 #endif
127
128 static void initResources()
129 {
130 #if defined(Q_WS_WINCE)
131     Q_INIT_RESOURCE_EXTERN(qstyle_wince)
132     Q_INIT_RESOURCE(qstyle_wince);
133 #elif defined(Q_OS_SYMBIAN)
134     Q_INIT_RESOURCE_EXTERN(qstyle_s60)
135     Q_INIT_RESOURCE(qstyle_s60);
136 #else
137     Q_INIT_RESOURCE_EXTERN(qstyle)
138     Q_INIT_RESOURCE(qstyle);
139 #endif
140     Q_INIT_RESOURCE_EXTERN(qmessagebox)
141     Q_INIT_RESOURCE(qmessagebox);
142
143 }
144
145 QT_BEGIN_NAMESPACE
146
147 Q_CORE_EXPORT void qt_call_post_routines();
148
149 QApplication::Type qt_appType=QApplication::Tty;
150 QApplicationPrivate *QApplicationPrivate::self = 0;
151
152 QInputContext *QApplicationPrivate::inputContext = 0;
153
154 bool QApplicationPrivate::quitOnLastWindowClosed = true;
155
156 #ifdef Q_WS_WINCE
157 int QApplicationPrivate::autoMaximizeThreshold = -1;
158 bool QApplicationPrivate::autoSipEnabled = false;
159 #else
160 bool QApplicationPrivate::autoSipEnabled = true;
161 #endif
162
163 QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type, int flags)
164     : QApplicationPrivateBase(argc, argv, flags)
165 {
166     application_type = type;
167     qt_appType = type;
168
169 #ifndef QT_NO_SESSIONMANAGER
170     is_session_restored = false;
171 #endif
172
173     quitOnLastWindowClosed = true;
174
175 #if defined(Q_WS_QWS) && !defined(QT_NO_DIRECTPAINTER)
176     directPainters = 0;
177 #endif
178
179 #ifndef QT_NO_GESTURES
180     gestureManager = 0;
181     gestureWidget = 0;
182 #endif // QT_NO_GESTURES
183
184 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
185     move_cursor = 0;
186     copy_cursor = 0;
187     link_cursor = 0;
188 #endif
189 #if defined(Q_WS_WIN)
190     ignore_cursor = 0;
191 #endif
192
193     if (!self)
194         self = this;
195 }
196
197 QApplicationPrivate::~QApplicationPrivate()
198 {
199     if (self == this)
200         self = 0;
201 }
202
203 /*!
204     \class QApplication
205     \brief The QApplication class manages the GUI application's control
206     flow and main settings.
207
208     QApplication contains the main event loop, where all events from the window
209     system and other sources are processed and dispatched. It also handles the
210     application's initialization, finalization, and provides session
211     management. In addition, QApplication handles most of the system-wide and
212     application-wide settings.
213
214     For any GUI application using Qt, there is precisely \bold one QApplication
215     object, no matter whether the application has 0, 1, 2 or more windows at
216     any given time. For non-GUI Qt applications, use QCoreApplication instead,
217     as it does not depend on the \l QtGui library.
218
219     The QApplication object is accessible through the instance() function that
220     returns a pointer equivalent to the global qApp pointer.
221
222     QApplication's main areas of responsibility are:
223         \list
224             \o  It initializes the application with the user's desktop settings
225                 such as palette(), font() and doubleClickInterval(). It keeps
226                 track of these properties in case the user changes the desktop
227                 globally, for example through some kind of control panel.
228
229             \o  It performs event handling, meaning that it receives events
230                 from the underlying window system and dispatches them to the
231                 relevant widgets. By using sendEvent() and postEvent() you can
232                 send your own events to widgets.
233
234             \o  It parses common command line arguments and sets its internal
235                 state accordingly. See the \l{QApplication::QApplication()}
236                 {constructor documentation} below for more details.
237
238             \o  It defines the application's look and feel, which is
239                 encapsulated in a QStyle object. This can be changed at runtime
240                 with setStyle().
241
242             \o  It specifies how the application is to allocate colors. See
243                 setColorSpec() for details.
244
245             \o  It provides localization of strings that are visible to the
246                 user via translate().
247
248             \o  It provides some magical objects like the desktop() and the
249                 clipboard().
250
251             \o  It knows about the application's windows. You can ask which
252                 widget is at a certain position using widgetAt(), get a list of
253                 topLevelWidgets() and closeAllWindows(), etc.
254
255             \o  It manages the application's mouse cursor handling, see
256                 setOverrideCursor()
257
258             \o  On the X window system, it provides functions to flush and sync
259                 the communication stream, see flushX() and syncX().
260
261             \o  It provides support for sophisticated \l{Session Management}
262                 {session management}. This makes it possible for applications
263                 to terminate gracefully when the user logs out, to cancel a
264                 shutdown process if termination isn't possible and even to
265                 preserve the entire application's state for a future session.
266                 See isSessionRestored(), sessionId() and commitData() and
267                 saveState() for details.
268         \endlist
269
270     Since the QApplication object does so much initialization, it \e{must} be
271     created before any other objects related to the user interface are created.
272     QApplication also deals with common command line arguments. Hence, it is
273     usually a good idea to create it \e before any interpretation or
274     modification of \c argv is done in the application itself.
275
276     \table
277     \header
278         \o{2,1} Groups of functions
279
280         \row
281         \o  System settings
282         \o  desktopSettingsAware(),
283             setDesktopSettingsAware(),
284             cursorFlashTime(),
285             setCursorFlashTime(),
286             doubleClickInterval(),
287             setDoubleClickInterval(),
288             setKeyboardInputInterval(),
289             wheelScrollLines(),
290             setWheelScrollLines(),
291             palette(),
292             setPalette(),
293             font(),
294             setFont(),
295             fontMetrics().
296
297         \row
298         \o  Event handling
299         \o  exec(),
300             processEvents(),
301             exit(),
302             quit().
303             sendEvent(),
304             postEvent(),
305             sendPostedEvents(),
306             removePostedEvents(),
307             hasPendingEvents(),
308             notify(),
309             macEventFilter(),
310             qwsEventFilter(),
311             x11EventFilter(),
312             x11ProcessEvent(),
313             winEventFilter().
314
315         \row
316         \o  GUI Styles
317         \o  style(),
318             setStyle().
319
320         \row
321         \o  Color usage
322         \o  colorSpec(),
323             setColorSpec(),
324             qwsSetCustomColors().
325
326         \row
327         \o  Text handling
328         \o  installTranslator(),
329             removeTranslator()
330             translate().
331
332         \row
333         \o  Widgets
334         \o  allWidgets(),
335             topLevelWidgets(),
336             desktop(),
337             activePopupWidget(),
338             activeModalWidget(),
339             clipboard(),
340             focusWidget(),
341             activeWindow(),
342             widgetAt().
343
344         \row
345         \o  Advanced cursor handling
346         \o  overrideCursor(),
347             setOverrideCursor(),
348             restoreOverrideCursor().
349
350         \row
351         \o  X Window System synchronization
352         \o  flushX(),
353             syncX().
354
355         \row
356         \o  Session management
357         \o  isSessionRestored(),
358             sessionId(),
359             commitData(),
360             saveState().
361
362         \row
363         \o  Miscellaneous
364         \o  closeAllWindows(),
365             startingUp(),
366             closingDown(),
367             type().
368     \endtable
369
370     \sa QCoreApplication, QAbstractEventDispatcher, QEventLoop, QSettings
371 */
372
373 /*!
374     \enum QApplication::Type
375
376     \value Tty a console application
377     \value GuiClient a GUI client application
378     \value GuiServer a GUI server application (for Qt for Embedded Linux)
379 */
380
381 /*!
382     \enum QApplication::ColorSpec
383
384     \value NormalColor the default color allocation policy
385     \value CustomColor the same as NormalColor for X11; allocates colors
386     to a palette on demand under Windows
387     \value ManyColor the right choice for applications that use thousands of
388     colors
389
390     See setColorSpec() for full details.
391 */
392
393 /*!
394     \fn QWidget *QApplication::topLevelAt(const QPoint &point)
395
396     Returns the top-level widget at the given \a point; returns 0 if
397     there is no such widget.
398 */
399
400 /*!
401     \fn QWidget *QApplication::topLevelAt(int x, int y)
402
403     \overload
404
405     Returns the top-level widget at the point (\a{x}, \a{y}); returns
406     0 if there is no such widget.
407 */
408
409
410 /*
411     The qt_init() and qt_cleanup() functions are implemented in the
412     qapplication_xyz.cpp file.
413 */
414
415 void qt_init(QApplicationPrivate *priv, int type
416 #ifdef Q_WS_X11
417               , Display *display = 0, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0
418 #endif
419    );
420 void qt_cleanup();
421
422 Qt::MouseButtons QApplicationPrivate::mouse_buttons = Qt::NoButton;
423 Qt::KeyboardModifiers QApplicationPrivate::modifier_buttons = Qt::NoModifier;
424
425 QStyle *QApplicationPrivate::app_style = 0;        // default application style
426 QString QApplicationPrivate::styleOverride;        // style override
427
428 #ifndef QT_NO_STYLE_STYLESHEET
429 QString QApplicationPrivate::styleSheet;           // default application stylesheet
430 #endif
431 QPointer<QWidget> QApplicationPrivate::leaveAfterRelease = 0;
432
433 int QApplicationPrivate::app_cspec = QApplication::NormalColor;
434 QPalette *QApplicationPrivate::sys_pal = 0;        // default system palette
435 QPalette *QApplicationPrivate::set_pal = 0;        // default palette set by programmer
436
437 #ifndef Q_WS_QPA
438 Q_GLOBAL_STATIC(QMutex, applicationFontMutex)
439 QFont *QApplicationPrivate::app_font = 0;        // default application font
440 #endif
441 QFont *QApplicationPrivate::sys_font = 0;        // default system font
442 QFont *QApplicationPrivate::set_font = 0;        // default font set by programmer
443
444 QIcon *QApplicationPrivate::app_icon = 0;
445 QWidget *QApplicationPrivate::main_widget = 0;        // main application widget
446 QWidget *QApplicationPrivate::focus_widget = 0;        // has keyboard input focus
447 QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
448 QWidget *QApplicationPrivate::active_window = 0;        // toplevel with keyboard focus
449 bool QApplicationPrivate::obey_desktop_settings = true;        // use winsys resources
450 #ifndef QT_NO_WHEELEVENT
451 int QApplicationPrivate::wheel_scroll_lines;   // number of lines to scroll
452 #endif
453 bool qt_is_gui_used;
454 bool Q_WIDGETS_EXPORT qt_tab_all_widgets = true;
455 bool qt_in_tab_key_event = false;
456 int qt_antialiasing_threshold = -1;
457 QSize QApplicationPrivate::app_strut = QSize(0,0); // no default application strut
458 bool QApplicationPrivate::animate_ui = true;
459 bool QApplicationPrivate::animate_menu = false;
460 bool QApplicationPrivate::fade_menu = false;
461 bool QApplicationPrivate::animate_combo = false;
462 bool QApplicationPrivate::animate_tooltip = false;
463 bool QApplicationPrivate::fade_tooltip = false;
464 bool QApplicationPrivate::animate_toolbox = false;
465 bool QApplicationPrivate::widgetCount = false;
466 bool QApplicationPrivate::load_testability = false;
467 #ifdef QT_KEYPAD_NAVIGATION
468 #  ifdef Q_OS_SYMBIAN
469 Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadDirectional;
470 #  else
471 Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
472 #  endif
473 QWidget *QApplicationPrivate::oldEditFocus = 0;
474 #endif
475
476 bool qt_tabletChokeMouse = false;
477
478 inline bool QApplicationPrivate::isAlien(QWidget *widget)
479 {
480     return widget && !widget->isWindow();
481 }
482
483 // ######## move to QApplicationPrivate
484 // Default application palettes and fonts (per widget type)
485 Q_GLOBAL_STATIC(PaletteHash, app_palettes)
486 PaletteHash *qt_app_palettes_hash()
487 {
488     return app_palettes();
489 }
490
491 FontHash::FontHash()
492 {
493     QHash<QByteArray, QFont>::operator=(QGuiApplicationPrivate::platformIntegration()->fontDatabase()->defaultFonts());
494 }
495
496 Q_GLOBAL_STATIC(FontHash, app_fonts)
497 FontHash *qt_app_fonts_hash()
498 {
499     return app_fonts();
500 }
501
502 QWidgetList *QApplicationPrivate::popupWidgets = 0;        // has keyboard input focus
503
504 QDesktopWidget *qt_desktopWidget = 0;                // root window widgets
505 #if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
506 QClipboard              *qt_clipboard = 0;        // global clipboard object
507 #endif
508 QWidgetList * qt_modal_stack = 0;                // stack of modal widgets
509 bool app_do_modal = false;
510
511 /*!
512     \internal
513 */
514 void QApplicationPrivate::process_cmdline()
515 {
516     // process platform-indep command line
517     if (!qt_is_gui_used || !argc)
518         return;
519
520     int i, j;
521
522     j = 1;
523     for (i=1; i<argc; i++) { // if you add anything here, modify QCoreApplication::arguments()
524         if (argv[i] && *argv[i] != '-') {
525             argv[j++] = argv[i];
526             continue;
527         }
528         QByteArray arg = argv[i];
529         arg = arg;
530         QString s;
531         if (arg == "-qdevel" || arg == "-qdebug") {
532             // obsolete argument
533         } else if (arg.indexOf("-style=", 0) != -1) {
534             s = QString::fromLocal8Bit(arg.right(arg.length() - 7).toLower());
535         } else if (arg == "-style" && i < argc-1) {
536             s = QString::fromLocal8Bit(argv[++i]).toLower();
537 #ifndef QT_NO_SESSIONMANAGER
538         } else if (arg == "-session" && i < argc-1) {
539             ++i;
540             if (argv[i] && *argv[i]) {
541                 session_id = QString::fromLatin1(argv[i]);
542                 int p = session_id.indexOf(QLatin1Char('_'));
543                 if (p >= 0) {
544                     session_key = session_id.mid(p +1);
545                     session_id = session_id.left(p);
546                 }
547                 is_session_restored = true;
548             }
549 #endif
550 #ifndef QT_NO_STYLE_STYLESHEET
551         } else if (arg == "-stylesheet" && i < argc -1) {
552             styleSheet = QLatin1String("file:///");
553             styleSheet.append(QString::fromLocal8Bit(argv[++i]));
554         } else if (arg.indexOf("-stylesheet=") != -1) {
555             styleSheet = QLatin1String("file:///");
556             styleSheet.append(QString::fromLocal8Bit(arg.right(arg.length() - 12)));
557 #endif
558         } else if (qstrcmp(arg, "-widgetcount") == 0) {
559             widgetCount = true;
560         } else if (qstrcmp(arg, "-testability") == 0) {
561             load_testability = true;
562         } else {
563             argv[j++] = argv[i];
564         }
565         if (!s.isEmpty()) {
566             if (app_style) {
567                 delete app_style;
568                 app_style = 0;
569             }
570             styleOverride = s;
571         }
572     }
573
574     if(j < argc) {
575         argv[j] = 0;
576         argc = j;
577     }
578 }
579
580 /*!
581     Initializes the window system and constructs an application object with
582     \a argc command line arguments in \a argv.
583
584     \warning The data referred to by \a argc and \a argv must stay valid for
585     the entire lifetime of the QApplication object. In addition, \a argc must
586     be greater than zero and \a argv must contain at least one valid character
587     string.
588
589     The global \c qApp pointer refers to this application object. Only one
590     application object should be created.
591
592     This application object must be constructed before any \l{QPaintDevice}
593     {paint devices} (including widgets, pixmaps, bitmaps etc.).
594
595     \note \a argc and \a argv might be changed as Qt removes command line
596     arguments that it recognizes.
597
598     Qt debugging options (not available if Qt was compiled without the QT_DEBUG
599     flag defined):
600     \list
601         \o  -nograb, tells Qt that it must never grab the mouse or the
602             keyboard.
603         \o  -dograb (only under X11), running under a debugger can cause an
604             implicit -nograb, use -dograb to override.
605         \o  -sync (only under X11), switches to synchronous mode for
606             debugging.
607     \endlist
608
609     See \l{Debugging Techniques} for a more detailed explanation.
610
611     All Qt programs automatically support the following command line options:
612     \list
613         \o  -style= \e style, sets the application GUI style. Possible values
614             are \c motif, \c windows, and \c platinum. If you compiled Qt with
615             additional styles or have additional styles as plugins these will
616             be available to the \c -style command line option.
617         \o  -style \e style, is the same as listed above.
618         \o  -stylesheet= \e stylesheet, sets the application \l styleSheet. The
619             value must be a path to a file that contains the Style Sheet.
620             \note Relative URLs in the Style Sheet file are relative to the
621             Style Sheet file's path.
622         \o  -stylesheet \e stylesheet, is the same as listed above.
623         \o  -session= \e session, restores the application from an earlier
624             \l{Session Management}{session}.
625         \o  -session \e session, is the same as listed above.
626         \o  -widgetcount, prints debug message at the end about number of
627             widgets left undestroyed and maximum number of widgets existed at
628             the same time
629         \o  -reverse, sets the application's layout direction to
630             Qt::RightToLeft
631         \o  -qmljsdebugger=, activates the QML/JS debugger with a specified port.
632             The value must be of format port:1234[,block], where block is optional
633             and will make the application wait until a debugger connects to it.
634     \endlist
635
636     The X11 version of Qt supports some traditional X11 command line options:
637     \list
638         \o  -display \e display, sets the X display (default is $DISPLAY).
639         \o  -geometry \e geometry, sets the client geometry of the first window
640             that is shown.
641         \o  -fn or \c -font \e font, defines the application font. The font
642             should be specified using an X logical font description. Note that
643             this option is ignored when Qt is built with fontconfig support enabled.
644         \o  -bg or \c -background \e color, sets the default background color
645             and an application palette (light and dark shades are calculated).
646         \o  -fg or \c -foreground \e color, sets the default foreground color.
647         \o  -btn or \c -button \e color, sets the default button color.
648         \o  -name \e name, sets the application name.
649         \o  -title \e title, sets the application title.
650         \o  -visual \c TrueColor, forces the application to use a TrueColor
651             visual on an 8-bit display.
652         \o  -ncols \e count, limits the number of colors allocated in the color
653             cube on an 8-bit display, if the application is using the
654             QApplication::ManyColor color specification. If \e count is 216
655             then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
656             and 6 of blue); for other values, a cube approximately proportional
657             to a 2x3x1 cube is used.
658         \o  -cmap, causes the application to install a private color map on an
659             8-bit display.
660         \o  -im, sets the input method server (equivalent to setting the
661             XMODIFIERS environment variable)
662         \o  -inputstyle, defines how the input is inserted into the given
663             widget, e.g., \c onTheSpot makes the input appear directly in the
664             widget, while \c overTheSpot makes the input appear in a box
665             floating over the widget and is not inserted until the editing is
666             done.
667     \endlist
668
669     \section1 X11 Notes
670
671     If QApplication fails to open the X11 display, it will terminate
672     the process. This behavior is consistent with most X11
673     applications.
674
675     \sa arguments()
676 */
677
678 QApplication::QApplication(int &argc, char **argv)
679     : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
680 { Q_D(QApplication); d->construct(); }
681
682 QApplication::QApplication(int &argc, char **argv, int _internal)
683     : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
684 { Q_D(QApplication); d->construct(); }
685
686
687 /*!
688     Constructs an application object with \a argc command line arguments in
689     \a argv. If \a GUIenabled is true, a GUI application is constructed,
690     otherwise a non-GUI (console) application is created.
691
692     \warning The data referred to by \a argc and \a argv must stay valid for
693     the entire lifetime of the QApplication object. In addition, \a argc must
694     be greater than zero and \a argv must contain at least one valid character
695     string.
696
697     Set \a GUIenabled to false for programs without a graphical user interface
698     that should be able to run without a window system.
699
700     On X11, the window system is initialized if \a GUIenabled is true. If
701     \a GUIenabled is false, the application does not connect to the X server.
702     On Windows and Mac OS, currently the window system is always initialized,
703     regardless of the value of GUIenabled. This may change in future versions
704     of Qt.
705
706     The following example shows how to create an application that uses a
707     graphical interface when available.
708
709     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 0
710 */
711
712 QApplication::QApplication(int &argc, char **argv, bool GUIenabled )
713     : QApplicationBase(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, 0x040000))
714 { Q_D(QApplication); d->construct(); }
715
716 QApplication::QApplication(int &argc, char **argv, bool GUIenabled , int _internal)
717     : QApplicationBase(*new QApplicationPrivate(argc, argv, GUIenabled ? GuiClient : Tty, _internal))
718 { Q_D(QApplication); d->construct();}
719
720
721
722 /*!
723     Constructs an application object with \a argc command line arguments in
724     \a argv.
725
726     \warning The data referred to by \a argc and \a argv must stay valid for
727     the entire lifetime of the QApplication object. In addition, \a argc must
728     be greater than zero and \a argv must contain at least one valid character
729     string.
730
731     With Qt for Embedded Linux, passing QApplication::GuiServer for \a type
732     makes this application the server (equivalent to running with the
733     \c -qws option).
734 */
735 QApplication::QApplication(int &argc, char **argv, Type type)
736     : QApplicationBase(*new QApplicationPrivate(argc, argv, type, 0x040000))
737 { Q_D(QApplication); d->construct(); }
738
739 QApplication::QApplication(int &argc, char **argv, Type type , int _internal)
740     : QApplicationBase(*new QApplicationPrivate(argc, argv, type, _internal))
741 { Q_D(QApplication); d->construct(); }
742
743 #if defined(Q_WS_X11) && !defined(QT_NO_EGL)
744 static int qt_matchLibraryName(dl_phdr_info *info, size_t, void *data)
745 {
746     const char *name = static_cast<const char *>(data);
747     return strstr(info->dlpi_name, name) != 0;
748 }
749 #endif
750
751 /*!
752     \internal
753 */
754 void QApplicationPrivate::construct(
755 #ifdef Q_WS_X11
756                                     Display *dpy, Qt::HANDLE visual, Qt::HANDLE cmap
757 #endif
758                                     )
759 {
760     initResources();
761
762     qt_is_gui_used = (qt_appType != QApplication::Tty);
763     process_cmdline();
764
765     // Must be called before initialize()
766     qt_init(this, qt_appType
767 #ifdef Q_WS_X11
768             , dpy, visual, cmap
769 #endif
770             );
771     initialize();
772     eventDispatcher->startingUp();
773
774 #ifdef QT_EVAL
775     extern void qt_gui_eval_init(uint);
776     qt_gui_eval_init(application_type);
777 #endif
778
779 #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
780     symbianInit();
781 #endif
782
783 #ifndef QT_NO_LIBRARY
784     if(load_testability) {
785         QLibrary testLib(QLatin1String("qttestability"));
786         if (testLib.load()) {
787             typedef void (*TasInitialize)(void);
788             TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
789 #ifdef Q_OS_SYMBIAN
790             // resolving method by name does not work on Symbian OS so need to use ordinal
791             if(!initFunction) {
792                 initFunction = (TasInitialize)testLib.resolve("1");            
793             }
794 #endif
795             if (initFunction) {
796                 initFunction();
797             } else {
798                 qCritical("Library qttestability resolve failed!");
799             }
800         } else {
801             qCritical("Library qttestability load failed!");
802         }
803     }
804
805     //make sure the plugin is loaded
806     if (qt_is_gui_used)
807         qt_guiPlatformPlugin();
808 #endif
809 }
810
811 #if defined(Q_WS_X11)
812 // ### a string literal is a cont char*
813 // ### using it as a char* is wrong and could lead to segfaults
814 // ### if aargv is modified someday
815 // ########## make it work with argc == argv == 0
816 static int aargc = 1;
817 static char *aargv[] = { (char*)"unknown", 0 };
818
819 /*!
820     \fn QApplication::QApplication(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
821
822     Creates an application, given an already open display \a display. If
823     \a visual and \a colormap are non-zero, the application will use those
824     values as the default Visual and Colormap contexts.
825
826     \warning Qt only supports TrueColor visuals at depths higher than 8
827     bits-per-pixel.
828
829     This function is only available on X11.
830 */
831 QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap)
832     : QApplicationBase(*new QApplicationPrivate(aargc, aargv, GuiClient, 0x040000))
833 {
834     if (! dpy)
835         qWarning("QApplication: Invalid Display* argument");
836     Q_D(QApplication);
837     d->construct(dpy, visual, colormap);
838 }
839
840 QApplication::QApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
841     : QApplicationBase(*new QApplicationPrivate(aargc, aargv, GuiClient, _internal))
842 {
843     if (! dpy)
844         qWarning("QApplication: Invalid Display* argument");
845     Q_D(QApplication);
846     d->construct(dpy, visual, colormap);
847     QApplicationPrivate::app_compile_version = _internal;
848 }
849
850 /*!
851     \fn QApplication::QApplication(Display *display, int &argc, char **argv,
852         Qt::HANDLE visual, Qt::HANDLE colormap)
853
854     Creates an application, given an already open \a display and using \a argc
855     command line arguments in \a argv. If \a visual and \a colormap are
856     non-zero, the application will use those values as the default Visual
857     and Colormap contexts.
858
859     \warning Qt only supports TrueColor visuals at depths higher than 8
860     bits-per-pixel.
861
862     This function is only available on X11.
863 */
864 QApplication::QApplication(Display *dpy, int &argc, char **argv,
865                            Qt::HANDLE visual, Qt::HANDLE colormap)
866     : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, 0x040000))
867 {
868     if (! dpy)
869         qWarning("QApplication: Invalid Display* argument");
870     Q_D(QApplication);
871     d->construct(dpy, visual, colormap);
872 }
873
874 QApplication::QApplication(Display *dpy, int &argc, char **argv,
875                            Qt::HANDLE visual, Qt::HANDLE colormap, int _internal)
876     : QApplicationBase(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
877 {
878     if (! dpy)
879         qWarning("QApplication: Invalid Display* argument");
880     Q_D(QApplication);
881     d->construct(dpy, visual, colormap);
882     QApplicationPrivate::app_compile_version = _internal;
883 }
884
885 #endif // Q_WS_X11
886
887 #ifndef QT_NO_STATEMACHINE
888 extern int qRegisterGuiStateMachine();
889 extern int qUnregisterGuiStateMachine();
890 #endif
891
892 /*!
893   \fn void QApplicationPrivate::initialize()
894
895   Initializes the QApplication object, called from the constructors.
896 */
897 void QApplicationPrivate::initialize()
898 {
899     QWidgetPrivate::mapper = new QWidgetMapper;
900     QWidgetPrivate::allWidgets = new QWidgetSet;
901
902     if (qt_appType != QApplication::Tty)
903         (void) QApplication::style();  // trigger creation of application style
904 #ifndef QT_NO_STATEMACHINE
905     // trigger registering of QStateMachine's GUI types
906     qRegisterGuiStateMachine();
907 #endif
908
909     is_app_running = true; // no longer starting up
910
911     Q_Q(QApplication);
912 #ifndef QT_NO_SESSIONMANAGER
913     // connect to the session manager
914     session_manager = new QSessionManager(q, session_id, session_key);
915 #endif
916
917     if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0)
918         q->setAttribute(Qt::AA_NativeWindows);
919
920 #ifdef Q_WS_WINCE
921 #ifdef QT_AUTO_MAXIMIZE_THRESHOLD
922     autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD;
923 #else
924     if (qt_wince_is_mobile())
925         autoMaximizeThreshold = 50;
926     else
927         autoMaximizeThreshold = -1;
928 #endif //QT_AUTO_MAXIMIZE_THRESHOLD
929 #endif //Q_WS_WINCE
930
931 #ifndef QT_NO_WHEELEVENT
932     QApplicationPrivate::wheel_scroll_lines = 3;
933 #endif
934
935     if (qt_is_gui_used)
936         initializeMultitouch();
937 }
938
939 /*!
940     Returns the type of application (\l Tty, GuiClient, or
941     GuiServer). The type is set when constructing the QApplication
942     object.
943 */
944 QApplication::Type QApplication::type()
945 {
946     return qt_appType;
947 }
948
949 /*****************************************************************************
950   Functions returning the active popup and modal widgets.
951  *****************************************************************************/
952
953 /*!
954     Returns the active popup widget.
955
956     A popup widget is a special top-level widget that sets the \c
957     Qt::WType_Popup widget flag, e.g. the QMenu widget. When the application
958     opens a popup widget, all events are sent to the popup. Normal widgets and
959     modal widgets cannot be accessed before the popup widget is closed.
960
961     Only other popup widgets may be opened when a popup widget is shown. The
962     popup widgets are organized in a stack. This function returns the active
963     popup widget at the top of the stack.
964
965     \sa activeModalWidget(), topLevelWidgets()
966 */
967
968 QWidget *QApplication::activePopupWidget()
969 {
970     return QApplicationPrivate::popupWidgets && !QApplicationPrivate::popupWidgets->isEmpty() ?
971         QApplicationPrivate::popupWidgets->last() : 0;
972 }
973
974
975 /*!
976     Returns the active modal widget.
977
978     A modal widget is a special top-level widget which is a subclass of QDialog
979     that specifies the modal parameter of the constructor as true. A modal
980     widget must be closed before the user can continue with other parts of the
981     program.
982
983     Modal widgets are organized in a stack. This function returns the active
984     modal widget at the top of the stack.
985
986     \sa activePopupWidget(), topLevelWidgets()
987 */
988
989 QWidget *QApplication::activeModalWidget()
990 {
991     return qt_modal_stack && !qt_modal_stack->isEmpty() ? qt_modal_stack->first() : 0;
992 }
993
994 /*!
995     Cleans up any window system resources that were allocated by this
996     application. Sets the global variable \c qApp to 0.
997 */
998
999 QApplication::~QApplication()
1000 {
1001     Q_D(QApplication);
1002
1003 #if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
1004     // flush clipboard contents
1005     if (qt_clipboard) {
1006         QEvent event(QEvent::Clipboard);
1007         QApplication::sendEvent(qt_clipboard, &event);
1008     }
1009 #endif
1010
1011     //### this should probable be done even later
1012     qt_call_post_routines();
1013
1014     // kill timers before closing down the dispatcher
1015     d->toolTipWakeUp.stop();
1016     d->toolTipFallAsleep.stop();
1017
1018 #if !defined(Q_WS_QPA)
1019     d->eventDispatcher->closingDown();
1020     d->eventDispatcher = 0;
1021 #endif
1022     QApplicationPrivate::is_app_closing = true;
1023     QApplicationPrivate::is_app_running = false;
1024
1025     delete QWidgetPrivate::mapper;
1026     QWidgetPrivate::mapper = 0;
1027
1028     // delete all widgets
1029     if (QWidgetPrivate::allWidgets) {
1030         QWidgetSet *mySet = QWidgetPrivate::allWidgets;
1031         QWidgetPrivate::allWidgets = 0;
1032         for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
1033             register QWidget *w = *it;
1034             if (!w->parent())                        // window
1035                 w->destroy(true, true);
1036         }
1037         delete mySet;
1038     }
1039
1040     delete qt_desktopWidget;
1041     qt_desktopWidget = 0;
1042
1043 #if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
1044     delete qt_clipboard;
1045     qt_clipboard = 0;
1046 #endif
1047
1048 #if defined(Q_WS_X11) || defined(Q_WS_WIN)
1049     delete d->move_cursor; d->move_cursor = 0;
1050     delete d->copy_cursor; d->copy_cursor = 0;
1051     delete d->link_cursor; d->link_cursor = 0;
1052 #endif
1053 #if defined(Q_WS_WIN)
1054     delete d->ignore_cursor; d->ignore_cursor = 0;
1055 #endif
1056
1057     delete QApplicationPrivate::app_pal;
1058     QApplicationPrivate::app_pal = 0;
1059     delete QApplicationPrivate::sys_pal;
1060     QApplicationPrivate::sys_pal = 0;
1061     delete QApplicationPrivate::set_pal;
1062     QApplicationPrivate::set_pal = 0;
1063     app_palettes()->clear();
1064
1065 #ifndef Q_WS_QPA
1066     {
1067         QMutexLocker locker(applicationFontMutex());
1068         delete QApplicationPrivate::app_font;
1069         QApplicationPrivate::app_font = 0;
1070     }
1071 #endif
1072
1073     delete QApplicationPrivate::sys_font;
1074     QApplicationPrivate::sys_font = 0;
1075     delete QApplicationPrivate::set_font;
1076     QApplicationPrivate::set_font = 0;
1077     app_fonts()->clear();
1078
1079     delete QApplicationPrivate::app_style;
1080     QApplicationPrivate::app_style = 0;
1081     delete QApplicationPrivate::app_icon;
1082     QApplicationPrivate::app_icon = 0;
1083
1084 #ifndef QT_NO_DRAGANDDROP
1085     if (qt_is_gui_used)
1086         delete QDragManager::self();
1087 #endif
1088
1089     d->cleanupMultitouch();
1090
1091     qt_cleanup();
1092
1093     if (QApplicationPrivate::widgetCount)
1094         qDebug("Widgets left: %i    Max widgets: %i \n", QWidgetPrivate::instanceCounter, QWidgetPrivate::maxInstances);
1095 #ifndef QT_NO_SESSIONMANAGER
1096     delete d->session_manager;
1097     d->session_manager = 0;
1098 #endif //QT_NO_SESSIONMANAGER
1099
1100     QApplicationPrivate::obey_desktop_settings = true;
1101
1102     QApplicationPrivate::app_strut = QSize(0, 0);
1103     QApplicationPrivate::animate_ui = true;
1104     QApplicationPrivate::animate_menu = false;
1105     QApplicationPrivate::fade_menu = false;
1106     QApplicationPrivate::animate_combo = false;
1107     QApplicationPrivate::animate_tooltip = false;
1108     QApplicationPrivate::fade_tooltip = false;
1109     QApplicationPrivate::widgetCount = false;
1110
1111 #ifndef QT_NO_STATEMACHINE
1112     // trigger unregistering of QStateMachine's GUI types
1113     qUnregisterGuiStateMachine();
1114 #endif
1115 }
1116
1117
1118 /*!
1119     \fn QWidget *QApplication::widgetAt(const QPoint &point)
1120
1121     Returns the widget at global screen position \a point, or 0 if there is no
1122     Qt widget there.
1123
1124     This function can be slow.
1125
1126     \sa QCursor::pos(), QWidget::grabMouse(), QWidget::grabKeyboard()
1127 */
1128 QWidget *QApplication::widgetAt(const QPoint &p)
1129 {
1130     QWidget *window = QApplication::topLevelAt(p);
1131     if (!window)
1132         return 0;
1133
1134     QWidget *child = 0;
1135
1136     if (!window->testAttribute(Qt::WA_TransparentForMouseEvents))
1137         child = window->childAt(window->mapFromGlobal(p));
1138
1139     if (child)
1140         return child;
1141
1142     if (window->testAttribute(Qt::WA_TransparentForMouseEvents)) {
1143         //shoot a hole in the widget and try once again,
1144         //suboptimal on Qt for Embedded Linux where we do
1145         //know the stacking order of the toplevels.
1146         int x = p.x();
1147         int y = p.y();
1148         QRegion oldmask = window->mask();
1149         QPoint wpoint = window->mapFromGlobal(QPoint(x, y));
1150         QRegion newmask = (oldmask.isEmpty() ? QRegion(window->rect()) : oldmask)
1151                           - QRegion(wpoint.x(), wpoint.y(), 1, 1);
1152         window->setMask(newmask);
1153         QWidget *recurse = 0;
1154         if (QApplication::topLevelAt(p) != window) // verify recursion will terminate
1155             recurse = widgetAt(x, y);
1156         if (oldmask.isEmpty())
1157             window->clearMask();
1158         else
1159             window->setMask(oldmask);
1160         return recurse;
1161     }
1162     return window;
1163 }
1164
1165 /*!
1166     \fn QWidget *QApplication::widgetAt(int x, int y)
1167
1168     \overload
1169
1170     Returns the widget at global screen position (\a x, \a y), or 0 if there is
1171     no Qt widget there.
1172 */
1173
1174 /*!
1175     \fn void QApplication::setArgs(int argc, char **argv)
1176     \internal
1177 */
1178
1179
1180
1181 /*!
1182     \internal
1183 */
1184 bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1185 {
1186     if ((event->type() == QEvent::UpdateRequest
1187           || event->type() == QEvent::LayoutRequest
1188           || event->type() == QEvent::Resize
1189           || event->type() == QEvent::Move
1190           || event->type() == QEvent::LanguageChange
1191           || event->type() == QEvent::UpdateSoftKeys
1192           || event->type() == QEvent::InputMethod)) {
1193         for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) {
1194             const QPostEvent &cur = *it;
1195             if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type())
1196                 continue;
1197             if (cur.event->type() == QEvent::LayoutRequest
1198                  || cur.event->type() == QEvent::UpdateRequest) {
1199                 ;
1200             } else if (cur.event->type() == QEvent::Resize) {
1201                 ((QResizeEvent *)(cur.event))->s = ((QResizeEvent *)event)->s;
1202             } else if (cur.event->type() == QEvent::Move) {
1203                 ((QMoveEvent *)(cur.event))->p = ((QMoveEvent *)event)->p;
1204             } else if (cur.event->type() == QEvent::LanguageChange) {
1205                 ;
1206             } else if (cur.event->type() == QEvent::UpdateSoftKeys) {
1207                 ;
1208             } else if ( cur.event->type() == QEvent::InputMethod ) {
1209                 *(QInputMethodEvent *)(cur.event) = *(QInputMethodEvent *)event;
1210             } else {
1211                 continue;
1212             }
1213             delete event;
1214             return true;
1215         }
1216         return false;
1217     }
1218     return QApplicationBase::compressEvent(event, receiver, postedEvents);
1219 }
1220
1221 /*!
1222     \property QApplication::styleSheet
1223     \brief the application style sheet
1224     \since 4.2
1225
1226     By default, this property returns an empty string unless the user specifies
1227     the \c{-stylesheet} option on the command line when running the application.
1228
1229     \sa QWidget::setStyle(), {Qt Style Sheets}
1230 */
1231
1232 /*!
1233     \property QApplication::autoMaximizeThreshold
1234     \since 4.4
1235     \brief defines a threshold for auto maximizing widgets
1236
1237     \bold{The auto maximize threshold is only available as part of Qt for
1238     Windows CE.}
1239
1240     This property defines a threshold for the size of a window as a percentage
1241     of the screen size. If the minimum size hint of a window exceeds the
1242     threshold, calling show() will cause the window to be maximized
1243     automatically.
1244
1245     Setting the threshold to 100 or greater means that the widget will always
1246     be maximized. Alternatively, setting the threshold to 50 means that the
1247     widget will be maximized only if the vertical minimum size hint is at least
1248     50% of the vertical screen size.
1249
1250     Setting the threshold to -1 disables the feature.
1251
1252     On Windows CE the default is -1 (i.e., it is disabled).
1253     On Windows Mobile the default is 40.
1254 */
1255
1256 /*!
1257     \property QApplication::autoSipEnabled
1258     \since 4.5
1259     \brief toggles automatic SIP (software input panel) visibility
1260
1261     Set this property to \c true to automatically display the SIP when entering
1262     widgets that accept keyboard input. This property only affects widgets with
1263     the WA_InputMethodEnabled attribute set, and is typically used to launch
1264     a virtual keyboard on devices which have very few or no keys.
1265
1266     \bold{ The property only has an effect on platforms which use software input
1267     panels, such as Windows CE and Symbian.}
1268
1269     The default is platform dependent.
1270 */
1271
1272 #ifdef Q_WS_WINCE
1273 void QApplication::setAutoMaximizeThreshold(const int threshold)
1274 {
1275     QApplicationPrivate::autoMaximizeThreshold = threshold;
1276 }
1277
1278 int QApplication::autoMaximizeThreshold() const
1279 {
1280     return QApplicationPrivate::autoMaximizeThreshold;
1281 }
1282 #endif
1283
1284 void QApplication::setAutoSipEnabled(const bool enabled)
1285 {
1286     QApplicationPrivate::autoSipEnabled = enabled;
1287 }
1288
1289 bool QApplication::autoSipEnabled() const
1290 {
1291     return QApplicationPrivate::autoSipEnabled;
1292 }
1293
1294 #ifndef QT_NO_STYLE_STYLESHEET
1295
1296 QString QApplication::styleSheet() const
1297 {
1298     return QApplicationPrivate::styleSheet;
1299 }
1300
1301 void QApplication::setStyleSheet(const QString& styleSheet)
1302 {
1303     QApplicationPrivate::styleSheet = styleSheet;
1304     QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
1305     if (styleSheet.isEmpty()) { // application style sheet removed
1306         if (!proxy)
1307             return; // there was no stylesheet before
1308         setStyle(proxy->base);
1309     } else if (proxy) { // style sheet update, just repolish
1310         proxy->repolish(qApp);
1311     } else { // stylesheet set the first time
1312         QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
1313         QApplicationPrivate::app_style->setParent(newProxy);
1314         setStyle(newProxy);
1315     }
1316 }
1317
1318 #endif // QT_NO_STYLE_STYLESHEET
1319
1320 /*!
1321     Returns the application's style object.
1322
1323     \sa setStyle(), QStyle
1324 */
1325 QStyle *QApplication::style()
1326 {
1327     if (QApplicationPrivate::app_style)
1328         return QApplicationPrivate::app_style;
1329     if (!qt_is_gui_used) {
1330         Q_ASSERT(!"No style available in non-gui applications!");
1331         return 0;
1332     }
1333
1334     if (!QApplicationPrivate::app_style) {
1335         // Compile-time search for default style
1336         //
1337         QString style;
1338 #ifdef QT_BUILD_INTERNAL
1339         QString envStyle = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
1340 #else
1341         QString envStyle;
1342 #endif
1343         if (!QApplicationPrivate::styleOverride.isEmpty()) {
1344             style = QApplicationPrivate::styleOverride;
1345         } else if (!envStyle.isEmpty()) {
1346             style = envStyle;
1347         } else {
1348             style = QApplicationPrivate::desktopStyleKey();
1349         }
1350
1351         QStyle *&app_style = QApplicationPrivate::app_style;
1352         app_style = QStyleFactory::create(style);
1353         if (!app_style) {
1354             QStringList styles = QStyleFactory::keys();
1355             for (int i = 0; i < styles.size(); ++i) {
1356                 if ((app_style = QStyleFactory::create(styles.at(i))))
1357                     break;
1358             }
1359         }
1360         if (!app_style) {
1361             Q_ASSERT(!"No styles available!");
1362             return 0;
1363         }
1364     }
1365     // take ownership of the style
1366     QApplicationPrivate::app_style->setParent(qApp);
1367
1368     if (!QApplicationPrivate::sys_pal)
1369         QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
1370     if (QApplicationPrivate::set_pal) // repolish set palette with the new style
1371         QApplication::setPalette(*QApplicationPrivate::set_pal);
1372
1373 #ifndef QT_NO_STYLE_STYLESHEET
1374     if (!QApplicationPrivate::styleSheet.isEmpty()) {
1375         qApp->setStyleSheet(QApplicationPrivate::styleSheet);
1376     } else
1377 #endif
1378         QApplicationPrivate::app_style->polish(qApp);
1379
1380     return QApplicationPrivate::app_style;
1381 }
1382
1383 /*!
1384     Sets the application's GUI style to \a style. Ownership of the style object
1385     is transferred to QApplication, so QApplication will delete the style
1386     object on application exit or when a new style is set and the old style is
1387     still the parent of the application object.
1388
1389     Example usage:
1390     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 1
1391
1392     When switching application styles, the color palette is set back to the
1393     initial colors or the system defaults. This is necessary since certain
1394     styles have to adapt the color palette to be fully style-guide compliant.
1395
1396     Setting the style before a palette has been se, i.e., before creating
1397     QApplication, will cause the application to use QStyle::standardPalette()
1398     for the palette.
1399
1400     \warning Qt style sheets are currently not supported for custom QStyle
1401     subclasses. We plan to address this in some future release.
1402
1403     \sa style(), QStyle, setPalette(), desktopSettingsAware()
1404 */
1405 void QApplication::setStyle(QStyle *style)
1406 {
1407     if (!style || style == QApplicationPrivate::app_style)
1408         return;
1409
1410     QWidgetList all = allWidgets();
1411
1412     // clean up the old style
1413     if (QApplicationPrivate::app_style) {
1414         if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1415             for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
1416                 register QWidget *w = *it;
1417                 if (!(w->windowType() == Qt::Desktop) &&        // except desktop
1418                      w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
1419                     QApplicationPrivate::app_style->unpolish(w);
1420                 }
1421             }
1422         }
1423         QApplicationPrivate::app_style->unpolish(qApp);
1424     }
1425
1426     QStyle *old = QApplicationPrivate::app_style; // save
1427
1428 #ifndef QT_NO_STYLE_STYLESHEET
1429     if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
1430         // we have a stylesheet already and a new style is being set
1431         QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
1432         style->setParent(newProxy);
1433         QApplicationPrivate::app_style = newProxy;
1434     } else
1435 #endif // QT_NO_STYLE_STYLESHEET
1436         QApplicationPrivate::app_style = style;
1437     QApplicationPrivate::app_style->setParent(qApp); // take ownership
1438
1439     // take care of possible palette requirements of certain gui
1440     // styles. Do it before polishing the application since the style
1441     // might call QApplication::setPalette() itself
1442     if (QApplicationPrivate::set_pal) {
1443         QApplication::setPalette(*QApplicationPrivate::set_pal);
1444     } else if (QApplicationPrivate::sys_pal) {
1445         QApplicationPrivate::initializeWidgetPaletteHash();
1446         QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
1447     } else if (!QApplicationPrivate::sys_pal) {
1448         // Initialize the sys_pal if it hasn't happened yet...
1449         QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
1450     }
1451
1452     // initialize the application with the new style
1453     QApplicationPrivate::app_style->polish(qApp);
1454
1455     // re-polish existing widgets if necessary
1456     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1457         for (QWidgetList::ConstIterator it1 = all.constBegin(); it1 != all.constEnd(); ++it1) {
1458             register QWidget *w = *it1;
1459             if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
1460                 if (w->style() == QApplicationPrivate::app_style)
1461                     QApplicationPrivate::app_style->polish(w);                // repolish
1462 #ifndef QT_NO_STYLE_STYLESHEET
1463                 else
1464                     w->setStyleSheet(w->styleSheet()); // touch
1465 #endif
1466             }
1467         }
1468
1469         for (QWidgetList::ConstIterator it2 = all.constBegin(); it2 != all.constEnd(); ++it2) {
1470             register QWidget *w = *it2;
1471             if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
1472                     QEvent e(QEvent::StyleChange);
1473                     QApplication::sendEvent(w, &e);
1474                     w->update();
1475             }
1476         }
1477     }
1478
1479 #ifndef QT_NO_STYLE_STYLESHEET
1480     if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
1481         oldProxy->deref();
1482     } else
1483 #endif
1484     if (old && old->parent() == qApp) {
1485         delete old;
1486     }
1487
1488     if (QApplicationPrivate::focus_widget) {
1489         QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
1490         QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
1491         QApplicationPrivate::focus_widget->update();
1492     }
1493 }
1494
1495 /*!
1496     \overload
1497
1498     Requests a QStyle object for \a style from the QStyleFactory.
1499
1500     The string must be one of the QStyleFactory::keys(), typically one of
1501     "windows", "motif", "cde", "plastique", "windowsxp", or "macintosh". Style
1502     names are case insensitive.
1503
1504     Returns 0 if an unknown \a style is passed, otherwise the QStyle object
1505     returned is set as the application's GUI style.
1506
1507     \warning To ensure that the application's style is set correctly, it is
1508     best to call this function before the QApplication constructor, if
1509     possible.
1510 */
1511 QStyle* QApplication::setStyle(const QString& style)
1512 {
1513     QStyle *s = QStyleFactory::create(style);
1514     if (!s)
1515         return 0;
1516
1517     setStyle(s);
1518     return s;
1519 }
1520
1521 /*!
1522     Returns the color specification.
1523
1524     \sa QApplication::setColorSpec()
1525 */
1526
1527 int QApplication::colorSpec()
1528 {
1529     return QApplicationPrivate::app_cspec;
1530 }
1531
1532 /*!
1533     Sets the color specification for the application to \a spec.
1534
1535     The color specification controls how the application allocates colors when
1536     run on a display with a limited amount of colors, e.g. 8 bit / 256 color
1537     displays.
1538
1539     The color specification must be set before you create the QApplication
1540     object.
1541
1542     The options are:
1543     \list
1544         \o  QApplication::NormalColor. This is the default color allocation
1545             strategy. Use this option if your application uses buttons, menus,
1546             texts and pixmaps with few colors. With this option, the
1547             application uses system global colors. This works fine for most
1548             applications under X11, but on the Windows platform, it may cause
1549             dithering of non-standard colors.
1550         \o  QApplication::CustomColor. Use this option if your application
1551             needs a small number of custom colors. On X11, this option is the
1552             same as NormalColor. On Windows, Qt creates a Windows palette, and
1553             allocates colors to it on demand.
1554         \o  QApplication::ManyColor. Use this option if your application is
1555             very color hungry, e.g., it requires thousands of colors. \br
1556             Under X11 the effect is:
1557             \list
1558                 \o  For 256-color displays which have at best a 256 color true
1559                     color visual, the default visual is used, and colors are
1560                     allocated from a color cube. The color cube is the 6x6x6
1561                     (216 color) "Web palette" (the red, green, and blue
1562                     components always have one of the following values: 0x00,
1563                     0x33, 0x66, 0x99, 0xCC, or 0xFF), but the number of colors
1564                     can be changed by the \e -ncols option. The user can force
1565                     the application to use the true color visual with the
1566                     \l{QApplication::QApplication()}{-visual} option.
1567                 \o  For 256-color displays which have a true color visual with
1568                     more than 256 colors, use that visual. Silicon Graphics X
1569                     servers this feature, for example. They provide an 8 bit
1570                     visual by default but can deliver true color when asked.
1571             \endlist
1572             On Windows, Qt creates a Windows palette, and fills it with a color
1573             cube.
1574     \endlist
1575
1576     Be aware that the CustomColor and ManyColor choices may lead to colormap
1577     flashing: The foreground application gets (most) of the available colors,
1578     while the background windows will look less attractive.
1579
1580     Example:
1581
1582     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 2
1583
1584     \sa colorSpec()
1585 */
1586
1587 void QApplication::setColorSpec(int spec)
1588 {
1589     if (qApp)
1590         qWarning("QApplication::setColorSpec: This function must be "
1591                  "called before the QApplication object is created");
1592     QApplicationPrivate::app_cspec = spec;
1593 }
1594
1595 /*!
1596     \property QApplication::globalStrut
1597     \brief the minimum size that any GUI element that the user can interact
1598            with should have
1599
1600     For example, no button should be resized to be smaller than the global
1601     strut size. The strut size should be considered when reimplementing GUI
1602     controls that may be used on touch-screens or similar I/O devices.
1603
1604     Example:
1605
1606     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 3
1607
1608     By default, this property contains a QSize object with zero width and height.
1609 */
1610 QSize QApplication::globalStrut()
1611 {
1612     return QApplicationPrivate::app_strut;
1613 }
1614
1615 void QApplication::setGlobalStrut(const QSize& strut)
1616 {
1617     QApplicationPrivate::app_strut = strut;
1618 }
1619
1620
1621 /*!
1622     \fn QPalette QApplication::palette(const QWidget* widget)
1623     \overload
1624
1625     If a \a widget is passed, the default palette for the widget's class is
1626     returned. This may or may not be the application palette. In most cases
1627     there is no special palette for certain types of widgets, but one notable
1628     exception is the popup menu under Windows, if the user has defined a
1629     special background color for menus in the display settings.
1630
1631     \sa setPalette(), QWidget::palette()
1632 */
1633 QPalette QApplication::palette(const QWidget* w)
1634 {
1635     PaletteHash *hash = app_palettes();
1636     if (w && hash && hash->size()) {
1637         QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(w->metaObject()->className());
1638         if (it != hash->constEnd())
1639             return *it;
1640         for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
1641             if (w->inherits(it.key()))
1642                 return it.value();
1643         }
1644     }
1645     return palette();
1646 }
1647
1648 /*!
1649     \overload
1650
1651     Returns the palette for widgets of the given \a className.
1652
1653     \sa setPalette(), QWidget::palette()
1654 */
1655 QPalette QApplication::palette(const char *className)
1656 {
1657     if (!QApplicationPrivate::app_pal)
1658         palette();
1659     PaletteHash *hash = app_palettes();
1660     if (className && hash && hash->size()) {
1661         QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(className);
1662         if (it != hash->constEnd())
1663             return *it;
1664     }
1665     return *QApplicationPrivate::app_pal;
1666 }
1667
1668 void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash)
1669 {
1670     QPalette pal = palette;
1671
1672     if (QApplicationPrivate::app_style)
1673         QApplicationPrivate::app_style->polish(pal); // NB: non-const reference
1674
1675     bool all = false;
1676     PaletteHash *hash = app_palettes();
1677     if (!className) {
1678         if (QApplicationPrivate::app_pal && pal.isCopyOf(*QApplicationPrivate::app_pal))
1679             return;
1680         if (!QApplicationPrivate::app_pal)
1681             QApplicationPrivate::app_pal = new QPalette(pal);
1682         else
1683             *QApplicationPrivate::app_pal = pal;
1684         if (hash && hash->size()) {
1685             all = true;
1686             if (clearWidgetPaletteHash)
1687                 hash->clear();
1688         }
1689     } else if (hash) {
1690         hash->insert(className, pal);
1691     }
1692
1693     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1694         // Send ApplicationPaletteChange to qApp itself, and to the widgets.
1695         QEvent e(QEvent::ApplicationPaletteChange);
1696         QApplication::sendEvent(QApplication::instance(), &e);
1697
1698         QWidgetList wids = QApplication::allWidgets();
1699         for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
1700             register QWidget *w = *it;
1701             if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
1702                 QApplication::sendEvent(w, &e);
1703         }
1704
1705         // Send to all scenes as well.
1706 #ifndef QT_NO_GRAPHICSVIEW
1707         QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
1708         for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
1709              it != scenes.constEnd(); ++it) {
1710             QApplication::sendEvent(*it, &e);
1711         }
1712 #endif //QT_NO_GRAPHICSVIEW
1713     }
1714     if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) {
1715         if (!QApplicationPrivate::set_pal)
1716             QApplicationPrivate::set_pal = new QPalette(palette);
1717         else
1718             *QApplicationPrivate::set_pal = palette;
1719     }
1720 }
1721
1722 /*!
1723     Changes the default application palette to \a palette.
1724
1725     If \a className is passed, the change applies only to widgets that inherit
1726     \a className (as reported by QObject::inherits()). If \a className is left
1727     0, the change affects all widgets, thus overriding any previously set class
1728     specific palettes.
1729
1730     The palette may be changed according to the current GUI style in
1731     QStyle::polish().
1732
1733     \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
1734     When using style sheets, the palette of a widget can be customized using
1735     the "color", "background-color", "selection-color",
1736     "selection-background-color" and "alternate-background-color".
1737
1738     \note Some styles do not use the palette for all drawing, for instance, if
1739     they make use of native theme engines. This is the case for the Windows XP,
1740     Windows Vista, and Mac OS X styles.
1741
1742     \sa QWidget::setPalette(), palette(), QStyle::polish()
1743 */
1744
1745 void QApplication::setPalette(const QPalette &palette, const char* className)
1746 {
1747     QApplicationPrivate::setPalette_helper(palette, className, /*clearWidgetPaletteHash=*/ true);
1748 }
1749
1750
1751
1752 void QApplicationPrivate::setSystemPalette(const QPalette &pal)
1753 {
1754     QPalette adjusted;
1755
1756 #if 0
1757     // adjust the system palette to avoid dithering
1758     QColormap cmap = QColormap::instance();
1759     if (cmap.depths() > 4 && cmap.depths() < 24) {
1760         for (int g = 0; g < QPalette::NColorGroups; g++)
1761             for (int i = 0; i < QPalette::NColorRoles; i++) {
1762                 QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
1763                 color = cmap.colorAt(cmap.pixel(color));
1764                 adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
1765             }
1766     }
1767 #else
1768     adjusted = pal;
1769 #endif
1770
1771     if (!sys_pal)
1772         sys_pal = new QPalette(adjusted);
1773     else
1774         *sys_pal = adjusted;
1775
1776
1777     if (!QApplicationPrivate::set_pal)
1778         QApplication::setPalette(*sys_pal);
1779 }
1780
1781 /*!
1782     Returns the default application font.
1783
1784     \sa fontMetrics(), QWidget::font()
1785 */
1786 QFont QApplication::font()
1787 {
1788 #ifndef Q_WS_QPA
1789     QMutexLocker locker(applicationFontMutex());
1790     if (!QApplicationPrivate::app_font)
1791         QApplicationPrivate::app_font = new QFont(QLatin1String("Helvetica"));
1792     return *QApplicationPrivate::app_font;
1793 #else
1794     return QGuiApplication::font();
1795 #endif
1796 }
1797
1798 /*!
1799     \overload
1800
1801     Returns the default font for the \a widget.
1802
1803     \sa fontMetrics(), QWidget::setFont()
1804 */
1805
1806 QFont QApplication::font(const QWidget *widget)
1807 {
1808     FontHash *hash = app_fonts();
1809
1810 #ifdef Q_WS_MAC
1811     // short circuit for small and mini controls
1812     if (widget->testAttribute(Qt::WA_MacSmallSize)) {
1813         return hash->value("QSmallFont");
1814     } else if (widget->testAttribute(Qt::WA_MacMiniSize)) {
1815         return hash->value("QMiniFont");
1816     }
1817 #endif
1818     if (widget && hash  && hash->size()) {
1819         QHash<QByteArray, QFont>::ConstIterator it =
1820                 hash->constFind(widget->metaObject()->className());
1821         if (it != hash->constEnd())
1822             return it.value();
1823         for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
1824             if (widget->inherits(it.key()))
1825                 return it.value();
1826         }
1827     }
1828     return font();
1829 }
1830
1831 /*!
1832     \overload
1833
1834     Returns the font for widgets of the given \a className.
1835
1836     \sa setFont(), QWidget::font()
1837 */
1838 QFont QApplication::font(const char *className)
1839 {
1840     FontHash *hash = app_fonts();
1841     if (className && hash && hash->size()) {
1842         QHash<QByteArray, QFont>::ConstIterator it = hash->constFind(className);
1843         if (it != hash->constEnd())
1844             return *it;
1845     }
1846     return font();
1847 }
1848
1849
1850 /*!
1851     Changes the default application font to \a font. If \a className is passed,
1852     the change applies only to classes that inherit \a className (as reported
1853     by QObject::inherits()).
1854
1855     On application start-up, the default font depends on the window system. It
1856     can vary depending on both the window system version and the locale. This
1857     function lets you override the default font; but overriding may be a bad
1858     idea because, for example, some locales need extra large fonts to support
1859     their special characters.
1860
1861     \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
1862     The font of an application can be customized using the "font" style sheet
1863     property. To set a bold font for all QPushButtons, set the application
1864     styleSheet() as "QPushButton { font: bold }"
1865
1866     \sa font(), fontMetrics(), QWidget::setFont()
1867 */
1868
1869 void QApplication::setFont(const QFont &font, const char *className)
1870 {
1871     bool all = false;
1872     FontHash *hash = app_fonts();
1873     if (!className) {
1874 #ifndef Q_WS_QPA
1875         QMutexLocker locker(applicationFontMutex());
1876         if (!QApplicationPrivate::app_font)
1877             QApplicationPrivate::app_font = new QFont(font);
1878         else
1879             *QApplicationPrivate::app_font = font;
1880 #else
1881         QGuiApplication::setFont(font);
1882 #endif
1883         if (hash && hash->size()) {
1884             all = true;
1885             hash->clear();
1886         }
1887     } else if (hash) {
1888         hash->insert(className, font);
1889     }
1890     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1891         // Send ApplicationFontChange to qApp itself, and to the widgets.
1892         QEvent e(QEvent::ApplicationFontChange);
1893         QApplication::sendEvent(QApplication::instance(), &e);
1894
1895         QWidgetList wids = QApplication::allWidgets();
1896         for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
1897             register QWidget *w = *it;
1898             if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
1899                 sendEvent(w, &e);
1900         }
1901
1902 #ifndef QT_NO_GRAPHICSVIEW
1903         // Send to all scenes as well.
1904         QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
1905         for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
1906              it != scenes.constEnd(); ++it) {
1907             QApplication::sendEvent(*it, &e);
1908         }
1909 #endif //QT_NO_GRAPHICSVIEW
1910     }
1911     if (!className && (!QApplicationPrivate::sys_font || !font.isCopyOf(*QApplicationPrivate::sys_font))) {
1912         if (!QApplicationPrivate::set_font)
1913             QApplicationPrivate::set_font = new QFont(font);
1914         else
1915             *QApplicationPrivate::set_font = font;
1916     }
1917 }
1918
1919 /*! \internal
1920 */
1921 void QApplicationPrivate::setSystemFont(const QFont &font)
1922 {
1923      if (!sys_font)
1924         sys_font = new QFont(font);
1925     else
1926         *sys_font = font;
1927
1928     if (!QApplicationPrivate::set_font)
1929         QApplication::setFont(*sys_font);
1930 }
1931
1932 /*! \internal
1933 */
1934 QString QApplicationPrivate::desktopStyleKey()
1935 {
1936     return qt_guiPlatformPlugin()->styleName();
1937 }
1938
1939 /*!
1940     \property QApplication::windowIcon
1941     \brief the default window icon
1942
1943     \sa QWidget::setWindowIcon(), {Setting the Application Icon}
1944 */
1945 QIcon QApplication::windowIcon()
1946 {
1947     return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
1948 }
1949
1950 void QApplication::setWindowIcon(const QIcon &icon)
1951 {
1952     if (!QApplicationPrivate::app_icon)
1953         QApplicationPrivate::app_icon = new QIcon();
1954     *QApplicationPrivate::app_icon = icon;
1955     if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
1956 #ifdef Q_WS_MAC
1957         void qt_mac_set_app_icon(const QPixmap &); //qapplication_mac.cpp
1958         QSize size = QApplicationPrivate::app_icon->actualSize(QSize(128, 128));
1959         qt_mac_set_app_icon(QApplicationPrivate::app_icon->pixmap(size));
1960 #endif
1961         QEvent e(QEvent::ApplicationWindowIconChange);
1962         QWidgetList all = QApplication::allWidgets();
1963         for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
1964             register QWidget *w = *it;
1965             if (w->isWindow())
1966                 sendEvent(w, &e);
1967         }
1968     }
1969 }
1970
1971 /*!
1972     Returns a list of the top-level widgets (windows) in the application.
1973
1974     \note Some of the top-level widgets may be hidden, for example a tooltip if
1975     no tooltip is currently shown.
1976
1977     Example:
1978
1979     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 4
1980
1981     \sa allWidgets(), QWidget::isWindow(), QWidget::isHidden()
1982 */
1983 QWidgetList QApplication::topLevelWidgets()
1984 {
1985     QWidgetList list;
1986     QWidgetList all = allWidgets();
1987
1988     for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
1989         QWidget *w = *it;
1990         if (w->isWindow() && w->windowType() != Qt::Desktop)
1991             list.append(w);
1992     }
1993     return list;
1994 }
1995
1996 /*!
1997     Returns a list of all the widgets in the application.
1998
1999     The list is empty (QList::isEmpty()) if there are no widgets.
2000
2001     \note Some of the widgets may be hidden.
2002
2003     Example:
2004     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 5
2005
2006     \sa topLevelWidgets(), QWidget::isVisible()
2007 */
2008
2009 QWidgetList QApplication::allWidgets()
2010 {
2011     if (QWidgetPrivate::allWidgets)
2012         return QWidgetPrivate::allWidgets->toList();
2013     return QWidgetList();
2014 }
2015
2016 /*!
2017     Returns the application widget that has the keyboard input focus, or 0 if
2018     no widget in this application has the focus.
2019
2020     \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged()
2021 */
2022
2023 QWidget *QApplication::focusWidget()
2024 {
2025     return QApplicationPrivate::focus_widget;
2026 }
2027
2028 void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
2029 {
2030 #ifndef QT_NO_GRAPHICSVIEW
2031     if (focus && focus->window()->graphicsProxyWidget())
2032         return;
2033 #endif
2034
2035     hidden_focus_widget = 0;
2036
2037     if (focus != focus_widget) {
2038         if (focus && focus->isHidden()) {
2039             hidden_focus_widget = focus;
2040             return;
2041         }
2042
2043         if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
2044             && qt_in_tab_key_event)
2045             focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
2046         else if (focus && reason == Qt::ShortcutFocusReason) {
2047             focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
2048         }
2049         QWidget *prev = focus_widget;
2050         focus_widget = focus;
2051 #ifndef QT_NO_IM
2052         if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason
2053                       && prev->testAttribute(Qt::WA_InputMethodEnabled))
2054                      // Do reset the input context, in case the new focus widget won't accept keyboard input
2055                      // or it is not created fully yet.
2056                      || (focus_widget && (!focus_widget->testAttribute(Qt::WA_InputMethodEnabled)
2057                                           || !focus_widget->testAttribute(Qt::WA_WState_Created))))) {
2058             qApp->inputPanel()->commit();
2059             qApp->inputPanel()->setInputItem(0);
2060         }
2061 #endif //QT_NO_IM
2062
2063         if(focus_widget)
2064             focus_widget->d_func()->setFocus_sys();
2065
2066         if (reason != Qt::NoFocusReason) {
2067
2068             //send events
2069             if (prev) {
2070 #ifdef QT_KEYPAD_NAVIGATION
2071                 if (QApplication::keypadNavigationEnabled()) {
2072                     if (prev->hasEditFocus() && reason != Qt::PopupFocusReason
2073 #ifdef Q_OS_SYMBIAN
2074                             && reason != Qt::ActiveWindowFocusReason
2075 #endif
2076                             )
2077                         prev->setEditFocus(false);
2078                 }
2079 #endif
2080                 QFocusEvent out(QEvent::FocusOut, reason);
2081                 QPointer<QWidget> that = prev;
2082                 QApplication::sendEvent(prev, &out);
2083                 if (that)
2084                     QApplication::sendEvent(that->style(), &out);
2085             }
2086             if(focus && QApplicationPrivate::focus_widget == focus) {
2087 #ifndef QT_NO_IM
2088                 if (focus->testAttribute(Qt::WA_InputMethodEnabled)
2089                     && focus->testAttribute(Qt::WA_WState_Created)
2090                     && focus->isEnabled()) {
2091                     qApp->inputPanel()->setInputItem(focus);
2092                 }
2093 #endif //QT_NO_IM
2094                 QFocusEvent in(QEvent::FocusIn, reason);
2095                 QPointer<QWidget> that = focus;
2096                 QApplication::sendEvent(focus, &in);
2097                 if (that)
2098                     QApplication::sendEvent(that->style(), &in);
2099             }
2100             emit qApp->focusChanged(prev, focus_widget);
2101         }
2102     }
2103 }
2104
2105
2106 /*!
2107     Returns the application top-level window that has the keyboard input focus,
2108     or 0 if no application window has the focus. There might be an
2109     activeWindow() even if there is no focusWidget(), for example if no widget
2110     in that window accepts key events.
2111
2112     \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
2113 */
2114
2115 QWidget *QApplication::activeWindow()
2116 {
2117     return QApplicationPrivate::active_window;
2118 }
2119
2120 /*!
2121     Returns display (screen) font metrics for the application font.
2122
2123     \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
2124 */
2125
2126 QFontMetrics QApplication::fontMetrics()
2127 {
2128     return desktop()->fontMetrics();
2129 }
2130
2131
2132 /*!
2133     Closes all top-level windows.
2134
2135     This function is particularly useful for applications with many top-level
2136     windows. It could, for example, be connected to a \gui{Exit} entry in the
2137     \gui{File} menu:
2138
2139     \snippet examples/mainwindows/mdi/mainwindow.cpp 0
2140
2141     The windows are closed in random order, until one window does not accept
2142     the close event. The application quits when the last window was
2143     successfully closed; this can be turned off by setting
2144     \l quitOnLastWindowClosed to false.
2145
2146     \sa quitOnLastWindowClosed, lastWindowClosed(), QWidget::close(),
2147     QWidget::closeEvent(), lastWindowClosed(), quit(), topLevelWidgets(),
2148     QWidget::isWindow()
2149 */
2150 void QApplication::closeAllWindows()
2151 {
2152     bool did_close = true;
2153     QWidget *w;
2154     while ((w = activeModalWidget()) && did_close) {
2155         if (!w->isVisible() || w->data->is_closing)
2156             break;
2157         did_close = w->close();
2158     }
2159     QWidgetList list = QApplication::topLevelWidgets();
2160     for (int i = 0; did_close && i < list.size(); ++i) {
2161         w = list.at(i);
2162         if (w->isVisible()
2163             && w->windowType() != Qt::Desktop
2164             && !w->data->is_closing) {
2165             did_close = w->close();
2166             list = QApplication::topLevelWidgets();
2167             i = -1;
2168         }
2169     }
2170 }
2171
2172 /*!
2173     Displays a simple message box about Qt. The message includes the version
2174     number of Qt being used by the application.
2175
2176     This is useful for inclusion in the \gui Help menu of an application, as
2177     shown in the \l{mainwindows/menus}{Menus} example.
2178
2179     This function is a convenience slot for QMessageBox::aboutQt().
2180 */
2181 void QApplication::aboutQt()
2182 {
2183 #ifndef QT_NO_MESSAGEBOX
2184     QMessageBox::aboutQt(
2185 #ifdef Q_WS_MAC
2186             0
2187 #else
2188             activeWindow()
2189 #endif // Q_WS_MAC
2190             );
2191 #endif // QT_NO_MESSAGEBOX
2192 }
2193
2194
2195 /*!
2196     \fn void QApplication::lastWindowClosed()
2197
2198     This signal is emitted from QApplication::exec() when the last visible
2199     primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
2200     attribute set is closed.
2201
2202     By default,
2203
2204     \list
2205         \o  this attribute is set for all widgets except transient windows such
2206             as splash screens, tool windows, and popup menus
2207
2208         \o  QApplication implicitly quits when this signal is emitted.
2209     \endlist
2210
2211     This feature can be turned off by setting \l quitOnLastWindowClosed to
2212     false.
2213
2214     \sa QWidget::close()
2215 */
2216
2217 /*!
2218     \since 4.1
2219     \fn void QApplication::focusChanged(QWidget *old, QWidget *now)
2220
2221     This signal is emitted when the widget that has keyboard focus changed from
2222     \a old to \a now, i.e., because the user pressed the tab-key, clicked into
2223     a widget or changed the active window. Both \a old and \a now can be the
2224     null-pointer.
2225
2226     The signal is emitted after both widget have been notified about the change
2227     through QFocusEvent.
2228
2229     \sa QWidget::setFocus(), QWidget::clearFocus(), Qt::FocusReason
2230 */
2231
2232 /*!\reimp
2233
2234 */
2235 bool QApplication::event(QEvent *e)
2236 {
2237     Q_D(QApplication);
2238     if(e->type() == QEvent::Close) {
2239 #if defined(Q_OS_SYMBIAN)
2240         // In order to have proper application-exit effects on Symbian, certain
2241         // native APIs have to be called _before_ closing/destroying the widgets.
2242         bool effectStarted = qt_beginFullScreenEffect();
2243 #endif
2244         QCloseEvent *ce = static_cast<QCloseEvent*>(e);
2245         ce->accept();
2246         closeAllWindows();
2247
2248         QWidgetList list = topLevelWidgets();
2249         for (int i = 0; i < list.size(); ++i) {
2250             QWidget *w = list.at(i);
2251             if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
2252                  (!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
2253                 ce->ignore();
2254                 break;
2255             }
2256         }
2257         if (ce->isAccepted()) {
2258             return true;
2259         } else {
2260 #if defined(Q_OS_SYMBIAN)
2261             if (effectStarted)
2262                 qt_abortFullScreenEffect();
2263 #endif
2264         }
2265 #ifndef Q_OS_WIN
2266     } else if (e->type() == QEvent::LocaleChange) {
2267         // on Windows the event propagation is taken care by the
2268         // WM_SETTINGCHANGE event handler.
2269         QWidgetList list = topLevelWidgets();
2270         for (int i = 0; i < list.size(); ++i) {
2271             QWidget *w = list.at(i);
2272             if (!(w->windowType() == Qt::Desktop)) {
2273                 if (!w->testAttribute(Qt::WA_SetLocale))
2274                     w->d_func()->setLocale_helper(QLocale(), true);
2275             }
2276         }
2277 #endif
2278     } else if (e->type() == QEvent::Timer) {
2279         QTimerEvent *te = static_cast<QTimerEvent*>(e);
2280         Q_ASSERT(te != 0);
2281         if (te->timerId() == d->toolTipWakeUp.timerId()) {
2282             d->toolTipWakeUp.stop();
2283             if (d->toolTipWidget) {
2284                 QWidget *w = d->toolTipWidget->window();
2285                 // show tooltip if WA_AlwaysShowToolTips is set, or if
2286                 // any ancestor of d->toolTipWidget is the active
2287                 // window
2288                 bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);
2289                 while (w && !showToolTip) {
2290                     showToolTip = w->isActiveWindow();
2291                     w = w->parentWidget();
2292                     w = w ? w->window() : 0;
2293                 }
2294                 if (showToolTip) {
2295                     QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
2296                     QApplication::sendEvent(d->toolTipWidget, &e);
2297                     if (e.isAccepted())
2298                         d->toolTipFallAsleep.start(2000, this);
2299                 }
2300             }
2301         } else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
2302             d->toolTipFallAsleep.stop();
2303         }
2304     }
2305
2306     if(e->type() == QEvent::LanguageChange) {
2307 #if defined(QT_MAC_USE_COCOA)
2308         qt_mac_post_retranslateAppMenu();
2309 #endif
2310         QWidgetList list = topLevelWidgets();
2311         for (int i = 0; i < list.size(); ++i) {
2312             QWidget *w = list.at(i);
2313             if (!(w->windowType() == Qt::Desktop))
2314                 postEvent(w, new QEvent(QEvent::LanguageChange));
2315         }
2316     }
2317
2318     return QApplicationBase::event(e);
2319 }
2320
2321 #if !defined(Q_WS_X11)
2322
2323 // The doc and X implementation of this function is in qapplication_x11.cpp
2324
2325 void QApplication::syncX()        {}                // do nothing
2326
2327 #endif
2328
2329 void QApplicationPrivate::notifyLayoutDirectionChange()
2330 {
2331     Q_Q(QApplication);
2332     QWidgetList list = q->topLevelWidgets();
2333     for (int i = 0; i < list.size(); ++i) {
2334         QWidget *w = list.at(i);
2335         QEvent ev(QEvent::ApplicationLayoutDirectionChange);
2336         q->sendEvent(w, &ev);
2337     }
2338 }
2339
2340 /*!
2341     \fn Qt::WindowsVersion QApplication::winVersion()
2342
2343     Use \l QSysInfo::WindowsVersion instead.
2344 */
2345
2346 /*!
2347     \fn void QApplication::setActiveWindow(QWidget* active)
2348
2349     Sets the active window to the \a active widget in response to a system
2350     event. The function is called from the platform specific event handlers.
2351
2352     \warning This function does \e not set the keyboard focus to the active
2353     widget. Call QWidget::activateWindow() instead.
2354
2355     It sets the activeWindow() and focusWidget() attributes and sends proper
2356     \l{QEvent::WindowActivate}{WindowActivate}/\l{QEvent::WindowDeactivate}
2357     {WindowDeactivate} and \l{QEvent::FocusIn}{FocusIn}/\l{QEvent::FocusOut}
2358     {FocusOut} events to all appropriate widgets. The window will then be
2359     painted in active state (e.g. cursors in line edits will blink), and it
2360     will have tool tips enabled.
2361
2362     \sa activeWindow(), QWidget::activateWindow()
2363 */
2364 void QApplication::setActiveWindow(QWidget* act)
2365 {
2366     QWidget* window = act?act->window():0;
2367
2368     if (QApplicationPrivate::active_window == window)
2369         return;
2370
2371 #ifndef QT_NO_GRAPHICSVIEW
2372     if (window && window->graphicsProxyWidget()) {
2373         // Activate the proxy's view->viewport() ?
2374         return;
2375     }
2376 #endif
2377
2378     QWidgetList toBeActivated;
2379     QWidgetList toBeDeactivated;
2380
2381     if (QApplicationPrivate::active_window) {
2382         if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
2383             QWidgetList list = topLevelWidgets();
2384             for (int i = 0; i < list.size(); ++i) {
2385                 QWidget *w = list.at(i);
2386                 if (w->isVisible() && w->isActiveWindow())
2387                     toBeDeactivated.append(w);
2388             }
2389         } else {
2390             toBeDeactivated.append(QApplicationPrivate::active_window);
2391         }
2392     }
2393
2394 #if !defined(Q_WS_MAC)
2395     QWidget *previousActiveWindow =  QApplicationPrivate::active_window;
2396 #endif
2397     QApplicationPrivate::active_window = window;
2398
2399     if (QApplicationPrivate::active_window) {
2400         if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
2401             QWidgetList list = topLevelWidgets();
2402             for (int i = 0; i < list.size(); ++i) {
2403                 QWidget *w = list.at(i);
2404                 if (w->isVisible() && w->isActiveWindow())
2405                     toBeActivated.append(w);
2406             }
2407         } else {
2408             toBeActivated.append(QApplicationPrivate::active_window);
2409         }
2410
2411     }
2412
2413     // first the activation/deactivation events
2414     QEvent activationChange(QEvent::ActivationChange);
2415     QEvent windowActivate(QEvent::WindowActivate);
2416     QEvent windowDeactivate(QEvent::WindowDeactivate);
2417
2418 #if !defined(Q_WS_MAC)
2419     if (!previousActiveWindow) {
2420         QEvent appActivate(QEvent::ApplicationActivate);
2421         sendSpontaneousEvent(qApp, &appActivate);
2422     }
2423 #endif
2424
2425     for (int i = 0; i < toBeActivated.size(); ++i) {
2426         QWidget *w = toBeActivated.at(i);
2427         sendSpontaneousEvent(w, &windowActivate);
2428         sendSpontaneousEvent(w, &activationChange);
2429     }
2430
2431 #ifdef QT_MAC_USE_COCOA
2432     // In case the user clicked on a child window, we need to
2433     // reestablish the stacking order of the window so
2434     // it pops in front of other child windows in cocoa:
2435     qt_cocoaStackChildWindowOnTopOfOtherChildren(window);
2436 #endif
2437
2438     for(int i = 0; i < toBeDeactivated.size(); ++i) {
2439         QWidget *w = toBeDeactivated.at(i);
2440         sendSpontaneousEvent(w, &windowDeactivate);
2441         sendSpontaneousEvent(w, &activationChange);
2442     }
2443
2444 #if !defined(Q_WS_MAC)
2445     if (!QApplicationPrivate::active_window) {
2446         QEvent appDeactivate(QEvent::ApplicationDeactivate);
2447         sendSpontaneousEvent(qApp, &appDeactivate);
2448     }
2449 #endif
2450
2451     if (QApplicationPrivate::popupWidgets == 0) { // !inPopupMode()
2452         // then focus events
2453         if (!QApplicationPrivate::active_window && QApplicationPrivate::focus_widget) {
2454             QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
2455         } else if (QApplicationPrivate::active_window) {
2456             QWidget *w = QApplicationPrivate::active_window->focusWidget();
2457             if (w && w->isVisible() /*&& w->focusPolicy() != QWidget::NoFocus*/)
2458                 w->setFocus(Qt::ActiveWindowFocusReason);
2459             else {
2460                 w = QApplicationPrivate::focusNextPrevChild_helper(QApplicationPrivate::active_window, true);
2461                 if (w) {
2462                     w->setFocus(Qt::ActiveWindowFocusReason);
2463                 } else {
2464                     // If the focus widget is not in the activate_window, clear the focus
2465                     w = QApplicationPrivate::focus_widget;
2466                     if (!w && QApplicationPrivate::active_window->focusPolicy() != Qt::NoFocus)
2467                         QApplicationPrivate::setFocusWidget(QApplicationPrivate::active_window, Qt::ActiveWindowFocusReason);
2468                     else if (!QApplicationPrivate::active_window->isAncestorOf(w))
2469                         QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
2470                 }
2471             }
2472         }
2473     }
2474 }
2475
2476 /*!internal
2477  * Helper function that returns the new focus widget, but does not set the focus reason.
2478  * Returns 0 if a new focus widget could not be found.
2479  * Shared with QGraphicsProxyWidgetPrivate::findFocusChild()
2480 */
2481 QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next)
2482 {
2483     uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
2484
2485     QWidget *f = toplevel->focusWidget();
2486     if (!f)
2487         f = toplevel;
2488
2489     QWidget *w = f;
2490     QWidget *test = f->d_func()->focus_next;
2491     while (test && test != f) {
2492         if ((test->focusPolicy() & focus_flag) == focus_flag
2493             && !(test->d_func()->extra && test->d_func()->extra->focus_proxy)
2494             && test->isVisibleTo(toplevel) && test->isEnabled()
2495             && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
2496             && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
2497             w = test;
2498             if (next)
2499                 break;
2500         }
2501         test = test->d_func()->focus_next;
2502     }
2503     if (w == f) {
2504         if (qt_in_tab_key_event) {
2505             w->window()->setAttribute(Qt::WA_KeyboardFocusChange);
2506             w->update();
2507         }
2508         return 0;
2509     }
2510     return w;
2511 }
2512
2513 /*!
2514     \fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave)
2515     \internal
2516
2517     Creates the proper Enter/Leave event when widget \a enter is entered and
2518     widget \a leave is left.
2519  */
2520 void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) {
2521 #if 0
2522     if (leave) {
2523         QEvent e(QEvent::Leave);
2524         QApplication::sendEvent(leave, & e);
2525     }
2526     if (enter) {
2527         QEvent e(QEvent::Enter);
2528         QApplication::sendEvent(enter, & e);
2529     }
2530     return;
2531 #endif
2532
2533     QWidget* w ;
2534     if ((!enter && !leave) || (enter == leave))
2535         return;
2536 #ifdef ALIEN_DEBUG
2537     qDebug() << "QApplicationPrivate::dispatchEnterLeave, ENTER:" << enter << "LEAVE:" << leave;
2538 #endif
2539     QWidgetList leaveList;
2540     QWidgetList enterList;
2541
2542     bool sameWindow = leave && enter && leave->window() == enter->window();
2543     if (leave && !sameWindow) {
2544         w = leave;
2545         do {
2546             leaveList.append(w);
2547         } while (!w->isWindow() && (w = w->parentWidget()));
2548     }
2549     if (enter && !sameWindow) {
2550         w = enter;
2551         do {
2552             enterList.prepend(w);
2553         } while (!w->isWindow() && (w = w->parentWidget()));
2554     }
2555     if (sameWindow) {
2556         int enterDepth = 0;
2557         int leaveDepth = 0;
2558         w = enter;
2559         while (!w->isWindow() && (w = w->parentWidget()))
2560             enterDepth++;
2561         w = leave;
2562         while (!w->isWindow() && (w = w->parentWidget()))
2563             leaveDepth++;
2564         QWidget* wenter = enter;
2565         QWidget* wleave = leave;
2566         while (enterDepth > leaveDepth) {
2567             wenter = wenter->parentWidget();
2568             enterDepth--;
2569         }
2570         while (leaveDepth > enterDepth) {
2571             wleave = wleave->parentWidget();
2572             leaveDepth--;
2573         }
2574         while (!wenter->isWindow() && wenter != wleave) {
2575             wenter = wenter->parentWidget();
2576             wleave = wleave->parentWidget();
2577         }
2578
2579         w = leave;
2580         while (w != wleave) {
2581             leaveList.append(w);
2582             w = w->parentWidget();
2583         }
2584         w = enter;
2585         while (w != wenter) {
2586             enterList.prepend(w);
2587             w = w->parentWidget();
2588         }
2589     }
2590
2591     QEvent leaveEvent(QEvent::Leave);
2592     for (int i = 0; i < leaveList.size(); ++i) {
2593         w = leaveList.at(i);
2594         if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
2595 #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_MAC)
2596             if (leaveAfterRelease == w)
2597                 leaveAfterRelease = 0;
2598 #endif
2599             QApplication::sendEvent(w, &leaveEvent);
2600             if (w->testAttribute(Qt::WA_Hover) &&
2601                 (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
2602                 Q_ASSERT(instance());
2603                 QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos),
2604                                QApplication::keyboardModifiers());
2605                 qApp->d_func()->notify_helper(w, &he);
2606             }
2607         }
2608     }
2609     QPoint posEnter = QCursor::pos();
2610     QEvent enterEvent(QEvent::Enter);
2611     for (int i = 0; i < enterList.size(); ++i) {
2612         w = enterList.at(i);
2613         if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
2614             QApplication::sendEvent(w, &enterEvent);
2615             if (w->testAttribute(Qt::WA_Hover) &&
2616                 (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
2617                 QHoverEvent he(QEvent::HoverEnter, w->mapFromGlobal(posEnter), QPoint(-1, -1),
2618                                QApplication::keyboardModifiers());
2619                 qApp->d_func()->notify_helper(w, &he);
2620             }
2621         }
2622     }
2623
2624 #ifndef QT_NO_CURSOR
2625     // Update cursor for alien/graphics widgets.
2626
2627     const bool enterOnAlien = (enter && (isAlien(enter) || enter->testAttribute(Qt::WA_DontShowOnScreen)));
2628 #if defined(Q_WS_X11) || defined(Q_WS_QPA)
2629     //Whenever we leave an alien widget on X11, we need to reset its nativeParentWidget()'s cursor.
2630     // This is not required on Windows as the cursor is reset on every single mouse move.
2631     QWidget *parentOfLeavingCursor = 0;
2632     for (int i = 0; i < leaveList.size(); ++i) {
2633         w = leaveList.at(i);
2634         if (!isAlien(w))
2635             break;
2636         if (w->testAttribute(Qt::WA_SetCursor)) {
2637             QWidget *parent = w->parentWidget();
2638             while (parent && parent->d_func()->data.in_destructor)
2639                 parent = parent->parentWidget();
2640             parentOfLeavingCursor = parent;
2641             //continue looping, we need to find the downest alien widget with a cursor.
2642             // (downest on the screen)
2643         }
2644     }
2645     //check that we will not call qt_x11_enforce_cursor twice with the same native widget
2646     if (parentOfLeavingCursor && (!enterOnAlien
2647         || parentOfLeavingCursor->effectiveWinId() != enter->effectiveWinId())) {
2648 #ifndef QT_NO_GRAPHICSVIEW
2649         if (!parentOfLeavingCursor->window()->graphicsProxyWidget())
2650 #endif
2651         {
2652 #if defined(Q_WS_X11)
2653             qt_x11_enforce_cursor(parentOfLeavingCursor,true);
2654 #elif defined(Q_WS_QPA)
2655             if (enter == QApplication::desktop()) {
2656                 qt_qpa_set_cursor(enter, true);
2657             } else {
2658                 qt_qpa_set_cursor(parentOfLeavingCursor, true);
2659             }
2660 #endif
2661         }
2662     }
2663 #endif
2664     if (enterOnAlien) {
2665         QWidget *cursorWidget = enter;
2666         while (!cursorWidget->isWindow() && !cursorWidget->isEnabled())
2667             cursorWidget = cursorWidget->parentWidget();
2668
2669         if (!cursorWidget)
2670             return;
2671
2672 #ifndef QT_NO_GRAPHICSVIEW
2673         if (cursorWidget->window()->graphicsProxyWidget()) {
2674             QWidgetPrivate::nearestGraphicsProxyWidget(cursorWidget)->setCursor(cursorWidget->cursor());
2675         } else
2676 #endif
2677         {
2678 #if defined(Q_WS_WIN)
2679             qt_win_set_cursor(cursorWidget, true);
2680 #elif defined(Q_WS_X11)
2681             qt_x11_enforce_cursor(cursorWidget, true);
2682 #elif defined(Q_OS_SYMBIAN)
2683             qt_symbian_set_cursor(cursorWidget, true);
2684 #elif defined(Q_WS_QPA)
2685             qt_qpa_set_cursor(cursorWidget, true);
2686 #endif
2687         }
2688     }
2689 #endif
2690 }
2691
2692 /* exported for the benefit of testing tools */
2693 Q_WIDGETS_EXPORT bool qt_tryModalHelper(QWidget *widget, QWidget **rettop)
2694 {
2695     return QApplicationPrivate::tryModalHelper(widget, rettop);
2696 }
2697
2698 /*! \internal
2699     Returns true if \a widget is blocked by a modal window.
2700  */
2701 bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
2702 {
2703     widget = widget->window();
2704     if (!modalState())
2705         return false;
2706     if (QApplication::activePopupWidget() == widget)
2707         return false;
2708
2709     for (int i = 0; i < qt_modal_stack->size(); ++i) {
2710         QWidget *modalWidget = qt_modal_stack->at(i);
2711
2712         {
2713             // check if the active modal widget is our widget or a parent of our widget
2714             QWidget *w = widget;
2715             while (w) {
2716                 if (w == modalWidget)
2717                     return false;
2718                 w = w->parentWidget();
2719             }
2720 #ifdef Q_WS_WIN
2721             if ((widget->testAttribute(Qt::WA_WState_Created) || widget->data->winid)
2722                 && (modalWidget->testAttribute(Qt::WA_WState_Created) || modalWidget->data->winid)
2723                 && IsChild(modalWidget->data->winid, widget->data->winid))
2724                 return false;
2725 #endif
2726         }
2727
2728         Qt::WindowModality windowModality = modalWidget->windowModality();
2729         if (windowModality == Qt::NonModal) {
2730             // determine the modality type if it hasn't been set on the
2731             // modalWidget, this normally happens when waiting for a
2732             // native dialog. use WindowModal if we are the child of a
2733             // group leader; otherwise use ApplicationModal.
2734             QWidget *m = modalWidget;
2735             while (m && !m->testAttribute(Qt::WA_GroupLeader)) {
2736                 m = m->parentWidget();
2737                 if (m)
2738                     m = m->window();
2739             }
2740             windowModality = (m && m->testAttribute(Qt::WA_GroupLeader))
2741                              ? Qt::WindowModal
2742                              : Qt::ApplicationModal;
2743         }
2744
2745         switch (windowModality) {
2746         case Qt::ApplicationModal:
2747             {
2748                 QWidget *groupLeaderForWidget = widget;
2749                 while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader))
2750                     groupLeaderForWidget = groupLeaderForWidget->parentWidget();
2751
2752                 if (groupLeaderForWidget) {
2753                     // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children
2754                     QWidget *m = modalWidget;
2755                     while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader))
2756                         m = m->parentWidget();
2757                     if (m == groupLeaderForWidget)
2758                         return true;
2759                 } else if (modalWidget != widget) {
2760                     return true;
2761                 }
2762                 break;
2763             }
2764         case Qt::WindowModal:
2765             {
2766                 QWidget *w = widget;
2767                 do {
2768                     QWidget *m = modalWidget;
2769                     do {
2770                         if (m == w)
2771                             return true;
2772                         m = m->parentWidget();
2773                         if (m)
2774                             m = m->window();
2775                     } while (m);
2776                     w = w->parentWidget();
2777                     if (w)
2778                         w = w->window();
2779                 } while (w);
2780                 break;
2781             }
2782         default:
2783             Q_ASSERT_X(false, "QApplication", "internal error, a modal widget cannot be modeless");
2784             break;
2785         }
2786     }
2787     return false;
2788 }
2789
2790 /*!\internal
2791  */
2792 void QApplicationPrivate::enterModal(QWidget *widget)
2793 {
2794     QSet<QWidget*> blocked;
2795     QList<QWidget*> windows = QApplication::topLevelWidgets();
2796     for (int i = 0; i < windows.count(); ++i) {
2797         QWidget *window = windows.at(i);
2798         if (window->windowType() != Qt::Tool && isBlockedByModal(window))
2799             blocked.insert(window);
2800     }
2801
2802     enterModal_sys(widget);
2803
2804     windows = QApplication::topLevelWidgets();
2805     QEvent e(QEvent::WindowBlocked);
2806     for (int i = 0; i < windows.count(); ++i) {
2807         QWidget *window = windows.at(i);
2808         if (!blocked.contains(window) && window->windowType() != Qt::Tool && isBlockedByModal(window))
2809             QApplication::sendEvent(window, &e);
2810     }
2811 }
2812
2813 /*!\internal
2814  */
2815 void QApplicationPrivate::leaveModal(QWidget *widget)
2816 {
2817     QSet<QWidget*> blocked;
2818     QList<QWidget*> windows = QApplication::topLevelWidgets();
2819     for (int i = 0; i < windows.count(); ++i) {
2820         QWidget *window = windows.at(i);
2821         if (window->windowType() != Qt::Tool && isBlockedByModal(window))
2822             blocked.insert(window);
2823     }
2824
2825     leaveModal_sys(widget);
2826
2827     windows = QApplication::topLevelWidgets();
2828     QEvent e(QEvent::WindowUnblocked);
2829     for (int i = 0; i < windows.count(); ++i) {
2830         QWidget *window = windows.at(i);
2831         if(blocked.contains(window) && window->windowType() != Qt::Tool && !isBlockedByModal(window))
2832             QApplication::sendEvent(window, &e);
2833     }
2834 }
2835
2836
2837
2838 /*!\internal
2839
2840   Called from qapplication_\e{platform}.cpp, returns true
2841   if the widget should accept the event.
2842  */
2843 bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
2844 {
2845     QWidget *top = QApplication::activeModalWidget();
2846     if (rettop)
2847         *rettop = top;
2848
2849     // the active popup widget always gets the input event
2850     if (QApplication::activePopupWidget())
2851         return true;
2852
2853 #if defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)
2854     top = QApplicationPrivate::tryModalHelper_sys(top);
2855     if (rettop)
2856         *rettop = top;
2857 #endif
2858
2859     return !isBlockedByModal(widget->window());
2860 }
2861
2862 /*
2863    \internal
2864 */
2865 QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint &globalPos,
2866                                                 QPoint &pos, QEvent::Type type,
2867                                                 Qt::MouseButtons buttons, QWidget *buttonDown,
2868                                                 QWidget *alienWidget)
2869 {
2870     Q_ASSERT(candidate);
2871
2872     QWidget *mouseGrabber = QWidget::mouseGrabber();
2873     if (((type == QEvent::MouseMove && buttons) || (type == QEvent::MouseButtonRelease))
2874             && !buttonDown && !mouseGrabber) {
2875         return 0;
2876     }
2877
2878     if (alienWidget && alienWidget->internalWinId())
2879         alienWidget = 0;
2880
2881     QWidget *receiver = candidate;
2882
2883     if (!mouseGrabber)
2884         mouseGrabber = (buttonDown && !isBlockedByModal(buttonDown)) ? buttonDown : alienWidget;
2885
2886     if (mouseGrabber && mouseGrabber != candidate) {
2887         receiver = mouseGrabber;
2888         pos = receiver->mapFromGlobal(globalPos);
2889 #ifdef ALIEN_DEBUG
2890         qDebug() << "  ** receiver adjusted to:" << receiver << "pos:" << pos;
2891 #endif
2892     }
2893
2894     return receiver;
2895
2896 }
2897
2898 /*
2899    \internal
2900 */
2901 bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
2902                                          QWidget *alienWidget, QWidget *nativeWidget,
2903                                          QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
2904                                          bool spontaneous)
2905 {
2906     Q_ASSERT(receiver);
2907     Q_ASSERT(event);
2908     Q_ASSERT(nativeWidget);
2909     Q_ASSERT(buttonDown);
2910
2911     if (alienWidget && !isAlien(alienWidget))
2912         alienWidget = 0;
2913
2914     QPointer<QWidget> receiverGuard = receiver;
2915     QPointer<QWidget> nativeGuard = nativeWidget;
2916     QPointer<QWidget> alienGuard = alienWidget;
2917     QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
2918
2919     const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
2920
2921     if (*buttonDown) {
2922         if (!graphicsWidget) {
2923             // Register the widget that shall receive a leave event
2924             // after the last button is released.
2925             if ((alienWidget || !receiver->internalWinId()) && !leaveAfterRelease && !QWidget::mouseGrabber())
2926                 leaveAfterRelease = *buttonDown;
2927             if (event->type() == QEvent::MouseButtonRelease && !event->buttons())
2928                 *buttonDown = 0;
2929         }
2930     } else if (lastMouseReceiver) {
2931         // Dispatch enter/leave if we move:
2932         // 1) from an alien widget to another alien widget or
2933         //    from a native widget to an alien widget (first OR case)
2934         // 2) from an alien widget to a native widget (second OR case)
2935         if ((alienWidget && alienWidget != lastMouseReceiver)
2936             || (isAlien(lastMouseReceiver) && !alienWidget)) {
2937             if (activePopupWidget) {
2938                 if (!QWidget::mouseGrabber())
2939                     dispatchEnterLeave(alienWidget ? alienWidget : nativeWidget, lastMouseReceiver);
2940             } else {
2941                 dispatchEnterLeave(receiver, lastMouseReceiver);
2942             }
2943
2944         }
2945     }
2946
2947 #ifdef ALIEN_DEBUG
2948     qDebug() << "QApplicationPrivate::sendMouseEvent: receiver:" << receiver
2949              << "pos:" << event->pos() << "alien" << alienWidget << "button down"
2950              << *buttonDown << "last" << lastMouseReceiver << "leave after release"
2951              << leaveAfterRelease;
2952 #endif
2953
2954     // We need this quard in case someone opens a modal dialog / popup. If that's the case
2955     // leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
2956     const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
2957     bool result;
2958     if (spontaneous)
2959         result = QApplication::sendSpontaneousEvent(receiver, event);
2960     else
2961         result = QApplication::sendEvent(receiver, event);
2962
2963     if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
2964         && !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
2965         // Dispatch enter/leave if:
2966         // 1) the mouse grabber is an alien widget
2967         // 2) the button is released on an alien widget
2968         QWidget *enter = 0;
2969         if (nativeGuard)
2970             enter = alienGuard ? alienWidget : nativeWidget;
2971         else // The receiver is typically deleted on mouse release with drag'n'drop.
2972             enter = QApplication::widgetAt(event->globalPos());
2973         dispatchEnterLeave(enter, leaveAfterRelease);
2974         leaveAfterRelease = 0;
2975         lastMouseReceiver = enter;
2976     } else if (!wasLeaveAfterRelease) {
2977         if (activePopupWidget) {
2978             if (!QWidget::mouseGrabber())
2979                 lastMouseReceiver = alienGuard ? alienWidget : (nativeGuard ? nativeWidget : 0);
2980         } else {
2981             lastMouseReceiver = receiverGuard ? receiver : QApplication::widgetAt(event->globalPos());
2982         }
2983     }
2984
2985     return result;
2986 }
2987
2988 #if defined(Q_WS_WIN) || defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_WS_MAC) || defined(Q_WS_QPA)
2989 /*
2990     This function should only be called when the widget changes visibility, i.e.
2991     when the \a widget is shown, hidden or deleted. This function does nothing
2992     if the widget is a top-level or native, i.e. not an alien widget. In that
2993     case enter/leave events are genereated by the underlying windowing system.
2994 */
2995 extern QPointer<QWidget> qt_last_mouse_receiver;
2996 extern QWidget *qt_button_down;
2997 void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
2998 {
2999 #ifndef QT_NO_CURSOR
3000 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
3001     if (!widget || widget->isWindow())
3002         return;
3003 #else
3004     if (!widget || widget->internalWinId() || widget->isWindow())
3005         return;
3006 #endif
3007     const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor;
3008     if (!widgetInShow && widget != qt_last_mouse_receiver)
3009         return; // Widget was not under the cursor when it was hidden/deleted.
3010
3011     if (widgetInShow && widget->parentWidget()->data->in_show)
3012         return; // Ingore recursive show.
3013
3014     QWidget *mouseGrabber = QWidget::mouseGrabber();
3015     if (mouseGrabber && mouseGrabber != widget)
3016         return; // Someone else has the grab; enter/leave should not occur.
3017
3018     QWidget *tlw = widget->window();
3019     if (tlw->data->in_destructor || tlw->data->is_closing)
3020         return; // Closing down the business.
3021
3022     if (widgetInShow && (!qt_last_mouse_receiver || qt_last_mouse_receiver->window() != tlw))
3023         return; // Mouse cursor not inside the widget's top-level.
3024
3025     const QPoint globalPos(QCursor::pos());
3026     QPoint windowPos = tlw->mapFromGlobal(globalPos);
3027
3028     // Find the current widget under the mouse. If this function was called from
3029     // the widget's destructor, we have to make sure childAt() doesn't take into
3030     // account widgets that are about to be destructed.
3031     QWidget *widgetUnderCursor = tlw->d_func()->childAt_helper(windowPos, widget->data->in_destructor);
3032     if (!widgetUnderCursor)
3033         widgetUnderCursor = tlw;
3034     QPoint pos = widgetUnderCursor->mapFrom(tlw, windowPos);
3035
3036     if (widgetInShow && widgetUnderCursor != widget && !widget->isAncestorOf(widgetUnderCursor))
3037         return; // Mouse cursor not inside the widget or any of its children.
3038
3039     if (widget->data->in_destructor && qt_button_down == widget)
3040         qt_button_down = 0;
3041
3042     // Send enter/leave events followed by a mouse move on the entered widget.
3043     QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
3044     sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
3045 #endif // QT_NO_CURSOR
3046 }
3047 #endif // Q_WS_WIN || Q_WS_X11 || Q_WS_MAC
3048
3049 /*!
3050     Returns the desktop widget (also called the root window).
3051
3052     The desktop may be composed of multiple screens, so it would be incorrect,
3053     for example, to attempt to \e center some widget in the desktop's geometry.
3054     QDesktopWidget has various functions for obtaining useful geometries upon
3055     the desktop, such as QDesktopWidget::screenGeometry() and
3056     QDesktopWidget::availableGeometry().
3057
3058     On X11, it is also possible to draw on the desktop.
3059 */
3060 QDesktopWidget *QApplication::desktop()
3061 {
3062     if (!qt_desktopWidget || // not created yet
3063          !(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away
3064         qt_desktopWidget = new QDesktopWidget();
3065     }
3066     return qt_desktopWidget;
3067 }
3068
3069 #if !defined(Q_WS_QPA) && !defined(QT_NO_CLIPBOARD)
3070 /*!
3071     Returns a pointer to the application global clipboard.
3072
3073     \note The QApplication object should already be constructed before
3074     accessing the clipboard.
3075 */
3076 QClipboard *QApplication::clipboard()
3077 {
3078     if (qt_clipboard == 0) {
3079         if (!qApp) {
3080             qWarning("QApplication: Must construct a QApplication before accessing a QClipboard");
3081             return 0;
3082         }
3083         qt_clipboard = new QClipboard(0);
3084     }
3085     return qt_clipboard;
3086 }
3087 #endif // Q_WS_QPA && QT_NO_CLIPBOARD
3088 /*!
3089     Sets whether Qt should use the system's standard colors, fonts, etc., to
3090     \a on. By default, this is true.
3091
3092     This function must be called before creating the QApplication object, like
3093     this:
3094
3095     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 6
3096
3097     \sa desktopSettingsAware()
3098 */
3099 void QApplication::setDesktopSettingsAware(bool on)
3100 {
3101     QApplicationPrivate::obey_desktop_settings = on;
3102 }
3103
3104 /*!
3105     Returns true if Qt is set to use the system's standard colors, fonts, etc.;
3106     otherwise returns false. The default is true.
3107
3108     \sa setDesktopSettingsAware()
3109 */
3110 bool QApplication::desktopSettingsAware()
3111 {
3112     return QApplicationPrivate::obey_desktop_settings;
3113 }
3114
3115 /*!
3116     Returns the current state of the modifier keys on the keyboard. The current
3117     state is updated sychronously as the event queue is emptied of events that
3118     will spontaneously change the keyboard state (QEvent::KeyPress and
3119     QEvent::KeyRelease events).
3120
3121     It should be noted this may not reflect the actual keys held on the input
3122     device at the time of calling but rather the modifiers as last reported in
3123     one of the above events. If no keys are being held Qt::NoModifier is
3124     returned.
3125
3126     \sa mouseButtons(), queryKeyboardModifiers()
3127 */
3128
3129 Qt::KeyboardModifiers QApplication::keyboardModifiers()
3130 {
3131     return QApplicationPrivate::modifier_buttons;
3132 }
3133
3134 /*!
3135     \fn Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
3136
3137     Queries and returns the state of the modifier keys on the keyboard.
3138     Unlike keyboardModifiers, this method returns the actual keys held
3139     on the input device at the time of calling the method.
3140
3141     It does not rely on the keypress events having been received by this
3142     process, which makes it possible to check the modifiers while moving
3143     a window, for instance. Note that in most cases, you should use
3144     keyboardModifiers(), which is faster and more accurate since it contains
3145     the state of the modifiers as they were when the currently processed
3146     event was received.
3147
3148     \sa keyboardModifiers()
3149
3150     \since 4.8
3151 */
3152
3153 Qt::KeyboardModifiers QApplication::queryKeyboardModifiers()
3154 {
3155     qWarning("queryKeyboardModifiers() doesn't have a QPA implementation");
3156     return QApplicationPrivate::modifier_buttons;
3157 }
3158
3159 /*!
3160     Returns the current state of the buttons on the mouse. The current state is
3161     updated syncronously as the event queue is emptied of events that will
3162     spontaneously change the mouse state (QEvent::MouseButtonPress and
3163     QEvent::MouseButtonRelease events).
3164
3165     It should be noted this may not reflect the actual buttons held on the
3166     input device at the time of calling but rather the mouse buttons as last
3167     reported in one of the above events. If no mouse buttons are being held
3168     Qt::NoButton is returned.
3169
3170     \sa keyboardModifiers()
3171 */
3172
3173 Qt::MouseButtons QApplication::mouseButtons()
3174 {
3175     return QApplicationPrivate::mouse_buttons;
3176 }
3177
3178 /*!
3179     \fn bool QApplication::isSessionRestored() const
3180
3181     Returns true if the application has been restored from an earlier
3182     \l{Session Management}{session}; otherwise returns false.
3183
3184     \sa sessionId(), commitData(), saveState()
3185 */
3186
3187
3188 /*!
3189     \fn QString QApplication::sessionId() const
3190
3191     Returns the current \l{Session Management}{session's} identifier.
3192
3193     If the application has been restored from an earlier session, this
3194     identifier is the same as it was in that previous session. The session
3195     identifier is guaranteed to be unique both for different applications
3196     and for different instances of the same application.
3197
3198     \sa isSessionRestored(), sessionKey(), commitData(), saveState()
3199 */
3200
3201 /*!
3202     \fn QString QApplication::sessionKey() const
3203
3204     Returns the session key in the current \l{Session Management}{session}.
3205
3206     If the application has been restored from an earlier session, this key is
3207     the same as it was when the previous session ended.
3208
3209     The session key changes with every call of commitData() or saveState().
3210
3211     \sa isSessionRestored(), sessionId(), commitData(), saveState()
3212 */
3213 #ifndef QT_NO_SESSIONMANAGER
3214 bool QApplication::isSessionRestored() const
3215 {
3216     Q_D(const QApplication);
3217     return d->is_session_restored;
3218 }
3219
3220 QString QApplication::sessionId() const
3221 {
3222     Q_D(const QApplication);
3223     return d->session_id;
3224 }
3225
3226 QString QApplication::sessionKey() const
3227 {
3228     Q_D(const QApplication);
3229     return d->session_key;
3230 }
3231 #endif
3232
3233
3234
3235 /*!
3236     \since 4.2
3237     \fn void QApplication::commitDataRequest(QSessionManager &manager)
3238
3239     This signal deals with \l{Session Management}{session management}. It is
3240     emitted when the QSessionManager wants the application to commit all its
3241     data.
3242
3243     Usually this means saving all open files, after getting permission from
3244     the user. Furthermore you may want to provide a means by which the user
3245     can cancel the shutdown.
3246
3247     You should not exit the application within this signal. Instead,
3248     the session manager may or may not do this afterwards, depending on the
3249     context.
3250
3251     \warning Within this signal, no user interaction is possible, \e
3252     unless you ask the \a manager for explicit permission. See
3253     QSessionManager::allowsInteraction() and
3254     QSessionManager::allowsErrorInteraction() for details and example
3255     usage.
3256
3257     \note You should use Qt::DirectConnection when connecting to this signal.
3258
3259     \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
3260 */
3261
3262 /*!
3263     This function deals with \l{Session Management}{session management}. It is
3264     invoked when the QSessionManager wants the application to commit all its
3265     data.
3266
3267     Usually this means saving all open files, after getting permission from the
3268     user. Furthermore you may want to provide a means by which the user can
3269     cancel the shutdown.
3270
3271     You should not exit the application within this function. Instead, the
3272     session manager may or may not do this afterwards, depending on the
3273     context.
3274
3275     \warning Within this function, no user interaction is possible, \e
3276     unless you ask the \a manager for explicit permission. See
3277     QSessionManager::allowsInteraction() and
3278     QSessionManager::allowsErrorInteraction() for details and example
3279     usage.
3280
3281     The default implementation requests interaction and sends a close event to
3282     all visible top-level widgets. If any event was rejected, the shutdown is
3283     canceled.
3284
3285     \sa isSessionRestored(), sessionId(), saveState(), {Session Management}
3286 */
3287 #ifndef QT_NO_SESSIONMANAGER
3288 void QApplication::commitData(QSessionManager& manager )
3289 {
3290     emit commitDataRequest(manager);
3291     if (manager.allowsInteraction()) {
3292         QWidgetList done;
3293         QWidgetList list = QApplication::topLevelWidgets();
3294         bool cancelled = false;
3295         for (int i = 0; !cancelled && i < list.size(); ++i) {
3296             QWidget* w = list.at(i);
3297             if (w->isVisible() && !done.contains(w)) {
3298                 cancelled = !w->close();
3299                 if (!cancelled)
3300                     done.append(w);
3301                 list = QApplication::topLevelWidgets();
3302                 i = -1;
3303             }
3304         }
3305         if (cancelled)
3306             manager.cancel();
3307     }
3308 }
3309
3310 /*!
3311     \since 4.2
3312     \fn void QApplication::saveStateRequest(QSessionManager &manager)
3313
3314     This signal deals with \l{Session Management}{session management}. It is
3315     invoked when the \l{QSessionManager}{session manager} wants the application
3316     to preserve its state for a future session.
3317
3318     For example, a text editor would create a temporary file that includes the
3319     current contents of its edit buffers, the location of the cursor and other
3320     aspects of the current editing session.
3321
3322     You should never exit the application within this signal. Instead, the
3323     session manager may or may not do this afterwards, depending on the
3324     context. Futhermore, most session managers will very likely request a saved
3325     state immediately after the application has been started. This permits the
3326     session manager to learn about the application's restart policy.
3327
3328     \warning Within this function, no user interaction is possible, \e
3329     unless you ask the \a manager for explicit permission. See
3330     QSessionManager::allowsInteraction() and
3331     QSessionManager::allowsErrorInteraction() for details.
3332
3333     \note You should use Qt::DirectConnection when connecting to this signal.
3334
3335     \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
3336 */
3337
3338 /*!
3339     This function deals with \l{Session Management}{session management}. It is
3340     invoked when the \l{QSessionManager}{session manager} wants the application
3341     to preserve its state for a future session.
3342
3343     For example, a text editor would create a temporary file that includes the
3344     current contents of its edit buffers, the location of the cursor and other
3345     aspects of the current editing session.
3346
3347     You should never exit the application within this function. Instead, the
3348     session manager may or may not do this afterwards, depending on the
3349     context. Futhermore, most session managers will very likely request a saved
3350     state immediately after the application has been started. This permits the
3351     session manager to learn about the application's restart policy.
3352
3353     \warning Within this function, no user interaction is possible, \e
3354     unless you ask the \a manager for explicit permission. See
3355     QSessionManager::allowsInteraction() and
3356     QSessionManager::allowsErrorInteraction() for details.
3357
3358     \sa isSessionRestored(), sessionId(), commitData(), {Session Management}
3359 */
3360
3361 void QApplication::saveState(QSessionManager &manager)
3362 {
3363     emit saveStateRequest(manager);
3364 }
3365 #endif //QT_NO_SESSIONMANAGER
3366 /*
3367   Sets the time after which a drag should start to \a ms ms.
3368
3369   \sa startDragTime()
3370 */
3371
3372 void QApplication::setStartDragTime(int ms)
3373 {
3374     Q_UNUSED(ms)
3375 }
3376
3377 /*!
3378     \property QApplication::startDragTime
3379     \brief the time in milliseconds that a mouse button must be held down
3380     before a drag and drop operation will begin
3381
3382     If you support drag and drop in your application, and want to start a drag
3383     and drop operation after the user has held down a mouse button for a
3384     certain amount of time, you should use this property's value as the delay.
3385
3386     Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, for
3387     starting a drag.
3388
3389     The default value is 500 ms.
3390
3391     \sa startDragDistance(), {Drag and Drop}
3392 */
3393
3394 int QApplication::startDragTime()
3395 {
3396     return qApp->styleHints()->startDragTime();
3397 }
3398
3399 /*
3400     Sets the distance after which a drag should start to \a l pixels.
3401
3402     \sa startDragDistance()
3403 */
3404
3405 void QApplication::setStartDragDistance(int l)
3406 {
3407     Q_UNUSED(l);
3408 }
3409
3410 /*!
3411     \property QApplication::startDragDistance
3412
3413     If you support drag and drop in your application, and want to start a drag
3414     and drop operation after the user has moved the cursor a certain distance
3415     with a button held down, you should use this property's value as the
3416     minimum distance required.
3417
3418     For example, if the mouse position of the click is stored in \c startPos
3419     and the current position (e.g. in the mouse move event) is \c currentPos,
3420     you can find out if a drag should be started with code like this:
3421
3422     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 7
3423
3424     Qt uses this value internally, e.g. in QFileDialog.
3425
3426     The default value is 4 pixels.
3427
3428     \sa startDragTime() QPoint::manhattanLength() {Drag and Drop}
3429 */
3430
3431 int QApplication::startDragDistance()
3432 {
3433     return qApp->styleHints()->startDragDistance();
3434 }
3435
3436 /*!
3437     \fn void QApplication::setReverseLayout(bool reverse)
3438
3439     Use setLayoutDirection() instead.
3440 */
3441
3442 /*!
3443     \fn void QApplication::reverseLayout()
3444
3445     Use layoutDirection() instead.
3446 */
3447
3448
3449 /*!
3450     \obsolete
3451
3452     Strips out vertical alignment flags and transforms an alignment \a align
3453     of Qt::AlignLeft into Qt::AlignLeft or Qt::AlignRight according to the
3454     language used.
3455 */
3456
3457
3458 /*!
3459     Enters the main event loop and waits until exit() is called, then returns
3460     the value that was set to exit() (which is 0 if exit() is called via
3461     quit()).
3462
3463     It is necessary to call this function to start event handling. The main
3464     event loop receives events from the window system and dispatches these to
3465     the application widgets.
3466
3467     Generally, no user interaction can take place before calling exec(). As a
3468     special case, modal widgets like QMessageBox can be used before calling
3469     exec(), because modal widgets call exec() to start a local event loop.
3470
3471     To make your application perform idle processing, i.e., executing a special
3472     function whenever there are no pending events, use a QTimer with 0 timeout.
3473     More advanced idle processing schemes can be achieved using processEvents().
3474
3475     We recommend that you connect clean-up code to the
3476     \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
3477     application's \c{main()} function. This is because, on some platforms the
3478     QApplication::exec() call may not return. For example, on the Windows
3479     platform, when the user logs off, the system terminates the process after Qt
3480     closes all top-level windows. Hence, there is \e{no guarantee} that the
3481     application will have time to exit its event loop and execute code at the
3482     end of the \c{main()} function, after the QApplication::exec() call.
3483
3484     \sa quitOnLastWindowClosed, quit(), exit(), processEvents(),
3485         QCoreApplication::exec()
3486 */
3487 int QApplication::exec()
3488 {
3489 #ifndef QT_NO_ACCESSIBILITY
3490     QAccessible::setRootObject(qApp);
3491 #endif
3492     return QApplicationBase::exec();
3493 }
3494
3495 /*! \reimp
3496  */
3497 bool QApplication::notify(QObject *receiver, QEvent *e)
3498 {
3499     Q_D(QApplication);
3500     // no events are delivered after ~QCoreApplication() has started
3501     if (QApplicationPrivate::is_app_closing)
3502         return true;
3503
3504     if (receiver == 0) {                        // serious error
3505         qWarning("QApplication::notify: Unexpected null receiver");
3506         return true;
3507     }
3508
3509 #ifndef QT_NO_DEBUG
3510     d->checkReceiverThread(receiver);
3511 #endif
3512
3513     // capture the current mouse/keyboard state
3514     if(e->spontaneous()) {
3515         if (e->type() == QEvent::KeyPress
3516             || e->type() == QEvent::KeyRelease) {
3517             QKeyEvent *ke = static_cast<QKeyEvent*>(e);
3518             QApplicationPrivate::modifier_buttons = ke->modifiers();
3519         } else if(e->type() == QEvent::MouseButtonPress
3520             || e->type() == QEvent::MouseButtonRelease) {
3521                 QMouseEvent *me = static_cast<QMouseEvent*>(e);
3522                 QApplicationPrivate::modifier_buttons = me->modifiers();
3523                 if(me->type() == QEvent::MouseButtonPress)
3524                     QApplicationPrivate::mouse_buttons |= me->button();
3525                 else
3526                     QApplicationPrivate::mouse_buttons &= ~me->button();
3527             }
3528 #if !defined(QT_NO_WHEELEVENT) || !defined(QT_NO_TABLETEVENT)
3529             else if (false
3530 #  ifndef QT_NO_WHEELEVENT
3531                      || e->type() == QEvent::Wheel
3532 #  endif
3533 #  ifndef QT_NO_TABLETEVENT
3534                      || e->type() == QEvent::TabletMove
3535                      || e->type() == QEvent::TabletPress
3536                      || e->type() == QEvent::TabletRelease
3537 #  endif
3538                      ) {
3539             QInputEvent *ie = static_cast<QInputEvent*>(e);
3540             QApplicationPrivate::modifier_buttons = ie->modifiers();
3541         }
3542 #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT
3543     }
3544
3545 #ifndef QT_NO_GESTURES
3546     // walk through parents and check for gestures
3547     if (d->gestureManager) {
3548         switch (e->type()) {
3549         case QEvent::Paint:
3550         case QEvent::MetaCall:
3551         case QEvent::DeferredDelete:
3552         case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
3553         case QEvent::Drop: case QEvent::DragResponse:
3554         case QEvent::ChildAdded: case QEvent::ChildPolished:
3555         case QEvent::ChildRemoved:
3556         case QEvent::UpdateRequest:
3557         case QEvent::UpdateLater:
3558         case QEvent::AccessibilityPrepare:
3559         case QEvent::LocaleChange:
3560         case QEvent::Style:
3561         case QEvent::IconDrag:
3562         case QEvent::StyleChange:
3563         case QEvent::AccessibilityHelp:
3564         case QEvent::AccessibilityDescription:
3565         case QEvent::GraphicsSceneDragEnter:
3566         case QEvent::GraphicsSceneDragMove:
3567         case QEvent::GraphicsSceneDragLeave:
3568         case QEvent::GraphicsSceneDrop:
3569         case QEvent::DynamicPropertyChange:
3570         case QEvent::NetworkReplyUpdated:
3571             break;
3572         default:
3573             if (receiver->isWidgetType()) {
3574                 if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
3575                     return true;
3576             } else {
3577                 // a special case for events that go to QGesture objects.
3578                 // We pass the object to the gesture manager and it'll figure
3579                 // out if it's QGesture or not.
3580                 if (d->gestureManager->filterEvent(receiver, e))
3581                     return true;
3582             }
3583         }
3584     }
3585 #endif // QT_NO_GESTURES
3586
3587     // User input and window activation makes tooltips sleep
3588     switch (e->type()) {
3589     case QEvent::Wheel:
3590     case QEvent::ActivationChange:
3591     case QEvent::KeyPress:
3592     case QEvent::KeyRelease:
3593     case QEvent::FocusOut:
3594     case QEvent::FocusIn:
3595     case QEvent::MouseButtonPress:
3596     case QEvent::MouseButtonRelease:
3597     case QEvent::MouseButtonDblClick:
3598         d->toolTipFallAsleep.stop();
3599         // fall-through
3600     case QEvent::Leave:
3601         d->toolTipWakeUp.stop();
3602     default:
3603         break;
3604     }
3605
3606     bool res = false;
3607     if (!receiver->isWidgetType()) {
3608         res = d->notify_helper(receiver, e);
3609     } else switch (e->type()) {
3610 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
3611     case QEvent::Accel:
3612         {
3613             if (d->use_compat()) {
3614                 QKeyEvent* key = static_cast<QKeyEvent*>(e);
3615                 res = d->notify_helper(receiver, e);
3616
3617                 if (!res && !key->isAccepted())
3618                     res = d->qt_dispatchAccelEvent(static_cast<QWidget *>(receiver), key);
3619
3620                 // next lines are for compatibility with Qt <= 3.0.x: old
3621                 // QAccel was listening on toplevel widgets
3622                 if (!res && !key->isAccepted() && !static_cast<QWidget *>(receiver)->isWindow())
3623                     res = d->notify_helper(static_cast<QWidget *>(receiver)->window(), e);
3624             }
3625             break;
3626         }
3627 #endif //QT3_SUPPORT && !QT_NO_SHORTCUT
3628     case QEvent::ShortcutOverride:
3629     case QEvent::KeyPress:
3630     case QEvent::KeyRelease:
3631         {
3632             bool isWidget = receiver->isWidgetType();
3633             bool isGraphicsWidget = false;
3634 #ifndef QT_NO_GRAPHICSVIEW
3635             isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver);
3636 #endif
3637             if (!isWidget && !isGraphicsWidget) {
3638                 res = d->notify_helper(receiver, e);
3639                 break;
3640             }
3641
3642             QKeyEvent* key = static_cast<QKeyEvent*>(e);
3643 #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT)
3644             if (d->use_compat() && d->qt_tryComposeUnicode(static_cast<QWidget*>(receiver), key))
3645                 break;
3646 #endif
3647             if (key->type()==QEvent::KeyPress) {
3648 #ifndef QT_NO_SHORTCUT
3649                 // Try looking for a Shortcut before sending key events
3650                 if ((res = qApp->d_func()->shortcutMap.tryShortcutEvent(receiver, key)))
3651                     return res;
3652 #endif
3653                 qt_in_tab_key_event = (key->key() == Qt::Key_Backtab
3654                                        || key->key() == Qt::Key_Tab
3655                                        || key->key() == Qt::Key_Left
3656                                        || key->key() == Qt::Key_Up
3657                                        || key->key() == Qt::Key_Right
3658                                        || key->key() == Qt::Key_Down);
3659             }
3660             bool def = key->isAccepted();
3661             QPointer<QObject> pr = receiver;
3662             while (receiver) {
3663                 if (def)
3664                     key->accept();
3665                 else
3666                     key->ignore();
3667                 res = d->notify_helper(receiver, e);
3668                 QWidget *w = isWidget ? static_cast<QWidget *>(receiver) : 0;
3669 #ifndef QT_NO_GRAPHICSVIEW
3670                 QGraphicsWidget *gw = isGraphicsWidget ? static_cast<QGraphicsWidget *>(receiver) : 0;
3671 #endif
3672
3673                 if ((res && key->isAccepted())
3674                     /*
3675                        QLineEdit will emit a signal on Key_Return, but
3676                        ignore the event, and sometimes the connected
3677                        slot deletes the QLineEdit (common in itemview
3678                        delegates), so we have to check if the widget
3679                        was destroyed even if the event was ignored (to
3680                        prevent a crash)
3681
3682                        note that we don't have to reset pw while
3683                        propagating (because the original receiver will
3684                        be destroyed if one of its ancestors is)
3685                     */
3686                     || !pr
3687                     || (isWidget && (w->isWindow() || !w->parentWidget()))
3688 #ifndef QT_NO_GRAPHICSVIEW
3689                     || (isGraphicsWidget && (gw->isWindow() || !gw->parentWidget()))
3690 #endif
3691                     ) {
3692                     break;
3693                 }
3694
3695 #ifndef QT_NO_GRAPHICSVIEW
3696                 receiver = w ? (QObject *)w->parentWidget() : (QObject *)gw->parentWidget();
3697 #else
3698                 receiver = w->parentWidget();
3699 #endif
3700             }
3701             qt_in_tab_key_event = false;
3702         }
3703         break;
3704     case QEvent::MouseButtonPress:
3705     case QEvent::MouseButtonRelease:
3706     case QEvent::MouseButtonDblClick:
3707     case QEvent::MouseMove:
3708         {
3709             QWidget* w = static_cast<QWidget *>(receiver);
3710
3711             QMouseEvent* mouse = static_cast<QMouseEvent*>(e);
3712             QPoint relpos = mouse->pos();
3713
3714             if (e->spontaneous()) {
3715
3716                 if (e->type() == QEvent::MouseButtonPress) {
3717                     QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
3718                                                                          Qt::ClickFocus,
3719                                                                          Qt::MouseFocusReason);
3720                 }
3721
3722                 // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
3723                 // like Mac OS X (probably others too), can optimize their views by not
3724                 // dispatching mouse move events. We have attributes to control hover,
3725                 // and mouse tracking, but as long as we are deciding to implement this
3726                 // feature without choice of opting-in or out, you ALWAYS have to have
3727                 // tracking enabled. Therefore, the other properties give a false sense of
3728                 // performance enhancement.
3729                 if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
3730                     d->toolTipWidget = w;
3731                     d->toolTipPos = relpos;
3732                     d->toolTipGlobalPos = mouse->globalPos();
3733                     d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
3734                 }
3735             }
3736
3737             bool eventAccepted = mouse->isAccepted();
3738
3739             QPointer<QWidget> pw = w;
3740             while (w) {
3741                 QMouseEvent me(mouse->type(), relpos, mouse->windowPos(), mouse->globalPos(), mouse->button(), mouse->buttons(),
3742                                mouse->modifiers());
3743                 me.spont = mouse->spontaneous();
3744                 me.setTimestamp(mouse->timestamp());
3745                 // throw away any mouse-tracking-only mouse events
3746                 if (!w->hasMouseTracking()
3747                     && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
3748                     // but still send them through all application event filters (normally done by notify_helper)
3749                     for (int i = 0; i < d->eventFilters.size(); ++i) {
3750                         register QObject *obj = d->eventFilters.at(i);
3751                         if (!obj)
3752                             continue;
3753                         if (obj->d_func()->threadData != w->d_func()->threadData) {
3754                             qWarning("QApplication: Object event filter cannot be in a different thread.");
3755                             continue;
3756                         }
3757                         if (obj->eventFilter(w, w == receiver ? mouse : &me))
3758                             break;
3759                     }
3760                     res = true;
3761                 } else {
3762                     w->setAttribute(Qt::WA_NoMouseReplay, false);
3763                     res = d->notify_helper(w, w == receiver ? mouse : &me);
3764                     e->spont = false;
3765                 }
3766                 eventAccepted = (w == receiver ? mouse : &me)->isAccepted();
3767                 if (res && eventAccepted)
3768                     break;
3769                 if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
3770                     break;
3771                 relpos += w->pos();
3772                 w = w->parentWidget();
3773             }
3774
3775             mouse->setAccepted(eventAccepted);
3776
3777             if (e->type() == QEvent::MouseMove) {
3778                 if (!pw)
3779                     break;
3780
3781                 w = static_cast<QWidget *>(receiver);
3782                 relpos = mouse->pos();
3783                 QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
3784                 while (w) {
3785                     if (w->testAttribute(Qt::WA_Hover) &&
3786                         (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
3787                         QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff, mouse->modifiers());
3788                         d->notify_helper(w, &he);
3789                     }
3790                     if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
3791                         break;
3792                     relpos += w->pos();
3793                     w = w->parentWidget();
3794                 }
3795             }
3796
3797             d->hoverGlobalPos = mouse->globalPos();
3798         }
3799         break;
3800 #ifndef QT_NO_WHEELEVENT
3801     case QEvent::Wheel:
3802         {
3803             QWidget* w = static_cast<QWidget *>(receiver);
3804             QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
3805             QPoint relpos = wheel->pos();
3806             bool eventAccepted = wheel->isAccepted();
3807
3808             if (e->spontaneous()) {
3809                 QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
3810                                                                      Qt::WheelFocus,
3811                                                                      Qt::MouseFocusReason);
3812             }
3813
3814             while (w) {
3815                 QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->buttons(),
3816                                wheel->modifiers(), wheel->orientation());
3817                 we.spont = wheel->spontaneous();
3818                 res = d->notify_helper(w, w == receiver ? wheel : &we);
3819                 eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
3820                 e->spont = false;
3821                 if ((res && eventAccepted)
3822                     || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
3823                     break;
3824
3825                 relpos += w->pos();
3826                 w = w->parentWidget();
3827             }
3828             wheel->setAccepted(eventAccepted);
3829         }
3830         break;
3831 #endif
3832 #ifndef QT_NO_CONTEXTMENU
3833     case QEvent::ContextMenu:
3834         {
3835             QWidget* w = static_cast<QWidget *>(receiver);
3836             QContextMenuEvent *context = static_cast<QContextMenuEvent*>(e);
3837             QPoint relpos = context->pos();
3838             bool eventAccepted = context->isAccepted();
3839             while (w) {
3840                 QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->modifiers());
3841                 ce.spont = e->spontaneous();
3842                 res = d->notify_helper(w, w == receiver ? context : &ce);
3843                 eventAccepted = ((w == receiver) ? context : &ce)->isAccepted();
3844                 e->spont = false;
3845
3846                 if ((res && eventAccepted)
3847                     || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
3848                     break;
3849
3850                 relpos += w->pos();
3851                 w = w->parentWidget();
3852             }
3853             context->setAccepted(eventAccepted);
3854         }
3855         break;
3856 #endif // QT_NO_CONTEXTMENU
3857 #ifndef QT_NO_TABLETEVENT
3858     case QEvent::TabletMove:
3859     case QEvent::TabletPress:
3860     case QEvent::TabletRelease:
3861         {
3862             QWidget *w = static_cast<QWidget *>(receiver);
3863             QTabletEvent *tablet = static_cast<QTabletEvent*>(e);
3864             QPoint relpos = tablet->pos();
3865             bool eventAccepted = tablet->isAccepted();
3866             while (w) {
3867                 QTabletEvent te(tablet->type(), relpos, tablet->globalPos(),
3868                                 tablet->hiResGlobalPos(), tablet->device(), tablet->pointerType(),
3869                                 tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
3870                                 tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
3871                                 tablet->modifiers(), tablet->uniqueId());
3872                 te.spont = e->spontaneous();
3873                 res = d->notify_helper(w, w == receiver ? tablet : &te);
3874                 eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
3875                 e->spont = false;
3876                 if ((res && eventAccepted)
3877                      || w->isWindow()
3878                      || w->testAttribute(Qt::WA_NoMousePropagation))
3879                     break;
3880
3881                 relpos += w->pos();
3882                 w = w->parentWidget();
3883             }
3884             tablet->setAccepted(eventAccepted);
3885             qt_tabletChokeMouse = tablet->isAccepted();
3886         }
3887         break;
3888 #endif // QT_NO_TABLETEVENT
3889
3890 #if !defined(QT_NO_TOOLTIP) || !defined(QT_NO_WHATSTHIS)
3891     case QEvent::ToolTip:
3892     case QEvent::WhatsThis:
3893     case QEvent::QueryWhatsThis:
3894         {
3895             QWidget* w = static_cast<QWidget *>(receiver);
3896             QHelpEvent *help = static_cast<QHelpEvent*>(e);
3897             QPoint relpos = help->pos();
3898             bool eventAccepted = help->isAccepted();
3899             while (w) {
3900                 QHelpEvent he(help->type(), relpos, help->globalPos());
3901                 he.spont = e->spontaneous();
3902                 res = d->notify_helper(w, w == receiver ? help : &he);
3903                 e->spont = false;
3904                 eventAccepted = (w == receiver ? help : &he)->isAccepted();
3905                 if ((res && eventAccepted) || w->isWindow())
3906                     break;
3907
3908                 relpos += w->pos();
3909                 w = w->parentWidget();
3910             }
3911             help->setAccepted(eventAccepted);
3912         }
3913         break;
3914 #endif
3915 #if !defined(QT_NO_STATUSTIP) || !defined(QT_NO_WHATSTHIS)
3916     case QEvent::StatusTip:
3917     case QEvent::WhatsThisClicked:
3918         {
3919             QWidget *w = static_cast<QWidget *>(receiver);
3920             while (w) {
3921                 res = d->notify_helper(w, e);
3922                 if ((res && e->isAccepted()) || w->isWindow())
3923                     break;
3924                 w = w->parentWidget();
3925             }
3926         }
3927         break;
3928 #endif
3929
3930 #ifndef QT_NO_DRAGANDDROP
3931     case QEvent::DragEnter: {
3932             QWidget* w = static_cast<QWidget *>(receiver);
3933             QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(e);
3934 #ifdef Q_WS_MAC
3935             // HIView has a slight difference in how it delivers events to children and parents
3936             // It will not give a leave to a child's parent when it enters a child.
3937             QWidget *currentTarget = QDragManager::self()->currentTarget();
3938             if (currentTarget) {
3939                 // Assume currentTarget did not get a leave
3940                 QDragLeaveEvent event;
3941                 QApplication::sendEvent(currentTarget, &event);
3942             }
3943 #endif
3944 #ifndef QT_NO_GRAPHICSVIEW
3945             // QGraphicsProxyWidget handles its own propagation,
3946             // and we must not change QDragManagers currentTarget.
3947             QWExtra *extra = w->window()->d_func()->extra;
3948             if (extra && extra->proxyWidget) {
3949                 res = d->notify_helper(w, dragEvent);
3950                 break;
3951             }
3952 #endif
3953             while (w) {
3954                 if (w->isEnabled() && w->acceptDrops()) {
3955                     res = d->notify_helper(w, dragEvent);
3956                     if (res && dragEvent->isAccepted()) {
3957                         QDragManager::self()->setCurrentTarget(w);
3958                         break;
3959                     }
3960                 }
3961                 if (w->isWindow())
3962                     break;
3963                 dragEvent->p = w->mapToParent(dragEvent->p);
3964                 w = w->parentWidget();
3965             }
3966         }
3967         break;
3968     case QEvent::DragMove:
3969     case QEvent::Drop:
3970     case QEvent::DragLeave: {
3971             QWidget* w = static_cast<QWidget *>(receiver);
3972 #ifndef QT_NO_GRAPHICSVIEW
3973             // QGraphicsProxyWidget handles its own propagation,
3974             // and we must not change QDragManagers currentTarget.
3975             QWExtra *extra = w->window()->d_func()->extra;
3976             bool isProxyWidget = extra && extra->proxyWidget;
3977             if (!isProxyWidget)
3978 #endif
3979                 w = qobject_cast<QWidget *>(QDragManager::self()->currentTarget());
3980
3981             if (!w) {
3982 #ifdef Q_WS_MAC
3983                 // HIView has a slight difference in how it delivers events to children and parents
3984                 // It will not give an enter to a child's parent when it leaves the child.
3985                 if (e->type() == QEvent::DragLeave)
3986                     break;
3987                 // Assume that w did not get an enter.
3988                 QDropEvent *dropEvent = static_cast<QDropEvent *>(e);
3989                 QDragEnterEvent dragEnterEvent(dropEvent->pos(), dropEvent->possibleActions(),
3990                                                dropEvent->mimeData(), dropEvent->mouseButtons(),
3991                                                dropEvent->keyboardModifiers());
3992                 QApplication::sendEvent(receiver, &dragEnterEvent);
3993                 w = QDragManager::self()->currentTarget();
3994                 if (!w)
3995 #endif
3996                     break;
3997             }
3998             if (e->type() == QEvent::DragMove || e->type() == QEvent::Drop) {
3999                 QDropEvent *dragEvent = static_cast<QDropEvent *>(e);
4000                 QWidget *origReciver = static_cast<QWidget *>(receiver);
4001                 while (origReciver && w != origReciver) {
4002                     dragEvent->p = origReciver->mapToParent(dragEvent->p);
4003                     origReciver = origReciver->parentWidget();
4004                 }
4005             }
4006             res = d->notify_helper(w, e);
4007             if (e->type() != QEvent::DragMove
4008 #ifndef QT_NO_GRAPHICSVIEW
4009                 && !isProxyWidget
4010 #endif
4011                 )
4012                 QDragManager::self()->setCurrentTarget(0, e->type() == QEvent::Drop);
4013         }
4014         break;
4015 #endif
4016     case QEvent::TouchBegin:
4017     // Note: TouchUpdate and TouchEnd events are never propagated
4018     {
4019         QWidget *widget = static_cast<QWidget *>(receiver);
4020         QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
4021         bool eventAccepted = touchEvent->isAccepted();
4022         if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
4023             // give the widget focus if the focus policy allows it
4024             QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
4025                                                                  Qt::ClickFocus,
4026                                                                  Qt::MouseFocusReason);
4027         }
4028
4029         while (widget) {
4030             // first, try to deliver the touch event
4031             bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
4032             touchEvent->setWidget(widget);
4033             touchEvent->setAccepted(acceptTouchEvents);
4034             QWeakPointer<QWidget> p = widget;
4035             res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
4036             eventAccepted = touchEvent->isAccepted();
4037             if (p.isNull()) {
4038                 // widget was deleted
4039                 widget = 0;
4040             } else {
4041                 widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
4042             }
4043             touchEvent->spont = false;
4044             if (res && eventAccepted) {
4045                 // the first widget to accept the TouchBegin gets an implicit grab.
4046                 for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
4047                     const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
4048                     d->widgetForTouchPointId[touchPoint.id()] = widget;
4049                 }
4050                 break;
4051             } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
4052                 break;
4053             }
4054             QPoint offset = widget->pos();
4055             widget = widget->parentWidget();
4056             touchEvent->setWidget(widget);
4057             for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
4058                 QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
4059                 QRectF rect = pt.rect();
4060                 rect.moveCenter(offset);
4061                 pt.d->rect = rect;
4062                 pt.d->startPos = pt.startPos() + offset;
4063                 pt.d->lastPos = pt.lastPos() + offset;
4064             }
4065         }
4066
4067         touchEvent->setAccepted(eventAccepted);
4068         break;
4069     }
4070     case QEvent::RequestSoftwareInputPanel:
4071         inputPanel()->show();
4072         break;
4073     case QEvent::CloseSoftwareInputPanel:
4074         inputPanel()->hide();
4075         break;
4076
4077 #ifndef QT_NO_GESTURES
4078     case QEvent::NativeGesture:
4079     {
4080         // only propagate the first gesture event (after the GID_BEGIN)
4081         QWidget *w = static_cast<QWidget *>(receiver);
4082         while (w) {
4083             e->ignore();
4084             res = d->notify_helper(w, e);
4085             if ((res && e->isAccepted()) || w->isWindow())
4086                 break;
4087             w = w->parentWidget();
4088         }
4089         break;
4090     }
4091     case QEvent::Gesture:
4092     case QEvent::GestureOverride:
4093     {
4094         if (receiver->isWidgetType()) {
4095             QWidget *w = static_cast<QWidget *>(receiver);
4096             QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
4097             QList<QGesture *> allGestures = gestureEvent->gestures();
4098
4099             bool eventAccepted = gestureEvent->isAccepted();
4100             bool wasAccepted = eventAccepted;
4101             while (w) {
4102                 // send only gestures the widget expects
4103                 QList<QGesture *> gestures;
4104                 QWidgetPrivate *wd = w->d_func();
4105                 for (int i = 0; i < allGestures.size();) {
4106                     QGesture *g = allGestures.at(i);
4107                     Qt::GestureType type = g->gestureType();
4108                     QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
4109                             wd->gestureContext.find(type);
4110                     bool deliver = contextit != wd->gestureContext.end() &&
4111                         (g->state() == Qt::GestureStarted || w == receiver ||
4112                          (contextit.value() & Qt::ReceivePartialGestures));
4113                     if (deliver) {
4114                         allGestures.removeAt(i);
4115                         gestures.append(g);
4116                     } else {
4117                         ++i;
4118                     }
4119                 }
4120                 if (!gestures.isEmpty()) { // we have gestures for this w
4121                     QGestureEvent ge(gestures);
4122                     ge.t = gestureEvent->t;
4123                     ge.spont = gestureEvent->spont;
4124                     ge.m_accept = wasAccepted;
4125                     ge.d_func()->accepted = gestureEvent->d_func()->accepted;
4126                     res = d->notify_helper(w, &ge);
4127                     gestureEvent->spont = false;
4128                     eventAccepted = ge.isAccepted();
4129                     for (int i = 0; i < gestures.size(); ++i) {
4130                         QGesture *g = gestures.at(i);
4131                         // Ignore res [event return value] because handling of multiple gestures
4132                         // packed into a single QEvent depends on not consuming the event
4133                         if (eventAccepted || ge.isAccepted(g)) {
4134                             // if the gesture was accepted, mark the target widget for it
4135                             gestureEvent->d_func()->targetWidgets[g->gestureType()] = w;
4136                             gestureEvent->setAccepted(g, true);
4137                         } else {
4138                             // if the gesture was explicitly ignored by the application,
4139                             // put it back so a parent can get it
4140                             allGestures.append(g);
4141                         }
4142                     }
4143                 }
4144                 if (allGestures.isEmpty()) // everything delivered
4145                     break;
4146                 if (w->isWindow())
4147                     break;
4148                 w = w->parentWidget();
4149             }
4150             foreach (QGesture *g, allGestures)
4151                 gestureEvent->setAccepted(g, false);
4152             gestureEvent->m_accept = false; // to make sure we check individual gestures
4153         } else {
4154             res = d->notify_helper(receiver, e);
4155         }
4156         break;
4157     }
4158 #endif // QT_NO_GESTURES
4159 #ifdef QT_MAC_USE_COCOA
4160     case QEvent::Enter:
4161         if (receiver->isWidgetType()) {
4162             QWidget *w = static_cast<QWidget *>(receiver);
4163             if (w->testAttribute(Qt::WA_AcceptTouchEvents))
4164                 qt_widget_private(w)->registerTouchWindow(true);
4165         }
4166         res = d->notify_helper(receiver, e);
4167     break;
4168     case QEvent::Leave:
4169         if (receiver->isWidgetType()) {
4170             QWidget *w = static_cast<QWidget *>(receiver);
4171             if (w->testAttribute(Qt::WA_AcceptTouchEvents))
4172                 qt_widget_private(w)->registerTouchWindow(false);
4173         }
4174         res = d->notify_helper(receiver, e);
4175     break;
4176 #endif
4177     default:
4178         res = d->notify_helper(receiver, e);
4179         break;
4180     }
4181
4182     return res;
4183 }
4184
4185 bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
4186 {
4187     // send to all application event filters
4188     if (sendThroughApplicationEventFilters(receiver, e))
4189         return true;
4190
4191     if (receiver->isWidgetType()) {
4192         QWidget *widget = static_cast<QWidget *>(receiver);
4193
4194 #if !defined(Q_WS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
4195         // toggle HasMouse widget state on enter and leave
4196         if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) &&
4197             (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window()))
4198             widget->setAttribute(Qt::WA_UnderMouse, true);
4199         else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave)
4200             widget->setAttribute(Qt::WA_UnderMouse, false);
4201 #endif
4202
4203         if (QLayout *layout=widget->d_func()->layout) {
4204             layout->widgetEvent(e);
4205         }
4206     }
4207
4208     // send to all receiver event filters
4209     if (sendThroughObjectEventFilters(receiver, e))
4210         return true;
4211
4212     // deliver the event
4213     bool consumed = receiver->event(e);
4214     e->spont = false;
4215     return consumed;
4216 }
4217
4218
4219 /*!
4220     \class QSessionManager
4221     \brief The QSessionManager class provides access to the session manager.
4222
4223     A session manager in a desktop environment (in which Qt GUI applications
4224     live) keeps track of a session, which is a group of running applications,
4225     each of which has a particular state. The state of an application contains
4226     (most notably) the documents the application has open and the position and
4227     size of its windows.
4228
4229     The session manager is used to save the session, e.g., when the machine is
4230     shut down, and to restore a session, e.g., when the machine is started up.
4231     We recommend that you use QSettings to save an application's settings,
4232     for example, window positions, recently used files, etc. When the
4233     application is restarted by the session manager, you can restore the
4234     settings.
4235
4236     QSessionManager provides an interface between the application and the
4237     session manager so that the program can work well with the session manager.
4238     In Qt, session management requests for action are handled by the two
4239     virtual functions QApplication::commitData() and QApplication::saveState().
4240     Both provide a reference to a session manager object as argument, to allow
4241     the application to communicate with the session manager. The session
4242     manager can only be accessed through these functions.
4243
4244     No user interaction is possible \e unless the application gets explicit
4245     permission from the session manager. You ask for permission by calling
4246     allowsInteraction() or, if it is really urgent, allowsErrorInteraction().
4247     Qt does not enforce this, but the session manager may.
4248
4249     You can try to abort the shutdown process by calling cancel(). The default
4250     commitData() function does this if some top-level window rejected its
4251     closeEvent().
4252
4253     For sophisticated session managers provided on Unix/X11, QSessionManager
4254     offers further possibilities to fine-tune an application's session
4255     management behavior: setRestartCommand(), setDiscardCommand(),
4256     setRestartHint(), setProperty(), requestPhase2(). See the respective
4257     function descriptions for further details.
4258
4259     \sa QApplication, {Session Management}
4260 */
4261
4262 /*! \enum QSessionManager::RestartHint
4263
4264     This enum type defines the circumstances under which this application wants
4265     to be restarted by the session manager. The current values are:
4266
4267     \value  RestartIfRunning    If the application is still running when the
4268                                 session is shut down, it wants to be restarted
4269                                 at the start of the next session.
4270
4271     \value  RestartAnyway       The application wants to be started at the
4272                                 start of the next session, no matter what.
4273                                 (This is useful for utilities that run just
4274                                 after startup and then quit.)
4275
4276     \value  RestartImmediately  The application wants to be started immediately
4277                                 whenever it is not running.
4278
4279     \value  RestartNever        The application does not want to be restarted
4280                                 automatically.
4281
4282     The default hint is \c RestartIfRunning.
4283 */
4284
4285
4286 /*!
4287     \fn QString QSessionManager::sessionId() const
4288
4289     Returns the identifier of the current session.
4290
4291     If the application has been restored from an earlier session, this
4292     identifier is the same as it was in the earlier session.
4293
4294     \sa sessionKey(), QApplication::sessionId()
4295 */
4296
4297 /*!
4298     \fn QString QSessionManager::sessionKey() const
4299
4300     Returns the session key in the current session.
4301
4302     If the application has been restored from an earlier session, this key is
4303     the same as it was when the previous session ended.
4304
4305     The session key changes with every call of commitData() or saveState().
4306
4307     \sa sessionId(), QApplication::sessionKey()
4308 */
4309
4310 /*!
4311     \fn void* QSessionManager::handle() const
4312
4313     \internal
4314 */
4315
4316 /*!
4317     \fn bool QSessionManager::allowsInteraction()
4318
4319     Asks the session manager for permission to interact with the user. Returns
4320     true if interaction is permitted; otherwise returns false.
4321
4322     The rationale behind this mechanism is to make it possible to synchronize
4323     user interaction during a shutdown. Advanced session managers may ask all
4324     applications simultaneously to commit their data, resulting in a much
4325     faster shutdown.
4326
4327     When the interaction is completed we strongly recommend releasing the user
4328     interaction semaphore with a call to release(). This way, other
4329     applications may get the chance to interact with the user while your
4330     application is still busy saving data. (The semaphore is implicitly
4331     released when the application exits.)
4332
4333     If the user decides to cancel the shutdown process during the interaction
4334     phase, you must tell the session manager that this has happened by calling
4335     cancel().
4336
4337     Here's an example of how an application's QApplication::commitData() might
4338     be implemented:
4339
4340     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 8
4341
4342     If an error occurred within the application while saving its data, you may
4343     want to try allowsErrorInteraction() instead.
4344
4345     \sa QApplication::commitData(), release(), cancel()
4346 */
4347
4348
4349 /*!
4350     \fn bool QSessionManager::allowsErrorInteraction()
4351
4352     Returns true if error interaction is permitted; otherwise returns false.
4353
4354     This is similar to allowsInteraction(), but also enables the application to
4355     tell the user about any errors that occur. Session managers may give error
4356     interaction requests higher priority, which means that it is more likely
4357     that an error interaction is permitted. However, you are still not
4358     guaranteed that the session manager will allow interaction.
4359
4360     \sa allowsInteraction(), release(), cancel()
4361 */
4362
4363 /*!
4364     \fn void QSessionManager::release()
4365
4366     Releases the session manager's interaction semaphore after an interaction
4367     phase.
4368
4369     \sa allowsInteraction(), allowsErrorInteraction()
4370 */
4371
4372 /*!
4373     \fn void QSessionManager::cancel()
4374
4375     Tells the session manager to cancel the shutdown process.  Applications
4376     should not call this function without asking the user first.
4377
4378     \sa allowsInteraction(), allowsErrorInteraction()
4379 */
4380
4381 /*!
4382     \fn void QSessionManager::setRestartHint(RestartHint hint)
4383
4384     Sets the application's restart hint to \a hint. On application startup, the
4385     hint is set to \c RestartIfRunning.
4386
4387     \note These flags are only hints, a session manager may or may not respect
4388     them.
4389
4390     We recommend setting the restart hint in QApplication::saveState() because
4391     most session managers perform a checkpoint shortly after an application's
4392     startup.
4393
4394     \sa restartHint()
4395 */
4396
4397 /*!
4398     \fn QSessionManager::RestartHint QSessionManager::restartHint() const
4399
4400     Returns the application's current restart hint. The default is
4401     \c RestartIfRunning.
4402
4403     \sa setRestartHint()
4404 */
4405
4406 /*!
4407     \fn void QSessionManager::setRestartCommand(const QStringList& command)
4408
4409     If the session manager is capable of restoring sessions it will execute
4410     \a command in order to restore the application. The command defaults to
4411
4412     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 9
4413
4414     The \c -session option is mandatory; otherwise QApplication cannot tell
4415     whether it has been restored or what the current session identifier is.
4416     See QApplication::isSessionRestored() and QApplication::sessionId() for
4417     details.
4418
4419     If your application is very simple, it may be possible to store the entire
4420     application state in additional command line options. This is usually a
4421     very bad idea because command lines are often limited to a few hundred
4422     bytes. Instead, use QSettings, temporary files, or a database for this
4423     purpose. By marking the data with the unique sessionId(), you will be able
4424     to restore the application in a future  session.
4425
4426     \sa restartCommand(), setDiscardCommand(), setRestartHint()
4427 */
4428
4429 /*!
4430     \fn QStringList QSessionManager::restartCommand() const
4431
4432     Returns the currently set restart command.
4433
4434     To iterate over the list, you can use the \l foreach pseudo-keyword:
4435
4436     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 10
4437
4438     \sa setRestartCommand(), restartHint()
4439 */
4440
4441 /*!
4442     \fn void QSessionManager::setDiscardCommand(const QStringList& list)
4443
4444     Sets the discard command to the given \a list.
4445
4446     \sa discardCommand(), setRestartCommand()
4447 */
4448
4449
4450 /*!
4451     \fn QStringList QSessionManager::discardCommand() const
4452
4453     Returns the currently set discard command.
4454
4455     To iterate over the list, you can use the \l foreach pseudo-keyword:
4456
4457     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 11
4458
4459     \sa setDiscardCommand(), restartCommand(), setRestartCommand()
4460 */
4461
4462 /*!
4463     \fn void QSessionManager::setManagerProperty(const QString &name, const QString &value)
4464     \overload
4465
4466     Low-level write access to the application's identification and state
4467     records are kept in the session manager.
4468
4469     The property called \a name has its value set to the string \a value.
4470 */
4471
4472 /*!
4473     \fn void QSessionManager::setManagerProperty(const QString& name,
4474                                                  const QStringList& value)
4475
4476     Low-level write access to the application's identification and state record
4477     are kept in the session manager.
4478
4479     The property called \a name has its value set to the string list \a value.
4480 */
4481
4482 /*!
4483     \fn bool QSessionManager::isPhase2() const
4484
4485     Returns true if the session manager is currently performing a second
4486     session management phase; otherwise returns false.
4487
4488     \sa requestPhase2()
4489 */
4490
4491 /*!
4492     \fn void QSessionManager::requestPhase2()
4493
4494     Requests a second session management phase for the application. The
4495     application may then return immediately from the QApplication::commitData()
4496     or QApplication::saveState() function, and they will be called again once
4497     most or all other applications have finished their session management.
4498
4499     The two phases are useful for applications such as the X11 window manager
4500     that need to store information about another application's windows and
4501     therefore have to wait until these applications have completed their
4502     respective session management tasks.
4503
4504     \note If another application has requested a second phase it may get called
4505     before, simultaneously with, or after your application's second phase.
4506
4507     \sa isPhase2()
4508 */
4509
4510 /*****************************************************************************
4511   Stubbed session management support
4512  *****************************************************************************/
4513 #ifndef QT_NO_SESSIONMANAGER
4514 #if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
4515
4516 #if defined(Q_OS_WINCE)
4517 HRESULT qt_CoCreateGuid(GUID* guid)
4518 {
4519     // We will use the following information to create the GUID
4520     // 1. absolute path to application
4521     wchar_t tempFilename[MAX_PATH];
4522     if (!GetModuleFileName(0, tempFilename, MAX_PATH))
4523         return S_FALSE;
4524     unsigned int hash = qHash(QString::fromWCharArray(tempFilename));
4525     guid->Data1 = hash;
4526     // 2. creation time of file
4527     QFileInfo info(QString::fromWCharArray(tempFilename));
4528     guid->Data2 = qHash(info.created().toTime_t());
4529     // 3. current system time
4530     guid->Data3 = qHash(QDateTime::currentDateTime().toTime_t());
4531     return S_OK;
4532 }
4533 #if !defined(OLE32_MCOMGUID) || defined(QT_WINCE_FORCE_CREATE_GUID)
4534 #define CoCreateGuid qt_CoCreateGuid
4535 #endif
4536
4537 #endif
4538
4539 class QSessionManagerPrivate : public QObjectPrivate
4540 {
4541 public:
4542     QStringList restartCommand;
4543     QStringList discardCommand;
4544     QString sessionId;
4545     QString sessionKey;
4546     QSessionManager::RestartHint restartHint;
4547 };
4548
4549 QSessionManager* qt_session_manager_self = 0;
4550 QSessionManager::QSessionManager(QApplication * app, QString &id, QString &key)
4551     : QObject(*new QSessionManagerPrivate, app)
4552 {
4553     Q_D(QSessionManager);
4554     setObjectName(QLatin1String("qt_sessionmanager"));
4555     qt_session_manager_self = this;
4556 #if defined(Q_WS_WIN)
4557     wchar_t guidstr[40];
4558     GUID guid;
4559     CoCreateGuid(&guid);
4560     StringFromGUID2(guid, guidstr, 40);
4561     id = QString::fromWCharArray(guidstr);
4562     CoCreateGuid(&guid);
4563     StringFromGUID2(guid, guidstr, 40);
4564     key = QString::fromWCharArray(guidstr);
4565 #endif
4566     d->sessionId = id;
4567     d->sessionKey = key;
4568     d->restartHint = RestartIfRunning;
4569 }
4570
4571 QSessionManager::~QSessionManager()
4572 {
4573     qt_session_manager_self = 0;
4574 }
4575
4576 QString QSessionManager::sessionId() const
4577 {
4578     Q_D(const QSessionManager);
4579     return d->sessionId;
4580 }
4581
4582 QString QSessionManager::sessionKey() const
4583 {
4584     Q_D(const QSessionManager);
4585     return d->sessionKey;
4586 }
4587
4588
4589 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
4590 void* QSessionManager::handle() const
4591 {
4592     return 0;
4593 }
4594 #endif
4595
4596 #if !defined(Q_WS_WIN)
4597 bool QSessionManager::allowsInteraction()
4598 {
4599     return true;
4600 }
4601
4602 bool QSessionManager::allowsErrorInteraction()
4603 {
4604     return true;
4605 }
4606 void QSessionManager::release()
4607 {
4608 }
4609
4610 void QSessionManager::cancel()
4611 {
4612 }
4613 #endif
4614
4615
4616 void QSessionManager::setRestartHint(QSessionManager::RestartHint hint)
4617 {
4618     Q_D(QSessionManager);
4619     d->restartHint = hint;
4620 }
4621
4622 QSessionManager::RestartHint QSessionManager::restartHint() const
4623 {
4624     Q_D(const QSessionManager);
4625     return d->restartHint;
4626 }
4627
4628 void QSessionManager::setRestartCommand(const QStringList& command)
4629 {
4630     Q_D(QSessionManager);
4631     d->restartCommand = command;
4632 }
4633
4634 QStringList QSessionManager::restartCommand() const
4635 {
4636     Q_D(const QSessionManager);
4637     return d->restartCommand;
4638 }
4639
4640 void QSessionManager::setDiscardCommand(const QStringList& command)
4641 {
4642     Q_D(QSessionManager);
4643     d->discardCommand = command;
4644 }
4645
4646 QStringList QSessionManager::discardCommand() const
4647 {
4648     Q_D(const QSessionManager);
4649     return d->discardCommand;
4650 }
4651
4652 void QSessionManager::setManagerProperty(const QString&, const QString&)
4653 {
4654 }
4655
4656 void QSessionManager::setManagerProperty(const QString&, const QStringList&)
4657 {
4658 }
4659
4660 bool QSessionManager::isPhase2() const
4661 {
4662     return false;
4663 }
4664
4665 void QSessionManager::requestPhase2()
4666 {
4667 }
4668
4669 #endif
4670 #endif // QT_NO_SESSIONMANAGER
4671
4672 /*!
4673     \typedef QApplication::ColorMode
4674     \compat
4675
4676     Use ColorSpec instead.
4677 */
4678
4679 /*!
4680     \fn Qt::MacintoshVersion QApplication::macVersion()
4681
4682     Use QSysInfo::MacintoshVersion instead.
4683 */
4684
4685 /*!
4686     \fn QApplication::ColorMode QApplication::colorMode()
4687
4688     Use colorSpec() instead, and use ColorSpec as the enum type.
4689 */
4690
4691 /*!
4692     \fn void QApplication::setColorMode(ColorMode mode)
4693
4694     Use setColorSpec() instead, and pass a ColorSpec value instead.
4695 */
4696
4697 /*!
4698     \fn bool QApplication::hasGlobalMouseTracking()
4699
4700     This feature does not exist anymore. This function always returns true
4701     in Qt 4.
4702 */
4703
4704 /*!
4705     \fn void QApplication::setGlobalMouseTracking(bool dummy)
4706
4707     This function does nothing in Qt 4. The \a dummy parameter is ignored.
4708 */
4709
4710 /*!
4711     \fn void QApplication::flushX()
4712
4713     Use flush() instead.
4714 */
4715
4716 /*!
4717     \fn void QApplication::setWinStyleHighlightColor(const QColor &c)
4718
4719     Use the palette instead.
4720
4721     \oldcode
4722     app.setWinStyleHighlightColor(color);
4723     \newcode
4724     QPalette palette(QApplication::palette());
4725     palette.setColor(QPalette::Highlight, color);
4726     QApplication::setPalette(palette);
4727     \endcode
4728 */
4729
4730 /*!
4731     \fn void QApplication::setPalette(const QPalette &pal, bool b, const char* className = 0)
4732
4733     Use the two-argument overload instead.
4734 */
4735
4736 /*!
4737     \fn void QApplication::setFont(const QFont &font, bool b, const char* className = 0)
4738
4739     Use the two-argument overload instead.
4740 */
4741
4742 /*!
4743     \fn const QColor &QApplication::winStyleHighlightColor()
4744
4745     Use QApplication::palette().color(QPalette::Active, QPalette::Highlight) instead.
4746 */
4747
4748 /*!
4749     \fn QWidget *QApplication::widgetAt(int x, int y, bool child)
4750
4751     Use the two-argument widgetAt() overload to get the child widget. To get
4752     the top-level widget do this:
4753
4754     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 12
4755 */
4756
4757 /*!
4758     \fn QWidget *QApplication::widgetAt(const QPoint &point, bool child)
4759
4760     Use the single-argument widgetAt() overload to get the child widget. To get
4761     the top-level widget do this:
4762
4763     \snippet doc/src/snippets/code/src_gui_kernel_qapplication.cpp 13
4764 */
4765
4766 bool QApplicationPrivate::inPopupMode() const
4767 {
4768     return QApplicationPrivate::popupWidgets != 0;
4769 }
4770
4771 /*!
4772     \property QApplication::quitOnLastWindowClosed
4773
4774     \brief whether the application implicitly quits when the last window is
4775     closed.
4776
4777     The default is true.
4778
4779     If this property is true, the applications quits when the last visible
4780     primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose
4781     attribute set is closed. By default this attribute is set for all widgets
4782     except for sub-windows. Refer to \l{Qt::WindowType} for a detailed list of
4783     Qt::Window objects.
4784
4785     \sa quit(), QWidget::close()
4786  */
4787
4788 void QApplication::setQuitOnLastWindowClosed(bool quit)
4789 {
4790     QApplicationPrivate::quitOnLastWindowClosed = quit;
4791 }
4792
4793 bool QApplication::quitOnLastWindowClosed()
4794 {
4795     return QApplicationPrivate::quitOnLastWindowClosed;
4796 }
4797
4798 void QApplicationPrivate::emitLastWindowClosed()
4799 {
4800     if (qApp && qApp->d_func()->in_exec) {
4801         if (QApplicationPrivate::quitOnLastWindowClosed) {
4802             // get ready to quit, this event might be removed if the
4803             // event loop is re-entered, however
4804             QApplication::postEvent(qApp, new QEvent(QEvent::Quit));
4805         }
4806         emit qApp->lastWindowClosed();
4807     }
4808 }
4809
4810 /*! \variable QApplication::NormalColors
4811     \compat
4812
4813     Use \l NormalColor instead.
4814 */
4815
4816 /*! \variable QApplication::CustomColors
4817     \compat
4818
4819     Use \l CustomColor instead.
4820 */
4821
4822 #ifdef QT_KEYPAD_NAVIGATION
4823 /*!
4824     Sets the kind of focus navigation Qt should use to \a mode.
4825
4826     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
4827     only.
4828
4829     \note On Windows CE this feature is disabled by default for touch device
4830           mkspecs. To enable keypad navigation, build Qt with
4831           QT_KEYPAD_NAVIGATION defined.
4832
4833     \note On Symbian, setting the mode to Qt::NavigationModeCursorAuto will enable a
4834           virtual mouse cursor on non touchscreen devices, which is controlled
4835           by the cursor keys if there is no analog pointer device.
4836           On other platforms and on touchscreen devices, it has the same
4837           meaning as Qt::NavigationModeNone.
4838
4839     \since 4.6
4840
4841     \sa keypadNavigationEnabled()
4842 */
4843 void QApplication::setNavigationMode(Qt::NavigationMode mode)
4844 {
4845 #ifdef Q_OS_SYMBIAN
4846     QApplicationPrivate::setNavigationMode(mode);
4847 #else
4848     QApplicationPrivate::navigationMode = mode;
4849 #endif
4850 }
4851
4852 /*!
4853     Returns what kind of focus navigation Qt is using.
4854
4855     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
4856     only.
4857
4858     \note On Windows CE this feature is disabled by default for touch device
4859           mkspecs. To enable keypad navigation, build Qt with
4860           QT_KEYPAD_NAVIGATION defined.
4861
4862     \note On Symbian, the default mode is Qt::NavigationModeNone for touch
4863           devices, and Qt::NavigationModeKeypadDirectional.
4864
4865     \since 4.6
4866
4867     \sa keypadNavigationEnabled()
4868 */
4869 Qt::NavigationMode QApplication::navigationMode()
4870 {
4871     return QApplicationPrivate::navigationMode;
4872 }
4873
4874 /*!
4875     Sets whether Qt should use focus navigation suitable for use with a
4876     minimal keypad.
4877
4878     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
4879     only.
4880
4881     \note On Windows CE this feature is disabled by default for touch device
4882           mkspecs. To enable keypad navigation, build Qt with
4883           QT_KEYPAD_NAVIGATION defined.
4884
4885     \deprecated
4886
4887     \sa setNavigationMode()
4888 */
4889 void QApplication::setKeypadNavigationEnabled(bool enable)
4890 {
4891     if (enable) {
4892 #ifdef Q_OS_SYMBIAN
4893         QApplication::setNavigationMode(Qt::NavigationModeKeypadDirectional);
4894 #else
4895         QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
4896 #endif
4897     }
4898     else {
4899         QApplication::setNavigationMode(Qt::NavigationModeNone);
4900     }
4901 }
4902
4903 /*!
4904     Returns true if Qt is set to use keypad navigation; otherwise returns
4905     false.  The default value is true on Symbian, but false on other platforms.
4906
4907     This feature is available in Qt for Embedded Linux, Symbian and Windows CE
4908     only.
4909
4910     \note On Windows CE this feature is disabled by default for touch device
4911           mkspecs. To enable keypad navigation, build Qt with
4912           QT_KEYPAD_NAVIGATION defined.
4913
4914     \deprecated
4915
4916     \sa navigationMode()
4917 */
4918 bool QApplication::keypadNavigationEnabled()
4919 {
4920     return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
4921         QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
4922 }
4923 #endif
4924
4925 /*!
4926     \fn void QApplication::alert(QWidget *widget, int msec)
4927     \since 4.3
4928
4929     Causes an alert to be shown for \a widget if the window is not the active
4930     window. The alert is shown for \a msec miliseconds. If \a msec is zero (the
4931     default), then the alert is shown indefinitely until the window becomes
4932     active again.
4933
4934     Currently this function does nothing on Qt for Embedded Linux.
4935
4936     On Mac OS X, this works more at the application level and will cause the
4937     application icon to bounce in the dock.
4938
4939     On Windows, this causes the window's taskbar entry to flash for a time. If
4940     \a msec is zero, the flashing will stop and the taskbar entry will turn a
4941     different color (currently orange).
4942
4943     On X11, this will cause the window to be marked as "demands attention", the
4944     window must not be hidden (i.e. not have hide() called on it, but be
4945     visible in some sort of way) in order for this to work.
4946 */
4947
4948 /*!
4949     \property QApplication::cursorFlashTime
4950     \brief the text cursor's flash (blink) time in milliseconds
4951
4952     The flash time is the time required to display, invert and restore the
4953     caret display. Usually the text cursor is displayed for half the cursor
4954     flash time, then hidden for the same amount of time, but this may vary.
4955
4956     The default value on X11 is 1000 milliseconds. On Windows, the
4957     \gui{Control Panel} value is used and setting this property sets the cursor
4958     flash time for all applications.
4959
4960     We recommend that widgets do not cache this value as it may change at any
4961     time if the user changes the global desktop settings.
4962 */
4963 void QApplication::setCursorFlashTime(int msecs)
4964 {
4965     Q_UNUSED(msecs);
4966 }
4967
4968 int QApplication::cursorFlashTime()
4969 {
4970     return qApp->styleHints()->cursorFlashTime();
4971 }
4972
4973
4974 /*!
4975     \property QApplication::doubleClickInterval
4976     \brief the time limit in milliseconds that distinguishes a double click
4977     from two consecutive mouse clicks
4978
4979     The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
4980     operating system's value is used.
4981
4982     Setting the interval is not supported anymore in Qt 5.
4983 */
4984 void QApplication::setDoubleClickInterval(int ms)
4985 {
4986     Q_UNUSED(ms);
4987 }
4988
4989 int QApplication::doubleClickInterval()
4990 {
4991     return qApp->styleHints()->mouseDoubleClickInterval();
4992 }
4993
4994 /*!
4995     \property QApplication::keyboardInputInterval
4996     \brief the time limit in milliseconds that distinguishes a key press
4997     from two consecutive key presses
4998     \since 4.2
4999
5000     The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
5001     operating system's value is used.
5002 */
5003 void QApplication::setKeyboardInputInterval(int ms)
5004 {
5005     Q_UNUSED(ms);
5006 }
5007
5008 int QApplication::keyboardInputInterval()
5009 {
5010     return qApp->styleHints()->keyboardInputInterval();
5011 }
5012
5013 /*!
5014     \property QApplication::wheelScrollLines
5015     \brief the number of lines to scroll a widget, when the
5016     mouse wheel is rotated.
5017
5018     If the value exceeds the widget's number of visible lines, the widget
5019     should interpret the scroll operation as a single \e{page up} or
5020     \e{page down}. If the widget is an \l{QAbstractItemView}{item view class},
5021     then the result of scrolling one \e line depends on the setting of the
5022     widget's \l{QAbstractItemView::verticalScrollMode()}{scroll mode}. Scroll
5023     one \e line can mean \l{QAbstractItemView::ScrollPerItem}{scroll one item}
5024     or \l{QAbstractItemView::ScrollPerPixel}{scroll one pixel}.
5025
5026     By default, this property has a value of 3.
5027 */
5028
5029 /*!
5030     \fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
5031
5032     Enables the UI effect \a effect if \a enable is true, otherwise the effect
5033     will not be used.
5034
5035     \note All effects are disabled on screens running at less than 16-bit color
5036     depth.
5037
5038     \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
5039 */
5040
5041 /*!
5042     \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect)
5043
5044     Returns true if \a effect is enabled; otherwise returns false.
5045
5046     By default, Qt will try to use the desktop settings. To prevent this, call
5047     setDesktopSettingsAware(false).
5048
5049     \note All effects are disabled on screens running at less than 16-bit color
5050     depth.
5051
5052     \sa setEffectEnabled(), Qt::UIEffect
5053 */
5054
5055 /*!
5056     \fn QWidget *QApplication::mainWidget()
5057
5058     Returns the main application widget, or 0 if there is no main widget.
5059 */
5060
5061 /*!
5062     \fn void QApplication::setMainWidget(QWidget *mainWidget)
5063
5064     Sets the application's main widget to \a mainWidget.
5065
5066     In most respects the main widget is like any other widget, except that if
5067     it is closed, the application exits. QApplication does \e not take
5068     ownership of the \a mainWidget, so if you create your main widget on the
5069     heap you must delete it yourself.
5070
5071     You need not have a main widget; connecting lastWindowClosed() to quit()
5072     is an alternative.
5073
5074     On X11, this function also resizes and moves the main widget according
5075     to the \e -geometry command-line option, so you should set the default
5076     geometry (using \l QWidget::setGeometry()) before calling setMainWidget().
5077
5078     \sa mainWidget(), exec(), quit()
5079 */
5080
5081 /*!
5082     \fn void QApplication::beep()
5083
5084     Sounds the bell, using the default volume and sound. The function is \e not
5085     available in Qt for Embedded Linux.
5086 */
5087
5088
5089 /*!
5090     \macro qApp
5091     \relates QApplication
5092
5093     A global pointer referring to the unique application object. It is
5094     equivalent to the pointer returned by the QCoreApplication::instance()
5095     function except that, in GUI applications, it is a pointer to a
5096     QApplication instance.
5097
5098     Only one application object can be created.
5099
5100     \sa QCoreApplication::instance()
5101 */
5102
5103 #ifndef QT_NO_IM
5104 // ************************************************************************
5105 // Input Method support
5106 // ************************************************************************
5107
5108 /*!
5109     This function replaces the QInputContext instance used by the application
5110     with \a inputContext.
5111
5112     Qt takes ownership of the given \a inputContext.
5113
5114     \sa inputContext()
5115 */
5116 void QApplication::setInputContext(QInputContext *inputContext)
5117 {
5118     if (inputContext == QApplicationPrivate::inputContext)
5119         return;
5120     if (!inputContext) {
5121         qWarning("QApplication::setInputContext: called with 0 input context");
5122         return;
5123     }
5124     delete QApplicationPrivate::inputContext;
5125     QApplicationPrivate::inputContext = inputContext;
5126     QApplicationPrivate::inputContext->setParent(this);
5127 }
5128
5129 /*!
5130     Returns the QInputContext instance used by the application.
5131
5132     \sa setInputContext()
5133 */
5134 QInputContext *QApplication::inputContext() const
5135 {
5136     return QApplicationPrivate::inputContext;
5137 }
5138 #endif // QT_NO_IM
5139
5140 bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
5141 {
5142     return QApplicationBase::sendSpontaneousEvent(receiver, event);
5143 }
5144
5145
5146 void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
5147                                                           Qt::FocusPolicy focusPolicy,
5148                                                           Qt::FocusReason focusReason)
5149 {
5150     QWidget *focusWidget = widget;
5151     while (focusWidget) {
5152         if (focusWidget->isEnabled()
5153             && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
5154             focusWidget->setFocus(focusReason);
5155             break;
5156         }
5157         if (focusWidget->isWindow())
5158             break;
5159         focusWidget = focusWidget->parentWidget();
5160     }
5161 }
5162
5163 bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
5164 {
5165     QWidget *f = w;
5166     while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
5167         f = f->d_func()->extra->focus_proxy;
5168
5169     if ((w->focusPolicy() & policy) != policy)
5170         return false;
5171     if (w != f && (f->focusPolicy() & policy) != policy)
5172         return false;
5173     return true;
5174 }
5175
5176 /*! \fn QDecoration &QApplication::qwsDecoration()
5177     Return the QWSDecoration used for decorating windows.
5178
5179     \warning This method is non-portable. It is only available in
5180     Qt for Embedded Linux.
5181
5182     \sa QDecoration
5183 */
5184
5185 /*!
5186     \fn void QApplication::qwsSetDecoration(QDecoration *decoration)
5187
5188     Sets the QDecoration derived class to use for decorating the
5189     windows used by Qt for Embedded Linux to the \a decoration
5190     specified.
5191
5192     This method is non-portable. It is only available in Qt for Embedded Linux.
5193
5194     \sa QDecoration
5195 */
5196
5197 /*! \fn QDecoration* QApplication::qwsSetDecoration(const QString &decoration)
5198     \overload
5199
5200     Requests a QDecoration object for \a decoration from the
5201     QDecorationFactory.
5202
5203     The string must be one of the QDecorationFactory::keys(). Keys are case
5204     insensitive.
5205
5206     A later call to the QApplication constructor will override the requested
5207     style when a "-style" option is passed in as a commandline parameter.
5208
5209     Returns 0 if an unknown \a decoration is passed, otherwise the QStyle object
5210     returned is set as the application's GUI style.
5211 */
5212
5213 /*!
5214     \fn bool QApplication::qwsEventFilter(QWSEvent *event)
5215
5216     This virtual function is only implemented under Qt for Embedded Linux.
5217
5218     If you create an application that inherits QApplication and
5219     reimplement this function, you get direct access to all QWS (Q
5220     Window System) events that the are received from the QWS master
5221     process. The events are passed in the \a event parameter.
5222
5223     Return true if you want to stop the event from being processed.
5224     Return false for normal event dispatching. The default
5225     implementation returns false.
5226 */
5227
5228 /*! \fn void QApplication::qwsSetCustomColors(QRgb *colorTable, int start, int numColors)
5229     Set Qt for Embedded Linux custom color table.
5230
5231     Qt for Embedded Linux on 8-bpp displays allocates a standard 216 color cube.
5232     The remaining 40 colors may be used by setting a custom color
5233     table in the QWS master process before any clients connect.
5234
5235     \a colorTable is an array of up to 40 custom colors. \a start is
5236     the starting index (0-39) and \a numColors is the number of colors
5237     to be set (1-40).
5238
5239     This method is non-portable. It is available \e only in
5240     Qt for Embedded Linux.
5241
5242     \note The custom colors will not be used by the default screen
5243     driver. To make use of the new colors, implement a custom screen
5244     driver, or use QDirectPainter.
5245 */
5246
5247 /*! \fn int QApplication::qwsProcessEvent(QWSEvent* event)
5248     \internal
5249 */
5250
5251 /*! \fn int QApplication::x11ClientMessage(QWidget* w, XEvent* event, bool passive_only)
5252     \internal
5253 */
5254
5255 /*! \fn int QApplication::x11ProcessEvent(XEvent* event)
5256     This function does the core processing of individual X
5257     \a{event}s, normally by dispatching Qt events to the right
5258     destination.
5259
5260     It returns 1 if the event was consumed by special handling, 0 if
5261     the \a event was consumed by normal handling, and -1 if the \a
5262     event was for an unrecognized widget.
5263
5264     \sa x11EventFilter()
5265 */
5266
5267 /*!
5268     \fn bool QApplication::x11EventFilter(XEvent *event)
5269
5270     \warning This virtual function is only implemented under X11.
5271
5272     If you create an application that inherits QApplication and
5273     reimplement this function, you get direct access to all X events
5274     that the are received from the X server. The events are passed in
5275     the \a event parameter.
5276
5277     Return true if you want to stop the event from being processed.
5278     Return false for normal event dispatching. The default
5279     implementation returns false.
5280
5281     It is only the directly addressed messages that are filtered.
5282     You must install an event filter directly on the event
5283     dispatcher, which is returned by
5284     QAbstractEventDispatcher::instance(), to handle system wide
5285     messages.
5286
5287     \sa x11ProcessEvent()
5288 */
5289
5290 /*! \fn void QApplication::winFocus(QWidget *widget, bool gotFocus)
5291     \internal
5292     \since 4.1
5293
5294     If \a gotFocus is true, \a widget will become the active window.
5295     Otherwise the active window is reset to 0.
5296 */
5297
5298 /*! \fn void QApplication::winMouseButtonUp()
5299   \internal
5300  */
5301
5302 /*! \fn void QApplication::syncX()
5303   Synchronizes with the X server in the X11 implementation.
5304   This normally takes some time. Does nothing on other platforms.
5305 */
5306
5307 void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
5308 {
5309     for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
5310         QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
5311
5312         // preserve the sub-pixel resolution
5313         QRectF rect = touchPoint.screenRect();
5314         const QPointF screenPos = rect.center();
5315         const QPointF delta = screenPos - screenPos.toPoint();
5316
5317         rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
5318         touchPoint.d->rect = rect;
5319         if (touchPoint.state() == Qt::TouchPointPressed) {
5320             touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
5321             touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
5322         }
5323     }
5324 }
5325
5326 void QApplicationPrivate::initializeMultitouch()
5327 {
5328     widgetForTouchPointId.clear();
5329     appCurrentTouchPoints.clear();
5330
5331     initializeMultitouch_sys();
5332 }
5333
5334 void QApplicationPrivate::cleanupMultitouch()
5335 {
5336     cleanupMultitouch_sys();
5337
5338     widgetForTouchPointId.clear();
5339     appCurrentTouchPoints.clear();
5340 }
5341
5342 int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos)
5343 {
5344     int closestTouchPointId = -1;
5345     qreal closestDistance = qreal(0.);
5346     foreach (const QTouchEvent::TouchPoint &touchPoint, appCurrentTouchPoints) {
5347         qreal distance = QLineF(screenPos, touchPoint.screenPos()).length();
5348         if (closestTouchPointId == -1 || distance < closestDistance) {
5349             closestTouchPointId = touchPoint.id();
5350             closestDistance = distance;
5351         }
5352     }
5353     return closestTouchPointId;
5354 }
5355
5356 void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
5357                                                  QTouchEvent::DeviceType deviceType,
5358                                                  const QList<QTouchEvent::TouchPoint> &touchPoints)
5359 {
5360     QApplicationPrivate *d = self;
5361     typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
5362     QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
5363
5364     for (int i = 0; i < touchPoints.count(); ++i) {
5365         QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
5366         // explicitly detach from the original touch point that we got, so even
5367         // if the touchpoint structs are reused, we will make a copy that we'll
5368         // deliver to the user (which might want to store the struct for later use).
5369         touchPoint.d = touchPoint.d->detach();
5370
5371         // update state
5372         QWeakPointer<QWidget> widget;
5373         switch (touchPoint.state()) {
5374         case Qt::TouchPointPressed:
5375         {
5376             if (deviceType == QTouchEvent::TouchPad) {
5377                 // on touch-pads, send all touch points to the same widget
5378                 widget = d->widgetForTouchPointId.isEmpty()
5379                          ? QWeakPointer<QWidget>()
5380                          : d->widgetForTouchPointId.constBegin().value();
5381             }
5382
5383             if (!widget) {
5384                 // determine which widget this event will go to
5385                 if (!window)
5386                     window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
5387                 if (!window)
5388                     continue;
5389                 widget = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
5390                 if (!widget)
5391                     widget = window;
5392             }
5393
5394             if (deviceType == QTouchEvent::TouchScreen) {
5395                 int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos());
5396                 QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data();
5397                 if (closestWidget
5398                     && (widget.data()->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget.data()))) {
5399                     widget = closestWidget;
5400                 }
5401             }
5402
5403             d->widgetForTouchPointId[touchPoint.id()] = widget;
5404             touchPoint.d->startScreenPos = touchPoint.screenPos();
5405             touchPoint.d->lastScreenPos = touchPoint.screenPos();
5406             touchPoint.d->startNormalizedPos = touchPoint.normalizedPos();
5407             touchPoint.d->lastNormalizedPos = touchPoint.normalizedPos();
5408             if (touchPoint.pressure() < qreal(0.))
5409                 touchPoint.d->pressure = qreal(1.);
5410
5411             d->appCurrentTouchPoints.insert(touchPoint.id(), touchPoint);
5412             break;
5413         }
5414         case Qt::TouchPointReleased:
5415         {
5416             widget = d->widgetForTouchPointId.take(touchPoint.id());
5417             if (!widget)
5418                 continue;
5419
5420             QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.take(touchPoint.id());
5421             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
5422             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
5423             touchPoint.d->startPos = previousTouchPoint.startPos();
5424             touchPoint.d->lastPos = previousTouchPoint.pos();
5425             touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
5426             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
5427             if (touchPoint.pressure() < qreal(0.))
5428                 touchPoint.d->pressure = qreal(0.);
5429             break;
5430         }
5431         default:
5432             widget = d->widgetForTouchPointId.value(touchPoint.id());
5433             if (!widget)
5434                 continue;
5435
5436             Q_ASSERT(d->appCurrentTouchPoints.contains(touchPoint.id()));
5437             QTouchEvent::TouchPoint previousTouchPoint = d->appCurrentTouchPoints.value(touchPoint.id());
5438             touchPoint.d->startScreenPos = previousTouchPoint.startScreenPos();
5439             touchPoint.d->lastScreenPos = previousTouchPoint.screenPos();
5440             touchPoint.d->startPos = previousTouchPoint.startPos();
5441             touchPoint.d->lastPos = previousTouchPoint.pos();
5442             touchPoint.d->startNormalizedPos = previousTouchPoint.startNormalizedPos();
5443             touchPoint.d->lastNormalizedPos = previousTouchPoint.normalizedPos();
5444             if (touchPoint.pressure() < qreal(0.))
5445                 touchPoint.d->pressure = qreal(1.);
5446             d->appCurrentTouchPoints[touchPoint.id()] = touchPoint;
5447             break;
5448         }
5449         Q_ASSERT(widget.data() != 0);
5450
5451         // make the *scene* functions return the same as the *screen* functions
5452         touchPoint.d->sceneRect = touchPoint.screenRect();
5453         touchPoint.d->startScenePos = touchPoint.startScreenPos();
5454         touchPoint.d->lastScenePos = touchPoint.lastScreenPos();
5455
5456         StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[widget.data()];
5457         maskAndPoints.first |= touchPoint.state();
5458         if (touchPoint.isPrimary())
5459             maskAndPoints.first |= Qt::TouchPointPrimary;
5460         maskAndPoints.second.append(touchPoint);
5461     }
5462
5463     if (widgetsNeedingEvents.isEmpty())
5464         return;
5465
5466     QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
5467     const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
5468     for (; it != end; ++it) {
5469         QWidget *widget = it.key();
5470         if (!QApplicationPrivate::tryModalHelper(widget, 0))
5471             continue;
5472
5473         QEvent::Type eventType;
5474         switch (it.value().first & Qt::TouchPointStateMask) {
5475         case Qt::TouchPointPressed:
5476             eventType = QEvent::TouchBegin;
5477             break;
5478         case Qt::TouchPointReleased:
5479             eventType = QEvent::TouchEnd;
5480             break;
5481         case Qt::TouchPointStationary:
5482             // don't send the event if nothing changed
5483             continue;
5484         default:
5485             eventType = QEvent::TouchUpdate;
5486             break;
5487         }
5488
5489         QTouchEvent touchEvent(eventType,
5490                                deviceType,
5491                                QApplication::keyboardModifiers(),
5492                                it.value().first,
5493                                it.value().second);
5494         updateTouchPointsForWidget(widget, &touchEvent);
5495
5496         switch (touchEvent.type()) {
5497         case QEvent::TouchBegin:
5498         {
5499             // if the TouchBegin handler recurses, we assume that means the event
5500             // has been implicitly accepted and continue to send touch events
5501             widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
5502             (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
5503             break;
5504         }
5505         default:
5506             if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
5507                 if (touchEvent.type() == QEvent::TouchEnd)
5508                     widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
5509                 (void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
5510             }
5511             break;
5512         }
5513     }
5514 }
5515
5516 Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window,
5517                                             QTouchEvent::DeviceType deviceType,
5518                                             const QList<QTouchEvent::TouchPoint> &touchPoints)
5519 {
5520     QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints);
5521 }
5522
5523 #ifndef QT_NO_GESTURES
5524 QGestureManager* QGestureManager::instance()
5525 {
5526     QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
5527     if (!qAppPriv)
5528         return 0;
5529     if (!qAppPriv->gestureManager)
5530         qAppPriv->gestureManager = new QGestureManager(qApp);
5531     return qAppPriv->gestureManager;
5532 }
5533 #endif // QT_NO_GESTURES
5534
5535 QT_END_NAMESPACE
5536
5537 #include "moc_qapplication.cpp"