qskinny/inputcontext/QskPinyinTextPredictor.cpp

105 lines
2.6 KiB
C++
Raw Normal View History

2018-02-06 14:55:35 +01:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskPinyinTextPredictor.h"
2018-04-04 15:19:51 +02:00
#include "QskInputContext.h"
2017-07-21 18:21:34 +02:00
#include "pinyinime.h"
2017-07-21 18:21:34 +02:00
2018-04-04 20:19:47 +02:00
#include <QDebug>
2018-08-03 08:15:28 +02:00
#include <QStringList>
2017-07-21 18:21:34 +02:00
class QskPinyinTextPredictor::PrivateData
2017-07-21 18:21:34 +02:00
{
2018-08-03 08:15:28 +02:00
public:
2018-04-01 12:47:44 +02:00
QStringList candidates;
2017-07-21 18:21:34 +02:00
};
2018-08-03 08:15:28 +02:00
QskPinyinTextPredictor::QskPinyinTextPredictor( QObject* parent )
: Inherited( Attributes(), parent )
, m_data( new PrivateData )
2017-07-21 18:21:34 +02:00
{
#if 1
const char dictionary[] = "XXX/3rdparty/pinyin/data/dict_pinyin.dat";
#endif
// ### prevent having 2 calls to im_open_decoder by using a singleton or so
bool opened = ime_pinyin::im_open_decoder( dictionary, "" );
2018-08-03 08:15:28 +02:00
if ( !opened )
{
qWarning() << "could not open pinyin decoder dictionary at" << dictionary;
}
2017-07-21 18:21:34 +02:00
}
QskPinyinTextPredictor::~QskPinyinTextPredictor()
2017-07-21 18:21:34 +02:00
{
ime_pinyin::im_close_decoder();
2017-07-21 18:21:34 +02:00
}
int QskPinyinTextPredictor::candidateCount() const
2017-07-21 18:21:34 +02:00
{
2018-04-01 12:47:44 +02:00
return m_data->candidates.count();
}
2017-07-21 18:21:34 +02:00
QString QskPinyinTextPredictor::candidate( int index ) const
{
2018-04-01 12:47:44 +02:00
if ( ( index >= 0 ) && ( index < m_data->candidates.count() ) )
return m_data->candidates[ index ];
return QString();
2017-07-21 18:21:34 +02:00
}
void QskPinyinTextPredictor::reset()
2017-07-21 18:21:34 +02:00
{
2018-04-20 08:52:26 +02:00
ime_pinyin::im_reset_search();
2017-07-21 18:21:34 +02:00
2018-04-20 08:52:26 +02:00
if ( !m_data->candidates.isEmpty() )
2017-07-21 18:21:34 +02:00
{
2018-04-20 08:52:26 +02:00
m_data->candidates.clear();
Q_EMIT predictionChanged();
2017-07-21 18:21:34 +02:00
}
2018-04-20 08:52:26 +02:00
}
2017-07-21 18:21:34 +02:00
void QskPinyinTextPredictor::request( const QString& text )
2018-04-20 08:52:26 +02:00
{
const QByteArray bytes = text.toLatin1();
2017-07-21 18:21:34 +02:00
2018-04-20 08:52:26 +02:00
size_t count = ime_pinyin::im_search(
bytes.constData(), size_t( bytes.length() ) );
2017-07-21 18:21:34 +02:00
2018-08-03 08:15:28 +02:00
if ( count <= 0 )
2018-04-20 08:52:26 +02:00
return;
2017-07-21 18:21:34 +02:00
2018-04-20 08:52:26 +02:00
const size_t maxCount = 20;
2018-08-03 08:15:28 +02:00
if ( count > maxCount )
2018-04-20 08:52:26 +02:00
count = maxCount;
2017-07-21 18:21:34 +02:00
2018-04-20 08:52:26 +02:00
QVector< QChar > candidateBuffer;
candidateBuffer.resize( ime_pinyin::kMaxSearchSteps + 1 );
2017-07-21 18:21:34 +02:00
2018-04-20 08:52:26 +02:00
QStringList candidates;
candidates.reserve( count );
2018-08-03 08:15:28 +02:00
for ( unsigned int i = 0; i < count; i++ )
2018-04-20 08:52:26 +02:00
{
size_t length = static_cast< size_t >( candidateBuffer.length() - 1 );
const auto buf = reinterpret_cast< ime_pinyin::char16* >( candidateBuffer.data() );
2018-04-20 08:52:26 +02:00
const bool found = ime_pinyin::im_get_candidate( i, buf, length );
Q_ASSERT( found );
candidateBuffer.last() = 0;
auto candidate = QString( candidateBuffer.data() );
2018-08-03 08:15:28 +02:00
candidate = QChar( Qt::Key( candidate[ 0 ].unicode() ) );
2018-04-20 08:52:26 +02:00
candidates += candidate;
2017-07-21 18:21:34 +02:00
}
2018-04-20 08:52:26 +02:00
m_data->candidates = candidates;
Q_EMIT predictionChanged();
2017-07-21 18:21:34 +02:00
}