diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-09-13 11:56:52 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2017-09-13 11:58:09 +0200 |
commit | c1edda931d81f159e5c4be9f753153b621bdbad2 (patch) | |
tree | 813f713d8ab7d73f910dff8e2e8781506a01469c /framework/src/domain/documenthandler.cpp | |
parent | 152aff4c7e26c4eccf0168ae401dbcd13b54c796 (diff) | |
download | kube-c1edda931d81f159e5c4be9f753153b621bdbad2.tar.gz kube-c1edda931d81f159e5c4be9f753153b621bdbad2.zip |
Replaced the invisible char hack with a better solution
We now cache the format until the next char is inserted,
which seems to work fine, doesn't break selection and is overall much
cleaner.
Diffstat (limited to 'framework/src/domain/documenthandler.cpp')
-rw-r--r-- | framework/src/domain/documenthandler.cpp | 118 |
1 files changed, 42 insertions, 76 deletions
diff --git a/framework/src/domain/documenthandler.cpp b/framework/src/domain/documenthandler.cpp index 3589fc9f..d9a17e34 100644 --- a/framework/src/domain/documenthandler.cpp +++ b/framework/src/domain/documenthandler.cpp | |||
@@ -82,21 +82,15 @@ void DocumentHandler::setDocument(QQuickTextDocument *document) | |||
82 | connect(m_document->textDocument(), &QTextDocument::contentsChanged, this, [this] () { | 82 | connect(m_document->textDocument(), &QTextDocument::contentsChanged, this, [this] () { |
83 | emit textChanged(); | 83 | emit textChanged(); |
84 | }); | 84 | }); |
85 | connect(m_document->textDocument(), &QTextDocument::contentsChange, this, &DocumentHandler::contentsChange); | ||
85 | emit documentChanged(); | 86 | emit documentChanged(); |
86 | } | 87 | } |
87 | } | 88 | } |
88 | 89 | ||
89 | static QString stripInvisibleChars(const QString &s) | ||
90 | { | ||
91 | auto text = s; | ||
92 | text.replace("\u2063", ""); | ||
93 | return text; | ||
94 | } | ||
95 | |||
96 | QString DocumentHandler::plainText() const | 90 | QString DocumentHandler::plainText() const |
97 | { | 91 | { |
98 | if (m_document) { | 92 | if (m_document) { |
99 | return stripInvisibleChars(m_document->textDocument()->toPlainText()); | 93 | return m_document->textDocument()->toPlainText(); |
100 | } | 94 | } |
101 | return {}; | 95 | return {}; |
102 | } | 96 | } |
@@ -104,7 +98,7 @@ QString DocumentHandler::plainText() const | |||
104 | QString DocumentHandler::htmlText() const | 98 | QString DocumentHandler::htmlText() const |
105 | { | 99 | { |
106 | if (m_document) { | 100 | if (m_document) { |
107 | return stripInvisibleChars(m_document->textDocument()->toHtml()); | 101 | return m_document->textDocument()->toHtml(); |
108 | } | 102 | } |
109 | return {}; | 103 | return {}; |
110 | } | 104 | } |
@@ -117,25 +111,6 @@ int DocumentHandler::cursorPosition() const | |||
117 | void DocumentHandler::setCursorPosition(int position) | 111 | void DocumentHandler::setCursorPosition(int position) |
118 | { | 112 | { |
119 | if (position != m_cursorPosition) { | 113 | if (position != m_cursorPosition) { |
120 | //Skip over invisible char | ||
121 | if (m_cursorPosition < position) { | ||
122 | auto cursor = textCursor(); | ||
123 | if (!cursor.atEnd()) { | ||
124 | cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); | ||
125 | if (cursor.selectedText() == "\u2063") { | ||
126 | position++; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | if (m_cursorPosition > position) { | ||
131 | auto cursor = textCursor(); | ||
132 | if (!cursor.atStart()) { | ||
133 | cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); | ||
134 | if (cursor.selectedText() == "\u2063") { | ||
135 | position--; | ||
136 | } | ||
137 | } | ||
138 | } | ||
139 | m_cursorPosition = position; | 114 | m_cursorPosition = position; |
140 | reset(); | 115 | reset(); |
141 | emit cursorPositionChanged(); | 116 | emit cursorPositionChanged(); |
@@ -168,13 +143,21 @@ void DocumentHandler::setSelectionEnd(int position) | |||
168 | } | 143 | } |
169 | } | 144 | } |
170 | 145 | ||
171 | QString DocumentHandler::fontFamily() const | 146 | QTextCharFormat DocumentHandler::charFormat() const |
172 | { | 147 | { |
148 | if (m_cachedTextFormat) { | ||
149 | return *m_cachedTextFormat; | ||
150 | } | ||
173 | auto cursor = textCursor(); | 151 | auto cursor = textCursor(); |
174 | if (cursor.isNull()) { | 152 | if (cursor.isNull()) { |
175 | return QString(); | 153 | return {}; |
176 | } | 154 | } |
177 | return cursor.charFormat().font().family(); | 155 | return cursor.charFormat(); |
156 | } | ||
157 | |||
158 | QString DocumentHandler::fontFamily() const | ||
159 | { | ||
160 | return charFormat().font().family(); | ||
178 | } | 161 | } |
179 | 162 | ||
180 | void DocumentHandler::setFontFamily(const QString &family) | 163 | void DocumentHandler::setFontFamily(const QString &family) |
@@ -187,11 +170,7 @@ void DocumentHandler::setFontFamily(const QString &family) | |||
187 | 170 | ||
188 | QColor DocumentHandler::textColor() const | 171 | QColor DocumentHandler::textColor() const |
189 | { | 172 | { |
190 | auto cursor = textCursor(); | 173 | return charFormat().foreground().color(); |
191 | if (cursor.isNull()) { | ||
192 | return QColor(Qt::black); | ||
193 | } | ||
194 | return cursor.charFormat().foreground().color(); | ||
195 | } | 174 | } |
196 | 175 | ||
197 | void DocumentHandler::setTextColor(const QColor &color) | 176 | void DocumentHandler::setTextColor(const QColor &color) |
@@ -222,11 +201,7 @@ void DocumentHandler::setAlignment(Qt::Alignment alignment) | |||
222 | 201 | ||
223 | bool DocumentHandler::bold() const | 202 | bool DocumentHandler::bold() const |
224 | { | 203 | { |
225 | auto cursor = textCursor(); | 204 | return charFormat().fontWeight() == QFont::Bold; |
226 | if (cursor.isNull()) { | ||
227 | return false; | ||
228 | } | ||
229 | return cursor.charFormat().fontWeight() == QFont::Bold; | ||
230 | } | 205 | } |
231 | 206 | ||
232 | void DocumentHandler::setBold(bool bold) | 207 | void DocumentHandler::setBold(bool bold) |
@@ -239,11 +214,7 @@ void DocumentHandler::setBold(bool bold) | |||
239 | 214 | ||
240 | bool DocumentHandler::italic() const | 215 | bool DocumentHandler::italic() const |
241 | { | 216 | { |
242 | auto cursor = textCursor(); | 217 | return charFormat().fontItalic(); |
243 | if (cursor.isNull()) { | ||
244 | return false; | ||
245 | } | ||
246 | return cursor.charFormat().fontItalic(); | ||
247 | } | 218 | } |
248 | 219 | ||
249 | void DocumentHandler::setItalic(bool italic) | 220 | void DocumentHandler::setItalic(bool italic) |
@@ -256,11 +227,7 @@ void DocumentHandler::setItalic(bool italic) | |||
256 | 227 | ||
257 | bool DocumentHandler::underline() const | 228 | bool DocumentHandler::underline() const |
258 | { | 229 | { |
259 | auto cursor = textCursor(); | 230 | return charFormat().fontUnderline(); |
260 | if (cursor.isNull()) { | ||
261 | return false; | ||
262 | } | ||
263 | return cursor.charFormat().fontUnderline(); | ||
264 | } | 231 | } |
265 | 232 | ||
266 | void DocumentHandler::setUnderline(bool underline) | 233 | void DocumentHandler::setUnderline(bool underline) |
@@ -273,11 +240,7 @@ void DocumentHandler::setUnderline(bool underline) | |||
273 | 240 | ||
274 | int DocumentHandler::fontSize() const | 241 | int DocumentHandler::fontSize() const |
275 | { | 242 | { |
276 | QTextCursor cursor = textCursor(); | 243 | return charFormat().font().pointSize(); |
277 | if (cursor.isNull()) | ||
278 | return 0; | ||
279 | QTextCharFormat format = cursor.charFormat(); | ||
280 | return format.font().pointSize(); | ||
281 | } | 244 | } |
282 | 245 | ||
283 | void DocumentHandler::setFontSize(int size) | 246 | void DocumentHandler::setFontSize(int size) |
@@ -285,14 +248,7 @@ void DocumentHandler::setFontSize(int size) | |||
285 | if (size <= 0) | 248 | if (size <= 0) |
286 | return; | 249 | return; |
287 | 250 | ||
288 | QTextCursor cursor = textCursor(); | 251 | if (charFormat().property(QTextFormat::FontPointSize).toInt() == size) |
289 | if (cursor.isNull()) | ||
290 | return; | ||
291 | |||
292 | if (!cursor.hasSelection()) | ||
293 | cursor.select(QTextCursor::WordUnderCursor); | ||
294 | |||
295 | if (cursor.charFormat().property(QTextFormat::FontPointSize).toInt() == size) | ||
296 | return; | 252 | return; |
297 | 253 | ||
298 | QTextCharFormat format; | 254 | QTextCharFormat format; |
@@ -335,21 +291,31 @@ QTextDocument *DocumentHandler::textDocument() const | |||
335 | return m_document->textDocument(); | 291 | return m_document->textDocument(); |
336 | } | 292 | } |
337 | 293 | ||
294 | void DocumentHandler::contentsChange(int position, int charsRemoved, int charsAdded) | ||
295 | { | ||
296 | if (m_cachedTextFormat) { | ||
297 | if (charsAdded) { | ||
298 | //Apply cached formatting | ||
299 | QTextCursor cursor = textCursor(); | ||
300 | cursor.setPosition(position + charsAdded, QTextCursor::KeepAnchor); | ||
301 | cursor.mergeCharFormat(*m_cachedTextFormat); | ||
302 | } | ||
303 | m_cachedTextFormat = {}; | ||
304 | } | ||
305 | } | ||
306 | |||
338 | void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) | 307 | void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) |
339 | { | 308 | { |
340 | QTextCursor cursor = textCursor(); | 309 | QTextCursor cursor = textCursor(); |
341 | 310 | ||
342 | cursor.mergeCharFormat(format); | 311 | if (cursor.hasSelection()) { |
343 | 312 | cursor.mergeCharFormat(format); | |
344 | /* | 313 | } else { |
345 | * FIXME: This is a fantastic hack to change the text format on the TextArea's internal cursor. | 314 | if (m_cachedTextFormat) { |
346 | * The TextArea internally listens for the contentChanged signal of the document and then simply | 315 | m_cachedTextFormat->merge(format); |
347 | * copies the format with QTextCursor::charFormat. This does of course not work without any text in | 316 | } else { |
348 | * said format. The Qt Example solution to the problem was to select the current word, which is both not | 317 | //If we have nothing to format right now we cache the result until the next char is inserted. |
349 | * the behaviour that we want, nor does it work if you don't currently have a word under the cursor. | 318 | m_cachedTextFormat = QSharedPointer<QTextCharFormat>::create(format); |
350 | * We therefore have to insert an invisible character to transport the format, which we have to clear out in the end again. | 319 | } |
351 | */ | ||
352 | if (!cursor.hasSelection()) { | ||
353 | cursor.insertText("\u2063"); | ||
354 | } | 320 | } |
355 | } | 321 | } |