P
Ich greife dieses alte Thema nochmal auf, da die Rechtschreibprüfung mittlerweile fertig implementiert ist und vielleicht noch jemand etwas damit anfangen kann...
SeppJ schrieb:
Warum nicht? Von wegen "verständlicherweise", ich verstehe bei dieser Beschreibung gar nicht, wieso eine fertige, freie Lösung nicht optimal wäre.
Weil z.B. Hunspell komplexer als unsere komplette Bibliothek ist. Ich wollte nur eine ganze einfache Rechtschreibprüfung (siehe unten) und wenn ich den Code selber schreibe, weiß ich genau was Sache ist und bin unabhängig
Hier der Code von unserem Spellchecker, zur Verwendung ohne cutex müssen nur die jeweiligen Includes entfernt werden. Anschließend mit setDictionary() die Wortliste zuweisen und die Rechtschreibprüfung mit setActive() aktivieren. Der Editor wird dann einfach dem Konstruktor übergeben.
/***********************************************************************************************************************
**
** Copyright (C) 2016-2017 Partsoft UG (haftungsbeschränkt)
** Contact: https://www.partsoft.de/index.php/kontakt
**
** This file is part of cutex
**
** cutex is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
** version.
**
** cutex is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
** of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License along with cutex. If not, see
** http://www.gnu.org/licenses.
**
***********************************************************************************************************************/
#ifndef QXSPELLCHECKER_H
#define QXSPELLCHECKER_H
#include "cutex.h"
namespace cutex {
/*!
\brief Mit %QxSpellChecker kann eine Rechtschreibprüfung für QTextEdit realisiert werden.
%QxSpellChecker vergleicht die Inhalte eines QTextEdit mit einer Wortliste und markiert alle Wörter, die nicht in der
Liste enthalten sind.
*/
class QxSpellChecker : public QObject
{
Q_OBJECT
public:
QxSpellChecker(QTextEdit *editor);
static bool setDictionary(const QString &fileName);
static void setActive(bool active);
static void setDelay(int delay);
public slots:
void run();
private:
static QSet<QString> m_wordList;
static bool m_active;
static int m_delay;
QTextEdit *m_editor;
bool m_finished;
QTime m_interval;
private slots:
void wake();
void restart();
};
} // namespace
#endif // QXSPELLCHECKER_H
/***********************************************************************************************************************
**
** Copyright (C) 2016-2017 Partsoft UG (haftungsbeschränkt)
** Contact: https://www.partsoft.de/index.php/kontakt
**
** This file is part of cutex
**
** cutex is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
** version.
**
** cutex is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
** of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License along with cutex. If not, see
** http://www.gnu.org/licenses.
**
***********************************************************************************************************************/
#include "qxspellchecker.h"
#include "qxwaitcursor.h"
using namespace cutex;
QSet<QString> QxSpellChecker::m_wordList;
bool QxSpellChecker::m_active = false;
int QxSpellChecker::m_delay = 1000;
/*!
Erzeugt ein neues Objekt zur Rechtschreibprüfung für den Editor <i>editor</i>.
*/
QxSpellChecker::QxSpellChecker(QTextEdit *editor) : QObject(editor)
{
QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
m_editor = editor;
m_finished = false;
connect(dispatcher, SIGNAL(awake()), this, SLOT(wake()));
connect(m_editor->document(), SIGNAL(contentsChanged()), this, SLOT(restart()));
}
/*!
Aktualisiert die Wortliste mit dem Inhalt der Datei <i>fileName</i>.
*/
bool QxSpellChecker::setDictionary(const QString &fileName)
{
QFile file(fileName);
QTextStream inStream(&file);
bool success = false;
QxWaitCursor wait;
Q_UNUSED(wait);
m_wordList.clear();
success = file.open(QFile::ReadOnly);
if (success) {
while (!inStream.atEnd())
m_wordList.insert(inStream.readLine().toLower());
}
return success;
}
/*!
Aktiviert oder deaktiviert die Rechtschreibprüfung.
*/
void QxSpellChecker::setActive(bool active)
{
m_active = active;
}
/*!
Setzt den Zeitraum zur Aktualisierung der Rechtschreibprüfung auf <i>delay</i> Millisekunden.
*/
void QxSpellChecker::setDelay(int delay)
{
m_delay = delay;
}
/*!
Führt die Rechtschreibprüfung durch und markiert alle ungültigen Wörter.
*/
void QxSpellChecker::run()
{
QList<QTextEdit::ExtraSelection> selections;
if (m_active) {
QTextCursor cursor = m_editor->textCursor();
QString word;
QString text = m_editor->document()->toPlainText();
QStringList allWords = text.split(QRegExp("\\W+"), QString::SkipEmptyParts);
QStringList invalidWords;
foreach (word, allWords) {
word = word.toLower();
if (!invalidWords.contains(word)) {
bool isNumber;
word.toInt(&isNumber);
if (!isNumber && !m_wordList.contains(word))
invalidWords.append(word);
}
}
cursor.movePosition(QTextCursor::Start);
while (!cursor.atEnd()) {
cursor.select(QTextCursor::WordUnderCursor);
word = cursor.selectedText().toLower();
if (invalidWords.contains(word)) {
QTextEdit::ExtraSelection extraSelection;
extraSelection.cursor = cursor;
extraSelection.format.setUnderlineColor(Qt::red);
extraSelection.format.setUnderlineStyle(QTextCharFormat::WaveUnderline);
selections.append(extraSelection);
}
cursor.movePosition(QTextCursor::NextWord);
}
}
m_editor->setExtraSelections(selections);
m_finished = true;
}
void QxSpellChecker::wake()
{
if ((m_interval.isNull() || m_interval.elapsed() > m_delay) && !m_finished) {
m_interval = QTime::currentTime();
run();
}
}
void QxSpellChecker::restart()
{
m_interval = QTime::currentTime();
m_finished = false;
}