/****************************************************************************
**
** 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 "qprogressdialog.h"

#include "qshortcut.h"
#include "qpainter.h"
#include "qdrawutil.h"
#include "qlabel.h"
#include "qprogressbar.h"
#include "qapplication.h"
#include "qstyle.h"
#include "qpushbutton.h"
#include "qtimer.h"
#include "qelapsedtimer.h"
#include <private/qdialog_p.h>
#include <limits.h>

QT_BEGIN_NAMESPACE

// If the operation is expected to take this long (as predicted by
// progress time), show the progress dialog.
static const int defaultShowTime = 4000;
// Wait at least this long before attempting to make a prediction.
static const int minWaitTime = 50;

class QProgressDialogPrivate : public QDialogPrivate
{
    Q_DECLARE_PUBLIC(QProgressDialog)

public:
    QProgressDialogPrivate() : label(nullptr), cancel(nullptr), bar(nullptr),
        shown_once(false),
        cancellation_flag(false),
        setValue_called(false),
        showTime(defaultShowTime),
#ifndef QT_NO_SHORTCUT
        escapeShortcut(nullptr),
#endif
        useDefaultCancelText(false)
    {
    }

    void init(const QString &labelText, const QString &cancelText, int min, int max);
    void layout();
    void retranslateStrings();
    void setCancelButtonText(const QString &cancelButtonText);
    void adoptChildWidget(QWidget *c);
    void ensureSizeIsAtLeastSizeHint();
    void _q_disconnectOnClose();

    QLabel *label;
    QPushButton *cancel;
    QProgressBar *bar;
    QTimer *forceTimer;
    bool shown_once;
    bool cancellation_flag;
    bool setValue_called;
    QElapsedTimer starttime;
    int showTime;
    bool autoClose;
    bool autoReset;
    bool forceHide;
#ifndef QT_NO_SHORTCUT
    QShortcut *escapeShortcut;
#endif
    bool useDefaultCancelText;
    QPointer<QObject> receiverToDisconnectOnClose;
    QByteArray memberToDisconnectOnClose;
};

void QProgressDialogPrivate::init(const QString &labelText, const QString &cancelText,
                                  int min, int max)
{
    Q_Q(QProgressDialog);
    label = new QLabel(labelText, q);
    bar = new QProgressBar(q);
    bar->setRange(min, max);
    int align = q->style()->styleHint(QStyle::SH_ProgressDialog_TextLabelAlignment, nullptr, q);
    label->setAlignment(Qt::Alignment(align));
    autoClose = true;
    autoReset = true;
    forceHide = false;
    QObject::connect(q, SIGNAL(canceled()), q, SLOT(cancel()));
    forceTimer = new QTimer(q);
    QObject::connect(forceTimer, SIGNAL(timeout()), q, SLOT(forceShow()));
    if (useDefaultCancelText) {
        retranslateStrings();
    } else {
        q->setCancelButtonText(cancelText);
    }
    starttime.start();
    forceTimer->start(showTime);
}

void QProgressDialogPrivate::layout()
{
    Q_Q(QProgressDialog);
    int sp = q->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing, nullptr, q);
    int mb = q->style()->pixelMetric(QStyle::PM_LayoutBottomMargin, nullptr, q);
    int ml = qMin(q->width() / 10, q->style()->pixelMetric(QStyle::PM_LayoutLeftMargin, nullptr, q));
    int mr = qMin(q->width() / 10, q->style()->pixelMetric(QStyle::PM_LayoutRightMargin, nullptr, q));
    const bool centered =
        bool(q->style()->styleHint(QStyle::SH_ProgressDialog_CenterCancelButton, nullptr, q));

    int additionalSpacing = 0;
    QSize cs = cancel ? cancel->sizeHint() : QSize(0,0);
    QSize bh = bar->sizeHint();
    int cspc;
    int lh = 0;

    // Find spacing and sizes that fit.  It is important that a progress
    // dialog can be made very small if the user demands it so.
    for (int attempt=5; attempt--;) {
        cspc = cancel ? cs.height() + sp : 0;
        lh = qMax(0, q->height() - mb - bh.height() - sp - cspc);

        if (lh < q->height()/4) {
            // Getting cramped
            sp /= 2;
            mb /= 2;
            if (cancel) {
                cs.setHeight(qMax(4,cs.height()-sp-2));
            }
            bh.setHeight(qMax(4,bh.height()-sp-1));
        } else {
            break;
        }
    }

    if (cancel) {
        cancel->setGeometry(
            centered ? q->width()/2 - cs.width()/2 : q->width() - mr - cs.width(),
            q->height() - mb - cs.height(),
            cs.width(), cs.height());
    }

    if (label)
        label->setGeometry(ml, additionalSpacing, q->width() - ml - mr, lh);
    bar->setGeometry(ml, lh + sp + additionalSpacing, q->width() - ml - mr, bh.height());
}

void QProgressDialogPrivate::retranslateStrings()
{
    if (useDefaultCancelText)
        setCancelButtonText(QProgressDialog::tr("Cancel"));
}

void QProgressDialogPrivate::_q_disconnectOnClose()
{
    Q_Q(QProgressDialog);
    if (receiverToDisconnectOnClose) {
        QObject::disconnect(q, SIGNAL(canceled()), receiverToDisconnectOnClose,
                            memberToDisconnectOnClose);
        receiverToDisconnectOnClose = nullptr;
    }
    memberToDisconnectOnClose.clear();
}

/*!
  \class QProgressDialog
  \brief The QProgressDialog class provides feedback on the progress of a slow operation.
  \ingroup standard-dialogs
  \inmodule QtWidgets


  A progress dialog is used to give the user an indication of how long
  an operation is going to take, and to demonstrate that the
  application has not frozen. It can also give the user an opportunity
  to abort the operation.

  A common problem with progress dialogs is that it is difficult to know
  when to use them; operations take different amounts of time on different
  hardware.  QProgressDialog offers a solution to this problem:
  it estimates the time the operation will take (based on time for
  steps), and only shows itself if that estimate is beyond minimumDuration()
  (4 seconds by default).

  Use setMinimum() and setMaximum() or the constructor to set the number of
  "steps" in the operation and call setValue() as the operation
  progresses. The number of steps can be chosen arbitrarily. It can be the
  number of files copied, the number of bytes received, the number of
  iterations through the main loop of your algorithm, or some other
  suitable unit. Progress starts at the value set by setMinimum(),
  and the progress dialog shows that the operation has finished when
  you call setValue() with the value set by setMaximum() as its argument.

  The dialog automatically resets and hides itself at the end of the
  operation.  Use setAutoReset() and setAutoClose() to change this
  behavior. Note that if you set a new maximum (using setMaximum() or
  setRange()) that equals your current value(), the dialog will not
  close regardless.

  There are two ways of using QProgressDialog: modal and modeless.

  Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler
  to use for the programmer. Do the operation in a loop, call \l setValue() at
  intervals, and check for cancellation with wasCanceled(). For example:

  \snippet dialogs/dialogs.cpp 3

  A modeless progress dialog is suitable for operations that take
  place in the background, where the user is able to interact with the
  application. Such operations are typically based on QTimer (or
  QObject::timerEvent()) or QSocketNotifier; or performed
  in a separate thread. A QProgressBar in the status bar of your main window
  is often an alternative to a modeless progress dialog.

  You need to have an event loop to be running, connect the
  canceled() signal to a slot that stops the operation, and call \l
  setValue() at intervals. For example:

  \snippet dialogs/dialogs.cpp 4
  \codeline
  \snippet dialogs/dialogs.cpp 5
  \codeline
  \snippet dialogs/dialogs.cpp 6

  In both modes the progress dialog may be customized by
  replacing the child widgets with custom widgets by using setLabel(),
  setBar(), and setCancelButton().
  The functions setLabelText() and setCancelButtonText()
  set the texts shown.

  \image fusion-progressdialog.png A progress dialog shown in the Fusion widget style.

  \sa QDialog, QProgressBar, {fowler}{GUI Design Handbook: Progress Indicator},
      {Find Files Example}, {Pixelator Example}
*/


/*!
  Constructs a progress dialog.

  Default settings:
  \list
  \li The label text is empty.
  \li The cancel button text is (translated) "Cancel".
  \li minimum is 0;
  \li maximum is 100
  \endlist

  The \a parent argument is dialog's parent widget. The widget flags, \a f, are
  passed to the QDialog::QDialog() constructor.

  \sa setLabelText(), setCancelButtonText(), setCancelButton(),
  setMinimum(), setMaximum()
*/

QProgressDialog::QProgressDialog(QWidget *parent, Qt::WindowFlags f)
    : QDialog(*(new QProgressDialogPrivate), parent, f)
{
    Q_D(QProgressDialog);
    d->useDefaultCancelText = true;
    d->init(QString::fromLatin1(""), QString(), 0, 100);
}

/*!
  Constructs a progress dialog.

   The \a labelText is the text used to remind the user what is progressing.

   The \a cancelButtonText is the text to display on the cancel button.  If
   QString() is passed then no cancel button is shown.

   The \a minimum and \a maximum is the number of steps in the operation for
   which this progress dialog shows progress.  For example, if the
   operation is to examine 50 files, this value minimum value would be 0,
   and the maximum would be 50. Before examining the first file, call
   setValue(0). As each file is processed call setValue(1), setValue(2),
   etc., finally calling setValue(50) after examining the last file.

   The \a parent argument is the dialog's parent widget. The parent, \a parent, and
   widget flags, \a f, are passed to the QDialog::QDialog() constructor.

  \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
  setMinimum(), setMaximum()
*/

QProgressDialog::QProgressDialog(const QString &labelText,
                                 const QString &cancelButtonText,
                                 int minimum, int maximum,
                                 QWidget *parent, Qt::WindowFlags f)
    : QDialog(*(new QProgressDialogPrivate), parent, f)
{
    Q_D(QProgressDialog);
    d->init(labelText, cancelButtonText, minimum, maximum);
}


/*!
  Destroys the progress dialog.
*/

QProgressDialog::~QProgressDialog()
{
}

/*!
  \fn void QProgressDialog::canceled()

  This signal is emitted when the cancel button is clicked.
  It is connected to the cancel() slot by default.

  \sa wasCanceled()
*/


/*!
  Sets the label to \a label. The progress dialog resizes to fit. The
  label becomes owned by the progress dialog and will be deleted when
  necessary, so do not pass the address of an object on the stack.

  \sa setLabelText()
*/

void QProgressDialog::setLabel(QLabel *label)
{
    Q_D(QProgressDialog);
    if (label == d->label) {
        if (Q_UNLIKELY(label))
            qWarning("QProgressDialog::setLabel: Attempt to set the same label again");
        return;
    }
    delete d->label;
    d->label = label;
    d->adoptChildWidget(label);
}


/*!
  \property QProgressDialog::labelText
  \brief the label's text

  The default text is an empty string.
*/

QString QProgressDialog::labelText() const
{
    Q_D(const QProgressDialog);
    if (d->label)
        return d->label->text();
    return QString();
}

void QProgressDialog::setLabelText(const QString &text)
{
    Q_D(QProgressDialog);
    if (d->label) {
        d->label->setText(text);
        d->ensureSizeIsAtLeastSizeHint();
    }
}


/*!
  Sets the cancel button to the push button, \a cancelButton. The
  progress dialog takes ownership of this button which will be deleted
  when necessary, so do not pass the address of an object that is on
  the stack, i.e. use new() to create the button.  If \nullptr is passed,
  no cancel button will be shown.

  \sa setCancelButtonText()
*/

void QProgressDialog::setCancelButton(QPushButton *cancelButton)
{
    Q_D(QProgressDialog);
    if (d->cancel == cancelButton) {
        if (Q_UNLIKELY(cancelButton))
            qWarning("QProgressDialog::setCancelButton: Attempt to set the same button again");
        return;
    }
    delete d->cancel;
    d->cancel = cancelButton;
    if (cancelButton) {
        connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled()));
#ifndef QT_NO_SHORTCUT
        // FIXME: This only registers the primary key sequence of the cancel action
        d->escapeShortcut = new QShortcut(QKeySequence::Cancel, this, SIGNAL(canceled()));
#endif
    } else {
#ifndef QT_NO_SHORTCUT
        delete d->escapeShortcut;
        d->escapeShortcut = nullptr;
#endif
    }
    d->adoptChildWidget(cancelButton);
}

/*!
  Sets the cancel button's text to \a cancelButtonText.  If the text
  is set to QString() then it will cause the cancel button to be
  hidden and deleted.

  \sa setCancelButton()
*/

void QProgressDialog::setCancelButtonText(const QString &cancelButtonText)
{
    Q_D(QProgressDialog);
    d->useDefaultCancelText = false;
    d->setCancelButtonText(cancelButtonText);
}

void QProgressDialogPrivate::setCancelButtonText(const QString &cancelButtonText)
{
    Q_Q(QProgressDialog);

    if (!cancelButtonText.isNull()) {
        if (cancel) {
            cancel->setText(cancelButtonText);
        } else {
            q->setCancelButton(new QPushButton(cancelButtonText, q));
        }
    } else {
        q->setCancelButton(nullptr);
    }
    ensureSizeIsAtLeastSizeHint();
}


/*!
  Sets the progress bar widget to \a bar. The progress dialog resizes to
  fit. The progress dialog takes ownership of the progress \a bar which
  will be deleted when necessary, so do not use a progress bar
  allocated on the stack.
*/

void QProgressDialog::setBar(QProgressBar *bar)
{
    Q_D(QProgressDialog);
    if (Q_UNLIKELY(!bar)) {
        qWarning("QProgressDialog::setBar: Cannot set a null progress bar");
        return;
    }
#ifndef QT_NO_DEBUG
    if (Q_UNLIKELY(value() > 0))
        qWarning("QProgressDialog::setBar: Cannot set a new progress bar "
                  "while the old one is active");
#endif
    if (Q_UNLIKELY(bar == d->bar)) {
        qWarning("QProgressDialog::setBar: Attempt to set the same progress bar again");
        return;
    }
    delete d->bar;
    d->bar = bar;
    d->adoptChildWidget(bar);
}

void QProgressDialogPrivate::adoptChildWidget(QWidget *c)
{
    Q_Q(QProgressDialog);

    if (c) {
        if (c->parentWidget() == q)
            c->hide(); // until after ensureSizeIsAtLeastSizeHint()
        else
            c->setParent(q, { });
    }
    ensureSizeIsAtLeastSizeHint();
    if (c)
        c->show();
}

void QProgressDialogPrivate::ensureSizeIsAtLeastSizeHint()
{
    Q_Q(QProgressDialog);

    QSize size = q->sizeHint();
    if (q->isVisible())
        size = size.expandedTo(q->size());
    q->resize(size);
}


/*!
  \property QProgressDialog::wasCanceled
  \brief whether the dialog was canceled
*/

bool QProgressDialog::wasCanceled() const
{
    Q_D(const QProgressDialog);
    return d->cancellation_flag;
}


/*!
    \property QProgressDialog::maximum
    \brief the highest value represented by the progress bar

    The default is 100.

    \sa minimum, setRange()
*/

int QProgressDialog::maximum() const
{
    Q_D(const QProgressDialog);
    return d->bar->maximum();
}

void QProgressDialog::setMaximum(int maximum)
{
    Q_D(QProgressDialog);
    d->bar->setMaximum(maximum);
}

/*!
    \property QProgressDialog::minimum
    \brief the lowest value represented by the progress bar

    The default is 0.

    \sa maximum, setRange()
*/

int QProgressDialog::minimum() const
{
    Q_D(const QProgressDialog);
    return d->bar->minimum();
}

void QProgressDialog::setMinimum(int minimum)
{
    Q_D(QProgressDialog);
    d->bar->setMinimum(minimum);
}

/*!
    Sets the progress dialog's minimum and maximum values
    to \a minimum and \a maximum, respectively.

    If \a maximum is smaller than \a minimum, \a minimum becomes the only
    legal value.

    If the current value falls outside the new range, the progress
    dialog is reset with reset().

    \sa minimum, maximum
*/
void QProgressDialog::setRange(int minimum, int maximum)
{
    Q_D(QProgressDialog);
    d->bar->setRange(minimum, maximum);
}


/*!
  Resets the progress dialog.
  The progress dialog becomes hidden if autoClose() is true.

  \sa setAutoClose(), setAutoReset()
*/

void QProgressDialog::reset()
{
    Q_D(QProgressDialog);
    if (d->autoClose || d->forceHide)
        hide();
    d->bar->reset();
    d->cancellation_flag = false;
    d->shown_once = false;
    d->setValue_called = false;
    d->forceTimer->stop();

    /*
        I wish we could disconnect the user slot provided to open() here but
        unfortunately reset() is usually called before the slot has been invoked.
        (reset() is itself invoked when canceled() is emitted.)
    */
    if (d->receiverToDisconnectOnClose)
        QMetaObject::invokeMethod(this, "_q_disconnectOnClose", Qt::QueuedConnection);
}

/*!
  Resets the progress dialog. wasCanceled() becomes true until
  the progress dialog is reset.
  The progress dialog becomes hidden.
*/

void QProgressDialog::cancel()
{
    Q_D(QProgressDialog);
    d->forceHide = true;
    reset();
    d->forceHide = false;
    d->cancellation_flag = true;
}


int QProgressDialog::value() const
{
    Q_D(const QProgressDialog);
    return d->bar->value();
}

/*!
  \property QProgressDialog::value
  \brief the current amount of progress made.

  For the progress dialog to work as expected, you should initially set
  this property to QProgressDialog::minimum() and finally set it to
  QProgressDialog::maximum(); you can call setValue() any number of times
  in-between.

  \warning If the progress dialog is modal
    (see QProgressDialog::QProgressDialog()),
    setValue() calls QCoreApplication::processEvents(), so take care that
    this does not cause undesirable re-entrancy in your code. For example,
    don't use a QProgressDialog inside a paintEvent()!

  \sa minimum, maximum
*/
void QProgressDialog::setValue(int progress)
{
    Q_D(QProgressDialog);
    if (d->setValue_called && progress == d->bar->value())
        return;

    d->bar->setValue(progress);

    if (d->shown_once) {
        if (isModal())
            QCoreApplication::processEvents();
    } else {
        if ((!d->setValue_called && progress == 0 /* for compat with Qt < 5.4 */) || progress == minimum()) {
            d->starttime.start();
            d->forceTimer->start(d->showTime);
            d->setValue_called = true;
            return;
        } else {
            d->setValue_called = true;
            bool need_show;
            int elapsed = d->starttime.elapsed();
            if (elapsed >= d->showTime) {
                need_show = true;
            } else {
                if (elapsed > minWaitTime) {
                    int estimate;
                    int totalSteps = maximum() - minimum();
                    int myprogress = progress - minimum();
                    if (myprogress == 0) myprogress = 1;
                    if ((totalSteps - myprogress) >= INT_MAX / elapsed)
                        estimate = (totalSteps - myprogress) / myprogress * elapsed;
                    else
                        estimate = elapsed * (totalSteps - myprogress) / myprogress;
                    need_show = estimate >= d->showTime;
                } else {
                    need_show = false;
                }
            }
            if (need_show) {
                d->ensureSizeIsAtLeastSizeHint();
                show();
                d->shown_once = true;
            }
        }
    }

    if (progress == d->bar->maximum() && d->autoReset)
        reset();
}

/*!
  Returns a size that fits the contents of the progress dialog.
  The progress dialog resizes itself as required, so you should not
  need to call this yourself.
*/

QSize QProgressDialog::sizeHint() const
{
    Q_D(const QProgressDialog);
    QSize labelSize = d->label ? d->label->sizeHint() : QSize(0, 0);
    QSize barSize = d->bar->sizeHint();
    int marginBottom = style()->pixelMetric(QStyle::PM_LayoutBottomMargin, 0, this);
    int spacing = style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing, 0, this);
    int marginLeft = style()->pixelMetric(QStyle::PM_LayoutLeftMargin, 0, this);
    int marginRight = style()->pixelMetric(QStyle::PM_LayoutRightMargin, 0, this);

    int height = marginBottom * 2 + barSize.height() + labelSize.height() + spacing;
    if (d->cancel)
        height += d->cancel->sizeHint().height() + spacing;
    return QSize(qMax(200, labelSize.width() + marginLeft + marginRight), height);
}

/*!\reimp
*/
void QProgressDialog::resizeEvent(QResizeEvent *)
{
    Q_D(QProgressDialog);
    d->layout();
}

/*!
  \reimp
*/
void QProgressDialog::changeEvent(QEvent *ev)
{
    Q_D(QProgressDialog);
    if (ev->type() == QEvent::StyleChange) {
        d->layout();
    } else if (ev->type() == QEvent::LanguageChange) {
        d->retranslateStrings();
    }
    QDialog::changeEvent(ev);
}

/*!
    \property QProgressDialog::minimumDuration
    \brief the time that must pass before the dialog appears

    If the expected duration of the task is less than the
    minimumDuration, the dialog will not appear at all. This prevents
    the dialog popping up for tasks that are quickly over. For tasks
    that are expected to exceed the minimumDuration, the dialog will
    pop up after the minimumDuration time or as soon as any progress
    is set.

    If set to 0, the dialog is always shown as soon as any progress is
    set. The default is 4000 milliseconds.
*/
void QProgressDialog::setMinimumDuration(int ms)
{
    Q_D(QProgressDialog);
    d->showTime = ms;
    if (d->bar->value() == d->bar->minimum()) {
        d->forceTimer->stop();
        d->forceTimer->start(ms);
    }
}

int QProgressDialog::minimumDuration() const
{
    Q_D(const QProgressDialog);
    return d->showTime;
}


/*!
  \reimp
*/

void QProgressDialog::closeEvent(QCloseEvent *e)
{
    emit canceled();
    QDialog::closeEvent(e);
}

/*!
  \property QProgressDialog::autoReset
  \brief whether the progress dialog calls reset() as soon as value() equals maximum()

  The default is true.

  \sa setAutoClose()
*/

void QProgressDialog::setAutoReset(bool b)
{
    Q_D(QProgressDialog);
    d->autoReset = b;
}

bool QProgressDialog::autoReset() const
{
    Q_D(const QProgressDialog);
    return d->autoReset;
}

/*!
  \property QProgressDialog::autoClose
  \brief whether the dialog gets hidden by reset()

  The default is true.

  \sa setAutoReset()
*/

void QProgressDialog::setAutoClose(bool close)
{
    Q_D(QProgressDialog);
    d->autoClose = close;
}

bool QProgressDialog::autoClose() const
{
    Q_D(const QProgressDialog);
    return d->autoClose;
}

/*!
  \reimp
*/

void QProgressDialog::showEvent(QShowEvent *e)
{
    Q_D(QProgressDialog);
    QDialog::showEvent(e);
    d->ensureSizeIsAtLeastSizeHint();
    d->forceTimer->stop();
}

/*!
  Shows the dialog if it is still hidden after the algorithm has been started
  and minimumDuration milliseconds have passed.

  \sa setMinimumDuration()
*/

void QProgressDialog::forceShow()
{
    Q_D(QProgressDialog);
    d->forceTimer->stop();
    if (d->shown_once || d->cancellation_flag)
        return;

    show();
    d->shown_once = true;
}

/*!
    \since 4.5

    Opens the dialog and connects its canceled() signal to the slot specified
    by \a receiver and \a member.

    The signal will be disconnected from the slot when the dialog is closed.
*/
void QProgressDialog::open(QObject *receiver, const char *member)
{
    Q_D(QProgressDialog);
    connect(this, SIGNAL(canceled()), receiver, member);
    d->receiverToDisconnectOnClose = receiver;
    d->memberToDisconnectOnClose = member;
    QDialog::open();
}

QT_END_NAMESPACE

#include "moc_qprogressdialog.cpp"
