summaryrefslogtreecommitdiffstats
path: root/framework/src/domain/textdocumenthandler.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-10-06 11:43:33 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-10-06 11:46:58 +0200
commit737770bfa4bb91ed96412d18d6490db3450bcb1c (patch)
tree9b4bd7a6252c687b4cb5ac3d91ebe786e7891377 /framework/src/domain/textdocumenthandler.cpp
parent41e3f3544f3ec7ae3c14f18010005e3e55c003e7 (diff)
downloadkube-737770bfa4bb91ed96412d18d6490db3450bcb1c.tar.gz
kube-737770bfa4bb91ed96412d18d6490db3450bcb1c.zip
TextDocumentHandler to deal with HTML formatting
Diffstat (limited to 'framework/src/domain/textdocumenthandler.cpp')
-rw-r--r--framework/src/domain/textdocumenthandler.cpp280
1 files changed, 280 insertions, 0 deletions
diff --git a/framework/src/domain/textdocumenthandler.cpp b/framework/src/domain/textdocumenthandler.cpp
new file mode 100644
index 00000000..729d39e8
--- /dev/null
+++ b/framework/src/domain/textdocumenthandler.cpp
@@ -0,0 +1,280 @@
1/*
2 Copyright (c) 2017 Christian Mollekopf <mollekopf@kolabsystems.com>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19#include "textdocumenthandler.h"
20
21#include <QQuickTextDocument>
22#include <QTextCharFormat>
23#include <QTextDocument>
24#include <QDebug>
25
26TextDocumentHandler::TextDocumentHandler(QObject *parent)
27 : QObject(parent),
28 mDocument(nullptr),
29 mCursorPosition(-1),
30 mSelectionStart(0),
31 mSelectionEnd(0)
32{
33}
34
35QQuickTextDocument *TextDocumentHandler::document() const
36{
37 return mDocument;
38}
39
40void TextDocumentHandler::setDocument(QQuickTextDocument *document)
41{
42 if (document != mDocument) {
43 mDocument = document;
44 connect(mDocument->textDocument(), &QTextDocument::contentsChanged, this, [this] () {
45 emit textChanged();
46 });
47 connect(mDocument->textDocument(), &QTextDocument::contentsChange, this, &TextDocumentHandler::contentsChange);
48 emit documentChanged();
49 }
50}
51
52QString TextDocumentHandler::plainText() const
53{
54 if (mDocument) {
55 return mDocument->textDocument()->toPlainText();
56 }
57 return {};
58}
59
60QString TextDocumentHandler::htmlText() const
61{
62 if (mDocument) {
63 return mDocument->textDocument()->toHtml();
64 }
65 return {};
66}
67
68int TextDocumentHandler::cursorPosition() const
69{
70 return mCursorPosition;
71}
72
73void TextDocumentHandler::setCursorPosition(int position)
74{
75 if (position != mCursorPosition) {
76 mCursorPosition = position;
77 reset();
78 emit cursorPositionChanged();
79 }
80}
81
82int TextDocumentHandler::selectionStart() const
83{
84 return mSelectionStart;
85}
86
87void TextDocumentHandler::setSelectionStart(int position)
88{
89 if (position != mSelectionStart) {
90 mSelectionStart = position;
91 emit selectionStartChanged();
92 }
93}
94
95int TextDocumentHandler::selectionEnd() const
96{
97 return mSelectionEnd;
98}
99
100void TextDocumentHandler::setSelectionEnd(int position)
101{
102 if (position != mSelectionEnd) {
103 mSelectionEnd = position;
104 emit selectionEndChanged();
105 }
106}
107
108QTextCharFormat TextDocumentHandler::charFormat() const
109{
110 if (mCachedTextFormat) {
111 return *mCachedTextFormat;
112 }
113 auto cursor = textCursor();
114 if (cursor.isNull()) {
115 return {};
116 }
117 return cursor.charFormat();
118}
119
120QString TextDocumentHandler::fontFamily() const
121{
122 return charFormat().font().family();
123}
124
125void TextDocumentHandler::setFontFamily(const QString &family)
126{
127 QTextCharFormat format;
128 format.setFontFamily(family);
129 mergeFormatOnWordOrSelection(format);
130 emit fontFamilyChanged();
131}
132
133QColor TextDocumentHandler::textColor() const
134{
135 return charFormat().foreground().color();
136}
137
138void TextDocumentHandler::setTextColor(const QColor &color)
139{
140 QTextCharFormat format;
141 format.setForeground(QBrush(color));
142 mergeFormatOnWordOrSelection(format);
143 emit textColorChanged();
144}
145
146Qt::Alignment TextDocumentHandler::alignment() const
147{
148 auto cursor = textCursor();
149 if (cursor.isNull()) {
150 return Qt::AlignLeft;
151 }
152 return cursor.blockFormat().alignment();
153}
154
155void TextDocumentHandler::setAlignment(Qt::Alignment alignment)
156{
157 QTextBlockFormat format;
158 format.setAlignment(alignment);
159 QTextCursor cursor = textCursor();
160 cursor.mergeBlockFormat(format);
161 emit alignmentChanged();
162}
163
164bool TextDocumentHandler::bold() const
165{
166 return charFormat().fontWeight() == QFont::Bold;
167}
168
169void TextDocumentHandler::setBold(bool bold)
170{
171 QTextCharFormat format;
172 format.setFontWeight(bold ? QFont::Bold : QFont::Normal);
173 mergeFormatOnWordOrSelection(format);
174 emit boldChanged();
175}
176
177bool TextDocumentHandler::italic() const
178{
179 return charFormat().fontItalic();
180}
181
182void TextDocumentHandler::setItalic(bool italic)
183{
184 QTextCharFormat format;
185 format.setFontItalic(italic);
186 mergeFormatOnWordOrSelection(format);
187 emit italicChanged();
188}
189
190bool TextDocumentHandler::underline() const
191{
192 return charFormat().fontUnderline();
193}
194
195void TextDocumentHandler::setUnderline(bool underline)
196{
197 QTextCharFormat format;
198 format.setFontUnderline(underline);
199 mergeFormatOnWordOrSelection(format);
200 emit underlineChanged();
201}
202
203int TextDocumentHandler::fontSize() const
204{
205 return charFormat().font().pointSize();
206}
207
208void TextDocumentHandler::setFontSize(int size)
209{
210 if (size <= 0)
211 return;
212
213 if (charFormat().property(QTextFormat::FontPointSize).toInt() == size)
214 return;
215
216 QTextCharFormat format;
217 format.setFontPointSize(size);
218 mergeFormatOnWordOrSelection(format);
219 emit fontSizeChanged();
220}
221
222void TextDocumentHandler::reset()
223{
224 emit fontFamilyChanged();
225 emit alignmentChanged();
226 emit boldChanged();
227 emit italicChanged();
228 emit underlineChanged();
229 emit fontSizeChanged();
230 emit textColorChanged();
231}
232
233QTextCursor TextDocumentHandler::textCursor() const
234{
235 if (mDocument) {
236 if (QTextDocument *doc = mDocument->textDocument()) {
237 QTextCursor cursor = QTextCursor(doc);
238 if (mSelectionStart != mSelectionEnd) {
239 cursor.setPosition(mSelectionStart);
240 cursor.setPosition(mSelectionEnd, QTextCursor::KeepAnchor);
241 } else {
242 cursor.setPosition(mCursorPosition);
243 }
244 return cursor;
245 }
246 }
247 return QTextCursor();
248}
249
250void TextDocumentHandler::contentsChange(int position, int charsRemoved, int charsAdded)
251{
252 Q_UNUSED(charsRemoved)
253 if (mCachedTextFormat) {
254 if (charsAdded) {
255 //Apply cached formatting
256 QTextCursor cursor = textCursor();
257 cursor.setPosition(position + charsAdded, QTextCursor::KeepAnchor);
258 cursor.mergeCharFormat(*mCachedTextFormat);
259 //This is somehow necessary, otherwise space can break in the editor.
260 cursor.setPosition(position + charsAdded, QTextCursor::MoveAnchor);
261 }
262 mCachedTextFormat = {};
263 }
264}
265
266void TextDocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
267{
268 QTextCursor cursor = textCursor();
269
270 if (cursor.hasSelection()) {
271 cursor.mergeCharFormat(format);
272 } else {
273 if (mCachedTextFormat) {
274 mCachedTextFormat->merge(format);
275 } else {
276 //If we have nothing to format right now we cache the result until the next char is inserted.
277 mCachedTextFormat = QSharedPointer<QTextCharFormat>::create(format);
278 }
279 }
280}