diff options
author | Jarkko Koivikko <jarkko.koivikko@code-q.fi> | 2014-08-05 13:37:49 +0300 |
---|---|---|
committer | Jarkko Koivikko <jarkko.koivikko@code-q.fi> | 2014-08-14 09:41:52 +0300 |
commit | 1290471fc3e542388e79e27cb2c4ce654f5023f3 (patch) | |
tree | 23a81b2c339c394db4d14ef3cfe3931eaadf9a81 | |
parent | 7a7ddb56dee32cc7acf284abed3bfbd1cbb5c99b (diff) |
Make the keyboard layout changeable in password / url input mode
Removed latin-only restriction with specific input method hints.
More specifically, the latin-only keyboard was previously enforced
when password, hidden, sensitive or latin-only flags were set for
the input control.
Now it is possible to use non-latin input methods and keyboard
layouts with these modes too. However, this change implies some
additional changes to the Pinyin and Hunspell input methods.
Changes to PinyinInputMethod:
- Disable the user dictionary when sensitive data flag is set.
This is required so that sensitive data (such as passwords)
is not stored in the user dictionary.
Changes to HunspellInputMethod:
- Disable the auto space functionality when the input mode is not
latin, or the exclusive input mode is set to url or email input.
Task-number: QTRD-3210
Change-Id: I444c4b87c9805b69dc773ef6cac76f1c11dd220a
Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
Reviewed-by: Rainer Keller <rainer.keller@digia.com>
-rw-r--r-- | src/virtualkeyboard/3rdparty/pinyin/include/matrixsearch.h | 4 | ||||
-rw-r--r-- | src/virtualkeyboard/3rdparty/pinyin/include/pinyinime.h | 12 | ||||
-rw-r--r-- | src/virtualkeyboard/3rdparty/pinyin/share/matrixsearch.cpp | 23 | ||||
-rw-r--r-- | src/virtualkeyboard/3rdparty/pinyin/share/pinyinime.cpp | 11 | ||||
-rw-r--r-- | src/virtualkeyboard/content/components/Keyboard.qml | 33 | ||||
-rw-r--r-- | src/virtualkeyboard/declarativeinputcontext.cpp | 3 | ||||
-rw-r--r-- | src/virtualkeyboard/hunspellinputmethod.cpp | 30 | ||||
-rw-r--r-- | src/virtualkeyboard/pinyindecoderservice.cpp | 18 | ||||
-rw-r--r-- | src/virtualkeyboard/pinyindecoderservice.h | 2 | ||||
-rw-r--r-- | src/virtualkeyboard/pinyininputmethod.cpp | 11 |
10 files changed, 119 insertions, 28 deletions
diff --git a/src/virtualkeyboard/3rdparty/pinyin/include/matrixsearch.h b/src/virtualkeyboard/3rdparty/pinyin/include/matrixsearch.h index f581d30a..61e78aa6 100644 --- a/src/virtualkeyboard/3rdparty/pinyin/include/matrixsearch.h +++ b/src/virtualkeyboard/3rdparty/pinyin/include/matrixsearch.h @@ -380,6 +380,10 @@ class MatrixSearch { bool init_fd(int sys_fd, long start_offset, long length, const char *fn_usr_dict); + void init_user_dictionary(const char *fn_usr_dict); + + bool is_user_dictionary_enabled() const; + void set_max_lens(size_t max_sps_len, size_t max_hzs_len); void close(); diff --git a/src/virtualkeyboard/3rdparty/pinyin/include/pinyinime.h b/src/virtualkeyboard/3rdparty/pinyin/include/pinyinime.h index 0744ec7d..e376c20c 100644 --- a/src/virtualkeyboard/3rdparty/pinyin/include/pinyinime.h +++ b/src/virtualkeyboard/3rdparty/pinyin/include/pinyinime.h @@ -202,6 +202,18 @@ extern "C" { * Enable Yunmus in ShouZiMu mode. */ void im_enable_ym_as_szm(bool enable); + + /** + * Initializes or uninitializes the user dictionary. + * + * @param fn_usr_dict The file name of the user dictionary. + */ + void im_init_user_dictionary(const char *fn_usr_dict); + + /** + * Returns the current status of user dictinary. + */ + bool im_is_user_dictionary_enabled(void); } #ifdef __cplusplus diff --git a/src/virtualkeyboard/3rdparty/pinyin/share/matrixsearch.cpp b/src/virtualkeyboard/3rdparty/pinyin/share/matrixsearch.cpp index 12d092a9..41e11433 100644 --- a/src/virtualkeyboard/3rdparty/pinyin/share/matrixsearch.cpp +++ b/src/virtualkeyboard/3rdparty/pinyin/share/matrixsearch.cpp @@ -169,6 +169,29 @@ bool MatrixSearch::init_fd(int sys_fd, long start_offset, long length, return true; } +void MatrixSearch::init_user_dictionary(const char *fn_usr_dict) { + assert(inited_); + + if (NULL != user_dict_) { + delete user_dict_; + user_dict_ = NULL; + } + + if (NULL != fn_usr_dict) { + user_dict_ = static_cast<AtomDictBase*>(new UserDict()); + if (!user_dict_->load_dict(fn_usr_dict, kUserDictIdStart, kUserDictIdEnd)) { + delete user_dict_; + user_dict_ = NULL; + } + } + + reset_search0(); +} + +bool MatrixSearch::is_user_dictionary_enabled() const { + return NULL != user_dict_; +} + void MatrixSearch::set_max_lens(size_t max_sps_len, size_t max_hzs_len) { if (0 != max_sps_len) max_sps_len_ = max_sps_len; diff --git a/src/virtualkeyboard/3rdparty/pinyin/share/pinyinime.cpp b/src/virtualkeyboard/3rdparty/pinyin/share/pinyinime.cpp index 550da7bf..4d206a76 100644 --- a/src/virtualkeyboard/3rdparty/pinyin/share/pinyinime.cpp +++ b/src/virtualkeyboard/3rdparty/pinyin/share/pinyinime.cpp @@ -181,6 +181,17 @@ extern "C" { spl_trie.szm_enable_ym(enable); } + void im_init_user_dictionary(const char *fn_usr_dict) { + if (!matrix_search) + return; + matrix_search->flush_cache(); + matrix_search->init_user_dictionary(fn_usr_dict); + } + + bool im_is_user_dictionary_enabled(void) { + return NULL != matrix_search ? matrix_search->is_user_dictionary_enabled() : false; + } + #ifdef __cplusplus } #endif diff --git a/src/virtualkeyboard/content/components/Keyboard.qml b/src/virtualkeyboard/content/components/Keyboard.qml index b4da5a35..a6bc89a2 100644 --- a/src/virtualkeyboard/content/components/Keyboard.qml +++ b/src/virtualkeyboard/content/components/Keyboard.qml @@ -49,7 +49,7 @@ Item { property bool dialpadMode: InputContext.inputMethodHints & Qt.ImhDialableCharactersOnly property bool numberMode: InputContext.inputMethodHints & Qt.ImhFormattedNumbersOnly property bool digitMode: InputContext.inputMethodHints & Qt.ImhDigitsOnly - property bool latinOnly: InputContext.inputMethodHints & (Qt.ImhHiddenText | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText | Qt.ImhLatinOnly) + property bool latinOnly: InputContext.inputMethodHints & Qt.ImhLatinOnly property bool symbolMode property var defaultInputMethod: initDefaultInputMethod() property var plainInputMethod: PlainInputMethod {} @@ -83,7 +83,6 @@ Item { updateLayout() } onLatinOnlyChanged: { - updateLayout() updateInputMethod() } @@ -766,21 +765,15 @@ Item { return var inputMethod = null var inputMode = InputContext.inputEngine.inputMode - // Force plain input method in password mode - if (latinOnly) { - inputMethod = keyboard.plainInputMethod + // Use input method from keyboard layout + if (keyboardLayoutLoader.item.inputMethod) + inputMethod = keyboardLayoutLoader.item.inputMethod + else + inputMethod = keyboard.defaultInputMethod + if (latinOnly) inputMode = InputEngine.Latin - } else { - // Use input method from keyboard layout - if (keyboardLayoutLoader.item.inputMethod) { - inputMethod = keyboardLayoutLoader.item.inputMethod - } else { - inputMethod = keyboard.defaultInputMethod - } - if (keyboardLayoutLoader.item.inputMode !== -1) { - inputMode = keyboardLayoutLoader.item.inputMode - } - } + else if (keyboardLayoutLoader.item.inputMode !== -1) + inputMode = keyboardLayoutLoader.item.inputMode var inputMethodChanged = InputContext.inputEngine.inputMethod !== inputMethod if (inputMethodChanged) { InputContext.inputEngine.inputMethod = inputMethod @@ -802,11 +795,11 @@ Item { function updateLayout() { var newLayout - newLayout = findLayout(latinOnly ? defaultLocale : locale, layoutType) + newLayout = findLayout(locale, layoutType) if (!newLayout.length) { - newLayout = findLayout(latinOnly ? defaultLocale : locale, "main") + newLayout = findLayout(locale, "main") } - inputLocale = !latinOnly && layoutExists(locale, layoutType) ? locale : defaultLocale + inputLocale = layoutExists(locale, layoutType) ? locale : defaultLocale layout = newLayout } @@ -859,7 +852,7 @@ Item { } function canChangeInputLanguage(customLayoutsOnly) { - return !latinOnly && availableLocaleIndices.length > 1 + return availableLocaleIndices.length > 1 } function findLocale(localeName, defaultValue) { diff --git a/src/virtualkeyboard/declarativeinputcontext.cpp b/src/virtualkeyboard/declarativeinputcontext.cpp index 6e1c17df..dff138eb 100644 --- a/src/virtualkeyboard/declarativeinputcontext.cpp +++ b/src/virtualkeyboard/declarativeinputcontext.cpp @@ -486,6 +486,9 @@ void DeclarativeInputContext::update(Qt::InputMethodQueries queries) if (newSurroundingText || newCursorPosition) { d->inputEngine->update(); } + if (newInputMethodHints) { + d->inputEngine->reset(); + } // notify if (newInputMethodHints) { diff --git a/src/virtualkeyboard/hunspellinputmethod.cpp b/src/virtualkeyboard/hunspellinputmethod.cpp index 7f78fa29..e8e97a94 100644 --- a/src/virtualkeyboard/hunspellinputmethod.cpp +++ b/src/virtualkeyboard/hunspellinputmethod.cpp @@ -148,6 +148,19 @@ public: return !wordCandidates.isEmpty(); } + bool isAutoSpaceAllowed() const + { + Q_Q(const HunspellInputMethod); + if (q->inputEngine()->inputMode() != DeclarativeInputEngine::Latin) + return false; + DeclarativeInputContext *ic = q->inputContext(); + if (!ic) + return false; + Qt::InputMethodHints inputMethodHints = ic->inputMethodHints(); + return !inputMethodHints.testFlag(Qt::ImhUrlCharactersOnly) && + !inputMethodHints.testFlag(Qt::ImhEmailCharactersOnly); + } + HunspellInputMethod *q_ptr; QScopedPointer<HunspellWorker> hunspellWorker; QString locale; @@ -189,6 +202,7 @@ bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboar { Q_UNUSED(modifiers) Q_D(HunspellInputMethod); + DeclarativeInputContext *ic = inputContext(); bool accept = false; switch (key) { case Qt::Key_Enter: @@ -200,7 +214,7 @@ bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboar case Qt::Key_Backspace: if (!d->word.isEmpty()) { d->word.remove(d->word.length() - 1, 1); - inputContext()->setPreeditText(d->word); + ic->setPreeditText(d->word); if (d->updateSuggestions()) { emit selectionListChanged(DeclarativeSelectionListModel::WordCandidateList); emit selectionListActiveItemChanged(DeclarativeSelectionListModel::WordCandidateList, d->activeWordIndex); @@ -209,6 +223,8 @@ bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboar } break; default: + if (ic->inputMethodHints().testFlag(Qt::ImhNoPredictiveText)) + break; if (text.length() > 0) { QChar c = text.at(0); bool addToWord = !c.isPunct() && !c.isSymbol(); @@ -219,7 +235,6 @@ bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboar } } if (addToWord) { - DeclarativeInputContext *ic = inputContext(); /* Automatic space insertion. */ if (d->word.isEmpty()) { QString surroundingText = ic->surroundingText(); @@ -234,8 +249,9 @@ bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboar QChar lastChar = surroundingText.at(cursorPosition - 1); if (!lastChar.isSpace() && lastChar != Qt::Key_Minus && - lastChar != Qt::Key_Apostrophe) { - inputContext()->commit(" "); + lastChar != Qt::Key_Apostrophe && + d->isAutoSpaceAllowed()) { + ic->commit(" "); } } } @@ -249,9 +265,9 @@ bool HunspellInputMethod::keyEvent(Qt::Key key, const QString &text, Qt::Keyboar } else if (text.length() > 1) { bool addSpace = !d->word.isEmpty(); update(); - if (addSpace) - inputContext()->commit(" "); - inputContext()->commit(text); + if (addSpace && d->isAutoSpaceAllowed()) + ic->commit(" "); + ic->commit(text); accept = true; } else { update(); diff --git a/src/virtualkeyboard/pinyindecoderservice.cpp b/src/virtualkeyboard/pinyindecoderservice.cpp index a765e40f..7a7b5eed 100644 --- a/src/virtualkeyboard/pinyindecoderservice.cpp +++ b/src/virtualkeyboard/pinyindecoderservice.cpp @@ -74,6 +74,24 @@ bool PinyinDecoderService::init() return initDone; } +void PinyinDecoderService::setUserDictionary(bool enabled) +{ + if (enabled == im_is_user_dictionary_enabled()) + return; + if (enabled) { + QString usrDictPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation); + QFileInfo usrDictInfo(usrDictPath + "/qtvirtualkeyboard/pinyin/usr_dict.dat"); + im_init_user_dictionary(usrDictInfo.absoluteFilePath().toUtf8().constData()); + } else { + im_init_user_dictionary(NULL); + } +} + +bool PinyinDecoderService::isUserDictionaryEnabled() const +{ + return im_is_user_dictionary_enabled(); +} + void PinyinDecoderService::setLimits(int maxSpsLen, int maxHzsLen) { if (maxSpsLen <= 0) diff --git a/src/virtualkeyboard/pinyindecoderservice.h b/src/virtualkeyboard/pinyindecoderservice.h index a926a2ac..61c36440 100644 --- a/src/virtualkeyboard/pinyindecoderservice.h +++ b/src/virtualkeyboard/pinyindecoderservice.h @@ -33,6 +33,8 @@ public: static PinyinDecoderService *getInstance(); bool init(); + void setUserDictionary(bool enabled); + bool isUserDictionaryEnabled() const; void setLimits(int maxSpelling, int maxHzsLen); int search(const QString &spelling); int deleteSearch(int pos, bool isPosInSpellingId, bool clearFixedInThisStep); diff --git a/src/virtualkeyboard/pinyininputmethod.cpp b/src/virtualkeyboard/pinyininputmethod.cpp index b188987c..a8a99c0c 100644 --- a/src/virtualkeyboard/pinyininputmethod.cpp +++ b/src/virtualkeyboard/pinyininputmethod.cpp @@ -53,6 +53,16 @@ public: void resetToIdleState() { Q_Q(PinyinInputMethod); + + DeclarativeInputContext *inputContext = q->inputContext(); + + // Disable the user dictionary when entering sensitive data + if (inputContext) { + bool userDictionaryEnabled = !inputContext->inputMethodHints().testFlag(Qt::ImhSensitiveData); + if (userDictionaryEnabled != pinyinDecoderService->isUserDictionaryEnabled()) + pinyinDecoderService->setUserDictionary(userDictionaryEnabled); + } + if (state == Idle) return; @@ -61,7 +71,6 @@ public: fixedLen = 0; finishSelection = true; composingStr.clear(); - DeclarativeInputContext *inputContext = q->inputContext(); if (inputContext) inputContext->setPreeditText(""); activeCmpsLen = 0; |