Explorar o código

support left alignment for RTL text in edit mode

Vim mode does not support it for now.
Le Tan %!s(int64=6) %!d(string=hai) anos
pai
achega
14617a4172
Modificáronse 1 ficheiros con 73 adicións e 7 borrados
  1. 73 7
      src/vtextdocumentlayout.cpp

+ 73 - 7
src/vtextdocumentlayout.cpp

@@ -256,15 +256,43 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
         int cursorWidth = m_cursorWidth;
         int cursorPosition = p_context.cursorPosition - blpos;
         if (drawCursor && m_cursorBlockMode != CursorBlock::None) {
-            if (cursorPosition > 0 && m_cursorBlockMode == CursorBlock::LeftSide) {
-                --cursorPosition;
+            auto direction = layout->textOption().textDirection();
+            bool needUpdateWidthViaSelection = true;
+            int deltaPosition = direction == Qt::RightToLeft ? -1 : 1;
+            // FIXME: the rect to update is error in RTL case.
+            if (m_cursorBlockMode == CursorBlock::LeftSide) {
+                if (direction == Qt::RightToLeft) {
+                    if (cursorPosition == 0) {
+                        cursorWidth = 1;
+                        needUpdateWidthViaSelection = false;
+                    }
+                } else {
+                    if (cursorPosition > 0) {
+                        --cursorPosition;
+                    } else {
+                        cursorWidth = 1;
+                        needUpdateWidthViaSelection = false;
+                    }
+                }
+            } else if (m_cursorBlockMode == CursorBlock::RightSide) {
+                if (direction == Qt::RightToLeft) {
+                    if (cursorPosition < bllen - 1) {
+                        ++cursorPosition;
+                    } else {
+                        cursorWidth = 1;
+                        needUpdateWidthViaSelection = false;
+                    }
+                } else {
+                    if (cursorPosition == bllen - 1) {
+                        cursorWidth = m_virtualCursorBlockWidth;
+                        needUpdateWidthViaSelection = false;
+                    }
+                }
             }
 
-            if (cursorPosition == bllen - 1) {
-                cursorWidth = m_virtualCursorBlockWidth;
-            } else {
+            if (needUpdateWidthViaSelection) {
                 // Get the width of the selection to update cursor width.
-                cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, 1);
+                cursorWidth = getTextWidthWithinTextLine(layout, cursorPosition, deltaPosition);
                 if (cursorWidth < m_cursorWidth) {
                     cursorWidth = m_cursorWidth;
                 }
@@ -274,6 +302,8 @@ void VTextDocumentLayout::draw(QPainter *p_painter, const PaintContext &p_contex
                 m_lastCursorBlockWidth = cursorWidth;
                 emit cursorBlockWidthUpdated(m_lastCursorBlockWidth);
             }
+
+            Q_ASSERT(cursorWidth > 0);
         }
 
         // Draw cursor line block.
@@ -511,6 +541,26 @@ void VTextDocumentLayout::clearBlockLayout(QTextBlock &p_block)
     info->reset();
 }
 
+// From Qt's qguiapplication_p.h.
+static Qt::Alignment visualAlignment(Qt::LayoutDirection p_direction,
+                                     Qt::Alignment p_alignment)
+{
+    if (!(p_alignment & Qt::AlignHorizontal_Mask)) {
+        p_alignment |= Qt::AlignLeft;
+    }
+
+    if (!(p_alignment & Qt::AlignAbsolute)
+        && (p_alignment & (Qt::AlignLeft | Qt::AlignRight))) {
+        if (p_direction == Qt::RightToLeft) {
+            p_alignment ^= (Qt::AlignLeft | Qt::AlignRight);
+        }
+
+        p_alignment |= Qt::AlignAbsolute;
+    }
+
+    return p_alignment;
+}
+
 void VTextDocumentLayout::layoutBlock(const QTextBlock &p_block)
 {
     QTextDocument *doc = document();
@@ -518,6 +568,21 @@ void VTextDocumentLayout::layoutBlock(const QTextBlock &p_block)
 
     QTextLayout *tl = p_block.layout();
     QTextOption option = doc->defaultTextOption();
+
+    {
+    auto direction = p_block.textDirection();
+    option.setTextDirection(direction);
+
+    auto alignment = option.alignment();
+    QTextBlockFormat blockFormat = p_block.blockFormat();
+    if (blockFormat.hasProperty(QTextFormat::BlockAlignment)) {
+        alignment = blockFormat.alignment();
+    }
+
+    // For paragraph that are RTL, alignment is auto-reversed.
+    option.setAlignment(visualAlignment(direction, alignment));
+    }
+
     tl->setTextOption(option);
 
     int extraMargin = 0;
@@ -1125,7 +1190,8 @@ int VTextDocumentLayout::getTextWidthWithinTextLine(const QTextLayout *p_layout,
     QTextLine line = p_layout->lineForTextPosition(p_pos);
     V_ASSERT(line.isValid());
     V_ASSERT(p_pos + p_length <= line.textStart() + line.textLength());
-    return line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos);
+    V_ASSERT(p_pos + p_length >= 0);
+    return qAbs(line.cursorToX(p_pos + p_length) - line.cursorToX(p_pos));
 }
 
 void VTextDocumentLayout::updateBlockByNumber(int p_blockNumber)