summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qwidgettextcontrol.cpp
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2017-03-14 15:00:13 +0100
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2017-03-20 10:10:26 +0000
commit391e3aeef45efc937979b44c32147206e389a60b (patch)
tree428cae7c04863fa2fa605e9d83ed95b1c981dd73 /src/widgets/widgets/qwidgettextcontrol.cpp
parentac74abdf50f7047cf43b3577a70d0995e197659d (diff)
Fix char format of preedit text in empty text block
When a text block is empty, and we are adding preedit text to it, we need to merge the format of the preedit text with the current format of the cursor, otherwise we will use a default format and then suddenly switch to the proper one when the text is committed. The reason this becomes a bit complex is that there are no rules preventing someone from using several ime attributes to specify formats for isolated parts of the text, and no rules defining the order of such attributes. So even if the common case is one text format attribute for the entire string, we need to make sure we also handle the other cases gracefully, e.g. when we are setting different formats for different substrings and then providing these out of order. To make sure we have these corner cases covered, we also add a set of autotests. [ChangeLog][Qt Widgets][TextEdit] Fixed initial char format of input method text as it is in pre-edit mode. Task-number: QTBUG-59196 Change-Id: I1e37928e3bd1395fec1b5591908d4c69b84eb618 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/widgets/widgets/qwidgettextcontrol.cpp')
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp47
1 files changed, 45 insertions, 2 deletions
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index f5672bd87a..dacb4806ce 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2052,16 +2052,59 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
preeditCursor = a.start;
hideCursor = !a.length;
} else if (a.type == QInputMethodEvent::TextFormat) {
- QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+ QTextCharFormat f = cursor.charFormat();
+ f.merge(qvariant_cast<QTextFormat>(a.value).toCharFormat());
if (f.isValid()) {
QTextLayout::FormatRange o;
o.start = a.start + cursor.position() - block.position();
o.length = a.length;
o.format = f;
- overrides.append(o);
+
+ // Make sure list is sorted by start index
+ QVector<QTextLayout::FormatRange>::iterator it = overrides.end();
+ while (it != overrides.begin()) {
+ QVector<QTextLayout::FormatRange>::iterator previous = it - 1;
+ if (o.start >= previous->start) {
+ overrides.insert(it, o);
+ break;
+ }
+ it = previous;
+ }
+
+ if (it == overrides.begin())
+ overrides.prepend(o);
}
}
}
+
+ if (cursor.charFormat().isValid()) {
+ int start = cursor.position() - block.position();
+ int end = start + e->preeditString().length();
+
+ QVector<QTextLayout::FormatRange>::iterator it = overrides.begin();
+ while (it != overrides.end()) {
+ QTextLayout::FormatRange range = *it;
+ int rangeStart = range.start;
+ if (rangeStart > start) {
+ QTextLayout::FormatRange o;
+ o.start = start;
+ o.length = rangeStart - start;
+ o.format = cursor.charFormat();
+ it = overrides.insert(it, o) + 1;
+ }
+
+ ++it;
+ start = range.start + range.length;
+ }
+
+ if (start < end) {
+ QTextLayout::FormatRange o;
+ o.start = start;
+ o.length = end - start;
+ o.format = cursor.charFormat();
+ overrides.append(o);
+ }
+ }
layout->setFormats(overrides);
cursor.endEditBlock();