kdeui: drop support for spelling correction via dialog

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-10 01:04:04 +03:00
parent 67cd9d4db8
commit 8c9f56e862
7 changed files with 2 additions and 506 deletions

View file

@ -360,7 +360,6 @@ install(
KPtyProcess
KSpeller
KSpellHighlighter
KSpellDialog
KSpellDictionaryComboBox
KSpellConfigWidget
KSpellBackgroundChecker

View file

@ -1 +0,0 @@
#include "../kspelldialog.h"

View file

@ -177,7 +177,6 @@ set(kdeui_LIB_SRCS
shortcuts/kcheckaccelerators.cpp
spell/kspeller.cpp
spell/kspellhighlighter.cpp
spell/kspelldialog.cpp
spell/kspelldictionarycombobox.cpp
spell/kspellconfigwidget.cpp
spell/kspellbackgroundchecker.cpp
@ -494,7 +493,6 @@ install(
shortcuts/kacceleratormanager.h
spell/kspeller.h
spell/kspellhighlighter.h
spell/kspelldialog.h
spell/kspelldictionarycombobox.h
spell/kspellconfigwidget.h
spell/kspellbackgroundchecker.h

View file

@ -1,301 +0,0 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kspelldialog.h"
#include "kspeller.h"
#include "klocale.h"
#include "klistwidget.h"
#include "kpushbutton.h"
#include "kmessagebox.h"
#include "kdebug.h"
#include <QThread>
#include <QCoreApplication>
#include <QTextBoundaryFinder>
#include <QGridLayout>
#include <QLabel>
class KSpellDialogThread : public QThread
{
Q_OBJECT
public:
KSpellDialogThread(QObject *parent, KSpeller *speller, const QString &text);
void run() final;
void interrupt();
void findNext();
int position() const;
Q_SIGNALS:
void foundWord(const QString &word);
void atEnd();
private:
bool m_interrupt;
QString m_text;
KSpeller* m_speller;
QTextBoundaryFinder m_finder;
bool m_findprevious;
bool m_findnext;
int m_wordstart;
};
KSpellDialogThread::KSpellDialogThread(QObject *parent, KSpeller *speller, const QString &text)
: QThread(parent),
m_interrupt(false),
m_text(text),
m_speller(speller),
m_finder(QTextBoundaryFinder::Word, text),
m_findnext(false),
m_wordstart(0)
{
// qDebug() << Q_FUNC_INFO << lang;
}
void KSpellDialogThread::run()
{
while (!m_interrupt) {
if (!m_findnext) {
// kDebug() << "Busy loop for 200ms";
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
QThread::msleep(100);
continue;
}
kDebug() << "Looking for the next word";
const int finderresult = m_finder.toNextBoundary();
if (finderresult < 0) {
emit atEnd();
break;
}
QTextBoundaryFinder::BoundaryReasons boundary = m_finder.boundaryReasons();
if (boundary & QTextBoundaryFinder::StartWord) {
m_wordstart = m_finder.position();
}
if (boundary & QTextBoundaryFinder::EndWord) {
QString word = m_text.mid(m_wordstart, m_finder.position() - m_wordstart);
if (word.size() < 2) {
continue;
}
if (word.at(word.size() - 1).isPunct()) {
word = word.mid(0, word.size() - 1);
}
kDebug() << "Found word at" << m_wordstart << m_finder.position() << word;
if (!m_speller->check(word)) {
m_findnext = false;
emit foundWord(word);
}
}
}
}
void KSpellDialogThread::interrupt()
{
m_interrupt = true;
}
void KSpellDialogThread::findNext()
{
m_findnext = true;
}
int KSpellDialogThread::position() const
{
return m_finder.position();
}
class KSpellDialogPrivate
{
public:
KSpellDialogPrivate(KConfig *config);
QWidget* dialogwidget;
QGridLayout* layout;
QLabel* misspelledlabel;
QLabel* wordlabel;
KListWidget* suggestionswidget;
KPushButton* correctbutton;
KPushButton* nextbutton;
bool showcompletionmessage;
bool continueaftercorrect;
QString text;
KSpeller speller;
KSpellDialogThread* spellerthread;
};
KSpellDialogPrivate::KSpellDialogPrivate(KConfig *config)
: dialogwidget(nullptr),
layout(nullptr),
misspelledlabel(nullptr),
wordlabel(nullptr),
suggestionswidget(nullptr),
correctbutton(nullptr),
nextbutton(nullptr),
showcompletionmessage(true),
continueaftercorrect(false),
speller(config),
spellerthread(nullptr)
{
}
KSpellDialog::KSpellDialog(KConfig *config, QWidget *parent)
: KDialog(parent),
d(new KSpellDialogPrivate(config))
{
setCaption(i18nc("@title:window", "Check Spelling"));
d->dialogwidget = new QWidget(this);
d->layout = new QGridLayout(d->dialogwidget);
d->layout->setSpacing(KDialog::spacingHint());
d->misspelledlabel = new QLabel(i18n("Misspelled word:"), this);
d->layout->addWidget(d->misspelledlabel, 0, 0);
d->wordlabel = new QLabel(QString::fromLatin1("..."), this);
d->wordlabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
d->layout->addWidget(d->wordlabel, 0, 1);
d->suggestionswidget = new KListWidget(this);
d->layout->addWidget(d->suggestionswidget, 1, 0, 5, 1);
d->correctbutton = new KPushButton(i18n("Correct"), this);
d->correctbutton->setIcon(KIcon("edit-node")); // TODO: or tools-check-spelling?
connect(
d->correctbutton, SIGNAL(pressed()),
this, SLOT(_correct())
);
d->layout->addWidget(d->correctbutton, 1, 1);
d->nextbutton = new KPushButton(i18n("Next"), this);
d->nextbutton->setIcon(KIcon("go-next"));
connect(
d->nextbutton, SIGNAL(pressed()),
this, SLOT(_next())
);
d->layout->addWidget(d->nextbutton, 2, 1);
setMainWidget(d->dialogwidget);
}
KSpellDialog::~KSpellDialog()
{
if (d->spellerthread) {
d->spellerthread->interrupt();
d->spellerthread->wait();
delete d->spellerthread;
}
delete d;
}
void KSpellDialog::showSpellCheckCompletionMessage(bool b)
{
d->showcompletionmessage = b;
}
void KSpellDialog::setSpellCheckContinuedAfterReplacement(bool b)
{
d->continueaftercorrect = b;
}
QString KSpellDialog::buffer() const
{
return d->text;
}
void KSpellDialog::setBuffer(const QString &buffer)
{
d->text = buffer;
if (d->spellerthread) {
d->spellerthread->interrupt();
d->spellerthread->wait();
delete d->spellerthread;
}
d->spellerthread = new KSpellDialogThread(this, &d->speller, d->text);
connect(
d->spellerthread, SIGNAL(foundWord(QString)),
this, SLOT(_suggest(QString))
);
connect(
d->spellerthread, SIGNAL(atEnd()),
this, SLOT(_done())
);
d->spellerthread->start();
_next();
}
void KSpellDialog::changeLanguage(const QString &lang)
{
d->speller.setDictionary(lang);
emit languageChanged(lang);
}
void KSpellDialog::_correct()
{
QListWidgetItem* suggestionitem = d->suggestionswidget->currentItem();
Q_ASSERT(suggestionitem);
const QString word = d->wordlabel->text();
emit replace(word, d->spellerthread->position() - word.size(), suggestionitem->text());
if (d->continueaftercorrect) {
kDebug() << "Spell checking continues..";
_next();
}
}
void KSpellDialog::_next()
{
Q_ASSERT(d->spellerthread);
kDebug() << "Looking for the next word";
d->spellerthread->findNext();
}
void KSpellDialog::_done()
{
kDebug() << "Done checking";
Q_ASSERT(d->spellerthread);
d->spellerthread->interrupt();
d->spellerthread->wait();
delete d->spellerthread;
d->spellerthread = nullptr;
if (d->showcompletionmessage) {
KMessageBox::information(this, i18n("Spell check complete."), i18nc("@title:window", "Check Spelling"));
}
KDialog::accept();
}
void KSpellDialog::_suggest(const QString &word)
{
kDebug() << "Got a word from the checker" << word;
d->wordlabel->setText(word);
d->suggestionswidget->clear();
const QStringList suggestions = d->speller.suggest(word);
foreach (const QString &suggestion, suggestions) {
d->suggestionswidget->addItem(suggestion);
}
if (suggestions.isEmpty()) {
d->correctbutton->setEnabled(false);
} else {
d->correctbutton->setEnabled(true);
d->suggestionswidget->setCurrentRow(0);
}
emit misspelling(word, d->spellerthread->position() - word.size());
}
#include "moc_kspelldialog.cpp"
#include "kspelldialog.moc"

View file

@ -1,65 +0,0 @@
/* This file is part of the KDE libraries
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KSPELLDIALOG_H
#define KSPELLDIALOG_H
#include "kdeui_export.h"
#include "kdialog.h"
class KSpellDialogPrivate;
/*!
Dialog to check spelling and apply correction interactively.
@since 4.23
@warning Recommended use of this dialog is on selected words
*/
class KDEUI_EXPORT KSpellDialog : public KDialog
{
Q_OBJECT
public:
KSpellDialog(KConfig *config, QWidget *parent = nullptr);
~KSpellDialog();
void showSpellCheckCompletionMessage(bool b = true);
void setSpellCheckContinuedAfterReplacement(bool b);
QString buffer() const;
public Q_SLOTS:
void setBuffer(const QString &buffer);
void changeLanguage(const QString &lang);
Q_SIGNALS:
void misspelling(const QString &word, int start);
void replace(const QString &oldWord, int start, const QString &newWord);
void languageChanged(const QString &language);
private Q_SLOTS:
void _correct();
void _next();
void _done();
void _suggest(const QString &word);
private:
Q_DISABLE_COPY(KSpellDialog);
KSpellDialogPrivate *d;
};
#endif // KSPELLDIALOG_H

View file

@ -48,7 +48,6 @@
#include <kmenu.h>
#include <kwindowsystem.h>
#include <kspellhighlighter.h>
#include <kspelldialog.h>
#include <QDebug>
class KTextEdit::Private
@ -96,10 +95,6 @@ class KTextEdit::Private
*/
bool handleShortcut(const QKeyEvent* e);
void spellCheckerMisspelling( const QString &text, int pos );
void spellCheckerCorrected( const QString &, int,const QString &);
void spellCheckerCanceled();
void spellCheckerFinished();
void toggleAutoSpellCheck();
void slotFindHighlight(const QString& text, int matchingIndex, int matchingLength);
@ -118,11 +113,9 @@ class KTextEdit::Private
void init();
void checkSpelling(bool force);
KTextEdit *parent;
QAction *autoSpellCheckAction;
QAction *allowTab;
QAction *spellCheckAction;
QString clickMessage;
bool italicizePlaceholder : 1;
bool customPalette : 1;
@ -141,85 +134,6 @@ class KTextEdit::Private
int lastReplacedPosition;
};
void KTextEdit::Private::checkSpelling(bool force)
{
if (parent->document()->isEmpty()) {
KMessageBox::information(parent, i18n("Nothing to spell check."));
if (force) {
emit parent->spellCheckingFinished();
}
return;
}
KSpellDialog *spellDialog = new KSpellDialog(KGlobal::config().data(), force ? parent : 0);
if (!spellCheckingLanguage.isEmpty()) {
spellDialog->changeLanguage(spellCheckingLanguage);
}
spellDialog->setAttribute(Qt::WA_DeleteOnClose, true);
connect(
spellDialog, SIGNAL(replace(QString,int,QString)),
parent, SLOT(spellCheckerCorrected(QString,int,QString))
);
connect(
spellDialog, SIGNAL(misspelling(QString,int)),
parent, SLOT(spellCheckerMisspelling(QString,int))
);
connect(
spellDialog, SIGNAL(accepted()),
parent, SLOT(spellCheckerFinished())
);
connect(
spellDialog, SIGNAL(rejected()),
parent, SLOT(spellCheckerCanceled())
);
connect(
spellDialog, SIGNAL(languageChanged(QString)),
parent, SIGNAL(languageChanged(QString))
);
if (force) {
connect(spellDialog, SIGNAL(accepted()), parent, SIGNAL(spellCheckingFinished()));
connect(spellDialog, SIGNAL(rejected()), parent, SIGNAL(spellCheckingCanceled()));
}
originalDoc = QTextDocumentFragment(parent->document());
spellDialog->setBuffer(parent->toPlainText());
spellDialog->show();
}
void KTextEdit::Private::spellCheckerCanceled()
{
QTextDocument *doc = parent->document();
doc->clear();
QTextCursor cursor(doc);
cursor.insertFragment(originalDoc);
spellCheckerFinished();
}
void KTextEdit::Private::spellCheckerMisspelling( const QString &text, int pos )
{
//kDebug()<<"TextEdit::Private::spellCheckerMisspelling :"<<text<<" pos :"<<pos;
parent->highlightWord( text.length(), pos );
}
void KTextEdit::Private::spellCheckerCorrected( const QString& oldWord, int pos,const QString& newWord)
{
//kDebug()<<" oldWord :"<<oldWord<<" newWord :"<<newWord<<" pos : "<<pos;
if (oldWord != newWord ) {
QTextCursor cursor(parent->document());
cursor.setPosition(pos);
cursor.setPosition(pos+oldWord.length(),QTextCursor::KeepAnchor);
cursor.insertText(newWord);
}
}
void KTextEdit::Private::spellCheckerFinished()
{
QTextCursor cursor(parent->document());
cursor.clearSelection();
parent->setTextCursor(cursor);
if (parent->highlighter())
parent->highlighter()->rehighlight();
}
void KTextEdit::Private::toggleAutoSpellCheck()
{
parent->setCheckSpellingEnabled( !parent->checkSpellingEnabled() );
@ -242,9 +156,7 @@ void KTextEdit::Private::slotAllowTab()
void KTextEdit::Private::menuActivated( QAction* action )
{
if ( action == spellCheckAction )
parent->checkSpelling();
else if ( action == autoSpellCheckAction )
if ( action == autoSpellCheckAction )
toggleAutoSpellCheck();
else if ( action == allowTab )
slotAllowTab();
@ -500,10 +412,6 @@ QMenu *KTextEdit::mousePopupMenu()
if( !isReadOnly() )
{
popup->addSeparator();
d->spellCheckAction = popup->addAction( KIcon( "tools-check-spelling" ),
i18n( "Check Spelling..." ) );
if ( emptyDocument )
d->spellCheckAction->setEnabled( false );
d->autoSpellCheckAction = popup->addAction( i18n( "Auto Spell Check" ) );
d->autoSpellCheckAction->setCheckable( true );
d->autoSpellCheckAction->setChecked( checkSpellingEnabled() );
@ -745,16 +653,6 @@ void KTextEdit::setReadOnly( bool readOnly )
QTextEdit::setReadOnly( readOnly );
}
void KTextEdit::checkSpelling()
{
d->checkSpelling(false);
}
void KTextEdit::forceSpellChecking()
{
d->checkSpelling(true);
}
void KTextEdit::highlightWord( int length, int pos )
{
QTextCursor cursor(document());

View file

@ -191,13 +191,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
*/
void showTabAction(bool show);
/**
* @since 4.10
* create a modal spellcheck dialogbox and spellCheckingFinished signal we sent when
* we finish spell checking or spellCheckingCanceled signal when we cancel spell checking
*/
void forceSpellChecking();
Q_SIGNALS:
/**
* emit signal when we activate or not autospellchecking
@ -207,8 +200,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
void checkSpellingChanged( bool );
/**
* Emitted when the user changes the language in the spellcheck dialog
* shown by checkSpelling() or when calling setSpellCheckingLanguage().
* Emitted when calling setSpellCheckingLanguage().
*
* @param language the new language the user selected
* @since 4.1
@ -230,20 +222,7 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
*/
void aboutToShowContextMenu(QMenu* menu);
/**
* signal spellCheckingFinished is sent when we finish spell check or we click on "Terminate" button in speller dialogbox
* @since 4.10
*/
void spellCheckingFinished();
/**
* signal spellCheckingCanceled is sent when we cancel spell checking.
* @since 4.10
*/
void spellCheckingCanceled();
public Q_SLOTS:
/**
* Set the spell check language which will be used for highlighting spelling
* mistakes and for the spellcheck dialog.
@ -254,13 +233,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
*/
void setSpellCheckingLanguage(const QString &language);
/**
* Show a dialog to check the spelling. The spellCheckingFinished() or
* spellCheckingCanceled() signal will be emitted when the spell checking
* dialog is closed.
*/
void checkSpelling();
/**
* Create replace dialogbox
* @since 4.1
@ -328,10 +300,6 @@ class KDEUI_EXPORT KTextEdit : public QTextEdit //krazy:exclude=qclasses
class Private;
Private *const d;
Q_PRIVATE_SLOT( d, void spellCheckerMisspelling( const QString&, int ) )
Q_PRIVATE_SLOT( d, void spellCheckerCorrected(const QString&, int,const QString&) )
Q_PRIVATE_SLOT( d, void spellCheckerCanceled())
Q_PRIVATE_SLOT( d, void spellCheckerFinished() )
Q_PRIVATE_SLOT( d, void undoableClear() )
Q_PRIVATE_SLOT( d, void toggleAutoSpellCheck() )
Q_PRIVATE_SLOT( d, void slotAllowTab() )