Files
RedBear-OS/local/recipes/kde/kf6-sonnet/source/src/quick/spellcheckhighlighter.h
T
2026-04-14 10:51:06 +01:00

242 lines
9.3 KiB
C++

// SPDX-FileCopyrightText: 2004 Zack Rusin <zack@kde.org>
// SPDX-FileCopyrightText: 2013 Martin Sandsmark <martin.sandsmark@kde.org>
// SPDX-FileCopyrightText: 2013 Aurélien Gâteau <agateau@kde.org>
// SPDX-FileCopyrightText: 2020 Christian Mollekopf <mollekopf@kolabsystems.com>
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
// TODO KF6 create AbstractSpellcheckHighlighter and make the QtQuick and QtWidget inherit
// from it.
#include <QQuickTextDocument>
#include <QSyntaxHighlighter>
class HighlighterPrivate;
/// \brief The Sonnet Highlighter class, used for drawing red lines in text fields
/// when detecting spelling mistakes.
///
/// SpellcheckHighlighter is adapted for QML applications. In usual Kirigami/QQC2-desktop-style
/// applications, this can be used directly by adding `Kirigami.SpellCheck.enabled: true` on
/// a TextArea.
///
/// On other QML applications, you can add the SpellcheckHighlighter as a child of a TextArea.
///
/// Note: TextField is not supported, as it lacks QTextDocument API that Sonnet relies on.
///
/// \code{.qml}
/// TextArea {
/// id: textArea
/// Sonnet.SpellcheckHighlighter {
/// id: spellcheckhighlighter
/// document: textArea.textDocument
/// cursorPosition: textArea.cursorPosition
/// selectionStart: textArea.selectionStart
/// selectionEnd: textArea.selectionEnd
/// misspelledColor: Kirigami.Theme.negativeTextColor
/// active: true
///
/// onChangeCursorPosition: {
/// textArea.cursorPosition = start;
/// textArea.moveCursorSelection(end, TextEdit.SelectCharacters);
/// }
/// }
/// }
/// \endcode
///
/// Additionally SpellcheckHighlighter provides some convenient methods to create
/// a context menu with suggestions. \see suggestions
///
/// \since 5.88
class SpellcheckHighlighter : public QSyntaxHighlighter
{
Q_OBJECT
QML_ELEMENT
/// This property holds the underneath document from a QML TextEdit.
/// \since 5.88
Q_PROPERTY(QQuickTextDocument *document READ quickDocument WRITE setQuickDocument NOTIFY documentChanged)
/// This property holds the current cursor position.
/// \since 5.88
Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
/// This property holds the start of the selection.
/// \since 5.88
Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged)
/// This property holds the end of the selection.
/// \since 5.88
Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged)
/// This property holds whether the current word under the mouse is misspelled.
/// \since 5.88
Q_PROPERTY(bool wordIsMisspelled READ wordIsMisspelled NOTIFY wordIsMisspelledChanged)
/// This property holds the current word under the mouse.
/// \since 5.88
Q_PROPERTY(QString wordUnderMouse READ wordUnderMouse NOTIFY wordUnderMouseChanged)
/// This property holds the spell color. By default, it's red.
/// \since 5.88
Q_PROPERTY(QColor misspelledColor READ misspelledColor WRITE setMisspelledColor NOTIFY misspelledColorChanged)
/// This property holds the current language used for spell checking.
/// \since 5.88
Q_PROPERTY(QString currentLanguage READ currentLanguage NOTIFY currentLanguageChanged)
/// This property holds whether a spell checking backend with support for the
/// \ref currentLanguage was found.
/// \since 5.88
Q_PROPERTY(bool spellCheckerFound READ spellCheckerFound CONSTANT)
/// \brief This property holds whether spell checking is enabled.
///
/// If \p active is true then spell checking is enabled; otherwise it
/// is disabled. Note that you have to disable automatic (de)activation
/// with \ref automatic before you change the state of spell
/// checking if you want to persistently enable/disable spell
/// checking.
///
/// \see automatic
/// \since 5.88
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
/// This property holds whether spell checking is automatically disabled
/// if there's too many errors.
/// \since 5.88
Q_PROPERTY(bool automatic READ automatic WRITE setAutomatic NOTIFY automaticChanged)
/// This property holds whether the automatic language detection is disabled
/// overriding the Sonnet global settings.
/// \since 5.88
Q_PROPERTY(bool autoDetectLanguageDisabled READ autoDetectLanguageDisabled WRITE setAutoDetectLanguageDisabled NOTIFY autoDetectLanguageDisabledChanged)
public:
explicit SpellcheckHighlighter(QObject *parent = nullptr);
~SpellcheckHighlighter() override;
/// Returns a list of suggested replacements for the given misspelled word.
/// If the word is not misspelled, the list will be empty.
///
/// \param word the misspelled word
/// \param max at most this many suggestions will be returned. If this is
/// -1, as many suggestions as the spell backend supports will
/// be returned.
/// \return a list of suggested replacements for the word
/// \since 5.88
Q_INVOKABLE QStringList suggestions(int position, int max = 5);
/// Ignores the given word. This word will not be marked misspelled for
/// this session. It will again be marked as misspelled when creating
/// new highlighters.
///
/// \param word the word which will be ignored
/// \since 5.88
Q_INVOKABLE void ignoreWord(const QString &word);
/// Adds the given word permanently to the dictionary. It will never
/// be marked as misspelled again, even after restarting the application.
///
/// \param word the word which will be added to the dictionary
/// \since 5.88
Q_INVOKABLE void addWordToDictionary(const QString &word);
/// Replace word at the current cursor position, or @param at if
/// @param at is not -1.
/// \since 5.88
Q_INVOKABLE void replaceWord(const QString &word, int at = -1);
/// Checks if a given word is marked as misspelled by the highlighter.
///
/// \param word the word to be checked
/// \return true if the given word is misspelled.
/// \since 5.88
Q_INVOKABLE bool isWordMisspelled(const QString &word);
Q_REQUIRED_RESULT QQuickTextDocument *quickDocument() const;
void setQuickDocument(QQuickTextDocument *document);
Q_REQUIRED_RESULT int cursorPosition() const;
void setCursorPosition(int position);
Q_REQUIRED_RESULT int selectionStart() const;
void setSelectionStart(int position);
Q_REQUIRED_RESULT int selectionEnd() const;
void setSelectionEnd(int position);
Q_REQUIRED_RESULT bool wordIsMisspelled() const;
Q_REQUIRED_RESULT QString wordUnderMouse() const;
Q_REQUIRED_RESULT bool spellCheckerFound() const;
Q_REQUIRED_RESULT QString currentLanguage() const;
void setActive(bool active);
Q_REQUIRED_RESULT bool active() const;
void setAutomatic(bool automatic);
Q_REQUIRED_RESULT bool automatic() const;
void setAutoDetectLanguageDisabled(bool autoDetectDisabled);
Q_REQUIRED_RESULT bool autoDetectLanguageDisabled() const;
void setMisspelledColor(const QColor &color);
Q_REQUIRED_RESULT QColor misspelledColor() const;
void setQuoteColor(const QColor &color);
Q_REQUIRED_RESULT QColor quoteColor() const;
/// Set a new @ref QTextDocument for this highlighter to operate on.
/// \param document the new document to operate on.
/// \since 5.88
void setDocument(QTextDocument *document);
Q_SIGNALS:
void documentChanged();
void cursorPositionChanged();
void selectionStartChanged();
void selectionEndChanged();
void wordIsMisspelledChanged();
void wordUnderMouseChanged();
void changeCursorPosition(int start, int end);
void activeChanged();
void misspelledColorChanged();
void autoDetectLanguageDisabledChanged();
void automaticChanged();
void currentLanguageChanged();
/// Emitted when as-you-type spell checking is enabled or disabled.
///
/// \param description is a i18n description of the new state,
/// with an optional reason
/// \since 5.88
void activeChanged(const QString &description);
protected:
void highlightBlock(const QString &text) override;
virtual void setMisspelled(int start, int count);
virtual void setMisspelledSelected(int start, int count);
virtual void unsetMisspelled(int start, int count);
bool eventFilter(QObject *o, QEvent *e) override;
bool intraWordEditing() const;
void setIntraWordEditing(bool editing);
public Q_SLOTS:
/// Set language to use for spell checking.
///
/// \param language the language code for the new language to use.
/// \since 5.88
void setCurrentLanguage(const QString &language);
/// Run auto detection, disabling spell checking if too many errors are found.
/// \since 5.88
void slotAutoDetection();
/// Force a new highlighting.
/// \since 5.88
void slotRehighlight();
private:
Q_REQUIRED_RESULT QTextCursor textCursor() const;
Q_REQUIRED_RESULT QTextDocument *textDocument() const;
void contentsChange(int pos, int add, int rem);
void autodetectLanguage(const QString &sentence);
HighlighterPrivate *const d;
Q_DISABLE_COPY(SpellcheckHighlighter)
};