/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtWidgets/qtwidgetsglobal.h>
#if QT_CONFIG(colordialog)
#include "qcolordialog.h"
#endif
#if QT_CONFIG(fontdialog)
#include "qfontdialog.h"
#endif
#if QT_CONFIG(filedialog)
#include "qfiledialog.h"
#endif

#include "qevent.h"
#include "qdesktopwidget.h"
#include <private/qdesktopwidget_p.h>
#include "qapplication.h"
#include "qlayout.h"
#if QT_CONFIG(sizegrip)
#include "qsizegrip.h"
#endif
#if QT_CONFIG(whatsthis)
#include "qwhatsthis.h"
#endif
#if QT_CONFIG(menu)
#include "qmenu.h"
#endif
#include "qcursor.h"
#if QT_CONFIG(messagebox)
#include "qmessagebox.h"
#endif
#if QT_CONFIG(errormessage)
#include "qerrormessage.h"
#endif
#include <qpa/qplatformtheme.h>
#include "private/qdialog_p.h"
#include "private/qguiapplication_p.h"
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif

QT_BEGIN_NAMESPACE

static inline int themeDialogType(const QDialog *dialog)
{
#if QT_CONFIG(filedialog)
    if (qobject_cast<const QFileDialog *>(dialog))
        return QPlatformTheme::FileDialog;
#endif
#if QT_CONFIG(colordialog)
    if (qobject_cast<const QColorDialog *>(dialog))
        return QPlatformTheme::ColorDialog;
#endif
#if QT_CONFIG(fontdialog)
    if (qobject_cast<const QFontDialog *>(dialog))
        return QPlatformTheme::FontDialog;
#endif
#if QT_CONFIG(messagebox)
    if (qobject_cast<const QMessageBox *>(dialog))
        return QPlatformTheme::MessageDialog;
#endif
#if QT_CONFIG(errormessage)
    if (qobject_cast<const QErrorMessage *>(dialog))
        return QPlatformTheme::MessageDialog;
#endif
#if !QT_CONFIG(filedialog) && !QT_CONFIG(colordialog) && !QT_CONFIG(fontdialog) && \
    !QT_CONFIG(messagebox) && !QT_CONFIG(errormessage)
    Q_UNUSED(dialog);
#endif
    return -1;
}

QDialogPrivate::~QDialogPrivate()
{
    delete m_platformHelper;
}

QPlatformDialogHelper *QDialogPrivate::platformHelper() const
{
    // Delayed creation of the platform, ensuring that
    // that qobject_cast<> on the dialog works in the plugin.
    if (!m_platformHelperCreated && canBeNativeDialog()) {
        m_platformHelperCreated = true;
        QDialogPrivate *ncThis = const_cast<QDialogPrivate *>(this);
        QDialog *dialog = ncThis->q_func();
        const int type = themeDialogType(dialog);
        if (type >= 0) {
            m_platformHelper = QGuiApplicationPrivate::platformTheme()
                    ->createPlatformDialogHelper(static_cast<QPlatformTheme::DialogType>(type));
            if (m_platformHelper) {
                QObject::connect(m_platformHelper, SIGNAL(accept()), dialog, SLOT(accept()));
                QObject::connect(m_platformHelper, SIGNAL(reject()), dialog, SLOT(reject()));
                ncThis->initHelper(m_platformHelper);
            }
        }
    }
    return m_platformHelper;
}

bool QDialogPrivate::canBeNativeDialog() const
{
    QDialogPrivate *ncThis = const_cast<QDialogPrivate *>(this);
    QDialog *dialog = ncThis->q_func();
    const int type = themeDialogType(dialog);
    if (type >= 0)
        return QGuiApplicationPrivate::platformTheme()
                ->usePlatformNativeDialog(static_cast<QPlatformTheme::DialogType>(type));
    return false;
}

/*!
    \internal

    Properly hides dialog and sets the \a resultCode.
 */
void QDialogPrivate::hide(int resultCode)
{
    Q_Q(QDialog);

    q->setResult(resultCode);
    q->hide();

    close_helper(QWidgetPrivate::CloseNoEvent);
    resetModalitySetByOpen();
}

/*!
    \internal

    Emits finished() signal with \a resultCode. If the \a dialogCode
    is equal to 0 emits rejected(), if the \a dialogCode is equal to
    1 emits accepted().
 */
void QDialogPrivate::finalize(int resultCode, int dialogCode)
{
    Q_Q(QDialog);

    if (dialogCode == QDialog::Accepted)
        emit q->accepted();
    else if (dialogCode == QDialog::Rejected)
        emit q->rejected();

    emit q->finished(resultCode);
}

QWindow *QDialogPrivate::transientParentWindow() const
{
    Q_Q(const QDialog);
    if (const QWidget *parent = q->nativeParentWidget())
        return parent->windowHandle();
    else if (q->windowHandle())
        return q->windowHandle()->transientParent();
    return nullptr;
}

bool QDialogPrivate::setNativeDialogVisible(bool visible)
{
    if (QPlatformDialogHelper *helper = platformHelper()) {
        if (visible) {
            Q_Q(QDialog);
            helperPrepareShow(helper);
            nativeDialogInUse = helper->show(q->windowFlags(), q->windowModality(), transientParentWindow());
        } else if (nativeDialogInUse) {
            helper->hide();
        }
    }
    return nativeDialogInUse;
}

QVariant QDialogPrivate::styleHint(QPlatformDialogHelper::StyleHint hint) const
{
    if (const QPlatformDialogHelper *helper = platformHelper())
        return helper->styleHint(hint);
    return QPlatformDialogHelper::defaultStyleHint(hint);
}

void QDialogPrivate::deletePlatformHelper()
{
    delete m_platformHelper;
    m_platformHelper = nullptr;
    m_platformHelperCreated = false;
    nativeDialogInUse = false;
}

/*!
    \class QDialog
    \brief The QDialog class is the base class of dialog windows.

    \ingroup dialog-classes
    \ingroup abstractwidgets
    \inmodule QtWidgets

    A dialog window is a top-level window mostly used for short-term
    tasks and brief communications with the user. QDialogs may be
    modal or modeless. QDialogs can
    provide a \l{#return}{return value}, and they can have \l{#default}{default buttons}. QDialogs can also have a QSizeGrip in their
    lower-right corner, using setSizeGripEnabled().

    Note that QDialog (and any other widget that has type \c Qt::Dialog) uses
    the parent widget slightly differently from other classes in Qt. A dialog is
    always a top-level widget, but if it has a parent, its default location is
    centered on top of the parent's top-level widget (if it is not top-level
    itself). It will also share the parent's taskbar entry.

    Use the overload of the QWidget::setParent() function to change
    the ownership of a QDialog widget. This function allows you to
    explicitly set the window flags of the reparented widget; using
    the overloaded function will clear the window flags specifying the
    window-system properties for the widget (in particular it will
    reset the Qt::Dialog flag).

    \note The parent relationship of the dialog does \e{not} imply
    that the dialog will always be stacked on top of the parent
    window. To ensure that the dialog is always on top, make the
    dialog modal. This also applies for child windows of the dialog
    itself. To ensure that child windows of the dialog stay on top
    of the dialog, make the child windows modal as well.

    \section1 Modal Dialogs

    A \b{modal} dialog is a dialog that blocks input to other
    visible windows in the same application. Dialogs that are used to
    request a file name from the user or that are used to set
    application preferences are usually modal. Dialogs can be
    \l{Qt::ApplicationModal}{application modal} (the default) or
    \l{Qt::WindowModal}{window modal}.

    When an application modal dialog is opened, the user must finish
    interacting with the dialog and close it before they can access
    any other window in the application. Window modal dialogs only
    block access to the window associated with the dialog, allowing
    the user to continue to use other windows in an application.

    The most common way to display a modal dialog is to call its
    exec() function. When the user closes the dialog, exec() will
    provide a useful \l{#return}{return value}. To close the dialog
    and return the appropriate value, you must connect a default button,
    e.g. an \uicontrol OK button to the accept() slot and a
    \uicontrol Cancel button to the reject() slot. Alternatively, you
    can call the done() slot with \c Accepted or \c Rejected.

    An alternative is to call setModal(true) or setWindowModality(),
    then show(). Unlike exec(), show() returns control to the caller
    immediately. Calling setModal(true) is especially useful for
    progress dialogs, where the user must have the ability to interact
    with the dialog, e.g.  to cancel a long running operation. If you
    use show() and setModal(true) together to perform a long operation,
    you must call QCoreApplication::processEvents() periodically during
    processing to enable the user to interact with the dialog. (See
    QProgressDialog.)

    \section1 Modeless Dialogs

    A \b{modeless} dialog is a dialog that operates
    independently of other windows in the same application. Find and
    replace dialogs in word-processors are often modeless to allow the
    user to interact with both the application's main window and with
    the dialog.

    Modeless dialogs are displayed using show(), which returns control
    to the caller immediately.

    If you invoke the \l{QWidget::show()}{show()} function after hiding
    a dialog, the dialog will be displayed in its original position. This is
    because the window manager decides the position for windows that
    have not been explicitly placed by the programmer. To preserve the
    position of a dialog that has been moved by the user, save its position
    in your \l{QWidget::closeEvent()}{closeEvent()}  handler and then
    move the dialog to that position, before showing it again.

    \target default
    \section1 Default Button

    A dialog's \e default button is the button that's pressed when the
    user presses Enter (Return). This button is used to signify that
    the user accepts the dialog's settings and wants to close the
    dialog. Use QPushButton::setDefault(), QPushButton::isDefault()
    and QPushButton::autoDefault() to set and control the dialog's
    default button.

    \target escapekey
    \section1 Escape Key

    If the user presses the Esc key in a dialog, QDialog::reject()
    will be called. This will cause the window to close: The \l{QCloseEvent}{close event} cannot be \l{QEvent::ignore()}{ignored}.

    \section1 Extensibility

    Extensibility is the ability to show the dialog in two ways: a
    partial dialog that shows the most commonly used options, and a
    full dialog that shows all the options. Typically an extensible
    dialog will initially appear as a partial dialog, but with a
    \uicontrol More toggle button. If the user presses the \uicontrol More button down,
    the dialog is expanded. The \l{Extension Example} shows how to achieve
    extensible dialogs using Qt.

    \target return
    \section1 Return Value (Modal Dialogs)

    Modal dialogs are often used in situations where a return value is
    required, e.g. to indicate whether the user pressed \uicontrol OK or
    \uicontrol Cancel. A dialog can be closed by calling the accept() or the
    reject() slots, and exec() will return \c Accepted or \c Rejected
    as appropriate. The exec() call returns the result of the dialog.
    The result is also available from result() if the dialog has not
    been destroyed.

    In order to modify your dialog's close behavior, you can reimplement
    the functions accept(), reject() or done(). The
    \l{QWidget::closeEvent()}{closeEvent()} function should only be
    reimplemented to preserve the dialog's position or to override the
    standard close or reject behavior.

    \target examples
    \section1 Code Examples

    A modal dialog:

    \snippet dialogs/dialogs.cpp 1

    A modeless dialog:

    \snippet dialogs/dialogs.cpp 0

    \sa QDialogButtonBox, QTabWidget, QWidget, QProgressDialog,
        {fowler}{GUI Design Handbook: Dialogs, Standard}, {Extension Example},
        {Standard Dialogs Example}
*/

/*! \enum QDialog::DialogCode

    The value returned by a modal dialog.

    \value Accepted
    \value Rejected
*/

/*!
  \property QDialog::sizeGripEnabled
  \brief whether the size grip is enabled

  A QSizeGrip is placed in the bottom-right corner of the dialog when this
  property is enabled. By default, the size grip is disabled.
*/


/*!
  Constructs a dialog with parent \a parent.

  A dialog is always a top-level widget, but if it has a parent, its
  default location is centered on top of the parent. It will also
  share the parent's taskbar entry.

  The widget flags \a f are passed on to the QWidget constructor.
  If, for example, you don't want a What's This button in the title bar
  of the dialog, pass Qt::WindowTitleHint | Qt::WindowSystemMenuHint in \a f.

  \sa QWidget::setWindowFlags()
*/

QDialog::QDialog(QWidget *parent, Qt::WindowFlags f)
    : QWidget(*new QDialogPrivate, parent,
              f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)))
{
}

/*!
  \overload
  \internal
*/
QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f)
    : QWidget(dd, parent, f | ((f & Qt::WindowType_Mask) == 0 ? Qt::Dialog : Qt::WindowType(0)))
{
}

/*!
  Destroys the QDialog, deleting all its children.
*/

QDialog::~QDialog()
{
    QT_TRY {
        // Need to hide() here, as our (to-be) overridden hide()
        // will not be called in ~QWidget.
        hide();
    } QT_CATCH(...) {
        // we're in the destructor - just swallow the exception
    }
}

/*!
  \internal
  This function is called by the push button \a pushButton when it
  becomes the default button. If \a pushButton is \nullptr, the dialogs
  default default button becomes the default button. This is what a
  push button calls when it loses focus.
*/
#if QT_CONFIG(pushbutton)
void QDialogPrivate::setDefault(QPushButton *pushButton)
{
    Q_Q(QDialog);
    bool hasMain = false;
    QList<QPushButton*> list = q->findChildren<QPushButton*>();
    for (int i=0; i<list.size(); ++i) {
        QPushButton *pb = list.at(i);
        if (pb->window() == q) {
            if (pb == mainDef)
                hasMain = true;
            if (pb != pushButton)
                pb->setDefault(false);
        }
    }
    if (!pushButton && hasMain)
        mainDef->setDefault(true);
    if (!hasMain)
        mainDef = pushButton;
}

/*!
  \internal
  This function sets the default default push button to \a pushButton.
  This function is called by QPushButton::setDefault().
*/
void QDialogPrivate::setMainDefault(QPushButton *pushButton)
{
    mainDef = nullptr;
    setDefault(pushButton);
}

/*!
  \internal
  Hides the default button indicator. Called when non auto-default
  push button get focus.
 */
void QDialogPrivate::hideDefault()
{
    Q_Q(QDialog);
    QList<QPushButton*> list = q->findChildren<QPushButton*>();
    for (int i=0; i<list.size(); ++i) {
        list.at(i)->setDefault(false);
    }
}
#endif

void QDialogPrivate::resetModalitySetByOpen()
{
    Q_Q(QDialog);
    if (resetModalityTo != -1 && !q->testAttribute(Qt::WA_SetWindowModality)) {
        // open() changed the window modality and the user didn't touch it afterwards; restore it
        q->setWindowModality(Qt::WindowModality(resetModalityTo));
        q->setAttribute(Qt::WA_SetWindowModality, wasModalitySet);
#ifdef Q_OS_MAC
        Q_ASSERT(resetModalityTo != Qt::WindowModal);
        q->setParent(q->parentWidget(), Qt::Dialog);
#endif
    }
    resetModalityTo = -1;
}

/*!
  In general returns the modal dialog's result code, \c Accepted or
  \c Rejected.

  \note When called on a QMessageBox instance, the returned value is a
  value of the \l QMessageBox::StandardButton enum.

  Do not call this function if the dialog was constructed with the
  Qt::WA_DeleteOnClose attribute.
*/
int QDialog::result() const
{
    Q_D(const QDialog);
    return d->rescode;
}

/*!
  \fn void QDialog::setResult(int i)

  Sets the modal dialog's result code to \a i.

  \note We recommend that you use one of the values defined by
  QDialog::DialogCode.
*/
void QDialog::setResult(int r)
{
    Q_D(QDialog);
    d->rescode = r;
}

/*!
    \since 4.5

    Shows the dialog as a \l{QDialog#Modal Dialogs}{window modal dialog},
    returning immediately.

    \sa exec(), show(), result(), setWindowModality()
*/
void QDialog::open()
{
    Q_D(QDialog);

    Qt::WindowModality modality = windowModality();
    if (modality != Qt::WindowModal) {
        d->resetModalityTo = modality;
        d->wasModalitySet = testAttribute(Qt::WA_SetWindowModality);
        setWindowModality(Qt::WindowModal);
        setAttribute(Qt::WA_SetWindowModality, false);
#ifdef Q_OS_MAC
        setParent(parentWidget(), Qt::Sheet);
#endif
    }

    setResult(0);
    show();
}

/*!
    Shows the dialog as a \l{QDialog#Modal Dialogs}{modal dialog},
    blocking until the user closes it. The function returns a \l
    DialogCode result.

    If the dialog is \l{Qt::ApplicationModal}{application modal}, users cannot
    interact with any other window in the same application until they close
    the dialog. If the dialog is \l{Qt::ApplicationModal}{window modal}, only
    interaction with the parent window is blocked while the dialog is open.
    By default, the dialog is application modal.

    \note Avoid using this function; instead, use \c{open()}. Unlike exec(),
    open() is asynchronous, and does not spin an additional event loop. This
    prevents a series of dangerous bugs from happening (e.g. deleting the
    dialog's parent while the dialog is open via exec()). When using open() you
    can connect to the finished() signal of QDialog to be notified when the
    dialog is closed.

    \sa open(), show(), result(), setWindowModality()
*/

int QDialog::exec()
{
    Q_D(QDialog);

    if (Q_UNLIKELY(d->eventLoop)) {
        qWarning("QDialog::exec: Recursive call detected");
        return -1;
    }

    bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
    setAttribute(Qt::WA_DeleteOnClose, false);

    d->resetModalitySetByOpen();

    bool wasShowModal = testAttribute(Qt::WA_ShowModal);
    setAttribute(Qt::WA_ShowModal, true);
    setResult(0);

    show();

    QPointer<QDialog> guard = this;
    if (d->nativeDialogInUse) {
        d->platformHelper()->exec();
    } else {
        QEventLoop eventLoop;
        d->eventLoop = &eventLoop;
        (void) eventLoop.exec(QEventLoop::DialogExec);
    }
    if (guard.isNull())
        return QDialog::Rejected;
    d->eventLoop = nullptr;

    setAttribute(Qt::WA_ShowModal, wasShowModal);

    int res = result();
    if (d->nativeDialogInUse)
        d->helperDone(static_cast<QDialog::DialogCode>(res), d->platformHelper());
    if (deleteOnClose)
        delete this;
    return res;
}

/*!
  Closes the dialog and sets its result code to \a r. The finished() signal
  will emit \a r; if \a r is QDialog::Accepted or QDialog::Rejected, the
  accepted() or the rejected() signals will also be emitted, respectively.

  If this dialog is shown with exec(), done() also causes the local event loop
  to finish, and exec() to return \a r.

  As with QWidget::close(), done() deletes the dialog if the
  Qt::WA_DeleteOnClose flag is set. If the dialog is the application's
  main widget, the application terminates. If the dialog is the
  last window closed, the QApplication::lastWindowClosed() signal is
  emitted.

  \sa accept(), reject(), QApplication::activeWindow(), QCoreApplication::quit()
*/

void QDialog::done(int r)
{
    Q_D(QDialog);
    d->hide(r);
    d->finalize(r, r);
}

/*!
  Hides the modal dialog and sets the result code to \c Accepted.

  \sa reject(), done()
*/

void QDialog::accept()
{
    done(Accepted);
}

/*!
  Hides the modal dialog and sets the result code to \c Rejected.

  \sa accept(), done()
*/

void QDialog::reject()
{
    done(Rejected);
}

/*! \reimp */
bool QDialog::eventFilter(QObject *o, QEvent *e)
{
    return QWidget::eventFilter(o, e);
}

/*****************************************************************************
  Event handlers
 *****************************************************************************/

#ifndef QT_NO_CONTEXTMENU
/*! \reimp */
void QDialog::contextMenuEvent(QContextMenuEvent *e)
{
#if !QT_CONFIG(whatsthis) || !QT_CONFIG(menu)
    Q_UNUSED(e);
#else
    QWidget *w = childAt(e->pos());
    if (!w) {
        w = rect().contains(e->pos()) ? this : nullptr;
        if (!w)
            return;
    }
    while (w && w->whatsThis().size() == 0 && !w->testAttribute(Qt::WA_CustomWhatsThis))
        w = w->isWindow() ? nullptr : w->parentWidget();
    if (w) {
        QPointer<QMenu> p = new QMenu(this);
        QAction *wt = p.data()->addAction(tr("What's This?"));
        if (p.data()->exec(e->globalPos()) == wt) {
            QHelpEvent e(QEvent::WhatsThis, w->rect().center(),
                         w->mapToGlobal(w->rect().center()));
            QCoreApplication::sendEvent(w, &e);
        }
        delete p.data();
    }
#endif
}
#endif // QT_NO_CONTEXTMENU

/*! \reimp */
void QDialog::keyPressEvent(QKeyEvent *e)
{
#ifndef QT_NO_SHORTCUT
    //   Calls reject() if Escape is pressed. Simulates a button
    //   click for the default button if Enter is pressed. Move focus
    //   for the arrow keys. Ignore the rest.
    if (e->matches(QKeySequence::Cancel)) {
        reject();
    } else
#endif
    if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) {
        switch (e->key()) {
#if QT_CONFIG(pushbutton)
        case Qt::Key_Enter:
        case Qt::Key_Return: {
            QList<QPushButton*> list = findChildren<QPushButton*>();
            for (int i=0; i<list.size(); ++i) {
                QPushButton *pb = list.at(i);
                if (pb->isDefault() && pb->isVisible()) {
                    if (pb->isEnabled())
                        pb->click();
                    return;
                }
            }
        }
        break;
#endif
        default:
            e->ignore();
            return;
        }
    } else {
        e->ignore();
    }
}

/*! \reimp */
void QDialog::closeEvent(QCloseEvent *e)
{
#if QT_CONFIG(whatsthis)
    if (isModal() && QWhatsThis::inWhatsThisMode())
        QWhatsThis::leaveWhatsThisMode();
#endif
    if (isVisible()) {
        QPointer<QObject> that = this;
        reject();
        if (that && isVisible())
            e->ignore();
    } else {
        e->accept();
    }
}

/*****************************************************************************
  Geometry management.
 *****************************************************************************/

/*! \reimp
*/

void QDialog::setVisible(bool visible)
{
    Q_D(QDialog);
    if (!testAttribute(Qt::WA_DontShowOnScreen) && d->canBeNativeDialog() && d->setNativeDialogVisible(visible))
        return;

    // We should not block windows by the invisible modal dialog
    // if a platform-specific dialog is implemented as an in-process
    // Qt window, because in this case it will also be blocked.
    const bool dontBlockWindows = testAttribute(Qt::WA_DontShowOnScreen)
            && d->styleHint(QPlatformDialogHelper::DialogIsQtWindow).toBool();
    Qt::WindowModality oldModality;
    bool wasModalitySet;

    if (dontBlockWindows) {
        oldModality = windowModality();
        wasModalitySet = testAttribute(Qt::WA_SetWindowModality);
        setWindowModality(Qt::NonModal);
    }

    if (visible) {
        if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden))
            return;

        QWidget::setVisible(visible);
#if QT_DEPRECATED_SINCE(5, 13)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
        showExtension(d->doShowExtension);
QT_WARNING_POP
#endif
        QWidget *fw = window()->focusWidget();
        if (!fw)
            fw = this;

        /*
          The following block is to handle a special case, and does not
          really follow propper logic in concern of autoDefault and TAB
          order. However, it's here to ease usage for the users. If a
          dialog has a default QPushButton, and first widget in the TAB
          order also is a QPushButton, then we give focus to the main
          default QPushButton. This simplifies code for the developers,
          and actually catches most cases... If not, then they simply
          have to use [widget*]->setFocus() themselves...
        */
#if QT_CONFIG(pushbutton)
        if (d->mainDef && fw->focusPolicy() == Qt::NoFocus) {
            QWidget *first = fw;
            while ((first = first->nextInFocusChain()) != fw && first->focusPolicy() == Qt::NoFocus)
                ;
            if (first != d->mainDef && qobject_cast<QPushButton*>(first))
                d->mainDef->setFocus();
        }
        if (!d->mainDef && isWindow()) {
            QWidget *w = fw;
            while ((w = w->nextInFocusChain()) != fw) {
                QPushButton *pb = qobject_cast<QPushButton *>(w);
                if (pb && pb->autoDefault() && pb->focusPolicy() != Qt::NoFocus) {
                    pb->setDefault(true);
                    break;
                }
            }
        }
#endif
        if (fw && !fw->hasFocus()) {
            QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
            QCoreApplication::sendEvent(fw, &e);
        }

#ifndef QT_NO_ACCESSIBILITY
        QAccessibleEvent event(this, QAccessible::DialogStart);
        QAccessible::updateAccessibility(&event);
#endif

    } else {
        if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden))
            return;

#ifndef QT_NO_ACCESSIBILITY
        if (isVisible()) {
            QAccessibleEvent event(this, QAccessible::DialogEnd);
            QAccessible::updateAccessibility(&event);
        }
#endif

        // Reimplemented to exit a modal event loop when the dialog is hidden.
        QWidget::setVisible(visible);
        if (d->eventLoop)
            d->eventLoop->exit();
    }

    if (dontBlockWindows) {
        setWindowModality(oldModality);
        setAttribute(Qt::WA_SetWindowModality, wasModalitySet);
    }

#if QT_CONFIG(pushbutton)
    const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
    if (d->mainDef && isActiveWindow()
        && theme->themeHint(QPlatformTheme::DialogSnapToDefaultButton).toBool())
        QCursor::setPos(d->mainDef->mapToGlobal(d->mainDef->rect().center()));
#endif
}

/*!\reimp */
void QDialog::showEvent(QShowEvent *event)
{
    if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) {
        Qt::WindowStates  state = windowState();
        adjustPosition(parentWidget());
        setAttribute(Qt::WA_Moved, false); // not really an explicit position
        if (state != windowState())
            setWindowState(state);
    }
}

/*! \internal */
void QDialog::adjustPosition(QWidget* w)
{

    if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
        if (theme->themeHint(QPlatformTheme::WindowAutoPlacement).toBool())
            return;
    QPoint p(0, 0);
    int extraw = 0, extrah = 0, scrn = 0;
    if (w)
        w = w->window();
    QRect desk;
    if (w) {
        scrn = QDesktopWidgetPrivate::screenNumber(w);
    } else if (QDesktopWidgetPrivate::isVirtualDesktop()) {
        scrn = QDesktopWidgetPrivate::screenNumber(QCursor::pos());
    } else {
        scrn = QDesktopWidgetPrivate::screenNumber(this);
    }
    desk = QDesktopWidgetPrivate::availableGeometry(scrn);

    QWidgetList list = QApplication::topLevelWidgets();
    for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) {
        QWidget * current = list.at(i);
        if (current->isVisible()) {
            int framew = current->geometry().x() - current->x();
            int frameh = current->geometry().y() - current->y();

            extraw = qMax(extraw, framew);
            extrah = qMax(extrah, frameh);
        }
    }

    // sanity check for decoration frames. With embedding, we
    // might get extraordinary values
    if (extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40) {
        extrah = 40;
        extraw = 10;
    }


    if (w) {
        // Use pos() if the widget is embedded into a native window
        QPoint pp;
        if (w->windowHandle() && qvariant_cast<WId>(w->windowHandle()->property("_q_embedded_native_parent_handle")))
            pp = w->pos();
        else
            pp = w->mapToGlobal(QPoint(0,0));
        p = QPoint(pp.x() + w->width()/2,
                    pp.y() + w->height()/ 2);
    } else {
        // p = middle of the desktop
        p = QPoint(desk.x() + desk.width()/2, desk.y() + desk.height()/2);
    }

    // p = origin of this
    p = QPoint(p.x()-width()/2 - extraw,
                p.y()-height()/2 - extrah);


    if (p.x() + extraw + width() > desk.x() + desk.width())
        p.setX(desk.x() + desk.width() - width() - extraw);
    if (p.x() < desk.x())
        p.setX(desk.x());

    if (p.y() + extrah + height() > desk.y() + desk.height())
        p.setY(desk.y() + desk.height() - height() - extrah);
    if (p.y() < desk.y())
        p.setY(desk.y());

    // QTBUG-52735: Manually set the correct target screen since scaling in a
    // subsequent call to QWindow::resize() may otherwise use the wrong factor
    // if the screen changed notification is still in an event queue.
    if (scrn >= 0) {
        if (QWindow *window = windowHandle())
            window->setScreen(QGuiApplication::screens().at(scrn));
    }

    move(p);
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete

    If \a orientation is Qt::Horizontal, the extension will be displayed
    to the right of the dialog's main area. If \a orientation is
    Qt::Vertical, the extension will be displayed below the dialog's main
    area.

    Instead of using this functionality, we recommend that you simply call
    show() or hide() on the part of the dialog that you want to use as an
    extension. See the \l{Extension Example} for details.

    \sa setExtension()
*/
void QDialog::setOrientation(Qt::Orientation orientation)
{
    Q_D(QDialog);
    d->orientation = orientation;
}

/*!
    \obsolete

    Returns the dialog's extension orientation.

    Instead of using this functionality, we recommend that you simply call
    show() or hide() on the part of the dialog that you want to use as an
    extension. See the \l{Extension Example} for details.

    \sa extension()
*/
Qt::Orientation QDialog::orientation() const
{
    Q_D(const QDialog);
    return d->orientation;
}

/*!
    \obsolete

    Sets the widget, \a extension, to be the dialog's extension,
    deleting any previous extension. The dialog takes ownership of the
    extension. Note that if \nullptr is passed, any existing extension will be
    deleted. This function must only be called while the dialog is hidden.

    Instead of using this functionality, we recommend that you simply call
    show() or hide() on the part of the dialog that you want to use as an
    extension. See the \l{Extension Example} for details.

    \sa showExtension(), setOrientation()
*/
void QDialog::setExtension(QWidget* extension)
{
    Q_D(QDialog);
    delete d->extension;
    d->extension = extension;

    if (!extension)
        return;

    if (extension->parentWidget() != this)
        extension->setParent(this);
    extension->hide();
}

/*!
    \obsolete

    Returns the dialog's extension or \nullptr if no extension has been
    defined.

    Instead of using this functionality, we recommend that you simply call
    show() or hide() on the part of the dialog that you want to use as an
    extension. See the \l{Extension Example} for details.

    \sa showExtension(), setOrientation()
*/
QWidget* QDialog::extension() const
{
    Q_D(const QDialog);
    return d->extension;
}


/*!
    \obsolete

    If \a showIt is true, the dialog's extension is shown; otherwise the
    extension is hidden.

    Instead of using this functionality, we recommend that you simply call
    show() or hide() on the part of the dialog that you want to use as an
    extension. See the \l{Extension Example} for details.

    \sa show(), setExtension(), setOrientation()
*/
void QDialog::showExtension(bool showIt)
{
    Q_D(QDialog);
    d->doShowExtension = showIt;
    if (!d->extension)
        return;
    if (!testAttribute(Qt::WA_WState_Visible))
        return;
    if (d->extension->isVisible() == showIt)
        return;

    if (showIt) {
        d->size = size();
        d->min = minimumSize();
        d->max = maximumSize();
        if (layout())
            layout()->setEnabled(false);
        QSize s(d->extension->sizeHint()
                 .expandedTo(d->extension->minimumSize())
                 .boundedTo(d->extension->maximumSize()));
        if (d->orientation == Qt::Horizontal) {
            int h = qMax(height(), s.height());
            d->extension->setGeometry(width(), 0, s.width(), h);
            setFixedSize(width() + s.width(), h);
        } else {
            int w = qMax(width(), s.width());
            d->extension->setGeometry(0, height(), w, s.height());
            setFixedSize(w, height() + s.height());
        }
        d->extension->show();
#if QT_CONFIG(sizegrip)
        const bool sizeGripEnabled = isSizeGripEnabled();
        setSizeGripEnabled(false);
        d->sizeGripEnabled = sizeGripEnabled;
#endif
    } else {
        d->extension->hide();
        // workaround for CDE window manager that won't shrink with (-1,-1)
        setMinimumSize(d->min.expandedTo(QSize(1, 1)));
        setMaximumSize(d->max);
        resize(d->size);
        if (layout())
            layout()->setEnabled(true);
#if QT_CONFIG(sizegrip)
        setSizeGripEnabled(d->sizeGripEnabled);
#endif
    }
}
#endif

/*! \reimp */
QSize QDialog::sizeHint() const
{
    Q_D(const QDialog);
    if (d->extension) {
        if (d->orientation == Qt::Horizontal)
            return QSize(QWidget::sizeHint().width(),
                        qMax(QWidget::sizeHint().height(),d->extension->sizeHint().height()));
        else
            return QSize(qMax(QWidget::sizeHint().width(), d->extension->sizeHint().width()),
                        QWidget::sizeHint().height());
    }
    return QWidget::sizeHint();
}


/*! \reimp */
QSize QDialog::minimumSizeHint() const
{
    Q_D(const QDialog);
    if (d->extension) {
        if (d->orientation == Qt::Horizontal)
            return QSize(QWidget::minimumSizeHint().width(),
                        qMax(QWidget::minimumSizeHint().height(), d->extension->minimumSizeHint().height()));
        else
            return QSize(qMax(QWidget::minimumSizeHint().width(), d->extension->minimumSizeHint().width()),
                        QWidget::minimumSizeHint().height());
    }

    return QWidget::minimumSizeHint();
}

/*!
    \property QDialog::modal
    \brief whether show() should pop up the dialog as modal or modeless

    By default, this property is \c false and show() pops up the dialog
    as modeless. Setting this property to true is equivalent to setting
    QWidget::windowModality to Qt::ApplicationModal.

    exec() ignores the value of this property and always pops up the
    dialog as modal.

    \sa QWidget::windowModality, show(), exec()
*/

void QDialog::setModal(bool modal)
{
    setAttribute(Qt::WA_ShowModal, modal);
}


bool QDialog::isSizeGripEnabled() const
{
#if QT_CONFIG(sizegrip)
    Q_D(const QDialog);
    return !!d->resizer;
#else
    return false;
#endif
}


void QDialog::setSizeGripEnabled(bool enabled)
{
#if !QT_CONFIG(sizegrip)
    Q_UNUSED(enabled);
#else
    Q_D(QDialog);
#if QT_CONFIG(sizegrip)
    d->sizeGripEnabled = enabled;
    if (enabled && d->doShowExtension)
        return;
#endif
    if (!enabled != !d->resizer) {
        if (enabled) {
            d->resizer = new QSizeGrip(this);
            // adjustSize() processes all events, which is suboptimal
            d->resizer->resize(d->resizer->sizeHint());
            if (isRightToLeft())
                d->resizer->move(rect().bottomLeft() -d->resizer->rect().bottomLeft());
            else
                d->resizer->move(rect().bottomRight() -d->resizer->rect().bottomRight());
            d->resizer->raise();
            d->resizer->show();
        } else {
            delete d->resizer;
            d->resizer = nullptr;
        }
    }
#endif // QT_CONFIG(sizegrip)
}



/*! \reimp */
void QDialog::resizeEvent(QResizeEvent *)
{
#if QT_CONFIG(sizegrip)
    Q_D(QDialog);
    if (d->resizer) {
        if (isRightToLeft())
            d->resizer->move(rect().bottomLeft() -d->resizer->rect().bottomLeft());
        else
            d->resizer->move(rect().bottomRight() -d->resizer->rect().bottomRight());
        d->resizer->raise();
    }
#endif
}

/*! \fn void QDialog::finished(int result)
    \since 4.1

    This signal is emitted when the dialog's \a result code has been
    set, either by the user or by calling done(), accept(), or
    reject().

    Note that this signal is \e not emitted when hiding the dialog
    with hide() or setVisible(false). This includes deleting the
    dialog while it is visible.

    \sa accepted(), rejected()
*/

/*! \fn void QDialog::accepted()
    \since 4.1

    This signal is emitted when the dialog has been accepted either by
    the user or by calling accept() or done() with the
    QDialog::Accepted argument.

    Note that this signal is \e not emitted when hiding the dialog
    with hide() or setVisible(false). This includes deleting the
    dialog while it is visible.

    \sa finished(), rejected()
*/

/*! \fn void QDialog::rejected()
    \since 4.1

    This signal is emitted when the dialog has been rejected either by
    the user or by calling reject() or done() with the
    QDialog::Rejected argument.

    Note that this signal is \e not emitted when hiding the dialog
    with hide() or setVisible(false). This includes deleting the
    dialog while it is visible.

    \sa finished(), accepted()
*/

QT_END_NAMESPACE
#include "moc_qdialog.cpp"
