source: vendor/trolltech/current/src/kernel/qapplication.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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