diff options
Diffstat (limited to 'src/gui/inputmethod/qcoefepinputcontext_s60.cpp')
-rw-r--r-- | src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 77 |
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(); |