~ubuntu-branches/ubuntu/wily/qtbase-opensource-src/wily

« back to all changes in this revision

Viewing changes to src/widgets/kernel/qapplication.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-02-05 12:46:17 UTC
  • Revision ID: package-import@ubuntu.com-20130205124617-c8jouts182j002fx
Tags: upstream-5.0.1+dfsg
ImportĀ upstreamĀ versionĀ 5.0.1+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtGui module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include "qplatformdefs.h"
 
43
#include "qabstracteventdispatcher.h"
 
44
#include "qapplication.h"
 
45
#include "qclipboard.h"
 
46
#include "qcursor.h"
 
47
#include "qdesktopwidget.h"
 
48
#include "qdir.h"
 
49
#include "qevent.h"
 
50
#include "qfile.h"
 
51
#include "qfileinfo.h"
 
52
#include "qgraphicsscene.h"
 
53
#include "qhash.h"
 
54
#include "qset.h"
 
55
#include "qlayout.h"
 
56
#include "qstyle.h"
 
57
#include "qstyleoption.h"
 
58
#include "qstylefactory.h"
 
59
#include "qtextcodec.h"
 
60
#include "qtranslator.h"
 
61
#include "qvariant.h"
 
62
#include "qwidget.h"
 
63
#include "private/qdnd_p.h"
 
64
#include "private/qguiapplication_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 "qwidgetwindow_qpa_p.h"
 
71
#include <QtWidgets/qgraphicsproxywidget.h>
 
72
#include <QtGui/qstylehints.h>
 
73
#include <QtGui/qinputmethod.h>
 
74
#include <qpa/qplatformtheme.h>
 
75
 
 
76
#include "private/qkeymapper_p.h"
 
77
 
 
78
#include <qthread.h>
 
79
#include <private/qthread_p.h>
 
80
 
 
81
#include <private/qfont_p.h>
 
82
 
 
83
#include <stdlib.h>
 
84
 
 
85
#include "qapplication_p.h"
 
86
#include "private/qevent_p.h"
 
87
#include "qwidget_p.h"
 
88
 
 
89
#include "qgesture.h"
 
90
#include "private/qgesturemanager_p.h"
 
91
#include <qpa/qplatformfontdatabase.h>
 
92
#ifndef QT_NO_LIBRARY
 
93
#include "qlibrary.h"
 
94
#endif
 
95
 
 
96
#include "qdatetime.h"
 
97
 
 
98
#ifdef Q_OS_WINCE
 
99
extern bool qt_wince_is_smartphone(); //qguifunctions_wince.cpp
 
100
extern bool qt_wince_is_mobile();     //qguifunctions_wince.cpp
 
101
extern bool qt_wince_is_pocket_pc();  //qguifunctions_wince.cpp
 
102
#endif
 
103
 
 
104
#include <qpa/qplatformwindow.h>
 
105
 
 
106
//#define ALIEN_DEBUG
 
107
 
 
108
static void initResources()
 
109
{
 
110
#if defined(Q_OS_WINCE)
 
111
    Q_INIT_RESOURCE_EXTERN(qstyle_wince)
 
112
    Q_INIT_RESOURCE(qstyle_wince);
 
113
#else
 
114
    Q_INIT_RESOURCE_EXTERN(qstyle)
 
115
    Q_INIT_RESOURCE(qstyle);
 
116
#endif
 
117
    Q_INIT_RESOURCE_EXTERN(qmessagebox)
 
118
    Q_INIT_RESOURCE(qmessagebox);
 
119
 
 
120
}
 
121
 
 
122
QT_BEGIN_NAMESPACE
 
123
 
 
124
Q_CORE_EXPORT void qt_call_post_routines();
 
125
 
 
126
QApplicationPrivate *QApplicationPrivate::self = 0;
 
127
 
 
128
static void initSystemPalette()
 
129
{
 
130
    if (!QApplicationPrivate::sys_pal) {
 
131
        QPalette defaultPlatte;
 
132
        if (QApplicationPrivate::app_style)
 
133
            defaultPlatte = QApplicationPrivate::app_style->standardPalette();
 
134
        if (const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette()) {
 
135
            QApplicationPrivate::setSystemPalette(themePalette->resolve(defaultPlatte));
 
136
            QApplicationPrivate::initializeWidgetPaletteHash();
 
137
        } else {
 
138
            QApplicationPrivate::setSystemPalette(defaultPlatte);
 
139
        }
 
140
    }
 
141
}
 
142
 
 
143
static void clearSystemPalette()
 
144
{
 
145
    delete QApplicationPrivate::sys_pal;
 
146
    QApplicationPrivate::sys_pal = 0;
 
147
}
 
148
 
 
149
#ifdef Q_OS_WINCE
 
150
int QApplicationPrivate::autoMaximizeThreshold = -1;
 
151
bool QApplicationPrivate::autoSipEnabled = false;
 
152
#else
 
153
bool QApplicationPrivate::autoSipEnabled = true;
 
154
#endif
 
155
 
 
156
QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, int flags)
 
157
    : QApplicationPrivateBase(argc, argv, flags)
 
158
{
 
159
    application_type = QApplicationPrivate::Gui;
 
160
 
 
161
#ifndef QT_NO_GESTURES
 
162
    gestureManager = 0;
 
163
    gestureWidget = 0;
 
164
#endif // QT_NO_GESTURES
 
165
 
 
166
    if (!self)
 
167
        self = this;
 
168
}
 
169
 
 
170
QApplicationPrivate::~QApplicationPrivate()
 
171
{
 
172
    if (self == this)
 
173
        self = 0;
 
174
}
 
175
 
 
176
/*!
 
177
    \class QApplication
 
178
    \brief The QApplication class manages the GUI application's control
 
179
    flow and main settings.
 
180
 
 
181
    \inmodule QtWidgets
 
182
 
 
183
    QApplication specializes QGuiApplication with some functionality needed
 
184
    for QWidget-based applications. It handles widget specific initialization,
 
185
    finalization.
 
186
 
 
187
    For any GUI application using Qt, there is precisely \b one QApplication
 
188
    object, no matter whether the application has 0, 1, 2 or more windows at
 
189
    any given time. For non-QWidget based Qt applications, use QGuiApplication instead,
 
190
    as it does not depend on the \l QtWidgets library.
 
191
 
 
192
    Some GUI applications provide a special batch mode ie. provide command line
 
193
    arguments for executing tasks without manual intervention. In such non-GUI
 
194
    mode, it is often sufficient to instantiate a plain QCoreApplication to
 
195
    avoid unnecessarily initializing resources needed for a graphical user
 
196
    interface. The following example shows how to dynamically create an
 
197
    appropriate type of application instance:
 
198
 
 
199
    \snippet code/src_gui_kernel_qapplication.cpp 0
 
200
 
 
201
    The QApplication object is accessible through the instance() function that
 
202
    returns a pointer equivalent to the global qApp pointer.
 
203
 
 
204
    QApplication's main areas of responsibility are:
 
205
        \list
 
206
            \li  It initializes the application with the user's desktop settings
 
207
                such as palette(), font() and doubleClickInterval(). It keeps
 
208
                track of these properties in case the user changes the desktop
 
209
                globally, for example through some kind of control panel.
 
210
 
 
211
            \li  It performs event handling, meaning that it receives events
 
212
                from the underlying window system and dispatches them to the
 
213
                relevant widgets. By using sendEvent() and postEvent() you can
 
214
                send your own events to widgets.
 
215
 
 
216
            \li  It parses common command line arguments and sets its internal
 
217
                state accordingly. See the \l{QApplication::QApplication()}
 
218
                {constructor documentation} below for more details.
 
219
 
 
220
            \li  It defines the application's look and feel, which is
 
221
                encapsulated in a QStyle object. This can be changed at runtime
 
222
                with setStyle().
 
223
 
 
224
            \li  It specifies how the application is to allocate colors. See
 
225
                setColorSpec() for details.
 
226
 
 
227
            \li  It provides localization of strings that are visible to the
 
228
                user via translate().
 
229
 
 
230
            \li  It provides some magical objects like the desktop() and the
 
231
                clipboard().
 
232
 
 
233
            \li  It knows about the application's windows. You can ask which
 
234
                widget is at a certain position using widgetAt(), get a list of
 
235
                topLevelWidgets() and closeAllWindows(), etc.
 
236
 
 
237
            \li  It manages the application's mouse cursor handling, see
 
238
                setOverrideCursor()
 
239
        \endlist
 
240
 
 
241
    Since the QApplication object does so much initialization, it \e{must} be
 
242
    created before any other objects related to the user interface are created.
 
243
    QApplication also deals with common command line arguments. Hence, it is
 
244
    usually a good idea to create it \e before any interpretation or
 
245
    modification of \c argv is done in the application itself.
 
246
 
 
247
    \table
 
248
    \header
 
249
        \li{2,1} Groups of functions
 
250
 
 
251
        \row
 
252
        \li  System settings
 
253
        \li  desktopSettingsAware(),
 
254
            setDesktopSettingsAware(),
 
255
            cursorFlashTime(),
 
256
            setCursorFlashTime(),
 
257
            doubleClickInterval(),
 
258
            setDoubleClickInterval(),
 
259
            setKeyboardInputInterval(),
 
260
            wheelScrollLines(),
 
261
            setWheelScrollLines(),
 
262
            palette(),
 
263
            setPalette(),
 
264
            font(),
 
265
            setFont(),
 
266
            fontMetrics().
 
267
 
 
268
        \row
 
269
        \li  Event handling
 
270
        \li  exec(),
 
271
            processEvents(),
 
272
            exit(),
 
273
            quit().
 
274
            sendEvent(),
 
275
            postEvent(),
 
276
            sendPostedEvents(),
 
277
            removePostedEvents(),
 
278
            hasPendingEvents(),
 
279
            notify().
 
280
 
 
281
        \row
 
282
        \li  GUI Styles
 
283
        \li  style(),
 
284
            setStyle().
 
285
 
 
286
        \row
 
287
        \li  Color usage
 
288
        \li  colorSpec(),
 
289
            setColorSpec().
 
290
 
 
291
        \row
 
292
        \li  Text handling
 
293
        \li  installTranslator(),
 
294
            removeTranslator()
 
295
            translate().
 
296
 
 
297
        \row
 
298
        \li  Widgets
 
299
        \li  allWidgets(),
 
300
            topLevelWidgets(),
 
301
            desktop(),
 
302
            activePopupWidget(),
 
303
            activeModalWidget(),
 
304
            clipboard(),
 
305
            focusWidget(),
 
306
            activeWindow(),
 
307
            widgetAt().
 
308
 
 
309
        \row
 
310
        \li  Advanced cursor handling
 
311
        \li  overrideCursor(),
 
312
            setOverrideCursor(),
 
313
            restoreOverrideCursor().
 
314
 
 
315
        \row
 
316
        \li  Miscellaneous
 
317
        \li  closeAllWindows(),
 
318
            startingUp(),
 
319
            closingDown(),
 
320
            type().
 
321
    \endtable
 
322
 
 
323
    \sa QCoreApplication, QAbstractEventDispatcher, QEventLoop, QSettings
 
324
*/
 
325
 
 
326
/*!
 
327
    \enum QApplication::ColorSpec
 
328
 
 
329
    \value NormalColor the default color allocation policy
 
330
    \value CustomColor the same as NormalColor for X11; allocates colors
 
331
    to a palette on demand under Windows
 
332
    \value ManyColor the right choice for applications that use thousands of
 
333
    colors
 
334
 
 
335
    See setColorSpec() for full details.
 
336
*/
 
337
 
 
338
/*!
 
339
    \fn QWidget *QApplication::topLevelAt(const QPoint &point)
 
340
 
 
341
    Returns the top-level widget at the given \a point; returns 0 if
 
342
    there is no such widget.
 
343
*/
 
344
 
 
345
/*!
 
346
    \fn QWidget *QApplication::topLevelAt(int x, int y)
 
347
 
 
348
    \overload
 
349
 
 
350
    Returns the top-level widget at the point (\a{x}, \a{y}); returns
 
351
    0 if there is no such widget.
 
352
*/
 
353
 
 
354
 
 
355
/*
 
356
    The qt_init() and qt_cleanup() functions are implemented in the
 
357
    qapplication_xyz.cpp file.
 
358
*/
 
359
 
 
360
void qt_init(QApplicationPrivate *priv, int type
 
361
   );
 
362
void qt_cleanup();
 
363
 
 
364
QStyle *QApplicationPrivate::app_style = 0;        // default application style
 
365
QString QApplicationPrivate::styleOverride;        // style override
 
366
 
 
367
#ifndef QT_NO_STYLE_STYLESHEET
 
368
QString QApplicationPrivate::styleSheet;           // default application stylesheet
 
369
#endif
 
370
QPointer<QWidget> QApplicationPrivate::leaveAfterRelease = 0;
 
371
 
 
372
int QApplicationPrivate::app_cspec = QApplication::NormalColor;
 
373
 
 
374
QPalette *QApplicationPrivate::sys_pal = 0;        // default system palette
 
375
QPalette *QApplicationPrivate::set_pal = 0;        // default palette set by programmer
 
376
 
 
377
QFont *QApplicationPrivate::sys_font = 0;        // default system font
 
378
QFont *QApplicationPrivate::set_font = 0;        // default font set by programmer
 
379
 
 
380
QIcon *QApplicationPrivate::app_icon = 0;
 
381
QWidget *QApplicationPrivate::main_widget = 0;        // main application widget
 
382
QWidget *QApplicationPrivate::focus_widget = 0;        // has keyboard input focus
 
383
QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
 
384
QWidget *QApplicationPrivate::active_window = 0;        // toplevel with keyboard focus
 
385
#ifndef QT_NO_WHEELEVENT
 
386
int QApplicationPrivate::wheel_scroll_lines;   // number of lines to scroll
 
387
#endif
 
388
bool qt_in_tab_key_event = false;
 
389
int qt_antialiasing_threshold = -1;
 
390
QSize QApplicationPrivate::app_strut = QSize(0,0); // no default application strut
 
391
int QApplicationPrivate::enabledAnimations = QPlatformTheme::GeneralUiEffect;
 
392
bool QApplicationPrivate::widgetCount = false;
 
393
bool QApplicationPrivate::load_testability = false;
 
394
#ifdef QT_KEYPAD_NAVIGATION
 
395
Qt::NavigationMode QApplicationPrivate::navigationMode = Qt::NavigationModeKeypadTabOrder;
 
396
QWidget *QApplicationPrivate::oldEditFocus = 0;
 
397
#endif
 
398
 
 
399
bool qt_tabletChokeMouse = false;
 
400
 
 
401
inline bool QApplicationPrivate::isAlien(QWidget *widget)
 
402
{
 
403
    return widget && !widget->isWindow();
 
404
}
 
405
 
 
406
bool Q_WIDGETS_EXPORT qt_tab_all_widgets()
 
407
{
 
408
    if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
 
409
        return theme->themeHint(QPlatformTheme::TabAllWidgets).toBool();
 
410
    return true;
 
411
}
 
412
 
 
413
// ######## move to QApplicationPrivate
 
414
// Default application palettes and fonts (per widget type)
 
415
Q_GLOBAL_STATIC(PaletteHash, app_palettes)
 
416
PaletteHash *qt_app_palettes_hash()
 
417
{
 
418
    return app_palettes();
 
419
}
 
420
 
 
421
Q_GLOBAL_STATIC(FontHash, app_fonts)
 
422
FontHash *qt_app_fonts_hash()
 
423
{
 
424
    return app_fonts();
 
425
}
 
426
 
 
427
QWidgetList *QApplicationPrivate::popupWidgets = 0;        // has keyboard input focus
 
428
 
 
429
QDesktopWidget *qt_desktopWidget = 0;                // root window widgets
 
430
 
 
431
/*!
 
432
    \internal
 
433
*/
 
434
void QApplicationPrivate::process_cmdline()
 
435
{
 
436
    // process platform-indep command line
 
437
    if (!qt_is_gui_used || !argc)
 
438
        return;
 
439
 
 
440
    int i, j;
 
441
 
 
442
    j = 1;
 
443
    for (i=1; i<argc; i++) { // if you add anything here, modify QCoreApplication::arguments()
 
444
        if (argv[i] && *argv[i] != '-') {
 
445
            argv[j++] = argv[i];
 
446
            continue;
 
447
        }
 
448
        QByteArray arg = argv[i];
 
449
        arg = arg;
 
450
        QString s;
 
451
        if (arg == "-qdevel" || arg == "-qdebug") {
 
452
            // obsolete argument
 
453
        } else if (arg.indexOf("-style=", 0) != -1) {
 
454
            s = QString::fromLocal8Bit(arg.right(arg.length() - 7).toLower());
 
455
        } else if (arg == "-style" && i < argc-1) {
 
456
            s = QString::fromLocal8Bit(argv[++i]).toLower();
 
457
#ifndef QT_NO_STYLE_STYLESHEET
 
458
        } else if (arg == "-stylesheet" && i < argc -1) {
 
459
            styleSheet = QLatin1String("file:///");
 
460
            styleSheet.append(QString::fromLocal8Bit(argv[++i]));
 
461
        } else if (arg.indexOf("-stylesheet=") != -1) {
 
462
            styleSheet = QLatin1String("file:///");
 
463
            styleSheet.append(QString::fromLocal8Bit(arg.right(arg.length() - 12)));
 
464
#endif
 
465
        } else if (qstrcmp(arg, "-widgetcount") == 0) {
 
466
            widgetCount = true;
 
467
        } else if (qstrcmp(arg, "-testability") == 0) {
 
468
            load_testability = true;
 
469
        } else {
 
470
            argv[j++] = argv[i];
 
471
        }
 
472
        if (!s.isEmpty()) {
 
473
            if (app_style) {
 
474
                delete app_style;
 
475
                app_style = 0;
 
476
            }
 
477
            styleOverride = s;
 
478
        }
 
479
    }
 
480
 
 
481
    if(j < argc) {
 
482
        argv[j] = 0;
 
483
        argc = j;
 
484
    }
 
485
}
 
486
 
 
487
/*!
 
488
    Initializes the window system and constructs an application object with
 
489
    \a argc command line arguments in \a argv.
 
490
 
 
491
    \warning The data referred to by \a argc and \a argv must stay valid for
 
492
    the entire lifetime of the QApplication object. In addition, \a argc must
 
493
    be greater than zero and \a argv must contain at least one valid character
 
494
    string.
 
495
 
 
496
    The global \c qApp pointer refers to this application object. Only one
 
497
    application object should be created.
 
498
 
 
499
    This application object must be constructed before any \l{QPaintDevice}
 
500
    {paint devices} (including widgets, pixmaps, bitmaps etc.).
 
501
 
 
502
    \note \a argc and \a argv might be changed as Qt removes command line
 
503
    arguments that it recognizes.
 
504
 
 
505
    All Qt programs automatically support the following command line options:
 
506
    \list
 
507
        \li  -style= \e style, sets the application GUI style. Possible values
 
508
            depend on your system configuration. If you compiled Qt with
 
509
            additional styles or have additional styles as plugins these will
 
510
            be available to the \c -style command line option.  You can also
 
511
            set the style for all Qt applications by setting the
 
512
            \c QT_STYLE_OVERRIDE environment variable.
 
513
        \li  -style \e style, is the same as listed above.
 
514
        \li  -stylesheet= \e stylesheet, sets the application \l styleSheet. The
 
515
            value must be a path to a file that contains the Style Sheet.
 
516
            \note Relative URLs in the Style Sheet file are relative to the
 
517
            Style Sheet file's path.
 
518
        \li  -stylesheet \e stylesheet, is the same as listed above.
 
519
        \li  -widgetcount, prints debug message at the end about number of
 
520
            widgets left undestroyed and maximum number of widgets existed at
 
521
            the same time
 
522
        \li  -reverse, sets the application's layout direction to
 
523
            Qt::RightToLeft
 
524
        \li  -qmljsdebugger=, activates the QML/JS debugger with a specified port.
 
525
            The value must be of format port:1234[,block], where block is optional
 
526
            and will make the application wait until a debugger connects to it.
 
527
    \endlist
 
528
 
 
529
    \sa arguments()
 
530
*/
 
531
 
 
532
#ifdef Q_QDOC
 
533
QApplication::QApplication(int &argc, char **argv)
 
534
#else
 
535
QApplication::QApplication(int &argc, char **argv, int _internal)
 
536
#endif
 
537
    : QGuiApplication(*new QApplicationPrivate(argc, argv, _internal))
 
538
{ Q_D(QApplication); d->construct(); }
 
539
 
 
540
/*!
 
541
    \internal
 
542
*/
 
543
void QApplicationPrivate::construct()
 
544
{
 
545
    initResources();
 
546
 
 
547
    qt_is_gui_used = (application_type != QApplicationPrivate::Tty);
 
548
    process_cmdline();
 
549
 
 
550
    // Must be called before initialize()
 
551
    qt_init(this, application_type);
 
552
    initialize();
 
553
    eventDispatcher->startingUp();
 
554
 
 
555
#ifdef QT_EVAL
 
556
    extern void qt_gui_eval_init(uint);
 
557
    qt_gui_eval_init(application_type);
 
558
#endif
 
559
 
 
560
#ifndef QT_NO_LIBRARY
 
561
    if(load_testability) {
 
562
        QLibrary testLib(QLatin1String("qttestability"));
 
563
        if (testLib.load()) {
 
564
            typedef void (*TasInitialize)(void);
 
565
            TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init");
 
566
            if (initFunction) {
 
567
                initFunction();
 
568
            } else {
 
569
                qCritical("Library qttestability resolve failed!");
 
570
            }
 
571
        } else {
 
572
            qCritical("Library qttestability load failed!");
 
573
        }
 
574
    }
 
575
#endif
 
576
}
 
577
 
 
578
#ifndef QT_NO_STATEMACHINE
 
579
void qRegisterGuiStateMachine();
 
580
void qUnregisterGuiStateMachine();
 
581
#endif
 
582
 
 
583
/*!
 
584
  \fn void QApplicationPrivate::initialize()
 
585
 
 
586
  Initializes the QApplication object, called from the constructors.
 
587
*/
 
588
void QApplicationPrivate::initialize()
 
589
{
 
590
    QWidgetPrivate::mapper = new QWidgetMapper;
 
591
    QWidgetPrivate::allWidgets = new QWidgetSet;
 
592
 
 
593
    if (application_type != QApplicationPrivate::Tty)
 
594
        (void) QApplication::style();  // trigger creation of application style
 
595
#ifndef QT_NO_STATEMACHINE
 
596
    // trigger registering of QStateMachine's GUI types
 
597
    qRegisterGuiStateMachine();
 
598
#endif
 
599
 
 
600
    is_app_running = true; // no longer starting up
 
601
 
 
602
    Q_Q(QApplication);
 
603
 
 
604
    if (qgetenv("QT_USE_NATIVE_WINDOWS").toInt() > 0)
 
605
        q->setAttribute(Qt::AA_NativeWindows);
 
606
 
 
607
#ifdef Q_OS_WINCE
 
608
#ifdef QT_AUTO_MAXIMIZE_THRESHOLD
 
609
    autoMaximizeThreshold = QT_AUTO_MAXIMIZE_THRESHOLD;
 
610
#else
 
611
    if (qt_wince_is_mobile())
 
612
        autoMaximizeThreshold = 50;
 
613
    else
 
614
        autoMaximizeThreshold = -1;
 
615
#endif //QT_AUTO_MAXIMIZE_THRESHOLD
 
616
#endif //Q_OS_WINCE
 
617
 
 
618
#ifndef QT_NO_WHEELEVENT
 
619
    QApplicationPrivate::wheel_scroll_lines = 3;
 
620
#endif
 
621
 
 
622
    if (qt_is_gui_used)
 
623
        initializeMultitouch();
 
624
 
 
625
    if (QApplication::desktopSettingsAware())
 
626
        if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
 
627
            QApplicationPrivate::enabledAnimations = theme->themeHint(QPlatformTheme::UiEffects).toInt();
 
628
}
 
629
 
 
630
/*****************************************************************************
 
631
  Functions returning the active popup and modal widgets.
 
632
 *****************************************************************************/
 
633
 
 
634
/*!
 
635
    Returns the active popup widget.
 
636
 
 
637
    A popup widget is a special top-level widget that sets the \c
 
638
    Qt::WType_Popup widget flag, e.g. the QMenu widget. When the application
 
639
    opens a popup widget, all events are sent to the popup. Normal widgets and
 
640
    modal widgets cannot be accessed before the popup widget is closed.
 
641
 
 
642
    Only other popup widgets may be opened when a popup widget is shown. The
 
643
    popup widgets are organized in a stack. This function returns the active
 
644
    popup widget at the top of the stack.
 
645
 
 
646
    \sa activeModalWidget(), topLevelWidgets()
 
647
*/
 
648
 
 
649
QWidget *QApplication::activePopupWidget()
 
650
{
 
651
    return QApplicationPrivate::popupWidgets && !QApplicationPrivate::popupWidgets->isEmpty() ?
 
652
        QApplicationPrivate::popupWidgets->last() : 0;
 
653
}
 
654
 
 
655
 
 
656
/*!
 
657
    Returns the active modal widget.
 
658
 
 
659
    A modal widget is a special top-level widget which is a subclass of QDialog
 
660
    that specifies the modal parameter of the constructor as true. A modal
 
661
    widget must be closed before the user can continue with other parts of the
 
662
    program.
 
663
 
 
664
    Modal widgets are organized in a stack. This function returns the active
 
665
    modal widget at the top of the stack.
 
666
 
 
667
    \sa activePopupWidget(), topLevelWidgets()
 
668
*/
 
669
 
 
670
QWidget *QApplication::activeModalWidget()
 
671
{
 
672
    QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(modalWindow());
 
673
    return widgetWindow ? widgetWindow->widget() : 0;
 
674
}
 
675
 
 
676
/*!
 
677
    Cleans up any window system resources that were allocated by this
 
678
    application. Sets the global variable \c qApp to 0.
 
679
*/
 
680
 
 
681
QApplication::~QApplication()
 
682
{
 
683
    Q_D(QApplication);
 
684
 
 
685
    //### this should probable be done even later
 
686
    qt_call_post_routines();
 
687
 
 
688
    // kill timers before closing down the dispatcher
 
689
    d->toolTipWakeUp.stop();
 
690
    d->toolTipFallAsleep.stop();
 
691
 
 
692
    QApplicationPrivate::is_app_closing = true;
 
693
    QApplicationPrivate::is_app_running = false;
 
694
 
 
695
    delete QWidgetPrivate::mapper;
 
696
    QWidgetPrivate::mapper = 0;
 
697
 
 
698
    // delete all widgets
 
699
    if (QWidgetPrivate::allWidgets) {
 
700
        QWidgetSet *mySet = QWidgetPrivate::allWidgets;
 
701
        QWidgetPrivate::allWidgets = 0;
 
702
        for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
 
703
            register QWidget *w = *it;
 
704
            if (!w->parent())                        // window
 
705
                w->destroy(true, true);
 
706
        }
 
707
        delete mySet;
 
708
    }
 
709
 
 
710
    delete qt_desktopWidget;
 
711
    qt_desktopWidget = 0;
 
712
 
 
713
    delete QApplicationPrivate::app_pal;
 
714
    QApplicationPrivate::app_pal = 0;
 
715
    clearSystemPalette();
 
716
    delete QApplicationPrivate::set_pal;
 
717
    QApplicationPrivate::set_pal = 0;
 
718
    app_palettes()->clear();
 
719
 
 
720
    delete QApplicationPrivate::sys_font;
 
721
    QApplicationPrivate::sys_font = 0;
 
722
    delete QApplicationPrivate::set_font;
 
723
    QApplicationPrivate::set_font = 0;
 
724
    app_fonts()->clear();
 
725
 
 
726
    delete QApplicationPrivate::app_style;
 
727
    QApplicationPrivate::app_style = 0;
 
728
    delete QApplicationPrivate::app_icon;
 
729
    QApplicationPrivate::app_icon = 0;
 
730
 
 
731
#ifndef QT_NO_DRAGANDDROP
 
732
    if (qt_is_gui_used)
 
733
        delete QDragManager::self();
 
734
#endif
 
735
 
 
736
    d->cleanupMultitouch();
 
737
 
 
738
    qt_cleanup();
 
739
 
 
740
    if (QApplicationPrivate::widgetCount)
 
741
        qDebug("Widgets left: %i    Max widgets: %i \n", QWidgetPrivate::instanceCounter, QWidgetPrivate::maxInstances);
 
742
 
 
743
    QApplicationPrivate::obey_desktop_settings = true;
 
744
 
 
745
    QApplicationPrivate::app_strut = QSize(0, 0);
 
746
    QApplicationPrivate::enabledAnimations = QPlatformTheme::GeneralUiEffect;
 
747
    QApplicationPrivate::widgetCount = false;
 
748
 
 
749
#ifndef QT_NO_STATEMACHINE
 
750
    // trigger unregistering of QStateMachine's GUI types
 
751
    qUnregisterGuiStateMachine();
 
752
#endif
 
753
}
 
754
 
 
755
 
 
756
/*!
 
757
    \fn QWidget *QApplication::widgetAt(const QPoint &point)
 
758
 
 
759
    Returns the widget at global screen position \a point, or 0 if there is no
 
760
    Qt widget there.
 
761
 
 
762
    This function can be slow.
 
763
 
 
764
    \sa QCursor::pos(), QWidget::grabMouse(), QWidget::grabKeyboard()
 
765
*/
 
766
QWidget *QApplication::widgetAt(const QPoint &p)
 
767
{
 
768
    QWidget *window = QApplication::topLevelAt(p);
 
769
    if (!window)
 
770
        return 0;
 
771
 
 
772
    QWidget *child = 0;
 
773
 
 
774
    if (!window->testAttribute(Qt::WA_TransparentForMouseEvents))
 
775
        child = window->childAt(window->mapFromGlobal(p));
 
776
 
 
777
    if (child)
 
778
        return child;
 
779
 
 
780
    if (window->testAttribute(Qt::WA_TransparentForMouseEvents)) {
 
781
        //shoot a hole in the widget and try once again,
 
782
        //suboptimal on Qt for Embedded Linux where we do
 
783
        //know the stacking order of the toplevels.
 
784
        int x = p.x();
 
785
        int y = p.y();
 
786
        QRegion oldmask = window->mask();
 
787
        QPoint wpoint = window->mapFromGlobal(QPoint(x, y));
 
788
        QRegion newmask = (oldmask.isEmpty() ? QRegion(window->rect()) : oldmask)
 
789
                          - QRegion(wpoint.x(), wpoint.y(), 1, 1);
 
790
        window->setMask(newmask);
 
791
        QWidget *recurse = 0;
 
792
        if (QApplication::topLevelAt(p) != window) // verify recursion will terminate
 
793
            recurse = widgetAt(x, y);
 
794
        if (oldmask.isEmpty())
 
795
            window->clearMask();
 
796
        else
 
797
            window->setMask(oldmask);
 
798
        return recurse;
 
799
    }
 
800
    return window;
 
801
}
 
802
 
 
803
/*!
 
804
    \fn QWidget *QApplication::widgetAt(int x, int y)
 
805
 
 
806
    \overload
 
807
 
 
808
    Returns the widget at global screen position (\a x, \a y), or 0 if there is
 
809
    no Qt widget there.
 
810
*/
 
811
 
 
812
/*!
 
813
    \internal
 
814
*/
 
815
bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
 
816
{
 
817
    if ((event->type() == QEvent::UpdateRequest
 
818
          || event->type() == QEvent::LayoutRequest
 
819
          || event->type() == QEvent::Resize
 
820
          || event->type() == QEvent::Move
 
821
          || event->type() == QEvent::LanguageChange
 
822
          || event->type() == QEvent::InputMethod)) {
 
823
        for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) {
 
824
            const QPostEvent &cur = *it;
 
825
            if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type())
 
826
                continue;
 
827
            if (cur.event->type() == QEvent::LayoutRequest
 
828
                 || cur.event->type() == QEvent::UpdateRequest) {
 
829
                ;
 
830
            } else if (cur.event->type() == QEvent::Resize) {
 
831
                ((QResizeEvent *)(cur.event))->s = ((QResizeEvent *)event)->s;
 
832
            } else if (cur.event->type() == QEvent::Move) {
 
833
                ((QMoveEvent *)(cur.event))->p = ((QMoveEvent *)event)->p;
 
834
            } else if (cur.event->type() == QEvent::LanguageChange) {
 
835
                ;
 
836
            } else if ( cur.event->type() == QEvent::InputMethod ) {
 
837
                *(QInputMethodEvent *)(cur.event) = *(QInputMethodEvent *)event;
 
838
            } else {
 
839
                continue;
 
840
            }
 
841
            delete event;
 
842
            return true;
 
843
        }
 
844
        return false;
 
845
    }
 
846
    return QGuiApplication::compressEvent(event, receiver, postedEvents);
 
847
}
 
848
 
 
849
/*!
 
850
    \property QApplication::styleSheet
 
851
    \brief the application style sheet
 
852
    \since 4.2
 
853
 
 
854
    By default, this property returns an empty string unless the user specifies
 
855
    the \c{-stylesheet} option on the command line when running the application.
 
856
 
 
857
    \sa QWidget::setStyle(), {Qt Style Sheets}
 
858
*/
 
859
 
 
860
/*!
 
861
    \property QApplication::autoMaximizeThreshold
 
862
    \since 4.4
 
863
    \brief defines a threshold for auto maximizing widgets
 
864
 
 
865
    \b{The auto maximize threshold is only available as part of Qt for
 
866
    Windows CE.}
 
867
 
 
868
    This property defines a threshold for the size of a window as a percentage
 
869
    of the screen size. If the minimum size hint of a window exceeds the
 
870
    threshold, calling show() will cause the window to be maximized
 
871
    automatically.
 
872
 
 
873
    Setting the threshold to 100 or greater means that the widget will always
 
874
    be maximized. Alternatively, setting the threshold to 50 means that the
 
875
    widget will be maximized only if the vertical minimum size hint is at least
 
876
    50% of the vertical screen size.
 
877
 
 
878
    Setting the threshold to -1 disables the feature.
 
879
 
 
880
    On Windows CE the default is -1 (i.e., it is disabled).
 
881
    On Windows Mobile the default is 40.
 
882
*/
 
883
 
 
884
/*!
 
885
    \property QApplication::autoSipEnabled
 
886
    \since 4.5
 
887
    \brief toggles automatic SIP (software input panel) visibility
 
888
 
 
889
    Set this property to \c true to automatically display the SIP when entering
 
890
    widgets that accept keyboard input. This property only affects widgets with
 
891
    the WA_InputMethodEnabled attribute set, and is typically used to launch
 
892
    a virtual keyboard on devices which have very few or no keys.
 
893
 
 
894
    \b{ The property only has an effect on platforms which use software input
 
895
    panels, such as Windows CE.}
 
896
 
 
897
    The default is platform dependent.
 
898
*/
 
899
 
 
900
#ifdef Q_OS_WINCE
 
901
void QApplication::setAutoMaximizeThreshold(const int threshold)
 
902
{
 
903
    QApplicationPrivate::autoMaximizeThreshold = threshold;
 
904
}
 
905
 
 
906
int QApplication::autoMaximizeThreshold() const
 
907
{
 
908
    return QApplicationPrivate::autoMaximizeThreshold;
 
909
}
 
910
#endif
 
911
 
 
912
void QApplication::setAutoSipEnabled(const bool enabled)
 
913
{
 
914
    QApplicationPrivate::autoSipEnabled = enabled;
 
915
}
 
916
 
 
917
bool QApplication::autoSipEnabled() const
 
918
{
 
919
    return QApplicationPrivate::autoSipEnabled;
 
920
}
 
921
 
 
922
#ifndef QT_NO_STYLE_STYLESHEET
 
923
 
 
924
QString QApplication::styleSheet() const
 
925
{
 
926
    return QApplicationPrivate::styleSheet;
 
927
}
 
928
 
 
929
void QApplication::setStyleSheet(const QString& styleSheet)
 
930
{
 
931
    QApplicationPrivate::styleSheet = styleSheet;
 
932
    QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle*>(QApplicationPrivate::app_style);
 
933
    if (styleSheet.isEmpty()) { // application style sheet removed
 
934
        if (!proxy)
 
935
            return; // there was no stylesheet before
 
936
        setStyle(proxy->base);
 
937
    } else if (proxy) { // style sheet update, just repolish
 
938
        proxy->repolish(qApp);
 
939
    } else { // stylesheet set the first time
 
940
        QStyleSheetStyle *newProxy = new QStyleSheetStyle(QApplicationPrivate::app_style);
 
941
        QApplicationPrivate::app_style->setParent(newProxy);
 
942
        setStyle(newProxy);
 
943
    }
 
944
}
 
945
 
 
946
#endif // QT_NO_STYLE_STYLESHEET
 
947
 
 
948
/*!
 
949
    Returns the application's style object.
 
950
 
 
951
    \sa setStyle(), QStyle
 
952
*/
 
953
QStyle *QApplication::style()
 
954
{
 
955
    if (QApplicationPrivate::app_style)
 
956
        return QApplicationPrivate::app_style;
 
957
    if (!qobject_cast<QApplication *>(QCoreApplication::instance())) {
 
958
        Q_ASSERT(!"No style available without QApplication!");
 
959
        return 0;
 
960
    }
 
961
 
 
962
    if (!QApplicationPrivate::app_style) {
 
963
        // Compile-time search for default style
 
964
        //
 
965
        QString style;
 
966
#ifdef QT_BUILD_INTERNAL
 
967
        QString envStyle = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
 
968
#else
 
969
        QString envStyle;
 
970
#endif
 
971
        if (!QApplicationPrivate::styleOverride.isEmpty()) {
 
972
            style = QApplicationPrivate::styleOverride;
 
973
        } else if (!envStyle.isEmpty()) {
 
974
            style = envStyle;
 
975
        } else {
 
976
            style = QApplicationPrivate::desktopStyleKey();
 
977
        }
 
978
 
 
979
        QStyle *&app_style = QApplicationPrivate::app_style;
 
980
        app_style = QStyleFactory::create(style);
 
981
        if (!app_style) {
 
982
            QStringList styles = QStyleFactory::keys();
 
983
            for (int i = 0; i < styles.size(); ++i) {
 
984
                if ((app_style = QStyleFactory::create(styles.at(i))))
 
985
                    break;
 
986
            }
 
987
        }
 
988
        if (!app_style) {
 
989
            Q_ASSERT(!"No styles available!");
 
990
            return 0;
 
991
        }
 
992
    }
 
993
    // take ownership of the style
 
994
    QApplicationPrivate::app_style->setParent(qApp);
 
995
 
 
996
    initSystemPalette();
 
997
 
 
998
    if (QApplicationPrivate::set_pal) // repolish set palette with the new style
 
999
        QApplication::setPalette(*QApplicationPrivate::set_pal);
 
1000
 
 
1001
#ifndef QT_NO_STYLE_STYLESHEET
 
1002
    if (!QApplicationPrivate::styleSheet.isEmpty()) {
 
1003
        qApp->setStyleSheet(QApplicationPrivate::styleSheet);
 
1004
    } else
 
1005
#endif
 
1006
        QApplicationPrivate::app_style->polish(qApp);
 
1007
 
 
1008
    return QApplicationPrivate::app_style;
 
1009
}
 
1010
 
 
1011
/*!
 
1012
    Sets the application's GUI style to \a style. Ownership of the style object
 
1013
    is transferred to QApplication, so QApplication will delete the style
 
1014
    object on application exit or when a new style is set and the old style is
 
1015
    still the parent of the application object.
 
1016
 
 
1017
    Example usage:
 
1018
    \snippet code/src_gui_kernel_qapplication.cpp 1
 
1019
 
 
1020
    When switching application styles, the color palette is set back to the
 
1021
    initial colors or the system defaults. This is necessary since certain
 
1022
    styles have to adapt the color palette to be fully style-guide compliant.
 
1023
 
 
1024
    Setting the style before a palette has been set, i.e., before creating
 
1025
    QApplication, will cause the application to use QStyle::standardPalette()
 
1026
    for the palette.
 
1027
 
 
1028
    \warning Qt style sheets are currently not supported for custom QStyle
 
1029
    subclasses. We plan to address this in some future release.
 
1030
 
 
1031
    \sa style(), QStyle, setPalette(), desktopSettingsAware()
 
1032
*/
 
1033
void QApplication::setStyle(QStyle *style)
 
1034
{
 
1035
    if (!style || style == QApplicationPrivate::app_style)
 
1036
        return;
 
1037
 
 
1038
    QWidgetList all = allWidgets();
 
1039
 
 
1040
    // clean up the old style
 
1041
    if (QApplicationPrivate::app_style) {
 
1042
        if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
 
1043
            for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
 
1044
                register QWidget *w = *it;
 
1045
                if (!(w->windowType() == Qt::Desktop) &&        // except desktop
 
1046
                     w->testAttribute(Qt::WA_WState_Polished)) { // has been polished
 
1047
                    QApplicationPrivate::app_style->unpolish(w);
 
1048
                }
 
1049
            }
 
1050
        }
 
1051
        QApplicationPrivate::app_style->unpolish(qApp);
 
1052
    }
 
1053
 
 
1054
    QStyle *old = QApplicationPrivate::app_style; // save
 
1055
 
 
1056
#ifndef QT_NO_STYLE_STYLESHEET
 
1057
    if (!QApplicationPrivate::styleSheet.isEmpty() && !qobject_cast<QStyleSheetStyle *>(style)) {
 
1058
        // we have a stylesheet already and a new style is being set
 
1059
        QStyleSheetStyle *newProxy = new QStyleSheetStyle(style);
 
1060
        style->setParent(newProxy);
 
1061
        QApplicationPrivate::app_style = newProxy;
 
1062
    } else
 
1063
#endif // QT_NO_STYLE_STYLESHEET
 
1064
        QApplicationPrivate::app_style = style;
 
1065
    QApplicationPrivate::app_style->setParent(qApp); // take ownership
 
1066
 
 
1067
    // take care of possible palette requirements of certain gui
 
1068
    // styles. Do it before polishing the application since the style
 
1069
    // might call QApplication::setPalette() itself
 
1070
    if (QApplicationPrivate::set_pal) {
 
1071
        QApplication::setPalette(*QApplicationPrivate::set_pal);
 
1072
    } else if (QApplicationPrivate::sys_pal) {
 
1073
        QApplicationPrivate::initializeWidgetPaletteHash();
 
1074
        QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
 
1075
    } else if (!QApplicationPrivate::sys_pal) {
 
1076
        // Initialize the sys_pal if it hasn't happened yet...
 
1077
        QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
 
1078
    }
 
1079
 
 
1080
    // initialize the application with the new style
 
1081
    QApplicationPrivate::app_style->polish(qApp);
 
1082
 
 
1083
    // re-polish existing widgets if necessary
 
1084
    if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
 
1085
        for (QWidgetList::ConstIterator it1 = all.constBegin(); it1 != all.constEnd(); ++it1) {
 
1086
            register QWidget *w = *it1;
 
1087
            if (w->windowType() != Qt::Desktop && w->testAttribute(Qt::WA_WState_Polished)) {
 
1088
                if (w->style() == QApplicationPrivate::app_style)
 
1089
                    QApplicationPrivate::app_style->polish(w);                // repolish
 
1090
#ifndef QT_NO_STYLE_STYLESHEET
 
1091
                else
 
1092
                    w->setStyleSheet(w->styleSheet()); // touch
 
1093
#endif
 
1094
            }
 
1095
        }
 
1096
 
 
1097
        for (QWidgetList::ConstIterator it2 = all.constBegin(); it2 != all.constEnd(); ++it2) {
 
1098
            register QWidget *w = *it2;
 
1099
            if (w->windowType() != Qt::Desktop && !w->testAttribute(Qt::WA_SetStyle)) {
 
1100
                    QEvent e(QEvent::StyleChange);
 
1101
                    QApplication::sendEvent(w, &e);
 
1102
                    w->update();
 
1103
            }
 
1104
        }
 
1105
    }
 
1106
 
 
1107
#ifndef QT_NO_STYLE_STYLESHEET
 
1108
    if (QStyleSheetStyle *oldProxy = qobject_cast<QStyleSheetStyle *>(old)) {
 
1109
        oldProxy->deref();
 
1110
    } else
 
1111
#endif
 
1112
    if (old && old->parent() == qApp) {
 
1113
        delete old;
 
1114
    }
 
1115
 
 
1116
    if (QApplicationPrivate::focus_widget) {
 
1117
        QFocusEvent in(QEvent::FocusIn, Qt::OtherFocusReason);
 
1118
        QApplication::sendEvent(QApplicationPrivate::focus_widget->style(), &in);
 
1119
        QApplicationPrivate::focus_widget->update();
 
1120
    }
 
1121
}
 
1122
 
 
1123
/*!
 
1124
    \overload
 
1125
 
 
1126
    Requests a QStyle object for \a style from the QStyleFactory.
 
1127
 
 
1128
    The string must be one of the QStyleFactory::keys(), typically one of
 
1129
    "windows", "fusion", "windowsxp", or "macintosh". Style
 
1130
    names are case insensitive.
 
1131
 
 
1132
    Returns 0 if an unknown \a style is passed, otherwise the QStyle object
 
1133
    returned is set as the application's GUI style.
 
1134
 
 
1135
    \warning To ensure that the application's style is set correctly, it is
 
1136
    best to call this function before the QApplication constructor, if
 
1137
    possible.
 
1138
*/
 
1139
QStyle* QApplication::setStyle(const QString& style)
 
1140
{
 
1141
    QStyle *s = QStyleFactory::create(style);
 
1142
    if (!s)
 
1143
        return 0;
 
1144
 
 
1145
    setStyle(s);
 
1146
    return s;
 
1147
}
 
1148
 
 
1149
/*!
 
1150
    Returns the color specification.
 
1151
 
 
1152
    \sa QApplication::setColorSpec()
 
1153
*/
 
1154
 
 
1155
int QApplication::colorSpec()
 
1156
{
 
1157
    return QApplicationPrivate::app_cspec;
 
1158
}
 
1159
 
 
1160
/*!
 
1161
    Sets the color specification for the application to \a spec.
 
1162
 
 
1163
    The color specification controls how the application allocates colors when
 
1164
    run on a display with a limited amount of colors, e.g. 8 bit / 256 color
 
1165
    displays.
 
1166
 
 
1167
    The color specification must be set before you create the QApplication
 
1168
    object.
 
1169
 
 
1170
    The options are:
 
1171
    \list
 
1172
        \li  QApplication::NormalColor. This is the default color allocation
 
1173
            strategy. Use this option if your application uses buttons, menus,
 
1174
            texts and pixmaps with few colors. With this option, the
 
1175
            application uses system global colors. This works fine for most
 
1176
            applications under X11, but on the Windows platform, it may cause
 
1177
            dithering of non-standard colors.
 
1178
        \li  QApplication::CustomColor. Use this option if your application
 
1179
            needs a small number of custom colors. On X11, this option is the
 
1180
            same as NormalColor. On Windows, Qt creates a Windows palette, and
 
1181
            allocates colors to it on demand.
 
1182
        \li  QApplication::ManyColor. Use this option if your application is
 
1183
            very color hungry, e.g., it requires thousands of colors. \br
 
1184
            Under X11 the effect is:
 
1185
            \list
 
1186
                \li  For 256-color displays which have at best a 256 color true
 
1187
                    color visual, the default visual is used, and colors are
 
1188
                    allocated from a color cube. The color cube is the 6x6x6
 
1189
                    (216 color) "Web palette" (the red, green, and blue
 
1190
                    components always have one of the following values: 0x00,
 
1191
                    0x33, 0x66, 0x99, 0xCC, or 0xFF), but the number of colors
 
1192
                    can be changed by the \e -ncols option. The user can force
 
1193
                    the application to use the true color visual with the
 
1194
                    \l{QApplication::QApplication()}{-visual} option.
 
1195
                \li  For 256-color displays which have a true color visual with
 
1196
                    more than 256 colors, use that visual. Silicon Graphics X
 
1197
                    servers this feature, for example. They provide an 8 bit
 
1198
                    visual by default but can deliver true color when asked.
 
1199
            \endlist
 
1200
            On Windows, Qt creates a Windows palette, and fills it with a color
 
1201
            cube.
 
1202
    \endlist
 
1203
 
 
1204
    Be aware that the CustomColor and ManyColor choices may lead to colormap
 
1205
    flashing: The foreground application gets (most) of the available colors,
 
1206
    while the background windows will look less attractive.
 
1207
 
 
1208
    Example:
 
1209
 
 
1210
    \snippet code/src_gui_kernel_qapplication.cpp 2
 
1211
 
 
1212
    \sa colorSpec()
 
1213
*/
 
1214
 
 
1215
void QApplication::setColorSpec(int spec)
 
1216
{
 
1217
    if (qApp)
 
1218
        qWarning("QApplication::setColorSpec: This function must be "
 
1219
                 "called before the QApplication object is created");
 
1220
    QApplicationPrivate::app_cspec = spec;
 
1221
}
 
1222
 
 
1223
/*!
 
1224
    \property QApplication::globalStrut
 
1225
    \brief the minimum size that any GUI element that the user can interact
 
1226
           with should have
 
1227
 
 
1228
    For example, no button should be resized to be smaller than the global
 
1229
    strut size. The strut size should be considered when reimplementing GUI
 
1230
    controls that may be used on touch-screens or similar I/O devices.
 
1231
 
 
1232
    Example:
 
1233
 
 
1234
    \snippet code/src_gui_kernel_qapplication.cpp 3
 
1235
 
 
1236
    By default, this property contains a QSize object with zero width and height.
 
1237
*/
 
1238
QSize QApplication::globalStrut()
 
1239
{
 
1240
    return QApplicationPrivate::app_strut;
 
1241
}
 
1242
 
 
1243
void QApplication::setGlobalStrut(const QSize& strut)
 
1244
{
 
1245
    QApplicationPrivate::app_strut = strut;
 
1246
}
 
1247
 
 
1248
 
 
1249
/*!
 
1250
    \fn QPalette QApplication::palette(const QWidget* widget)
 
1251
    \overload
 
1252
 
 
1253
    If a \a widget is passed, the default palette for the widget's class is
 
1254
    returned. This may or may not be the application palette. In most cases
 
1255
    there is no special palette for certain types of widgets, but one notable
 
1256
    exception is the popup menu under Windows, if the user has defined a
 
1257
    special background color for menus in the display settings.
 
1258
 
 
1259
    \sa setPalette(), QWidget::palette()
 
1260
*/
 
1261
QPalette QApplication::palette(const QWidget* w)
 
1262
{
 
1263
    PaletteHash *hash = app_palettes();
 
1264
    if (w && hash && hash->size()) {
 
1265
        QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(w->metaObject()->className());
 
1266
        if (it != hash->constEnd())
 
1267
            return *it;
 
1268
        for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
 
1269
            if (w->inherits(it.key()))
 
1270
                return it.value();
 
1271
        }
 
1272
    }
 
1273
    return palette();
 
1274
}
 
1275
 
 
1276
/*!
 
1277
    \overload
 
1278
 
 
1279
    Returns the palette for widgets of the given \a className.
 
1280
 
 
1281
    \sa setPalette(), QWidget::palette()
 
1282
*/
 
1283
QPalette QApplication::palette(const char *className)
 
1284
{
 
1285
    if (!QApplicationPrivate::app_pal)
 
1286
        palette();
 
1287
    PaletteHash *hash = app_palettes();
 
1288
    if (className && hash && hash->size()) {
 
1289
        QHash<QByteArray, QPalette>::ConstIterator it = hash->constFind(className);
 
1290
        if (it != hash->constEnd())
 
1291
            return *it;
 
1292
    }
 
1293
    return *QApplicationPrivate::app_pal;
 
1294
}
 
1295
 
 
1296
void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* className, bool clearWidgetPaletteHash)
 
1297
{
 
1298
    QPalette pal = palette;
 
1299
 
 
1300
    if (QApplicationPrivate::app_style)
 
1301
        QApplicationPrivate::app_style->polish(pal); // NB: non-const reference
 
1302
 
 
1303
    bool all = false;
 
1304
    PaletteHash *hash = app_palettes();
 
1305
    if (!className) {
 
1306
        if (QApplicationPrivate::app_pal && pal.isCopyOf(*QApplicationPrivate::app_pal))
 
1307
            return;
 
1308
        if (!QApplicationPrivate::app_pal)
 
1309
            QApplicationPrivate::app_pal = new QPalette(pal);
 
1310
        else
 
1311
            *QApplicationPrivate::app_pal = pal;
 
1312
        if (hash && hash->size()) {
 
1313
            all = true;
 
1314
            if (clearWidgetPaletteHash)
 
1315
                hash->clear();
 
1316
        }
 
1317
    } else if (hash) {
 
1318
        hash->insert(className, pal);
 
1319
    }
 
1320
 
 
1321
    if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
 
1322
        // Send ApplicationPaletteChange to qApp itself, and to the widgets.
 
1323
        QEvent e(QEvent::ApplicationPaletteChange);
 
1324
        QApplication::sendEvent(QApplication::instance(), &e);
 
1325
 
 
1326
        QWidgetList wids = QApplication::allWidgets();
 
1327
        for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
 
1328
            register QWidget *w = *it;
 
1329
            if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
 
1330
                QApplication::sendEvent(w, &e);
 
1331
        }
 
1332
 
 
1333
        // Send to all scenes as well.
 
1334
#ifndef QT_NO_GRAPHICSVIEW
 
1335
        QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
 
1336
        for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
 
1337
             it != scenes.constEnd(); ++it) {
 
1338
            QApplication::sendEvent(*it, &e);
 
1339
        }
 
1340
#endif //QT_NO_GRAPHICSVIEW
 
1341
    }
 
1342
    if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) {
 
1343
        if (!QApplicationPrivate::set_pal)
 
1344
            QApplicationPrivate::set_pal = new QPalette(palette);
 
1345
        else
 
1346
            *QApplicationPrivate::set_pal = palette;
 
1347
    }
 
1348
}
 
1349
 
 
1350
/*!
 
1351
    Changes the default application palette to \a palette.
 
1352
 
 
1353
    If \a className is passed, the change applies only to widgets that inherit
 
1354
    \a className (as reported by QObject::inherits()). If \a className is left
 
1355
    0, the change affects all widgets, thus overriding any previously set class
 
1356
    specific palettes.
 
1357
 
 
1358
    The palette may be changed according to the current GUI style in
 
1359
    QStyle::polish().
 
1360
 
 
1361
    \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
 
1362
    When using style sheets, the palette of a widget can be customized using
 
1363
    the "color", "background-color", "selection-color",
 
1364
    "selection-background-color" and "alternate-background-color".
 
1365
 
 
1366
    \note Some styles do not use the palette for all drawing, for instance, if
 
1367
    they make use of native theme engines. This is the case for the Windows XP,
 
1368
    Windows Vista, and Mac OS X styles.
 
1369
 
 
1370
    \sa QWidget::setPalette(), palette(), QStyle::polish()
 
1371
*/
 
1372
 
 
1373
void QApplication::setPalette(const QPalette &palette, const char* className)
 
1374
{
 
1375
    QApplicationPrivate::setPalette_helper(palette, className, /*clearWidgetPaletteHash=*/ true);
 
1376
}
 
1377
 
 
1378
 
 
1379
 
 
1380
void QApplicationPrivate::setSystemPalette(const QPalette &pal)
 
1381
{
 
1382
    QPalette adjusted;
 
1383
 
 
1384
#if 0
 
1385
    // adjust the system palette to avoid dithering
 
1386
    QColormap cmap = QColormap::instance();
 
1387
    if (cmap.depths() > 4 && cmap.depths() < 24) {
 
1388
        for (int g = 0; g < QPalette::NColorGroups; g++)
 
1389
            for (int i = 0; i < QPalette::NColorRoles; i++) {
 
1390
                QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
 
1391
                color = cmap.colorAt(cmap.pixel(color));
 
1392
                adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
 
1393
            }
 
1394
    }
 
1395
#else
 
1396
    adjusted = pal;
 
1397
#endif
 
1398
 
 
1399
    if (!sys_pal)
 
1400
        sys_pal = new QPalette(adjusted);
 
1401
    else
 
1402
        *sys_pal = adjusted;
 
1403
 
 
1404
 
 
1405
    if (!QApplicationPrivate::set_pal)
 
1406
        QApplication::setPalette(*sys_pal);
 
1407
}
 
1408
 
 
1409
/*!
 
1410
    Returns the default application font.
 
1411
 
 
1412
    \sa fontMetrics(), QWidget::font()
 
1413
*/
 
1414
QFont QApplication::font()
 
1415
{
 
1416
    return QGuiApplication::font();
 
1417
}
 
1418
 
 
1419
/*!
 
1420
    \overload
 
1421
 
 
1422
    Returns the default font for the \a widget.
 
1423
 
 
1424
    \sa fontMetrics(), QWidget::setFont()
 
1425
*/
 
1426
 
 
1427
QFont QApplication::font(const QWidget *widget)
 
1428
{
 
1429
    FontHash *hash = app_fonts();
 
1430
 
 
1431
    if (widget && hash  && hash->size()) {
 
1432
#ifdef Q_OS_MAC
 
1433
        // short circuit for small and mini controls
 
1434
        if (widget->testAttribute(Qt::WA_MacSmallSize)) {
 
1435
            return hash->value(QByteArrayLiteral("QSmallFont"));
 
1436
        } else if (widget->testAttribute(Qt::WA_MacMiniSize)) {
 
1437
            return hash->value(QByteArrayLiteral("QMiniFont"));
 
1438
        }
 
1439
#endif
 
1440
        QHash<QByteArray, QFont>::ConstIterator it =
 
1441
                hash->constFind(widget->metaObject()->className());
 
1442
        if (it != hash->constEnd())
 
1443
            return it.value();
 
1444
        for (it = hash->constBegin(); it != hash->constEnd(); ++it) {
 
1445
            if (widget->inherits(it.key()))
 
1446
                return it.value();
 
1447
        }
 
1448
    }
 
1449
    return font();
 
1450
}
 
1451
 
 
1452
/*!
 
1453
    \overload
 
1454
 
 
1455
    Returns the font for widgets of the given \a className.
 
1456
 
 
1457
    \sa setFont(), QWidget::font()
 
1458
*/
 
1459
QFont QApplication::font(const char *className)
 
1460
{
 
1461
    FontHash *hash = app_fonts();
 
1462
    if (className && hash && hash->size()) {
 
1463
        QHash<QByteArray, QFont>::ConstIterator it = hash->constFind(className);
 
1464
        if (it != hash->constEnd())
 
1465
            return *it;
 
1466
    }
 
1467
    return font();
 
1468
}
 
1469
 
 
1470
 
 
1471
/*!
 
1472
    Changes the default application font to \a font. If \a className is passed,
 
1473
    the change applies only to classes that inherit \a className (as reported
 
1474
    by QObject::inherits()).
 
1475
 
 
1476
    On application start-up, the default font depends on the window system. It
 
1477
    can vary depending on both the window system version and the locale. This
 
1478
    function lets you override the default font; but overriding may be a bad
 
1479
    idea because, for example, some locales need extra large fonts to support
 
1480
    their special characters.
 
1481
 
 
1482
    \warning Do not use this function in conjunction with \l{Qt Style Sheets}.
 
1483
    The font of an application can be customized using the "font" style sheet
 
1484
    property. To set a bold font for all QPushButtons, set the application
 
1485
    styleSheet() as "QPushButton { font: bold }"
 
1486
 
 
1487
    \sa font(), fontMetrics(), QWidget::setFont()
 
1488
*/
 
1489
 
 
1490
void QApplication::setFont(const QFont &font, const char *className)
 
1491
{
 
1492
    bool all = false;
 
1493
    FontHash *hash = app_fonts();
 
1494
    if (!className) {
 
1495
        QGuiApplication::setFont(font);
 
1496
        if (hash && hash->size()) {
 
1497
            all = true;
 
1498
            hash->clear();
 
1499
        }
 
1500
    } else if (hash) {
 
1501
        hash->insert(className, font);
 
1502
    }
 
1503
    if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
 
1504
        // Send ApplicationFontChange to qApp itself, and to the widgets.
 
1505
        QEvent e(QEvent::ApplicationFontChange);
 
1506
        QApplication::sendEvent(QApplication::instance(), &e);
 
1507
 
 
1508
        QWidgetList wids = QApplication::allWidgets();
 
1509
        for (QWidgetList::ConstIterator it = wids.constBegin(); it != wids.constEnd(); ++it) {
 
1510
            register QWidget *w = *it;
 
1511
            if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class
 
1512
                sendEvent(w, &e);
 
1513
        }
 
1514
 
 
1515
#ifndef QT_NO_GRAPHICSVIEW
 
1516
        // Send to all scenes as well.
 
1517
        QList<QGraphicsScene *> &scenes = qApp->d_func()->scene_list;
 
1518
        for (QList<QGraphicsScene *>::ConstIterator it = scenes.constBegin();
 
1519
             it != scenes.constEnd(); ++it) {
 
1520
            QApplication::sendEvent(*it, &e);
 
1521
        }
 
1522
#endif //QT_NO_GRAPHICSVIEW
 
1523
    }
 
1524
    if (!className && (!QApplicationPrivate::sys_font || !font.isCopyOf(*QApplicationPrivate::sys_font))) {
 
1525
        if (!QApplicationPrivate::set_font)
 
1526
            QApplicationPrivate::set_font = new QFont(font);
 
1527
        else
 
1528
            *QApplicationPrivate::set_font = font;
 
1529
    }
 
1530
}
 
1531
 
 
1532
/*! \internal
 
1533
*/
 
1534
void QApplicationPrivate::setSystemFont(const QFont &font)
 
1535
{
 
1536
     if (!sys_font)
 
1537
        sys_font = new QFont(font);
 
1538
    else
 
1539
        *sys_font = font;
 
1540
 
 
1541
    if (!QApplicationPrivate::set_font)
 
1542
        QApplication::setFont(*sys_font);
 
1543
}
 
1544
 
 
1545
/*! \internal
 
1546
*/
 
1547
QString QApplicationPrivate::desktopStyleKey()
 
1548
{
 
1549
    // The platform theme might return a style that is not available, find
 
1550
    // first valid one.
 
1551
    if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
 
1552
        const QStringList availableKeys = QStyleFactory::keys();
 
1553
        foreach (const QString &style, theme->themeHint(QPlatformTheme::StyleNames).toStringList())
 
1554
            if (availableKeys.contains(style, Qt::CaseInsensitive))
 
1555
                return style;
 
1556
    }
 
1557
    return QString();
 
1558
}
 
1559
 
 
1560
/*!
 
1561
    \property QApplication::windowIcon
 
1562
    \brief the default window icon
 
1563
 
 
1564
    \sa QWidget::setWindowIcon(), {Setting the Application Icon}
 
1565
*/
 
1566
QIcon QApplication::windowIcon()
 
1567
{
 
1568
    return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
 
1569
}
 
1570
 
 
1571
void QApplication::setWindowIcon(const QIcon &icon)
 
1572
{
 
1573
    if (!QApplicationPrivate::app_icon)
 
1574
        QApplicationPrivate::app_icon = new QIcon();
 
1575
    *QApplicationPrivate::app_icon = icon;
 
1576
    if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
 
1577
        QEvent e(QEvent::ApplicationWindowIconChange);
 
1578
        QWidgetList all = QApplication::allWidgets();
 
1579
        for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
 
1580
            register QWidget *w = *it;
 
1581
            if (w->isWindow())
 
1582
                sendEvent(w, &e);
 
1583
        }
 
1584
    }
 
1585
}
 
1586
 
 
1587
/*!
 
1588
    Returns a list of the top-level widgets (windows) in the application.
 
1589
 
 
1590
    \note Some of the top-level widgets may be hidden, for example a tooltip if
 
1591
    no tooltip is currently shown.
 
1592
 
 
1593
    Example:
 
1594
 
 
1595
    \snippet code/src_gui_kernel_qapplication.cpp 4
 
1596
 
 
1597
    \sa allWidgets(), QWidget::isWindow(), QWidget::isHidden()
 
1598
*/
 
1599
QWidgetList QApplication::topLevelWidgets()
 
1600
{
 
1601
    QWidgetList list;
 
1602
    QWidgetList all = allWidgets();
 
1603
 
 
1604
    for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
 
1605
        QWidget *w = *it;
 
1606
        if (w->isWindow() && w->windowType() != Qt::Desktop)
 
1607
            list.append(w);
 
1608
    }
 
1609
    return list;
 
1610
}
 
1611
 
 
1612
/*!
 
1613
    Returns a list of all the widgets in the application.
 
1614
 
 
1615
    The list is empty (QList::isEmpty()) if there are no widgets.
 
1616
 
 
1617
    \note Some of the widgets may be hidden.
 
1618
 
 
1619
    Example:
 
1620
    \snippet code/src_gui_kernel_qapplication.cpp 5
 
1621
 
 
1622
    \sa topLevelWidgets(), QWidget::isVisible()
 
1623
*/
 
1624
 
 
1625
QWidgetList QApplication::allWidgets()
 
1626
{
 
1627
    if (QWidgetPrivate::allWidgets)
 
1628
        return QWidgetPrivate::allWidgets->toList();
 
1629
    return QWidgetList();
 
1630
}
 
1631
 
 
1632
/*!
 
1633
    Returns the application widget that has the keyboard input focus, or 0 if
 
1634
    no widget in this application has the focus.
 
1635
 
 
1636
    \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged()
 
1637
*/
 
1638
 
 
1639
QWidget *QApplication::focusWidget()
 
1640
{
 
1641
    return QApplicationPrivate::focus_widget;
 
1642
}
 
1643
 
 
1644
void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason)
 
1645
{
 
1646
#ifndef QT_NO_GRAPHICSVIEW
 
1647
    if (focus && focus->window()->graphicsProxyWidget())
 
1648
        return;
 
1649
#endif
 
1650
 
 
1651
    hidden_focus_widget = 0;
 
1652
 
 
1653
    if (focus != focus_widget) {
 
1654
        if (focus && focus->isHidden()) {
 
1655
            hidden_focus_widget = focus;
 
1656
            return;
 
1657
        }
 
1658
 
 
1659
        if (focus && (reason == Qt::BacktabFocusReason || reason == Qt::TabFocusReason)
 
1660
            && qt_in_tab_key_event)
 
1661
            focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
 
1662
        else if (focus && reason == Qt::ShortcutFocusReason) {
 
1663
            focus->window()->setAttribute(Qt::WA_KeyboardFocusChange);
 
1664
        }
 
1665
        QWidget *prev = focus_widget;
 
1666
        focus_widget = focus;
 
1667
 
 
1668
        if(focus_widget)
 
1669
            focus_widget->d_func()->setFocus_sys();
 
1670
 
 
1671
        if (reason != Qt::NoFocusReason) {
 
1672
 
 
1673
            //send events
 
1674
            if (prev) {
 
1675
#ifdef QT_KEYPAD_NAVIGATION
 
1676
                if (QApplication::keypadNavigationEnabled()) {
 
1677
                    if (prev->hasEditFocus() && reason != Qt::PopupFocusReason)
 
1678
                        prev->setEditFocus(false);
 
1679
                }
 
1680
#endif
 
1681
                QFocusEvent out(QEvent::FocusOut, reason);
 
1682
                QPointer<QWidget> that = prev;
 
1683
                QApplication::sendEvent(prev, &out);
 
1684
                if (that)
 
1685
                    QApplication::sendEvent(that->style(), &out);
 
1686
            }
 
1687
            if(focus && QApplicationPrivate::focus_widget == focus) {
 
1688
                QFocusEvent in(QEvent::FocusIn, reason);
 
1689
                QPointer<QWidget> that = focus;
 
1690
                QApplication::sendEvent(focus, &in);
 
1691
                if (that)
 
1692
                    QApplication::sendEvent(that->style(), &in);
 
1693
            }
 
1694
            emit qApp->focusChanged(prev, focus_widget);
 
1695
        }
 
1696
    }
 
1697
}
 
1698
 
 
1699
 
 
1700
/*!
 
1701
    Returns the application top-level window that has the keyboard input focus,
 
1702
    or 0 if no application window has the focus. There might be an
 
1703
    activeWindow() even if there is no focusWidget(), for example if no widget
 
1704
    in that window accepts key events.
 
1705
 
 
1706
    \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
 
1707
*/
 
1708
 
 
1709
QWidget *QApplication::activeWindow()
 
1710
{
 
1711
    return QApplicationPrivate::active_window;
 
1712
}
 
1713
 
 
1714
/*!
 
1715
    Returns display (screen) font metrics for the application font.
 
1716
 
 
1717
    \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
 
1718
*/
 
1719
 
 
1720
QFontMetrics QApplication::fontMetrics()
 
1721
{
 
1722
    return desktop()->fontMetrics();
 
1723
}
 
1724
 
 
1725
 
 
1726
/*!
 
1727
    Closes all top-level windows.
 
1728
 
 
1729
    This function is particularly useful for applications with many top-level
 
1730
    windows. It could, for example, be connected to a \uicontrol{Exit} entry in the
 
1731
    \uicontrol{File} menu:
 
1732
 
 
1733
    \snippet mainwindows/mdi/mainwindow.cpp 0
 
1734
 
 
1735
    The windows are closed in random order, until one window does not accept
 
1736
    the close event. The application quits when the last window was
 
1737
    successfully closed; this can be turned off by setting
 
1738
    \l quitOnLastWindowClosed to false.
 
1739
 
 
1740
    \sa quitOnLastWindowClosed, lastWindowClosed(), QWidget::close(),
 
1741
    QWidget::closeEvent(), lastWindowClosed(), quit(), topLevelWidgets(),
 
1742
    QWidget::isWindow()
 
1743
*/
 
1744
void QApplication::closeAllWindows()
 
1745
{
 
1746
    bool did_close = true;
 
1747
    QWidget *w;
 
1748
    while ((w = activeModalWidget()) && did_close) {
 
1749
        if (!w->isVisible() || w->data->is_closing)
 
1750
            break;
 
1751
        did_close = w->close();
 
1752
    }
 
1753
    QWidgetList list = QApplication::topLevelWidgets();
 
1754
    for (int i = 0; did_close && i < list.size(); ++i) {
 
1755
        w = list.at(i);
 
1756
        if (w->isVisible()
 
1757
            && w->windowType() != Qt::Desktop
 
1758
            && !w->data->is_closing) {
 
1759
            did_close = w->close();
 
1760
            list = QApplication::topLevelWidgets();
 
1761
            i = -1;
 
1762
        }
 
1763
    }
 
1764
}
 
1765
 
 
1766
/*!
 
1767
    Displays a simple message box about Qt. The message includes the version
 
1768
    number of Qt being used by the application.
 
1769
 
 
1770
    This is useful for inclusion in the \uicontrol Help menu of an application, as
 
1771
    shown in the \l{mainwindows/menus}{Menus} example.
 
1772
 
 
1773
    This function is a convenience slot for QMessageBox::aboutQt().
 
1774
*/
 
1775
void QApplication::aboutQt()
 
1776
{
 
1777
#ifndef QT_NO_MESSAGEBOX
 
1778
    QMessageBox::aboutQt(activeWindow());
 
1779
#endif // QT_NO_MESSAGEBOX
 
1780
}
 
1781
 
 
1782
/*!
 
1783
    \since 4.1
 
1784
    \fn void QApplication::focusChanged(QWidget *old, QWidget *now)
 
1785
 
 
1786
    This signal is emitted when the widget that has keyboard focus changed from
 
1787
    \a old to \a now, i.e., because the user pressed the tab-key, clicked into
 
1788
    a widget or changed the active window. Both \a old and \a now can be the
 
1789
    null-pointer.
 
1790
 
 
1791
    The signal is emitted after both widget have been notified about the change
 
1792
    through QFocusEvent.
 
1793
 
 
1794
    \sa QWidget::setFocus(), QWidget::clearFocus(), Qt::FocusReason
 
1795
*/
 
1796
 
 
1797
/*!\reimp
 
1798
 
 
1799
*/
 
1800
bool QApplication::event(QEvent *e)
 
1801
{
 
1802
    Q_D(QApplication);
 
1803
    if(e->type() == QEvent::Close) {
 
1804
        QCloseEvent *ce = static_cast<QCloseEvent*>(e);
 
1805
        ce->accept();
 
1806
        closeAllWindows();
 
1807
 
 
1808
        QWidgetList list = topLevelWidgets();
 
1809
        for (int i = 0; i < list.size(); ++i) {
 
1810
            QWidget *w = list.at(i);
 
1811
            if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) &&
 
1812
                 (!(w->windowType() == Qt::Dialog) || !w->parentWidget())) {
 
1813
                ce->ignore();
 
1814
                break;
 
1815
            }
 
1816
        }
 
1817
        if (ce->isAccepted()) {
 
1818
            return true;
 
1819
        }
 
1820
#ifndef Q_OS_WIN
 
1821
    } else if (e->type() == QEvent::LocaleChange) {
 
1822
        // on Windows the event propagation is taken care by the
 
1823
        // WM_SETTINGCHANGE event handler.
 
1824
        QWidgetList list = topLevelWidgets();
 
1825
        for (int i = 0; i < list.size(); ++i) {
 
1826
            QWidget *w = list.at(i);
 
1827
            if (!(w->windowType() == Qt::Desktop)) {
 
1828
                if (!w->testAttribute(Qt::WA_SetLocale))
 
1829
                    w->d_func()->setLocale_helper(QLocale(), true);
 
1830
            }
 
1831
        }
 
1832
#endif
 
1833
    } else if (e->type() == QEvent::Timer) {
 
1834
        QTimerEvent *te = static_cast<QTimerEvent*>(e);
 
1835
        Q_ASSERT(te != 0);
 
1836
        if (te->timerId() == d->toolTipWakeUp.timerId()) {
 
1837
            d->toolTipWakeUp.stop();
 
1838
            if (d->toolTipWidget) {
 
1839
                QWidget *w = d->toolTipWidget->window();
 
1840
                // show tooltip if WA_AlwaysShowToolTips is set, or if
 
1841
                // any ancestor of d->toolTipWidget is the active
 
1842
                // window
 
1843
                bool showToolTip = w->testAttribute(Qt::WA_AlwaysShowToolTips);
 
1844
                while (w && !showToolTip) {
 
1845
                    showToolTip = w->isActiveWindow();
 
1846
                    w = w->parentWidget();
 
1847
                    w = w ? w->window() : 0;
 
1848
                }
 
1849
                if (showToolTip) {
 
1850
                    QHelpEvent e(QEvent::ToolTip, d->toolTipPos, d->toolTipGlobalPos);
 
1851
                    QApplication::sendEvent(d->toolTipWidget, &e);
 
1852
                    if (e.isAccepted())
 
1853
                        d->toolTipFallAsleep.start(2000, this);
 
1854
                }
 
1855
            }
 
1856
        } else if (te->timerId() == d->toolTipFallAsleep.timerId()) {
 
1857
            d->toolTipFallAsleep.stop();
 
1858
        }
 
1859
    }
 
1860
 
 
1861
    if(e->type() == QEvent::LanguageChange) {
 
1862
        QWidgetList list = topLevelWidgets();
 
1863
        for (int i = 0; i < list.size(); ++i) {
 
1864
            QWidget *w = list.at(i);
 
1865
            if (!(w->windowType() == Qt::Desktop))
 
1866
                postEvent(w, new QEvent(QEvent::LanguageChange));
 
1867
        }
 
1868
    }
 
1869
 
 
1870
    return QGuiApplication::event(e);
 
1871
}
 
1872
 
 
1873
/*!
 
1874
   \fn void QApplication::syncX()
 
1875
    Was used to synchronize with the X server in 4.x, here for source compatibility.
 
1876
    \internal
 
1877
    \obsolete
 
1878
*/
 
1879
 
 
1880
void QApplicationPrivate::notifyLayoutDirectionChange()
 
1881
{
 
1882
    QWidgetList list = QApplication::topLevelWidgets();
 
1883
    for (int i = 0; i < list.size(); ++i) {
 
1884
        QWidget *w = list.at(i);
 
1885
        QEvent ev(QEvent::ApplicationLayoutDirectionChange);
 
1886
        QCoreApplication::sendEvent(w, &ev);
 
1887
    }
 
1888
}
 
1889
 
 
1890
/*!
 
1891
    \fn void QApplication::setActiveWindow(QWidget* active)
 
1892
 
 
1893
    Sets the active window to the \a active widget in response to a system
 
1894
    event. The function is called from the platform specific event handlers.
 
1895
 
 
1896
    \warning This function does \e not set the keyboard focus to the active
 
1897
    widget. Call QWidget::activateWindow() instead.
 
1898
 
 
1899
    It sets the activeWindow() and focusWidget() attributes and sends proper
 
1900
    \l{QEvent::WindowActivate}{WindowActivate}/\l{QEvent::WindowDeactivate}
 
1901
    {WindowDeactivate} and \l{QEvent::FocusIn}{FocusIn}/\l{QEvent::FocusOut}
 
1902
    {FocusOut} events to all appropriate widgets. The window will then be
 
1903
    painted in active state (e.g. cursors in line edits will blink), and it
 
1904
    will have tool tips enabled.
 
1905
 
 
1906
    \sa activeWindow(), QWidget::activateWindow()
 
1907
*/
 
1908
void QApplication::setActiveWindow(QWidget* act)
 
1909
{
 
1910
    QWidget* window = act?act->window():0;
 
1911
 
 
1912
    if (QApplicationPrivate::active_window == window)
 
1913
        return;
 
1914
 
 
1915
#ifndef QT_NO_GRAPHICSVIEW
 
1916
    if (window && window->graphicsProxyWidget()) {
 
1917
        // Activate the proxy's view->viewport() ?
 
1918
        return;
 
1919
    }
 
1920
#endif
 
1921
 
 
1922
    QWidgetList toBeActivated;
 
1923
    QWidgetList toBeDeactivated;
 
1924
 
 
1925
    if (QApplicationPrivate::active_window) {
 
1926
        if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
 
1927
            QWidgetList list = topLevelWidgets();
 
1928
            for (int i = 0; i < list.size(); ++i) {
 
1929
                QWidget *w = list.at(i);
 
1930
                if (w->isVisible() && w->isActiveWindow())
 
1931
                    toBeDeactivated.append(w);
 
1932
            }
 
1933
        } else {
 
1934
            toBeDeactivated.append(QApplicationPrivate::active_window);
 
1935
        }
 
1936
    }
 
1937
 
 
1938
    if (QApplicationPrivate::focus_widget) {
 
1939
        if (QApplicationPrivate::focus_widget->testAttribute(Qt::WA_InputMethodEnabled))
 
1940
            qApp->inputMethod()->commit();
 
1941
 
 
1942
        QFocusEvent focusAboutToChange(QEvent::FocusAboutToChange, Qt::ActiveWindowFocusReason);
 
1943
        QApplication::sendEvent(QApplicationPrivate::focus_widget, &focusAboutToChange);
 
1944
    }
 
1945
 
 
1946
    QApplicationPrivate::active_window = window;
 
1947
 
 
1948
    if (QApplicationPrivate::active_window) {
 
1949
        if (style()->styleHint(QStyle::SH_Widget_ShareActivation, 0, QApplicationPrivate::active_window)) {
 
1950
            QWidgetList list = topLevelWidgets();
 
1951
            for (int i = 0; i < list.size(); ++i) {
 
1952
                QWidget *w = list.at(i);
 
1953
                if (w->isVisible() && w->isActiveWindow())
 
1954
                    toBeActivated.append(w);
 
1955
            }
 
1956
        } else {
 
1957
            toBeActivated.append(QApplicationPrivate::active_window);
 
1958
        }
 
1959
 
 
1960
    }
 
1961
 
 
1962
    // first the activation/deactivation events
 
1963
    QEvent activationChange(QEvent::ActivationChange);
 
1964
    QEvent windowActivate(QEvent::WindowActivate);
 
1965
    QEvent windowDeactivate(QEvent::WindowDeactivate);
 
1966
 
 
1967
    for (int i = 0; i < toBeActivated.size(); ++i) {
 
1968
        QWidget *w = toBeActivated.at(i);
 
1969
        sendSpontaneousEvent(w, &windowActivate);
 
1970
        sendSpontaneousEvent(w, &activationChange);
 
1971
    }
 
1972
 
 
1973
    for(int i = 0; i < toBeDeactivated.size(); ++i) {
 
1974
        QWidget *w = toBeDeactivated.at(i);
 
1975
        sendSpontaneousEvent(w, &windowDeactivate);
 
1976
        sendSpontaneousEvent(w, &activationChange);
 
1977
    }
 
1978
 
 
1979
    if (QApplicationPrivate::popupWidgets == 0) { // !inPopupMode()
 
1980
        // then focus events
 
1981
        if (!QApplicationPrivate::active_window && QApplicationPrivate::focus_widget) {
 
1982
            QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
 
1983
        } else if (QApplicationPrivate::active_window) {
 
1984
            QWidget *w = QApplicationPrivate::active_window->focusWidget();
 
1985
            if (w && w->isVisible() /*&& w->focusPolicy() != QWidget::NoFocus*/)
 
1986
                w->setFocus(Qt::ActiveWindowFocusReason);
 
1987
            else {
 
1988
                w = QApplicationPrivate::focusNextPrevChild_helper(QApplicationPrivate::active_window, true);
 
1989
                if (w) {
 
1990
                    w->setFocus(Qt::ActiveWindowFocusReason);
 
1991
                } else {
 
1992
                    // If the focus widget is not in the activate_window, clear the focus
 
1993
                    w = QApplicationPrivate::focus_widget;
 
1994
                    if (!w && QApplicationPrivate::active_window->focusPolicy() != Qt::NoFocus)
 
1995
                        QApplicationPrivate::setFocusWidget(QApplicationPrivate::active_window, Qt::ActiveWindowFocusReason);
 
1996
                    else if (!QApplicationPrivate::active_window->isAncestorOf(w))
 
1997
                        QApplicationPrivate::setFocusWidget(0, Qt::ActiveWindowFocusReason);
 
1998
                }
 
1999
            }
 
2000
        }
 
2001
    }
 
2002
}
 
2003
 
 
2004
/*!internal
 
2005
 * Helper function that returns the new focus widget, but does not set the focus reason.
 
2006
 * Returns 0 if a new focus widget could not be found.
 
2007
 * Shared with QGraphicsProxyWidgetPrivate::findFocusChild()
 
2008
*/
 
2009
QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next)
 
2010
{
 
2011
    uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
 
2012
 
 
2013
    QWidget *f = toplevel->focusWidget();
 
2014
    if (!f)
 
2015
        f = toplevel;
 
2016
 
 
2017
    QWidget *w = f;
 
2018
    QWidget *test = f->d_func()->focus_next;
 
2019
    while (test && test != f) {
 
2020
        if ((test->focusPolicy() & focus_flag) == focus_flag
 
2021
            && !(test->d_func()->extra && test->d_func()->extra->focus_proxy)
 
2022
            && test->isVisibleTo(toplevel) && test->isEnabled()
 
2023
            && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
 
2024
            && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
 
2025
            w = test;
 
2026
            if (next)
 
2027
                break;
 
2028
        }
 
2029
        test = test->d_func()->focus_next;
 
2030
    }
 
2031
    if (w == f) {
 
2032
        if (qt_in_tab_key_event) {
 
2033
            w->window()->setAttribute(Qt::WA_KeyboardFocusChange);
 
2034
            w->update();
 
2035
        }
 
2036
        return 0;
 
2037
    }
 
2038
    return w;
 
2039
}
 
2040
 
 
2041
/*!
 
2042
    \fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, const QPointF &globalPosF)
 
2043
    \internal
 
2044
 
 
2045
    Creates the proper Enter/Leave event when widget \a enter is entered and
 
2046
    widget \a leave is left.
 
2047
 */
 
2048
void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, const QPointF &globalPosF)
 
2049
{
 
2050
    const QPoint globalPos = globalPosF.toPoint();
 
2051
#if 0
 
2052
    if (leave) {
 
2053
        QEvent e(QEvent::Leave);
 
2054
        QApplication::sendEvent(leave, & e);
 
2055
    }
 
2056
    if (enter) {
 
2057
        const QPoint windowPos = enter->window()->mapFromGlobal(globalPos);
 
2058
        QEnterEvent e(enter->mapFromGlobal(globalPos), windowPos, globalPos);
 
2059
        QApplication::sendEvent(enter, & e);
 
2060
    }
 
2061
    return;
 
2062
#endif
 
2063
 
 
2064
    QWidget* w ;
 
2065
    if ((!enter && !leave) || (enter == leave))
 
2066
        return;
 
2067
#ifdef ALIEN_DEBUG
 
2068
    qDebug() << "QApplicationPrivate::dispatchEnterLeave, ENTER:" << enter << "LEAVE:" << leave;
 
2069
#endif
 
2070
    QWidgetList leaveList;
 
2071
    QWidgetList enterList;
 
2072
 
 
2073
    bool sameWindow = leave && enter && leave->window() == enter->window();
 
2074
    if (leave && !sameWindow) {
 
2075
        w = leave;
 
2076
        do {
 
2077
            leaveList.append(w);
 
2078
        } while (!w->isWindow() && (w = w->parentWidget()));
 
2079
    }
 
2080
    if (enter && !sameWindow) {
 
2081
        w = enter;
 
2082
        do {
 
2083
            enterList.prepend(w);
 
2084
        } while (!w->isWindow() && (w = w->parentWidget()));
 
2085
    }
 
2086
    if (sameWindow) {
 
2087
        int enterDepth = 0;
 
2088
        int leaveDepth = 0;
 
2089
        w = enter;
 
2090
        while (!w->isWindow() && (w = w->parentWidget()))
 
2091
            enterDepth++;
 
2092
        w = leave;
 
2093
        while (!w->isWindow() && (w = w->parentWidget()))
 
2094
            leaveDepth++;
 
2095
        QWidget* wenter = enter;
 
2096
        QWidget* wleave = leave;
 
2097
        while (enterDepth > leaveDepth) {
 
2098
            wenter = wenter->parentWidget();
 
2099
            enterDepth--;
 
2100
        }
 
2101
        while (leaveDepth > enterDepth) {
 
2102
            wleave = wleave->parentWidget();
 
2103
            leaveDepth--;
 
2104
        }
 
2105
        while (!wenter->isWindow() && wenter != wleave) {
 
2106
            wenter = wenter->parentWidget();
 
2107
            wleave = wleave->parentWidget();
 
2108
        }
 
2109
 
 
2110
        w = leave;
 
2111
        while (w != wleave) {
 
2112
            leaveList.append(w);
 
2113
            w = w->parentWidget();
 
2114
        }
 
2115
        w = enter;
 
2116
        while (w != wenter) {
 
2117
            enterList.prepend(w);
 
2118
            w = w->parentWidget();
 
2119
        }
 
2120
    }
 
2121
 
 
2122
    QEvent leaveEvent(QEvent::Leave);
 
2123
    for (int i = 0; i < leaveList.size(); ++i) {
 
2124
        w = leaveList.at(i);
 
2125
        if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
 
2126
            QApplication::sendEvent(w, &leaveEvent);
 
2127
            if (w->testAttribute(Qt::WA_Hover) &&
 
2128
                (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
 
2129
                Q_ASSERT(instance());
 
2130
                QHoverEvent he(QEvent::HoverLeave, QPoint(-1, -1), w->mapFromGlobal(QApplicationPrivate::instance()->hoverGlobalPos),
 
2131
                               QApplication::keyboardModifiers());
 
2132
                qApp->d_func()->notify_helper(w, &he);
 
2133
            }
 
2134
        }
 
2135
    }
 
2136
    if (!enterList.isEmpty()) {
 
2137
        const QPoint windowPos = enterList.front()->window()->mapFromGlobal(globalPos);
 
2138
        for (int i = 0; i < enterList.size(); ++i) {
 
2139
            w = enterList.at(i);
 
2140
            if (!QApplication::activeModalWidget() || QApplicationPrivate::tryModalHelper(w, 0)) {
 
2141
                const QPointF localPos = w->mapFromGlobal(globalPos);
 
2142
                QEnterEvent enterEvent(localPos, windowPos, globalPosF);
 
2143
                QApplication::sendEvent(w, &enterEvent);
 
2144
                if (w->testAttribute(Qt::WA_Hover) &&
 
2145
                        (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
 
2146
                    QHoverEvent he(QEvent::HoverEnter, localPos, QPoint(-1, -1),
 
2147
                                   QApplication::keyboardModifiers());
 
2148
                    qApp->d_func()->notify_helper(w, &he);
 
2149
                }
 
2150
            }
 
2151
        }
 
2152
    }
 
2153
 
 
2154
#ifndef QT_NO_CURSOR
 
2155
    // Update cursor for alien/graphics widgets.
 
2156
 
 
2157
    const bool enterOnAlien = (enter && (isAlien(enter) || enter->testAttribute(Qt::WA_DontShowOnScreen)));
 
2158
    // Whenever we leave an alien widget on X11/QPA, we need to reset its nativeParentWidget()'s cursor.
 
2159
    // This is not required on Windows as the cursor is reset on every single mouse move.
 
2160
    QWidget *parentOfLeavingCursor = 0;
 
2161
    for (int i = 0; i < leaveList.size(); ++i) {
 
2162
        w = leaveList.at(i);
 
2163
        if (!isAlien(w))
 
2164
            break;
 
2165
        if (w->testAttribute(Qt::WA_SetCursor)) {
 
2166
            QWidget *parent = w->parentWidget();
 
2167
            while (parent && parent->d_func()->data.in_destructor)
 
2168
                parent = parent->parentWidget();
 
2169
            parentOfLeavingCursor = parent;
 
2170
            //continue looping, we need to find the downest alien widget with a cursor.
 
2171
            // (downest on the screen)
 
2172
        }
 
2173
    }
 
2174
    //check that we will not call qt_x11_enforce_cursor twice with the same native widget
 
2175
    if (parentOfLeavingCursor && (!enterOnAlien
 
2176
        || parentOfLeavingCursor->effectiveWinId() != enter->effectiveWinId())) {
 
2177
#ifndef QT_NO_GRAPHICSVIEW
 
2178
        if (!parentOfLeavingCursor->window()->graphicsProxyWidget())
 
2179
#endif
 
2180
        {
 
2181
            if (enter == QApplication::desktop()) {
 
2182
                qt_qpa_set_cursor(enter, true);
 
2183
            } else {
 
2184
                qt_qpa_set_cursor(parentOfLeavingCursor, true);
 
2185
            }
 
2186
        }
 
2187
    }
 
2188
    if (enterOnAlien) {
 
2189
        QWidget *cursorWidget = enter;
 
2190
        while (!cursorWidget->isWindow() && !cursorWidget->isEnabled())
 
2191
            cursorWidget = cursorWidget->parentWidget();
 
2192
 
 
2193
        if (!cursorWidget)
 
2194
            return;
 
2195
 
 
2196
#ifndef QT_NO_GRAPHICSVIEW
 
2197
        if (cursorWidget->window()->graphicsProxyWidget()) {
 
2198
            QWidgetPrivate::nearestGraphicsProxyWidget(cursorWidget)->setCursor(cursorWidget->cursor());
 
2199
        } else
 
2200
#endif
 
2201
        {
 
2202
            qt_qpa_set_cursor(cursorWidget, true);
 
2203
        }
 
2204
    }
 
2205
#endif
 
2206
}
 
2207
 
 
2208
/* exported for the benefit of testing tools */
 
2209
Q_WIDGETS_EXPORT bool qt_tryModalHelper(QWidget *widget, QWidget **rettop)
 
2210
{
 
2211
    return QApplicationPrivate::tryModalHelper(widget, rettop);
 
2212
}
 
2213
 
 
2214
/*! \internal
 
2215
    Returns true if \a widget is blocked by a modal window.
 
2216
 */
 
2217
bool QApplicationPrivate::isBlockedByModal(QWidget *widget)
 
2218
{
 
2219
    widget = widget->window();
 
2220
    QWindow *window = widget->windowHandle();
 
2221
    return window && self->isWindowBlocked(window);
 
2222
}
 
2223
 
 
2224
bool QApplicationPrivate::isWindowBlocked(QWindow *window, QWindow **blockingWindow) const
 
2225
{
 
2226
    QWindow *unused = 0;
 
2227
    if (!window) {
 
2228
        qWarning().nospace() << "window == 0 passed.";
 
2229
        return false;
 
2230
    }
 
2231
    if (!blockingWindow)
 
2232
        blockingWindow = &unused;
 
2233
 
 
2234
    if (modalWindowList.isEmpty()) {
 
2235
        *blockingWindow = 0;
 
2236
        return false;
 
2237
    }
 
2238
    QWidget *popupWidget = QApplication::activePopupWidget();
 
2239
    QWindow *popupWindow = popupWidget ? popupWidget->windowHandle() : 0;
 
2240
    if (popupWindow == window) {
 
2241
        *blockingWindow = 0;
 
2242
        return false;
 
2243
    }
 
2244
 
 
2245
    for (int i = 0; i < modalWindowList.count(); ++i) {
 
2246
        QWindow *modalWindow = modalWindowList.at(i);
 
2247
 
 
2248
        {
 
2249
            // check if the modal window is our window or a (transient) parent of our window
 
2250
            QWindow *w = window;
 
2251
            while (w) {
 
2252
                if (w == modalWindow) {
 
2253
                    *blockingWindow = 0;
 
2254
                    return false;
 
2255
                }
 
2256
                QWindow *p = w->parent();
 
2257
                if (!p)
 
2258
                    p = w->transientParent();
 
2259
                w = p;
 
2260
            }
 
2261
 
 
2262
            // Embedded in-process windows are not visible in normal parent-child chain,
 
2263
            // so check the native parent chain, too.
 
2264
            const QPlatformWindow *platWin = window->handle();
 
2265
            const QPlatformWindow *modalPlatWin = modalWindow->handle();
 
2266
            if (platWin && modalPlatWin && platWin->isEmbedded(modalPlatWin))
 
2267
                return false;
 
2268
        }
 
2269
 
 
2270
        Qt::WindowModality windowModality = modalWindow->modality();
 
2271
        QWidgetWindow *modalWidgetWindow = qobject_cast<QWidgetWindow *>(modalWindow);
 
2272
        if (windowModality == Qt::NonModal) {
 
2273
            // determine the modality type if it hasn't been set on the
 
2274
            // modalWindow's widget, this normally happens when waiting for a
 
2275
            // native dialog. use WindowModal if we are the child of a group
 
2276
            // leader; otherwise use ApplicationModal.
 
2277
            QWidget *m = modalWidgetWindow ? modalWidgetWindow->widget() : 0;
 
2278
            while (m && !m->testAttribute(Qt::WA_GroupLeader)) {
 
2279
                m = m->parentWidget();
 
2280
                if (m)
 
2281
                    m = m->window();
 
2282
            }
 
2283
            windowModality = (m && m->testAttribute(Qt::WA_GroupLeader))
 
2284
                             ? Qt::WindowModal
 
2285
                             : Qt::ApplicationModal;
 
2286
        }
 
2287
 
 
2288
        switch (windowModality) {
 
2289
        case Qt::ApplicationModal:
 
2290
        {
 
2291
            QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(window);
 
2292
            QWidget *groupLeaderForWidget = widgetWindow ? widgetWindow->widget() : 0;
 
2293
            while (groupLeaderForWidget && !groupLeaderForWidget->testAttribute(Qt::WA_GroupLeader))
 
2294
                groupLeaderForWidget = groupLeaderForWidget->parentWidget();
 
2295
 
 
2296
            if (groupLeaderForWidget) {
 
2297
                // if \a widget has WA_GroupLeader, it can only be blocked by ApplicationModal children
 
2298
                QWidget *m = modalWidgetWindow ? modalWidgetWindow->widget() : 0;
 
2299
                while (m && m != groupLeaderForWidget && !m->testAttribute(Qt::WA_GroupLeader))
 
2300
                    m = m->parentWidget();
 
2301
                if (m == groupLeaderForWidget) {
 
2302
                    *blockingWindow = m->windowHandle();
 
2303
                    return true;
 
2304
                }
 
2305
            } else if (modalWindow != window) {
 
2306
                *blockingWindow = modalWindow;
 
2307
                return true;
 
2308
            }
 
2309
            break;
 
2310
        }
 
2311
        case Qt::WindowModal:
 
2312
        {
 
2313
            QWindow *w = window;
 
2314
            do {
 
2315
                QWindow *m = modalWindow;
 
2316
                do {
 
2317
                    if (m == w) {
 
2318
                        *blockingWindow = m;
 
2319
                        return true;
 
2320
                    }
 
2321
                    QWindow *p = m->parent();
 
2322
                    if (!p)
 
2323
                        p = m->transientParent();
 
2324
                    m = p;
 
2325
                } while (m);
 
2326
                QWindow *p = w->parent();
 
2327
                if (!p)
 
2328
                    p = w->transientParent();
 
2329
                w = p;
 
2330
            } while (w);
 
2331
            break;
 
2332
        }
 
2333
        default:
 
2334
            Q_ASSERT_X(false, "QApplication", "internal error, a modal window cannot be modeless");
 
2335
            break;
 
2336
        }
 
2337
    }
 
2338
    *blockingWindow = 0;
 
2339
    return false;
 
2340
}
 
2341
 
 
2342
/*!\internal
 
2343
 
 
2344
  Called from qapplication_\e{platform}.cpp, returns true
 
2345
  if the widget should accept the event.
 
2346
 */
 
2347
bool QApplicationPrivate::tryModalHelper(QWidget *widget, QWidget **rettop)
 
2348
{
 
2349
    QWidget *top = QApplication::activeModalWidget();
 
2350
    if (rettop)
 
2351
        *rettop = top;
 
2352
 
 
2353
    // the active popup widget always gets the input event
 
2354
    if (QApplication::activePopupWidget())
 
2355
        return true;
 
2356
 
 
2357
    return !isBlockedByModal(widget->window());
 
2358
}
 
2359
 
 
2360
/*
 
2361
   \internal
 
2362
*/
 
2363
QWidget *QApplicationPrivate::pickMouseReceiver(QWidget *candidate, const QPoint &windowPos,
 
2364
                                                QPoint *pos, QEvent::Type type,
 
2365
                                                Qt::MouseButtons buttons, QWidget *buttonDown,
 
2366
                                                QWidget *alienWidget)
 
2367
{
 
2368
    Q_ASSERT(candidate);
 
2369
 
 
2370
    QWidget *mouseGrabber = QWidget::mouseGrabber();
 
2371
    if (((type == QEvent::MouseMove && buttons) || (type == QEvent::MouseButtonRelease))
 
2372
            && !buttonDown && !mouseGrabber) {
 
2373
        return 0;
 
2374
    }
 
2375
 
 
2376
    if (alienWidget && alienWidget->internalWinId())
 
2377
        alienWidget = 0;
 
2378
 
 
2379
    QWidget *receiver = candidate;
 
2380
 
 
2381
    if (!mouseGrabber)
 
2382
        mouseGrabber = (buttonDown && !isBlockedByModal(buttonDown)) ? buttonDown : alienWidget;
 
2383
 
 
2384
    if (mouseGrabber && mouseGrabber != candidate) {
 
2385
        receiver = mouseGrabber;
 
2386
        *pos = receiver->mapFromGlobal(candidate->mapToGlobal(windowPos));
 
2387
#ifdef ALIEN_DEBUG
 
2388
        qDebug() << "  ** receiver adjusted to:" << receiver << "pos:" << pos;
 
2389
#endif
 
2390
    }
 
2391
 
 
2392
    return receiver;
 
2393
 
 
2394
}
 
2395
 
 
2396
/*
 
2397
   \internal
 
2398
*/
 
2399
bool QApplicationPrivate::sendMouseEvent(QWidget *receiver, QMouseEvent *event,
 
2400
                                         QWidget *alienWidget, QWidget *nativeWidget,
 
2401
                                         QWidget **buttonDown, QPointer<QWidget> &lastMouseReceiver,
 
2402
                                         bool spontaneous)
 
2403
{
 
2404
    Q_ASSERT(receiver);
 
2405
    Q_ASSERT(event);
 
2406
    Q_ASSERT(nativeWidget);
 
2407
    Q_ASSERT(buttonDown);
 
2408
 
 
2409
    if (alienWidget && !isAlien(alienWidget))
 
2410
        alienWidget = 0;
 
2411
 
 
2412
    QPointer<QWidget> receiverGuard = receiver;
 
2413
    QPointer<QWidget> nativeGuard = nativeWidget;
 
2414
    QPointer<QWidget> alienGuard = alienWidget;
 
2415
    QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
 
2416
 
 
2417
    const bool graphicsWidget = nativeWidget->testAttribute(Qt::WA_DontShowOnScreen);
 
2418
 
 
2419
    bool widgetUnderMouse = QRectF(receiver->rect()).contains(event->localPos());
 
2420
 
 
2421
    // Clear the obsolete leaveAfterRelease value, if mouse button has been released but
 
2422
    // leaveAfterRelease has not been updated.
 
2423
    // This happens e.g. when modal dialog or popup is shown as a response to button click.
 
2424
    if (leaveAfterRelease && !*buttonDown && !event->buttons())
 
2425
        leaveAfterRelease = 0;
 
2426
 
 
2427
    if (*buttonDown) {
 
2428
        if (!graphicsWidget) {
 
2429
            // Register the widget that shall receive a leave event
 
2430
            // after the last button is released.
 
2431
            if ((alienWidget || !receiver->internalWinId()) && !leaveAfterRelease && !QWidget::mouseGrabber())
 
2432
                leaveAfterRelease = *buttonDown;
 
2433
            if (event->type() == QEvent::MouseButtonRelease && !event->buttons())
 
2434
                *buttonDown = 0;
 
2435
        }
 
2436
    } else if (lastMouseReceiver && widgetUnderMouse) {
 
2437
        // Dispatch enter/leave if we move:
 
2438
        // 1) from an alien widget to another alien widget or
 
2439
        //    from a native widget to an alien widget (first OR case)
 
2440
        // 2) from an alien widget to a native widget (second OR case)
 
2441
        if ((alienWidget && alienWidget != lastMouseReceiver)
 
2442
            || (isAlien(lastMouseReceiver) && !alienWidget)) {
 
2443
            if (activePopupWidget) {
 
2444
                if (!QWidget::mouseGrabber())
 
2445
                    dispatchEnterLeave(alienWidget ? alienWidget : nativeWidget, lastMouseReceiver, event->screenPos());
 
2446
            } else {
 
2447
                dispatchEnterLeave(receiver, lastMouseReceiver, event->screenPos());
 
2448
            }
 
2449
 
 
2450
        }
 
2451
    }
 
2452
 
 
2453
#ifdef ALIEN_DEBUG
 
2454
    qDebug() << "QApplicationPrivate::sendMouseEvent: receiver:" << receiver
 
2455
             << "pos:" << event->pos() << "alien" << alienWidget << "button down"
 
2456
             << *buttonDown << "last" << lastMouseReceiver << "leave after release"
 
2457
             << leaveAfterRelease;
 
2458
#endif
 
2459
 
 
2460
    // We need this quard in case someone opens a modal dialog / popup. If that's the case
 
2461
    // leaveAfterRelease is set to null, but we shall not update lastMouseReceiver.
 
2462
    const bool wasLeaveAfterRelease = leaveAfterRelease != 0;
 
2463
    bool result;
 
2464
    if (spontaneous)
 
2465
        result = QApplication::sendSpontaneousEvent(receiver, event);
 
2466
    else
 
2467
        result = QApplication::sendEvent(receiver, event);
 
2468
 
 
2469
    if (!graphicsWidget && leaveAfterRelease && event->type() == QEvent::MouseButtonRelease
 
2470
        && !event->buttons() && QWidget::mouseGrabber() != leaveAfterRelease) {
 
2471
        // Dispatch enter/leave if:
 
2472
        // 1) the mouse grabber is an alien widget
 
2473
        // 2) the button is released on an alien widget
 
2474
        QWidget *enter = 0;
 
2475
        if (nativeGuard)
 
2476
            enter = alienGuard ? alienWidget : nativeWidget;
 
2477
        else // The receiver is typically deleted on mouse release with drag'n'drop.
 
2478
            enter = QApplication::widgetAt(event->globalPos());
 
2479
        dispatchEnterLeave(enter, leaveAfterRelease, event->screenPos());
 
2480
        leaveAfterRelease = 0;
 
2481
        lastMouseReceiver = enter;
 
2482
    } else if (!wasLeaveAfterRelease) {
 
2483
        if (activePopupWidget) {
 
2484
            if (!QWidget::mouseGrabber())
 
2485
                lastMouseReceiver = alienGuard ? alienWidget : (nativeGuard ? nativeWidget : 0);
 
2486
        } else {
 
2487
            lastMouseReceiver = receiverGuard ? receiver : QApplication::widgetAt(event->globalPos());
 
2488
        }
 
2489
    }
 
2490
 
 
2491
    return result;
 
2492
}
 
2493
 
 
2494
/*
 
2495
    This function should only be called when the widget changes visibility, i.e.
 
2496
    when the \a widget is shown, hidden or deleted. This function does nothing
 
2497
    if the widget is a top-level or native, i.e. not an alien widget. In that
 
2498
    case enter/leave events are genereated by the underlying windowing system.
 
2499
*/
 
2500
extern QPointer<QWidget> qt_last_mouse_receiver;
 
2501
extern QWidget *qt_button_down;
 
2502
void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
 
2503
{
 
2504
#ifndef QT_NO_CURSOR
 
2505
    if (!widget || widget->isWindow())
 
2506
        return;
 
2507
    const bool widgetInShow = widget->isVisible() && !widget->data->in_destructor;
 
2508
    if (!widgetInShow && widget != qt_last_mouse_receiver)
 
2509
        return; // Widget was not under the cursor when it was hidden/deleted.
 
2510
 
 
2511
    if (widgetInShow && widget->parentWidget()->data->in_show)
 
2512
        return; // Ingore recursive show.
 
2513
 
 
2514
    QWidget *mouseGrabber = QWidget::mouseGrabber();
 
2515
    if (mouseGrabber && mouseGrabber != widget)
 
2516
        return; // Someone else has the grab; enter/leave should not occur.
 
2517
 
 
2518
    QWidget *tlw = widget->window();
 
2519
    if (tlw->data->in_destructor || tlw->data->is_closing)
 
2520
        return; // Closing down the business.
 
2521
 
 
2522
    if (widgetInShow && (!qt_last_mouse_receiver || qt_last_mouse_receiver->window() != tlw))
 
2523
        return; // Mouse cursor not inside the widget's top-level.
 
2524
 
 
2525
    const QPoint globalPos(QCursor::pos());
 
2526
    QPoint windowPos = tlw->mapFromGlobal(globalPos);
 
2527
 
 
2528
    // Find the current widget under the mouse. If this function was called from
 
2529
    // the widget's destructor, we have to make sure childAt() doesn't take into
 
2530
    // account widgets that are about to be destructed.
 
2531
    QWidget *widgetUnderCursor = tlw->d_func()->childAt_helper(windowPos, widget->data->in_destructor);
 
2532
    if (!widgetUnderCursor)
 
2533
        widgetUnderCursor = tlw;
 
2534
    QPoint pos = widgetUnderCursor->mapFrom(tlw, windowPos);
 
2535
 
 
2536
    if (widgetInShow && widgetUnderCursor != widget && !widget->isAncestorOf(widgetUnderCursor))
 
2537
        return; // Mouse cursor not inside the widget or any of its children.
 
2538
 
 
2539
    if (widget->data->in_destructor && qt_button_down == widget)
 
2540
        qt_button_down = 0;
 
2541
 
 
2542
    // Send enter/leave events followed by a mouse move on the entered widget.
 
2543
    QMouseEvent e(QEvent::MouseMove, pos, windowPos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
 
2544
    sendMouseEvent(widgetUnderCursor, &e, widgetUnderCursor, tlw, &qt_button_down, qt_last_mouse_receiver);
 
2545
#endif // QT_NO_CURSOR
 
2546
}
 
2547
 
 
2548
/*!
 
2549
    Returns the desktop widget (also called the root window).
 
2550
 
 
2551
    The desktop may be composed of multiple screens, so it would be incorrect,
 
2552
    for example, to attempt to \e center some widget in the desktop's geometry.
 
2553
    QDesktopWidget has various functions for obtaining useful geometries upon
 
2554
    the desktop, such as QDesktopWidget::screenGeometry() and
 
2555
    QDesktopWidget::availableGeometry().
 
2556
 
 
2557
    On X11, it is also possible to draw on the desktop.
 
2558
*/
 
2559
QDesktopWidget *QApplication::desktop()
 
2560
{
 
2561
    if (!qt_desktopWidget || // not created yet
 
2562
         !(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away
 
2563
        qt_desktopWidget = new QDesktopWidget();
 
2564
    }
 
2565
    return qt_desktopWidget;
 
2566
}
 
2567
 
 
2568
/*
 
2569
  Sets the time after which a drag should start to \a ms ms.
 
2570
 
 
2571
  \sa startDragTime()
 
2572
*/
 
2573
 
 
2574
void QApplication::setStartDragTime(int ms)
 
2575
{
 
2576
    Q_UNUSED(ms)
 
2577
}
 
2578
 
 
2579
/*!
 
2580
    \property QApplication::startDragTime
 
2581
    \brief the time in milliseconds that a mouse button must be held down
 
2582
    before a drag and drop operation will begin
 
2583
 
 
2584
    If you support drag and drop in your application, and want to start a drag
 
2585
    and drop operation after the user has held down a mouse button for a
 
2586
    certain amount of time, you should use this property's value as the delay.
 
2587
 
 
2588
    Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit, for
 
2589
    starting a drag.
 
2590
 
 
2591
    The default value is 500 ms.
 
2592
 
 
2593
    \sa startDragDistance(), {Drag and Drop}
 
2594
*/
 
2595
 
 
2596
int QApplication::startDragTime()
 
2597
{
 
2598
    return qApp->styleHints()->startDragTime();
 
2599
}
 
2600
 
 
2601
/*
 
2602
    Sets the distance after which a drag should start to \a l pixels.
 
2603
 
 
2604
    \sa startDragDistance()
 
2605
*/
 
2606
 
 
2607
void QApplication::setStartDragDistance(int l)
 
2608
{
 
2609
    Q_UNUSED(l);
 
2610
}
 
2611
 
 
2612
/*!
 
2613
    \property QApplication::startDragDistance
 
2614
 
 
2615
    If you support drag and drop in your application, and want to start a drag
 
2616
    and drop operation after the user has moved the cursor a certain distance
 
2617
    with a button held down, you should use this property's value as the
 
2618
    minimum distance required.
 
2619
 
 
2620
    For example, if the mouse position of the click is stored in \c startPos
 
2621
    and the current position (e.g. in the mouse move event) is \c currentPos,
 
2622
    you can find out if a drag should be started with code like this:
 
2623
 
 
2624
    \snippet code/src_gui_kernel_qapplication.cpp 7
 
2625
 
 
2626
    Qt uses this value internally, e.g. in QFileDialog.
 
2627
 
 
2628
    The default value is 4 pixels.
 
2629
 
 
2630
    \sa startDragTime(), QPoint::manhattanLength(), {Drag and Drop}
 
2631
*/
 
2632
 
 
2633
int QApplication::startDragDistance()
 
2634
{
 
2635
    return qApp->styleHints()->startDragDistance();
 
2636
}
 
2637
 
 
2638
/*!
 
2639
    Enters the main event loop and waits until exit() is called, then returns
 
2640
    the value that was set to exit() (which is 0 if exit() is called via
 
2641
    quit()).
 
2642
 
 
2643
    It is necessary to call this function to start event handling. The main
 
2644
    event loop receives events from the window system and dispatches these to
 
2645
    the application widgets.
 
2646
 
 
2647
    Generally, no user interaction can take place before calling exec(). As a
 
2648
    special case, modal widgets like QMessageBox can be used before calling
 
2649
    exec(), because modal widgets call exec() to start a local event loop.
 
2650
 
 
2651
    To make your application perform idle processing, i.e., executing a special
 
2652
    function whenever there are no pending events, use a QTimer with 0 timeout.
 
2653
    More advanced idle processing schemes can be achieved using processEvents().
 
2654
 
 
2655
    We recommend that you connect clean-up code to the
 
2656
    \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in your
 
2657
    application's \c{main()} function. This is because, on some platforms the
 
2658
    QApplication::exec() call may not return. For example, on the Windows
 
2659
    platform, when the user logs off, the system terminates the process after Qt
 
2660
    closes all top-level windows. Hence, there is \e{no guarantee} that the
 
2661
    application will have time to exit its event loop and execute code at the
 
2662
    end of the \c{main()} function, after the QApplication::exec() call.
 
2663
 
 
2664
    \sa quitOnLastWindowClosed, quit(), exit(), processEvents(),
 
2665
        QCoreApplication::exec()
 
2666
*/
 
2667
int QApplication::exec()
 
2668
{
 
2669
    return QGuiApplication::exec();
 
2670
}
 
2671
 
 
2672
bool QApplicationPrivate::shouldQuit()
 
2673
{
 
2674
    /* if there is no non-withdrawn primary window left (except
 
2675
        the ones without QuitOnClose), we emit the lastWindowClosed
 
2676
        signal */
 
2677
    QWidgetList list = QApplication::topLevelWidgets();
 
2678
    for (int i = 0; i < list.size(); ++i) {
 
2679
        QWidget *w = list.at(i);
 
2680
        if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose))
 
2681
            return false;
 
2682
    }
 
2683
    return QGuiApplicationPrivate::shouldQuit();
 
2684
}
 
2685
 
 
2686
static inline void closeAllPopups()
 
2687
{
 
2688
    // Close all popups: In case some popup refuses to close,
 
2689
    // we give up after 1024 attempts (to avoid an infinite loop).
 
2690
    int maxiter = 1024;
 
2691
    QWidget *popup;
 
2692
    while ((popup = QApplication::activePopupWidget()) && maxiter--)
 
2693
        popup->close();
 
2694
}
 
2695
 
 
2696
/*! \reimp
 
2697
 */
 
2698
bool QApplication::notify(QObject *receiver, QEvent *e)
 
2699
{
 
2700
    Q_D(QApplication);
 
2701
    // no events are delivered after ~QCoreApplication() has started
 
2702
    if (QApplicationPrivate::is_app_closing)
 
2703
        return true;
 
2704
 
 
2705
    if (receiver == 0) {                        // serious error
 
2706
        qWarning("QApplication::notify: Unexpected null receiver");
 
2707
        return true;
 
2708
    }
 
2709
 
 
2710
#ifndef QT_NO_DEBUG
 
2711
    d->checkReceiverThread(receiver);
 
2712
#endif
 
2713
 
 
2714
    if (receiver->isWindowType())
 
2715
        QGuiApplicationPrivate::sendQWindowEventToQPlatformWindow(static_cast<QWindow *>(receiver), e);
 
2716
 
 
2717
    if(e->spontaneous()) {
 
2718
        // Capture the current mouse and keyboard states. Doing so here is
 
2719
        // required in order to support QTestLib synthesized events. Real mouse
 
2720
        // and keyboard state updates from the platform plugin are managed by
 
2721
        // QGuiApplicationPrivate::process(Mouse|Wheel|Key|Touch|Tablet)Event();
 
2722
        switch (e->type()) {
 
2723
        case QEvent::MouseButtonPress:
 
2724
            {
 
2725
                QMouseEvent *me = static_cast<QMouseEvent*>(e);
 
2726
                QApplicationPrivate::modifier_buttons = me->modifiers();
 
2727
                QApplicationPrivate::mouse_buttons |= me->button();
 
2728
                break;
 
2729
            }
 
2730
        case QEvent::MouseButtonRelease:
 
2731
            {
 
2732
                QMouseEvent *me = static_cast<QMouseEvent*>(e);
 
2733
                QApplicationPrivate::modifier_buttons = me->modifiers();
 
2734
                QApplicationPrivate::mouse_buttons &= ~me->button();
 
2735
                break;
 
2736
            }
 
2737
        case QEvent::KeyPress:
 
2738
        case QEvent::KeyRelease:
 
2739
        case QEvent::MouseMove:
 
2740
#ifndef QT_NO_WHEELEVENT
 
2741
        case QEvent::Wheel:
 
2742
#endif
 
2743
        case QEvent::TouchBegin:
 
2744
        case QEvent::TouchUpdate:
 
2745
        case QEvent::TouchEnd:
 
2746
#ifndef QT_NO_TABLETEVENT
 
2747
        case QEvent::TabletMove:
 
2748
        case QEvent::TabletPress:
 
2749
        case QEvent::TabletRelease:
 
2750
#endif
 
2751
            {
 
2752
                QInputEvent *ie = static_cast<QInputEvent*>(e);
 
2753
                QApplicationPrivate::modifier_buttons = ie->modifiers();
 
2754
                break;
 
2755
            }
 
2756
        default:
 
2757
            break;
 
2758
        }
 
2759
    }
 
2760
 
 
2761
#ifndef QT_NO_GESTURES
 
2762
    // walk through parents and check for gestures
 
2763
    if (d->gestureManager) {
 
2764
        switch (e->type()) {
 
2765
        case QEvent::Paint:
 
2766
        case QEvent::MetaCall:
 
2767
        case QEvent::DeferredDelete:
 
2768
        case QEvent::DragEnter: case QEvent::DragMove: case QEvent::DragLeave:
 
2769
        case QEvent::Drop: case QEvent::DragResponse:
 
2770
        case QEvent::ChildAdded: case QEvent::ChildPolished:
 
2771
        case QEvent::ChildRemoved:
 
2772
        case QEvent::UpdateRequest:
 
2773
        case QEvent::UpdateLater:
 
2774
        case QEvent::LocaleChange:
 
2775
        case QEvent::Style:
 
2776
        case QEvent::IconDrag:
 
2777
        case QEvent::StyleChange:
 
2778
        case QEvent::GraphicsSceneDragEnter:
 
2779
        case QEvent::GraphicsSceneDragMove:
 
2780
        case QEvent::GraphicsSceneDragLeave:
 
2781
        case QEvent::GraphicsSceneDrop:
 
2782
        case QEvent::DynamicPropertyChange:
 
2783
        case QEvent::NetworkReplyUpdated:
 
2784
            break;
 
2785
        default:
 
2786
            if (receiver->isWidgetType()) {
 
2787
                if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
 
2788
                    return true;
 
2789
            } else {
 
2790
                // a special case for events that go to QGesture objects.
 
2791
                // We pass the object to the gesture manager and it'll figure
 
2792
                // out if it's QGesture or not.
 
2793
                if (d->gestureManager->filterEvent(receiver, e))
 
2794
                    return true;
 
2795
            }
 
2796
        }
 
2797
    }
 
2798
#endif // QT_NO_GESTURES
 
2799
 
 
2800
    switch (e->type()) {
 
2801
    case QEvent::ApplicationDeactivate:
 
2802
        // Close all popups (triggers when switching applications
 
2803
        // by pressing ALT-TAB on Windows, which is not receive as key event.
 
2804
        closeAllPopups();
 
2805
        break;
 
2806
    case QEvent::Wheel: // User input and window activation makes tooltips sleep
 
2807
    case QEvent::ActivationChange:
 
2808
    case QEvent::KeyPress:
 
2809
    case QEvent::KeyRelease:
 
2810
    case QEvent::FocusOut:
 
2811
    case QEvent::FocusIn:
 
2812
    case QEvent::MouseButtonPress:
 
2813
    case QEvent::MouseButtonRelease:
 
2814
    case QEvent::MouseButtonDblClick:
 
2815
        d->toolTipFallAsleep.stop();
 
2816
        // fall-through
 
2817
    case QEvent::Leave:
 
2818
        d->toolTipWakeUp.stop();
 
2819
    default:
 
2820
        break;
 
2821
    }
 
2822
 
 
2823
    bool res = false;
 
2824
    if (!receiver->isWidgetType()) {
 
2825
        res = d->notify_helper(receiver, e);
 
2826
    } else switch (e->type()) {
 
2827
    case QEvent::ShortcutOverride:
 
2828
    case QEvent::KeyPress:
 
2829
    case QEvent::KeyRelease:
 
2830
        {
 
2831
            bool isWidget = receiver->isWidgetType();
 
2832
            bool isGraphicsWidget = false;
 
2833
#ifndef QT_NO_GRAPHICSVIEW
 
2834
            isGraphicsWidget = !isWidget && qobject_cast<QGraphicsWidget *>(receiver);
 
2835
#endif
 
2836
            if (!isWidget && !isGraphicsWidget) {
 
2837
                res = d->notify_helper(receiver, e);
 
2838
                break;
 
2839
            }
 
2840
 
 
2841
            QKeyEvent* key = static_cast<QKeyEvent*>(e);
 
2842
            if (key->type()==QEvent::KeyPress) {
 
2843
#ifndef QT_NO_SHORTCUT
 
2844
                // Try looking for a Shortcut before sending key events
 
2845
                if ((res = qApp->d_func()->shortcutMap.tryShortcutEvent(receiver, key)))
 
2846
                    return res;
 
2847
#endif
 
2848
                qt_in_tab_key_event = (key->key() == Qt::Key_Backtab
 
2849
                                       || key->key() == Qt::Key_Tab
 
2850
                                       || key->key() == Qt::Key_Left
 
2851
                                       || key->key() == Qt::Key_Up
 
2852
                                       || key->key() == Qt::Key_Right
 
2853
                                       || key->key() == Qt::Key_Down);
 
2854
            }
 
2855
            bool def = key->isAccepted();
 
2856
            QPointer<QObject> pr = receiver;
 
2857
            while (receiver) {
 
2858
                if (def)
 
2859
                    key->accept();
 
2860
                else
 
2861
                    key->ignore();
 
2862
                res = d->notify_helper(receiver, e);
 
2863
                QWidget *w = isWidget ? static_cast<QWidget *>(receiver) : 0;
 
2864
#ifndef QT_NO_GRAPHICSVIEW
 
2865
                QGraphicsWidget *gw = isGraphicsWidget ? static_cast<QGraphicsWidget *>(receiver) : 0;
 
2866
#endif
 
2867
 
 
2868
                if ((res && key->isAccepted())
 
2869
                    /*
 
2870
                       QLineEdit will emit a signal on Key_Return, but
 
2871
                       ignore the event, and sometimes the connected
 
2872
                       slot deletes the QLineEdit (common in itemview
 
2873
                       delegates), so we have to check if the widget
 
2874
                       was destroyed even if the event was ignored (to
 
2875
                       prevent a crash)
 
2876
 
 
2877
                       note that we don't have to reset pw while
 
2878
                       propagating (because the original receiver will
 
2879
                       be destroyed if one of its ancestors is)
 
2880
                    */
 
2881
                    || !pr
 
2882
                    || (isWidget && (w->isWindow() || !w->parentWidget()))
 
2883
#ifndef QT_NO_GRAPHICSVIEW
 
2884
                    || (isGraphicsWidget && (gw->isWindow() || !gw->parentWidget()))
 
2885
#endif
 
2886
                    ) {
 
2887
                    break;
 
2888
                }
 
2889
 
 
2890
#ifndef QT_NO_GRAPHICSVIEW
 
2891
                receiver = w ? (QObject *)w->parentWidget() : (QObject *)gw->parentWidget();
 
2892
#else
 
2893
                receiver = w->parentWidget();
 
2894
#endif
 
2895
            }
 
2896
            qt_in_tab_key_event = false;
 
2897
        }
 
2898
        break;
 
2899
    case QEvent::MouseButtonPress:
 
2900
    case QEvent::MouseButtonRelease:
 
2901
    case QEvent::MouseButtonDblClick:
 
2902
    case QEvent::MouseMove:
 
2903
        {
 
2904
            QWidget* w = static_cast<QWidget *>(receiver);
 
2905
 
 
2906
            QMouseEvent* mouse = static_cast<QMouseEvent*>(e);
 
2907
            QPoint relpos = mouse->pos();
 
2908
 
 
2909
            if (e->spontaneous()) {
 
2910
 
 
2911
                if (e->type() == QEvent::MouseButtonPress) {
 
2912
                    QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
 
2913
                                                                         Qt::ClickFocus,
 
2914
                                                                         Qt::MouseFocusReason);
 
2915
                }
 
2916
 
 
2917
                // ### Qt 5 These dynamic tool tips should be an OPT-IN feature. Some platforms
 
2918
                // like Mac OS X (probably others too), can optimize their views by not
 
2919
                // dispatching mouse move events. We have attributes to control hover,
 
2920
                // and mouse tracking, but as long as we are deciding to implement this
 
2921
                // feature without choice of opting-in or out, you ALWAYS have to have
 
2922
                // tracking enabled. Therefore, the other properties give a false sense of
 
2923
                // performance enhancement.
 
2924
                if (e->type() == QEvent::MouseMove && mouse->buttons() == 0) {
 
2925
                    d->toolTipWidget = w;
 
2926
                    d->toolTipPos = relpos;
 
2927
                    d->toolTipGlobalPos = mouse->globalPos();
 
2928
                    d->toolTipWakeUp.start(d->toolTipFallAsleep.isActive()?20:700, this);
 
2929
                }
 
2930
            }
 
2931
 
 
2932
            bool eventAccepted = mouse->isAccepted();
 
2933
 
 
2934
            QPointer<QWidget> pw = w;
 
2935
            while (w) {
 
2936
                QMouseEvent me(mouse->type(), relpos, mouse->windowPos(), mouse->globalPos(), mouse->button(), mouse->buttons(),
 
2937
                               mouse->modifiers());
 
2938
                me.spont = mouse->spontaneous();
 
2939
                me.setTimestamp(mouse->timestamp());
 
2940
                // throw away any mouse-tracking-only mouse events
 
2941
                if (!w->hasMouseTracking()
 
2942
                    && mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
 
2943
                    // but still send them through all application event filters (normally done by notify_helper)
 
2944
                    for (int i = 0; d->extraData && i < d->extraData->eventFilters.size(); ++i) {
 
2945
                        register QObject *obj = d->extraData->eventFilters.at(i);
 
2946
                        if (!obj)
 
2947
                            continue;
 
2948
                        if (obj->d_func()->threadData != w->d_func()->threadData) {
 
2949
                            qWarning("QApplication: Object event filter cannot be in a different thread.");
 
2950
                            continue;
 
2951
                        }
 
2952
                        if (obj->eventFilter(w, w == receiver ? mouse : &me))
 
2953
                            break;
 
2954
                    }
 
2955
                    res = true;
 
2956
                } else {
 
2957
                    w->setAttribute(Qt::WA_NoMouseReplay, false);
 
2958
                    res = d->notify_helper(w, w == receiver ? mouse : &me);
 
2959
                    e->spont = false;
 
2960
                }
 
2961
                eventAccepted = (w == receiver ? mouse : &me)->isAccepted();
 
2962
                if (res && eventAccepted)
 
2963
                    break;
 
2964
                if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
 
2965
                    break;
 
2966
                relpos += w->pos();
 
2967
                w = w->parentWidget();
 
2968
            }
 
2969
 
 
2970
            mouse->setAccepted(eventAccepted);
 
2971
 
 
2972
            if (e->type() == QEvent::MouseMove) {
 
2973
                if (!pw)
 
2974
                    break;
 
2975
 
 
2976
                w = static_cast<QWidget *>(receiver);
 
2977
                relpos = mouse->pos();
 
2978
                QPoint diff = relpos - w->mapFromGlobal(d->hoverGlobalPos);
 
2979
                while (w) {
 
2980
                    if (w->testAttribute(Qt::WA_Hover) &&
 
2981
                        (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == w->window())) {
 
2982
                        QHoverEvent he(QEvent::HoverMove, relpos, relpos - diff, mouse->modifiers());
 
2983
                        d->notify_helper(w, &he);
 
2984
                    }
 
2985
                    if (w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
 
2986
                        break;
 
2987
                    relpos += w->pos();
 
2988
                    w = w->parentWidget();
 
2989
                }
 
2990
            }
 
2991
 
 
2992
            d->hoverGlobalPos = mouse->globalPos();
 
2993
        }
 
2994
        break;
 
2995
#ifndef QT_NO_WHEELEVENT
 
2996
    case QEvent::Wheel:
 
2997
        {
 
2998
            QWidget* w = static_cast<QWidget *>(receiver);
 
2999
            QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
 
3000
            QPoint relpos = wheel->pos();
 
3001
            bool eventAccepted = wheel->isAccepted();
 
3002
 
 
3003
            if (e->spontaneous()) {
 
3004
                QApplicationPrivate::giveFocusAccordingToFocusPolicy(w,
 
3005
                                                                     Qt::WheelFocus,
 
3006
                                                                     Qt::MouseFocusReason);
 
3007
            }
 
3008
 
 
3009
            while (w) {
 
3010
                QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
 
3011
                               wheel->modifiers());
 
3012
                we.spont = wheel->spontaneous();
 
3013
                res = d->notify_helper(w, w == receiver ? wheel : &we);
 
3014
                eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
 
3015
                e->spont = false;
 
3016
                if ((res && eventAccepted)
 
3017
                    || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
 
3018
                    break;
 
3019
 
 
3020
                relpos += w->pos();
 
3021
                w = w->parentWidget();
 
3022
            }
 
3023
            wheel->setAccepted(eventAccepted);
 
3024
        }
 
3025
        break;
 
3026
#endif
 
3027
#ifndef QT_NO_CONTEXTMENU
 
3028
    case QEvent::ContextMenu:
 
3029
        {
 
3030
            QWidget* w = static_cast<QWidget *>(receiver);
 
3031
            QContextMenuEvent *context = static_cast<QContextMenuEvent*>(e);
 
3032
            QPoint relpos = context->pos();
 
3033
            bool eventAccepted = context->isAccepted();
 
3034
            while (w) {
 
3035
                QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->modifiers());
 
3036
                ce.spont = e->spontaneous();
 
3037
                res = d->notify_helper(w, w == receiver ? context : &ce);
 
3038
                eventAccepted = ((w == receiver) ? context : &ce)->isAccepted();
 
3039
                e->spont = false;
 
3040
 
 
3041
                if ((res && eventAccepted)
 
3042
                    || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation))
 
3043
                    break;
 
3044
 
 
3045
                relpos += w->pos();
 
3046
                w = w->parentWidget();
 
3047
            }
 
3048
            context->setAccepted(eventAccepted);
 
3049
        }
 
3050
        break;
 
3051
#endif // QT_NO_CONTEXTMENU
 
3052
#ifndef QT_NO_TABLETEVENT
 
3053
    case QEvent::TabletMove:
 
3054
    case QEvent::TabletPress:
 
3055
    case QEvent::TabletRelease:
 
3056
        {
 
3057
            QWidget *w = static_cast<QWidget *>(receiver);
 
3058
            QTabletEvent *tablet = static_cast<QTabletEvent*>(e);
 
3059
            QPointF relpos = tablet->posF();
 
3060
            bool eventAccepted = tablet->isAccepted();
 
3061
            while (w) {
 
3062
                QTabletEvent te(tablet->type(), relpos, tablet->globalPosF(),
 
3063
                                tablet->device(), tablet->pointerType(),
 
3064
                                tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
 
3065
                                tablet->tangentialPressure(), tablet->rotation(), tablet->z(),
 
3066
                                tablet->modifiers(), tablet->uniqueId());
 
3067
                te.spont = e->spontaneous();
 
3068
                res = d->notify_helper(w, w == receiver ? tablet : &te);
 
3069
                eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted();
 
3070
                e->spont = false;
 
3071
                if ((res && eventAccepted)
 
3072
                     || w->isWindow()
 
3073
                     || w->testAttribute(Qt::WA_NoMousePropagation))
 
3074
                    break;
 
3075
 
 
3076
                relpos += w->pos();
 
3077
                w = w->parentWidget();
 
3078
            }
 
3079
            tablet->setAccepted(eventAccepted);
 
3080
            qt_tabletChokeMouse = tablet->isAccepted();
 
3081
        }
 
3082
        break;
 
3083
#endif // QT_NO_TABLETEVENT
 
3084
 
 
3085
#if !defined(QT_NO_TOOLTIP) || !defined(QT_NO_WHATSTHIS)
 
3086
    case QEvent::ToolTip:
 
3087
    case QEvent::WhatsThis:
 
3088
    case QEvent::QueryWhatsThis:
 
3089
        {
 
3090
            QWidget* w = static_cast<QWidget *>(receiver);
 
3091
            QHelpEvent *help = static_cast<QHelpEvent*>(e);
 
3092
            QPoint relpos = help->pos();
 
3093
            bool eventAccepted = help->isAccepted();
 
3094
            while (w) {
 
3095
                QHelpEvent he(help->type(), relpos, help->globalPos());
 
3096
                he.spont = e->spontaneous();
 
3097
                res = d->notify_helper(w, w == receiver ? help : &he);
 
3098
                e->spont = false;
 
3099
                eventAccepted = (w == receiver ? help : &he)->isAccepted();
 
3100
                if ((res && eventAccepted) || w->isWindow())
 
3101
                    break;
 
3102
 
 
3103
                relpos += w->pos();
 
3104
                w = w->parentWidget();
 
3105
            }
 
3106
            help->setAccepted(eventAccepted);
 
3107
        }
 
3108
        break;
 
3109
#endif
 
3110
#if !defined(QT_NO_STATUSTIP) || !defined(QT_NO_WHATSTHIS)
 
3111
    case QEvent::StatusTip:
 
3112
    case QEvent::WhatsThisClicked:
 
3113
        {
 
3114
            QWidget *w = static_cast<QWidget *>(receiver);
 
3115
            while (w) {
 
3116
                res = d->notify_helper(w, e);
 
3117
                if ((res && e->isAccepted()) || w->isWindow())
 
3118
                    break;
 
3119
                w = w->parentWidget();
 
3120
            }
 
3121
        }
 
3122
        break;
 
3123
#endif
 
3124
 
 
3125
#ifndef QT_NO_DRAGANDDROP
 
3126
    case QEvent::DragEnter: {
 
3127
            QWidget* w = static_cast<QWidget *>(receiver);
 
3128
            QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(e);
 
3129
#ifndef QT_NO_GRAPHICSVIEW
 
3130
            // QGraphicsProxyWidget handles its own propagation,
 
3131
            // and we must not change QDragManagers currentTarget.
 
3132
            QWExtra *extra = w->window()->d_func()->extra;
 
3133
            if (extra && extra->proxyWidget) {
 
3134
                res = d->notify_helper(w, dragEvent);
 
3135
                break;
 
3136
            }
 
3137
#endif
 
3138
            while (w) {
 
3139
                if (w->isEnabled() && w->acceptDrops()) {
 
3140
                    res = d->notify_helper(w, dragEvent);
 
3141
                    if (res && dragEvent->isAccepted()) {
 
3142
                        QDragManager::self()->setCurrentTarget(w);
 
3143
                        break;
 
3144
                    }
 
3145
                }
 
3146
                if (w->isWindow())
 
3147
                    break;
 
3148
                dragEvent->p = w->mapToParent(dragEvent->p.toPoint());
 
3149
                w = w->parentWidget();
 
3150
            }
 
3151
        }
 
3152
        break;
 
3153
    case QEvent::DragMove:
 
3154
    case QEvent::Drop:
 
3155
    case QEvent::DragLeave: {
 
3156
            QWidget* w = static_cast<QWidget *>(receiver);
 
3157
#ifndef QT_NO_GRAPHICSVIEW
 
3158
            // QGraphicsProxyWidget handles its own propagation,
 
3159
            // and we must not change QDragManagers currentTarget.
 
3160
            QWExtra *extra = w->window()->d_func()->extra;
 
3161
            bool isProxyWidget = extra && extra->proxyWidget;
 
3162
            if (!isProxyWidget)
 
3163
#endif
 
3164
                w = qobject_cast<QWidget *>(QDragManager::self()->currentTarget());
 
3165
 
 
3166
            if (!w) {
 
3167
                    break;
 
3168
            }
 
3169
            if (e->type() == QEvent::DragMove || e->type() == QEvent::Drop) {
 
3170
                QDropEvent *dragEvent = static_cast<QDropEvent *>(e);
 
3171
                QWidget *origReciver = static_cast<QWidget *>(receiver);
 
3172
                while (origReciver && w != origReciver) {
 
3173
                    dragEvent->p = origReciver->mapToParent(dragEvent->p.toPoint());
 
3174
                    origReciver = origReciver->parentWidget();
 
3175
                }
 
3176
            }
 
3177
            res = d->notify_helper(w, e);
 
3178
            if (e->type() != QEvent::DragMove
 
3179
#ifndef QT_NO_GRAPHICSVIEW
 
3180
                && !isProxyWidget
 
3181
#endif
 
3182
                )
 
3183
                QDragManager::self()->setCurrentTarget(0, e->type() == QEvent::Drop);
 
3184
        }
 
3185
        break;
 
3186
#endif
 
3187
 
 
3188
    case QEvent::TouchUpdate:
 
3189
    case QEvent::TouchEnd:
 
3190
    {
 
3191
        QWidget *widget = static_cast<QWidget *>(receiver);
 
3192
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
 
3193
        const bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
 
3194
 
 
3195
        touchEvent->setTarget(widget);
 
3196
        touchEvent->setAccepted(acceptTouchEvents);
 
3197
 
 
3198
        res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
 
3199
 
 
3200
        // If the touch event wasn't accepted, synthesize a mouse event and see if the widget wants it.
 
3201
        if (!touchEvent->isAccepted())
 
3202
            res = d->translateTouchToMouse(widget, touchEvent);
 
3203
        break;
 
3204
    }
 
3205
 
 
3206
    case QEvent::TouchBegin:
 
3207
    // Note: TouchUpdate and TouchEnd events are never propagated
 
3208
    {
 
3209
        QWidget *widget = static_cast<QWidget *>(receiver);
 
3210
        QTouchEvent *touchEvent = static_cast<QTouchEvent *>(e);
 
3211
        bool eventAccepted = touchEvent->isAccepted();
 
3212
        if (widget->testAttribute(Qt::WA_AcceptTouchEvents) && e->spontaneous()) {
 
3213
            // give the widget focus if the focus policy allows it
 
3214
            QApplicationPrivate::giveFocusAccordingToFocusPolicy(widget,
 
3215
                                                                 Qt::ClickFocus,
 
3216
                                                                 Qt::MouseFocusReason);
 
3217
        }
 
3218
 
 
3219
        while (widget) {
 
3220
            // first, try to deliver the touch event
 
3221
            bool acceptTouchEvents = widget->testAttribute(Qt::WA_AcceptTouchEvents);
 
3222
            touchEvent->setTarget(widget);
 
3223
            touchEvent->setAccepted(acceptTouchEvents);
 
3224
            QPointer<QWidget> p = widget;
 
3225
            res = acceptTouchEvents && d->notify_helper(widget, touchEvent);
 
3226
 
 
3227
            // If the touch event wasn't accepted, synthesize a mouse event and see if the widget wants it.
 
3228
            if (!touchEvent->isAccepted()) {
 
3229
                res = d->translateTouchToMouse(widget, touchEvent);
 
3230
                eventAccepted = touchEvent->isAccepted();
 
3231
                if (eventAccepted)
 
3232
                    break;
 
3233
            }
 
3234
 
 
3235
            eventAccepted = touchEvent->isAccepted();
 
3236
            if (p.isNull()) {
 
3237
                // widget was deleted
 
3238
                widget = 0;
 
3239
            } else {
 
3240
                widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, res && eventAccepted);
 
3241
            }
 
3242
            touchEvent->spont = false;
 
3243
            if (res && eventAccepted) {
 
3244
                // the first widget to accept the TouchBegin gets an implicit grab.
 
3245
                for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
 
3246
                    const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().at(i);
 
3247
                    d->activeTouchPoints[QGuiApplicationPrivate::ActiveTouchPointsKey(touchEvent->device(), touchPoint.id())].target = widget;
 
3248
                }
 
3249
                break;
 
3250
            } else if (p.isNull() || widget->isWindow() || widget->testAttribute(Qt::WA_NoMousePropagation)) {
 
3251
                break;
 
3252
            }
 
3253
            QPoint offset = widget->pos();
 
3254
            widget = widget->parentWidget();
 
3255
            touchEvent->setTarget(widget);
 
3256
            for (int i = 0; i < touchEvent->_touchPoints.size(); ++i) {
 
3257
                QTouchEvent::TouchPoint &pt = touchEvent->_touchPoints[i];
 
3258
                QRectF rect = pt.rect();
 
3259
                rect.moveCenter(offset);
 
3260
                pt.d->rect = rect;
 
3261
                pt.d->startPos = pt.startPos() + offset;
 
3262
                pt.d->lastPos = pt.lastPos() + offset;
 
3263
            }
 
3264
        }
 
3265
 
 
3266
        touchEvent->setAccepted(eventAccepted);
 
3267
        break;
 
3268
    }
 
3269
    case QEvent::RequestSoftwareInputPanel:
 
3270
        inputMethod()->show();
 
3271
        break;
 
3272
    case QEvent::CloseSoftwareInputPanel:
 
3273
        inputMethod()->hide();
 
3274
        break;
 
3275
 
 
3276
#ifndef QT_NO_GESTURES
 
3277
    case QEvent::NativeGesture:
 
3278
    {
 
3279
        // only propagate the first gesture event (after the GID_BEGIN)
 
3280
        QWidget *w = static_cast<QWidget *>(receiver);
 
3281
        while (w) {
 
3282
            e->ignore();
 
3283
            res = d->notify_helper(w, e);
 
3284
            if ((res && e->isAccepted()) || w->isWindow())
 
3285
                break;
 
3286
            w = w->parentWidget();
 
3287
        }
 
3288
        break;
 
3289
    }
 
3290
    case QEvent::Gesture:
 
3291
    case QEvent::GestureOverride:
 
3292
    {
 
3293
        if (receiver->isWidgetType()) {
 
3294
            QWidget *w = static_cast<QWidget *>(receiver);
 
3295
            QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e);
 
3296
            QList<QGesture *> allGestures = gestureEvent->gestures();
 
3297
 
 
3298
            bool eventAccepted = gestureEvent->isAccepted();
 
3299
            bool wasAccepted = eventAccepted;
 
3300
            while (w) {
 
3301
                // send only gestures the widget expects
 
3302
                QList<QGesture *> gestures;
 
3303
                QWidgetPrivate *wd = w->d_func();
 
3304
                for (int i = 0; i < allGestures.size();) {
 
3305
                    QGesture *g = allGestures.at(i);
 
3306
                    Qt::GestureType type = g->gestureType();
 
3307
                    QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
 
3308
                            wd->gestureContext.find(type);
 
3309
                    bool deliver = contextit != wd->gestureContext.end() &&
 
3310
                        (g->state() == Qt::GestureStarted || w == receiver ||
 
3311
                         (contextit.value() & Qt::ReceivePartialGestures));
 
3312
                    if (deliver) {
 
3313
                        allGestures.removeAt(i);
 
3314
                        gestures.append(g);
 
3315
                    } else {
 
3316
                        ++i;
 
3317
                    }
 
3318
                }
 
3319
                if (!gestures.isEmpty()) { // we have gestures for this w
 
3320
                    QGestureEvent ge(gestures);
 
3321
                    ge.t = gestureEvent->t;
 
3322
                    ge.spont = gestureEvent->spont;
 
3323
                    ge.m_accept = wasAccepted;
 
3324
                    ge.m_accepted = gestureEvent->m_accepted;
 
3325
                    res = d->notify_helper(w, &ge);
 
3326
                    gestureEvent->spont = false;
 
3327
                    eventAccepted = ge.isAccepted();
 
3328
                    for (int i = 0; i < gestures.size(); ++i) {
 
3329
                        QGesture *g = gestures.at(i);
 
3330
                        // Ignore res [event return value] because handling of multiple gestures
 
3331
                        // packed into a single QEvent depends on not consuming the event
 
3332
                        if (eventAccepted || ge.isAccepted(g)) {
 
3333
                            // if the gesture was accepted, mark the target widget for it
 
3334
                            gestureEvent->m_targetWidgets[g->gestureType()] = w;
 
3335
                            gestureEvent->setAccepted(g, true);
 
3336
                        } else {
 
3337
                            // if the gesture was explicitly ignored by the application,
 
3338
                            // put it back so a parent can get it
 
3339
                            allGestures.append(g);
 
3340
                        }
 
3341
                    }
 
3342
                }
 
3343
                if (allGestures.isEmpty()) // everything delivered
 
3344
                    break;
 
3345
                if (w->isWindow())
 
3346
                    break;
 
3347
                w = w->parentWidget();
 
3348
            }
 
3349
            foreach (QGesture *g, allGestures)
 
3350
                gestureEvent->setAccepted(g, false);
 
3351
            gestureEvent->m_accept = false; // to make sure we check individual gestures
 
3352
        } else {
 
3353
            res = d->notify_helper(receiver, e);
 
3354
        }
 
3355
        break;
 
3356
    }
 
3357
#endif // QT_NO_GESTURES
 
3358
    default:
 
3359
        res = d->notify_helper(receiver, e);
 
3360
        break;
 
3361
    }
 
3362
 
 
3363
    return res;
 
3364
}
 
3365
 
 
3366
bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e)
 
3367
{
 
3368
    // send to all application event filters
 
3369
    if (sendThroughApplicationEventFilters(receiver, e))
 
3370
        return true;
 
3371
 
 
3372
    if (receiver->isWidgetType()) {
 
3373
        QWidget *widget = static_cast<QWidget *>(receiver);
 
3374
 
 
3375
#if !defined(Q_OS_WINCE) || (defined(GWES_ICONCURS) && !defined(QT_NO_CURSOR))
 
3376
        // toggle HasMouse widget state on enter and leave
 
3377
        if ((e->type() == QEvent::Enter || e->type() == QEvent::DragEnter) &&
 
3378
            (!QApplication::activePopupWidget() || QApplication::activePopupWidget() == widget->window()))
 
3379
            widget->setAttribute(Qt::WA_UnderMouse, true);
 
3380
        else if (e->type() == QEvent::Leave || e->type() == QEvent::DragLeave)
 
3381
            widget->setAttribute(Qt::WA_UnderMouse, false);
 
3382
#endif
 
3383
 
 
3384
        if (QLayout *layout=widget->d_func()->layout) {
 
3385
            layout->widgetEvent(e);
 
3386
        }
 
3387
    }
 
3388
 
 
3389
    // send to all receiver event filters
 
3390
    if (sendThroughObjectEventFilters(receiver, e))
 
3391
        return true;
 
3392
 
 
3393
    // deliver the event
 
3394
    bool consumed = receiver->event(e);
 
3395
    e->spont = false;
 
3396
    return consumed;
 
3397
}
 
3398
 
 
3399
bool QApplicationPrivate::inPopupMode()
 
3400
{
 
3401
    return QApplicationPrivate::popupWidgets != 0;
 
3402
}
 
3403
 
 
3404
#ifdef QT_KEYPAD_NAVIGATION
 
3405
/*!
 
3406
    Sets the kind of focus navigation Qt should use to \a mode.
 
3407
 
 
3408
    This feature is available in Qt for Embedded Linux, and Windows CE
 
3409
    only.
 
3410
 
 
3411
    \note On Windows CE this feature is disabled by default for touch device
 
3412
          mkspecs. To enable keypad navigation, build Qt with
 
3413
          QT_KEYPAD_NAVIGATION defined.
 
3414
 
 
3415
    \since 4.6
 
3416
 
 
3417
    \sa keypadNavigationEnabled()
 
3418
*/
 
3419
void QApplication::setNavigationMode(Qt::NavigationMode mode)
 
3420
{
 
3421
    QApplicationPrivate::navigationMode = mode;
 
3422
}
 
3423
 
 
3424
/*!
 
3425
    Returns what kind of focus navigation Qt is using.
 
3426
 
 
3427
    This feature is available in Qt for Embedded Linux, and Windows CE only.
 
3428
 
 
3429
    \note On Windows CE this feature is disabled by default for touch device
 
3430
          mkspecs. To enable keypad navigation, build Qt with
 
3431
          QT_KEYPAD_NAVIGATION defined.
 
3432
 
 
3433
    \since 4.6
 
3434
 
 
3435
    \sa keypadNavigationEnabled()
 
3436
*/
 
3437
Qt::NavigationMode QApplication::navigationMode()
 
3438
{
 
3439
    return QApplicationPrivate::navigationMode;
 
3440
}
 
3441
 
 
3442
/*!
 
3443
    Sets whether Qt should use focus navigation suitable for use with a
 
3444
    minimal keypad.
 
3445
 
 
3446
    This feature is available in Qt for Embedded Linux, and Windows CE only.
 
3447
 
 
3448
    \note On Windows CE this feature is disabled by default for touch device
 
3449
          mkspecs. To enable keypad navigation, build Qt with
 
3450
          QT_KEYPAD_NAVIGATION defined.
 
3451
 
 
3452
    \deprecated
 
3453
 
 
3454
    \sa setNavigationMode()
 
3455
*/
 
3456
void QApplication::setKeypadNavigationEnabled(bool enable)
 
3457
{
 
3458
    if (enable) {
 
3459
        QApplication::setNavigationMode(Qt::NavigationModeKeypadTabOrder);
 
3460
    } else {
 
3461
        QApplication::setNavigationMode(Qt::NavigationModeNone);
 
3462
    }
 
3463
}
 
3464
 
 
3465
/*!
 
3466
    Returns true if Qt is set to use keypad navigation; otherwise returns
 
3467
    false.  The default value is false.
 
3468
 
 
3469
    This feature is available in Qt for Embedded Linux, and Windows CE only.
 
3470
 
 
3471
    \note On Windows CE this feature is disabled by default for touch device
 
3472
          mkspecs. To enable keypad navigation, build Qt with
 
3473
          QT_KEYPAD_NAVIGATION defined.
 
3474
 
 
3475
    \deprecated
 
3476
 
 
3477
    \sa navigationMode()
 
3478
*/
 
3479
bool QApplication::keypadNavigationEnabled()
 
3480
{
 
3481
    return QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadTabOrder ||
 
3482
        QApplicationPrivate::navigationMode == Qt::NavigationModeKeypadDirectional;
 
3483
}
 
3484
#endif
 
3485
 
 
3486
/*!
 
3487
    \fn void QApplication::alert(QWidget *widget, int msec)
 
3488
    \since 4.3
 
3489
 
 
3490
    Causes an alert to be shown for \a widget if the window is not the active
 
3491
    window. The alert is shown for \a msec miliseconds. If \a msec is zero (the
 
3492
    default), then the alert is shown indefinitely until the window becomes
 
3493
    active again.
 
3494
 
 
3495
    Currently this function does nothing on Qt for Embedded Linux.
 
3496
 
 
3497
    On Mac OS X, this works more at the application level and will cause the
 
3498
    application icon to bounce in the dock.
 
3499
 
 
3500
    On Windows, this causes the window's taskbar entry to flash for a time. If
 
3501
    \a msec is zero, the flashing will stop and the taskbar entry will turn a
 
3502
    different color (currently orange).
 
3503
 
 
3504
    On X11, this will cause the window to be marked as "demands attention", the
 
3505
    window must not be hidden (i.e. not have hide() called on it, but be
 
3506
    visible in some sort of way) in order for this to work.
 
3507
*/
 
3508
 
 
3509
/*!
 
3510
    \property QApplication::cursorFlashTime
 
3511
    \brief the text cursor's flash (blink) time in milliseconds
 
3512
 
 
3513
    The flash time is the time required to display, invert and restore the
 
3514
    caret display. Usually the text cursor is displayed for half the cursor
 
3515
    flash time, then hidden for the same amount of time, but this may vary.
 
3516
 
 
3517
    The default value on X11 is 1000 milliseconds. On Windows, the
 
3518
    \uicontrol{Control Panel} value is used and setting this property sets the cursor
 
3519
    flash time for all applications.
 
3520
 
 
3521
    We recommend that widgets do not cache this value as it may change at any
 
3522
    time if the user changes the global desktop settings.
 
3523
*/
 
3524
void QApplication::setCursorFlashTime(int msecs)
 
3525
{
 
3526
    Q_UNUSED(msecs);
 
3527
}
 
3528
 
 
3529
int QApplication::cursorFlashTime()
 
3530
{
 
3531
    return qApp->styleHints()->cursorFlashTime();
 
3532
}
 
3533
 
 
3534
/*!
 
3535
    \property QApplication::doubleClickInterval
 
3536
    \brief the time limit in milliseconds that distinguishes a double click
 
3537
    from two consecutive mouse clicks
 
3538
 
 
3539
    The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
 
3540
    operating system's value is used.
 
3541
 
 
3542
    Setting the interval is not supported anymore in Qt 5.
 
3543
*/
 
3544
void QApplication::setDoubleClickInterval(int ms)
 
3545
{
 
3546
    Q_UNUSED(ms);
 
3547
}
 
3548
 
 
3549
int QApplication::doubleClickInterval()
 
3550
{
 
3551
    return qApp->styleHints()->mouseDoubleClickInterval();
 
3552
}
 
3553
 
 
3554
/*!
 
3555
    \fn QApplication::keyboardInputDirection()
 
3556
    \since 4.2
 
3557
    \deprecated
 
3558
 
 
3559
    Returns the current keyboard input direction. Replaced with QInputPanel::inputDirection()
 
3560
    \sa QInputPanel::inputDirection()
 
3561
*/
 
3562
 
 
3563
/*!
 
3564
    \property QApplication::keyboardInputInterval
 
3565
    \brief the time limit in milliseconds that distinguishes a key press
 
3566
    from two consecutive key presses
 
3567
    \since 4.2
 
3568
 
 
3569
    The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
 
3570
    operating system's value is used.
 
3571
*/
 
3572
void QApplication::setKeyboardInputInterval(int ms)
 
3573
{
 
3574
    Q_UNUSED(ms);
 
3575
}
 
3576
 
 
3577
int QApplication::keyboardInputInterval()
 
3578
{
 
3579
    return qApp->styleHints()->keyboardInputInterval();
 
3580
}
 
3581
 
 
3582
/*!
 
3583
    \property QApplication::wheelScrollLines
 
3584
    \brief the number of lines to scroll a widget, when the
 
3585
    mouse wheel is rotated.
 
3586
 
 
3587
    If the value exceeds the widget's number of visible lines, the widget
 
3588
    should interpret the scroll operation as a single \e{page up} or
 
3589
    \e{page down}. If the widget is an \l{QAbstractItemView}{item view class},
 
3590
    then the result of scrolling one \e line depends on the setting of the
 
3591
    widget's \l{QAbstractItemView::verticalScrollMode()}{scroll mode}. Scroll
 
3592
    one \e line can mean \l{QAbstractItemView::ScrollPerItem}{scroll one item}
 
3593
    or \l{QAbstractItemView::ScrollPerPixel}{scroll one pixel}.
 
3594
 
 
3595
    By default, this property has a value of 3.
 
3596
*/
 
3597
 
 
3598
/*!
 
3599
    \fn void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
 
3600
 
 
3601
    Enables the UI effect \a effect if \a enable is true, otherwise the effect
 
3602
    will not be used.
 
3603
 
 
3604
    \note All effects are disabled on screens running at less than 16-bit color
 
3605
    depth.
 
3606
 
 
3607
    \sa isEffectEnabled(), Qt::UIEffect, setDesktopSettingsAware()
 
3608
*/
 
3609
 
 
3610
/*!
 
3611
    \fn bool QApplication::isEffectEnabled(Qt::UIEffect effect)
 
3612
 
 
3613
    Returns true if \a effect is enabled; otherwise returns false.
 
3614
 
 
3615
    By default, Qt will try to use the desktop settings. To prevent this, call
 
3616
    setDesktopSettingsAware(false).
 
3617
 
 
3618
    \note All effects are disabled on screens running at less than 16-bit color
 
3619
    depth.
 
3620
 
 
3621
    \sa setEffectEnabled(), Qt::UIEffect
 
3622
*/
 
3623
 
 
3624
/*!
 
3625
    \fn void QApplication::beep()
 
3626
 
 
3627
    Sounds the bell, using the default volume and sound. The function is \e not
 
3628
    available in Qt for Embedded Linux.
 
3629
*/
 
3630
 
 
3631
/*!
 
3632
    \macro qApp
 
3633
    \relates QApplication
 
3634
 
 
3635
    A global pointer referring to the unique application object. It is
 
3636
    equivalent to the pointer returned by the QCoreApplication::instance()
 
3637
    function except that, in GUI applications, it is a pointer to a
 
3638
    QApplication instance.
 
3639
 
 
3640
    Only one application object can be created.
 
3641
 
 
3642
    \sa QCoreApplication::instance()
 
3643
*/
 
3644
 
 
3645
/*!
 
3646
    \fn QLocale QApplication::keyboardInputLocale()
 
3647
    \since 4.2
 
3648
    \obsolete
 
3649
 
 
3650
    Returns the current keyboard input locale. Replaced with QInputMethod::locale()
 
3651
*/
 
3652
 
 
3653
bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event)
 
3654
{
 
3655
    return QGuiApplication::sendSpontaneousEvent(receiver, event);
 
3656
}
 
3657
 
 
3658
 
 
3659
void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget,
 
3660
                                                          Qt::FocusPolicy focusPolicy,
 
3661
                                                          Qt::FocusReason focusReason)
 
3662
{
 
3663
    QWidget *focusWidget = widget;
 
3664
    while (focusWidget) {
 
3665
        if (focusWidget->isEnabled()
 
3666
            && QApplicationPrivate::shouldSetFocus(focusWidget, focusPolicy)) {
 
3667
            focusWidget->setFocus(focusReason);
 
3668
            break;
 
3669
        }
 
3670
        if (focusWidget->isWindow())
 
3671
            break;
 
3672
        focusWidget = focusWidget->parentWidget();
 
3673
    }
 
3674
}
 
3675
 
 
3676
bool QApplicationPrivate::shouldSetFocus(QWidget *w, Qt::FocusPolicy policy)
 
3677
{
 
3678
    QWidget *f = w;
 
3679
    while (f->d_func()->extra && f->d_func()->extra->focus_proxy)
 
3680
        f = f->d_func()->extra->focus_proxy;
 
3681
 
 
3682
    if ((w->focusPolicy() & policy) != policy)
 
3683
        return false;
 
3684
    if (w != f && (f->focusPolicy() & policy) != policy)
 
3685
        return false;
 
3686
    return true;
 
3687
}
 
3688
 
 
3689
void QApplicationPrivate::updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent)
 
3690
{
 
3691
    for (int i = 0; i < touchEvent->touchPoints().count(); ++i) {
 
3692
        QTouchEvent::TouchPoint &touchPoint = touchEvent->_touchPoints[i];
 
3693
 
 
3694
        // preserve the sub-pixel resolution
 
3695
        QRectF rect = touchPoint.screenRect();
 
3696
        const QPointF screenPos = rect.center();
 
3697
        const QPointF delta = screenPos - screenPos.toPoint();
 
3698
 
 
3699
        rect.moveCenter(widget->mapFromGlobal(screenPos.toPoint()) + delta);
 
3700
        touchPoint.d->rect = rect;
 
3701
        touchPoint.d->startPos = widget->mapFromGlobal(touchPoint.startScreenPos().toPoint()) + delta;
 
3702
        touchPoint.d->lastPos = widget->mapFromGlobal(touchPoint.lastScreenPos().toPoint()) + delta;
 
3703
    }
 
3704
}
 
3705
 
 
3706
void QApplicationPrivate::initializeMultitouch()
 
3707
{
 
3708
    initializeMultitouch_sys();
 
3709
}
 
3710
 
 
3711
void QApplicationPrivate::cleanupMultitouch()
 
3712
{
 
3713
    cleanupMultitouch_sys();
 
3714
}
 
3715
 
 
3716
QWidget *QApplicationPrivate::findClosestTouchPointTarget(QTouchDevice *device, const QPointF &screenPos)
 
3717
{
 
3718
    int closestTouchPointId = -1;
 
3719
    QObject *closestTarget = 0;
 
3720
    qreal closestDistance = qreal(0.);
 
3721
    QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it = activeTouchPoints.constBegin(),
 
3722
            ite = activeTouchPoints.constEnd();
 
3723
    while (it != ite) {
 
3724
        if (it.key().device == device) {
 
3725
            const QTouchEvent::TouchPoint &touchPoint = it->touchPoint;
 
3726
            qreal dx = screenPos.x() - touchPoint.screenPos().x();
 
3727
            qreal dy = screenPos.y() - touchPoint.screenPos().y();
 
3728
            qreal distance = dx * dx + dy * dy;
 
3729
            if (closestTouchPointId == -1 || distance < closestDistance) {
 
3730
                closestTouchPointId = touchPoint.id();
 
3731
                closestDistance = distance;
 
3732
                closestTarget = it.value().target.data();
 
3733
            }
 
3734
        }
 
3735
        ++it;
 
3736
    }
 
3737
    return static_cast<QWidget *>(closestTarget);
 
3738
}
 
3739
 
 
3740
class WidgetAttributeSaver
 
3741
{
 
3742
public:
 
3743
    explicit WidgetAttributeSaver(QWidget *widget, Qt::WidgetAttribute attribute, bool forcedValue)
 
3744
        : m_widget(widget),
 
3745
          m_attribute(attribute),
 
3746
          m_savedValue(widget->testAttribute(attribute))
 
3747
    {
 
3748
        widget->setAttribute(attribute, forcedValue);
 
3749
    }
 
3750
 
 
3751
    ~WidgetAttributeSaver()
 
3752
    {
 
3753
        m_widget->setAttribute(m_attribute, m_savedValue);
 
3754
    }
 
3755
 
 
3756
private:
 
3757
    QWidget * const m_widget;
 
3758
    const Qt::WidgetAttribute m_attribute;
 
3759
    const bool m_savedValue;
 
3760
};
 
3761
 
 
3762
bool QApplicationPrivate::translateTouchToMouse(QWidget *widget, QTouchEvent *event)
 
3763
{
 
3764
    Q_Q(QApplication);
 
3765
 
 
3766
    // Check if the platform wants synthesized mouse events.
 
3767
    if (!QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::SynthesizeMouseFromTouchEvents).toBool())
 
3768
        return false;
 
3769
 
 
3770
    Q_FOREACH (const QTouchEvent::TouchPoint &p, event->touchPoints()) {
 
3771
        const QEvent::Type eventType = (p.state() & Qt::TouchPointPressed) ? QEvent::MouseButtonPress
 
3772
                                     : (p.state() & Qt::TouchPointReleased) ? QEvent::MouseButtonRelease
 
3773
                                     : (p.state() & Qt::TouchPointMoved) ? QEvent::MouseMove
 
3774
                                     : QEvent::None;
 
3775
 
 
3776
        if (eventType == QEvent::None)
 
3777
            continue;
 
3778
 
 
3779
        const QPoint pos = widget->mapFromGlobal(p.screenPos().toPoint());
 
3780
 
 
3781
        QMouseEvent mouseEvent(eventType, pos,
 
3782
                               Qt::LeftButton, Qt::LeftButton,
 
3783
                               event->modifiers());
 
3784
        mouseEvent.setAccepted(true);
 
3785
        mouseEvent.setTimestamp(event->timestamp());
 
3786
 
 
3787
        // Make sure our synthesized mouse event doesn't propagate
 
3788
        // we want to control the propagation ourself to get a chance to
 
3789
        // deliver a proper touch event higher up in the hierarchy if that
 
3790
        // widget doesn't pick up the mouse event either.
 
3791
        WidgetAttributeSaver saver(widget, Qt::WA_NoMousePropagation, true);
 
3792
 
 
3793
        // Note it has to be a spontaneous event if we want the focus management
 
3794
        // and input method support to behave properly. Quite some of the code
 
3795
        // related to those aspect check for the spontaneous flag.
 
3796
        const bool res = q->sendSpontaneousEvent(widget, &mouseEvent);
 
3797
        event->setAccepted(mouseEvent.isAccepted());
 
3798
 
 
3799
        if (mouseEvent.isAccepted())
 
3800
            return res;
 
3801
    }
 
3802
 
 
3803
    return false;
 
3804
}
 
3805
 
 
3806
void QApplicationPrivate::translateRawTouchEvent(QWidget *window,
 
3807
                                                 QTouchDevice *device,
 
3808
                                                 const QList<QTouchEvent::TouchPoint> &touchPoints,
 
3809
                                                 ulong timestamp)
 
3810
{
 
3811
    QApplicationPrivate *d = self;
 
3812
    typedef QPair<Qt::TouchPointStates, QList<QTouchEvent::TouchPoint> > StatesAndTouchPoints;
 
3813
    QHash<QWidget *, StatesAndTouchPoints> widgetsNeedingEvents;
 
3814
 
 
3815
    for (int i = 0; i < touchPoints.count(); ++i) {
 
3816
        QTouchEvent::TouchPoint touchPoint = touchPoints.at(i);
 
3817
        // explicitly detach from the original touch point that we got, so even
 
3818
        // if the touchpoint structs are reused, we will make a copy that we'll
 
3819
        // deliver to the user (which might want to store the struct for later use).
 
3820
        touchPoint.d = touchPoint.d->detach();
 
3821
 
 
3822
        // update state
 
3823
        QPointer<QObject> target;
 
3824
        ActiveTouchPointsKey touchInfoKey(device, touchPoint.id());
 
3825
        ActiveTouchPointsValue &touchInfo = d->activeTouchPoints[touchInfoKey];
 
3826
        if (touchPoint.state() == Qt::TouchPointPressed) {
 
3827
            if (device->type() == QTouchDevice::TouchPad) {
 
3828
                // on touch-pads, send all touch points to the same widget
 
3829
                target = d->activeTouchPoints.isEmpty()
 
3830
                        ? QPointer<QObject>()
 
3831
                        : d->activeTouchPoints.constBegin().value().target;
 
3832
            }
 
3833
 
 
3834
            if (!target) {
 
3835
                // determine which widget this event will go to
 
3836
                if (!window)
 
3837
                    window = QApplication::topLevelAt(touchPoint.screenPos().toPoint());
 
3838
                if (!window)
 
3839
                    continue;
 
3840
                target = window->childAt(window->mapFromGlobal(touchPoint.screenPos().toPoint()));
 
3841
                if (!target)
 
3842
                    target = window;
 
3843
            }
 
3844
 
 
3845
            if (device->type() == QTouchDevice::TouchScreen) {
 
3846
                QWidget *closestWidget = d->findClosestTouchPointTarget(device, touchPoint.screenPos());
 
3847
                QWidget *widget = static_cast<QWidget *>(target.data());
 
3848
                if (closestWidget
 
3849
                        && (widget->isAncestorOf(closestWidget) || closestWidget->isAncestorOf(widget))) {
 
3850
                    target = closestWidget;
 
3851
                }
 
3852
            }
 
3853
 
 
3854
            touchInfo.target = target;
 
3855
        } else {
 
3856
            target = touchInfo.target;
 
3857
            if (!target)
 
3858
                continue;
 
3859
        }
 
3860
        Q_ASSERT(target.data() != 0);
 
3861
 
 
3862
        StatesAndTouchPoints &maskAndPoints = widgetsNeedingEvents[static_cast<QWidget *>(target.data())];
 
3863
        maskAndPoints.first |= touchPoint.state();
 
3864
        maskAndPoints.second.append(touchPoint);
 
3865
    }
 
3866
 
 
3867
    if (widgetsNeedingEvents.isEmpty())
 
3868
        return;
 
3869
 
 
3870
    QHash<QWidget *, StatesAndTouchPoints>::ConstIterator it = widgetsNeedingEvents.constBegin();
 
3871
    const QHash<QWidget *, StatesAndTouchPoints>::ConstIterator end = widgetsNeedingEvents.constEnd();
 
3872
    for (; it != end; ++it) {
 
3873
        QWidget *widget = it.key();
 
3874
        if (!QApplicationPrivate::tryModalHelper(widget, 0))
 
3875
            continue;
 
3876
 
 
3877
        QEvent::Type eventType;
 
3878
        switch (it.value().first) {
 
3879
        case Qt::TouchPointPressed:
 
3880
            eventType = QEvent::TouchBegin;
 
3881
            break;
 
3882
        case Qt::TouchPointReleased:
 
3883
            eventType = QEvent::TouchEnd;
 
3884
            break;
 
3885
        case Qt::TouchPointStationary:
 
3886
            // don't send the event if nothing changed
 
3887
            continue;
 
3888
        default:
 
3889
            eventType = QEvent::TouchUpdate;
 
3890
            break;
 
3891
        }
 
3892
 
 
3893
        QTouchEvent touchEvent(eventType,
 
3894
                               device,
 
3895
                               QApplication::keyboardModifiers(),
 
3896
                               it.value().first,
 
3897
                               it.value().second);
 
3898
        updateTouchPointsForWidget(widget, &touchEvent);
 
3899
        touchEvent.setTimestamp(timestamp);
 
3900
        touchEvent.setWindow(window->windowHandle());
 
3901
        touchEvent.setTarget(widget);
 
3902
 
 
3903
        switch (touchEvent.type()) {
 
3904
        case QEvent::TouchBegin:
 
3905
        {
 
3906
            // if the TouchBegin handler recurses, we assume that means the event
 
3907
            // has been implicitly accepted and continue to send touch events
 
3908
            widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent);
 
3909
            (void ) QApplication::sendSpontaneousEvent(widget, &touchEvent);
 
3910
            break;
 
3911
        }
 
3912
        default:
 
3913
            if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
 
3914
                if (touchEvent.type() == QEvent::TouchEnd)
 
3915
                    widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
 
3916
                (void) QApplication::sendSpontaneousEvent(widget, &touchEvent);
 
3917
            }
 
3918
            break;
 
3919
        }
 
3920
    }
 
3921
}
 
3922
 
 
3923
void QApplicationPrivate::translateTouchCancel(QTouchDevice *device, ulong timestamp)
 
3924
{
 
3925
    QTouchEvent touchEvent(QEvent::TouchCancel, device, QApplication::keyboardModifiers());
 
3926
    touchEvent.setTimestamp(timestamp);
 
3927
    QHash<ActiveTouchPointsKey, ActiveTouchPointsValue>::const_iterator it
 
3928
            = self->activeTouchPoints.constBegin(), ite = self->activeTouchPoints.constEnd();
 
3929
    QSet<QWidget *> widgetsNeedingCancel;
 
3930
    while (it != ite) {
 
3931
        QWidget *widget = static_cast<QWidget *>(it->target.data());
 
3932
        if (widget)
 
3933
            widgetsNeedingCancel.insert(widget);
 
3934
        ++it;
 
3935
    }
 
3936
    for (QSet<QWidget *>::const_iterator widIt = widgetsNeedingCancel.constBegin(),
 
3937
         widItEnd = widgetsNeedingCancel.constEnd(); widIt != widItEnd; ++widIt) {
 
3938
        QWidget *widget = *widIt;
 
3939
        touchEvent.setWindow(widget->windowHandle());
 
3940
        touchEvent.setTarget(widget);
 
3941
        QApplication::sendSpontaneousEvent(widget, &touchEvent);
 
3942
    }
 
3943
}
 
3944
 
 
3945
void QApplicationPrivate::notifyThemeChanged()
 
3946
{
 
3947
    QGuiApplicationPrivate::notifyThemeChanged();
 
3948
    clearSystemPalette();
 
3949
    initSystemPalette();
 
3950
}
 
3951
 
 
3952
#ifndef QT_NO_DRAGANDDROP
 
3953
void QApplicationPrivate::notifyDragStarted(const QDrag *drag)
 
3954
{
 
3955
    // Prevent pickMouseReceiver() from using the widget where the drag was started after a drag operation.
 
3956
    QGuiApplicationPrivate::notifyDragStarted(drag);
 
3957
    qt_button_down = 0;
 
3958
}
 
3959
#endif // QT_NO_DRAGANDDROP
 
3960
 
 
3961
#ifndef QT_NO_GESTURES
 
3962
QGestureManager* QGestureManager::instance()
 
3963
{
 
3964
    QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
 
3965
    if (!qAppPriv)
 
3966
        return 0;
 
3967
    if (!qAppPriv->gestureManager)
 
3968
        qAppPriv->gestureManager = new QGestureManager(qApp);
 
3969
    return qAppPriv->gestureManager;
 
3970
}
 
3971
#endif // QT_NO_GESTURES
 
3972
 
 
3973
QPixmap QApplicationPrivate::applyQIconStyleHelper(QIcon::Mode mode, const QPixmap& base) const
 
3974
{
 
3975
    QStyleOption opt(0);
 
3976
    opt.palette = QGuiApplication::palette();
 
3977
    return QApplication::style()->generatedIconPixmap(mode, base, &opt);
 
3978
}
 
3979
 
 
3980
QT_END_NAMESPACE
 
3981
 
 
3982
#include "moc_qapplication.cpp"