summaryrefslogtreecommitdiffstats
path: root/src/gui/inputmethod
diff options
context:
space:
mode:
authorJanne Koskinen <janne.p.koskinen@digia.com>2009-05-11 12:16:25 (GMT)
committerJanne Koskinen <janne.p.koskinen@digia.com>2009-05-11 12:16:25 (GMT)
commitf005af3b8c8405219b39bacd348d3861f1243aa8 (patch)
treea2d1f332de493d3d2cf0e0d1b3ad7c062176fe39 /src/gui/inputmethod
parent8aaa0cbf3451dee7bc8e8276faad3b2f2954dc1c (diff)
parent565f2957fb049f2df0330fac72ec5335860b9c7f (diff)
downloadQt-f005af3b8c8405219b39bacd348d3861f1243aa8.zip
Qt-f005af3b8c8405219b39bacd348d3861f1243aa8.tar.gz
Qt-f005af3b8c8405219b39bacd348d3861f1243aa8.tar.bz2
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt-s60-public
Conflicts: src/gui/widgets/qmenu_symbian.cpp
Diffstat (limited to 'src/gui/inputmethod')
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_p.h5
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp210
-rw-r--r--src/gui/inputmethod/qinputcontext.cpp16
-rw-r--r--src/gui/inputmethod/qwininputcontext_win.cpp10
-rw-r--r--src/gui/inputmethod/qximinputcontext_p.h1
-rw-r--r--src/gui/inputmethod/qximinputcontext_x11.cpp13
6 files changed, 211 insertions, 44 deletions
diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h
index 7f0a482..9ce9724 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_p.h
+++ b/src/gui/inputmethod/qcoefepinputcontext_p.h
@@ -63,6 +63,8 @@ public:
private:
void commitCurrentString();
+ void updateHints();
+ void applyHints(Qt::InputMethodHints hints);
// From MCoeFepAwareTextEditor
public:
@@ -98,11 +100,12 @@ private:
QSymbianControl *m_parent;
CAknEdwinState *m_fepState;
QString m_preeditString;
+ Qt::InputMethodHints m_lastImHints;
+ TUint m_textCapabilities;
bool m_isEditing;
bool m_inDestruction;
int m_cursorVisibility;
int m_inlinePosition;
- QPoint m_mousePressPos;
MFepInlineTextFormatRetriever *m_formatRetriever;
MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler;
};
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index b9ea4c7..1ae3d79 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -31,6 +31,8 @@ QT_BEGIN_NAMESPACE
QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
: QInputContext(parent),
m_fepState(new (ELeave) CAknEdwinState),
+ m_lastImHints(Qt::ImhNone),
+ m_textCapabilities(TCoeInputCapabilities::EAllText),
m_isEditing(false),
m_inDestruction(false),
m_cursorVisibility(1),
@@ -41,12 +43,10 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_fepState->SetObjectProvider(this);
m_fepState->SetFlags(EAknEditorFlagDefault);
m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
- m_fepState->SetCurrentInputMode( EAknEditorTextInputMode );
m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
m_fepState->SetLocalLanguage(ELangEnglish);
m_fepState->SetDefaultLanguage(ELangEnglish);
m_fepState->SetDefaultCase( EAknEditorLowerCase );
- m_fepState->SetCurrentCase( EAknEditorLowerCase );
m_fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase );
m_fepState->SetSpecialCharacterTableResourceId( 0 );
m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
@@ -74,7 +74,9 @@ void QCoeFepInputContext::reset()
void QCoeFepInputContext::update()
{
- // For pre-5.0 SDKs, we don't do any work.
+ updateHints();
+
+ // For pre-5.0 SDKs, we don't do text updates on S60 side.
if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) {
return;
}
@@ -92,6 +94,8 @@ void QCoeFepInputContext::setFocusWidget(QWidget *w)
CCoeEnv::Static()->Fep()->CancelTransaction();
QInputContext::setFocusWidget(w);
+
+ updateHints();
}
void QCoeFepInputContext::widgetDestroyed(QWidget *w)
@@ -203,44 +207,49 @@ QString QCoeFepInputContext::language()
bool QCoeFepInputContext::filterEvent(const QEvent *event)
{
- // For pre-5.0 SDKs, we don't do any work.
+ // 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;
+
+ if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) {
+ const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event);
+ Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints());
+ if (keyEvent->key() == Qt::Key_F20 && m_lastImHints & Qt::ImhHiddenText) {
+ // Special case in Symbian. On editors with secret text, F20 is for some reason
+ // considered to be a backspace.
+ QKeyEvent modifiedEvent(keyEvent->type(), Qt::Key_Backspace, keyEvent->modifiers(),
+ keyEvent->text(), keyEvent->isAutoRepeat(), keyEvent->count());
+ QApplication::sendEvent(focusWidget(), &modifiedEvent);
+ return true;
+ }
+ }
+
+ // For pre-5.0 SDKs, we don't launch the keyboard.
if (QSysInfo::s60Version() != QSysInfo::SV_S60_5_0) {
return false;
}
- if (event->type() == QEvent::MouseButtonPress) {
- const QMouseEvent *mEvent = static_cast<const QMouseEvent *>(event);
- m_mousePressPos = mEvent->globalPos();
- } else if (event->type() == QEvent::MouseButtonRelease) {
+ if (event->type() == QEvent::RequestSoftwareInputPanel) {
// Notify S60 that we want the virtual keyboard to show up.
- const QMouseEvent *mEvent = static_cast<const QMouseEvent *>(event);
-
- if (mEvent->modifiers() == Qt::NoModifier
- && mEvent->button() == Qt::LeftButton
- && focusWidget() // Not set if prior MouseButtonPress was not on this widget
- && focusWidget()->rect().contains(focusWidget()->mapFromGlobal(mEvent->globalPos()))
- && (m_mousePressPos - mEvent->globalPos()).manhattanLength() < QApplication::startDragDistance()) {
-
- QSymbianControl *sControl;
- sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl);
- // The FEP UI temporarily steals focus when it shows up the first time, causing
- // all sorts of weird effects on the focused widgets. Since it will immediately give
- // back focus to us, we temporarily disable focus handling until the job's done.
- if (sControl) {
- sControl->setIgnoreFocusChanged(true);
- }
+ QSymbianControl *sControl;
+ sControl = focusWidget()->effectiveWinId()->MopGetObject(sControl);
+ Q_ASSERT(sControl);
+
+ // The FEP UI temporarily steals focus when it shows up the first time, causing
+ // all sorts of weird effects on the focused widgets. Since it will immediately give
+ // back focus to us, we temporarily disable focus handling until the job's done.
+ if (sControl) {
+ sControl->setIgnoreFocusChanged(true);
+ }
- m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest);
+ m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::QT_EAknActivatePenInputRequest);
- if (sControl) {
- sControl->setIgnoreFocusChanged(false);
- }
-
- // Although it is tempting to let the click through by returning false, we have to return
- // true because the event might have caused focus switches, which may in turn delete
- // widgets.
- return true;
+ if (sControl) {
+ sControl->setIgnoreFocusChanged(false);
}
+ return true;
}
return false;
@@ -307,7 +316,7 @@ TCoeInputCapabilities QCoeFepInputContext::inputCapabilities()
return TCoeInputCapabilities(TCoeInputCapabilities::ENone, 0, 0);
}
- return TCoeInputCapabilities(TCoeInputCapabilities::EAllText, this, 0);
+ return TCoeInputCapabilities(m_textCapabilities, this, 0);
}
static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat)
@@ -323,6 +332,139 @@ static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat
return qFormat;
}
+void QCoeFepInputContext::updateHints()
+{
+ QWidget *w = focusWidget();
+ if (w) {
+ Qt::InputMethodHints hints = w->inputMethodHints();
+ if (hints != m_lastImHints) {
+ m_lastImHints = hints;
+ applyHints(hints);
+ }
+ }
+}
+
+void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
+{
+ using namespace Qt;
+
+ bool numbersOnly = hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
+ || hints & ImhDialableCharactersOnly;
+ bool noOnlys = !(numbersOnly || hints & ImhUppercaseOnly
+ || hints & ImhLowercaseOnly);
+ TInt flags;
+ Qt::InputMethodHints oldHints = hints;
+
+ // Some sanity checking. Make sure that only one preference is set.
+ InputMethodHints prefs = ImhPreferNumbers | ImhPreferUppercase | ImhPreferLowercase;
+ prefs &= hints;
+ if (prefs != ImhPreferNumbers && prefs != ImhPreferUppercase && prefs != ImhPreferLowercase) {
+ hints &= ~prefs;
+ }
+ if (!noOnlys) {
+ // Make sure that the preference is within the permitted set.
+ if (hints & ImhPreferNumbers && !(hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
+ || hints & ImhDialableCharactersOnly)) {
+ hints &= ~ImhPreferNumbers;
+ } else if (hints & ImhPreferUppercase && !(hints & ImhUppercaseOnly)) {
+ hints &= ~ImhPreferUppercase;
+ } else if (hints & ImhPreferLowercase && !(hints & ImhLowercaseOnly)) {
+ hints &= ~ImhPreferLowercase;
+ }
+ // If there is no preference, set it to something within the permitted set.
+ if (!(hints & ImhPreferNumbers || hints & ImhPreferUppercase || hints & ImhPreferLowercase)) {
+ if (hints & ImhLowercaseOnly) {
+ hints |= ImhPreferLowercase;
+ } else if (hints & ImhUppercaseOnly) {
+ hints |= ImhPreferUppercase;
+ } else if (hints & ImhDigitsOnly || hints & ImhFormattedNumbersOnly
+ || hints & ImhDialableCharactersOnly) {
+ hints |= ImhPreferNumbers;
+ }
+ }
+ }
+
+ if (hints & ImhPreferNumbers) {
+ m_fepState->SetDefaultInputMode(EAknEditorNumericInputMode);
+ m_fepState->SetCurrentInputMode(EAknEditorNumericInputMode);
+ } else {
+ m_fepState->SetDefaultInputMode(EAknEditorTextInputMode);
+ m_fepState->SetCurrentInputMode(EAknEditorTextInputMode);
+ }
+ flags = 0;
+ if (numbersOnly) {
+ flags |= EAknEditorNumericInputMode;
+ }
+ if (hints & ImhUppercaseOnly || hints & ImhLowercaseOnly) {
+ flags |= EAknEditorTextInputMode;
+ }
+ if (flags == 0) {
+ flags = EAknEditorAllInputModes;
+ }
+ m_fepState->SetPermittedInputModes(flags);
+ m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateInputModeUpdate);
+
+ if (hints & ImhPreferLowercase) {
+ m_fepState->SetDefaultCase(EAknEditorLowerCase);
+ m_fepState->SetCurrentCase(EAknEditorLowerCase);
+ } else if (hints & ImhPreferUppercase) {
+ m_fepState->SetDefaultCase(EAknEditorUpperCase);
+ m_fepState->SetCurrentCase(EAknEditorUpperCase);
+ } else if (hints & ImhNoAutoUppercase) {
+ m_fepState->SetDefaultCase(EAknEditorLowerCase);
+ m_fepState->SetCurrentCase(EAknEditorLowerCase);
+ } else {
+ m_fepState->SetDefaultCase(EAknEditorTextCase);
+ m_fepState->SetCurrentCase(EAknEditorTextCase);
+ }
+ flags = 0;
+ if (hints & ImhUppercaseOnly) {
+ flags |= EAknEditorUpperCase;
+ }
+ if (hints & ImhLowercaseOnly) {
+ flags |= EAknEditorLowerCase;
+ }
+ if (flags == 0) {
+ flags = EAknEditorAllCaseModes;
+ if (hints & ImhNoAutoUppercase) {
+ flags &= ~EAknEditorTextCase;
+ }
+ }
+ m_fepState->SetPermittedCases(flags);
+ m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateCaseModeUpdate);
+
+ flags = 0;
+ if (hints & ImhUppercaseOnly && !(hints & ImhLowercaseOnly)
+ || hints & ImhLowercaseOnly && !(hints & ImhUppercaseOnly)) {
+ flags |= EAknEditorFlagFixedCase;
+ }
+ // Using T9 and hidden text together may actually crash the FEP, so check for hidden text too.
+ if (hints & ImhNoPredictiveText || hints & ImhHiddenText) {
+ flags |= EAknEditorFlagNoT9;
+ }
+ m_fepState->SetFlags(flags);
+ m_fepState->ReportAknEdStateEventL(MAknEdStateObserver::EAknEdwinStateFlagsUpdate);
+
+ if (hints & ImhFormattedNumbersOnly) {
+ flags = EAknEditorCalculatorNumberModeKeymap;
+ } else if (hints & ImhDigitsOnly) {
+ flags = EAknEditorPlainNumberModeKeymap;
+ } else {
+ // ImhDialableCharactersOnly is the fallback as well, so we don't need to check for
+ // that flag.
+ flags = EAknEditorStandardNumberModeKeymap;
+ }
+ m_fepState->SetNumericKeymap(static_cast<TAknEditorNumericKeymap>(flags));
+
+ if (hints & ImhHiddenText) {
+ m_textCapabilities = TCoeInputCapabilities::EAllText | TCoeInputCapabilities::ESecretText;
+ } else {
+ m_textCapabilities = TCoeInputCapabilities::EAllText;
+ }
+
+ CCoeEnv::Static()->InputCapabilitiesChanged();
+}
+
void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
TInt aPositionOfInsertionPointInInlineText, TBool aCursorVisibility, const MFormCustomDraw* /*aCustomDraw*/,
MFepInlineTextFormatRetriever& aInlineTextFormatRetriever,
diff --git a/src/gui/inputmethod/qinputcontext.cpp b/src/gui/inputmethod/qinputcontext.cpp
index 3d6d303..c7d156c 100644
--- a/src/gui/inputmethod/qinputcontext.cpp
+++ b/src/gui/inputmethod/qinputcontext.cpp
@@ -209,7 +209,19 @@ void QInputContext::setFocusWidget(QWidget *widget)
way. Although the input events have accept() and ignore()
methods, leave it untouched.
- \a event is currently restricted to QKeyEvent and QMouseEvent.
+ \a event is currently restricted to events of these types:
+
+ \list
+ \i CloseSoftwareInputPanel
+ \i KeyPress
+ \i KeyRelease
+ \i MouseButtonDblClick
+ \i MouseButtonPress
+ \i MouseButtonRelease
+ \i MouseMove
+ \i RequestSoftwareInputPanel
+ \endlist
+
But some input method related events such as QWheelEvent or
QTabletEvent may be added in future.
@@ -464,7 +476,7 @@ bool QInputContext::x11FilterEvent(QWidget * /*keywidget*/, XEvent * /*event*/)
This function may be overridden only if input method is depending
on Symbian and you need raw TWsEvent. Otherwise, this function must not.
- This function is designed to filter raw key events for XIM, but
+ This function is designed to filter raw key events on S60, but
other input methods may use this to implement some special
features.
diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp
index 720f0b8..e3e8aa4 100644
--- a/src/gui/inputmethod/qwininputcontext_win.cpp
+++ b/src/gui/inputmethod/qwininputcontext_win.cpp
@@ -57,15 +57,17 @@
#ifdef Q_IME_DEBUG
#include "qdebug.h"
-#endif
-
-QT_BEGIN_NAMESPACE
+#endif
-extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
#if defined(Q_OS_WINCE)
extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp
#endif
+QT_BEGIN_NAMESPACE
+
+extern bool qt_sendSpontaneousEvent(QObject*, QEvent*);
+
+
DEFINE_GUID(IID_IActiveIMMApp,
0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e);
diff --git a/src/gui/inputmethod/qximinputcontext_p.h b/src/gui/inputmethod/qximinputcontext_p.h
index ca2103b..3773122 100644
--- a/src/gui/inputmethod/qximinputcontext_p.h
+++ b/src/gui/inputmethod/qximinputcontext_p.h
@@ -98,6 +98,7 @@ public:
QString text;
QBitArray selectedChars;
bool composing;
+ bool preeditEmpty;
void clear();
};
diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp
index 48a96b1..c320fb4 100644
--- a/src/gui/inputmethod/qximinputcontext_x11.cpp
+++ b/src/gui/inputmethod/qximinputcontext_x11.cpp
@@ -264,6 +264,7 @@ extern "C" {
qic->standardFormat(QInputContext::PreeditFormat));
attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, sellen ? 0 : 1, QVariant());
QInputMethodEvent e(data->text, attrs);
+ data->preeditEmpty = data->text.isEmpty();
qic->sendEvent(e);
return 0;
@@ -286,6 +287,7 @@ void QXIMInputContext::ICData::clear()
text = QString();
selectedChars.clear();
composing = false;
+ preeditEmpty = true;
}
QXIMInputContext::ICData *QXIMInputContext::icData() const
@@ -435,7 +437,8 @@ void QXIMInputContext::create_xim()
// reinitialize input context after the input method
// server (like SCIM) has been launched without
// requiring the user to manually switch focus.
- if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled))
+ if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled)
+ && focusWidget->testAttribute(Qt::WA_WState_Created))
setFocusWidget(focusWidget);
}
// following code fragment is not required for immodule
@@ -537,9 +540,12 @@ void QXIMInputContext::reset()
if (mb) {
e.setCommitString(QString::fromLocal8Bit(mb));
XFree(mb);
+ data->preeditEmpty = false; // force sending an event
+ }
+ if (!data->preeditEmpty) {
+ sendEvent(e);
+ update();
}
- sendEvent(e);
- update();
}
data->clear();
}
@@ -686,6 +692,7 @@ QXIMInputContext::ICData *QXIMInputContext::createICData(QWidget *w)
{
ICData *data = new ICData;
data->widget = w;
+ data->preeditEmpty = true;
XVaNestedList preedit_attr = 0;
XIMCallback startcallback, drawcallback, donecallback;