diff options
author | Jarkko Koivikko <jarkko.koivikko@code-q.fi> | 2015-03-25 10:08:02 +0200 |
---|---|---|
committer | Jarkko Koivikko <jarkko.koivikko@code-q.fi> | 2015-06-17 12:35:27 +0300 |
commit | 1d5eae310178006383a298156bdb134beffca36b (patch) | |
tree | c49abdb16c05cf01c22335b5a3cf69ba4037f0fc /src/virtualkeyboard/hunspellinputmethod_p.cpp | |
parent | a6333e2fedb2798f62c7cee16a3634707b6b52d5 (diff) |
Move Hunspell dictionary loading to worker thread
This change moves the Hunspell dictionary loading to worker thread.
The dictionary loading is relatively heavy task for large dictionary
files, such as Arabic, which can take more than 2 seconds to load on
the Nexus 7 hardware.
The Hunspell worker thread is no longer destroyed and created every
time the dictionary changes, instead the worker thread is re-used.
The dictionary loading happens by adding a new kind of task for the
worker thread. Also, added a special function for clearing all but
dictionary loading tasks from the worker task queue. This is needed
for a special case where the dictionary is still loading while the
user starts typing.
Updated the test cases to take into account changes in delays in
loading the dictionary.
Change-Id: If9be14c7703b39af79f6e3b6708e297a28c49f2f
Reviewed-by: Gatis Paeglis <gatis.paeglis@theqtcompany.com>
Diffstat (limited to 'src/virtualkeyboard/hunspellinputmethod_p.cpp')
-rw-r--r-- | src/virtualkeyboard/hunspellinputmethod_p.cpp | 57 |
1 files changed, 18 insertions, 39 deletions
diff --git a/src/virtualkeyboard/hunspellinputmethod_p.cpp b/src/virtualkeyboard/hunspellinputmethod_p.cpp index 90fe6efb..7fd98191 100644 --- a/src/virtualkeyboard/hunspellinputmethod_p.cpp +++ b/src/virtualkeyboard/hunspellinputmethod_p.cpp @@ -20,7 +20,6 @@ #include "declarativeinputcontext.h" #include <hunspell/hunspell.h> #include <QStringList> -#include <QFileInfo> #include <QDir> #include "virtualkeyboarddebug.h" #include <QTextCodec> @@ -29,7 +28,7 @@ HunspellInputMethodPrivate::HunspellInputMethodPrivate(HunspellInputMethod *q_ptr) : AbstractInputMethodPrivate(), q_ptr(q_ptr), - hunspellWorker(0), + hunspellWorker(new HunspellWorker()), locale(), word(), wordCandidates(), @@ -38,6 +37,8 @@ HunspellInputMethodPrivate::HunspellInputMethodPrivate(HunspellInputMethod *q_pt ignoreUpdate(false), autoSpaceAllowed(false) { + if (hunspellWorker) + hunspellWorker->start(); } HunspellInputMethodPrivate::~HunspellInputMethodPrivate() @@ -46,9 +47,10 @@ HunspellInputMethodPrivate::~HunspellInputMethodPrivate() bool HunspellInputMethodPrivate::createHunspell(const QString &locale) { + if (!hunspellWorker) + return false; if (this->locale != locale) { - hunspellWorker.reset(0); - Hunhandle *hunspell = 0; + hunspellWorker->removeAllTasks(); QString hunspellDataPath(QString::fromLatin1(qgetenv("QT_VIRTUALKEYBOARD_HUNSPELL_DATA_PATH").constData())); const QString pathListSep( #if defined(Q_OS_WIN32) @@ -58,43 +60,20 @@ bool HunspellInputMethodPrivate::createHunspell(const QString &locale) #endif ); QStringList searchPaths(hunspellDataPath.split(pathListSep, QString::SkipEmptyParts)); - searchPaths.append(QDir(QLibraryInfo::location(QLibraryInfo::DataPath) + "/qtvirtualkeyboard/hunspell").absolutePath()); + const QStringList defaultPaths = QStringList() + << QDir(QLibraryInfo::location(QLibraryInfo::DataPath) + QStringLiteral("/qtvirtualkeyboard/hunspell")).absolutePath() #if !defined(Q_OS_WIN32) - searchPaths.append(QStringLiteral("/usr/share/hunspell")); - searchPaths.append(QStringLiteral("/usr/share/myspell/dicts")); + << QStringLiteral("/usr/share/hunspell") + << QStringLiteral("/usr/share/myspell/dicts") #endif - foreach (const QString &searchPath, searchPaths) { - QByteArray affpath(QString("%1/%2.aff").arg(searchPath).arg(locale).toUtf8()); - QByteArray dpath(QString("%1/%2.dic").arg(searchPath).arg(locale).toUtf8()); - if (QFileInfo(dpath).exists()) { - hunspell = Hunspell_create(affpath.constData(), dpath.constData()); - if (hunspell) { - /* Make sure the encoding used by the dictionary is supported - by the QTextCodec. - */ - if (QTextCodec::codecForName(Hunspell_get_dic_encoding(hunspell))) { - break; - } else { - qWarning() << "The Hunspell dictionary" << QString("%1/%2.dic").arg(searchPath).arg(locale) << "cannot be used because it uses an unknown text codec" << QString(Hunspell_get_dic_encoding(hunspell)); - Hunspell_destroy(hunspell); - hunspell = 0; - } - } - } - } - if (!hunspell) { - VIRTUALKEYBOARD_DEBUG() << "Missing Hunspell dictionary for locale" << locale << "in" << searchPaths; - this->locale.clear(); - return false; + ; + foreach (const QString &defaultPath, defaultPaths) { + if (!searchPaths.contains(defaultPath)) + searchPaths.append(defaultPath); } + QSharedPointer<HunspellLoadDictionaryTask> loadDictionaryTask(new HunspellLoadDictionaryTask(locale, searchPaths)); + hunspellWorker->addTask(loadDictionaryTask); this->locale = locale; - hunspellWorker.reset(new HunspellWorker(hunspell)); - if (!hunspellWorker) { - Hunspell_destroy(hunspell); - this->locale.clear(); - return false; - } - hunspellWorker->start(); } return true; } @@ -115,7 +94,7 @@ bool HunspellInputMethodPrivate::updateSuggestions() bool wordCandidateListChanged = false; if (!word.isEmpty()) { if (hunspellWorker) - hunspellWorker->removeAllTasks(); + hunspellWorker->removeAllTasksExcept<HunspellLoadDictionaryTask>(); if (wordCandidates.isEmpty()) { wordCandidates.append(word); activeWordIndex = 0; @@ -154,7 +133,7 @@ bool HunspellInputMethodPrivate::updateSuggestions() bool HunspellInputMethodPrivate::clearSuggestions() { if (hunspellWorker) - hunspellWorker->removeAllTasks(); + hunspellWorker->removeAllTasksExcept<HunspellLoadDictionaryTask>(); if (wordCandidates.isEmpty()) return false; wordCandidates.clear(); |