aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Vuorela <pekka.ta.vuorela@nokia.com>2012-04-24 16:46:27 +0300
committerQt by Nokia <qt-info@nokia.com>2012-04-27 13:47:34 +0200
commit70e17b48e751c9a9f9d456404c8df61cb5080037 (patch)
treef21b5ed04c717e56aa32b2fc2715640339ae3569
parent7c288f1a61173f1904960c96c703ee89ab5a847e (diff)
TextEdit to honor input direction on neutral text
Text with neutral direction, such as e.g. plain spaces, do not need to make text left aligned on arabic input method. Change-Id: I9aab5244ec47cf80fb2ba0f83e7087430eb2c7bb Reviewed-by: Joona Petrell <joona.t.petrell@nokia.com>
-rw-r--r--src/quick/items/qquicktextedit.cpp63
-rw-r--r--src/quick/items/qquicktextedit_p_p.h6
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp10
3 files changed, 62 insertions, 17 deletions
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index fc02815adf..0e5023f272 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -537,20 +537,39 @@ bool QQuickTextEditPrivate::setHAlign(QQuickTextEdit::HAlignment alignment, bool
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;
}
@@ -1781,7 +1800,11 @@ void QQuickTextEdit::q_textChanged()
{
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();
@@ -2016,24 +2039,34 @@ void QQuickTextEditPrivate::updateDefaultTextOption()
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);
+ }
}
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index f0a35d5266..e556367bcf 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -73,12 +73,13 @@ public:
, 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)
{
}
@@ -93,6 +94,7 @@ public:
bool setHAlign(QQuickTextEdit::HAlignment, bool forceAlign = false);
void mirrorChange();
qreal getImplicitWidth() const;
+ Qt::LayoutDirection textDirection(const QString &text) const;
QColor color;
QColor selectionColor;
@@ -127,6 +129,7 @@ public:
QQuickTextEdit::VAlignment vAlign;
QQuickTextEdit::TextFormat format;
QQuickTextEdit::WrapMode wrapMode;
+ Qt::LayoutDirection contentDirection;
QQuickTextEdit::SelectionMode mouseSelectionMode;
Qt::InputMethodHints inputMethodHints;
UpdateType updateType;
@@ -142,7 +145,6 @@ public:
bool canPaste:1;
bool canPasteValid:1;
bool hAlignImplicit:1;
- bool rightToLeftText:1;
bool textCached:1;
bool inLayout:1;
};
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 0bc48c98da..51b04cf7a0 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -751,6 +751,16 @@ void tst_qquicktextedit::hAlign_RightToLeft()
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");