qt-bugs@ issue: 40356 applied: no author: Frerich Raabe This optimization makes QProgressBar::setProgress() only repaint itself if stepping to the new progress would cause a graphical change. This means that for a width W and a total number of steps S, it will repaint itself 'W' times (every 'S/W' steps) instead of 'S' times (every step) as it is right now. --- work/qt-x11-free-3.3.8/src/widgets/qprogressbar.h.orig 2004-01-30 11:10:24.000000000 +0000 +++ work/qt-x11-free-3.3.8/src/widgets/qprogressbar.h 2004-01-29 22:24:06.000000000 +0000 @@ -61,6 +61,7 @@ public: QProgressBar( QWidget* parent=0, const char* name=0, WFlags f=0 ); QProgressBar( int totalSteps, QWidget* parent=0, const char* name=0, WFlags f=0 ); + virtual ~QProgressBar(); int totalSteps() const; int progress() const; @@ -91,6 +92,7 @@ virtual bool setIndicator( QString & progress_str, int progress, int totalSteps ); void styleChange( QStyle& ); + bool requireRepaint( int newProgress ) const; private: int total_steps; --- work/qt-x11-free-3.3.8/src/widgets/qprogressbar.cpp.orig 2004-01-30 11:10:24.000000000 +0000 +++ work/qt-x11-free-3.3.8/src/widgets/qprogressbar.cpp 2004-01-30 11:13:03.000000000 +0000 @@ -47,6 +47,14 @@ #endif #include +class QProgressBarPrivate +{ + public: + QProgressBarPrivate() : last_painted_progress( 0 ) { } + + int last_painted_progress; +}; + /*! \class QProgressBar qprogressbar.h \brief The QProgressBar widget provides a horizontal progress bar. @@ -99,7 +107,7 @@ center_indicator( TRUE ), auto_indicator( TRUE ), percentage_visible( TRUE ), - d( 0 ) + d( new QProgressBarPrivate ) { setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); initFrame(); @@ -130,12 +138,20 @@ center_indicator( TRUE ), auto_indicator( TRUE ), percentage_visible( TRUE ), - d( 0 ) + d( new QProgressBarPrivate ) { setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); initFrame(); } +/*! + Destroys the object and frees any allocated ressources. +*/ + +QProgressBar::~QProgressBar() +{ + delete d; +} /*! Reset the progress bar. The progress bar "rewinds" and shows no @@ -188,11 +204,16 @@ progress < 0 || ( ( progress > total_steps ) && total_steps ) ) return; + const bool needRepaint = isVisible() && requireRepaint( progress ); + progress_val = progress; setIndicator( progress_str, progress_val, total_steps ); - repaint( FALSE ); + if ( needRepaint ) { + repaint( FALSE ); + d->last_painted_progress = progress; + } #if defined(QT_ACCESSIBILITY_SUPPORT) QAccessible::updateAccessibility( this, 0, QAccessible::ValueChanged ); @@ -318,6 +339,31 @@ QFrame::styleChange( old ); } +/*! + This method returns whether changing the progress to the \a newValue + would require a repaint of the progress bar. This allows efficient + repainting. +*/ +bool QProgressBar::requireRepaint( int newProgress ) const +{ + if ( newProgress == progress_val || + newProgress == d->last_painted_progress ) { + return false; + } + + const int width = contentsRect().width(); + if ( width == 0 ) { + return false; + } + + float progressPerPixel = 1.0; + if ( total_steps > width ) { + progressPerPixel = float( total_steps ) / float( width ); + } + + const int delta = d->last_painted_progress - newProgress; + return QABS( delta ) >= progressPerPixel; +} /*! This method is called to generate the text displayed in the center