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

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

trunk: Merged in qt 4.6.2 sources.

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