~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/dialogs/qprogressdialog.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the dialog module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "qprogressdialog.h"
 
30
 
 
31
#ifndef QT_NO_PROGRESSDIALOG
 
32
 
 
33
#include "qshortcut.h"
 
34
#include "qpainter.h"
 
35
#include "qdrawutil.h"
 
36
#include "qdatetime.h"
 
37
#include "qlabel.h"
 
38
#include "qprogressbar.h"
 
39
#include "qapplication.h"
 
40
#include "qstyle.h"
 
41
#include "qpushbutton.h"
 
42
#include "qcursor.h"
 
43
#include "qtimer.h"
 
44
#include <private/qdialog_p.h>
 
45
#include <limits.h>
 
46
 
 
47
// If the operation is expected to take this long (as predicted by
 
48
// progress time), show the progress dialog.
 
49
static const int defaultShowTime    = 4000;
 
50
// Wait at least this long before attempting to make a prediction.
 
51
static const int minWaitTime = 50;
 
52
 
 
53
// Various layout values
 
54
static const int margin_lr   = 10;
 
55
static const int margin_tb   = 10;
 
56
static const int spacing     = 4;
 
57
 
 
58
 
 
59
class QProgressDialogPrivate : public QDialogPrivate
 
60
{
 
61
    Q_DECLARE_PUBLIC(QProgressDialog)
 
62
public:
 
63
    QProgressDialogPrivate() : label(0), cancel(0), bar(0),
 
64
        shown_once(false),
 
65
        cancellation_flag(false),
 
66
        showTime(defaultShowTime)
 
67
    {
 
68
    }
 
69
 
 
70
    void init(const QString &labelText, const QString &cancelText, int min, int max);
 
71
    void layout();
 
72
 
 
73
    QLabel         *label;
 
74
    QPushButton         *cancel;
 
75
    QProgressBar *bar;
 
76
    QTimer *forceTimer;
 
77
    bool          shown_once;
 
78
    bool          cancellation_flag;
 
79
    QTime          starttime;
 
80
#ifndef QT_NO_CURSOR
 
81
    QCursor          parentCursor;
 
82
#endif
 
83
    int                  showTime;
 
84
    bool autoClose;
 
85
    bool autoReset;
 
86
    bool forceHide;
 
87
};
 
88
 
 
89
void QProgressDialogPrivate::init(const QString &labelText, const QString &cancelText,
 
90
                                  int min, int max)
 
91
{
 
92
    Q_Q(QProgressDialog);
 
93
    label = new QLabel(labelText, q);
 
94
    int align = q->style()->styleHint(QStyle::SH_ProgressDialog_TextLabelAlignment, 0, q);
 
95
    label->setAlignment(Qt::Alignment(align));
 
96
    bar = new QProgressBar(q);
 
97
    bar->setRange(min, max);
 
98
    autoClose = true;
 
99
    autoReset = true;
 
100
    forceHide = false;
 
101
    q->setCancelButtonText(cancelText);
 
102
    QObject::connect(q, SIGNAL(canceled()), q, SLOT(cancel()));
 
103
    forceTimer = new QTimer(q);
 
104
    QObject::connect(forceTimer, SIGNAL(timeout()), q, SLOT(forceShow()));
 
105
}
 
106
 
 
107
void QProgressDialogPrivate::layout()
 
108
{
 
109
    Q_Q(QProgressDialog);
 
110
    int sp = spacing;
 
111
    int mtb = margin_tb;
 
112
    int mlr = qMin(q->width() / 10, margin_lr);
 
113
    const bool centered =
 
114
        bool(q->style()->styleHint(QStyle::SH_ProgressDialog_CenterCancelButton, 0, q));
 
115
 
 
116
    QSize cs = cancel ? cancel->sizeHint() : QSize(0,0);
 
117
    QSize bh = bar->sizeHint();
 
118
    int cspc;
 
119
    int lh = 0;
 
120
 
 
121
    // Find spacing and sizes that fit.  It is important that a progress
 
122
    // dialog can be made very small if the user demands it so.
 
123
    for (int attempt=5; attempt--;) {
 
124
        cspc = cancel ? cs.height() + sp : 0;
 
125
        lh = qMax(0, q->height() - mtb - bh.height() - sp - cspc);
 
126
 
 
127
        if (lh < q->height()/4) {
 
128
            // Getting cramped
 
129
            sp /= 2;
 
130
            mtb /= 2;
 
131
            if (cancel) {
 
132
                cs.setHeight(qMax(4,cs.height()-sp-2));
 
133
            }
 
134
            bh.setHeight(qMax(4,bh.height()-sp-1));
 
135
        } else {
 
136
            break;
 
137
        }
 
138
    }
 
139
 
 
140
    if (cancel) {
 
141
        cancel->setGeometry(
 
142
            centered ? q->width()/2 - cs.width()/2 : q->width() - mlr - cs.width(),
 
143
            q->height() - mtb - cs.height() + sp,
 
144
            cs.width(), cs.height());
 
145
    }
 
146
 
 
147
    label->setGeometry(mlr, 0, q->width()-mlr*2, lh);
 
148
    bar->setGeometry(mlr, lh+sp, q->width()-mlr*2, bh.height());
 
149
}
 
150
 
 
151
 
 
152
/*!
 
153
  \class QProgressDialog
 
154
  \brief The QProgressDialog class provides feedback on the progress of a slow operation.
 
155
  \ingroup dialogs
 
156
  \mainclass
 
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.
 
182
 
 
183
  There are two ways of using QProgressDialog: modal and modeless.
 
184
 
 
185
  Using a modal QProgressDialog is simpler for the programmer, but you
 
186
  must call QApplication::processEvents() or
 
187
  QEventLoop::processEvents(ExcludeUserInput) to keep the event loop
 
188
  running to ensure that the application doesn't freeze. Do the
 
189
  operation in a loop, call \l setValue() at intervals, and check
 
190
  for cancelation with wasCanceled(). For example:
 
191
 
 
192
  \quotefromfile snippets/dialogs/dialogs.cpp
 
193
  \skipto QProgressDialog progress("Copying files...", "Abort Copy", 0, numFiles, this);
 
194
  \printuntil progress.setValue(numFiles);
 
195
 
 
196
  A modeless progress dialog is suitable for operations that take
 
197
  place in the background, where the user is able to interact with the
 
198
  application. Such operations are typically based on QTimer (or
 
199
  QObject::timerEvent()), QSocketNotifier, or QUrlOperator; or performed
 
200
  in a separate thread. A QProgressBar in the status bar of your main window
 
201
  is often an alternative to a modeless progress dialog.
 
202
 
 
203
  You need to have an event loop to be running, connect the
 
204
  canceled() signal to a slot that stops the operation, and call \l
 
205
  setValue() at intervals. For example:
 
206
 
 
207
  \skipto Operation constructor
 
208
  \printuntil }
 
209
  \printuntil }
 
210
  \printuntil }
 
211
 
 
212
  In both modes the progress dialog may be customized by
 
213
  replacing the child widgets with custom widgets by using setLabel(),
 
214
  setBar(), and setCancelButton().
 
215
  The functions setLabelText() and setCancelButtonText()
 
216
  set the texts shown.
 
217
 
 
218
  The \l{dialogs/standarddialogs}{Standard Dialogs} example shows
 
219
  how to use QProgressDialog as well as other built-in Qt dialogs.
 
220
 
 
221
  \inlineimage qprogdlg-m.png Screenshot in Motif style
 
222
  \inlineimage qprogdlg-w.png Screenshot in Windows style
 
223
 
 
224
  \sa QDialog, QProgressBar, {fowler}{GUI Design Handbook: Progress Indicator}
 
225
*/
 
226
 
 
227
 
 
228
/*!
 
229
  Constructs a progress dialog.
 
230
 
 
231
  Default settings:
 
232
  \list
 
233
  \i The label text is empty.
 
234
  \i The cancel button text is (translated) "Cancel".
 
235
  \i minimum is 0;
 
236
  \i maximum is 100
 
237
  \endlist
 
238
 
 
239
  The \a parent argument is dialog's parent widget. The widget flags, \a f, are
 
240
  passed to the QDialog::QDialog() constructor.
 
241
 
 
242
  \sa setLabelText(), setCancelButtonText(), setCancelButton(),
 
243
  setMinimum(), setMaximum()
 
244
*/
 
245
 
 
246
QProgressDialog::QProgressDialog(QWidget *parent, Qt::WFlags f)
 
247
    : QDialog(*(new QProgressDialogPrivate), parent, f)
 
248
{
 
249
    Q_D(QProgressDialog);
 
250
    d->init(QString::fromLatin1(""), tr("Cancel"), 0, 100);
 
251
}
 
252
 
 
253
/*!
 
254
  Constructs a progress dialog.
 
255
 
 
256
   The \a labelText is the text used to remind the user what is progressing.
 
257
 
 
258
   The \a cancelButtonText is the text to display on the cancel button,
 
259
   or 0 if no cancel button is to be shown.
 
260
 
 
261
   The \a minimum and \a maximum is the number of steps in the operation for
 
262
   which this progress dialog shows progress.  For example, if the
 
263
   operation is to examine 50 files, this value minimum value would be 0,
 
264
   and the maximum would be 50. Before examining the first file, call
 
265
   setValue(0). As each file is processed call setValue(1), setValue(2),
 
266
   etc., finally calling setValue(50) after examining the last file.
 
267
 
 
268
   The \a parent argument is the dialog's parent widget. The  and widget flags,
 
269
   \a f, are passed to the QDialog::QDialog() constructor.
 
270
 
 
271
  \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
 
272
  setMinimum(), setMaximum()
 
273
*/
 
274
 
 
275
QProgressDialog::QProgressDialog(const QString &labelText,
 
276
                                  const QString &cancelButtonText,
 
277
                                  int minimum, int maximum,
 
278
                                  QWidget *parent, Qt::WFlags f)
 
279
    : QDialog(*(new QProgressDialogPrivate), parent, f)
 
280
{
 
281
    Q_D(QProgressDialog);
 
282
    d->init(labelText, cancelButtonText, minimum, maximum);
 
283
}
 
284
 
 
285
 
 
286
/*!
 
287
  Destroys the progress dialog.
 
288
*/
 
289
 
 
290
QProgressDialog::~QProgressDialog()
 
291
{
 
292
}
 
293
 
 
294
/*!
 
295
  \fn void QProgressDialog::canceled()
 
296
 
 
297
  This signal is emitted when the cancel button is clicked.
 
298
  It is connected to the cancel() slot by default.
 
299
 
 
300
  \sa wasCanceled()
 
301
*/
 
302
 
 
303
 
 
304
/*!
 
305
  Sets the label to \a label. The progress dialog resizes to fit. The
 
306
  label becomes owned by the progress dialog and will be deleted when
 
307
  necessary, so do not pass the address of an object on the stack.
 
308
 
 
309
  \sa setLabelText()
 
310
*/
 
311
 
 
312
void QProgressDialog::setLabel(QLabel *label)
 
313
{
 
314
    Q_D(QProgressDialog);
 
315
    delete d->label;
 
316
    d->label = label;
 
317
    if (label) {
 
318
        if (label->parentWidget() == this) {
 
319
            label->hide(); // until we resize
 
320
        } else {
 
321
            label->setParent(this, 0);
 
322
        }
 
323
    }
 
324
    int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
325
    int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
326
    resize(w, h);
 
327
    if (label)
 
328
        label->show();
 
329
}
 
330
 
 
331
 
 
332
/*!
 
333
  \property QProgressDialog::labelText
 
334
  \brief the label's text
 
335
 
 
336
  The default text is an empty string.
 
337
*/
 
338
 
 
339
QString QProgressDialog::labelText() const
 
340
{
 
341
    Q_D(const QProgressDialog);
 
342
    if (d->label)
 
343
        return d->label->text();
 
344
    return QString();
 
345
}
 
346
 
 
347
void QProgressDialog::setLabelText(const QString &text)
 
348
{
 
349
    Q_D(QProgressDialog);
 
350
    if (d->label) {
 
351
        d->label->setText(text);
 
352
        int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
353
        int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
354
        resize(w, h);
 
355
    }
 
356
}
 
357
 
 
358
 
 
359
/*!
 
360
  Sets the cancel button to the push button, \a cancelButton. The
 
361
  progress dialog takes ownership of this button which will be deleted
 
362
  when necessary, so do not pass the address of an object that is on
 
363
  the stack, i.e. use new() to create the button.
 
364
 
 
365
  \sa setCancelButtonText()
 
366
*/
 
367
 
 
368
void QProgressDialog::setCancelButton(QPushButton *cancelButton)
 
369
{
 
370
    Q_D(QProgressDialog);
 
371
    delete d->cancel;
 
372
    d->cancel = cancelButton;
 
373
    if (cancelButton) {
 
374
        if (cancelButton->parentWidget() == this) {
 
375
            cancelButton->hide(); // until we resize
 
376
        } else {
 
377
            cancelButton->setParent(this, 0);
 
378
        }
 
379
        connect(d->cancel, SIGNAL(clicked()), this, SIGNAL(canceled()));
 
380
        new QShortcut(Qt::Key_Escape, this, SIGNAL(canceled()));
 
381
    }
 
382
    int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
383
    int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
384
    resize(w, h);
 
385
    if (cancelButton)
 
386
        cancelButton->show();
 
387
}
 
388
 
 
389
/*!
 
390
  Sets the cancel button's text to \a cancelButtonText.
 
391
  \sa setCancelButton()
 
392
*/
 
393
 
 
394
void QProgressDialog::setCancelButtonText(const QString &cancelButtonText)
 
395
{
 
396
    Q_D(QProgressDialog);
 
397
    if (!cancelButtonText.isNull()) {
 
398
        if (d->cancel)
 
399
            d->cancel->setText(cancelButtonText);
 
400
        else
 
401
            setCancelButton(new QPushButton(cancelButtonText, this));
 
402
    } else {
 
403
        setCancelButton(0);
 
404
    }
 
405
    int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
406
    int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
407
    resize(w, h);
 
408
}
 
409
 
 
410
 
 
411
/*!
 
412
  Sets the progress bar widget to \a bar. The progress dialog resizes to
 
413
  fit. The progress dialog takes ownership of the progress \a bar which
 
414
  will be deleted when necessary, so do not use a progress bar
 
415
  allocated on the stack.
 
416
*/
 
417
 
 
418
void QProgressDialog::setBar(QProgressBar *bar)
 
419
{
 
420
    Q_D(QProgressDialog);
 
421
#ifndef QT_NO_DEBUG
 
422
    if (value() > 0)
 
423
        qWarning("QProgressDialog::setBar: Cannot set a new progress bar "
 
424
                  "while the old one is active");
 
425
#endif
 
426
    delete d->bar;
 
427
    d->bar = bar;
 
428
    int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
429
    int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
430
    resize(w, h);
 
431
}
 
432
 
 
433
 
 
434
/*!
 
435
  \property QProgressDialog::wasCanceled
 
436
  \brief whether the dialog was canceled
 
437
*/
 
438
 
 
439
bool QProgressDialog::wasCanceled() const
 
440
{
 
441
    Q_D(const QProgressDialog);
 
442
    return d->cancellation_flag;
 
443
}
 
444
 
 
445
 
 
446
/*!
 
447
    \property QProgressDialog::maximum
 
448
    \brief the highest value represented by the progress bar
 
449
 
 
450
    The default is 0.
 
451
 
 
452
    \sa minimum, setRange()
 
453
*/
 
454
 
 
455
int QProgressDialog::maximum() const
 
456
{
 
457
    Q_D(const QProgressDialog);
 
458
    return d->bar->maximum();
 
459
}
 
460
 
 
461
void QProgressDialog::setMaximum(int maximum)
 
462
{
 
463
    Q_D(QProgressDialog);
 
464
    d->bar->setMaximum(maximum);
 
465
}
 
466
 
 
467
/*!
 
468
    \property QProgressDialog::minimum
 
469
    \brief the lowest value represented by the progress bar
 
470
 
 
471
    The default is 0.
 
472
 
 
473
    \sa maximum, setRange()
 
474
*/
 
475
 
 
476
int QProgressDialog::minimum() const
 
477
{
 
478
    Q_D(const QProgressDialog);
 
479
    return d->bar->minimum();
 
480
}
 
481
 
 
482
void QProgressDialog::setMinimum(int minimum)
 
483
{
 
484
    Q_D(QProgressDialog);
 
485
    d->bar->setMinimum(minimum);
 
486
}
 
487
 
 
488
/*!
 
489
    Sets the progress dialog's minimum and maximum values
 
490
    to \a minimum and \a maximum, respectively.
 
491
 
 
492
    If \a maximum is smaller than \a minimum, \a minimum becomes the only
 
493
    legal value.
 
494
 
 
495
    If the current value falls outside the new range, the progress
 
496
    dialog is reset with reset().
 
497
 
 
498
    \sa minimum, maximum
 
499
*/
 
500
void QProgressDialog::setRange(int minimum, int maximum)
 
501
{
 
502
    Q_D(QProgressDialog);
 
503
    d->bar->setRange(minimum, maximum);
 
504
}
 
505
 
 
506
 
 
507
/*!
 
508
  Resets the progress dialog.
 
509
  The progress dialog becomes hidden if autoClose() is true.
 
510
 
 
511
  \sa setAutoClose(), setAutoReset()
 
512
*/
 
513
 
 
514
void QProgressDialog::reset()
 
515
{
 
516
    Q_D(QProgressDialog);
 
517
#ifndef QT_NO_CURSOR
 
518
    if (value() >= 0) {
 
519
        if (parentWidget())
 
520
            parentWidget()->setCursor(d->parentCursor);
 
521
    }
 
522
#endif
 
523
    if (d->autoClose || d->forceHide)
 
524
        hide();
 
525
    d->bar->reset();
 
526
    d->cancellation_flag = false;
 
527
    d->shown_once = false;
 
528
    d->forceTimer->stop();
 
529
}
 
530
 
 
531
/*!
 
532
  Resets the progress dialog. wasCanceled() becomes true until
 
533
  the progress dialog is reset.
 
534
  The progress dialog becomes hidden.
 
535
*/
 
536
 
 
537
void QProgressDialog::cancel()
 
538
{
 
539
    Q_D(QProgressDialog);
 
540
    d->forceHide = true;
 
541
    reset();
 
542
    d->forceHide = false;
 
543
    d->cancellation_flag = true;
 
544
}
 
545
 
 
546
 
 
547
int QProgressDialog::value() const
 
548
{
 
549
    Q_D(const QProgressDialog);
 
550
    return d->bar->value();
 
551
}
 
552
 
 
553
/*!
 
554
  \property QProgressDialog::value
 
555
  \brief the current amount of progress made.
 
556
 
 
557
  For the progress dialog to work as expected, you should initially set
 
558
  this property to 0 and finally set it to
 
559
  QProgressDialog::totalSteps(); you can call setProgress() any number of times
 
560
  in-between.
 
561
 
 
562
  \warning If the progress dialog is modal
 
563
    (see QProgressDialog::QProgressDialog()),
 
564
    this function calls QApplication::processEvents(), so take care that
 
565
    this does not cause undesirable re-entrancy in your code. For example,
 
566
    don't use a QProgressDialog inside a paintEvent()!
 
567
 
 
568
  \sa minimum, maximum
 
569
*/
 
570
void QProgressDialog::setValue(int progress)
 
571
{
 
572
    Q_D(QProgressDialog);
 
573
    if (progress == d->bar->value() ||
 
574
         d->bar->value() == -1 && progress == d->bar->maximum())
 
575
        return;
 
576
 
 
577
    d->bar->setValue(progress);
 
578
 
 
579
    if (d->shown_once) {
 
580
        if (testAttribute(Qt::WA_ShowModal))
 
581
            qApp->processEvents();
 
582
    } else {
 
583
        if (progress == 0) {
 
584
            d->starttime.start();
 
585
            d->forceTimer->start(d->showTime);
 
586
            return;
 
587
        } else {
 
588
            bool need_show;
 
589
            int elapsed = d->starttime.elapsed();
 
590
            if (elapsed >= d->showTime) {
 
591
                need_show = true;
 
592
            } else {
 
593
                if (elapsed > minWaitTime) {
 
594
                    int estimate;
 
595
                    int totalSteps = maximum() - minimum();
 
596
                    int myprogress = progress - minimum();
 
597
                    if ((totalSteps - myprogress) >= INT_MAX / elapsed)
 
598
                        estimate = (totalSteps - myprogress) / myprogress * elapsed;
 
599
                    else
 
600
                        estimate = elapsed * (totalSteps - myprogress) / myprogress;
 
601
                    need_show = estimate >= d->showTime;
 
602
                } else {
 
603
                    need_show = false;
 
604
                }
 
605
            }
 
606
            if (need_show) {
 
607
                int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
608
                int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
609
                resize(w, h);
 
610
                show();
 
611
                d->shown_once = true;
 
612
            }
 
613
        }
 
614
#ifdef Q_WS_MAC
 
615
        QApplication::flush();
 
616
#endif
 
617
    }
 
618
 
 
619
    if (progress == d->bar->maximum() && d->autoReset)
 
620
        reset();
 
621
}
 
622
 
 
623
/*!
 
624
  Returns a size that fits the contents of the progress dialog.
 
625
  The progress dialog resizes itself as required, so you should not
 
626
  need to call this yourself.
 
627
*/
 
628
 
 
629
QSize QProgressDialog::sizeHint() const
 
630
{
 
631
    Q_D(const QProgressDialog);
 
632
    QSize sh = d->label->sizeHint();
 
633
    QSize bh = d->bar->sizeHint();
 
634
    int h = margin_tb*2 + bh.height() + sh.height() + spacing;
 
635
    if (d->cancel)
 
636
        h += d->cancel->sizeHint().height() + spacing;
 
637
    return QSize(qMax(200, sh.width() + 2*margin_lr), h);
 
638
}
 
639
 
 
640
/*!\reimp
 
641
*/
 
642
void QProgressDialog::resizeEvent(QResizeEvent *)
 
643
{
 
644
    Q_D(QProgressDialog);
 
645
    d->layout();
 
646
}
 
647
 
 
648
/*!
 
649
  \reimp
 
650
*/
 
651
void QProgressDialog::changeEvent(QEvent *ev)
 
652
{
 
653
    Q_D(QProgressDialog);
 
654
    if(ev->type() == QEvent::StyleChange)
 
655
        d->layout();
 
656
    QDialog::changeEvent(ev);
 
657
}
 
658
 
 
659
/*!
 
660
    \property QProgressDialog::minimumDuration
 
661
    \brief the time that must pass before the dialog appears
 
662
 
 
663
    If the expected duration of the task is less than the
 
664
    minimumDuration, the dialog will not appear at all. This prevents
 
665
    the dialog popping up for tasks that are quickly over. For tasks
 
666
    that are expected to exceed the minimumDuration, the dialog will
 
667
    pop up after the minimumDuration time or as soon as any progress
 
668
    is set.
 
669
 
 
670
    If set to 0, the dialog is always shown as soon as any progress is
 
671
    set. The default is 4000 milliseconds.
 
672
*/
 
673
void QProgressDialog::setMinimumDuration(int ms)
 
674
{
 
675
    Q_D(QProgressDialog);
 
676
    d->showTime = ms;
 
677
    if (d->bar->value() == 0) {
 
678
        d->forceTimer->stop();
 
679
        d->forceTimer->start(ms);
 
680
    }
 
681
}
 
682
 
 
683
int QProgressDialog::minimumDuration() const
 
684
{
 
685
    Q_D(const QProgressDialog);
 
686
    return d->showTime;
 
687
}
 
688
 
 
689
 
 
690
/*!
 
691
  \reimp
 
692
*/
 
693
 
 
694
void QProgressDialog::closeEvent(QCloseEvent *e)
 
695
{
 
696
    emit canceled();
 
697
    QDialog::closeEvent(e);
 
698
}
 
699
 
 
700
/*!
 
701
  \property QProgressDialog::autoReset
 
702
  \brief whether the progress dialog calls reset() as soon as progress() equals totalSteps()
 
703
 
 
704
  The default is true.
 
705
 
 
706
  \sa setAutoClose()
 
707
*/
 
708
 
 
709
void QProgressDialog::setAutoReset(bool b)
 
710
{
 
711
    Q_D(QProgressDialog);
 
712
    d->autoReset = b;
 
713
}
 
714
 
 
715
bool QProgressDialog::autoReset() const
 
716
{
 
717
    Q_D(const QProgressDialog);
 
718
    return d->autoReset;
 
719
}
 
720
 
 
721
/*!
 
722
  \property QProgressDialog::autoClose
 
723
  \brief whether the dialog gets hidden by reset()
 
724
 
 
725
  The default is true.
 
726
 
 
727
  \sa setAutoReset()
 
728
*/
 
729
 
 
730
void QProgressDialog::setAutoClose(bool b)
 
731
{
 
732
    Q_D(QProgressDialog);
 
733
    d->autoClose = b;
 
734
}
 
735
 
 
736
bool QProgressDialog::autoClose() const
 
737
{
 
738
    Q_D(const QProgressDialog);
 
739
    return d->autoClose;
 
740
}
 
741
 
 
742
/*!
 
743
  \reimp
 
744
*/
 
745
 
 
746
void QProgressDialog::showEvent(QShowEvent *e)
 
747
{
 
748
    Q_D(QProgressDialog);
 
749
    QDialog::showEvent(e);
 
750
    int w = qMax(isVisible() ? width() : 0, sizeHint().width());
 
751
    int h = qMax(isVisible() ? height() : 0, sizeHint().height());
 
752
    resize(w, h);
 
753
    d->forceTimer->stop();
 
754
}
 
755
 
 
756
/*!
 
757
  Shows the dialog if it is still hidden after the algorithm has been started
 
758
  and minimumDuration milliseconds have passed.
 
759
 
 
760
  \sa setMinimumDuration()
 
761
*/
 
762
 
 
763
void QProgressDialog::forceShow()
 
764
{
 
765
    Q_D(QProgressDialog);
 
766
    if (d->shown_once || d->cancellation_flag)
 
767
        return;
 
768
 
 
769
    show();
 
770
    d->shown_once = true;
 
771
}
 
772
 
 
773
#endif