xref: /OK3568_Linux_fs/app/forlinx/flapp/src/keyboard/keyboard/pinyindecoderservice.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 or (at your option) any later version
20 ** approved by the KDE Free Qt Foundation. The licenses are as published by
21 ** the Free Software Foundation and appearing in the file LICENSE.GPL3
22 ** included in the packaging of this file. Please review the following
23 ** information to ensure the GNU General Public License requirements will
24 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25 **
26 ** $QT_END_LICENSE$
27 **
28 ****************************************************************************/
29 
30 #include <pinyindecoderservice.h>
31 #include <pinyinime.h>
32 #include <dictdef.h>
33 #include <QStandardPaths>
34 #include <QFileInfo>
35 #include <QDir>
36 #include <QtCore/QLibraryInfo>
37 #include <QtCore/QCoreApplication>
38 #include <QDebug>
39 
40 namespace QtVirtualKeyboard {
41 
42 using namespace ime_pinyin;
43 
44 QScopedPointer<PinyinDecoderService> PinyinDecoderService::_instance;
45 
46 /*!
47     \class QtVirtualKeyboard::PinyinDecoderService
48     \internal
49 */
50 
PinyinDecoderService(QObject * parent)51 PinyinDecoderService::PinyinDecoderService(QObject *parent) :
52     QObject(parent),
53     initDone(false)
54 {
55 }
56 
~PinyinDecoderService()57 PinyinDecoderService::~PinyinDecoderService()
58 {
59     if (initDone) {
60         im_close_decoder();
61         initDone = false;
62     }
63 }
64 
getInstance()65 PinyinDecoderService *PinyinDecoderService::getInstance()
66 {
67     if (!_instance)
68         _instance.reset(new PinyinDecoderService());
69     if (!_instance->init())
70         return 0;
71     return _instance.data();
72 }
73 
init()74 bool PinyinDecoderService::init()
75 {
76     if (initDone)
77         return true;
78 
79     //QString strDir = QCoreApplication::applicationDirPath();
80 //    QString sysDict = "/usr/local/pinyin/dict_pinyin.dat";
81 //    QString usrDictPath = "/usr/local/pinyin/usr_dict.dat";
82        QString sysDict = qApp->applicationDirPath() +"/pinyin/dict_pinyin.dat";
83        QString usrDictPath = qApp->applicationDirPath() +"/pinyin/usr_dict.dat";
84 
85     if (QFileInfo::exists(sysDict) == false)
86     {
87         qDebug() << qApp->applicationDirPath() +"/pinyin/dict_pinyin.dat not found" << sysDict;
88         return false;
89     }
90 
91     QFileInfo usrDictInfo(usrDictPath);
92     if (!usrDictInfo.exists()) {
93         qDebug() << "PinyinDecoderService::init(): creating directory for user dictionary" << usrDictInfo.absolutePath();
94         QDir().mkpath(usrDictInfo.absolutePath());
95     }
96 
97     initDone = im_open_decoder(sysDict.toUtf8().constData(), usrDictInfo.absoluteFilePath().toUtf8().constData());
98     if (!initDone)
99         qDebug() << "Could not initialize pinyin engine. sys_dict:" << sysDict << "usr_dict:" << usrDictInfo.absoluteFilePath();
100 
101     return initDone;
102 }
103 
setUserDictionary(bool enabled)104 void PinyinDecoderService::setUserDictionary(bool enabled)
105 {
106     if (enabled == im_is_user_dictionary_enabled())
107         return;
108     if (enabled) {
109         //QString usrDictPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
110         QFileInfo usrDictInfo(qApp->applicationDirPath() +"/pinyin/usr_dict.dat");
111         im_init_user_dictionary(usrDictInfo.absoluteFilePath().toUtf8().constData());
112     } else {
113         im_init_user_dictionary(NULL);
114     }
115 }
116 
isUserDictionaryEnabled() const117 bool PinyinDecoderService::isUserDictionaryEnabled() const
118 {
119     return im_is_user_dictionary_enabled();
120 }
121 
setLimits(int maxSpsLen,int maxHzsLen)122 void PinyinDecoderService::setLimits(int maxSpsLen, int maxHzsLen)
123 {
124     if (maxSpsLen <= 0)
125         maxSpsLen = kMaxSearchSteps - 1;
126     if (maxHzsLen <= 0)
127         maxHzsLen = kMaxSearchSteps;
128     im_set_max_lens(size_t(maxSpsLen), size_t(maxHzsLen));
129 }
130 
search(const QString & spelling)131 int PinyinDecoderService::search(const QString &spelling)
132 {
133     QByteArray spellingBuf = spelling.toLatin1();
134     return int(im_search(spellingBuf.constData(), spellingBuf.length()));
135 }
136 
deleteSearch(int pos,bool isPosInSpellingId,bool clearFixedInThisStep)137 int PinyinDecoderService::deleteSearch(int pos, bool isPosInSpellingId, bool clearFixedInThisStep)
138 {
139     if (pos <= 0)
140         pos = 0;
141     return int(im_delsearch(size_t(pos), isPosInSpellingId, clearFixedInThisStep));
142 }
143 
resetSearch()144 void PinyinDecoderService::resetSearch()
145 {
146     im_reset_search();
147 }
148 
pinyinString(bool decoded)149 QString PinyinDecoderService::pinyinString(bool decoded)
150 {
151     size_t py_len;
152     const char *py = im_get_sps_str(&py_len);
153     if (!decoded)
154         py_len = strlen(py);
155 
156     return QString(QLatin1String(py, (int)py_len));
157 }
158 
pinyinStringLength(bool decoded)159 int PinyinDecoderService::pinyinStringLength(bool decoded)
160 {
161     size_t py_len;
162     const char *py = im_get_sps_str(&py_len);
163     if (!decoded)
164         py_len = strlen(py);
165     return (int)py_len;
166 }
167 
spellingStartPositions()168 QVector<int> PinyinDecoderService::spellingStartPositions()
169 {
170     const unsigned short *spl_start;
171     int len;
172     // There will be len + 1 elements in the buffer when len > 0.
173     len = (int)im_get_spl_start_pos(spl_start);
174 
175     QVector<int> arr;
176     arr.resize(len + 2);
177     arr[0] = len; // element 0 is used to store the length of buffer.
178     for (int i = 0; i <= len; i++)
179         arr[i + 1] = spl_start[i];
180     return arr;
181 }
182 
candidateAt(int index)183 QString PinyinDecoderService::candidateAt(int index)
184 {
185     Q_ASSERT(index >= 0);
186     QVector<QChar> candidateBuf;
187     candidateBuf.resize(kMaxSearchSteps + 1);
188     if (!im_get_candidate(size_t(index), (char16 *)candidateBuf.data(), candidateBuf.length() - 1))
189         return QString();
190     candidateBuf.last() = 0;
191     return QString(candidateBuf.data());
192 }
193 
fetchCandidates(int index,int count,int sentFixedLen)194 QList<QString> PinyinDecoderService::fetchCandidates(int index, int count, int sentFixedLen)
195 {
196     QList<QString> candidatesList;
197     for (int i = index; i < index + count; i++) {
198         QString retStr = candidateAt(i);
199         if (0 == i)
200             retStr.remove(0, sentFixedLen);
201         candidatesList.append(retStr);
202     }
203     return candidatesList;
204 }
205 
chooceCandidate(int index)206 int PinyinDecoderService::chooceCandidate(int index)
207 {
208     return int(im_choose(index));
209 }
210 
cancelLastChoice()211 int PinyinDecoderService::cancelLastChoice()
212 {
213     return int(im_cancel_last_choice());
214 }
215 
fixedLength()216 int PinyinDecoderService::fixedLength()
217 {
218     return (int)im_get_fixed_len();
219 }
220 
flushCache()221 void PinyinDecoderService::flushCache()
222 {
223     im_flush_cache();
224 }
225 
predictionList(const QString & history)226 QList<QString> PinyinDecoderService::predictionList(const QString &history)
227 {
228     QList<QString> predictList;
229     char16 (*predictItems)[kMaxPredictSize + 1] = 0;
230     int predictNum = int(im_get_predicts(history.utf16(), predictItems));
231     predictList.reserve(predictNum);
232     for (int i = 0; i < predictNum; i++)
233         predictList.append(QString((QChar *)predictItems[i]));
234     return predictList;
235 }
236 
237 } // namespace QtVirtualKeyboard
238