From 6e5d6d292ba6bcd686367077228b17d02160bee9 Mon Sep 17 00:00:00 2001 From: Marko Kenttala Date: Fri, 20 Apr 2012 16:14:23 +0300 Subject: Fix for clipped Vietnamese characters when typed with VKB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding tone marks with VKB to Vietnamese vowels caused them to be clipped from top. Added character conversion to Symbian VKB handling so that correct characters without clipping are used. Task-Number: ou1cimx1#981433 Change-Id: Iaf9f2ce9f5cf42e74cac100658025eb6e20e6487 Reviewed-by: Juha Kukkonen Reviewed-by: Pasi Pentikäinen --- src/gui/inputmethod/qcoefepinputcontext_p.h | 1 + src/gui/inputmethod/qcoefepinputcontext_s60.cpp | 108 ++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index 4b36da3..1b62a25 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -132,6 +132,7 @@ private: void commitTemporaryPreeditString(); bool isWidgetVisible(QWidget *widget, int offset = 0); bool isPartialKeyboardSupported(); + bool vietCharConversion(const QEvent *event); private Q_SLOTS: void ensureInputCapabilitiesChanged(); diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 44a54a3..5ced556 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -101,6 +101,49 @@ _LIT(KAvkonResourceFile, "z:\\resource\\avkon.rsc" ); +// Vietnamese tone tables +const int VietToneMarks = 5; + +const QChar VietToneList[VietToneMarks] = { + 0x0301, 0x0300, 0x0309, 0x0303, 0x0323 +}; + +const QChar VietVowelList[] = { + 0x0041, 0x0061, 0x0102, 0x0103, 0x00c2, + 0x00e2, 0x0045, 0x0065, 0x00ca, 0x00ea, + 0x0049, 0x0069, 0x004f, 0x006f, 0x00d4, + 0x00f4, 0x01a0, 0x01a1, 0x0055, 0x0075, + 0x01af, 0x01b0, 0x0059, 0x0079 +}; + +const QChar VietToneMatrix[][VietToneMarks] = { + // Matrix for each vowel (row) after applying certain tone mark (column) + 0x00c1, 0x00c0, 0x1ea2, 0x00c3, 0x1ea0, + 0x00e1, 0x00e0, 0x1ea3, 0x00e3, 0x1ea1, + 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, + 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, + 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, + 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, + 0x00c9, 0x00c8, 0x1eba, 0x1ebc, 0x1eb8, + 0x00e9, 0x00e8, 0x1ebb, 0x1ebd, 0x1eb9, + 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, + 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, + 0x00cd, 0x00cc, 0x1ec8, 0x0128, 0x1eca, + 0x00ed, 0x00ec, 0x1ec9, 0x0129, 0x1ecb, + 0x00d3, 0x00d2, 0x1ece, 0x00d5, 0x1ecc, + 0x00f3, 0x00f2, 0x1ecf, 0x00f5, 0x1ecd, + 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, + 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, + 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, + 0x1edb, 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, + 0x00da, 0x00d9, 0x1ee6, 0x0168, 0x1ee4, + 0x00fa, 0x00f9, 0x1ee7, 0x0169, 0x1ee5, + 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0, + 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1, + 0x00dd, 0x1ef2, 0x1ef6, 0x1ef8, 0x1ef4, + 0x00fd, 0x1ef3, 0x1ef7, 0x1ef9, 0x1ef5 +}; + QT_BEGIN_NAMESPACE static QWidget* getFocusedChild(const QList& objectList) @@ -572,11 +615,76 @@ bool QCoeFepInputContext::needsInputPanel() } } +bool QCoeFepInputContext::vietCharConversion(const QEvent *event) +{ + const QKeyEvent *keyEvent = static_cast(event); + const uint VietVowelListCount = sizeof(VietVowelList)/sizeof(VietVowelList[0]); + for (int tone = 0; tone < VietToneMarks; tone++) { + if (keyEvent->key() == VietToneList[tone]) { + // Vietnamese vowel tone mark pressed, check previous character + const int cursor = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); + if (cursor > 0) { + QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString(); + for (int vowel = 0; vowel < VietVowelListCount; vowel++) { + if (widgetText[cursor-1].unicode() == VietVowelList[vowel]) { + // Previous character is Vietnamese vowel, replace it from matrix + QList attributes; + if (event->type() == QEvent::KeyPress) { + QInputMethodEvent imEvent(QString(VietToneMatrix[vowel][tone]), attributes); + sendEvent(imEvent); + } else { + // event->type() == QEvent::KeyRelease + QInputMethodEvent imEvent(QLatin1String(""), attributes); + imEvent.setCommitString(QString(VietToneMatrix[vowel][tone]), -1, 1); + sendEvent(imEvent); + } + return true; + } + } + } + return false; + } + } + if (keyEvent->key() == Qt::Key_Backspace) { + // Backspace pressed, check previous character + const int cursor = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); + if (cursor > 0) { + QString widgetText = focusWidget()->inputMethodQuery(Qt::ImSurroundingText).toString(); + for (int vowel = 0; vowel < VietVowelListCount; vowel++) { + for (int tone = 0; tone < VietToneMarks; tone++) { + if (widgetText[cursor-1].unicode() == VietToneMatrix[vowel][tone]) { + // Previous character is Vietnamese vowel with tone, replace it with plain vowel + QList attributes; + if (event->type() == QEvent::KeyPress) { + QInputMethodEvent imEvent(QString(VietVowelList[vowel]), attributes); + sendEvent(imEvent); + } else { + // event->type() == QEvent::KeyRelease + QInputMethodEvent imEvent(QLatin1String(""), attributes); + imEvent.setCommitString(QString(VietVowelList[vowel]), -1, 1); + sendEvent(imEvent); + } + return true; + } + } + } + } + } + return false; +} + bool QCoeFepInputContext::filterEvent(const QEvent *event) { if (!focusWidget()) return false; + if ((event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) && + QApplication::keyboardInputLocale().language() == QLocale::Vietnamese) { + // Vietnamese character conversions + if (vietCharConversion(event)) + return true; + } + switch (event->type()) { case QEvent::KeyPress: commitTemporaryPreeditString(); -- cgit v0.12