source: trunk/src/gui/kernel/qapplication.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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