#include <QGraphicsView>
#include <QMimeData>
#include <QTimer>
+#include <QTouchEvent>
KItemListController::KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent) :
QObject(parent),
m_scrollerIsScrolling(false),
m_pinchGestureInProgress(false),
m_mousePress(false),
+ m_isTouchEvent(false),
m_selectionBehavior(NoSelection),
m_autoActivationBehavior(ActivationAndExpansion),
m_mouseDoubleClickAction(ActivateItemOnly),
m_autoActivationTimer(nullptr),
m_swipeGesture(Qt::CustomGesture),
m_twoFingerTapGesture(Qt::CustomGesture),
- m_lastSource(Qt::MouseEventNotSynthesized),
m_oldSelection(),
m_keyboardAnchorIndex(-1),
m_keyboardAnchorPos(0)
m_selectionManager->setModel(m_model);
- emit modelChanged(m_model, oldModel);
+ Q_EMIT modelChanged(m_model, oldModel);
}
KItemModelBase* KItemListController::model() const
updateExtendedSelectionRegion();
}
- emit viewChanged(m_view, oldView);
+ Q_EMIT viewChanged(m_view, oldView);
}
KItemListView* KItemListController::view() const
case Qt::Key_Return: {
const KItemSet selectedItems = m_selectionManager->selectedItems();
if (selectedItems.count() >= 2) {
- emit itemsActivated(selectedItems);
+ Q_EMIT itemsActivated(selectedItems);
} else if (selectedItems.count() == 1) {
- emit itemActivated(selectedItems.first());
+ Q_EMIT itemActivated(selectedItems.first());
} else {
- emit itemActivated(index);
+ Q_EMIT itemActivated(index);
}
break;
}
if (index >= 0) {
const QRectF contextRect = m_view->itemContextRect(index);
const QPointF pos(m_view->scene()->views().first()->mapToGlobal(contextRect.bottomRight().toPoint()));
- emit itemContextMenuRequested(index, pos);
+ Q_EMIT itemContextMenuRequested(index, pos);
} else {
- emit viewContextMenuRequested(QCursor::pos());
+ Q_EMIT viewContextMenuRequested(QCursor::pos());
}
break;
}
m_selectionManager->clearSelection();
}
m_keyboardManager->cancelSearch();
- emit escapePressed();
+ Q_EMIT escapePressed();
break;
case Qt::Key_Space:
const bool expanded = m_model->isExpanded(index);
m_model->setExpanded(index, !expanded);
} else if (m_autoActivationBehavior != ExpansionOnly) {
- emit itemActivated(index);
+ Q_EMIT itemActivated(index);
}
}
}
bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
{
m_mousePress = true;
- m_lastSource = event->source();
- if (event->source() == Qt::MouseEventSynthesizedByQt) {
+ if (event->source() == Qt::MouseEventSynthesizedByQt && m_isTouchEvent) {
return false;
}
return false;
}
- if (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;
- }
-
return true;
}
m_view->m_tapAndHoldIndicator->setActive(false);
}
- if (event->source() == Qt::MouseEventSynthesizedByQt && !m_dragActionOrRightClick) {
+ if (event->source() == Qt::MouseEventSynthesizedByQt && !m_dragActionOrRightClick && m_isTouchEvent) {
return false;
}
bool KItemListController::mouseReleaseEvent(QGraphicsSceneMouseEvent* event, const QTransform& transform)
{
m_mousePress = false;
+ m_isTouchEvent = false;
if (!m_view) {
return false;
}
KItemListRubberBand* rubberBand = m_view->rubberBand();
- if (event->source() == Qt::MouseEventSynthesizedByQt && !rubberBand->isActive()) {
+ if (event->source() == Qt::MouseEventSynthesizedByQt && !rubberBand->isActive() && m_isTouchEvent) {
return false;
}
- emit mouseButtonReleased(m_pressedIndex, event->buttons());
+ Q_EMIT mouseButtonReleased(m_pressedIndex, event->buttons());
return onRelease(transform.map(event->pos()), event->modifiers(), event->button(), false);
}
m_selectionManager->clearSelection();
if (index >= 0) {
m_selectionManager->setSelected(index);
- emit itemContextMenuRequested(index, event->screenPos());
+ Q_EMIT itemContextMenuRequested(index, event->screenPos());
} else {
const QRectF headerBounds = m_view->headerBoundaries();
if (headerBounds.contains(event->pos())) {
- emit headerContextMenuRequested(event->screenPos());
+ Q_EMIT headerContextMenuRequested(event->screenPos());
} else {
- emit viewContextMenuRequested(event->screenPos());
+ Q_EMIT viewContextMenuRequested(event->screenPos());
}
}
return true;
(event->button() & Qt::LeftButton) &&
index >= 0 && index < m_model->count();
if (emitItemActivated) {
- emit itemActivated(index);
+ Q_EMIT itemActivated(index);
}
return false;
}
KItemListWidget* widget = hoveredWidget();
if (widget) {
widget->setHovered(false);
- emit itemUnhovered(widget->index());
+ Q_EMIT itemUnhovered(widget->index());
}
return false;
}
if (oldHoveredWidget) {
oldHoveredWidget->setHovered(false);
- emit itemUnhovered(oldHoveredWidget->index());
+ Q_EMIT itemUnhovered(oldHoveredWidget->index());
}
}
m_view->hideDropIndicator();
if (!newHoveredWidget->isHovered()) {
newHoveredWidget->setHovered(true);
- emit itemHovered(index);
+ Q_EMIT itemHovered(index);
}
if (!m_autoActivationTimer->isActive() && m_autoActivationTimer->interval() >= 0) {
m_autoActivationTimer->stop();
if (newHoveredWidget && newHoveredWidget->isHovered()) {
newHoveredWidget->setHovered(false);
- emit itemUnhovered(index);
+ Q_EMIT itemUnhovered(index);
}
}
} else {
if (dropAboveIndex >= 0) {
// Something has been dropped between two items.
m_view->hideDropIndicator();
- emit aboveItemDropEvent(dropAboveIndex, event);
+ Q_EMIT aboveItemDropEvent(dropAboveIndex, event);
} 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);
+ Q_EMIT itemDropEvent(m_view->itemAt(pos), event);
}
QAccessibleEvent accessibilityEvent(view(), QAccessible::DragDropEnd);
if (oldHoveredWidget != newHoveredWidget) {
if (oldHoveredWidget) {
oldHoveredWidget->setHovered(false);
- emit itemUnhovered(oldHoveredWidget->index());
+ Q_EMIT itemUnhovered(oldHoveredWidget->index());
}
if (newHoveredWidget) {
newHoveredWidget->setHovered(true);
const QPointF mappedPos = newHoveredWidget->mapFromItem(m_view, pos);
newHoveredWidget->setHoverPosition(mappedPos);
- emit itemHovered(newHoveredWidget->index());
+ Q_EMIT itemHovered(newHoveredWidget->index());
}
} else if (oldHoveredWidget) {
const QPointF mappedPos = oldHoveredWidget->mapFromItem(m_view, pos);
Q_UNUSED(transform)
m_mousePress = false;
+ m_isTouchEvent = false;
if (!m_model || !m_view) {
return false;
}
- foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
+ const auto widgets = m_view->visibleItemListWidgets();
+ for (KItemListWidget* widget : widgets) {
if (widget->isHovered()) {
widget->setHovered(false);
- emit itemUnhovered(widget->index());
+ Q_EMIT itemUnhovered(widget->index());
}
}
return false;
return accepted;
}
+bool KItemListController::touchBeginEvent(QTouchEvent* event, const QTransform& transform)
+{
+ Q_UNUSED(event)
+ Q_UNUSED(transform)
+
+ m_isTouchEvent = true;
+ return false;
+}
+
void KItemListController::tapTriggered(QTapGesture* tap, const QTransform& transform)
{
static bool scrollerWasActive = false;
m_dragActionOrRightClick = false;
m_isSwipeGesture = false;
m_pinchGestureInProgress = false;
- m_lastSource = Qt::MouseEventSynthesizedByQt;
scrollerWasActive = m_scrollerIsScrolling;
}
onPress(tap->hotSpot().toPoint(), tap->position().toPoint(), Qt::NoModifier, Qt::LeftButton);
onRelease(transform.map(tap->position()), Qt::NoModifier, Qt::LeftButton, true);
}
+ m_isTouchEvent = false;
}
}
{
//the Qt TabAndHold gesture is triggerable with a mouse click, we don't want this
- if (m_lastSource == Qt::MouseEventNotSynthesized) {
+ if (!m_isTouchEvent) {
return;
}
startRubberBand();
}
- emit scrollerStop();
+ Q_EMIT scrollerStop();
m_view->m_tapAndHoldIndicator->setStartPosition(m_pressedMousePos);
m_view->m_tapAndHoldIndicator->setActive(true);
}
counter = counter + (pinch->scaleFactor() - 1);
if (counter >= sensitivityModifier) {
- emit increaseZoom();
+ Q_EMIT increaseZoom();
counter = 0;
} else if (counter <= -sensitivityModifier) {
- emit decreaseZoom();
+ Q_EMIT decreaseZoom();
counter = 0;
}
}
}
if (swipe->state() == Qt::GestureFinished) {
- emit scrollerStop();
+ Q_EMIT scrollerStop();
if (swipe->swipeAngle() <= 20 || swipe->swipeAngle() >= 340) {
- emit mouseButtonPressed(m_pressedIndex, Qt::BackButton);
+ Q_EMIT mouseButtonPressed(m_pressedIndex, Qt::BackButton);
} else if (swipe->swipeAngle() <= 200 && swipe->swipeAngle() >= 160) {
- emit mouseButtonPressed(m_pressedIndex, Qt::ForwardButton);
+ Q_EMIT mouseButtonPressed(m_pressedIndex, Qt::ForwardButton);
} else if (swipe->swipeAngle() <= 110 && swipe->swipeAngle() >= 60) {
- emit swipeUp();
+ Q_EMIT swipeUp();
}
m_isSwipeGesture = true;
}
return resizeEvent(static_cast<QGraphicsSceneResizeEvent*>(event), transform);
case QEvent::Gesture:
return gestureEvent(static_cast<QGestureEvent*>(event), transform);
+ case QEvent::TouchBegin:
+ return touchBeginEvent(static_cast<QTouchEvent*>(event), transform);
default:
break;
}
KItemSet selectedItems;
// Select all visible items that intersect with the rubberband
- foreach (const KItemListWidget* widget, m_view->visibleItemListWidgets()) {
+ const auto widgets = m_view->visibleItemListWidgets();
+ for (const KItemListWidget* widget : widgets) {
const int index = widget->index();
const QRectF widgetRect = m_view->itemRect(index);
{
Q_ASSERT(m_view);
- foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
+ const auto widgets = m_view->visibleItemListWidgets();
+ for (KItemListWidget* widget : widgets) {
if (widget->isHovered()) {
return widget;
}
{
Q_ASSERT(m_view);
- foreach (KItemListWidget* widget, m_view->visibleItemListWidgets()) {
+ const auto widgets = m_view->visibleItemListWidgets();
+ for (KItemListWidget* widget : widgets) {
const QPointF mappedPos = widget->mapFromItem(m_view, pos);
const bool hovered = widget->contains(mappedPos) &&
bool KItemListController::onPress(const QPoint& screenPos, const QPointF& pos, const Qt::KeyboardModifiers modifiers, const Qt::MouseButtons buttons)
{
- emit mouseButtonPressed(m_pressedIndex, buttons);
+ Q_EMIT mouseButtonPressed(m_pressedIndex, buttons);
+
+ if (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;
+ }
if (m_view->isAboveExpansionToggle(m_pressedIndex, m_pressedMousePos)) {
m_selectionManager->endAnchoredSelection();
m_clearSelectionIfItemsAreNotDragged = true;
if (m_selectionManager->selectedItems().count() == 1 && m_view->isAboveText(m_pressedIndex, m_pressedMousePos)) {
- emit selectedItemTextPressed(m_pressedIndex);
+ Q_EMIT selectedItemTextPressed(m_pressedIndex);
}
}
}
if (buttons & Qt::RightButton) {
- emit itemContextMenuRequested(m_pressedIndex, screenPos);
+ Q_EMIT itemContextMenuRequested(m_pressedIndex, screenPos);
}
return true;
if (buttons & Qt::RightButton) {
const QRectF headerBounds = m_view->headerBoundaries();
if (headerBounds.contains(pos)) {
- emit headerContextMenuRequested(screenPos);
+ Q_EMIT headerContextMenuRequested(screenPos);
} else {
- emit viewContextMenuRequested(screenPos);
+ Q_EMIT viewContextMenuRequested(screenPos);
}
return true;
}
return true;
}
+ const bool controlPressed = modifiers & Qt::ControlModifier;
const bool shiftOrControlPressed = modifiers & Qt::ShiftModifier ||
- modifiers & Qt::ControlModifier;
+ controlPressed;
KItemListRubberBand* rubberBand = m_view->rubberBand();
if (rubberBand->isActive()) {
const bool expanded = m_model->isExpanded(index);
m_model->setExpanded(index, !expanded);
- emit itemExpansionToggleClicked(index);
+ Q_EMIT itemExpansionToggleClicked(index);
emitItemActivated = false;
} else if (shiftOrControlPressed) {
// The mouse click should only update the selection, not trigger the item
emitItemActivated = false;
+ // When Ctrl-clicking an item when in single selection mode
+ // i.e. where Ctrl won't change the selection, pretend it was middle clicked
+ if (controlPressed && m_selectionBehavior == SingleSelection) {
+ Q_EMIT itemMiddleClicked(index);
+ }
} else if (!(m_view->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick) || m_singleClickActivationEnforced)) {
if (touch) {
emitItemActivated = true;
}
}
if (emitItemActivated) {
- emit itemActivated(index);
+ Q_EMIT itemActivated(index);
}
} else if (buttons & Qt::MiddleButton) {
- emit itemMiddleClicked(index);
+ Q_EMIT itemMiddleClicked(index);
}
}