Fix disappearing selection spanning different scripts
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Wed, 29 Jul 2015 11:47:45 +0000 (13:47 +0200)
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
Mon, 3 Aug 2015 07:18:44 +0000 (07:18 +0000)
Due to the way itemization is currently done in Qt,
Cyrillic text (and other writing systems) separated by
spaces will become separate items because the spaces
are itemized as Script_Common. In the Scenegraph's text
node engine, we should merge these items into a single node
as long as the same font is used for all the text. But
a bug in the engine caused this to fail when the text
was selected. The symptom of this was that in some rare
cases one of the items would vanish if it were in the
middle of a selection.

In order to support the bearing of selected text leaning outside
the selection rect, I previously added a hack which would add
all selected text as unselected text as well in
b0783c21fb54b939f07ddf5658cc51113b8014e6. This was an awkward
way of doing it and caused said regression. A less intrusive way
is just to add the text to the scene graph twice, as this does not
interfere with the logic needed to support selecting part of
ligatures nor the engine's ability to merge nodes correctly.

[ChangeLog][Text] Fixed regression with selections spanning
different scripts.

Task-number: QTBUG-46829
Change-Id: I0faed76fb2cd1ac0b2e5cc54b81008b5e2550733
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
src/quick/items/qquicktextnodeengine.cpp
tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected_all.qml [new file with mode: 0644]

index 7903f79..5140ccb 100644 (file)
@@ -596,7 +596,6 @@ void QQuickTextNodeEngine::addGlyphsInRange(int rangeStart, int rangeLength,
             for (int j=0; j<glyphRuns.size(); ++j) {
                 const QGlyphRun &glyphRun = glyphRuns.at(j);
                 addSelectedGlyphs(glyphRun);
-                addUnselectedGlyphs(glyphRun);
             }
         }
 
@@ -762,11 +761,10 @@ void  QQuickTextNodeEngine::addToSceneGraph(QQuickTextNode *parentNode,
         parentNode->addRectangleNode(rect, color);
     }
 
-    // Add all unselected text first
+    // Add all text with unselected color first
     for (int i = 0; i < nodes.size(); ++i) {
         const BinaryTreeNode *node = nodes.at(i);
-        if (node->selectionState == Unselected)
-            parentNode->addGlyphs(node->position, node->glyphRun, node->color, style, styleColor, 0);
+        parentNode->addGlyphs(node->position, node->glyphRun, node->color, style, styleColor, 0);
     }
 
     for (int i = 0; i < imageNodes.size(); ++i) {
diff --git a/tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected_all.qml b/tests/manual/scenegraph_lancelot/data/text/textedit_cyrillic_selected_all.qml
new file mode 100644 (file)
index 0000000..9580f28
--- /dev/null
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Item {
+    width: 320
+    height: 480
+    TextEdit {
+        id: textEdit
+        text: "и в у"
+        anchors.centerIn: parent
+        Component.onCompleted: textEdit.selectAll()
+        font.pixelSize: 14
+    }
+}