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.cpp76
1 files changed, 59 insertions, 17 deletions
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index 602c734..bc27c1e 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -64,6 +64,8 @@
#define QT_EAknCursorPositionChanged MAknEdStateObserver::EAknEdwinStateEvent(6)
// MAknEdStateObserver::EAknActivatePenInputRequest
#define QT_EAknActivatePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(7)
+// MAknEdStateObserver::EAknClosePenInputRequest
+#define QT_EAknClosePenInputRequest MAknEdStateObserver::EAknEdwinStateEvent(10)
// EAknEditorFlagSelectionVisible is only valid from 3.2 onwards.
// Sym^3 AVKON FEP manager expects that this flag is used for FEP-aware editors
@@ -83,6 +85,8 @@ Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
{
S60->partial_keyboard = enable;
+ QApplication::setAttribute(Qt::AA_S60DisablePartialScreenInputMode, !S60->partial_keyboard);
+
QInputContext *ic = 0;
if (QApplication::focusWidget()) {
ic = QApplication::focusWidget()->inputContext();
@@ -93,6 +97,11 @@ Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable)
ic->update();
}
+Q_GUI_EXPORT void qt_s60_setPartialScreenAutomaticTranslation(bool enable)
+{
+ S60->partial_keyboardAutoTranslation = enable;
+}
+
QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
: QInputContext(parent),
m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new
@@ -100,6 +109,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_textCapabilities(TCoeInputCapabilities::EAllText),
m_inDestruction(false),
m_pendingInputCapabilitiesChanged(false),
+ m_pendingTransactionCancel(false),
m_cursorVisibility(1),
m_inlinePosition(0),
m_formatRetriever(0),
@@ -111,7 +121,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_fepState->SetObjectProvider(this);
int defaultFlags = EAknEditorFlagDefault;
if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- if (S60->partial_keyboard) {
+ if (isPartialKeyboardSupported()) {
defaultFlags |= QT_EAknEditorFlagEnablePartialScreen;
}
defaultFlags |= QT_EAknEditorFlagSelectionVisible;
@@ -245,9 +255,6 @@ bool QCoeFepInputContext::needsInputPanel()
bool QCoeFepInputContext::filterEvent(const QEvent *event)
{
- // The CloseSoftwareInputPanel event is not handled here, because the VK will automatically
- // close when it discovers that the underlying widget does not have input capabilities.
-
if (!focusWidget())
return false;
@@ -311,6 +318,12 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
if (!needsInputPanel())
return false;
+ if ((event->type() == QEvent::CloseSoftwareInputPanel)
+ && (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0)) {
+ m_fepState->ReportAknEdStateEventL(QT_EAknClosePenInputRequest);
+ return false;
+ }
+
if (event->type() == QEvent::RequestSoftwareInputPanel) {
// Only request virtual keyboard if it is not yet active or if this is the first time
// panel is requested for this application.
@@ -347,10 +360,6 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event)
if (sControl) {
sControl->setIgnoreFocusChanged(false);
}
- //If m_pointerHandler has already been set, it means that fep inline editing is in progress.
- //When this is happening, do not filter out pointer events.
- if (!m_pointerHandler)
- return true;
}
}
@@ -420,7 +429,8 @@ void QCoeFepInputContext::mouseHandler(int x, QMouseEvent *event)
//If splitview is open and T9 word is tapped, pass the pointer event to pointer handler.
//This will open the "suggested words" list. Pass pointer position always as zero, to make
//full word replacement in case user makes a selection.
- if (S60->partial_keyboard && S60->partialKeyboardOpen
+ if (isPartialKeyboardSupported()
+ && S60->partialKeyboardOpen
&& m_pointerHandler
&& !(currentHints & Qt::ImhNoPredictiveText)
&& (x > 0 && x < m_preeditString.length())) {
@@ -466,7 +476,7 @@ void QCoeFepInputContext::resetSplitViewWidget(bool keepInputWidget)
if (!alwaysResize) {
if (gv->scene()) {
- if (gv->scene()->focusItem()) {
+ if (gv->scene()->focusItem() && S60->partial_keyboardAutoTranslation) {
// 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));
@@ -534,6 +544,11 @@ bool QCoeFepInputContext::isWidgetVisible(QWidget *widget, int offset)
return visible;
}
+bool QCoeFepInputContext::isPartialKeyboardSupported()
+{
+ return (S60->partial_keyboard || !QApplication::testAttribute(Qt::AA_S60DisablePartialScreenInputMode));
+}
+
// Ensure that the input widget is visible in the splitview rect.
void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
@@ -567,7 +582,7 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
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()) {
+ 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()));
@@ -604,12 +619,13 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget)
widget->resize(widget->width(), splitViewRect.height() - windowTop);
}
- if (gv->scene()) {
+ if (gv->scene() && S60->partial_keyboardAutoTranslation) {
const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF();
gv->ensureVisible(microFocusRect);
}
} else {
- translateInputWidget();
+ if (S60->partial_keyboardAutoTranslation)
+ translateInputWidget();
}
if (alwaysResize)
@@ -644,7 +660,7 @@ void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities)
// we need to update its state separately.
if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
TInt currentFlags = m_fepState->Flags();
- if (S60->partial_keyboard)
+ if (isPartialKeyboardSupported())
currentFlags |= QT_EAknEditorFlagEnablePartialScreen;
else
currentFlags &= ~QT_EAknEditorFlagEnablePartialScreen;
@@ -761,7 +777,7 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
flags = 0;
if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) {
- if (S60->partial_keyboard)
+ if (isPartialKeyboardSupported())
flags |= QT_EAknEditorFlagEnablePartialScreen;
flags |= QT_EAknEditorFlagSelectionVisible;
}
@@ -1055,15 +1071,24 @@ void QCoeFepInputContext::CancelFepInlineEdit()
// We are not supposed to ever have a tempPreeditString and a real preedit string
// from S60 at the same time, so it should be safe to rely on this test to determine
// whether we should honor S60's request to clear the text or not.
- if (m_hasTempPreeditString)
+ if (m_hasTempPreeditString || m_pendingTransactionCancel)
return;
+ m_pendingTransactionCancel = true;
+
QList<QInputMethodEvent::Attribute> attributes;
QInputMethodEvent event(QLatin1String(""), attributes);
event.setCommitString(QLatin1String(""), 0, 0);
m_preeditString.clear();
m_inlinePosition = 0;
sendEvent(event);
+
+ // Sync with native side editor state. Native side can then do various operations
+ // based on editor state, such as removing 'exact word bubble'.
+ if (!m_pendingInputCapabilitiesChanged)
+ ReportAknEdStateEvent(MAknEdStateObserver::EAknSyncEdwinState);
+
+ m_pendingTransactionCancel = false;
}
TInt QCoeFepInputContext::DocumentLengthForFep() const
@@ -1073,7 +1098,18 @@ TInt QCoeFepInputContext::DocumentLengthForFep() const
return 0;
QVariant variant = w->inputMethodQuery(Qt::ImSurroundingText);
- return variant.value<QString>().size() + m_preeditString.size();
+
+ int size = variant.value<QString>().size() + m_preeditString.size();
+
+ // To fix an issue with backspaces not being generated if document size is zero,
+ // fake document length to be at least one always, except when dealing with
+ // hidden text widgets, where this faking would generate extra asterisk. Since the
+ // primary use of hidden text widgets is password fields, they are unlikely to
+ // support multiple lines anyway.
+ if (size == 0 && !(m_textCapabilities & TCoeInputCapabilities::ESecretText))
+ size = 1;
+
+ return size;
}
TInt QCoeFepInputContext::DocumentMaximumLengthForFep() const
@@ -1156,6 +1192,12 @@ void QCoeFepInputContext::GetEditorContentForFep(TDes& aEditorContent, TInt aDoc
// FEP expects the preedit string to be part of the editor content, so let's mix it in.
int cursor = w->inputMethodQuery(Qt::ImCursorPosition).toInt();
text.insert(cursor, m_preeditString);
+
+ // Add additional space to empty non-password text to compensate
+ // for the fake length we specified in DocumentLengthForFep().
+ if (text.size() == 0 && !(m_textCapabilities & TCoeInputCapabilities::ESecretText))
+ text += QChar(0x20);
+
aEditorContent.Copy(qt_QString2TPtrC(text.mid(aDocumentPosition, aLengthToRetrieve)));
}