src/gui/widgets/qprogressbar.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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     // Check if the text needs to be repainted
00102     if ((value == minimum || value == maximum)
00103             || (textVisible && valueDifference >= qAbs((maximum - minimum) / 100)))
00104         return true;
00105 
00106     // Check if the bar needs to be repainted
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     // This expression is basically
00111     // (valueDifference / (maximum - minimum) > cw / groove.width())
00112     // transformed to avoid integer division.
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     // If max and min are equal and we get this far, it means that the
00399     // progress bar has one step and that we are on that step. Return
00400     // 100% here in order to avoid division by zero further down.
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     // Get the values down to something usable.
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

Generated on Thu Mar 15 11:57:04 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1