QtSpell  1.0.1
Spell checking for Qt text widgets
TextEditChecker_p.hpp
1 /* QtSpell - Spell checking for Qt text widgets.
2  * Copyright (c) 2014-2022 Sandro Mani
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef QTSPELL_TEXTEDITCHECKER_P_HPP
20 #define QTSPELL_TEXTEDITCHECKER_P_HPP
21 
22 #include "QtSpell.hpp"
23 #include "Checker_p.hpp"
24 
25 #include <QRegularExpression>
26 #include <QTextCursor>
27 
28 class QMenu;
29 class QTextDocument;
30 
31 namespace QtSpell {
32 
33 class TextEditChecker;
34 class TextEditProxy;
35 class UndoRedoStack;
36 
37 class TextEditCheckerPrivate : public CheckerPrivate
38 {
39 public:
40  TextEditCheckerPrivate();
41  virtual ~TextEditCheckerPrivate();
42 
43  void setTextEdit(TextEditProxy* newTextEdit);
44  bool noSpellingPropertySet(const QTextCursor& cursor) const;
45 
46  TextEditProxy* textEdit = nullptr;
47  QTextDocument* document = nullptr;
48  UndoRedoStack* undoRedoStack = nullptr;
49  bool undoRedoInProgress = false;
50  Qt::ContextMenuPolicy oldContextMenuPolicy;
51  int noSpellingProperty = -1;
52 
53  Q_DECLARE_PUBLIC(TextEditChecker)
54 };
55 
59 class TextCursor : public QTextCursor
60 {
61 public:
62  TextCursor()
63  : QTextCursor(), m_wordRegEx(QRegularExpression("^\\w$")) {}
64  TextCursor(QTextDocument* document)
65  : QTextCursor(document), m_wordRegEx(QRegularExpression("^\\w$")) {}
66  TextCursor(const QTextBlock& block)
67  : QTextCursor(block), m_wordRegEx(QRegularExpression("^\\w$")) {}
68  TextCursor(const QTextCursor& cursor)
69  : QTextCursor(cursor), m_wordRegEx(QRegularExpression("^\\w$")) {}
70 
76  QString nextChar(int num = 1) const;
77 
83  QString prevChar(int num = 1) const;
84 
90  void moveWordStart(MoveMode moveMode = MoveAnchor);
91 
97  void moveWordEnd(MoveMode moveMode = MoveAnchor);
98 
103  bool isInsideWord() const{
104  return nextChar().contains(m_wordRegEx) || prevChar().contains(m_wordRegEx);
105  }
106 
111  bool isWordChar(const QString& character) const{
112  return character.contains(m_wordRegEx);
113  }
114 
115 private:
116  QRegularExpression m_wordRegEx;
117 };
118 
120 
121 class TextEditProxy : public QObject {
122  Q_OBJECT
123 public:
124  TextEditProxy(QObject* parent = nullptr) : QObject(parent) {}
125  virtual QTextCursor textCursor() const = 0;
126  virtual QTextDocument* document() const = 0;
127  virtual QPoint mapToGlobal(const QPoint& pos) const = 0;
128  virtual QMenu* createStandardContextMenu() = 0;
129  virtual QTextCursor cursorForPosition(const QPoint& pos) const = 0;
130  virtual void setContextMenuPolicy(Qt::ContextMenuPolicy policy) = 0;
131  virtual void setTextCursor(const QTextCursor& cursor) = 0;
132  virtual Qt::ContextMenuPolicy contextMenuPolicy() const = 0;
133  virtual void installEventFilter(QObject* filterObj) = 0;
134  virtual void removeEventFilter(QObject* filterObj) = 0;
135  virtual void ensureCursorVisible() = 0;
136 
137 signals:
138  void customContextMenuRequested(const QPoint& pos);
139  void textChanged();
140  void editDestroyed();
141 };
142 
143 template<class T>
144 class TextEditProxyT : public TextEditProxy {
145 public:
146  TextEditProxyT(T* textEdit, QObject* parent = nullptr) : TextEditProxy(parent), m_textEdit(textEdit) {
147  connect(textEdit, &T::customContextMenuRequested, this, &TextEditProxy::customContextMenuRequested);
148  connect(textEdit, &T::textChanged, this, &TextEditProxy::textChanged);
149  connect(textEdit, &T::destroyed, this, &TextEditProxy::editDestroyed);
150  }
151  QTextCursor textCursor() const{ return m_textEdit->textCursor(); }
152  QTextDocument* document() const{ return m_textEdit->document(); }
153  QPoint mapToGlobal(const QPoint& pos) const{ return m_textEdit->mapToGlobal(pos); }
154  QMenu* createStandardContextMenu(){ return m_textEdit->createStandardContextMenu(); }
155  QTextCursor cursorForPosition(const QPoint& pos) const{ return m_textEdit->cursorForPosition(pos); }
156  void setContextMenuPolicy(Qt::ContextMenuPolicy policy){ m_textEdit->setContextMenuPolicy(policy); }
157  void setTextCursor(const QTextCursor& cursor){ m_textEdit->setTextCursor(cursor); }
158  Qt::ContextMenuPolicy contextMenuPolicy() const{ return m_textEdit->contextMenuPolicy(); }
159  void installEventFilter(QObject* filterObj){ m_textEdit->installEventFilter(filterObj); }
160  void removeEventFilter(QObject* filterObj){ m_textEdit->removeEventFilter(filterObj); }
161  void ensureCursorVisible() { m_textEdit->ensureCursorVisible(); }
162 
163 private:
164  T* m_textEdit = nullptr;
165 };
166 
167 } // QtSpell
168 
169 #endif // QTSPELL_TEXTEDITCHECKER_P_HPP
QString prevChar(int num=1) const
Retreive the num-th previous character.
bool isInsideWord() const
Returns whether the cursor is inside a word.
bool isWordChar(const QString &character) const
Returns whether the specified character is a word character.
QString nextChar(int num=1) const
Retreive the num-th next character.
QtSpell namespace.
Definition: Checker.cpp:77
void moveWordEnd(MoveMode moveMode=MoveAnchor)
Move the cursor to the end of the current word. Cursor must be inside a word. This method correctly h...
void moveWordStart(MoveMode moveMode=MoveAnchor)
Move the cursor to the start of the current word. Cursor must be inside a word. This method correctly...
An enhanced QTextCursor.