00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qprogressbar.h"
00025 #ifndef QT_NO_PROGRESSBAR
00026 #include <qevent.h>
00027 #include <qpainter.h>
00028 #include <qstylepainter.h>
00029 #include <qstyleoption.h>
00030 #include <private/qwidget_p.h>
00031 #ifndef QT_NO_ACCESSIBILITY
00032 #include <qaccessible.h>
00033 #endif
00034 #include <limits.h>
00035
00036 class QProgressBarPrivate : public QWidgetPrivate
00037 {
00038 Q_DECLARE_PUBLIC(QProgressBar)
00039 public:
00040 QProgressBarPrivate();
00041 void init();
00042
00043 int minimum;
00044 int maximum;
00045 int value;
00046 Qt::Alignment alignment;
00047 uint textVisible : 1;
00048 int lastPaintedValue;
00049 Qt::Orientation orientation;
00050 bool invertedAppearance;
00051 QProgressBar::Direction textDirection;
00052 QString format;
00053 QStyleOptionProgressBarV2 getStyleOption() const;
00054 inline int bound(int val) const { return qMax(minimum-1, qMin(maximum, val)); }
00055 bool repaintRequired() const;
00056 };
00057
00058 QProgressBarPrivate::QProgressBarPrivate()
00059 : minimum(0), maximum(100), value(-1), alignment(Qt::AlignLeft), textVisible(true),
00060 lastPaintedValue(-1), orientation(Qt::Horizontal), invertedAppearance(false),
00061 textDirection(QProgressBar::TopToBottom), format(QLatin1String("%p%"))
00062 {
00063 }
00064
00065 void QProgressBarPrivate::init()
00066 {
00067 Q_Q(QProgressBar);
00068 QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Fixed);
00069 if (orientation == Qt::Vertical)
00070 sp.transpose();
00071 q->setSizePolicy(sp);
00072 q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00073 }
00074
00075 QStyleOptionProgressBarV2 QProgressBarPrivate::getStyleOption() const
00076 {
00077 QStyleOptionProgressBarV2 opt;
00078 opt.init(q_func());
00079
00080 opt.minimum = minimum;
00081 opt.maximum = maximum;
00082 opt.progress = value;
00083 opt.textAlignment = alignment;
00084 opt.textVisible = textVisible;
00085 opt.text = q_func()->text();
00086 opt.orientation = orientation;
00087 opt.invertedAppearance = invertedAppearance;
00088 opt.bottomToTop = (textDirection == QProgressBar::BottomToTop);
00089
00090 return opt;
00091 }
00092
00093 bool QProgressBarPrivate::repaintRequired() const
00094 {
00095 Q_Q(const QProgressBar);
00096 if (value == lastPaintedValue)
00097 return false;
00098
00099 int valueDifference = qAbs(value - lastPaintedValue);
00100
00101
00102 if ((value == minimum || value == maximum)
00103 || (textVisible && valueDifference >= qAbs((maximum - minimum) / 100)))
00104 return true;
00105
00106
00107 QStyleOptionProgressBarV2 opt = getStyleOption();
00108 int cw = q->style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &opt, q);
00109 QRect groove = q->style()->subElementRect(QStyle::SE_ProgressBarGroove, &opt, q);
00110
00111
00112
00113 return (valueDifference * groove.width() > cw * (maximum - minimum));
00114 }
00115
00186 QProgressBar::QProgressBar(QWidget *parent)
00187 : QWidget(*(new QProgressBarPrivate), parent, 0)
00188 {
00189 d_func()->init();
00190 }
00191
00197 void QProgressBar::reset()
00198 {
00199 Q_D(QProgressBar);
00200 d->value = d->minimum - 1;
00201 if (d->minimum == INT_MIN)
00202 d->value = INT_MIN;
00203 repaint();
00204 }
00205
00215 void QProgressBar::setMinimum(int minimum)
00216 {
00217 setRange(minimum, qMax(d_func()->maximum, minimum));
00218 }
00219
00220 int QProgressBar::minimum() const
00221 {
00222 return d_func()->minimum;
00223 }
00224
00225
00236 void QProgressBar::setMaximum(int maximum)
00237 {
00238 setRange(qMin(d_func()->minimum, maximum), maximum);
00239 }
00240
00241 int QProgressBar::maximum() const
00242 {
00243 return d_func()->maximum;
00244 }
00245
00253 void QProgressBar::setValue(int value)
00254 {
00255 Q_D(QProgressBar);
00256 if (d->value == value
00257 || ((value > d->maximum || value < d->minimum)
00258 && (d->maximum != 0 || d->minimum != 0)))
00259 return;
00260 d->value = value;
00261 emit valueChanged(value);
00262 #ifndef QT_NO_ACCESSIBILITY
00263 QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
00264 #endif
00265 if (d->repaintRequired())
00266 repaint();
00267 }
00268
00269 int QProgressBar::value() const
00270 {
00271 return d_func()->value;
00272 }
00273
00286 void QProgressBar::setRange(int minimum, int maximum)
00287 {
00288 Q_D(QProgressBar);
00289 d->minimum = minimum;
00290 d->maximum = qMax(minimum, maximum);
00291 if ( d->value <(d->minimum-1) || d->value > d->maximum)
00292 reset();
00293 }
00300 void QProgressBar::setTextVisible(bool visible)
00301 {
00302 Q_D(QProgressBar);
00303 if (d->textVisible != visible) {
00304 d->textVisible = visible;
00305 repaint();
00306 }
00307 }
00308
00309 bool QProgressBar::isTextVisible() const
00310 {
00311 return d_func()->textVisible;
00312 }
00313
00318 void QProgressBar::setAlignment(Qt::Alignment alignment)
00319 {
00320 if (d_func()->alignment != alignment) {
00321 d_func()->alignment = alignment;
00322 repaint();
00323 }
00324 }
00325
00326 Qt::Alignment QProgressBar::alignment() const
00327 {
00328 return d_func()->alignment;
00329 }
00330
00334 void QProgressBar::paintEvent(QPaintEvent *)
00335 {
00336 QStylePainter paint(this);
00337 QStyleOptionProgressBarV2 opt = d_func()->getStyleOption();
00338 paint.drawControl(QStyle::CE_ProgressBar, opt);
00339 d_func()->lastPaintedValue = d_func()->value;
00340 }
00341
00345 QSize QProgressBar::sizeHint() const
00346 {
00347 ensurePolished();
00348 QFontMetrics fm = fontMetrics();
00349 QStyleOptionProgressBarV2 opt = d_func()->getStyleOption();
00350 int cw = style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &opt, this);
00351 QSize size = QSize(cw * 7 + fm.width(QLatin1Char('0')) * 4, fm.height() + 8);
00352 if (opt.orientation == Qt::Vertical)
00353 size.transpose();
00354 return style()->sizeFromContents(QStyle::CT_ProgressBar, &opt, size, this);
00355 }
00356
00360 QSize QProgressBar::minimumSizeHint() const
00361 {
00362 QSize size;
00363 if (orientation() == Qt::Horizontal)
00364 size = QSize(sizeHint().width(), fontMetrics().height() + 2);
00365 else
00366 size = QSize(fontMetrics().height() + 2, sizeHint().height());
00367 return size;
00368 }
00369
00385 QString QProgressBar::text() const
00386 {
00387 Q_D(const QProgressBar);
00388 if (d->maximum == 0 || d->value < d->minimum
00389 || (d->value == INT_MIN && d->minimum == INT_MIN))
00390 return QString();
00391
00392 int totalSteps = d->maximum - d->minimum;
00393
00394 QString result = d->format;
00395 result.replace(QLatin1String("%m"), QString::fromLatin1("%1").arg(totalSteps));
00396 result.replace(QLatin1String("%v"), QString::fromLatin1("%1").arg(d->value));
00397
00398
00399
00400
00401 if (totalSteps == 0) {
00402 result.replace(QLatin1String("%p"), QString::fromLatin1("%1").arg(100));
00403 return result;
00404 }
00405
00406 int progress = d->value - d->minimum;
00407
00408 if (totalSteps > INT_MAX / 1000) {
00409 progress /= 1000;
00410 totalSteps /= 1000;
00411 }
00412
00413 result.replace(QLatin1String("%p"), QString::fromLatin1("%1").arg((progress * 100) / totalSteps));
00414 return result;
00415 }
00416
00428 void QProgressBar::setOrientation(Qt::Orientation orientation)
00429 {
00430 Q_D(QProgressBar);
00431 if (d->orientation == orientation)
00432 return;
00433 d->orientation = orientation;
00434 if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) {
00435 QSizePolicy sp = sizePolicy();
00436 sp.transpose();
00437 setSizePolicy(sp);
00438 setAttribute(Qt::WA_WState_OwnSizePolicy, false);
00439 }
00440 update();
00441 updateGeometry();
00442 }
00443
00444 Qt::Orientation QProgressBar::orientation() const
00445 {
00446 Q_D(const QProgressBar);
00447 return d->orientation;
00448 }
00449
00462 void QProgressBar::setInvertedAppearance(bool invert)
00463 {
00464 Q_D(QProgressBar);
00465 d->invertedAppearance = invert;
00466 update();
00467 }
00468
00469 bool QProgressBar::invertedAppearance()
00470 {
00471 Q_D(QProgressBar);
00472 return d->invertedAppearance;
00473 }
00474
00485 void QProgressBar::setTextDirection(QProgressBar::Direction textDirection)
00486 {
00487 Q_D(QProgressBar);
00488 d->textDirection = textDirection;
00489 update();
00490 }
00491
00492 QProgressBar::Direction QProgressBar::textDirection()
00493 {
00494 Q_D(QProgressBar);
00495 return d->textDirection;
00496 }
00497
00499 bool QProgressBar::event(QEvent *e)
00500 {
00501 return QWidget::event(e);
00502 }
00503
00517 void QProgressBar::setFormat(const QString &format)
00518 {
00519 Q_D(QProgressBar);
00520 d->format = format;
00521 }
00522
00523 QString QProgressBar::format() const
00524 {
00525 Q_D(const QProgressBar);
00526 return d->format;
00527 }
00528
00529 #endif // QT_NO_PROGRESSBAR