diff options
author | Prasanth Ullattil <prasanth.ullattil@nokia.com> | 2009-08-25 11:08:09 (GMT) |
---|---|---|
committer | Prasanth Ullattil <prasanth.ullattil@nokia.com> | 2009-08-27 09:43:26 (GMT) |
commit | 917d176fb49ee1cd54a57305e4d7ef1bd7ce6f34 (patch) | |
tree | 991185e86c865280b614d41a24a1c366a3b129d1 | |
parent | bca6787b48c152110b4afb2bd389b1fb9a6032cb (diff) | |
download | Qt-917d176fb49ee1cd54a57305e4d7ef1bd7ce6f34.zip Qt-917d176fb49ee1cd54a57305e4d7ef1bd7ce6f34.tar.gz Qt-917d176fb49ee1cd54a57305e4d7ef1bd7ce6f34.tar.bz2 |
Implement IME reconversion on windows.
Windows IME supports reconversion of text. e.g. On a Japanese layout,
up on pressing the HENKAN key a list of choices for the current word are
shown in a popup. This patch adds that support to Qt. We will select the
current word in the widget and the choices are shown as in the editing
mode.
Task-number:225588
Reviewed-by: axis
-rw-r--r-- | src/gui/inputmethod/qwininputcontext_p.h | 1 | ||||
-rw-r--r-- | src/gui/inputmethod/qwininputcontext_win.cpp | 49 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_win.cpp | 25 |
3 files changed, 74 insertions, 1 deletions
diff --git a/src/gui/inputmethod/qwininputcontext_p.h b/src/gui/inputmethod/qwininputcontext_p.h index eff223b..767fc33 100644 --- a/src/gui/inputmethod/qwininputcontext_p.h +++ b/src/gui/inputmethod/qwininputcontext_p.h @@ -79,6 +79,7 @@ public: bool startComposition(); bool endComposition(); bool composition(LPARAM lparam); + int reconvertString(RECONVERTSTRING *reconv); static void TranslateMessage(const MSG *msg); static LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp index 684f325..d917cb3 100644 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ b/src/gui/inputmethod/qwininputcontext_win.cpp @@ -47,6 +47,7 @@ #include "qapplication.h" #include "qevent.h" #include "qtextformat.h" +#include "qtextboundaryfinder.h" //#define Q_IME_DEBUG @@ -810,4 +811,52 @@ QString QWinInputContext::language() return QString(); } +int QWinInputContext::reconvertString(RECONVERTSTRING *reconv) +{ + QWidget *w = focusWidget(); + if(!w) + return -1; + + Q_ASSERT(w->testAttribute(Qt::WA_WState_Created)); + QString surroundingText = qvariant_cast<QString>(w->inputMethodQuery(Qt::ImSurroundingText)); + int memSize = sizeof(RECONVERTSTRING)+(surroundingText.length()+1)*sizeof(ushort); + // If memory is not allocated, return the required size. + if (!reconv) { + if (surroundingText.isEmpty()) + return -1; + else + return memSize; + } + int pos = qvariant_cast<int>(w->inputMethodQuery(Qt::ImCursorPosition)); + // find the word in the surrounding text. + QTextBoundaryFinder bounds(QTextBoundaryFinder::Word, surroundingText); + bounds.setPosition(pos); + if (bounds.isAtBoundary()) { + if (QTextBoundaryFinder::EndWord == bounds.boundaryReasons()) + bounds.toPreviousBoundary(); + } else { + bounds.toPreviousBoundary(); + } + int startPos = bounds.position(); + bounds.toNextBoundary(); + int endPos = bounds.position(); + // select the text, this will be overwritten by following ime events. + QList<QInputMethodEvent::Attribute> attrs; + attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant()); + QInputMethodEvent e(QString(), attrs); + qt_sendSpontaneousEvent(w, &e); + + reconv->dwSize = memSize; + reconv->dwVersion = 0; + + reconv->dwStrLen = surroundingText.length(); + reconv->dwStrOffset = sizeof(RECONVERTSTRING); + reconv->dwCompStrLen = endPos-startPos; + reconv->dwCompStrOffset = startPos*sizeof(ushort); + reconv->dwTargetStrLen = reconv->dwCompStrLen; + reconv->dwTargetStrOffset = reconv->dwCompStrOffset; + memcpy((char*)(reconv+1), surroundingText.utf16(), surroundingText.length()*sizeof(ushort)); + return memSize; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 76a3b1e..b92bf03 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -171,6 +171,10 @@ typedef struct tagTOUCHINPUT #include <mywinsock.h> #endif +#ifndef IMR_CONFIRMRECONVERTSTRING +#define IMR_CONFIRMRECONVERTSTRING 0x0005 +#endif + QT_BEGIN_NAMESPACE #ifdef Q_WS_WINCE @@ -2263,7 +2267,26 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam } break; } - + case WM_IME_REQUEST: { + QWidget *fw = QApplication::focusWidget(); + QWinInputContext *im = fw ? qobject_cast<QWinInputContext *>(fw->inputContext()) : 0; + if (fw && im) { + if(wParam == IMR_RECONVERTSTRING) { + int ret = im->reconvertString((RECONVERTSTRING *)lParam); + if (ret == -1) { + result = false; + } else { + return ret; + } + } else if (wParam == IMR_CONFIRMRECONVERTSTRING) { + RETURN(TRUE); + } else { + // in all other cases, call DefWindowProc() + result = false; + } + } + break; + } #ifndef Q_WS_WINCE case WM_CHANGECBCHAIN: case WM_DRAWCLIPBOARD: |