summaryrefslogtreecommitdiffstats
path: root/src/declarative/graphicsitems/qmlgraphicstextinput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/graphicsitems/qmlgraphicstextinput.cpp')
-rw-r--r--src/declarative/graphicsitems/qmlgraphicstextinput.cpp777
1 files changed, 777 insertions, 0 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicstextinput.cpp b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp
new file mode 100644
index 0000000..44ccda1
--- /dev/null
+++ b/src/declarative/graphicsitems/qmlgraphicstextinput.cpp
@@ -0,0 +1,777 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlgraphicstextinput_p.h"
+#include "qmlgraphicstextinput_p_p.h"
+#include "qmlinfo.h"
+#include <QValidator>
+#include <QApplication>
+#include <QFontMetrics>
+#include <QPainter>
+
+QT_BEGIN_NAMESPACE
+
+QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,TextInput,QmlGraphicsTextInput);
+QML_DEFINE_NOCREATE_TYPE(QValidator);
+QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,QIntValidator,QIntValidator);
+
+/*!
+ \qmlclass TextInput QFxTextInput
+ The TextInput item allows you to add an editable line of text to a scene.
+
+ TextInput can only display a single line of text, and can only display
+ plain text. However it can provide addition input constraints on the text.
+
+ Input constraints include setting a QValidator, an input mask, or a
+ maximum input length.
+*/
+QmlGraphicsTextInput::QmlGraphicsTextInput(QmlGraphicsItem* parent)
+ : QmlGraphicsPaintedItem(*(new QmlGraphicsTextInputPrivate), parent)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->init();
+}
+
+/*
+ \internal
+*/
+QmlGraphicsTextInput::QmlGraphicsTextInput(QmlGraphicsTextInputPrivate &dd, QmlGraphicsItem* parent)
+ : QmlGraphicsPaintedItem(dd, parent)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->init();
+}
+
+QmlGraphicsTextInput::~QmlGraphicsTextInput()
+{
+}
+
+/*!
+ \qmlproperty string TextInput::text
+
+ The text in the TextInput.
+*/
+
+QString QmlGraphicsTextInput::text() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->text();
+}
+
+void QmlGraphicsTextInput::setText(const QString &s)
+{
+ Q_D(QmlGraphicsTextInput);
+ if(s == text())
+ return;
+ d->control->setText(s);
+ //emit textChanged();
+}
+
+/*!
+ \qmlproperty string TextInput::font.family
+ \qmlproperty bool TextInput::font.bold
+ \qmlproperty bool TextInput::font.italic
+ \qmlproperty bool TextInput::font.underline
+ \qmlproperty real TextInput::font.pointSize
+ \qmlproperty int TextInput::font.pixelSize
+
+ Set the TextInput's font attributes.
+*/
+QFont QmlGraphicsTextInput::font() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->font;
+}
+
+void QmlGraphicsTextInput::setFont(const QFont &font)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->font = font;
+
+ d->control->setFont(d->font);
+ if(d->cursorItem){
+ d->cursorItem->setHeight(QFontMetrics(d->font).height());
+ moveCursor();
+ }
+ updateSize();
+}
+
+/*!
+ \qmlproperty color TextInput::color
+
+ The text color.
+*/
+QColor QmlGraphicsTextInput::color() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->color;
+}
+
+void QmlGraphicsTextInput::setColor(const QColor &c)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->color = c;
+}
+
+
+/*!
+ \qmlproperty color TextInput::selectionColor
+
+ The text highlight color, used behind selections.
+*/
+QColor QmlGraphicsTextInput::selectionColor() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->selectionColor;
+}
+
+void QmlGraphicsTextInput::setSelectionColor(const QColor &color)
+{
+ Q_D(QmlGraphicsTextInput);
+ if (d->selectionColor == color)
+ return;
+
+ d->selectionColor = color;
+ QPalette p = d->control->palette();
+ p.setColor(QPalette::Highlight, d->selectionColor);
+ d->control->setPalette(p);
+}
+
+/*!
+ \qmlproperty color TextInput::selectedTextColor
+
+ The highlighted text color, used in selections.
+*/
+QColor QmlGraphicsTextInput::selectedTextColor() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->selectedTextColor;
+}
+
+void QmlGraphicsTextInput::setSelectedTextColor(const QColor &color)
+{
+ Q_D(QmlGraphicsTextInput);
+ if (d->selectedTextColor == color)
+ return;
+
+ d->selectedTextColor = color;
+ QPalette p = d->control->palette();
+ p.setColor(QPalette::HighlightedText, d->selectedTextColor);
+ d->control->setPalette(p);
+}
+
+/*!
+ \qmlproperty enumeration TextInput::horizontalAlignment
+
+ Sets the horizontal alignment of the text within the TextInput item's
+ width and height. By default, the text is left aligned.
+
+ 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
+ manually to something larger, TextInput will always be top aligned
+ vertically. You can use anchors to align it however you want within
+ another item.
+
+ The valid values for \c horizontalAlignment are \c AlignLeft, \c AlignRight and
+ \c AlignHCenter.
+*/
+QmlGraphicsTextInput::HAlignment QmlGraphicsTextInput::hAlign() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->hAlign;
+}
+
+void QmlGraphicsTextInput::setHAlign(HAlignment align)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->hAlign = align;
+ //TODO: implement
+}
+
+bool QmlGraphicsTextInput::isReadOnly() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->isReadOnly();
+}
+
+void QmlGraphicsTextInput::setReadOnly(bool ro)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->setReadOnly(ro);
+}
+
+int QmlGraphicsTextInput::maxLength() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->maxLength();
+}
+
+void QmlGraphicsTextInput::setMaxLength(int ml)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->setMaxLength(ml);
+}
+
+/*!
+ \qmlproperty bool TextInput::cursorVisible
+ If true the text edit shows a cursor.
+
+ This property is set and unset when the line edit gets focus, but it can also
+ be set directly (useful, for example, if a KeyProxy might forward keys to it).
+*/
+bool QmlGraphicsTextInput::isCursorVisible() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->cursorVisible;
+}
+
+void QmlGraphicsTextInput::setCursorVisible(bool on)
+{
+ Q_D(QmlGraphicsTextInput);
+ if (d->cursorVisible == on)
+ return;
+ d->cursorVisible = on;
+ d->control->setCursorBlinkPeriod(on?QApplication::cursorFlashTime():0);
+ //d->control should emit the cursor update regions
+}
+
+/*!
+ \qmlproperty int TextInput::cursorPosition
+ The position of the cursor in the TextInput.
+*/
+int QmlGraphicsTextInput::cursorPosition() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->cursor();
+}
+void QmlGraphicsTextInput::setCursorPosition(int cp)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->moveCursor(cp);
+}
+
+/*!
+ \internal
+
+ Returns a Rect which encompasses the cursor, but which may be larger than is
+ required. Ignores custom cursor delegates.
+*/
+QRect QmlGraphicsTextInput::cursorRect() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->cursorRect();
+}
+
+/*!
+ \qmlproperty int TextInput::selectionStart
+
+ The cursor position before the first character in the current selection.
+ Setting this and selectionEnd allows you to specify a selection in the
+ text edit.
+
+ Note that if selectionStart == selectionEnd then there is no current
+ selection. If you attempt to set selectionStart to a value outside of
+ the current text, selectionStart will not be changed.
+
+ \sa selectionEnd, cursorPosition, selectedText
+*/
+int QmlGraphicsTextInput::selectionStart() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->lastSelectionStart;
+}
+
+void QmlGraphicsTextInput::setSelectionStart(int s)
+{
+ Q_D(QmlGraphicsTextInput);
+ if(d->lastSelectionStart == s || s < 0 || s > text().length())
+ return;
+ d->lastSelectionStart = s;
+ d->control->setSelection(s, d->lastSelectionEnd - s);
+}
+
+/*!
+ \qmlproperty int TextInput::selectionEnd
+
+ The cursor position after the last character in the current selection.
+ Setting this and selectionStart allows you to specify a selection in the
+ text edit.
+
+ Note that if selectionStart == selectionEnd then there is no current
+ selection. If you attempt to set selectionEnd to a value outside of
+ the current text, selectionEnd will not be changed.
+
+ \sa selectionStart, cursorPosition, selectedText
+*/
+int QmlGraphicsTextInput::selectionEnd() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->lastSelectionEnd;
+}
+
+void QmlGraphicsTextInput::setSelectionEnd(int s)
+{
+ Q_D(QmlGraphicsTextInput);
+ if(d->lastSelectionEnd == s || s < 0 || s > text().length())
+ return;
+ d->lastSelectionEnd = s;
+ d->control->setSelection(d->lastSelectionStart, s - d->lastSelectionStart);
+}
+
+/*!
+ \qmlproperty string TextInput::selectedText
+
+ This read-only property provides the text currently selected in the
+ text input.
+
+ It is equivalent to the following snippet, but is faster and easier
+ to use.
+
+ \qml
+ myTextInput.text.toString().substring(myTextInput.selectionStart,
+ myTextInput.selectionEnd);
+ \endqml
+*/
+QString QmlGraphicsTextInput::selectedText() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->selectedText();
+}
+
+/*!
+ \qmlproperty bool TextInput::focusOnPress
+
+ Whether the TextInput should gain focus on a mouse press. By default this is
+ set to true.
+*/
+bool QmlGraphicsTextInput::focusOnPress() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->focusOnPress;
+}
+
+void QmlGraphicsTextInput::setFocusOnPress(bool b)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->focusOnPress = b;
+}
+
+/*!
+ \qmlproperty QValidator* TextInput::validator
+
+ Allows you to set a QValidator on the TextInput. When a validator is set
+ the TextInput will only accept input which leaves the text property in
+ an acceptable or intermediate state. The accepted signal will only be sent
+ if the text is in an acceptable state when enter is pressed.
+
+ \sa acceptableInput, inputMask
+*/
+QValidator* QmlGraphicsTextInput::validator() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ //###const cast isn't good, but needed for property system?
+ return const_cast<QValidator*>(d->control->validator());
+}
+
+void QmlGraphicsTextInput::setValidator(QValidator* v)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->setValidator(v);
+ if(!d->control->hasAcceptableInput()){
+ d->oldValidity = false;
+ emit acceptableInputChanged();
+ }
+}
+
+/*!
+ \qmlproperty string TextInput::inputMask
+
+ Allows you to set an input mask on the TextInput, restricting the allowable
+ text inputs. See QLineEdit::inputMask for further details, as the exact
+ same mask strings are used by TextInput.
+
+ \sa acceptableInput, validator
+*/
+QString QmlGraphicsTextInput::inputMask() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->inputMask();
+}
+
+void QmlGraphicsTextInput::setInputMask(const QString &im)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->setInputMask(im);
+}
+
+/*!
+ \qmlproperty bool TextInput::acceptableInput
+
+ This property is always true unless a validator or input mask has been set.
+ If a validator or input mask has been set, this property will only be true
+ if the current text is acceptable to the validator or input mask as a final
+ string (not as an intermediate string).
+*/
+bool QmlGraphicsTextInput::hasAcceptableInput() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->hasAcceptableInput();
+}
+
+/*!
+ \qmlproperty TextInput.EchoMode TextInput::echoMode
+
+ Specifies how the text should be displayed in the TextInput.
+ The default is Normal, which displays the text as it is. Other values
+ are Password, which displays asterixes instead of characters, NoEcho,
+ which displays nothing, and PasswordEchoOnEdit, which displays all but the
+ current character as asterixes.
+
+*/
+QmlGraphicsTextInput::EchoMode QmlGraphicsTextInput::echoMode() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return (QmlGraphicsTextInput::EchoMode)d->control->echoMode();
+}
+
+void QmlGraphicsTextInput::setEchoMode(QmlGraphicsTextInput::EchoMode echo)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->setEchoMode((uint)echo);
+}
+
+/*!
+ \qmlproperty Component TextInput::cursorDelegate
+ The delegate for the cursor in the TextInput.
+
+ If you set a cursorDelegate for a TextInput, this delegate will be used for
+ drawing the cursor instead of the standard cursor. An instance of the
+ delegate will be created and managed by the TextInput when a cursor is
+ needed, and the x property of delegate instance will be set so as
+ to be one pixel before the top left of the current character.
+
+ Note that the root item of the delegate component must be a QmlGraphicsItem or
+ QmlGraphicsItem derived item.
+*/
+QmlComponent* QmlGraphicsTextInput::cursorDelegate() const
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->cursorComponent;
+}
+
+void QmlGraphicsTextInput::setCursorDelegate(QmlComponent* c)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->cursorComponent = c;
+ if(!c){
+ //note that the components are owned by something else
+ disconnect(d->control, SIGNAL(cursorPositionChanged(int, int)),
+ this, SLOT(moveCursor()));
+ delete d->cursorItem;
+ }else{
+ d->startCreatingCursor();
+ }
+}
+
+void QmlGraphicsTextInputPrivate::startCreatingCursor()
+{
+ Q_Q(QmlGraphicsTextInput);
+ q->connect(control, SIGNAL(cursorPositionChanged(int, int)),
+ q, SLOT(moveCursor()));
+ if(cursorComponent->isReady()){
+ q->createCursor();
+ }else if(cursorComponent->isLoading()){
+ q->connect(cursorComponent, SIGNAL(statusChanged(int)),
+ q, SLOT(createCursor()));
+ }else{//isError
+ qmlInfo(QmlGraphicsTextInput::tr("Could not load cursor delegate"), q);
+ qWarning() << cursorComponent->errors();
+ }
+}
+
+void QmlGraphicsTextInput::createCursor()
+{
+ Q_D(QmlGraphicsTextInput);
+ if(d->cursorComponent->isError()){
+ qmlInfo(tr("Could not load cursor delegate"),this);
+ qWarning() << d->cursorComponent->errors();
+ return;
+ }
+
+ if(!d->cursorComponent->isReady())
+ return;
+
+ if(d->cursorItem)
+ delete d->cursorItem;
+ d->cursorItem = qobject_cast<QmlGraphicsItem*>(d->cursorComponent->create());
+ if(!d->cursorItem){
+ qmlInfo(tr("Could not instantiate cursor delegate"),this);
+ //The failed instantiation should print its own error messages
+ return;
+ }
+
+ d->cursorItem->setParentItem(this);
+ d->cursorItem->setX(d->control->cursorToX());
+ d->cursorItem->setHeight(d->control->height());
+}
+
+void QmlGraphicsTextInput::moveCursor()
+{
+ Q_D(QmlGraphicsTextInput);
+ if(!d->cursorItem)
+ return;
+ d->cursorItem->setX(d->control->cursorToX() - d->hscroll);
+}
+
+int QmlGraphicsTextInput::xToPos(int x)
+{
+ Q_D(const QmlGraphicsTextInput);
+ return d->control->xToPos(x - d->hscroll);
+}
+
+void QmlGraphicsTextInput::focusChanged(bool hasFocus)
+{
+ Q_D(QmlGraphicsTextInput);
+ d->focused = hasFocus;
+ setCursorVisible(hasFocus);
+ QmlGraphicsItem::focusChanged(hasFocus);
+}
+
+void QmlGraphicsTextInput::keyPressEvent(QKeyEvent* ev)
+{
+ Q_D(QmlGraphicsTextInput);
+ if((d->control->cursor() == 0 && ev->key() == Qt::Key_Left)
+ || (d->control->cursor() == d->control->text().length()
+ && ev->key() == Qt::Key_Right)){
+ //ignore when moving off the end
+ ev->ignore();
+ }else{
+ d->control->processKeyEvent(ev);
+ }
+ if (!ev->isAccepted())
+ QmlGraphicsPaintedItem::keyPressEvent(ev);
+}
+
+void QmlGraphicsTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QmlGraphicsTextInput);
+ if(d->focusOnPress){
+ setFocus(true);
+ setCursorVisible(true);
+ d->focused = true;
+ }
+ d->control->processEvent(event);
+}
+
+bool QmlGraphicsTextInput::event(QEvent* ev)
+{
+ Q_D(QmlGraphicsTextInput);
+ //Anything we don't deal with ourselves, pass to the control
+ bool handled = false;
+ switch(ev->type()){
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease://###Should the control be doing anything with release?
+ case QEvent::GraphicsSceneMousePress:
+ break;
+ default:
+ handled = d->control->processEvent(ev);
+ }
+ if(!handled)
+ return QmlGraphicsPaintedItem::event(ev);
+ return true;
+}
+
+void QmlGraphicsTextInput::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ if (newGeometry.width() != oldGeometry.width())
+ updateSize();
+ QmlGraphicsPaintedItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+void QmlGraphicsTextInput::drawContents(QPainter *p, const QRect &r)
+{
+ Q_D(QmlGraphicsTextInput);
+ p->setRenderHint(QPainter::TextAntialiasing, true);
+ p->save();
+ p->setPen(QPen(d->color));
+ int flags = QLineControl::DrawText;
+ if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
+ flags |= QLineControl::DrawCursor;
+ if (d->control->hasSelectedText()){
+ flags |= QLineControl::DrawSelections;
+ }
+
+ QPoint offset = QPoint(0,0);
+ QRect clipRect = r;
+ d->control->draw(p, offset, clipRect, flags);
+
+ p->restore();
+}
+
+void QmlGraphicsTextInput::selectAll()
+{
+ Q_D(QmlGraphicsTextInput);
+ d->control->setSelection(0, d->control->text().length());
+}
+
+
+/*!
+ \qmlproperty bool TextInput::smooth
+
+ Set this property if you want the text to be smoothly scaled or
+ transformed. Smooth filtering gives better visual quality, but is slower. If
+ the item is displayed at its natural size, this property has no visual or
+ performance effect.
+
+ \note Generally scaling artifacts are only visible if the item is stationary on
+ the screen. A common pattern when animating an item is to disable smooth
+ filtering at the beginning of the animation and reenable it at the conclusion.
+*/
+
+void QmlGraphicsTextInputPrivate::init()
+{
+ Q_Q(QmlGraphicsTextInput);
+ control->setCursorWidth(1);
+ control->setPasswordCharacter(QLatin1Char('*'));
+ control->setLayoutDirection(Qt::LeftToRight);
+ q->setSmoothTransform(smooth);
+ q->setAcceptedMouseButtons(Qt::LeftButton);
+ q->setFlag(QGraphicsItem::ItemHasNoContents, false);
+ q->setFlag(QGraphicsItem::ItemAcceptsInputMethod);
+ q->connect(control, SIGNAL(cursorPositionChanged(int,int)),
+ q, SLOT(cursorPosChanged()));
+ q->connect(control, SIGNAL(selectionChanged()),
+ q, SLOT(selectionChanged()));
+ q->connect(control, SIGNAL(textChanged(const QString &)),
+ q, SLOT(q_textChanged()));
+ q->connect(control, SIGNAL(accepted()),
+ q, SIGNAL(accepted()));
+ q->connect(control, SIGNAL(updateNeeded(QRect)),
+ q, SLOT(updateRect(QRect)));
+ q->connect(control, SIGNAL(cursorPositionChanged(int,int)),
+ q, SLOT(updateRect()));//TODO: Only update rect between pos's
+ q->connect(control, SIGNAL(selectionChanged()),
+ q, SLOT(updateRect()));//TODO: Only update rect in selection
+ //Note that above TODOs probably aren't that big a savings
+ q->updateSize();
+ oldValidity = control->hasAcceptableInput();
+ lastSelectionStart = 0;
+ lastSelectionEnd = 0;
+}
+
+void QmlGraphicsTextInput::cursorPosChanged()
+{
+ Q_D(QmlGraphicsTextInput);
+ emit cursorPositionChanged();
+
+ if(!d->control->hasSelectedText()){
+ if(d->lastSelectionStart != d->control->cursor()){
+ d->lastSelectionStart = d->control->cursor();
+ emit selectionStartChanged();
+ }
+ if(d->lastSelectionEnd != d->control->cursor()){
+ d->lastSelectionEnd = d->control->cursor();
+ emit selectionEndChanged();
+ }
+ }
+}
+
+void QmlGraphicsTextInput::selectionChanged()
+{
+ Q_D(QmlGraphicsTextInput);
+ emit selectedTextChanged();
+
+ if(d->lastSelectionStart != d->control->selectionStart()){
+ d->lastSelectionStart = d->control->selectionStart();
+ if(d->lastSelectionStart == -1)
+ d->lastSelectionStart = d->control->cursor();
+ emit selectionStartChanged();
+ }
+ if(d->lastSelectionEnd != d->control->selectionEnd()){
+ d->lastSelectionEnd = d->control->selectionEnd();
+ if(d->lastSelectionEnd == -1)
+ d->lastSelectionEnd = d->control->cursor();
+ emit selectionEndChanged();
+ }
+}
+
+void QmlGraphicsTextInput::q_textChanged()
+{
+ Q_D(QmlGraphicsTextInput);
+ updateSize();
+ emit textChanged();
+ if(hasAcceptableInput() != d->oldValidity){
+ d->oldValidity = hasAcceptableInput();
+ emit acceptableInputChanged();
+ }
+}
+
+void QmlGraphicsTextInput::updateRect(const QRect &r)
+{
+ if(r == QRect())
+ clearCache();
+ else
+ dirtyCache(r);
+ update();
+}
+
+void QmlGraphicsTextInput::updateSize(bool needsRedraw)
+{
+ Q_D(QmlGraphicsTextInput);
+ int w = width();
+ int h = height();
+ setImplicitHeight(d->control->height());
+ int cursorWidth = d->control->cursorWidth();
+ if(d->cursorItem)
+ cursorWidth = d->cursorItem->width();
+ //### Is QFontMetrics too slow?
+ QFontMetricsF fm(d->font);
+ setImplicitWidth(fm.width(d->control->displayText())+cursorWidth);
+ setContentsSize(QSize(width(), height()));//Repaints if changed
+ if(w==width() && h==height() && needsRedraw){
+ clearCache();
+ update();
+ }
+}
+
+QT_END_NAMESPACE
+