summaryrefslogtreecommitdiffstats
path: root/framework/src
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2017-09-13 11:56:52 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2017-09-13 11:58:09 +0200
commitc1edda931d81f159e5c4be9f753153b621bdbad2 (patch)
tree813f713d8ab7d73f910dff8e2e8781506a01469c /framework/src
parent152aff4c7e26c4eccf0168ae401dbcd13b54c796 (diff)
downloadkube-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')
-rw-r--r--framework/src/domain/documenthandler.cpp118
-rw-r--r--framework/src/domain/documenthandler.h5
2 files changed, 47 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
89static QString stripInvisibleChars(const QString &s)
90{
91 auto text = s;
92 text.replace("\u2063", "");
93 return text;
94}
95
96QString DocumentHandler::plainText() const 90QString 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
104QString DocumentHandler::htmlText() const 98QString 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
117void DocumentHandler::setCursorPosition(int position) 111void 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
171QString DocumentHandler::fontFamily() const 146QTextCharFormat 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
158QString DocumentHandler::fontFamily() const
159{
160 return charFormat().font().family();
178} 161}
179 162
180void DocumentHandler::setFontFamily(const QString &family) 163void DocumentHandler::setFontFamily(const QString &family)
@@ -187,11 +170,7 @@ void DocumentHandler::setFontFamily(const QString &family)
187 170
188QColor DocumentHandler::textColor() const 171QColor 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
197void DocumentHandler::setTextColor(const QColor &color) 176void DocumentHandler::setTextColor(const QColor &color)
@@ -222,11 +201,7 @@ void DocumentHandler::setAlignment(Qt::Alignment alignment)
222 201
223bool DocumentHandler::bold() const 202bool 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
232void DocumentHandler::setBold(bool bold) 207void DocumentHandler::setBold(bool bold)
@@ -239,11 +214,7 @@ void DocumentHandler::setBold(bool bold)
239 214
240bool DocumentHandler::italic() const 215bool 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
249void DocumentHandler::setItalic(bool italic) 220void DocumentHandler::setItalic(bool italic)
@@ -256,11 +227,7 @@ void DocumentHandler::setItalic(bool italic)
256 227
257bool DocumentHandler::underline() const 228bool 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
266void DocumentHandler::setUnderline(bool underline) 233void DocumentHandler::setUnderline(bool underline)
@@ -273,11 +240,7 @@ void DocumentHandler::setUnderline(bool underline)
273 240
274int DocumentHandler::fontSize() const 241int 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
283void DocumentHandler::setFontSize(int size) 246void 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
294void 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
338void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) 307void 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}
diff --git a/framework/src/domain/documenthandler.h b/framework/src/domain/documenthandler.h
index 0c1bf971..8be3ba16 100644
--- a/framework/src/domain/documenthandler.h
+++ b/framework/src/domain/documenthandler.h
@@ -140,8 +140,12 @@ Q_SIGNALS:
140 140
141 void textChanged(); 141 void textChanged();
142 142
143private Q_SLOTS:
144 void contentsChange(int position, int charsRemoved, int charsAdded);
145
143private: 146private:
144 void reset(); 147 void reset();
148 QTextCharFormat charFormat() const;
145 QTextCursor textCursor() const; 149 QTextCursor textCursor() const;
146 QTextDocument *textDocument() const; 150 QTextDocument *textDocument() const;
147 void mergeFormatOnWordOrSelection(const QTextCharFormat &format); 151 void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
@@ -151,6 +155,7 @@ private:
151 int m_cursorPosition; 155 int m_cursorPosition;
152 int m_selectionStart; 156 int m_selectionStart;
153 int m_selectionEnd; 157 int m_selectionEnd;
158 QSharedPointer<QTextCharFormat> m_cachedTextFormat;
154}; 159};
155 160
156#endif // DOCUMENTHANDLER_H 161#endif // DOCUMENTHANDLER_H