aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/pinyin/pinyindecoderservice.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/pinyin/pinyindecoderservice.cpp')
-rw-r--r--src/plugins/pinyin/pinyindecoderservice.cpp210
1 files changed, 210 insertions, 0 deletions
diff --git a/src/plugins/pinyin/pinyindecoderservice.cpp b/src/plugins/pinyin/pinyindecoderservice.cpp
new file mode 100644
index 00000000..9613dd9e
--- /dev/null
+++ b/src/plugins/pinyin/pinyindecoderservice.cpp
@@ -0,0 +1,210 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#include "pinyindecoderservice_p.h"
+#include "pinyinime.h"
+#include "dictdef.h"
+#include <QStandardPaths>
+#include <QFileInfo>
+#include <QDir>
+#include <QtCore/QLibraryInfo>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+namespace QtVirtualKeyboard {
+
+Q_DECLARE_LOGGING_CATEGORY(lcPinyin)
+
+using namespace ime_pinyin;
+
+QScopedPointer<PinyinDecoderService> PinyinDecoderService::_instance;
+
+/*!
+ \class QtVirtualKeyboard::PinyinDecoderService
+ \internal
+*/
+
+PinyinDecoderService::PinyinDecoderService(QObject *parent) :
+ QObject(parent),
+ initDone(false)
+{
+}
+
+PinyinDecoderService::~PinyinDecoderService()
+{
+ if (initDone) {
+ im_close_decoder();
+ initDone = false;
+ }
+}
+
+PinyinDecoderService *PinyinDecoderService::getInstance()
+{
+ if (!_instance)
+ _instance.reset(new PinyinDecoderService());
+ if (!_instance->init())
+ return nullptr;
+ return _instance.data();
+}
+
+bool PinyinDecoderService::init()
+{
+ if (initDone)
+ return true;
+
+ QString sysDict(qEnvironmentVariable("QT_VIRTUALKEYBOARD_PINYIN_DICTIONARY"));
+ if (!QFileInfo::exists(sysDict)) {
+ sysDict = QLibraryInfo::path(QLibraryInfo::DataPath) + QLatin1String("/qtvirtualkeyboard/pinyin/dict_pinyin.dat");
+ if (!QFileInfo::exists(sysDict))
+ sysDict = QLatin1String(":/qt-project.org/imports/QtQuick/VirtualKeyboard/3rdparty/pinyin/data/dict_pinyin.dat");
+ }
+
+ QString usrDictPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
+ QFileInfo usrDictInfo(usrDictPath + QLatin1String("/qtvirtualkeyboard/pinyin/usr_dict.dat"));
+ if (!usrDictInfo.exists()) {
+ qCWarning(lcPinyin) << "PinyinDecoderService::init(): creating directory for user dictionary" << usrDictInfo.absolutePath();
+ QDir().mkpath(usrDictInfo.absolutePath());
+ }
+
+ initDone = im_open_decoder(sysDict.toUtf8().constData(), usrDictInfo.absoluteFilePath().toUtf8().constData());
+ if (!initDone)
+ qCWarning(lcPinyin) << "Could not initialize pinyin engine. sys_dict:" << sysDict << "usr_dict:" << usrDictInfo.absoluteFilePath();
+
+ 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 + QLatin1String("/qtvirtualkeyboard/pinyin/usr_dict.dat"));
+ im_init_user_dictionary(usrDictInfo.absoluteFilePath().toUtf8().constData());
+ } else {
+ im_init_user_dictionary(nullptr);
+ }
+}
+
+bool PinyinDecoderService::isUserDictionaryEnabled() const
+{
+ return im_is_user_dictionary_enabled();
+}
+
+void PinyinDecoderService::setLimits(int maxSpsLen, int maxHzsLen)
+{
+ if (maxSpsLen <= 0)
+ maxSpsLen = kMaxSearchSteps - 1;
+ if (maxHzsLen <= 0)
+ maxHzsLen = kMaxSearchSteps;
+ im_set_max_lens(size_t(maxSpsLen), size_t(maxHzsLen));
+}
+
+int PinyinDecoderService::search(const QString &spelling)
+{
+ QByteArray spellingBuf = spelling.toLatin1();
+ return int(im_search(spellingBuf.constData(), spellingBuf.size()));
+}
+
+int PinyinDecoderService::deleteSearch(int pos, bool isPosInSpellingId, bool clearFixedInThisStep)
+{
+ if (pos <= 0)
+ pos = 0;
+ return int(im_delsearch(size_t(pos), isPosInSpellingId, clearFixedInThisStep));
+}
+
+void PinyinDecoderService::resetSearch()
+{
+ im_reset_search();
+}
+
+QString PinyinDecoderService::pinyinString(bool decoded)
+{
+ size_t py_len;
+ const char *py = im_get_sps_str(&py_len);
+ if (!decoded)
+ py_len = strlen(py);
+
+ return QString(QLatin1String(py, (int)py_len));
+}
+
+int PinyinDecoderService::pinyinStringLength(bool decoded)
+{
+ size_t py_len;
+ const char *py = im_get_sps_str(&py_len);
+ if (!decoded)
+ py_len = strlen(py);
+ return (int)py_len;
+}
+
+QList<int> PinyinDecoderService::spellingStartPositions()
+{
+ const unsigned short *spl_start;
+ int len;
+ // There will be len + 1 elements in the buffer when len > 0.
+ len = (int)im_get_spl_start_pos(spl_start);
+
+ QList<int> arr;
+ arr.resize(len + 2);
+ arr[0] = len; // element 0 is used to store the length of buffer.
+ for (int i = 0; i <= len; i++)
+ arr[i + 1] = spl_start[i];
+ return arr;
+}
+
+QString PinyinDecoderService::candidateAt(int index)
+{
+ Q_ASSERT(index >= 0);
+ QList<QChar> candidateBuf;
+ candidateBuf.resize(kMaxSearchSteps + 1);
+ if (!im_get_candidate(size_t(index), (char16 *)candidateBuf.data(), candidateBuf.size() - 1))
+ return QString();
+ candidateBuf.last() = u'\0';
+ return QString(candidateBuf.data());
+}
+
+QList<QString> PinyinDecoderService::fetchCandidates(int index, int count, int sentFixedLen)
+{
+ QList<QString> candidatesList;
+ for (int i = index; i < index + count; i++) {
+ QString retStr = candidateAt(i);
+ if (0 == i)
+ retStr.remove(0, sentFixedLen);
+ candidatesList.append(retStr);
+ }
+ return candidatesList;
+}
+
+int PinyinDecoderService::chooceCandidate(int index)
+{
+ return int(im_choose(index));
+}
+
+int PinyinDecoderService::cancelLastChoice()
+{
+ return int(im_cancel_last_choice());
+}
+
+int PinyinDecoderService::fixedLength()
+{
+ return (int)im_get_fixed_len();
+}
+
+void PinyinDecoderService::flushCache()
+{
+ im_flush_cache();
+}
+
+QList<QString> PinyinDecoderService::predictionList(const QString &history)
+{
+ QList<QString> predictList;
+ char16 (*predictItems)[kMaxPredictSize + 1] = nullptr;
+ int predictNum = int(im_get_predicts(history.utf16(), predictItems));
+ predictList.reserve(predictNum);
+ for (int i = 0; i < predictNum; i++)
+ predictList.append(QString((QChar *)predictItems[i]));
+ return predictList;
+}
+
+} // namespace QtVirtualKeyboard
+QT_END_NAMESPACE