From bf20b404c820f00b6d75f0ad123b93cb45eb7487 Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Wed, 24 Aug 2011 21:28:46 +0200 Subject: [PATCH] Dragging and selection fixes - Don't clear the selection on mouse-press events, do it (if allowed) in the mouse-release-event. Otherwise dragging of multiple selected items would not be possible. - Don't clear the selection when the context-menu gets opened by a right-click. - Fix issue that dragging is not possible after the first drop that has been canceled. --- src/kitemviews/kitemlistcontroller.cpp | 80 +++++++++++++++----------- src/kitemviews/kitemlistcontroller.h | 4 +- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index c3f3b36f42..29e2f47d67 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -238,6 +238,7 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const return false; } + m_dragging = false; m_pressedMousePos = transform.map(event->pos()); m_pressedIndex = m_view->itemAt(m_pressedMousePos); @@ -247,9 +248,8 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const const bool shiftPressed = event->modifiers() & Qt::ShiftModifier; const bool controlPressed = event->modifiers() & Qt::ControlModifier; - const bool shiftOrControlPressed = shiftPressed || controlPressed; - if (!shiftOrControlPressed || m_selectionBehavior == SingleSelection) { + if (m_selectionBehavior == SingleSelection) { m_selectionManager->clearSelection(); } @@ -318,13 +318,13 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const if (m_pressedIndex >= 0) { // Check whether a dragging should be started - if (!m_dragging) { + if (!m_dragging && (event->buttons() & Qt::LeftButton)) { const QPointF pos = transform.map(event->pos()); const qreal minDragDiff = 4; - m_dragging = qAbs(pos.x() - m_pressedMousePos.x()) >= minDragDiff || - qAbs(pos.y() - m_pressedMousePos.y()) >= minDragDiff; - if (m_dragging) { - startDragging(); + const bool hasMinDragDiff = qAbs(pos.x() - m_pressedMousePos.x()) >= minDragDiff || + qAbs(pos.y() - m_pressedMousePos.y()) >= minDragDiff; + if (hasMinDragDiff && startDragging()) { + m_dragging = true; } } } else { @@ -354,38 +354,51 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con return false; } + const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier || + event->modifiers() & Qt::ControlModifier; + + bool clearSelection = !shiftOrControlPressed && !m_dragging && !(event->button() == Qt::RightButton); + KItemListRubberBand* rubberBand = m_view->rubberBand(); if (rubberBand->isActive()) { disconnect(rubberBand, SIGNAL(endPositionChanged(QPointF,QPointF)), this, SLOT(slotRubberBandChanged())); rubberBand->setActive(false); m_oldSelection.clear(); - } else { - const QPointF pos = transform.map(event->pos()); - const int index = m_view->itemAt(pos); - const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier || - event->modifiers() & Qt::ControlModifier; - if (index >= 0 && index == m_pressedIndex) { - // The release event is done above the same item as the press event - bool emitItemClicked = true; - if (event->button() & Qt::LeftButton) { - if (m_view->isAboveExpansionToggle(index, pos)) { - emit itemExpansionToggleClicked(index); - emitItemClicked = false; - } else if (shiftOrControlPressed) { - // The mouse click should only update the selection, not trigger the item - emitItemClicked = false; - } - } - - if (emitItemClicked) { - emit itemClicked(index, event->button()); - } - } else if (!shiftOrControlPressed) { - m_selectionManager->clearSelection(); + if (rubberBand->startPosition() != rubberBand->endPosition()) { + clearSelection = false; } } + const QPointF pos = transform.map(event->pos()); + const int index = m_view->itemAt(pos); + + if (index >= 0 && index == m_pressedIndex) { + // The release event is done above the same item as the press event + + if (clearSelection) { + // Clear the previous selection but reselect the current index + m_selectionManager->setSelectedItems(QSet() << index); + } + + bool emitItemClicked = true; + if (event->button() & Qt::LeftButton) { + if (m_view->isAboveExpansionToggle(index, pos)) { + emit itemExpansionToggleClicked(index); + emitItemClicked = false; + } else if (shiftOrControlPressed) { + // The mouse click should only update the selection, not trigger the item + emitItemClicked = false; + } + } + + if (emitItemClicked) { + emit itemClicked(index, event->button()); + } + } else if (clearSelection) { + m_selectionManager->clearSelection(); + } + m_dragging = false; m_pressedMousePos = QPointF(); m_pressedIndex = -1; @@ -656,16 +669,16 @@ void KItemListController::slotRubberBandChanged() m_selectionManager->setSelectedItems(selectedItems + m_oldSelection); } -void KItemListController::startDragging() +bool KItemListController::startDragging() { if (!m_view || !m_model) { - return; + return false; } const QSet selectedItems = m_selectionManager->selectedItems(); QMimeData* data = m_model->createMimeData(selectedItems); if (!data) { - return; + return false; } // The created drag object will be owned and deleted @@ -677,6 +690,7 @@ void KItemListController::startDragging() drag->setPixmap(pixmap); drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::IgnoreAction); + return true; } #include "kitemlistcontroller.moc" diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h index 01d1b94081..134e116731 100644 --- a/src/kitemviews/kitemlistcontroller.h +++ b/src/kitemviews/kitemlistcontroller.h @@ -135,8 +135,10 @@ private slots: private: /** * Creates a QDrag object to start a drag-operation. + * @return True if the QDrag object has been created. If false is returned + * there is no implementation available for KItemModelBase::createMimeData(). */ - void startDragging(); + bool startDragging(); private: bool m_dragging;