X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/fc4315d57e8fe64d05aad2a1c24800f0149b21da..76a46fd9094b17eb99e8a42cca8562fdc0b3814c:/src/kitemviews/kitemlistcontroller.cpp diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 854a0087a..0c25ebb8b 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -2,8 +2,7 @@ * 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 * + * Based on the Itemviews NG project from Trolltech Labs * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -23,24 +22,20 @@ #include "kitemlistcontroller.h" -#include -#include - -#include "kitemlistview.h" #include "kitemlistselectionmanager.h" - -#include "private/kitemlistrubberband.h" +#include "kitemlistview.h" #include "private/kitemlistkeyboardsearchmanager.h" +#include "private/kitemlistrubberband.h" +#include "views/draganddrophelper.h" +#include #include #include -#include #include #include #include #include #include -#include KItemListController::KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent) : QObject(parent), @@ -50,13 +45,13 @@ KItemListController::KItemListController(KItemModelBase* model, KItemListView* v m_selectionBehavior(NoSelection), m_autoActivationBehavior(ActivationAndExpansion), m_mouseDoubleClickAction(ActivateItemOnly), - m_model(0), - m_view(0), + m_model(nullptr), + m_view(nullptr), m_selectionManager(new KItemListSelectionManager(this)), m_keyboardManager(new KItemListKeyboardSearchManager(this)), m_pressedIndex(-1), m_pressedMousePos(), - m_autoActivationTimer(0), + m_autoActivationTimer(nullptr), m_oldSelection(), m_keyboardAnchorIndex(-1), m_keyboardAnchorPos(0) @@ -65,6 +60,8 @@ KItemListController::KItemListController(KItemModelBase* model, KItemListView* v this, &KItemListController::slotChangeCurrentItem); connect(m_selectionManager, &KItemListSelectionManager::currentChanged, m_keyboardManager, &KItemListKeyboardSearchManager::slotCurrentChanged); + connect(m_selectionManager, &KItemListSelectionManager::selectionChanged, + m_keyboardManager, &KItemListKeyboardSearchManager::slotSelectionChanged); m_autoActivationTimer = new QTimer(this); m_autoActivationTimer->setSingleShot(true); @@ -77,10 +74,10 @@ KItemListController::KItemListController(KItemModelBase* model, KItemListView* v KItemListController::~KItemListController() { - setView(0); + setView(nullptr); Q_ASSERT(!m_view); - setModel(0); + setModel(nullptr); Q_ASSERT(!m_model); } @@ -180,6 +177,20 @@ KItemListController::MouseDoubleClickAction KItemListController::mouseDoubleClic return m_mouseDoubleClickAction; } +int KItemListController::indexCloseToMousePressedPosition() const +{ + QHashIterator it(m_view->m_visibleGroups); + while (it.hasNext()) { + it.next(); + KItemListGroupHeader *groupHeader = it.value(); + const QPointF mappedToGroup = groupHeader->mapFromItem(nullptr, m_pressedMousePos); + if (groupHeader->contains(mappedToGroup)) { + return it.key()->index(); + } + } + return -1; +} + void KItemListController::setAutoActivationDelay(int delay) { m_autoActivationTimer->setInterval(delay); @@ -200,18 +211,6 @@ bool KItemListController::singleClickActivationEnforced() const return m_singleClickActivationEnforced; } -bool KItemListController::showEvent(QShowEvent* event) -{ - Q_UNUSED(event); - return false; -} - -bool KItemListController::hideEvent(QHideEvent* event) -{ - Q_UNUSED(event); - return false; -} - bool KItemListController::keyPressEvent(QKeyEvent* event) { int index = m_selectionManager->currentItem(); @@ -233,6 +232,10 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) const bool shiftPressed = event->modifiers() & Qt::ShiftModifier; const bool controlPressed = event->modifiers() & Qt::ControlModifier; const bool shiftOrControlPressed = shiftPressed || controlPressed; + const bool navigationPressed = key == Qt::Key_Home || key == Qt::Key_End || + key == Qt::Key_PageUp || key == Qt::Key_PageDown || + key == Qt::Key_Up || key == Qt::Key_Down || + key == Qt::Key_Left || key == Qt::Key_Right; const int itemCount = m_model->count(); @@ -248,11 +251,8 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } } - 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); + const bool selectSingleItem = m_selectionBehavior != NoSelection && itemCount == 1 && navigationPressed; + if (selectSingleItem) { const int current = m_selectionManager->currentItem(); m_selectionManager->setSelected(current); @@ -423,8 +423,7 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } } } - // Fall through to the default case and add the Space to the current search string. - + Q_FALLTHROUGH(); // fall through to the default case and add the Space to the current search string. default: m_keyboardManager->addKeys(event->text()); // Make sure unconsumed events get propagated up the chain. #302329 @@ -461,7 +460,9 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } break; } + } + if (navigationPressed) { m_view->scrollToItem(index); } return true; @@ -472,19 +473,18 @@ void KItemListController::slotChangeCurrentItem(const QString& text, bool search if (!m_model || m_model->count() == 0) { return; } - const int currentIndex = m_selectionManager->currentItem(); int index; if (searchFromNextItem) { + const int currentIndex = m_selectionManager->currentItem(); index = m_model->indexForKeyboardSearch(text, (currentIndex + 1) % m_model->count()); } else { - index = m_model->indexForKeyboardSearch(text, currentIndex); + index = m_model->indexForKeyboardSearch(text, 0); } if (index >= 0) { m_selectionManager->setCurrentItem(index); if (m_selectionBehavior != NoSelection) { - m_selectionManager->clearSelection(); - m_selectionManager->setSelected(index, 1); + m_selectionManager->replaceSelection(index); m_selectionManager->beginAnchoredSelection(index); } @@ -524,7 +524,7 @@ void KItemListController::slotAutoActivationTimeout() bool KItemListController::inputMethodEvent(QInputMethodEvent* event) { - Q_UNUSED(event); + Q_UNUSED(event) return false; } @@ -538,8 +538,7 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const m_pressedIndex = m_view->itemAt(m_pressedMousePos); emit mouseButtonPressed(m_pressedIndex, event->buttons()); - // TODO: Qt5: Replace Qt::XButton1 by Qt::BackButton and Qt::XButton2 by Qt::ForwardButton - if (event->buttons() & (Qt::XButton1 | Qt::XButton2)) { + if (event->buttons() & (Qt::BackButton | Qt::ForwardButton)) { // Do not select items when clicking the back/forward buttons, see // https://bugs.kde.org/show_bug.cgi?id=327412. return true; @@ -586,6 +585,10 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const // -> 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 (m_selectionManager->selectedItems().count() == 1 && m_view->isAboveText(m_pressedIndex, m_pressedMousePos)) { + emit selectedItemTextPressed(m_pressedIndex); + } } if (!shiftPressed) { @@ -593,6 +596,16 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const m_selectionManager->endAnchoredSelection(); } + if (event->buttons() & Qt::RightButton) { + // Stop rubber band from persisting after right-clicks + KItemListRubberBand* rubberBand = m_view->rubberBand(); + if (rubberBand->isActive()) { + disconnect(rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListController::slotRubberBandChanged); + rubberBand->setActive(false); + m_view->setAutoScroll(false); + } + } + if (m_pressedIndex >= 0) { m_selectionManager->setCurrentItem(m_pressedIndex); @@ -774,7 +787,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() || m_singleClickActivationEnforced)) { + } else if (!(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced)) { emitItemActivated = false; } if (emitItemActivated) { @@ -804,7 +817,23 @@ bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, } } - bool emitItemActivated = !(KGlobalSettings::singleClick() || m_singleClickActivationEnforced) && + if (event->button() & Qt::RightButton) { + m_selectionManager->clearSelection(); + if (index >= 0) { + m_selectionManager->setSelected(index); + emit itemContextMenuRequested(index, event->screenPos()); + } else { + const QRectF headerBounds = m_view->headerBoundaries(); + if (headerBounds.contains(event->pos())) { + emit headerContextMenuRequested(event->screenPos()); + } else { + emit viewContextMenuRequested(event->screenPos()); + } + } + return true; + } + + bool emitItemActivated = !(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced) && (event->button() & Qt::LeftButton) && index >= 0 && index < m_model->count(); if (emitItemActivated) { @@ -815,16 +844,20 @@ bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, bool KItemListController::dragEnterEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform) { - Q_UNUSED(event); - Q_UNUSED(transform); + Q_UNUSED(event) + Q_UNUSED(transform) + + DragAndDropHelper::clearUrlListMatchesUrlCache(); + return false; } bool KItemListController::dragLeaveEvent(QGraphicsSceneDragDropEvent* event, const QTransform& transform) { - Q_UNUSED(event); - Q_UNUSED(transform); + Q_UNUSED(event) + Q_UNUSED(transform) + m_autoActivationTimer->stop(); m_view->setAutoScroll(false); m_view->hideDropIndicator(); @@ -842,8 +875,8 @@ bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, cons return false; } - event->acceptProposedAction(); + QUrl hoveredDir = m_model->directory(); KItemListWidget* oldHoveredWidget = hoveredWidget(); const QPointF pos = transform.map(event->pos()); @@ -866,6 +899,11 @@ bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, cons } const int index = newHoveredWidget->index(); + + if (m_model->isDir(index)) { + hoveredDir = m_model->url(index); + } + if (!droppingBetweenItems) { if (m_model->supportsDropping(index)) { // Something has been dragged on an item. @@ -891,6 +929,13 @@ bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, cons m_view->hideDropIndicator(); } + if (DragAndDropHelper::urlListMatchesUrl(event->mimeData()->urls(), hoveredDir)) { + event->setDropAction(Qt::IgnoreAction); + event->ignore(); + } else { + event->setDropAction(event->proposedAction()); + event->accept(); + } return false; } @@ -915,26 +960,27 @@ bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QT // Something has been dropped between two items. m_view->hideDropIndicator(); emit aboveItemDropEvent(dropAboveIndex, event); - } else { + } else if (!event->mimeData()->hasFormat(m_model->blacklistItemDropEventMimeType())) { // Something has been dropped on an item or on an empty part of the view. emit itemDropEvent(m_view->itemAt(pos), event); } - QAccessible::updateAccessibility(view(), 0, QAccessible::DragDropEnd); + QAccessibleEvent accessibilityEvent(view(), QAccessible::DragDropEnd); + QAccessible::updateAccessibility(&accessibilityEvent); return true; } bool KItemListController::hoverEnterEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform) { - Q_UNUSED(event); - Q_UNUSED(transform); + Q_UNUSED(event) + Q_UNUSED(transform) return false; } bool KItemListController::hoverMoveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform) { - Q_UNUSED(transform); + Q_UNUSED(transform) if (!m_model || !m_view) { return false; } @@ -965,8 +1011,8 @@ bool KItemListController::hoverMoveEvent(QGraphicsSceneHoverEvent* event, const bool KItemListController::hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform) { - Q_UNUSED(event); - Q_UNUSED(transform); + Q_UNUSED(event) + Q_UNUSED(transform) if (!m_model || !m_view) { return false; @@ -983,15 +1029,15 @@ bool KItemListController::hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const bool KItemListController::wheelEvent(QGraphicsSceneWheelEvent* event, const QTransform& transform) { - Q_UNUSED(event); - Q_UNUSED(transform); + Q_UNUSED(event) + Q_UNUSED(transform) return false; } bool KItemListController::resizeEvent(QGraphicsSceneResizeEvent* event, const QTransform& transform) { - Q_UNUSED(event); - Q_UNUSED(transform); + Q_UNUSED(event) + Q_UNUSED(transform) return false; } @@ -1170,11 +1216,13 @@ void KItemListController::startDragging() const QPixmap pixmap = m_view->createDragPixmap(selectedItems); drag->setPixmap(pixmap); - const QPoint hotSpot(pixmap.width() / 2, 0); + const QPoint hotSpot((pixmap.width() / pixmap.devicePixelRatio()) / 2, 0); drag->setHotSpot(hotSpot); - drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::CopyAction); - QAccessible::updateAccessibility(view(), 0, QAccessible::DragDropStart); + drag->exec(Qt::MoveAction | Qt::CopyAction | Qt::LinkAction, Qt::MoveAction); + + QAccessibleEvent accessibilityEvent(view(), QAccessible::DragDropStart); + QAccessible::updateAccessibility(&accessibilityEvent); } KItemListWidget* KItemListController::hoveredWidget() const @@ -1187,7 +1235,7 @@ KItemListWidget* KItemListController::hoveredWidget() const } } - return 0; + return nullptr; } KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const @@ -1204,7 +1252,7 @@ KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const } } - return 0; + return nullptr; } void KItemListController::updateKeyboardAnchor()