src/qt3support/widgets/q3progressbar.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt3Support module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "q3progressbar.h"
       
    43 #ifndef QT_NO_PROGRESSBAR
       
    44 #include "qpainter.h"
       
    45 #include "qdrawutil.h"
       
    46 #include "qpixmap.h"
       
    47 #include "qstyle.h"
       
    48 #include "qstyleoption.h"
       
    49 #ifndef QT_NO_ACCESSIBILITY
       
    50 #include "qaccessible.h"
       
    51 #endif
       
    52 #include "qevent.h"
       
    53 #include <limits.h>
       
    54 
       
    55 QT_BEGIN_NAMESPACE
       
    56 
       
    57 /*!
       
    58     \class Q3ProgressBar
       
    59     \brief The Q3ProgressBar widget provides a horizontal progress bar.
       
    60 
       
    61     \compat
       
    62 
       
    63     A progress bar is used to give the user an indication of the
       
    64     progress of an operation and to reassure them that the application
       
    65     is still running.
       
    66 
       
    67     The progress bar uses the concept of \e steps; you give it the
       
    68     total number of steps and the number of steps completed so far and
       
    69     it will display the percentage of steps that have been completed.
       
    70     You can specify the total number of steps in the constructor or
       
    71     later with setTotalSteps(). The current number of steps is set
       
    72     with setProgress(). The progress bar can be rewound to the
       
    73     beginning with reset().
       
    74 
       
    75     If the total is given as 0 the progress bar shows a busy indicator
       
    76     instead of a percentage of steps. This is useful, for example,
       
    77     when using QFtp or QHttp to download items when they are unable to
       
    78     determine the size of the item being downloaded.
       
    79 
       
    80     \sa QProgressDialog
       
    81 
       
    82     \inlineimage qprogbar-m.png Screenshot in Motif style
       
    83     \inlineimage qprogbar-w.png Screenshot in Windows style
       
    84 
       
    85     \sa QProgressDialog
       
    86 */
       
    87 
       
    88 
       
    89 /*! \obsolete
       
    90     Constructs a progress bar.
       
    91 
       
    92     The total number of steps is set to 100 by default.
       
    93 
       
    94     The \a parent, \a name and widget flags, \a f, are passed on to
       
    95     the QFrame::QFrame() constructor.
       
    96 
       
    97     \sa setTotalSteps()
       
    98 */
       
    99 
       
   100 Q3ProgressBar::Q3ProgressBar(QWidget *parent, const char *name, Qt::WindowFlags f)
       
   101     : QFrame(parent, f),
       
   102       total_steps(100),
       
   103       progress_val(-1),
       
   104       percentage(-1),
       
   105       center_indicator(true),
       
   106       percentage_visible(true),
       
   107       d(0)
       
   108 {
       
   109     setObjectName(QLatin1String(name));
       
   110     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
       
   111     initFrame();
       
   112 }
       
   113 
       
   114 
       
   115 /*! \obsolete
       
   116     Constructs a progress bar.
       
   117 
       
   118     The \a totalSteps is the total number of steps that need to be
       
   119     completed for the operation which this progress bar represents.
       
   120     For example, if the operation is to examine 50 files, this value
       
   121     would be 50. Before examining the first file, call setProgress(0);
       
   122     call setProgress(50) after examining the last file.
       
   123 
       
   124     The \a parent, \a name and widget flags, \a f, are passed to the
       
   125     QFrame::QFrame() constructor.
       
   126 
       
   127     \sa setTotalSteps(), setProgress()
       
   128 */
       
   129 
       
   130 Q3ProgressBar::Q3ProgressBar(int totalSteps, QWidget *parent, const char *name, Qt::WindowFlags f)
       
   131     : QFrame(parent, f),
       
   132       total_steps(totalSteps),
       
   133       progress_val(-1),
       
   134       percentage(-1),
       
   135       center_indicator(true),
       
   136       percentage_visible(true),
       
   137       d(0)
       
   138 {
       
   139     setObjectName(QLatin1String(name));
       
   140     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
       
   141     initFrame();
       
   142 }
       
   143 #endif
       
   144 
       
   145 /*!
       
   146     Constructs a progress bar.
       
   147 
       
   148     The total number of steps is set to 100 by default.
       
   149 
       
   150     The \a parent, and widget flags, \a f, are passed on to
       
   151     the QFrame::QFrame() constructor.
       
   152 
       
   153     \sa setTotalSteps()
       
   154 */
       
   155 
       
   156 Q3ProgressBar::Q3ProgressBar(QWidget *parent, Qt::WindowFlags f)
       
   157     : QFrame(parent, f),
       
   158       total_steps(100),
       
   159       progress_val(-1),
       
   160       percentage(-1),
       
   161       center_indicator(true),
       
   162       percentage_visible(true),
       
   163       d(0)
       
   164 {
       
   165     setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
       
   166     initFrame();
       
   167 }
       
   168 
       
   169 
       
   170 /*!
       
   171     Constructs a progress bar.
       
   172 
       
   173     The \a totalSteps is the total number of steps that need to be
       
   174     completed for the operation which this progress bar represents.
       
   175     For example, if the operation is to examine 50 files, this value
       
   176     would be 50. Before examining the first file, call setProgress(0);
       
   177     call setProgress(50) after examining the last file.
       
   178 
       
   179     The \a parent, and widget flags, \a f, are passed to the
       
   180     QFrame::QFrame() constructor.
       
   181 
       
   182     \sa setTotalSteps(), setProgress()
       
   183 */
       
   184 
       
   185 Q3ProgressBar::Q3ProgressBar(int totalSteps, QWidget *parent, Qt::WindowFlags f)
       
   186     : QFrame(parent, f),
       
   187       total_steps(totalSteps),
       
   188       progress_val(-1),
       
   189       percentage(-1),
       
   190       center_indicator(true),
       
   191       percentage_visible(true),
       
   192       d(0)
       
   193 {
       
   194     setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
       
   195     initFrame();
       
   196 }
       
   197 
       
   198 
       
   199 /*!
       
   200     Reset the progress bar. The progress bar "rewinds" and shows no
       
   201     progress.
       
   202 */
       
   203 
       
   204 void Q3ProgressBar::reset()
       
   205 {
       
   206     progress_val = -1;
       
   207     percentage = -1;
       
   208     setIndicator(progress_str, progress_val, total_steps);
       
   209     repaint();
       
   210 }
       
   211 
       
   212 
       
   213 /*!
       
   214     \property Q3ProgressBar::totalSteps
       
   215     \brief The total number of steps.
       
   216 
       
   217     If totalSteps is 0, the progress bar will display a busy
       
   218     indicator.
       
   219 */
       
   220 
       
   221 void Q3ProgressBar::setTotalSteps(int totalSteps)
       
   222 {
       
   223     total_steps = totalSteps;
       
   224 
       
   225     // Current progress is invalid if larger than total
       
   226     if (total_steps < progress_val)
       
   227         progress_val = -1;
       
   228 
       
   229     if (isVisible() &&
       
   230          (setIndicator(progress_str, progress_val, total_steps) || !total_steps))
       
   231         repaint();
       
   232 }
       
   233 
       
   234 
       
   235 /*!
       
   236     \property Q3ProgressBar::progress
       
   237     \brief The current amount of progress
       
   238 
       
   239     This property is -1 if progress counting has not started.
       
   240 */
       
   241 
       
   242 void Q3ProgressBar::setProgress(int progress)
       
   243 {
       
   244     if (progress == progress_val ||
       
   245          progress < 0 || ((progress > total_steps) && total_steps))
       
   246         return;
       
   247 
       
   248     int old_progress_val = progress_val;
       
   249     progress_val = progress;
       
   250 
       
   251     if (setIndicator(progress_str, progress_val, total_steps)
       
   252         || ( total_steps == 0 || (width() * progress_val / total_steps != width() * old_progress_val / total_steps )))
       
   253         repaint();
       
   254 
       
   255 #ifndef QT_NO_ACCESSIBILITY
       
   256     QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged);
       
   257 #endif
       
   258 }
       
   259 
       
   260 /*!
       
   261     \overload
       
   262 
       
   263     Sets the amount of progress to \a progress and the total number of
       
   264     steps to \a totalSteps.
       
   265 
       
   266     \sa setTotalSteps()
       
   267 */
       
   268 
       
   269 void Q3ProgressBar::setProgress(int progress, int totalSteps)
       
   270 {
       
   271     if (total_steps != totalSteps)
       
   272         setTotalSteps(totalSteps);
       
   273     setProgress(progress);
       
   274 }
       
   275 
       
   276 /*!
       
   277   \property Q3ProgressBar::progressString
       
   278   \brief the amount of progress as a string
       
   279 
       
   280     This property is an empty string if progress counting has not started.
       
   281 */
       
   282 
       
   283 static QStyleOptionProgressBar getStyleOption(const Q3ProgressBar *pb)
       
   284 {
       
   285     QStyleOptionProgressBar opt;
       
   286     opt.init(pb);
       
   287     opt.rect = pb->contentsRect();
       
   288     opt.minimum = 0;
       
   289     opt.maximum = pb->totalSteps();
       
   290     opt.progress = pb->progress();
       
   291     if (pb->centerIndicator())
       
   292         opt.textAlignment = Qt::AlignCenter;
       
   293     else
       
   294         opt.textAlignment = Qt::AlignAuto;
       
   295     opt.textVisible = pb->percentageVisible();
       
   296     opt.text = pb->progressString();
       
   297     return opt;
       
   298 }
       
   299 
       
   300 /*!
       
   301     \reimp
       
   302 */
       
   303 QSize Q3ProgressBar::sizeHint() const
       
   304 {
       
   305     ensurePolished();
       
   306     QFontMetrics fm = fontMetrics();
       
   307     QStyleOptionProgressBar opt = getStyleOption(this);
       
   308     int cw = style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &opt, this);
       
   309     return style()->sizeFromContents(QStyle::CT_ProgressBar, &opt,
       
   310                                     QSize(cw * 7 + fm.width(QLatin1Char('0')) * 4, fm.height() + 8), this);
       
   311 }
       
   312 
       
   313 /*!
       
   314     \reimp
       
   315 */
       
   316 QSize Q3ProgressBar::minimumSizeHint() const
       
   317 {
       
   318     return sizeHint();
       
   319 }
       
   320 
       
   321 /*!
       
   322     \property Q3ProgressBar::centerIndicator
       
   323     \brief whether the indicator string should be centered
       
   324 */
       
   325 
       
   326 void Q3ProgressBar::setCenterIndicator(bool on)
       
   327 {
       
   328     if (on == center_indicator)
       
   329         return;
       
   330     center_indicator = on;
       
   331     repaint();
       
   332 }
       
   333 
       
   334 /*!
       
   335     \property Q3ProgressBar::percentageVisible
       
   336     \brief whether the current progress value is displayed
       
   337 
       
   338     The default is true.
       
   339 
       
   340     \sa centerIndicator
       
   341 */
       
   342 void Q3ProgressBar::setPercentageVisible(bool on)
       
   343 {
       
   344     if (on == percentage_visible)
       
   345         return;
       
   346     percentage_visible = on;
       
   347     repaint();
       
   348 }
       
   349 
       
   350 /*!
       
   351     \reimp
       
   352 */
       
   353 void Q3ProgressBar::setVisible(bool visible)
       
   354 {
       
   355     if (visible)
       
   356         setIndicator(progress_str, progress_val, total_steps);
       
   357     QFrame::setVisible(visible);
       
   358 }
       
   359 
       
   360 void Q3ProgressBar::initFrame()
       
   361 {
       
   362     setFrameStyle(QFrame::NoFrame);
       
   363 }
       
   364 
       
   365 /*!
       
   366     \reimp
       
   367 */
       
   368 void Q3ProgressBar::changeEvent(QEvent *ev)
       
   369 {
       
   370     if(ev->type() == QEvent::StyleChange)
       
   371         initFrame();
       
   372     QFrame::changeEvent(ev);
       
   373 }
       
   374 
       
   375 
       
   376 /*!
       
   377     This method is called to generate the text displayed in the center
       
   378     (or in some styles, to the left) of the progress bar.
       
   379 
       
   380     The \a progress may be negative, indicating that the progress bar
       
   381     is in the "reset" state before any progress is set.
       
   382 
       
   383     The default implementation is the percentage of completion or
       
   384     blank in the reset state. The percentage is calculated based on
       
   385     the \a progress and \a totalSteps. You can set the \a indicator
       
   386     text if you wish.
       
   387 
       
   388     To allow efficient repainting of the progress bar, this method
       
   389     should return false if the string is unchanged from the last call
       
   390     to this function.
       
   391 */
       
   392 
       
   393 bool Q3ProgressBar::setIndicator(QString & indicator, int progress,
       
   394                                  int totalSteps)
       
   395 {
       
   396     if (!totalSteps)
       
   397         return false;
       
   398     if (progress < 0) {
       
   399         indicator = QString::fromLatin1("");
       
   400         return true;
       
   401     } else {
       
   402         // Get the values down to something usable.
       
   403         if (totalSteps > INT_MAX/1000) {
       
   404             progress /= 1000;
       
   405             totalSteps /= 1000;
       
   406         }
       
   407 
       
   408         int np = progress * 100 / totalSteps;
       
   409         if (np != percentage) {
       
   410             percentage = np;
       
   411             indicator.sprintf("%d%%", np);
       
   412             return true;
       
   413         } else {
       
   414             return false;
       
   415         }
       
   416     }
       
   417 }
       
   418 
       
   419 
       
   420 /*!
       
   421     \reimp
       
   422 */
       
   423 void Q3ProgressBar::paintEvent(QPaintEvent *)
       
   424 {
       
   425     QPainter paint(this);
       
   426     QPainter *p = &paint;
       
   427     drawFrame(p);
       
   428 
       
   429     QStyleOptionProgressBar opt = getStyleOption(this);
       
   430     opt.rect = style()->subElementRect(QStyle::SE_ProgressBarGroove, &opt, this);
       
   431 
       
   432     style()->drawControl(QStyle::CE_ProgressBarGroove, &opt, p, this);
       
   433     opt.rect = contentsRect();
       
   434     opt.rect = style()->subElementRect(QStyle::SE_ProgressBarContents, &opt, this);
       
   435     style()->drawControl(QStyle::CE_ProgressBarContents, &opt, p, this);
       
   436 
       
   437     if (percentageVisible()) {
       
   438         opt.rect = contentsRect();
       
   439         opt.rect = style()->subElementRect(QStyle::SE_ProgressBarLabel, &opt, this);
       
   440         style()->drawControl(QStyle::CE_ProgressBarLabel, &opt, p, this);
       
   441     }
       
   442 }
       
   443 
       
   444 /*!
       
   445     \fn void Q3ProgressBar::setMargin(int margin)
       
   446     \since 4.2
       
   447 
       
   448     Sets the width of the margin around the contents of the widget to \a margin.
       
   449     
       
   450     This function uses QWidget::setContentsMargins() to set the margin.
       
   451     \sa margin(), QWidget::setContentsMargins()
       
   452 */
       
   453 
       
   454 /*!
       
   455     \fn int Q3ProgressBar::margin() const
       
   456     \since 4.2
       
   457 
       
   458     Returns the width of the margin around the contents of the widget.
       
   459     
       
   460     This function uses QWidget::getContentsMargins() to get the margin.
       
   461     \sa setMargin(), QWidget::getContentsMargins()
       
   462 */
       
   463 
       
   464 QT_END_NAMESPACE