]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kcategorizedview.cpp
Keep consistent all views. Peter, if you decide to revert the change that David did...
[dolphin.git] / src / kcategorizedview.cpp
index 152573214d32a1f0c129315218886ae4b21433ef..dae4f912162a3c42db89d1045c67d853c10ed228 100644 (file)
 // Qt 4.4, so that this workaround can be skipped.
 #define DOLPHIN_DRAGANDDROP
 
-// By defining KDE_WORKAROUND_FOR_QT_VIEW_BUG we save the selection being held
-// before mousePressEvent happens. On Qt there is something clearing the last
-// selection made, what make it impossible to save our very last selection.
-#define KDE_WORKAROUND_FOR_QT_VIEW_BUG
-
 KCategorizedView::Private::Private(KCategorizedView *listView)
     : listView(listView)
     , categoryDrawer(0)
     , biggestItemSize(QSize(0, 0))
     , mouseButtonPressed(false)
+    , rightMouseButtonPressed(false)
     , isDragging(false)
     , dragLeftViewport(false)
     , proxyModel(0)
@@ -504,7 +500,6 @@ void KCategorizedView::setGridSize(const QSize &size)
 void KCategorizedView::setModel(QAbstractItemModel *model)
 {
     d->lastSelection = QItemSelection();
-    d->currentViewIndex = QModelIndex();
     d->forcedSelectionPosition = 0;
     d->elementsInfo.clear();
     d->elementsPosition.clear();
@@ -515,6 +510,7 @@ void KCategorizedView::setModel(QAbstractItemModel *model)
     d->modelIndexList.clear();
     d->hovered = QModelIndex();
     d->mouseButtonPressed = false;
+    d->rightMouseButtonPressed = false;
 
     if (d->proxyModel)
     {
@@ -590,7 +586,6 @@ KCategoryDrawer *KCategorizedView::categoryDrawer() const
 void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer)
 {
     d->lastSelection = QItemSelection();
-    d->currentViewIndex = QModelIndex();
     d->forcedSelectionPosition = 0;
     d->elementsInfo.clear();
     d->elementsPosition.clear();
@@ -601,6 +596,7 @@ void KCategorizedView::setCategoryDrawer(KCategoryDrawer *categoryDrawer)
     d->modelIndexList.clear();
     d->hovered = QModelIndex();
     d->mouseButtonPressed = false;
+    d->rightMouseButtonPressed = false;
 
     if (!categoryDrawer && d->proxyModel)
     {
@@ -666,8 +662,6 @@ QModelIndex KCategorizedView::indexAt(const QPoint &point) const
         index = item[0];
     }
 
-    d->hovered = index;
-
     return index;
 }
 
@@ -676,7 +670,6 @@ void KCategorizedView::reset()
     QListView::reset();
 
     d->lastSelection = QItemSelection();
-    d->currentViewIndex = QModelIndex();
     d->forcedSelectionPosition = 0;
     d->elementsInfo.clear();
     d->elementsPosition.clear();
@@ -688,6 +681,7 @@ void KCategorizedView::reset()
     d->hovered = QModelIndex();
     d->biggestItemSize = QSize(0, 0);
     d->mouseButtonPressed = false;
+    d->rightMouseButtonPressed = false;
 }
 
 void KCategorizedView::paintEvent(QPaintEvent *event)
@@ -748,7 +742,10 @@ void KCategorizedView::paintEvent(QPaintEvent *event)
                 option.state |= QStyle::State_Editing;
         }
 
-        if ((index == d->hovered) && !d->mouseButtonPressed)
+        // we are only interested to give the mouse over feedback when no
+        // dragging is happening (ereslibre)
+        if ((index == d->hovered) && !d->mouseButtonPressed &&
+            (this->state() == QAbstractItemView::NoState))
             option.state |= QStyle::State_MouseOver;
         else
             option.state &= ~QStyle::State_MouseOver;
@@ -855,6 +852,7 @@ void KCategorizedView::setSelection(const QRect &rect,
     if (flags & QItemSelectionModel::Clear)
     {
         selectionModel()->clear();
+        d->lastSelection.clear();
     }
 
     QModelIndexList dirtyIndexes = d->intersectionSet(rect);
@@ -862,20 +860,7 @@ void KCategorizedView::setSelection(const QRect &rect,
     // no items affected, just leave
     if (!dirtyIndexes.count())
     {
-        selectionModel()->select(d->lastSelection, flags);
-
-        d->lastSelection.clear();
-
-        return;
-    }
-
-    d->lastSelection.clear();
-
-    if (!(flags & QItemSelectionModel::Current))
-    {
-        Q_ASSERT(dirtyIndexes.count() == 1);
-
-        selectionModel()->select(dirtyIndexes[0], flags);
+        selectionModel()->select(d->lastSelection, QItemSelectionModel::SelectCurrent);
 
         return;
     }
@@ -883,14 +868,17 @@ void KCategorizedView::setSelection(const QRect &rect,
     QModelIndex topLeft;
     QModelIndex bottomRight;
 
-    if (d->mouseButtonPressed) // selection with click + drag
+    if (d->mouseButtonPressed || d->rightMouseButtonPressed) // selection with click + drag
     {
+        QItemSelection selection;
+
         QModelIndex prev = dirtyIndexes[0];
         QModelIndex first = prev;
         foreach (const QModelIndex &index, dirtyIndexes)
         {
+            // we have a different interval. non-contiguous items
             if ((index.row() - prev.row()) > 1) {
-                d->lastSelection << QItemSelectionRange(first, prev);
+                selection << QItemSelectionRange(first, prev);
 
                 first = index;
             }
@@ -898,9 +886,27 @@ void KCategorizedView::setSelection(const QRect &rect,
             prev = index;
         }
 
-        d->lastSelection << QItemSelectionRange(first, prev);
+        selection << QItemSelectionRange(first, prev);
+
+        if (flags & QItemSelectionModel::Current)
+        {
+            if (rect.topLeft() == rect.bottomRight())
+            {
+                selectionModel()->setCurrentIndex(indexAt(rect.topLeft()), QItemSelectionModel::NoUpdate);
+            }
+
+            selection.merge(d->lastSelection, flags);
+        }
+        else
+        {
+            selection.merge(selectionModel()->selection(), flags);
+
+            selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
 
-        selectionModel()->select(d->lastSelection, flags);
+            return;
+        }
+
+        selectionModel()->select(selection, flags);
     }
     else // selection with click + keyboard keys
     {
@@ -965,10 +971,9 @@ void KCategorizedView::setSelection(const QRect &rect,
             dirtyIndexes << model()->index(i, theoricDirty[0].column(), theoricDirty[0].parent());
         }
 
-        // our current selection will result modified
-        d->lastSelection = QItemSelection(topLeft, bottomRight);
+        QItemSelection selection(topLeft, bottomRight);
 
-        selectionModel()->select(d->lastSelection, flags);
+        selectionModel()->select(selection, flags);
     }
 }
 
@@ -982,6 +987,17 @@ void KCategorizedView::mouseMoveEvent(QMouseEvent *event)
         return;
     }
 
+    QModelIndexList item = d->intersectionSet(QRect(event->pos(), event->pos()));
+
+    if (item.count() == 1)
+    {
+        d->hovered = item[0];
+    }
+    else
+    {
+        d->hovered = QModelIndex();
+    }
+
     const QString previousHoveredCategory = d->hoveredCategory;
 
     d->mousePosition = event->pos();
@@ -1025,6 +1041,8 @@ void KCategorizedView::mouseMoveEvent(QMouseEvent *event)
         }
 
         rect = QRect(start, end).intersected(viewport()->rect().adjusted(-16, -16, 16, 16));
+
+        viewport()->update();
     }
 }
 
@@ -1042,14 +1060,14 @@ void KCategorizedView::mousePressEvent(QMouseEvent *event)
         d->initialPressPosition.setX(d->initialPressPosition.x() +
                                                             horizontalOffset());
     }
+    else if (event->button() == Qt::RightButton)
+    {
+        d->rightMouseButtonPressed = true;
+    }
 
-#ifdef KDE_WORKAROUND_FOR_QT_VIEW_BUG
-    QItemSelection prevSelection = selectionModel()->selection();
-#endif
     QListView::mousePressEvent(event);
-#ifdef KDE_WORKAROUND_FOR_QT_VIEW_BUG
-    selectionModel()->select(prevSelection, QItemSelectionModel::Select);
-#endif
+
+    d->lastSelection = selectionModel()->selection();
 
     viewport()->update(d->categoryVisualRect(d->hoveredCategory));
 }
@@ -1057,6 +1075,7 @@ void KCategorizedView::mousePressEvent(QMouseEvent *event)
 void KCategorizedView::mouseReleaseEvent(QMouseEvent *event)
 {
     d->mouseButtonPressed = false;
+    d->rightMouseButtonPressed = false;
 
     QListView::mouseReleaseEvent(event);
 
@@ -1086,7 +1105,7 @@ void KCategorizedView::mouseReleaseEvent(QMouseEvent *event)
                     selection << QItemSelectionRange(selectIndex);
                 }
 
-                selectionModel()->select(selection, QItemSelectionModel::SelectCurrent);
+                selectionModel()->select(selection, QItemSelectionModel::Select);
 
                 break;
             }
@@ -1120,6 +1139,7 @@ void KCategorizedView::startDrag(Qt::DropActions supportedActions)
 
     d->isDragging = false;
     d->mouseButtonPressed = false;
+    d->rightMouseButtonPressed = false;
 
     viewport()->update(d->lastDraggedItemsRect);
 }
@@ -1139,14 +1159,15 @@ void KCategorizedView::dragMoveEvent(QDragMoveEvent *event)
 
     d->dragLeftViewport = false;
 
-    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
-        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
-    {
 #if defined(DOLPHIN_DRAGANDDROP)
-        QAbstractItemView::dragMoveEvent(event);
+    QAbstractItemView::dragMoveEvent(event);
 #else
-        QListView::dragMoveEvent(event);
+    QListView::dragMoveEvent(event);
 #endif
+
+    if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
+        !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
+    {
         return;
     }
 
@@ -1191,7 +1212,7 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction,
     if (!current.isValid())
     {
         current = model()->index(0, 0, QModelIndex());
-        setCurrentIndex(current);
+        selectionModel()->select(current, QItemSelectionModel::NoUpdate);
         d->forcedSelectionPosition = 0;
 
         return current;
@@ -1367,8 +1388,6 @@ void KCategorizedView::rowsInserted(const QModelIndex &parent,
     if ((viewMode() != KCategorizedView::IconMode) || !d->proxyModel ||
         !d->categoryDrawer || !d->proxyModel->isCategorizedModel())
     {
-        d->lastSelection = QItemSelection();
-        d->currentViewIndex = QModelIndex();
         d->forcedSelectionPosition = 0;
         d->elementsInfo.clear();
         d->elementsPosition.clear();
@@ -1380,6 +1399,7 @@ void KCategorizedView::rowsInserted(const QModelIndex &parent,
         d->hovered = QModelIndex();
         d->biggestItemSize = QSize(0, 0);
         d->mouseButtonPressed = false;
+        d->rightMouseButtonPressed = false;
 
         return;
     }
@@ -1393,8 +1413,6 @@ void KCategorizedView::rowsInsertedArtifficial(const QModelIndex &parent,
 {
     Q_UNUSED(parent);
 
-    d->lastSelection = QItemSelection();
-    d->currentViewIndex = QModelIndex();
     d->forcedSelectionPosition = 0;
     d->elementsInfo.clear();
     d->elementsPosition.clear();
@@ -1406,6 +1424,7 @@ void KCategorizedView::rowsInsertedArtifficial(const QModelIndex &parent,
     d->hovered = QModelIndex();
     d->biggestItemSize = QSize(0, 0);
     d->mouseButtonPressed = false;
+    d->rightMouseButtonPressed = false;
 
     if (start > end || end < 0 || start < 0 || !d->proxyModel->rowCount())
     {
@@ -1458,6 +1477,10 @@ void KCategorizedView::rowsInsertedArtifficial(const QModelIndex &parent,
     d->categories << prevCategory;
 
     d->updateScrollbars();
+
+    // FIXME: We need to safely save the last selection. This is on my TODO
+    // list (ereslibre).
+    selectionModel()->clear();
 }
 
 void KCategorizedView::rowsRemoved(const QModelIndex &parent,
@@ -1491,4 +1514,36 @@ void KCategorizedView::slotLayoutChanged()
     d->layoutChanged();
 }
 
+void KCategorizedView::currentChanged(const QModelIndex &current,
+                                      const QModelIndex &previous)
+{
+    // We need to update the forcedSelectionPosition property in order to correctly
+    // navigate after with keyboard using up & down keys
+
+    int viewportWidth = viewport()->width() - spacing();
+
+    int itemHeight;
+    int itemWidth;
+
+    if (gridSize().isEmpty())
+    {
+        itemHeight = d->biggestItemSize.height();
+        itemWidth = d->biggestItemSize.width();
+    }
+    else
+    {
+        itemHeight = gridSize().height();
+        itemWidth = gridSize().width();
+    }
+
+    int itemWidthPlusSeparation = spacing() + itemWidth;
+    int elementsPerRow = viewportWidth / itemWidthPlusSeparation;
+    if (!elementsPerRow)
+        elementsPerRow++;
+
+    d->forcedSelectionPosition = d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow;
+
+    QListView::currentChanged(current, previous);
+}
+
 #include "kcategorizedview.moc"