1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qprogressdialog.h"
5
6#if QT_CONFIG(shortcut)
7# include "qshortcut.h"
8#endif
9#include "qpainter.h"
10#include "qdrawutil.h"
11#include "qlabel.h"
12#include "qprogressbar.h"
13#include "qapplication.h"
14#include "qstyle.h"
15#include "qpushbutton.h"
16#include "qtimer.h"
17#include "qelapsedtimer.h"
18#include "qscopedvaluerollback.h"
19#include <private/qdialog_p.h>
20#include <limits.h>
21
22QT_BEGIN_NAMESPACE
23
24// If the operation is expected to take this long (as predicted by
25// progress time), show the progress dialog.
26static const int defaultShowTime = 4000;
27// Wait at least this long before attempting to make a prediction.
28static const int minWaitTime = 50;
29
30class QProgressDialogPrivate : public QDialogPrivate
31{
32 Q_DECLARE_PUBLIC(QProgressDialog)
33
34public:
35 QProgressDialogPrivate() = default;
36
37 void init(const QString &labelText, const QString &cancelText, int min, int max);
38 void layout();
39 void retranslateStrings();
40 void setCancelButtonText(const QString &cancelButtonText);
41 void adoptChildWidget(QWidget *c);
42 void ensureSizeIsAtLeastSizeHint();
43 void _q_disconnectOnClose();
44
45 QLabel *label = nullptr;
46 QPushButton *cancel = nullptr;
47 QProgressBar *bar = nullptr;
48 QTimer *forceTimer = nullptr;
49#ifndef QT_NO_SHORTCUT
50 QShortcut *escapeShortcut = nullptr;
51#endif
52 QPointer<QObject> receiverToDisconnectOnClose;
53 QElapsedTimer starttime;
54 QByteArray memberToDisconnectOnClose;
55 int showTime = defaultShowTime;
56 bool processingEvents = false;
57 bool shownOnce = false;
58 bool autoClose = true;
59 bool autoReset = true;
60 bool forceHide = false;
61 bool cancellationFlag = false;
62 bool setValueCalled = false;
63 bool useDefaultCancelText = false;
64};
65
66void QProgressDialogPrivate::init(const QString &labelText, const QString &cancelText,
67 int min, int max)
68{
69 Q_Q(QProgressDialog);
70 label = new QLabel(labelText, q);
71 bar = new QProgressBar(q);
72 bar->setRange(minimum: min, maximum: max);
73 int align = q->style()->styleHint(stylehint: QStyle::SH_ProgressDialog_TextLabelAlignment, opt: nullptr, widget: q);
74 label->setAlignment(Qt::Alignment(align));
75 QObject::connect(sender: q, SIGNAL(canceled()), receiver: q, SLOT(cancel()));
76 forceTimer = new QTimer(q);
77 QObject::connect(sender: forceTimer, SIGNAL(timeout()), receiver: q, SLOT(forceShow()));
78 if (useDefaultCancelText) {
79 retranslateStrings();
80 } else {
81 q->setCancelButtonText(cancelText);
82 }
83 starttime.start();
84 forceTimer->start(msec: showTime);
85}
86
87void QProgressDialogPrivate::layout()
88{
89 Q_Q(QProgressDialog);
90 int sp = q->style()->pixelMetric(metric: QStyle::PM_LayoutVerticalSpacing, option: nullptr, widget: q);
91 int mb = q->style()->pixelMetric(metric: QStyle::PM_LayoutBottomMargin, option: nullptr, widget: q);
92 int ml = qMin(a: q->width() / 10, b: q->style()->pixelMetric(metric: QStyle::PM_LayoutLeftMargin, option: nullptr, widget: q));
93 int mr = qMin(a: q->width() / 10, b: q->style()->pixelMetric(metric: QStyle::PM_LayoutRightMargin, option: nullptr, widget: q));
94 const bool centered =
95 bool(q->style()->styleHint(stylehint: QStyle::SH_ProgressDialog_CenterCancelButton, opt: nullptr, widget: q));
96
97 int additionalSpacing = 0;
98 QSize cs = cancel ? cancel->sizeHint() : QSize(0,0);
99 QSize bh = bar->sizeHint();
100 int cspc;
101 int lh = 0;
102
103 // Find spacing and sizes that fit. It is important that a progress
104 // dialog can be made very small if the user demands it so.
105 for (int attempt=5; attempt--;) {
106 cspc = cancel ? cs.height() + sp : 0;
107 lh = qMax(a: 0, b: q->height() - mb - bh.height() - sp - cspc);
108
109 if (lh < q->height()/4) {
110 // Getting cramped
111 sp /= 2;
112 mb /= 2;
113 if (cancel) {
114 cs.setHeight(qMax(a: 4,b: cs.height()-sp-2));
115 }
116 bh.setHeight(qMax(a: 4,b: bh.height()-sp-1));
117 } else {
118 break;
119 }
120 }
121
122 if (cancel) {
123 cancel->setGeometry(
124 ax: centered ? q->width()/2 - cs.width()/2 : q->width() - mr - cs.width(),
125 ay: q->height() - mb - cs.height(),
126 aw: cs.width(), ah: cs.height());
127 }
128
129 if (label)
130 label->setGeometry(ax: ml, ay: additionalSpacing, aw: q->width() - ml - mr, ah: lh);
131 bar->setGeometry(ax: ml, ay: lh + sp + additionalSpacing, aw: q->width() - ml - mr, ah: bh.height());
132}
133
134void QProgressDialogPrivate::retranslateStrings()
135{
136 if (useDefaultCancelText)
137 setCancelButtonText(QProgressDialog::tr(s: "Cancel"));
138}
139
140void QProgressDialogPrivate::_q_disconnectOnClose()
141{
142 Q_Q(QProgressDialog);
143 if (receiverToDisconnectOnClose) {
144 QObject::disconnect(sender: q, SIGNAL(canceled()), receiver: receiverToDisconnectOnClose,
145 member: memberToDisconnectOnClose);
146 receiverToDisconnectOnClose = nullptr;
147 }
148 memberToDisconnectOnClose.clear();
149}
150
151/*!
152 \class QProgressDialog
153 \brief The QProgressDialog class provides feedback on the progress of a slow operation.
154 \ingroup standard-dialogs
155 \inmodule QtWidgets
156
157
158 A progress dialog is used to give the user an indication of how long
159 an operation is going to take, and to demonstrate that the
160 application has not frozen. It can also give the user an opportunity
161 to abort the operation.
162
163 A common problem with progress dialogs is that it is difficult to know
164 when to use them; operations take different amounts of time on different
165 hardware. QProgressDialog offers a solution to this problem:
166 it estimates the time the operation will take (based on time for
167 steps), and only shows itself if that estimate is beyond minimumDuration()
168 (4 seconds by default).
169
170 Use setMinimum() and setMaximum() or the constructor to set the number of
171 "steps" in the operation and call setValue() as the operation
172 progresses. The number of steps can be chosen arbitrarily. It can be the
173 number of files copied, the number of bytes received, the number of
174 iterations through the main loop of your algorithm, or some other
175 suitable unit. Progress starts at the value set by setMinimum(),
176 and the progress dialog shows that the operation has finished when
177 you call setValue() with the value set by setMaximum() as its argument.
178
179 The dialog automatically resets and hides itself at the end of the
180 operation. Use setAutoReset() and setAutoClose() to change this
181 behavior. Note that if you set a new maximum (using setMaximum() or
182 setRange()) that equals your current value(), the dialog will not
183 close regardless.
184
185 There are two ways of using QProgressDialog: modal and modeless.
186
187 Compared to a modeless QProgressDialog, a modal QProgressDialog is simpler
188 to use for the programmer. Do the operation in a loop, call \l setValue() at
189 intervals, and check for cancellation with wasCanceled(). For example:
190
191 \snippet dialogs/dialogs.cpp 3
192
193 A modeless progress dialog is suitable for operations that take
194 place in the background, where the user is able to interact with the
195 application. Such operations are typically based on QTimer (or
196 QObject::timerEvent()) or QSocketNotifier; or performed
197 in a separate thread. A QProgressBar in the status bar of your main window
198 is often an alternative to a modeless progress dialog.
199
200 You need to have an event loop to be running, connect the
201 canceled() signal to a slot that stops the operation, and call \l
202 setValue() at intervals. For example:
203
204 \snippet dialogs/dialogs.cpp 4
205 \codeline
206 \snippet dialogs/dialogs.cpp 5
207 \codeline
208 \snippet dialogs/dialogs.cpp 6
209
210 In both modes the progress dialog may be customized by
211 replacing the child widgets with custom widgets by using setLabel(),
212 setBar(), and setCancelButton().
213 The functions setLabelText() and setCancelButtonText()
214 set the texts shown.
215
216 \image fusion-progressdialog.png A progress dialog shown in the Fusion widget style.
217
218 \sa QDialog, QProgressBar
219*/
220
221
222/*!
223 Constructs a progress dialog.
224
225 Default settings:
226 \list
227 \li The label text is empty.
228 \li The cancel button text is (translated) "Cancel".
229 \li minimum is 0;
230 \li maximum is 100
231 \endlist
232
233 The \a parent argument is dialog's parent widget. The widget flags, \a f, are
234 passed to the QDialog::QDialog() constructor.
235
236 \sa setLabelText(), setCancelButtonText(), setCancelButton(),
237 setMinimum(), setMaximum()
238*/
239
240QProgressDialog::QProgressDialog(QWidget *parent, Qt::WindowFlags f)
241 : QDialog(*(new QProgressDialogPrivate), parent, f)
242{
243 Q_D(QProgressDialog);
244 d->useDefaultCancelText = true;
245 d->init(labelText: QString::fromLatin1(ba: ""), cancelText: QString(), min: 0, max: 100);
246}
247
248/*!
249 Constructs a progress dialog.
250
251 The \a labelText is the text used to remind the user what is progressing.
252
253 The \a cancelButtonText is the text to display on the cancel button. If
254 QString() is passed then no cancel button is shown.
255
256 The \a minimum and \a maximum is the number of steps in the operation for
257 which this progress dialog shows progress. For example, if the
258 operation is to examine 50 files, this value minimum value would be 0,
259 and the maximum would be 50. Before examining the first file, call
260 setValue(0). As each file is processed call setValue(1), setValue(2),
261 etc., finally calling setValue(50) after examining the last file.
262
263 The \a parent argument is the dialog's parent widget. The parent, \a parent, and
264 widget flags, \a f, are passed to the QDialog::QDialog() constructor.
265
266 \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
267 setMinimum(), setMaximum()
268*/
269
270QProgressDialog::QProgressDialog(const QString &labelText,
271 const QString &cancelButtonText,
272 int minimum, int maximum,
273 QWidget *parent, Qt::WindowFlags f)
274 : QDialog(*(new QProgressDialogPrivate), parent, f)
275{
276 Q_D(QProgressDialog);
277 d->init(labelText, cancelText: cancelButtonText, min: minimum, max: maximum);
278}
279
280
281/*!
282 Destroys the progress dialog.
283*/
284
285QProgressDialog::~QProgressDialog()
286{
287}
288
289/*!
290 \fn void QProgressDialog::canceled()
291
292 This signal is emitted when the cancel button is clicked.
293 It is connected to the cancel() slot by default.
294
295 \sa wasCanceled()
296*/
297
298
299/*!
300 Sets the label to \a label. The progress dialog resizes to fit. The
301 label becomes owned by the progress dialog and will be deleted when
302 necessary, so do not pass the address of an object on the stack.
303
304 \sa setLabelText()
305*/
306
307void QProgressDialog::setLabel(QLabel *label)
308{
309 Q_D(QProgressDialog);
310 if (label == d->label) {
311 if (Q_UNLIKELY(label))
312 qWarning(msg: "QProgressDialog::setLabel: Attempt to set the same label again");
313 return;
314 }
315 delete d->label;
316 d->label = label;
317 d->adoptChildWidget(c: label);
318}
319
320
321/*!
322 \property QProgressDialog::labelText
323 \brief the label's text
324
325 The default text is an empty string.
326*/
327
328QString QProgressDialog::labelText() const
329{
330 Q_D(const QProgressDialog);
331 if (d->label)
332 return d->label->text();
333 return QString();
334}
335
336void QProgressDialog::setLabelText(const QString &text)
337{
338 Q_D(QProgressDialog);
339 if (d->label) {
340 d->label->setText(text);
341 d->ensureSizeIsAtLeastSizeHint();
342 }
343}
344
345
346/*!
347 Sets the cancel button to the push button, \a cancelButton. The
348 progress dialog takes ownership of this button which will be deleted
349 when necessary, so do not pass the address of an object that is on
350 the stack, i.e. use new() to create the button. If \nullptr is passed,
351 no cancel button will be shown.
352
353 \sa setCancelButtonText()
354*/
355
356void QProgressDialog::setCancelButton(QPushButton *cancelButton)
357{
358 Q_D(QProgressDialog);
359 if (d->cancel == cancelButton) {
360 if (Q_UNLIKELY(cancelButton))
361 qWarning(msg: "QProgressDialog::setCancelButton: Attempt to set the same button again");
362 return;
363 }
364 delete d->cancel;
365 d->cancel = cancelButton;
366 if (cancelButton) {
367 connect(sender: d->cancel, SIGNAL(clicked()), receiver: this, SIGNAL(canceled()));
368#ifndef QT_NO_SHORTCUT
369 d->escapeShortcut = new QShortcut(QKeySequence::Cancel, this, SIGNAL(canceled()));
370#endif
371 } else {
372#ifndef QT_NO_SHORTCUT
373 delete d->escapeShortcut;
374 d->escapeShortcut = nullptr;
375#endif
376 }
377 d->adoptChildWidget(c: cancelButton);
378}
379
380/*!
381 Sets the cancel button's text to \a cancelButtonText. If the text
382 is set to QString() then it will cause the cancel button to be
383 hidden and deleted.
384
385 \sa setCancelButton()
386*/
387
388void QProgressDialog::setCancelButtonText(const QString &cancelButtonText)
389{
390 Q_D(QProgressDialog);
391 d->useDefaultCancelText = false;
392 d->setCancelButtonText(cancelButtonText);
393}
394
395void QProgressDialogPrivate::setCancelButtonText(const QString &cancelButtonText)
396{
397 Q_Q(QProgressDialog);
398
399 if (!cancelButtonText.isNull()) {
400 if (cancel) {
401 cancel->setText(cancelButtonText);
402 } else {
403 q->setCancelButton(new QPushButton(cancelButtonText, q));
404 }
405 } else {
406 q->setCancelButton(nullptr);
407 }
408 ensureSizeIsAtLeastSizeHint();
409}
410
411
412/*!
413 Sets the progress bar widget to \a bar. The progress dialog resizes to
414 fit. The progress dialog takes ownership of the progress \a bar which
415 will be deleted when necessary, so do not use a progress bar
416 allocated on the stack.
417*/
418
419void QProgressDialog::setBar(QProgressBar *bar)
420{
421 Q_D(QProgressDialog);
422 if (Q_UNLIKELY(!bar)) {
423 qWarning(msg: "QProgressDialog::setBar: Cannot set a null progress bar");
424 return;
425 }
426#ifndef QT_NO_DEBUG
427 if (Q_UNLIKELY(value() > 0))
428 qWarning(msg: "QProgressDialog::setBar: Cannot set a new progress bar "
429 "while the old one is active");
430#endif
431 if (Q_UNLIKELY(bar == d->bar)) {
432 qWarning(msg: "QProgressDialog::setBar: Attempt to set the same progress bar again");
433 return;
434 }
435 delete d->bar;
436 d->bar = bar;
437 d->adoptChildWidget(c: bar);
438}
439
440void QProgressDialogPrivate::adoptChildWidget(QWidget *c)
441{
442 Q_Q(QProgressDialog);
443
444 if (c) {
445 if (c->parentWidget() == q)
446 c->hide(); // until after ensureSizeIsAtLeastSizeHint()
447 else
448 c->setParent(parent: q, f: { });
449 }
450 ensureSizeIsAtLeastSizeHint();
451 //The layout should be updated again to prevent layout errors when the new 'widget' is replaced
452 layout();
453 if (c)
454 c->show();
455}
456
457void QProgressDialogPrivate::ensureSizeIsAtLeastSizeHint()
458{
459 Q_Q(QProgressDialog);
460
461 QSize size = q->sizeHint();
462 if (q->isVisible())
463 size = size.expandedTo(otherSize: q->size());
464 q->resize(size);
465}
466
467
468/*!
469 \property QProgressDialog::wasCanceled
470 \brief whether the dialog was canceled
471*/
472
473bool QProgressDialog::wasCanceled() const
474{
475 Q_D(const QProgressDialog);
476 return d->cancellationFlag;
477}
478
479
480/*!
481 \property QProgressDialog::maximum
482 \brief the highest value represented by the progress bar
483
484 The default is 100.
485
486 \sa minimum, setRange()
487*/
488
489int QProgressDialog::maximum() const
490{
491 Q_D(const QProgressDialog);
492 return d->bar->maximum();
493}
494
495void QProgressDialog::setMaximum(int maximum)
496{
497 Q_D(QProgressDialog);
498 d->bar->setMaximum(maximum);
499}
500
501/*!
502 \property QProgressDialog::minimum
503 \brief the lowest value represented by the progress bar
504
505 The default is 0.
506
507 \sa maximum, setRange()
508*/
509
510int QProgressDialog::minimum() const
511{
512 Q_D(const QProgressDialog);
513 return d->bar->minimum();
514}
515
516void QProgressDialog::setMinimum(int minimum)
517{
518 Q_D(QProgressDialog);
519 d->bar->setMinimum(minimum);
520}
521
522/*!
523 Sets the progress dialog's minimum and maximum values
524 to \a minimum and \a maximum, respectively.
525
526 If \a maximum is smaller than \a minimum, \a minimum becomes the only
527 legal value.
528
529 If the current value falls outside the new range, the progress
530 dialog is reset with reset().
531
532 \sa minimum, maximum
533*/
534void QProgressDialog::setRange(int minimum, int maximum)
535{
536 Q_D(QProgressDialog);
537 d->bar->setRange(minimum, maximum);
538}
539
540
541/*!
542 Resets the progress dialog.
543 The progress dialog becomes hidden if autoClose() is true.
544
545 \sa setAutoClose(), setAutoReset()
546*/
547
548void QProgressDialog::reset()
549{
550 Q_D(QProgressDialog);
551 if (d->autoClose || d->forceHide)
552 hide();
553 d->bar->reset();
554 d->cancellationFlag = false;
555 d->shownOnce = false;
556 d->setValueCalled = false;
557 d->forceTimer->stop();
558
559 /*
560 I wish we could disconnect the user slot provided to open() here but
561 unfortunately reset() is usually called before the slot has been invoked.
562 (reset() is itself invoked when canceled() is emitted.)
563 */
564 if (d->receiverToDisconnectOnClose)
565 QMetaObject::invokeMethod(obj: this, member: "_q_disconnectOnClose", c: Qt::QueuedConnection);
566}
567
568/*!
569 Resets the progress dialog. wasCanceled() becomes true until
570 the progress dialog is reset.
571 The progress dialog becomes hidden.
572*/
573
574void QProgressDialog::cancel()
575{
576 Q_D(QProgressDialog);
577 d->forceHide = true;
578 reset();
579 d->forceHide = false;
580 d->cancellationFlag = true;
581}
582
583
584int QProgressDialog::value() const
585{
586 Q_D(const QProgressDialog);
587 return d->bar->value();
588}
589
590/*!
591 \property QProgressDialog::value
592 \brief the current amount of progress made.
593
594 For the progress dialog to work as expected, you should initially set
595 this property to QProgressDialog::minimum() and finally set it to
596 QProgressDialog::maximum(); you can call setValue() any number of times
597 in-between.
598
599 \warning If the progress dialog is modal
600 (see QProgressDialog::QProgressDialog()),
601 setValue() calls QCoreApplication::processEvents(), so take care that
602 this does not cause undesirable re-entrancy in your code. For example,
603 don't use a QProgressDialog inside a paintEvent()!
604
605 \sa minimum, maximum
606*/
607void QProgressDialog::setValue(int progress)
608{
609 Q_D(QProgressDialog);
610 if (d->setValueCalled && progress == d->bar->value())
611 return;
612
613 d->bar->setValue(progress);
614
615 if (d->shownOnce) {
616 if (isModal() && !d->processingEvents) {
617 const QScopedValueRollback guard(d->processingEvents, true);
618 QCoreApplication::processEvents();
619 }
620 } else {
621 if ((!d->setValueCalled && progress == 0 /* for compat with Qt < 5.4 */) || progress == minimum()) {
622 d->starttime.start();
623 d->forceTimer->start(msec: d->showTime);
624 d->setValueCalled = true;
625 return;
626 } else {
627 d->setValueCalled = true;
628 bool need_show;
629 int elapsed = d->starttime.elapsed();
630 if (elapsed >= d->showTime) {
631 need_show = true;
632 } else {
633 if (elapsed > minWaitTime) {
634 int estimate;
635 int totalSteps = maximum() - minimum();
636 int myprogress = progress - minimum();
637 if (myprogress == 0) myprogress = 1;
638 if ((totalSteps - myprogress) >= INT_MAX / elapsed)
639 estimate = (totalSteps - myprogress) / myprogress * elapsed;
640 else
641 estimate = elapsed * (totalSteps - myprogress) / myprogress;
642 need_show = estimate >= d->showTime;
643 } else {
644 need_show = false;
645 }
646 }
647 if (need_show) {
648 d->ensureSizeIsAtLeastSizeHint();
649 show();
650 d->shownOnce = true;
651 }
652 }
653 }
654
655 if (progress == d->bar->maximum() && d->autoReset)
656 reset();
657}
658
659/*!
660 Returns a size that fits the contents of the progress dialog.
661 The progress dialog resizes itself as required, so you should not
662 need to call this yourself.
663*/
664
665QSize QProgressDialog::sizeHint() const
666{
667 Q_D(const QProgressDialog);
668 QSize labelSize = d->label ? d->label->sizeHint() : QSize(0, 0);
669 QSize barSize = d->bar->sizeHint();
670 int marginBottom = style()->pixelMetric(metric: QStyle::PM_LayoutBottomMargin, option: 0, widget: this);
671 int spacing = style()->pixelMetric(metric: QStyle::PM_LayoutVerticalSpacing, option: 0, widget: this);
672 int marginLeft = style()->pixelMetric(metric: QStyle::PM_LayoutLeftMargin, option: 0, widget: this);
673 int marginRight = style()->pixelMetric(metric: QStyle::PM_LayoutRightMargin, option: 0, widget: this);
674
675 int height = marginBottom * 2 + barSize.height() + labelSize.height() + spacing;
676 if (d->cancel)
677 height += d->cancel->sizeHint().height() + spacing;
678 return QSize(qMax(a: 200, b: labelSize.width() + marginLeft + marginRight), height);
679}
680
681/*!\reimp
682*/
683void QProgressDialog::resizeEvent(QResizeEvent *)
684{
685 Q_D(QProgressDialog);
686 d->layout();
687}
688
689/*!
690 \reimp
691*/
692void QProgressDialog::changeEvent(QEvent *ev)
693{
694 Q_D(QProgressDialog);
695 if (ev->type() == QEvent::StyleChange) {
696 d->layout();
697 } else if (ev->type() == QEvent::LanguageChange) {
698 d->retranslateStrings();
699 }
700 QDialog::changeEvent(ev);
701}
702
703/*!
704 \property QProgressDialog::minimumDuration
705 \brief the time that must pass before the dialog appears
706
707 If the expected duration of the task is less than the
708 minimumDuration, the dialog will not appear at all. This prevents
709 the dialog popping up for tasks that are quickly over. For tasks
710 that are expected to exceed the minimumDuration, the dialog will
711 pop up after the minimumDuration time or as soon as any progress
712 is set.
713
714 If set to 0, the dialog is always shown as soon as any progress is
715 set. The default is 4000 milliseconds.
716*/
717void QProgressDialog::setMinimumDuration(int ms)
718{
719 Q_D(QProgressDialog);
720 d->showTime = ms;
721 if (d->bar->value() == d->bar->minimum()) {
722 d->forceTimer->stop();
723 d->forceTimer->start(msec: ms);
724 }
725}
726
727int QProgressDialog::minimumDuration() const
728{
729 Q_D(const QProgressDialog);
730 return d->showTime;
731}
732
733
734/*!
735 \reimp
736*/
737
738void QProgressDialog::closeEvent(QCloseEvent *e)
739{
740 emit canceled();
741 QDialog::closeEvent(e);
742}
743
744/*!
745 \property QProgressDialog::autoReset
746 \brief whether the progress dialog calls reset() as soon as value() equals maximum()
747
748 The default is true.
749
750 \sa setAutoClose()
751*/
752
753void QProgressDialog::setAutoReset(bool b)
754{
755 Q_D(QProgressDialog);
756 d->autoReset = b;
757}
758
759bool QProgressDialog::autoReset() const
760{
761 Q_D(const QProgressDialog);
762 return d->autoReset;
763}
764
765/*!
766 \property QProgressDialog::autoClose
767 \brief whether the dialog gets hidden by reset()
768
769 The default is true.
770
771 \sa setAutoReset()
772*/
773
774void QProgressDialog::setAutoClose(bool close)
775{
776 Q_D(QProgressDialog);
777 d->autoClose = close;
778}
779
780bool QProgressDialog::autoClose() const
781{
782 Q_D(const QProgressDialog);
783 return d->autoClose;
784}
785
786/*!
787 \reimp
788*/
789
790void QProgressDialog::showEvent(QShowEvent *e)
791{
792 Q_D(QProgressDialog);
793 QDialog::showEvent(e);
794 d->ensureSizeIsAtLeastSizeHint();
795 d->forceTimer->stop();
796}
797
798/*!
799 Shows the dialog if it is still hidden after the algorithm has been started
800 and minimumDuration milliseconds have passed.
801
802 \sa setMinimumDuration()
803*/
804
805void QProgressDialog::forceShow()
806{
807 Q_D(QProgressDialog);
808 d->forceTimer->stop();
809 if (d->shownOnce || d->cancellationFlag)
810 return;
811
812 show();
813 d->shownOnce = true;
814}
815
816/*!
817 \since 4.5
818
819 Opens the dialog and connects its canceled() signal to the slot specified
820 by \a receiver and \a member.
821
822 The signal will be disconnected from the slot when the dialog is closed.
823*/
824void QProgressDialog::open(QObject *receiver, const char *member)
825{
826 Q_D(QProgressDialog);
827 connect(sender: this, SIGNAL(canceled()), receiver, member);
828 d->receiverToDisconnectOnClose = receiver;
829 d->memberToDisconnectOnClose = member;
830 QDialog::open();
831}
832
833QT_END_NAMESPACE
834
835#include "moc_qprogressdialog.cpp"
836

source code of qtbase/src/widgets/dialogs/qprogressdialog.cpp