1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtGui module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "qdialog.h" |
43 | |
44 | |
45 | #include "qevent.h" |
46 | #include "qdesktopwidget.h" |
47 | #include "qpushbutton.h" |
48 | #include "qapplication.h" |
49 | #include "qlayout.h" |
50 | #include "qsizegrip.h" |
51 | #include "qwhatsthis.h" |
52 | #include "qmenu.h" |
53 | #include "qcursor.h" |
54 | #include "private/qdialog_p.h" |
55 | #ifndef QT_NO_ACCESSIBILITY |
56 | #include "qaccessible.h" |
57 | #endif |
58 | #if defined(Q_WS_WINCE) |
59 | #include "qt_windows.h" |
60 | #include "qmenubar.h" |
61 | #include "qpointer.h" |
62 | #include "qguifunctions_wince.h" |
63 | extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp |
64 | extern bool qt_wince_is_smartphone(); //is defined in qguifunctions_wce.cpp |
65 | #elif defined(Q_WS_X11) |
66 | # include "../kernel/qt_x11_p.h" |
67 | #elif defined(Q_OS_SYMBIAN) |
68 | # include "qfiledialog.h" |
69 | # include "qfontdialog.h" |
70 | # include "qwizard.h" |
71 | # include "private/qt_s60_p.h" |
72 | #elif defined(Q_OS_BLACKBERRY) |
73 | # include "qmessagebox.h" |
74 | #endif |
75 | |
76 | #if defined(Q_WS_S60) |
77 | #include <AknUtils.h> // AknLayoutUtils |
78 | #endif |
79 | |
80 | #ifndef SPI_GETSNAPTODEFBUTTON |
81 | # define SPI_GETSNAPTODEFBUTTON 95 |
82 | #endif |
83 | |
84 | QT_BEGIN_NAMESPACE |
85 | |
86 | /*! |
87 | \class QDialog |
88 | \brief The QDialog class is the base class of dialog windows. |
89 | |
90 | \ingroup dialog-classes |
91 | \ingroup abstractwidgets |
92 | |
93 | |
94 | A dialog window is a top-level window mostly used for short-term |
95 | tasks and brief communications with the user. QDialogs may be |
96 | modal or modeless. QDialogs can |
97 | provide a \link #return return |
98 | value\endlink, and they can have \link #default default |
99 | buttons\endlink. QDialogs can also have a QSizeGrip in their |
100 | lower-right corner, using setSizeGripEnabled(). |
101 | |
102 | Note that QDialog (and any other widget that has type \c Qt::Dialog) uses |
103 | the parent widget slightly differently from other classes in Qt. A |
104 | dialog is always a top-level widget, but if it has a parent, its |
105 | default location is centered on top of the parent's top-level widget |
106 | (if it is not top-level itself). It will also share the parent's |
107 | taskbar entry. |
108 | |
109 | Use the overload of the QWidget::setParent() function to change |
110 | the ownership of a QDialog widget. This function allows you to |
111 | explicitly set the window flags of the reparented widget; using |
112 | the overloaded function will clear the window flags specifying the |
113 | window-system properties for the widget (in particular it will |
114 | reset the Qt::Dialog flag). |
115 | |
116 | \section1 Modal Dialogs |
117 | |
118 | A \bold{modal} dialog is a dialog that blocks input to other |
119 | visible windows in the same application. Dialogs that are used to |
120 | request a file name from the user or that are used to set |
121 | application preferences are usually modal. Dialogs can be |
122 | \l{Qt::ApplicationModal}{application modal} (the default) or |
123 | \l{Qt::WindowModal}{window modal}. |
124 | |
125 | When an application modal dialog is opened, the user must finish |
126 | interacting with the dialog and close it before they can access |
127 | any other window in the application. Window modal dialogs only |
128 | block access to the window associated with the dialog, allowing |
129 | the user to continue to use other windows in an application. |
130 | |
131 | The most common way to display a modal dialog is to call its |
132 | exec() function. When the user closes the dialog, exec() will |
133 | provide a useful \link #return return value\endlink. Typically, |
134 | to get the dialog to close and return the appropriate value, we |
135 | connect a default button, e.g. \gui OK, to the accept() slot and a |
136 | \gui Cancel button to the reject() slot. |
137 | Alternatively you can call the done() slot with \c Accepted or |
138 | \c Rejected. |
139 | |
140 | An alternative is to call setModal(true) or setWindowModality(), |
141 | then show(). Unlike exec(), show() returns control to the caller |
142 | immediately. Calling setModal(true) is especially useful for |
143 | progress dialogs, where the user must have the ability to interact |
144 | with the dialog, e.g. to cancel a long running operation. If you |
145 | use show() and setModal(true) together to perform a long operation, |
146 | you must call QApplication::processEvents() periodically during |
147 | processing to enable the user to interact with the dialog. (See |
148 | QProgressDialog.) |
149 | |
150 | \section1 Modeless Dialogs |
151 | |
152 | A \bold{modeless} dialog is a dialog that operates |
153 | independently of other windows in the same application. Find and |
154 | replace dialogs in word-processors are often modeless to allow the |
155 | user to interact with both the application's main window and with |
156 | the dialog. |
157 | |
158 | Modeless dialogs are displayed using show(), which returns control |
159 | to the caller immediately. |
160 | |
161 | If you invoke the \l{QWidget::show()}{show()} function after hiding |
162 | a dialog, the dialog will be displayed in its original position. This is |
163 | because the window manager decides the position for windows that |
164 | have not been explicitly placed by the programmer. To preserve the |
165 | position of a dialog that has been moved by the user, save its position |
166 | in your \l{QWidget::closeEvent()}{closeEvent()} handler and then |
167 | move the dialog to that position, before showing it again. |
168 | |
169 | \target default |
170 | \section1 Default Button |
171 | |
172 | A dialog's \e default button is the button that's pressed when the |
173 | user presses Enter (Return). This button is used to signify that |
174 | the user accepts the dialog's settings and wants to close the |
175 | dialog. Use QPushButton::setDefault(), QPushButton::isDefault() |
176 | and QPushButton::autoDefault() to set and control the dialog's |
177 | default button. |
178 | |
179 | \target escapekey |
180 | \section1 Escape Key |
181 | |
182 | If the user presses the Esc key in a dialog, QDialog::reject() |
183 | will be called. This will cause the window to close: The \link |
184 | QCloseEvent close event \endlink cannot be \link |
185 | QCloseEvent::ignore() ignored \endlink. |
186 | |
187 | \section1 Extensibility |
188 | |
189 | Extensibility is the ability to show the dialog in two ways: a |
190 | partial dialog that shows the most commonly used options, and a |
191 | full dialog that shows all the options. Typically an extensible |
192 | dialog will initially appear as a partial dialog, but with a |
193 | \gui More toggle button. If the user presses the \gui More button down, |
194 | the dialog is expanded. The \l{Extension Example} shows how to achieve |
195 | extensible dialogs using Qt. |
196 | |
197 | \target return |
198 | \section1 Return Value (Modal Dialogs) |
199 | |
200 | Modal dialogs are often used in situations where a return value is |
201 | required, e.g. to indicate whether the user pressed \gui OK or |
202 | \gui Cancel. A dialog can be closed by calling the accept() or the |
203 | reject() slots, and exec() will return \c Accepted or \c Rejected |
204 | as appropriate. The exec() call returns the result of the dialog. |
205 | The result is also available from result() if the dialog has not |
206 | been destroyed. |
207 | |
208 | In order to modify your dialog's close behavior, you can reimplement |
209 | the functions accept(), reject() or done(). The |
210 | \l{QWidget::closeEvent()}{closeEvent()} function should only be |
211 | reimplemented to preserve the dialog's position or to override the |
212 | standard close or reject behavior. |
213 | |
214 | \target examples |
215 | \section1 Code Examples |
216 | |
217 | A modal dialog: |
218 | |
219 | \snippet doc/src/snippets/dialogs/dialogs.cpp 1 |
220 | |
221 | A modeless dialog: |
222 | |
223 | \snippet doc/src/snippets/dialogs/dialogs.cpp 0 |
224 | |
225 | \sa QDialogButtonBox, QTabWidget, QWidget, QProgressDialog, |
226 | {fowler}{GUI Design Handbook: Dialogs, Standard}, {Extension Example}, |
227 | {Standard Dialogs Example} |
228 | */ |
229 | |
230 | /*! \enum QDialog::DialogCode |
231 | |
232 | The value returned by a modal dialog. |
233 | |
234 | \value Accepted |
235 | \value Rejected |
236 | */ |
237 | |
238 | /*! |
239 | \property QDialog::sizeGripEnabled |
240 | \brief whether the size grip is enabled |
241 | |
242 | A QSizeGrip is placed in the bottom-right corner of the dialog when this |
243 | property is enabled. By default, the size grip is disabled. |
244 | */ |
245 | |
246 | |
247 | /*! |
248 | Constructs a dialog with parent \a parent. |
249 | |
250 | A dialog is always a top-level widget, but if it has a parent, its |
251 | default location is centered on top of the parent. It will also |
252 | share the parent's taskbar entry. |
253 | |
254 | The widget flags \a f are passed on to the QWidget constructor. |
255 | If, for example, you don't want a What's This button in the title bar |
256 | of the dialog, pass Qt::WindowTitleHint | Qt::WindowSystemMenuHint in \a f. |
257 | |
258 | \sa QWidget::setWindowFlags() |
259 | */ |
260 | |
261 | QDialog::QDialog(QWidget *parent, Qt::WindowFlags f) |
262 | : QWidget(*new QDialogPrivate, parent, |
263 | f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0))) |
264 | { |
265 | #ifdef Q_WS_WINCE |
266 | if (!qt_wince_is_smartphone()) |
267 | setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint)); |
268 | #endif |
269 | |
270 | #ifdef Q_WS_S60 |
271 | if (S60->avkonComponentsSupportTransparency) { |
272 | bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground); |
273 | setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground |
274 | setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute |
275 | } |
276 | #endif |
277 | } |
278 | |
279 | #ifdef QT3_SUPPORT |
280 | /*! |
281 | \overload |
282 | \obsolete |
283 | */ |
284 | QDialog::QDialog(QWidget *parent, const char *name, bool modal, Qt::WindowFlags f) |
285 | : QWidget(*new QDialogPrivate, parent, |
286 | f |
287 | | QFlag(modal ? Qt::WShowModal : Qt::WindowType(0)) |
288 | | QFlag((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)) |
289 | ) |
290 | { |
291 | setObjectName(QString::fromAscii(name)); |
292 | } |
293 | #endif |
294 | |
295 | /*! |
296 | \overload |
297 | \internal |
298 | */ |
299 | QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f) |
300 | : QWidget(dd, parent, f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0))) |
301 | { |
302 | #ifdef Q_WS_WINCE |
303 | if (!qt_wince_is_smartphone()) |
304 | setWindowFlags(windowFlags() | Qt::WindowOkButtonHint | QFlag(qt_wince_is_mobile() ? 0 : Qt::WindowCancelButtonHint)); |
305 | #endif |
306 | |
307 | #ifdef Q_WS_S60 |
308 | if (S60->avkonComponentsSupportTransparency) { |
309 | bool noSystemBackground = testAttribute(Qt::WA_NoSystemBackground); |
310 | setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground |
311 | setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute |
312 | } |
313 | #endif |
314 | } |
315 | |
316 | /*! |
317 | Destroys the QDialog, deleting all its children. |
318 | */ |
319 | |
320 | QDialog::~QDialog() |
321 | { |
322 | QT_TRY { |
323 | // Need to hide() here, as our (to-be) overridden hide() |
324 | // will not be called in ~QWidget. |
325 | hide(); |
326 | } QT_CATCH(...) { |
327 | // we're in the destructor - just swallow the exception |
328 | } |
329 | } |
330 | |
331 | /*! |
332 | \internal |
333 | This function is called by the push button \a pushButton when it |
334 | becomes the default button. If \a pushButton is 0, the dialogs |
335 | default default button becomes the default button. This is what a |
336 | push button calls when it loses focus. |
337 | */ |
338 | void QDialogPrivate::setDefault(QPushButton *pushButton) |
339 | { |
340 | Q_Q(QDialog); |
341 | bool hasMain = false; |
342 | QList<QPushButton*> list = q->findChildren<QPushButton*>(); |
343 | for (int i=0; i<list.size(); ++i) { |
344 | QPushButton *pb = list.at(i); |
345 | if (pb->window() == q) { |
346 | if (pb == mainDef) |
347 | hasMain = true; |
348 | if (pb != pushButton) |
349 | pb->setDefault(false); |
350 | } |
351 | } |
352 | if (!pushButton && hasMain) |
353 | mainDef->setDefault(true); |
354 | if (!hasMain) |
355 | mainDef = pushButton; |
356 | } |
357 | |
358 | /*! |
359 | \internal |
360 | This function sets the default default push button to \a pushButton. |
361 | This function is called by QPushButton::setDefault(). |
362 | */ |
363 | void QDialogPrivate::setMainDefault(QPushButton *pushButton) |
364 | { |
365 | mainDef = 0; |
366 | setDefault(pushButton); |
367 | } |
368 | |
369 | /*! |
370 | \internal |
371 | Hides the default button indicator. Called when non auto-default |
372 | push button get focus. |
373 | */ |
374 | void QDialogPrivate::hideDefault() |
375 | { |
376 | Q_Q(QDialog); |
377 | QList<QPushButton*> list = q->findChildren<QPushButton*>(); |
378 | for (int i=0; i<list.size(); ++i) { |
379 | list.at(i)->setDefault(false); |
380 | } |
381 | } |
382 | |
383 | void QDialogPrivate::resetModalitySetByOpen() |
384 | { |
385 | Q_Q(QDialog); |
386 | if (resetModalityTo != -1 && !q->testAttribute(Qt::WA_SetWindowModality)) { |
387 | // open() changed the window modality and the user didn't touch it afterwards; restore it |
388 | q->setWindowModality(Qt::WindowModality(resetModalityTo)); |
389 | q->setAttribute(Qt::WA_SetWindowModality, wasModalitySet); |
390 | #ifdef Q_WS_MAC |
391 | Q_ASSERT(resetModalityTo != Qt::WindowModal); |
392 | q->setParent(q->parentWidget(), Qt::Dialog); |
393 | #endif |
394 | } |
395 | resetModalityTo = -1; |
396 | } |
397 | |
398 | #if defined(Q_WS_WINCE) || defined(Q_OS_SYMBIAN) |
399 | #ifdef Q_WS_WINCE_WM |
400 | void QDialogPrivate::_q_doneAction() |
401 | { |
402 | //Done... |
403 | QApplication::postEvent(q_func(), new QEvent(QEvent::OkRequest)); |
404 | } |
405 | #endif |
406 | |
407 | /*! |
408 | \reimp |
409 | */ |
410 | bool QDialog::event(QEvent *e) |
411 | { |
412 | bool result = QWidget::event(e); |
413 | #ifdef Q_WS_WINCE |
414 | if (e->type() == QEvent::OkRequest) { |
415 | accept(); |
416 | result = true; |
417 | } |
418 | #elif defined(Q_WS_S60) |
419 | if ((e->type() == QEvent::StyleChange) || (e->type() == QEvent::Resize )) { |
420 | if (!testAttribute(Qt::WA_Moved)) { |
421 | Qt::WindowStates state = windowState(); |
422 | adjustPosition(parentWidget()); |
423 | setAttribute(Qt::WA_Moved, false); // not really an explicit position |
424 | if (state != windowState()) |
425 | setWindowState(state); |
426 | } |
427 | } |
428 | // TODO is Symbian, non-S60 behaviour required? |
429 | #endif |
430 | return result; |
431 | } |
432 | #endif |
433 | |
434 | /*! |
435 | In general returns the modal dialog's result code, \c Accepted or \c Rejected. |
436 | |
437 | \note When used from QMessageBox instance the result code type is \l QMessageBox::StandardButton |
438 | |
439 | Do not call this function if the dialog was constructed with the |
440 | Qt::WA_DeleteOnClose attribute. |
441 | */ |
442 | int QDialog::result() const |
443 | { |
444 | Q_D(const QDialog); |
445 | return d->rescode; |
446 | } |
447 | |
448 | /*! |
449 | \fn void QDialog::setResult(int i) |
450 | |
451 | Sets the modal dialog's result code to \a i. |
452 | |
453 | \note We recommend that you use one of the values defined by |
454 | QDialog::DialogCode. |
455 | */ |
456 | void QDialog::setResult(int r) |
457 | { |
458 | Q_D(QDialog); |
459 | d->rescode = r; |
460 | } |
461 | |
462 | /*! |
463 | \since 4.5 |
464 | |
465 | Shows the dialog as a \l{QDialog#Modal Dialogs}{window modal dialog}, |
466 | returning immediately. |
467 | |
468 | \sa exec(), show(), result(), setWindowModality() |
469 | */ |
470 | void QDialog::open() |
471 | { |
472 | Q_D(QDialog); |
473 | |
474 | Qt::WindowModality modality = windowModality(); |
475 | if (modality != Qt::WindowModal) { |
476 | d->resetModalityTo = modality; |
477 | d->wasModalitySet = testAttribute(Qt::WA_SetWindowModality); |
478 | setWindowModality(Qt::WindowModal); |
479 | setAttribute(Qt::WA_SetWindowModality, false); |
480 | #ifdef Q_WS_MAC |
481 | setParent(parentWidget(), Qt::Sheet); |
482 | #endif |
483 | } |
484 | |
485 | setResult(0); |
486 | show(); |
487 | } |
488 | |
489 | /*! |
490 | Shows the dialog as a \l{QDialog#Modal Dialogs}{modal dialog}, |
491 | blocking until the user closes it. The function returns a \l |
492 | DialogCode result. |
493 | |
494 | If the dialog is \l{Qt::ApplicationModal}{application modal}, users cannot |
495 | interact with any other window in the same application until they close |
496 | the dialog. If the dialog is \l{Qt::ApplicationModal}{window modal}, only |
497 | interaction with the parent window is blocked while the dialog is open. |
498 | By default, the dialog is application modal. |
499 | |
500 | \sa open(), show(), result(), setWindowModality() |
501 | */ |
502 | |
503 | int QDialog::exec() |
504 | { |
505 | Q_D(QDialog); |
506 | |
507 | if (d->eventLoop) { |
508 | qWarning("QDialog::exec: Recursive call detected" ); |
509 | return -1; |
510 | } |
511 | |
512 | bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose); |
513 | setAttribute(Qt::WA_DeleteOnClose, false); |
514 | |
515 | d->resetModalitySetByOpen(); |
516 | |
517 | bool wasShowModal = testAttribute(Qt::WA_ShowModal); |
518 | setAttribute(Qt::WA_ShowModal, true); |
519 | setResult(0); |
520 | |
521 | //On Windows Mobile we create an empty menu to hide the current menu |
522 | #ifdef Q_WS_WINCE_WM |
523 | #ifndef QT_NO_MENUBAR |
524 | QMenuBar *menuBar = 0; |
525 | if (!findChild<QMenuBar *>()) |
526 | menuBar = new QMenuBar(this); |
527 | if (qt_wince_is_smartphone()) { |
528 | QAction *doneAction = new QAction(tr("Done" ), this); |
529 | menuBar->setDefaultAction(doneAction); |
530 | connect(doneAction, SIGNAL(triggered()), this, SLOT(_q_doneAction())); |
531 | } |
532 | #endif //QT_NO_MENUBAR |
533 | #endif //Q_WS_WINCE_WM |
534 | |
535 | bool showSystemDialogFullScreen = false; |
536 | |
537 | #ifdef Q_OS_SYMBIAN |
538 | if (qobject_cast<QFileDialog *>(this) || qobject_cast<QFontDialog *>(this) || |
539 | qobject_cast<QWizard *>(this)) { |
540 | showSystemDialogFullScreen = true; |
541 | } |
542 | #endif // Q_OS_SYMBIAN |
543 | |
544 | #ifdef Q_OS_BLACKBERRY |
545 | if (!qobject_cast<QMessageBox *>(this)) |
546 | showSystemDialogFullScreen = true; |
547 | #endif // Q_OS_BLACKBERRY |
548 | |
549 | if (showSystemDialogFullScreen) { |
550 | setWindowFlags(windowFlags() | Qt::WindowSoftkeysVisibleHint); |
551 | setWindowState(Qt::WindowFullScreen); |
552 | } |
553 | show(); |
554 | |
555 | #ifdef Q_WS_MAC |
556 | d->mac_nativeDialogModalHelp(); |
557 | #endif |
558 | |
559 | QEventLoop eventLoop; |
560 | d->eventLoop = &eventLoop; |
561 | QPointer<QDialog> guard = this; |
562 | (void) eventLoop.exec(QEventLoop::DialogExec); |
563 | if (guard.isNull()) |
564 | return QDialog::Rejected; |
565 | d->eventLoop = 0; |
566 | |
567 | setAttribute(Qt::WA_ShowModal, wasShowModal); |
568 | |
569 | int res = result(); |
570 | if (deleteOnClose) |
571 | delete this; |
572 | #ifdef Q_WS_WINCE_WM |
573 | #ifndef QT_NO_MENUBAR |
574 | else if (menuBar) |
575 | delete menuBar; |
576 | #endif //QT_NO_MENUBAR |
577 | #endif //Q_WS_WINCE_WM |
578 | return res; |
579 | } |
580 | |
581 | |
582 | /*! |
583 | Closes the dialog and sets its result code to \a r. If this dialog |
584 | is shown with exec(), done() causes the local event loop to finish, |
585 | and exec() to return \a r. |
586 | |
587 | As with QWidget::close(), done() deletes the dialog if the |
588 | Qt::WA_DeleteOnClose flag is set. If the dialog is the application's |
589 | main widget, the application terminates. If the dialog is the |
590 | last window closed, the QApplication::lastWindowClosed() signal is |
591 | emitted. |
592 | |
593 | \sa accept(), reject(), QApplication::activeWindow(), QApplication::quit() |
594 | */ |
595 | |
596 | void QDialog::done(int r) |
597 | { |
598 | Q_D(QDialog); |
599 | hide(); |
600 | setResult(r); |
601 | |
602 | d->close_helper(QWidgetPrivate::CloseNoEvent); |
603 | d->resetModalitySetByOpen(); |
604 | |
605 | emit finished(r); |
606 | if (r == Accepted) |
607 | emit accepted(); |
608 | else if (r == Rejected) |
609 | emit rejected(); |
610 | } |
611 | |
612 | /*! |
613 | Hides the modal dialog and sets the result code to \c Accepted. |
614 | |
615 | \sa reject() done() |
616 | */ |
617 | |
618 | void QDialog::accept() |
619 | { |
620 | done(Accepted); |
621 | } |
622 | |
623 | /*! |
624 | Hides the modal dialog and sets the result code to \c Rejected. |
625 | |
626 | \sa accept() done() |
627 | */ |
628 | |
629 | void QDialog::reject() |
630 | { |
631 | done(Rejected); |
632 | } |
633 | |
634 | /*! \reimp */ |
635 | bool QDialog::eventFilter(QObject *o, QEvent *e) |
636 | { |
637 | return QWidget::eventFilter(o, e); |
638 | } |
639 | |
640 | /***************************************************************************** |
641 | Event handlers |
642 | *****************************************************************************/ |
643 | |
644 | #ifndef QT_NO_CONTEXTMENU |
645 | /*! \reimp */ |
646 | void QDialog::(QContextMenuEvent *e) |
647 | { |
648 | #if defined(QT_NO_WHATSTHIS) || defined(QT_NO_MENU) |
649 | Q_UNUSED(e); |
650 | #else |
651 | QWidget *w = childAt(e->pos()); |
652 | if (!w) { |
653 | w = rect().contains(e->pos()) ? this : 0; |
654 | if (!w) |
655 | return; |
656 | } |
657 | while (w && w->whatsThis().size() == 0 && !w->testAttribute(Qt::WA_CustomWhatsThis)) |
658 | w = w->isWindow() ? 0 : w->parentWidget(); |
659 | if (w) { |
660 | QWeakPointer<QMenu> p = new QMenu(this); |
661 | QAction *wt = p.data()->addAction(tr("What's This?" )); |
662 | if (p.data()->exec(e->globalPos()) == wt) { |
663 | QHelpEvent e(QEvent::WhatsThis, w->rect().center(), |
664 | w->mapToGlobal(w->rect().center())); |
665 | QApplication::sendEvent(w, &e); |
666 | } |
667 | delete p.data(); |
668 | } |
669 | #endif |
670 | } |
671 | #endif // QT_NO_CONTEXTMENU |
672 | |
673 | /*! \reimp */ |
674 | void QDialog::keyPressEvent(QKeyEvent *e) |
675 | { |
676 | // Calls reject() if Escape is pressed. Simulates a button |
677 | // click for the default button if Enter is pressed. Move focus |
678 | // for the arrow keys. Ignore the rest. |
679 | #ifdef Q_WS_MAC |
680 | if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) { |
681 | reject(); |
682 | } else |
683 | #endif |
684 | if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) { |
685 | switch (e->key()) { |
686 | case Qt::Key_Enter: |
687 | case Qt::Key_Return: { |
688 | QList<QPushButton*> list = findChildren<QPushButton*>(); |
689 | for (int i=0; i<list.size(); ++i) { |
690 | QPushButton *pb = list.at(i); |
691 | if (pb->isDefault() && pb->isVisible()) { |
692 | if (pb->isEnabled()) |
693 | pb->click(); |
694 | return; |
695 | } |
696 | } |
697 | } |
698 | break; |
699 | case Qt::Key_Escape: |
700 | reject(); |
701 | break; |
702 | default: |
703 | e->ignore(); |
704 | return; |
705 | } |
706 | } else { |
707 | e->ignore(); |
708 | } |
709 | } |
710 | |
711 | /*! \reimp */ |
712 | void QDialog::closeEvent(QCloseEvent *e) |
713 | { |
714 | #ifndef QT_NO_WHATSTHIS |
715 | if (isModal() && QWhatsThis::inWhatsThisMode()) |
716 | QWhatsThis::leaveWhatsThisMode(); |
717 | #endif |
718 | if (isVisible()) { |
719 | QPointer<QObject> that = this; |
720 | reject(); |
721 | if (that && isVisible()) |
722 | e->ignore(); |
723 | } else { |
724 | e->accept(); |
725 | } |
726 | } |
727 | |
728 | /***************************************************************************** |
729 | Geometry management. |
730 | *****************************************************************************/ |
731 | |
732 | /*! \reimp |
733 | */ |
734 | |
735 | void QDialog::setVisible(bool visible) |
736 | { |
737 | Q_D(QDialog); |
738 | if (visible) { |
739 | if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) |
740 | return; |
741 | |
742 | if (!testAttribute(Qt::WA_Moved)) { |
743 | Qt::WindowStates state = windowState(); |
744 | adjustPosition(parentWidget()); |
745 | setAttribute(Qt::WA_Moved, false); // not really an explicit position |
746 | if (state != windowState()) |
747 | setWindowState(state); |
748 | } |
749 | QWidget::setVisible(visible); |
750 | showExtension(d->doShowExtension); |
751 | QWidget *fw = window()->focusWidget(); |
752 | if (!fw) |
753 | fw = this; |
754 | |
755 | /* |
756 | The following block is to handle a special case, and does not |
757 | really follow propper logic in concern of autoDefault and TAB |
758 | order. However, it's here to ease usage for the users. If a |
759 | dialog has a default QPushButton, and first widget in the TAB |
760 | order also is a QPushButton, then we give focus to the main |
761 | default QPushButton. This simplifies code for the developers, |
762 | and actually catches most cases... If not, then they simply |
763 | have to use [widget*]->setFocus() themselves... |
764 | */ |
765 | if (d->mainDef && fw->focusPolicy() == Qt::NoFocus) { |
766 | QWidget *first = fw; |
767 | while ((first = first->nextInFocusChain()) != fw && first->focusPolicy() == Qt::NoFocus) |
768 | ; |
769 | if (first != d->mainDef && qobject_cast<QPushButton*>(first)) |
770 | d->mainDef->setFocus(); |
771 | } |
772 | if (!d->mainDef && isWindow()) { |
773 | QWidget *w = fw; |
774 | while ((w = w->nextInFocusChain()) != fw) { |
775 | QPushButton *pb = qobject_cast<QPushButton *>(w); |
776 | if (pb && pb->autoDefault() && pb->focusPolicy() != Qt::NoFocus) { |
777 | pb->setDefault(true); |
778 | break; |
779 | } |
780 | } |
781 | } |
782 | if (fw && !fw->hasFocus()) { |
783 | QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason); |
784 | QApplication::sendEvent(fw, &e); |
785 | } |
786 | |
787 | #ifndef QT_NO_ACCESSIBILITY |
788 | QAccessible::updateAccessibility(this, 0, QAccessible::DialogStart); |
789 | #endif |
790 | |
791 | } else { |
792 | if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) |
793 | return; |
794 | |
795 | #ifndef QT_NO_ACCESSIBILITY |
796 | if (isVisible()) |
797 | QAccessible::updateAccessibility(this, 0, QAccessible::DialogEnd); |
798 | #endif |
799 | |
800 | // Reimplemented to exit a modal event loop when the dialog is hidden. |
801 | QWidget::setVisible(visible); |
802 | if (d->eventLoop) |
803 | d->eventLoop->exit(); |
804 | } |
805 | #ifdef Q_WS_WIN |
806 | if (d->mainDef && isActiveWindow()) { |
807 | BOOL snapToDefault = false; |
808 | if (SystemParametersInfo(SPI_GETSNAPTODEFBUTTON, 0, &snapToDefault, 0)) { |
809 | if (snapToDefault) |
810 | QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center())); |
811 | } |
812 | } |
813 | #endif |
814 | } |
815 | |
816 | /*!\reimp */ |
817 | void QDialog::showEvent(QShowEvent *event) |
818 | { |
819 | if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) { |
820 | Qt::WindowStates state = windowState(); |
821 | adjustPosition(parentWidget()); |
822 | setAttribute(Qt::WA_Moved, false); // not really an explicit position |
823 | if (state != windowState()) |
824 | setWindowState(state); |
825 | } |
826 | } |
827 | |
828 | /*! \internal */ |
829 | void QDialog::adjustPosition(QWidget* w) |
830 | { |
831 | #ifdef Q_WS_X11 |
832 | // if the WM advertises that it will place the windows properly for us, let it do it :) |
833 | if (X11->isSupportedByWM(ATOM(_NET_WM_FULL_PLACEMENT))) |
834 | return; |
835 | #endif |
836 | |
837 | #ifdef Q_OS_SYMBIAN |
838 | if (symbianAdjustedPosition()) |
839 | //dialog has already been positioned |
840 | return; |
841 | #endif |
842 | |
843 | QPoint p(0, 0); |
844 | int = 0, = 0, scrn = 0; |
845 | if (w) |
846 | w = w->window(); |
847 | QRect desk; |
848 | if (w) { |
849 | scrn = QApplication::desktop()->screenNumber(w); |
850 | } else if (QApplication::desktop()->isVirtualDesktop()) { |
851 | scrn = QApplication::desktop()->screenNumber(QCursor::pos()); |
852 | } else { |
853 | scrn = QApplication::desktop()->screenNumber(this); |
854 | } |
855 | desk = QApplication::desktop()->availableGeometry(scrn); |
856 | |
857 | QWidgetList list = QApplication::topLevelWidgets(); |
858 | for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) { |
859 | QWidget * current = list.at(i); |
860 | if (current->isVisible()) { |
861 | int framew = current->geometry().x() - current->x(); |
862 | int frameh = current->geometry().y() - current->y(); |
863 | |
864 | extraw = qMax(extraw, framew); |
865 | extrah = qMax(extrah, frameh); |
866 | } |
867 | } |
868 | |
869 | // sanity check for decoration frames. With embedding, we |
870 | // might get extraordinary values |
871 | if (extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40) { |
872 | extrah = 40; |
873 | extraw = 10; |
874 | } |
875 | |
876 | |
877 | if (w) { |
878 | // Use mapToGlobal rather than geometry() in case w might |
879 | // be embedded in another application |
880 | QPoint pp = w->mapToGlobal(QPoint(0,0)); |
881 | p = QPoint(pp.x() + w->width()/2, |
882 | pp.y() + w->height()/ 2); |
883 | } else { |
884 | // p = middle of the desktop |
885 | p = QPoint(desk.x() + desk.width()/2, desk.y() + desk.height()/2); |
886 | } |
887 | |
888 | // p = origin of this |
889 | p = QPoint(p.x()-width()/2 - extraw, |
890 | p.y()-height()/2 - extrah); |
891 | |
892 | |
893 | if (p.x() + extraw + width() > desk.x() + desk.width()) |
894 | p.setX(desk.x() + desk.width() - width() - extraw); |
895 | if (p.x() < desk.x()) |
896 | p.setX(desk.x()); |
897 | |
898 | if (p.y() + extrah + height() > desk.y() + desk.height()) |
899 | p.setY(desk.y() + desk.height() - height() - extrah); |
900 | if (p.y() < desk.y()) |
901 | p.setY(desk.y()); |
902 | |
903 | move(p); |
904 | } |
905 | |
906 | #if defined(Q_OS_SYMBIAN) |
907 | /*! \internal */ |
908 | bool QDialog::symbianAdjustedPosition() |
909 | { |
910 | #if defined(Q_WS_S60) |
911 | QPoint p; |
912 | QPoint oldPos = pos(); |
913 | if (isFullScreen()) { |
914 | p.setX(0); |
915 | p.setY(0); |
916 | } else if (isMaximized()) { |
917 | TRect statusPaneRect = TRect(); |
918 | if (S60->screenHeightInPixels > S60->screenWidthInPixels) { |
919 | AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane, statusPaneRect); |
920 | } else { |
921 | AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, statusPaneRect); |
922 | // In some native layouts, StaCon is not used. Try to fetch the status pane |
923 | // height from StatusPane component. |
924 | if (statusPaneRect.IsEmpty()) |
925 | AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStatusPane, statusPaneRect); |
926 | } |
927 | |
928 | p.setX(0); |
929 | p.setY(statusPaneRect.Height()); |
930 | } else { |
931 | // naive way to deduce screen orientation |
932 | if (S60->screenHeightInPixels > S60->screenWidthInPixels) { |
933 | int cbaHeight; |
934 | TRect rect; |
935 | AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, rect); |
936 | cbaHeight = rect.Height(); |
937 | p.setY(S60->screenHeightInPixels - height() - cbaHeight); |
938 | p.setX(0); |
939 | } else { |
940 | const int scrollbarWidth = style()->pixelMetric(QStyle::PM_ScrollBarExtent); |
941 | TRect staConTopRect = TRect(); |
942 | AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EStaconTop, staConTopRect); |
943 | if (staConTopRect.IsEmpty()) { |
944 | TRect cbaRect = TRect(); |
945 | AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect); |
946 | AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation(); |
947 | switch (cbaLocation) { |
948 | case AknLayoutUtils::EAknCbaLocationBottom: |
949 | p.setY(S60->screenHeightInPixels - height() - cbaRect.Height()); |
950 | p.setX((S60->screenWidthInPixels - width()) >> 1); |
951 | break; |
952 | case AknLayoutUtils::EAknCbaLocationRight: |
953 | p.setY((S60->screenHeightInPixels - height()) >> 1); |
954 | p.setX(qMax(0,S60->screenWidthInPixels - width() - scrollbarWidth - cbaRect.Width())); |
955 | break; |
956 | case AknLayoutUtils::EAknCbaLocationLeft: |
957 | p.setY((S60->screenHeightInPixels - height()) >> 1); |
958 | p.setX(qMax(0,scrollbarWidth + cbaRect.Width())); |
959 | break; |
960 | } |
961 | } else { |
962 | p.setY((S60->screenHeightInPixels - height()) >> 1); |
963 | p.setX(qMax(0,S60->screenWidthInPixels - width())); |
964 | } |
965 | } |
966 | } |
967 | if (oldPos != p || p.y() < 0) |
968 | move(p); |
969 | return true; |
970 | #else |
971 | // TODO - check positioning requirement for Symbian, non-s60 |
972 | return false; |
973 | #endif |
974 | } |
975 | #endif |
976 | |
977 | /*! |
978 | \obsolete |
979 | |
980 | If \a orientation is Qt::Horizontal, the extension will be displayed |
981 | to the right of the dialog's main area. If \a orientation is |
982 | Qt::Vertical, the extension will be displayed below the dialog's main |
983 | area. |
984 | |
985 | Instead of using this functionality, we recommend that you simply call |
986 | show() or hide() on the part of the dialog that you want to use as an |
987 | extension. See the \l{Extension Example} for details. |
988 | |
989 | \sa setExtension() |
990 | */ |
991 | void QDialog::setOrientation(Qt::Orientation orientation) |
992 | { |
993 | Q_D(QDialog); |
994 | d->orientation = orientation; |
995 | } |
996 | |
997 | /*! |
998 | \obsolete |
999 | |
1000 | Returns the dialog's extension orientation. |
1001 | |
1002 | Instead of using this functionality, we recommend that you simply call |
1003 | show() or hide() on the part of the dialog that you want to use as an |
1004 | extension. See the \l{Extension Example} for details. |
1005 | |
1006 | \sa extension() |
1007 | */ |
1008 | Qt::Orientation QDialog::orientation() const |
1009 | { |
1010 | Q_D(const QDialog); |
1011 | return d->orientation; |
1012 | } |
1013 | |
1014 | /*! |
1015 | \obsolete |
1016 | |
1017 | Sets the widget, \a extension, to be the dialog's extension, |
1018 | deleting any previous extension. The dialog takes ownership of the |
1019 | extension. Note that if 0 is passed any existing extension will be |
1020 | deleted. This function must only be called while the dialog is hidden. |
1021 | |
1022 | Instead of using this functionality, we recommend that you simply call |
1023 | show() or hide() on the part of the dialog that you want to use as an |
1024 | extension. See the \l{Extension Example} for details. |
1025 | |
1026 | \sa showExtension(), setOrientation() |
1027 | */ |
1028 | void QDialog::setExtension(QWidget* extension) |
1029 | { |
1030 | Q_D(QDialog); |
1031 | delete d->extension; |
1032 | d->extension = extension; |
1033 | |
1034 | if (!extension) |
1035 | return; |
1036 | |
1037 | if (extension->parentWidget() != this) |
1038 | extension->setParent(this); |
1039 | extension->hide(); |
1040 | } |
1041 | |
1042 | /*! |
1043 | \obsolete |
1044 | |
1045 | Returns the dialog's extension or 0 if no extension has been |
1046 | defined. |
1047 | |
1048 | Instead of using this functionality, we recommend that you simply call |
1049 | show() or hide() on the part of the dialog that you want to use as an |
1050 | extension. See the \l{Extension Example} for details. |
1051 | |
1052 | \sa showExtension(), setOrientation() |
1053 | */ |
1054 | QWidget* QDialog::extension() const |
1055 | { |
1056 | Q_D(const QDialog); |
1057 | return d->extension; |
1058 | } |
1059 | |
1060 | |
1061 | /*! |
1062 | \obsolete |
1063 | |
1064 | If \a showIt is true, the dialog's extension is shown; otherwise the |
1065 | extension is hidden. |
1066 | |
1067 | Instead of using this functionality, we recommend that you simply call |
1068 | show() or hide() on the part of the dialog that you want to use as an |
1069 | extension. See the \l{Extension Example} for details. |
1070 | |
1071 | \sa show(), setExtension(), setOrientation() |
1072 | */ |
1073 | void QDialog::showExtension(bool showIt) |
1074 | { |
1075 | Q_D(QDialog); |
1076 | d->doShowExtension = showIt; |
1077 | if (!d->extension) |
1078 | return; |
1079 | if (!testAttribute(Qt::WA_WState_Visible)) |
1080 | return; |
1081 | if (d->extension->isVisible() == showIt) |
1082 | return; |
1083 | |
1084 | if (showIt) { |
1085 | d->size = size(); |
1086 | d->min = minimumSize(); |
1087 | d->max = maximumSize(); |
1088 | if (layout()) |
1089 | layout()->setEnabled(false); |
1090 | QSize s(d->extension->sizeHint() |
1091 | .expandedTo(d->extension->minimumSize()) |
1092 | .boundedTo(d->extension->maximumSize())); |
1093 | if (d->orientation == Qt::Horizontal) { |
1094 | int h = qMax(height(), s.height()); |
1095 | d->extension->setGeometry(width(), 0, s.width(), h); |
1096 | setFixedSize(width() + s.width(), h); |
1097 | } else { |
1098 | int w = qMax(width(), s.width()); |
1099 | d->extension->setGeometry(0, height(), w, s.height()); |
1100 | setFixedSize(w, height() + s.height()); |
1101 | } |
1102 | d->extension->show(); |
1103 | #ifndef QT_NO_SIZEGRIP |
1104 | const bool sizeGripEnabled = isSizeGripEnabled(); |
1105 | setSizeGripEnabled(false); |
1106 | d->sizeGripEnabled = sizeGripEnabled; |
1107 | #endif |
1108 | } else { |
1109 | d->extension->hide(); |
1110 | // workaround for CDE window manager that won't shrink with (-1,-1) |
1111 | setMinimumSize(d->min.expandedTo(QSize(1, 1))); |
1112 | setMaximumSize(d->max); |
1113 | resize(d->size); |
1114 | if (layout()) |
1115 | layout()->setEnabled(true); |
1116 | #ifndef QT_NO_SIZEGRIP |
1117 | setSizeGripEnabled(d->sizeGripEnabled); |
1118 | #endif |
1119 | } |
1120 | } |
1121 | |
1122 | |
1123 | /*! \reimp */ |
1124 | QSize QDialog::sizeHint() const |
1125 | { |
1126 | Q_D(const QDialog); |
1127 | if (d->extension) { |
1128 | if (d->orientation == Qt::Horizontal) |
1129 | return QSize(QWidget::sizeHint().width(), |
1130 | qMax(QWidget::sizeHint().height(),d->extension->sizeHint().height())); |
1131 | else |
1132 | return QSize(qMax(QWidget::sizeHint().width(), d->extension->sizeHint().width()), |
1133 | QWidget::sizeHint().height()); |
1134 | } |
1135 | #if defined(Q_WS_S60) |
1136 | // if size is not fixed, try to adjust it according to S60 layoutting |
1137 | if (minimumSize() != maximumSize()) { |
1138 | // In S60, dialogs are always the width of screen (in portrait, regardless of current layout) |
1139 | return QSize(qMin(S60->screenHeightInPixels, S60->screenWidthInPixels), QWidget::sizeHint().height()); |
1140 | } else { |
1141 | return QWidget::sizeHint(); |
1142 | } |
1143 | #else |
1144 | return QWidget::sizeHint(); |
1145 | #endif //Q_WS_S60 |
1146 | } |
1147 | |
1148 | |
1149 | /*! \reimp */ |
1150 | QSize QDialog::minimumSizeHint() const |
1151 | { |
1152 | Q_D(const QDialog); |
1153 | if (d->extension) { |
1154 | if (d->orientation == Qt::Horizontal) |
1155 | return QSize(QWidget::minimumSizeHint().width(), |
1156 | qMax(QWidget::minimumSizeHint().height(), d->extension->minimumSizeHint().height())); |
1157 | else |
1158 | return QSize(qMax(QWidget::minimumSizeHint().width(), d->extension->minimumSizeHint().width()), |
1159 | QWidget::minimumSizeHint().height()); |
1160 | } |
1161 | |
1162 | return QWidget::minimumSizeHint(); |
1163 | } |
1164 | |
1165 | /*! |
1166 | \property QDialog::modal |
1167 | \brief whether show() should pop up the dialog as modal or modeless |
1168 | |
1169 | By default, this property is false and show() pops up the dialog |
1170 | as modeless. Setting his property to true is equivalent to setting |
1171 | QWidget::windowModality to Qt::ApplicationModal. |
1172 | |
1173 | exec() ignores the value of this property and always pops up the |
1174 | dialog as modal. |
1175 | |
1176 | \sa QWidget::windowModality, show(), exec() |
1177 | */ |
1178 | |
1179 | void QDialog::setModal(bool modal) |
1180 | { |
1181 | setAttribute(Qt::WA_ShowModal, modal); |
1182 | } |
1183 | |
1184 | |
1185 | bool QDialog::isSizeGripEnabled() const |
1186 | { |
1187 | #ifndef QT_NO_SIZEGRIP |
1188 | Q_D(const QDialog); |
1189 | return !!d->resizer; |
1190 | #else |
1191 | return false; |
1192 | #endif |
1193 | } |
1194 | |
1195 | |
1196 | void QDialog::setSizeGripEnabled(bool enabled) |
1197 | { |
1198 | #ifdef QT_NO_SIZEGRIP |
1199 | Q_UNUSED(enabled); |
1200 | #else |
1201 | Q_D(QDialog); |
1202 | #ifndef QT_NO_SIZEGRIP |
1203 | d->sizeGripEnabled = enabled; |
1204 | if (enabled && d->doShowExtension) |
1205 | return; |
1206 | #endif |
1207 | if (!enabled != !d->resizer) { |
1208 | if (enabled) { |
1209 | d->resizer = new QSizeGrip(this); |
1210 | // adjustSize() processes all events, which is suboptimal |
1211 | d->resizer->resize(d->resizer->sizeHint()); |
1212 | if (isRightToLeft()) |
1213 | d->resizer->move(rect().bottomLeft() -d->resizer->rect().bottomLeft()); |
1214 | else |
1215 | d->resizer->move(rect().bottomRight() -d->resizer->rect().bottomRight()); |
1216 | d->resizer->raise(); |
1217 | d->resizer->show(); |
1218 | } else { |
1219 | delete d->resizer; |
1220 | d->resizer = 0; |
1221 | } |
1222 | } |
1223 | #endif //QT_NO_SIZEGRIP |
1224 | } |
1225 | |
1226 | |
1227 | |
1228 | /*! \reimp */ |
1229 | void QDialog::resizeEvent(QResizeEvent *) |
1230 | { |
1231 | #ifndef QT_NO_SIZEGRIP |
1232 | Q_D(QDialog); |
1233 | if (d->resizer) { |
1234 | if (isRightToLeft()) |
1235 | d->resizer->move(rect().bottomLeft() -d->resizer->rect().bottomLeft()); |
1236 | else |
1237 | d->resizer->move(rect().bottomRight() -d->resizer->rect().bottomRight()); |
1238 | d->resizer->raise(); |
1239 | } |
1240 | #endif |
1241 | } |
1242 | |
1243 | /*! \fn void QDialog::finished(int result) |
1244 | \since 4.1 |
1245 | |
1246 | This signal is emitted when the dialog's \a result code has been |
1247 | set, either by the user or by calling done(), accept(), or |
1248 | reject(). |
1249 | |
1250 | Note that this signal is \e not emitted when hiding the dialog |
1251 | with hide() or setVisible(false). This includes deleting the |
1252 | dialog while it is visible. |
1253 | |
1254 | \sa accepted(), rejected() |
1255 | */ |
1256 | |
1257 | /*! \fn void QDialog::accepted() |
1258 | \since 4.1 |
1259 | |
1260 | This signal is emitted when the dialog has been accepted either by |
1261 | the user or by calling accept() or done() with the |
1262 | QDialog::Accepted argument. |
1263 | |
1264 | Note that this signal is \e not emitted when hiding the dialog |
1265 | with hide() or setVisible(false). This includes deleting the |
1266 | dialog while it is visible. |
1267 | |
1268 | \sa finished(), rejected() |
1269 | */ |
1270 | |
1271 | /*! \fn void QDialog::rejected() |
1272 | \since 4.1 |
1273 | |
1274 | This signal is emitted when the dialog has been rejected either by |
1275 | the user or by calling reject() or done() with the |
1276 | QDialog::Rejected argument. |
1277 | |
1278 | Note that this signal is \e not emitted when hiding the dialog |
1279 | with hide() or setVisible(false). This includes deleting the |
1280 | dialog while it is visible. |
1281 | |
1282 | \sa finished(), accepted() |
1283 | */ |
1284 | |
1285 | QT_END_NAMESPACE |
1286 | #include "moc_qdialog.cpp" |
1287 | |