t9writeworker.cpp 11.32 KiB
/****************************************************************************
**
** 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 "t9writeworker.h"
#include "virtualkeyboarddebug.h"
#include <QFile>
#include <QTime>
namespace QtVirtualKeyboard {
/*!
    \class QtVirtualKeyboard::T9WriteTask
    \internal
T9WriteTask::T9WriteTask(QObject *parent) :
    QObject(parent),
    decumaSession(0),
    runSema()
void T9WriteTask::wait()
    runSema.acquire();
    runSema.release();
/*!
    \class QtVirtualKeyboard::T9WriteDictionaryTask
    \internal
T9WriteDictionaryTask::T9WriteDictionaryTask(QSharedPointer<T9WriteDictionary> dictionary,
                                             const QString &dictionaryFileName,
                                             bool convertDictionary,
                                             const DECUMA_SRC_DICTIONARY_INFO &dictionaryInfo) :
    dictionary(dictionary),
    dictionaryFileName(dictionaryFileName),
    convertDictionary(convertDictionary),
    dictionaryInfo(dictionaryInfo)
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
void T9WriteDictionaryTask::run() { VIRTUALKEYBOARD_DEBUG() << "T9WriteDictionaryTask::run()"; #ifdef QT_VIRTUALKEYBOARD_DEBUG QTime perf; perf.start(); #endif bool result = false; if (dictionary) { result = dictionary->load(dictionaryFileName); if (result && convertDictionary) result = dictionary->convert(dictionaryInfo); } #ifdef QT_VIRTUALKEYBOARD_DEBUG VIRTUALKEYBOARD_DEBUG() << "T9WriteDictionaryTask::run(): time:" << perf.elapsed() << "ms"; #endif if (result) emit completed(dictionary); } /*! \class QtVirtualKeyboard::T9WriteRecognitionResult \internal */ T9WriteRecognitionResult::T9WriteRecognitionResult(int id, int maxResults, int maxCharsPerWord) : status(decumaNoError), numResults(0), instantGesture(0), id(id), maxResults(maxResults), maxCharsPerWord(maxCharsPerWord) { Q_ASSERT(maxResults > 0); Q_ASSERT(maxCharsPerWord > 0); results.resize(maxResults); int bufferLength = (maxCharsPerWord + 1); _chars.resize(maxResults * bufferLength); _symbolChars.resize(maxResults * bufferLength); _symbolStrokes.resize(maxResults * bufferLength); for (int i = 0; i < maxResults; i++) { DECUMA_HWR_RESULT &hwrResult = results[i]; hwrResult.pChars = &_chars[i * bufferLength]; hwrResult.pSymbolChars = &_symbolChars[i * bufferLength]; hwrResult.pSymbolStrokes = &_symbolStrokes[i * bufferLength]; } } /*! \class QtVirtualKeyboard::T9WriteRecognitionTask \internal */ T9WriteRecognitionTask::T9WriteRecognitionTask(QSharedPointer<T9WriteRecognitionResult> result, const DECUMA_INSTANT_GESTURE_SETTINGS &instantGestureSettings, BOOST_LEVEL boostLevel, const QString &stringStart) : T9WriteTask(), result(result), instantGestureSettings(instantGestureSettings), boostLevel(boostLevel), stringStart(stringStart), stateCancelled(false) { VIRTUALKEYBOARD_DEBUG() << "T9WriteRecognitionTask():" << "boostLevel:" << boostLevel << "stringStart:" << stringStart;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} void T9WriteRecognitionTask::run() { VIRTUALKEYBOARD_DEBUG() << "T9WriteRecognitionTask::run()"; if (!decumaSession) return; { QMutexLocker stateGuard(&stateLock); Q_UNUSED(stateGuard); if (stateCancelled) return; } //In a normal text composition case boostDictWords and canBeContinued are the preffered settings DECUMA_RECOGNITION_SETTINGS recSettings; memset(&recSettings, 0, sizeof(recSettings)); recSettings.boostLevel = boostLevel; recSettings.stringCompleteness = canBeContinued; if (!stringStart.isEmpty()) recSettings.pStringStart = (DECUMA_UNICODE *)stringStart.utf16(); #ifdef QT_VIRTUALKEYBOARD_DEBUG QTime perf; perf.start(); #endif DECUMA_STATUS status; if (!cjk) { status = DECUMA_API(IndicateInstantGesture)(decumaSession, &result->instantGesture, &instantGestureSettings); Q_ASSERT(status == decumaNoError); } DECUMA_INTERRUPT_FUNCTIONS interruptFunctions; interruptFunctions.pShouldAbortRecognize = shouldAbortRecognize; interruptFunctions.pUserData = (void *)this; result->status = DECUMA_API(Recognize)(decumaSession, result->results.data(), result->results.size(), &result->numResults, result->maxCharsPerWord, &recSettings, &interruptFunctions); if (result->status == decumaAbortRecognitionUnsupported) result->status = DECUMA_API(Recognize)(decumaSession, result->results.data(), result->results.size(), &result->numResults, result->maxCharsPerWord, &recSettings, NULL); QStringList resultList; QString gesture; for (int i = 0; i < result->numResults; i++) { QString resultString; resultString.reserve(result->results[i].nChars); int charPos = 0; for (int symbolIndex = 0; symbolIndex < result->results[i].nSymbols; symbolIndex++) { int symbolLength = result->results[i].pSymbolChars[symbolIndex]; QString symbol(QString::fromUtf16(&result->results[i].pChars[charPos], symbolLength)); // Do not append gesture symbol to result string if (result->results[i].bGesture && symbolIndex == (result->results[i].nSymbols - 1)) { if (i == 0 && (result->instantGesture || (symbol != QLatin1String(" ") && symbol != QLatin1String("\b")))) gesture = symbol; } else { resultString.append(symbol); } charPos += symbolLength; } resultList.append(resultString); } #ifdef QT_VIRTUALKEYBOARD_DEBUG int perfElapsed = perf.elapsed(); #endif { QMutexLocker stateGuard(&stateLock);
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
Q_UNUSED(stateGuard) if (stateCancelled) result.reset(); #ifdef QT_VIRTUALKEYBOARD_DEBUG VIRTUALKEYBOARD_DEBUG() << "T9WriteRecognitionTask::run(): time:" << perfElapsed << "ms" << (stateCancelled ? "(cancelled)" : ""); #endif } } int T9WriteRecognitionTask::shouldAbortRecognize(void *pUserData) { T9WriteRecognitionTask *pThis = (T9WriteRecognitionTask *)pUserData; QMutexLocker stateGuard(&pThis->stateLock); Q_UNUSED(stateGuard) return pThis->stateCancelled; } bool T9WriteRecognitionTask::cancelRecognition() { QMutexLocker stateGuard(&stateLock); Q_UNUSED(stateGuard) stateCancelled = true; return true; } int T9WriteRecognitionTask::resultId() const { return result != 0 ? result->id : -1; } /*! \class QtVirtualKeyboard::T9WriteRecognitionResultsTask \internal */ T9WriteRecognitionResultsTask::T9WriteRecognitionResultsTask(QSharedPointer<T9WriteRecognitionResult> result) : T9WriteTask(), result(result) { } void T9WriteRecognitionResultsTask::run() { if (!result) return; if (result->status != decumaNoError) { emit recognitionError(result->status); return; } QVariantList resultList; for (int i = 0; i < result->numResults; i++) { QVariantMap resultMap; QString resultString; QString gesture; const DECUMA_HWR_RESULT &hwrResult = result->results.at(i); resultString.reserve(hwrResult.nChars); QVariantList symbolStrokes; int charPos = 0; for (int symbolIndex = 0; symbolIndex < hwrResult.nSymbols; symbolIndex++) { int symbolLength = hwrResult.pSymbolChars[symbolIndex]; QString symbol(QString::fromUtf16(&hwrResult.pChars[charPos], symbolLength)); // Do not append gesture symbol to result string if (hwrResult.bGesture && symbolIndex == (hwrResult.nSymbols - 1)) { if (result->instantGesture || (symbol != QLatin1String(" ") && symbol != QLatin1String("\b"))) gesture = symbol; } else { resultString.append(symbol);
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
} charPos += symbolLength; if (hwrResult.pSymbolStrokes) symbolStrokes.append(QVariant((int)hwrResult.pSymbolStrokes[symbolIndex])); } resultMap["resultId"] = result->id; resultMap["chars"] = resultString; resultMap["symbolStrokes"] = symbolStrokes; if (!gesture.isEmpty()) resultMap["gesture"] = gesture; resultList.append(resultMap); } if (resultList.isEmpty()) return; emit resultsAvailable(resultList); } /*! \class QtVirtualKeyboard::T9WriteWorker \internal */ T9WriteWorker::T9WriteWorker(DECUMA_SESSION *decumaSession, const bool cjk, QObject *parent) : QThread(parent), taskSema(), taskLock(), decumaSession(decumaSession), cjk(cjk) { abort = false; } T9WriteWorker::~T9WriteWorker() { abort = true; taskSema.release(); wait(); } void T9WriteWorker::addTask(QSharedPointer<T9WriteTask> task) { if (task) { QMutexLocker guard(&taskLock); task->moveToThread(this); taskList.append(task); taskSema.release(); } } int T9WriteWorker::removeTask(QSharedPointer<T9WriteTask> task) { int count = 0; if (task) { QMutexLocker guard(&taskLock); count = taskList.removeAll(task); taskSema.acquire(qMin(count, taskSema.available())); } return count; } int T9WriteWorker::removeAllTasks() { QMutexLocker guard(&taskLock); int count = taskList.count(); taskList.clear(); if (taskSema.available())
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
taskSema.acquire(taskSema.available()); return count; } void T9WriteWorker::run() { while (!abort) { taskSema.acquire(); if (abort) break; QSharedPointer<T9WriteTask> currentTask; { QMutexLocker guard(&taskLock); if (!taskList.isEmpty()) { currentTask = taskList.front(); taskList.pop_front(); } } if (currentTask) { currentTask->decumaSession = decumaSession; currentTask->cjk = cjk; currentTask->run(); currentTask->runSema.release(); } } } } // namespace QtVirtualKeyboard