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

List:       kde-core-devel
Subject:    [PATCH] Fixing KWidgetItemDelegate::focusedIndex()
From:       Aurélien_Gâteau <aurelien.gateau () free ! fr>
Date:       2008-10-16 21:24:12
Message-ID: 48F7B0FC.40504 () free ! fr
[Download RAW message or body]

Hello,

I just experienced problems with KWidgetItemDelegate::focusedIndex(), it
do not always return the correct value. I have a list looking like this:

Item1 [-]
Item2 [-]

The [-] is a button to remove the item. When I click on the [-] button
of Item1, it is removed. My mouse button is now over the [-] button
of Item2. If I click, focusedIndex() returns an invalid index.

Investigating in the code I found out that KWidgetItemDelegate tracks 
the index under the mouse using event filters installed on the
list and on the child widgets. These event filters look for mouse
events and update KWidgetItemDelegatePrivate::focusedIndex.
This does not work in my case, because I didn't move the mouse, so I
didn't trigger any mouse event.

Attached patches use an alternative approach: instead of tracking
the focused index, I just let KWidgetItemDelegate::focusedIndex() figure 
out which one is focused when it's called. It's much simpler and seems 
to work well. Is it ok for you?

Aurélien

["0001-Fix-KWidgetItemDelegate-focusedIndex.diff" (text/x-diff)]

From ad01c6dd5b087a85eaed869982d26195b7a4e1d8 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Aurélien Gâteau?= <aurelien@trinity.(none)>
Date: Thu, 16 Oct 2008 19:06:30 +0200
Subject: [PATCH] Fix KWidgetItemDelegate::focusedIndex()
 Rather than keeping an index up-to-date, find out which index is focused
 whenever the class user ask about it.

---
 kdeui/itemviews/kwidgetitemdelegate.cpp     |    7 ++-----
 kdeui/itemviews/kwidgetitemdelegate_p.h     |    1 -
 kdeui/itemviews/kwidgetitemdelegatepool.cpp |   15 ---------------
 3 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/kdeui/itemviews/kwidgetitemdelegate.cpp \
b/kdeui/itemviews/kwidgetitemdelegate.cpp index f5db2f5..200c10b 100644
--- a/kdeui/itemviews/kwidgetitemdelegate.cpp
+++ b/kdeui/itemviews/kwidgetitemdelegate.cpp
@@ -55,7 +55,6 @@ KWidgetItemDelegatePrivate::KWidgetItemDelegatePrivate(KWidgetItemDelegate \
*q, Q  , itemView(0)
     , widgetPool(new KWidgetItemDelegatePool(q))
     , model(0)
-    , focusedIndex(QPersistentModelIndex())
     , q(q)
 {
 }
@@ -183,7 +182,8 @@ QAbstractItemView *KWidgetItemDelegate::itemView() const

 QPersistentModelIndex KWidgetItemDelegate::focusedIndex() const
 {
-    return d->focusedIndex;
+    const QPoint pos = d->itemView->viewport()->mapFromGlobal(QCursor::pos());
+    return d->itemView->indexAt(pos);
 }

 void KWidgetItemDelegate::paintWidgets(QPainter *painter, const QStyleOptionViewItem \
&option, @@ -227,12 +227,9 @@ bool KWidgetItemDelegatePrivate::eventFilter(QObject \
*watched, QEvent *event)  itemView->viewport()->update();
             break;
         case QEvent::Leave:
-            focusedIndex = QModelIndex();
             itemView->viewport()->update();
             break;
         case QEvent::MouseMove: {
-                QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
-                focusedIndex = itemView->indexAt(mouseEvent->pos());
                 itemView->viewport()->update(); // TODO: more granular update
             }
             break;
diff --git a/kdeui/itemviews/kwidgetitemdelegate_p.h \
b/kdeui/itemviews/kwidgetitemdelegate_p.h index 154f03d..da4e041 100644
--- a/kdeui/itemviews/kwidgetitemdelegate_p.h
+++ b/kdeui/itemviews/kwidgetitemdelegate_p.h
@@ -59,7 +59,6 @@ public:
     QAbstractItemView *itemView;
     KWidgetItemDelegatePool *widgetPool;
     QAbstractItemModel *model;
-    QPersistentModelIndex focusedIndex;

     KWidgetItemDelegate *q;
 };
diff --git a/kdeui/itemviews/kwidgetitemdelegatepool.cpp \
b/kdeui/itemviews/kwidgetitemdelegatepool.cpp index 3499475..7f59997 100644
--- a/kdeui/itemviews/kwidgetitemdelegatepool.cpp
+++ b/kdeui/itemviews/kwidgetitemdelegatepool.cpp
@@ -159,21 +159,6 @@ bool EventListener::eventFilter(QObject *watched, QEvent *event)
 {
     QWidget *widget = static_cast<QWidget*>(watched);
     switch (event->type()) {
-        case QEvent::Enter:
-        case QEvent::FocusIn:
-        case QEvent::MouseMove: {
-                const QAbstractProxyModel *proxyModel = qobject_cast<const \
                QAbstractProxyModel*>(poolPrivate->delegate->d->model);
-                const QModelIndex idx = poolPrivate->widgetInIndex[widget];
-                if (idx.isValid()) {
-                    QModelIndex index;
-                    if (proxyModel) {
-                        index = proxyModel->mapFromSource(idx);
-                    } else {
-                        index = idx;
-                    }
-                    poolPrivate->delegate->d->focusedIndex = index;
-                }
-            } // fall through
         default:
             if (dynamic_cast<QInputEvent*>(event) && \
                !poolPrivate->delegate->blockedEventTypes(widget).contains(event->type())) \
                {
                 QWidget *viewport = poolPrivate->delegate->d->itemView->viewport();
--
1.5.4.4


["0002-This-switch-is-no-longer-useful.diff" (text/x-diff)]

From ea37f4dea278bc2fbcf4ccf3600b7cd15a401e94 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Aurélien Gâteau?= <aurelien@trinity.(none)>
Date: Thu, 16 Oct 2008 19:10:15 +0200
Subject: [PATCH] This switch() is no longer useful.

---
 kdeui/itemviews/kwidgetitemdelegatepool.cpp |   80 +++++++++++++--------------
 1 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/kdeui/itemviews/kwidgetitemdelegatepool.cpp \
b/kdeui/itemviews/kwidgetitemdelegatepool.cpp index 7f59997..e235119 100644
--- a/kdeui/itemviews/kwidgetitemdelegatepool.cpp
+++ b/kdeui/itemviews/kwidgetitemdelegatepool.cpp
@@ -158,49 +158,45 @@ void KWidgetItemDelegatePool::fullClear()
 bool EventListener::eventFilter(QObject *watched, QEvent *event)
 {
     QWidget *widget = static_cast<QWidget*>(watched);
-    switch (event->type()) {
-        default:
-            if (dynamic_cast<QInputEvent*>(event) && \
                !poolPrivate->delegate->blockedEventTypes(widget).contains(event->type())) \
                {
-                QWidget *viewport = poolPrivate->delegate->d->itemView->viewport();
-                switch(event->type()) {
-                    case QEvent::MouseMove:
-                    case QEvent::MouseButtonPress:
-                    case QEvent::MouseButtonRelease:
-                    case QEvent::MouseButtonDblClick: {
-                            QMouseEvent *mouseEvent = \
                static_cast<QMouseEvent*>(event);
-                            QMouseEvent evt(event->type(), \
                viewport->mapFromGlobal(mouseEvent->globalPos()),
-                                            mouseEvent->button(), \
                mouseEvent->buttons(), mouseEvent->modifiers());
-                            QApplication::sendEvent(viewport, &evt);
-                        }
-                        break;
-                    case QEvent::Wheel: {
-                            QWheelEvent *wheelEvent = \
                static_cast<QWheelEvent*>(event);
-                            QWheelEvent \
                evt(viewport->mapFromGlobal(wheelEvent->globalPos()),
-                                            wheelEvent->delta(), \
                wheelEvent->buttons(), wheelEvent->modifiers(),
-                                            wheelEvent->orientation());
-                            QApplication::sendEvent(viewport, &evt);
-                        }
-                        break;
-                    case QEvent::TabletMove:
-                    case QEvent::TabletPress:
-                    case QEvent::TabletRelease:
-                    case QEvent::TabletEnterProximity:
-                    case QEvent::TabletLeaveProximity: {
-                            QTabletEvent *tabletEvent = \
                static_cast<QTabletEvent*>(event);
-                            QTabletEvent evt(event->type(), \
                viewport->mapFromGlobal(tabletEvent->globalPos()),
-                                             tabletEvent->globalPos(), \
                tabletEvent->hiResGlobalPos(), tabletEvent->device(),
-                                             tabletEvent->pointerType(), \
                tabletEvent->pressure(), tabletEvent->xTilt(),
-                                             tabletEvent->yTilt(), \
                tabletEvent->tangentialPressure(), tabletEvent->rotation(),
-                                             tabletEvent->z(), \
                tabletEvent->modifiers(), tabletEvent->uniqueId());
-                            QApplication::sendEvent(viewport, &evt);
-                        }
-                        break;
-                    default:
-                        QApplication::sendEvent(viewport, event);
-                        break;
+    if (dynamic_cast<QInputEvent*>(event) && \
!poolPrivate->delegate->blockedEventTypes(widget).contains(event->type())) { +        \
QWidget *viewport = poolPrivate->delegate->d->itemView->viewport(); +        \
switch(event->type()) { +            case QEvent::MouseMove:
+            case QEvent::MouseButtonPress:
+            case QEvent::MouseButtonRelease:
+            case QEvent::MouseButtonDblClick: {
+                    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
+                    QMouseEvent evt(event->type(), \
viewport->mapFromGlobal(mouseEvent->globalPos()), +                                   \
mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers()); +              \
QApplication::sendEvent(viewport, &evt);  }
-            }
-            break;
+                break;
+            case QEvent::Wheel: {
+                    QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
+                    QWheelEvent \
evt(viewport->mapFromGlobal(wheelEvent->globalPos()), +                               \
wheelEvent->delta(), wheelEvent->buttons(), wheelEvent->modifiers(), +                \
wheelEvent->orientation()); +                    QApplication::sendEvent(viewport, \
&evt); +                }
+                break;
+            case QEvent::TabletMove:
+            case QEvent::TabletPress:
+            case QEvent::TabletRelease:
+            case QEvent::TabletEnterProximity:
+            case QEvent::TabletLeaveProximity: {
+                    QTabletEvent *tabletEvent = static_cast<QTabletEvent*>(event);
+                    QTabletEvent evt(event->type(), \
viewport->mapFromGlobal(tabletEvent->globalPos()), +                                  \
tabletEvent->globalPos(), tabletEvent->hiResGlobalPos(), tabletEvent->device(), +     \
tabletEvent->pointerType(), tabletEvent->pressure(), tabletEvent->xTilt(), +          \
tabletEvent->yTilt(), tabletEvent->tangentialPressure(), tabletEvent->rotation(), +   \
tabletEvent->z(), tabletEvent->modifiers(), tabletEvent->uniqueId()); +               \
QApplication::sendEvent(viewport, &evt); +                }
+                break;
+            default:
+                QApplication::sendEvent(viewport, event);
+                break;
+        }
     }

     return QObject::eventFilter(watched, event);
--
1.5.4.4



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

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