source: trunk/src/kernel/qapplication.cpp

Last change on this file was 180, checked in by dmik, 17 years ago

kernel: Make sure that eventloop is cleaned up after all post-routines (that may still use some eventloop services such as timers) are called and that start timer requests are ignored after the eventloop has been cleaned up during application termination. This fixes assertions and crashes that might have happened at program termination otherwise.

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