[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: [PATCH] BIG usability improvement for Konqy's listviews
From:       Michael Brade <Michael.Brade () informatik ! uni-muenchen ! de>
Date:       2001-07-30 18:44:43
[Download RAW message or body]

Uff, finished! There were quite some bugs left, seems I posted the previous 
patch too early :} I committed the attached patch, it is now perfectly 
working and includes an auto-scroll-timer and quite some speed improvements.

Ciao,
  Michael

-- 

       Some operating systems are called `user friendly',
             Linux however is `expert friendly'.

["diff" (text/x-diff)]

? diff
Index: konq_listviewwidget.cc
===================================================================
RCS file: /home/kde/kdebase/konqueror/listview/konq_listviewwidget.cc,v
retrieving revision 1.160
diff -u -p -r1.160 konq_listviewwidget.cc
--- konq_listviewwidget.cc	2001/07/28 16:04:13	1.160
+++ konq_listviewwidget.cc	2001/07/30 18:40:43
@@ -75,6 +75,8 @@ KonqBaseListViewWidget::KonqBaseListView
 ,m_pBrowserView(parent)
 ,m_dirLister(new KonqDirLister( true /*m_showIcons==FALSE*/))
 ,m_dragOverItem(0)
+,m_scrollTimer(0)
+,m_rubber(0)
 ,m_showIcons(true)
 ,m_bCaseInsensitive(true)
 ,m_bAscending(true)
@@ -308,6 +310,196 @@ void KonqBaseListViewWidget::initConfig(
    setItemColor( m_pSettings->normalTextColor() );
 
    updateListContents();
+}
+
+void KonqBaseListViewWidget::contentsMousePressEvent( QMouseEvent *e )
+{
+   if ( m_rubber )
+   {
+      drawRubber();
+      delete m_rubber;
+      m_rubber = 0;
+   }
+
+   m_selected.clear();
+
+   QPoint vp = contentsToViewport( e->pos() );
+   KonqBaseListViewItem *item = isExecuteArea( vp ) ?
+         (KonqBaseListViewItem*)itemAt( vp ) : 0L;
+
+   if ( item )
+      KListView::contentsMousePressEvent( e );
+   else {
+      if ( e->button() == LeftButton )
+      {
+         m_rubber = new QRect( e->x(), e->y(), 0, 0 );
+         if ( e->state() & ControlButton )
+            selectedItems( m_selected );
+         else
+            setSelected( itemAt( vp ), false );
+      }
+
+      QListView::contentsMousePressEvent( e );
+   }
+}
+
+void KonqBaseListViewWidget::contentsMouseReleaseEvent( QMouseEvent *e )
+{
+   if ( m_rubber )
+   {
+      drawRubber();
+      delete m_rubber;
+      m_rubber = 0;
+   }
+   m_selected.clear();
+
+   KListView::contentsMouseReleaseEvent( e );
+}
+
+void KonqBaseListViewWidget::contentsMouseMoveEvent( QMouseEvent *e )
+{
+   if ( m_rubber )
+      slotAutoScroll();
+   else
+      KListView::contentsMouseMoveEvent( e );
+}
+
+void KonqBaseListViewWidget::drawRubber()
+{
+   if ( !m_rubber )
+      return;
+
+   QPainter p;
+   p.begin( viewport() );
+   p.setRasterOp( NotROP );
+   p.setPen( QPen( color0, 1 ) );
+   p.setBrush( NoBrush );
+
+   QPoint pt( m_rubber->x(), m_rubber->y() );
+   pt = contentsToViewport( pt );
+   style().drawFocusRect( &p, QRect( pt.x(), pt.y(), m_rubber->width(), m_rubber->height() ),
+                          colorGroup(), &colorGroup().base() );
+   p.end();
+}
+
+void KonqBaseListViewWidget::slotAutoScroll()
+{
+   if ( !m_rubber )
+      return;
+
+   // this code assumes that all items have the same height
+   drawRubber();
+
+   QPoint pos = viewport()->mapFromGlobal( QCursor::pos() );
+   QPoint vc = viewportToContents( pos );
+   ensureVisible( vc.x(), vc.y() );
+
+   int oldTop = m_rubber->normalize().top();
+   int oldBottom = m_rubber->normalize().bottom();
+
+   m_rubber->setRight( vc.x() );
+   m_rubber->setBottom( vc.y() );
+
+   QRect* oldRubber = m_rubber;
+   m_rubber = 0;
+
+   QListViewItem *cur = itemAt( QPoint(0,0) );
+
+   bool block = signalsBlocked();
+   blockSignals( true );
+
+   if ( cur )
+   {
+      QRect rect = itemRect( cur );
+      rect = QRect( viewportToContents( rect.topLeft() ),
+                    viewportToContents( rect.bottomRight() ) );
+
+      int offset = 0;
+      if ( !allColumnsShowFocus() )
+      {
+         int hpos = header()->mapToIndex( 0 );
+         for ( int index = 0; index < hpos; index++ )
+            offset += columnWidth( header()->mapToSection( index ) );
+
+         rect.setLeft( offset );
+         rect.setRight( offset + columnWidth( 0 ) );
+      }
+      else
+      {
+         for ( int index = 0; index < columns(); index++ )
+            offset += columnWidth( header()->mapToSection( index ) );
+
+         rect.setLeft( 0 );
+         rect.setRight( offset );
+      }
+
+      QRect r = rect;
+      QListViewItem *tmp = cur;
+
+      while ( cur && rect.top() <= oldBottom )
+      {
+         if ( rect.intersects( oldRubber->normalize() ) )
+         {
+            if ( !cur->isSelected() && cur->isSelectable() )
+               setSelected( cur, true );
+         } else if ( !m_selected.contains( (KonqBaseListViewItem*)cur ) )
+            setSelected( cur, false );
+
+         cur = cur->itemBelow();
+         rect.moveBy( 0, rect.height() );
+      }
+
+      rect = r;
+      rect.moveBy( 0, -rect.height() );
+      cur = tmp->itemAbove();
+
+      while ( cur && rect.bottom() >= oldTop )
+      {
+         if ( rect.intersects( oldRubber->normalize() ) )
+         {
+            if ( !cur->isSelected() && cur->isSelectable() )
+               setSelected( cur, true );
+         } else if ( !m_selected.contains( (KonqBaseListViewItem*)cur ) )
+            setSelected( cur, false );
+
+         cur = cur->itemAbove();
+         rect.moveBy( 0, -rect.height() );
+      }
+   }
+
+   blockSignals( block );
+   emit selectionChanged();
+
+   m_rubber = oldRubber;
+   drawRubber();
+
+   pos = viewport()->mapFromGlobal( QCursor::pos() );
+   vc = viewportToContents( pos );
+   if ( !QRect( 0, 0, viewport()->width(), viewport()->height() ).contains( vc ) &&
+        !m_scrollTimer )
+   {
+      m_scrollTimer = new QTimer( this );
+
+      connect( m_scrollTimer, SIGNAL( timeout() ),
+               this, SLOT( slotAutoScroll() ) );
+      m_scrollTimer->start( 100, false );
+   }
+   else if ( QRect( 0, 0, viewport()->width(), viewport()->height() ).contains( vc ) &&
+             m_scrollTimer )
+   {
+      disconnect( m_scrollTimer, SIGNAL( timeout() ),
+                  this, SLOT( slotAutoScroll() ) );
+      m_scrollTimer->stop();
+      delete m_scrollTimer;
+      m_scrollTimer = 0;
+   }
+}
+
+void KonqBaseListViewWidget::viewportPaintEvent( QPaintEvent *e )
+{
+   drawRubber();
+   KListView::viewportPaintEvent( e );
+   drawRubber();
 }
 
 void KonqBaseListViewWidget::viewportResizeEvent(QResizeEvent * e)
Index: konq_listviewwidget.h
===================================================================
RCS file: /home/kde/kdebase/konqueror/listview/konq_listviewwidget.h,v
retrieving revision 1.64
diff -u -p -r1.64 konq_listviewwidget.h
--- konq_listviewwidget.h	2001/07/28 16:04:13	1.64
+++ konq_listviewwidget.h	2001/07/30 18:40:43
@@ -21,9 +21,9 @@
 
 #include <qcursor.h>
 #include <qpixmap.h>
-#include <qintdict.h>
 #include <qtimer.h>
 #include <qevent.h>
+#include <qvaluelist.h>
 
 #include <kurl.h>
 #include <konq_fileitem.h>
@@ -34,6 +34,7 @@
 
 namespace KIO { class Job; }
 class QCursor;
+class QRect;
 class KonqDirLister;
 class KonqFMSettings;
 class ListViewPropertiesExtension;
@@ -144,6 +145,8 @@ class KonqBaseListViewWidget : public KL
       void slotItemRenamed(QListViewItem*, const QString &, int);
 
    protected slots:
+      void slotAutoScroll();
+
       // from QListView
       virtual void slotReturnPressed( QListViewItem *_item );
       virtual void slotRightButtonPressed( QListViewItem *_item, const QPoint &_global, int _column );
@@ -186,7 +189,13 @@ class KonqBaseListViewWidget : public KL
       virtual void viewportDragEnterEvent( QDragEnterEvent *_ev );
       virtual void viewportDragLeaveEvent( QDragLeaveEvent *_ev );
       virtual void viewportDropEvent( QDropEvent *_ev );
-      virtual void viewportResizeEvent(QResizeEvent * e);
+      virtual void viewportPaintEvent( QPaintEvent *e );
+      virtual void viewportResizeEvent( QResizeEvent *e );
+
+      virtual void drawRubber();
+      virtual void contentsMousePressEvent( QMouseEvent *e );
+      virtual void contentsMouseReleaseEvent( QMouseEvent *e );
+      virtual void contentsMouseMoveEvent( QMouseEvent *e );
 
       /** Common method for slotCompleted and slotCanceled */
       virtual void setComplete();
@@ -212,10 +221,14 @@ class KonqBaseListViewWidget : public KL
 
       KonqBaseListViewItem* m_dragOverItem;
     //QStringList m_lstDropFormats;
+      QValueList<KonqBaseListViewItem*> m_selected;
+      QTimer *m_scrollTimer;
 
       QFont m_itemFont;
       QColor m_itemColor;
 
+      QRect *m_rubber;
+
       bool m_bTopLevelComplete:1;
       bool m_showIcons:1;
       bool m_bCaseInsensitive:1;
@@ -231,7 +244,6 @@ class KonqBaseListViewWidget : public KL
       KURL m_url;
 
       QString m_itemToGoTo;
-
 };
 
 #endif


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic