| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | SPDX-FileCopyrightText: 2002 Carsten Pfeiffer <pfeiffer@kde.org> |
| 4 | |
| 5 | SPDX-License-Identifier: LGPL-2.0-or-later |
| 6 | */ |
| 7 | |
| 8 | #ifndef KTEXTEDIT_H |
| 9 | #define KTEXTEDIT_H |
| 10 | |
| 11 | #include "ktextwidgets_export.h" |
| 12 | |
| 13 | #include <QTextEdit> |
| 14 | #include <memory> |
| 15 | #include <sonnet/highlighter.h> |
| 16 | |
| 17 | namespace Sonnet |
| 18 | { |
| 19 | class SpellCheckDecorator; |
| 20 | } |
| 21 | |
| 22 | class KTextEditPrivate; |
| 23 | |
| 24 | /*! |
| 25 | * \class KTextEdit |
| 26 | * \inmodule KTextWidgets |
| 27 | * |
| 28 | * \brief A KDE'ified QTextEdit. |
| 29 | * |
| 30 | * This is just a little subclass of QTextEdit, implementing |
| 31 | * some standard KDE features, like cursor auto-hiding, configurable |
| 32 | * wheelscrolling (fast-scroll or zoom), spell checking and deleting of entire |
| 33 | * words with Ctrl-Backspace or Ctrl-Delete. |
| 34 | * |
| 35 | * This text edit provides two ways of spell checking: background checking, |
| 36 | * which will mark incorrectly spelled words red, and a spell check dialog, |
| 37 | * which lets the user check and correct all incorrectly spelled words. |
| 38 | * |
| 39 | * Basic rule: whenever you want to use QTextEdit, use KTextEdit! |
| 40 | * |
| 41 | * \image ktextedit.png "KTextEdit Widget" |
| 42 | */ |
| 43 | class KTEXTWIDGETS_EXPORT KTextEdit : public QTextEdit // krazy:exclude=qclasses |
| 44 | { |
| 45 | Q_OBJECT |
| 46 | |
| 47 | /*! |
| 48 | * \property KTextEdit::checkSpellingEnabled |
| 49 | */ |
| 50 | Q_PROPERTY(bool checkSpellingEnabled READ checkSpellingEnabled WRITE setCheckSpellingEnabled) |
| 51 | |
| 52 | /*! |
| 53 | * \property KTextEdit::spellCheckingLanguage |
| 54 | */ |
| 55 | Q_PROPERTY(QString spellCheckingLanguage READ spellCheckingLanguage WRITE setSpellCheckingLanguage) |
| 56 | |
| 57 | public: |
| 58 | /*! |
| 59 | * Constructs a KTextEdit object. See QTextEdit::QTextEdit |
| 60 | * for details. |
| 61 | */ |
| 62 | explicit KTextEdit(const QString &text, QWidget *parent = nullptr); |
| 63 | |
| 64 | /*! |
| 65 | * Constructs a KTextEdit object. See QTextEdit::QTextEdit |
| 66 | * for details. |
| 67 | */ |
| 68 | explicit KTextEdit(QWidget *parent = nullptr); |
| 69 | |
| 70 | ~KTextEdit() override; |
| 71 | |
| 72 | /*! |
| 73 | * Sets the text edit control to the state of \a readOnly. |
| 74 | * |
| 75 | * Reimplemented to set a proper "deactivated" background color. |
| 76 | */ |
| 77 | virtual void setReadOnly(bool readOnly); |
| 78 | |
| 79 | /*! |
| 80 | * Turns background spell checking for this text edit to the value of \a check. |
| 81 | * Note that spell checking is only available in read-writable KTextEdits. |
| 82 | * |
| 83 | * Enabling spell checking will set back the current highlighter to the one |
| 84 | * returned by createHighlighter(). |
| 85 | * |
| 86 | * \sa checkSpellingEnabled() |
| 87 | * \sa setReadOnly() |
| 88 | */ |
| 89 | virtual void setCheckSpellingEnabled(bool check); |
| 90 | |
| 91 | /*! |
| 92 | * Returns true if background spell checking is enabled for this text edit. |
| 93 | * Note that it even returns true if this is a read-only KTextEdit, |
| 94 | * where spell checking is actually disabled. |
| 95 | * By default spell checking is disabled. |
| 96 | * |
| 97 | * \sa setCheckSpellingEnabled() |
| 98 | */ |
| 99 | virtual bool checkSpellingEnabled() const; |
| 100 | |
| 101 | /*! |
| 102 | * Returns true if the given paragraph or \a block should be spellchecked. |
| 103 | * For example, a mail client does not want to check quoted text, and |
| 104 | * would return false here (by checking whether the block starts with a |
| 105 | * quote sign). |
| 106 | * |
| 107 | * Always returns true by default. |
| 108 | * |
| 109 | */ |
| 110 | virtual bool shouldBlockBeSpellChecked(const QString &block) const; |
| 111 | |
| 112 | /*! |
| 113 | * Selects the characters at the specified position. Any previous |
| 114 | * selection will be lost. The cursor is moved to the first character |
| 115 | * of the new selection. |
| 116 | * |
| 117 | * \a length The length of the selection, in number of characters |
| 118 | * |
| 119 | * \a pos The position of the first character of the selection |
| 120 | */ |
| 121 | void highlightWord(int length, int pos); |
| 122 | |
| 123 | /*! |
| 124 | * Allows to create a specific highlighter if reimplemented. |
| 125 | * |
| 126 | * This highlighter is set each time spell checking is toggled on by |
| 127 | * calling setCheckSpellingEnabled(), but can later be overridden by calling |
| 128 | * setHighlighter(). |
| 129 | * |
| 130 | * \sa setHighlighter() |
| 131 | * \sa highlighter() |
| 132 | */ |
| 133 | virtual void createHighlighter(); |
| 134 | |
| 135 | /*! |
| 136 | * Returns the current highlighter, which is 0 if spell checking is disabled. |
| 137 | * The default highlighter is the one created by createHighlighter(), but |
| 138 | * might be overridden by setHighlighter(). |
| 139 | * |
| 140 | * \sa setHighlighter() |
| 141 | * \sa createHighlighter() |
| 142 | */ |
| 143 | Sonnet::Highlighter *highlighter() const; |
| 144 | |
| 145 | /*! |
| 146 | * Sets a custom background spellcheck highlighter for this text edit. |
| 147 | * Normally, the highlighter returned by createHighlighter() will be |
| 148 | * used to detect and highlight incorrectly spelled words, but this |
| 149 | * function allows to set a custom highlighter. |
| 150 | * |
| 151 | * This has to be called after enabling spell checking with |
| 152 | * setCheckSpellingEnabled(), otherwise it has no effect. |
| 153 | * |
| 154 | * Ownership is transferred to the KTextEdit |
| 155 | * |
| 156 | * \a _highLighter is the spellcheck highlighter to use |
| 157 | * |
| 158 | * \sa highlighter() |
| 159 | * \sa createHighlighter() |
| 160 | */ |
| 161 | void setHighlighter(Sonnet::Highlighter *_highLighter); |
| 162 | |
| 163 | /*! |
| 164 | * Returns standard KTextEdit popupMenu |
| 165 | * \since 4.1 |
| 166 | */ |
| 167 | virtual QMenu *(); |
| 168 | |
| 169 | /*! |
| 170 | * Sets the find/replace action to the value of \a enabled. |
| 171 | * \since 4.1 |
| 172 | */ |
| 173 | void enableFindReplace(bool enabled); |
| 174 | |
| 175 | /*! |
| 176 | * Returns the spell checking language which was set by |
| 177 | * setSpellCheckingLanguage(), the spellcheck dialog or the spellcheck |
| 178 | * config dialog, or an empty string if that has never been called. |
| 179 | * \since 4.2 |
| 180 | */ |
| 181 | const QString &spellCheckingLanguage() const; |
| 182 | |
| 183 | /*! |
| 184 | * Sets the show tab action to the value of \a show. |
| 185 | * \since 4.10 |
| 186 | */ |
| 187 | void showTabAction(bool show); |
| 188 | |
| 189 | /*! |
| 190 | * Shows the auto-correct button if the value of \a show is true. |
| 191 | * \since 4.10 |
| 192 | */ |
| 193 | void showAutoCorrectButton(bool show); |
| 194 | |
| 195 | /*! |
| 196 | * \since 4.10 |
| 197 | * create a modal spellcheck dialogbox and spellCheckingFinished signal we sent when |
| 198 | * we finish spell checking or spellCheckingCanceled signal when we cancel spell checking |
| 199 | */ |
| 200 | void forceSpellChecking(); |
| 201 | |
| 202 | Q_SIGNALS: |
| 203 | /*! |
| 204 | * emit signal when we activate or not autospellchecking |
| 205 | * |
| 206 | * \since 4.1 |
| 207 | */ |
| 208 | void checkSpellingChanged(bool); |
| 209 | |
| 210 | /*! |
| 211 | * Signal sends when spell checking is finished/stopped/completed |
| 212 | * \since 4.1 |
| 213 | */ |
| 214 | void spellCheckStatus(const QString &); |
| 215 | |
| 216 | /*! |
| 217 | * Emitted when the user changes the language in the spellcheck dialog |
| 218 | * shown by checkSpelling() or when calling setSpellCheckingLanguage(). |
| 219 | * |
| 220 | * \a language the new language the user selected |
| 221 | * \since 4.1 |
| 222 | */ |
| 223 | void languageChanged(const QString &language); |
| 224 | |
| 225 | /*! |
| 226 | * Emitted before the context \a menu is displayed. |
| 227 | * |
| 228 | * The signal allows you to add your own entries into the |
| 229 | * the context menu that is created on demand. |
| 230 | * |
| 231 | * \note Do not store the pointer to the QMenu |
| 232 | * provided through since it is created and deleted |
| 233 | * on demand. |
| 234 | * |
| 235 | * \since 4.5 |
| 236 | */ |
| 237 | void (QMenu *); |
| 238 | |
| 239 | /*! |
| 240 | * This signal is emitted when the spell checker wants the user to decide |
| 241 | * if \a currentWord should be replaced with \a autoCorrectWord. |
| 242 | * |
| 243 | * \since 4.10 |
| 244 | */ |
| 245 | void spellCheckerAutoCorrect(const QString ¤tWord, const QString &autoCorrectWord); |
| 246 | |
| 247 | /*! |
| 248 | * signal spellCheckingFinished is sent when we finish spell check or we click on "Terminate" button in sonnet dialogbox |
| 249 | * \since 4.10 |
| 250 | */ |
| 251 | void spellCheckingFinished(); |
| 252 | |
| 253 | /*! |
| 254 | * signal spellCheckingCanceled is sent when we cancel spell checking. |
| 255 | * \since 4.10 |
| 256 | */ |
| 257 | void spellCheckingCanceled(); |
| 258 | |
| 259 | public Q_SLOTS: |
| 260 | |
| 261 | /*! |
| 262 | * Set the spell check \a language which will be used for highlighting spelling |
| 263 | * mistakes and for the spellcheck dialog. |
| 264 | * The languageChanged() signal will be emitted when the new language is |
| 265 | * different from the old one. |
| 266 | * |
| 267 | * \since 4.1 |
| 268 | */ |
| 269 | void setSpellCheckingLanguage(const QString &language); |
| 270 | |
| 271 | /*! |
| 272 | * Show a dialog to check the spelling. The spellCheckStatus() signal |
| 273 | * will be emitted when the spell checking dialog is closed. |
| 274 | */ |
| 275 | void checkSpelling(); |
| 276 | |
| 277 | /*! |
| 278 | * Opens a Sonnet::ConfigDialog for this text edit. |
| 279 | * The spellcheck language of the config dialog is set to the current spellcheck |
| 280 | * language of the textedit. If the user changes the language in that dialog, |
| 281 | * the languageChanged() signal is emitted. |
| 282 | * |
| 283 | * \a windowIcon the icon which is used for the titlebar of the spell dialog |
| 284 | * window. Can be empty, then no icon is set. |
| 285 | * |
| 286 | * \since 4.2 |
| 287 | */ |
| 288 | void showSpellConfigDialog(const QString &windowIcon = QString()); |
| 289 | |
| 290 | /*! |
| 291 | * Create replace dialogbox |
| 292 | * \since 4.1 |
| 293 | */ |
| 294 | void replace(); |
| 295 | |
| 296 | /*! |
| 297 | * Add custom spell checker \a decorator |
| 298 | * \since 5.11 |
| 299 | */ |
| 300 | void addTextDecorator(Sonnet::SpellCheckDecorator *decorator); |
| 301 | |
| 302 | /*! |
| 303 | * \brief clearDecorator clear the spellcheckerdecorator |
| 304 | * \since 5.11 |
| 305 | */ |
| 306 | void clearDecorator(); |
| 307 | |
| 308 | protected Q_SLOTS: |
| 309 | void slotDoReplace(); |
| 310 | void slotReplaceNext(); |
| 311 | void slotDoFind(); |
| 312 | void slotFind(); |
| 313 | void slotFindNext(); |
| 314 | void slotFindPrevious(); |
| 315 | void slotReplace(); |
| 316 | void slotSpeakText(); |
| 317 | |
| 318 | protected: |
| 319 | bool event(QEvent *) override; |
| 320 | |
| 321 | void keyPressEvent(QKeyEvent *) override; |
| 322 | |
| 323 | void focusInEvent(QFocusEvent *) override; |
| 324 | |
| 325 | /*! |
| 326 | * Deletes a word backwards from the current cursor position, |
| 327 | * if available. |
| 328 | */ |
| 329 | virtual void deleteWordBack(); |
| 330 | |
| 331 | /*! |
| 332 | * Deletes a word forwards from the current cursor position, |
| 333 | * if available. |
| 334 | */ |
| 335 | virtual void deleteWordForward(); |
| 336 | |
| 337 | void (QContextMenuEvent *) override; |
| 338 | |
| 339 | protected: |
| 340 | KTEXTWIDGETS_NO_EXPORT KTextEdit(KTextEditPrivate &dd, const QString &text, QWidget *parent); |
| 341 | KTEXTWIDGETS_NO_EXPORT KTextEdit(KTextEditPrivate &dd, QWidget *parent); |
| 342 | |
| 343 | protected: |
| 344 | std::unique_ptr<class KTextEditPrivate> const d_ptr; |
| 345 | |
| 346 | private: |
| 347 | Q_DECLARE_PRIVATE(KTextEdit) |
| 348 | }; |
| 349 | |
| 350 | #endif // KTEXTEDIT_H |
| 351 | |