]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kitemlistcontainer.cpp
Focus-tracking for widgets in Dolphin View now works.
[dolphin.git] / src / kitemviews / kitemlistcontainer.cpp
index d006e2c4d48d455c9b1c80372b2afda0fde77b37..01a4cfd4eb14971f58f383cfa984759ca55f4d79 100644 (file)
 #include "kitemlistcontainer.h"
 
 #include "kitemlistcontroller.h"
-#include "kitemlistsmoothscroller_p.h"
 #include "kitemlistview.h"
 #include "kitemmodelbase.h"
 
+#include "private/kitemlistsmoothscroller.h"
+
 #include <QApplication>
 #include <QGraphicsScene>
 #include <QGraphicsView>
 #include <QPropertyAnimation>
 #include <QScrollBar>
 #include <QStyle>
+#include <QStyleOption>
 
 #include <KDebug>
 
+#include "kitemlistviewaccessible.h"
+
 /**
  * Replaces the default viewport of KItemListContainer by a
  * non-scrollable viewport. The scrolling is done in an optimized
@@ -65,7 +69,15 @@ void KItemListContainerViewport::wheelEvent(QWheelEvent* event)
     event->ignore();
 }
 
-
+QAccessibleInterface* accessibleContainerFactory(const QString &key, QObject *object)
+{
+    Q_UNUSED(key)
+    if (KItemListContainer*view = qobject_cast<KItemListContainer*>(object))
+        return new KItemListContainerAccessible(view);
+    if (KItemListView *view = qobject_cast<KItemListView*>(object))
+        return new KItemListViewAccessible(view);
+    return 0;
+}
 
 KItemListContainer::KItemListContainer(KItemListController* controller, QWidget* parent) :
     QAbstractScrollArea(parent),
@@ -75,20 +87,36 @@ KItemListContainer::KItemListContainer(KItemListController* controller, QWidget*
 {
     Q_ASSERT(controller);
     controller->setParent(this);
-    initialize();
-}
 
-KItemListContainer::KItemListContainer(QWidget* parent) :
-    QAbstractScrollArea(parent),
-    m_controller(0),
-    m_horizontalSmoothScroller(0),
-    m_verticalSmoothScroller(0)
-{
-    initialize();
+    QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
+    setViewport(graphicsView);
+
+    m_horizontalSmoothScroller = new KItemListSmoothScroller(horizontalScrollBar(), this);
+    m_verticalSmoothScroller = new KItemListSmoothScroller(verticalScrollBar(), this);
+
+    if (controller->model()) {
+        slotModelChanged(controller->model(), 0);
+    }
+    if (controller->view()) {
+        slotViewChanged(controller->view(), 0);
+    }
+
+    connect(controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)),
+            this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
+    connect(controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)),
+            this, SLOT(slotViewChanged(KItemListView*,KItemListView*)));
+
+    QAccessible::installFactory(accessibleContainerFactory);
 }
 
 KItemListContainer::~KItemListContainer()
 {
+    // Don't rely on the QObject-order to delete the controller, otherwise
+    // the QGraphicsScene might get deleted before the view.
+    delete m_controller;
+    m_controller = 0;
+
+    QAccessible::removeFactory(accessibleContainerFactory);
 }
 
 KItemListController* KItemListContainer::controller() const
@@ -96,6 +124,33 @@ KItemListController* KItemListContainer::controller() const
     return m_controller;
 }
 
+void KItemListContainer::setEnabledFrame(bool enable)
+{
+    QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(viewport());
+    if (enable) {
+        setFrameShape(QFrame::StyledPanel);
+        graphicsView->setPalette(palette());
+        graphicsView->viewport()->setAutoFillBackground(true);
+    } else {
+        setFrameShape(QFrame::NoFrame);
+        // Make the background of the container transparent and apply the window-text color
+        // to the text color, so that enough contrast is given for all color
+        // schemes
+        QPalette p = graphicsView->palette();
+        p.setColor(QPalette::Active,   QPalette::Text, p.color(QPalette::Active,   QPalette::WindowText));
+        p.setColor(QPalette::Inactive, QPalette::Text, p.color(QPalette::Inactive, QPalette::WindowText));
+        p.setColor(QPalette::Disabled, QPalette::Text, p.color(QPalette::Disabled, QPalette::WindowText));
+        graphicsView->setPalette(p);
+        graphicsView->viewport()->setAutoFillBackground(false);
+    }
+}
+
+bool KItemListContainer::enabledFrame() const
+{
+    const QGraphicsView* graphicsView = qobject_cast<QGraphicsView*>(viewport());
+    return graphicsView->autoFillBackground();
+}
+
 void KItemListContainer::keyPressEvent(QKeyEvent* event)
 {
     // TODO: We should find a better way to handle the key press events in the view.
@@ -108,6 +163,7 @@ void KItemListContainer::keyPressEvent(QKeyEvent* event)
     if (view) {
         QApplication::sendEvent(view, event);
     }
+    //QAccessible::updateAccessibility(view, 0, QAccessible::Focus);
 }
 
 void KItemListContainer::showEvent(QShowEvent* event)
@@ -172,7 +228,7 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView*
     QGraphicsScene* scene = static_cast<QGraphicsView*>(viewport())->scene();
     if (previous) {
         scene->removeItem(previous);
-        disconnect(current, SIGNAL(scrollOrientationChanged(Qt::Orientation,Qt::Orientation)), this, SLOT(slotScrollOrientationChanged(Qt::Orientation,Qt::Orientation)));
+        disconnect(previous, SIGNAL(scrollOrientationChanged(Qt::Orientation,Qt::Orientation)), this, SLOT(slotScrollOrientationChanged(Qt::Orientation,Qt::Orientation)));
         disconnect(previous, SIGNAL(scrollOffsetChanged(qreal,qreal)),        this, SLOT(updateScrollOffsetScrollBar()));
         disconnect(previous, SIGNAL(maximumScrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar()));
         disconnect(previous, SIGNAL(itemOffsetChanged(qreal,qreal)),          this, SLOT(updateItemOffsetScrollBar()));
@@ -233,11 +289,19 @@ void KItemListContainer::updateScrollOffsetScrollBar()
     const int value = view->scrollOffset();
     const int maximum = qMax(0, int(view->maximumScrollOffset() - pageStep));
     if (smoothScroller->requestScrollBarUpdate(maximum)) {
+        const bool updatePolicy = (scrollOffsetScrollBar->maximum() > 0 && maximum == 0)
+                                  || horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn;
+
         scrollOffsetScrollBar->setSingleStep(singleStep);
         scrollOffsetScrollBar->setPageStep(pageStep);
         scrollOffsetScrollBar->setMinimum(0);
         scrollOffsetScrollBar->setMaximum(maximum);
         scrollOffsetScrollBar->setValue(value);
+
+        if (updatePolicy) {
+            // Prevent a potential endless layout loop (see bug #293318).
+            updateScrollOffsetScrollBarPolicy();
+        }
     }
 }
 
@@ -279,13 +343,20 @@ void KItemListContainer::updateGeometries()
 {
     QRect rect = geometry();
 
+    int extra = frameWidth() * 2;
+    QStyleOption option;
+    option.initFrom(this);
+    if (style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &option, this)) {
+        extra += style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &option, this);
+    }
+
     const int widthDec = verticalScrollBar()->isVisible()
-                         ? frameWidth() + style()->pixelMetric(QStyle::PM_ScrollBarExtent)
-                         : frameWidth() * 2;
+                         ? extra + style()->pixelMetric(QStyle::PM_ScrollBarExtent, &option, this)
+                         : extra;
 
     const int heightDec = horizontalScrollBar()->isVisible()
-                          ? frameWidth() + style()->pixelMetric(QStyle::PM_ScrollBarExtent)
-                          : frameWidth() * 2;
+                          ? extra + style()->pixelMetric(QStyle::PM_ScrollBarExtent, &option, this)
+                          : extra;
 
     rect.adjust(0, 0, -widthDec, -heightDec);
 
@@ -312,22 +383,30 @@ void KItemListContainer::updateSmoothScrollers(Qt::Orientation orientation)
     }
 }
 
-void KItemListContainer::initialize()
+void KItemListContainer::updateScrollOffsetScrollBarPolicy()
 {
-    if (!m_controller) {
-        m_controller = new KItemListController(this);
-    }
+    const KItemListView* view = m_controller->view();
+    Q_ASSERT(view);
+    const bool vertical = (view->scrollOrientation() == Qt::Vertical);
 
-    connect(m_controller, SIGNAL(modelChanged(KItemModelBase*,KItemModelBase*)),
-            this, SLOT(slotModelChanged(KItemModelBase*,KItemModelBase*)));
-    connect(m_controller, SIGNAL(viewChanged(KItemListView*,KItemListView*)),
-            this, SLOT(slotViewChanged(KItemListView*,KItemListView*)));
+    QStyleOption option;
+    option.initFrom(this);
+    const int scrollBarInc = style()->pixelMetric(QStyle::PM_ScrollBarExtent, &option, this);
 
-    QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
-    setViewport(graphicsView);
+    QSizeF newViewSize = m_controller->view()->size();
+    if (vertical) {
+        newViewSize.rwidth() += scrollBarInc;
+    } else {
+        newViewSize.rheight() += scrollBarInc;
+    }
 
-    m_horizontalSmoothScroller = new KItemListSmoothScroller(horizontalScrollBar(), this);
-    m_verticalSmoothScroller = new KItemListSmoothScroller(verticalScrollBar(), this);
+    const Qt::ScrollBarPolicy policy = view->scrollBarRequired(newViewSize)
+                                       ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded;
+    if (vertical) {
+        setVerticalScrollBarPolicy(policy);
+    } else {
+        setHorizontalScrollBarPolicy(policy);
+    }
 }
 
 #include "kitemlistcontainer.moc"