/****************************************************************************
**
** Copyright (C) 2011 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$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qdeclarativetextedit_p.h"
#include "private/qdeclarativetextedit_p_p.h"

#include "private/qdeclarativeevents_p_p.h"
#include <private/qdeclarativeglobal_p.h>
#include <qdeclarativeinfo.h>

#include <QtCore/qmath.h>

#include <private/qtextengine_p.h>
#include <QTextLayout>
#include <QTextLine>
#include <QTextDocument>
#include <QTextObject>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QPainter>

#include <private/qtextcontrol_p.h>

QT_BEGIN_NAMESPACE

/*!
    \qmlclass TextEdit QDeclarativeTextEdit
    \ingroup qml-basic-visual-elements
    \since 4.7
    \brief The TextEdit item displays multiple lines of editable formatted text.
    \inherits Item

    The TextEdit item displays a block of editable, formatted text.

    It can display both plain and rich text. For example:

    \qml
TextEdit {
    width: 240
    text: "<b>Hello</b> <i>World!</i>"
    font.family: "Helvetica"
    font.pointSize: 20
    color: "blue"
    focus: true
}
    \endqml

    \image declarative-textedit.gif

    Setting \l {Item::focus}{focus} to \c true enables the TextEdit item to receive keyboard focus.

    Note that the TextEdit does not implement scrolling, following the cursor, or other behaviors specific
    to a look-and-feel. For example, to add flickable scrolling that follows the cursor:

    \snippet snippets/declarative/texteditor.qml 0

    A particular look-and-feel might use smooth scrolling (eg. using SmoothedFollow), might have a visible
    scrollbar, or a scrollbar that fades in to show location, etc.

    Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can
    be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely
    from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord().

    You can translate between cursor positions (characters from the start of the document) and pixel
    points using positionAt() and positionToRectangle().

    \sa Text, TextInput, {declarative/text/textselection}{Text Selection example}
*/

/*!
    \qmlsignal TextEdit::onLinkActivated(string link)
    \since QtQuick 1.1

    This handler is called when the user clicks on a link embedded in the text.
    The link must be in rich text or HTML format and the
    \a link string provides access to the particular link.
*/
QDeclarativeTextEdit::QDeclarativeTextEdit(QDeclarativeItem *parent)
: QDeclarativeImplicitSizePaintedItem(*(new QDeclarativeTextEditPrivate), parent)
{
    Q_D(QDeclarativeTextEdit);
    d->init();
}

QString QDeclarativeTextEdit::text() const
{
    Q_D(const QDeclarativeTextEdit);

#ifndef QT_NO_TEXTHTMLPARSER
    if (d->richText)
        return d->document->toHtml();
    else
#endif
        return d->document->toPlainText();
}

/*!
    \qmlproperty string TextEdit::font.family

    Sets the family name of the font.

    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
    If the family isn't available a family will be set using the font matching algorithm.
*/

/*!
    \qmlproperty bool TextEdit::font.bold

    Sets whether the font weight is bold.
*/

/*!
    \qmlproperty enumeration TextEdit::font.weight

    Sets the font's weight.

    The weight can be one of:
    \list
    \o Font.Light
    \o Font.Normal - the default
    \o Font.DemiBold
    \o Font.Bold
    \o Font.Black
    \endlist

    \qml
    TextEdit { text: "Hello"; font.weight: Font.DemiBold }
    \endqml
*/

/*!
    \qmlproperty bool TextEdit::font.italic

    Sets whether the font has an italic style.
*/

/*!
    \qmlproperty bool TextEdit::font.underline

    Sets whether the text is underlined.
*/

/*!
    \qmlproperty bool TextEdit::font.strikeout

    Sets whether the font has a strikeout style.
*/

/*!
    \qmlproperty real TextEdit::font.pointSize

    Sets the font size in points. The point size must be greater than zero.
*/

/*!
    \qmlproperty int TextEdit::font.pixelSize

    Sets the font size in pixels.

    Using this function makes the font device dependent.  Use
    \l{TextEdit::font.pointSize} to set the size of the font in a
    device independent manner.
*/

/*!
    \qmlproperty real TextEdit::font.letterSpacing

    Sets the letter spacing for the font.

    Letter spacing changes the default spacing between individual letters in the font.
    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
*/

/*!
    \qmlproperty real TextEdit::font.wordSpacing

    Sets the word spacing for the font.

    Word spacing changes the default spacing between individual words.
    A positive value increases the word spacing by a corresponding amount of pixels,
    while a negative value decreases the inter-word spacing accordingly.
*/

/*!
    \qmlproperty enumeration TextEdit::font.capitalization

    Sets the capitalization for the text.

    \list
    \o Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
    \o Font.AllUppercase - This alters the text to be rendered in all uppercase type.
    \o Font.AllLowercase	 - This alters the text to be rendered in all lowercase type.
    \o Font.SmallCaps -	This alters the text to be rendered in small-caps type.
    \o Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
    \endlist

    \qml
    TextEdit { text: "Hello"; font.capitalization: Font.AllLowercase }
    \endqml
*/

/*!
    \qmlproperty string TextEdit::text

    The text to display.  If the text format is AutoText the text edit will
    automatically determine whether the text should be treated as
    rich text.  This determination is made using Qt::mightBeRichText().
*/
void QDeclarativeTextEdit::setText(const QString &text)
{
    Q_D(QDeclarativeTextEdit);
    if (QDeclarativeTextEdit::text() == text)
        return;

    d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text));
    if (d->richText) {
#ifndef QT_NO_TEXTHTMLPARSER
        d->control->setHtml(text);
#else
        d->control->setPlainText(text);
#endif
    } else {
        d->control->setPlainText(text);
    }
    q_textChanged();
}

/*!
    \qmlproperty enumeration TextEdit::textFormat

    The way the text property should be displayed.

    \list
    \o TextEdit.AutoText
    \o TextEdit.PlainText
    \o TextEdit.RichText
    \o TextEdit.StyledText
    \endlist

    The default is TextEdit.AutoText.  If the text format is TextEdit.AutoText the text edit
    will automatically determine whether the text should be treated as
    rich text.  This determination is made using Qt::mightBeRichText().

    \table
    \row
    \o
    \qml
Column {
    TextEdit {
        font.pointSize: 24
        text: "<b>Hello</b> <i>World!</i>"
    }
    TextEdit {
        font.pointSize: 24
        textFormat: TextEdit.RichText
        text: "<b>Hello</b> <i>World!</i>"
    }
    TextEdit {
        font.pointSize: 24
        textFormat: TextEdit.PlainText
        text: "<b>Hello</b> <i>World!</i>"
    }
}
    \endqml
    \o \image declarative-textformat.png
    \endtable
*/
QDeclarativeTextEdit::TextFormat QDeclarativeTextEdit::textFormat() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->format;
}

void QDeclarativeTextEdit::setTextFormat(TextFormat format)
{
    Q_D(QDeclarativeTextEdit);
    if (format == d->format)
        return;
    bool wasRich = d->richText;
    d->richText = format == RichText || (format == AutoText && Qt::mightBeRichText(d->text));

    if (wasRich && !d->richText) {
        d->control->setPlainText(d->text);
        updateSize();
    } else if (!wasRich && d->richText) {
#ifndef QT_NO_TEXTHTMLPARSER
        d->control->setHtml(d->text);
#else
        d->control->setPlainText(d->text);
#endif
        updateSize();
    }
    d->format = format;
    d->control->setAcceptRichText(d->format != PlainText);
    emit textFormatChanged(d->format);
}

QFont QDeclarativeTextEdit::font() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->sourceFont;
}

void QDeclarativeTextEdit::setFont(const QFont &font)
{
    Q_D(QDeclarativeTextEdit);
    if (d->sourceFont == font)
        return;

    d->sourceFont = font;
    QFont oldFont = d->font;
    d->font = font;
    if (d->font.pointSizeF() != -1) {
        // 0.5pt resolution
        qreal size = qRound(d->font.pointSizeF()*2.0);
        d->font.setPointSizeF(size/2.0);
    }

    if (oldFont != d->font) {
        clearCache();
        d->document->setDefaultFont(d->font);
        if(d->cursor){
            d->cursor->setHeight(QFontMetrics(d->font).height());
            moveCursorDelegate();
        }
        updateSize();
        update();
    }
    emit fontChanged(d->sourceFont);
}

/*!
    \qmlproperty color TextEdit::color

    The text color.

    \qml
    // green text using hexadecimal notation
    TextEdit { color: "#00FF00" }
    \endqml

    \qml
    // steelblue text using SVG color name
    TextEdit { color: "steelblue" }
    \endqml
*/
QColor QDeclarativeTextEdit::color() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->color;
}

void QDeclarativeTextEdit::setColor(const QColor &color)
{
    Q_D(QDeclarativeTextEdit);
    if (d->color == color)
        return;

    clearCache();
    d->color = color;
    QPalette pal = d->control->palette();
    pal.setColor(QPalette::Text, color);
    d->control->setPalette(pal);
    update();
    emit colorChanged(d->color);
}

/*!
    \qmlproperty color TextEdit::selectionColor

    The text highlight color, used behind selections.
*/
QColor QDeclarativeTextEdit::selectionColor() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->selectionColor;
}

void QDeclarativeTextEdit::setSelectionColor(const QColor &color)
{
    Q_D(QDeclarativeTextEdit);
    if (d->selectionColor == color)
        return;

    clearCache();
    d->selectionColor = color;
    QPalette pal = d->control->palette();
    pal.setColor(QPalette::Highlight, color);
    d->control->setPalette(pal);
    update();
    emit selectionColorChanged(d->selectionColor);
}

/*!
    \qmlproperty color TextEdit::selectedTextColor

    The selected text color, used in selections.
*/
QColor QDeclarativeTextEdit::selectedTextColor() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->selectedTextColor;
}

void QDeclarativeTextEdit::setSelectedTextColor(const QColor &color)
{
    Q_D(QDeclarativeTextEdit);
    if (d->selectedTextColor == color)
        return;

    clearCache();
    d->selectedTextColor = color;
    QPalette pal = d->control->palette();
    pal.setColor(QPalette::HighlightedText, color);
    d->control->setPalette(pal);
    update();
    emit selectedTextColorChanged(d->selectedTextColor);
}

/*!
    \qmlproperty enumeration TextEdit::horizontalAlignment
    \qmlproperty enumeration TextEdit::verticalAlignment

    Sets the horizontal and vertical alignment of the text within the TextEdit item's
    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.

    Valid values for \c horizontalAlignment are:
    \list
    \o TextEdit.AlignLeft (default)
    \o TextEdit.AlignRight 
    \o TextEdit.AlignHCenter
    \o TextEdit.AlignJustify
    \endlist
    
    Valid values for \c verticalAlignment are:
    \list
    \o TextEdit.AlignTop (default)
    \o TextEdit.AlignBottom
    \o TextEdit.AlignVCenter
    \endlist

    When using the attached property \l {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 TextEdit, use the property \l {LayoutMirroring::enabled}.
*/
QDeclarativeTextEdit::HAlignment QDeclarativeTextEdit::hAlign() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->hAlign;
}

void QDeclarativeTextEdit::setHAlign(HAlignment align)
{
    Q_D(QDeclarativeTextEdit);
    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
    d->hAlignImplicit = false;
    if (d->setHAlign(align, forceAlign) && isComponentComplete()) {
        d->updateDefaultTextOption();
        updateSize();
    }
}

void QDeclarativeTextEdit::resetHAlign()
{
    Q_D(QDeclarativeTextEdit);
    d->hAlignImplicit = true;
    if (d->determineHorizontalAlignment() && isComponentComplete()) {
        d->updateDefaultTextOption();
        updateSize();
    }
}

QDeclarativeTextEdit::HAlignment QDeclarativeTextEdit::effectiveHAlign() const
{
    Q_D(const QDeclarativeTextEdit);
    QDeclarativeTextEdit::HAlignment effectiveAlignment = d->hAlign;
    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
        switch (d->hAlign) {
        case QDeclarativeTextEdit::AlignLeft:
            effectiveAlignment = QDeclarativeTextEdit::AlignRight;
            break;
        case QDeclarativeTextEdit::AlignRight:
            effectiveAlignment = QDeclarativeTextEdit::AlignLeft;
            break;
        default:
            break;
        }
    }
    return effectiveAlignment;
}

bool QDeclarativeTextEditPrivate::setHAlign(QDeclarativeTextEdit::HAlignment alignment, bool forceAlign)
{
    Q_Q(QDeclarativeTextEdit);
    if (hAlign != alignment || forceAlign) {
        QDeclarativeTextEdit::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
        hAlign = alignment;
        emit q->horizontalAlignmentChanged(alignment);
        return true;
    }
    return false;
}

bool QDeclarativeTextEditPrivate::determineHorizontalAlignment()
{
    Q_Q(QDeclarativeTextEdit);
    if (hAlignImplicit && q->isComponentComplete()) {
        bool alignToRight = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : rightToLeftText;
        return setHAlign(alignToRight ? QDeclarativeTextEdit::AlignRight : QDeclarativeTextEdit::AlignLeft);
    }
    return false;
}

void QDeclarativeTextEditPrivate::mirrorChange()
{
    Q_Q(QDeclarativeTextEdit);
    if (q->isComponentComplete()) {
        if (!hAlignImplicit && (hAlign == QDeclarativeTextEdit::AlignRight || hAlign == QDeclarativeTextEdit::AlignLeft)) {
            updateDefaultTextOption();
            q->updateSize();
        }
    }
}

QDeclarativeTextEdit::VAlignment QDeclarativeTextEdit::vAlign() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->vAlign;
}

void QDeclarativeTextEdit::setVAlign(QDeclarativeTextEdit::VAlignment alignment)
{
    Q_D(QDeclarativeTextEdit);
    if (alignment == d->vAlign)
        return;
    d->vAlign = alignment;
    d->updateDefaultTextOption();
    updateSize();
    moveCursorDelegate();
    emit verticalAlignmentChanged(d->vAlign);
}

/*!
    \qmlproperty enumeration TextEdit::wrapMode

    Set this property to wrap the text to the TextEdit item's width.
    The text will only wrap if an explicit width has been set.

    \list
    \o TextEdit.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width.
    \o TextEdit.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width.
    \o TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
    \o TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
    \endlist

    The default is TextEdit.NoWrap. If you set a width, consider using TextEdit.Wrap.
*/
QDeclarativeTextEdit::WrapMode QDeclarativeTextEdit::wrapMode() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->wrapMode;
}

void QDeclarativeTextEdit::setWrapMode(WrapMode mode)
{
    Q_D(QDeclarativeTextEdit);
    if (mode == d->wrapMode)
        return;
    d->wrapMode = mode;
    d->updateDefaultTextOption();
    updateSize();
    emit wrapModeChanged();
}

/*!
    \qmlproperty int TextEdit::lineCount
    \since QtQuick 1.1

    Returns the total number of lines in the textEdit item.
*/
int QDeclarativeTextEdit::lineCount() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->lineCount;
}

/*!
    \qmlproperty real TextEdit::paintedWidth

    Returns the width of the text, including the width past the width
    which is covered due to insufficient wrapping if \l wrapMode is set.
*/
qreal QDeclarativeTextEdit::paintedWidth() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->paintedSize.width();
}

/*!
    \qmlproperty real TextEdit::paintedHeight

    Returns the height of the text, including the height past the height
    that is covered if the text does not fit within the set height.
*/
qreal QDeclarativeTextEdit::paintedHeight() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->paintedSize.height();
}

/*!
    \qmlmethod rectangle TextEdit::positionToRectangle(position)

    Returns the rectangle at the given \a position in the text. The x, y,
    and height properties correspond to the cursor that would describe
    that position.
*/
QRectF QDeclarativeTextEdit::positionToRectangle(int pos) const
{
    Q_D(const QDeclarativeTextEdit);
    QTextCursor c(d->document);
    c.setPosition(pos);
    return d->control->cursorRect(c);

}

/*!
    \qmlmethod int TextEdit::positionAt(int x, int y)

    Returns the text position closest to pixel position (\a x, \a y).

    Position 0 is before the first character, position 1 is after the first character
    but before the second, and so on until position \l {text}.length, which is after all characters.
*/
int QDeclarativeTextEdit::positionAt(int x, int y) const
{
    Q_D(const QDeclarativeTextEdit);
    int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
    QTextCursor cursor = d->control->textCursor();
    if (r > cursor.position()) {
        // The cursor position includes positions within the preedit text, but only positions in the
        // same text block are offset so it is possible to get a position that is either part of the
        // preedit or the next text block.
        QTextLayout *layout = cursor.block().layout();
        const int preeditLength = layout
                ? layout->preeditAreaText().length()
                : 0;
        if (preeditLength > 0
                && d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x,y-d->yoff)) {
            r = r > cursor.position() + preeditLength
                    ? r - preeditLength
                    : cursor.position();
        }
    }
    return r;
}

void QDeclarativeTextEdit::moveCursorSelection(int pos)
{
    //Note that this is the same as setCursorPosition but with the KeepAnchor flag set
    Q_D(QDeclarativeTextEdit);
    QTextCursor cursor = d->control->textCursor();
    if (cursor.position() == pos)
        return;
    cursor.setPosition(pos, QTextCursor::KeepAnchor);
    d->control->setTextCursor(cursor);
}

/*!
    \qmlmethod void TextEdit::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters)
    \since QtQuick 1.1

    Moves the cursor to \a position and updates the selection according to the optional \a mode
    parameter. (To only move the cursor, set the \l cursorPosition property.)

    When this method is called it additionally sets either the
    selectionStart or the selectionEnd (whichever was at the previous cursor position)
    to the specified position. This allows you to easily extend and contract the selected
    text range.

    The selection mode specifies whether the selection is updated on a per character or a per word
    basis.  If not specified the selection mode will default to TextEdit.SelectCharacters.

    \list
    \o TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
    the previous cursor position) to the specified position.
    \o TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
    words between the specified postion and the previous cursor position.  Words partially in the
    range are included.
    \endlist

    For example, take this sequence of calls:

    \code
        cursorPosition = 5
        moveCursorSelection(9, TextEdit.SelectCharacters)
        moveCursorSelection(7, TextEdit.SelectCharacters)
    \endcode

    This moves the cursor to position 5, extend the selection end from 5 to 9
    and then retract the selection end from 9 to 7, leaving the text from position 5 to 7
    selected (the 6th and 7th characters).

    The same sequence with TextEdit.SelectWords will extend the selection start to a word boundary
    before or on position 5 and extend the selection end to a word boundary on or past position 9.
*/
void QDeclarativeTextEdit::moveCursorSelection(int pos, SelectionMode mode)
{
    Q_D(QDeclarativeTextEdit);
    QTextCursor cursor = d->control->textCursor();
    if (cursor.position() == pos)
        return;
    if (mode == SelectCharacters) {
        cursor.setPosition(pos, QTextCursor::KeepAnchor);
    } else if (cursor.anchor() < pos || (cursor.anchor() == pos && cursor.position() < pos)) {
        if (cursor.anchor() > cursor.position()) {
            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
            if (cursor.position() == cursor.anchor())
                cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor);
            else
                cursor.setPosition(cursor.position(), QTextCursor::MoveAnchor);
        } else {
            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
        }

        cursor.setPosition(pos, QTextCursor::KeepAnchor);
        cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
        if (cursor.position() != pos)
            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
    } else if (cursor.anchor() > pos || (cursor.anchor() == pos && cursor.position() > pos)) {
        if (cursor.anchor() < cursor.position()) {
            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
        } else {
            cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
            if (cursor.position() != cursor.anchor()) {
                cursor.setPosition(cursor.anchor(), QTextCursor::MoveAnchor);
                cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
            }
        }

        cursor.setPosition(pos, QTextCursor::KeepAnchor);
        cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
        if (cursor.position() != pos) {
            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor);
            cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::KeepAnchor);
        }
    }
    d->control->setTextCursor(cursor);
}

/*!
    \qmlproperty bool TextEdit::cursorVisible
    If true the text edit shows a cursor.

    This property is set and unset when the text edit gets active focus, but it can also
    be set directly (useful, for example, if a KeyProxy might forward keys to it).
*/
bool QDeclarativeTextEdit::isCursorVisible() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->cursorVisible;
}

void QDeclarativeTextEdit::setCursorVisible(bool on)
{
    Q_D(QDeclarativeTextEdit);
    if (d->cursorVisible == on)
        return;
    d->cursorVisible = on;
    QFocusEvent focusEvent(on ? QEvent::FocusIn : QEvent::FocusOut);
    if (!on && !d->persistentSelection)
        d->control->setCursorIsFocusIndicator(true);
    d->control->processEvent(&focusEvent, QPointF(0, -d->yoff));
    emit cursorVisibleChanged(d->cursorVisible);
}

/*!
    \qmlproperty int TextEdit::cursorPosition
    The position of the cursor in the TextEdit.
*/
int QDeclarativeTextEdit::cursorPosition() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->textCursor().position();
}

void QDeclarativeTextEdit::setCursorPosition(int pos)
{
    Q_D(QDeclarativeTextEdit);
    if (pos < 0 || pos > d->text.length())
        return;
    QTextCursor cursor = d->control->textCursor();
    if (cursor.position() == pos && cursor.anchor() == pos)
        return;
    cursor.setPosition(pos);
    d->control->setTextCursor(cursor);
}

/*!
    \qmlproperty Component TextEdit::cursorDelegate
    The delegate for the cursor in the TextEdit.

    If you set a cursorDelegate for a TextEdit, 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 text edit when a cursor is
    needed, and the x and y properties 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 QDeclarativeItem or
    QDeclarativeItem derived item.
*/
QDeclarativeComponent* QDeclarativeTextEdit::cursorDelegate() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->cursorComponent;
}

void QDeclarativeTextEdit::setCursorDelegate(QDeclarativeComponent* c)
{
    Q_D(QDeclarativeTextEdit);
    if(d->cursorComponent){
        if(d->cursor){
            d->control->setCursorWidth(-1);
            dirtyCache(cursorRectangle());
            delete d->cursor;
            d->cursor = 0;
        }
    }
    d->cursorComponent = c;
    if(c && c->isReady()){
        loadCursorDelegate();
    }else{
        if(c)
            connect(c, SIGNAL(statusChanged()),
                    this, SLOT(loadCursorDelegate()));
    }

    emit cursorDelegateChanged();
}

void QDeclarativeTextEdit::loadCursorDelegate()
{
    Q_D(QDeclarativeTextEdit);
    if(d->cursorComponent->isLoading())
        return;
    d->cursor = qobject_cast<QDeclarativeItem*>(d->cursorComponent->create(qmlContext(this)));
    if(d->cursor){
        d->control->setCursorWidth(0);
        dirtyCache(cursorRectangle());
        QDeclarative_setParent_noEvent(d->cursor, this);
        d->cursor->setParentItem(this);
        d->cursor->setHeight(QFontMetrics(d->font).height());
        moveCursorDelegate();
    }else{
        qmlInfo(this) << "Error loading cursor delegate.";
    }
}

/*!
    \qmlproperty int TextEdit::selectionStart

    The cursor position before the first character in the current selection.

    This property is read-only. To change the selection, use select(start,end),
    selectAll(), or selectWord().

    \sa selectionEnd, cursorPosition, selectedText
*/
int QDeclarativeTextEdit::selectionStart() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->textCursor().selectionStart();
}

/*!
    \qmlproperty int TextEdit::selectionEnd

    The cursor position after the last character in the current selection.

    This property is read-only. To change the selection, use select(start,end),
    selectAll(), or selectWord().

    \sa selectionStart, cursorPosition, selectedText
*/
int QDeclarativeTextEdit::selectionEnd() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->textCursor().selectionEnd();
}

/*!
    \qmlproperty string TextEdit::selectedText

    This read-only property provides the text currently selected in the
    text edit.

    It is equivalent to the following snippet, but is faster and easier
    to use.
    \code
    //myTextEdit is the id of the TextEdit
    myTextEdit.text.toString().substring(myTextEdit.selectionStart,
            myTextEdit.selectionEnd);
    \endcode
*/
QString QDeclarativeTextEdit::selectedText() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->textCursor().selectedText();
}

/*!
    \qmlproperty bool TextEdit::activeFocusOnPress

    Whether the TextEdit should gain active focus on a mouse press. By default this is
    set to true.
*/
bool QDeclarativeTextEdit::focusOnPress() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->focusOnPress;
}

void QDeclarativeTextEdit::setFocusOnPress(bool on)
{
    Q_D(QDeclarativeTextEdit);
    if (d->focusOnPress == on)
        return;
    d->focusOnPress = on;
    emit activeFocusOnPressChanged(d->focusOnPress);
}

/*!
    \qmlproperty bool TextEdit::persistentSelection

    Whether the TextEdit should keep the selection visible when it loses active focus to another
    item in the scene. By default this is set to true;
*/
bool QDeclarativeTextEdit::persistentSelection() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->persistentSelection;
}

void QDeclarativeTextEdit::setPersistentSelection(bool on)
{
    Q_D(QDeclarativeTextEdit);
    if (d->persistentSelection == on)
        return;
    d->persistentSelection = on;
    emit persistentSelectionChanged(d->persistentSelection);
}

/*
   \qmlproperty real TextEdit::textMargin

   The margin, in pixels, around the text in the TextEdit.
*/
qreal QDeclarativeTextEdit::textMargin() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->textMargin;
}

void QDeclarativeTextEdit::setTextMargin(qreal margin)
{
    Q_D(QDeclarativeTextEdit);
    if (d->textMargin == margin)
        return;
    d->textMargin = margin;
    d->document->setDocumentMargin(d->textMargin);
    emit textMarginChanged(d->textMargin);
}

void QDeclarativeTextEdit::geometryChanged(const QRectF &newGeometry,
                                  const QRectF &oldGeometry)
{
    if (newGeometry.width() != oldGeometry.width())
        updateSize();
    QDeclarativePaintedItem::geometryChanged(newGeometry, oldGeometry);
}

/*!
    Ensures any delayed caching or data loading the class
    needs to performed is complete.
*/
void QDeclarativeTextEdit::componentComplete()
{
    Q_D(QDeclarativeTextEdit);
    QDeclarativePaintedItem::componentComplete();
    if (d->dirty) {
        d->determineHorizontalAlignment();
        d->updateDefaultTextOption();
        updateSize();
        d->dirty = false;
    }
}

/*!
    \qmlproperty bool TextEdit::selectByMouse

    Defaults to false.

    If true, the user can use the mouse to select text in some
    platform-specific way. Note that for some platforms this may
    not be an appropriate interaction (eg. may conflict with how
    the text needs to behave inside a Flickable.
*/
bool QDeclarativeTextEdit::selectByMouse() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->selectByMouse;
}

void QDeclarativeTextEdit::setSelectByMouse(bool on)
{
    Q_D(QDeclarativeTextEdit);
    if (d->selectByMouse != on) {
        d->selectByMouse = on;
        setKeepMouseGrab(on);
        if (on)
            setTextInteractionFlags(d->control->textInteractionFlags() | Qt::TextSelectableByMouse);
        else
            setTextInteractionFlags(d->control->textInteractionFlags() & ~Qt::TextSelectableByMouse);
        emit selectByMouseChanged(on);
    }
}


/*!
    \qmlproperty enum TextEdit::mouseSelectionMode
    \since QtQuick 1.1

    Specifies how text should be selected using a mouse.

    \list
    \o TextEdit.SelectCharacters - The selection is updated with individual characters. (Default)
    \o TextEdit.SelectWords - The selection is updated with whole words.
    \endlist

    This property only applies when \l selectByMouse is true.
*/

QDeclarativeTextEdit::SelectionMode QDeclarativeTextEdit::mouseSelectionMode() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->mouseSelectionMode;
}

void QDeclarativeTextEdit::setMouseSelectionMode(SelectionMode mode)
{
    Q_D(QDeclarativeTextEdit);
    if (d->mouseSelectionMode != mode) {
        d->mouseSelectionMode = mode;
        d->control->setWordSelectionEnabled(mode == SelectWords);
        emit mouseSelectionModeChanged(mode);
    }
}

/*!
    \qmlproperty bool TextEdit::readOnly

    Whether the user an interact with the TextEdit item. If this
    property is set to true the text cannot be edited by user interaction.

    By default this property is false.
*/
void QDeclarativeTextEdit::setReadOnly(bool r)
{
    Q_D(QDeclarativeTextEdit);
    if (r == isReadOnly())
        return;

    setFlag(QGraphicsItem::ItemAcceptsInputMethod, !r);

    Qt::TextInteractionFlags flags = Qt::LinksAccessibleByMouse;
    if (d->selectByMouse)
        flags = flags | Qt::TextSelectableByMouse;
    if (!r)
        flags = flags | Qt::TextSelectableByKeyboard | Qt::TextEditable;
    d->control->setTextInteractionFlags(flags);
    if (!r)
        d->control->moveCursor(QTextCursor::End);

    emit readOnlyChanged(r);
}

bool QDeclarativeTextEdit::isReadOnly() const
{
    Q_D(const QDeclarativeTextEdit);
    return !(d->control->textInteractionFlags() & Qt::TextEditable);
}

/*!
    Sets how the text edit should interact with user input to the given
    \a flags.
*/
void QDeclarativeTextEdit::setTextInteractionFlags(Qt::TextInteractionFlags flags)
{
    Q_D(QDeclarativeTextEdit);
    d->control->setTextInteractionFlags(flags);
}

/*!
    Returns the flags specifying how the text edit should interact
    with user input.
*/
Qt::TextInteractionFlags QDeclarativeTextEdit::textInteractionFlags() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->textInteractionFlags();
}

/*!
    \qmlproperty rectangle TextEdit::cursorRectangle

    The rectangle where the text cursor is rendered
    within the text edit. Read-only.
*/
QRect QDeclarativeTextEdit::cursorRectangle() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->cursorRect().toRect().translated(0,d->yoff);
}


/*!
\overload
Handles the given \a event.
*/
bool QDeclarativeTextEdit::event(QEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    if (event->type() == QEvent::ShortcutOverride) {
        d->control->processEvent(event, QPointF(0, -d->yoff));
        return event->isAccepted();
    }
    return QDeclarativePaintedItem::event(event);
}

/*!
\overload
Handles the given key \a event.
*/
void QDeclarativeTextEdit::keyPressEvent(QKeyEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    keyPressPreHandler(event);
    if (!event->isAccepted())
        d->control->processEvent(event, QPointF(0, -d->yoff));
    if (!event->isAccepted())
        QDeclarativePaintedItem::keyPressEvent(event);
}

/*!
\overload
Handles the given key \a event.
*/
void QDeclarativeTextEdit::keyReleaseEvent(QKeyEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    keyReleasePreHandler(event);
    if (!event->isAccepted())
        d->control->processEvent(event, QPointF(0, -d->yoff));
    if (!event->isAccepted())
        QDeclarativePaintedItem::keyReleaseEvent(event);
}

void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus)
{
    Q_Q(QDeclarativeTextEdit);
    q->setCursorVisible(hasFocus && scene && scene->hasFocus());
    QDeclarativeItemPrivate::focusChanged(hasFocus);
}

/*!
    \qmlmethod void TextEdit::deselect()
    \since QtQuick 1.1

    Removes active text selection.
*/
void QDeclarativeTextEdit::deselect()
{
    Q_D(QDeclarativeTextEdit);
    QTextCursor c = d->control->textCursor();
    c.clearSelection();
    d->control->setTextCursor(c);
}

/*!
    \qmlmethod void TextEdit::selectAll()

    Causes all text to be selected.
*/
void QDeclarativeTextEdit::selectAll()
{
    Q_D(QDeclarativeTextEdit);
    d->control->selectAll();
}

/*!
    \qmlmethod void TextEdit::selectWord()

    Causes the word closest to the current cursor position to be selected.
*/
void QDeclarativeTextEdit::selectWord()
{
    Q_D(QDeclarativeTextEdit);
    QTextCursor c = d->control->textCursor();
    c.select(QTextCursor::WordUnderCursor);
    d->control->setTextCursor(c);
}

/*!
    \qmlmethod void TextEdit::select(int start, int end)

    Causes the text from \a start to \a end to be selected.

    If either start or end is out of range, the selection is not changed.

    After calling this, selectionStart will become the lesser
    and selectionEnd will become the greater (regardless of the order passed
    to this method).

    \sa selectionStart, selectionEnd
*/
void QDeclarativeTextEdit::select(int start, int end)
{
    Q_D(QDeclarativeTextEdit);
    if (start < 0 || end < 0 || start > d->text.length() || end > d->text.length())
        return;
    QTextCursor cursor = d->control->textCursor();
    cursor.beginEditBlock();
    cursor.setPosition(start, QTextCursor::MoveAnchor);
    cursor.setPosition(end, QTextCursor::KeepAnchor);
    cursor.endEditBlock();
    d->control->setTextCursor(cursor);

    // QTBUG-11100
    updateSelectionMarkers();
}

/*!
    \qmlmethod void TextEdit::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 QDeclarativeTextEdit::isRightToLeft(int start, int end)
{
    Q_D(QDeclarativeTextEdit);
    if (start > end) {
        qmlInfo(this) << "isRightToLeft(start, end) called with the end property being smaller than the start.";
        return false;
    } else {
        return d->text.mid(start, end - start).isRightToLeft();
    }
}

#ifndef QT_NO_CLIPBOARD
/*!
    \qmlmethod TextEdit::cut()

    Moves the currently selected text to the system clipboard.
*/
void QDeclarativeTextEdit::cut()
{
    Q_D(QDeclarativeTextEdit);
    d->control->cut();
}

/*!
    \qmlmethod TextEdit::copy()

    Copies the currently selected text to the system clipboard.
*/
void QDeclarativeTextEdit::copy()
{
    Q_D(QDeclarativeTextEdit);
    d->control->copy();
}

/*!
    \qmlmethod TextEdit::paste()

    Replaces the currently selected text by the contents of the system clipboard.
*/
void QDeclarativeTextEdit::paste()
{
    Q_D(QDeclarativeTextEdit);
    d->control->paste();
}
#endif // QT_NO_CLIPBOARD

/*!
\overload
Handles the given mouse \a event.
*/
void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    if (d->focusOnPress){
        bool hadActiveFocus = hasActiveFocus();
        forceActiveFocus();
        if (d->showInputPanelOnFocus) {
            if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) {
                // re-open input panel on press if already focused
                openSoftwareInputPanel();
            }
        } else { // show input panel on click
            if (hasActiveFocus() && !hadActiveFocus) {
                d->clickCausedFocus = true;
            }
        }
    }

    d->control->processEvent(event, QPointF(0, -d->yoff));
    if (!event->isAccepted())
        QDeclarativePaintedItem::mousePressEvent(event);
}

/*!
\overload
Handles the given mouse \a event.
*/
void QDeclarativeTextEdit::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    d->control->processEvent(event, QPointF(0, -d->yoff));
    if (!d->showInputPanelOnFocus) { // input panel on click
        if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) {
            if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
                if (view->scene() && view->scene() == scene()) {
                    qt_widget_private(view)->handleSoftwareInputPanel(event->button(), d->clickCausedFocus);
                }
            }
        }
    }
    d->clickCausedFocus = false;

    if (!event->isAccepted())
        QDeclarativePaintedItem::mouseReleaseEvent(event);
}

/*!
\overload
Handles the given mouse \a event.
*/
void QDeclarativeTextEdit::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativeTextEdit);

    d->control->processEvent(event, QPointF(0, -d->yoff));
    if (!event->isAccepted())
        QDeclarativePaintedItem::mouseDoubleClickEvent(event);

}

/*!
\overload
Handles the given mouse \a event.
*/
void QDeclarativeTextEdit::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    d->control->processEvent(event, QPointF(0, -d->yoff));
    if (!event->isAccepted())
        QDeclarativePaintedItem::mouseMoveEvent(event);
}

/*!
\overload
Handles the given input method \a event.
*/
void QDeclarativeTextEdit::inputMethodEvent(QInputMethodEvent *event)
{
    Q_D(QDeclarativeTextEdit);
    const bool wasComposing = isInputMethodComposing();
    d->control->processEvent(event, QPointF(0, -d->yoff));
    if (wasComposing != isInputMethodComposing())
        emit inputMethodComposingChanged();
}

/*!
\overload
Returns the value of the given \a property.
*/
QVariant QDeclarativeTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
    Q_D(const QDeclarativeTextEdit);
    return d->control->inputMethodQuery(property);
}

/*!
Draws the contents of the text edit using the given \a painter within
the given \a bounds.
*/
void QDeclarativeTextEdit::drawContents(QPainter *painter, const QRect &bounds)
{
    Q_D(QDeclarativeTextEdit);

    painter->setRenderHint(QPainter::TextAntialiasing, true);
    painter->translate(0,d->yoff);

    d->control->drawContents(painter, bounds.translated(0,-d->yoff));

    painter->translate(0,-d->yoff);
}

void QDeclarativeTextEdit::updateImgCache(const QRectF &rf)
{
    Q_D(const QDeclarativeTextEdit);
    QRect r;
    if (!rf.isValid()) {
        r = QRect(0,0,INT_MAX,INT_MAX);
    } else {
        r = rf.toRect();
        if (r.height() > INT_MAX/2) {
            // Take care of overflow when translating "everything"
            r.setTop(r.y() + d->yoff);
            r.setBottom(INT_MAX/2);
        } else {
            r = r.translated(0,d->yoff);
        }
    }
    dirtyCache(r);
    emit update();
}

/*!
    \qmlproperty bool TextEdit::smooth

    This property holds whether the text is 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.
*/

/*!
    \qmlproperty bool TextEdit::canPaste
    \since QtQuick 1.1

    Returns true if the TextEdit is writable and the content of the clipboard is
    suitable for pasting into the TextEdit.
*/
bool QDeclarativeTextEdit::canPaste() const
{
    Q_D(const QDeclarativeTextEdit);
    return d->canPaste;
}

/*!
    \qmlproperty bool TextEdit::inputMethodComposing

    \since QtQuick 1.1

    This property holds whether the TextEdit has partial text input from an
    input method.

    While it is composing an input method may rely on mouse or key events from
    the TextEdit to edit or commit the partial text.  This property can be used
    to determine when to disable events handlers that may interfere with the
    correct operation of an input method.
*/
bool QDeclarativeTextEdit::isInputMethodComposing() const
{
    Q_D(const QDeclarativeTextEdit);
    if (QTextLayout *layout = d->control->textCursor().block().layout())
        return layout->preeditAreaText().length() > 0;
    return false;
}

void QDeclarativeTextEditPrivate::init()
{
    Q_Q(QDeclarativeTextEdit);

    q->setSmooth(smooth);
    q->setAcceptedMouseButtons(Qt::LeftButton);
    q->setFlag(QGraphicsItem::ItemHasNoContents, false);
    q->setFlag(QGraphicsItem::ItemAcceptsInputMethod);

    control = new QTextControl(q);
    control->setIgnoreUnusedNavigationEvents(true);
    control->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextEditable);
    control->setDragEnabled(false);

    // QTextControl follows the default text color
    // defined by the platform, declarative text
    // should be black by default
    QPalette pal = control->palette();
    if (pal.color(QPalette::Text) != color) {
        pal.setColor(QPalette::Text, color);
        control->setPalette(pal);
    }

    QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateImgCache(QRectF)));

    QObject::connect(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
    QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
    QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
    QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
    QObject::connect(control, SIGNAL(microFocusChanged()), q, SLOT(moveCursorDelegate()));
    QObject::connect(control, SIGNAL(linkActivated(QString)), q, SIGNAL(linkActivated(QString)));
#ifndef QT_NO_CLIPBOARD
    QObject::connect(q, SIGNAL(readOnlyChanged(bool)), q, SLOT(q_canPasteChanged()));
    QObject::connect(QApplication::clipboard(), SIGNAL(dataChanged()), q, SLOT(q_canPasteChanged()));
    canPaste = control->canPaste();
#endif

    document = control->document();
    document->setDefaultFont(font);
    document->setDocumentMargin(textMargin);
    document->setUndoRedoEnabled(false); // flush undo buffer.
    document->setUndoRedoEnabled(true);
    updateDefaultTextOption();
}

void QDeclarativeTextEdit::q_textChanged()
{
    Q_D(QDeclarativeTextEdit);
    d->text = text();
    d->rightToLeftText = d->document->begin().layout()->engine()->isRightToLeft();
    d->determineHorizontalAlignment();
    d->updateDefaultTextOption();
    updateSize();
    updateTotalLines();
    emit textChanged(d->text);
}

void QDeclarativeTextEdit::moveCursorDelegate()
{
    Q_D(QDeclarativeTextEdit);
    updateMicroFocus();
    emit cursorRectangleChanged();
    if(!d->cursor)
        return;
    QRectF cursorRect = cursorRectangle();
    d->cursor->setX(cursorRect.x());
    d->cursor->setY(cursorRect.y());
}

void QDeclarativeTextEditPrivate::updateSelection()
{
    Q_Q(QDeclarativeTextEdit);
    QTextCursor cursor = control->textCursor();
    bool startChange = (lastSelectionStart != cursor.selectionStart());
    bool endChange = (lastSelectionEnd != cursor.selectionEnd());
    cursor.beginEditBlock();
    cursor.setPosition(lastSelectionStart, QTextCursor::MoveAnchor);
    cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor);
    cursor.endEditBlock();
    control->setTextCursor(cursor);
    if(startChange)
        q->selectionStartChanged();
    if(endChange)
        q->selectionEndChanged();
}

void QDeclarativeTextEdit::updateSelectionMarkers()
{
    Q_D(QDeclarativeTextEdit);
    if(d->lastSelectionStart != d->control->textCursor().selectionStart()){
        d->lastSelectionStart = d->control->textCursor().selectionStart();
        emit selectionStartChanged();
    }
    if(d->lastSelectionEnd != d->control->textCursor().selectionEnd()){
        d->lastSelectionEnd = d->control->textCursor().selectionEnd();
        emit selectionEndChanged();
    }
}

QRectF QDeclarativeTextEdit::boundingRect() const
{
    Q_D(const QDeclarativeTextEdit);
    QRectF r = QDeclarativePaintedItem::boundingRect();
    int cursorWidth = 1;
    if(d->cursor)
        cursorWidth = d->cursor->width();
    if(!d->document->isEmpty())
        cursorWidth += 3;// ### Need a better way of accounting for space between char and cursor

    // Could include font max left/right bearings to either side of rectangle.

    r.setRight(r.right() + cursorWidth);
    return r.translated(0,d->yoff);
}

qreal QDeclarativeTextEditPrivate::implicitWidth() const
{
    Q_Q(const QDeclarativeTextEdit);
    if (!requireImplicitWidth) {
        // We don't calculate implicitWidth unless it is required.
        // We need to force a size update now to ensure implicitWidth is calculated
        const_cast<QDeclarativeTextEditPrivate*>(this)->requireImplicitWidth = true;
        const_cast<QDeclarativeTextEdit*>(q)->updateSize();
    }
    return mImplicitWidth;
}

//### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't
//    need to do all the calculations each time
void QDeclarativeTextEdit::updateSize()
{
    Q_D(QDeclarativeTextEdit);
    if (isComponentComplete()) {
        qreal naturalWidth = d->mImplicitWidth;
        // ### assumes that if the width is set, the text will fill to edges
        // ### (unless wrap is false, then clipping will occur)
        if (widthValid()) {
            if (!d->requireImplicitWidth) {
                emit implicitWidthChanged();
                // if the implicitWidth is used, then updateSize() has already been called (recursively)
                if (d->requireImplicitWidth)
                    return;
            }
            if (d->requireImplicitWidth) {
                d->document->setTextWidth(-1);
                naturalWidth = d->document->idealWidth();
            }
            if (d->document->textWidth() != width())
                d->document->setTextWidth(width());
        } else {
            d->document->setTextWidth(-1);
        }
        QFontMetrics fm = QFontMetrics(d->font);
        int dy = height();
        dy -= (int)d->document->size().height();

        int nyoff;
        if (heightValid()) {
            if (d->vAlign == AlignBottom)
                nyoff = dy;
            else if (d->vAlign == AlignVCenter)
                nyoff = dy/2;
            else
                nyoff = 0;
        } else {
            nyoff = 0;
        }
        if (nyoff != d->yoff) {
            prepareGeometryChange();
            d->yoff = nyoff;
        }
        setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);

        //### need to comfirm cost of always setting these
        int newWidth = qCeil(d->document->idealWidth());
        if (!widthValid() && d->document->textWidth() != newWidth)
            d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug)
        // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed.
        if (!widthValid())
            setImplicitWidth(newWidth);
        else if (d->requireImplicitWidth)
            setImplicitWidth(naturalWidth);
        qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height();
        setImplicitHeight(newHeight);

        d->paintedSize = QSize(newWidth, newHeight);
        setContentsSize(d->paintedSize);
        emit paintedSizeChanged();
    } else {
        d->dirty = true;
    }
    emit update();
}

void QDeclarativeTextEdit::updateTotalLines()
{
    Q_D(QDeclarativeTextEdit);

    int subLines = 0;

    for (QTextBlock it = d->document->begin(); it != d->document->end(); it = it.next()) {
        QTextLayout *layout = it.layout();
        if (!layout)
            continue;
        subLines += layout->lineCount()-1;
    }

    int newTotalLines = d->document->lineCount() + subLines;
    if (d->lineCount != newTotalLines) {
        d->lineCount = newTotalLines;
        emit lineCountChanged();
    }
}

void QDeclarativeTextEditPrivate::updateDefaultTextOption()
{
    Q_Q(QDeclarativeTextEdit);
    QTextOption opt = document->defaultTextOption();
    int oldAlignment = opt.alignment();

    QDeclarativeTextEdit::HAlignment horizontalAlignment = q->effectiveHAlign();
    if (rightToLeftText) {
        if (horizontalAlignment == QDeclarativeTextEdit::AlignLeft)
            horizontalAlignment = QDeclarativeTextEdit::AlignRight;
        else if (horizontalAlignment == QDeclarativeTextEdit::AlignRight)
            horizontalAlignment = QDeclarativeTextEdit::AlignLeft;
    }
    opt.setAlignment((Qt::Alignment)(int)(horizontalAlignment | vAlign));

    QTextOption::WrapMode oldWrapMode = opt.wrapMode();
    opt.setWrapMode(QTextOption::WrapMode(wrapMode));

    if (oldWrapMode == opt.wrapMode() && oldAlignment == opt.alignment())
        return;
    document->setDefaultTextOption(opt);
}


/*!
    \qmlmethod void TextEdit::openSoftwareInputPanel()

    Opens software input panels like virtual keyboards for typing, useful for
    customizing when you want the input keyboard to be shown and hidden in
    your application.

    By default the opening of input panels follows the platform style. On Symbian^1 and
    Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms
    the panels are automatically opened when TextEdit element gains active focus. Input panels are
    always closed if no editor has active focus.

    You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
    the behavior you want.

    Only relevant on platforms, which provide virtual keyboards.

    \code
        import QtQuick 1.0
        TextEdit {
            id: textEdit
            text: "Hello world!"
            activeFocusOnPress: false
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    if (!textEdit.activeFocus) {
                        textEdit.forceActiveFocus();
                        textEdit.openSoftwareInputPanel();
                    } else {
                        textEdit.focus = false;
                    }
                }
                onPressAndHold: textEdit.closeSoftwareInputPanel();
            }
        }
    \endcode
*/
void QDeclarativeTextEdit::openSoftwareInputPanel()
{
    QEvent event(QEvent::RequestSoftwareInputPanel);
    if (qApp) {
        if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
            if (view->scene() && view->scene() == scene()) {
                QApplication::sendEvent(view, &event);
            }
        }
    }
}

/*!
    \qmlmethod void TextEdit::closeSoftwareInputPanel()

    Closes a software input panel like a virtual keyboard shown on the screen, useful
    for customizing when you want the input keyboard to be shown and hidden in
    your application.

    By default the opening of input panels follows the platform style. On Symbian^1 and
    Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms
    the panels are automatically opened when TextEdit element gains active focus. Input panels are
    always closed if no editor has active focus.

    You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
    and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
    the behavior you want.

    Only relevant on platforms, which provide virtual keyboards.

    \code
        import QtQuick 1.0
        TextEdit {
            id: textEdit
            text: "Hello world!"
            activeFocusOnPress: false
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    if (!textEdit.activeFocus) {
                        textEdit.forceActiveFocus();
                        textEdit.openSoftwareInputPanel();
                    } else {
                        textEdit.focus = false;
                    }
                }
                onPressAndHold: textEdit.closeSoftwareInputPanel();
            }
        }
    \endcode
*/
void QDeclarativeTextEdit::closeSoftwareInputPanel()
{
    QEvent event(QEvent::CloseSoftwareInputPanel);
    if (qApp) {
        if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
            if (view->scene() && view->scene() == scene()) {
                QApplication::sendEvent(view, &event);
            }
        }
    }
}

void QDeclarativeTextEdit::focusInEvent(QFocusEvent *event)
{
    Q_D(const QDeclarativeTextEdit);
    if (d->showInputPanelOnFocus) {
        if (d->focusOnPress && !isReadOnly()) {
            openSoftwareInputPanel();
        }
    }
    QDeclarativePaintedItem::focusInEvent(event);
}

void QDeclarativeTextEdit::q_canPasteChanged()
{
    Q_D(QDeclarativeTextEdit);
    bool old = d->canPaste;
    d->canPaste = d->control->canPaste();
    if(old!=d->canPaste)
        emit canPasteChanged();
}

QT_END_NAMESPACE
