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

List:       kde-commits
Subject:    branches/KDE/4.4/kdelibs/kdeui/itemviews
From:       Peter Penz <peter.penz () gmx ! at>
Date:       2010-01-31 12:39:29
Message-ID: 1264941569.733635.32479.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 1082878 by ppenz:

Backport of SVN commit 1082876: Fixed regression introduced during the KDE SC 4.4 \
cycle: Selecting and deselecting items by clicking on the categories did not work \
anymore.

Thanks to Todd for the patch!

CCBUG: 214859
CCMAIL: toddrme2178@gmail.com

 M  +100 -1    kcategorizedview.cpp  
 M  +24 -0     kcategorizedview_p.h  


--- branches/KDE/4.4/kdelibs/kdeui/itemviews/kcategorizedview.cpp #1082877:1082878
@@ -55,6 +55,7 @@
     , hoveredIndex(QModelIndex())
     , pressedPosition(QPoint())
     , rubberBandRect(QRect())
+    , pastSelected(QModelIndexList())
 {
 }
 
@@ -462,6 +463,75 @@
     item.size.setWidth(viewportWidth());
 }
 
+QModelIndex KCategorizedView::Private::drawerIndexAt(const QPoint &point)
+{
+    if (blocks.isEmpty()) {
+        return QModelIndex();
+    }
+
+    for (QHash<QString, Private::Block>::Iterator it = blocks.begin(); it != \
blocks.end(); ++it) { +        Block &block = *it;
+        QModelIndex categoryIndex = block.firstIndex;
+        QStyleOptionViewItemV4 option(q->viewOptions());
+        int height = categoryDrawer->categoryHeight(categoryIndex, \
q->viewOptions()); +        QPoint pos = blockPosition(it.key());
+        pos.ry() -= height;
+        option.rect.setTopLeft(pos);
+        option.rect.setWidth(viewportWidth() + categoryDrawer->leftMargin() + \
categoryDrawer->rightMargin()); +        option.rect.setHeight(height);
+
+        if (option.rect.contains(point)) {
+            return categoryIndex;
+        }
+    }
+
+    return QModelIndex();
+}
+
+void KCategorizedView::Private::listSelect(const QModelIndexList &indexList) const
+{
+    QModelIndexList::ConstIterator it;
+    for (it = indexList.constBegin(); it != indexList.constEnd(); ++it) {
+        const QModelIndex itemIndex = *it;
+        q->selectionModel()->select(itemIndex, QItemSelectionModel::SelectCurrent);
+    }
+}
+
+bool KCategorizedView::Private::rangeSelected(const QModelIndex &firstIndex, const \
int &rowCount) const +{
+    Q_ASSERT(rowCount >= 0);
+
+    if (rowCount == 0) {
+        return q->selectionModel()->isSelected(firstIndex);
+    }
+
+    // If there are no selected items in the view
+    // or if the number of selected items is less
+    // than the length of the list you are checking,
+    // then the items in the list cannot all be
+    // selected
+    if (!q->selectionModel()->hasSelection() || \
(q->selectionModel()->selectedIndexes().count() < rowCount)) { +        return false;
+    }
+
+    // If all of the items in the view are selected,
+    // all of the items in a subset of that view must
+    // also be selected
+    if (q->selectionModel()->selectedIndexes().count() == proxyModel->rowCount()) {
+        return true;
+    }
+
+    for (int row = 0; row != rowCount; ++row) {
+        const QModelIndex itemIndex = firstIndex.sibling(firstIndex.row() + row, \
firstIndex.column()); +        if (!q->selectionModel()->isSelected(itemIndex)) {
+            return false;
+        }
+    }
+
+    return true;
+
+}
+
 void KCategorizedView::Private::_k_slotCollapseOrExpandClicked(QModelIndex)
 {
 }
@@ -883,19 +953,48 @@
 
 void KCategorizedView::mousePressEvent(QMouseEvent *event)
 {
-    QListView::mousePressEvent(event);
     if (event->button() == Qt::LeftButton) {
+        d->pastSelected = selectionModel()->selectedIndexes();
         d->pressedPosition = event->pos();
         d->pressedPosition.rx() += horizontalOffset();
         d->pressedPosition.ry() += verticalOffset();
     }
+    QListView::mousePressEvent(event);
 }
 
 void KCategorizedView::mouseReleaseEvent(QMouseEvent *event)
 {
+    if (d->isCategorized()) {
+        const QRect rect(d->pressedPosition, event->pos() + \
QPoint(horizontalOffset(), verticalOffset())); +        if ((event->button() == \
Qt::LeftButton) && (rect.topLeft() == rect.bottomRight())) { +            const \
QModelIndex index = d->drawerIndexAt(rect.topLeft()); +            if \
(index.isValid()) { +
+                const QString category = d->categoryForIndex(index);
+                const Private::Block &block = d->blocks[category];
+
+                d->listSelect(d->pastSelected);
+
+                QItemSelectionModel::SelectionFlags flags;
+                flags |= d->rangeSelected(block.firstIndex, block.items.count() -1) \
? QItemSelectionModel::Deselect +                                                     \
: QItemSelectionModel::Select; +
+                QItemSelection selection;
+
+                const QModelIndex lastIndex = \
block.firstIndex.sibling(block.firstIndex.row() + block.items.count() - 1, \
block.firstIndex.column()); +
+                selection << QItemSelectionRange(block.firstIndex, lastIndex);
+                selectionModel()->select(selection, flags);
+
+                d->pastSelected.clear();
+                return;
+            }
+        }
+    }
     QListView::mouseReleaseEvent(event);
     d->pressedPosition = QPoint();
     d->rubberBandRect = QRect();
+    d->pastSelected.clear();
 }
 
 void KCategorizedView::leaveEvent(QEvent *event)
--- branches/KDE/4.4/kdelibs/kdeui/itemviews/kcategorizedview_p.h #1082877:1082878
@@ -122,6 +122,29 @@
     void topToBottomVisualRect(const QModelIndex &index, Item &item,
                                const Block &block, const QPoint &blockPos) const;
 
+    /**
+      * If the provided QPoint is in a category drawer (category title),
+      * returns the index of the first item in the category.
+      * Otherwise returns an invalid index.
+      */
+    QModelIndex drawerIndexAt(const QPoint &point);
+
+    /**
+      * Selects all of items provided in the list of indices.
+      * This should not remove the existing selection,
+      * but that has not been well-tested.
+      */
+    void listSelect(const QModelIndexList &indexList) const;
+
+    /**
+      * Determines if all the items are selected in a
+      * linear range defined starting at firstIndex and
+      * continuing for the number of row defined by rowCount.
+      * Since this is part of KCategorizedView, only the
+      * rows are varied.
+      */
+    bool rangeSelected(const QModelIndex &firstIndex, const int &rowCount) const;
+
     void _k_slotCollapseOrExpandClicked(QModelIndex);
 
     KCategorizedView *q;
@@ -136,6 +159,7 @@
 
     QPoint pressedPosition;
     QRect rubberBandRect;
+    QModelIndexList pastSelected;
 
     QHash<QString, Block> blocks;
 };


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

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