1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qcolordialog.h"
43 #include "qfontdialog.h"
44 #include "qfiledialog.h"
47 #include "qdesktopwidget.h"
48 #include "qpushbutton.h"
49 #include "qapplication.h"
51 #include "qsizegrip.h"
52 #include "qwhatsthis.h"
55 #include "private/qdialog_p.h"
56 #include "private/qguiapplication_p.h"
57 #ifndef QT_NO_ACCESSIBILITY
58 #include "qaccessible.h"
63 static inline int themeDialogType(const QDialog *dialog)
65 if (qobject_cast<const QFileDialog *>(dialog))
66 return QPlatformTheme::FileDialog;
67 if (qobject_cast<const QColorDialog *>(dialog))
68 return QPlatformTheme::ColorDialog;
69 if (qobject_cast<const QFontDialog *>(dialog))
70 return QPlatformTheme::FontDialog;
74 QPlatformDialogHelper *QDialogPrivate::platformHelper() const
76 // Delayed creation of the platform, ensuring that
77 // that qobject_cast<> on the dialog works in the plugin.
78 if (!m_platformHelperCreated) {
79 m_platformHelperCreated = true;
80 QDialogPrivate *ncThis = const_cast<QDialogPrivate *>(this);
81 QDialog *dialog = ncThis->q_func();
82 const int type = themeDialogType(dialog);
84 m_platformHelper = QGuiApplicationPrivate::platformTheme()
85 ->createPlatformDialogHelper(static_cast<QPlatformTheme::DialogType>(type));
86 if (m_platformHelper) {
87 QObject::connect(m_platformHelper, SIGNAL(accept()), dialog, SLOT(accept()));
88 QObject::connect(m_platformHelper, SIGNAL(reject()), dialog, SLOT(reject()));
89 QObject::connect(m_platformHelper, SIGNAL(launchNativeAppModalPanel()),
90 dialog, SLOT(_q_platformRunNativeAppModalPanel()));
91 ncThis->initHelper(m_platformHelper);
95 return m_platformHelper;
98 QWindow *QDialogPrivate::parentWindow() const
100 if (const QWidget *parent = q_func()->nativeParentWidget())
101 return parent->windowHandle();
105 bool QDialogPrivate::setNativeDialogVisible(bool visible)
107 if (QPlatformDialogHelper *helper = platformHelper()) {
109 helperPrepareShow(helper);
110 QPlatformDialogHelper::ShowFlags flags(0);
111 if (q_func()->isModal())
112 flags |= QPlatformDialogHelper::ShowModal;
113 nativeDialogInUse = helper->show_sys(flags, q_func()->windowFlags(), parentWindow());
118 return nativeDialogInUse;
121 void QDialogPrivate::_q_platformRunNativeAppModalPanel()
123 if (nativeDialogInUse)
124 platformHelper()->_q_platformRunNativeAppModalPanel();
128 QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const
130 if (const QPlatformDialogHelper *helper = platformHelper())
131 return helper->styleHint(hint);
132 return QPlatformDialogHelper::defaultStyleHint(hint);
137 \brief The QDialog class is the base class of dialog windows.
139 \ingroup dialog-classes
140 \ingroup abstractwidgets
143 A dialog window is a top-level window mostly used for short-term
144 tasks and brief communications with the user. QDialogs may be
145 modal or modeless. QDialogs can
146 provide a \link #return return
147 value\endlink, and they can have \link #default default
148 buttons\endlink. QDialogs can also have a QSizeGrip in their
149 lower-right corner, using setSizeGripEnabled().
151 Note that QDialog (an any other widget that has type Qt::Dialog) uses
152 the parent widget slightly differently from other classes in Qt. A
153 dialog is always a top-level widget, but if it has a parent, its
154 default location is centered on top of the parent's top-level widget
155 (if it is not top-level itself). It will also share the parent's
158 Use the overload of the QWidget::setParent() function to change
159 the ownership of a QDialog widget. This function allows you to
160 explicitly set the window flags of the reparented widget; using
161 the overloaded function will clear the window flags specifying the
162 window-system properties for the widget (in particular it will
163 reset the Qt::Dialog flag).
165 \section1 Modal Dialogs
167 A \bold{modal} dialog is a dialog that blocks input to other
168 visible windows in the same application. Dialogs that are used to
169 request a file name from the user or that are used to set
170 application preferences are usually modal. Dialogs can be
171 \l{Qt::ApplicationModal}{application modal} (the default) or
172 \l{Qt::WindowModal}{window modal}.
174 When an application modal dialog is opened, the user must finish
175 interacting with the dialog and close it before they can access
176 any other window in the application. Window modal dialogs only
177 block access to the window associated with the dialog, allowing
178 the user to continue to use other windows in an application.
180 The most common way to display a modal dialog is to call its
181 exec() function. When the user closes the dialog, exec() will
182 provide a useful \link #return return value\endlink. Typically,
183 to get the dialog to close and return the appropriate value, we
184 connect a default button, e.g. \gui OK, to the accept() slot and a
185 \gui Cancel button to the reject() slot.
186 Alternatively you can call the done() slot with \c Accepted or
189 An alternative is to call setModal(true) or setWindowModality(),
190 then show(). Unlike exec(), show() returns control to the caller
191 immediately. Calling setModal(true) is especially useful for
192 progress dialogs, where the user must have the ability to interact
193 with the dialog, e.g. to cancel a long running operation. If you
194 use show() and setModal(true) together to perform a long operation,
195 you must call QApplication::processEvents() periodically during
196 processing to enable the user to interact with the dialog. (See
199 \section1 Modeless Dialogs
201 A \bold{modeless} dialog is a dialog that operates
202 independently of other windows in the same application. Find and
203 replace dialogs in word-processors are often modeless to allow the
204 user to interact with both the application's main window and with
207 Modeless dialogs are displayed using show(), which returns control
208 to the caller immediately.
210 If you invoke the \l{QWidget::show()}{show()} function after hiding
211 a dialog, the dialog will be displayed in its original position. This is
212 because the window manager decides the position for windows that
213 have not been explicitly placed by the programmer. To preserve the
214 position of a dialog that has been moved by the user, save its position
215 in your \l{QWidget::closeEvent()}{closeEvent()} handler and then
216 move the dialog to that position, before showing it again.
219 \section1 Default Button
221 A dialog's \e default button is the button that's pressed when the
222 user presses Enter (Return). This button is used to signify that
223 the user accepts the dialog's settings and wants to close the
224 dialog. Use QPushButton::setDefault(), QPushButton::isDefault()
225 and QPushButton::autoDefault() to set and control the dialog's
231 If the user presses the Esc key in a dialog, QDialog::reject()
232 will be called. This will cause the window to close: The \link
233 QCloseEvent close event \endlink cannot be \link
234 QCloseEvent::ignore() ignored \endlink.
236 \section1 Extensibility
238 Extensibility is the ability to show the dialog in two ways: a
239 partial dialog that shows the most commonly used options, and a
240 full dialog that shows all the options. Typically an extensible
241 dialog will initially appear as a partial dialog, but with a
242 \gui More toggle button. If the user presses the \gui More button down,
243 the dialog is expanded. The \l{Extension Example} shows how to achieve
244 extensible dialogs using Qt.
247 \section1 Return Value (Modal Dialogs)
249 Modal dialogs are often used in situations where a return value is
250 required, e.g. to indicate whether the user pressed \gui OK or
251 \gui Cancel. A dialog can be closed by calling the accept() or the
252 reject() slots, and exec() will return \c Accepted or \c Rejected
253 as appropriate. The exec() call returns the result of the dialog.
254 The result is also available from result() if the dialog has not
257 In order to modify your dialog's close behavior, you can reimplement
258 the functions accept(), reject() or done(). The
259 \l{QWidget::closeEvent()}{closeEvent()} function should only be
260 reimplemented to preserve the dialog's position or to override the
261 standard close or reject behavior.
264 \section1 Code Examples
268 \snippet doc/src/snippets/dialogs/dialogs.cpp 1
272 \snippet doc/src/snippets/dialogs/dialogs.cpp 0
274 \sa QDialogButtonBox, QTabWidget, QWidget, QProgressDialog,
275 {fowler}{GUI Design Handbook: Dialogs, Standard}, {Extension Example},
276 {Standard Dialogs Example}
279 /*! \enum QDialog::DialogCode
281 The value returned by a modal dialog.
288 \property QDialog::sizeGripEnabled
289 \brief whether the size grip is enabled
291 A QSizeGrip is placed in the bottom-right corner of the dialog when this
292 property is enabled. By default, the size grip is disabled.
297 Constructs a dialog with parent \a parent.
299 A dialog is always a top-level widget, but if it has a parent, its
300 default location is centered on top of the parent. It will also
301 share the parent's taskbar entry.
303 The widget flags \a f are passed on to the QWidget constructor.
304 If, for example, you don't want a What's This button in the title bar
305 of the dialog, pass Qt::WindowTitleHint | Qt::WindowSystemMenuHint in \a f.
307 \sa QWidget::setWindowFlags()
310 QDialog::QDialog(QWidget *parent, Qt::WindowFlags f)
311 : QWidget(*new QDialogPrivate, parent,
312 f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)))
320 QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f)
321 : QWidget(dd, parent, f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)))
326 Destroys the QDialog, deleting all its children.
332 // Need to hide() here, as our (to-be) overridden hide()
333 // will not be called in ~QWidget.
336 // we're in the destructor - just swallow the exception
342 This function is called by the push button \a pushButton when it
343 becomes the default button. If \a pushButton is 0, the dialogs
344 default default button becomes the default button. This is what a
345 push button calls when it loses focus.
347 void QDialogPrivate::setDefault(QPushButton *pushButton)
350 bool hasMain = false;
351 QList<QPushButton*> list = q->findChildren<QPushButton*>();
352 for (int i=0; i<list.size(); ++i) {
353 QPushButton *pb = list.at(i);
354 if (pb->window() == q) {
357 if (pb != pushButton)
358 pb->setDefault(false);
361 if (!pushButton && hasMain)
362 mainDef->setDefault(true);
364 mainDef = pushButton;
369 This function sets the default default push button to \a pushButton.
370 This function is called by QPushButton::setDefault().
372 void QDialogPrivate::setMainDefault(QPushButton *pushButton)
375 setDefault(pushButton);
380 Hides the default button indicator. Called when non auto-default
381 push button get focus.
383 void QDialogPrivate::hideDefault()
386 QList<QPushButton*> list = q->findChildren<QPushButton*>();
387 for (int i=0; i<list.size(); ++i) {
388 list.at(i)->setDefault(false);
392 void QDialogPrivate::resetModalitySetByOpen()
395 if (resetModalityTo != -1 && !q->testAttribute(Qt::WA_SetWindowModality)) {
396 // open() changed the window modality and the user didn't touch it afterwards; restore it
397 q->setWindowModality(Qt::WindowModality(resetModalityTo));
398 q->setAttribute(Qt::WA_SetWindowModality, wasModalitySet);
400 Q_ASSERT(resetModalityTo != Qt::WindowModal);
401 q->setParent(q->parentWidget(), Qt::Dialog);
404 resetModalityTo = -1;
407 #if defined(Q_OS_WINCE)
409 void QDialogPrivate::_q_doneAction()
412 QApplication::postEvent(q_func(), new QEvent(QEvent::OkRequest));
419 bool QDialog::event(QEvent *e)
421 bool result = QWidget::event(e);
423 if (e->type() == QEvent::OkRequest) {
433 Returns the modal dialog's result code, \c Accepted or \c Rejected.
435 Do not call this function if the dialog was constructed with the
436 Qt::WA_DeleteOnClose attribute.
438 int QDialog::result() const
445 \fn void QDialog::setResult(int i)
447 Sets the modal dialog's result code to \a i.
449 \note We recommend that you use one of the values defined by
452 void QDialog::setResult(int r)
461 Shows the dialog as a \l{QDialog#Modal Dialogs}{window modal dialog},
462 returning immediately.
464 \sa exec(), show(), result(), setWindowModality()
470 Qt::WindowModality modality = windowModality();
471 if (modality != Qt::WindowModal) {
472 d->resetModalityTo = modality;
473 d->wasModalitySet = testAttribute(Qt::WA_SetWindowModality);
474 setWindowModality(Qt::WindowModal);
475 setAttribute(Qt::WA_SetWindowModality, false);
477 setParent(parentWidget(), Qt::Sheet);
486 Shows the dialog as a \l{QDialog#Modal Dialogs}{modal dialog},
487 blocking until the user closes it. The function returns a \l
490 If the dialog is \l{Qt::ApplicationModal}{application modal}, users cannot
491 interact with any other window in the same application until they close
492 the dialog. If the dialog is \l{Qt::ApplicationModal}{window modal}, only
493 interaction with the parent window is blocked while the dialog is open.
494 By default, the dialog is application modal.
496 \sa open(), show(), result(), setWindowModality()
504 qWarning("QDialog::exec: Recursive call detected");
508 bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
509 setAttribute(Qt::WA_DeleteOnClose, false);
511 d->resetModalitySetByOpen();
513 bool wasShowModal = testAttribute(Qt::WA_ShowModal);
514 setAttribute(Qt::WA_ShowModal, true);
517 bool showSystemDialogFullScreen = false;
518 if (showSystemDialogFullScreen) {
519 setWindowFlags(windowFlags() | Qt::WindowSoftkeysVisibleHint);
520 setWindowState(Qt::WindowFullScreen);
524 if (d->nativeDialogInUse)
525 d->platformHelper()->platformNativeDialogModalHelp();
527 QEventLoop eventLoop;
528 d->eventLoop = &eventLoop;
529 QPointer<QDialog> guard = this;
530 (void) eventLoop.exec(QEventLoop::DialogExec);
532 return QDialog::Rejected;
535 setAttribute(Qt::WA_ShowModal, wasShowModal);
538 if (d->nativeDialogInUse)
539 d->helperDone(static_cast<QDialog::DialogCode>(res), d->platformHelper());
546 Closes the dialog and sets its result code to \a r. If this dialog
547 is shown with exec(), done() causes the local event loop to finish,
548 and exec() to return \a r.
550 As with QWidget::close(), done() deletes the dialog if the
551 Qt::WA_DeleteOnClose flag is set. If the dialog is the application's
552 main widget, the application terminates. If the dialog is the
553 last window closed, the QApplication::lastWindowClosed() signal is
556 \sa accept(), reject(), QApplication::activeWindow(), QApplication::quit()
559 void QDialog::done(int r)
565 d->close_helper(QWidgetPrivate::CloseNoEvent);
566 d->resetModalitySetByOpen();
571 else if (r == Rejected)
576 Hides the modal dialog and sets the result code to \c Accepted.
581 void QDialog::accept()
587 Hides the modal dialog and sets the result code to \c Rejected.
592 void QDialog::reject()
598 bool QDialog::eventFilter(QObject *o, QEvent *e)
600 return QWidget::eventFilter(o, e);
603 /*****************************************************************************
605 *****************************************************************************/
607 #ifndef QT_NO_CONTEXTMENU
609 void QDialog::contextMenuEvent(QContextMenuEvent *e)
611 #if defined(QT_NO_WHATSTHIS) || defined(QT_NO_MENU)
614 QWidget *w = childAt(e->pos());
616 w = rect().contains(e->pos()) ? this : 0;
620 while (w && w->whatsThis().size() == 0 && !w->testAttribute(Qt::WA_CustomWhatsThis))
621 w = w->isWindow() ? 0 : w->parentWidget();
623 QWeakPointer<QMenu> p = new QMenu(this);
624 QAction *wt = p.data()->addAction(tr("What's This?"));
625 if (p.data()->exec(e->globalPos()) == wt) {
626 QHelpEvent e(QEvent::WhatsThis, w->rect().center(),
627 w->mapToGlobal(w->rect().center()));
628 QApplication::sendEvent(w, &e);
634 #endif // QT_NO_CONTEXTMENU
637 void QDialog::keyPressEvent(QKeyEvent *e)
639 // Calls reject() if Escape is pressed. Simulates a button
640 // click for the default button if Enter is pressed. Move focus
641 // for the arrow keys. Ignore the rest.
643 if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) {
647 if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) {
650 case Qt::Key_Return: {
651 QList<QPushButton*> list = findChildren<QPushButton*>();
652 for (int i=0; i<list.size(); ++i) {
653 QPushButton *pb = list.at(i);
654 if (pb->isDefault() && pb->isVisible()) {
675 void QDialog::closeEvent(QCloseEvent *e)
677 #ifndef QT_NO_WHATSTHIS
678 if (isModal() && QWhatsThis::inWhatsThisMode())
679 QWhatsThis::leaveWhatsThisMode();
682 QPointer<QObject> that = this;
684 if (that && isVisible())
691 /*****************************************************************************
693 *****************************************************************************/
698 void QDialog::setVisible(bool visible)
702 if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
705 if (!testAttribute(Qt::WA_Moved)) {
706 Qt::WindowStates state = windowState();
707 adjustPosition(parentWidget());
708 setAttribute(Qt::WA_Moved, false); // not really an explicit position
709 if (state != windowState())
710 setWindowState(state);
712 QWidget::setVisible(visible);
713 showExtension(d->doShowExtension);
714 QWidget *fw = window()->focusWidget();
719 The following block is to handle a special case, and does not
720 really follow propper logic in concern of autoDefault and TAB
721 order. However, it's here to ease usage for the users. If a
722 dialog has a default QPushButton, and first widget in the TAB
723 order also is a QPushButton, then we give focus to the main
724 default QPushButton. This simplifies code for the developers,
725 and actually catches most cases... If not, then they simply
726 have to use [widget*]->setFocus() themselves...
728 if (d->mainDef && fw->focusPolicy() == Qt::NoFocus) {
730 while ((first = first->nextInFocusChain()) != fw && first->focusPolicy() == Qt::NoFocus)
732 if (first != d->mainDef && qobject_cast<QPushButton*>(first))
733 d->mainDef->setFocus();
735 if (!d->mainDef && isWindow()) {
737 while ((w = w->nextInFocusChain()) != fw) {
738 QPushButton *pb = qobject_cast<QPushButton *>(w);
739 if (pb && pb->autoDefault() && pb->focusPolicy() != Qt::NoFocus) {
740 pb->setDefault(true);
745 if (fw && !fw->hasFocus()) {
746 QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
747 QApplication::sendEvent(fw, &e);
750 #ifndef QT_NO_ACCESSIBILITY
751 QAccessible::updateAccessibility(QAccessibleEvent(QAccessible::DialogStart, this, 0));
755 if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
758 #ifndef QT_NO_ACCESSIBILITY
760 QAccessible::updateAccessibility(QAccessibleEvent(QAccessible::DialogEnd, this, 0));
763 // Reimplemented to exit a modal event loop when the dialog is hidden.
764 QWidget::setVisible(visible);
766 d->eventLoop->exit();
768 if (d->mainDef && isActiveWindow()
769 && d->styleHint(QPlatformDialogHelper::SnapToDefaultButton).toBool())
770 QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center()));
774 void QDialog::showEvent(QShowEvent *event)
776 if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) {
777 Qt::WindowStates state = windowState();
778 adjustPosition(parentWidget());
779 setAttribute(Qt::WA_Moved, false); // not really an explicit position
780 if (state != windowState())
781 setWindowState(state);
786 void QDialog::adjustPosition(QWidget* w)
789 // if the WM advertises that it will place the windows properly for us, let it do it :)
790 if (X11->isSupportedByWM(ATOM(_NET_WM_FULL_PLACEMENT)))
794 int extraw = 0, extrah = 0, scrn = 0;
799 scrn = QApplication::desktop()->screenNumber(w);
800 } else if (QApplication::desktop()->isVirtualDesktop()) {
801 scrn = QApplication::desktop()->screenNumber(QCursor::pos());
803 scrn = QApplication::desktop()->screenNumber(this);
805 desk = QApplication::desktop()->availableGeometry(scrn);
807 QWidgetList list = QApplication::topLevelWidgets();
808 for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) {
809 QWidget * current = list.at(i);
810 if (current->isVisible()) {
811 int framew = current->geometry().x() - current->x();
812 int frameh = current->geometry().y() - current->y();
814 extraw = qMax(extraw, framew);
815 extrah = qMax(extrah, frameh);
819 // sanity check for decoration frames. With embedding, we
820 // might get extraordinary values
821 if (extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40) {
828 // Use mapToGlobal rather than geometry() in case w might
829 // be embedded in another application
830 QPoint pp = w->mapToGlobal(QPoint(0,0));
831 p = QPoint(pp.x() + w->width()/2,
832 pp.y() + w->height()/ 2);
834 // p = middle of the desktop
835 p = QPoint(desk.x() + desk.width()/2, desk.y() + desk.height()/2);
838 // p = origin of this
839 p = QPoint(p.x()-width()/2 - extraw,
840 p.y()-height()/2 - extrah);
843 if (p.x() + extraw + width() > desk.x() + desk.width())
844 p.setX(desk.x() + desk.width() - width() - extraw);
845 if (p.x() < desk.x())
848 if (p.y() + extrah + height() > desk.y() + desk.height())
849 p.setY(desk.y() + desk.height() - height() - extrah);
850 if (p.y() < desk.y())
859 If \a orientation is Qt::Horizontal, the extension will be displayed
860 to the right of the dialog's main area. If \a orientation is
861 Qt::Vertical, the extension will be displayed below the dialog's main
864 Instead of using this functionality, we recommend that you simply call
865 show() or hide() on the part of the dialog that you want to use as an
866 extension. See the \l{Extension Example} for details.
870 void QDialog::setOrientation(Qt::Orientation orientation)
873 d->orientation = orientation;
879 Returns the dialog's extension orientation.
881 Instead of using this functionality, we recommend that you simply call
882 show() or hide() on the part of the dialog that you want to use as an
883 extension. See the \l{Extension Example} for details.
887 Qt::Orientation QDialog::orientation() const
890 return d->orientation;
896 Sets the widget, \a extension, to be the dialog's extension,
897 deleting any previous extension. The dialog takes ownership of the
898 extension. Note that if 0 is passed any existing extension will be
899 deleted. This function must only be called while the dialog is hidden.
901 Instead of using this functionality, we recommend that you simply call
902 show() or hide() on the part of the dialog that you want to use as an
903 extension. See the \l{Extension Example} for details.
905 \sa showExtension(), setOrientation()
907 void QDialog::setExtension(QWidget* extension)
911 d->extension = extension;
916 if (extension->parentWidget() != this)
917 extension->setParent(this);
924 Returns the dialog's extension or 0 if no extension has been
927 Instead of using this functionality, we recommend that you simply call
928 show() or hide() on the part of the dialog that you want to use as an
929 extension. See the \l{Extension Example} for details.
931 \sa showExtension(), setOrientation()
933 QWidget* QDialog::extension() const
943 If \a showIt is true, the dialog's extension is shown; otherwise the
946 Instead of using this functionality, we recommend that you simply call
947 show() or hide() on the part of the dialog that you want to use as an
948 extension. See the \l{Extension Example} for details.
950 \sa show(), setExtension(), setOrientation()
952 void QDialog::showExtension(bool showIt)
955 d->doShowExtension = showIt;
958 if (!testAttribute(Qt::WA_WState_Visible))
960 if (d->extension->isVisible() == showIt)
965 d->min = minimumSize();
966 d->max = maximumSize();
968 layout()->setEnabled(false);
969 QSize s(d->extension->sizeHint()
970 .expandedTo(d->extension->minimumSize())
971 .boundedTo(d->extension->maximumSize()));
972 if (d->orientation == Qt::Horizontal) {
973 int h = qMax(height(), s.height());
974 d->extension->setGeometry(width(), 0, s.width(), h);
975 setFixedSize(width() + s.width(), h);
977 int w = qMax(width(), s.width());
978 d->extension->setGeometry(0, height(), w, s.height());
979 setFixedSize(w, height() + s.height());
981 d->extension->show();
982 #ifndef QT_NO_SIZEGRIP
983 const bool sizeGripEnabled = isSizeGripEnabled();
984 setSizeGripEnabled(false);
985 d->sizeGripEnabled = sizeGripEnabled;
988 d->extension->hide();
989 // workaround for CDE window manager that won't shrink with (-1,-1)
990 setMinimumSize(d->min.expandedTo(QSize(1, 1)));
991 setMaximumSize(d->max);
994 layout()->setEnabled(true);
995 #ifndef QT_NO_SIZEGRIP
996 setSizeGripEnabled(d->sizeGripEnabled);
1003 QSize QDialog::sizeHint() const
1007 if (d->orientation == Qt::Horizontal)
1008 return QSize(QWidget::sizeHint().width(),
1009 qMax(QWidget::sizeHint().height(),d->extension->sizeHint().height()));
1011 return QSize(qMax(QWidget::sizeHint().width(), d->extension->sizeHint().width()),
1012 QWidget::sizeHint().height());
1014 return QWidget::sizeHint();
1019 QSize QDialog::minimumSizeHint() const
1023 if (d->orientation == Qt::Horizontal)
1024 return QSize(QWidget::minimumSizeHint().width(),
1025 qMax(QWidget::minimumSizeHint().height(), d->extension->minimumSizeHint().height()));
1027 return QSize(qMax(QWidget::minimumSizeHint().width(), d->extension->minimumSizeHint().width()),
1028 QWidget::minimumSizeHint().height());
1031 return QWidget::minimumSizeHint();
1035 \property QDialog::modal
1036 \brief whether show() should pop up the dialog as modal or modeless
1038 By default, this property is false and show() pops up the dialog
1039 as modeless. Setting his property to true is equivalent to setting
1040 QWidget::windowModality to Qt::ApplicationModal.
1042 exec() ignores the value of this property and always pops up the
1045 \sa QWidget::windowModality, show(), exec()
1048 void QDialog::setModal(bool modal)
1050 setAttribute(Qt::WA_ShowModal, modal);
1054 bool QDialog::isSizeGripEnabled() const
1056 #ifndef QT_NO_SIZEGRIP
1058 return !!d->resizer;
1065 void QDialog::setSizeGripEnabled(bool enabled)
1067 #ifdef QT_NO_SIZEGRIP
1071 #ifndef QT_NO_SIZEGRIP
1072 d->sizeGripEnabled = enabled;
1073 if (enabled && d->doShowExtension)
1076 if (!enabled != !d->resizer) {
1078 d->resizer = new QSizeGrip(this);
1079 // adjustSize() processes all events, which is suboptimal
1080 d->resizer->resize(d->resizer->sizeHint());
1081 if (isRightToLeft())
1082 d->resizer->move(rect().bottomLeft() -d->resizer->rect().bottomLeft());
1084 d->resizer->move(rect().bottomRight() -d->resizer->rect().bottomRight());
1085 d->resizer->raise();
1092 #endif //QT_NO_SIZEGRIP
1098 void QDialog::resizeEvent(QResizeEvent *)
1100 #ifndef QT_NO_SIZEGRIP
1103 if (isRightToLeft())
1104 d->resizer->move(rect().bottomLeft() -d->resizer->rect().bottomLeft());
1106 d->resizer->move(rect().bottomRight() -d->resizer->rect().bottomRight());
1107 d->resizer->raise();
1112 /*! \fn void QDialog::finished(int result)
1115 This signal is emitted when the dialog's \a result code has been
1116 set, either by the user or by calling done(), accept(), or
1119 Note that this signal is \e not emitted when hiding the dialog
1120 with hide() or setVisible(false). This includes deleting the
1121 dialog while it is visible.
1123 \sa accepted(), rejected()
1126 /*! \fn void QDialog::accepted()
1129 This signal is emitted when the dialog has been accepted either by
1130 the user or by calling accept() or done() with the
1131 QDialog::Accepted argument.
1133 Note that this signal is \e not emitted when hiding the dialog
1134 with hide() or setVisible(false). This includes deleting the
1135 dialog while it is visible.
1137 \sa finished(), rejected()
1140 /*! \fn void QDialog::rejected()
1143 This signal is emitted when the dialog has been rejected either by
1144 the user or by calling reject() or done() with the
1145 QDialog::Rejected argument.
1147 Note that this signal is \e not emitted when hiding the dialog
1148 with hide() or setVisible(false). This includes deleting the
1149 dialog while it is visible.
1151 \sa finished(), accepted()
1155 #include "moc_qdialog.cpp"