diff options
Diffstat (limited to 'src/plugins/hunspell/hunspellinputmethod/hunspellinputmethod_p.cpp')
-rw-r--r-- | src/plugins/hunspell/hunspellinputmethod/hunspellinputmethod_p.cpp | 337 |
1 files changed, 0 insertions, 337 deletions
diff --git a/src/plugins/hunspell/hunspellinputmethod/hunspellinputmethod_p.cpp b/src/plugins/hunspell/hunspellinputmethod/hunspellinputmethod_p.cpp deleted file mode 100644 index 5835fa3e..00000000 --- a/src/plugins/hunspell/hunspellinputmethod/hunspellinputmethod_p.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtHunspellInputMethod/private/hunspellinputmethod_p_p.h> -#include <QtVirtualKeyboard/qvirtualkeyboardinputcontext.h> -#include <hunspell/hunspell.h> -#include <QStringList> -#include <QDir> -#include <QtCore/QLibraryInfo> -#include <QStandardPaths> - -QT_BEGIN_NAMESPACE -namespace QtVirtualKeyboard { - -const int HunspellInputMethodPrivate::userDictionaryMaxSize = 100; - -/*! - \class QtVirtualKeyboard::HunspellInputMethodPrivate - \internal -*/ - -HunspellInputMethodPrivate::HunspellInputMethodPrivate(HunspellInputMethod *q_ptr) : - q_ptr(q_ptr), - hunspellWorker(new HunspellWorker()), - locale(), - wordCompletionPoint(2), - ignoreUpdate(false), - autoSpaceAllowed(false), - dictionaryState(DictionaryNotLoaded), - userDictionaryWords(new HunspellWordList(userDictionaryMaxSize)), - blacklistedWords(new HunspellWordList(userDictionaryMaxSize)), - wordCandidatesUpdateTag(0) -{ - if (hunspellWorker) - hunspellWorker->start(); -} - -HunspellInputMethodPrivate::~HunspellInputMethodPrivate() -{ -} - -bool HunspellInputMethodPrivate::createHunspell(const QString &locale) -{ - Q_Q(HunspellInputMethod); - if (!hunspellWorker) - return false; - if (this->locale != locale) { - clearSuggestionsRelatedTasks(); - hunspellWorker->waitForAllTasks(); - QString hunspellDataPath(qEnvironmentVariable("QT_VIRTUALKEYBOARD_HUNSPELL_DATA_PATH")); - const QString pathListSep( -#if defined(Q_OS_WIN32) - QStringLiteral(";") -#else - QStringLiteral(":") -#endif - ); - QStringList searchPaths(hunspellDataPath.split(pathListSep, Qt::SkipEmptyParts)); - const QStringList defaultPaths = QStringList() - << QDir(QLibraryInfo::location(QLibraryInfo::DataPath) + QStringLiteral("/qtvirtualkeyboard/hunspell")).absolutePath() -#if !defined(Q_OS_WIN32) - << QStringLiteral("/usr/share/hunspell") - << QStringLiteral("/usr/share/myspell/dicts") -#endif - ; - for (const QString &defaultPath : defaultPaths) { - if (!searchPaths.contains(defaultPath)) - searchPaths.append(defaultPath); - } - QSharedPointer<HunspellLoadDictionaryTask> loadDictionaryTask(new HunspellLoadDictionaryTask(locale, searchPaths)); - QObject::connect(loadDictionaryTask.data(), &HunspellLoadDictionaryTask::completed, q, &HunspellInputMethod::dictionaryLoadCompleted); - dictionaryState = HunspellInputMethodPrivate::DictionaryLoading; - emit q->selectionListsChanged(); - hunspellWorker->addTask(loadDictionaryTask); - this->locale = locale; - - loadCustomDictionary(userDictionaryWords, QLatin1String("userdictionary")); - addToHunspell(userDictionaryWords); - loadCustomDictionary(blacklistedWords, QLatin1String("blacklist")); - removeFromHunspell(blacklistedWords); - } - return true; -} - -void HunspellInputMethodPrivate::reset() -{ - if (clearSuggestions(true)) { - Q_Q(HunspellInputMethod); - emit q->selectionListChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList); - emit q->selectionListActiveItemChanged(QVirtualKeyboardSelectionListModel::Type::WordCandidateList, wordCandidates.index()); - } - autoSpaceAllowed = false; -} - -bool HunspellInputMethodPrivate::updateSuggestions() -{ - bool wordCandidateListChanged = false; - QString word = wordCandidates.wordAt(0); - if (!word.isEmpty() && dictionaryState != HunspellInputMethodPrivate::DictionaryNotLoaded) { - wordCandidateListChanged = true; - if (word.length() >= wordCompletionPoint) { - if (hunspellWorker) { - QSharedPointer<HunspellWordList> wordList(new HunspellWordList(wordCandidates)); - - // Clear obsolete tasks from the worker queue - clearSuggestionsRelatedTasks(); - - // Build suggestions - QSharedPointer<HunspellBuildSuggestionsTask> buildSuggestionsTask(new HunspellBuildSuggestionsTask()); - buildSuggestionsTask->wordList = wordList; - buildSuggestionsTask->autoCorrect = false; - hunspellWorker->addTask(buildSuggestionsTask); - - // Filter out blacklisted word (sometimes Hunspell suggests, - // e.g. with different text case) - QSharedPointer<HunspellFilterWordTask> filterWordTask(new HunspellFilterWordTask()); - filterWordTask->wordList = wordList; - filterWordTask->filterList = blacklistedWords; - hunspellWorker->addTask(filterWordTask); - - // Boost words from user dictionary - QSharedPointer<HunspellBoostWordTask> boostWordTask(new HunspellBoostWordTask()); - boostWordTask->wordList = wordList; - boostWordTask->boostList = userDictionaryWords; - hunspellWorker->addTask(boostWordTask); - - // Update word candidate list - QSharedPointer<HunspellUpdateSuggestionsTask> updateSuggestionsTask(new HunspellUpdateSuggestionsTask()); - updateSuggestionsTask->wordList = wordList; - updateSuggestionsTask->tag = ++wordCandidatesUpdateTag; - Q_Q(HunspellInputMethod); - QObject::connect(updateSuggestionsTask.data(), &HunspellUpdateSuggestionsTask::updateSuggestions, q, &HunspellInputMethod::updateSuggestions); - hunspellWorker->addTask(updateSuggestionsTask); - } - } - } else { - wordCandidateListChanged = clearSuggestions(); - } - return wordCandidateListChanged; -} - -bool HunspellInputMethodPrivate::clearSuggestions(bool clearInputWord) -{ - clearSuggestionsRelatedTasks(); - return clearInputWord ? wordCandidates.clear() : wordCandidates.clearSuggestions(); -} - -void HunspellInputMethodPrivate::clearSuggestionsRelatedTasks() -{ - if (hunspellWorker) { - hunspellWorker->removeAllTasksOfType<HunspellBuildSuggestionsTask>(); - hunspellWorker->removeAllTasksOfType<HunspellFilterWordTask>(); - hunspellWorker->removeAllTasksOfType<HunspellBoostWordTask>(); - hunspellWorker->removeAllTasksOfType<HunspellUpdateSuggestionsTask>(); - } -} - -bool HunspellInputMethodPrivate::isAutoSpaceAllowed() const -{ - Q_Q(const HunspellInputMethod); - if (!autoSpaceAllowed) - return false; - if (q->inputEngine()->inputMode() == QVirtualKeyboardInputEngine::InputMode::Numeric) - return false; - QVirtualKeyboardInputContext *ic = q->inputContext(); - if (!ic) - return false; - Qt::InputMethodHints inputMethodHints = ic->inputMethodHints(); - return !inputMethodHints.testFlag(Qt::ImhUrlCharactersOnly) && - !inputMethodHints.testFlag(Qt::ImhEmailCharactersOnly); -} - -bool HunspellInputMethodPrivate::isValidInputChar(const QChar &c) const -{ - if (c.isLetterOrNumber()) - return true; - if (isJoiner(c)) - return true; - if (c.isMark()) - return true; - return false; -} - -bool HunspellInputMethodPrivate::isJoiner(const QChar &c) const -{ - if (c.isPunct() || c.isSymbol()) { - Q_Q(const HunspellInputMethod); - QVirtualKeyboardInputContext *ic = q->inputContext(); - if (ic) { - Qt::InputMethodHints inputMethodHints = ic->inputMethodHints(); - if (inputMethodHints.testFlag(Qt::ImhUrlCharactersOnly) || inputMethodHints.testFlag(Qt::ImhEmailCharactersOnly)) - return QString(QStringLiteral(":/?#[]@!$&'()*+,;=-_.%")).contains(c); - } - ushort unicode = c.unicode(); - if (unicode == Qt::Key_Apostrophe || unicode == Qt::Key_Minus) - return true; - } - return false; -} - -QString HunspellInputMethodPrivate::customDictionaryLocation(const QString &dictionaryType) const -{ - if (dictionaryType.isEmpty() || locale.isEmpty()) - return QString(); - - QString location = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); - if (location.isEmpty()) - return QString(); - - return QStringLiteral("%1/qtvirtualkeyboard/hunspell/%2-%3.txt") - .arg(location) - .arg(dictionaryType) - .arg(locale); -} - -void HunspellInputMethodPrivate::loadCustomDictionary(const QSharedPointer<HunspellWordList> &wordList, - const QString &dictionaryType) const -{ - QSharedPointer<HunspellLoadWordListTask> loadWordsTask(new HunspellLoadWordListTask()); - loadWordsTask->filePath = customDictionaryLocation(dictionaryType); - loadWordsTask->wordList = wordList; - hunspellWorker->addTask(loadWordsTask); -} - -void HunspellInputMethodPrivate::saveCustomDictionary(const QSharedPointer<HunspellWordList> &wordList, - const QString &dictionaryType) const -{ - QSharedPointer<HunspellSaveWordListTask> saveWordsTask(new HunspellSaveWordListTask()); - saveWordsTask->filePath = customDictionaryLocation(dictionaryType); - saveWordsTask->wordList = wordList; - hunspellWorker->addTask(saveWordsTask); -} - -void HunspellInputMethodPrivate::addToHunspell(const QSharedPointer<HunspellWordList> &wordList) const -{ - QSharedPointer<HunspellAddWordTask> addWordTask(new HunspellAddWordTask()); - addWordTask->wordList = wordList; - hunspellWorker->addTask(addWordTask); -} - -void HunspellInputMethodPrivate::removeFromHunspell(const QSharedPointer<HunspellWordList> &wordList) const -{ - QSharedPointer<HunspellRemoveWordTask> removeWordTask(new HunspellRemoveWordTask()); - removeWordTask->wordList = wordList; - hunspellWorker->addTask(removeWordTask); -} - -void HunspellInputMethodPrivate::removeFromDictionary(const QString &word) -{ - if (userDictionaryWords->removeWord(word) > 0) { - saveCustomDictionary(userDictionaryWords, QLatin1String("userdictionary")); - } else if (!blacklistedWords->contains(word)) { - blacklistedWords->appendWord(word); - saveCustomDictionary(blacklistedWords, QLatin1String("blacklist")); - } - - QSharedPointer<HunspellWordList> wordList(new HunspellWordList()); - wordList->appendWord(word); - removeFromHunspell(wordList); - - updateSuggestions(); -} - -void HunspellInputMethodPrivate::addToDictionary() -{ - Q_Q(HunspellInputMethod); - // This feature is not allowed when dealing with sensitive information - const Qt::InputMethodHints inputMethodHints(q->inputContext()->inputMethodHints()); - const bool userDictionaryEnabled = - !inputMethodHints.testFlag(Qt::ImhHiddenText) && - !inputMethodHints.testFlag(Qt::ImhSensitiveData); - if (!userDictionaryEnabled) - return; - - if (wordCandidates.isEmpty()) - return; - - QString word; - HunspellWordList::Flags wordFlags; - const int activeWordIndex = wordCandidates.index(); - wordCandidates.wordAt(activeWordIndex, word, wordFlags); - if (activeWordIndex == 0) { - if (blacklistedWords->removeWord(word) > 0) { - saveCustomDictionary(blacklistedWords, QLatin1String("blacklist")); - } else if (word.length() > 1 && !wordFlags.testFlag(HunspellWordList::SpellCheckOk) && !userDictionaryWords->contains(word)) { - userDictionaryWords->appendWord(word); - saveCustomDictionary(userDictionaryWords, QLatin1String("userdictionary")); - } else { - // Avoid adding words to Hunspell which are too short or passed spell check - return; - } - - QSharedPointer<HunspellWordList> wordList(new HunspellWordList()); - wordList->appendWord(word); - addToHunspell(wordList); - } else { - // Check if found in the user dictionary and move as last in the list. - // This way the list is always ordered by use. - // If userDictionaryMaxSize is greater than zero the number of words in the - // list will be limited to that amount. By pushing last used items to end of - // list we can avoid (to certain extent) removing frequently used words. - int userDictionaryIndex = userDictionaryWords->indexOfWord(word); - if (userDictionaryIndex != -1) { - userDictionaryWords->moveWord(userDictionaryIndex, userDictionaryWords->size() - 1); - saveCustomDictionary(userDictionaryWords, QLatin1String("userdictionary")); - } - } -} - -} // namespace QtVirtualKeyboard -QT_END_NAMESPACE |