| 1 | /****************************************************************************
 | 
|---|
| 2 | ** $Id: qdialog.cpp 2 2005-11-16 15:49:26Z dmik $
 | 
|---|
| 3 | **
 | 
|---|
| 4 | ** Implementation of QDialog class
 | 
|---|
| 5 | **
 | 
|---|
| 6 | ** Created : 950502
 | 
|---|
| 7 | **
 | 
|---|
| 8 | ** Copyright (C) 1992-2002 Trolltech AS.  All rights reserved.
 | 
|---|
| 9 | **
 | 
|---|
| 10 | ** This file is part of the dialogs 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 "qdialog.h"
 | 
|---|
| 39 | 
 | 
|---|
| 40 | #ifndef QT_NO_DIALOG
 | 
|---|
| 41 | 
 | 
|---|
| 42 | #include "qpushbutton.h"
 | 
|---|
| 43 | #include "qfocusdata.h"
 | 
|---|
| 44 | #include "qapplication.h"
 | 
|---|
| 45 | #include "qobjectlist.h"
 | 
|---|
| 46 | #include "qwidgetlist.h"
 | 
|---|
| 47 | #include "qlayout.h"
 | 
|---|
| 48 | #include "qsizegrip.h"
 | 
|---|
| 49 | #include "qwhatsthis.h"
 | 
|---|
| 50 | #include "qpopupmenu.h"
 | 
|---|
| 51 | #include "qcursor.h"
 | 
|---|
| 52 | #if defined(QT_ACCESSIBILITY_SUPPORT)
 | 
|---|
| 53 | #include "qaccessible.h"
 | 
|---|
| 54 | #endif
 | 
|---|
| 55 | #if defined( Q_OS_TEMP )
 | 
|---|
| 56 | #include "qt_windows.h"
 | 
|---|
| 57 | #endif
 | 
|---|
| 58 | 
 | 
|---|
| 59 | /*!
 | 
|---|
| 60 |     \class QDialog
 | 
|---|
| 61 |     \brief The QDialog class is the base class of dialog windows.
 | 
|---|
| 62 | 
 | 
|---|
| 63 |     \ingroup dialogs
 | 
|---|
| 64 |     \ingroup abstractwidgets
 | 
|---|
| 65 |     \mainclass
 | 
|---|
| 66 | 
 | 
|---|
| 67 |     A dialog window is a top-level window mostly used for short-term
 | 
|---|
| 68 |     tasks and brief communications with the user. QDialogs may be
 | 
|---|
| 69 |     modal or modeless. QDialogs support \link #extensibility
 | 
|---|
| 70 |     extensibility\endlink and can provide a \link #return return
 | 
|---|
| 71 |     value\endlink. They can have \link #default default
 | 
|---|
| 72 |     buttons\endlink. QDialogs can also have a QSizeGrip in their
 | 
|---|
| 73 |     lower-right corner, using setSizeGripEnabled().
 | 
|---|
| 74 | 
 | 
|---|
| 75 |     Note that QDialog uses the parent widget slightly differently from
 | 
|---|
| 76 |     other classes in Qt. A dialog is always a top-level widget, but if
 | 
|---|
| 77 |     it has a parent, its default location is centered on top of the
 | 
|---|
| 78 |     parent's top-level widget (if it is not top-level itself). It will
 | 
|---|
| 79 |     also share the parent's taskbar entry.
 | 
|---|
| 80 | 
 | 
|---|
| 81 |     \target modal
 | 
|---|
| 82 |     \section1 Modal Dialogs
 | 
|---|
| 83 | 
 | 
|---|
| 84 |     A <b>modal</b> dialog is a dialog that blocks input to other
 | 
|---|
| 85 |     visible windows in the same application. Users must finish
 | 
|---|
| 86 |     interacting with the dialog and close it before they can access
 | 
|---|
| 87 |     any other window in the application. Dialogs that are used to
 | 
|---|
| 88 |     request a file name from the user or that are used to set
 | 
|---|
| 89 |     application preferences are usually modal.
 | 
|---|
| 90 | 
 | 
|---|
| 91 |     The most common way to display a modal dialog is to call its
 | 
|---|
| 92 |     exec() function. When the user closes the dialog, exec() will
 | 
|---|
| 93 |     provide a useful \link #return return value\endlink. Typically we
 | 
|---|
| 94 |     connect a default button, e.g. "OK", to the accept() slot and a
 | 
|---|
| 95 |     "Cancel" button to the reject() slot, to get the dialog to close
 | 
|---|
| 96 |     and return the appropriate value. Alternatively you can connect to
 | 
|---|
| 97 |     the done() slot, passing it \c Accepted or \c Rejected.
 | 
|---|
| 98 | 
 | 
|---|
| 99 |     An alternative is to call setModal(TRUE), then show(). Unlike
 | 
|---|
| 100 |     exec(), show() returns control to the caller immediately. Calling
 | 
|---|
| 101 |     setModal(TRUE) is especially useful for progress dialogs, where
 | 
|---|
| 102 |     the user must have the ability to interact with the dialog, e.g.
 | 
|---|
| 103 |     to cancel a long running operation. If you use show() and
 | 
|---|
| 104 |     setModal(TRUE) together you must call
 | 
|---|
| 105 |     QApplication::processEvents() periodically during processing to
 | 
|---|
| 106 |     enable the user to interact with the dialog. (See \l
 | 
|---|
| 107 |     QProgressDialog.)
 | 
|---|
| 108 | 
 | 
|---|
| 109 |     \target modeless
 | 
|---|
| 110 |     \section1 Modeless Dialogs
 | 
|---|
| 111 | 
 | 
|---|
| 112 |     A <b>modeless</b> dialog is a dialog that operates
 | 
|---|
| 113 |     independently of other windows in the same application. Find and
 | 
|---|
| 114 |     replace dialogs in word-processors are often modeless to allow the
 | 
|---|
| 115 |     user to interact with both the application's main window and with
 | 
|---|
| 116 |     the dialog.
 | 
|---|
| 117 | 
 | 
|---|
| 118 |     Modeless dialogs are displayed using show(), which returns control
 | 
|---|
| 119 |     to the caller immediately.
 | 
|---|
| 120 | 
 | 
|---|
| 121 |     \target default
 | 
|---|
| 122 |     \section1 Default button
 | 
|---|
| 123 | 
 | 
|---|
| 124 |     A dialog's \e default button is the button that's pressed when the
 | 
|---|
| 125 |     user presses Enter (Return). This button is used to signify that
 | 
|---|
| 126 |     the user accepts the dialog's settings and wants to close the
 | 
|---|
| 127 |     dialog. Use QPushButton::setDefault(), QPushButton::isDefault()
 | 
|---|
| 128 |     and QPushButton::autoDefault() to set and control the dialog's
 | 
|---|
| 129 |     default button.
 | 
|---|
| 130 | 
 | 
|---|
| 131 |     \target escapekey
 | 
|---|
| 132 |     \section1 Escape Key
 | 
|---|
| 133 | 
 | 
|---|
| 134 |     If the user presses the Esc key in a dialog, QDialog::reject()
 | 
|---|
| 135 |     will be called. This will cause the window to close: the \link
 | 
|---|
| 136 |     QCloseEvent closeEvent \endlink cannot be \link
 | 
|---|
| 137 |     QCloseEvent::ignore() ignored \endlink.
 | 
|---|
| 138 | 
 | 
|---|
| 139 |     \target extensibility
 | 
|---|
| 140 |     \section1 Extensibility
 | 
|---|
| 141 | 
 | 
|---|
| 142 |     Extensibility is the ability to show the dialog in two ways: a
 | 
|---|
| 143 |     partial dialog that shows the most commonly used options, and a
 | 
|---|
| 144 |     full dialog that shows all the options. Typically an extensible
 | 
|---|
| 145 |     dialog will initially appear as a partial dialog, but with a
 | 
|---|
| 146 |     "More" toggle button. If the user presses the "More" button down,
 | 
|---|
| 147 |     the full dialog will appear. The extension widget will be resized
 | 
|---|
| 148 |     to its sizeHint(). If orientation is \c Horizontal the extension
 | 
|---|
| 149 |     widget's height() will be expanded to the height() of the dialog.
 | 
|---|
| 150 |     If the orientation is \c Vertical the extension widget's width()
 | 
|---|
| 151 |     will be expanded to the width() of the dialog. Extensibility is
 | 
|---|
| 152 |     controlled with setExtension(), setOrientation() and
 | 
|---|
| 153 |     showExtension().
 | 
|---|
| 154 | 
 | 
|---|
| 155 |     \target return
 | 
|---|
| 156 |     \section1 Return value (modal dialogs)
 | 
|---|
| 157 | 
 | 
|---|
| 158 |     Modal dialogs are often used in situations where a return value is
 | 
|---|
| 159 |     required, e.g. to indicate whether the user pressed "OK" or
 | 
|---|
| 160 |     "Cancel". A dialog can be closed by calling the accept() or the
 | 
|---|
| 161 |     reject() slots, and exec() will return \c Accepted or \c Rejected
 | 
|---|
| 162 |     as appropriate. The exec() call returns the result of the dialog.
 | 
|---|
| 163 |     The result is also available from result() if the dialog has not
 | 
|---|
| 164 |     been destroyed. If the \c WDestructiveClose flag is set, the
 | 
|---|
| 165 |     dialog is deleted after exec() returns.
 | 
|---|
| 166 | 
 | 
|---|
| 167 |     \target examples
 | 
|---|
| 168 |     \section1 Examples
 | 
|---|
| 169 | 
 | 
|---|
| 170 |     A modal dialog.
 | 
|---|
| 171 | 
 | 
|---|
| 172 |     \quotefile network/networkprotocol/view.cpp
 | 
|---|
| 173 |     \skipto QFileDialog *dlg
 | 
|---|
| 174 |     \printuntil return
 | 
|---|
| 175 | 
 | 
|---|
| 176 |     A modeless dialog. After the show() call, control returns to the main
 | 
|---|
| 177 |     event loop.
 | 
|---|
| 178 |     \quotefile life/main.cpp
 | 
|---|
| 179 |     \skipto argv
 | 
|---|
| 180 |     \printuntil QApplication
 | 
|---|
| 181 |     \skipto scale
 | 
|---|
| 182 |     \printline
 | 
|---|
| 183 |     \skipto LifeDialog
 | 
|---|
| 184 |     \printuntil show
 | 
|---|
| 185 |     \skipto exec
 | 
|---|
| 186 |     \printuntil }
 | 
|---|
| 187 | 
 | 
|---|
| 188 |     \sa QTabDialog QWidget QProgressDialog
 | 
|---|
| 189 |     \link guibooks.html#fowler GUI Design Handbook: Dialogs, Standard\endlink
 | 
|---|
| 190 | */
 | 
|---|
| 191 | 
 | 
|---|
| 192 | /*! \enum QDialog::DialogCode
 | 
|---|
| 193 | 
 | 
|---|
| 194 |     The value returned by a modal dialog.
 | 
|---|
| 195 | 
 | 
|---|
| 196 |     \value Accepted
 | 
|---|
| 197 |     \value Rejected
 | 
|---|
| 198 | 
 | 
|---|
| 199 | */
 | 
|---|
| 200 | 
 | 
|---|
| 201 | /*!
 | 
|---|
| 202 |   \property QDialog::sizeGripEnabled
 | 
|---|
| 203 |   \brief whether the size grip is enabled
 | 
|---|
| 204 | 
 | 
|---|
| 205 |   A QSizeGrip is placed in the bottom right corner of the dialog when this
 | 
|---|
| 206 |   property is enabled. By default, the size grip is disabled.
 | 
|---|
| 207 | */
 | 
|---|
| 208 | 
 | 
|---|
| 209 | class QDialogPrivate : public Qt
 | 
|---|
| 210 | {
 | 
|---|
| 211 | public:
 | 
|---|
| 212 | 
 | 
|---|
| 213 |     QDialogPrivate()
 | 
|---|
| 214 |         : mainDef(0), orientation(Horizontal),extension(0), doShowExtension(FALSE)
 | 
|---|
| 215 | #ifndef QT_NO_SIZEGRIP
 | 
|---|
| 216 |         ,resizer(0)
 | 
|---|
| 217 | #endif
 | 
|---|
| 218 |         {
 | 
|---|
| 219 |     }
 | 
|---|
| 220 | 
 | 
|---|
| 221 |     QPushButton* mainDef;
 | 
|---|
| 222 |     Orientation orientation;
 | 
|---|
| 223 |     QWidget* extension;
 | 
|---|
| 224 |     bool doShowExtension;
 | 
|---|
| 225 |     QSize size, min, max;
 | 
|---|
| 226 | #ifndef QT_NO_SIZEGRIP
 | 
|---|
| 227 |     QSizeGrip* resizer;
 | 
|---|
| 228 | #endif
 | 
|---|
| 229 |     QPoint lastRMBPress;
 | 
|---|
| 230 |     QPoint relPos; // relative position to the main window
 | 
|---|
| 231 | };
 | 
|---|
| 232 | 
 | 
|---|
| 233 | /*!
 | 
|---|
| 234 |   Constructs a dialog called \a name, with parent \a parent.
 | 
|---|
| 235 | 
 | 
|---|
| 236 |   A dialog is always a top-level widget, but if it has a parent, its
 | 
|---|
| 237 |   default location is centered on top of the parent. It will also
 | 
|---|
| 238 |   share the parent's taskbar entry.
 | 
|---|
| 239 | 
 | 
|---|
| 240 |   The widget flags \a f are passed on to the QWidget constructor.
 | 
|---|
| 241 |   If, for example, you don't want a What's This button in the titlebar
 | 
|---|
| 242 |   of the dialog, pass WStyle_Customize | WStyle_NormalBorder |
 | 
|---|
| 243 |   WStyle_Title | WStyle_SysMenu in \a f.
 | 
|---|
| 244 | 
 | 
|---|
| 245 |   \warning In Qt 3.2, the \a modal flag is obsolete. There is now a
 | 
|---|
| 246 |   setModal() function that can be used for obtaining a modal behavior
 | 
|---|
| 247 |   when calling show(). This is rarely needed, because modal dialogs
 | 
|---|
| 248 |   are usually invoked using exec(), which ignores the \a modal flag.
 | 
|---|
| 249 | 
 | 
|---|
| 250 |   \sa QWidget::setWFlags() Qt::WidgetFlags
 | 
|---|
| 251 | */
 | 
|---|
| 252 | 
 | 
|---|
| 253 | QDialog::QDialog( QWidget *parent, const char *name, bool modal, WFlags f )
 | 
|---|
| 254 |     : QWidget( parent, name,
 | 
|---|
| 255 |                (modal ? (f|WShowModal) : f) | WType_Dialog ),
 | 
|---|
| 256 |       rescode(0), did_move(0), has_relpos(0), did_resize(0), in_loop(0)
 | 
|---|
| 257 | {
 | 
|---|
| 258 |     d = new QDialogPrivate;
 | 
|---|
| 259 | }
 | 
|---|
| 260 | 
 | 
|---|
| 261 | /*!
 | 
|---|
| 262 |   Destroys the QDialog, deleting all its children.
 | 
|---|
| 263 | */
 | 
|---|
| 264 | 
 | 
|---|
| 265 | QDialog::~QDialog()
 | 
|---|
| 266 | {
 | 
|---|
| 267 |     // Need to hide() here, as our (to-be) overridden hide()
 | 
|---|
| 268 |     // will not be called in ~QWidget.
 | 
|---|
| 269 |     hide();
 | 
|---|
| 270 |     delete d;
 | 
|---|
| 271 | }
 | 
|---|
| 272 | 
 | 
|---|
| 273 | /*!
 | 
|---|
| 274 |   \internal
 | 
|---|
| 275 |   This function is called by the push button \a pushButton when it
 | 
|---|
| 276 |   becomes the default button. If \a pushButton is 0, the dialogs
 | 
|---|
| 277 |   default default button becomes the default button. This is what a
 | 
|---|
| 278 |   push button calls when it loses focus.
 | 
|---|
| 279 | */
 | 
|---|
| 280 | 
 | 
|---|
| 281 | void QDialog::setDefault( QPushButton *pushButton )
 | 
|---|
| 282 | {
 | 
|---|
| 283 | #ifndef QT_NO_PUSHBUTTON
 | 
|---|
| 284 |     QObjectList *list = queryList( "QPushButton" );
 | 
|---|
| 285 |     Q_ASSERT(list);
 | 
|---|
| 286 |     QObjectListIt it( *list );
 | 
|---|
| 287 |     QPushButton *pb;
 | 
|---|
| 288 |     bool hasMain = FALSE;
 | 
|---|
| 289 |     while ( (pb = (QPushButton*)it.current()) ) {
 | 
|---|
| 290 |         ++it;
 | 
|---|
| 291 |         if ( pb->topLevelWidget() != this )
 | 
|---|
| 292 |             continue;
 | 
|---|
| 293 |         if ( pb == d->mainDef )
 | 
|---|
| 294 |             hasMain = TRUE;
 | 
|---|
| 295 |         if ( pb != pushButton )
 | 
|---|
| 296 |             pb->setDefault( FALSE );
 | 
|---|
| 297 |     }
 | 
|---|
| 298 |     if (!pushButton && hasMain)
 | 
|---|
| 299 |         d->mainDef->setDefault( TRUE );
 | 
|---|
| 300 |     if (!hasMain)
 | 
|---|
| 301 |         d->mainDef = pushButton;
 | 
|---|
| 302 |     delete list;
 | 
|---|
| 303 | #endif
 | 
|---|
| 304 | }
 | 
|---|
| 305 | 
 | 
|---|
| 306 | /*!
 | 
|---|
| 307 |   \internal
 | 
|---|
| 308 |   This function sets the default default pushbutton to \a pushButton.
 | 
|---|
| 309 |   This function is called by QPushButton::setDefault().
 | 
|---|
| 310 | */
 | 
|---|
| 311 | void QDialog::setMainDefault( QPushButton *pushButton )
 | 
|---|
| 312 | {
 | 
|---|
| 313 | #ifndef QT_NO_PUSHBUTTON
 | 
|---|
| 314 |     d->mainDef = 0;
 | 
|---|
| 315 |     setDefault(pushButton);
 | 
|---|
| 316 | #endif
 | 
|---|
| 317 | }
 | 
|---|
| 318 | 
 | 
|---|
| 319 | /*!
 | 
|---|
| 320 |   \internal
 | 
|---|
| 321 |   Hides the default button indicator. Called when non auto-default
 | 
|---|
| 322 |   push button get focus.
 | 
|---|
| 323 |  */
 | 
|---|
| 324 | void QDialog::hideDefault()
 | 
|---|
| 325 | {
 | 
|---|
| 326 | #ifndef QT_NO_PUSHBUTTON
 | 
|---|
| 327 |     QObjectList *list = queryList( "QPushButton" );
 | 
|---|
| 328 |     QObjectListIt it( *list );
 | 
|---|
| 329 |     QPushButton *pb;
 | 
|---|
| 330 |     while ( (pb = (QPushButton*)it.current()) ) {
 | 
|---|
| 331 |         ++it;
 | 
|---|
| 332 |         pb->setDefault( FALSE );
 | 
|---|
| 333 |     }
 | 
|---|
| 334 |     delete list;
 | 
|---|
| 335 | #endif
 | 
|---|
| 336 | }
 | 
|---|
| 337 | 
 | 
|---|
| 338 | #ifdef Q_OS_TEMP
 | 
|---|
| 339 | /*!
 | 
|---|
| 340 |   \internal
 | 
|---|
| 341 |   Hides special buttons which are rather shown in the titlebar
 | 
|---|
| 342 |   on WinCE, to conserve screen space.
 | 
|---|
| 343 | */
 | 
|---|
| 344 | # include "qmessagebox.h"
 | 
|---|
| 345 | extern const char * mb_texts[]; // Defined in qmessagebox.cpp
 | 
|---|
| 346 | void QDialog::hideSpecial()
 | 
|---|
| 347 | {
 | 
|---|
| 348 |     // "OK"     buttons are hidden, and (Ok) shown on titlebar
 | 
|---|
| 349 |     // "Cancel" buttons are hidden, and (X)  shown on titlebar
 | 
|---|
| 350 |     // "Help"   buttons are hidden, and (?)  shown on titlebar
 | 
|---|
| 351 |     bool showOK = FALSE,
 | 
|---|
| 352 |          showX  = FALSE,
 | 
|---|
| 353 |          showQ  = FALSE;
 | 
|---|
| 354 |     QObjectList *list = queryList( "QPushButton" );
 | 
|---|
| 355 |     QObjectListIt it( *list );
 | 
|---|
| 356 |     QPushButton *pb;
 | 
|---|
| 357 |     while ( (pb = (QPushButton*)it.current()) ) {
 | 
|---|
| 358 |         if ( !showOK &&
 | 
|---|
| 359 |              pb->text() == qApp->translate( "QMessageBox", mb_texts[QMessageBox::Ok] ) ) {
 | 
|---|
| 360 |             pb->hide();
 | 
|---|
| 361 |             showOK = TRUE;
 | 
|---|
| 362 |         } else if ( !showX &&
 | 
|---|
| 363 |                     pb->text() == qApp->translate( "QMessageBox", mb_texts[QMessageBox::Cancel] ) ) {
 | 
|---|
| 364 |             pb->hide();
 | 
|---|
| 365 |             showX = TRUE;
 | 
|---|
| 366 |         } else if ( !showQ &&
 | 
|---|
| 367 |                     pb->text() == qApp->tr("Help") ) {
 | 
|---|
| 368 |             pb->hide();
 | 
|---|
| 369 |             showQ = TRUE;
 | 
|---|
| 370 |         }
 | 
|---|
| 371 |         ++it;
 | 
|---|
| 372 |     }
 | 
|---|
| 373 |     delete list;
 | 
|---|
| 374 |     if ( showOK || showQ ) {
 | 
|---|
| 375 |         DWORD ext = GetWindowLong( winId(), GWL_EXSTYLE );
 | 
|---|
| 376 |         ext |= showOK ? WS_EX_CAPTIONOKBTN : 0;
 | 
|---|
| 377 |         ext |= showQ  ? WS_EX_CONTEXTHELP: 0;
 | 
|---|
| 378 |         SetWindowLong( winId(), GWL_EXSTYLE, ext );
 | 
|---|
| 379 |     }
 | 
|---|
| 380 |     if ( !showX ) {
 | 
|---|
| 381 |         DWORD ext = GetWindowLong( winId(), GWL_STYLE );
 | 
|---|
| 382 |         ext &= ~WS_SYSMENU;
 | 
|---|
| 383 |         SetWindowLong( winId(), GWL_STYLE, ext );
 | 
|---|
| 384 |     }
 | 
|---|
| 385 | }
 | 
|---|
| 386 | #endif
 | 
|---|
| 387 | 
 | 
|---|
| 388 | /*!
 | 
|---|
| 389 |   \fn int QDialog::result() const
 | 
|---|
| 390 | 
 | 
|---|
| 391 |   Returns the modal dialog's result code, \c Accepted or \c Rejected.
 | 
|---|
| 392 | 
 | 
|---|
| 393 |   Do not call this function if the dialog was constructed with the \c
 | 
|---|
| 394 |   WDestructiveClose flag.
 | 
|---|
| 395 | */
 | 
|---|
| 396 | 
 | 
|---|
| 397 | /*!
 | 
|---|
| 398 |   \fn void QDialog::setResult( int i )
 | 
|---|
| 399 | 
 | 
|---|
| 400 |   Sets the modal dialog's result code to \a i.
 | 
|---|
| 401 | */
 | 
|---|
| 402 | 
 | 
|---|
| 403 | 
 | 
|---|
| 404 | /*!
 | 
|---|
| 405 |     Shows the dialog as a \link #modal modal \endlink dialog,
 | 
|---|
| 406 |     blocking until the user closes it. The function returns a \l
 | 
|---|
| 407 |     DialogCode result.
 | 
|---|
| 408 | 
 | 
|---|
| 409 |     Users cannot interact with any other window in the same
 | 
|---|
| 410 |     application until they close the dialog.
 | 
|---|
| 411 | 
 | 
|---|
| 412 |   \sa show(), result()
 | 
|---|
| 413 | */
 | 
|---|
| 414 | 
 | 
|---|
| 415 | int QDialog::exec()
 | 
|---|
| 416 | {
 | 
|---|
| 417 |     if ( in_loop ) {
 | 
|---|
| 418 |         qWarning( "QDialog::exec: Recursive call detected" );
 | 
|---|
| 419 |         return -1;
 | 
|---|
| 420 |     }
 | 
|---|
| 421 | 
 | 
|---|
| 422 |     bool destructiveClose = testWFlags( WDestructiveClose );
 | 
|---|
| 423 |     clearWFlags( WDestructiveClose );
 | 
|---|
| 424 | 
 | 
|---|
| 425 |     bool wasShowModal = testWFlags( WShowModal );
 | 
|---|
| 426 |     setWFlags( WShowModal );
 | 
|---|
| 427 |     setResult( 0 );
 | 
|---|
| 428 | 
 | 
|---|
| 429 |     show();
 | 
|---|
| 430 | 
 | 
|---|
| 431 |     in_loop = TRUE;
 | 
|---|
| 432 |     qApp->enter_loop();
 | 
|---|
| 433 | 
 | 
|---|
| 434 |     if ( !wasShowModal )
 | 
|---|
| 435 |         clearWFlags( WShowModal );
 | 
|---|
| 436 | 
 | 
|---|
| 437 |     int res = result();
 | 
|---|
| 438 | 
 | 
|---|
| 439 |     if ( destructiveClose )
 | 
|---|
| 440 |         delete this;
 | 
|---|
| 441 | 
 | 
|---|
| 442 |     return res;
 | 
|---|
| 443 | }
 | 
|---|
| 444 | 
 | 
|---|
| 445 | 
 | 
|---|
| 446 | /*! Closes the dialog and sets its result code to \a r. If this dialog
 | 
|---|
| 447 |   is shown with exec(), done() causes the local event loop to finish,
 | 
|---|
| 448 |   and exec() to return \a r.
 | 
|---|
| 449 | 
 | 
|---|
| 450 |   As with QWidget::close(), done() deletes the dialog if the \c
 | 
|---|
| 451 |   WDestructiveClose flag is set. If the dialog is the application's
 | 
|---|
| 452 |   main widget, the application terminates. If the dialog is the
 | 
|---|
| 453 |   last window closed, the QApplication::lastWindowClosed() signal is
 | 
|---|
| 454 |   emitted.
 | 
|---|
| 455 | 
 | 
|---|
| 456 |   \sa accept(), reject(), QApplication::mainWidget(), QApplication::quit()
 | 
|---|
| 457 | */
 | 
|---|
| 458 | 
 | 
|---|
| 459 | void QDialog::done( int r )
 | 
|---|
| 460 | {
 | 
|---|
| 461 |     hide();
 | 
|---|
| 462 |     setResult( r );
 | 
|---|
| 463 | 
 | 
|---|
| 464 |     // emulate QWidget::close()
 | 
|---|
| 465 |     bool isMain = qApp->mainWidget() == this;
 | 
|---|
| 466 |     bool checkLastWindowClosed = isTopLevel() && !isPopup();
 | 
|---|
| 467 |     if ( checkLastWindowClosed
 | 
|---|
| 468 |          && qApp->receivers(SIGNAL(lastWindowClosed())) ) {
 | 
|---|
| 469 |         /* if there is no non-withdrawn top level window left (except
 | 
|---|
| 470 |            the desktop, popups, or dialogs with parents), we emit the
 | 
|---|
| 471 |            lastWindowClosed signal */
 | 
|---|
| 472 |         QWidgetList *list   = qApp->topLevelWidgets();
 | 
|---|
| 473 |         QWidget     *widget = list->first();
 | 
|---|
| 474 |         while ( widget ) {
 | 
|---|
| 475 |             if ( !widget->isHidden()
 | 
|---|
| 476 |                  && !widget->isDesktop()
 | 
|---|
| 477 |                  && !widget->isPopup()
 | 
|---|
| 478 |                  && (!widget->isDialog() || !widget->parentWidget()))
 | 
|---|
| 479 |                 break;
 | 
|---|
| 480 |             widget = list->next();
 | 
|---|
| 481 |         }
 | 
|---|
| 482 |         delete list;
 | 
|---|
| 483 |         if ( widget == 0 )
 | 
|---|
| 484 |             emit qApp->lastWindowClosed();
 | 
|---|
| 485 |     }
 | 
|---|
| 486 |     if ( isMain )
 | 
|---|
| 487 |         qApp->quit();
 | 
|---|
| 488 |     else if ( testWFlags(WDestructiveClose) ) {
 | 
|---|
| 489 |         clearWFlags(WDestructiveClose);
 | 
|---|
| 490 |         deleteLater();
 | 
|---|
| 491 |     }
 | 
|---|
| 492 | }
 | 
|---|
| 493 | 
 | 
|---|
| 494 | /*!
 | 
|---|
| 495 |   Hides the modal dialog and sets the result code to \c Accepted.
 | 
|---|
| 496 | 
 | 
|---|
| 497 |   \sa reject() done()
 | 
|---|
| 498 | */
 | 
|---|
| 499 | 
 | 
|---|
| 500 | void QDialog::accept()
 | 
|---|
| 501 | {
 | 
|---|
| 502 |     done( Accepted );
 | 
|---|
| 503 | }
 | 
|---|
| 504 | 
 | 
|---|
| 505 | /*!
 | 
|---|
| 506 |   Hides the modal dialog and sets the result code to \c Rejected.
 | 
|---|
| 507 | 
 | 
|---|
| 508 |   \sa accept() done()
 | 
|---|
| 509 | */
 | 
|---|
| 510 | 
 | 
|---|
| 511 | void QDialog::reject()
 | 
|---|
| 512 | {
 | 
|---|
| 513 |     done( Rejected );
 | 
|---|
| 514 | }
 | 
|---|
| 515 | 
 | 
|---|
| 516 | /*! \reimp */
 | 
|---|
| 517 | bool QDialog::eventFilter( QObject *o, QEvent *e )
 | 
|---|
| 518 | {
 | 
|---|
| 519 |     return QWidget::eventFilter( o, e );
 | 
|---|
| 520 | }
 | 
|---|
| 521 | 
 | 
|---|
| 522 | /*****************************************************************************
 | 
|---|
| 523 |   Event handlers
 | 
|---|
| 524 |  *****************************************************************************/
 | 
|---|
| 525 | 
 | 
|---|
| 526 | /*! \reimp */
 | 
|---|
| 527 | void QDialog::contextMenuEvent( QContextMenuEvent *e )
 | 
|---|
| 528 | {
 | 
|---|
| 529 | #if !defined(QT_NO_WHATSTHIS) && !defined(QT_NO_POPUPMENU)
 | 
|---|
| 530 |     QWidget* w = childAt( e->pos(), TRUE );
 | 
|---|
| 531 |     if ( !w )
 | 
|---|
| 532 |         return;
 | 
|---|
| 533 |     QString s;
 | 
|---|
| 534 |     while ( s.isEmpty() && w ) {
 | 
|---|
| 535 |         s = QWhatsThis::textFor( w, e->pos(), FALSE );
 | 
|---|
| 536 |         if ( s.isEmpty() )
 | 
|---|
| 537 |             w = w->parentWidget(TRUE);
 | 
|---|
| 538 |     }
 | 
|---|
| 539 |     if ( !s.isEmpty() ) {
 | 
|---|
| 540 |         QPopupMenu p(0,"qt_whats_this_menu");
 | 
|---|
| 541 |         p.insertItem( tr("What's This?"), 42 );
 | 
|---|
| 542 |         if ( p.exec( e->globalPos() ) >= 42 )
 | 
|---|
| 543 |             QWhatsThis::display( s, w->mapToGlobal( w->rect().center() ), w );
 | 
|---|
| 544 |     }
 | 
|---|
| 545 | #endif
 | 
|---|
| 546 | }
 | 
|---|
| 547 | 
 | 
|---|
| 548 | /*! \reimp */
 | 
|---|
| 549 | void QDialog::keyPressEvent( QKeyEvent *e )
 | 
|---|
| 550 | {
 | 
|---|
| 551 |     //   Calls reject() if Escape is pressed. Simulates a button
 | 
|---|
| 552 |     //   click for the default button if Enter is pressed. Move focus
 | 
|---|
| 553 |     //   for the arrow keys. Ignore the rest.
 | 
|---|
| 554 | #ifdef Q_OS_MAC
 | 
|---|
| 555 |     if(e->state() == ControlButton && e->key() == Key_Period) {
 | 
|---|
| 556 |         reject();
 | 
|---|
| 557 |     } else
 | 
|---|
| 558 | #endif
 | 
|---|
| 559 |     if ( e->state() == 0 || ( e->state() & Keypad && e->key() == Key_Enter ) ) {
 | 
|---|
| 560 |         switch ( e->key() ) {
 | 
|---|
| 561 |         case Key_Enter:
 | 
|---|
| 562 |         case Key_Return: {
 | 
|---|
| 563 | #ifndef QT_NO_PUSHBUTTON
 | 
|---|
| 564 |             QObjectList *list = queryList( "QPushButton" );
 | 
|---|
| 565 |             QObjectListIt it( *list );
 | 
|---|
| 566 |             QPushButton *pb;
 | 
|---|
| 567 |             while ( (pb = (QPushButton*)it.current()) ) {
 | 
|---|
| 568 |                 if ( pb->isDefault() && pb->isVisible() ) {
 | 
|---|
| 569 |                     delete list;
 | 
|---|
| 570 |                     if ( pb->isEnabled() ) {
 | 
|---|
| 571 |                         emit pb->clicked();
 | 
|---|
| 572 |                     }
 | 
|---|
| 573 |                     return;
 | 
|---|
| 574 |                 }
 | 
|---|
| 575 |                 ++it;
 | 
|---|
| 576 |             }
 | 
|---|
| 577 |             delete list;
 | 
|---|
| 578 | #endif
 | 
|---|
| 579 |         }
 | 
|---|
| 580 |         break;
 | 
|---|
| 581 |         case Key_Escape:
 | 
|---|
| 582 |             reject();
 | 
|---|
| 583 |             break;
 | 
|---|
| 584 |         case Key_Up:
 | 
|---|
| 585 |         case Key_Left:
 | 
|---|
| 586 |             if ( focusWidget() &&
 | 
|---|
| 587 |                  ( focusWidget()->focusPolicy() == QWidget::StrongFocus ||
 | 
|---|
| 588 |                    focusWidget()->focusPolicy() == QWidget::WheelFocus ) ) {
 | 
|---|
| 589 |                 e->ignore();
 | 
|---|
| 590 |                 break;
 | 
|---|
| 591 |             }
 | 
|---|
| 592 |             // call ours, since c++ blocks us from calling the one
 | 
|---|
| 593 |             // belonging to focusWidget().
 | 
|---|
| 594 |             QFocusEvent::setReason(QFocusEvent::Backtab);
 | 
|---|
| 595 |             focusNextPrevChild( FALSE );
 | 
|---|
| 596 |             QFocusEvent::resetReason();
 | 
|---|
| 597 |             break;
 | 
|---|
| 598 |         case Key_Down:
 | 
|---|
| 599 |         case Key_Right:
 | 
|---|
| 600 |             if ( focusWidget() &&
 | 
|---|
| 601 |                  ( focusWidget()->focusPolicy() == QWidget::StrongFocus ||
 | 
|---|
| 602 |                    focusWidget()->focusPolicy() == QWidget::WheelFocus ) ) {
 | 
|---|
| 603 |                 e->ignore();
 | 
|---|
| 604 |                 break;
 | 
|---|
| 605 |             }
 | 
|---|
| 606 |             QFocusEvent::setReason(QFocusEvent::Tab);
 | 
|---|
| 607 |             focusNextPrevChild( TRUE );
 | 
|---|
| 608 |             QFocusEvent::resetReason();
 | 
|---|
| 609 |             break;
 | 
|---|
| 610 |         default:
 | 
|---|
| 611 |             e->ignore();
 | 
|---|
| 612 |             return;
 | 
|---|
| 613 |         }
 | 
|---|
| 614 |     } else {
 | 
|---|
| 615 |         e->ignore();
 | 
|---|
| 616 |     }
 | 
|---|
| 617 | }
 | 
|---|
| 618 | 
 | 
|---|
| 619 | /*! \reimp */
 | 
|---|
| 620 | void QDialog::closeEvent( QCloseEvent *e )
 | 
|---|
| 621 | {
 | 
|---|
| 622 | #ifndef QT_NO_WHATSTHIS
 | 
|---|
| 623 |     if ( isModal() && QWhatsThis::inWhatsThisMode() )
 | 
|---|
| 624 |         QWhatsThis::leaveWhatsThisMode();
 | 
|---|
| 625 | #endif
 | 
|---|
| 626 |     if ( isShown() )
 | 
|---|
| 627 |         reject();
 | 
|---|
| 628 |     if ( isHidden() )
 | 
|---|
| 629 |         e->accept();
 | 
|---|
| 630 | }
 | 
|---|
| 631 | 
 | 
|---|
| 632 | #ifdef Q_OS_TEMP
 | 
|---|
| 633 | /*! \internal
 | 
|---|
| 634 |     \reimp
 | 
|---|
| 635 | */
 | 
|---|
| 636 | bool QDialog::event( QEvent *e )
 | 
|---|
| 637 | {
 | 
|---|
| 638 |     switch ( e->type() ) {
 | 
|---|
| 639 |     case QEvent::OkRequest:
 | 
|---|
| 640 |     case QEvent::HelpRequest:
 | 
|---|
| 641 |         {
 | 
|---|
| 642 |             QString bName =
 | 
|---|
| 643 |                 (e->type() == QEvent::OkRequest)
 | 
|---|
| 644 |                 ? qApp->translate( "QMessageBox", mb_texts[QMessageBox::Ok] )
 | 
|---|
| 645 |                 : qApp->tr( "Help" );
 | 
|---|
| 646 | 
 | 
|---|
| 647 |             QObjectList *list = queryList( "QPushButton" );
 | 
|---|
| 648 |             QObjectListIt it( *list );
 | 
|---|
| 649 |             QPushButton *pb;
 | 
|---|
| 650 |             while ( (pb = (QPushButton*)it.current()) ) {
 | 
|---|
| 651 |                 if ( pb->text() == bName ) {
 | 
|---|
| 652 |                     delete list;
 | 
|---|
| 653 |                     if ( pb->isEnabled() )
 | 
|---|
| 654 |                         emit pb->clicked();
 | 
|---|
| 655 |                     return pb->isEnabled();
 | 
|---|
| 656 |                 }
 | 
|---|
| 657 |                 ++it;
 | 
|---|
| 658 |             }
 | 
|---|
| 659 |             delete list;
 | 
|---|
| 660 |         }
 | 
|---|
| 661 |     }
 | 
|---|
| 662 |     return QWidget::event( e );
 | 
|---|
| 663 | }
 | 
|---|
| 664 | #endif
 | 
|---|
| 665 | 
 | 
|---|
| 666 | 
 | 
|---|
| 667 | /*****************************************************************************
 | 
|---|
| 668 |   Geometry management.
 | 
|---|
| 669 |  *****************************************************************************/
 | 
|---|
| 670 | 
 | 
|---|
| 671 | #if defined(Q_WS_X11)
 | 
|---|
| 672 | extern "C" { int XSetTransientForHint( Display *, unsigned long, unsigned long ); }
 | 
|---|
| 673 | #endif // Q_WS_X11
 | 
|---|
| 674 | 
 | 
|---|
| 675 | /*!
 | 
|---|
| 676 |     Shows the dialog as a \link #modeless modeless \endlink dialog.
 | 
|---|
| 677 |     Control returns immediately to the calling code.
 | 
|---|
| 678 | 
 | 
|---|
| 679 |     The dialog will be modal or modeless according to the value
 | 
|---|
| 680 |     of the \l modal property.
 | 
|---|
| 681 | 
 | 
|---|
| 682 |     \sa exec(), modal
 | 
|---|
| 683 | */
 | 
|---|
| 684 | 
 | 
|---|
| 685 | void QDialog::show()
 | 
|---|
| 686 | {
 | 
|---|
| 687 |     if ( testWState(WState_Visible) )
 | 
|---|
| 688 |         return;
 | 
|---|
| 689 |     if ( !did_resize )
 | 
|---|
| 690 |         adjustSize();
 | 
|---|
| 691 |     if ( has_relpos && !did_move ) {
 | 
|---|
| 692 |         adjustPositionInternal( parentWidget(), TRUE );
 | 
|---|
| 693 |     } else if ( !did_move ) {
 | 
|---|
| 694 |         adjustPositionInternal( parentWidget() );
 | 
|---|
| 695 |     }
 | 
|---|
| 696 | 
 | 
|---|
| 697 | #if defined(Q_WS_X11)
 | 
|---|
| 698 |     if (!parentWidget() && testWFlags(WShowModal)
 | 
|---|
| 699 |         && qApp->mainWidget() && qApp->mainWidget()->isVisible()
 | 
|---|
| 700 |         && !qApp->mainWidget()->isMinimized()) {
 | 
|---|
| 701 |         // make sure the transient for hint is set properly for modal dialogs
 | 
|---|
| 702 |         XSetTransientForHint( x11Display(), winId(), qApp->mainWidget()->winId() );
 | 
|---|
| 703 |     }
 | 
|---|
| 704 | #endif // Q_WS_X11
 | 
|---|
| 705 | 
 | 
|---|
| 706 | #ifdef Q_OS_TEMP
 | 
|---|
| 707 |     hideSpecial();
 | 
|---|
| 708 | #endif
 | 
|---|
| 709 | 
 | 
|---|
| 710 |     QWidget::show();
 | 
|---|
| 711 |     showExtension( d->doShowExtension );
 | 
|---|
| 712 | #ifndef QT_NO_PUSHBUTTON
 | 
|---|
| 713 |     QWidget *fw = focusWidget();
 | 
|---|
| 714 |     QFocusData *fd = focusData();
 | 
|---|
| 715 | 
 | 
|---|
| 716 |     /*
 | 
|---|
| 717 |       The following block is to handle a special case, and does not
 | 
|---|
| 718 |       really follow propper logic in concern of autoDefault and TAB
 | 
|---|
| 719 |       order. However, it's here to ease usage for the users. If a
 | 
|---|
| 720 |       dialog has a default QPushButton, and first widget in the TAB
 | 
|---|
| 721 |       order also is a QPushButton, then we give focus to the main
 | 
|---|
| 722 |       default QPushButton. This simplifies code for the developers,
 | 
|---|
| 723 |       and actually catches most cases... If not, then they simply
 | 
|---|
| 724 |       have to use [widget*]->setFocus() themselves...
 | 
|---|
| 725 |     */
 | 
|---|
| 726 |     if ( !fw || fw->focusPolicy() == NoFocus ) {
 | 
|---|
| 727 |         fd->home(); // Skip main form
 | 
|---|
| 728 |         QWidget *first = fd->next(); // Get first main widget
 | 
|---|
| 729 |         if ( d->mainDef &&
 | 
|---|
| 730 |              first != d->mainDef &&
 | 
|---|
| 731 |              ::qt_cast<QPushButton*>(first) )
 | 
|---|
| 732 |             d->mainDef->setFocus();
 | 
|---|
| 733 |     }
 | 
|---|
| 734 | 
 | 
|---|
| 735 |     if ( !d->mainDef && isTopLevel() ) {
 | 
|---|
| 736 |         if ( !fw || fw->focusPolicy() == NoFocus ) {
 | 
|---|
| 737 |             focusNextPrevChild( TRUE );
 | 
|---|
| 738 |             fw = focusWidget();
 | 
|---|
| 739 |         }
 | 
|---|
| 740 |         if ( fw ) {
 | 
|---|
| 741 |             fd = focusData();
 | 
|---|
| 742 |             QWidget *home = fd->home();
 | 
|---|
| 743 |             QWidget *candidate = home;
 | 
|---|
| 744 |             Q_ASSERT( candidate == fw );
 | 
|---|
| 745 |             do {
 | 
|---|
| 746 |                 QPushButton *pb = ::qt_cast<QPushButton*>(candidate);
 | 
|---|
| 747 |                 if ( pb && pb->autoDefault() ) {
 | 
|---|
| 748 |                     pb->setDefault( TRUE );
 | 
|---|
| 749 |                     break;
 | 
|---|
| 750 |                 }
 | 
|---|
| 751 |                 candidate = fd->next();
 | 
|---|
| 752 |             } while ( candidate != home );
 | 
|---|
| 753 |         }
 | 
|---|
| 754 |     }
 | 
|---|
| 755 |     if ( fw ) {
 | 
|---|
| 756 |         QFocusEvent e( QEvent::FocusIn );
 | 
|---|
| 757 |         QFocusEvent::setReason( QFocusEvent::Tab );
 | 
|---|
| 758 |         QApplication::sendEvent( fw, &e );
 | 
|---|
| 759 |         QFocusEvent::resetReason();
 | 
|---|
| 760 |     }
 | 
|---|
| 761 | 
 | 
|---|
| 762 | #endif
 | 
|---|
| 763 | #if defined(QT_ACCESSIBILITY_SUPPORT)
 | 
|---|
| 764 |     QAccessible::updateAccessibility( this, 0, QAccessible::DialogStart );
 | 
|---|
| 765 | #endif
 | 
|---|
| 766 | }
 | 
|---|
| 767 | 
 | 
|---|
| 768 | /*! \internal */
 | 
|---|
| 769 | void QDialog::adjustPosition( QWidget* w)
 | 
|---|
| 770 | {
 | 
|---|
| 771 |     adjustPositionInternal( w );
 | 
|---|
| 772 | }
 | 
|---|
| 773 | 
 | 
|---|
| 774 | 
 | 
|---|
| 775 | void QDialog::adjustPositionInternal( QWidget*w, bool useRelPos)
 | 
|---|
| 776 | {
 | 
|---|
| 777 |     /* need to make sure these events are already sent to be sure
 | 
|---|
| 778 |        our information below is correct --sam */
 | 
|---|
| 779 |     QApplication::sendPostedEvents( this, QEvent::LayoutHint );
 | 
|---|
| 780 |     QApplication::sendPostedEvents( this, QEvent::Resize );
 | 
|---|
| 781 | 
 | 
|---|
| 782 |     // processing the events might call polish(), which is a nice place
 | 
|---|
| 783 |     // to restore geometries, so return if the dialog has been positioned
 | 
|---|
| 784 |     if ( did_move || has_relpos )
 | 
|---|
| 785 |         return;
 | 
|---|
| 786 | 
 | 
|---|
| 787 |     QPoint p( 0, 0 );
 | 
|---|
| 788 |     int extraw = 0, extrah = 0, scrn = 0;
 | 
|---|
| 789 |     if ( w )
 | 
|---|
| 790 |         w = w->topLevelWidget();
 | 
|---|
| 791 |     QRect desk;
 | 
|---|
| 792 |     if ( w ) {
 | 
|---|
| 793 |         scrn = QApplication::desktop()->screenNumber( w );
 | 
|---|
| 794 |     } else if ( QApplication::desktop()->isVirtualDesktop() ) {
 | 
|---|
| 795 |         scrn = QApplication::desktop()->screenNumber( QCursor::pos() );
 | 
|---|
| 796 |     } else {
 | 
|---|
| 797 |         scrn = QApplication::desktop()->screenNumber( this );
 | 
|---|
| 798 |     }
 | 
|---|
| 799 |     desk = QApplication::desktop()->availableGeometry( scrn );
 | 
|---|
| 800 | 
 | 
|---|
| 801 |     QWidgetList  *list = QApplication::topLevelWidgets();
 | 
|---|
| 802 |     QWidgetListIt it( *list );
 | 
|---|
| 803 |     while ( (extraw == 0 || extrah == 0) &&
 | 
|---|
| 804 |             it.current() != 0 ) {
 | 
|---|
| 805 |         int framew, frameh;
 | 
|---|
| 806 |         QWidget * current = it.current();
 | 
|---|
| 807 |         ++it;
 | 
|---|
| 808 |         if ( ! current->isVisible() )
 | 
|---|
| 809 |             continue;
 | 
|---|
| 810 | 
 | 
|---|
| 811 |         framew = current->geometry().x() - current->x();
 | 
|---|
| 812 |         frameh = current->geometry().y() - current->y();
 | 
|---|
| 813 | 
 | 
|---|
| 814 |         extraw = QMAX( extraw, framew );
 | 
|---|
| 815 |         extrah = QMAX( extrah, frameh );
 | 
|---|
| 816 |     }
 | 
|---|
| 817 |     delete list;
 | 
|---|
| 818 | 
 | 
|---|
| 819 |     // sanity check for decoration frames. With embedding, we
 | 
|---|
| 820 |     // might get extraordinary values
 | 
|---|
| 821 |     if ( extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40 ) {
 | 
|---|
| 822 |         extrah = 40;
 | 
|---|
| 823 |         extraw = 10;
 | 
|---|
| 824 |     }
 | 
|---|
| 825 | 
 | 
|---|
| 826 |     if ( useRelPos && w ) {
 | 
|---|
| 827 |         p = w->pos() + d->relPos;
 | 
|---|
| 828 |     } else {
 | 
|---|
| 829 | #ifndef Q_OS_TEMP
 | 
|---|
| 830 |         if ( w ) {
 | 
|---|
| 831 |             // Use mapToGlobal rather than geometry() in case w might
 | 
|---|
| 832 |             // be embedded in another application
 | 
|---|
| 833 |             QPoint pp = w->mapToGlobal( QPoint(0,0) );
 | 
|---|
| 834 |             p = QPoint( pp.x() + w->width()/2,
 | 
|---|
| 835 |                         pp.y() + w->height()/ 2 );
 | 
|---|
| 836 |         } else {
 | 
|---|
| 837 |             // p = middle of the desktop
 | 
|---|
| 838 |             p = QPoint( desk.x() + desk.width()/2, desk.y() + desk.height()/2 );
 | 
|---|
| 839 |         }
 | 
|---|
| 840 | #else
 | 
|---|
| 841 |         p = QPoint( desk.x() + desk.width()/2, desk.y() + desk.height()/2 );
 | 
|---|
| 842 | #endif
 | 
|---|
| 843 | 
 | 
|---|
| 844 |         // p = origin of this
 | 
|---|
| 845 |         p = QPoint( p.x()-width()/2 - extraw,
 | 
|---|
| 846 |                     p.y()-height()/2 - extrah );
 | 
|---|
| 847 |     }
 | 
|---|
| 848 | 
 | 
|---|
| 849 | 
 | 
|---|
| 850 |     if ( p.x() + extraw + width() > desk.x() + desk.width() )
 | 
|---|
| 851 |         p.setX( desk.x() + desk.width() - width() - extraw );
 | 
|---|
| 852 |     if ( p.x() < desk.x() )
 | 
|---|
| 853 |         p.setX( desk.x() );
 | 
|---|
| 854 | 
 | 
|---|
| 855 |     if ( p.y() + extrah + height() > desk.y() + desk.height() )
 | 
|---|
| 856 |         p.setY( desk.y() + desk.height() - height() - extrah );
 | 
|---|
| 857 |     if ( p.y() < desk.y() )
 | 
|---|
| 858 |         p.setY( desk.y() );
 | 
|---|
| 859 | 
 | 
|---|
| 860 |     move( p );
 | 
|---|
| 861 |     did_move = !useRelPos;
 | 
|---|
| 862 | }
 | 
|---|
| 863 | 
 | 
|---|
| 864 | 
 | 
|---|
| 865 | /*! \reimp */
 | 
|---|
| 866 | void QDialog::hide()
 | 
|---|
| 867 | {
 | 
|---|
| 868 |     if ( isHidden() )
 | 
|---|
| 869 |         return;
 | 
|---|
| 870 | 
 | 
|---|
| 871 | #if defined(QT_ACCESSIBILITY_SUPPORT)
 | 
|---|
| 872 |     if ( isVisible() )
 | 
|---|
| 873 |         QAccessible::updateAccessibility( this, 0, QAccessible::DialogEnd );
 | 
|---|
| 874 | #endif
 | 
|---|
| 875 | 
 | 
|---|
| 876 |     if ( parentWidget() && !did_move ) {
 | 
|---|
| 877 |         d->relPos = pos() - parentWidget()->topLevelWidget()->pos();
 | 
|---|
| 878 |         has_relpos = 1;
 | 
|---|
| 879 |     }
 | 
|---|
| 880 | 
 | 
|---|
| 881 |     // Reimplemented to exit a modal when the dialog is hidden.
 | 
|---|
| 882 |     QWidget::hide();
 | 
|---|
| 883 |     if ( in_loop ) {
 | 
|---|
| 884 |         in_loop = FALSE;
 | 
|---|
| 885 |         qApp->exit_loop();
 | 
|---|
| 886 |     }
 | 
|---|
| 887 | }
 | 
|---|
| 888 | 
 | 
|---|
| 889 | 
 | 
|---|
| 890 | /*****************************************************************************
 | 
|---|
| 891 |   Detects any widget geometry changes done by the user.
 | 
|---|
| 892 |  *****************************************************************************/
 | 
|---|
| 893 | 
 | 
|---|
| 894 | /*! \reimp */
 | 
|---|
| 895 | 
 | 
|---|
| 896 | void QDialog::move( int x, int y )
 | 
|---|
| 897 | {
 | 
|---|
| 898 |     did_move = TRUE;
 | 
|---|
| 899 |     QWidget::move( x, y );
 | 
|---|
| 900 | }
 | 
|---|
| 901 | 
 | 
|---|
| 902 | /*! \reimp */
 | 
|---|
| 903 | 
 | 
|---|
| 904 | void QDialog::move( const QPoint &p )
 | 
|---|
| 905 | {
 | 
|---|
| 906 |     did_move = TRUE;
 | 
|---|
| 907 |     QWidget::move( p );
 | 
|---|
| 908 | }
 | 
|---|
| 909 | 
 | 
|---|
| 910 | /*! \reimp */
 | 
|---|
| 911 | 
 | 
|---|
| 912 | void QDialog::resize( int w, int h )
 | 
|---|
| 913 | {
 | 
|---|
| 914 |     did_resize = TRUE;
 | 
|---|
| 915 |     QWidget::resize( w, h );
 | 
|---|
| 916 | }
 | 
|---|
| 917 | 
 | 
|---|
| 918 | /*! \reimp */
 | 
|---|
| 919 | 
 | 
|---|
| 920 | void QDialog::resize( const QSize &s )
 | 
|---|
| 921 | {
 | 
|---|
| 922 |     did_resize = TRUE;
 | 
|---|
| 923 |     QWidget::resize( s );
 | 
|---|
| 924 | }
 | 
|---|
| 925 | 
 | 
|---|
| 926 | /*! \reimp */
 | 
|---|
| 927 | 
 | 
|---|
| 928 | void QDialog::setGeometry( int x, int y, int w, int h )
 | 
|---|
| 929 | {
 | 
|---|
| 930 |     did_move   = TRUE;
 | 
|---|
| 931 |     did_resize = TRUE;
 | 
|---|
| 932 |     QWidget::setGeometry( x, y, w, h );
 | 
|---|
| 933 | }
 | 
|---|
| 934 | 
 | 
|---|
| 935 | /*! \reimp */
 | 
|---|
| 936 | 
 | 
|---|
| 937 | void QDialog::setGeometry( const QRect &r )
 | 
|---|
| 938 | {
 | 
|---|
| 939 |     did_move   = TRUE;
 | 
|---|
| 940 |     did_resize = TRUE;
 | 
|---|
| 941 |     QWidget::setGeometry( r );
 | 
|---|
| 942 | }
 | 
|---|
| 943 | 
 | 
|---|
| 944 | 
 | 
|---|
| 945 | /*!
 | 
|---|
| 946 |     If \a orientation is \c Horizontal, the extension will be displayed
 | 
|---|
| 947 |     to the right of the dialog's main area. If \a orientation is \c
 | 
|---|
| 948 |     Vertical, the extension will be displayed below the dialog's main
 | 
|---|
| 949 |     area.
 | 
|---|
| 950 | 
 | 
|---|
| 951 |   \sa orientation(), setExtension()
 | 
|---|
| 952 | */
 | 
|---|
| 953 | void QDialog::setOrientation( Orientation orientation )
 | 
|---|
| 954 | {
 | 
|---|
| 955 |     d->orientation = orientation;
 | 
|---|
| 956 | }
 | 
|---|
| 957 | 
 | 
|---|
| 958 | /*!
 | 
|---|
| 959 |   Returns the dialog's extension orientation.
 | 
|---|
| 960 | 
 | 
|---|
| 961 |   \sa setOrientation()
 | 
|---|
| 962 | */
 | 
|---|
| 963 | Qt::Orientation QDialog::orientation() const
 | 
|---|
| 964 | {
 | 
|---|
| 965 |     return d->orientation;
 | 
|---|
| 966 | }
 | 
|---|
| 967 | 
 | 
|---|
| 968 | /*!
 | 
|---|
| 969 |     Sets the widget, \a extension, to be the dialog's extension,
 | 
|---|
| 970 |     deleting any previous extension. The dialog takes ownership of the
 | 
|---|
| 971 |     extension. Note that if 0 is passed any existing extension will be
 | 
|---|
| 972 |     deleted.
 | 
|---|
| 973 | 
 | 
|---|
| 974 |   This function must only be called while the dialog is hidden.
 | 
|---|
| 975 | 
 | 
|---|
| 976 |   \sa showExtension(), setOrientation(), extension()
 | 
|---|
| 977 |  */
 | 
|---|
| 978 | void QDialog::setExtension( QWidget* extension )
 | 
|---|
| 979 | {
 | 
|---|
| 980 |     delete d->extension;
 | 
|---|
| 981 |     d->extension = extension;
 | 
|---|
| 982 | 
 | 
|---|
| 983 |     if ( !extension )
 | 
|---|
| 984 |         return;
 | 
|---|
| 985 | 
 | 
|---|
| 986 |     if ( extension->parentWidget() != this )
 | 
|---|
| 987 |         extension->reparent( this, QPoint(0,0) );
 | 
|---|
| 988 |     extension->hide();
 | 
|---|
| 989 | }
 | 
|---|
| 990 | 
 | 
|---|
| 991 | /*!
 | 
|---|
| 992 |   Returns the dialog's extension or 0 if no extension has been
 | 
|---|
| 993 |   defined.
 | 
|---|
| 994 | 
 | 
|---|
| 995 |   \sa setExtension()
 | 
|---|
| 996 |  */
 | 
|---|
| 997 | QWidget* QDialog::extension() const
 | 
|---|
| 998 | {
 | 
|---|
| 999 |     return d->extension;
 | 
|---|
| 1000 | }
 | 
|---|
| 1001 | 
 | 
|---|
| 1002 | 
 | 
|---|
| 1003 | /*!
 | 
|---|
| 1004 |   If \a showIt is TRUE, the dialog's extension is shown; otherwise the
 | 
|---|
| 1005 |   extension is hidden.
 | 
|---|
| 1006 | 
 | 
|---|
| 1007 |   This slot is usually connected to the \l QButton::toggled() signal
 | 
|---|
| 1008 |   of a QPushButton.
 | 
|---|
| 1009 | 
 | 
|---|
| 1010 |   A dialog with a visible extension is not resizeable.
 | 
|---|
| 1011 | 
 | 
|---|
| 1012 |   \sa show(), setExtension(), setOrientation()
 | 
|---|
| 1013 |  */
 | 
|---|
| 1014 | void QDialog::showExtension( bool showIt )
 | 
|---|
| 1015 | {
 | 
|---|
| 1016 |     d->doShowExtension = showIt;
 | 
|---|
| 1017 |     if ( !d->extension )
 | 
|---|
| 1018 |         return;
 | 
|---|
| 1019 |     if ( !testWState(WState_Visible) )
 | 
|---|
| 1020 |         return;
 | 
|---|
| 1021 |     if ( d->extension->isVisible() == showIt )
 | 
|---|
| 1022 |         return;
 | 
|---|
| 1023 | 
 | 
|---|
| 1024 |     if ( showIt ) {
 | 
|---|
| 1025 |         d->size = size();
 | 
|---|
| 1026 |         d->min = minimumSize();
 | 
|---|
| 1027 |         d->max = maximumSize();
 | 
|---|
| 1028 | #ifndef QT_NO_LAYOUT
 | 
|---|
| 1029 |         if ( layout() )
 | 
|---|
| 1030 |             layout()->setEnabled( FALSE );
 | 
|---|
| 1031 | #endif
 | 
|---|
| 1032 |         QSize s( d->extension->sizeHint()
 | 
|---|
| 1033 |                  .expandedTo( d->extension->minimumSize() )
 | 
|---|
| 1034 |                  .boundedTo( d->extension->maximumSize() ) );
 | 
|---|
| 1035 |         if ( d->orientation == Horizontal ) {
 | 
|---|
| 1036 |             int h = QMAX( height(), s.height() );
 | 
|---|
| 1037 |             d->extension->setGeometry( width(), 0, s.width(), h );
 | 
|---|
| 1038 |             setFixedSize( width() + s.width(), h );
 | 
|---|
| 1039 |         } else {
 | 
|---|
| 1040 |             int w = QMAX( width(), s.width() );
 | 
|---|
| 1041 |             d->extension->setGeometry( 0, height(), w, s.height() );
 | 
|---|
| 1042 |             setFixedSize( w, height() + s.height() );
 | 
|---|
| 1043 |         }
 | 
|---|
| 1044 |         d->extension->show();
 | 
|---|
| 1045 |     } else {
 | 
|---|
| 1046 |         d->extension->hide();
 | 
|---|
| 1047 |         // workaround for CDE window manager that won't shrink with (-1,-1)
 | 
|---|
| 1048 |         setMinimumSize( d->min.expandedTo( QSize( 1, 1 ) ) );
 | 
|---|
| 1049 |         setMaximumSize( d->max );
 | 
|---|
| 1050 |         resize( d->size );
 | 
|---|
| 1051 | #ifndef QT_NO_LAYOUT
 | 
|---|
| 1052 |         if ( layout() )
 | 
|---|
| 1053 |             layout()->setEnabled( TRUE );
 | 
|---|
| 1054 | #endif
 | 
|---|
| 1055 |     }
 | 
|---|
| 1056 | }
 | 
|---|
| 1057 | 
 | 
|---|
| 1058 | 
 | 
|---|
| 1059 | /*! \reimp */
 | 
|---|
| 1060 | QSize QDialog::sizeHint() const
 | 
|---|
| 1061 | {
 | 
|---|
| 1062 |     if ( d->extension )
 | 
|---|
| 1063 |         if ( d->orientation == Horizontal )
 | 
|---|
| 1064 |             return QSize( QWidget::sizeHint().width(),
 | 
|---|
| 1065 |                         QMAX( QWidget::sizeHint().height(),d->extension->sizeHint().height() ) );
 | 
|---|
| 1066 |         else
 | 
|---|
| 1067 |             return QSize( QMAX( QWidget::sizeHint().width(), d->extension->sizeHint().width() ),
 | 
|---|
| 1068 |                         QWidget::sizeHint().height() );
 | 
|---|
| 1069 | 
 | 
|---|
| 1070 |     return QWidget::sizeHint();
 | 
|---|
| 1071 | }
 | 
|---|
| 1072 | 
 | 
|---|
| 1073 | 
 | 
|---|
| 1074 | /*! \reimp */
 | 
|---|
| 1075 | QSize QDialog::minimumSizeHint() const
 | 
|---|
| 1076 | {
 | 
|---|
| 1077 |     if ( d->extension )
 | 
|---|
| 1078 |         if (d->orientation == Horizontal )
 | 
|---|
| 1079 |             return QSize( QWidget::minimumSizeHint().width(),
 | 
|---|
| 1080 |                         QMAX( QWidget::minimumSizeHint().height(), d->extension->minimumSizeHint().height() ) );
 | 
|---|
| 1081 |         else
 | 
|---|
| 1082 |             return QSize( QMAX( QWidget::minimumSizeHint().width(), d->extension->minimumSizeHint().width() ),
 | 
|---|
| 1083 |                         QWidget::minimumSizeHint().height() );
 | 
|---|
| 1084 | 
 | 
|---|
| 1085 |     return QWidget::minimumSizeHint();
 | 
|---|
| 1086 | }
 | 
|---|
| 1087 | 
 | 
|---|
| 1088 | /*! \property QDialog::modal
 | 
|---|
| 1089 |     \brief whether show() should pop up the dialog as modal or modeless
 | 
|---|
| 1090 | 
 | 
|---|
| 1091 |     By default, this property is false and show() pops up the dialog as
 | 
|---|
| 1092 |     modeless.
 | 
|---|
| 1093 | 
 | 
|---|
| 1094 |     exec() ignores the value of this property and always pops up the
 | 
|---|
| 1095 |     dialog as modal.
 | 
|---|
| 1096 | 
 | 
|---|
| 1097 |     \sa show(), exec()
 | 
|---|
| 1098 | */
 | 
|---|
| 1099 | 
 | 
|---|
| 1100 | void QDialog::setModal( bool modal )
 | 
|---|
| 1101 | {
 | 
|---|
| 1102 |     if ( modal )
 | 
|---|
| 1103 |         setWFlags( WShowModal );
 | 
|---|
| 1104 |     else
 | 
|---|
| 1105 |         clearWFlags( WShowModal );
 | 
|---|
| 1106 | }
 | 
|---|
| 1107 | 
 | 
|---|
| 1108 | bool QDialog::isModal() const
 | 
|---|
| 1109 | {
 | 
|---|
| 1110 |     return testWFlags( WShowModal ) != 0;
 | 
|---|
| 1111 | }
 | 
|---|
| 1112 | 
 | 
|---|
| 1113 | bool QDialog::isSizeGripEnabled() const
 | 
|---|
| 1114 | {
 | 
|---|
| 1115 | #ifndef QT_NO_SIZEGRIP
 | 
|---|
| 1116 |     return !!d->resizer;
 | 
|---|
| 1117 | #else
 | 
|---|
| 1118 |     return FALSE;
 | 
|---|
| 1119 | #endif
 | 
|---|
| 1120 | }
 | 
|---|
| 1121 | 
 | 
|---|
| 1122 | 
 | 
|---|
| 1123 | void QDialog::setSizeGripEnabled(bool enabled)
 | 
|---|
| 1124 | {
 | 
|---|
| 1125 | #ifndef QT_NO_SIZEGRIP
 | 
|---|
| 1126 |     if ( !enabled != !d->resizer ) {
 | 
|---|
| 1127 |         if ( enabled ) {
 | 
|---|
| 1128 |             d->resizer = new QSizeGrip( this, "QDialog::resizer" );
 | 
|---|
| 1129 |             // adjustSize() processes all events, which is suboptimal
 | 
|---|
| 1130 |             d->resizer->resize( d->resizer->sizeHint() );
 | 
|---|
| 1131 |             if ( QApplication::reverseLayout() )
 | 
|---|
| 1132 |                 d->resizer->move( rect().bottomLeft() -d->resizer->rect().bottomLeft() );
 | 
|---|
| 1133 |             else
 | 
|---|
| 1134 |                 d->resizer->move( rect().bottomRight() -d->resizer->rect().bottomRight() );
 | 
|---|
| 1135 |             d->resizer->raise();
 | 
|---|
| 1136 |             d->resizer->show();
 | 
|---|
| 1137 |         } else {
 | 
|---|
| 1138 |             delete d->resizer;
 | 
|---|
| 1139 |             d->resizer = 0;
 | 
|---|
| 1140 |         }
 | 
|---|
| 1141 |     }
 | 
|---|
| 1142 | #endif //QT_NO_SIZEGRIP
 | 
|---|
| 1143 | }
 | 
|---|
| 1144 | 
 | 
|---|
| 1145 | 
 | 
|---|
| 1146 | 
 | 
|---|
| 1147 | /*! \reimp */
 | 
|---|
| 1148 | void QDialog::resizeEvent( QResizeEvent * )
 | 
|---|
| 1149 | {
 | 
|---|
| 1150 | #ifndef QT_NO_SIZEGRIP
 | 
|---|
| 1151 |     if ( d->resizer ) {
 | 
|---|
| 1152 |         if ( QApplication::reverseLayout() )
 | 
|---|
| 1153 |             d->resizer->move( rect().bottomLeft() -d->resizer->rect().bottomLeft() );
 | 
|---|
| 1154 |         else
 | 
|---|
| 1155 |             d->resizer->move( rect().bottomRight() -d->resizer->rect().bottomRight() );
 | 
|---|
| 1156 |     }
 | 
|---|
| 1157 | #endif
 | 
|---|
| 1158 | }
 | 
|---|
| 1159 | 
 | 
|---|
| 1160 | #endif // QT_NO_DIALOG
 | 
|---|