File indexing completed on 2024-05-05 16:18:44

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2002 Carsten Pfeiffer <pfeiffer@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KTEXTEDIT_H
0009 #define KTEXTEDIT_H
0010 
0011 #include "ktextwidgets_export.h"
0012 
0013 #include <QTextEdit>
0014 #include <memory>
0015 #include <sonnet/highlighter.h>
0016 
0017 namespace Sonnet
0018 {
0019 class SpellCheckDecorator;
0020 }
0021 
0022 class KTextEditPrivate;
0023 
0024 /**
0025  * @class KTextEdit ktextedit.h <KTextEdit>
0026  *
0027  * @short A KDE'ified QTextEdit
0028  *
0029  * This is just a little subclass of QTextEdit, implementing
0030  * some standard KDE features, like cursor auto-hiding, configurable
0031  * wheelscrolling (fast-scroll or zoom), spell checking and deleting of entire
0032  * words with Ctrl-Backspace or Ctrl-Delete.
0033  *
0034  * This text edit provides two ways of spell checking: background checking,
0035  * which will mark incorrectly spelled words red, and a spell check dialog,
0036  * which lets the user check and correct all incorrectly spelled words.
0037  *
0038  * Basic rule: whenever you want to use QTextEdit, use KTextEdit!
0039  *
0040  * \image html ktextedit.png "KTextEdit Widget"
0041  *
0042  * @see QTextEdit
0043  * @author Carsten Pfeiffer <pfeiffer@kde.org>
0044  */
0045 class KTEXTWIDGETS_EXPORT KTextEdit : public QTextEdit // krazy:exclude=qclasses
0046 {
0047     Q_OBJECT
0048 #if KTEXTWIDGETS_BUILD_DEPRECATED_SINCE(5, 0)
0049     Q_PROPERTY(QString clickMessage READ clickMessage WRITE setClickMessage)
0050 #endif
0051     Q_PROPERTY(bool checkSpellingEnabled READ checkSpellingEnabled WRITE setCheckSpellingEnabled)
0052     Q_PROPERTY(QString spellCheckingLanguage READ spellCheckingLanguage WRITE setSpellCheckingLanguage)
0053 
0054 public:
0055     /**
0056      * Constructs a KTextEdit object. See QTextEdit::QTextEdit
0057      * for details.
0058      */
0059     explicit KTextEdit(const QString &text, QWidget *parent = nullptr);
0060 
0061     /**
0062      * Constructs a KTextEdit object. See QTextEdit::QTextEdit
0063      * for details.
0064      */
0065     explicit KTextEdit(QWidget *parent = nullptr);
0066 
0067     /**
0068      * Destroys the KTextEdit object.
0069      */
0070     ~KTextEdit() override;
0071 
0072     /**
0073      * Reimplemented to set a proper "deactivated" background color.
0074      */
0075     virtual void setReadOnly(bool readOnly);
0076 
0077     /**
0078      * Turns background spell checking for this text edit on or off.
0079      * Note that spell checking is only available in read-writable KTextEdits.
0080      *
0081      * Enabling spell checking will set back the current highlighter to the one
0082      * returned by createHighlighter().
0083      *
0084      * @see checkSpellingEnabled()
0085      * @see isReadOnly()
0086      * @see setReadOnly()
0087      */
0088     virtual void setCheckSpellingEnabled(bool check);
0089 
0090     /**
0091      * Returns true if background spell checking is enabled for this text edit.
0092      * Note that it even returns true if this is a read-only KTextEdit,
0093      * where spell checking is actually disabled.
0094      * By default spell checking is disabled.
0095      *
0096      * @see setCheckSpellingEnabled()
0097      */
0098     virtual bool checkSpellingEnabled() const;
0099 
0100     /**
0101      * Returns true if the given paragraph or block should be spellcheck.
0102      * For example, a mail client does not want to check quoted text, and
0103      * would return false here (by checking whether the block starts with a
0104      * quote sign).
0105      *
0106      * Always returns true by default.
0107      *
0108      */
0109     virtual bool shouldBlockBeSpellChecked(const QString &block) const;
0110 
0111     /**
0112      * Selects the characters at the specified position. Any previous
0113      * selection will be lost. The cursor is moved to the first character
0114      * of the new selection.
0115      *
0116      * @param length The length of the selection, in number of characters
0117      * @param pos The position of the first character of the selection
0118      */
0119     void highlightWord(int length, int pos);
0120 
0121     /**
0122      * Allows to create a specific highlighter if reimplemented.
0123      *
0124      * By default, it creates a normal highlighter, based on the config
0125      * file given to setSpellCheckingConfigFileName().
0126      *
0127      * This highlighter is set each time spell checking is toggled on by
0128      * calling setCheckSpellingEnabled(), but can later be overridden by calling
0129      * setHighlighter().
0130      *
0131      * @see setHighlighter()
0132      * @see highlighter()
0133      * @see setSpellCheckingConfigFileName()
0134      */
0135     virtual void createHighlighter();
0136 
0137     /**
0138      * Returns the current highlighter, which is 0 if spell checking is disabled.
0139      * The default highlighter is the one created by createHighlighter(), but
0140      * might be overridden by setHighlighter().
0141      *
0142      * @see setHighlighter()
0143      * @see createHighlighter()
0144      */
0145     Sonnet::Highlighter *highlighter() const;
0146 
0147     /**
0148      * Sets a custom background spell highlighter for this text edit.
0149      * Normally, the highlighter returned by createHighlighter() will be
0150      * used to detect and highlight incorrectly spelled words, but this
0151      * function allows to set a custom highlighter.
0152      *
0153      * This has to be called after enabling spell checking with
0154      * setCheckSpellingEnabled(), otherwise it has no effect.
0155      *
0156      * Ownership is transferred to the KTextEdit
0157      *
0158      * @see highlighter()
0159      * @see createHighlighter()
0160      * @param highLighter the new highlighter which will be used now
0161      */
0162     void setHighlighter(Sonnet::Highlighter *_highLighter);
0163 
0164     /**
0165      * Return standard KTextEdit popupMenu
0166      * @since 4.1
0167      */
0168     virtual QMenu *mousePopupMenu();
0169 
0170     /**
0171      * Enable find replace action.
0172      * @since 4.1
0173      */
0174     void enableFindReplace(bool enabled);
0175 
0176     /**
0177      * @return the spell checking language which was set by
0178      *         setSpellCheckingLanguage(), the spellcheck dialog or the spellcheck
0179      *         config dialog, or an empty string if that has never been called.
0180      * @since 4.2
0181      */
0182     const QString &spellCheckingLanguage() const;
0183 
0184 #if KTEXTWIDGETS_ENABLE_DEPRECATED_SINCE(5, 0)
0185     /**
0186      * This makes the text edit display a grayed-out hinting text as long as
0187      * the user didn't enter any text. It is often used as indication about
0188      * the purpose of the text edit.
0189      * @deprecated since 5.0, use QTextEdit::setPlaceholderText instead
0190      */
0191     KTEXTWIDGETS_DEPRECATED_VERSION(5, 0, "Use QTextEdit::setPlaceholderText(const QString&)")
0192     inline void setClickMessage(const QString &msg)
0193     {
0194         setPlaceholderText(msg);
0195     }
0196 #endif
0197 
0198 #if KTEXTWIDGETS_ENABLE_DEPRECATED_SINCE(5, 0)
0199     /**
0200      * @return the message set with setClickMessage
0201      * @deprecated since 5.0, use QTextEdit::placeholderText instead
0202      */
0203     KTEXTWIDGETS_DEPRECATED_VERSION(5, 0, "Use QTextEdit::placeholderText()")
0204     inline QString clickMessage() const
0205     {
0206         return placeholderText();
0207     }
0208 #endif
0209 
0210     /**
0211      * @since 4.10
0212      */
0213     void showTabAction(bool show);
0214 
0215     /**
0216      * @since 4.10
0217      */
0218     void showAutoCorrectButton(bool show);
0219 
0220     /**
0221      * @since 4.10
0222      * create a modal spellcheck dialogbox and spellCheckingFinished signal we sent when
0223      * we finish spell checking or spellCheckingCanceled signal when we cancel spell checking
0224      */
0225     void forceSpellChecking();
0226 
0227 Q_SIGNALS:
0228     /**
0229      * emit signal when we activate or not autospellchecking
0230      *
0231      * @since 4.1
0232      */
0233     void checkSpellingChanged(bool);
0234 
0235     /**
0236      * Signal sends when spell checking is finished/stopped/completed
0237      * @since 4.1
0238      */
0239     void spellCheckStatus(const QString &);
0240 
0241     /**
0242      * Emitted when the user changes the language in the spellcheck dialog
0243      * shown by checkSpelling() or when calling setSpellCheckingLanguage().
0244      *
0245      * @param language the new language the user selected
0246      * @since 4.1
0247      */
0248     void languageChanged(const QString &language);
0249 
0250     /**
0251      * Emitted before the context menu is displayed.
0252      *
0253      * The signal allows you to add your own entries into the
0254      * the context menu that is created on demand.
0255      *
0256      * NOTE: Do not store the pointer to the QMenu
0257      * provided through since it is created and deleted
0258      * on demand.
0259      *
0260      * @param p the context menu about to be displayed
0261      * @since 4.5
0262      */
0263     void aboutToShowContextMenu(QMenu *menu);
0264 
0265     /**
0266      * @since 4.10
0267      */
0268     void spellCheckerAutoCorrect(const QString &currentWord, const QString &autoCorrectWord);
0269 
0270     /**
0271      * signal spellCheckingFinished is sent when we finish spell check or we click on "Terminate" button in sonnet dialogbox
0272      * @since 4.10
0273      */
0274     void spellCheckingFinished();
0275 
0276     /**
0277      * signal spellCheckingCanceled is sent when we cancel spell checking.
0278      * @since 4.10
0279      */
0280     void spellCheckingCanceled();
0281 
0282 public Q_SLOTS:
0283 
0284     /**
0285      * Set the spell check language which will be used for highlighting spelling
0286      * mistakes and for the spellcheck dialog.
0287      * The languageChanged() signal will be emitted when the new language is
0288      * different from the old one.
0289      *
0290      * @since 4.1
0291      */
0292     void setSpellCheckingLanguage(const QString &language);
0293 
0294     /**
0295      * Show a dialog to check the spelling. The spellCheckStatus() signal
0296      * will be emitted when the spell checking dialog is closed.
0297      */
0298     void checkSpelling();
0299 
0300     /**
0301      * Opens a Sonnet::ConfigDialog for this text edit.
0302      * The spellcheck language of the config dialog is set to the current spellcheck
0303      * language of the textedit. If the user changes the language in that dialog,
0304      * the languageChanged() signal is emitted.
0305      *
0306      * @param configFileName The file which is used to store and load the config
0307      *                       settings
0308      * @param windowIcon the icon which is used for the titlebar of the spell dialog
0309      *                   window. Can be empty, then no icon is set.
0310      *
0311      * @since 4.2
0312      */
0313     void showSpellConfigDialog(const QString &windowIcon = QString());
0314 
0315     /**
0316      * Create replace dialogbox
0317      * @since 4.1
0318      */
0319     void replace();
0320 
0321     /**
0322      * Add custom spell checker decorator
0323      * @since 5.11
0324      */
0325     void addTextDecorator(Sonnet::SpellCheckDecorator *decorator);
0326 
0327     /**
0328      * @brief clearDecorator clear the spellcheckerdecorator
0329      * @since 5.11
0330      */
0331     void clearDecorator();
0332 
0333 protected Q_SLOTS:
0334     /**
0335      * @since 4.1
0336      */
0337     void slotDoReplace();
0338     void slotReplaceNext();
0339     void slotDoFind();
0340     void slotFind();
0341     void slotFindNext();
0342     /**
0343      * @since 5.11
0344      */
0345     void slotFindPrevious();
0346     void slotReplace();
0347     /**
0348      * @since 4.3
0349      */
0350     void slotSpeakText();
0351 
0352 protected:
0353     /**
0354      * Reimplemented to catch "delete word" shortcut events.
0355      */
0356     bool event(QEvent *) override;
0357 
0358     /**
0359      * Reimplemented for internal reasons
0360      */
0361     void keyPressEvent(QKeyEvent *) override;
0362 
0363     /**
0364      * Reimplemented to instantiate a KDictSpellingHighlighter, if
0365      * spellchecking is enabled.
0366      */
0367     void focusInEvent(QFocusEvent *) override;
0368 
0369     /**
0370      * Deletes a word backwards from the current cursor position,
0371      * if available.
0372      */
0373     virtual void deleteWordBack();
0374 
0375     /**
0376      * Deletes a word forwards from the current cursor position,
0377      * if available.
0378      */
0379     virtual void deleteWordForward();
0380 
0381     /**
0382      * Reimplemented from QTextEdit to add spelling related items
0383      * when appropriate.
0384      */
0385     void contextMenuEvent(QContextMenuEvent *) override;
0386 
0387 protected:
0388     KTEXTWIDGETS_NO_EXPORT KTextEdit(KTextEditPrivate &dd, const QString &text, QWidget *parent);
0389     KTEXTWIDGETS_NO_EXPORT KTextEdit(KTextEditPrivate &dd, QWidget *parent);
0390 
0391 private:
0392     friend class KRichTextEdit;
0393     friend class KRichTextWidget;
0394     Q_DECLARE_PRIVATE_D(d, KTextEdit)
0395     std::unique_ptr<class KTextEditPrivate> const d;
0396     // KF6 TODO: change private d to protected d_ptr, use normal Q_DECLARE_PRIVATE, remove friend
0397 };
0398 
0399 #endif // KTEXTEDIT_H