Merge TextFormat attributes for identical ranges in QInputMethodEvents
IBus can hand us multiple attributes for different formatting properties of the same text range for events. The IBus input method plugin used to convert these straight into multiple QInputMethodEvent::Attributes, each with their own QTextCharFormat instance. According to the QInputMethodEvent documentation, behavior with multiple TextFormat attributes for the same text range is undefined. In at least one known user, KDE's Kate text editor, it causes invisible text for pre-edit text events as the QTextCharFormats are applied in turn with partially default-constructed foreground/background brushes: https://bugs.kde.org/show_bug.cgi?id=339467 This patch makes an effort to merge formatting information for identical text ranges into a single QTextCharFomat, while otherwise preserving existing behavior (attribute order is unchanged and attributes deseria- lized from D-Bus as having invalid QTextFormats remain untouched). No attempt is made to cope with overlapping text ranges. Segmenting into smaller ranges and merging for the overlaps would be conceivable, but until a case of an input method creating events with overlapping ranges is known seems not worth the effort. It's worth noting that the IBus input method plugin for Qt 4 also attempts to merge formatting information into a single QTextCharFormat, but with a distinct implementation from this one. Change-Id: Ie3dc38b353724ffb7b5f2d7f316393027373baf2 Task-number: 41640 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
parent
79f832594d
commit
c493546a0a
@ -32,7 +32,6 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qibustypes.h"
|
||||
#include <qtextformat.h>
|
||||
#include <QtDBus>
|
||||
#include <QHash>
|
||||
|
||||
@ -134,7 +133,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, QIBusAttribute &a
|
||||
return argument;
|
||||
}
|
||||
|
||||
QTextFormat QIBusAttribute::format() const
|
||||
QTextCharFormat QIBusAttribute::format() const
|
||||
{
|
||||
QTextCharFormat fmt;
|
||||
switch (type) {
|
||||
@ -225,11 +224,32 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QIBusAttributeList &at
|
||||
|
||||
QList<QInputMethodEvent::Attribute> QIBusAttributeList::imAttributes() const
|
||||
{
|
||||
QList<QInputMethodEvent::Attribute> imAttrs;
|
||||
QHash<QPair<int, int>, QTextCharFormat> rangeAttrs;
|
||||
|
||||
// Merge text fomats for identical ranges into a single QTextFormat.
|
||||
for (int i = 0; i < attributes.size(); ++i) {
|
||||
const QIBusAttribute &attr = attributes.at(i);
|
||||
imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, attr.start, attr.end - attr.start, attr.format());
|
||||
const QTextCharFormat &format = attr.format();
|
||||
|
||||
if (format.isValid()) {
|
||||
const QPair<int, int> range(attr.start, attr.end);
|
||||
rangeAttrs[range].merge(format);
|
||||
}
|
||||
}
|
||||
|
||||
// Assemble list in original attribute order.
|
||||
QList<QInputMethodEvent::Attribute> imAttrs;
|
||||
|
||||
for (int i = 0; i < attributes.size(); ++i) {
|
||||
const QIBusAttribute &attr = attributes.at(i);
|
||||
const QTextFormat &format = attr.format();
|
||||
|
||||
imAttrs += QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
|
||||
attr.start,
|
||||
attr.end - attr.start,
|
||||
format.isValid() ? rangeAttrs[QPair<int, int>(attr.start, attr.end)] : format);
|
||||
}
|
||||
|
||||
return imAttrs;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <qvector.h>
|
||||
#include <qevent.h>
|
||||
#include <QDBusArgument>
|
||||
#include <QTextCharFormat>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -70,7 +71,7 @@ public:
|
||||
QIBusAttribute();
|
||||
~QIBusAttribute();
|
||||
|
||||
QTextFormat format() const;
|
||||
QTextCharFormat format() const;
|
||||
|
||||
Type type;
|
||||
quint32 value;
|
||||
|
Loading…
Reference in New Issue
Block a user