Branch: master

9f882f9d 2014-09-15 20:41:12 Frerich Raabe
Add repaint optimization to TQProgressBar

This optimization makes TQProgressBar::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.
M src/widgets/qprogressbar.cpp
M src/widgets/qprogressbar.h
diff --git a/src/widgets/qprogressbar.cpp b/src/widgets/qprogressbar.cpp
index 99dedb0..1219419 100644
--- a/src/widgets/qprogressbar.cpp
+++ b/src/widgets/qprogressbar.cpp
@@ -51,6 +51,14 @@
 #endif
 #include <limits.h>
 
+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.
@@ -103,7 +111,7 @@
       center_indicator( TRUE ),
       auto_indicator( TRUE ),
       percentage_visible( TRUE ),
-      d( 0 ),
+      d( new QProgressBarPrivate ),
       m_orientation( Horizontal )
 {
     setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
@@ -135,11 +143,21 @@
       center_indicator( TRUE ),
       auto_indicator( TRUE ),
       percentage_visible( TRUE ),
-      d( 0 ),
+      d( new QProgressBarPrivate ),
       m_orientation( Horizontal )
 {
     setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
     initFrame();
+}
+
+
+/*!
+    Destroys the object and frees any allocated ressources.
+*/
+ 
+QProgressBar::~QProgressBar()
+{
+    delete d;
 }
 
 
@@ -194,11 +212,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 );
@@ -330,6 +353,32 @@
     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;
+}
+
 Qt::Orientation QProgressBar::orientation() const
 {
     return m_orientation;
diff --git a/src/widgets/qprogressbar.h b/src/widgets/qprogressbar.h
index ac69914..3ba2388 100644
--- a/src/widgets/qprogressbar.h
+++ b/src/widgets/qprogressbar.h
@@ -65,6 +65,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;
@@ -95,6 +96,7 @@
     virtual bool setIndicator( QString & progress_str, int progress,
 			       int totalSteps );
     void styleChange( QStyle& );
+    bool	requireRepaint( int newProgress ) const;
 
 private:
     int		total_steps;
36ee984c 2014-09-15 20:41:24 Benoit Walter
Remove unnecessary scrollbar in TQIconView

Test case (using konqueror icon view):
- The first icons are being shown (no scrollbar yet)
- When there is no space left, a vertical scrollbar is needed
- The vertical scrollbar may cover the right edge of the icons
(in the last column) => an horizontal scrollbar is needed :-(

Solution:
When using ScrollBarMode::Auto, prevent TQt from drawing icons on the
scrollbar area (before the scrollbar is shown).

Related to KDE bug #69589
M src/iconview/qiconview.cpp
M src/iconview/qiconview.h
diff --git a/src/iconview/qiconview.cpp b/src/iconview/qiconview.cpp
index a92ed46..f7b4439 100644
--- a/src/iconview/qiconview.cpp
+++ b/src/iconview/qiconview.cpp
@@ -1107,7 +1107,7 @@
 
     if ( view ) {
 	if ( QRect( view->contentsX(), view->contentsY(),
-		    view->visibleWidth(), view->visibleHeight() ).
+		    view->visibleWidthSB(), view->visibleHeightSB() ).
 	     intersects( oR ) )
 	    view->repaintContents( oR.x() - 1, oR.y() - 1,
 				   oR.width() + 2, oR.height() + 2, FALSE );
@@ -1159,7 +1159,7 @@
 
     if ( view ) {
 	if ( QRect( view->contentsX(), view->contentsY(),
-		    view->visibleWidth(), view->visibleHeight() ).
+		    view->visibleWidthSB(), view->visibleHeightSB() ).
 	     intersects( oR ) )
 	    view->repaintContents( oR.x() - 1, oR.y() - 1,
 				   oR.width() + 2, oR.height() + 2, FALSE );
@@ -1195,7 +1195,7 @@
 
     if ( view ) {
 	if ( QRect( view->contentsX(), view->contentsY(),
-		    view->visibleWidth(), view->visibleHeight() ).
+		    view->visibleWidthSB(), view->visibleHeightSB() ).
 	     intersects( oR ) )
 	    view->repaintContents( oR.x() - 1, oR.y() - 1,
 				   oR.width() + 2, oR.height() + 2, FALSE );
@@ -1263,7 +1263,7 @@
 
 	    if ( view ) {
 		if ( QRect( view->contentsX(), view->contentsY(),
-			    view->visibleWidth(), view->visibleHeight() ).
+			    view->visibleWidthSB(), view->visibleHeightSB() ).
 		     intersects( oR ) )
 		    view->repaintContents( oR.x() - 1, oR.y() - 1,
 					   oR.width() + 2, oR.height() + 2, FALSE );
@@ -5638,8 +5638,8 @@
 	}
 	item->dirty = FALSE;
     } else {
-	QRegion r( QRect( 0, 0, QMAX( contentsWidth(), visibleWidth() ),
-			  QMAX( contentsHeight(), visibleHeight() ) ) );
+	QRegion r( QRect( 0, 0, QMAX( contentsWidth(), visibleWidthSB() ),
+			  QMAX( contentsHeight(), visibleHeightSB() ) ) );
 
 	QIconViewItem *i = d->firstItem;
 	int y = -1;
@@ -5902,7 +5902,7 @@
 	    QIconViewItem *item = begin;
 	    for (;;) {
 		x += d->spacing + item->width();
-		if ( x > visibleWidth() && item != begin ) {
+		if ( x > visibleWidthSB() && item != begin ) {
 		    item = item->prev;
 		    while (item && (item->isVisible() == FALSE)) {
 			item = item->prev;
@@ -5933,7 +5933,7 @@
 		int x;
 		if ( item == begin ) {
 		    if ( reverse )
-			x = visibleWidth() - d->spacing - item->width();
+			x = visibleWidthSB() - d->spacing - item->width();
 		    else
 			x = d->spacing;
 		} else {
@@ -5969,7 +5969,7 @@
 		    i += r;
 		    x = i * d->rastX + sp * d->spacing;
 		}
-		if ( x > visibleWidth() && item != begin ) {
+		if ( x > visibleWidthSB() && item != begin ) {
 		    item = item->prev;
 		    while (item && (item->isVisible() == FALSE)) {
 			item = item->prev;
@@ -6041,7 +6041,7 @@
 	    QIconViewItem *item = begin;
 	    for (;;) {
 		y += d->spacing + item->height();
-		if ( y > visibleHeight() && item != begin ) {
+		if ( y > visibleHeightSB() && item != begin ) {
 		    item = item->prev;
 		    while (item && (item->isVisible() == FALSE)) {
 			item = item->prev;
@@ -6605,4 +6605,24 @@
 #endif
 }
 
+int QIconView::visibleWidthSB() const
+{
+    if ( vScrollBarMode() != Auto )
+        return visibleWidth();
+
+    int offset = verticalScrollBar()->isVisible() ? 0
+        : style().pixelMetric( QStyle::PM_ScrollBarExtent, verticalScrollBar() );
+    return QMAX( 0, visibleWidth() - offset );
+}
+
+int QIconView::visibleHeightSB() const
+{
+    if ( hScrollBarMode() != Auto )
+        return visibleHeight();
+
+    int offset = horizontalScrollBar()->isVisible() ? 0
+        : style().pixelMetric( QStyle::PM_ScrollBarExtent, horizontalScrollBar() );
+    return QMAX( 0, visibleHeight() - offset );
+}
+
 #endif // QT_NO_ICONVIEW
diff --git a/src/iconview/qiconview.h b/src/iconview/qiconview.h
index 109779f..4504690 100644
--- a/src/iconview/qiconview.h
+++ b/src/iconview/qiconview.h
@@ -504,6 +504,8 @@
 			const QPoint &relativeTo,
 			const QIconViewItem *item ) const;
     QBitmap mask( QPixmap *pix ) const;
+    int visibleWidthSB() const;
+    int visibleHeightSB() const;
 
     QIconViewPrivate *d;
 
14f96e80 2014-09-15 20:41:24 Waldo Bastian
Fix zoom in TQTextEdit

TQTextEdit::zoomIn / TQTextEdit::zoomOut does not work if the original
font had its size specified in pixels instead of points.
pointSize() returns 0 in such case.
M src/widgets/qtextedit.cpp
diff --git a/src/widgets/qtextedit.cpp b/src/widgets/qtextedit.cpp
index 2171e75..f2a4a91 100644
--- a/src/widgets/qtextedit.cpp
 ** Diff limit reached (max: 250 lines) **
fdc4699b 2014-09-15 20:41:24 François Andriot
Enhance warning verbosity in TQFile (unix)
M src/tools/qfile_unix.cpp
 ** Diff limit reached (max: 250 lines) **
a9448305 2014-09-15 20:41:25 François Andriot
Fix crash in TQTranslator
M src/kernel/qtranslator.cpp
 ** Diff limit reached (max: 250 lines) **
e4b05c8f 2014-09-15 20:41:25 François Andriot
Fix dpi detection when using xft2
M src/kernel/qfontdatabase_x11.cpp
 ** Diff limit reached (max: 250 lines) **
fbc4cf8e 2014-09-15 20:41:25 Enrico Ros
Fix unwanted toggling TQIconViewItem focus on click

This fixes the 'flashing' icon when clicking repeatedly on a TQIconView or
derivates (ie TDEIconView, KonqIconViewWidget, the KDesktop and so on..).
The current behavior considers that if not over an icon, the user is
clicking down to perform icons selection (with the rubberband).
This is not always true, since a click might be used to give focus to a
window or unselect some icons.

How this is fixed: when clicking down the mouse a flag is set. If the pointer
is moved on the iconview with the button held down, then (and only at that
moment) the rubber is created. Now a selection operation (the one done with
the rubber) begins when moving the mouse and not only when clicking on the
empty space.
M src/iconview/qiconview.cpp
 ** Diff limit reached (max: 250 lines) **