source: trunk/src/kernel/qapplication.cpp@ 154

Last change on this file since 154 was 111, checked in by dmik, 19 years ago

Kernel: Fixed the memory leak in QApplication::event( QEvent *e ).

  • Property svn:keywords set to Id
File size: 126.9 KB
Line 
1/****************************************************************************
2** $Id: qapplication.cpp 111 2006-07-30 17:13:16Z dmik $
3**
4** Implementation of QApplication class
5**
6** Created : 931107
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qobjectlist.h"
39#include "qapplication.h"
40#include "qeventloop.h"
41#include "qeventloop_p.h"
42#include "qwidget.h"
43#include "qwidgetlist.h"
44#include "qwidgetintdict.h"
45#include "qptrdict.h"
46#include "qcleanuphandler.h"
47
48#include "qtranslator.h"
49#include "qtextcodec.h"
50#include "qsessionmanager.h"
51#include "qdragobject.h"
52#include "qclipboard.h"
53#include "qcursor.h"
54#include "qstyle.h"
55#include "qstylefactory.h"
56#include "qfile.h"
57#include "qmessagebox.h"
58#include "qdir.h"
59#include "qfileinfo.h"
60#ifdef Q_WS_WIN
61#include "qinputcontext_p.h"
62#endif
63#include "qfontdata_p.h"
64
65#if defined(QT_THREAD_SUPPORT)
66# include "qmutex.h"
67# include "qthread.h"
68#endif // QT_THREAD_SUPPORT
69
70#include <stdlib.h>
71
72#ifdef truncate
73# undef truncate
74#endif
75
76/*!
77 \class QApplication qapplication.h
78 \brief The QApplication class manages the GUI application's control
79 flow and main settings.
80
81 \ingroup application
82 \mainclass
83
84 It contains the main event loop, where all events from the window
85 system and other sources are processed and dispatched. It also
86 handles the application's initialization and finalization, and
87 provides session management. It also handles most system-wide and
88 application-wide settings.
89
90 For any GUI application that uses Qt, there is precisely one
91 QApplication object, no matter whether the application has 0, 1, 2
92 or more windows at any time.
93
94 The QApplication object is accessible through the global pointer \c
95 qApp. Its main areas of responsibility are:
96 \list
97
98 \i It initializes the application with the user's desktop settings
99 such as palette(), font() and doubleClickInterval(). It keeps track
100 of these properties in case the user changes the desktop globally, for
101 example through some kind of control panel.
102
103 \i It performs event handling, meaning that it receives events
104 from the underlying window system and dispatches them to the relevant
105 widgets. By using sendEvent() and postEvent() you can send your own
106 events to widgets.
107
108 \i It parses common command line arguments and sets its internal
109 state accordingly. See the \link QApplication::QApplication()
110 constructor documentation\endlink below for more details about this.
111
112 \i It defines the application's look and feel, which is
113 encapsulated in a QStyle object. This can be changed at runtime
114 with setStyle().
115
116 \i It specifies how the application is to allocate colors.
117 See setColorSpec() for details.
118
119 \i It provides localization of strings that are visible to the user
120 via translate().
121
122 \i It provides some magical objects like the desktop() and the
123 clipboard().
124
125 \i It knows about the application's windows. You can ask which
126 widget is at a certain position using widgetAt(), get a list of
127 topLevelWidgets() and closeAllWindows(), etc.
128
129 \i It manages the application's mouse cursor handling,
130 see setOverrideCursor() and setGlobalMouseTracking().
131
132 \i On the X window system, it provides functions to flush and sync
133 the communication stream, see flushX() and syncX().
134
135 \i It provides support for sophisticated \link
136 session.html session management \endlink. This makes it possible
137 for applications to terminate gracefully when the user logs out, to
138 cancel a shutdown process if termination isn't possible and even to
139 preserve the entire application's state for a future session. See
140 isSessionRestored(), sessionId() and commitData() and saveState()
141 for details.
142
143 \endlist
144
145 The <a href="simple-application.html">Application walk-through
146 example</a> contains a typical complete main() that does the usual
147 things with QApplication.
148
149 Since the QApplication object does so much initialization, it
150 <b>must</b> be created before any other objects related to the user
151 interface are created.
152
153 Since it also deals with common command line arguments, it is
154 usually a good idea to create it \e before any interpretation or
155 modification of \c argv is done in the application itself. (Note
156 also that for X11, setMainWidget() may change the main widget
157 according to the \c -geometry option. To preserve this
158 functionality, you must set your defaults before setMainWidget() and
159 any overrides after.)
160
161 \table
162 \header \i21 Groups of functions
163 \row
164 \i System settings
165 \i
166 desktopSettingsAware(),
167 setDesktopSettingsAware(),
168 cursorFlashTime(),
169 setCursorFlashTime(),
170 doubleClickInterval(),
171 setDoubleClickInterval(),
172 wheelScrollLines(),
173 setWheelScrollLines(),
174 palette(),
175 setPalette(),
176 font(),
177 setFont(),
178 fontMetrics().
179
180 \row
181 \i Event handling
182 \i
183 exec(),
184 processEvents(),
185 enter_loop(),
186 exit_loop(),
187 exit(),
188 quit().
189 sendEvent(),
190 postEvent(),
191 sendPostedEvents(),
192 removePostedEvents(),
193 hasPendingEvents(),
194 notify(),
195 macEventFilter(),
196 qwsEventFilter(),
197 x11EventFilter(),
198 x11ProcessEvent(),
199 winEventFilter().
200
201 \row
202 \i GUI Styles
203 \i
204 style(),
205 setStyle(),
206 polish().
207
208 \row
209 \i Color usage
210 \i
211 colorSpec(),
212 setColorSpec(),
213 qwsSetCustomColors().
214
215 \row
216 \i Text handling
217 \i
218 installTranslator(),
219 removeTranslator()
220 translate().
221
222 \row
223 \i Widgets
224 \i
225 mainWidget(),
226 setMainWidget(),
227 allWidgets(),
228 topLevelWidgets(),
229 desktop(),
230 activePopupWidget(),
231 activeModalWidget(),
232 clipboard(),
233 focusWidget(),
234 winFocus(),
235 activeWindow(),
236 widgetAt().
237
238 \row
239 \i Advanced cursor handling
240 \i
241 hasGlobalMouseTracking(),
242 setGlobalMouseTracking(),
243 overrideCursor(),
244 setOverrideCursor(),
245 restoreOverrideCursor().
246
247 \row
248 \i X Window System synchronization
249 \i
250 flushX(),
251 syncX().
252
253 \row
254 \i Session management
255 \i
256 isSessionRestored(),
257 sessionId(),
258 commitData(),
259 saveState().
260
261 \row
262 \i Threading
263 \i
264 lock(), unlock(), locked(), tryLock(),
265 wakeUpGuiThread()
266
267 \row
268 \i Miscellaneous
269 \i
270 closeAllWindows(),
271 startingUp(),
272 closingDown(),
273 type().
274 \endtable
275
276 \e {Non-GUI programs:} While Qt is not optimized or
277 designed for writing non-GUI programs, it's possible to use
278 \link tools.html some of its classes \endlink without creating a
279 QApplication. This can be useful if you wish to share code between
280 a non-GUI server and a GUI client.
281
282 \headerfile qnamespace.h
283 \headerfile qwindowdefs.h
284 \headerfile qglobal.h
285*/
286
287/*! \enum Qt::HANDLE
288 \internal
289*/
290
291/*!
292 \enum QApplication::Type
293
294 \value Tty a console application
295 \value GuiClient a GUI client application
296 \value GuiServer a GUI server application
297*/
298
299/*!
300 \enum QApplication::ColorSpec
301
302 \value NormalColor the default color allocation policy
303 \value CustomColor the same as NormalColor for X11; allocates colors
304 to a palette on demand under Windows
305 \value ManyColor the right choice for applications that use thousands of
306 colors
307
308 See setColorSpec() for full details.
309*/
310
311/*
312 The qt_init() and qt_cleanup() functions are implemented in the
313 qapplication_xyz.cpp file.
314*/
315
316void qt_init( int *, char **, QApplication::Type );
317void qt_cleanup();
318#if defined(Q_WS_X11)
319void qt_init( Display* dpy, Qt::HANDLE, Qt::HANDLE );
320#endif
321bool qt_tryModalHelper( QWidget *widget, QWidget **rettop );
322
323QApplication *qApp = 0; // global application object
324
325QStyle *QApplication::app_style = 0; // default application style
326bool qt_explicit_app_style = FALSE; // style explicitly set by programmer
327
328int QApplication::app_cspec = QApplication::NormalColor;
329#ifndef QT_NO_PALETTE
330QPalette *QApplication::app_pal = 0; // default application palette
331#endif
332QFont *QApplication::app_font = 0; // default application font
333bool qt_app_has_font = FALSE;
334#ifndef QT_NO_CURSOR
335QCursor *QApplication::app_cursor = 0; // default application cursor
336#endif
337int QApplication::app_tracking = 0; // global mouse tracking
338bool QApplication::is_app_running = FALSE; // app starting up if FALSE
339bool QApplication::is_app_closing = FALSE; // app closing down if TRUE
340int QApplication::loop_level = 0; // event loop level
341QWidget *QApplication::main_widget = 0; // main application widget
342QWidget *QApplication::focus_widget = 0; // has keyboard input focus
343QWidget *QApplication::active_window = 0; // toplevel with keyboard focus
344bool QApplication::obey_desktop_settings = TRUE; // use winsys resources
345int QApplication::cursor_flash_time = 1000; // text caret flash time
346int QApplication::mouse_double_click_time = 400; // mouse dbl click limit
347#ifndef QT_NO_WHEELEVENT
348int QApplication::wheel_scroll_lines = 3; // number of lines to scroll
349#endif
350bool qt_is_gui_used;
351bool Q_EXPORT qt_resolve_symlinks = TRUE;
352bool Q_EXPORT qt_tab_all_widgets = TRUE;
353QRect qt_maxWindowRect;
354static int drag_time = 500;
355static int drag_distance = 4;
356static bool reverse_layout = FALSE;
357QSize QApplication::app_strut = QSize( 0,0 ); // no default application strut
358bool QApplication::animate_ui = TRUE;
359bool QApplication::animate_menu = FALSE;
360bool QApplication::fade_menu = FALSE;
361bool QApplication::animate_combo = FALSE;
362bool QApplication::animate_tooltip = FALSE;
363bool QApplication::fade_tooltip = FALSE;
364bool QApplication::animate_toolbox = FALSE;
365bool QApplication::widgetCount = FALSE;
366QApplication::Type qt_appType=QApplication::Tty;
367#ifndef QT_NO_COMPONENT
368QStringList *QApplication::app_libpaths = 0;
369#endif
370bool QApplication::metaComposeUnicode = FALSE;
371int QApplication::composedUnicode = 0;
372
373#ifdef QT_THREAD_SUPPORT
374QMutex *QApplication::qt_mutex = 0;
375static QMutex *postevent_mutex = 0;
376static Qt::HANDLE qt_application_thread_id = 0;
377Q_EXPORT Qt::HANDLE qt_get_application_thread_id()
378{
379 return qt_application_thread_id;
380}
381#endif // QT_THREAD_SUPPORT
382
383QEventLoop *QApplication::eventloop = 0; // application event loop
384
385#ifndef QT_NO_ACCEL
386extern bool qt_dispatchAccelEvent( QWidget*, QKeyEvent* ); // def in qaccel.cpp
387extern bool qt_tryComposeUnicode( QWidget*, QKeyEvent* ); // def in qaccel.cpp
388#endif
389
390#if defined(QT_TABLET_SUPPORT)
391bool chokeMouse = FALSE;
392#endif
393
394void qt_setMaxWindowRect(const QRect& r)
395{
396 qt_maxWindowRect = r;
397 // Re-resize any maximized windows
398 QWidgetList* l = QApplication::topLevelWidgets();
399 if ( l ) {
400 QWidget *w = l->first();
401 while ( w ) {
402 if ( w->isVisible() && w->isMaximized() )
403 {
404 w->showNormal(); //#### flicker
405 w->showMaximized();
406 }
407 w = l->next();
408 }
409 delete l;
410 }
411}
412
413typedef void (*VFPTR)();
414typedef QValueList<VFPTR> QVFuncList;
415static QVFuncList *postRList = 0; // list of post routines
416
417/*!
418 \relates QApplication
419
420 Adds a global routine that will be called from the QApplication
421 destructor. This function is normally used to add cleanup routines
422 for program-wide functionality.
423
424 The function given by \a p should take no arguments and return
425 nothing, like this:
426 \code
427 static int *global_ptr = 0;
428
429 static void cleanup_ptr()
430 {
431 delete [] global_ptr;
432 global_ptr = 0;
433 }
434
435 void init_ptr()
436 {
437 global_ptr = new int[100]; // allocate data
438 qAddPostRoutine( cleanup_ptr ); // delete later
439 }
440 \endcode
441
442 Note that for an application- or module-wide cleanup,
443 qAddPostRoutine() is often not suitable. People have a tendency to
444 make such modules dynamically loaded, and then unload those modules
445 long before the QApplication destructor is called, for example.
446
447 For modules and libraries, using a reference-counted initialization
448 manager or Qt' parent-child delete mechanism may be better. Here is
449 an example of a private class which uses the parent-child mechanism
450 to call a cleanup function at the right time:
451
452 \code
453 class MyPrivateInitStuff: public QObject {
454 private:
455 MyPrivateInitStuff( QObject * parent ): QObject( parent) {
456 // initialization goes here
457 }
458 MyPrivateInitStuff * p;
459
460 public:
461 static MyPrivateInitStuff * initStuff( QObject * parent ) {
462 if ( !p )
463 p = new MyPrivateInitStuff( parent );
464 return p;
465 }
466
467 ~MyPrivateInitStuff() {
468 // cleanup (the "post routine") goes here
469 }
470 }
471 \endcode
472
473 By selecting the right parent widget/object, this can often be made
474 to clean up the module's data at the exact right moment.
475*/
476
477Q_EXPORT void qAddPostRoutine( QtCleanUpFunction p)
478{
479 if ( !postRList ) {
480 postRList = new QVFuncList;
481 Q_CHECK_PTR( postRList );
482 }
483 postRList->prepend( p );
484}
485
486
487Q_EXPORT void qRemovePostRoutine( QtCleanUpFunction p )
488{
489 if ( !postRList ) return;
490 QVFuncList::Iterator it = postRList->begin();
491 while ( it != postRList->end() ) {
492 if ( *it == p ) {
493 postRList->remove( it );
494 it = postRList->begin();
495 } else {
496 ++it;
497 }
498 }
499}
500
501// Default application palettes and fonts (per widget type)
502QAsciiDict<QPalette> *QApplication::app_palettes = 0;
503QAsciiDict<QFont> *QApplication::app_fonts = 0;
504
505#ifndef QT_NO_SESSIONMANAGER
506QString *QApplication::session_key = 0; // ## session key. Should be a member in 4.0
507#endif
508QWidgetList *QApplication::popupWidgets = 0; // has keyboard input focus
509
510QDesktopWidget *qt_desktopWidget = 0; // root window widgets
511#ifndef QT_NO_CLIPBOARD
512QClipboard *qt_clipboard = 0; // global clipboard object
513#endif
514QWidgetList * qt_modal_stack=0; // stack of modal widgets
515
516// Definitions for posted events
517struct QPostEvent {
518 QPostEvent( QObject *r, QEvent *e ): receiver( r ), event( e ) {}
519 ~QPostEvent() { delete event; }
520 QObject *receiver;
521 QEvent *event;
522};
523
524class Q_EXPORT QPostEventList : public QPtrList<QPostEvent>
525{
526public:
527 QPostEventList() : QPtrList<QPostEvent>() {}
528 QPostEventList( const QPostEventList &list ) : QPtrList<QPostEvent>(list) {}
529 ~QPostEventList() { clear(); }
530 QPostEventList &operator=(const QPostEventList &list)
531 { return (QPostEventList&)QPtrList<QPostEvent>::operator=(list); }
532};
533class Q_EXPORT QPostEventListIt : public QPtrListIterator<QPostEvent>
534{
535public:
536 QPostEventListIt( const QPostEventList &l ) : QPtrListIterator<QPostEvent>(l) {}
537 QPostEventListIt &operator=(const QPostEventListIt &i)
538{ return (QPostEventListIt&)QPtrListIterator<QPostEvent>::operator=(i); }
539};
540
541static QPostEventList *globalPostedEvents = 0; // list of posted events
542
543uint qGlobalPostedEventsCount()
544{
545 if (!globalPostedEvents)
546 return 0;
547 return globalPostedEvents->count();
548}
549
550static QSingleCleanupHandler<QPostEventList> qapp_cleanup_events;
551
552#ifndef QT_NO_PALETTE
553QPalette *qt_std_pal = 0;
554
555void qt_create_std_palette()
556{
557 if ( qt_std_pal )
558 delete qt_std_pal;
559
560 QColor standardLightGray( 192, 192, 192 );
561 QColor light( 255, 255, 255 );
562 QColor dark( standardLightGray.dark( 150 ) );
563 QColorGroup std_act( Qt::black, standardLightGray,
564 light, dark, Qt::gray,
565 Qt::black, Qt::white );
566 QColorGroup std_dis( Qt::darkGray, standardLightGray,
567 light, dark, Qt::gray,
568 Qt::darkGray, std_act.background() );
569 QColorGroup std_inact( Qt::black, standardLightGray,
570 light, dark, Qt::gray,
571 Qt::black, Qt::white );
572 qt_std_pal = new QPalette( std_act, std_dis, std_inact );
573}
574
575static void qt_fix_tooltips()
576{
577 // No resources for this yet (unlike on Windows).
578 QColorGroup cg( Qt::black, QColor(255,255,220),
579 QColor(96,96,96), Qt::black, Qt::black,
580 Qt::black, QColor(255,255,220) );
581 QPalette pal( cg, cg, cg );
582 QApplication::setPalette( pal, TRUE, "QTipLabel");
583}
584#endif
585
586void QApplication::process_cmdline( int* argcptr, char ** argv )
587{
588 // process platform-indep command line
589 if ( !qt_is_gui_used || !*argcptr)
590 return;
591
592 int argc = *argcptr;
593 int i, j;
594
595 j = 1;
596 for ( i=1; i<argc; i++ ) {
597 if ( argv[i] && *argv[i] != '-' ) {
598 argv[j++] = argv[i];
599 continue;
600 }
601 QCString arg = argv[i];
602 QCString s;
603 if ( arg == "-qdevel" || arg == "-qdebug") {
604 // obsolete argument
605 } else if ( arg.find( "-style=", 0, FALSE ) != -1 ) {
606 s = arg.right( arg.length() - 7 );
607 } else if ( qstrcmp(arg,"-style") == 0 && i < argc-1 ) {
608 s = argv[++i];
609 s = s.lower();
610#ifndef QT_NO_SESSIONMANAGER
611 } else if ( qstrcmp(arg,"-session") == 0 && i < argc-1 ) {
612 QCString s = argv[++i];
613 if ( !s.isEmpty() ) {
614 session_id = QString::fromLatin1( s );
615 int p = session_id.find( '_' );
616 if ( p >= 0 ) {
617 if ( !session_key )
618 session_key = new QString;
619 *session_key = session_id.mid( p +1 );
620 session_id = session_id.left( p );
621 }
622 is_session_restored = TRUE;
623 }
624#endif
625 } else if ( qstrcmp(arg, "-reverse") == 0 ) {
626 setReverseLayout( TRUE );
627 } else if ( qstrcmp(arg, "-widgetcount") == 0 ) {
628 widgetCount = TRUE;;
629 } else {
630 argv[j++] = argv[i];
631 }
632#ifndef QT_NO_STYLE
633 if ( !s.isEmpty() ) {
634 setStyle( s );
635 }
636#endif
637 }
638
639 if(j < argc) {
640#ifdef Q_WS_MACX
641 static char* empty = "\0";
642 argv[j] = empty;
643#else
644 argv[j] = 0;
645#endif
646 *argcptr = j;
647 }
648}
649
650/*!
651 Initializes the window system and constructs an application object
652 with \a argc command line arguments in \a argv.
653
654 The global \c qApp pointer refers to this application object. Only
655 one application object should be created.
656
657 This application object must be constructed before any \link
658 QPaintDevice paint devices\endlink (including widgets, pixmaps, bitmaps
659 etc.).
660
661 Note that \a argc and \a argv might be changed. Qt removes command
662 line arguments that it recognizes. The original \a argc and \a argv
663 can be accessed later with \c qApp->argc() and \c qApp->argv().
664 The documentation for argv() contains a detailed description of how
665 to process command line arguments.
666
667 Qt debugging options (not available if Qt was compiled with the
668 QT_NO_DEBUG flag defined):
669 \list
670 \i -nograb, tells Qt that it must never grab the mouse or the keyboard.
671 \i -dograb (only under X11), running under a debugger can cause
672 an implicit -nograb, use -dograb to override.
673 \i -sync (only under X11), switches to synchronous mode for
674 debugging.
675 \endlist
676
677 See \link debug.html Debugging Techniques \endlink for a more
678 detailed explanation.
679
680 All Qt programs automatically support the following command line options:
681 \list
682 \i -style= \e style, sets the application GUI style. Possible values
683 are \c motif, \c windows, and \c platinum. If you compiled Qt
684 with additional styles or have additional styles as plugins these
685 will be available to the \c -style command line option.
686 \i -style \e style, is the same as listed above.
687 \i -session= \e session, restores the application from an earlier
688 \link session.html session \endlink.
689 \i -session \e session, is the same as listed above.
690 \i -widgetcount, prints debug message at the end about number of widgets left
691 undestroyed and maximum number of widgets existed at the same time
692 \endlist
693
694 The X11 version of Qt also supports some traditional X11
695 command line options:
696 \list
697 \i -display \e display, sets the X display (default is $DISPLAY).
698 \i -geometry \e geometry, sets the client geometry of the
699 \link setMainWidget() main widget\endlink.
700 \i -fn or \c -font \e font, defines the application font. The
701 font should be specified using an X logical font description.
702 \i -bg or \c -background \e color, sets the default background color
703 and an application palette (light and dark shades are calculated).
704 \i -fg or \c -foreground \e color, sets the default foreground color.
705 \i -btn or \c -button \e color, sets the default button color.
706 \i -name \e name, sets the application name.
707 \i -title \e title, sets the application title (caption).
708 \i -visual \c TrueColor, forces the application to use a TrueColor visual
709 on an 8-bit display.
710 \i -ncols \e count, limits the number of colors allocated in the
711 color cube on an 8-bit display, if the application is using the
712 \c QApplication::ManyColor color specification. If \e count is
713 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
714 and 6 of blue); for other values, a cube
715 approximately proportional to a 2x3x1 cube is used.
716 \i -cmap, causes the application to install a private color map
717 on an 8-bit display.
718 \endlist
719
720 \sa argc(), argv()
721*/
722
723//######### BINARY COMPATIBILITY constructor
724QApplication::QApplication( int &argc, char **argv )
725{
726 construct( argc, argv, GuiClient );
727}
728
729
730/*!
731 Constructs an application object with \a argc command line arguments
732 in \a argv. If \a GUIenabled is TRUE, a GUI application is
733 constructed, otherwise a non-GUI (console) application is created.
734
735 Set \a GUIenabled to FALSE for programs without a graphical user
736 interface that should be able to run without a window system.
737
738 On X11, the window system is initialized if \a GUIenabled is TRUE.
739 If \a GUIenabled is FALSE, the application does not connect to the
740 X-server.
741 On Windows, OS/2 and Macintosh, currently the window system is always
742 initialized, regardless of the value of GUIenabled. This may change in
743 future versions of Qt.
744
745 The following example shows how to create an application that
746 uses a graphical interface when available.
747 \code
748 int main( int argc, char **argv )
749 {
750#ifdef Q_WS_X11
751 bool useGUI = getenv( "DISPLAY" ) != 0;
752#else
753 bool useGUI = TRUE;
754#endif
755 QApplication app(argc, argv, useGUI);
756
757 if ( useGUI ) {
758 //start GUI version
759 ...
760 } else {
761 //start non-GUI version
762 ...
763 }
764 return app.exec();
765 }
766\endcode
767*/
768
769QApplication::QApplication( int &argc, char **argv, bool GUIenabled )
770{
771 construct( argc, argv, GUIenabled ? GuiClient : Tty );
772}
773
774/*!
775 Constructs an application object with \a argc command line arguments
776 in \a argv.
777
778 For Qt/Embedded, passing \c QApplication::GuiServer for \a type
779 makes this application the server (equivalent to running with the
780 -qws option).
781*/
782QApplication::QApplication( int &argc, char **argv, Type type )
783{
784 construct( argc, argv, type );
785}
786
787Q_EXPORT void qt_ucm_initialize( QApplication *theApp )
788{
789 if ( qApp )
790 return;
791 int argc = theApp->argc();
792 char **argv = theApp->argv();
793 theApp->construct( argc, argv, qApp->type() );
794
795 Q_ASSERT( qApp == theApp );
796}
797
798void QApplication::construct( int &argc, char **argv, Type type )
799{
800 qt_appType = type;
801 qt_is_gui_used = (type != Tty);
802 init_precmdline();
803 static const char *empty = "";
804 if ( argc == 0 || argv == 0 ) {
805 argc = 0;
806 argv = (char **)&empty; // ouch! careful with QApplication::argv()!
807 }
808 app_argc = argc;
809 app_argv = argv;
810
811 qt_init( &argc, argv, type ); // Must be called before initialize()
812 process_cmdline( &argc, argv );
813 initialize( argc, argv );
814 if ( qt_is_gui_used )
815 qt_maxWindowRect = desktop()->rect();
816 if ( eventloop )
817 eventloop->appStartingUp();
818}
819
820/*!
821 Returns the type of application, Tty, GuiClient or GuiServer.
822*/
823
824QApplication::Type QApplication::type() const
825{
826 return qt_appType;
827}
828
829#if defined(Q_WS_X11)
830/*!
831 Create an application, given an already open display \a dpy. If \a
832 visual and \a colormap are non-zero, the application will use those as
833 the default Visual and Colormap contexts.
834
835 \warning Qt only supports TrueColor visuals at depths higher than 8
836 bits-per-pixel.
837
838 This is available only on X11.
839*/
840
841QApplication::QApplication( Display* dpy, HANDLE visual, HANDLE colormap )
842{
843 static int aargc = 1;
844 // ### a string literal is a cont char*
845 // ### using it as a char* is wrong and could lead to segfaults
846 // ### if aargv is modified someday
847 static char *aargv[] = { (char*)"unknown", 0 };
848
849 app_argc = aargc;
850 app_argv = aargv;
851
852 qt_appType = GuiClient;
853 qt_is_gui_used = TRUE;
854 qt_appType = GuiClient;
855 init_precmdline();
856 // ... no command line.
857
858 if ( ! dpy ) {
859#ifdef QT_CHECK_STATE
860 qWarning( "QApplication: invalid Display* argument." );
861#endif // QT_CHECK_STATE
862
863 qt_init( &aargc, aargv, GuiClient );
864 } else {
865 qt_init( dpy, visual, colormap );
866 }
867
868 initialize( aargc, aargv );
869
870 if ( qt_is_gui_used )
871 qt_maxWindowRect = desktop()->rect();
872 if ( eventloop )
873 eventloop->appStartingUp();
874}
875
876/*!
877 Create an application, given an already open display \a dpy and using
878 \a argc command line arguments in \a argv. If \a
879 visual and \a colormap are non-zero, the application will use those as
880 the default Visual and Colormap contexts.
881
882 \warning Qt only supports TrueColor visuals at depths higher than 8
883 bits-per-pixel.
884
885 This is available only on X11.
886
887*/
888QApplication::QApplication(Display *dpy, int argc, char **argv,
889 HANDLE visual, HANDLE colormap)
890{
891 qt_appType = GuiClient;
892 qt_is_gui_used = TRUE;
893 qt_appType = GuiClient;
894 init_precmdline();
895
896 app_argc = argc;
897 app_argv = argv;
898
899 if ( ! dpy ) {
900#ifdef QT_CHECK_STATE
901 qWarning( "QApplication: invalid Display* argument." );
902#endif // QT_CHECK_STATE
903
904 qt_init( &argc, argv, GuiClient );
905 } else {
906 qt_init(dpy, visual, colormap);
907 }
908
909 process_cmdline( &argc, argv );
910 initialize(argc, argv);
911
912 if ( qt_is_gui_used )
913 qt_maxWindowRect = desktop()->rect();
914 if ( eventloop )
915 eventloop->appStartingUp();
916}
917
918
919#endif // Q_WS_X11
920
921
922void QApplication::init_precmdline()
923{
924 translators = 0;
925 is_app_closing = FALSE;
926#ifndef QT_NO_SESSIONMANAGER
927 is_session_restored = FALSE;
928#endif
929#if defined(QT_CHECK_STATE)
930 if ( qApp )
931 qWarning( "QApplication: There should be max one application object" );
932#endif
933 qApp = (QApplication*)this;
934}
935
936/*!
937 Initializes the QApplication object, called from the constructors.
938*/
939
940void QApplication::initialize( int argc, char **argv )
941{
942#ifdef QT_THREAD_SUPPORT
943 qt_mutex = new QMutex( TRUE );
944 postevent_mutex = new QMutex( TRUE );
945 qt_application_thread_id = QThread::currentThread();
946#endif // QT_THREAD_SUPPORT
947
948 app_argc = argc;
949 app_argv = argv;
950 quit_now = FALSE;
951 quit_code = 0;
952 QWidget::createMapper(); // create widget mapper
953#ifndef QT_NO_PALETTE
954 (void) palette(); // trigger creation of application palette
955#endif
956 is_app_running = TRUE; // no longer starting up
957
958#ifndef QT_NO_SESSIONMANAGER
959 // connect to the session manager
960 if ( !session_key )
961 session_key = new QString;
962 session_manager = new QSessionManager( qApp, session_id, *session_key );
963#endif
964
965}
966
967
968/*****************************************************************************
969 Functions returning the active popup and modal widgets.
970 *****************************************************************************/
971
972/*!
973 Returns the active popup widget.
974
975 A popup widget is a special top level widget that sets the \c
976 WType_Popup widget flag, e.g. the QPopupMenu widget. When the
977 application opens a popup widget, all events are sent to the popup.
978 Normal widgets and modal widgets cannot be accessed before the popup
979 widget is closed.
980
981 Only other popup widgets may be opened when a popup widget is shown.
982 The popup widgets are organized in a stack. This function returns
983 the active popup widget at the top of the stack.
984
985 \sa activeModalWidget(), topLevelWidgets()
986*/
987
988QWidget *QApplication::activePopupWidget()
989{
990 return popupWidgets ? popupWidgets->getLast() : 0;
991}
992
993
994/*!
995 Returns the active modal widget.
996
997 A modal widget is a special top level widget which is a subclass of
998 QDialog that specifies the modal parameter of the constructor as
999 TRUE. A modal widget must be closed before the user can continue
1000 with other parts of the program.
1001
1002 Modal widgets are organized in a stack. This function returns
1003 the active modal widget at the top of the stack.
1004
1005 \sa activePopupWidget(), topLevelWidgets()
1006*/
1007
1008QWidget *QApplication::activeModalWidget()
1009{
1010 return qt_modal_stack ? qt_modal_stack->getFirst() : 0;
1011}
1012
1013/*!
1014 Cleans up any window system resources that were allocated by this
1015 application. Sets the global variable \c qApp to 0.
1016*/
1017
1018QApplication::~QApplication()
1019{
1020#ifndef QT_NO_CLIPBOARD
1021 // flush clipboard contents
1022 if ( qt_clipboard ) {
1023 QCustomEvent event( QEvent::Clipboard );
1024 QApplication::sendEvent( qt_clipboard, &event );
1025 }
1026#endif
1027
1028 if ( eventloop )
1029 eventloop->appClosingDown();
1030 if ( postRList ) {
1031 QVFuncList::Iterator it = postRList->begin();
1032 while ( it != postRList->end() ) { // call post routines
1033 (**it)();
1034 postRList->remove( it );
1035 it = postRList->begin();
1036 }
1037 delete postRList;
1038 postRList = 0;
1039 }
1040
1041 QObject *tipmanager = child( "toolTipManager", "QTipManager", FALSE );
1042 delete tipmanager;
1043
1044 delete qt_desktopWidget;
1045 qt_desktopWidget = 0;
1046 is_app_closing = TRUE;
1047
1048#ifndef QT_NO_CLIPBOARD
1049 delete qt_clipboard;
1050 qt_clipboard = 0;
1051#endif
1052 QWidget::destroyMapper();
1053#ifndef QT_NO_PALETTE
1054 delete qt_std_pal;
1055 qt_std_pal = 0;
1056 delete app_pal;
1057 app_pal = 0;
1058 delete app_palettes;
1059 app_palettes = 0;
1060#endif
1061 delete app_font;
1062 app_font = 0;
1063 delete app_fonts;
1064 app_fonts = 0;
1065#ifndef QT_NO_STYLE
1066 delete app_style;
1067 app_style = 0;
1068#endif
1069#ifndef QT_NO_CURSOR
1070 delete app_cursor;
1071 app_cursor = 0;
1072#endif
1073#ifndef QT_NO_TRANSLATION
1074 delete translators;
1075#endif
1076
1077#ifndef QT_NO_DRAGANDDROP
1078 extern QDragManager *qt_dnd_manager;
1079 delete qt_dnd_manager;
1080#endif
1081
1082 qt_cleanup();
1083
1084#ifndef QT_NO_COMPONENT
1085 delete app_libpaths;
1086 app_libpaths = 0;
1087#endif
1088
1089#ifdef QT_THREAD_SUPPORT
1090 delete qt_mutex;
1091 qt_mutex = 0;
1092 delete postevent_mutex;
1093 postevent_mutex = 0;
1094#endif // QT_THREAD_SUPPORT
1095
1096 if( qApp == this ) {
1097 if ( postedEvents )
1098 removePostedEvents( this );
1099 qApp = 0;
1100 }
1101 is_app_running = FALSE;
1102
1103 if ( widgetCount ) {
1104 qDebug( "Widgets left: %i Max widgets: %i \n", QWidget::instanceCounter, QWidget::maxInstances );
1105 }
1106#ifndef QT_NO_SESSIONMANAGER
1107 delete session_manager;
1108 session_manager = 0;
1109 delete session_key;
1110 session_key = 0;
1111#endif //QT_NO_SESSIONMANAGER
1112
1113 qt_explicit_app_style = FALSE;
1114 qt_app_has_font = FALSE;
1115 app_tracking = 0;
1116 obey_desktop_settings = TRUE;
1117 cursor_flash_time = 1000;
1118 mouse_double_click_time = 400;
1119#ifndef QT_NO_WHEELEVENT
1120 wheel_scroll_lines = 3;
1121#endif
1122 drag_time = 500;
1123 drag_distance = 4;
1124 reverse_layout = FALSE;
1125 app_strut = QSize( 0, 0 );
1126 animate_ui = TRUE;
1127 animate_menu = FALSE;
1128 fade_menu = FALSE;
1129 animate_combo = FALSE;
1130 animate_tooltip = FALSE;
1131 fade_tooltip = FALSE;
1132 widgetCount = FALSE;
1133}
1134
1135
1136/*!
1137 \fn int QApplication::argc() const
1138
1139 Returns the number of command line arguments.
1140
1141 The documentation for argv() describes how to process command line
1142 arguments.
1143
1144 \sa argv(), QApplication::QApplication()
1145*/
1146
1147/*!
1148 \fn char **QApplication::argv() const
1149
1150 Returns the command line argument vector.
1151
1152 \c argv()[0] is the program name, \c argv()[1] is the first
1153 argument and \c argv()[argc()-1] is the last argument.
1154
1155 A QApplication object is constructed by passing \e argc and \e
1156 argv from the \c main() function. Some of the arguments may be
1157 recognized as Qt options and removed from the argument vector. For
1158 example, the X11 version of Qt knows about \c -display, \c -font
1159 and a few more options.
1160
1161 Example:
1162 \code
1163 // showargs.cpp - displays program arguments in a list box
1164
1165 #include <qapplication.h>
1166 #include <qlistbox.h>
1167
1168 int main( int argc, char **argv )
1169 {
1170 QApplication a( argc, argv );
1171 QListBox b;
1172 a.setMainWidget( &b );
1173 for ( int i = 0; i < a.argc(); i++ ) // a.argc() == argc
1174 b.insertItem( a.argv()[i] ); // a.argv()[i] == argv[i]
1175 b.show();
1176 return a.exec();
1177 }
1178 \endcode
1179
1180 If you run \c{showargs -display unix:0 -font 9x15bold hello world}
1181 under X11, the list box contains the three strings "showargs",
1182 "hello" and "world".
1183
1184 Qt provides a global pointer, \c qApp, that points to the
1185 QApplication object, and through which you can access argc() and
1186 argv() in functions other than main().
1187
1188 \sa argc(), QApplication::QApplication()
1189*/
1190
1191/*!
1192 \fn void QApplication::setArgs( int argc, char **argv )
1193 \internal
1194*/
1195
1196
1197#ifndef QT_NO_STYLE
1198
1199static QString *qt_style_override = 0;
1200
1201/*!
1202 Returns the application's style object.
1203
1204 \sa setStyle(), QStyle
1205*/
1206QStyle& QApplication::style()
1207{
1208#ifndef QT_NO_STYLE
1209 if ( app_style )
1210 return *app_style;
1211 if ( !qt_is_gui_used )
1212 qFatal( "No style available in non-gui applications!" );
1213
1214#if defined(Q_WS_X11)
1215 if(!qt_style_override)
1216 x11_initialize_style(); // run-time search for default style
1217#endif
1218 if ( !app_style ) {
1219 // Compile-time search for default style
1220 //
1221 QString style;
1222 if ( qt_style_override ) {
1223 style = *qt_style_override;
1224 delete qt_style_override;
1225 qt_style_override = 0;
1226 } else {
1227# if defined(Q_WS_WIN) && defined(Q_OS_TEMP)
1228 style = "PocketPC";
1229#elif defined(Q_WS_WIN)
1230 if ( qWinVersion() == WV_XP )
1231 style = "WindowsXP";
1232 else
1233 style = "Windows"; // default styles for Windows
1234#elif defined(Q_WS_PM)
1235 /// @todo (dmik) temporary, until the native style is done
1236 style = "Windows"; // default style for OS/2
1237#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS)
1238 style = "CDE"; // default style for X11 on Solaris
1239#elif defined(Q_WS_X11) && defined(Q_OS_IRIX)
1240 style = "SGI"; // default style for X11 on IRIX
1241#elif defined(Q_WS_X11)
1242 style = "Motif"; // default style for X11
1243#elif defined(Q_WS_MAC)
1244 style = "Macintosh"; // default style for all Mac's
1245#elif defined(Q_WS_QWS)
1246 style = "Compact"; // default style for small devices
1247#endif
1248 }
1249 app_style = QStyleFactory::create( style );
1250 if ( !app_style && // platform default style not available, try alternatives
1251 !(app_style = QStyleFactory::create( "Windows" ) ) &&
1252 !(app_style = QStyleFactory::create( "Platinum" ) ) &&
1253 !(app_style = QStyleFactory::create( "MotifPlus" ) ) &&
1254 !(app_style = QStyleFactory::create( "Motif" ) ) &&
1255 !(app_style = QStyleFactory::create( "CDE" ) ) &&
1256 !(app_style = QStyleFactory::create( "Aqua" ) ) &&
1257 !(app_style = QStyleFactory::create( "SGI" ) ) &&
1258 !(app_style = QStyleFactory::create( "Compact" ) )
1259#ifndef QT_NO_STRINGLIST
1260 && !(app_style = QStyleFactory::create( QStyleFactory::keys()[0] ) )
1261#endif
1262 )
1263 qFatal( "No %s style available!", style.latin1() );
1264 }
1265
1266 QPalette app_pal_copy ( *app_pal );
1267 app_style->polish( *app_pal );
1268
1269 if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) {
1270 QEvent e( QEvent::ApplicationPaletteChange );
1271 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1272 register QWidget *w;
1273 while ( (w=it.current()) ) { // for all widgets...
1274 ++it;
1275 sendEvent( w, &e );
1276 }
1277 }
1278
1279 app_style->polish( qApp );
1280#endif
1281 return *app_style;
1282}
1283
1284/*!
1285 Sets the application's GUI style to \a style. Ownership of the style
1286 object is transferred to QApplication, so QApplication will delete
1287 the style object on application exit or when a new style is set.
1288
1289 Example usage:
1290 \code
1291 QApplication::setStyle( new QWindowStyle );
1292 \endcode
1293
1294 When switching application styles, the color palette is set back to
1295 the initial colors or the system defaults. This is necessary since
1296 certain styles have to adapt the color palette to be fully
1297 style-guide compliant.
1298
1299 \sa style(), QStyle, setPalette(), desktopSettingsAware()
1300*/
1301void QApplication::setStyle( QStyle *style )
1302{
1303 QStyle* old = app_style;
1304 app_style = style;
1305#ifdef Q_WS_X11
1306 qt_explicit_app_style = TRUE;
1307#endif // Q_WS_X11
1308
1309 if ( startingUp() ) {
1310 delete old;
1311 return;
1312 }
1313
1314 // clean up the old style
1315 if (old) {
1316 if ( is_app_running && !is_app_closing ) {
1317 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1318 register QWidget *w;
1319 while ( (w=it.current()) ) { // for all widgets...
1320 ++it;
1321 if ( !w->testWFlags(WType_Desktop) && // except desktop
1322 w->testWState(WState_Polished) ) { // has been polished
1323 old->unPolish(w);
1324 }
1325 }
1326 }
1327 old->unPolish( qApp );
1328 }
1329
1330 // take care of possible palette requirements of certain gui
1331 // styles. Do it before polishing the application since the style
1332 // might call QApplication::setStyle() itself
1333 if ( !qt_std_pal )
1334 qt_create_std_palette();
1335 QPalette tmpPal = *qt_std_pal;
1336 setPalette( tmpPal, TRUE );
1337
1338 // initialize the application with the new style
1339 app_style->polish( qApp );
1340
1341 // re-polish existing widgets if necessary
1342 if (old) {
1343 if ( is_app_running && !is_app_closing ) {
1344 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1345 register QWidget *w;
1346 while ( (w=it.current()) ) { // for all widgets...
1347 ++it;
1348 if ( !w->testWFlags(WType_Desktop) ) { // except desktop
1349 if ( w->testWState(WState_Polished) )
1350 app_style->polish(w); // repolish
1351 w->styleChange( *old );
1352 if ( w->isVisible() ){
1353 w->update();
1354 }
1355 }
1356 }
1357 }
1358 delete old;
1359 }
1360}
1361
1362/*!
1363 \overload
1364
1365 Requests a QStyle object for \a style from the QStyleFactory.
1366
1367 The string must be one of the QStyleFactory::keys(), typically one
1368 of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and
1369 "compact". Depending on the platform, "windowsxp", "aqua" or
1370 "macintosh" may be available.
1371
1372 A later call to the QApplication constructor will override the
1373 requested style when a "-style" option is passed in as a commandline
1374 parameter.
1375
1376 Returns 0 if an unknown \a style is passed, otherwise the QStyle object
1377 returned is set as the application's GUI style.
1378*/
1379QStyle* QApplication::setStyle( const QString& style )
1380{
1381#ifdef Q_WS_X11
1382 qt_explicit_app_style = TRUE;
1383#endif // Q_WS_X11
1384
1385 if ( startingUp() ) {
1386 if(qt_style_override)
1387 *qt_style_override = style;
1388 else
1389 qt_style_override = new QString(style);
1390 return 0;
1391 }
1392 QStyle *s = QStyleFactory::create( style );
1393 if ( !s )
1394 return 0;
1395
1396 setStyle( s );
1397 return s;
1398}
1399
1400#endif
1401
1402
1403#if 1 /* OBSOLETE */
1404
1405QApplication::ColorMode QApplication::colorMode()
1406{
1407 return (QApplication::ColorMode)app_cspec;
1408}
1409
1410void QApplication::setColorMode( QApplication::ColorMode mode )
1411{
1412 app_cspec = mode;
1413}
1414#endif
1415
1416
1417/*!
1418 Returns the color specification.
1419 \sa QApplication::setColorSpec()
1420 */
1421
1422int QApplication::colorSpec()
1423{
1424 return app_cspec;
1425}
1426
1427/*!
1428 Sets the color specification for the application to \a spec.
1429
1430 The color specification controls how the application allocates colors
1431 when run on a display with a limited amount of colors, e.g. 8 bit / 256
1432 color displays.
1433
1434 The color specification must be set before you create the QApplication
1435 object.
1436
1437 The options are:
1438 \list
1439 \i QApplication::NormalColor.
1440 This is the default color allocation strategy. Use this option if
1441 your application uses buttons, menus, texts and pixmaps with few
1442 colors. With this option, the application uses system global
1443 colors. This works fine for most applications under X11, but on
1444 Windows machines it may cause dithering of non-standard colors.
1445 \i QApplication::CustomColor.
1446 Use this option if your application needs a small number of custom
1447 colors. On X11, this option is the same as NormalColor. On Windows, Qt
1448 creates a Windows palette, and allocates colors to it on demand.
1449 \i QApplication::ManyColor.
1450 Use this option if your application is very color hungry
1451 (e.g. it requires thousands of colors).
1452 Under X11 the effect is:
1453 \list
1454 \i For 256-color displays which have at best a 256 color true color
1455 visual, the default visual is used, and colors are allocated
1456 from a color cube. The color cube is the 6x6x6 (216 color) "Web
1457 palette"<sup>*</sup>, but the number of colors can be changed
1458 by the \e -ncols option. The user can force the application to
1459 use the true color visual with the \link
1460 QApplication::QApplication() -visual \endlink option.
1461 \i For 256-color displays which have a true color visual with more
1462 than 256 colors, use that visual. Silicon Graphics X servers
1463 have this feature, for example. They provide an 8 bit visual
1464 by default but can deliver true color when asked.
1465 \endlist
1466 On Windows, Qt creates a Windows palette, and fills it with a color cube.
1467 \endlist
1468
1469 Be aware that the CustomColor and ManyColor choices may lead to colormap
1470 flashing: The foreground application gets (most) of the available
1471 colors, while the background windows will look less attractive.
1472
1473 Example:
1474 \code
1475 int main( int argc, char **argv )
1476 {
1477 QApplication::setColorSpec( QApplication::ManyColor );
1478 QApplication a( argc, argv );
1479 ...
1480 }
1481 \endcode
1482
1483 QColor provides more functionality for controlling color allocation and
1484 freeing up certain colors. See QColor::enterAllocContext() for more
1485 information.
1486
1487 To check what mode you end up with, call QColor::numBitPlanes() once
1488 the QApplication object exists. A value greater than 8 (typically
1489 16, 24 or 32) means true color.
1490
1491 <sup>*</sup> The color cube used by Qt has 216 colors whose red,
1492 green, and blue components always have one of the following values:
1493 0x00, 0x33, 0x66, 0x99, 0xCC, or 0xFF.
1494
1495 \sa colorSpec(), QColor::numBitPlanes(), QColor::enterAllocContext() */
1496
1497void QApplication::setColorSpec( int spec )
1498{
1499#if defined(QT_CHECK_STATE)
1500 if ( qApp ) {
1501 qWarning( "QApplication::setColorSpec: This function must be "
1502 "called before the QApplication object is created" );
1503 }
1504#endif
1505 app_cspec = spec;
1506}
1507
1508/*!
1509 \fn QSize QApplication::globalStrut()
1510
1511 Returns the application's global strut.
1512
1513 The strut is a size object whose dimensions are the minimum that any
1514 GUI element that the user can interact with should have. For example
1515 no button should be resized to be smaller than the global strut size.
1516
1517 \sa setGlobalStrut()
1518*/
1519
1520/*!
1521 Sets the application's global strut to \a strut.
1522
1523 The strut is a size object whose dimensions are the minimum that any
1524 GUI element that the user can interact with should have. For example
1525 no button should be resized to be smaller than the global strut size.
1526
1527 The strut size should be considered when reimplementing GUI controls
1528 that may be used on touch-screens or similar IO-devices.
1529
1530 Example:
1531 \code
1532 QSize& WidgetClass::sizeHint() const
1533 {
1534 return QSize( 80, 25 ).expandedTo( QApplication::globalStrut() );
1535 }
1536 \endcode
1537
1538 \sa globalStrut()
1539*/
1540
1541void QApplication::setGlobalStrut( const QSize& strut )
1542{
1543 app_strut = strut;
1544}
1545
1546#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1547extern const char *qAppFileName();
1548#endif
1549
1550#ifndef QT_NO_DIR
1551#if !defined(Q_WS_WIN) && !(defined Q_WS_PM)
1552static QString resolveSymlinks( const QString& path, int depth = 0 )
1553{
1554 bool foundLink = FALSE;
1555 QString linkTarget;
1556 QString part = path;
1557 int slashPos = path.length();
1558
1559 // too deep; we give up
1560 if ( depth == 128 )
1561 return QString::null;
1562
1563 do {
1564 part = part.left( slashPos );
1565 QFileInfo fileInfo( part );
1566 if ( fileInfo.isSymLink() ) {
1567 foundLink = TRUE;
1568 linkTarget = fileInfo.readLink();
1569 break;
1570 }
1571 } while ( (slashPos = part.findRev('/')) != -1 );
1572
1573 if ( foundLink ) {
1574 QString path2;
1575 if ( linkTarget[0] == '/' ) {
1576 path2 = linkTarget;
1577 if ( slashPos < (int) path.length() )
1578 path2 += "/" + path.right( path.length() - slashPos - 1 );
1579 } else {
1580 QString relPath;
1581 relPath = part.left( part.findRev('/') + 1 ) + linkTarget;
1582 if ( slashPos < (int) path.length() ) {
1583 if ( !linkTarget.endsWith( "/" ) )
1584 relPath += "/";
1585 relPath += path.right( path.length() - slashPos - 1 );
1586 }
1587 path2 = QDir::current().absFilePath( relPath );
1588 }
1589 path2 = QDir::cleanDirPath( path2 );
1590 return resolveSymlinks( path2, depth + 1 );
1591 } else {
1592 return path;
1593 }
1594}
1595#endif // !Q_WS_WIN && !Q_WS_PM
1596
1597/*!
1598 Returns the directory that contains the application executable.
1599
1600 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1601 directory, and you run the \c{demo} example, this function will
1602 return "C:/Trolltech/Qt/examples/demo".
1603
1604 \warning On Unix and Mac OS X, this function assumes that argv[0]
1605 contains the file name of the executable (which it normally
1606 does). It also assumes that the current directory hasn't been
1607 changed by the application.
1608
1609 \sa applicationFilePath()
1610*/
1611QString QApplication::applicationDirPath()
1612{
1613 return QFileInfo( applicationFilePath() ).dirPath();
1614}
1615
1616/*!
1617 Returns the file path of the application executable.
1618
1619 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1620 directory, and you run the \c{demo} example, this function will
1621 return "C:/Trolltech/Qt/examples/demo/demo.exe".
1622
1623 \warning On Unix and Mac OS X, this function assumes that argv[0]
1624 contains the file name of the executable (which it normally
1625 does). It also assumes that the current directory hasn't been
1626 changed by the application.
1627
1628 \sa applicationDirPath()
1629*/
1630QString QApplication::applicationFilePath()
1631{
1632#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1633 return QDir::cleanDirPath( QFile::decodeName( qAppFileName() ) );
1634#else
1635 QString argv0 = QFile::decodeName( argv()[0] );
1636 QString absPath;
1637
1638 if ( argv0[0] == '/' ) {
1639 /*
1640 If argv0 starts with a slash, it is already an absolute
1641 file path.
1642 */
1643 absPath = argv0;
1644 } else if ( argv0.find('/') != -1 ) {
1645 /*
1646 If argv0 contains one or more slashes, it is a file path
1647 relative to the current directory.
1648 */
1649 absPath = QDir::current().absFilePath( argv0 );
1650 } else {
1651 /*
1652 Otherwise, the file path has to be determined using the
1653 PATH environment variable.
1654 */
1655 char *pEnv = getenv( "PATH" );
1656 QStringList paths( QStringList::split(QChar(':'), pEnv) );
1657 QStringList::const_iterator p = paths.begin();
1658 while ( p != paths.end() ) {
1659 QString candidate = QDir::current().absFilePath( *p + "/" + argv0 );
1660 if ( QFile::exists(candidate) ) {
1661 absPath = candidate;
1662 break;
1663 }
1664 ++p;
1665 }
1666 }
1667
1668 absPath = QDir::cleanDirPath( absPath );
1669 if ( QFile::exists(absPath) ) {
1670 return resolveSymlinks( absPath );
1671 } else {
1672 return QString::null;
1673 }
1674#endif
1675}
1676#endif // QT_NO_DIR
1677
1678#ifndef QT_NO_COMPONENT
1679
1680/*!
1681 Returns a list of paths that the application will search when
1682 dynamically loading libraries.
1683 The installation directory for plugins is the only entry if no
1684 paths have been set. The default installation directory for plugins
1685 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
1686 installed. The directory of the application executable (NOT the
1687 working directory) is also added to the plugin paths.
1688
1689 If you want to iterate over the list, you should iterate over a
1690 copy, e.g.
1691 \code
1692 QStringList list = app.libraryPaths();
1693 QStringList::Iterator it = list.begin();
1694 while( it != list.end() ) {
1695 myProcessing( *it );
1696 ++it;
1697 }
1698 \endcode
1699
1700 See the \link plugins-howto.html plugins documentation\endlink for a
1701 description of how the library paths are used.
1702
1703 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
1704*/
1705QStringList QApplication::libraryPaths()
1706{
1707 if ( !app_libpaths ) {
1708 app_libpaths = new QStringList;
1709 QString installPathPlugins = QString::fromLocal8Bit(qInstallPathPlugins());
1710 if ( QFile::exists(installPathPlugins) ) {
1711#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1712 installPathPlugins.replace('\\', '/');
1713#endif
1714 app_libpaths->append(installPathPlugins);
1715 }
1716
1717 QString app_location;
1718 if (qApp)
1719 app_location = qApp->applicationFilePath();
1720#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1721 else {
1722 app_location = QString(qAppFileName());
1723 app_location.replace('\\', '/');
1724 }
1725#endif
1726 if (!app_location.isEmpty()) {
1727 app_location.truncate( app_location.findRev( '/' ) );
1728 if ( app_location != qInstallPathPlugins() && QFile::exists( app_location ) )
1729 app_libpaths->append( app_location );
1730 }
1731 }
1732 return *app_libpaths;
1733}
1734
1735
1736/*!
1737 Sets the list of directories to search when loading libraries to \a paths.
1738 All existing paths will be deleted and the path list will consist of the
1739 paths given in \a paths.
1740
1741 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
1742 */
1743void QApplication::setLibraryPaths( const QStringList &paths )
1744{
1745 delete app_libpaths;
1746 app_libpaths = new QStringList( paths );
1747}
1748
1749/*!
1750 Append \a path to the end of the library path list. If \a path is
1751 empty or already in the path list, the path list is not changed.
1752
1753 The default path list consists of a single entry, the installation
1754 directory for plugins. The default installation directory for plugins
1755 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
1756 installed.
1757
1758 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
1759 */
1760void QApplication::addLibraryPath( const QString &path )
1761{
1762 if ( path.isEmpty() )
1763 return;
1764
1765 // make sure that library paths is initialized
1766 libraryPaths();
1767
1768 if ( !app_libpaths->contains( path ) )
1769 app_libpaths->prepend( path );
1770}
1771
1772/*!
1773 Removes \a path from the library path list. If \a path is empty or not
1774 in the path list, the list is not changed.
1775
1776 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
1777*/
1778void QApplication::removeLibraryPath( const QString &path )
1779{
1780 if ( path.isEmpty() )
1781 return;
1782
1783 // make sure that library paths is initialized
1784 libraryPaths();
1785
1786 if ( app_libpaths->contains( path ) )
1787 app_libpaths->remove( path );
1788}
1789#endif //QT_NO_COMPONENT
1790
1791/*!
1792 Returns the application palette.
1793
1794 If a widget is passed in \a w, the default palette for the
1795 widget's class is returned. This may or may not be the application
1796 palette. In most cases there isn't a special palette for certain
1797 types of widgets, but one notable exception is the popup menu under
1798 Windows, if the user has defined a special background color for
1799 menus in the display settings.
1800
1801 \sa setPalette(), QWidget::palette()
1802*/
1803#ifndef QT_NO_PALETTE
1804QPalette QApplication::palette(const QWidget* w)
1805{
1806#if defined(QT_CHECK_STATE)
1807 if ( !qApp )
1808 qWarning( "QApplication::palette: This function can only be "
1809 "called after the QApplication object has been created" );
1810#endif
1811 if ( !app_pal ) {
1812 if ( !qt_std_pal )
1813 qt_create_std_palette();
1814 app_pal = new QPalette( *qt_std_pal );
1815 qt_fix_tooltips();
1816 }
1817
1818 if ( w && app_palettes ) {
1819 QPalette* wp = app_palettes->find( w->className() );
1820 if ( wp )
1821 return *wp;
1822 QAsciiDictIterator<QPalette> it( *app_palettes );
1823 const char* name;
1824 while ( (name=it.currentKey()) != 0 ) {
1825 if ( w->inherits( name ) )
1826 return *it.current();
1827 ++it;
1828 }
1829 }
1830 return *app_pal;
1831}
1832
1833/*!
1834 Changes the default application palette to \a palette. If \a
1835 informWidgets is TRUE, then existing widgets are informed about the
1836 change and may adjust themselves to the new application
1837 setting. If \a informWidgets is FALSE, the change only affects newly
1838 created widgets.
1839
1840 If \a className is passed, the change applies only to widgets that
1841 inherit \a className (as reported by QObject::inherits()). If
1842 \a className is left 0, the change affects all widgets, thus overriding
1843 any previously set class specific palettes.
1844
1845 The palette may be changed according to the current GUI style in
1846 QStyle::polish().
1847
1848 \sa QWidget::setPalette(), palette(), QStyle::polish()
1849*/
1850
1851void QApplication::setPalette( const QPalette &palette, bool informWidgets,
1852 const char* className )
1853{
1854 QPalette pal = palette;
1855 QPalette *oldpal = 0;
1856#ifndef QT_NO_STYLE
1857 if ( !startingUp() ) // on startup this has been done already
1858 qApp->style().polish( pal ); // NB: non-const reference
1859#endif
1860 bool all = FALSE;
1861 if ( !className ) {
1862 if ( !app_pal ) {
1863 app_pal = new QPalette( pal );
1864 Q_CHECK_PTR( app_pal );
1865 } else {
1866 *app_pal = pal;
1867 }
1868 all = app_palettes != 0;
1869 delete app_palettes;
1870 app_palettes = 0;
1871 qt_fix_tooltips();
1872 } else {
1873 if ( !app_palettes ) {
1874 app_palettes = new QAsciiDict<QPalette>;
1875 Q_CHECK_PTR( app_palettes );
1876 app_palettes->setAutoDelete( TRUE );
1877 }
1878 oldpal = app_palettes->find( className );
1879 app_palettes->insert( className, new QPalette( pal ) );
1880 }
1881 if ( informWidgets && is_app_running && !is_app_closing ) {
1882 if ( !oldpal || ( *oldpal != pal ) ) {
1883 QEvent e( QEvent::ApplicationPaletteChange );
1884 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1885 register QWidget *w;
1886 while ( (w=it.current()) ) { // for all widgets...
1887 ++it;
1888 if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
1889 sendEvent( w, &e );
1890 }
1891 }
1892 }
1893}
1894
1895#endif // QT_NO_PALETTE
1896
1897/*!
1898 Returns the default font for the widget \a w, or the default
1899 application font if \a w is 0.
1900
1901 \sa setFont(), fontMetrics(), QWidget::font()
1902*/
1903
1904QFont QApplication::font( const QWidget *w )
1905{
1906 if ( w && app_fonts ) {
1907 QFont* wf = app_fonts->find( w->className() );
1908 if ( wf )
1909 return *wf;
1910 QAsciiDictIterator<QFont> it( *app_fonts );
1911 const char* name;
1912 while ( (name=it.currentKey()) != 0 ) {
1913 if ( w->inherits( name ) )
1914 return *it.current();
1915 ++it;
1916 }
1917 }
1918 if ( !app_font ) {
1919 app_font = new QFont( "Helvetica" );
1920 Q_CHECK_PTR( app_font );
1921 }
1922 return *app_font;
1923}
1924
1925/*! Changes the default application font to \a font. If \a
1926 informWidgets is TRUE, then existing widgets are informed about the
1927 change and may adjust themselves to the new application
1928 setting. If \a informWidgets is FALSE, the change only affects newly
1929 created widgets. If \a className is passed, the change applies only
1930 to classes that inherit \a className (as reported by
1931 QObject::inherits()).
1932
1933 On application start-up, the default font depends on the window
1934 system. It can vary depending on both the window system version and
1935 the locale. This function lets you override the default font; but
1936 overriding may be a bad idea because, for example, some locales need
1937 extra-large fonts to support their special characters.
1938
1939 \sa font(), fontMetrics(), QWidget::setFont()
1940*/
1941
1942void QApplication::setFont( const QFont &font, bool informWidgets,
1943 const char* className )
1944{
1945 bool all = FALSE;
1946 if ( !className ) {
1947 qt_app_has_font = TRUE;
1948 if ( !app_font ) {
1949 app_font = new QFont( font );
1950 Q_CHECK_PTR( app_font );
1951 } else {
1952 *app_font = font;
1953 }
1954
1955 // make sure the application font is complete
1956 app_font->detach();
1957 app_font->d->mask = QFontPrivate::Complete;
1958
1959 all = app_fonts != 0;
1960 delete app_fonts;
1961 app_fonts = 0;
1962 } else {
1963 if (!app_fonts){
1964 app_fonts = new QAsciiDict<QFont>;
1965 Q_CHECK_PTR( app_fonts );
1966 app_fonts->setAutoDelete( TRUE );
1967 }
1968 QFont* fnt = new QFont(font);
1969 Q_CHECK_PTR( fnt );
1970 app_fonts->insert(className, fnt);
1971 }
1972 if ( informWidgets && is_app_running && !is_app_closing ) {
1973 QEvent e( QEvent::ApplicationFontChange );
1974 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1975 register QWidget *w;
1976 while ( (w=it.current()) ) { // for all widgets...
1977 ++it;
1978 if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
1979 sendEvent( w, &e );
1980 }
1981 }
1982}
1983
1984
1985/*!
1986 Initialization of the appearance of the widget \a w \e before it is first
1987 shown.
1988
1989 Usually widgets call this automatically when they are polished. It
1990 may be used to do some style-based central customization of widgets.
1991
1992 Note that you are not limited to the public functions of QWidget.
1993 Instead, based on meta information like QObject::className() you are
1994 able to customize any kind of widget.
1995
1996 \sa QStyle::polish(), QWidget::polish(), setPalette(), setFont()
1997*/
1998
1999void QApplication::polish( QWidget *w )
2000{
2001#ifndef QT_NO_STYLE
2002 w->style().polish( w );
2003#endif
2004}
2005
2006
2007/*!
2008 Returns a list of the top level widgets in the application.
2009
2010 The list is created using \c new and must be deleted by the caller.
2011
2012 The list is empty (QPtrList::isEmpty()) if there are no top level
2013 widgets.
2014
2015 Note that some of the top level widgets may be hidden, for example
2016 the tooltip if no tooltip is currently shown.
2017
2018 Example:
2019 \code
2020 // Show all hidden top level widgets.
2021 QWidgetList *list = QApplication::topLevelWidgets();
2022 QWidgetListIt it( *list ); // iterate over the widgets
2023 QWidget * w;
2024 while ( (w=it.current()) != 0 ) { // for each top level widget...
2025 ++it;
2026 if ( !w->isVisible() )
2027 w->show();
2028 }
2029 delete list; // delete the list, not the widgets
2030 \endcode
2031
2032 \warning Delete the list as soon you have finished using it.
2033 The widgets in the list may be deleted by someone else at any time.
2034
2035 \sa allWidgets(), QWidget::isTopLevel(), QWidget::isVisible(),
2036 QPtrList::isEmpty()
2037*/
2038
2039QWidgetList *QApplication::topLevelWidgets()
2040{
2041 return QWidget::tlwList();
2042}
2043
2044/*!
2045 Returns a list of all the widgets in the application.
2046
2047 The list is created using \c new and must be deleted by the caller.
2048
2049 The list is empty (QPtrList::isEmpty()) if there are no widgets.
2050
2051 Note that some of the widgets may be hidden.
2052
2053 Example that updates all widgets:
2054 \code
2055 QWidgetList *list = QApplication::allWidgets();
2056 QWidgetListIt it( *list ); // iterate over the widgets
2057 QWidget * w;
2058 while ( (w=it.current()) != 0 ) { // for each widget...
2059 ++it;
2060 w->update();
2061 }
2062 delete list; // delete the list, not the widgets
2063 \endcode
2064
2065 The QWidgetList class is defined in the \c qwidgetlist.h header
2066 file.
2067
2068 \warning Delete the list as soon as you have finished using it.
2069 The widgets in the list may be deleted by someone else at any time.
2070
2071 \sa topLevelWidgets(), QWidget::isVisible(), QPtrList::isEmpty(),
2072*/
2073
2074QWidgetList *QApplication::allWidgets()
2075{
2076 return QWidget::wList();
2077}
2078
2079/*!
2080 \fn QWidget *QApplication::focusWidget() const
2081
2082 Returns the application widget that has the keyboard input focus, or
2083 0 if no widget in this application has the focus.
2084
2085 \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow()
2086*/
2087
2088/*!
2089 \fn QWidget *QApplication::activeWindow() const
2090
2091 Returns the application top-level window that has the keyboard input
2092 focus, or 0 if no application window has the focus. Note that
2093 there might be an activeWindow() even if there is no focusWidget(),
2094 for example if no widget in that window accepts key events.
2095
2096 \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
2097*/
2098
2099/*!
2100 Returns display (screen) font metrics for the application font.
2101
2102 \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
2103*/
2104
2105QFontMetrics QApplication::fontMetrics()
2106{
2107 return desktop()->fontMetrics();
2108}
2109
2110
2111
2112/*!
2113 Tells the application to exit with return code 0 (success).
2114 Equivalent to calling QApplication::exit( 0 ).
2115
2116 It's common to connect the lastWindowClosed() signal to quit(), and
2117 you also often connect e.g. QButton::clicked() or signals in
2118 QAction, QPopupMenu or QMenuBar to it.
2119
2120 Example:
2121 \code
2122 QPushButton *quitButton = new QPushButton( "Quit" );
2123 connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );
2124 \endcode
2125
2126 \sa exit() aboutToQuit() lastWindowClosed() QAction
2127*/
2128
2129void QApplication::quit()
2130{
2131 QApplication::exit( 0 );
2132}
2133
2134
2135/*!
2136 Closes all top-level windows.
2137
2138 This function is particularly useful for applications with many
2139 top-level windows. It could, for example, be connected to a "Quit"
2140 entry in the file menu as shown in the following code example:
2141
2142 \code
2143 // the "Quit" menu entry should try to close all windows
2144 QPopupMenu* file = new QPopupMenu( this );
2145 file->insertItem( "&Quit", qApp, SLOT(closeAllWindows()), CTRL+Key_Q );
2146
2147 // when the last window is closed, the application should quit
2148 connect( qApp, SIGNAL( lastWindowClosed() ), qApp, SLOT( quit() ) );
2149 \endcode
2150
2151 The windows are closed in random order, until one window does not
2152 accept the close event.
2153
2154 \sa QWidget::close(), QWidget::closeEvent(), lastWindowClosed(),
2155 quit(), topLevelWidgets(), QWidget::isTopLevel()
2156
2157 */
2158void QApplication::closeAllWindows()
2159{
2160 bool did_close = TRUE;
2161 QWidget *w;
2162 while((w = activeModalWidget()) && did_close) {
2163 if(w->isHidden())
2164 break;
2165 did_close = w->close();
2166 }
2167 QWidgetList *list = QApplication::topLevelWidgets();
2168 for ( w = list->first(); did_close && w; ) {
2169 if ( !w->isHidden() ) {
2170 did_close = w->close();
2171 delete list;
2172 list = QApplication::topLevelWidgets();
2173 w = list->first();
2174 } else {
2175 w = list->next();
2176 }
2177 }
2178 delete list;
2179}
2180
2181/*!
2182 Displays a simple message box about Qt. The message includes the
2183 version number of Qt being used by the application.
2184
2185 This is useful for inclusion in the Help menu of an application.
2186 See the examples/menu/menu.cpp example.
2187
2188 This function is a convenience slot for QMessageBox::aboutQt().
2189*/
2190void QApplication::aboutQt()
2191{
2192#ifndef QT_NO_MESSAGEBOX
2193 QMessageBox::aboutQt( mainWidget() );
2194#endif // QT_NO_MESSAGEBOX
2195}
2196
2197
2198/*!
2199 \fn void QApplication::lastWindowClosed()
2200
2201 This signal is emitted when the user has closed the last
2202 top level window.
2203
2204 The signal is very useful when your application has many top level
2205 widgets but no main widget. You can then connect it to the quit()
2206 slot.
2207
2208 For convenience, this signal is \e not emitted for transient top level
2209 widgets such as popup menus and dialogs.
2210
2211 \sa mainWidget(), topLevelWidgets(), QWidget::isTopLevel(), QWidget::close()
2212*/
2213
2214/*!
2215 \fn void QApplication::aboutToQuit()
2216
2217 This signal is emitted when the application is about to quit the
2218 main event loop, e.g. when the event loop level drops to zero.
2219 This may happen either after a call to quit() from inside the
2220 application or when the users shuts down the entire desktop session.
2221
2222 The signal is particularly useful if your application has to do some
2223 last-second cleanup. Note that no user interaction is possible in
2224 this state.
2225
2226 \sa quit()
2227*/
2228
2229
2230/*!
2231 \fn void QApplication::guiThreadAwake()
2232
2233 This signal is emitted after the event loop returns from a function
2234 that could block.
2235
2236 \sa wakeUpGuiThread()
2237*/
2238
2239
2240/*!
2241 \fn bool QApplication::sendEvent( QObject *receiver, QEvent *event )
2242
2243 Sends event \a event directly to receiver \a receiver, using the
2244 notify() function. Returns the value that was returned from the event
2245 handler.
2246
2247 The event is \e not deleted when the event has been sent. The normal
2248 approach is to create the event on the stack, e.g.
2249 \code
2250 QMouseEvent me( QEvent::MouseButtonPress, pos, 0, 0 );
2251 QApplication::sendEvent( mainWindow, &me );
2252 \endcode
2253 If you create the event on the heap you must delete it.
2254
2255 \sa postEvent(), notify()
2256*/
2257
2258/*!
2259 Sends event \a e to \a receiver: \a {receiver}->event(\a e).
2260 Returns the value that is returned from the receiver's event handler.
2261
2262 For certain types of events (e.g. mouse and key events),
2263 the event will be propagated to the receiver's parent and so on up to
2264 the top-level object if the receiver is not interested in the event
2265 (i.e., it returns FALSE).
2266
2267 There are five different ways that events can be processed;
2268 reimplementing this virtual function is just one of them. All five
2269 approaches are listed below:
2270 \list 1
2271 \i Reimplementing this function. This is very powerful, providing
2272 complete control; but only one subclass can be qApp.
2273
2274 \i Installing an event filter on qApp. Such an event filter is able
2275 to process all events for all widgets, so it's just as powerful as
2276 reimplementing notify(); furthermore, it's possible to have more
2277 than one application-global event filter. Global event filters even
2278 see mouse events for \link QWidget::isEnabled() disabled
2279 widgets, \endlink and if \link setGlobalMouseTracking() global mouse
2280 tracking \endlink is enabled, as well as mouse move events for all
2281 widgets.
2282
2283 \i Reimplementing QObject::event() (as QWidget does). If you do
2284 this you get Tab key presses, and you get to see the events before
2285 any widget-specific event filters.
2286
2287 \i Installing an event filter on the object. Such an event filter
2288 gets all the events except Tab and Shift-Tab key presses.
2289
2290 \i Reimplementing paintEvent(), mousePressEvent() and so
2291 on. This is the commonest, easiest and least powerful way.
2292 \endlist
2293
2294 \sa QObject::event(), installEventFilter()
2295*/
2296
2297bool QApplication::notify( QObject *receiver, QEvent *e )
2298{
2299 // no events are delivered after ~QApplication() has started
2300 if ( is_app_closing )
2301 return FALSE;
2302
2303 if ( receiver == 0 ) { // serious error
2304#if defined(QT_CHECK_NULL)
2305 qWarning( "QApplication::notify: Unexpected null receiver" );
2306#endif
2307 return FALSE;
2308 }
2309
2310 if ( e->type() == QEvent::ChildRemoved && receiver->postedEvents ) {
2311
2312#ifdef QT_THREAD_SUPPORT
2313 QMutexLocker locker( postevent_mutex );
2314#endif // QT_THREAD_SUPPORT
2315
2316 // the QObject destructor calls QObject::removeChild, which calls
2317 // QApplication::sendEvent() directly. this can happen while the event
2318 // loop is in the middle of posting events, and when we get here, we may
2319 // not have any more posted events for this object.
2320 if ( receiver->postedEvents ) {
2321 // if this is a child remove event and the child insert
2322 // hasn't been dispatched yet, kill that insert
2323 QPostEventList * l = receiver->postedEvents;
2324 QObject * c = ((QChildEvent*)e)->child();
2325 QPostEvent * pe;
2326 l->first();
2327 while( ( pe = l->current()) != 0 ) {
2328 if ( pe->event && pe->receiver == receiver &&
2329 pe->event->type() == QEvent::ChildInserted &&
2330 ((QChildEvent*)pe->event)->child() == c ) {
2331 pe->event->posted = FALSE;
2332 delete pe->event;
2333 pe->event = 0;
2334 l->remove();
2335 continue;
2336 }
2337 l->next();
2338 }
2339 }
2340 }
2341
2342 bool res = FALSE;
2343 if ( !receiver->isWidgetType() )
2344 res = internalNotify( receiver, e );
2345 else switch ( e->type() ) {
2346#ifndef QT_NO_ACCEL
2347 case QEvent::Accel:
2348 {
2349 QKeyEvent* key = (QKeyEvent*) e;
2350 res = internalNotify( receiver, e );
2351
2352 if ( !res && !key->isAccepted() )
2353 res = qt_dispatchAccelEvent( (QWidget*)receiver, key );
2354
2355 // next lines are for compatibility with Qt <= 3.0.x: old
2356 // QAccel was listening on toplevel widgets
2357 if ( !res && !key->isAccepted() && !((QWidget*)receiver)->isTopLevel() )
2358 res = internalNotify( ((QWidget*)receiver)->topLevelWidget(), e );
2359 }
2360 break;
2361#endif //QT_NO_ACCEL
2362 case QEvent::KeyPress:
2363 case QEvent::KeyRelease:
2364 case QEvent::AccelOverride:
2365 {
2366 QWidget* w = (QWidget*)receiver;
2367 QKeyEvent* key = (QKeyEvent*) e;
2368#ifndef QT_NO_ACCEL
2369 if ( qt_tryComposeUnicode( w, key ) )
2370 break;
2371#endif
2372 bool def = key->isAccepted();
2373 while ( w ) {
2374 if ( def )
2375 key->accept();
2376 else
2377 key->ignore();
2378 res = internalNotify( w, e );
2379 if ( res || key->isAccepted() )
2380 break;
2381 w = w->parentWidget( TRUE );
2382 }
2383 }
2384 break;
2385 case QEvent::MouseButtonPress:
2386 if ( e->spontaneous() ) {
2387 QWidget* fw = (QWidget*)receiver;
2388 while ( fw->focusProxy() )
2389 fw = fw->focusProxy();
2390 if ( fw->isEnabled() && fw->focusPolicy() & QWidget::ClickFocus ) {
2391 QFocusEvent::setReason( QFocusEvent::Mouse);
2392 fw->setFocus();
2393 QFocusEvent::resetReason();
2394 }
2395 }
2396 // fall through intended
2397 case QEvent::MouseButtonRelease:
2398 case QEvent::MouseButtonDblClick:
2399 case QEvent::MouseMove:
2400 {
2401 QWidget* w = (QWidget*)receiver;
2402 QMouseEvent* mouse = (QMouseEvent*) e;
2403 QPoint relpos = mouse->pos();
2404 while ( w ) {
2405 QMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->state());
2406 me.spont = mouse->spontaneous();
2407 res = internalNotify( w, w == receiver ? mouse : &me );
2408 e->spont = FALSE;
2409 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2410 break;
2411
2412 relpos += w->pos();
2413 w = w->parentWidget();
2414 }
2415 if ( res )
2416 mouse->accept();
2417 else
2418 mouse->ignore();
2419 }
2420 break;
2421#ifndef QT_NO_WHEELEVENT
2422 case QEvent::Wheel:
2423 {
2424 if ( e->spontaneous() ) {
2425 QWidget* fw = (QWidget*)receiver;
2426 while ( fw->focusProxy() )
2427 fw = fw->focusProxy();
2428 if ( fw->isEnabled() && (fw->focusPolicy() & QWidget::WheelFocus) == QWidget::WheelFocus ) {
2429 QFocusEvent::setReason( QFocusEvent::Mouse);
2430 fw->setFocus();
2431 QFocusEvent::resetReason();
2432 }
2433 }
2434
2435 QWidget* w = (QWidget*)receiver;
2436 QWheelEvent* wheel = (QWheelEvent*) e;
2437 QPoint relpos = wheel->pos();
2438 while ( w ) {
2439 QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->state(), wheel->orientation());
2440 we.spont = wheel->spontaneous();
2441 res = internalNotify( w, w == receiver ? wheel : &we );
2442 e->spont = FALSE;
2443 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2444 break;
2445
2446 relpos += w->pos();
2447 w = w->parentWidget();
2448 }
2449 if ( res )
2450 wheel->accept();
2451 else
2452 wheel->ignore();
2453 }
2454 break;
2455#endif
2456 case QEvent::ContextMenu:
2457 {
2458 QWidget* w = (QWidget*)receiver;
2459 QContextMenuEvent *context = (QContextMenuEvent*) e;
2460 QPoint relpos = context->pos();
2461 while ( w ) {
2462 QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->state());
2463 ce.spont = e->spontaneous();
2464 res = internalNotify( w, w == receiver ? context : &ce );
2465 e->spont = FALSE;
2466
2467 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2468 break;
2469
2470 relpos += w->pos();
2471 w = w->parentWidget();
2472 }
2473 if ( res )
2474 context->accept();
2475 else
2476 context->ignore();
2477 }
2478 break;
2479#if defined (QT_TABLET_SUPPORT)
2480 case QEvent::TabletMove:
2481 case QEvent::TabletPress:
2482 case QEvent::TabletRelease:
2483 {
2484 QWidget *w = (QWidget*)receiver;
2485 QTabletEvent *tablet = (QTabletEvent*)e;
2486 QPoint relpos = tablet->pos();
2487 while ( w ) {
2488 QTabletEvent te(tablet->pos(), tablet->globalPos(), tablet->device(),
2489 tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
2490 tablet->uniqueId());
2491 te.spont = e->spontaneous();
2492 res = internalNotify( w, w == receiver ? tablet : &te );
2493 e->spont = FALSE;
2494 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2495 break;
2496
2497 relpos += w->pos();
2498 w = w->parentWidget();
2499 }
2500 if ( res )
2501 tablet->accept();
2502 else
2503 tablet->ignore();
2504 chokeMouse = tablet->isAccepted();
2505 }
2506 break;
2507#endif
2508 default:
2509 res = internalNotify( receiver, e );
2510 break;
2511 }
2512
2513 return res;
2514}
2515
2516/*!\reimp
2517
2518*/
2519bool QApplication::event( QEvent *e )
2520{
2521 if(e->type() == QEvent::Close) {
2522 QCloseEvent *ce = (QCloseEvent*)e;
2523 ce->accept();
2524 closeAllWindows();
2525
2526 QWidgetList *list = topLevelWidgets();
2527 for(QWidget *w = list->first(); w; w = list->next()) {
2528 if ( !w->isHidden() && !w->isDesktop() && !w->isPopup() &&
2529 (!w->isDialog() || !w->parentWidget())) {
2530 ce->ignore();
2531 break;
2532 }
2533 }
2534 delete list;
2535 if(ce->isAccepted())
2536 return TRUE;
2537 } else if (e->type() == QEvent::Quit) {
2538 quit();
2539 return TRUE;
2540 }
2541 return QObject::event(e);
2542}
2543
2544/*!\internal
2545
2546 Helper function called by notify()
2547 */
2548bool QApplication::internalNotify( QObject *receiver, QEvent * e)
2549{
2550 if ( eventFilters ) {
2551 QObjectListIt it( *eventFilters );
2552 register QObject *obj;
2553 while ( (obj=it.current()) != 0 ) { // send to all filters
2554 ++it; // until one returns TRUE
2555 if ( obj->eventFilter(receiver,e) )
2556 return TRUE;
2557 }
2558 }
2559
2560 bool consumed = FALSE;
2561 bool handled = FALSE;
2562 if ( receiver->isWidgetType() ) {
2563 QWidget *widget = (QWidget*)receiver;
2564
2565 // toggle HasMouse widget state on enter and leave
2566 if ( e->type() == QEvent::Enter || e->type() == QEvent::DragEnter )
2567 widget->setWState( WState_HasMouse );
2568 else if ( e->type() == QEvent::Leave || e->type() == QEvent::DragLeave )
2569 widget->clearWState( WState_HasMouse );
2570
2571 // throw away any mouse-tracking-only mouse events
2572 if ( e->type() == QEvent::MouseMove &&
2573 (((QMouseEvent*)e)->state()&QMouseEvent::MouseButtonMask) == 0 &&
2574 !widget->hasMouseTracking() ) {
2575 handled = TRUE;
2576 consumed = TRUE;
2577 } else if ( !widget->isEnabled() ) { // throw away mouse events to disabled widgets
2578 switch(e->type()) {
2579 case QEvent::MouseButtonPress:
2580 case QEvent::MouseButtonRelease:
2581 case QEvent::MouseButtonDblClick:
2582 case QEvent::MouseMove:
2583 ( (QMouseEvent*) e)->ignore();
2584 handled = TRUE;
2585 consumed = TRUE;
2586 break;
2587#ifndef QT_NO_DRAGANDDROP
2588 case QEvent::DragEnter:
2589 case QEvent::DragMove:
2590 ( (QDragMoveEvent*) e)->ignore();
2591 handled = TRUE;
2592 break;
2593
2594 case QEvent::DragLeave:
2595 case QEvent::DragResponse:
2596 handled = TRUE;
2597 break;
2598
2599 case QEvent::Drop:
2600 ( (QDropEvent*) e)->ignore();
2601 handled = TRUE;
2602 break;
2603#endif
2604#ifndef QT_NO_WHEELEVENT
2605 case QEvent::Wheel:
2606 ( (QWheelEvent*) e)->ignore();
2607 handled = TRUE;
2608 break;
2609#endif
2610 case QEvent::ContextMenu:
2611 ( (QContextMenuEvent*) e)->ignore();
2612 handled = TRUE;
2613 break;
2614 default:
2615 break;
2616 }
2617 }
2618
2619 }
2620
2621 if (!handled)
2622 consumed = receiver->event( e );
2623 e->spont = FALSE;
2624 return consumed;
2625}
2626
2627/*!
2628 Returns TRUE if an application object has not been created yet;
2629 otherwise returns FALSE.
2630
2631 \sa closingDown()
2632*/
2633
2634bool QApplication::startingUp()
2635{
2636 return !is_app_running;
2637}
2638
2639/*!
2640 Returns TRUE if the application objects are being destroyed;
2641 otherwise returns FALSE.
2642
2643 \sa startingUp()
2644*/
2645
2646bool QApplication::closingDown()
2647{
2648 return is_app_closing;
2649}
2650
2651
2652/*!
2653 Processes pending events, for 3 seconds or until there are no more
2654 events to process, whichever is shorter.
2655
2656 You can call this function occasionally when your program is busy
2657 performing a long operation (e.g. copying a file).
2658
2659 \sa exec(), QTimer, QEventLoop::processEvents()
2660*/
2661
2662void QApplication::processEvents()
2663{
2664 processEvents( 3000 );
2665}
2666
2667/*!
2668 \overload
2669
2670 Processes pending events for \a maxtime milliseconds or until
2671 there are no more events to process, whichever is shorter.
2672
2673 You can call this function occasionally when you program is busy
2674 doing a long operation (e.g. copying a file).
2675
2676 \sa exec(), QTimer, QEventLoop::processEvents()
2677*/
2678void QApplication::processEvents( int maxtime )
2679{
2680 eventLoop()->processEvents( QEventLoop::AllEvents, maxtime );
2681}
2682
2683/*! \obsolete
2684 Waits for an event to occur, processes it, then returns.
2685
2686 This function is useful for adapting Qt to situations where the
2687 event processing must be grafted onto existing program loops.
2688
2689 Using this function in new applications may be an indication of design
2690 problems.
2691
2692 \sa processEvents(), exec(), QTimer
2693*/
2694
2695void QApplication::processOneEvent()
2696{
2697 eventLoop()->processEvents( QEventLoop::AllEvents |
2698 QEventLoop::WaitForMore );
2699}
2700
2701/*****************************************************************************
2702 Main event loop wrappers
2703 *****************************************************************************/
2704
2705/*!
2706 Returns the application event loop. This function will return
2707 zero if called during and after destroying QApplication.
2708
2709 To create your own instance of QEventLoop or QEventLoop subclass create
2710 it before you create the QApplication object.
2711
2712 \sa QEventLoop
2713*/
2714QEventLoop *QApplication::eventLoop()
2715{
2716 if ( !eventloop && !is_app_closing )
2717 (void) new QEventLoop( qApp, "default event loop" );
2718 return eventloop;
2719}
2720
2721
2722/*!
2723 Enters the main event loop and waits until exit() is called or the
2724 main widget is destroyed, and returns the value that was set to
2725 exit() (which is 0 if exit() is called via quit()).
2726
2727 It is necessary to call this function to start event handling. The
2728 main event loop receives events from the window system and
2729 dispatches these to the application widgets.
2730
2731 Generally speaking, no user interaction can take place before
2732 calling exec(). As a special case, modal widgets like QMessageBox
2733 can be used before calling exec(), because modal widgets call
2734 exec() to start a local event loop.
2735
2736 To make your application perform idle processing, i.e. executing a
2737 special function whenever there are no pending events, use a
2738 QTimer with 0 timeout. More advanced idle processing schemes can
2739 be achieved using processEvents().
2740
2741 \sa quit(), exit(), processEvents(), setMainWidget()
2742*/
2743int QApplication::exec()
2744{
2745 return eventLoop()->exec();
2746}
2747
2748/*!
2749 Tells the application to exit with a return code.
2750
2751 After this function has been called, the application leaves the main
2752 event loop and returns from the call to exec(). The exec() function
2753 returns \a retcode.
2754
2755 By convention, a \a retcode of 0 means success, and any non-zero
2756 value indicates an error.
2757
2758 Note that unlike the C library function of the same name, this
2759 function \e does return to the caller -- it is event processing that
2760 stops.
2761
2762 \sa quit(), exec()
2763*/
2764void QApplication::exit( int retcode )
2765{
2766 qApp->eventLoop()->exit( retcode );
2767}
2768
2769/*!
2770 \obsolete
2771
2772 This function enters the main event loop (recursively). Do not call
2773 it unless you really know what you are doing.
2774*/
2775int QApplication::enter_loop()
2776{
2777 return eventLoop()->enterLoop();
2778}
2779
2780/*!
2781 \obsolete
2782
2783 This function exits from a recursive call to the main event loop.
2784 Do not call it unless you are an expert.
2785*/
2786void QApplication::exit_loop()
2787{
2788 eventLoop()->exitLoop();
2789}
2790
2791/*!
2792 \obsolete
2793
2794 Returns the current loop level.
2795*/
2796int QApplication::loopLevel() const
2797{
2798 return eventLoop()->loopLevel();
2799}
2800
2801/*!
2802
2803 Wakes up the GUI thread.
2804
2805 \sa guiThreadAwake() \link threads.html Thread Support in Qt\endlink
2806*/
2807void QApplication::wakeUpGuiThread()
2808{
2809 eventLoop()->wakeUp();
2810}
2811
2812/*!
2813 This function returns TRUE if there are pending events; otherwise
2814 returns FALSE. Pending events can be either from the window system
2815 or posted events using QApplication::postEvent().
2816*/
2817bool QApplication::hasPendingEvents()
2818{
2819 return eventLoop()->hasPendingEvents();
2820}
2821
2822#if !defined(Q_WS_X11)
2823
2824// The doc and X implementation of these functions is in qapplication_x11.cpp
2825
2826void QApplication::flushX() {} // do nothing
2827
2828void QApplication::syncX() {} // do nothing
2829
2830#endif
2831
2832/*!
2833 \fn void QApplication::setWinStyleHighlightColor( const QColor & )
2834 \obsolete
2835
2836 Sets the color used to mark selections in windows style for all widgets
2837 in the application. Will repaint all widgets if the color is changed.
2838
2839 The default color is \c darkBlue.
2840 \sa winStyleHighlightColor()
2841*/
2842
2843/*!
2844 \fn const QColor& QApplication::winStyleHighlightColor()
2845 \obsolete
2846
2847 Returns the color used to mark selections in windows style.
2848
2849 \sa setWinStyleHighlightColor()
2850*/
2851
2852/*!
2853 Returns the version of the Windows operating system that is running:
2854
2855 \list
2856 \i Qt::WV_95 - Windows 95
2857 \i Qt::WV_98 - Windows 98
2858 \i Qt::WV_Me - Windows Me
2859 \i Qt::WV_NT - Windows NT 4.x
2860 \i Qt::WV_2000 - Windows 2000 (NT5)
2861 \i Qt::WV_XP - Windows XP
2862 \i Qt::WV_2003 - Windows Server 2003 family
2863 \i Qt::WV_CE - Windows CE
2864 \i Qt::WV_CENET - Windows CE.NET
2865 \endlist
2866
2867 Note that this function is implemented for the Windows version
2868 of Qt only.
2869*/
2870
2871#if defined(Q_OS_CYGWIN)
2872Qt::WindowsVersion QApplication::winVersion()
2873{
2874 return qt_winver;
2875}
2876#endif
2877
2878#ifndef QT_NO_TRANSLATION
2879
2880bool qt_detectRTLLanguage()
2881{
2882 return QApplication::tr( "QT_LAYOUT_DIRECTION",
2883 "Translate this string to the string 'LTR' in left-to-right"
2884 " languages or to 'RTL' in right-to-left languages (such as Hebrew"
2885 " and Arabic) to get proper widget layout." ) == "RTL";
2886}
2887
2888/*!
2889 Adds the message file \a mf to the list of message files to be used
2890 for translations.
2891
2892 Multiple message files can be installed. Translations are searched
2893 for in the last installed message file, then the one from last, and
2894 so on, back to the first installed message file. The search stops as
2895 soon as a matching translation is found.
2896
2897 \sa removeTranslator() translate() QTranslator::load()
2898*/
2899
2900void QApplication::installTranslator( QTranslator * mf )
2901{
2902 if ( !mf )
2903 return;
2904 if ( !translators )
2905 translators = new QValueList<QTranslator*>;
2906
2907 translators->prepend( mf );
2908
2909#ifndef QT_NO_TRANSLATION_BUILDER
2910 if ( mf->isEmpty() )
2911 return;
2912#endif
2913
2914 // hook to set the layout direction of dialogs
2915 setReverseLayout( qt_detectRTLLanguage() );
2916
2917 QWidgetList *list = topLevelWidgets();
2918 QWidgetListIt it( *list );
2919 QWidget *w;
2920 while ( ( w=it.current() ) != 0 ) {
2921 ++it;
2922 if (!w->isDesktop())
2923 postEvent( w, new QEvent( QEvent::LanguageChange ) );
2924 }
2925 delete list;
2926}
2927
2928/*!
2929 Removes the message file \a mf from the list of message files used by
2930 this application. (It does not delete the message file from the file
2931 system.)
2932
2933 \sa installTranslator() translate(), QObject::tr()
2934*/
2935
2936void QApplication::removeTranslator( QTranslator * mf )
2937{
2938 if ( !translators || !mf )
2939 return;
2940
2941 if ( translators->remove( mf ) && ! qApp->closingDown() ) {
2942 setReverseLayout( qt_detectRTLLanguage() );
2943
2944 QWidgetList *list = topLevelWidgets();
2945 QWidgetListIt it( *list );
2946 QWidget *w;
2947 while ( ( w=it.current() ) != 0 ) {
2948 ++it;
2949 postEvent( w, new QEvent( QEvent::LanguageChange ) );
2950 }
2951 delete list;
2952 }
2953}
2954
2955#ifndef QT_NO_TEXTCODEC
2956/*! \obsolete
2957 This is the same as QTextCodec::setCodecForTr().
2958*/
2959void QApplication::setDefaultCodec( QTextCodec* codec )
2960{
2961 QTextCodec::setCodecForTr( codec );
2962}
2963
2964/*! \obsolete
2965 Returns QTextCodec::codecForTr().
2966*/
2967QTextCodec* QApplication::defaultCodec() const
2968{
2969 return QTextCodec::codecForTr();
2970}
2971#endif //QT_NO_TEXTCODEC
2972
2973/*! \enum QApplication::Encoding
2974
2975 This enum type defines the 8-bit encoding of character string
2976 arguments to translate():
2977
2978 \value DefaultCodec - the encoding specified by
2979 QTextCodec::codecForTr() (Latin-1 if none has been set)
2980 \value UnicodeUTF8 - UTF-8
2981
2982 \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
2983*/
2984
2985/*! \reentrant
2986 Returns the translation text for \a sourceText, by querying the
2987 installed messages files. The message files are searched from the most
2988 recently installed message file back to the first installed message
2989 file.
2990
2991 QObject::tr() and QObject::trUtf8() provide this functionality more
2992 conveniently.
2993
2994 \a context is typically a class name (e.g., "MyDialog") and
2995 \a sourceText is either English text or a short identifying text, if
2996 the output text will be very long (as for help texts).
2997
2998 \a comment is a disambiguating comment, for when the same \a
2999 sourceText is used in different roles within the same context. By
3000 default, it is null. \a encoding indicates the 8-bit encoding of
3001 character stings
3002
3003 See the \l QTranslator documentation for more information about
3004 contexts and comments.
3005
3006 If none of the message files contain a translation for \a
3007 sourceText in \a context, this function returns a QString
3008 equivalent of \a sourceText. The encoding of \a sourceText is
3009 specified by \e encoding; it defaults to \c DefaultCodec.
3010
3011 This function is not virtual. You can use alternative translation
3012 techniques by subclassing \l QTranslator.
3013
3014 \warning This method is reentrant only if all translators are
3015 installed \e before calling this method. Installing or removing
3016 translators while performing translations is not supported. Doing
3017 so will most likely result in crashes or other undesirable behavior.
3018
3019 \sa QObject::tr() installTranslator() defaultCodec()
3020*/
3021
3022QString QApplication::translate( const char * context, const char * sourceText,
3023 const char * comment, Encoding encoding ) const
3024{
3025 if ( !sourceText )
3026 return QString::null;
3027
3028 if ( translators ) {
3029 QValueList<QTranslator*>::iterator it;
3030 QTranslator * mf;
3031 QString result;
3032 for ( it = translators->begin(); it != translators->end(); ++it ) {
3033 mf = *it;
3034 result = mf->findMessage( context, sourceText, comment ).translation();
3035 if ( !result.isNull() )
3036 return result;
3037 }
3038 }
3039#ifndef QT_NO_TEXTCODEC
3040 if ( encoding == UnicodeUTF8 )
3041 return QString::fromUtf8( sourceText );
3042 else if ( QTextCodec::codecForTr() != 0 )
3043 return QTextCodec::codecForTr()->toUnicode( sourceText );
3044 else
3045#endif
3046 return QString::fromLatin1( sourceText );
3047}
3048
3049#endif
3050
3051/*****************************************************************************
3052 QApplication management of posted events
3053 *****************************************************************************/
3054
3055//see also notify(), which does the removal of ChildInserted when ChildRemoved.
3056
3057/*!
3058 Adds the event \a event with the object \a receiver as the receiver of the
3059 event, to an event queue and returns immediately.
3060
3061 The event must be allocated on the heap since the post event queue
3062 will take ownership of the event and delete it once it has been posted.
3063
3064 When control returns to the main event loop, all events that are
3065 stored in the queue will be sent using the notify() function.
3066
3067 \threadsafe
3068
3069 \sa sendEvent(), notify()
3070*/
3071
3072void QApplication::postEvent( QObject *receiver, QEvent *event )
3073{
3074 if ( receiver == 0 ) {
3075#if defined(QT_CHECK_NULL)
3076 qWarning( "QApplication::postEvent: Unexpected null receiver" );
3077#endif
3078 delete event;
3079 return;
3080 }
3081
3082#ifdef QT_THREAD_SUPPORT
3083 QMutexLocker locker( postevent_mutex );
3084#endif // QT_THREAD_SUPPORT
3085
3086 if ( !globalPostedEvents ) { // create list
3087 globalPostedEvents = new QPostEventList;
3088 Q_CHECK_PTR( globalPostedEvents );
3089 globalPostedEvents->setAutoDelete( TRUE );
3090 qapp_cleanup_events.set( &globalPostedEvents );
3091 }
3092
3093 if ( !receiver->postedEvents )
3094 receiver->postedEvents = new QPostEventList;
3095 QPostEventList * l = receiver->postedEvents;
3096
3097 // if this is one of the compressible events, do compression
3098 if ( event->type() == QEvent::Paint ||
3099 event->type() == QEvent::LayoutHint ||
3100 event->type() == QEvent::Resize ||
3101 event->type() == QEvent::Move ||
3102 event->type() == QEvent::LanguageChange ) {
3103 l->first();
3104 QPostEvent * cur = 0;
3105 for ( ;; ) {
3106 while ( (cur=l->current()) != 0 &&
3107 ( cur->receiver != receiver ||
3108 cur->event == 0 ||
3109 cur->event->type() != event->type() ) )
3110 l->next();
3111 if ( l->current() != 0 ) {
3112 if ( cur->event->type() == QEvent::Paint ) {
3113 QPaintEvent * p = (QPaintEvent*)(cur->event);
3114 if ( p->erase != ((QPaintEvent*)event)->erase ) {
3115 l->next();
3116 continue;
3117 }
3118 p->reg = p->reg.unite( ((QPaintEvent *)event)->reg );
3119 p->rec = p->rec.unite( ((QPaintEvent *)event)->rec );
3120 delete event;
3121 return;
3122 } else if ( cur->event->type() == QEvent::LayoutHint ) {
3123 delete event;
3124 return;
3125 } else if ( cur->event->type() == QEvent::Resize ) {
3126 ((QResizeEvent *)(cur->event))->s = ((QResizeEvent *)event)->s;
3127 delete event;
3128 return;
3129 } else if ( cur->event->type() == QEvent::Move ) {
3130 ((QMoveEvent *)(cur->event))->p = ((QMoveEvent *)event)->p;
3131 delete event;
3132 return;
3133 } else if ( cur->event->type() == QEvent::LanguageChange ) {
3134 delete event;
3135 return;
3136 }
3137 }
3138 break;
3139 };
3140 }
3141
3142 // if no compression could be done, just append something
3143 event->posted = TRUE;
3144 QPostEvent * pe = new QPostEvent( receiver, event );
3145 l->append( pe );
3146 globalPostedEvents->append( pe );
3147
3148 if (eventloop)
3149 eventloop->wakeUp();
3150}
3151
3152
3153/*! \overload
3154
3155 Dispatches all posted events, i.e. empties the event queue.
3156*/
3157void QApplication::sendPostedEvents()
3158{
3159 sendPostedEvents( 0, 0 );
3160}
3161
3162
3163
3164/*!
3165 Immediately dispatches all events which have been previously queued
3166 with QApplication::postEvent() and which are for the object \a receiver
3167 and have the event type \a event_type.
3168
3169 Note that events from the window system are \e not dispatched by this
3170 function, but by processEvents().
3171
3172 If \a receiver is null, the events of \a event_type are sent for all
3173 objects. If \a event_type is 0, all the events are sent for \a receiver.
3174*/
3175
3176void QApplication::sendPostedEvents( QObject *receiver, int event_type )
3177{
3178 // Make sure the object hierarchy is stable before processing events
3179 // to avoid endless loops
3180 if ( receiver == 0 && event_type == 0 )
3181 sendPostedEvents( 0, QEvent::ChildInserted );
3182
3183 if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
3184 return;
3185
3186#ifdef QT_THREAD_SUPPORT
3187 QMutexLocker locker( postevent_mutex );
3188#endif
3189
3190 bool sent = TRUE;
3191 while ( sent ) {
3192 sent = FALSE;
3193
3194 if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
3195 return;
3196
3197 // if we have a receiver, use the local list. Otherwise, use the
3198 // global list
3199 QPostEventList * l = receiver ? receiver->postedEvents : globalPostedEvents;
3200
3201 // okay. here is the tricky loop. be careful about optimizing
3202 // this, it looks the way it does for good reasons.
3203 QPostEventListIt it( *l );
3204 QPostEvent *pe;
3205 while ( (pe=it.current()) != 0 ) {
3206 ++it;
3207 if ( pe->event // hasn't been sent yet
3208 && ( receiver == 0 // we send to all receivers
3209 || receiver == pe->receiver ) // we send to THAT receiver
3210 && ( event_type == 0 // we send all types
3211 || event_type == pe->event->type() ) ) { // we send THAT type
3212 // first, we diddle the event so that we can deliver
3213 // it, and that noone will try to touch it later.
3214 pe->event->posted = FALSE;
3215 QEvent * e = pe->event;
3216 QObject * r = pe->receiver;
3217 pe->event = 0;
3218
3219 // next, update the data structure so that we're ready
3220 // for the next event.
3221
3222 // look for the local list, and take whatever we're
3223 // delivering out of it. r->postedEvents maybe *l
3224 if ( r->postedEvents ) {
3225 r->postedEvents->removeRef( pe );
3226 // if possible, get rid of that list. this is not
3227 // ideal - we will create and delete a list for
3228 // each update() call. it would be better if we'd
3229 // leave the list empty here, and delete it
3230 // somewhere else if it isn't being used.
3231 if ( r->postedEvents->isEmpty() ) {
3232 delete r->postedEvents;
3233 r->postedEvents = 0;
3234 }
3235 }
3236
3237#ifdef QT_THREAD_SUPPORT
3238 if ( locker.mutex() ) locker.mutex()->unlock();
3239#endif // QT_THREAD_SUPPORT
3240 // after all that work, it's time to deliver the event.
3241 if ( e->type() == QEvent::Paint && r->isWidgetType() ) {
3242 QWidget * w = (QWidget*)r;
3243 QPaintEvent * p = (QPaintEvent*)e;
3244 if ( w->isVisible() )
3245 w->repaint( p->reg, p->erase );
3246 } else {
3247 sent = TRUE;
3248 QApplication::sendEvent( r, e );
3249 }
3250#ifdef QT_THREAD_SUPPORT
3251 if ( locker.mutex() ) locker.mutex()->lock();
3252#endif // QT_THREAD_SUPPORT
3253
3254 delete e;
3255 // careful when adding anything below this point - the
3256 // sendEvent() call might invalidate any invariants this
3257 // function depends on.
3258 }
3259 }
3260
3261 // clear the global list, i.e. remove everything that was
3262 // delivered.
3263 if ( l == globalPostedEvents ) {
3264 globalPostedEvents->first();
3265 while( (pe=globalPostedEvents->current()) != 0 ) {
3266 if ( pe->event )
3267 globalPostedEvents->next();
3268 else
3269 globalPostedEvents->remove();
3270 }
3271 }
3272 }
3273}
3274
3275/*!
3276 Removes all events posted using postEvent() for \a receiver.
3277
3278 The events are \e not dispatched, instead they are removed from the
3279 queue. You should never need to call this function. If you do call it,
3280 be aware that killing events may cause \a receiver to break one or
3281 more invariants.
3282
3283 \threadsafe
3284*/
3285
3286void QApplication::removePostedEvents( QObject *receiver )
3287{
3288 if ( !receiver )
3289 return;
3290
3291#ifdef QT_THREAD_SUPPORT
3292 QMutexLocker locker( postevent_mutex );
3293#endif // QT_THREAD_SUPPORT
3294
3295 // the QObject destructor calls this function directly. this can
3296 // happen while the event loop is in the middle of posting events,
3297 // and when we get here, we may not have any more posted events
3298 // for this object.
3299 if ( !receiver->postedEvents )
3300 return;
3301
3302 // iterate over the object-specifc list and delete the events.
3303 // leave the QPostEvent objects; they'll be deleted by
3304 // sendPostedEvents().
3305 QPostEventList * l = receiver->postedEvents;
3306 receiver->postedEvents = 0;
3307 l->first();
3308 QPostEvent * pe;
3309 while( (pe=l->current()) != 0 ) {
3310 if ( pe->event ) {
3311 pe->event->posted = FALSE;
3312 delete pe->event;
3313 pe->event = 0;
3314 }
3315 l->remove();
3316 }
3317 delete l;
3318}
3319
3320
3321/*!
3322 Removes \a event from the queue of posted events, and emits a
3323 warning message if appropriate.
3324
3325 \warning This function can be \e really slow. Avoid using it, if
3326 possible.
3327
3328 \threadsafe
3329*/
3330
3331void QApplication::removePostedEvent( QEvent * event )
3332{
3333 if ( !event || !event->posted )
3334 return;
3335
3336 if ( !globalPostedEvents ) {
3337#if defined(QT_DEBUG)
3338 qDebug( "QApplication::removePostedEvent: %p %d is posted: impossible",
3339 (void*)event, event->type() );
3340 return;
3341#endif
3342 }
3343
3344#ifdef QT_THREAD_SUPPORT
3345 QMutexLocker locker( postevent_mutex );
3346#endif // QT_THREAD_SUPPORT
3347
3348 QPostEventListIt it( *globalPostedEvents );
3349 QPostEvent * pe;
3350 while( (pe = it.current()) != 0 ) {
3351 ++it;
3352 if ( pe->event == event ) {
3353#if defined(QT_DEBUG)
3354 const char *n;
3355 switch ( event->type() ) {
3356 case QEvent::Timer:
3357 n = "Timer";
3358 break;
3359 case QEvent::MouseButtonPress:
3360 n = "MouseButtonPress";
3361 break;
3362 case QEvent::MouseButtonRelease:
3363 n = "MouseButtonRelease";
3364 break;
3365 case QEvent::MouseButtonDblClick:
3366 n = "MouseButtonDblClick";
3367 break;
3368 case QEvent::MouseMove:
3369 n = "MouseMove";
3370 break;
3371#ifndef QT_NO_WHEELEVENT
3372 case QEvent::Wheel:
3373 n = "Wheel";
3374 break;
3375#endif
3376 case QEvent::KeyPress:
3377 n = "KeyPress";
3378 break;
3379 case QEvent::KeyRelease:
3380 n = "KeyRelease";
3381 break;
3382 case QEvent::FocusIn:
3383 n = "FocusIn";
3384 break;
3385 case QEvent::FocusOut:
3386 n = "FocusOut";
3387 break;
3388 case QEvent::Enter:
3389 n = "Enter";
3390 break;
3391 case QEvent::Leave:
3392 n = "Leave";
3393 break;
3394 case QEvent::Paint:
3395 n = "Paint";
3396 break;
3397 case QEvent::Move:
3398 n = "Move";
3399 break;
3400 case QEvent::Resize:
3401 n = "Resize";
3402 break;
3403 case QEvent::Create:
3404 n = "Create";
3405 break;
3406 case QEvent::Destroy:
3407 n = "Destroy";
3408 break;
3409 case QEvent::Close:
3410 n = "Close";
3411 break;
3412 case QEvent::Quit:
3413 n = "Quit";
3414 break;
3415 default:
3416 n = "<other>";
3417 break;
3418 }
3419 qWarning("QEvent: Warning: %s event deleted while posted to %s %s",
3420 n,
3421 pe->receiver ? pe->receiver->className() : "null",
3422 pe->receiver ? pe->receiver->name() : "object" );
3423 // note the beautiful uglehack if !pe->receiver :)
3424#endif
3425 event->posted = FALSE;
3426 delete pe->event;
3427 pe->event = 0;
3428 return;
3429 }
3430 }
3431}
3432
3433/*!\internal
3434
3435 Sets the active window in reaction to a system event. Call this
3436 from the platform specific event handlers.
3437
3438 It sets the activeWindow() and focusWidget() attributes and sends
3439 proper WindowActivate/WindowDeactivate and FocusIn/FocusOut events
3440 to all appropriate widgets.
3441
3442 \sa activeWindow()
3443 */
3444void QApplication::setActiveWindow( QWidget* act )
3445{
3446 QWidget* window = act?act->topLevelWidget():0;
3447
3448 if ( active_window == window )
3449 return;
3450
3451 // first the activation/deactivation events
3452 if ( active_window ) {
3453 QWidgetList deacts;
3454#ifndef QT_NO_STYLE
3455 if ( style().styleHint(QStyle::SH_Widget_ShareActivation, active_window ) ) {
3456 QWidgetList *list = topLevelWidgets();
3457 if ( list ) {
3458 for ( QWidget *w = list->first(); w; w = list->next() ) {
3459 if ( w->isVisible() && w->isActiveWindow() )
3460 deacts.append(w);
3461 }
3462 delete list;
3463 }
3464 } else
3465#endif
3466 deacts.append(active_window);
3467 active_window = 0;
3468 QEvent e( QEvent::WindowDeactivate );
3469 for(QWidget *w = deacts.first(); w; w = deacts.next())
3470 QApplication::sendSpontaneousEvent( w, &e );
3471 }
3472
3473 active_window = window;
3474 if ( active_window ) {
3475 QEvent e( QEvent::WindowActivate );
3476 QWidgetList acts;
3477#ifndef QT_NO_STYLE
3478 if ( style().styleHint(QStyle::SH_Widget_ShareActivation, active_window ) ) {
3479 QWidgetList *list = topLevelWidgets();
3480 if ( list ) {
3481 for ( QWidget *w = list->first(); w; w = list->next() ) {
3482 if ( w->isVisible() && w->isActiveWindow() )
3483 acts.append(w);
3484 }
3485 delete list;
3486 }
3487 } else
3488#endif
3489 acts.append(active_window);
3490 for(QWidget *w = acts.first(); w; w = acts.next())
3491 QApplication::sendSpontaneousEvent( w, &e );
3492 }
3493
3494 // then focus events
3495 QFocusEvent::setReason( QFocusEvent::ActiveWindow );
3496 if ( !active_window && focus_widget ) {
3497 QFocusEvent out( QEvent::FocusOut );
3498 QWidget *tmp = focus_widget;
3499 focus_widget = 0;
3500#ifdef Q_WS_WIN
3501 QInputContext::accept( tmp );
3502#endif
3503 QApplication::sendSpontaneousEvent( tmp, &out );
3504 } else if ( active_window ) {
3505 QWidget *w = active_window->focusWidget();
3506 if ( w && w->focusPolicy() != QWidget::NoFocus )
3507 w->setFocus();
3508 else
3509 active_window->focusNextPrevChild( TRUE );
3510 }
3511 QFocusEvent::resetReason();
3512}
3513
3514
3515/*!\internal
3516
3517 Creates the proper Enter/Leave event when widget \a enter is entered
3518 and widget \a leave is left.
3519 */
3520Q_EXPORT void qt_dispatchEnterLeave( QWidget* enter, QWidget* leave ) {
3521#if 0
3522 if ( leave ) {
3523 QEvent e( QEvent::Leave );
3524 QApplication::sendEvent( leave, & e );
3525 }
3526 if ( enter ) {
3527 QEvent e( QEvent::Enter );
3528 QApplication::sendEvent( enter, & e );
3529 }
3530 return;
3531#endif
3532
3533 QWidget* w ;
3534 if ( !enter && !leave )
3535 return;
3536 QWidgetList leaveList;
3537 QWidgetList enterList;
3538
3539 bool sameWindow = leave && enter && leave->topLevelWidget() == enter->topLevelWidget();
3540 if ( leave && !sameWindow ) {
3541 w = leave;
3542 do {
3543 leaveList.append( w );
3544 } while ( (w = w->parentWidget( TRUE ) ) );
3545 }
3546 if ( enter && !sameWindow ) {
3547 w = enter;
3548 do {
3549 enterList.prepend( w );
3550 } while ( (w = w->parentWidget(TRUE) ) );
3551 }
3552 if ( sameWindow ) {
3553 int enterDepth = 0;
3554 int leaveDepth = 0;
3555 w = enter;
3556 while ( ( w = w->parentWidget( TRUE ) ) )
3557 enterDepth++;
3558 w = leave;
3559 while ( ( w = w->parentWidget( TRUE ) ) )
3560 leaveDepth++;
3561 QWidget* wenter = enter;
3562 QWidget* wleave = leave;
3563 while ( enterDepth > leaveDepth ) {
3564 wenter = wenter->parentWidget();
3565 enterDepth--;
3566 }
3567 while ( leaveDepth > enterDepth ) {
3568 wleave = wleave->parentWidget();
3569 leaveDepth--;
3570 }
3571 while ( !wenter->isTopLevel() && wenter != wleave ) {
3572 wenter = wenter->parentWidget();
3573 wleave = wleave->parentWidget();
3574 }
3575
3576 w = leave;
3577 while ( w != wleave ) {
3578 leaveList.append( w );
3579 w = w->parentWidget();
3580 }
3581 w = enter;
3582 while ( w != wenter ) {
3583 enterList.prepend( w );
3584 w = w->parentWidget();
3585 }
3586 }
3587
3588 QEvent leaveEvent( QEvent::Leave );
3589 for ( w = leaveList.first(); w; w = leaveList.next() ) {
3590 if ( !qApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
3591 QApplication::sendEvent( w, &leaveEvent );
3592 }
3593 QEvent enterEvent( QEvent::Enter );
3594 for ( w = enterList.first(); w; w = enterList.next() ) {
3595 if ( !qApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
3596 QApplication::sendEvent( w, &enterEvent );
3597 }
3598}
3599
3600
3601#ifdef Q_WS_MACX
3602extern QWidget *qt_tryModalHelperMac( QWidget * top ); //qapplication_mac.cpp
3603#endif
3604
3605
3606/*!\internal
3607
3608 Called from qapplication_<platform>.cpp, returns TRUE
3609 if the widget should accept the event.
3610 */
3611bool qt_tryModalHelper( QWidget *widget, QWidget **rettop ) {
3612 QWidget *modal=0, *top=QApplication::activeModalWidget();
3613 if ( rettop ) *rettop = top;
3614
3615 if ( qApp->activePopupWidget() )
3616 return TRUE;
3617
3618#ifdef Q_WS_MACX
3619 top = qt_tryModalHelperMac( top );
3620 if ( rettop ) *rettop = top;
3621#endif
3622
3623 QWidget* groupLeader = widget;
3624 widget = widget->topLevelWidget();
3625
3626 if ( widget->testWFlags(Qt::WShowModal) ) // widget is modal
3627 modal = widget;
3628 if ( !top || modal == top ) // don't block event
3629 return TRUE;
3630
3631 QWidget * p = widget->parentWidget(); // Check if the active modal widget is a parent of our widget
3632 while ( p ) {
3633 if ( p == top )
3634 return TRUE;
3635 p = p->parentWidget();
3636 }
3637
3638 while ( groupLeader && !groupLeader->testWFlags( Qt::WGroupLeader ) )
3639 groupLeader = groupLeader->parentWidget();
3640
3641 if ( groupLeader ) {
3642 // Does groupLeader have a child in qt_modal_stack?
3643 bool unrelated = TRUE;
3644 modal = qt_modal_stack->first();
3645 while (modal && unrelated) {
3646 QWidget* p = modal->parentWidget();
3647 while ( p && p != groupLeader && !p->testWFlags( Qt::WGroupLeader) ) {
3648 p = p->parentWidget();
3649 }
3650 modal = qt_modal_stack->next();
3651 if ( p == groupLeader ) unrelated = FALSE;
3652 }
3653
3654 if ( unrelated )
3655 return TRUE; // don't block event
3656 }
3657 return FALSE;
3658}
3659
3660
3661/*!
3662 Returns the desktop widget (also called the root window).
3663
3664 The desktop widget is useful for obtaining the size of the screen.
3665 It may also be possible to draw on the desktop. We recommend against
3666 assuming that it's possible to draw on the desktop, since this does
3667 not work on all operating systems.
3668
3669 \code
3670 QDesktopWidget *d = QApplication::desktop();
3671 int w = d->width(); // returns desktop width
3672 int h = d->height(); // returns desktop height
3673 \endcode
3674*/
3675
3676QDesktopWidget *QApplication::desktop()
3677{
3678 if ( !qt_desktopWidget || // not created yet
3679 !qt_desktopWidget->isDesktop() ) { // reparented away
3680 qt_desktopWidget = new QDesktopWidget();
3681 Q_CHECK_PTR( qt_desktopWidget );
3682 }
3683 return qt_desktopWidget;
3684}
3685
3686#ifndef QT_NO_CLIPBOARD
3687/*!
3688 Returns a pointer to the application global clipboard.
3689*/
3690QClipboard *QApplication::clipboard()
3691{
3692 if ( qt_clipboard == 0 ) {
3693 qt_clipboard = new QClipboard;
3694 Q_CHECK_PTR( qt_clipboard );
3695 }
3696 return qt_clipboard;
3697}
3698#endif // QT_NO_CLIPBOARD
3699
3700/*!
3701 By default, Qt will try to use the current standard colors, fonts
3702 etc., from the underlying window system's desktop settings,
3703 and use them for all relevant widgets. This behavior can be switched off
3704 by calling this function with \a on set to FALSE.
3705
3706 This static function must be called before creating the QApplication
3707 object, like this:
3708
3709 \code
3710 int main( int argc, char** argv ) {
3711 QApplication::setDesktopSettingsAware( FALSE ); // I know better than the user
3712 QApplication myApp( argc, argv ); // Use default fonts & colors
3713 ...
3714 }
3715 \endcode
3716
3717 \sa desktopSettingsAware()
3718*/
3719
3720void QApplication::setDesktopSettingsAware( bool on )
3721{
3722 obey_desktop_settings = on;
3723}
3724
3725/*!
3726 Returns the value set by setDesktopSettingsAware(); by default TRUE.
3727
3728 \sa setDesktopSettingsAware()
3729*/
3730
3731bool QApplication::desktopSettingsAware()
3732{
3733 return obey_desktop_settings;
3734}
3735
3736/*! \fn void QApplication::lock()
3737
3738 Lock the Qt Library Mutex. If another thread has already locked the
3739 mutex, the calling thread will block until the other thread has
3740 unlocked the mutex.
3741
3742 \sa unlock() locked() \link threads.html Thread Support in Qt\endlink
3743*/
3744
3745
3746/*! \fn void QApplication::unlock(bool wakeUpGui)
3747
3748 Unlock the Qt Library Mutex. If \a wakeUpGui is TRUE (the default),
3749 then the GUI thread will be woken with QApplication::wakeUpGuiThread().
3750
3751 \sa lock(), locked() \link threads.html Thread Support in Qt\endlink
3752*/
3753
3754
3755/*! \fn bool QApplication::locked()
3756
3757 Returns TRUE if the Qt Library Mutex is locked by a different thread;
3758 otherwise returns FALSE.
3759
3760 \warning Due to different implementations of recursive mutexes on
3761 the supported platforms, calling this function from the same thread
3762 that previously locked the mutex will give undefined results.
3763
3764 \sa lock() unlock() \link threads.html Thread Support in Qt\endlink
3765*/
3766
3767/*! \fn bool QApplication::tryLock()
3768
3769 Attempts to lock the Qt Library Mutex, and returns immediately. If
3770 the lock was obtained, this function returns TRUE. If another thread
3771 has locked the mutex, this function returns FALSE, instead of
3772 waiting for the lock to become available.
3773
3774 The mutex must be unlocked with unlock() before another thread can
3775 successfully lock it.
3776
3777 \sa lock(), unlock() \link threads.html Thread Support in Qt\endlink
3778*/
3779
3780#if defined(QT_THREAD_SUPPORT)
3781void QApplication::lock()
3782{
3783 qt_mutex->lock();
3784}
3785
3786void QApplication::unlock(bool wakeUpGui)
3787{
3788 qt_mutex->unlock();
3789
3790 if (wakeUpGui)
3791 wakeUpGuiThread();
3792}
3793
3794bool QApplication::locked()
3795{
3796 return qt_mutex->locked();
3797}
3798
3799bool QApplication::tryLock()
3800{
3801 return qt_mutex->tryLock();
3802}
3803#endif
3804
3805
3806/*!
3807 \fn bool QApplication::isSessionRestored() const
3808
3809 Returns TRUE if the application has been restored from an earlier
3810 \link session.html session\endlink; otherwise returns FALSE.
3811
3812 \sa sessionId(), commitData(), saveState()
3813*/
3814
3815
3816/*!
3817 \fn QString QApplication::sessionId() const
3818
3819 Returns the current \link session.html session's\endlink identifier.
3820
3821 If the application has been restored from an earlier session, this
3822 identifier is the same as it was in that previous session.
3823
3824 The session identifier is guaranteed to be unique both for different
3825 applications and for different instances of the same application.
3826
3827 \sa isSessionRestored(), sessionKey(), commitData(), saveState()
3828 */
3829
3830/*!
3831 \fn QString QApplication::sessionKey() const
3832
3833 Returns the session key in the current \link session.html
3834 session\endlink.
3835
3836 If the application has been restored from an earlier session, this
3837 key is the same as it was when the previous session ended.
3838
3839 The session key changes with every call of commitData() or
3840 saveState().
3841
3842 \sa isSessionRestored(), sessionId(), commitData(), saveState()
3843 */
3844
3845
3846/*!
3847 \fn void QApplication::commitData( QSessionManager& sm )
3848
3849 This function deals with \link session.html session
3850 management\endlink. It is invoked when the QSessionManager wants the
3851 application to commit all its data.
3852
3853 Usually this means saving all open files, after getting
3854 permission from the user. Furthermore you may want to provide a means
3855 by which the user can cancel the shutdown.
3856
3857 Note that you should not exit the application within this function.
3858 Instead, the session manager may or may not do this afterwards,
3859 depending on the context.
3860
3861 \warning Within this function, no user interaction is possible, \e
3862 unless you ask the session manager \a sm for explicit permission.
3863 See QSessionManager::allowsInteraction() and
3864 QSessionManager::allowsErrorInteraction() for details and example
3865 usage.
3866
3867 The default implementation requests interaction and sends a close
3868 event to all visible top level widgets. If any event was
3869 rejected, the shutdown is canceled.
3870
3871 \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink
3872*/
3873#ifndef QT_NO_SESSIONMANAGER
3874void QApplication::commitData( QSessionManager& sm )
3875{
3876
3877 if ( sm.allowsInteraction() ) {
3878 QWidgetList done;
3879 QWidgetList *list = QApplication::topLevelWidgets();
3880 bool cancelled = FALSE;
3881 QWidget* w = list->first();
3882 while ( !cancelled && w ) {
3883 if ( !w->isHidden() ) {
3884 QCloseEvent e;
3885 sendEvent( w, &e );
3886 cancelled = !e.isAccepted();
3887 if ( !cancelled )
3888 done.append( w );
3889 delete list; // one never knows...
3890 list = QApplication::topLevelWidgets();
3891 w = list->first();
3892 } else {
3893 w = list->next();
3894 }
3895 while ( w && done.containsRef( w ) )
3896 w = list->next();
3897 }
3898 delete list;
3899 if ( cancelled )
3900 sm.cancel();
3901 }
3902}
3903
3904
3905/*!
3906 \fn void QApplication::saveState( QSessionManager& sm )
3907
3908 This function deals with \link session.html session
3909 management\endlink. It is invoked when the
3910 \link QSessionManager session manager \endlink wants the application
3911 to preserve its state for a future session.
3912
3913 For example, a text editor would create a temporary file that
3914 includes the current contents of its edit buffers, the location of
3915 the cursor and other aspects of the current editing session.
3916
3917 Note that you should never exit the application within this
3918 function. Instead, the session manager may or may not do this
3919 afterwards, depending on the context. Futhermore, most session
3920 managers will very likely request a saved state immediately after
3921 the application has been started. This permits the session manager
3922 to learn about the application's restart policy.
3923
3924 \warning Within this function, no user interaction is possible, \e
3925 unless you ask the session manager \a sm for explicit permission.
3926 See QSessionManager::allowsInteraction() and
3927 QSessionManager::allowsErrorInteraction() for details.
3928
3929 \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink
3930*/
3931
3932void QApplication::saveState( QSessionManager& /* sm */ )
3933{
3934}
3935#endif //QT_NO_SESSIONMANAGER
3936/*!
3937 Sets the time after which a drag should start to \a ms ms.
3938
3939 \sa startDragTime()
3940*/
3941
3942void QApplication::setStartDragTime( int ms )
3943{
3944 drag_time = ms;
3945}
3946
3947/*!
3948 If you support drag and drop in you application and a drag should
3949 start after a mouse click and after a certain time elapsed, you
3950 should use the value which this method returns as the delay (in ms).
3951
3952 Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit,
3953 for starting a drag.
3954
3955 The default value is 500 ms.
3956
3957 \sa setStartDragTime(), startDragDistance()
3958*/
3959
3960int QApplication::startDragTime()
3961{
3962 return drag_time;
3963}
3964
3965/*!
3966 Sets the distance after which a drag should start to \a l pixels.
3967
3968 \sa startDragDistance()
3969*/
3970
3971void QApplication::setStartDragDistance( int l )
3972{
3973 drag_distance = l;
3974}
3975
3976/*!
3977 If you support drag and drop in you application and a drag should
3978 start after a mouse click and after moving the mouse a certain
3979 distance, you should use the value which this method returns as the
3980 distance.
3981
3982 For example, if the mouse position of the click is stored in \c
3983 startPos and the current position (e.g. in the mouse move event) is
3984 \c currPos, you can find out if a drag should be started with code
3985 like this:
3986 \code
3987 if ( ( startPos - currPos ).manhattanLength() >
3988 QApplication::startDragDistance() )
3989 startTheDrag();
3990 \endcode
3991
3992 Qt uses this value internally, e.g. in QFileDialog.
3993
3994 The default value is 4 pixels.
3995
3996 \sa setStartDragDistance(), startDragTime(), QPoint::manhattanLength()
3997*/
3998
3999int QApplication::startDragDistance()
4000{
4001 return drag_distance;
4002}
4003
4004/*!
4005 If \a b is TRUE, all dialogs and widgets will be laid out in a
4006 mirrored fashion, as required by right to left languages such as
4007 Arabic and Hebrew. If \a b is FALSE, dialogs and widgets are laid
4008 out left to right.
4009
4010 Changing this flag in runtime does not cause a relayout of already
4011 instantiated widgets.
4012
4013 \sa reverseLayout()
4014*/
4015void QApplication::setReverseLayout( bool b )
4016{
4017 if ( reverse_layout == b )
4018 return;
4019
4020 reverse_layout = b;
4021
4022 QWidgetList *list = topLevelWidgets();
4023 QWidgetListIt it( *list );
4024 QWidget *w;
4025 while ( ( w=it.current() ) != 0 ) {
4026 ++it;
4027 postEvent( w, new QEvent( QEvent::LayoutDirectionChange ) );
4028 }
4029 delete list;
4030}
4031
4032/*!
4033 Returns TRUE if all dialogs and widgets will be laid out in a
4034 mirrored (right to left) fashion. Returns FALSE if dialogs and
4035 widgets will be laid out left to right.
4036
4037 \sa setReverseLayout()
4038*/
4039bool QApplication::reverseLayout()
4040{
4041 return reverse_layout;
4042}
4043
4044
4045/*!
4046 \class QSessionManager qsessionmanager.h
4047 \brief The QSessionManager class provides access to the session manager.
4048
4049 \ingroup application
4050 \ingroup environment
4051
4052 The session manager is responsible for session management, most
4053 importantly for interruption and resumption. A "session" is a kind
4054 of record of the state of the system, e.g. which applications were
4055 run at start up and which applications are currently running. The
4056 session manager is used to save the session, e.g. when the machine
4057 is shut down; and to restore a session, e.g. when the machine is
4058 started up. Use QSettings to save and restore an individual
4059 application's settings, e.g. window positions, recently used files,
4060 etc.
4061
4062 QSessionManager provides an interface between the application and
4063 the session manager so that the program can work well with the
4064 session manager. In Qt, session management requests for action
4065 are handled by the two virtual functions QApplication::commitData()
4066 and QApplication::saveState(). Both provide a reference to
4067 a session manager object as argument, to allow the application
4068 to communicate with the session manager.
4069
4070 During a session management action (i.e. within commitData() and
4071 saveState()), no user interaction is possible \e unless the
4072 application got explicit permission from the session manager. You
4073 ask for permission by calling allowsInteraction() or, if it's really
4074 urgent, allowsErrorInteraction(). Qt does not enforce this, but the
4075 session manager may.
4076
4077 You can try to abort the shutdown process by calling cancel(). The
4078 default commitData() function does this if some top-level window
4079 rejected its closeEvent().
4080
4081 For sophisticated session managers provided on Unix/X11, QSessionManager
4082 offers further possibilites to fine-tune an application's session
4083 management behavior: setRestartCommand(), setDiscardCommand(),
4084 setRestartHint(), setProperty(), requestPhase2(). See the respective
4085 function descriptions for further details.
4086*/
4087
4088/*! \enum QSessionManager::RestartHint
4089
4090 This enum type defines the circumstances under which this
4091 application wants to be restarted by the session manager. The
4092 current values are
4093
4094 \value RestartIfRunning if the application is still running when
4095 the session is shut down, it wants to be restarted at the start of
4096 the next session.
4097
4098 \value RestartAnyway the application wants to be started at the
4099 start of the next session, no matter what. (This is useful for
4100 utilities that run just after startup and then quit.)
4101
4102 \value RestartImmediately the application wants to be started
4103 immediately whenever it is not running.
4104
4105 \value RestartNever the application does not want to be restarted
4106 automatically.
4107
4108 The default hint is \c RestartIfRunning.
4109*/
4110
4111
4112/*!
4113 \fn QString QSessionManager::sessionId() const
4114
4115 Returns the identifier of the current session.
4116
4117 If the application has been restored from an earlier session, this
4118 identifier is the same as it was in that earlier session.
4119
4120 \sa sessionKey(), QApplication::sessionId()
4121 */
4122
4123/*!
4124 \fn QString QSessionManager::sessionKey() const
4125
4126 Returns the session key in the current session.
4127
4128 If the application has been restored from an earlier session, this
4129 key is the same as it was when the previous session ended.
4130
4131 The session key changes with every call of commitData() or
4132 saveState().
4133
4134 \sa sessionId(), QApplication::sessionKey()
4135 */
4136
4137// ### Note: This function is undocumented, since it is #ifdef'd.
4138
4139/*!
4140 \fn void* QSessionManager::handle() const
4141
4142 X11 only: returns a handle to the current \c SmcConnection.
4143*/
4144
4145
4146/*!
4147 \fn bool QSessionManager::allowsInteraction()
4148
4149 Asks the session manager for permission to interact with the
4150 user. Returns TRUE if interaction is permitted; otherwise
4151 returns FALSE.
4152
4153 The rationale behind this mechanism is to make it possible to
4154 synchronize user interaction during a shutdown. Advanced session
4155 managers may ask all applications simultaneously to commit their
4156 data, resulting in a much faster shutdown.
4157
4158 When the interaction is completed we strongly recommend releasing the
4159 user interaction semaphore with a call to release(). This way, other
4160 applications may get the chance to interact with the user while your
4161 application is still busy saving data. (The semaphore is implicitly
4162 released when the application exits.)
4163
4164 If the user decides to cancel the shutdown process during the
4165 interaction phase, you must tell the session manager that this has
4166 happened by calling cancel().
4167
4168 Here's an example of how an application's QApplication::commitData()
4169 might be implemented:
4170
4171\code
4172void MyApplication::commitData( QSessionManager& sm ) {
4173 if ( sm.allowsInteraction() ) {
4174 switch ( QMessageBox::warning(
4175 yourMainWindow,
4176 tr("Application Name"),
4177 tr("Save changes to document Foo?"),
4178 tr("&Yes"),
4179 tr("&No"),
4180 tr("Cancel"),
4181 0, 2) ) {
4182 case 0: // yes
4183 sm.release();
4184 // save document here; if saving fails, call sm.cancel()
4185 break;
4186 case 1: // continue without saving
4187 break;
4188 default: // cancel
4189 sm.cancel();
4190 break;
4191 }
4192 } else {
4193 // we did not get permission to interact, then
4194 // do something reasonable instead.
4195 }
4196}
4197\endcode
4198
4199 If an error occurred within the application while saving its data,
4200 you may want to try allowsErrorInteraction() instead.
4201
4202 \sa QApplication::commitData(), release(), cancel()
4203*/
4204
4205
4206/*!
4207 \fn bool QSessionManager::allowsErrorInteraction()
4208
4209 This is similar to allowsInteraction(), but also tells the session
4210 manager that an error occurred. Session managers may give error
4211 interaction request higher priority, which means that it is more likely
4212 that an error interaction is permitted. However, you are still not
4213 guaranteed that the session manager will allow interaction.
4214
4215 \sa allowsInteraction(), release(), cancel()
4216*/
4217
4218/*!
4219 \fn void QSessionManager::release()
4220
4221 Releases the session manager's interaction semaphore after an
4222 interaction phase.
4223
4224 \sa allowsInteraction(), allowsErrorInteraction()
4225*/
4226
4227/*!
4228 \fn void QSessionManager::cancel()
4229
4230 Tells the session manager to cancel the shutdown process. Applications
4231 should not call this function without first asking the user.
4232
4233 \sa allowsInteraction(), allowsErrorInteraction()
4234
4235*/
4236
4237/*!
4238 \fn void QSessionManager::setRestartHint( RestartHint hint )
4239
4240 Sets the application's restart hint to \a hint. On application
4241 startup the hint is set to \c RestartIfRunning.
4242
4243 Note that these flags are only hints, a session manager may or may
4244 not respect them.
4245
4246 We recommend setting the restart hint in QApplication::saveState()
4247 because most session managers perform a checkpoint shortly after an
4248 application's startup.
4249
4250 \sa restartHint()
4251*/
4252
4253/*!
4254 \fn QSessionManager::RestartHint QSessionManager::restartHint() const
4255
4256 Returns the application's current restart hint. The default is
4257 \c RestartIfRunning.
4258
4259 \sa setRestartHint()
4260*/
4261
4262/*!
4263 \fn void QSessionManager::setRestartCommand( const QStringList& command )
4264
4265 If the session manager is capable of restoring sessions it will
4266 execute \a command in order to restore the application. The command
4267 defaults to
4268
4269 \code
4270 appname -session id
4271 \endcode
4272
4273 The \c -session option is mandatory; otherwise QApplication cannot
4274 tell whether it has been restored or what the current session
4275 identifier is. See QApplication::isSessionRestored() and
4276 QApplication::sessionId() for details.
4277
4278 If your application is very simple, it may be possible to store the
4279 entire application state in additional command line options. This
4280 is usually a very bad idea because command lines are often limited
4281 to a few hundred bytes. Instead, use QSettings, or temporary files
4282 or a database for this purpose. By marking the data with the unique
4283 sessionId(), you will be able to restore the application in a future
4284 session.
4285
4286 \sa restartCommand(), setDiscardCommand(), setRestartHint()
4287*/
4288
4289/*!
4290 \fn QStringList QSessionManager::restartCommand() const
4291
4292 Returns the currently set restart command.
4293
4294 Note that if you want to iterate over the list, you should
4295 iterate over a copy, e.g.
4296 \code
4297 QStringList list = mySession.restartCommand();
4298 QStringList::Iterator it = list.begin();
4299 while( it != list.end() ) {
4300 myProcessing( *it );
4301 ++it;
4302 }
4303 \endcode
4304
4305 \sa setRestartCommand(), restartHint()
4306*/
4307
4308/*!
4309 \fn void QSessionManager::setDiscardCommand( const QStringList& )
4310
4311 \sa discardCommand(), setRestartCommand()
4312*/
4313
4314
4315/*!
4316 \fn QStringList QSessionManager::discardCommand() const
4317
4318 Returns the currently set discard command.
4319
4320 Note that if you want to iterate over the list, you should
4321 iterate over a copy, e.g.
4322 \code
4323 QStringList list = mySession.discardCommand();
4324 QStringList::Iterator it = list.begin();
4325 while( it != list.end() ) {
4326 myProcessing( *it );
4327 ++it;
4328 }
4329 \endcode
4330
4331 \sa setDiscardCommand(), restartCommand(), setRestartCommand()
4332*/
4333
4334/*!
4335 \overload void QSessionManager::setManagerProperty( const QString& name,
4336 const QString& value )
4337
4338 Low-level write access to the application's identification and state
4339 records are kept in the session manager.
4340
4341 The property called \a name has its value set to the string \a value.
4342*/
4343
4344/*!
4345 \fn void QSessionManager::setManagerProperty( const QString& name,
4346 const QStringList& value )
4347
4348 Low-level write access to the application's identification and state
4349 record are kept in the session manager.
4350
4351 The property called \a name has its value set to the string list \a value.
4352*/
4353
4354/*!
4355 \fn bool QSessionManager::isPhase2() const
4356
4357 Returns TRUE if the session manager is currently performing a second
4358 session management phase; otherwise returns FALSE.
4359
4360 \sa requestPhase2()
4361*/
4362
4363/*!
4364 \fn void QSessionManager::requestPhase2()
4365
4366 Requests a second session management phase for the application. The
4367 application may then return immediately from the
4368 QApplication::commitData() or QApplication::saveState() function,
4369 and they will be called again once most or all other applications have
4370 finished their session management.
4371
4372 The two phases are useful for applications such as the X11 window manager
4373 that need to store information about another application's windows
4374 and therefore have to wait until these applications have completed their
4375 respective session management tasks.
4376
4377 Note that if another application has requested a second phase it
4378 may get called before, simultaneously with, or after your
4379 application's second phase.
4380
4381 \sa isPhase2()
4382*/
4383
4384/*!
4385 \fn int QApplication::horizontalAlignment( int align )
4386
4387 Strips out vertical alignment flags and transforms an
4388 alignment \a align of AlignAuto into AlignLeft or
4389 AlignRight according to the language used. The other horizontal
4390 alignment flags are left untouched.
4391*/
4392
4393
4394/*****************************************************************************
4395 Stubbed session management support
4396 *****************************************************************************/
4397#ifndef QT_NO_SESSIONMANAGER
4398#if defined( QT_NO_SM_SUPPORT ) || defined( Q_WS_WIN ) || defined( Q_WS_MAC ) || defined( Q_WS_QWS ) || defined( Q_WS_PM )
4399
4400class QSessionManagerData
4401{
4402public:
4403 QStringList restartCommand;
4404 QStringList discardCommand;
4405 QString sessionId;
4406 QString sessionKey;
4407 QSessionManager::RestartHint restartHint;
4408};
4409
4410QSessionManager* qt_session_manager_self = 0;
4411QSessionManager::QSessionManager( QApplication * app, QString &id, QString &key )
4412 : QObject( app, "qt_sessionmanager" )
4413{
4414 qt_session_manager_self = this;
4415 d = new QSessionManagerData;
4416#if defined(Q_WS_WIN) && !defined(Q_OS_TEMP)
4417 wchar_t guidstr[40];
4418 GUID guid;
4419 CoCreateGuid( &guid );
4420 StringFromGUID2(guid, guidstr, 40);
4421 id = QString::fromUcs2((ushort*)guidstr);
4422 CoCreateGuid( &guid );
4423 StringFromGUID2(guid, guidstr, 40);
4424 key = QString::fromUcs2((ushort*)guidstr);
4425#endif
4426 d->sessionId = id;
4427 d->sessionKey = key;
4428 d->restartHint = RestartIfRunning;
4429}
4430
4431QSessionManager::~QSessionManager()
4432{
4433 delete d;
4434 qt_session_manager_self = 0;
4435}
4436
4437QString QSessionManager::sessionId() const
4438{
4439 return d->sessionId;
4440}
4441
4442QString QSessionManager::sessionKey() const
4443{
4444 return d->sessionKey;
4445}
4446
4447
4448#if defined(Q_WS_X11) || defined(Q_WS_MAC)
4449void* QSessionManager::handle() const
4450{
4451 return 0;
4452}
4453#endif
4454
4455#if !defined(Q_WS_WIN) && !defined(Q_WS_PM)
4456bool QSessionManager::allowsInteraction()
4457{
4458 return TRUE;
4459}
4460
4461bool QSessionManager::allowsErrorInteraction()
4462{
4463 return TRUE;
4464}
4465void QSessionManager::release()
4466{
4467}
4468
4469void QSessionManager::cancel()
4470{
4471}
4472#endif
4473
4474
4475void QSessionManager::setRestartHint( QSessionManager::RestartHint hint)
4476{
4477 d->restartHint = hint;
4478}
4479
4480QSessionManager::RestartHint QSessionManager::restartHint() const
4481{
4482 return d->restartHint;
4483}
4484
4485void QSessionManager::setRestartCommand( const QStringList& command)
4486{
4487 d->restartCommand = command;
4488}
4489
4490QStringList QSessionManager::restartCommand() const
4491{
4492 return d->restartCommand;
4493}
4494
4495void QSessionManager::setDiscardCommand( const QStringList& command)
4496{
4497 d->discardCommand = command;
4498}
4499
4500QStringList QSessionManager::discardCommand() const
4501{
4502 return d->discardCommand;
4503}
4504
4505void QSessionManager::setManagerProperty( const QString&, const QString&)
4506{
4507}
4508
4509void QSessionManager::setManagerProperty( const QString&, const QStringList& )
4510{
4511}
4512
4513bool QSessionManager::isPhase2() const
4514{
4515 return FALSE;
4516}
4517
4518void QSessionManager::requestPhase2()
4519{
4520}
4521
4522#endif // QT_NO_SM_SUPPORT
4523#endif //QT_NO_SESSIONMANAGER
Note: See TracBrowser for help on using the repository browser.