X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/84033839269fe4cb8695ebc25b5634df97036650..d90da9a85ed554dbe347ec8af8ea596ad06bb729:/src/kitemviews/kitemlistcontroller.cpp diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 7798fc364..ad08223a4 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (C) 2011 by Peter Penz * + * Copyright (C) 2012 by Frank Reininghaus * * * * Based on the Itemviews NG project from Trolltech Labs: * * http://qt.gitorious.org/qt-labs/itemviews-ng * @@ -41,7 +42,9 @@ KItemListController::KItemListController(QObject* parent) : QObject(parent), + m_singleClickActivation(KGlobalSettings::singleClick()), m_selectionTogglePressed(false), + m_clearSelectionIfItemsAreNotDragged(false), m_selectionBehavior(NoSelection), m_model(0), m_view(0), @@ -142,6 +145,16 @@ int KItemListController::autoActivationDelay() const return m_autoActivationTimer->interval(); } +void KItemListController::setSingleClickActivation(bool singleClick) +{ + m_singleClickActivation = singleClick; +} + +bool KItemListController::singleClickActivation() const +{ + return m_singleClickActivation; +} + bool KItemListController::showEvent(QShowEvent* event) { Q_UNUSED(event); @@ -189,8 +202,9 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) default: break; } } - - const bool selectSingleItem = itemCount == 1 && + + const bool selectSingleItem = m_selectionBehavior != NoSelection && + itemCount == 1 && (key == Qt::Key_Home || key == Qt::Key_End || key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_Left || key == Qt::Key_Right); @@ -203,10 +217,14 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) switch (key) { case Qt::Key_Home: index = 0; + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); break; case Qt::Key_End: index = itemCount - 1; + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); break; case Qt::Key_Left: @@ -227,12 +245,68 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) case Qt::Key_Up: updateKeyboardAnchor(); - index = previousRowIndex(); + index = previousRowIndex(index); break; case Qt::Key_Down: updateKeyboardAnchor(); - index = nextRowIndex(); + index = nextRowIndex(index); + break; + + case Qt::Key_PageUp: + if (m_view->scrollOrientation() == Qt::Horizontal) { + // The new current index should correspond to the first item in the current column. + int newIndex = qMax(index - 1, 0); + while (newIndex != index && m_view->itemRect(newIndex).topLeft().y() < m_view->itemRect(index).topLeft().y()) { + index = newIndex; + newIndex = qMax(index - 1, 0); + } + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); + } else { + const qreal currentItemBottom = m_view->itemRect(index).bottomLeft().y(); + const qreal height = m_view->geometry().height(); + + // The new current item should be the first item in the current + // column whose itemRect's top coordinate is larger than targetY. + const qreal targetY = currentItemBottom - height; + + updateKeyboardAnchor(); + int newIndex = previousRowIndex(index); + do { + index = newIndex; + updateKeyboardAnchor(); + newIndex = previousRowIndex(index); + } while (m_view->itemRect(newIndex).topLeft().y() > targetY && newIndex != index); + } + break; + + case Qt::Key_PageDown: + if (m_view->scrollOrientation() == Qt::Horizontal) { + // The new current index should correspond to the last item in the current column. + int newIndex = qMin(index + 1, m_model->count() - 1); + while (newIndex != index && m_view->itemRect(newIndex).topLeft().y() > m_view->itemRect(index).topLeft().y()) { + index = newIndex; + newIndex = qMin(index + 1, m_model->count() - 1); + } + m_keyboardAnchorIndex = index; + m_keyboardAnchorPos = keyboardAnchorPos(index); + } else { + const qreal currentItemTop = m_view->itemRect(index).topLeft().y(); + const qreal height = m_view->geometry().height(); + + // The new current item should be the last item in the current + // column whose itemRect's bottom coordinate is smaller than targetY. + const qreal targetY = currentItemTop + height; + + updateKeyboardAnchor(); + int newIndex = nextRowIndex(index); + do { + index = newIndex; + updateKeyboardAnchor(); + newIndex = nextRowIndex(index); + } while (m_view->itemRect(newIndex).bottomLeft().y() < targetY && newIndex != index); + } break; case Qt::Key_Enter: @@ -249,13 +323,15 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } case Qt::Key_Space: - if (controlPressed) { - m_selectionManager->endAnchoredSelection(); - m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); - m_selectionManager->beginAnchoredSelection(index); - } else { - const int current = m_selectionManager->currentItem(); - m_selectionManager->setSelected(current); + if (m_selectionBehavior == MultiSelection) { + if (controlPressed) { + m_selectionManager->endAnchoredSelection(); + m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); + m_selectionManager->beginAnchoredSelection(index); + } else { + const int current = m_selectionManager->currentItem(); + m_selectionManager->setSelected(current); + } } break; @@ -288,19 +364,33 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } if (m_selectionManager->currentItem() != index) { - if (controlPressed) { - m_selectionManager->endAnchoredSelection(); - } - - m_selectionManager->setCurrentItem(index); + switch (m_selectionBehavior) { + case NoSelection: + m_selectionManager->setCurrentItem(index); + break; - if (!shiftOrControlPressed || m_selectionBehavior == SingleSelection) { + case SingleSelection: + m_selectionManager->setCurrentItem(index); m_selectionManager->clearSelection(); m_selectionManager->setSelected(index, 1); - } + break; + + case MultiSelection: + if (controlPressed) { + m_selectionManager->endAnchoredSelection(); + } + + m_selectionManager->setCurrentItem(index); - if (!shiftPressed) { - m_selectionManager->beginAnchoredSelection(index); + if (!shiftOrControlPressed) { + m_selectionManager->clearSelection(); + m_selectionManager->setSelected(index, 1); + } + + if (!shiftPressed) { + m_selectionManager->beginAnchoredSelection(index); + } + break; } m_view->scrollToItem(index); @@ -364,12 +454,12 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const m_pressedMousePos = transform.map(event->pos()); m_pressedIndex = m_view->itemAt(m_pressedMousePos); - if (m_pressedIndex >= 0) { - emit itemPressed(m_pressedIndex, event->button()); - } + emit mouseButtonPressed(m_pressedIndex, event->buttons()); if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) { + m_selectionManager->endAnchoredSelection(); m_selectionManager->setCurrentItem(m_pressedIndex); + m_selectionManager->beginAnchoredSelection(m_pressedIndex); return true; } @@ -400,6 +490,13 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const (!shiftOrControlPressed && !pressedItemAlreadySelected); if (clearSelection) { m_selectionManager->clearSelection(); + } else if (pressedItemAlreadySelected && !shiftOrControlPressed && (event->buttons() & Qt::LeftButton)) { + // The user might want to start dragging multiple items, but if he clicks the item + // in order to trigger it instead, the other selected items must be deselected. + // However, we do not know yet what the user is going to do. + // -> remember that the user pressed an item which had been selected already and + // clear the selection in mouseReleaseEvent(), unless the items are dragged. + m_clearSelectionIfItemsAreNotDragged = true; } if (!shiftPressed) { @@ -492,7 +589,12 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const // done on the mouse-press event, but when using the selection-toggle on a // selected item the dragged item is not selected yet. m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle); + } else { + // A selected item has been clicked to drag all selected items + // -> the selection should not be cleared when the mouse button is released. + m_clearSelectionIfItemsAreNotDragged = false; } + startDragging(); } } @@ -533,9 +635,7 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con return false; } - if (m_pressedIndex >= 0) { - emit itemReleased(m_pressedIndex, event->button()); - } + emit mouseButtonReleased(m_pressedIndex, event->buttons()); const bool isAboveSelectionToggle = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos); if (isAboveSelectionToggle) { @@ -566,6 +666,14 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con if (index >= 0 && index == m_pressedIndex) { // The release event is done above the same item as the press event + if (m_clearSelectionIfItemsAreNotDragged) { + // A selected item has been clicked, but no drag operation has been started + // -> clear the rest of the selection. + m_selectionManager->clearSelection(); + m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Select); + m_selectionManager->beginAnchoredSelection(m_pressedIndex); + } + if (event->button() & Qt::LeftButton) { bool emitItemActivated = true; if (m_view->isAboveExpansionToggle(index, pos)) { @@ -577,7 +685,7 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con } else if (shiftOrControlPressed) { // The mouse click should only update the selection, not trigger the item emitItemActivated = false; - } else if (!KGlobalSettings::singleClick()) { + } else if (!m_singleClickActivation) { emitItemActivated = false; } if (emitItemActivated) { @@ -590,6 +698,7 @@ bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, con m_pressedMousePos = QPointF(); m_pressedIndex = -1; + m_clearSelectionIfItemsAreNotDragged = false; return false; } @@ -598,7 +707,7 @@ bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const QPointF pos = transform.map(event->pos()); const int index = m_view->itemAt(pos); - bool emitItemActivated = !KGlobalSettings::singleClick() && + bool emitItemActivated = !m_singleClickActivation && (event->button() & Qt::LeftButton) && index >= 0 && index < m_model->count(); if (emitItemActivated) { @@ -618,6 +727,14 @@ bool KItemListController::dragLeaveEvent(QGraphicsSceneDragDropEvent* event, con { Q_UNUSED(event); Q_UNUSED(transform); + + m_view->setAutoScroll(false); + + KItemListWidget* widget = hoveredWidget(); + if (widget) { + widget->setHovered(false); + emit itemUnhovered(widget->index()); + } return false; } @@ -628,6 +745,8 @@ bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, cons return false; } + event->acceptProposedAction(); + KItemListWidget* oldHoveredWidget = hoveredWidget(); const QPointF pos = transform.map(event->pos()); @@ -666,6 +785,7 @@ bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QT } m_autoActivationTimer->stop(); + m_view->setAutoScroll(false); const QPointF pos = transform.map(event->pos()); const int index = m_view->itemAt(pos); @@ -914,7 +1034,7 @@ void KItemListController::startDragging() const QPixmap pixmap = m_view->createDragPixmap(selectedItems); drag->setPixmap(pixmap); - drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::IgnoreAction); + drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::CopyAction); } KItemListWidget* KItemListController::hoveredWidget() const @@ -959,24 +1079,23 @@ void KItemListController::updateKeyboardAnchor() } } -int KItemListController::nextRowIndex() const +int KItemListController::nextRowIndex(int index) const { - const int currentIndex = m_selectionManager->currentItem(); if (m_keyboardAnchorIndex < 0) { - return currentIndex; + return index; } const int maxIndex = m_model->count() - 1; - if (currentIndex == maxIndex) { - return currentIndex; + if (index == maxIndex) { + return index; } // Calculate the index of the last column inside the row of the current index - int lastColumnIndex = currentIndex; + int lastColumnIndex = index; while (keyboardAnchorPos(lastColumnIndex + 1) > keyboardAnchorPos(lastColumnIndex)) { ++lastColumnIndex; if (lastColumnIndex >= maxIndex) { - return currentIndex; + return index; } } @@ -997,19 +1116,18 @@ int KItemListController::nextRowIndex() const return nextRowIndex; } -int KItemListController::previousRowIndex() const +int KItemListController::previousRowIndex(int index) const { - const int currentIndex = m_selectionManager->currentItem(); - if (m_keyboardAnchorIndex < 0 || currentIndex == 0) { - return currentIndex; + if (m_keyboardAnchorIndex < 0 || index == 0) { + return index; } // Calculate the index of the first column inside the row of the current index - int firstColumnIndex = currentIndex; + int firstColumnIndex = index; while (keyboardAnchorPos(firstColumnIndex - 1) < keyboardAnchorPos(firstColumnIndex)) { --firstColumnIndex; if (firstColumnIndex <= 0) { - return currentIndex; + return index; } }