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

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

trunk: Merged in qt 4.6.3 sources from branches/vendor/nokia/qt.

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