From: Rafael Fernández López Date: Thu, 13 Dec 2007 23:24:14 +0000 (+0000) Subject: Fix the bug reported by Will. Now this code is also more polite. This was a TODO... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/51b61d7735bc4a6461a4b90493e04071ff566ae0 Fix the bug reported by Will. Now this code is also more polite. This was a TODO and now is fixed :) Still a bug somewhere on Qt... when you ctrl+selection rect (with mouse), it is lost the last selection done if they were done by groups. Going to dive more into this problem, but it lives on Qt. BUG: 153876 CCMAIL: peter.penz@gmx.at svn path=/trunk/KDE/kdebase/apps/; revision=748258 --- diff --git a/src/kcategorizedview.cpp b/src/kcategorizedview.cpp index 72936113c..03002d303 100644 --- a/src/kcategorizedview.cpp +++ b/src/kcategorizedview.cpp @@ -849,88 +849,122 @@ void KCategorizedView::setSelection(const QRect &rect, if (flags & QItemSelectionModel::Clear) { - if (!rect.intersects(d->categoryVisualRect(d->hoveredCategory))) - { - d->lastSelection = QItemSelection(); - } + selectionModel()->clear(); } - selectionModel()->clear(); - QModelIndexList dirtyIndexes = d->intersectionSet(rect); + // no items affected, just leave if (!dirtyIndexes.count()) { - if (!d->lastSelection.isEmpty() && - (rect.intersects(d->categoryVisualRect(d->hoveredCategory)) || d->mouseButtonPressed)) - { - selectionModel()->select(d->lastSelection, flags); - } + selectionModel()->select(d->lastSelection, flags); + + d->lastSelection.clear(); return; } - int viewportWidth = viewport()->width() - spacing(); - int itemWidth; + d->lastSelection.clear(); - if (gridSize().isEmpty()) + if (!(flags & QItemSelectionModel::Current)) { - itemWidth = d->biggestItemSize.width(); - } - else - { - itemWidth = gridSize().width(); - } - - int itemWidthPlusSeparation = spacing() + itemWidth; - int elementsPerRow = viewportWidth / itemWidthPlusSeparation; + Q_ASSERT(dirtyIndexes.count() == 1); - QItemSelection selection; + selectionModel()->select(dirtyIndexes[0], flags); - if (!d->mouseButtonPressed) - { - selection = QItemSelection(dirtyIndexes[0], dirtyIndexes[0]); - d->currentViewIndex = dirtyIndexes[0]; - selectionModel()->setCurrentIndex(d->currentViewIndex, flags); - d->forcedSelectionPosition = d->elementsInfo[d->currentViewIndex.row()].relativeOffsetToCategory % elementsPerRow; + return; } - else + + QModelIndex topLeft; + QModelIndex bottomRight; + + if (d->mouseButtonPressed) // selection with click + drag { - QModelIndex first = dirtyIndexes[0]; - QModelIndex last; + QModelIndex prev = dirtyIndexes[0]; + QModelIndex first = prev; foreach (const QModelIndex &index, dirtyIndexes) { - if (last.isValid() && last.row() + 1 != index.row()) - { - QItemSelectionRange range(first, last); - - selection << range; + if ((index.row() - prev.row()) > 1) { + d->lastSelection << QItemSelectionRange(first, prev); first = index; } - last = index; + prev = index; } - if (last.isValid()) - selection << QItemSelectionRange(first, last); + d->lastSelection << QItemSelectionRange(first, prev); + + selectionModel()->select(d->lastSelection, flags); + } + else // selection with click + keyboard keys + { + QModelIndex topLeftIndex = indexAt(QPoint(rect.topLeft().x(), + rect.topLeft().y())); + QModelIndex bottomRightIndex = indexAt(QPoint(rect.bottomRight().x(), + rect.bottomRight().y())); - if (first == last) + // keyboard selection comes "upside down". Let's normalize it + if (topLeftIndex.row() > bottomRightIndex.row()) { - selectionModel()->setCurrentIndex(first, QItemSelectionModel::SelectCurrent); - d->forcedSelectionPosition = d->elementsInfo[first.row()].relativeOffsetToCategory % elementsPerRow; + QModelIndex auxIndex = topLeftIndex; + topLeftIndex = bottomRightIndex; + bottomRightIndex = auxIndex; } - } - if (d->lastSelection.count()) - { - if ((selection.count() == 1) && (selection[0].indexes().count() == 1)) - selection.merge(d->lastSelection, flags); + int viewportWidth = viewport()->width() - spacing(); + int itemWidth; + + if (gridSize().isEmpty()) + { + itemWidth = d->biggestItemSize.width(); + } else - selection.merge(d->lastSelection, QItemSelectionModel::Select); - } + { + itemWidth = gridSize().width(); + } + + int itemWidthPlusSeparation = spacing() + itemWidth; + int elementsPerRow = viewportWidth / itemWidthPlusSeparation; + if (!elementsPerRow) + elementsPerRow++; + + QModelIndexList theoricDirty(dirtyIndexes); + dirtyIndexes.clear(); + int first = model()->rowCount(); + int last = 0; + + foreach (const QModelIndex &index, theoricDirty) + { + if ((index.row() < first) && + ((((topLeftIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) && + ((topLeftIndex.row() % elementsPerRow) <= (index.row() % elementsPerRow))) || + (topLeftIndex.row() / elementsPerRow) != (index.row() / elementsPerRow))) + { + first = index.row(); + topLeft = index; + } + + if ((index.row() > last) && + ((((bottomRightIndex.row() / elementsPerRow) == (index.row() / elementsPerRow)) && + ((bottomRightIndex.row() % elementsPerRow) >= (index.row() % elementsPerRow))) || + (bottomRightIndex.row() / elementsPerRow) != (index.row() / elementsPerRow))) + { + last = index.row(); + bottomRight = index; + } + } + + for (int i = first; i <= last; i++) + { + dirtyIndexes << model()->index(i, theoricDirty[0].column(), theoricDirty[0].parent()); + } - selectionModel()->select(selection, flags); + // our current selection will result modified + d->lastSelection = QItemSelection(topLeft, bottomRight); + + selectionModel()->select(d->lastSelection, flags); + } } void KCategorizedView::mouseMoveEvent(QMouseEvent *event) @@ -986,10 +1020,6 @@ void KCategorizedView::mouseMoveEvent(QMouseEvent *event) } rect = QRect(start, end).intersected(viewport()->rect().adjusted(-16, -16, 16, 16)); - - //viewport()->update(rect.united(d->lastSelectionRect)); - - d->lastSelectionRect = rect; } } @@ -1031,7 +1061,7 @@ void KCategorizedView::mouseReleaseEvent(QMouseEvent *event) QItemSelection selection; QItemSelection deselection; - +#if 0 if (initialPressPosition == d->initialPressPosition) { foreach(const QString &category, d->categories) @@ -1042,7 +1072,7 @@ void KCategorizedView::mouseReleaseEvent(QMouseEvent *event) { QModelIndex selectIndex = index.model()->index(index.row(), 0); - if (!d->lastSelection.contains(selectIndex)) + if (/*!d->lastSelection.contains(selectIndex)*/) { selection << QItemSelectionRange(selectIndex); } @@ -1059,8 +1089,7 @@ void KCategorizedView::mouseReleaseEvent(QMouseEvent *event) } } } - - d->lastSelection = selectionModel()->selection(); +#endif if (d->hovered.isValid()) viewport()->update(visualRect(d->hovered)); @@ -1155,7 +1184,16 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction, return QListView::moveCursor(cursorAction, modifiers); } - const QModelIndex current = selectionModel()->currentIndex(); + QModelIndex current = selectionModel()->currentIndex(); + + if (!current.isValid()) + { + current = model()->index(0, 0, QModelIndex()); + setCurrentIndex(current); + d->forcedSelectionPosition = 0; + + return current; + } int viewportWidth = viewport()->width() - spacing(); int itemWidth; @@ -1171,6 +1209,8 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction, int itemWidthPlusSeparation = spacing() + itemWidth; int elementsPerRow = viewportWidth / itemWidthPlusSeparation; + if (!elementsPerRow) + elementsPerRow++; QString lastCategory = d->categories.first(); QString theCategory = d->categories.first(); @@ -1256,36 +1296,56 @@ QModelIndex KCategorizedView::moveCursor(CursorAction cursorAction, case QAbstractItemView::MoveLeft: if (layoutDirection() == Qt::RightToLeft) { + if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow)) + return current; + d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow; +#if 0 //follow qt view behavior. lateral movements won't change visual row if (d->forcedSelectionPosition < 0) d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; +#endif return d->proxyModel->index(current.row() + 1, 0); } + if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow)) + return current; + d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow; +#if 0 //follow qt view behavior. lateral movements won't change visual row if (d->forcedSelectionPosition < 0) d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; +#endif return d->proxyModel->index(current.row() - 1, 0); case QAbstractItemView::MoveRight: if (layoutDirection() == Qt::RightToLeft) { + if (!(d->elementsInfo[current.row()].relativeOffsetToCategory % elementsPerRow)) + return current; + d->forcedSelectionPosition = d->elementsInfo[current.row() - 1].relativeOffsetToCategory % elementsPerRow; +#if 0 //follow qt view behavior. lateral movements won't change visual row if (d->forcedSelectionPosition < 0) d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; +#endif return d->proxyModel->index(current.row() - 1, 0); } + if (!(d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow)) + return current; + d->forcedSelectionPosition = d->elementsInfo[current.row() + 1].relativeOffsetToCategory % elementsPerRow; +#if 0 //follow qt view behavior. lateral movements won't change visual row if (d->forcedSelectionPosition < 0) d->forcedSelectionPosition = (d->categoriesIndexes[theCategory].count() - 1) % elementsPerRow; +#endif return d->proxyModel->index(current.row() + 1, 0); diff --git a/src/kcategorizedview_p.h b/src/kcategorizedview_p.h index aa55cda75..c420bb6ad 100644 --- a/src/kcategorizedview_p.h +++ b/src/kcategorizedview_p.h @@ -136,7 +136,6 @@ public: QString hoveredCategory; QPoint initialPressPosition; QPoint mousePosition; - QItemSelection lastSelection; QModelIndex currentViewIndex; int forcedSelectionPosition; @@ -150,12 +149,12 @@ public: QStringList categories; QModelIndexList intersectedIndexes; QRect lastDraggedItemsRect; - QRect lastSelectionRect; int modelSortRole; int modelSortColumn; int modelLastRowCount; bool modelCategorized; Qt::SortOrder modelSortOrder; + QItemSelection lastSelection; // Attributes for speed reasons KCategorizedSortFilterProxyModel *proxyModel;