summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorJanne Anttila <janne.anttila@digia.com>2010-02-25 09:28:47 (GMT)
committerJanne Anttila <janne.anttila@digia.com>2010-02-25 11:46:56 (GMT)
commitd8465414e6fd543cfc20e732030dedd8d2bc685f (patch)
tree1075f00a121c2f9de241dc2e561332c7d7ff93db /src/gui
parent68c909373d96f61f1a06cfb486df320e56b2e75a (diff)
downloadQt-d8465414e6fd543cfc20e732030dedd8d2bc685f.zip
Qt-d8465414e6fd543cfc20e732030dedd8d2bc685f.tar.gz
Qt-d8465414e6fd543cfc20e732030dedd8d2bc685f.tar.bz2
Improvements to itemview keypad navigation in S60.
The logic used in this commit is partially taken from sliders. This commit makes it possible to interact (change row or column) in itemview even itemview does not have editFocus. Interacting without editFocus is enabled when it is not possible to keypad navigate to reuqested direction. In addition if keypad navigation to any direction is not possible (i.e there is only one listwidget on screen), there is no sense to add "done" softkey to get out of edit focus. Task-number: QTBUG-4802 Reviewed-by: Alessandro Portale
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp41
-rw-r--r--src/gui/kernel/qwidget.cpp43
-rw-r--r--src/gui/kernel/qwidget_p.h2
-rw-r--r--src/gui/widgets/qabstractslider.cpp53
4 files changed, 89 insertions, 50 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index adf3ce3..555555e 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -2119,6 +2119,11 @@ void QAbstractItemView::focusOutEvent(QFocusEvent *event)
Q_D(QAbstractItemView);
QAbstractScrollArea::focusOutEvent(event);
d->viewport->update();
+
+#ifdef QT_SOFTKEYS_ENABLED
+ if(!hasEditFocus())
+ removeAction(d->doneSoftKey);
+#endif
}
/*!
@@ -2144,7 +2149,12 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
if (!hasEditFocus()) {
setEditFocus(true);
#ifdef QT_SOFTKEYS_ENABLED
- addAction(d->doneSoftKey);
+ // If we can't keypad navigate to any direction, there is no sense to add
+ // "Done" softkey, since it basically does nothing when there is
+ // only one widget in screen
+ if(QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
+ || QWidgetPrivate::canKeypadNavigate(Qt::Vertical))
+ addAction(d->doneSoftKey);
#endif
return;
}
@@ -2160,6 +2170,26 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
event->ignore();
}
return;
+ case Qt::Key_Down:
+ case Qt::Key_Up:
+ // Let's ignore vertical navigation events, only if there is no other widget
+ // what can take the focus in vertical direction. This means widget can handle navigation events
+ // even the widget don't have edit focus, and there is no other widget in requested direction.
+ if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
+ && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
+ event->ignore();
+ return;
+ }
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ // Similar logic as in up and down events
+ if(QApplication::keypadNavigationEnabled() && !hasEditFocus()
+ && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this))) {
+ event->ignore();
+ return;
+ }
+ break;
default:
if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) {
event->ignore();
@@ -2245,7 +2275,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
case Qt::Key_Down:
case Qt::Key_Up:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::keypadNavigationEnabled()) {
+ if (QApplication::keypadNavigationEnabled() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) {
event->accept(); // don't change focus
break;
}
@@ -2253,8 +2283,11 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
case Qt::Key_Left:
case Qt::Key_Right:
#ifdef QT_KEYPAD_NAVIGATION
- if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) {
- event->accept(); // don't change horizontal focus in directional mode
+ int colCount = d->model->columnCount(d->root);
+ if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional
+ && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal)
+ || (QWidgetPrivate::inTabWidget(this) && colCount > 1))) {
+ event->accept(); // don't change focus
break;
}
#endif // QT_KEYPAD_NAVIGATION
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 850e961..d3340df 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -118,6 +118,10 @@
#include "private/qgraphicssystem_p.h"
#include "private/qgesturemanager_p.h"
+#ifdef QT_KEYPAD_NAVIGATION
+#include "qtabwidget.h" // Needed in inTabWidget()
+#endif // QT_KEYPAD_NAVIGATION
+
// widget/widget data creation count
//#define QWIDGET_EXTRA_DEBUG
//#define ALIEN_DEBUG
@@ -11626,6 +11630,45 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction)
}
return targetWidget;
}
+
+/*!
+ \internal
+
+ Tells us if it there is currently a reachable widget by keypad navigation in
+ a certain \a orientation.
+ If no navigation is possible, occuring key events in that \a orientation may
+ be used to interact with the value in the focussed widget, even though it
+ currently has not the editFocus.
+
+ \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
+*/
+bool QWidgetPrivate::canKeypadNavigate(Qt::Orientation orientation)
+{
+ return orientation == Qt::Horizontal?
+ (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
+ || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
+ :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
+ || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
+}
+/*!
+ \internal
+
+ Checks, if the \a widget is inside a QTabWidget. If is is inside
+ one, left/right key events will be used to switch between tabs in keypad
+ navigation. If there is no QTabWidget, the horizontal key events can be used
+to
+ interact with the value in the focussed widget, even though it currently has
+ not the editFocus.
+
+ \sa QWidget::hasEditFocus()
+*/
+bool QWidgetPrivate::inTabWidget(QWidget *widget)
+{
+ for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
+ if (qobject_cast<const QTabWidget*>(tabWidget))
+ return true;
+ return false;
+}
#endif
/*!
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index b421d30..1cb6072 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -472,6 +472,8 @@ public:
#ifdef QT_KEYPAD_NAVIGATION
static bool navigateToDirection(Direction direction);
static QWidget *widgetInNavigationDirection(Direction direction);
+ static inline bool canKeypadNavigate(Qt::Orientation orientation);
+ static inline bool inTabWidget(QWidget *widget);
#endif
void setWindowIconText_sys(const QString &cap);
diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp
index 4bd7b5a..2888490 100644
--- a/src/gui/widgets/qabstractslider.cpp
+++ b/src/gui/widgets/qabstractslider.cpp
@@ -47,9 +47,6 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
-#ifdef QT_KEYPAD_NAVIGATION
-#include "qtabwidget.h" // Needed in inTabWidget()
-#endif // QT_KEYPAD_NAVIGATION
#include <limits.h>
QT_BEGIN_NAMESPACE
@@ -702,7 +699,7 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb
stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
offset_accumulated = 0;
} else {
- // Calculate how many lines to scroll. Depending on what delta is (and
+ // Calculate how many lines to scroll. Depending on what delta is (and
// offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
// only scroll whole lines, so we keep the reminder until next event.
qreal stepsToScrollF =
@@ -749,45 +746,7 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e)
}
#endif
-#ifdef QT_KEYPAD_NAVIGATION
-/*!
- \internal
-
- Tells us if it there is currently a reachable widget by keypad navigation in
- a certain \a orientation.
- If no navigation is possible, occuring key events in that \a orientation may
- be used to interact with the value in the focussed widget, even though it
- currently has not the editFocus.
- \sa QWidgetPrivate::widgetInNavigationDirection(), QWidget::hasEditFocus()
-*/
-inline static bool canKeypadNavigate(Qt::Orientation orientation)
-{
- return orientation == Qt::Horizontal?
- (QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionEast)
- || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionWest))
- :(QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionNorth)
- || QWidgetPrivate::widgetInNavigationDirection(QWidgetPrivate::DirectionSouth));
-}
-/*!
- \internal
-
- Checks, if the \a widget is inside a QTabWidget. If is is inside
- one, left/right key events will be used to switch between tabs in keypad
- navigation. If there is no QTabWidget, the horizontal key events can be used to
- interact with the value in the focussed widget, even though it currently has
- not the editFocus.
-
- \sa QWidget::hasEditFocus()
-*/
-inline static bool inTabWidget(QWidget *widget)
-{
- for (QWidget *tabWidget = widget; tabWidget; tabWidget = tabWidget->parentWidget())
- if (qobject_cast<const QTabWidget*>(tabWidget))
- return true;
- return false;
-}
-#endif // QT_KEYPAD_NAVIGATION
/*!
\reimp
*/
@@ -853,7 +812,8 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
if (QApplication::keypadNavigationEnabled()
&& (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
|| d->orientation == Qt::Vertical
- || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
+ || !hasEditFocus()
+ && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
ev->ignore();
return;
}
@@ -872,7 +832,8 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
if (QApplication::keypadNavigationEnabled()
&& (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
|| d->orientation == Qt::Vertical
- || !hasEditFocus() && (canKeypadNavigate(Qt::Horizontal) || inTabWidget(this)))) {
+ || !hasEditFocus()
+ && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
ev->ignore();
return;
}
@@ -892,7 +853,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
if (QApplication::keypadNavigationEnabled()
&& (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
|| d->orientation == Qt::Horizontal
- || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
+ || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
ev->ignore();
break;
}
@@ -905,7 +866,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev)
if (QApplication::keypadNavigationEnabled()
&& (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
|| d->orientation == Qt::Horizontal
- || !hasEditFocus() && canKeypadNavigate(Qt::Vertical))) {
+ || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
ev->ignore();
break;
}