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

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

Kernel: Fixed: Don't forget to unPolish() the currently active style on application termination (QApplication destruction).

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