]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kitemlistcontainer.cpp
GIT_SILENT Sync po/docbooks with svn
[dolphin.git] / src / kitemviews / kitemlistcontainer.cpp
index 3893ceaea0c25cf7785f0d776769f8e097885c89..3ec56e5f10c57da4423ac4ade5f79f0682b8d06e 100644 (file)
@@ -12,6 +12,9 @@
 #include "kitemlistview.h"
 #include "private/kitemlistsmoothscroller.h"
 
+#ifndef QT_NO_ACCESSIBILITY
+#include "accessibility/kitemlistviewaccessible.h"
+#endif
 #include <QApplication>
 #include <QFontMetrics>
 #include <QGraphicsScene>
@@ -138,6 +141,21 @@ void KItemListContainer::keyPressEvent(QKeyEvent *event)
     }
 }
 
+void KItemListContainer::contextMenuEvent(QContextMenuEvent *event)
+{
+    // Note copied from the keyPressEvent() method above because the same reasons probably also apply here.
+    // TODO: We should find a better way to handle the context menu events in the view.
+    // The reasons why we need this hack are:
+    // 1. Without reimplementing contextMenuEvent() here, the event would not reach the QGraphicsView.
+    // 2. By default, the KItemListView does not have the keyboard focus in the QGraphicsScene, so
+    //    simply sending the event to the QGraphicsView which is the KItemListContainer's viewport
+    //    does not work.
+    KItemListView *view = m_controller->view();
+    if (view) {
+        QApplication::sendEvent(view, event);
+    }
+}
+
 void KItemListContainer::showEvent(QShowEvent *event)
 {
     QAbstractScrollArea::showEvent(event);
@@ -175,6 +193,33 @@ void KItemListContainer::wheelEvent(QWheelEvent *event)
     smoothScroller->handleWheelEvent(event);
 }
 
+void KItemListContainer::focusInEvent(QFocusEvent *event)
+{
+    KItemListView *view = m_controller->view();
+    if (view) {
+        QApplication::sendEvent(view, event);
+
+        // We need to set the focus to the view or accessibility software will only announce the container (which has no information available itself).
+        // For some reason actively setting the focus to the view needs to be delayed or the focus will immediately go back to this container.
+        QTimer::singleShot(0, this, [this, view]() {
+            if (!isAncestorOf(QApplication::focusWidget())) {
+                view->setFocus();
+            }
+#ifndef QT_NO_ACCESSIBILITY
+            static_cast<KItemListViewAccessible *>(QAccessible::queryAccessibleInterface(view))->setAccessibleFocusAndAnnounceAll();
+#endif
+        });
+    }
+}
+
+void KItemListContainer::focusOutEvent(QFocusEvent *event)
+{
+    KItemListView *view = m_controller->view();
+    if (view) {
+        QApplication::sendEvent(view, event);
+    }
+}
+
 void KItemListContainer::slotScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous)
 {
     Q_UNUSED(previous)
@@ -241,20 +286,15 @@ void KItemListContainer::updateScrollOffsetScrollBar()
 
     KItemListSmoothScroller *smoothScroller = nullptr;
     QScrollBar *scrollOffsetScrollBar = nullptr;
-    int singleStep = 0;
     int pageStep = 0;
     int maximum = 0;
     if (view->scrollOrientation() == Qt::Vertical) {
         smoothScroller = m_verticalSmoothScroller;
+        if (smoothScroller->isAnimating()) {
+            return;
+        }
         scrollOffsetScrollBar = verticalScrollBar();
 
-        // Don't scroll super fast when using a wheel mouse:
-        // We want to consider one "line" to be the text label which has a
-        // roughly fixed height rather than using the height of the icon which
-        // may be very tall
-        const QFontMetrics metrics(font());
-        singleStep = metrics.height() * QApplication::wheelScrollLines();
-
         // We cannot use view->size().height() because this height might
         // include the header widget, which is not part of the scrolled area.
         pageStep = view->verticalPageStep();
@@ -266,12 +306,15 @@ void KItemListContainer::updateScrollOffsetScrollBar()
         maximum = qMax(0, int(view->maximumScrollOffset() - view->size().height()));
     } else {
         smoothScroller = m_horizontalSmoothScroller;
+        if (smoothScroller->isAnimating()) {
+            return;
+        }
         scrollOffsetScrollBar = horizontalScrollBar();
-        singleStep = view->itemSize().width();
         pageStep = view->size().width();
         maximum = qMax(0, int(view->maximumScrollOffset() - view->size().width()));
     }
 
+    const int singleStep = view->scrollSingleStep();
     const int value = view->scrollOffset();
     if (smoothScroller->requestScrollBarUpdate(maximum)) {
         const bool updatePolicy = (scrollOffsetScrollBar->maximum() > 0 && maximum == 0) || horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn;
@@ -302,11 +345,17 @@ void KItemListContainer::updateItemOffsetScrollBar()
     int pageStep = 0;
     if (view->scrollOrientation() == Qt::Vertical) {
         smoothScroller = m_horizontalSmoothScroller;
+        if (smoothScroller->isAnimating()) {
+            return;
+        }
         itemOffsetScrollBar = horizontalScrollBar();
         singleStep = view->size().width() / 10;
         pageStep = view->size().width();
     } else {
         smoothScroller = m_verticalSmoothScroller;
+        if (smoothScroller->isAnimating()) {
+            return;
+        }
         itemOffsetScrollBar = verticalScrollBar();
         singleStep = view->size().height() / 10;
         pageStep = view->size().height();
@@ -368,6 +417,11 @@ void KItemListContainer::updateSmoothScrollers(Qt::Orientation orientation)
         m_horizontalSmoothScroller->setPropertyName("scrollOffset");
         m_verticalSmoothScroller->setPropertyName("itemOffset");
     }
+
+    const bool isRightToLeft = m_controller->view()->layoutDirection() == Qt::RightToLeft;
+    QScrollBar *hScrollBar = horizontalScrollBar();
+    hScrollBar->setInvertedAppearance(isRightToLeft && orientation == Qt::Vertical);
+    hScrollBar->setInvertedControls(!isRightToLeft || orientation == Qt::Vertical);
 }
 
 void KItemListContainer::updateScrollOffsetScrollBarPolicy()