diff options
Diffstat (limited to 'src/declarative/graphicsitems/qdeclarativetextinput.cpp')
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativetextinput.cpp | 141 |
1 files changed, 120 insertions, 21 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 29b1f6b..6c26fd3 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -326,9 +326,12 @@ void QDeclarativeTextInput::setSelectedTextColor(const QColor &color) /*! \qmlproperty enumeration TextInput::horizontalAlignment + \qmlproperty enumeration TextInput::effectiveHorizontalAlignment Sets the horizontal alignment of the text within the TextInput item's - width and height. By default, the text is left aligned. + width and height. By default, the text alignment follows the natural alignment + of the text, for example text that is read from left to right will be aligned to + the left. TextInput does not have vertical alignment, as the natural height is exactly the height of the single line of text. If you set the height @@ -338,6 +341,11 @@ void QDeclarativeTextInput::setSelectedTextColor(const QColor &color) The valid values for \c horizontalAlignment are \c TextInput.AlignLeft, \c TextInput.AlignRight and \c TextInput.AlignHCenter. + + When using the attached property LayoutMirroring::enabled to mirror application + layouts, the horizontal alignment of text will also be mirrored. However, the property + \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment + of TextInput, use the read-only property \c effectiveHorizontalAlignment. */ QDeclarativeTextInput::HAlignment QDeclarativeTextInput::hAlign() const { @@ -348,12 +356,78 @@ QDeclarativeTextInput::HAlignment QDeclarativeTextInput::hAlign() const void QDeclarativeTextInput::setHAlign(HAlignment align) { Q_D(QDeclarativeTextInput); - if(align == d->hAlign) - return; - d->hAlign = align; - updateRect(); - d->updateHorizontalScroll(); - emit horizontalAlignmentChanged(d->hAlign); + bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror; + d->hAlignImplicit = false; + if (d->setHAlign(align, forceAlign) && isComponentComplete()) { + updateRect(); + d->updateHorizontalScroll(); + } +} + +void QDeclarativeTextInput::resetHAlign() +{ + Q_D(QDeclarativeTextInput); + d->hAlignImplicit = true; + if (d->determineHorizontalAlignment() && isComponentComplete()) { + updateRect(); + d->updateHorizontalScroll(); + } +} + +QDeclarativeTextInput::HAlignment QDeclarativeTextInput::effectiveHAlign() const +{ + Q_D(const QDeclarativeTextInput); + QDeclarativeTextInput::HAlignment effectiveAlignment = d->hAlign; + if (!d->hAlignImplicit && d->effectiveLayoutMirror) { + switch (d->hAlign) { + case QDeclarativeTextInput::AlignLeft: + effectiveAlignment = QDeclarativeTextInput::AlignRight; + break; + case QDeclarativeTextInput::AlignRight: + effectiveAlignment = QDeclarativeTextInput::AlignLeft; + break; + default: + break; + } + } + return effectiveAlignment; +} + +bool QDeclarativeTextInputPrivate::setHAlign(QDeclarativeTextInput::HAlignment alignment, bool forceAlign) +{ + Q_Q(QDeclarativeTextInput); + if ((hAlign != alignment || forceAlign) && alignment <= QDeclarativeTextInput::AlignHCenter) { // justify not supported + QDeclarativeTextInput::HAlignment oldEffectiveHAlign = q->effectiveHAlign(); + hAlign = alignment; + return true; + emit q->horizontalAlignmentChanged(alignment); + if (oldEffectiveHAlign != q->effectiveHAlign()) + emit q->effectiveHorizontalAlignmentChanged(); + } + return false; +} + +bool QDeclarativeTextInputPrivate::determineHorizontalAlignment() +{ + if (hAlignImplicit) { + // if no explicit alignment has been set, follow the natural layout direction of the text + QString text = control->text(); + bool isRightToLeft = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : text.isRightToLeft(); + return setHAlign(isRightToLeft ? QDeclarativeTextInput::AlignRight : QDeclarativeTextInput::AlignLeft); + } + return false; +} + +void QDeclarativeTextInputPrivate::mirrorChange() +{ + Q_Q(QDeclarativeTextInput); + if (q->isComponentComplete()) { + if (!hAlignImplicit && (hAlign == QDeclarativeTextInput::AlignRight || hAlign == QDeclarativeTextInput::AlignLeft)) { + q->updateRect(); + updateHorizontalScroll(); + emit q->effectiveHorizontalAlignmentChanged(); + } + } } /*! @@ -986,16 +1060,21 @@ void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev) keyPressPreHandler(ev); if (ev->isAccepted()) return; - if (((ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) && ev->modifiers() == Qt::NoModifier) // Don't allow MacOSX up/down support, and we don't allow a completer. - || (((d->control->cursor() == 0 && ev->key() == Qt::Key_Left) - || (d->control->cursor() == d->control->text().length() - && ev->key() == Qt::Key_Right)) - && (d->lastSelectionStart == d->lastSelectionEnd))) - { - //ignore when moving off the end - //unless there is a selection, because then moving will do something (deselect) + + // Don't allow MacOSX up/down support, and we don't allow a completer. + bool ignore = (ev->key() == Qt::Key_Up || ev->key() == Qt::Key_Down) && ev->modifiers() == Qt::NoModifier; + if (!ignore && (d->lastSelectionStart == d->lastSelectionEnd) && (ev->key() == Qt::Key_Right || ev->key() == Qt::Key_Left)) { + // Ignore when moving off the end unless there is a selection, + // because then moving will do something (deselect). + int cursorPosition = d->control->cursor(); + if (cursorPosition == 0) + ignore = ev->key() == (d->control->layoutDirection() == Qt::LeftToRight ? Qt::Key_Left : Qt::Key_Right); + if (cursorPosition == d->control->text().length()) + ignore = ev->key() == (d->control->layoutDirection() == Qt::LeftToRight ? Qt::Key_Right : Qt::Key_Left); + } + if (ignore) { ev->ignore(); - }else{ + } else { d->control->processKeyEvent(ev); } if (!ev->isAccepted()) @@ -1204,11 +1283,12 @@ void QDeclarativeTextInputPrivate::updateHorizontalScroll() int cix = qRound(control->cursorToX(control->cursor() + preeditLength)); QRect br(q->boundingRect().toRect()); int widthUsed = calculateTextWidth(); - Qt::Alignment va = QStyle::visualAlignment(control->layoutDirection(), QFlag(Qt::Alignment(hAlign))); + + QDeclarativeTextInput::HAlignment effectiveHAlign = q->effectiveHAlign(); if (autoScroll) { if (widthUsed <= br.width()) { // text fits in br; use hscroll for alignment - switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { + switch (effectiveHAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { case Qt::AlignRight: hscroll = widthUsed - br.width() - 1; break; @@ -1240,11 +1320,11 @@ void QDeclarativeTextInputPrivate::updateHorizontalScroll() hscroll = cix; } } else { - switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { - case Qt::AlignRight: + switch (effectiveHAlign) { + case QDeclarativeTextInput::AlignRight: hscroll = q->width() - widthUsed; break; - case Qt::AlignHCenter: + case QDeclarativeTextInput::AlignHCenter: hscroll = (q->width() - widthUsed) / 2; break; default: @@ -1334,6 +1414,23 @@ void QDeclarativeTextInput::selectAll() d->control->setSelection(0, d->control->text().length()); } +/*! + \qmlmethod void TextInput::isRightToLeft(int start, int end) + + Returns true if the natural reading direction of the editor text + found between positions \a start and \a end is right to left. +*/ +bool QDeclarativeTextInput::isRightToLeft(int start, int end) +{ + Q_D(QDeclarativeTextInput); + if (start > end) { + qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start."; + return false; + } else { + return d->control->text().mid(start, end - start).isRightToLeft(); + } +} + #ifndef QT_NO_CLIPBOARD /*! \qmlmethod TextInput::cut() @@ -1777,6 +1874,7 @@ void QDeclarativeTextInputPrivate::init() QPalette p = control->palette(); selectedTextColor = p.color(QPalette::HighlightedText); selectionColor = p.color(QPalette::Highlight); + determineHorizontalAlignment(); } void QDeclarativeTextInput::cursorPosChanged() @@ -1824,6 +1922,7 @@ void QDeclarativeTextInput::q_textChanged() { Q_D(QDeclarativeTextInput); updateSize(); + d->determineHorizontalAlignment(); d->updateHorizontalScroll(); updateMicroFocus(); emit textChanged(); |