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

Last change on this file since 108 was 77, checked in by dmik, 19 years ago

Implemented the OS/2 version of the QSessionManager class (see ticket:15 for more details); QT_NO_SESSIONMANAGER is no more defined by default.

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