parent
ec0b962bad
commit
cd82993bed
|
@ -21,7 +21,11 @@ macro(add_target name type)
|
||||||
|
|
||||||
set_target_properties(${name} PROPERTIES CXX_STANDARD 11 AUTOMOC ON)
|
set_target_properties(${name} PROPERTIES CXX_STANDARD 11 AUTOMOC ON)
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
target_include_directories(${name} PUBLIC include include/Qt ${CMAKE_SOURCE_DIR}/../../bottles/hunspell/include)
|
||||||
|
else()
|
||||||
target_include_directories(${name} PUBLIC include include/Qt)
|
target_include_directories(${name} PUBLIC include include/Qt)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${name} PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick Qt5::Network)
|
target_link_libraries(${name} PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt5::Quick Qt5::Network)
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,12 @@ class Hunspell;
|
||||||
#endif
|
#endif
|
||||||
class QTextCodec;
|
class QTextCodec;
|
||||||
|
|
||||||
class SpellChecker : public QSyntaxHighlighter
|
class SpellChecker : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
|
Q_PROPERTY(QString lang READ lang WRITE setLang NOTIFY langChanged)
|
||||||
Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged)
|
Q_PROPERTY(QString userDict READ userDict WRITE setUserDict NOTIFY userDictChanged)
|
||||||
Q_PROPERTY(QQuickTextDocument* document READ textDocument WRITE setTextDocument NOTIFY textDocumentChanged)
|
|
||||||
public:
|
public:
|
||||||
explicit SpellChecker(QObject *parent = nullptr);
|
explicit SpellChecker(QObject *parent = nullptr);
|
||||||
~SpellChecker();
|
~SpellChecker();
|
||||||
|
@ -25,30 +25,24 @@ public:
|
||||||
Q_INVOKABLE QVariantList suggest(const QString &word);
|
Q_INVOKABLE QVariantList suggest(const QString &word);
|
||||||
Q_INVOKABLE void ignoreWord(const QString &word);
|
Q_INVOKABLE void ignoreWord(const QString &word);
|
||||||
Q_INVOKABLE void addToUserWordlist(const QString &word);
|
Q_INVOKABLE void addToUserWordlist(const QString &word);
|
||||||
|
Q_INVOKABLE bool isInit() const;
|
||||||
|
|
||||||
void setText(const QString& text);
|
const QString& lang() const;
|
||||||
const QString& text() const;
|
void setLang(const QString& lang);
|
||||||
|
|
||||||
const QString& displayText() const;
|
const QString& userDict() const;
|
||||||
|
void setUserDict(const QString& userDict);
|
||||||
QQuickTextDocument* textDocument() const;
|
|
||||||
void setTextDocument(QQuickTextDocument* document);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void textChanged();
|
void langChanged();
|
||||||
void displayTextChanged();
|
void userDictChanged();
|
||||||
void textDocumentChanged();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void highlightBlock(const QString &text) final;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void makeDisplayText(const QString& text);
|
void initHunspell();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_text;
|
QString m_lang;
|
||||||
QString m_displayText;
|
QString m_userDict;
|
||||||
QString m_dictionaryPath;
|
|
||||||
|
|
||||||
QQuickTextDocument *m_document;
|
QQuickTextDocument *m_document;
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#include "DosSpellchecker.h"
|
#include "../include/DOtherSide/DosSpellchecker.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
#include "hunspell/hunspell.hxx"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "hunspell.hxx"
|
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -13,13 +16,49 @@
|
||||||
#include <QInputMethod>
|
#include <QInputMethod>
|
||||||
|
|
||||||
SpellChecker::SpellChecker(QObject *parent)
|
SpellChecker::SpellChecker(QObject *parent)
|
||||||
: QSyntaxHighlighter(parent)
|
: QObject(parent)
|
||||||
{
|
|
||||||
auto language = QLocale::system().bcp47Name();
|
|
||||||
|
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
QString dictFile = QApplication::applicationDirPath() + + "/dictionaries/" + language + "/index.dic";
|
, m_hunspell(nullptr)
|
||||||
QString affixFile = QApplication::applicationDirPath() + + "/dictionaries/" + language + "/index.aff";
|
#endif
|
||||||
|
, m_userDict("userDict_")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellChecker::~SpellChecker()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
delete m_hunspell;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpellChecker::spell(const QString &word)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
return m_hunspell->spell(m_codec->fromUnicode(word).toStdString());
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpellChecker::isInit() const
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
return !m_hunspell;
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellChecker::initHunspell()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_MACOS
|
||||||
|
if (m_hunspell) {
|
||||||
|
delete m_hunspell;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString dictFile = QApplication::applicationDirPath() + "/dictionaries/" + m_lang + "/index.dic";
|
||||||
|
QString affixFile = QApplication::applicationDirPath() + "/dictionaries/" + m_lang + "/index.aff";
|
||||||
QByteArray dictFilePathBA = dictFile.toLocal8Bit();
|
QByteArray dictFilePathBA = dictFile.toLocal8Bit();
|
||||||
QByteArray affixFilePathBA = affixFile.toLocal8Bit();
|
QByteArray affixFilePathBA = affixFile.toLocal8Bit();
|
||||||
m_hunspell = new Hunspell(affixFilePathBA.constData(),
|
m_hunspell = new Hunspell(affixFilePathBA.constData(),
|
||||||
|
@ -49,7 +88,7 @@ SpellChecker::SpellChecker(QObject *parent)
|
||||||
}
|
}
|
||||||
m_codec = QTextCodec::codecForName(encoding.toLatin1().constData());
|
m_codec = QTextCodec::codecForName(encoding.toLatin1().constData());
|
||||||
|
|
||||||
QString userDict = "userDict_" + language + ".txt";
|
QString userDict = m_userDict + m_lang + ".txt";
|
||||||
|
|
||||||
if (!userDict.isEmpty()) {
|
if (!userDict.isEmpty()) {
|
||||||
QFile userDictonaryFile(userDict);
|
QFile userDictonaryFile(userDict);
|
||||||
|
@ -70,22 +109,6 @@ SpellChecker::SpellChecker(QObject *parent)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellChecker::~SpellChecker()
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
delete m_hunspell;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SpellChecker::spell(const QString &word)
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_MACOS
|
|
||||||
return m_hunspell->spell(m_codec->fromUnicode(word).toStdString());
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantList SpellChecker::suggest(const QString &word)
|
QVariantList SpellChecker::suggest(const QString &word)
|
||||||
{
|
{
|
||||||
int numSuggestions = 0;
|
int numSuggestions = 0;
|
||||||
|
@ -117,9 +140,7 @@ void SpellChecker::ignoreWord(const QString &word)
|
||||||
void SpellChecker::addToUserWordlist(const QString &word)
|
void SpellChecker::addToUserWordlist(const QString &word)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_MACOS
|
#ifdef Q_OS_MACOS
|
||||||
auto language = QLocale::scriptToString(QLocale::system().script());
|
QString userDict = m_userDict + m_lang + ".txt";
|
||||||
|
|
||||||
QString userDict = "userDict_" + language + ".txt";
|
|
||||||
if (!userDict.isEmpty()) {
|
if (!userDict.isEmpty()) {
|
||||||
QFile userDictonaryFile(userDict);
|
QFile userDictonaryFile(userDict);
|
||||||
if (userDictonaryFile.open(QIODevice::Append)) {
|
if (userDictonaryFile.open(QIODevice::Append)) {
|
||||||
|
@ -136,67 +157,29 @@ void SpellChecker::addToUserWordlist(const QString &word)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpellChecker::setText(const QString &text)
|
const QString& SpellChecker::lang() const
|
||||||
{
|
{
|
||||||
if (m_text != text) {
|
return m_lang;
|
||||||
m_text = text;
|
}
|
||||||
emit textChanged();
|
|
||||||
makeDisplayText(m_text);
|
void SpellChecker::setLang(const QString& lang)
|
||||||
|
{
|
||||||
|
if (m_lang != lang) {
|
||||||
|
m_lang = lang;
|
||||||
|
initHunspell();
|
||||||
|
emit langChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &SpellChecker::text() const
|
const QString& SpellChecker::userDict() const
|
||||||
{
|
{
|
||||||
return m_text;
|
return m_userDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &SpellChecker::displayText() const
|
void SpellChecker::setUserDict(const QString& userDict)
|
||||||
{
|
{
|
||||||
return m_displayText;
|
if (m_userDict != userDict) {
|
||||||
}
|
m_userDict = userDict;
|
||||||
|
emit userDictChanged();
|
||||||
QQuickTextDocument *SpellChecker::textDocument() const
|
|
||||||
{
|
|
||||||
return m_document;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellChecker::setTextDocument(QQuickTextDocument *document)
|
|
||||||
{
|
|
||||||
if (m_document != document) {
|
|
||||||
m_document = document;
|
|
||||||
setDocument(m_document->textDocument());
|
|
||||||
emit textDocumentChanged();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpellChecker::highlightBlock(const QString &text)
|
|
||||||
{
|
|
||||||
QTextCharFormat format;
|
|
||||||
format.setFontUnderline(true);
|
|
||||||
|
|
||||||
QRegularExpression expression("\\S+");
|
|
||||||
QRegularExpressionMatchIterator i = expression.globalMatch(text);
|
|
||||||
while(i.hasNext()) {
|
|
||||||
QRegularExpressionMatch match = i.next();
|
|
||||||
if (!spell(match.captured())) {
|
|
||||||
setFormat(match.capturedStart(), match.capturedLength(), format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpellChecker::makeDisplayText(const QString &text)
|
|
||||||
{
|
|
||||||
auto words = text.split(" ");
|
|
||||||
QString gPattern = "<u style=\"color: red;\">%1</u>";
|
|
||||||
|
|
||||||
m_displayText = ""; // todo optimize delta
|
|
||||||
for (const auto& word: qAsConst(words)) {
|
|
||||||
if (!spell(word)) {
|
|
||||||
m_displayText.append(" " + gPattern.arg(word));
|
|
||||||
} else {
|
|
||||||
m_displayText.append(" " + word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit displayTextChanged();
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue