mirror of
https://invent.kde.org/system/dolphin
synced 2024-10-28 03:21:56 +00:00
Improve Touch support
With this patch dolphin now supports the following touch gestures: * Tap gesture to interact/open with directories, files and so on * TapAndHold and release gesture for access to the context menu (main window, panel folder, places and information) * TapAndHold and moving gesture for drag and drop action (main windows, panel folder and places) * pinch gesture for zoom in main window * kinetic scrolling (QScroller) for main window, panel folder, panel places, panel information, setting preview and service * two fingers swipe gesture to left, right and up as shortcut to navigate back, forward and up * two finger tap gesture to toggle item selection, similar to Ctrl and left mouse click FEATURE: 385066 FIXED-IN: 20.11.80 You are currently rebasing branch 'touch' on '85241a924'.
This commit is contained in:
parent
d899c2b401
commit
d7b33b76a1
|
@ -90,6 +90,8 @@ set(dolphinprivate_LIB_SRCS
|
|||
kitemviews/private/kitemlistviewanimation.cpp
|
||||
kitemviews/private/kitemlistviewlayouter.cpp
|
||||
kitemviews/private/kpixmapmodifier.cpp
|
||||
kitemviews/private/ktwofingerswipe.cpp
|
||||
kitemviews/private/ktwofingertap.cpp
|
||||
settings/applyviewpropsjob.cpp
|
||||
settings/viewmodes/viewmodesettings.cpp
|
||||
settings/viewpropertiesdialog.cpp
|
||||
|
|
|
@ -2095,6 +2095,8 @@ void DolphinMainWindow::connectViewSignals(DolphinViewContainer* container)
|
|||
this, &DolphinMainWindow::goForward);
|
||||
connect(view, &DolphinView::urlActivated,
|
||||
this, &DolphinMainWindow::handleUrl);
|
||||
connect(view, &DolphinView::goUpRequested,
|
||||
this, &DolphinMainWindow::goUp);
|
||||
|
||||
const KUrlNavigator* navigator = container->urlNavigator();
|
||||
connect(navigator, &KUrlNavigator::urlChanged,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QScrollBar>
|
||||
#include <QScroller>
|
||||
#include <QStyleOption>
|
||||
|
||||
/**
|
||||
|
@ -54,7 +55,8 @@ KItemListContainer::KItemListContainer(KItemListController* controller, QWidget*
|
|||
QAbstractScrollArea(parent),
|
||||
m_controller(controller),
|
||||
m_horizontalSmoothScroller(nullptr),
|
||||
m_verticalSmoothScroller(nullptr)
|
||||
m_verticalSmoothScroller(nullptr),
|
||||
m_scroller(nullptr)
|
||||
{
|
||||
Q_ASSERT(controller);
|
||||
controller->setParent(this);
|
||||
|
@ -76,6 +78,13 @@ KItemListContainer::KItemListContainer(KItemListController* controller, QWidget*
|
|||
this, &KItemListContainer::slotModelChanged);
|
||||
connect(controller, &KItemListController::viewChanged,
|
||||
this, &KItemListContainer::slotViewChanged);
|
||||
|
||||
m_scroller = QScroller::scroller(viewport());
|
||||
m_scroller->grabGesture(viewport());
|
||||
connect(controller, &KItemListController::scrollerStop,
|
||||
this, &KItemListContainer::stopScroller);
|
||||
connect(m_scroller, &QScroller::stateChanged,
|
||||
controller, &KItemListController::slotStateChanged);
|
||||
}
|
||||
|
||||
KItemListContainer::~KItemListContainer()
|
||||
|
@ -325,6 +334,11 @@ void KItemListContainer::updateItemOffsetScrollBar()
|
|||
}
|
||||
}
|
||||
|
||||
void KItemListContainer::stopScroller()
|
||||
{
|
||||
m_scroller->stop();
|
||||
}
|
||||
|
||||
void KItemListContainer::updateGeometries()
|
||||
{
|
||||
QRect rect = geometry();
|
||||
|
|
|
@ -17,6 +17,7 @@ class KItemListController;
|
|||
class KItemListSmoothScroller;
|
||||
class KItemListView;
|
||||
class KItemModelBase;
|
||||
class QScroller;
|
||||
|
||||
/**
|
||||
* @brief Provides a QWidget based scrolling view for a KItemListController.
|
||||
|
@ -57,6 +58,7 @@ private slots:
|
|||
void scrollTo(qreal offset);
|
||||
void updateScrollOffsetScrollBar();
|
||||
void updateItemOffsetScrollBar();
|
||||
void stopScroller();
|
||||
|
||||
private:
|
||||
void updateGeometries();
|
||||
|
@ -74,6 +76,7 @@ private:
|
|||
|
||||
KItemListSmoothScroller* m_horizontalSmoothScroller;
|
||||
KItemListSmoothScroller* m_verticalSmoothScroller;
|
||||
QScroller* m_scroller;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,11 +13,14 @@
|
|||
#include "kitemlistview.h"
|
||||
#include "private/kitemlistkeyboardsearchmanager.h"
|
||||
#include "private/kitemlistrubberband.h"
|
||||
#include "private/ktwofingerswipe.h"
|
||||
#include "private/ktwofingertap.h"
|
||||
#include "views/draganddrophelper.h"
|
||||
|
||||
#include <QAccessible>
|
||||
#include <QApplication>
|
||||
#include <QDrag>
|
||||
#include <QGesture>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneEvent>
|
||||
#include <QGraphicsView>
|
||||
|
@ -29,6 +32,11 @@ KItemListController::KItemListController(KItemModelBase* model, KItemListView* v
|
|||
m_singleClickActivationEnforced(false),
|
||||
m_selectionTogglePressed(false),
|
||||
m_clearSelectionIfItemsAreNotDragged(false),
|
||||
m_isSwipeGesture(false),
|
||||
m_dragActionOrRightClick(false),
|
||||
m_scrollerIsScrolling(false),
|
||||
m_pinchGestureInProgress(false),
|
||||
m_mousePress(false),
|
||||
m_selectionBehavior(NoSelection),
|
||||
m_autoActivationBehavior(ActivationAndExpansion),
|
||||
m_mouseDoubleClickAction(ActivateItemOnly),
|
||||
|
@ -39,6 +47,9 @@ KItemListController::KItemListController(KItemModelBase* model, KItemListView* v
|
|||
m_pressedIndex(-1),
|
||||
m_pressedMousePos(),
|
||||
m_autoActivationTimer(nullptr),
|
||||
m_swipeGesture(Qt::CustomGesture),
|
||||
m_twoFingerTapGesture(Qt::CustomGesture),
|
||||
m_lastSource(Qt::MouseEventNotSynthesized),
|
||||
m_oldSelection(),
|
||||
m_keyboardAnchorIndex(-1),
|
||||
m_keyboardAnchorPos(0)
|
||||
|
@ -57,6 +68,14 @@ KItemListController::KItemListController(KItemModelBase* model, KItemListView* v
|
|||
|
||||
setModel(model);
|
||||
setView(view);
|
||||
|
||||
m_swipeGesture = QGestureRecognizer::registerRecognizer(new KTwoFingerSwipeRecognizer());
|
||||
m_twoFingerTapGesture = QGestureRecognizer::registerRecognizer(new KTwoFingerTapRecognizer());
|
||||
view->grabGesture(m_swipeGesture);
|
||||
view->grabGesture(m_twoFingerTapGesture);
|
||||
view->grabGesture(Qt::TapGesture);
|
||||
view->grabGesture(Qt::TapAndHoldGesture);
|
||||
view->grabGesture(Qt::PinchGesture);
|
||||
}
|
||||
|
||||
KItemListController::~KItemListController()
|
||||
|
@ -517,13 +536,19 @@ bool KItemListController::inputMethodEvent(QInputMethodEvent* event)
|
|||
|
||||
bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
|
||||
{
|
||||
m_mousePress = true;
|
||||
m_lastSource = event->source();
|
||||
|
||||
if (event->source() == Qt::MouseEventSynthesizedByQt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pressedMousePos = transform.map(event->pos());
|
||||
m_pressedIndex = m_view->itemAt(m_pressedMousePos);
|
||||
emit mouseButtonPressed(m_pressedIndex, event->buttons());
|
||||
|
||||
if (event->buttons() & (Qt::BackButton | Qt::ForwardButton)) {
|
||||
// Do not select items when clicking the back/forward buttons, see
|
||||
|
@ -531,135 +556,12 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
|
|||
return true;
|
||||
}
|
||||
|
||||
if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) {
|
||||
m_selectionManager->endAnchoredSelection();
|
||||
m_selectionManager->setCurrentItem(m_pressedIndex);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
return true;
|
||||
const Qt::MouseButtons buttons = event->buttons();
|
||||
if (!onPress(event->screenPos(), event->pos(), event->modifiers(), buttons)) {
|
||||
startRubberBand();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_selectionTogglePressed = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos);
|
||||
if (m_selectionTogglePressed) {
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
|
||||
// The previous anchored selection has been finished already in
|
||||
// KItemListSelectionManager::setSelected(). We can safely change
|
||||
// the current item and start a new anchored selection now.
|
||||
m_selectionManager->setCurrentItem(m_pressedIndex);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool shiftPressed = event->modifiers() & Qt::ShiftModifier;
|
||||
const bool controlPressed = event->modifiers() & Qt::ControlModifier;
|
||||
|
||||
// The previous selection is cleared if either
|
||||
// 1. The selection mode is SingleSelection, or
|
||||
// 2. the selection mode is MultiSelection, and *none* of the following conditions are met:
|
||||
// a) Shift or Control are pressed.
|
||||
// b) The clicked item is selected already. In that case, the user might want to:
|
||||
// - start dragging multiple items, or
|
||||
// - open the context menu and perform an action for all selected items.
|
||||
const bool shiftOrControlPressed = shiftPressed || controlPressed;
|
||||
const bool pressedItemAlreadySelected = m_pressedIndex >= 0 && m_selectionManager->isSelected(m_pressedIndex);
|
||||
const bool clearSelection = m_selectionBehavior == SingleSelection ||
|
||||
(!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 (m_selectionManager->selectedItems().count() == 1 && m_view->isAboveText(m_pressedIndex, m_pressedMousePos)) {
|
||||
emit selectedItemTextPressed(m_pressedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!shiftPressed) {
|
||||
// Finish the anchored selection before the current index is changed
|
||||
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);
|
||||
|
||||
switch (m_selectionBehavior) {
|
||||
case NoSelection:
|
||||
break;
|
||||
|
||||
case SingleSelection:
|
||||
m_selectionManager->setSelected(m_pressedIndex);
|
||||
break;
|
||||
|
||||
case MultiSelection:
|
||||
if (controlPressed && !shiftPressed) {
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
} else if (!shiftPressed || !m_selectionManager->isAnchoredSelectionActive()) {
|
||||
// Select the pressed item and start a new anchored selection
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Select);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
emit itemContextMenuRequested(m_pressedIndex, event->screenPos());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
const QRectF headerBounds = m_view->headerBoundaries();
|
||||
if (headerBounds.contains(event->pos())) {
|
||||
emit headerContextMenuRequested(event->screenPos());
|
||||
} else {
|
||||
emit viewContextMenuRequested(event->screenPos());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_selectionBehavior == MultiSelection) {
|
||||
QPointF startPos = m_pressedMousePos;
|
||||
if (m_view->scrollOrientation() == Qt::Vertical) {
|
||||
startPos.ry() += m_view->scrollOffset();
|
||||
if (m_view->itemSize().width() < 0) {
|
||||
// Use a special rubberband for views that have only one column and
|
||||
// expand the rubberband to use the whole width of the view.
|
||||
startPos.setX(0);
|
||||
}
|
||||
} else {
|
||||
startPos.rx() += m_view->scrollOffset();
|
||||
}
|
||||
|
||||
m_oldSelection = m_selectionManager->selectedItems();
|
||||
KItemListRubberBand* rubberBand = m_view->rubberBand();
|
||||
rubberBand->setStartPosition(startPos);
|
||||
rubberBand->setEndPosition(startPos);
|
||||
rubberBand->setActive(true);
|
||||
connect(rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListController::slotRubberBandChanged);
|
||||
m_view->setAutoScroll(true);
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
|
||||
|
@ -668,6 +570,14 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (m_view->m_tapAndHoldIndicator->isActive()) {
|
||||
m_view->m_tapAndHoldIndicator->setActive(false);
|
||||
}
|
||||
|
||||
if (event->source() == Qt::MouseEventSynthesizedByQt && !m_dragActionOrRightClick) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_pressedIndex >= 0) {
|
||||
// Check whether a dragging should be started
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
|
@ -683,8 +593,8 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const
|
|||
// -> the selection should not be cleared when the mouse button is released.
|
||||
m_clearSelectionIfItemsAreNotDragged = false;
|
||||
}
|
||||
|
||||
startDragging();
|
||||
m_mousePress = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -720,75 +630,24 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const
|
|||
|
||||
bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
|
||||
{
|
||||
m_mousePress = false;
|
||||
|
||||
if (!m_view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_view->m_tapAndHoldIndicator->isActive()) {
|
||||
m_view->m_tapAndHoldIndicator->setActive(false);
|
||||
}
|
||||
|
||||
KItemListRubberBand* rubberBand = m_view->rubberBand();
|
||||
if (event->source() == Qt::MouseEventSynthesizedByQt && !rubberBand->isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
emit mouseButtonReleased(m_pressedIndex, event->buttons());
|
||||
|
||||
const bool isAboveSelectionToggle = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos);
|
||||
if (isAboveSelectionToggle) {
|
||||
m_selectionTogglePressed = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isAboveSelectionToggle && m_selectionTogglePressed) {
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
|
||||
m_selectionTogglePressed = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool shiftOrControlPressed = event->modifiers() & Qt::ShiftModifier ||
|
||||
event->modifiers() & Qt::ControlModifier;
|
||||
|
||||
KItemListRubberBand* rubberBand = m_view->rubberBand();
|
||||
if (rubberBand->isActive()) {
|
||||
disconnect(rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListController::slotRubberBandChanged);
|
||||
rubberBand->setActive(false);
|
||||
m_oldSelection.clear();
|
||||
m_view->setAutoScroll(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 (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)) {
|
||||
const bool expanded = m_model->isExpanded(index);
|
||||
m_model->setExpanded(index, !expanded);
|
||||
|
||||
emit itemExpansionToggleClicked(index);
|
||||
emitItemActivated = false;
|
||||
} else if (shiftOrControlPressed) {
|
||||
// The mouse click should only update the selection, not trigger the item
|
||||
emitItemActivated = false;
|
||||
} else if (!(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced)) {
|
||||
emitItemActivated = false;
|
||||
}
|
||||
if (emitItemActivated) {
|
||||
emit itemActivated(index);
|
||||
}
|
||||
} else if (event->button() & Qt::MiddleButton) {
|
||||
emit itemMiddleClicked(index);
|
||||
}
|
||||
}
|
||||
|
||||
m_pressedMousePos = QPointF();
|
||||
m_pressedIndex = -1;
|
||||
m_clearSelectionIfItemsAreNotDragged = false;
|
||||
return false;
|
||||
return onRelease(transform.map(event->pos()), event->modifiers(), event->button(), false);
|
||||
}
|
||||
|
||||
bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
|
||||
|
@ -1001,6 +860,8 @@ bool KItemListController::hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const
|
|||
Q_UNUSED(event)
|
||||
Q_UNUSED(transform)
|
||||
|
||||
m_mousePress = false;
|
||||
|
||||
if (!m_model || !m_view) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1028,6 +889,202 @@ bool KItemListController::resizeEvent(QGraphicsSceneResizeEvent* event, const QT
|
|||
return false;
|
||||
}
|
||||
|
||||
bool KItemListController::gestureEvent(QGestureEvent* event, const QTransform& transform)
|
||||
{
|
||||
if (!m_view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//you can touch on different views at the same time, but only one QWidget gets a mousePressEvent
|
||||
//we use this to get the right QWidget
|
||||
//the only exception is a tap gesture with state GestureStarted, we need to reset some variable
|
||||
if (!m_mousePress) {
|
||||
if (QGesture* tap = event->gesture(Qt::TapGesture)) {
|
||||
QTapGesture* tapGesture = static_cast<QTapGesture*>(tap);
|
||||
if (tapGesture->state() == Qt::GestureStarted) {
|
||||
tapTriggered(tapGesture, transform);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool accepted = false;
|
||||
|
||||
if (QGesture* tap = event->gesture(Qt::TapGesture)) {
|
||||
tapTriggered(static_cast<QTapGesture*>(tap), transform);
|
||||
accepted = true;
|
||||
}
|
||||
if (event->gesture(Qt::TapAndHoldGesture)) {
|
||||
tapAndHoldTriggered(event, transform);
|
||||
accepted = true;
|
||||
}
|
||||
if (event->gesture(Qt::PinchGesture)) {
|
||||
pinchTriggered(event, transform);
|
||||
accepted = true;
|
||||
}
|
||||
if (event->gesture(m_swipeGesture)) {
|
||||
swipeTriggered(event, transform);
|
||||
accepted = true;
|
||||
}
|
||||
if (event->gesture(m_twoFingerTapGesture)) {
|
||||
twoFingerTapTriggered(event, transform);
|
||||
accepted = true;
|
||||
}
|
||||
return accepted;
|
||||
}
|
||||
|
||||
void KItemListController::tapTriggered(QTapGesture* tap, const QTransform& transform)
|
||||
{
|
||||
static bool scrollerWasActive = false;
|
||||
|
||||
if (tap->state() == Qt::GestureStarted) {
|
||||
m_dragActionOrRightClick = false;
|
||||
m_isSwipeGesture = false;
|
||||
m_pinchGestureInProgress = false;
|
||||
m_lastSource = Qt::MouseEventSynthesizedByQt;
|
||||
scrollerWasActive = m_scrollerIsScrolling;
|
||||
}
|
||||
|
||||
if (tap->state() == Qt::GestureFinished) {
|
||||
m_mousePress = false;
|
||||
|
||||
//if at the moment of the gesture start the QScroller was active, the user made the tap
|
||||
//to stop the QScroller and not to tap on an item
|
||||
if (scrollerWasActive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_view->m_tapAndHoldIndicator->isActive()) {
|
||||
m_view->m_tapAndHoldIndicator->setActive(false);
|
||||
}
|
||||
|
||||
m_pressedMousePos = transform.map(tap->position());
|
||||
m_pressedIndex = m_view->itemAt(m_pressedMousePos);
|
||||
|
||||
if (m_dragActionOrRightClick) {
|
||||
onPress(tap->hotSpot().toPoint(), tap->position().toPoint(), Qt::NoModifier, Qt::RightButton);
|
||||
onRelease(transform.map(tap->position()), Qt::NoModifier, Qt::RightButton, false);
|
||||
m_dragActionOrRightClick = false;
|
||||
}
|
||||
else {
|
||||
onPress(tap->hotSpot().toPoint(), tap->position().toPoint(), Qt::NoModifier, Qt::LeftButton);
|
||||
onRelease(transform.map(tap->position()), Qt::NoModifier, Qt::LeftButton, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KItemListController::tapAndHoldTriggered(QGestureEvent* event, const QTransform& transform)
|
||||
{
|
||||
|
||||
//the Qt TabAndHold gesture is triggerable with a mouse click, we don't want this
|
||||
if (m_lastSource == Qt::MouseEventNotSynthesized) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QTapAndHoldGesture* tap = static_cast<QTapAndHoldGesture*>(event->gesture(Qt::TapAndHoldGesture));
|
||||
if (tap->state() == Qt::GestureFinished) {
|
||||
//if a pinch gesture is in progress we don't want a TabAndHold gesture
|
||||
if (m_pinchGestureInProgress) {
|
||||
return;
|
||||
}
|
||||
m_pressedMousePos = transform.map(event->mapToGraphicsScene(tap->position()));
|
||||
m_pressedIndex = m_view->itemAt(m_pressedMousePos);
|
||||
|
||||
if (m_pressedIndex >= 0 && !m_selectionManager->isSelected(m_pressedIndex)) {
|
||||
m_selectionManager->clearSelection();
|
||||
m_selectionManager->setSelected(m_pressedIndex);
|
||||
} else if (m_pressedIndex == -1) {
|
||||
m_selectionManager->clearSelection();
|
||||
startRubberBand();
|
||||
}
|
||||
|
||||
emit scrollerStop();
|
||||
|
||||
m_view->m_tapAndHoldIndicator->setStartPosition(m_pressedMousePos);
|
||||
m_view->m_tapAndHoldIndicator->setActive(true);
|
||||
|
||||
m_dragActionOrRightClick = true;
|
||||
}
|
||||
}
|
||||
|
||||
void KItemListController::pinchTriggered(QGestureEvent* event, const QTransform& transform)
|
||||
{
|
||||
Q_UNUSED(transform)
|
||||
|
||||
const QPinchGesture* pinch = static_cast<QPinchGesture*>(event->gesture(Qt::PinchGesture));
|
||||
const qreal sensitivityModifier = 0.2;
|
||||
static qreal counter = 0;
|
||||
|
||||
if (pinch->state() == Qt::GestureStarted) {
|
||||
m_pinchGestureInProgress = true;
|
||||
counter = 0;
|
||||
}
|
||||
if (pinch->state() == Qt::GestureUpdated) {
|
||||
//if a swipe gesture was recognized or in progress, we don't want a pinch gesture to change the zoom
|
||||
if (m_isSwipeGesture) {
|
||||
return;
|
||||
}
|
||||
counter = counter + (pinch->scaleFactor() - 1);
|
||||
if (counter >= sensitivityModifier) {
|
||||
emit increaseZoom();
|
||||
counter = 0;
|
||||
} else if (counter <= -sensitivityModifier) {
|
||||
emit decreaseZoom();
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KItemListController::swipeTriggered(QGestureEvent* event, const QTransform& transform)
|
||||
{
|
||||
Q_UNUSED(transform)
|
||||
|
||||
const KTwoFingerSwipe* swipe = static_cast<KTwoFingerSwipe*>(event->gesture(m_swipeGesture));
|
||||
|
||||
if (!swipe) {
|
||||
return;
|
||||
}
|
||||
if (swipe->state() == Qt::GestureStarted) {
|
||||
m_isSwipeGesture = true;
|
||||
}
|
||||
|
||||
if (swipe->state() == Qt::GestureCanceled) {
|
||||
m_isSwipeGesture = false;
|
||||
}
|
||||
|
||||
if (swipe->state() == Qt::GestureFinished) {
|
||||
emit scrollerStop();
|
||||
|
||||
if (swipe->swipeAngle() <= 20 || swipe->swipeAngle() >= 340) {
|
||||
emit mouseButtonPressed(m_pressedIndex, Qt::BackButton);
|
||||
} else if (swipe->swipeAngle() <= 200 && swipe->swipeAngle() >= 160) {
|
||||
emit mouseButtonPressed(m_pressedIndex, Qt::ForwardButton);
|
||||
} else if (swipe->swipeAngle() <= 110 && swipe->swipeAngle() >= 60) {
|
||||
emit swipeUp();
|
||||
}
|
||||
m_isSwipeGesture = true;
|
||||
}
|
||||
}
|
||||
|
||||
void KItemListController::twoFingerTapTriggered(QGestureEvent* event, const QTransform& transform)
|
||||
{
|
||||
const KTwoFingerTap* twoTap = static_cast<KTwoFingerTap*>(event->gesture(m_twoFingerTapGesture));
|
||||
|
||||
if (!twoTap) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (twoTap->state() == Qt::GestureStarted) {
|
||||
m_pressedMousePos = transform.map(twoTap->pos());
|
||||
m_pressedIndex = m_view->itemAt(m_pressedMousePos);
|
||||
if (m_pressedIndex >= 0) {
|
||||
onPress(twoTap->screenPos().toPoint(), twoTap->pos().toPoint(), Qt::ControlModifier, Qt::LeftButton);
|
||||
onRelease(transform.map(twoTap->pos()), Qt::ControlModifier, Qt::LeftButton, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool KItemListController::processEvent(QEvent* event, const QTransform& transform)
|
||||
{
|
||||
if (!event) {
|
||||
|
@ -1065,6 +1122,8 @@ bool KItemListController::processEvent(QEvent* event, const QTransform& transfor
|
|||
return hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent*>(event), QTransform());
|
||||
case QEvent::GraphicsSceneResize:
|
||||
return resizeEvent(static_cast<QGraphicsSceneResizeEvent*>(event), transform);
|
||||
case QEvent::Gesture:
|
||||
return gestureEvent(static_cast<QGestureEvent*>(event), transform);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1345,3 +1404,219 @@ void KItemListController::updateExtendedSelectionRegion()
|
|||
}
|
||||
}
|
||||
|
||||
bool KItemListController::onPress(const QPoint& screenPos, const QPointF& pos, const Qt::KeyboardModifiers modifiers, const Qt::MouseButtons buttons)
|
||||
{
|
||||
emit mouseButtonPressed(m_pressedIndex, buttons);
|
||||
|
||||
if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) {
|
||||
m_selectionManager->endAnchoredSelection();
|
||||
m_selectionManager->setCurrentItem(m_pressedIndex);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
m_selectionTogglePressed = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos);
|
||||
if (m_selectionTogglePressed) {
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
|
||||
// The previous anchored selection has been finished already in
|
||||
// KItemListSelectionManager::setSelected(). We can safely change
|
||||
// the current item and start a new anchored selection now.
|
||||
m_selectionManager->setCurrentItem(m_pressedIndex);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool shiftPressed = modifiers & Qt::ShiftModifier;
|
||||
const bool controlPressed = modifiers & Qt::ControlModifier;
|
||||
|
||||
// The previous selection is cleared if either
|
||||
// 1. The selection mode is SingleSelection, or
|
||||
// 2. the selection mode is MultiSelection, and *none* of the following conditions are met:
|
||||
// a) Shift or Control are pressed.
|
||||
// b) The clicked item is selected already. In that case, the user might want to:
|
||||
// - start dragging multiple items, or
|
||||
// - open the context menu and perform an action for all selected items.
|
||||
const bool shiftOrControlPressed = shiftPressed || controlPressed;
|
||||
const bool pressedItemAlreadySelected = m_pressedIndex >= 0 && m_selectionManager->isSelected(m_pressedIndex);
|
||||
const bool clearSelection = m_selectionBehavior == SingleSelection ||
|
||||
(!shiftOrControlPressed && !pressedItemAlreadySelected);
|
||||
if (clearSelection) {
|
||||
m_selectionManager->clearSelection();
|
||||
} else if (pressedItemAlreadySelected && !shiftOrControlPressed && (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 (m_selectionManager->selectedItems().count() == 1 && m_view->isAboveText(m_pressedIndex, m_pressedMousePos)) {
|
||||
emit selectedItemTextPressed(m_pressedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!shiftPressed) {
|
||||
// Finish the anchored selection before the current index is changed
|
||||
m_selectionManager->endAnchoredSelection();
|
||||
}
|
||||
|
||||
if (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);
|
||||
|
||||
switch (m_selectionBehavior) {
|
||||
case NoSelection:
|
||||
break;
|
||||
|
||||
case SingleSelection:
|
||||
m_selectionManager->setSelected(m_pressedIndex);
|
||||
break;
|
||||
|
||||
case MultiSelection:
|
||||
if (controlPressed && !shiftPressed) {
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
} else if (!shiftPressed || !m_selectionManager->isAnchoredSelectionActive()) {
|
||||
// Select the pressed item and start a new anchored selection
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Select);
|
||||
m_selectionManager->beginAnchoredSelection(m_pressedIndex);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if (buttons & Qt::RightButton) {
|
||||
emit itemContextMenuRequested(m_pressedIndex, screenPos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (buttons & Qt::RightButton) {
|
||||
const QRectF headerBounds = m_view->headerBoundaries();
|
||||
if (headerBounds.contains(pos)) {
|
||||
emit headerContextMenuRequested(screenPos);
|
||||
} else {
|
||||
emit viewContextMenuRequested(screenPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KItemListController::onRelease(const QPointF& pos, const Qt::KeyboardModifiers modifiers, const Qt::MouseButtons buttons, bool touch)
|
||||
{
|
||||
const bool isAboveSelectionToggle = m_view->isAboveSelectionToggle(m_pressedIndex, m_pressedMousePos);
|
||||
if (isAboveSelectionToggle) {
|
||||
m_selectionTogglePressed = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isAboveSelectionToggle && m_selectionTogglePressed) {
|
||||
m_selectionManager->setSelected(m_pressedIndex, 1, KItemListSelectionManager::Toggle);
|
||||
m_selectionTogglePressed = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool shiftOrControlPressed = modifiers & Qt::ShiftModifier ||
|
||||
modifiers & Qt::ControlModifier;
|
||||
|
||||
KItemListRubberBand* rubberBand = m_view->rubberBand();
|
||||
if (rubberBand->isActive()) {
|
||||
disconnect(rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListController::slotRubberBandChanged);
|
||||
rubberBand->setActive(false);
|
||||
m_oldSelection.clear();
|
||||
m_view->setAutoScroll(false);
|
||||
}
|
||||
|
||||
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 (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 (buttons & Qt::LeftButton) {
|
||||
bool emitItemActivated = true;
|
||||
if (m_view->isAboveExpansionToggle(index, pos)) {
|
||||
const bool expanded = m_model->isExpanded(index);
|
||||
m_model->setExpanded(index, !expanded);
|
||||
|
||||
emit itemExpansionToggleClicked(index);
|
||||
emitItemActivated = false;
|
||||
} else if (shiftOrControlPressed) {
|
||||
// The mouse click should only update the selection, not trigger the item
|
||||
emitItemActivated = false;
|
||||
} else if (!(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced)) {
|
||||
if (touch) {
|
||||
emitItemActivated = true;
|
||||
} else {
|
||||
emitItemActivated = false;
|
||||
}
|
||||
}
|
||||
if (emitItemActivated) {
|
||||
emit itemActivated(index);
|
||||
}
|
||||
} else if (buttons & Qt::MiddleButton) {
|
||||
emit itemMiddleClicked(index);
|
||||
}
|
||||
}
|
||||
|
||||
m_pressedMousePos = QPointF();
|
||||
m_pressedIndex = -1;
|
||||
m_clearSelectionIfItemsAreNotDragged = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void KItemListController::startRubberBand()
|
||||
{
|
||||
if (m_selectionBehavior == MultiSelection) {
|
||||
QPointF startPos = m_pressedMousePos;
|
||||
if (m_view->scrollOrientation() == Qt::Vertical) {
|
||||
startPos.ry() += m_view->scrollOffset();
|
||||
if (m_view->itemSize().width() < 0) {
|
||||
// Use a special rubberband for views that have only one column and
|
||||
// expand the rubberband to use the whole width of the view.
|
||||
startPos.setX(0);
|
||||
}
|
||||
} else {
|
||||
startPos.rx() += m_view->scrollOffset();
|
||||
}
|
||||
|
||||
m_oldSelection = m_selectionManager->selectedItems();
|
||||
KItemListRubberBand* rubberBand = m_view->rubberBand();
|
||||
rubberBand->setStartPosition(startPos);
|
||||
rubberBand->setEndPosition(startPos);
|
||||
rubberBand->setActive(true);
|
||||
connect(rubberBand, &KItemListRubberBand::endPositionChanged, this, &KItemListController::slotRubberBandChanged);
|
||||
m_view->setAutoScroll(true);
|
||||
}
|
||||
}
|
||||
|
||||
void KItemListController::slotStateChanged(QScroller::State newState)
|
||||
{
|
||||
if (newState == QScroller::Scrolling) {
|
||||
m_scrollerIsScrolling = true;
|
||||
} else if (newState == QScroller::Inactive) {
|
||||
m_scrollerIsScrolling = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QPointF>
|
||||
#include <QScroller>
|
||||
|
||||
class QTimer;
|
||||
class KItemModelBase;
|
||||
|
@ -21,6 +22,7 @@ class KItemListKeyboardSearchManager;
|
|||
class KItemListSelectionManager;
|
||||
class KItemListView;
|
||||
class KItemListWidget;
|
||||
class QGestureEvent;
|
||||
class QGraphicsSceneHoverEvent;
|
||||
class QGraphicsSceneDragDropEvent;
|
||||
class QGraphicsSceneMouseEvent;
|
||||
|
@ -28,6 +30,7 @@ class QGraphicsSceneResizeEvent;
|
|||
class QGraphicsSceneWheelEvent;
|
||||
class QInputMethodEvent;
|
||||
class QKeyEvent;
|
||||
class QTapGesture;
|
||||
class QTransform;
|
||||
|
||||
/**
|
||||
|
@ -208,6 +211,14 @@ signals:
|
|||
|
||||
void selectedItemTextPressed(int index);
|
||||
|
||||
void scrollerStop();
|
||||
void increaseZoom();
|
||||
void decreaseZoom();
|
||||
void swipeUp();
|
||||
|
||||
public slots:
|
||||
void slotStateChanged(QScroller::State newState);
|
||||
|
||||
private slots:
|
||||
void slotViewScrollOffsetChanged(qreal current, qreal previous);
|
||||
|
||||
|
@ -289,11 +300,25 @@ private:
|
|||
bool hoverLeaveEvent(QGraphicsSceneHoverEvent* event, const QTransform& transform);
|
||||
bool wheelEvent(QGraphicsSceneWheelEvent* event, const QTransform& transform);
|
||||
bool resizeEvent(QGraphicsSceneResizeEvent* event, const QTransform& transform);
|
||||
bool gestureEvent(QGestureEvent* event, const QTransform& transform);
|
||||
void tapTriggered(QTapGesture* tap, const QTransform& transform);
|
||||
void tapAndHoldTriggered(QGestureEvent* event, const QTransform& transform);
|
||||
void pinchTriggered(QGestureEvent* event, const QTransform& transform);
|
||||
void swipeTriggered(QGestureEvent* event, const QTransform& transform);
|
||||
void twoFingerTapTriggered(QGestureEvent* event, const QTransform& transform);
|
||||
bool onPress(const QPoint& screenPos, const QPointF& pos, const Qt::KeyboardModifiers modifiers, const Qt::MouseButtons buttons);
|
||||
bool onRelease(const QPointF& pos, const Qt::KeyboardModifiers modifiers, const Qt::MouseButtons buttons, bool touch);
|
||||
void startRubberBand();
|
||||
|
||||
private:
|
||||
bool m_singleClickActivationEnforced;
|
||||
bool m_selectionTogglePressed;
|
||||
bool m_clearSelectionIfItemsAreNotDragged;
|
||||
bool m_isSwipeGesture;
|
||||
bool m_dragActionOrRightClick;
|
||||
bool m_scrollerIsScrolling;
|
||||
bool m_pinchGestureInProgress;
|
||||
bool m_mousePress;
|
||||
SelectionBehavior m_selectionBehavior;
|
||||
AutoActivationBehavior m_autoActivationBehavior;
|
||||
MouseDoubleClickAction m_mouseDoubleClickAction;
|
||||
|
@ -306,6 +331,10 @@ private:
|
|||
|
||||
QTimer* m_autoActivationTimer;
|
||||
|
||||
Qt::GestureType m_swipeGesture;
|
||||
Qt::GestureType m_twoFingerTapGesture;
|
||||
Qt::MouseEventSource m_lastSource;
|
||||
|
||||
/**
|
||||
* When starting a rubberband selection during a Shift- or Control-key has been
|
||||
* pressed the current selection should never be deleted. To be able to restore
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <QElapsedTimer>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QGraphicsView>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QStyleOptionRubberBand>
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -80,11 +81,13 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
|
|||
m_oldMaximumItemOffset(0),
|
||||
m_skipAutoScrollForRubberBand(false),
|
||||
m_rubberBand(nullptr),
|
||||
m_tapAndHoldIndicator(nullptr),
|
||||
m_mousePos(),
|
||||
m_autoScrollIncrement(0),
|
||||
m_autoScrollTimer(nullptr),
|
||||
m_header(nullptr),
|
||||
m_headerWidget(nullptr),
|
||||
m_indicatorAnimation(nullptr),
|
||||
m_dropIndicator()
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
|
@ -105,6 +108,23 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
|
|||
m_rubberBand = new KItemListRubberBand(this);
|
||||
connect(m_rubberBand, &KItemListRubberBand::activationChanged, this, &KItemListView::slotRubberBandActivationChanged);
|
||||
|
||||
m_tapAndHoldIndicator = new KItemListRubberBand(this);
|
||||
m_indicatorAnimation = new QPropertyAnimation(m_tapAndHoldIndicator, "endPosition", this);
|
||||
connect(m_tapAndHoldIndicator, &KItemListRubberBand::activationChanged, this, [this](bool active) {
|
||||
if (active) {
|
||||
m_indicatorAnimation->setDuration(150);
|
||||
m_indicatorAnimation->setStartValue(QPointF(1, 1));
|
||||
m_indicatorAnimation->setEndValue(QPointF(40, 40));
|
||||
m_indicatorAnimation->start();
|
||||
}
|
||||
update();
|
||||
});
|
||||
connect(m_tapAndHoldIndicator, &KItemListRubberBand::endPositionChanged, this, [this]() {
|
||||
if (m_tapAndHoldIndicator->isActive()) {
|
||||
update();
|
||||
}
|
||||
});
|
||||
|
||||
m_headerWidget = new KItemListHeaderWidget(this);
|
||||
m_headerWidget->setVisible(false);
|
||||
|
||||
|
@ -658,6 +678,18 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
|
|||
style()->drawControl(QStyle::CE_RubberBand, &opt, painter);
|
||||
}
|
||||
|
||||
if (m_tapAndHoldIndicator->isActive()) {
|
||||
const QPointF indicatorSize = m_tapAndHoldIndicator->endPosition();
|
||||
const QRectF rubberBandRect = QRectF(m_tapAndHoldIndicator->startPosition() - indicatorSize,
|
||||
(m_tapAndHoldIndicator->startPosition()) + indicatorSize).normalized();
|
||||
QStyleOptionRubberBand opt;
|
||||
initStyleOption(&opt);
|
||||
opt.shape = QRubberBand::Rectangle;
|
||||
opt.opaque = false;
|
||||
opt.rect = rubberBandRect.toRect();
|
||||
style()->drawControl(QStyle::CE_RubberBand, &opt, painter);
|
||||
}
|
||||
|
||||
if (!m_dropIndicator.isEmpty()) {
|
||||
const QRectF r = m_dropIndicator.toRect();
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class KItemListWidget;
|
|||
class KItemListWidgetInformant;
|
||||
class KItemListWidgetCreatorBase;
|
||||
class QTimer;
|
||||
class QPropertyAnimation;
|
||||
|
||||
/**
|
||||
* @brief Represents the view of an item-list.
|
||||
|
@ -727,6 +728,7 @@ private:
|
|||
|
||||
bool m_skipAutoScrollForRubberBand;
|
||||
KItemListRubberBand* m_rubberBand;
|
||||
KItemListRubberBand* m_tapAndHoldIndicator;
|
||||
|
||||
QPointF m_mousePos;
|
||||
int m_autoScrollIncrement;
|
||||
|
@ -735,6 +737,8 @@ private:
|
|||
KItemListHeader* m_header;
|
||||
KItemListHeaderWidget* m_headerWidget;
|
||||
|
||||
QPropertyAnimation* m_indicatorAnimation;
|
||||
|
||||
// When dragging items into the view where the sort-role of the model
|
||||
// is empty, a visual indicator should be shown during dragging where
|
||||
// the dropping will happen. This indicator is specified by an index
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
class DOLPHIN_EXPORT KItemListRubberBand : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QPointF endPosition MEMBER m_endPos READ endPosition WRITE setEndPosition)
|
||||
|
||||
public:
|
||||
explicit KItemListRubberBand(QObject* parent = nullptr);
|
||||
|
|
139
src/kitemviews/private/ktwofingerswipe.cpp
Normal file
139
src/kitemviews/private/ktwofingerswipe.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
// Self
|
||||
#include "ktwofingerswipe.h"
|
||||
|
||||
// Qt
|
||||
#include <QTouchEvent>
|
||||
#include <QLineF>
|
||||
|
||||
KTwoFingerSwipeRecognizer::KTwoFingerSwipeRecognizer() :
|
||||
QGestureRecognizer(),
|
||||
m_touchBeginnTimestamp(0),
|
||||
m_gestureAlreadyTriggered(false)
|
||||
{
|
||||
}
|
||||
|
||||
KTwoFingerSwipeRecognizer::~KTwoFingerSwipeRecognizer()
|
||||
{
|
||||
}
|
||||
|
||||
QGesture* KTwoFingerSwipeRecognizer::create(QObject*)
|
||||
{
|
||||
return static_cast<QGesture*>(new KTwoFingerSwipe());
|
||||
}
|
||||
|
||||
QGestureRecognizer::Result KTwoFingerSwipeRecognizer::recognize(QGesture* gesture, QObject* watched, QEvent* event)
|
||||
{
|
||||
Q_UNUSED(watched)
|
||||
|
||||
KTwoFingerSwipe* const kTwoFingerSwipe = static_cast<KTwoFingerSwipe*>(gesture);
|
||||
const QTouchEvent* touchEvent = static_cast<const QTouchEvent*>(event);
|
||||
|
||||
const int maxTimeFrameForSwipe = 90;
|
||||
const int minDistanceForSwipe = 30;
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin: {
|
||||
m_touchBeginnTimestamp = touchEvent->timestamp();
|
||||
m_gestureAlreadyTriggered = false;
|
||||
kTwoFingerSwipe->setHotSpot(touchEvent->touchPoints().first().startScreenPos());
|
||||
kTwoFingerSwipe->setPos(touchEvent->touchPoints().first().startPos());
|
||||
kTwoFingerSwipe->setScreenPos(touchEvent->touchPoints().first().startScreenPos());
|
||||
kTwoFingerSwipe->setScenePos(touchEvent->touchPoints().first().startScenePos());
|
||||
return MayBeGesture;
|
||||
}
|
||||
|
||||
case QEvent::TouchUpdate: {
|
||||
const qint64 now = touchEvent->timestamp();
|
||||
const qint64 elapsedTime = now - m_touchBeginnTimestamp;
|
||||
const QPointF distance = touchEvent->touchPoints().first().startPos() - touchEvent->touchPoints().first().pos();
|
||||
kTwoFingerSwipe->setHotSpot(touchEvent->touchPoints().first().startScreenPos());
|
||||
kTwoFingerSwipe->setPos(touchEvent->touchPoints().first().startPos());
|
||||
kTwoFingerSwipe->setScreenPos(touchEvent->touchPoints().first().startScreenPos());
|
||||
kTwoFingerSwipe->setScenePos(touchEvent->touchPoints().first().startScenePos());
|
||||
const QLineF ql = QLineF(touchEvent->touchPoints().first().startPos(), touchEvent->touchPoints().first().pos());
|
||||
kTwoFingerSwipe->setSwipeAngle(ql.angle());
|
||||
|
||||
if (touchEvent->touchPoints().size() > 2) {
|
||||
return CancelGesture;
|
||||
}
|
||||
|
||||
if (touchEvent->touchPoints().size() == 2) {
|
||||
if ((elapsedTime) > maxTimeFrameForSwipe) {
|
||||
return CancelGesture;
|
||||
}
|
||||
|
||||
if (distance.manhattanLength() >= minDistanceForSwipe &&
|
||||
(elapsedTime) <= maxTimeFrameForSwipe && !m_gestureAlreadyTriggered) {
|
||||
m_gestureAlreadyTriggered = true;
|
||||
return FinishGesture;
|
||||
} else if ((elapsedTime) <= maxTimeFrameForSwipe && !m_gestureAlreadyTriggered) {
|
||||
return TriggerGesture;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return Ignore;
|
||||
}
|
||||
return Ignore;
|
||||
}
|
||||
|
||||
KTwoFingerSwipe::KTwoFingerSwipe(QObject* parent) :
|
||||
QGesture(parent),
|
||||
m_pos(QPointF(-1, -1)),
|
||||
m_screenPos(QPointF(-1, -1)),
|
||||
m_scenePos(QPointF(-1, -1)),
|
||||
m_swipeAngle(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
KTwoFingerSwipe::~KTwoFingerSwipe()
|
||||
{
|
||||
}
|
||||
|
||||
QPointF KTwoFingerSwipe::pos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
void KTwoFingerSwipe::setPos(QPointF _pos)
|
||||
{
|
||||
m_pos = _pos;
|
||||
}
|
||||
|
||||
QPointF KTwoFingerSwipe::screenPos() const
|
||||
{
|
||||
return m_screenPos;
|
||||
}
|
||||
|
||||
void KTwoFingerSwipe::setScreenPos(QPointF _screenPos)
|
||||
{
|
||||
m_screenPos = _screenPos;
|
||||
}
|
||||
|
||||
QPointF KTwoFingerSwipe::scenePos() const
|
||||
{
|
||||
return m_scenePos;
|
||||
}
|
||||
|
||||
void KTwoFingerSwipe::setScenePos(QPointF _scenePos)
|
||||
{
|
||||
m_scenePos = _scenePos;
|
||||
}
|
||||
|
||||
qreal KTwoFingerSwipe::swipeAngle() const
|
||||
{
|
||||
return m_swipeAngle;
|
||||
}
|
||||
void KTwoFingerSwipe::setSwipeAngle(qreal _swipeAngle)
|
||||
{
|
||||
m_swipeAngle = _swipeAngle;
|
||||
}
|
||||
|
54
src/kitemviews/private/ktwofingerswipe.h
Normal file
54
src/kitemviews/private/ktwofingerswipe.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KTWOFINGERSWIPE_H
|
||||
#define KTWOFINGERSWIPE_H
|
||||
|
||||
#include "dolphin_export.h"
|
||||
// Qt
|
||||
#include <QGesture>
|
||||
#include <QGestureRecognizer>
|
||||
|
||||
class DOLPHIN_EXPORT KTwoFingerSwipe : public QGesture
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
|
||||
Q_PROPERTY(QPointF screenPos READ screenPos WRITE setScreenPos)
|
||||
Q_PROPERTY(QPointF scenePos READ scenePos WRITE setScenePos)
|
||||
Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle)
|
||||
public:
|
||||
explicit KTwoFingerSwipe(QObject* parent = nullptr);
|
||||
~KTwoFingerSwipe();
|
||||
QPointF pos() const;
|
||||
void setPos(QPointF pos);
|
||||
QPointF screenPos() const;
|
||||
void setScreenPos(QPointF screenPos);
|
||||
QPointF scenePos() const;
|
||||
void setScenePos(QPointF scenePos);
|
||||
qreal swipeAngle() const;
|
||||
void setSwipeAngle(qreal swipeAngle);
|
||||
private:
|
||||
QPointF m_pos;
|
||||
QPointF m_screenPos;
|
||||
QPointF m_scenePos;
|
||||
qreal m_swipeAngle;
|
||||
};
|
||||
|
||||
class DOLPHIN_EXPORT KTwoFingerSwipeRecognizer : public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
explicit KTwoFingerSwipeRecognizer();
|
||||
~KTwoFingerSwipeRecognizer();
|
||||
QGesture* create(QObject*) override;
|
||||
Result recognize(QGesture*, QObject*, QEvent*) override;
|
||||
private:
|
||||
Q_DISABLE_COPY( KTwoFingerSwipeRecognizer )
|
||||
qint64 m_touchBeginnTimestamp;
|
||||
bool m_gestureAlreadyTriggered;
|
||||
};
|
||||
|
||||
#endif /* KTWOFINGERSWIPE_H */
|
||||
|
119
src/kitemviews/private/ktwofingertap.cpp
Normal file
119
src/kitemviews/private/ktwofingertap.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
// Self
|
||||
#include "ktwofingertap.h"
|
||||
|
||||
// Qt
|
||||
#include <QTouchEvent>
|
||||
#include <QApplication>
|
||||
|
||||
KTwoFingerTapRecognizer::KTwoFingerTapRecognizer() :
|
||||
QGestureRecognizer(),
|
||||
m_gestureTriggered(false)
|
||||
{
|
||||
}
|
||||
|
||||
KTwoFingerTapRecognizer::~KTwoFingerTapRecognizer()
|
||||
{
|
||||
}
|
||||
|
||||
QGesture* KTwoFingerTapRecognizer::create(QObject*)
|
||||
{
|
||||
return static_cast<QGesture*>(new KTwoFingerTap());
|
||||
}
|
||||
|
||||
QGestureRecognizer::Result KTwoFingerTapRecognizer::recognize(QGesture* gesture, QObject* watched, QEvent* event)
|
||||
{
|
||||
Q_UNUSED(watched)
|
||||
|
||||
KTwoFingerTap* const kTwoFingerTap = static_cast<KTwoFingerTap*>(gesture);
|
||||
const QTouchEvent* touchEvent = static_cast<const QTouchEvent*>(event);
|
||||
|
||||
switch (event->type()) {
|
||||
case QEvent::TouchBegin: {
|
||||
kTwoFingerTap->setHotSpot(touchEvent->touchPoints().first().startScreenPos());
|
||||
kTwoFingerTap->setPos(touchEvent->touchPoints().first().startPos());
|
||||
kTwoFingerTap->setScreenPos(touchEvent->touchPoints().first().startScreenPos());
|
||||
kTwoFingerTap->setScenePos(touchEvent->touchPoints().first().startScenePos());
|
||||
m_gestureTriggered = false;
|
||||
return MayBeGesture;
|
||||
}
|
||||
|
||||
case QEvent::TouchUpdate: {
|
||||
|
||||
if (touchEvent->touchPoints().size() > 2) {
|
||||
m_gestureTriggered = false;
|
||||
return CancelGesture;
|
||||
}
|
||||
|
||||
if (touchEvent->touchPoints().size() == 2) {
|
||||
if ((touchEvent->touchPoints().first().startPos() - touchEvent->touchPoints().first().pos()).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
m_gestureTriggered = false;
|
||||
return CancelGesture;
|
||||
}
|
||||
if ((touchEvent->touchPoints().at(1).startPos() - touchEvent->touchPoints().at(1).pos()).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
m_gestureTriggered = false;
|
||||
return CancelGesture;
|
||||
}
|
||||
if (touchEvent->touchPointStates() & Qt::TouchPointPressed) {
|
||||
m_gestureTriggered = true;
|
||||
}
|
||||
if (touchEvent->touchPointStates() & Qt::TouchPointReleased && m_gestureTriggered) {
|
||||
m_gestureTriggered = false;
|
||||
return FinishGesture;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return Ignore;
|
||||
}
|
||||
return Ignore;
|
||||
}
|
||||
|
||||
KTwoFingerTap::KTwoFingerTap(QObject* parent) :
|
||||
QGesture(parent),
|
||||
m_pos(QPointF(-1, -1)),
|
||||
m_screenPos(QPointF(-1, -1)),
|
||||
m_scenePos(QPointF(-1, -1))
|
||||
{
|
||||
}
|
||||
|
||||
KTwoFingerTap::~KTwoFingerTap()
|
||||
{
|
||||
}
|
||||
|
||||
QPointF KTwoFingerTap::pos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
void KTwoFingerTap::setPos(QPointF _pos)
|
||||
{
|
||||
m_pos = _pos;
|
||||
}
|
||||
|
||||
QPointF KTwoFingerTap::screenPos() const
|
||||
{
|
||||
return m_screenPos;
|
||||
}
|
||||
|
||||
void KTwoFingerTap::setScreenPos(QPointF _screenPos)
|
||||
{
|
||||
m_screenPos = _screenPos;
|
||||
}
|
||||
|
||||
QPointF KTwoFingerTap::scenePos() const
|
||||
{
|
||||
return m_scenePos;
|
||||
}
|
||||
|
||||
void KTwoFingerTap::setScenePos(QPointF _scenePos)
|
||||
{
|
||||
m_scenePos = _scenePos;
|
||||
}
|
48
src/kitemviews/private/ktwofingertap.h
Normal file
48
src/kitemviews/private/ktwofingertap.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Steffen Hartleib <steffenhartleib@t-online.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef KTWOFINGERTAP_H
|
||||
#define KTWOFINGERTAP_H
|
||||
|
||||
#include <dolphin_export.h>
|
||||
// Qt
|
||||
#include <QGesture>
|
||||
#include <QGestureRecognizer>
|
||||
|
||||
class DOLPHIN_EXPORT KTwoFingerTap : public QGesture
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QPointF pos READ pos WRITE setPos)
|
||||
Q_PROPERTY(QPointF screenPos READ screenPos WRITE setScreenPos)
|
||||
Q_PROPERTY(QPointF scenePos READ scenePos WRITE setScenePos)
|
||||
public:
|
||||
explicit KTwoFingerTap(QObject* parent = nullptr);
|
||||
~KTwoFingerTap();
|
||||
QPointF pos() const;
|
||||
void setPos(QPointF pos);
|
||||
QPointF screenPos() const;
|
||||
void setScreenPos(QPointF screenPos);
|
||||
QPointF scenePos() const;
|
||||
void setScenePos(QPointF scenePos);
|
||||
private:
|
||||
QPointF m_pos;
|
||||
QPointF m_screenPos;
|
||||
QPointF m_scenePos;
|
||||
};
|
||||
|
||||
class DOLPHIN_EXPORT KTwoFingerTapRecognizer : public QGestureRecognizer
|
||||
{
|
||||
public:
|
||||
explicit KTwoFingerTapRecognizer();
|
||||
~KTwoFingerTapRecognizer();
|
||||
QGesture* create(QObject*) override;
|
||||
Result recognize(QGesture*, QObject*, QEvent*) override;
|
||||
private:
|
||||
Q_DISABLE_COPY(KTwoFingerTapRecognizer)
|
||||
bool m_gestureTriggered;
|
||||
};
|
||||
|
||||
#endif /* KTWOFINGERTAP_H */
|
|
@ -405,6 +405,7 @@ void InformationPanel::init()
|
|||
m_content = new InformationPanelContent(this);
|
||||
connect(m_content, &InformationPanelContent::urlActivated, this, &InformationPanel::urlActivated);
|
||||
connect(m_content, &InformationPanelContent::configurationFinished, this, [this]() { m_inConfigurationMode = false; });
|
||||
connect(m_content, &InformationPanelContent::contextMenuRequested, this, &InformationPanel::showContextMenu);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
|
|
@ -33,11 +33,13 @@
|
|||
#include <QTextLayout>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QScroller>
|
||||
#include <QStyle>
|
||||
#include <QPainter>
|
||||
#include <QBitmap>
|
||||
#include <QLinearGradient>
|
||||
#include <QPolygon>
|
||||
#include <QGesture>
|
||||
|
||||
#include "dolphin_informationpanelsettings.h"
|
||||
#include "phononwidget.h"
|
||||
|
@ -134,6 +136,7 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) :
|
|||
m_metaDataArea->setFrameShape(QFrame::NoFrame);
|
||||
|
||||
QWidget* viewport = m_metaDataArea->viewport();
|
||||
QScroller::grabGesture(viewport, QScroller::TouchGesture);
|
||||
viewport->installEventFilter(this);
|
||||
|
||||
layout->addWidget(m_preview);
|
||||
|
@ -144,6 +147,8 @@ InformationPanelContent::InformationPanelContent(QWidget* parent) :
|
|||
layout->addWidget(m_metaDataArea);
|
||||
layout->addWidget(m_configureButtons);
|
||||
|
||||
grabGesture(Qt::TapAndHoldGesture);
|
||||
|
||||
m_placesItemModel = new PlacesItemModel(this);
|
||||
}
|
||||
|
||||
|
@ -338,6 +343,33 @@ bool InformationPanelContent::eventFilter(QObject* obj, QEvent* event)
|
|||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
bool InformationPanelContent::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::Gesture) {
|
||||
gestureEvent(static_cast<QGestureEvent*>(event));
|
||||
return true;
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
bool InformationPanelContent::gestureEvent(QGestureEvent* event)
|
||||
{
|
||||
if (!underMouse()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QTapAndHoldGesture* tap = static_cast<QTapAndHoldGesture*>(event->gesture(Qt::TapAndHoldGesture));
|
||||
|
||||
if (tap) {
|
||||
if (tap->state() == Qt::GestureFinished) {
|
||||
emit contextMenuRequested(tap->position().toPoint());
|
||||
}
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InformationPanelContent::showIcon(const KFileItem& item)
|
||||
{
|
||||
m_outdatedPreviewTimer->stop();
|
||||
|
|
|
@ -23,6 +23,7 @@ class QDialogButtonBox;
|
|||
class QString;
|
||||
class QLabel;
|
||||
class QScrollArea;
|
||||
class QGestureEvent;
|
||||
|
||||
namespace KIO {
|
||||
class PreviewJob;
|
||||
|
@ -78,6 +79,7 @@ public:
|
|||
signals:
|
||||
void urlActivated( const QUrl& url );
|
||||
void configurationFinished();
|
||||
void contextMenuRequested(const QPoint& pos);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
|
@ -90,6 +92,8 @@ protected:
|
|||
/** @see QObject::eventFilter() */
|
||||
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||
|
||||
bool event(QEvent * event) override;
|
||||
|
||||
private slots:
|
||||
/**
|
||||
* Is invoked if no preview is available for the item. In this
|
||||
|
@ -131,6 +135,8 @@ private:
|
|||
*/
|
||||
void refreshPixmapView();
|
||||
|
||||
bool gestureEvent(QGestureEvent* event);
|
||||
|
||||
private:
|
||||
KFileItem m_item;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <QLabel>
|
||||
#include <QListView>
|
||||
#include <QPainter>
|
||||
#include <QScroller>
|
||||
#include <QShowEvent>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QSpinBox>
|
||||
|
@ -42,6 +43,7 @@ PreviewsSettingsPage::PreviewsSettingsPage(QWidget* parent) :
|
|||
QLabel* showPreviewsLabel = new QLabel(i18nc("@title:group", "Show previews in the view for:"), this);
|
||||
|
||||
m_listView = new QListView(this);
|
||||
QScroller::grabGesture(m_listView->viewport(), QScroller::TouchGesture);
|
||||
|
||||
ServiceItemDelegate* delegate = new ServiceItemDelegate(m_listView, m_listView);
|
||||
connect(delegate, &ServiceItemDelegate::requestServiceConfiguration,
|
||||
|
@ -56,6 +58,7 @@ PreviewsSettingsPage::PreviewsSettingsPage(QWidget* parent) :
|
|||
m_listView->setModel(proxyModel);
|
||||
m_listView->setItemDelegate(delegate);
|
||||
m_listView->setVerticalScrollMode(QListView::ScrollPerPixel);
|
||||
m_listView->setUniformItemSizes(true);
|
||||
|
||||
QLabel* localFileSizeLabel = new QLabel(i18n("Skip previews for local files above:"), this);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QScroller>
|
||||
#include <QShowEvent>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QLineEdit>
|
||||
|
@ -56,6 +57,8 @@ ServicesSettingsPage::ServicesSettingsPage(QWidget* parent) :
|
|||
});
|
||||
|
||||
m_listView = new QListView(this);
|
||||
QScroller::grabGesture(m_listView->viewport(), QScroller::TouchGesture);
|
||||
|
||||
auto *delegate = new ServiceItemDelegate(m_listView, m_listView);
|
||||
m_serviceModel = new ServiceModel(this);
|
||||
m_sortModel = new QSortFilterProxyModel(this);
|
||||
|
|
|
@ -134,6 +134,9 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
|
|||
connect(controller, &KItemListController::escapePressed, this, &DolphinView::stopLoading);
|
||||
connect(controller, &KItemListController::modelChanged, this, &DolphinView::slotModelChanged);
|
||||
connect(controller, &KItemListController::selectedItemTextPressed, this, &DolphinView::slotSelectedItemTextPressed);
|
||||
connect(controller, &KItemListController::increaseZoom, this, &DolphinView::slotIncreaseZoom);
|
||||
connect(controller, &KItemListController::decreaseZoom, this, &DolphinView::slotDecreaseZoom);
|
||||
connect(controller, &KItemListController::swipeUp, this, &DolphinView::slotSwipeUp);
|
||||
|
||||
connect(m_model, &KFileItemModel::directoryLoadingStarted, this, &DolphinView::slotDirectoryLoadingStarted);
|
||||
connect(m_model, &KFileItemModel::directoryLoadingCompleted, this, &DolphinView::slotDirectoryLoadingCompleted);
|
||||
|
@ -1954,3 +1957,18 @@ void DolphinView::copyPathToClipboard()
|
|||
}
|
||||
clipboard->setText(path);
|
||||
}
|
||||
|
||||
void DolphinView::slotIncreaseZoom()
|
||||
{
|
||||
setZoomLevel(zoomLevel() + 1);
|
||||
}
|
||||
|
||||
void DolphinView::slotDecreaseZoom()
|
||||
{
|
||||
setZoomLevel(zoomLevel() - 1);
|
||||
}
|
||||
|
||||
void DolphinView::slotSwipeUp()
|
||||
{
|
||||
emit goUpRequested();
|
||||
}
|
||||
|
|
|
@ -582,6 +582,8 @@ signals:
|
|||
*/
|
||||
void urlActivated(const QUrl& url);
|
||||
|
||||
void goUpRequested();
|
||||
|
||||
protected:
|
||||
/** Changes the zoom level if Control is pressed during a wheel event. */
|
||||
void wheelEvent(QWheelEvent* event) override;
|
||||
|
@ -611,6 +613,9 @@ private slots:
|
|||
void slotRenameDialogRenamingFinished(const QList<QUrl>& urls);
|
||||
void slotSelectedItemTextPressed(int index);
|
||||
void slotCopyingDone(KIO::Job *, const QUrl &, const QUrl &to);
|
||||
void slotIncreaseZoom();
|
||||
void slotDecreaseZoom();
|
||||
void slotSwipeUp();
|
||||
|
||||
/*
|
||||
* Is called when new items get pasted or dropped.
|
||||
|
|
Loading…
Reference in a new issue