summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.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 /tests/auto/widgets/widgets/qtextedit/tst_qtextedit.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 'tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp')
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
index cecec48113..101f7d2d12 100644
--- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
@@ -46,6 +46,7 @@
#include <qcommonstyle.h>
#include <qlayout.h>
#include <qdir.h>
+#include <qpaintengine.h>
#include <qabstracttextdocumentlayout.h>
#include <qtextdocumentfragment.h>
@@ -60,6 +61,8 @@ typedef QPair<Qt::Key, Qt::KeyboardModifier> keyPairType;
typedef QList<keyPairType> pairListType;
Q_DECLARE_METATYPE(keyPairType);
+Q_DECLARE_METATYPE(QList<QInputMethodEvent::Attribute>);
+
QT_FORWARD_DECLARE_CLASS(QTextEdit)
class tst_QTextEdit : public QObject
@@ -200,6 +203,9 @@ private slots:
void wheelEvent();
#endif
+ void preeditCharFormat_data();
+ void preeditCharFormat();
+
private:
void createSelection();
int blockCount() const;
@@ -2594,5 +2600,235 @@ void tst_QTextEdit::wheelEvent()
#endif
+namespace {
+ class MyPaintEngine : public QPaintEngine
+ {
+ public:
+ bool begin(QPaintDevice *)
+ {
+ return true;
+ }
+
+ bool end()
+ {
+ return true;
+ }
+
+ void updateState(const QPaintEngineState &)
+ {
+ }
+
+ void drawPixmap(const QRectF &, const QPixmap &, const QRectF &)
+ {
+ }
+
+ void drawTextItem(const QPointF &, const QTextItem &textItem) Q_DECL_OVERRIDE
+ {
+ itemFonts.append(qMakePair(textItem.text(), textItem.font()));
+ }
+
+ Type type() const { return User; }
+
+
+ QList<QPair<QString, QFont> > itemFonts;
+ };
+
+ class MyPaintDevice : public QPaintDevice
+ {
+ public:
+ MyPaintDevice() : m_paintEngine(new MyPaintEngine)
+ {
+ }
+
+
+ QPaintEngine *paintEngine () const
+ {
+ return m_paintEngine;
+ }
+
+ int metric (QPaintDevice::PaintDeviceMetric metric) const {
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ case QPaintDevice::PdmHeight:
+ case QPaintDevice::PdmWidthMM:
+ case QPaintDevice::PdmHeightMM:
+ case QPaintDevice::PdmNumColors:
+ return INT_MAX;
+ case QPaintDevice::PdmDepth:
+ return 32;
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiX:
+ case QPaintDevice::PdmPhysicalDpiY:
+ return 72;
+ case QPaintDevice::PdmDevicePixelRatio:
+ case QPaintDevice::PdmDevicePixelRatioScaled:
+ ; // fall through
+ }
+ return 0;
+ }
+
+ MyPaintEngine *m_paintEngine;
+ };
+}
+
+void tst_QTextEdit::preeditCharFormat_data()
+{
+ QTest::addColumn<QList<QInputMethodEvent::Attribute> >("imeAttributes");
+ QTest::addColumn<QStringList>("substrings");
+ QTest::addColumn<QList<bool> >("boldnessList");
+ QTest::addColumn<QList<bool> >("italicnessList");
+ QTest::addColumn<QList<int> >("pointSizeList");
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 1, 1, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ QTest::newRow("Two formats, middle, in order")
+ << attributes
+ << (QStringList() << "P" << "r" << "eE" << "di" << "tText")
+ << (QList<bool>() << true << true << true << false << true)
+ << (QList<bool>() << false << true << false << false << false)
+ << (QList<int>() << 20 << 13 << 20 << 8 << 20);
+ }
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 1, 1, tcf));
+ }
+
+ QTest::newRow("Two formats, middle, out of order")
+ << attributes
+ << (QStringList() << "P" << "r" << "eE" << "di" << "tText")
+ << (QList<bool>() << true << true << true << false << true)
+ << (QList<bool>() << false << true << false << false << false)
+ << (QList<int>() << 20 << 13 << 20 << 8 << 20);
+ }
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, 1, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ QTest::newRow("Two formats, front, in order")
+ << attributes
+ << (QStringList() << "P" << "reE" << "di" << "tText")
+ << (QList<bool>() << true << true << false << true)
+ << (QList<bool>() << true << false << false << false)
+ << (QList<int>() << 13 << 20 << 8 << 20);
+ }
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(8);
+ tcf.setFontWeight(QFont::Normal);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 4, 2, tcf));
+ }
+
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(13);
+ tcf.setFontItalic(true);
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, 1, tcf));
+ }
+
+ QTest::newRow("Two formats, front, out of order")
+ << attributes
+ << (QStringList() << "P" << "reE" << "di" << "tText")
+ << (QList<bool>() << true << true << false << true)
+ << (QList<bool>() << true << false << false << false)
+ << (QList<int>() << 13 << 20 << 8 << 20);
+ }
+}
+
+void tst_QTextEdit::preeditCharFormat()
+{
+ QFETCH(QList<QInputMethodEvent::Attribute>, imeAttributes);
+ QFETCH(QStringList, substrings);
+ QFETCH(QList<bool>, boldnessList);
+ QFETCH(QList<bool>, italicnessList);
+ QFETCH(QList<int>, pointSizeList);
+
+ QTextEdit *w = new QTextEdit;
+ w->show();
+ QVERIFY(QTest::qWaitForWindowExposed(w));
+
+ // Set main char format
+ {
+ QTextCharFormat tcf;
+ tcf.setFontPointSize(20);
+ tcf.setFontWeight(QFont::Bold);
+ w->mergeCurrentCharFormat(tcf);
+ }
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ attributes.prepend(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ w->textCursor().position(),
+ 0,
+ QVariant()));
+
+ attributes += imeAttributes;
+
+ QInputMethodEvent event("PreEditText", attributes);
+ QApplication::sendEvent(w, &event);
+
+ MyPaintDevice device;
+ {
+ QPainter p(&device);
+ w->document()->drawContents(&p);
+ }
+
+ QCOMPARE(device.m_paintEngine->itemFonts.size(), substrings.size());
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).first, substrings.at(i));
+
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).second.bold(), boldnessList.at(i));
+
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).second.italic(), italicnessList.at(i));
+
+ for (int i = 0; i < substrings.size(); ++i)
+ QCOMPARE(device.m_paintEngine->itemFonts.at(i).second.pointSize(), pointSizeList.at(i));
+
+ delete w;
+}
+
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"