]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kitemlistcontroller.cpp
Merge branch 'Applications/18.12'
[dolphin.git] / src / kitemviews / kitemlistcontroller.cpp
index 854a0087aa4f3173e1b1bdad51f8d84c38b7ce32..d3dbeb35ccdd369b36abd3488728c64f8df006c3 100644 (file)
 
 #include "kitemlistcontroller.h"
 
-#include <KGlobalSettings>
-#include <KDebug>
-
-#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 <QAccessible>
 #include <QApplication>
 #include <QDrag>
-#include <QEvent>
 #include <QGraphicsScene>
 #include <QGraphicsSceneEvent>
 #include <QGraphicsView>
 #include <QMimeData>
 #include <QTimer>
-#include <QAccessible>
 
 KItemListController::KItemListController(KItemModelBase* model, KItemListView* view, QObject* parent) :
     QObject(parent),
@@ -50,13 +46,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)
@@ -77,10 +73,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 +176,20 @@ KItemListController::MouseDoubleClickAction KItemListController::mouseDoubleClic
     return m_mouseDoubleClickAction;
 }
 
+int KItemListController::indexCloseToMousePressedPosition() const
+{
+    QHashIterator<KItemListWidget*, KItemListGroupHeader*> 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 +210,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();
@@ -423,8 +421,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
@@ -538,8 +535,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 +582,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) {
@@ -774,7 +774,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 +804,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) {
@@ -817,6 +833,9 @@ bool KItemListController::dragEnterEvent(QGraphicsSceneDragDropEvent* event, con
 {
     Q_UNUSED(event);
     Q_UNUSED(transform);
+
+    DragAndDropHelper::clearUrlListMatchesUrlCache();
+
     return false;
 }
 
@@ -825,6 +844,7 @@ bool KItemListController::dragLeaveEvent(QGraphicsSceneDragDropEvent* event, con
     Q_UNUSED(event);
     Q_UNUSED(transform);
 
+    m_autoActivationTimer->stop();
     m_view->setAutoScroll(false);
     m_view->hideDropIndicator();
 
@@ -842,8 +862,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 +886,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 +916,8 @@ bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent* event, cons
         m_view->hideDropIndicator();
     }
 
+    event->setAccepted(!DragAndDropHelper::urlListMatchesUrl(event->mimeData()->urls(), hoveredDir));
+
     return false;
 }
 
@@ -915,12 +942,13 @@ 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;
 }
@@ -1170,11 +1198,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);
+
+    QAccessibleEvent accessibilityEvent(view(), QAccessible::DragDropStart);
+    QAccessible::updateAccessibility(&accessibilityEvent);
 }
 
 KItemListWidget* KItemListController::hoveredWidget() const
@@ -1187,7 +1217,7 @@ KItemListWidget* KItemListController::hoveredWidget() const
         }
     }
 
-    return 0;
+    return nullptr;
 }
 
 KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const
@@ -1204,7 +1234,7 @@ KItemListWidget* KItemListController::widgetForPos(const QPointF& pos) const
         }
     }
 
-    return 0;
+    return nullptr;
 }
 
 void KItemListController::updateKeyboardAnchor()