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

Last change on this file since 176 was 174, checked in by dmik, 18 years ago

Styles: Implemented the first version of the Warp4 style (contributed by Cornelis Bockemuehl).

  • Property svn:keywords set to Id
File size: 127.1 KB
Line 
1/****************************************************************************
2** $Id: qapplication.cpp 174 2007-11-06 22:27:57Z 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 if ( app_style != 0 ) {
1067 app_style->unPolish( this );
1068 delete app_style;
1069 app_style = 0;
1070 }
1071#endif
1072#ifndef QT_NO_CURSOR
1073 delete app_cursor;
1074 app_cursor = 0;
1075#endif
1076#ifndef QT_NO_TRANSLATION
1077 delete translators;
1078#endif
1079
1080#ifndef QT_NO_DRAGANDDROP
1081 extern QDragManager *qt_dnd_manager;
1082 delete qt_dnd_manager;
1083#endif
1084
1085 qt_cleanup();
1086
1087#ifndef QT_NO_COMPONENT
1088 delete app_libpaths;
1089 app_libpaths = 0;
1090#endif
1091
1092#ifdef QT_THREAD_SUPPORT
1093 delete qt_mutex;
1094 qt_mutex = 0;
1095 delete postevent_mutex;
1096 postevent_mutex = 0;
1097#endif // QT_THREAD_SUPPORT
1098
1099 if( qApp == this ) {
1100 if ( postedEvents )
1101 removePostedEvents( this );
1102 qApp = 0;
1103 }
1104 is_app_running = FALSE;
1105
1106 if ( widgetCount ) {
1107 qDebug( "Widgets left: %i Max widgets: %i \n", QWidget::instanceCounter, QWidget::maxInstances );
1108 }
1109#ifndef QT_NO_SESSIONMANAGER
1110 delete session_manager;
1111 session_manager = 0;
1112 delete session_key;
1113 session_key = 0;
1114#endif //QT_NO_SESSIONMANAGER
1115
1116 qt_explicit_app_style = FALSE;
1117 qt_app_has_font = FALSE;
1118 app_tracking = 0;
1119 obey_desktop_settings = TRUE;
1120 cursor_flash_time = 1000;
1121 mouse_double_click_time = 400;
1122#ifndef QT_NO_WHEELEVENT
1123 wheel_scroll_lines = 3;
1124#endif
1125 drag_time = 500;
1126 drag_distance = 4;
1127 reverse_layout = FALSE;
1128 app_strut = QSize( 0, 0 );
1129 animate_ui = TRUE;
1130 animate_menu = FALSE;
1131 fade_menu = FALSE;
1132 animate_combo = FALSE;
1133 animate_tooltip = FALSE;
1134 fade_tooltip = FALSE;
1135 widgetCount = FALSE;
1136}
1137
1138
1139/*!
1140 \fn int QApplication::argc() const
1141
1142 Returns the number of command line arguments.
1143
1144 The documentation for argv() describes how to process command line
1145 arguments.
1146
1147 \sa argv(), QApplication::QApplication()
1148*/
1149
1150/*!
1151 \fn char **QApplication::argv() const
1152
1153 Returns the command line argument vector.
1154
1155 \c argv()[0] is the program name, \c argv()[1] is the first
1156 argument and \c argv()[argc()-1] is the last argument.
1157
1158 A QApplication object is constructed by passing \e argc and \e
1159 argv from the \c main() function. Some of the arguments may be
1160 recognized as Qt options and removed from the argument vector. For
1161 example, the X11 version of Qt knows about \c -display, \c -font
1162 and a few more options.
1163
1164 Example:
1165 \code
1166 // showargs.cpp - displays program arguments in a list box
1167
1168 #include <qapplication.h>
1169 #include <qlistbox.h>
1170
1171 int main( int argc, char **argv )
1172 {
1173 QApplication a( argc, argv );
1174 QListBox b;
1175 a.setMainWidget( &b );
1176 for ( int i = 0; i < a.argc(); i++ ) // a.argc() == argc
1177 b.insertItem( a.argv()[i] ); // a.argv()[i] == argv[i]
1178 b.show();
1179 return a.exec();
1180 }
1181 \endcode
1182
1183 If you run \c{showargs -display unix:0 -font 9x15bold hello world}
1184 under X11, the list box contains the three strings "showargs",
1185 "hello" and "world".
1186
1187 Qt provides a global pointer, \c qApp, that points to the
1188 QApplication object, and through which you can access argc() and
1189 argv() in functions other than main().
1190
1191 \sa argc(), QApplication::QApplication()
1192*/
1193
1194/*!
1195 \fn void QApplication::setArgs( int argc, char **argv )
1196 \internal
1197*/
1198
1199
1200#ifndef QT_NO_STYLE
1201
1202static QString *qt_style_override = 0;
1203
1204/*!
1205 Returns the application's style object.
1206
1207 \sa setStyle(), QStyle
1208*/
1209QStyle& QApplication::style()
1210{
1211#ifndef QT_NO_STYLE
1212 if ( app_style )
1213 return *app_style;
1214 if ( !qt_is_gui_used )
1215 qFatal( "No style available in non-gui applications!" );
1216
1217#if defined(Q_WS_X11)
1218 if(!qt_style_override)
1219 x11_initialize_style(); // run-time search for default style
1220#endif
1221 if ( !app_style ) {
1222 // Compile-time search for default style
1223 //
1224 QString style;
1225 if ( qt_style_override ) {
1226 style = *qt_style_override;
1227 delete qt_style_override;
1228 qt_style_override = 0;
1229 } else {
1230# if defined(Q_WS_WIN) && defined(Q_OS_TEMP)
1231 style = "PocketPC";
1232#elif defined(Q_WS_WIN)
1233 if ( qWinVersion() == WV_XP )
1234 style = "WindowsXP";
1235 else
1236 style = "Windows"; // default styles for Windows
1237// this is temporarily disabled until most bugs are fixed,
1238// see http://svn.netlabs.org/qr3/ticket/9 for details
1239//#elif defined(Q_WS_PM)
1240// style = "Warp4"; // default style for OS/2
1241//#endif
1242#elif defined(Q_WS_X11) && defined(Q_OS_SOLARIS)
1243 style = "CDE"; // default style for X11 on Solaris
1244#elif defined(Q_WS_X11) && defined(Q_OS_IRIX)
1245 style = "SGI"; // default style for X11 on IRIX
1246#elif defined(Q_WS_X11)
1247 style = "Motif"; // default style for X11
1248#elif defined(Q_WS_MAC)
1249 style = "Macintosh"; // default style for all Mac's
1250#elif defined(Q_WS_QWS)
1251 style = "Compact"; // default style for small devices
1252#endif
1253 }
1254 app_style = QStyleFactory::create( style );
1255 if ( !app_style && // platform default style not available, try alternatives
1256 !(app_style = QStyleFactory::create( "Windows" ) ) &&
1257// !(app_style = QStyleFactory::create( "Warp4" ) ) &&
1258 !(app_style = QStyleFactory::create( "Platinum" ) ) &&
1259 !(app_style = QStyleFactory::create( "MotifPlus" ) ) &&
1260 !(app_style = QStyleFactory::create( "Motif" ) ) &&
1261 !(app_style = QStyleFactory::create( "CDE" ) ) &&
1262 !(app_style = QStyleFactory::create( "Aqua" ) ) &&
1263 !(app_style = QStyleFactory::create( "SGI" ) ) &&
1264 !(app_style = QStyleFactory::create( "Compact" ) )
1265#ifndef QT_NO_STRINGLIST
1266 && !(app_style = QStyleFactory::create( QStyleFactory::keys()[0] ) )
1267#endif
1268 )
1269 qFatal( "No %s style available!", style.latin1() );
1270 }
1271
1272 QPalette app_pal_copy ( *app_pal );
1273 app_style->polish( *app_pal );
1274
1275 if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) {
1276 QEvent e( QEvent::ApplicationPaletteChange );
1277 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1278 register QWidget *w;
1279 while ( (w=it.current()) ) { // for all widgets...
1280 ++it;
1281 sendEvent( w, &e );
1282 }
1283 }
1284
1285 app_style->polish( qApp );
1286#endif
1287 return *app_style;
1288}
1289
1290/*!
1291 Sets the application's GUI style to \a style. Ownership of the style
1292 object is transferred to QApplication, so QApplication will delete
1293 the style object on application exit or when a new style is set.
1294
1295 Example usage:
1296 \code
1297 QApplication::setStyle( new QWindowStyle );
1298 \endcode
1299
1300 When switching application styles, the color palette is set back to
1301 the initial colors or the system defaults. This is necessary since
1302 certain styles have to adapt the color palette to be fully
1303 style-guide compliant.
1304
1305 \sa style(), QStyle, setPalette(), desktopSettingsAware()
1306*/
1307void QApplication::setStyle( QStyle *style )
1308{
1309 QStyle* old = app_style;
1310 app_style = style;
1311#ifdef Q_WS_X11
1312 qt_explicit_app_style = TRUE;
1313#endif // Q_WS_X11
1314
1315 if ( startingUp() ) {
1316 delete old;
1317 return;
1318 }
1319
1320 // clean up the old style
1321 if (old) {
1322 if ( is_app_running && !is_app_closing ) {
1323 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1324 register QWidget *w;
1325 while ( (w=it.current()) ) { // for all widgets...
1326 ++it;
1327 if ( !w->testWFlags(WType_Desktop) && // except desktop
1328 w->testWState(WState_Polished) ) { // has been polished
1329 old->unPolish(w);
1330 }
1331 }
1332 }
1333 old->unPolish( qApp );
1334 }
1335
1336 // take care of possible palette requirements of certain gui
1337 // styles. Do it before polishing the application since the style
1338 // might call QApplication::setStyle() itself
1339 if ( !qt_std_pal )
1340 qt_create_std_palette();
1341 QPalette tmpPal = *qt_std_pal;
1342 setPalette( tmpPal, TRUE );
1343
1344 // initialize the application with the new style
1345 app_style->polish( qApp );
1346
1347 // re-polish existing widgets if necessary
1348 if (old) {
1349 if ( is_app_running && !is_app_closing ) {
1350 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1351 register QWidget *w;
1352 while ( (w=it.current()) ) { // for all widgets...
1353 ++it;
1354 if ( !w->testWFlags(WType_Desktop) ) { // except desktop
1355 if ( w->testWState(WState_Polished) )
1356 app_style->polish(w); // repolish
1357 w->styleChange( *old );
1358 if ( w->isVisible() ){
1359 w->update();
1360 }
1361 }
1362 }
1363 }
1364 delete old;
1365 }
1366}
1367
1368/*!
1369 \overload
1370
1371 Requests a QStyle object for \a style from the QStyleFactory.
1372
1373 The string must be one of the QStyleFactory::keys(), typically one
1374 of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and
1375 "compact". Depending on the platform, "windowsxp", "warp4", "aqua" or
1376 "macintosh" may be available.
1377
1378 A later call to the QApplication constructor will override the
1379 requested style when a "-style" option is passed in as a commandline
1380 parameter.
1381
1382 Returns 0 if an unknown \a style is passed, otherwise the QStyle object
1383 returned is set as the application's GUI style.
1384*/
1385QStyle* QApplication::setStyle( const QString& style )
1386{
1387#ifdef Q_WS_X11
1388 qt_explicit_app_style = TRUE;
1389#endif // Q_WS_X11
1390
1391 if ( startingUp() ) {
1392 if(qt_style_override)
1393 *qt_style_override = style;
1394 else
1395 qt_style_override = new QString(style);
1396 return 0;
1397 }
1398 QStyle *s = QStyleFactory::create( style );
1399 if ( !s )
1400 return 0;
1401
1402 setStyle( s );
1403 return s;
1404}
1405
1406#endif
1407
1408
1409#if 1 /* OBSOLETE */
1410
1411QApplication::ColorMode QApplication::colorMode()
1412{
1413 return (QApplication::ColorMode)app_cspec;
1414}
1415
1416void QApplication::setColorMode( QApplication::ColorMode mode )
1417{
1418 app_cspec = mode;
1419}
1420#endif
1421
1422
1423/*!
1424 Returns the color specification.
1425 \sa QApplication::setColorSpec()
1426 */
1427
1428int QApplication::colorSpec()
1429{
1430 return app_cspec;
1431}
1432
1433/*!
1434 Sets the color specification for the application to \a spec.
1435
1436 The color specification controls how the application allocates colors
1437 when run on a display with a limited amount of colors, e.g. 8 bit / 256
1438 color displays.
1439
1440 The color specification must be set before you create the QApplication
1441 object.
1442
1443 The options are:
1444 \list
1445 \i QApplication::NormalColor.
1446 This is the default color allocation strategy. Use this option if
1447 your application uses buttons, menus, texts and pixmaps with few
1448 colors. With this option, the application uses system global
1449 colors. This works fine for most applications under X11, but on
1450 Windows machines it may cause dithering of non-standard colors.
1451 \i QApplication::CustomColor.
1452 Use this option if your application needs a small number of custom
1453 colors. On X11, this option is the same as NormalColor. On Windows, Qt
1454 creates a Windows palette, and allocates colors to it on demand.
1455 \i QApplication::ManyColor.
1456 Use this option if your application is very color hungry
1457 (e.g. it requires thousands of colors).
1458 Under X11 the effect is:
1459 \list
1460 \i For 256-color displays which have at best a 256 color true color
1461 visual, the default visual is used, and colors are allocated
1462 from a color cube. The color cube is the 6x6x6 (216 color) "Web
1463 palette"<sup>*</sup>, but the number of colors can be changed
1464 by the \e -ncols option. The user can force the application to
1465 use the true color visual with the \link
1466 QApplication::QApplication() -visual \endlink option.
1467 \i For 256-color displays which have a true color visual with more
1468 than 256 colors, use that visual. Silicon Graphics X servers
1469 have this feature, for example. They provide an 8 bit visual
1470 by default but can deliver true color when asked.
1471 \endlist
1472 On Windows, Qt creates a Windows palette, and fills it with a color cube.
1473 \endlist
1474
1475 Be aware that the CustomColor and ManyColor choices may lead to colormap
1476 flashing: The foreground application gets (most) of the available
1477 colors, while the background windows will look less attractive.
1478
1479 Example:
1480 \code
1481 int main( int argc, char **argv )
1482 {
1483 QApplication::setColorSpec( QApplication::ManyColor );
1484 QApplication a( argc, argv );
1485 ...
1486 }
1487 \endcode
1488
1489 QColor provides more functionality for controlling color allocation and
1490 freeing up certain colors. See QColor::enterAllocContext() for more
1491 information.
1492
1493 To check what mode you end up with, call QColor::numBitPlanes() once
1494 the QApplication object exists. A value greater than 8 (typically
1495 16, 24 or 32) means true color.
1496
1497 <sup>*</sup> The color cube used by Qt has 216 colors whose red,
1498 green, and blue components always have one of the following values:
1499 0x00, 0x33, 0x66, 0x99, 0xCC, or 0xFF.
1500
1501 \sa colorSpec(), QColor::numBitPlanes(), QColor::enterAllocContext() */
1502
1503void QApplication::setColorSpec( int spec )
1504{
1505#if defined(QT_CHECK_STATE)
1506 if ( qApp ) {
1507 qWarning( "QApplication::setColorSpec: This function must be "
1508 "called before the QApplication object is created" );
1509 }
1510#endif
1511 app_cspec = spec;
1512}
1513
1514/*!
1515 \fn QSize QApplication::globalStrut()
1516
1517 Returns the application's global strut.
1518
1519 The strut is a size object whose dimensions are the minimum that any
1520 GUI element that the user can interact with should have. For example
1521 no button should be resized to be smaller than the global strut size.
1522
1523 \sa setGlobalStrut()
1524*/
1525
1526/*!
1527 Sets the application's global strut to \a strut.
1528
1529 The strut is a size object whose dimensions are the minimum that any
1530 GUI element that the user can interact with should have. For example
1531 no button should be resized to be smaller than the global strut size.
1532
1533 The strut size should be considered when reimplementing GUI controls
1534 that may be used on touch-screens or similar IO-devices.
1535
1536 Example:
1537 \code
1538 QSize& WidgetClass::sizeHint() const
1539 {
1540 return QSize( 80, 25 ).expandedTo( QApplication::globalStrut() );
1541 }
1542 \endcode
1543
1544 \sa globalStrut()
1545*/
1546
1547void QApplication::setGlobalStrut( const QSize& strut )
1548{
1549 app_strut = strut;
1550}
1551
1552#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1553extern const char *qAppFileName();
1554#endif
1555
1556#ifndef QT_NO_DIR
1557#if !defined(Q_WS_WIN) && !(defined Q_WS_PM)
1558static QString resolveSymlinks( const QString& path, int depth = 0 )
1559{
1560 bool foundLink = FALSE;
1561 QString linkTarget;
1562 QString part = path;
1563 int slashPos = path.length();
1564
1565 // too deep; we give up
1566 if ( depth == 128 )
1567 return QString::null;
1568
1569 do {
1570 part = part.left( slashPos );
1571 QFileInfo fileInfo( part );
1572 if ( fileInfo.isSymLink() ) {
1573 foundLink = TRUE;
1574 linkTarget = fileInfo.readLink();
1575 break;
1576 }
1577 } while ( (slashPos = part.findRev('/')) != -1 );
1578
1579 if ( foundLink ) {
1580 QString path2;
1581 if ( linkTarget[0] == '/' ) {
1582 path2 = linkTarget;
1583 if ( slashPos < (int) path.length() )
1584 path2 += "/" + path.right( path.length() - slashPos - 1 );
1585 } else {
1586 QString relPath;
1587 relPath = part.left( part.findRev('/') + 1 ) + linkTarget;
1588 if ( slashPos < (int) path.length() ) {
1589 if ( !linkTarget.endsWith( "/" ) )
1590 relPath += "/";
1591 relPath += path.right( path.length() - slashPos - 1 );
1592 }
1593 path2 = QDir::current().absFilePath( relPath );
1594 }
1595 path2 = QDir::cleanDirPath( path2 );
1596 return resolveSymlinks( path2, depth + 1 );
1597 } else {
1598 return path;
1599 }
1600}
1601#endif // !Q_WS_WIN && !Q_WS_PM
1602
1603/*!
1604 Returns the directory that contains the application executable.
1605
1606 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1607 directory, and you run the \c{demo} example, this function will
1608 return "C:/Trolltech/Qt/examples/demo".
1609
1610 \warning On Unix and Mac OS X, this function assumes that argv[0]
1611 contains the file name of the executable (which it normally
1612 does). It also assumes that the current directory hasn't been
1613 changed by the application.
1614
1615 \sa applicationFilePath()
1616*/
1617QString QApplication::applicationDirPath()
1618{
1619 return QFileInfo( applicationFilePath() ).dirPath();
1620}
1621
1622/*!
1623 Returns the file path of the application executable.
1624
1625 For example, if you have installed Qt in the \c{C:\Trolltech\Qt}
1626 directory, and you run the \c{demo} example, this function will
1627 return "C:/Trolltech/Qt/examples/demo/demo.exe".
1628
1629 \warning On Unix and Mac OS X, this function assumes that argv[0]
1630 contains the file name of the executable (which it normally
1631 does). It also assumes that the current directory hasn't been
1632 changed by the application.
1633
1634 \sa applicationDirPath()
1635*/
1636QString QApplication::applicationFilePath()
1637{
1638#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1639 return QDir::cleanDirPath( QFile::decodeName( qAppFileName() ) );
1640#else
1641 QString argv0 = QFile::decodeName( argv()[0] );
1642 QString absPath;
1643
1644 if ( argv0[0] == '/' ) {
1645 /*
1646 If argv0 starts with a slash, it is already an absolute
1647 file path.
1648 */
1649 absPath = argv0;
1650 } else if ( argv0.find('/') != -1 ) {
1651 /*
1652 If argv0 contains one or more slashes, it is a file path
1653 relative to the current directory.
1654 */
1655 absPath = QDir::current().absFilePath( argv0 );
1656 } else {
1657 /*
1658 Otherwise, the file path has to be determined using the
1659 PATH environment variable.
1660 */
1661 char *pEnv = getenv( "PATH" );
1662 QStringList paths( QStringList::split(QChar(':'), pEnv) );
1663 QStringList::const_iterator p = paths.begin();
1664 while ( p != paths.end() ) {
1665 QString candidate = QDir::current().absFilePath( *p + "/" + argv0 );
1666 if ( QFile::exists(candidate) ) {
1667 absPath = candidate;
1668 break;
1669 }
1670 ++p;
1671 }
1672 }
1673
1674 absPath = QDir::cleanDirPath( absPath );
1675 if ( QFile::exists(absPath) ) {
1676 return resolveSymlinks( absPath );
1677 } else {
1678 return QString::null;
1679 }
1680#endif
1681}
1682#endif // QT_NO_DIR
1683
1684#ifndef QT_NO_COMPONENT
1685
1686/*!
1687 Returns a list of paths that the application will search when
1688 dynamically loading libraries.
1689 The installation directory for plugins is the only entry if no
1690 paths have been set. The default installation directory for plugins
1691 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
1692 installed. The directory of the application executable (NOT the
1693 working directory) is also added to the plugin paths.
1694
1695 If you want to iterate over the list, you should iterate over a
1696 copy, e.g.
1697 \code
1698 QStringList list = app.libraryPaths();
1699 QStringList::Iterator it = list.begin();
1700 while( it != list.end() ) {
1701 myProcessing( *it );
1702 ++it;
1703 }
1704 \endcode
1705
1706 See the \link plugins-howto.html plugins documentation\endlink for a
1707 description of how the library paths are used.
1708
1709 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
1710*/
1711QStringList QApplication::libraryPaths()
1712{
1713 if ( !app_libpaths ) {
1714 app_libpaths = new QStringList;
1715 QString installPathPlugins = QString::fromLocal8Bit(qInstallPathPlugins());
1716 if ( QFile::exists(installPathPlugins) ) {
1717#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1718 installPathPlugins.replace('\\', '/');
1719#endif
1720 app_libpaths->append(installPathPlugins);
1721 }
1722
1723 QString app_location;
1724 if (qApp)
1725 app_location = qApp->applicationFilePath();
1726#if defined(Q_WS_WIN) || defined(Q_WS_PM)
1727 else {
1728 app_location = QString(qAppFileName());
1729 app_location.replace('\\', '/');
1730 }
1731#endif
1732 if (!app_location.isEmpty()) {
1733 app_location.truncate( app_location.findRev( '/' ) );
1734 if ( app_location != qInstallPathPlugins() && QFile::exists( app_location ) )
1735 app_libpaths->append( app_location );
1736 }
1737 }
1738 return *app_libpaths;
1739}
1740
1741
1742/*!
1743 Sets the list of directories to search when loading libraries to \a paths.
1744 All existing paths will be deleted and the path list will consist of the
1745 paths given in \a paths.
1746
1747 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
1748 */
1749void QApplication::setLibraryPaths( const QStringList &paths )
1750{
1751 delete app_libpaths;
1752 app_libpaths = new QStringList( paths );
1753}
1754
1755/*!
1756 Append \a path to the end of the library path list. If \a path is
1757 empty or already in the path list, the path list is not changed.
1758
1759 The default path list consists of a single entry, the installation
1760 directory for plugins. The default installation directory for plugins
1761 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
1762 installed.
1763
1764 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
1765 */
1766void QApplication::addLibraryPath( const QString &path )
1767{
1768 if ( path.isEmpty() )
1769 return;
1770
1771 // make sure that library paths is initialized
1772 libraryPaths();
1773
1774 if ( !app_libpaths->contains( path ) )
1775 app_libpaths->prepend( path );
1776}
1777
1778/*!
1779 Removes \a path from the library path list. If \a path is empty or not
1780 in the path list, the list is not changed.
1781
1782 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
1783*/
1784void QApplication::removeLibraryPath( const QString &path )
1785{
1786 if ( path.isEmpty() )
1787 return;
1788
1789 // make sure that library paths is initialized
1790 libraryPaths();
1791
1792 if ( app_libpaths->contains( path ) )
1793 app_libpaths->remove( path );
1794}
1795#endif //QT_NO_COMPONENT
1796
1797/*!
1798 Returns the application palette.
1799
1800 If a widget is passed in \a w, the default palette for the
1801 widget's class is returned. This may or may not be the application
1802 palette. In most cases there isn't a special palette for certain
1803 types of widgets, but one notable exception is the popup menu under
1804 Windows, if the user has defined a special background color for
1805 menus in the display settings.
1806
1807 \sa setPalette(), QWidget::palette()
1808*/
1809#ifndef QT_NO_PALETTE
1810QPalette QApplication::palette(const QWidget* w)
1811{
1812#if defined(QT_CHECK_STATE)
1813 if ( !qApp )
1814 qWarning( "QApplication::palette: This function can only be "
1815 "called after the QApplication object has been created" );
1816#endif
1817 if ( !app_pal ) {
1818 if ( !qt_std_pal )
1819 qt_create_std_palette();
1820 app_pal = new QPalette( *qt_std_pal );
1821 qt_fix_tooltips();
1822 }
1823
1824 if ( w && app_palettes ) {
1825 QPalette* wp = app_palettes->find( w->className() );
1826 if ( wp )
1827 return *wp;
1828 QAsciiDictIterator<QPalette> it( *app_palettes );
1829 const char* name;
1830 while ( (name=it.currentKey()) != 0 ) {
1831 if ( w->inherits( name ) )
1832 return *it.current();
1833 ++it;
1834 }
1835 }
1836 return *app_pal;
1837}
1838
1839/*!
1840 Changes the default application palette to \a palette. If \a
1841 informWidgets is TRUE, then existing widgets are informed about the
1842 change and may adjust themselves to the new application
1843 setting. If \a informWidgets is FALSE, the change only affects newly
1844 created widgets.
1845
1846 If \a className is passed, the change applies only to widgets that
1847 inherit \a className (as reported by QObject::inherits()). If
1848 \a className is left 0, the change affects all widgets, thus overriding
1849 any previously set class specific palettes.
1850
1851 The palette may be changed according to the current GUI style in
1852 QStyle::polish().
1853
1854 \sa QWidget::setPalette(), palette(), QStyle::polish()
1855*/
1856
1857void QApplication::setPalette( const QPalette &palette, bool informWidgets,
1858 const char* className )
1859{
1860 QPalette pal = palette;
1861 QPalette *oldpal = 0;
1862#ifndef QT_NO_STYLE
1863 if ( !startingUp() ) // on startup this has been done already
1864 qApp->style().polish( pal ); // NB: non-const reference
1865#endif
1866 bool all = FALSE;
1867 if ( !className ) {
1868 if ( !app_pal ) {
1869 app_pal = new QPalette( pal );
1870 Q_CHECK_PTR( app_pal );
1871 } else {
1872 *app_pal = pal;
1873 }
1874 all = app_palettes != 0;
1875 delete app_palettes;
1876 app_palettes = 0;
1877 qt_fix_tooltips();
1878 } else {
1879 if ( !app_palettes ) {
1880 app_palettes = new QAsciiDict<QPalette>;
1881 Q_CHECK_PTR( app_palettes );
1882 app_palettes->setAutoDelete( TRUE );
1883 }
1884 oldpal = app_palettes->find( className );
1885 app_palettes->insert( className, new QPalette( pal ) );
1886 }
1887 if ( informWidgets && is_app_running && !is_app_closing ) {
1888 if ( !oldpal || ( *oldpal != pal ) ) {
1889 QEvent e( QEvent::ApplicationPaletteChange );
1890 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1891 register QWidget *w;
1892 while ( (w=it.current()) ) { // for all widgets...
1893 ++it;
1894 if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
1895 sendEvent( w, &e );
1896 }
1897 }
1898 }
1899}
1900
1901#endif // QT_NO_PALETTE
1902
1903/*!
1904 Returns the default font for the widget \a w, or the default
1905 application font if \a w is 0.
1906
1907 \sa setFont(), fontMetrics(), QWidget::font()
1908*/
1909
1910QFont QApplication::font( const QWidget *w )
1911{
1912 if ( w && app_fonts ) {
1913 QFont* wf = app_fonts->find( w->className() );
1914 if ( wf )
1915 return *wf;
1916 QAsciiDictIterator<QFont> it( *app_fonts );
1917 const char* name;
1918 while ( (name=it.currentKey()) != 0 ) {
1919 if ( w->inherits( name ) )
1920 return *it.current();
1921 ++it;
1922 }
1923 }
1924 if ( !app_font ) {
1925 app_font = new QFont( "Helvetica" );
1926 Q_CHECK_PTR( app_font );
1927 }
1928 return *app_font;
1929}
1930
1931/*! Changes the default application font to \a font. If \a
1932 informWidgets is TRUE, then existing widgets are informed about the
1933 change and may adjust themselves to the new application
1934 setting. If \a informWidgets is FALSE, the change only affects newly
1935 created widgets. If \a className is passed, the change applies only
1936 to classes that inherit \a className (as reported by
1937 QObject::inherits()).
1938
1939 On application start-up, the default font depends on the window
1940 system. It can vary depending on both the window system version and
1941 the locale. This function lets you override the default font; but
1942 overriding may be a bad idea because, for example, some locales need
1943 extra-large fonts to support their special characters.
1944
1945 \sa font(), fontMetrics(), QWidget::setFont()
1946*/
1947
1948void QApplication::setFont( const QFont &font, bool informWidgets,
1949 const char* className )
1950{
1951 bool all = FALSE;
1952 if ( !className ) {
1953 qt_app_has_font = TRUE;
1954 if ( !app_font ) {
1955 app_font = new QFont( font );
1956 Q_CHECK_PTR( app_font );
1957 } else {
1958 *app_font = font;
1959 }
1960
1961 // make sure the application font is complete
1962 app_font->detach();
1963 app_font->d->mask = QFontPrivate::Complete;
1964
1965 all = app_fonts != 0;
1966 delete app_fonts;
1967 app_fonts = 0;
1968 } else {
1969 if (!app_fonts){
1970 app_fonts = new QAsciiDict<QFont>;
1971 Q_CHECK_PTR( app_fonts );
1972 app_fonts->setAutoDelete( TRUE );
1973 }
1974 QFont* fnt = new QFont(font);
1975 Q_CHECK_PTR( fnt );
1976 app_fonts->insert(className, fnt);
1977 }
1978 if ( informWidgets && is_app_running && !is_app_closing ) {
1979 QEvent e( QEvent::ApplicationFontChange );
1980 QWidgetIntDictIt it( *((QWidgetIntDict*)QWidget::mapper) );
1981 register QWidget *w;
1982 while ( (w=it.current()) ) { // for all widgets...
1983 ++it;
1984 if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
1985 sendEvent( w, &e );
1986 }
1987 }
1988}
1989
1990
1991/*!
1992 Initialization of the appearance of the widget \a w \e before it is first
1993 shown.
1994
1995 Usually widgets call this automatically when they are polished. It
1996 may be used to do some style-based central customization of widgets.
1997
1998 Note that you are not limited to the public functions of QWidget.
1999 Instead, based on meta information like QObject::className() you are
2000 able to customize any kind of widget.
2001
2002 \sa QStyle::polish(), QWidget::polish(), setPalette(), setFont()
2003*/
2004
2005void QApplication::polish( QWidget *w )
2006{
2007#ifndef QT_NO_STYLE
2008 w->style().polish( w );
2009#endif
2010}
2011
2012
2013/*!
2014 Returns a list of the top level widgets in the application.
2015
2016 The list is created using \c new and must be deleted by the caller.
2017
2018 The list is empty (QPtrList::isEmpty()) if there are no top level
2019 widgets.
2020
2021 Note that some of the top level widgets may be hidden, for example
2022 the tooltip if no tooltip is currently shown.
2023
2024 Example:
2025 \code
2026 // Show all hidden top level widgets.
2027 QWidgetList *list = QApplication::topLevelWidgets();
2028 QWidgetListIt it( *list ); // iterate over the widgets
2029 QWidget * w;
2030 while ( (w=it.current()) != 0 ) { // for each top level widget...
2031 ++it;
2032 if ( !w->isVisible() )
2033 w->show();
2034 }
2035 delete list; // delete the list, not the widgets
2036 \endcode
2037
2038 \warning Delete the list as soon you have finished using it.
2039 The widgets in the list may be deleted by someone else at any time.
2040
2041 \sa allWidgets(), QWidget::isTopLevel(), QWidget::isVisible(),
2042 QPtrList::isEmpty()
2043*/
2044
2045QWidgetList *QApplication::topLevelWidgets()
2046{
2047 return QWidget::tlwList();
2048}
2049
2050/*!
2051 Returns a list of all the widgets in the application.
2052
2053 The list is created using \c new and must be deleted by the caller.
2054
2055 The list is empty (QPtrList::isEmpty()) if there are no widgets.
2056
2057 Note that some of the widgets may be hidden.
2058
2059 Example that updates all widgets:
2060 \code
2061 QWidgetList *list = QApplication::allWidgets();
2062 QWidgetListIt it( *list ); // iterate over the widgets
2063 QWidget * w;
2064 while ( (w=it.current()) != 0 ) { // for each widget...
2065 ++it;
2066 w->update();
2067 }
2068 delete list; // delete the list, not the widgets
2069 \endcode
2070
2071 The QWidgetList class is defined in the \c qwidgetlist.h header
2072 file.
2073
2074 \warning Delete the list as soon as you have finished using it.
2075 The widgets in the list may be deleted by someone else at any time.
2076
2077 \sa topLevelWidgets(), QWidget::isVisible(), QPtrList::isEmpty(),
2078*/
2079
2080QWidgetList *QApplication::allWidgets()
2081{
2082 return QWidget::wList();
2083}
2084
2085/*!
2086 \fn QWidget *QApplication::focusWidget() const
2087
2088 Returns the application widget that has the keyboard input focus, or
2089 0 if no widget in this application has the focus.
2090
2091 \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow()
2092*/
2093
2094/*!
2095 \fn QWidget *QApplication::activeWindow() const
2096
2097 Returns the application top-level window that has the keyboard input
2098 focus, or 0 if no application window has the focus. Note that
2099 there might be an activeWindow() even if there is no focusWidget(),
2100 for example if no widget in that window accepts key events.
2101
2102 \sa QWidget::setFocus(), QWidget::hasFocus(), focusWidget()
2103*/
2104
2105/*!
2106 Returns display (screen) font metrics for the application font.
2107
2108 \sa font(), setFont(), QWidget::fontMetrics(), QPainter::fontMetrics()
2109*/
2110
2111QFontMetrics QApplication::fontMetrics()
2112{
2113 return desktop()->fontMetrics();
2114}
2115
2116
2117
2118/*!
2119 Tells the application to exit with return code 0 (success).
2120 Equivalent to calling QApplication::exit( 0 ).
2121
2122 It's common to connect the lastWindowClosed() signal to quit(), and
2123 you also often connect e.g. QButton::clicked() or signals in
2124 QAction, QPopupMenu or QMenuBar to it.
2125
2126 Example:
2127 \code
2128 QPushButton *quitButton = new QPushButton( "Quit" );
2129 connect( quitButton, SIGNAL(clicked()), qApp, SLOT(quit()) );
2130 \endcode
2131
2132 \sa exit() aboutToQuit() lastWindowClosed() QAction
2133*/
2134
2135void QApplication::quit()
2136{
2137 QApplication::exit( 0 );
2138}
2139
2140
2141/*!
2142 Closes all top-level windows.
2143
2144 This function is particularly useful for applications with many
2145 top-level windows. It could, for example, be connected to a "Quit"
2146 entry in the file menu as shown in the following code example:
2147
2148 \code
2149 // the "Quit" menu entry should try to close all windows
2150 QPopupMenu* file = new QPopupMenu( this );
2151 file->insertItem( "&Quit", qApp, SLOT(closeAllWindows()), CTRL+Key_Q );
2152
2153 // when the last window is closed, the application should quit
2154 connect( qApp, SIGNAL( lastWindowClosed() ), qApp, SLOT( quit() ) );
2155 \endcode
2156
2157 The windows are closed in random order, until one window does not
2158 accept the close event.
2159
2160 \sa QWidget::close(), QWidget::closeEvent(), lastWindowClosed(),
2161 quit(), topLevelWidgets(), QWidget::isTopLevel()
2162
2163 */
2164void QApplication::closeAllWindows()
2165{
2166 bool did_close = TRUE;
2167 QWidget *w;
2168 while((w = activeModalWidget()) && did_close) {
2169 if(w->isHidden())
2170 break;
2171 did_close = w->close();
2172 }
2173 QWidgetList *list = QApplication::topLevelWidgets();
2174 for ( w = list->first(); did_close && w; ) {
2175 if ( !w->isHidden() ) {
2176 did_close = w->close();
2177 delete list;
2178 list = QApplication::topLevelWidgets();
2179 w = list->first();
2180 } else {
2181 w = list->next();
2182 }
2183 }
2184 delete list;
2185}
2186
2187/*!
2188 Displays a simple message box about Qt. The message includes the
2189 version number of Qt being used by the application.
2190
2191 This is useful for inclusion in the Help menu of an application.
2192 See the examples/menu/menu.cpp example.
2193
2194 This function is a convenience slot for QMessageBox::aboutQt().
2195*/
2196void QApplication::aboutQt()
2197{
2198#ifndef QT_NO_MESSAGEBOX
2199 QMessageBox::aboutQt( mainWidget() );
2200#endif // QT_NO_MESSAGEBOX
2201}
2202
2203
2204/*!
2205 \fn void QApplication::lastWindowClosed()
2206
2207 This signal is emitted when the user has closed the last
2208 top level window.
2209
2210 The signal is very useful when your application has many top level
2211 widgets but no main widget. You can then connect it to the quit()
2212 slot.
2213
2214 For convenience, this signal is \e not emitted for transient top level
2215 widgets such as popup menus and dialogs.
2216
2217 \sa mainWidget(), topLevelWidgets(), QWidget::isTopLevel(), QWidget::close()
2218*/
2219
2220/*!
2221 \fn void QApplication::aboutToQuit()
2222
2223 This signal is emitted when the application is about to quit the
2224 main event loop, e.g. when the event loop level drops to zero.
2225 This may happen either after a call to quit() from inside the
2226 application or when the users shuts down the entire desktop session.
2227
2228 The signal is particularly useful if your application has to do some
2229 last-second cleanup. Note that no user interaction is possible in
2230 this state.
2231
2232 \sa quit()
2233*/
2234
2235
2236/*!
2237 \fn void QApplication::guiThreadAwake()
2238
2239 This signal is emitted after the event loop returns from a function
2240 that could block.
2241
2242 \sa wakeUpGuiThread()
2243*/
2244
2245
2246/*!
2247 \fn bool QApplication::sendEvent( QObject *receiver, QEvent *event )
2248
2249 Sends event \a event directly to receiver \a receiver, using the
2250 notify() function. Returns the value that was returned from the event
2251 handler.
2252
2253 The event is \e not deleted when the event has been sent. The normal
2254 approach is to create the event on the stack, e.g.
2255 \code
2256 QMouseEvent me( QEvent::MouseButtonPress, pos, 0, 0 );
2257 QApplication::sendEvent( mainWindow, &me );
2258 \endcode
2259 If you create the event on the heap you must delete it.
2260
2261 \sa postEvent(), notify()
2262*/
2263
2264/*!
2265 Sends event \a e to \a receiver: \a {receiver}->event(\a e).
2266 Returns the value that is returned from the receiver's event handler.
2267
2268 For certain types of events (e.g. mouse and key events),
2269 the event will be propagated to the receiver's parent and so on up to
2270 the top-level object if the receiver is not interested in the event
2271 (i.e., it returns FALSE).
2272
2273 There are five different ways that events can be processed;
2274 reimplementing this virtual function is just one of them. All five
2275 approaches are listed below:
2276 \list 1
2277 \i Reimplementing this function. This is very powerful, providing
2278 complete control; but only one subclass can be qApp.
2279
2280 \i Installing an event filter on qApp. Such an event filter is able
2281 to process all events for all widgets, so it's just as powerful as
2282 reimplementing notify(); furthermore, it's possible to have more
2283 than one application-global event filter. Global event filters even
2284 see mouse events for \link QWidget::isEnabled() disabled
2285 widgets, \endlink and if \link setGlobalMouseTracking() global mouse
2286 tracking \endlink is enabled, as well as mouse move events for all
2287 widgets.
2288
2289 \i Reimplementing QObject::event() (as QWidget does). If you do
2290 this you get Tab key presses, and you get to see the events before
2291 any widget-specific event filters.
2292
2293 \i Installing an event filter on the object. Such an event filter
2294 gets all the events except Tab and Shift-Tab key presses.
2295
2296 \i Reimplementing paintEvent(), mousePressEvent() and so
2297 on. This is the commonest, easiest and least powerful way.
2298 \endlist
2299
2300 \sa QObject::event(), installEventFilter()
2301*/
2302
2303bool QApplication::notify( QObject *receiver, QEvent *e )
2304{
2305 // no events are delivered after ~QApplication() has started
2306 if ( is_app_closing )
2307 return FALSE;
2308
2309 if ( receiver == 0 ) { // serious error
2310#if defined(QT_CHECK_NULL)
2311 qWarning( "QApplication::notify: Unexpected null receiver" );
2312#endif
2313 return FALSE;
2314 }
2315
2316 if ( e->type() == QEvent::ChildRemoved && receiver->postedEvents ) {
2317
2318#ifdef QT_THREAD_SUPPORT
2319 QMutexLocker locker( postevent_mutex );
2320#endif // QT_THREAD_SUPPORT
2321
2322 // the QObject destructor calls QObject::removeChild, which calls
2323 // QApplication::sendEvent() directly. this can happen while the event
2324 // loop is in the middle of posting events, and when we get here, we may
2325 // not have any more posted events for this object.
2326 if ( receiver->postedEvents ) {
2327 // if this is a child remove event and the child insert
2328 // hasn't been dispatched yet, kill that insert
2329 QPostEventList * l = receiver->postedEvents;
2330 QObject * c = ((QChildEvent*)e)->child();
2331 QPostEvent * pe;
2332 l->first();
2333 while( ( pe = l->current()) != 0 ) {
2334 if ( pe->event && pe->receiver == receiver &&
2335 pe->event->type() == QEvent::ChildInserted &&
2336 ((QChildEvent*)pe->event)->child() == c ) {
2337 pe->event->posted = FALSE;
2338 delete pe->event;
2339 pe->event = 0;
2340 l->remove();
2341 continue;
2342 }
2343 l->next();
2344 }
2345 }
2346 }
2347
2348 bool res = FALSE;
2349 if ( !receiver->isWidgetType() )
2350 res = internalNotify( receiver, e );
2351 else switch ( e->type() ) {
2352#ifndef QT_NO_ACCEL
2353 case QEvent::Accel:
2354 {
2355 QKeyEvent* key = (QKeyEvent*) e;
2356 res = internalNotify( receiver, e );
2357
2358 if ( !res && !key->isAccepted() )
2359 res = qt_dispatchAccelEvent( (QWidget*)receiver, key );
2360
2361 // next lines are for compatibility with Qt <= 3.0.x: old
2362 // QAccel was listening on toplevel widgets
2363 if ( !res && !key->isAccepted() && !((QWidget*)receiver)->isTopLevel() )
2364 res = internalNotify( ((QWidget*)receiver)->topLevelWidget(), e );
2365 }
2366 break;
2367#endif //QT_NO_ACCEL
2368 case QEvent::KeyPress:
2369 case QEvent::KeyRelease:
2370 case QEvent::AccelOverride:
2371 {
2372 QWidget* w = (QWidget*)receiver;
2373 QKeyEvent* key = (QKeyEvent*) e;
2374#ifndef QT_NO_ACCEL
2375 if ( qt_tryComposeUnicode( w, key ) )
2376 break;
2377#endif
2378 bool def = key->isAccepted();
2379 while ( w ) {
2380 if ( def )
2381 key->accept();
2382 else
2383 key->ignore();
2384 res = internalNotify( w, e );
2385 if ( res || key->isAccepted() )
2386 break;
2387 w = w->parentWidget( TRUE );
2388 }
2389 }
2390 break;
2391 case QEvent::MouseButtonPress:
2392 if ( e->spontaneous() ) {
2393 QWidget* fw = (QWidget*)receiver;
2394 while ( fw->focusProxy() )
2395 fw = fw->focusProxy();
2396 if ( fw->isEnabled() && fw->focusPolicy() & QWidget::ClickFocus ) {
2397 QFocusEvent::setReason( QFocusEvent::Mouse);
2398 fw->setFocus();
2399 QFocusEvent::resetReason();
2400 }
2401 }
2402 // fall through intended
2403 case QEvent::MouseButtonRelease:
2404 case QEvent::MouseButtonDblClick:
2405 case QEvent::MouseMove:
2406 {
2407 QWidget* w = (QWidget*)receiver;
2408 QMouseEvent* mouse = (QMouseEvent*) e;
2409 QPoint relpos = mouse->pos();
2410 while ( w ) {
2411 QMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->state());
2412 me.spont = mouse->spontaneous();
2413 res = internalNotify( w, w == receiver ? mouse : &me );
2414 e->spont = FALSE;
2415 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2416 break;
2417
2418 relpos += w->pos();
2419 w = w->parentWidget();
2420 }
2421 if ( res )
2422 mouse->accept();
2423 else
2424 mouse->ignore();
2425 }
2426 break;
2427#ifndef QT_NO_WHEELEVENT
2428 case QEvent::Wheel:
2429 {
2430 if ( e->spontaneous() ) {
2431 QWidget* fw = (QWidget*)receiver;
2432 while ( fw->focusProxy() )
2433 fw = fw->focusProxy();
2434 if ( fw->isEnabled() && (fw->focusPolicy() & QWidget::WheelFocus) == QWidget::WheelFocus ) {
2435 QFocusEvent::setReason( QFocusEvent::Mouse);
2436 fw->setFocus();
2437 QFocusEvent::resetReason();
2438 }
2439 }
2440
2441 QWidget* w = (QWidget*)receiver;
2442 QWheelEvent* wheel = (QWheelEvent*) e;
2443 QPoint relpos = wheel->pos();
2444 while ( w ) {
2445 QWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->state(), wheel->orientation());
2446 we.spont = wheel->spontaneous();
2447 res = internalNotify( w, w == receiver ? wheel : &we );
2448 e->spont = FALSE;
2449 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2450 break;
2451
2452 relpos += w->pos();
2453 w = w->parentWidget();
2454 }
2455 if ( res )
2456 wheel->accept();
2457 else
2458 wheel->ignore();
2459 }
2460 break;
2461#endif
2462 case QEvent::ContextMenu:
2463 {
2464 QWidget* w = (QWidget*)receiver;
2465 QContextMenuEvent *context = (QContextMenuEvent*) e;
2466 QPoint relpos = context->pos();
2467 while ( w ) {
2468 QContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->state());
2469 ce.spont = e->spontaneous();
2470 res = internalNotify( w, w == receiver ? context : &ce );
2471 e->spont = FALSE;
2472
2473 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2474 break;
2475
2476 relpos += w->pos();
2477 w = w->parentWidget();
2478 }
2479 if ( res )
2480 context->accept();
2481 else
2482 context->ignore();
2483 }
2484 break;
2485#if defined (QT_TABLET_SUPPORT)
2486 case QEvent::TabletMove:
2487 case QEvent::TabletPress:
2488 case QEvent::TabletRelease:
2489 {
2490 QWidget *w = (QWidget*)receiver;
2491 QTabletEvent *tablet = (QTabletEvent*)e;
2492 QPoint relpos = tablet->pos();
2493 while ( w ) {
2494 QTabletEvent te(tablet->pos(), tablet->globalPos(), tablet->device(),
2495 tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
2496 tablet->uniqueId());
2497 te.spont = e->spontaneous();
2498 res = internalNotify( w, w == receiver ? tablet : &te );
2499 e->spont = FALSE;
2500 if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
2501 break;
2502
2503 relpos += w->pos();
2504 w = w->parentWidget();
2505 }
2506 if ( res )
2507 tablet->accept();
2508 else
2509 tablet->ignore();
2510 chokeMouse = tablet->isAccepted();
2511 }
2512 break;
2513#endif
2514 default:
2515 res = internalNotify( receiver, e );
2516 break;
2517 }
2518
2519 return res;
2520}
2521
2522/*!\reimp
2523
2524*/
2525bool QApplication::event( QEvent *e )
2526{
2527 if(e->type() == QEvent::Close) {
2528 QCloseEvent *ce = (QCloseEvent*)e;
2529 ce->accept();
2530 closeAllWindows();
2531
2532 QWidgetList *list = topLevelWidgets();
2533 for(QWidget *w = list->first(); w; w = list->next()) {
2534 if ( !w->isHidden() && !w->isDesktop() && !w->isPopup() &&
2535 (!w->isDialog() || !w->parentWidget())) {
2536 ce->ignore();
2537 break;
2538 }
2539 }
2540 delete list;
2541 if(ce->isAccepted())
2542 return TRUE;
2543 } else if (e->type() == QEvent::Quit) {
2544 quit();
2545 return TRUE;
2546 }
2547 return QObject::event(e);
2548}
2549
2550/*!\internal
2551
2552 Helper function called by notify()
2553 */
2554bool QApplication::internalNotify( QObject *receiver, QEvent * e)
2555{
2556 if ( eventFilters ) {
2557 QObjectListIt it( *eventFilters );
2558 register QObject *obj;
2559 while ( (obj=it.current()) != 0 ) { // send to all filters
2560 ++it; // until one returns TRUE
2561 if ( obj->eventFilter(receiver,e) )
2562 return TRUE;
2563 }
2564 }
2565
2566 bool consumed = FALSE;
2567 bool handled = FALSE;
2568 if ( receiver->isWidgetType() ) {
2569 QWidget *widget = (QWidget*)receiver;
2570
2571 // toggle HasMouse widget state on enter and leave
2572 if ( e->type() == QEvent::Enter || e->type() == QEvent::DragEnter )
2573 widget->setWState( WState_HasMouse );
2574 else if ( e->type() == QEvent::Leave || e->type() == QEvent::DragLeave )
2575 widget->clearWState( WState_HasMouse );
2576
2577 // throw away any mouse-tracking-only mouse events
2578 if ( e->type() == QEvent::MouseMove &&
2579 (((QMouseEvent*)e)->state()&QMouseEvent::MouseButtonMask) == 0 &&
2580 !widget->hasMouseTracking() ) {
2581 handled = TRUE;
2582 consumed = TRUE;
2583 } else if ( !widget->isEnabled() ) { // throw away mouse events to disabled widgets
2584 switch(e->type()) {
2585 case QEvent::MouseButtonPress:
2586 case QEvent::MouseButtonRelease:
2587 case QEvent::MouseButtonDblClick:
2588 case QEvent::MouseMove:
2589 ( (QMouseEvent*) e)->ignore();
2590 handled = TRUE;
2591 consumed = TRUE;
2592 break;
2593#ifndef QT_NO_DRAGANDDROP
2594 case QEvent::DragEnter:
2595 case QEvent::DragMove:
2596 ( (QDragMoveEvent*) e)->ignore();
2597 handled = TRUE;
2598 break;
2599
2600 case QEvent::DragLeave:
2601 case QEvent::DragResponse:
2602 handled = TRUE;
2603 break;
2604
2605 case QEvent::Drop:
2606 ( (QDropEvent*) e)->ignore();
2607 handled = TRUE;
2608 break;
2609#endif
2610#ifndef QT_NO_WHEELEVENT
2611 case QEvent::Wheel:
2612 ( (QWheelEvent*) e)->ignore();
2613 handled = TRUE;
2614 break;
2615#endif
2616 case QEvent::ContextMenu:
2617 ( (QContextMenuEvent*) e)->ignore();
2618 handled = TRUE;
2619 break;
2620 default:
2621 break;
2622 }
2623 }
2624
2625 }
2626
2627 if (!handled)
2628 consumed = receiver->event( e );
2629 e->spont = FALSE;
2630 return consumed;
2631}
2632
2633/*!
2634 Returns TRUE if an application object has not been created yet;
2635 otherwise returns FALSE.
2636
2637 \sa closingDown()
2638*/
2639
2640bool QApplication::startingUp()
2641{
2642 return !is_app_running;
2643}
2644
2645/*!
2646 Returns TRUE if the application objects are being destroyed;
2647 otherwise returns FALSE.
2648
2649 \sa startingUp()
2650*/
2651
2652bool QApplication::closingDown()
2653{
2654 return is_app_closing;
2655}
2656
2657
2658/*!
2659 Processes pending events, for 3 seconds or until there are no more
2660 events to process, whichever is shorter.
2661
2662 You can call this function occasionally when your program is busy
2663 performing a long operation (e.g. copying a file).
2664
2665 \sa exec(), QTimer, QEventLoop::processEvents()
2666*/
2667
2668void QApplication::processEvents()
2669{
2670 processEvents( 3000 );
2671}
2672
2673/*!
2674 \overload
2675
2676 Processes pending events for \a maxtime milliseconds or until
2677 there are no more events to process, whichever is shorter.
2678
2679 You can call this function occasionally when you program is busy
2680 doing a long operation (e.g. copying a file).
2681
2682 \sa exec(), QTimer, QEventLoop::processEvents()
2683*/
2684void QApplication::processEvents( int maxtime )
2685{
2686 eventLoop()->processEvents( QEventLoop::AllEvents, maxtime );
2687}
2688
2689/*! \obsolete
2690 Waits for an event to occur, processes it, then returns.
2691
2692 This function is useful for adapting Qt to situations where the
2693 event processing must be grafted onto existing program loops.
2694
2695 Using this function in new applications may be an indication of design
2696 problems.
2697
2698 \sa processEvents(), exec(), QTimer
2699*/
2700
2701void QApplication::processOneEvent()
2702{
2703 eventLoop()->processEvents( QEventLoop::AllEvents |
2704 QEventLoop::WaitForMore );
2705}
2706
2707/*****************************************************************************
2708 Main event loop wrappers
2709 *****************************************************************************/
2710
2711/*!
2712 Returns the application event loop. This function will return
2713 zero if called during and after destroying QApplication.
2714
2715 To create your own instance of QEventLoop or QEventLoop subclass create
2716 it before you create the QApplication object.
2717
2718 \sa QEventLoop
2719*/
2720QEventLoop *QApplication::eventLoop()
2721{
2722 if ( !eventloop && !is_app_closing )
2723 (void) new QEventLoop( qApp, "default event loop" );
2724 return eventloop;
2725}
2726
2727
2728/*!
2729 Enters the main event loop and waits until exit() is called or the
2730 main widget is destroyed, and returns the value that was set to
2731 exit() (which is 0 if exit() is called via quit()).
2732
2733 It is necessary to call this function to start event handling. The
2734 main event loop receives events from the window system and
2735 dispatches these to the application widgets.
2736
2737 Generally speaking, no user interaction can take place before
2738 calling exec(). As a special case, modal widgets like QMessageBox
2739 can be used before calling exec(), because modal widgets call
2740 exec() to start a local event loop.
2741
2742 To make your application perform idle processing, i.e. executing a
2743 special function whenever there are no pending events, use a
2744 QTimer with 0 timeout. More advanced idle processing schemes can
2745 be achieved using processEvents().
2746
2747 \sa quit(), exit(), processEvents(), setMainWidget()
2748*/
2749int QApplication::exec()
2750{
2751 return eventLoop()->exec();
2752}
2753
2754/*!
2755 Tells the application to exit with a return code.
2756
2757 After this function has been called, the application leaves the main
2758 event loop and returns from the call to exec(). The exec() function
2759 returns \a retcode.
2760
2761 By convention, a \a retcode of 0 means success, and any non-zero
2762 value indicates an error.
2763
2764 Note that unlike the C library function of the same name, this
2765 function \e does return to the caller -- it is event processing that
2766 stops.
2767
2768 \sa quit(), exec()
2769*/
2770void QApplication::exit( int retcode )
2771{
2772 qApp->eventLoop()->exit( retcode );
2773}
2774
2775/*!
2776 \obsolete
2777
2778 This function enters the main event loop (recursively). Do not call
2779 it unless you really know what you are doing.
2780*/
2781int QApplication::enter_loop()
2782{
2783 return eventLoop()->enterLoop();
2784}
2785
2786/*!
2787 \obsolete
2788
2789 This function exits from a recursive call to the main event loop.
2790 Do not call it unless you are an expert.
2791*/
2792void QApplication::exit_loop()
2793{
2794 eventLoop()->exitLoop();
2795}
2796
2797/*!
2798 \obsolete
2799
2800 Returns the current loop level.
2801*/
2802int QApplication::loopLevel() const
2803{
2804 return eventLoop()->loopLevel();
2805}
2806
2807/*!
2808
2809 Wakes up the GUI thread.
2810
2811 \sa guiThreadAwake() \link threads.html Thread Support in Qt\endlink
2812*/
2813void QApplication::wakeUpGuiThread()
2814{
2815 eventLoop()->wakeUp();
2816}
2817
2818/*!
2819 This function returns TRUE if there are pending events; otherwise
2820 returns FALSE. Pending events can be either from the window system
2821 or posted events using QApplication::postEvent().
2822*/
2823bool QApplication::hasPendingEvents()
2824{
2825 return eventLoop()->hasPendingEvents();
2826}
2827
2828#if !defined(Q_WS_X11)
2829
2830// The doc and X implementation of these functions is in qapplication_x11.cpp
2831
2832void QApplication::flushX() {} // do nothing
2833
2834void QApplication::syncX() {} // do nothing
2835
2836#endif
2837
2838/*!
2839 \fn void QApplication::setWinStyleHighlightColor( const QColor & )
2840 \obsolete
2841
2842 Sets the color used to mark selections in windows style for all widgets
2843 in the application. Will repaint all widgets if the color is changed.
2844
2845 The default color is \c darkBlue.
2846 \sa winStyleHighlightColor()
2847*/
2848
2849/*!
2850 \fn const QColor& QApplication::winStyleHighlightColor()
2851 \obsolete
2852
2853 Returns the color used to mark selections in windows style.
2854
2855 \sa setWinStyleHighlightColor()
2856*/
2857
2858/*!
2859 Returns the version of the Windows operating system that is running:
2860
2861 \list
2862 \i Qt::WV_95 - Windows 95
2863 \i Qt::WV_98 - Windows 98
2864 \i Qt::WV_Me - Windows Me
2865 \i Qt::WV_NT - Windows NT 4.x
2866 \i Qt::WV_2000 - Windows 2000 (NT5)
2867 \i Qt::WV_XP - Windows XP
2868 \i Qt::WV_2003 - Windows Server 2003 family
2869 \i Qt::WV_CE - Windows CE
2870 \i Qt::WV_CENET - Windows CE.NET
2871 \endlist
2872
2873 Note that this function is implemented for the Windows version
2874 of Qt only.
2875*/
2876
2877#if defined(Q_OS_CYGWIN)
2878Qt::WindowsVersion QApplication::winVersion()
2879{
2880 return qt_winver;
2881}
2882#endif
2883
2884#ifndef QT_NO_TRANSLATION
2885
2886bool qt_detectRTLLanguage()
2887{
2888 return QApplication::tr( "QT_LAYOUT_DIRECTION",
2889 "Translate this string to the string 'LTR' in left-to-right"
2890 " languages or to 'RTL' in right-to-left languages (such as Hebrew"
2891 " and Arabic) to get proper widget layout." ) == "RTL";
2892}
2893
2894/*!
2895 Adds the message file \a mf to the list of message files to be used
2896 for translations.
2897
2898 Multiple message files can be installed. Translations are searched
2899 for in the last installed message file, then the one from last, and
2900 so on, back to the first installed message file. The search stops as
2901 soon as a matching translation is found.
2902
2903 \sa removeTranslator() translate() QTranslator::load()
2904*/
2905
2906void QApplication::installTranslator( QTranslator * mf )
2907{
2908 if ( !mf )
2909 return;
2910 if ( !translators )
2911 translators = new QValueList<QTranslator*>;
2912
2913 translators->prepend( mf );
2914
2915#ifndef QT_NO_TRANSLATION_BUILDER
2916 if ( mf->isEmpty() )
2917 return;
2918#endif
2919
2920 // hook to set the layout direction of dialogs
2921 setReverseLayout( qt_detectRTLLanguage() );
2922
2923 QWidgetList *list = topLevelWidgets();
2924 QWidgetListIt it( *list );
2925 QWidget *w;
2926 while ( ( w=it.current() ) != 0 ) {
2927 ++it;
2928 if (!w->isDesktop())
2929 postEvent( w, new QEvent( QEvent::LanguageChange ) );
2930 }
2931 delete list;
2932}
2933
2934/*!
2935 Removes the message file \a mf from the list of message files used by
2936 this application. (It does not delete the message file from the file
2937 system.)
2938
2939 \sa installTranslator() translate(), QObject::tr()
2940*/
2941
2942void QApplication::removeTranslator( QTranslator * mf )
2943{
2944 if ( !translators || !mf )
2945 return;
2946
2947 if ( translators->remove( mf ) && ! qApp->closingDown() ) {
2948 setReverseLayout( qt_detectRTLLanguage() );
2949
2950 QWidgetList *list = topLevelWidgets();
2951 QWidgetListIt it( *list );
2952 QWidget *w;
2953 while ( ( w=it.current() ) != 0 ) {
2954 ++it;
2955 postEvent( w, new QEvent( QEvent::LanguageChange ) );
2956 }
2957 delete list;
2958 }
2959}
2960
2961#ifndef QT_NO_TEXTCODEC
2962/*! \obsolete
2963 This is the same as QTextCodec::setCodecForTr().
2964*/
2965void QApplication::setDefaultCodec( QTextCodec* codec )
2966{
2967 QTextCodec::setCodecForTr( codec );
2968}
2969
2970/*! \obsolete
2971 Returns QTextCodec::codecForTr().
2972*/
2973QTextCodec* QApplication::defaultCodec() const
2974{
2975 return QTextCodec::codecForTr();
2976}
2977#endif //QT_NO_TEXTCODEC
2978
2979/*! \enum QApplication::Encoding
2980
2981 This enum type defines the 8-bit encoding of character string
2982 arguments to translate():
2983
2984 \value DefaultCodec - the encoding specified by
2985 QTextCodec::codecForTr() (Latin-1 if none has been set)
2986 \value UnicodeUTF8 - UTF-8
2987
2988 \sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
2989*/
2990
2991/*! \reentrant
2992 Returns the translation text for \a sourceText, by querying the
2993 installed messages files. The message files are searched from the most
2994 recently installed message file back to the first installed message
2995 file.
2996
2997 QObject::tr() and QObject::trUtf8() provide this functionality more
2998 conveniently.
2999
3000 \a context is typically a class name (e.g., "MyDialog") and
3001 \a sourceText is either English text or a short identifying text, if
3002 the output text will be very long (as for help texts).
3003
3004 \a comment is a disambiguating comment, for when the same \a
3005 sourceText is used in different roles within the same context. By
3006 default, it is null. \a encoding indicates the 8-bit encoding of
3007 character stings
3008
3009 See the \l QTranslator documentation for more information about
3010 contexts and comments.
3011
3012 If none of the message files contain a translation for \a
3013 sourceText in \a context, this function returns a QString
3014 equivalent of \a sourceText. The encoding of \a sourceText is
3015 specified by \e encoding; it defaults to \c DefaultCodec.
3016
3017 This function is not virtual. You can use alternative translation
3018 techniques by subclassing \l QTranslator.
3019
3020 \warning This method is reentrant only if all translators are
3021 installed \e before calling this method. Installing or removing
3022 translators while performing translations is not supported. Doing
3023 so will most likely result in crashes or other undesirable behavior.
3024
3025 \sa QObject::tr() installTranslator() defaultCodec()
3026*/
3027
3028QString QApplication::translate( const char * context, const char * sourceText,
3029 const char * comment, Encoding encoding ) const
3030{
3031 if ( !sourceText )
3032 return QString::null;
3033
3034 if ( translators ) {
3035 QValueList<QTranslator*>::iterator it;
3036 QTranslator * mf;
3037 QString result;
3038 for ( it = translators->begin(); it != translators->end(); ++it ) {
3039 mf = *it;
3040 result = mf->findMessage( context, sourceText, comment ).translation();
3041 if ( !result.isNull() )
3042 return result;
3043 }
3044 }
3045#ifndef QT_NO_TEXTCODEC
3046 if ( encoding == UnicodeUTF8 )
3047 return QString::fromUtf8( sourceText );
3048 else if ( QTextCodec::codecForTr() != 0 )
3049 return QTextCodec::codecForTr()->toUnicode( sourceText );
3050 else
3051#endif
3052 return QString::fromLatin1( sourceText );
3053}
3054
3055#endif
3056
3057/*****************************************************************************
3058 QApplication management of posted events
3059 *****************************************************************************/
3060
3061//see also notify(), which does the removal of ChildInserted when ChildRemoved.
3062
3063/*!
3064 Adds the event \a event with the object \a receiver as the receiver of the
3065 event, to an event queue and returns immediately.
3066
3067 The event must be allocated on the heap since the post event queue
3068 will take ownership of the event and delete it once it has been posted.
3069
3070 When control returns to the main event loop, all events that are
3071 stored in the queue will be sent using the notify() function.
3072
3073 \threadsafe
3074
3075 \sa sendEvent(), notify()
3076*/
3077
3078void QApplication::postEvent( QObject *receiver, QEvent *event )
3079{
3080 if ( receiver == 0 ) {
3081#if defined(QT_CHECK_NULL)
3082 qWarning( "QApplication::postEvent: Unexpected null receiver" );
3083#endif
3084 delete event;
3085 return;
3086 }
3087
3088#ifdef QT_THREAD_SUPPORT
3089 QMutexLocker locker( postevent_mutex );
3090#endif // QT_THREAD_SUPPORT
3091
3092 if ( !globalPostedEvents ) { // create list
3093 globalPostedEvents = new QPostEventList;
3094 Q_CHECK_PTR( globalPostedEvents );
3095 globalPostedEvents->setAutoDelete( TRUE );
3096 qapp_cleanup_events.set( &globalPostedEvents );
3097 }
3098
3099 if ( !receiver->postedEvents )
3100 receiver->postedEvents = new QPostEventList;
3101 QPostEventList * l = receiver->postedEvents;
3102
3103 // if this is one of the compressible events, do compression
3104 if ( event->type() == QEvent::Paint ||
3105 event->type() == QEvent::LayoutHint ||
3106 event->type() == QEvent::Resize ||
3107 event->type() == QEvent::Move ||
3108 event->type() == QEvent::LanguageChange ) {
3109 l->first();
3110 QPostEvent * cur = 0;
3111 for ( ;; ) {
3112 while ( (cur=l->current()) != 0 &&
3113 ( cur->receiver != receiver ||
3114 cur->event == 0 ||
3115 cur->event->type() != event->type() ) )
3116 l->next();
3117 if ( l->current() != 0 ) {
3118 if ( cur->event->type() == QEvent::Paint ) {
3119 QPaintEvent * p = (QPaintEvent*)(cur->event);
3120 if ( p->erase != ((QPaintEvent*)event)->erase ) {
3121 l->next();
3122 continue;
3123 }
3124 p->reg = p->reg.unite( ((QPaintEvent *)event)->reg );
3125 p->rec = p->rec.unite( ((QPaintEvent *)event)->rec );
3126 delete event;
3127 return;
3128 } else if ( cur->event->type() == QEvent::LayoutHint ) {
3129 delete event;
3130 return;
3131 } else if ( cur->event->type() == QEvent::Resize ) {
3132 ((QResizeEvent *)(cur->event))->s = ((QResizeEvent *)event)->s;
3133 delete event;
3134 return;
3135 } else if ( cur->event->type() == QEvent::Move ) {
3136 ((QMoveEvent *)(cur->event))->p = ((QMoveEvent *)event)->p;
3137 delete event;
3138 return;
3139 } else if ( cur->event->type() == QEvent::LanguageChange ) {
3140 delete event;
3141 return;
3142 }
3143 }
3144 break;
3145 };
3146 }
3147
3148 // if no compression could be done, just append something
3149 event->posted = TRUE;
3150 QPostEvent * pe = new QPostEvent( receiver, event );
3151 l->append( pe );
3152 globalPostedEvents->append( pe );
3153
3154 if (eventloop)
3155 eventloop->wakeUp();
3156}
3157
3158
3159/*! \overload
3160
3161 Dispatches all posted events, i.e. empties the event queue.
3162*/
3163void QApplication::sendPostedEvents()
3164{
3165 sendPostedEvents( 0, 0 );
3166}
3167
3168
3169
3170/*!
3171 Immediately dispatches all events which have been previously queued
3172 with QApplication::postEvent() and which are for the object \a receiver
3173 and have the event type \a event_type.
3174
3175 Note that events from the window system are \e not dispatched by this
3176 function, but by processEvents().
3177
3178 If \a receiver is null, the events of \a event_type are sent for all
3179 objects. If \a event_type is 0, all the events are sent for \a receiver.
3180*/
3181
3182void QApplication::sendPostedEvents( QObject *receiver, int event_type )
3183{
3184 // Make sure the object hierarchy is stable before processing events
3185 // to avoid endless loops
3186 if ( receiver == 0 && event_type == 0 )
3187 sendPostedEvents( 0, QEvent::ChildInserted );
3188
3189 if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
3190 return;
3191
3192#ifdef QT_THREAD_SUPPORT
3193 QMutexLocker locker( postevent_mutex );
3194#endif
3195
3196 bool sent = TRUE;
3197 while ( sent ) {
3198 sent = FALSE;
3199
3200 if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
3201 return;
3202
3203 // if we have a receiver, use the local list. Otherwise, use the
3204 // global list
3205 QPostEventList * l = receiver ? receiver->postedEvents : globalPostedEvents;
3206
3207 // okay. here is the tricky loop. be careful about optimizing
3208 // this, it looks the way it does for good reasons.
3209 QPostEventListIt it( *l );
3210 QPostEvent *pe;
3211 while ( (pe=it.current()) != 0 ) {
3212 ++it;
3213 if ( pe->event // hasn't been sent yet
3214 && ( receiver == 0 // we send to all receivers
3215 || receiver == pe->receiver ) // we send to THAT receiver
3216 && ( event_type == 0 // we send all types
3217 || event_type == pe->event->type() ) ) { // we send THAT type
3218 // first, we diddle the event so that we can deliver
3219 // it, and that noone will try to touch it later.
3220 pe->event->posted = FALSE;
3221 QEvent * e = pe->event;
3222 QObject * r = pe->receiver;
3223 pe->event = 0;
3224
3225 // next, update the data structure so that we're ready
3226 // for the next event.
3227
3228 // look for the local list, and take whatever we're
3229 // delivering out of it. r->postedEvents maybe *l
3230 if ( r->postedEvents ) {
3231 r->postedEvents->removeRef( pe );
3232 // if possible, get rid of that list. this is not
3233 // ideal - we will create and delete a list for
3234 // each update() call. it would be better if we'd
3235 // leave the list empty here, and delete it
3236 // somewhere else if it isn't being used.
3237 if ( r->postedEvents->isEmpty() ) {
3238 delete r->postedEvents;
3239 r->postedEvents = 0;
3240 }
3241 }
3242
3243#ifdef QT_THREAD_SUPPORT
3244 if ( locker.mutex() ) locker.mutex()->unlock();
3245#endif // QT_THREAD_SUPPORT
3246 // after all that work, it's time to deliver the event.
3247 if ( e->type() == QEvent::Paint && r->isWidgetType() ) {
3248 QWidget * w = (QWidget*)r;
3249 QPaintEvent * p = (QPaintEvent*)e;
3250 if ( w->isVisible() )
3251 w->repaint( p->reg, p->erase );
3252 } else {
3253 sent = TRUE;
3254 QApplication::sendEvent( r, e );
3255 }
3256#ifdef QT_THREAD_SUPPORT
3257 if ( locker.mutex() ) locker.mutex()->lock();
3258#endif // QT_THREAD_SUPPORT
3259
3260 delete e;
3261 // careful when adding anything below this point - the
3262 // sendEvent() call might invalidate any invariants this
3263 // function depends on.
3264 }
3265 }
3266
3267 // clear the global list, i.e. remove everything that was
3268 // delivered.
3269 if ( l == globalPostedEvents ) {
3270 globalPostedEvents->first();
3271 while( (pe=globalPostedEvents->current()) != 0 ) {
3272 if ( pe->event )
3273 globalPostedEvents->next();
3274 else
3275 globalPostedEvents->remove();
3276 }
3277 }
3278 }
3279}
3280
3281/*!
3282 Removes all events posted using postEvent() for \a receiver.
3283
3284 The events are \e not dispatched, instead they are removed from the
3285 queue. You should never need to call this function. If you do call it,
3286 be aware that killing events may cause \a receiver to break one or
3287 more invariants.
3288
3289 \threadsafe
3290*/
3291
3292void QApplication::removePostedEvents( QObject *receiver )
3293{
3294 if ( !receiver )
3295 return;
3296
3297#ifdef QT_THREAD_SUPPORT
3298 QMutexLocker locker( postevent_mutex );
3299#endif // QT_THREAD_SUPPORT
3300
3301 // the QObject destructor calls this function directly. this can
3302 // happen while the event loop is in the middle of posting events,
3303 // and when we get here, we may not have any more posted events
3304 // for this object.
3305 if ( !receiver->postedEvents )
3306 return;
3307
3308 // iterate over the object-specifc list and delete the events.
3309 // leave the QPostEvent objects; they'll be deleted by
3310 // sendPostedEvents().
3311 QPostEventList * l = receiver->postedEvents;
3312 receiver->postedEvents = 0;
3313 l->first();
3314 QPostEvent * pe;
3315 while( (pe=l->current()) != 0 ) {
3316 if ( pe->event ) {
3317 pe->event->posted = FALSE;
3318 delete pe->event;
3319 pe->event = 0;
3320 }
3321 l->remove();
3322 }
3323 delete l;
3324}
3325
3326
3327/*!
3328 Removes \a event from the queue of posted events, and emits a
3329 warning message if appropriate.
3330
3331 \warning This function can be \e really slow. Avoid using it, if
3332 possible.
3333
3334 \threadsafe
3335*/
3336
3337void QApplication::removePostedEvent( QEvent * event )
3338{
3339 if ( !event || !event->posted )
3340 return;
3341
3342 if ( !globalPostedEvents ) {
3343#if defined(QT_DEBUG)
3344 qDebug( "QApplication::removePostedEvent: %p %d is posted: impossible",
3345 (void*)event, event->type() );
3346 return;
3347#endif
3348 }
3349
3350#ifdef QT_THREAD_SUPPORT
3351 QMutexLocker locker( postevent_mutex );
3352#endif // QT_THREAD_SUPPORT
3353
3354 QPostEventListIt it( *globalPostedEvents );
3355 QPostEvent * pe;
3356 while( (pe = it.current()) != 0 ) {
3357 ++it;
3358 if ( pe->event == event ) {
3359#if defined(QT_DEBUG)
3360 const char *n;
3361 switch ( event->type() ) {
3362 case QEvent::Timer:
3363 n = "Timer";
3364 break;
3365 case QEvent::MouseButtonPress:
3366 n = "MouseButtonPress";
3367 break;
3368 case QEvent::MouseButtonRelease:
3369 n = "MouseButtonRelease";
3370 break;
3371 case QEvent::MouseButtonDblClick:
3372 n = "MouseButtonDblClick";
3373 break;
3374 case QEvent::MouseMove:
3375 n = "MouseMove";
3376 break;
3377#ifndef QT_NO_WHEELEVENT
3378 case QEvent::Wheel:
3379 n = "Wheel";
3380 break;
3381#endif
3382 case QEvent::KeyPress:
3383 n = "KeyPress";
3384 break;
3385 case QEvent::KeyRelease:
3386 n = "KeyRelease";
3387 break;
3388 case QEvent::FocusIn:
3389 n = "FocusIn";
3390 break;
3391 case QEvent::FocusOut:
3392 n = "FocusOut";
3393 break;
3394 case QEvent::Enter:
3395 n = "Enter";
3396 break;
3397 case QEvent::Leave:
3398 n = "Leave";
3399 break;
3400 case QEvent::Paint:
3401 n = "Paint";
3402 break;
3403 case QEvent::Move:
3404 n = "Move";
3405 break;
3406 case QEvent::Resize:
3407 n = "Resize";
3408 break;
3409 case QEvent::Create:
3410 n = "Create";
3411 break;
3412 case QEvent::Destroy:
3413 n = "Destroy";
3414 break;
3415 case QEvent::Close:
3416 n = "Close";
3417 break;
3418 case QEvent::Quit:
3419 n = "Quit";
3420 break;
3421 default:
3422 n = "<other>";
3423 break;
3424 }
3425 qWarning("QEvent: Warning: %s event deleted while posted to %s %s",
3426 n,
3427 pe->receiver ? pe->receiver->className() : "null",
3428 pe->receiver ? pe->receiver->name() : "object" );
3429 // note the beautiful uglehack if !pe->receiver :)
3430#endif
3431 event->posted = FALSE;
3432 delete pe->event;
3433 pe->event = 0;
3434 return;
3435 }
3436 }
3437}
3438
3439/*!\internal
3440
3441 Sets the active window in reaction to a system event. Call this
3442 from the platform specific event handlers.
3443
3444 It sets the activeWindow() and focusWidget() attributes and sends
3445 proper WindowActivate/WindowDeactivate and FocusIn/FocusOut events
3446 to all appropriate widgets.
3447
3448 \sa activeWindow()
3449 */
3450void QApplication::setActiveWindow( QWidget* act )
3451{
3452 QWidget* window = act?act->topLevelWidget():0;
3453
3454 if ( active_window == window )
3455 return;
3456
3457 // first the activation/deactivation events
3458 if ( active_window ) {
3459 QWidgetList deacts;
3460#ifndef QT_NO_STYLE
3461 if ( style().styleHint(QStyle::SH_Widget_ShareActivation, active_window ) ) {
3462 QWidgetList *list = topLevelWidgets();
3463 if ( list ) {
3464 for ( QWidget *w = list->first(); w; w = list->next() ) {
3465 if ( w->isVisible() && w->isActiveWindow() )
3466 deacts.append(w);
3467 }
3468 delete list;
3469 }
3470 } else
3471#endif
3472 deacts.append(active_window);
3473 active_window = 0;
3474 QEvent e( QEvent::WindowDeactivate );
3475 for(QWidget *w = deacts.first(); w; w = deacts.next())
3476 QApplication::sendSpontaneousEvent( w, &e );
3477 }
3478
3479 active_window = window;
3480 if ( active_window ) {
3481 QEvent e( QEvent::WindowActivate );
3482 QWidgetList acts;
3483#ifndef QT_NO_STYLE
3484 if ( style().styleHint(QStyle::SH_Widget_ShareActivation, active_window ) ) {
3485 QWidgetList *list = topLevelWidgets();
3486 if ( list ) {
3487 for ( QWidget *w = list->first(); w; w = list->next() ) {
3488 if ( w->isVisible() && w->isActiveWindow() )
3489 acts.append(w);
3490 }
3491 delete list;
3492 }
3493 } else
3494#endif
3495 acts.append(active_window);
3496 for(QWidget *w = acts.first(); w; w = acts.next())
3497 QApplication::sendSpontaneousEvent( w, &e );
3498 }
3499
3500 // then focus events
3501 QFocusEvent::setReason( QFocusEvent::ActiveWindow );
3502 if ( !active_window && focus_widget ) {
3503 QFocusEvent out( QEvent::FocusOut );
3504 QWidget *tmp = focus_widget;
3505 focus_widget = 0;
3506#ifdef Q_WS_WIN
3507 QInputContext::accept( tmp );
3508#endif
3509 QApplication::sendSpontaneousEvent( tmp, &out );
3510 } else if ( active_window ) {
3511 QWidget *w = active_window->focusWidget();
3512 if ( w && w->focusPolicy() != QWidget::NoFocus )
3513 w->setFocus();
3514 else
3515 active_window->focusNextPrevChild( TRUE );
3516 }
3517 QFocusEvent::resetReason();
3518}
3519
3520
3521/*!\internal
3522
3523 Creates the proper Enter/Leave event when widget \a enter is entered
3524 and widget \a leave is left.
3525 */
3526Q_EXPORT void qt_dispatchEnterLeave( QWidget* enter, QWidget* leave ) {
3527#if 0
3528 if ( leave ) {
3529 QEvent e( QEvent::Leave );
3530 QApplication::sendEvent( leave, & e );
3531 }
3532 if ( enter ) {
3533 QEvent e( QEvent::Enter );
3534 QApplication::sendEvent( enter, & e );
3535 }
3536 return;
3537#endif
3538
3539 QWidget* w ;
3540 if ( !enter && !leave )
3541 return;
3542 QWidgetList leaveList;
3543 QWidgetList enterList;
3544
3545 bool sameWindow = leave && enter && leave->topLevelWidget() == enter->topLevelWidget();
3546 if ( leave && !sameWindow ) {
3547 w = leave;
3548 do {
3549 leaveList.append( w );
3550 } while ( (w = w->parentWidget( TRUE ) ) );
3551 }
3552 if ( enter && !sameWindow ) {
3553 w = enter;
3554 do {
3555 enterList.prepend( w );
3556 } while ( (w = w->parentWidget(TRUE) ) );
3557 }
3558 if ( sameWindow ) {
3559 int enterDepth = 0;
3560 int leaveDepth = 0;
3561 w = enter;
3562 while ( ( w = w->parentWidget( TRUE ) ) )
3563 enterDepth++;
3564 w = leave;
3565 while ( ( w = w->parentWidget( TRUE ) ) )
3566 leaveDepth++;
3567 QWidget* wenter = enter;
3568 QWidget* wleave = leave;
3569 while ( enterDepth > leaveDepth ) {
3570 wenter = wenter->parentWidget();
3571 enterDepth--;
3572 }
3573 while ( leaveDepth > enterDepth ) {
3574 wleave = wleave->parentWidget();
3575 leaveDepth--;
3576 }
3577 while ( !wenter->isTopLevel() && wenter != wleave ) {
3578 wenter = wenter->parentWidget();
3579 wleave = wleave->parentWidget();
3580 }
3581
3582 w = leave;
3583 while ( w != wleave ) {
3584 leaveList.append( w );
3585 w = w->parentWidget();
3586 }
3587 w = enter;
3588 while ( w != wenter ) {
3589 enterList.prepend( w );
3590 w = w->parentWidget();
3591 }
3592 }
3593
3594 QEvent leaveEvent( QEvent::Leave );
3595 for ( w = leaveList.first(); w; w = leaveList.next() ) {
3596 if ( !qApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
3597 QApplication::sendEvent( w, &leaveEvent );
3598 }
3599 QEvent enterEvent( QEvent::Enter );
3600 for ( w = enterList.first(); w; w = enterList.next() ) {
3601 if ( !qApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
3602 QApplication::sendEvent( w, &enterEvent );
3603 }
3604}
3605
3606
3607#ifdef Q_WS_MACX
3608extern QWidget *qt_tryModalHelperMac( QWidget * top ); //qapplication_mac.cpp
3609#endif
3610
3611
3612/*!\internal
3613
3614 Called from qapplication_<platform>.cpp, returns TRUE
3615 if the widget should accept the event.
3616 */
3617bool qt_tryModalHelper( QWidget *widget, QWidget **rettop ) {
3618 QWidget *modal=0, *top=QApplication::activeModalWidget();
3619 if ( rettop ) *rettop = top;
3620
3621 if ( qApp->activePopupWidget() )
3622 return TRUE;
3623
3624#ifdef Q_WS_MACX
3625 top = qt_tryModalHelperMac( top );
3626 if ( rettop ) *rettop = top;
3627#endif
3628
3629 QWidget* groupLeader = widget;
3630 widget = widget->topLevelWidget();
3631
3632 if ( widget->testWFlags(Qt::WShowModal) ) // widget is modal
3633 modal = widget;
3634 if ( !top || modal == top ) // don't block event
3635 return TRUE;
3636
3637 QWidget * p = widget->parentWidget(); // Check if the active modal widget is a parent of our widget
3638 while ( p ) {
3639 if ( p == top )
3640 return TRUE;
3641 p = p->parentWidget();
3642 }
3643
3644 while ( groupLeader && !groupLeader->testWFlags( Qt::WGroupLeader ) )
3645 groupLeader = groupLeader->parentWidget();
3646
3647 if ( groupLeader ) {
3648 // Does groupLeader have a child in qt_modal_stack?
3649 bool unrelated = TRUE;
3650 modal = qt_modal_stack->first();
3651 while (modal && unrelated) {
3652 QWidget* p = modal->parentWidget();
3653 while ( p && p != groupLeader && !p->testWFlags( Qt::WGroupLeader) ) {
3654 p = p->parentWidget();
3655 }
3656 modal = qt_modal_stack->next();
3657 if ( p == groupLeader ) unrelated = FALSE;
3658 }
3659
3660 if ( unrelated )
3661 return TRUE; // don't block event
3662 }
3663 return FALSE;
3664}
3665
3666
3667/*!
3668 Returns the desktop widget (also called the root window).
3669
3670 The desktop widget is useful for obtaining the size of the screen.
3671 It may also be possible to draw on the desktop. We recommend against
3672 assuming that it's possible to draw on the desktop, since this does
3673 not work on all operating systems.
3674
3675 \code
3676 QDesktopWidget *d = QApplication::desktop();
3677 int w = d->width(); // returns desktop width
3678 int h = d->height(); // returns desktop height
3679 \endcode
3680*/
3681
3682QDesktopWidget *QApplication::desktop()
3683{
3684 if ( !qt_desktopWidget || // not created yet
3685 !qt_desktopWidget->isDesktop() ) { // reparented away
3686 qt_desktopWidget = new QDesktopWidget();
3687 Q_CHECK_PTR( qt_desktopWidget );
3688 }
3689 return qt_desktopWidget;
3690}
3691
3692#ifndef QT_NO_CLIPBOARD
3693/*!
3694 Returns a pointer to the application global clipboard.
3695*/
3696QClipboard *QApplication::clipboard()
3697{
3698 if ( qt_clipboard == 0 ) {
3699 qt_clipboard = new QClipboard;
3700 Q_CHECK_PTR( qt_clipboard );
3701 }
3702 return qt_clipboard;
3703}
3704#endif // QT_NO_CLIPBOARD
3705
3706/*!
3707 By default, Qt will try to use the current standard colors, fonts
3708 etc., from the underlying window system's desktop settings,
3709 and use them for all relevant widgets. This behavior can be switched off
3710 by calling this function with \a on set to FALSE.
3711
3712 This static function must be called before creating the QApplication
3713 object, like this:
3714
3715 \code
3716 int main( int argc, char** argv ) {
3717 QApplication::setDesktopSettingsAware( FALSE ); // I know better than the user
3718 QApplication myApp( argc, argv ); // Use default fonts & colors
3719 ...
3720 }
3721 \endcode
3722
3723 \sa desktopSettingsAware()
3724*/
3725
3726void QApplication::setDesktopSettingsAware( bool on )
3727{
3728 obey_desktop_settings = on;
3729}
3730
3731/*!
3732 Returns the value set by setDesktopSettingsAware(); by default TRUE.
3733
3734 \sa setDesktopSettingsAware()
3735*/
3736
3737bool QApplication::desktopSettingsAware()
3738{
3739 return obey_desktop_settings;
3740}
3741
3742/*! \fn void QApplication::lock()
3743
3744 Lock the Qt Library Mutex. If another thread has already locked the
3745 mutex, the calling thread will block until the other thread has
3746 unlocked the mutex.
3747
3748 \sa unlock() locked() \link threads.html Thread Support in Qt\endlink
3749*/
3750
3751
3752/*! \fn void QApplication::unlock(bool wakeUpGui)
3753
3754 Unlock the Qt Library Mutex. If \a wakeUpGui is TRUE (the default),
3755 then the GUI thread will be woken with QApplication::wakeUpGuiThread().
3756
3757 \sa lock(), locked() \link threads.html Thread Support in Qt\endlink
3758*/
3759
3760
3761/*! \fn bool QApplication::locked()
3762
3763 Returns TRUE if the Qt Library Mutex is locked by a different thread;
3764 otherwise returns FALSE.
3765
3766 \warning Due to different implementations of recursive mutexes on
3767 the supported platforms, calling this function from the same thread
3768 that previously locked the mutex will give undefined results.
3769
3770 \sa lock() unlock() \link threads.html Thread Support in Qt\endlink
3771*/
3772
3773/*! \fn bool QApplication::tryLock()
3774
3775 Attempts to lock the Qt Library Mutex, and returns immediately. If
3776 the lock was obtained, this function returns TRUE. If another thread
3777 has locked the mutex, this function returns FALSE, instead of
3778 waiting for the lock to become available.
3779
3780 The mutex must be unlocked with unlock() before another thread can
3781 successfully lock it.
3782
3783 \sa lock(), unlock() \link threads.html Thread Support in Qt\endlink
3784*/
3785
3786#if defined(QT_THREAD_SUPPORT)
3787void QApplication::lock()
3788{
3789 qt_mutex->lock();
3790}
3791
3792void QApplication::unlock(bool wakeUpGui)
3793{
3794 qt_mutex->unlock();
3795
3796 if (wakeUpGui)
3797 wakeUpGuiThread();
3798}
3799
3800bool QApplication::locked()
3801{
3802 return qt_mutex->locked();
3803}
3804
3805bool QApplication::tryLock()
3806{
3807 return qt_mutex->tryLock();
3808}
3809#endif
3810
3811
3812/*!
3813 \fn bool QApplication::isSessionRestored() const
3814
3815 Returns TRUE if the application has been restored from an earlier
3816 \link session.html session\endlink; otherwise returns FALSE.
3817
3818 \sa sessionId(), commitData(), saveState()
3819*/
3820
3821
3822/*!
3823 \fn QString QApplication::sessionId() const
3824
3825 Returns the current \link session.html session's\endlink identifier.
3826
3827 If the application has been restored from an earlier session, this
3828 identifier is the same as it was in that previous session.
3829
3830 The session identifier is guaranteed to be unique both for different
3831 applications and for different instances of the same application.
3832
3833 \sa isSessionRestored(), sessionKey(), commitData(), saveState()
3834 */
3835
3836/*!
3837 \fn QString QApplication::sessionKey() const
3838
3839 Returns the session key in the current \link session.html
3840 session\endlink.
3841
3842 If the application has been restored from an earlier session, this
3843 key is the same as it was when the previous session ended.
3844
3845 The session key changes with every call of commitData() or
3846 saveState().
3847
3848 \sa isSessionRestored(), sessionId(), commitData(), saveState()
3849 */
3850
3851
3852/*!
3853 \fn void QApplication::commitData( QSessionManager& sm )
3854
3855 This function deals with \link session.html session
3856 management\endlink. It is invoked when the QSessionManager wants the
3857 application to commit all its data.
3858
3859 Usually this means saving all open files, after getting
3860 permission from the user. Furthermore you may want to provide a means
3861 by which the user can cancel the shutdown.
3862
3863 Note that you should not exit the application within this function.
3864 Instead, the session manager may or may not do this afterwards,
3865 depending on the context.
3866
3867 \warning Within this function, no user interaction is possible, \e
3868 unless you ask the session manager \a sm for explicit permission.
3869 See QSessionManager::allowsInteraction() and
3870 QSessionManager::allowsErrorInteraction() for details and example
3871 usage.
3872
3873 The default implementation requests interaction and sends a close
3874 event to all visible top level widgets. If any event was
3875 rejected, the shutdown is canceled.
3876
3877 \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink
3878*/
3879#ifndef QT_NO_SESSIONMANAGER
3880void QApplication::commitData( QSessionManager& sm )
3881{
3882
3883 if ( sm.allowsInteraction() ) {
3884 QWidgetList done;
3885 QWidgetList *list = QApplication::topLevelWidgets();
3886 bool cancelled = FALSE;
3887 QWidget* w = list->first();
3888 while ( !cancelled && w ) {
3889 if ( !w->isHidden() ) {
3890 QCloseEvent e;
3891 sendEvent( w, &e );
3892 cancelled = !e.isAccepted();
3893 if ( !cancelled )
3894 done.append( w );
3895 delete list; // one never knows...
3896 list = QApplication::topLevelWidgets();
3897 w = list->first();
3898 } else {
3899 w = list->next();
3900 }
3901 while ( w && done.containsRef( w ) )
3902 w = list->next();
3903 }
3904 delete list;
3905 if ( cancelled )
3906 sm.cancel();
3907 }
3908}
3909
3910
3911/*!
3912 \fn void QApplication::saveState( QSessionManager& sm )
3913
3914 This function deals with \link session.html session
3915 management\endlink. It is invoked when the
3916 \link QSessionManager session manager \endlink wants the application
3917 to preserve its state for a future session.
3918
3919 For example, a text editor would create a temporary file that
3920 includes the current contents of its edit buffers, the location of
3921 the cursor and other aspects of the current editing session.
3922
3923 Note that you should never exit the application within this
3924 function. Instead, the session manager may or may not do this
3925 afterwards, depending on the context. Futhermore, most session
3926 managers will very likely request a saved state immediately after
3927 the application has been started. This permits the session manager
3928 to learn about the application's restart policy.
3929
3930 \warning Within this function, no user interaction is possible, \e
3931 unless you ask the session manager \a sm for explicit permission.
3932 See QSessionManager::allowsInteraction() and
3933 QSessionManager::allowsErrorInteraction() for details.
3934
3935 \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink
3936*/
3937
3938void QApplication::saveState( QSessionManager& /* sm */ )
3939{
3940}
3941#endif //QT_NO_SESSIONMANAGER
3942/*!
3943 Sets the time after which a drag should start to \a ms ms.
3944
3945 \sa startDragTime()
3946*/
3947
3948void QApplication::setStartDragTime( int ms )
3949{
3950 drag_time = ms;
3951}
3952
3953/*!
3954 If you support drag and drop in you application and a drag should
3955 start after a mouse click and after a certain time elapsed, you
3956 should use the value which this method returns as the delay (in ms).
3957
3958 Qt also uses this delay internally, e.g. in QTextEdit and QLineEdit,
3959 for starting a drag.
3960
3961 The default value is 500 ms.
3962
3963 \sa setStartDragTime(), startDragDistance()
3964*/
3965
3966int QApplication::startDragTime()
3967{
3968 return drag_time;
3969}
3970
3971/*!
3972 Sets the distance after which a drag should start to \a l pixels.
3973
3974 \sa startDragDistance()
3975*/
3976
3977void QApplication::setStartDragDistance( int l )
3978{
3979 drag_distance = l;
3980}
3981
3982/*!
3983 If you support drag and drop in you application and a drag should
3984 start after a mouse click and after moving the mouse a certain
3985 distance, you should use the value which this method returns as the
3986 distance.
3987
3988 For example, if the mouse position of the click is stored in \c
3989 startPos and the current position (e.g. in the mouse move event) is
3990 \c currPos, you can find out if a drag should be started with code
3991 like this:
3992 \code
3993 if ( ( startPos - currPos ).manhattanLength() >
3994 QApplication::startDragDistance() )
3995 startTheDrag();
3996 \endcode
3997
3998 Qt uses this value internally, e.g. in QFileDialog.
3999
4000 The default value is 4 pixels.
4001
4002 \sa setStartDragDistance(), startDragTime(), QPoint::manhattanLength()
4003*/
4004
4005int QApplication::startDragDistance()
4006{
4007 return drag_distance;
4008}
4009
4010/*!
4011 If \a b is TRUE, all dialogs and widgets will be laid out in a
4012 mirrored fashion, as required by right to left languages such as
4013 Arabic and Hebrew. If \a b is FALSE, dialogs and widgets are laid
4014 out left to right.
4015
4016 Changing this flag in runtime does not cause a relayout of already
4017 instantiated widgets.
4018
4019 \sa reverseLayout()
4020*/
4021void QApplication::setReverseLayout( bool b )
4022{
4023 if ( reverse_layout == b )
4024 return;
4025
4026 reverse_layout = b;
4027
4028 QWidgetList *list = topLevelWidgets();
4029 QWidgetListIt it( *list );
4030 QWidget *w;
4031 while ( ( w=it.current() ) != 0 ) {
4032 ++it;
4033 postEvent( w, new QEvent( QEvent::LayoutDirectionChange ) );
4034 }
4035 delete list;
4036}
4037
4038/*!
4039 Returns TRUE if all dialogs and widgets will be laid out in a
4040 mirrored (right to left) fashion. Returns FALSE if dialogs and
4041 widgets will be laid out left to right.
4042
4043 \sa setReverseLayout()
4044*/
4045bool QApplication::reverseLayout()
4046{
4047 return reverse_layout;
4048}
4049
4050
4051/*!
4052 \class QSessionManager qsessionmanager.h
4053 \brief The QSessionManager class provides access to the session manager.
4054
4055 \ingroup application
4056 \ingroup environment
4057
4058 The session manager is responsible for session management, most
4059 importantly for interruption and resumption. A "session" is a kind
4060 of record of the state of the system, e.g. which applications were
4061 run at start up and which applications are currently running. The
4062 session manager is used to save the session, e.g. when the machine
4063 is shut down; and to restore a session, e.g. when the machine is
4064 started up. Use QSettings to save and restore an individual
4065 application's settings, e.g. window positions, recently used files,
4066 etc.
4067
4068 QSessionManager provides an interface between the application and
4069 the session manager so that the program can work well with the
4070 session manager. In Qt, session management requests for action
4071 are handled by the two virtual functions QApplication::commitData()
4072 and QApplication::saveState(). Both provide a reference to
4073 a session manager object as argument, to allow the application
4074 to communicate with the session manager.
4075
4076 During a session management action (i.e. within commitData() and
4077 saveState()), no user interaction is possible \e unless the
4078 application got explicit permission from the session manager. You
4079 ask for permission by calling allowsInteraction() or, if it's really
4080 urgent, allowsErrorInteraction(). Qt does not enforce this, but the
4081 session manager may.
4082
4083 You can try to abort the shutdown process by calling cancel(). The
4084 default commitData() function does this if some top-level window
4085 rejected its closeEvent().
4086
4087 For sophisticated session managers provided on Unix/X11, QSessionManager
4088 offers further possibilites to fine-tune an application's session
4089 management behavior: setRestartCommand(), setDiscardCommand(),
4090 setRestartHint(), setProperty(), requestPhase2(). See the respective
4091 function descriptions for further details.
4092*/
4093
4094/*! \enum QSessionManager::RestartHint
4095
4096 This enum type defines the circumstances under which this
4097 application wants to be restarted by the session manager. The
4098 current values are
4099
4100 \value RestartIfRunning if the application is still running when
4101 the session is shut down, it wants to be restarted at the start of
4102 the next session.
4103
4104 \value RestartAnyway the application wants to be started at the
4105 start of the next session, no matter what. (This is useful for
4106 utilities that run just after startup and then quit.)
4107
4108 \value RestartImmediately the application wants to be started
4109 immediately whenever it is not running.
4110
4111 \value RestartNever the application does not want to be restarted
4112 automatically.
4113
4114 The default hint is \c RestartIfRunning.
4115*/
4116
4117
4118/*!
4119 \fn QString QSessionManager::sessionId() const
4120
4121 Returns the identifier of the current session.
4122
4123 If the application has been restored from an earlier session, this
4124 identifier is the same as it was in that earlier session.
4125
4126 \sa sessionKey(), QApplication::sessionId()
4127 */
4128
4129/*!
4130 \fn QString QSessionManager::sessionKey() const
4131
4132 Returns the session key in the current session.
4133
4134 If the application has been restored from an earlier session, this
4135 key is the same as it was when the previous session ended.
4136
4137 The session key changes with every call of commitData() or
4138 saveState().
4139
4140 \sa sessionId(), QApplication::sessionKey()
4141 */
4142
4143// ### Note: This function is undocumented, since it is #ifdef'd.
4144
4145/*!
4146 \fn void* QSessionManager::handle() const
4147
4148 X11 only: returns a handle to the current \c SmcConnection.
4149*/
4150
4151
4152/*!
4153 \fn bool QSessionManager::allowsInteraction()
4154
4155 Asks the session manager for permission to interact with the
4156 user. Returns TRUE if interaction is permitted; otherwise
4157 returns FALSE.
4158
4159 The rationale behind this mechanism is to make it possible to
4160 synchronize user interaction during a shutdown. Advanced session
4161 managers may ask all applications simultaneously to commit their
4162 data, resulting in a much faster shutdown.
4163
4164 When the interaction is completed we strongly recommend releasing the
4165 user interaction semaphore with a call to release(). This way, other
4166 applications may get the chance to interact with the user while your
4167 application is still busy saving data. (The semaphore is implicitly
4168 released when the application exits.)
4169
4170 If the user decides to cancel the shutdown process during the
4171 interaction phase, you must tell the session manager that this has
4172 happened by calling cancel().
4173
4174 Here's an example of how an application's QApplication::commitData()
4175 might be implemented:
4176
4177\code
4178void MyApplication::commitData( QSessionManager& sm ) {
4179 if ( sm.allowsInteraction() ) {
4180 switch ( QMessageBox::warning(
4181 yourMainWindow,
4182 tr("Application Name"),
4183 tr("Save changes to document Foo?"),
4184 tr("&Yes"),
4185 tr("&No"),
4186 tr("Cancel"),
4187 0, 2) ) {
4188 case 0: // yes
4189 sm.release();
4190 // save document here; if saving fails, call sm.cancel()
4191 break;
4192 case 1: // continue without saving
4193 break;
4194 default: // cancel
4195 sm.cancel();
4196 break;
4197 }
4198 } else {
4199 // we did not get permission to interact, then
4200 // do something reasonable instead.
4201 }
4202}
4203\endcode
4204
4205 If an error occurred within the application while saving its data,
4206 you may want to try allowsErrorInteraction() instead.
4207
4208 \sa QApplication::commitData(), release(), cancel()
4209*/
4210
4211
4212/*!
4213 \fn bool QSessionManager::allowsErrorInteraction()
4214
4215 This is similar to allowsInteraction(), but also tells the session
4216 manager that an error occurred. Session managers may give error
4217 interaction request higher priority, which means that it is more likely
4218 that an error interaction is permitted. However, you are still not
4219 guaranteed that the session manager will allow interaction.
4220
4221 \sa allowsInteraction(), release(), cancel()
4222*/
4223
4224/*!
4225 \fn void QSessionManager::release()
4226
4227 Releases the session manager's interaction semaphore after an
4228 interaction phase.
4229
4230 \sa allowsInteraction(), allowsErrorInteraction()
4231*/
4232
4233/*!
4234 \fn void QSessionManager::cancel()
4235
4236 Tells the session manager to cancel the shutdown process. Applications
4237 should not call this function without first asking the user.
4238
4239 \sa allowsInteraction(), allowsErrorInteraction()
4240
4241*/
4242
4243/*!
4244 \fn void QSessionManager::setRestartHint( RestartHint hint )
4245
4246 Sets the application's restart hint to \a hint. On application
4247 startup the hint is set to \c RestartIfRunning.
4248
4249 Note that these flags are only hints, a session manager may or may
4250 not respect them.
4251
4252 We recommend setting the restart hint in QApplication::saveState()
4253 because most session managers perform a checkpoint shortly after an
4254 application's startup.
4255
4256 \sa restartHint()
4257*/
4258
4259/*!
4260 \fn QSessionManager::RestartHint QSessionManager::restartHint() const
4261
4262 Returns the application's current restart hint. The default is
4263 \c RestartIfRunning.
4264
4265 \sa setRestartHint()
4266*/
4267
4268/*!
4269 \fn void QSessionManager::setRestartCommand( const QStringList& command )
4270
4271 If the session manager is capable of restoring sessions it will
4272 execute \a command in order to restore the application. The command
4273 defaults to
4274
4275 \code
4276 appname -session id
4277 \endcode
4278
4279 The \c -session option is mandatory; otherwise QApplication cannot
4280 tell whether it has been restored or what the current session
4281 identifier is. See QApplication::isSessionRestored() and
4282 QApplication::sessionId() for details.
4283
4284 If your application is very simple, it may be possible to store the
4285 entire application state in additional command line options. This
4286 is usually a very bad idea because command lines are often limited
4287 to a few hundred bytes. Instead, use QSettings, or temporary files
4288 or a database for this purpose. By marking the data with the unique
4289 sessionId(), you will be able to restore the application in a future
4290 session.
4291
4292 \sa restartCommand(), setDiscardCommand(), setRestartHint()
4293*/
4294
4295/*!
4296 \fn QStringList QSessionManager::restartCommand() const
4297
4298 Returns the currently set restart command.
4299
4300 Note that if you want to iterate over the list, you should
4301 iterate over a copy, e.g.
4302 \code
4303 QStringList list = mySession.restartCommand();
4304 QStringList::Iterator it = list.begin();
4305 while( it != list.end() ) {
4306 myProcessing( *it );
4307 ++it;
4308 }
4309 \endcode
4310
4311 \sa setRestartCommand(), restartHint()
4312*/
4313
4314/*!
4315 \fn void QSessionManager::setDiscardCommand( const QStringList& )
4316
4317 \sa discardCommand(), setRestartCommand()
4318*/
4319
4320
4321/*!
4322 \fn QStringList QSessionManager::discardCommand() const
4323
4324 Returns the currently set discard command.
4325
4326 Note that if you want to iterate over the list, you should
4327 iterate over a copy, e.g.
4328 \code
4329 QStringList list = mySession.discardCommand();
4330 QStringList::Iterator it = list.begin();
4331 while( it != list.end() ) {
4332 myProcessing( *it );
4333 ++it;
4334 }
4335 \endcode
4336
4337 \sa setDiscardCommand(), restartCommand(), setRestartCommand()
4338*/
4339
4340/*!
4341 \overload void QSessionManager::setManagerProperty( const QString& name,
4342 const QString& value )
4343
4344 Low-level write access to the application's identification and state
4345 records are kept in the session manager.
4346
4347 The property called \a name has its value set to the string \a value.
4348*/
4349
4350/*!
4351 \fn void QSessionManager::setManagerProperty( const QString& name,
4352 const QStringList& value )
4353
4354 Low-level write access to the application's identification and state
4355 record are kept in the session manager.
4356
4357 The property called \a name has its value set to the string list \a value.
4358*/
4359
4360/*!
4361 \fn bool QSessionManager::isPhase2() const
4362
4363 Returns TRUE if the session manager is currently performing a second
4364 session management phase; otherwise returns FALSE.
4365
4366 \sa requestPhase2()
4367*/
4368
4369/*!
4370 \fn void QSessionManager::requestPhase2()
4371
4372 Requests a second session management phase for the application. The
4373 application may then return immediately from the
4374 QApplication::commitData() or QApplication::saveState() function,
4375 and they will be called again once most or all other applications have
4376 finished their session management.
4377
4378 The two phases are useful for applications such as the X11 window manager
4379 that need to store information about another application's windows
4380 and therefore have to wait until these applications have completed their
4381 respective session management tasks.
4382
4383 Note that if another application has requested a second phase it
4384 may get called before, simultaneously with, or after your
4385 application's second phase.
4386
4387 \sa isPhase2()
4388*/
4389
4390/*!
4391 \fn int QApplication::horizontalAlignment( int align )
4392
4393 Strips out vertical alignment flags and transforms an
4394 alignment \a align of AlignAuto into AlignLeft or
4395 AlignRight according to the language used. The other horizontal
4396 alignment flags are left untouched.
4397*/
4398
4399
4400/*****************************************************************************
4401 Stubbed session management support
4402 *****************************************************************************/
4403#ifndef QT_NO_SESSIONMANAGER
4404#if defined( QT_NO_SM_SUPPORT ) || defined( Q_WS_WIN ) || defined( Q_WS_MAC ) || defined( Q_WS_QWS ) || defined( Q_WS_PM )
4405
4406class QSessionManagerData
4407{
4408public:
4409 QStringList restartCommand;
4410 QStringList discardCommand;
4411 QString sessionId;
4412 QString sessionKey;
4413 QSessionManager::RestartHint restartHint;
4414};
4415
4416QSessionManager* qt_session_manager_self = 0;
4417QSessionManager::QSessionManager( QApplication * app, QString &id, QString &key )
4418 : QObject( app, "qt_sessionmanager" )
4419{
4420 qt_session_manager_self = this;
4421 d = new QSessionManagerData;
4422#if defined(Q_WS_WIN) && !defined(Q_OS_TEMP)
4423 wchar_t guidstr[40];
4424 GUID guid;
4425 CoCreateGuid( &guid );
4426 StringFromGUID2(guid, guidstr, 40);
4427 id = QString::fromUcs2((ushort*)guidstr);
4428 CoCreateGuid( &guid );
4429 StringFromGUID2(guid, guidstr, 40);
4430 key = QString::fromUcs2((ushort*)guidstr);
4431#endif
4432 d->sessionId = id;
4433 d->sessionKey = key;
4434 d->restartHint = RestartIfRunning;
4435}
4436
4437QSessionManager::~QSessionManager()
4438{
4439 delete d;
4440 qt_session_manager_self = 0;
4441}
4442
4443QString QSessionManager::sessionId() const
4444{
4445 return d->sessionId;
4446}
4447
4448QString QSessionManager::sessionKey() const
4449{
4450 return d->sessionKey;
4451}
4452
4453
4454#if defined(Q_WS_X11) || defined(Q_WS_MAC)
4455void* QSessionManager::handle() const
4456{
4457 return 0;
4458}
4459#endif
4460
4461#if !defined(Q_WS_WIN) && !defined(Q_WS_PM)
4462bool QSessionManager::allowsInteraction()
4463{
4464 return TRUE;
4465}
4466
4467bool QSessionManager::allowsErrorInteraction()
4468{
4469 return TRUE;
4470}
4471void QSessionManager::release()
4472{
4473}
4474
4475void QSessionManager::cancel()
4476{
4477}
4478#endif
4479
4480
4481void QSessionManager::setRestartHint( QSessionManager::RestartHint hint)
4482{
4483 d->restartHint = hint;
4484}
4485
4486QSessionManager::RestartHint QSessionManager::restartHint() const
4487{
4488 return d->restartHint;
4489}
4490
4491void QSessionManager::setRestartCommand( const QStringList& command)
4492{
4493 d->restartCommand = command;
4494}
4495
4496QStringList QSessionManager::restartCommand() const
4497{
4498 return d->restartCommand;
4499}
4500
4501void QSessionManager::setDiscardCommand( const QStringList& command)
4502{
4503 d->discardCommand = command;
4504}
4505
4506QStringList QSessionManager::discardCommand() const
4507{
4508 return d->discardCommand;
4509}
4510
4511void QSessionManager::setManagerProperty( const QString&, const QString&)
4512{
4513}
4514
4515void QSessionManager::setManagerProperty( const QString&, const QStringList& )
4516{
4517}
4518
4519bool QSessionManager::isPhase2() const
4520{
4521 return FALSE;
4522}
4523
4524void QSessionManager::requestPhase2()
4525{
4526}
4527
4528#endif // QT_NO_SM_SUPPORT
4529#endif //QT_NO_SESSIONMANAGER
Note: See TracBrowser for help on using the repository browser.