summaryrefslogtreecommitdiffstats
path: root/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/inputmethod/qcoefepinputcontext_s60.cpp')
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp77
1 files changed, 53 insertions, 24 deletions
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 3546079..bacf07a 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -382,6 +382,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_hasTempPreeditString(false),
m_splitViewResizeBy(0),
m_splitViewPreviousWindowStates(Qt::WindowNoState),
+ m_splitViewPreviousFocusItem(0),
m_ccpu(0)
{
m_fepState->SetObjectProvider(this);
@@ -451,6 +452,11 @@ void QCoeFepInputContext::reset()
if (m_cachedPreeditString.isEmpty() && !(currentHints & Qt::ImhNoPredictiveText))
m_cachedPreeditString = m_preeditString;
commitCurrentString(true);
+
+ // QGraphicsScene calls reset() when changing focus item. Unfortunately, the new focus item is
+ // set right after resetting the input context. Therefore, asynchronously call ensureWidgetVisibility().
+ if (S60->splitViewLastWidget)
+ QMetaObject::invokeMethod(this,"ensureWidgetVisibility", Qt::QueuedConnection);
}
void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType)
@@ -793,9 +799,8 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
{
QGraphicsView *gv = qobject_cast<QGraphicsView*>(S60->splitViewLastWidget);
- if (!gv) {
+ if (!gv)
return;
- }
QSymbianControl *symControl = static_cast<QSymbianControl*>(gv->effectiveWinId());
symControl->CancelLongTapTimer();
@@ -810,11 +815,13 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
if (!alwaysResize) {
if (gv->scene() && S60->partial_keyboardAutoTranslation) {
if (gv->scene()->focusItem()) {
+ QGraphicsItem *focusItem =
+ m_splitViewPreviousFocusItem ? m_splitViewPreviousFocusItem : gv->scene()->focusItem();
// Check if the widget contains cursorPositionChanged signal and disconnect from it.
QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ int index = focusItem->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
if (index != -1)
- disconnect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ disconnect(focusItem->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
}
QGraphicsItem *rootItem = 0;
@@ -882,6 +889,11 @@ bool QCoeFepInputContext::isPartialKeyboardSupported()
return (S60->partial_keyboard || !QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode));
}
+void QCoeFepInputContext::ensureWidgetVisibility()
+{
+ ensureFocusWidgetVisible(S60->splitViewLastWidget);
+}
+
// Ensure that the input widget is visible in the splitview rect.
void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
@@ -913,17 +925,22 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
// states getting changed.
if (!moveWithinVisibleArea) {
- // Check if the widget contains cursorPositionChanged signal and connect to it.
- QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
- if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) {
- int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
- if (index != -1)
- connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
- }
S60->splitViewLastWidget = widget;
m_splitViewPreviousWindowStates = windowToMove->windowState();
}
+ // Check if the widget contains cursorPositionChanged signal and connect to it.
+ if (gv->scene() && gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) {
+ QByteArray signal = QMetaObject::normalizedSignature(SIGNAL(cursorPositionChanged()));
+ if (m_splitViewPreviousFocusItem && m_splitViewPreviousFocusItem != gv->scene()->focusItem())
+ disconnect(m_splitViewPreviousFocusItem->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ int index = gv->scene()->focusItem()->toGraphicsObject()->metaObject()->indexOfSignal(signal.right(signal.length() - 1));
+ if (index != -1) {
+ connect(gv->scene()->focusItem()->toGraphicsObject(), SIGNAL(cursorPositionChanged()), this, SLOT(translateInputWidget()));
+ m_splitViewPreviousFocusItem = gv->scene()->focusItem();
+ }
+ }
+
int windowTop = widget->window()->pos().y();
const bool userResize = widget->testAttribute(Qt::WA_Resized);
@@ -1266,10 +1283,15 @@ void QCoeFepInputContext::translateInputWidget()
m_transformation = (rootItem->transform().isTranslating()) ? QRectF(0,0, gv->width(), rootItem->transform().dy()) : QRectF();
- // Adjust cursor bounding rect to be lower, so that view translates if the cursor gets near
- // the splitview border.
- QRect cursorRect = cursorP.boundingRect().adjusted(0, cursor.height(), 0, cursor.height());
- if (splitViewRect.contains(cursorRect))
+ // Adjust cursor bounding rect towards navigation direction,
+ // so that view translates if the cursor gets near the splitview border.
+ QRect cursorRect = (cursorP.boundingRect().top() < 0) ?
+ cursorP.boundingRect().adjusted(0, -cursor.height(), 0, -cursor.height()) :
+ cursorP.boundingRect().adjusted(0, cursor.height(), 0, cursor.height());
+
+ // If the current cursor position and upcoming cursor positions are visible in the splitview
+ // area, do not move the view.
+ if (splitViewRect.contains(cursorRect) && splitViewRect.contains(cursorP.boundingRect()))
return;
// New Y position should be ideally just above the keyboard.
@@ -1281,22 +1303,29 @@ void QCoeFepInputContext::translateInputWidget()
const qreal itemHeight = path.boundingRect().height();
// Limit the maximum translation so that underlaying window content is not exposed.
- qreal maxY = gv->sceneRect().bottom() - splitViewRect.bottom();
- maxY = m_transformation.height() ? (qMin(itemHeight, maxY) + m_transformation.height()) : maxY;
- if (maxY < 0)
- maxY = 0;
+ qreal availableSpace = gv->sceneRect().bottom() - splitViewRect.bottom();
+ availableSpace = m_transformation.height() ?
+ (qMin(itemHeight, availableSpace) + m_transformation.height()) :
+ availableSpace;
// Translation should happen row-by-row, but initially it needs to ensure that cursor is visible.
const qreal translation = m_transformation.height() ?
cursor.height() : (cursorRect.bottom() - vkbRect.top());
- qreal dy = -(qMin(maxY, translation));
+ qreal dy = 0.0;
+ if (availableSpace > 0)
+ dy = -(qMin(availableSpace, translation));
+ else
+ dy = -(translation);
- // Correct the translation direction, if the cursor rect would be moved outside of application area.
- if ((cursorRect.bottom() + dy) < 0)
+ // Correct the translation direction, if the cursor rect would be moved above application area.
+ if ((cursorP.boundingRect().bottom() + dy) < 0)
dy *= -1;
- // Do not allow transform above screen top, nor beyond scenerect
- if (m_transformation.height() + dy > 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) {
+ // Do not allow transform above screen top, nor beyond scenerect. Also, if there is no available
+ // space anymore, skip translation.
+ if ((m_transformation.height() + dy) > 0
+ || (gv->sceneRect().bottom() + m_transformation.height()) < 0
+ || !availableSpace) {
// If we already have some transformation, remove it.
if (m_transformation.height() < 0 || gv->sceneRect().bottom() + m_transformation.height() < 0) {
rootItem->resetTransform();