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