return false;
}
+
+Qt::LayoutDirection QQuickTextEditPrivate::textDirection(const QString &text) const
+{
+ const QChar *character = text.constData();
+ while (!character->isNull()) {
+ switch (character->direction()) {
+ case QChar::DirL:
+ return Qt::LeftToRight;
+ case QChar::DirR:
+ case QChar::DirAL:
+ case QChar::DirAN:
+ return Qt::RightToLeft;
+ default:
+ break;
+ }
+ character++;
+ }
+ return Qt::LayoutDirectionAuto;
+}
+
bool QQuickTextEditPrivate::determineHorizontalAlignment()
{
Q_Q(QQuickTextEdit);
if (hAlignImplicit && q->isComponentComplete()) {
- bool alignToRight;
- if (document->isEmpty()) {
+ Qt::LayoutDirection direction = contentDirection;
+ if (direction == Qt::LayoutDirectionAuto) {
const QString preeditText = control->textCursor().block().layout()->preeditAreaText();
- alignToRight = preeditText.isEmpty()
- ? qApp->inputMethod()->inputDirection() == Qt::RightToLeft
- : preeditText.isRightToLeft();
- } else {
- alignToRight = rightToLeftText;
+ direction = textDirection(preeditText);
}
- return setHAlign(alignToRight ? QQuickTextEdit::AlignRight : QQuickTextEdit::AlignLeft);
+ if (direction == Qt::LayoutDirectionAuto)
+ direction = qGuiApp->inputMethod()->inputDirection();
+
+ return setHAlign(direction == Qt::RightToLeft ? QQuickTextEdit::AlignRight : QQuickTextEdit::AlignLeft);
}
return false;
}
{
Q_D(QQuickTextEdit);
d->textCached = false;
- d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft();
+ for (QTextBlock it = d->document->begin(); it != d->document->end(); it = it.next()) {
+ d->contentDirection = d->textDirection(it.text());
+ if (d->contentDirection != Qt::LayoutDirectionAuto)
+ break;
+ }
d->determineHorizontalAlignment();
d->updateDefaultTextOption();
updateSize();
Q_Q(QQuickTextEdit);
QTextOption opt = document->defaultTextOption();
int oldAlignment = opt.alignment();
+ Qt::LayoutDirection oldTextDirection = opt.textDirection();
QQuickTextEdit::HAlignment horizontalAlignment = q->effectiveHAlign();
- if (rightToLeftText) {
+ if (contentDirection == Qt::RightToLeft) {
if (horizontalAlignment == QQuickTextEdit::AlignLeft)
horizontalAlignment = QQuickTextEdit::AlignRight;
else if (horizontalAlignment == QQuickTextEdit::AlignRight)
horizontalAlignment = QQuickTextEdit::AlignLeft;
}
- opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign));
+ if (!hAlignImplicit)
+ opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign));
+ else
+ opt.setAlignment(Qt::Alignment(vAlign));
+
+ if (contentDirection == Qt::LayoutDirectionAuto) {
+ opt.setTextDirection(qGuiApp->inputMethod()->inputDirection());
+ } else {
+ opt.setTextDirection(contentDirection);
+ }
QTextOption::WrapMode oldWrapMode = opt.wrapMode();
opt.setWrapMode(QTextOption::WrapMode(wrapMode));
opt.setUseDesignMetrics(true);
- if (oldWrapMode == opt.wrapMode() && oldAlignment == opt.alignment())
- return;
-
- document->setDefaultTextOption(opt);
+ if (oldWrapMode != opt.wrapMode() || oldAlignment != opt.alignment()
+ || oldTextDirection != opt.textDirection()) {
+ document->setDefaultTextOption(opt);
+ }
}
, lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
+ , contentDirection(Qt::LayoutDirectionAuto)
, mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone)
, updateType(UpdatePaintNode)
, documentDirty(true), dirty(false), richText(false), cursorVisible(false)
, focusOnPress(true), persistentSelection(false), requireImplicitWidth(false)
, selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true)
- , rightToLeftText(false), textCached(false), inLayout(false)
+ , textCached(false), inLayout(false)
{
}
bool setHAlign(QQuickTextEdit::HAlignment, bool forceAlign = false);
void mirrorChange();
qreal getImplicitWidth() const;
+ Qt::LayoutDirection textDirection(const QString &text) const;
QColor color;
QColor selectionColor;
QQuickTextEdit::VAlignment vAlign;
QQuickTextEdit::TextFormat format;
QQuickTextEdit::WrapMode wrapMode;
+ Qt::LayoutDirection contentDirection;
QQuickTextEdit::SelectionMode mouseSelectionMode;
Qt::InputMethodHints inputMethodHints;
UpdateType updateType;
bool canPaste:1;
bool canPasteValid:1;
bool hAlignImplicit:1;
- bool rightToLeftText:1;
bool textCached:1;
bool inLayout:1;
};
QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight);
QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2);
+ // neutral text follows also input method direction
+ textEdit->resetHAlign();
+ textEdit->setText(" ()((=<>");
+ platformInputContext.setInputDirection(Qt::LeftToRight);
+ QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignLeft);
+ QVERIFY(textEdit->cursorRectangle().left() < canvas.width()/2);
+ platformInputContext.setInputDirection(Qt::RightToLeft);
+ QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight);
+ QVERIFY(textEdit->cursorRectangle().left() > canvas.width()/2);
+
// set input direction while having content
platformInputContext.setInputDirection(Qt::LeftToRight);
textEdit->setText("a");