src/hbwidgets/editors/hbabstractedit.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbwidgets/editors/hbabstractedit.cpp	Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,1681 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbWidgets module of the UI Extensions for Mobile.
+**
+** 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbabstractedit.h"
+#include "hbabstractedit_p.h"
+
+#include "hbvalidator.h"
+#include "hbstyle.h"
+#include "hbstyleoption.h"
+#include "hbwidget.h"
+#include "hbscrollarea.h"
+#include "hbevent.h"
+#include <hbwidgetfeedback.h>
+#include "hbmenu.h"
+#include "hbaction.h"
+#include "hbselectioncontrol_p.h"
+#include "hbmeshlayout_p.h"
+#include "hbsmileyengine.h"
+#include "hbinputeditorinterface.h"
+
+#include <QApplication>
+#include "hbpopup.h"
+#include "hbformatdialog.h"
+#include <QTextList>
+#include <QFontMetrics>
+#include <QGraphicsSceneMouseEvent>
+#include <QPainter>
+#include <QTextBlock>
+#include <QAbstractTextDocumentLayout>
+#include <QClipboard>
+#include <QInputContext>
+
+/*!
+    \class HbAbstractEdit
+    \brief HbAbstractEdit is a base class for all text editors.
+    @proto
+    @hbwidgets
+
+    This is not mentioned as a class to be used directly. All editors inherit this and
+    basic functionality is in this class.
+
+    It uses \ref QTextDocument internally to handle the content. And in some editors the document is also exposed to direct access and manipulation.
+
+    \section functionality Functionality this class provides
+
+    \li Editor content: The editor is set read-only with method \ref setReadOnly. Content changes emit a \ref contentsChanged signal.
+
+    \li Cursor position and visibility:  Cursor position can be set with slot \ref setCursorPosition and 
+    read with method \ref cursorPosition(). It is also a property. Cursor position changes emit a \ref cursorPositionChanged signal. 
+    Cursor visibility can be controlled with \ref setCursorVisibility.
+
+    \li Editing: There is a group of useful methods for editing the content. Clipboard functionality can be found 
+    in \ref cut, \ref copy and \paste.  Finishing editing emits a \ref editingFinished signal and text changes 
+    emit a \ref textChanged signal. 
+
+    \li Selection handling: Whenever there is a interactive selection special handles are shown which can be used to manipulate the selection. 
+    Selection changes emit a \ref selectionChanged signal.
+
+    \li Anchor support: Anchors are strings associated to some a content in editor. There are two \ref anchorAt methods to access the anchors. 
+    When user invokes an anchor it will open a context menu that may contain operations related to the anchor item (e.g. creating calls 
+    for phone numbers, opening a web browser for web-addresses, etc.). This is always application specific functionality. 
+    Editor itself does not create any anchors by examining the content.
+
+    There is also protected API in HbAbstractEdit. Some of these API methods can be exposed as public in more specific editor widgets.
+
+    \li Editor content:  Both rich text and plain text are supported in HbAbstractEdit. Depending on the actual 
+    editor widget only one or the other type might be supported. Plain text content is set with 
+    method \ref setPlainText. Method \ref toPlainText returns the content converted to plain text. 
+
+    \li Focus control: Editor is responsble for controlling the input panel visibility. In some situations special editor may need to also handle this, but in general it is always handled by HbAbstractEdit. 
+    Input panel is closed when editor loses focus.
+
+    \li Cursor control: A convenience method \ref moveCursor can also be used to move the cursor.
+
+    \li Scrolling: When e.g. the size of the content exceeds the size of editor, method \ref setScrollable
+    can be used to make the editor scrollable. Method isScrollable tells whether the editor is scrollable or not. 
+    Method scrollArea returns the used scroll area widget. Scrolling is enabled by default.
+
+    \li Input validation: The validator for restricting the content input is set with method \ref setValidator. Only \ref HbValidator
+    based validators can be used.
+
+    \section composition Widget composition
+
+    Editor widget consists of these sub-items visible in the picture. 
+    In this example editor shows only one visible line of the content.
+
+    \image html editor_composition.jpg
+
+    The size of the canvas is always same as the size of the document, and the width of the scroll area 
+    is same as the width of the document. The editor margins are defined in the CSS.
+
+*/
+
+/*!
+    \fn void HbAbstractEdit::contentsChanged()
+
+    This signal is emitted whenever the text changes. The text argument is the new text.
+    This signal is also emitted when the text is changed programmatically, for example,
+    by calling setPlainText().
+*/
+
+/*!
+    \fn void HbAbstractEdit::selectionChanged(const QTextCursor &oldCursor, const QTextCursor &newCursor)
+
+    This signal is emitted whenever the selection changes. */
+
+/*!
+    \fn void HbAbstractEdit::cursorPositionChanged(int oldPos, int newPos)
+
+    This signal is emitted when cursor position has been changed.
+*/
+
+/*!
+    \fn QString HbAbstractEdit::toPlainText() const
+
+    Returns the contents as plain text.
+
+    \sa QTextDocument::toPlainText()
+*/
+
+#define Hb_Invalid_Position QPointF(-1.0, -1.0)
+
+/*!
+    Constructs a HbAbstractEdit with parent \a parent.
+ */
+HbAbstractEdit::HbAbstractEdit(QGraphicsItem *parent) :
+    HbWidget(*new HbAbstractEditPrivate, parent)
+{
+    Q_D(HbAbstractEdit);
+    d->q_ptr = this;
+
+    d->init();
+}
+
+/*!
+    Constructs a HbAbstractEdit with abstract edit private object \a dd and parent \a parent.
+ */
+HbAbstractEdit::HbAbstractEdit(HbAbstractEditPrivate &dd, QGraphicsItem *parent) :
+    HbWidget(dd, parent)
+{
+    Q_D(HbAbstractEdit);
+    d->q_ptr = this;
+
+    d->init();
+}
+
+/*!
+    Destructor.
+*/
+HbAbstractEdit::~HbAbstractEdit()
+{
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::resizeEvent(QGraphicsSceneResizeEvent *event)
+{    
+    HbWidget::resizeEvent(event);
+    updatePrimitives();
+}
+
+/*!
+    \reimp
+*/
+bool HbAbstractEdit::event(QEvent* event)
+{
+    if(event->type() ==  QEvent::DynamicPropertyChange) {
+        const QString p = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName();
+        if(p == "SmileyIcon") {
+            Q_D(HbAbstractEdit);
+            QString iconName = property("SmileyIcon").toString();
+
+            HbSmileyTheme smileyTheme = d->smileyEngineInstance()->theme();
+
+            QString pattern = smileyTheme.patterns(iconName).first();
+
+            QTextCursor cursor = textCursor();
+            int oldPos = cursor.position();
+
+            cursor.insertText(pattern);
+            setTextCursor(cursor);
+
+            QTextCursor matchCursor(document());
+            matchCursor.setPosition(oldPos);
+            d->smileyEngineInstance()->insertSmiley(matchCursor);
+
+            d->cursorChanged(HbValidator::CursorChangeFromContentUpdate);
+        }
+    }
+    return HbWidget::event(event);
+}
+
+/*!
+    \reimp
+*/
+bool HbAbstractEdit::eventFilter(QObject *obj, QEvent *e)
+{
+    Q_D(HbAbstractEdit);
+
+    if (obj == d->scrollArea
+        && (e->type() == QEvent::GraphicsSceneMousePress
+        || e->type() == QEvent::GraphicsSceneMouseMove
+        || e->type() == QEvent::GraphicsSceneMouseRelease)) {
+
+        // map e->pos to the editor's coordinate system
+        QGraphicsSceneMouseEvent *event = static_cast<QGraphicsSceneMouseEvent*>(e);
+        QPointF oldPos = event->pos();
+        event->setPos(mapFromItem(d->scrollArea,oldPos));
+        bool ret = sceneEvent(e);
+        event->setPos(oldPos);
+        return ret;
+    }
+
+    return false;
+}
+
+QVariant HbAbstractEdit::inputMethodQuery (Qt::InputMethodQuery query) const
+{
+    Q_D(const HbAbstractEdit);
+
+    QTextBlock block = d->cursor.block();
+    switch(query) {
+    case Qt::ImMicroFocus:
+        return d->cursorRect();
+    case Qt::ImFont:
+        return QVariant(d->cursor.charFormat().font());
+    case Qt::ImCursorPosition:
+        return QVariant(d->cursor.position() - block.position());
+    case Qt::ImSurroundingText:
+        return QVariant(block.text());
+    case Qt::ImCurrentSelection:
+        return QVariant(d->cursor.selectedText());
+    default:
+        return QVariant();
+    }
+}
+
+void HbAbstractEdit::inputMethodEvent (QInputMethodEvent *e)
+{
+    Q_D(HbAbstractEdit);
+    
+    
+    if (!(d->interactionFlags & Qt::TextEditable) || d->cursor.isNull()) {
+        e->ignore();
+        return;
+    }
+
+    QTextBlock block = d->cursor.block();
+    QTextLayout *layout = block.layout();
+
+    bool isGettingInput = !e->commitString().isEmpty()
+            || e->preeditString() != layout->preeditAreaText()
+            || e->replacementLength() > 0;
+
+    d->cursor.beginEditBlock();
+
+    if (isGettingInput) {
+        if (!d->imEditInProgress) {
+            d->imEditInProgress = true;
+            d->imPosition = d->selectionCursor.selectionStart();
+            d->imRemoved = d->selectionCursor.selectionEnd() - d->selectionCursor.selectionStart();
+        }
+
+        d->selectionCursor.removeSelectedText();
+    }
+
+    // insert commit string
+    if (!e->commitString().isEmpty() || e->replacementLength()) {
+        QTextCursor c = d->cursor;
+        c.setPosition(c.position() + e->replacementStart());
+        c.setPosition(c.position() + e->replacementLength(), QTextCursor::KeepAnchor);
+        QString commitString = e->commitString();
+        c.insertText(commitString, d->nextCharCursor.charFormat());
+        d->imAdded = commitString.length();
+    }
+
+    if (isGettingInput) {
+        layout->setPreeditArea(d->cursor.position() - block.position(), e->preeditString());
+    }
+
+    QList<QTextLayout::FormatRange> overrides;
+    d->preeditCursor = e->preeditString().length();
+
+    d->preeditCursorVisible = true;
+    for (int i = 0; i < e->attributes().size(); ++i) {
+        const QInputMethodEvent::Attribute &a = e->attributes().at(i);
+        if (a.type == QInputMethodEvent::Cursor) {
+            d->preeditCursor = a.start;
+            d->preeditCursorVisible = a.length;
+        } else if (a.type == QInputMethodEvent::TextFormat) {
+            QTextCharFormat f = qvariant_cast<QTextFormat>(a.value).toCharFormat();
+            if (f.isValid()) {
+                QTextLayout::FormatRange o;
+                o.start = a.start + d->cursor.position() - block.position();
+                o.length = a.length;
+                o.format = f;
+                overrides.append(o);
+            }
+        }
+    }
+    layout->setAdditionalFormats(overrides);
+
+    d->acceptSignalContentsChange = false;
+    d->acceptSignalContentsChanged = false;
+    d->cursor.endEditBlock();
+    d->acceptSignalContentsChange = true;
+    d->acceptSignalContentsChanged = true;
+
+    d->cursorChanged(HbValidator::CursorChangeFromContentUpdate);
+
+    // Input method editing is done
+    if (!e->commitString().isEmpty() || e->replacementLength()) {
+        d->imEditInProgress = false;
+        d->imPosition = e->replacementStart();
+        d->imAdded = e->commitString().length();
+        d->imRemoved =  e->replacementLength();
+        d->_q_contentsChanged();
+    }
+
+    if(hasFocus()) {
+        d->cursorOn = true;
+    }
+    d->ensureCursorVisible();
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::keyPressEvent(QKeyEvent *event)
+{
+    Q_D(HbAbstractEdit);
+
+    if (d->interactionFlags & Qt::NoTextInteraction)
+        return;
+
+#ifndef QT_NO_SHORTCUT
+#ifndef QT_NO_CLIPBOARD
+    if (event == QKeySequence::Copy) {
+        event->accept();
+        copy();
+        return;
+    }
+    else if (event == QKeySequence::Cut) {
+        cut();
+        d->acceptKeyPressEvent(event);
+        return;
+    }
+    else if (event == QKeySequence::Paste) {
+        paste();
+        d->acceptKeyPressEvent(event);
+        return;
+    }
+#endif
+#endif // QT_NO_SHORTCUT
+
+    if (d->interactionFlags & Qt::TextSelectableByKeyboard
+        && d->cursorMoveKeyEvent(event))
+        d->acceptKeyPressEvent(event);
+
+    if (!(d->interactionFlags & Qt::TextEditable)) {
+        d->repaintOldAndNewSelection(d->selectionCursor);
+        d->cursorChanged(HbValidator::CursorChangeFromContentUpdate);
+        //ensureCursorVisible();
+        event->ignore();
+        return;
+    }
+
+    if (event->key() == Qt::Key_Direction_L || event->key() == Qt::Key_Direction_R) {
+        QTextBlockFormat fmt;
+        fmt.setLayoutDirection((event->key() == Qt::Key_Direction_L) ? Qt::LeftToRight : Qt::RightToLeft);
+        d->cursor.mergeBlockFormat(fmt);
+        d->acceptKeyPressEvent(event);
+    }
+
+    // schedule a repaint of the region of the cursor, as when we move it we
+    // want to make sure the old cursor disappears (not noticeable when moving
+    // only a few pixels but noticeable when jumping between cells in tables for
+    // example)
+    d->repaintOldAndNewSelection(QTextCursor());
+
+    if (event->key() == Qt::Key_Backspace && !(event->modifiers() & ~Qt::ShiftModifier)) {
+        QTextBlockFormat blockFmt = d->cursor.blockFormat();
+        QTextList *list = d->cursor.currentList();
+        if (list && d->cursor.atBlockStart()) {
+            list->remove(d->cursor.block());
+        } else if (d->cursor.atBlockStart() && blockFmt.indent() > 0) {
+            blockFmt.setIndent(blockFmt.indent() - 1);
+            d->cursor.setBlockFormat(blockFmt);
+        } else if (d->selectionCursor.hasSelection()) {
+            d->selectionCursor.removeSelectedText();
+        } else {
+            QTextCursor oldCursor(d->cursor);
+            oldCursor.deletePreviousChar();
+        }
+        d->ensureCursorVisible();
+    }
+#ifndef QT_NO_SHORTCUT
+      else if (event == QKeySequence::InsertParagraphSeparator) {
+        d->cursor.insertBlock();
+        d->acceptKeyPressEvent(event);
+    } else if (event == QKeySequence::InsertLineSeparator) {
+        d->cursor.insertText(QString(QChar::LineSeparator));
+        d->acceptKeyPressEvent(event);
+    }
+#endif
+    if (false) {
+    }
+#ifndef QT_NO_SHORTCUT
+      else if (event == QKeySequence::Delete) {
+        d->cursor.deleteChar();
+        d->acceptKeyPressEvent(event);
+    } else if (event == QKeySequence::DeleteEndOfWord) {
+        d->cursor.movePosition(QTextCursor::NextWord, QTextCursor::KeepAnchor);
+        d->cursor.removeSelectedText();
+        d->acceptKeyPressEvent(event);
+    } else if (event == QKeySequence::DeleteStartOfWord) {
+        d->cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::KeepAnchor);
+        d->cursor.removeSelectedText();
+        d->acceptKeyPressEvent(event);
+    } else if (event == QKeySequence::DeleteEndOfLine) {
+        QTextBlock block = d->cursor.block();
+        if (d->cursor.position() == block.position() + block.length() - 2) {
+            d->cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor);
+        } else {
+            d->cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+        }
+        d->cursor.removeSelectedText();
+        d->acceptKeyPressEvent(event);
+    }
+#endif // QT_NO_SHORTCUT
+    else {
+
+    QString text = event->text();
+    if (!text.isEmpty()
+        && (text.at(0).isPrint()
+        || text.at(0) == QLatin1Char('\t')
+        || (d->scrollable
+        && (text.at(0) == QLatin1Char('\n')
+        || text.at(0) == QLatin1Char('\r'))))) {
+            d->cursor.insertText(text, d->nextCharCursor.charFormat());
+            d->acceptKeyPressEvent(event);
+        }
+    }
+
+    d->cursorChanged(HbValidator::CursorChangeFromContentUpdate);
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::keyReleaseEvent (QKeyEvent *event)
+{   
+    event->accept();
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_D(HbAbstractEdit);
+
+    if (d->selectionControl) {
+        d->selectionControl->panStarted();
+    }
+
+    if (d->interactionFlags & Qt::NoTextInteraction)
+        return;
+
+    if (!(event->button() & Qt::LeftButton))
+        return;
+
+    if (!((d->interactionFlags & Qt::TextSelectableByMouse) || (d->interactionFlags & Qt::TextEditable)))
+        return;
+
+    d->mousePressPos = event->pos();
+    d->wasGesture = false;
+
+    HbWidgetFeedback::triggered(this, Hb::InstantPressed);
+
+//    d->minimizeInputPanel();
+
+    event->accept();
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_UNUSED(event)
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+    Q_D(HbAbstractEdit);
+
+    if (d->selectionControl) {
+        d->selectionControl->panFinished();
+    }
+    if (d->wasGesture) return;
+
+    if (d->interactionFlags & Qt::NoTextInteraction)
+        return;
+
+    if (d->mousePressPos != Hb_Invalid_Position) {
+        d->mousePressPos = Hb_Invalid_Position;
+
+        bool removeSelection = (d->hitTest(event->pos(), Qt::ExactHit) == -1);
+
+        if (removeSelection && d->cursor.hasSelection()) {
+            const QTextCursor oldCursor = d->cursor;
+            d->cursor.clearSelection();
+            d->repaintOldAndNewSelection(oldCursor);
+            emit selectionChanged(oldCursor, d->cursor);
+        }
+
+        int newCursorPos = d->hitTest(event->pos(), Qt::FuzzyHit);
+
+        if (d->cursor.hasSelection() &&
+            newCursorPos >= d->cursor.selectionStart() &&
+            newCursorPos <= d->cursor.selectionEnd()){
+            // we have a selection under mouse click
+            if (d->contextMenuShownOn.testFlag(Hb::ShowTextContextMenuOnSelectionClicked)) {
+                showContextMenu(mapToScene(event->pos()));
+            }
+        } else {
+
+            // Currently focused widget to listen to InputContext before updating the cursor position
+            d->sendMouseEventToInputContext(event);
+            setCursorPosition(newCursorPos);
+
+            HbWidgetFeedback::triggered(this, Hb::InstantReleased);
+
+            if (d->interactionFlags & Qt::TextEditable) {
+                d->updateCurrentCharFormat();
+            }
+            d->cursorChanged(HbValidator::CursorChangeFromMouse);
+        }
+    }
+
+    d->openInputPanel();
+
+    event->accept();
+}
+
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::focusInEvent(QFocusEvent *event)
+{
+    HbWidget::focusInEvent(event);
+
+    Q_D(HbAbstractEdit);
+
+    if (d->interactionFlags & Qt::NoTextInteraction)
+        return;
+
+    update(d->selectionRect());
+
+    if (d->interactionFlags & Qt::TextEditable) {
+        d->setBlinkingCursorEnabled(true);
+    } else {
+        d->cursorOn = (d->interactionFlags & Qt::TextSelectableByKeyboard);
+    }
+
+    d->openInputPanel();
+
+    event->accept();
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::focusOutEvent(QFocusEvent *event)
+{
+    HbWidget::focusOutEvent(event);
+
+    Q_D(HbAbstractEdit);
+
+    if (d->interactionFlags & Qt::NoTextInteraction)
+        return;
+
+    d->setBlinkingCursorEnabled(false);
+    d->repaintOldAndNewSelection(d->selectionCursor);
+
+    event->accept();
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::changeEvent (QEvent *event)
+{
+    Q_D(HbAbstractEdit);
+    HbWidget::changeEvent(event);
+
+    switch (event->type()) {
+        case QEvent::FontChange: {
+            d->doc->setDefaultFont(font());
+            updateGeometry();
+            break;
+        }
+        case QEvent::LayoutDirectionChange: {
+            QTextOption textOption = d->doc->defaultTextOption();
+            textOption.setTextDirection(layoutDirection());
+            d->doc->setDefaultTextOption(textOption);
+            if (d->selectionControl) {
+                d->selectionControl->updatePrimitives();
+            }
+            break;
+        }
+        default: {
+            if ( event->type() == HbEvent::ThemeChanged ) {
+                d->updatePaletteFromTheme();
+                updatePrimitives();
+                if (d->selectionControl) {
+                    d->selectionControl->updatePrimitives();
+                }
+            }
+            break;
+        }
+    }
+}
+
+/*!
+    \reimp
+ */
+void HbAbstractEdit::hideEvent(QHideEvent *event)
+{
+    HbWidget::hideEvent(event);
+
+    deselect();
+
+#if QT_VERSION >= 0x040600
+    // Send close input panel event.
+    QInputContext *ic = qApp->inputContext();
+    if (ic && !panel()) {
+        QEvent *closeEvent = new QEvent(QEvent::CloseSoftwareInputPanel);
+        ic->filterEvent(closeEvent);
+        delete closeEvent;
+    }
+#endif
+}
+
+
+
+/*!
+    Returns the cursor position.
+
+    Returned cursor position is a QTextDocucument index for the cursor
+    visible on the screen.
+
+    \sa setCursorPosition
+ */
+int HbAbstractEdit::cursorPosition () const
+{
+    Q_D(const HbAbstractEdit);
+    return d->cursor.position();
+}
+
+/*!
+    Sets the cursor postions to \a pos. If \a pos is greater than the length of the content
+    the cursor is set to the end of the text.
+
+    Additionally it is possible to create selection using \a mode QTextCursor::KeepAnchor.
+
+    \sa cursorPosition
+ */
+void HbAbstractEdit::setCursorPosition (int pos, QTextCursor::MoveMode mode)
+{
+    Q_D(HbAbstractEdit);
+    if (d->cursor.position() != pos) {
+        d->setCursorPosition(pos, mode);
+    }
+}
+
+/*!
+    Returns the cursor visibility mode.
+
+    \sa setCursorVisibility
+ */
+Hb::TextCursorVisibility HbAbstractEdit::cursorVisibility () const
+{
+    Q_D(const HbAbstractEdit);
+    return d->isCursorVisible() ? Hb::TextCursorVisible : Hb::TextCursorHidden;
+}
+
+/*!
+    Sets the cursor visibility mode to given \a value.
+
+    In a hidden mode the cursor is always at the end of the inputted content.
+    User can't change the position of the cursor, or select the content.
+
+    \sa cursorVisibility
+ */
+void HbAbstractEdit::setCursorVisibility (Hb::TextCursorVisibility value)
+{
+    Q_D(HbAbstractEdit);
+    bool b = (value == Hb::TextCursorVisible);
+    if (d->apiCursorVisible != b) {
+        d->apiCursorVisible = b;
+        d->repaintOldAndNewSelection(QTextCursor());
+    }
+}
+
+/*!
+    Returns true if edit is in read-only mode; otherwise return false.
+
+    \sa setReadOnly
+ */
+bool HbAbstractEdit::isReadOnly () const
+{
+    Q_D(const HbAbstractEdit);
+
+    return !(d->interactionFlags & Qt::TextEditable);
+}
+
+/*!
+    Sets edit's read-only mode to given \a value. In a read-only text edit the user
+    can only navigate through the text and select text; modifying the text
+    is not possible.
+
+    In read-only mode text can be set using setPlainText() or setHtml().
+
+    \sa isReadOnly
+ */
+void HbAbstractEdit::setReadOnly (bool value)
+{
+    Q_D(HbAbstractEdit);
+    Qt::TextInteractionFlags f = d->interactionFlags;
+
+    if (f.testFlag(Qt::TextEditable) != value) {
+        return;
+    }
+
+    f ^= Qt::TextEditable;
+
+    d->setTextInteractionFlags(f);
+
+    setFlag(QGraphicsItem::ItemAcceptsInputMethod, !value);
+}
+
+/*!
+    Returns pointer to a \a primitive of HbAbstractEdit.
+
+    Available primitive is HbStyle::P_Edit_text.
+
+    \reimp
+    \sa HbStyle::Primitive, HbWidget::primitive()
+*/
+QGraphicsItem *HbAbstractEdit::primitive (HbStyle::Primitive primitive) const
+{
+    Q_D(const HbAbstractEdit);
+
+    if (primitive == HbStyle::P_Edit_text) {
+        return d->scrollArea;
+    } else {
+        return HbWidget::primitive(primitive);
+    }
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::updatePrimitives()
+{
+    Q_D(HbAbstractEdit);
+    HbWidget::updatePrimitives();
+
+    if (d->scrollArea) {
+        d->doc->setTextWidth(d->scrollArea->size().width());
+    }
+    QRectF canvasGeom(QRectF(QPointF(0,0),d->doc->size()));
+    if(d->scrollArea && canvasGeom.height()<d->scrollArea->size().height()) {
+        canvasGeom.setHeight(d->scrollArea->size().height());
+    }
+    d->canvas->setGeometry(canvasGeom);
+    if (d->scrollArea) {
+        d->scrollArea->updateScrollMetrics();
+    }
+    d->ensureCursorVisible();
+}
+
+/*!
+    Replaces editor content with \a text.
+
+    HbAbstractEdit does not support richtext from cut, copy & paste
+    operations after setPlainText() has been called.
+
+    If smiley recognition is enabled the textual smiley patterns are replaced
+    with the corresponding image from the active smiley theme.
+
+    \sa setSmileysEnabled()
+*/
+void HbAbstractEdit::setPlainText(const QString &text)
+{
+    Q_D(HbAbstractEdit);
+    d->setContent(Qt::PlainText, text);
+}
+
+/*!
+    Replaces editor content with HTML-formatted string \a text.
+
+    If smiley recognition is enabled the textual smiley patterns are replaced
+    with the corresponding image from the active smiley theme.
+
+    \sa setSmileysEnabled()
+
+    \note It is the responsibility of the caller to make sure that the text
+    is correctly decoded when a QString containing HTML is created and passed to setHtml().
+*/
+void HbAbstractEdit::setHtml(const QString &text)
+{
+    Q_D(HbAbstractEdit);
+    d->setContent(Qt::RichText, text);
+}
+
+/*!
+     \internal
+     This is the cursor blinking timer.
+     \reimp
+ */
+void HbAbstractEdit::timerEvent(QTimerEvent *e)
+{
+    Q_D(HbAbstractEdit);
+
+    if (e->timerId() == d->cursorBlinkTimer.timerId()) {
+        d->cursorOn = !d->cursorOn;
+
+        if (d->cursor.hasSelection())
+            d->cursorOn &= (QApplication::style()->styleHint(QStyle::SH_BlinkCursorWhenTextSelected) != 0);
+
+        d->repaintCursor();
+    }
+}
+
+/*!
+    This is a slot for listening a signal with a same name from QTextDocument.
+    When creating custom editor this slot can be overridden but this base implementation
+    should be called.
+
+    \sa QTextDocument::documentLayoutChanged()
+*/
+void HbAbstractEdit::documentLayoutChanged()
+{
+    Q_D(HbAbstractEdit);
+
+    QAbstractTextDocumentLayout *layout = d->doc->documentLayout();
+    QObject::connect(layout, SIGNAL(update(QRectF)), this, SLOT(_q_updateRequest(QRectF)));
+    QObject::connect(layout, SIGNAL(updateBlock(QTextBlock)), this, SLOT(_q_updateBlock(QTextBlock)));
+    QObject::connect(layout, SIGNAL(documentSizeChanged(QSizeF)), this, SLOT(documentSizeChanged(QSizeF)));
+
+    updatePrimitives();
+}
+
+/*!
+    This is a slot for listening a signal with a same name from QTextDocument.
+    When creating custom editor this slot can be overridden but this base implementation
+    should be called.
+
+    \sa QTextDocument::documentSizeChanged(QSizeF size)
+*/
+void HbAbstractEdit::documentSizeChanged(const QSizeF &size)
+{
+    Q_UNUSED(size)
+    updateGeometry();
+    updatePrimitives();
+}
+
+/*!
+    Replaces the QTextDocument that is inside the editor.
+*/
+void HbAbstractEdit::setDocument(QTextDocument *document)
+{
+    Q_D(HbAbstractEdit);
+    if (d->doc == document)
+        return;
+    d->removeCurrentDocument();
+    d->connectToNewDocument(document);
+}
+
+/*!
+    Returns the QTextDocument currently in use.
+*/
+QTextDocument *HbAbstractEdit::document() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->doc;
+}
+
+/*!
+    Replaces the QTextCursor that is currently in use.
+    \sa textCursor
+*/
+void HbAbstractEdit::setTextCursor(const QTextCursor &cursor)
+{
+    Q_D(HbAbstractEdit);
+
+    // QTextCursor operator!= compares only position
+    if (    cursor.position() != d->cursor.position()
+        ||  cursor.anchor() != d->cursor.anchor() ) {
+        const QTextCursor oldCursor = d->cursor;
+        d->cursor = cursor;
+
+        d->updateCurrentCharFormat();
+
+        d->ensureCursorVisible();
+        d->repaintOldAndNewSelection(oldCursor);
+        d->cursorChanged(HbValidator::CursorChangeFromContentSet);
+    }
+}
+
+/*!
+    Returns the QTextCursor currently in use.
+    \sa setTextCursor
+ */
+QTextCursor HbAbstractEdit::textCursor() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->cursor;
+}
+
+/*!
+    Adds content which is currently selected in editor to clipboard and
+    deletes the content from editor.
+
+    When clipboad is not available this method does nothing.
+
+    \sa copy paste
+ */
+void HbAbstractEdit::cut()
+{
+#ifndef QT_NO_CLIPBOARD
+    Q_D(HbAbstractEdit);
+    if (!(d->interactionFlags & Qt::TextEditable) || !d->cursor.hasSelection())
+        return;
+    copy();
+    d->cursor.removeSelectedText();
+#endif//QT_NO_CLIPBOARD
+}
+
+/*!
+    Adds content which is currently selected in editor to clipboard.
+
+    When clipboad is not available this method does nothing.
+
+    \sa cut paste
+ */
+void HbAbstractEdit::copy()
+{
+#ifndef QT_NO_CLIPBOARD
+    Q_D(HbAbstractEdit);
+    if (!d->cursor.hasSelection() || !d->canCopy())
+        return;
+    QMimeData *data = createMimeDataFromSelection();
+    QApplication::clipboard()->setMimeData(data);
+#endif//QT_NO_CLIPBOARD
+}
+
+/*!
+    Inserts the content from clipboard to current cursor position in editor.
+    If there is a selection, the selection is replaced with the pasted content.
+
+    When clipboad is not available this method does nothing.
+
+    \sa cut copy
+ */
+void HbAbstractEdit::paste()
+{
+#ifndef QT_NO_CLIPBOARD
+    Q_D(HbAbstractEdit);
+    if (d->canPaste()) {
+        d->prepDocForPaste();
+        const QMimeData *md = QApplication::clipboard()->mimeData();
+        if (md) {
+            insertFromMimeData(md);
+        }
+    }
+
+#endif//QT_NO_CLIPBOARD
+}
+
+/*!
+    Selects the word under the cursor in the editor.
+    Word selection rules comes from QTextCursor::WordUnderCursor.
+    \sa selectAll deselect
+*/
+void HbAbstractEdit::selectClickedWord()
+{
+    Q_D(HbAbstractEdit);
+
+    int cursorPos = d->hitTest(d->mousePressPos, Qt::FuzzyHit);
+
+    if (cursorPos == -1)
+        return;
+
+    setCursorPosition(cursorPos);
+    const QTextCursor oldSelection = d->cursor;
+    d->cursor.select(QTextCursor::WordUnderCursor);
+    emit selectionChanged(oldSelection, d->cursor);
+    d->repaintOldAndNewSelection(oldSelection);
+    d->cursorChanged(HbValidator::CursorChangeFromMouse);
+    //TODO: focus is in VKB so needs to re-focus to editor
+//    setFocus();
+}
+
+/*!
+    Selects all the text in the editor.
+    \sa selectClickedWord deselect
+ */
+void HbAbstractEdit::selectAll()
+{
+    Q_D(HbAbstractEdit);
+    const QTextCursor oldSelection = d->cursor;
+    d->cursor.select(QTextCursor::Document);
+    emit selectionChanged(oldSelection, d->cursor);
+    d->repaintOldAndNewSelection(oldSelection);
+    d->cursorChanged(HbValidator::CursorChangeFromMouse);
+}
+
+/*!
+    Deselects the text in the editor if there is text selected.
+    \sa selectClickedWord selectAll
+ */
+void HbAbstractEdit::deselect()
+{
+    Q_D(HbAbstractEdit);
+    const QTextCursor oldSelection = d->cursor;
+    d->cursor.clearSelection();
+    emit selectionChanged(oldSelection, d->cursor);
+}
+
+/*!
+    Launches the format user interface.
+ */
+void HbAbstractEdit::format()
+{
+    Q_D(HbAbstractEdit);
+    if (d->formatDialog) {
+        d->formatDialog->launch(this);
+    }
+}
+
+/*!
+    This function returns a new MIME data object to represent the
+    contents of the text edit's current selection.
+
+    It is called when the selection needs to be encapsulated into a new
+    QMimeData object; for example when data is copyied to the clipboard.
+
+    Ownership of QMimeData is passed to caller.
+*/
+QMimeData *HbAbstractEdit::createMimeDataFromSelection() const
+{
+    Q_D(const HbAbstractEdit);
+    const QTextDocumentFragment fragment(d->cursor);
+    return new HbAbstractEditMimeData(fragment);
+}
+
+/*!
+    This function returns true if the contents of the MIME data object,
+    specified by source, can be decoded and inserted into the document.
+ */
+bool HbAbstractEdit::canInsertFromMimeData(const QMimeData *source) const
+{
+    return (source->hasText() && !source->text().isEmpty())
+        || source->hasHtml()
+        || source->hasFormat(QLatin1String("application/x-qrichtext"))
+        || source->hasFormat(QLatin1String("application/x-qt-richtext"));
+}
+
+/*!
+    This function inserts the contents of the MIME data object,
+    specified by \a source, into the text edit at the current cursor
+    position.
+
+    It is called for example when text is inserted as the result
+    of a clipboard paste operation.
+ */
+void HbAbstractEdit::insertFromMimeData(const QMimeData *source)
+{
+    Q_D(HbAbstractEdit);
+    if (!(d->interactionFlags & Qt::TextEditable) || !source)
+        return;
+
+    bool hasData = false;
+    QTextDocumentFragment fragment;
+#ifndef QT_NO_TEXTHTMLPARSER
+    if (source->hasFormat(QLatin1String("application/x-qrichtext"))) {
+        QString richtext = QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext")));
+        richtext.prepend(QLatin1String("<meta name=\"qrichtext\" content=\"1\" />"));
+        fragment = QTextDocumentFragment::fromHtml(richtext, d->doc);
+        hasData = true;
+    } else if (source->hasHtml()) {
+        fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc);
+        hasData = true;
+    } else
+#endif //QT_NO_TEXTHTMLPARSER
+    {
+        QString text = source->text();
+        if (!text.isNull()) {
+            fragment = QTextDocumentFragment::fromPlainText(text);
+            hasData = true;
+        }
+    }
+
+    if (hasData) {
+        d->cursor.insertFragment(fragment);
+    }
+    d->ensureCursorVisible();
+}
+
+/*!
+    Returns the calculated rect in item coordinates of the editor for the the given \a position inside a document.
+ */
+QRectF HbAbstractEdit::rectForPosition(int position, QTextLine::Edge edge) const
+{
+    Q_D(const HbAbstractEdit);
+
+    QRectF rect  = d->rectForPositionInCanvasCoords(position, edge);
+    rect = mapRectFromItem(d->canvas,rect);
+    return rect;
+}
+
+/*!
+    Returns the contents as plain text. If smiley recognition is enabled
+    all the smiley images will be replaced by their textual representations.
+
+    \sa QTextDocument::toPlainText() setSmileysEnabled()
+*/
+QString HbAbstractEdit::toPlainText() const
+{
+    Q_D(const HbAbstractEdit);
+    QString retVal;
+    if(isSmileysEnabled()) {
+        retVal = d->smileyEngineInstance()->toPlainText();
+    } else {
+        retVal = d->doc->toPlainText();
+    }
+    return retVal;
+}
+
+/*!
+    Returns the contents as HTML formatted string. If smiley recognition is enabled
+    all the smiley images will be replaced by their textual representations.
+
+    \sa QTextDocument::toHtml() setSmileysEnabled()
+*/
+QString HbAbstractEdit::toHtml() const
+{
+    Q_D(const HbAbstractEdit);
+    QString retVal;
+    if(isSmileysEnabled()) {
+        retVal = d->smileyEngineInstance()->toHtml();
+    } else {
+        retVal = d->doc->toHtml();
+    }
+    return retVal;
+}
+
+/*!
+    Validator is used to validate the content and cursor movements.
+
+    \note Validator uses undo stack to back out invalid changes. Therefore undo
+    is enabled when validator is set.
+ */
+void HbAbstractEdit::setValidator(HbValidator* validator)
+{
+    Q_D(HbAbstractEdit);
+
+    if(d->validator) {
+        delete d->validator;
+        d->validator = 0;
+    }
+
+    if(validator) {
+        d->validator = validator;
+        d->initValidator();
+    }
+}
+
+/*!
+    \property QLineEdit::acceptableInput
+    This property holds whether the input satisfies the validator.
+
+    By default, this property is true.
+
+    \sa setValidator()
+*/
+bool HbAbstractEdit::hasAcceptableInput() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->hasAcceptableInput();
+}
+
+/*!
+    Convenience method to manipulate cursor position.
+    \sa QTextCursor::movePosition()
+ */
+void HbAbstractEdit::moveCursor(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode)
+{
+    Q_D(HbAbstractEdit);
+    //const QTextCursor oldCursor = d->cursor;
+    d->cursor.movePosition(op, mode);
+
+    d->updateCurrentCharFormat();
+
+    d->ensureCursorVisible();
+    QTextCursor previousCursor(d->cursor);
+    previousCursor.setPosition(d->previousCursorAnchor);
+    previousCursor.setPosition(d->previousCursorPosition, QTextCursor::KeepAnchor);
+    d->repaintOldAndNewSelection(previousCursor);
+    d->cursorChanged(HbValidator::CursorChangeFromOperation);
+}
+
+/*!
+    Returns the bounding rect for given text block.
+
+    \sa QAbstractTextDocumentLayout::blockBoundingRect(const QTextBlock& block)
+ */
+QRectF HbAbstractEdit::blockBoundingRect(const QTextBlock &block) const
+{
+    Q_D(const HbAbstractEdit);
+    return d->doc->documentLayout()->blockBoundingRect(block);
+}
+
+/*!
+    This is a slot for listening a signal with a same name from QTextDocument.
+    When creating custom editor this slot can be overridden but this base implementation
+    should be called.
+
+    \sa QTextDocument::blockCountChanged(int newBlockCount)
+*/
+void HbAbstractEdit::blockCountChanged(int newBlockCount)
+{
+    Q_UNUSED(newBlockCount);
+
+    updatePrimitives();
+}
+
+/*!
+    Returns true if the content is scrollable.
+ */
+bool HbAbstractEdit::isScrollable() const
+{
+    Q_D(const HbAbstractEdit);
+
+    return d->scrollable;
+}
+
+/*!
+    Sets the editor as scrollable if \a value is true; othetwise edit is set as non-scrollable.
+*/
+void HbAbstractEdit::setScrollable(bool value)
+{
+    Q_D(HbAbstractEdit);
+    if (value != d->scrollable) {
+        d->scrollable = value;
+//            d->scrollArea->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
+    }
+}
+
+/*!
+    Content of the editor can be drawn to some outside widget by supplying \a painter and \a option.
+    This is used be the HbStyle system.
+ */
+void HbAbstractEdit::drawContents(QPainter *painter, const QStyleOptionGraphicsItem &option)
+{
+    Q_D(HbAbstractEdit);
+#ifdef HB_DEBUG_EDITOR_DRAW_RECTS
+    painter->setPen(Qt::green);
+    /*for(QTextBlock tb = d->doc->begin(); tb.isValid(); tb=tb.next()) {
+        painter->drawRect(blockBoundingRect(tb));
+    }*/
+    painter->drawRect(d->doc->documentLayout()->frameBoundingRect(
+        d->doc->rootFrame()).adjusted(2,2,-2,-2));
+    painter->setOpacity(0.3);
+    painter->setPen(Qt::blue);
+    painter->drawRect(d->cursorRect());
+    painter->setOpacity(1.0);
+#endif
+
+    QAbstractTextDocumentLayout::PaintContext ctx = d->getPaintContext();
+    if (option.exposedRect.isValid())
+        painter->setClipRect(option.exposedRect, Qt::IntersectClip);
+    ctx.clip = option.exposedRect;
+
+    d->drawContentBackground(painter, option);
+    document()->documentLayout()->draw(painter, ctx);
+    // Draw the pins for the selection handle
+    d->drawSelectionEdges(painter, ctx);
+
+#ifdef HB_DEBUG_EDITOR_HANDLES
+    QRectF a = rectForPosition(d->cursor.anchor());
+    QRectF c = rectForPosition(d->cursor.position());
+
+    painter->setPen(Qt::blue);
+    painter->drawRect(a);
+    painter->setPen(Qt::green);
+    painter->drawRect(c);
+    painter->setPen(Qt::red);
+    painter->drawRect(d->cursorRect());
+#endif
+}
+
+/*!
+    Returns the used scroll area if edit is set as scrollable;
+    otherwise returns null pointer.
+*/
+HbScrollArea *HbAbstractEdit::scrollArea() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->scrollArea;
+}
+
+/*!
+    Creates a context menu. Default implementation returns 0.
+*/
+HbMenu* HbAbstractEdit::createContextMenu()
+{
+    return 0;
+}
+
+/*!
+    Shows context menu at given \a position. Inheriting class can implement its own context menu instance using createContextMenu function. 
+
+    These actions are added to the context menu when appropriate: cut, copy, paste, select, select all, deselect, format.
+
+    \sa createContextMenu
+*/
+void HbAbstractEdit::showContextMenu(QPointF position)
+{
+    Q_D(HbAbstractEdit);
+    HbMenu *menu = createContextMenu();
+
+    if (!menu) {
+        menu = new HbMenu();
+    }
+
+    menu->setAttribute(Hb::InputMethodNeutral);
+
+    if (d->cursor.hasSelection() && d->canCopy()) {
+        connect(
+            menu->addAction("Cut"), SIGNAL(triggered()),
+            this, SLOT(cut()));
+        connect(
+            menu->addAction("Copy"), SIGNAL(triggered()),
+            this, SLOT(copy()));
+    }
+    else if (!d->doc->isEmpty() && d->canCopy()){
+        connect(
+            menu->addAction("Select"), SIGNAL(triggered()),
+            this, SLOT(selectClickedWord()));
+        connect(
+            menu->addAction("Select all"), SIGNAL(triggered()),
+            this, SLOT(selectAll()));
+    }
+    if (d->canPaste()) {
+        connect(
+            menu->addAction("Paste"), SIGNAL(triggered()), 
+            this, SLOT(paste()));
+    }
+    if (d->cursor.hasSelection()) {
+        connect(
+            menu->addAction("Deselect"), SIGNAL(triggered()), 
+            this, SLOT(deselect()));
+    }
+    if (d->canFormat()) {
+        connect(
+            menu->addAction("Format"), SIGNAL(triggered()), 
+            this, SLOT(format()));
+    }
+
+    emit aboutToShowContextMenu(menu, d->mousePressPos);
+
+    d->minimizeInputPanel();
+
+    if(menu->actions().count() > 0){
+        menu->setPreferredPos(position);
+        menu->show();
+    }
+}
+
+/*!
+    Returns the validator currently in use.
+
+    \sa setValidator HbValidator
+*/
+HbValidator *HbAbstractEdit::validator() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->validator;
+}
+
+/*!
+    \reimp
+*/
+int HbAbstractEdit::type() const
+{
+    return Type;
+}
+
+/*!
+    \reimp
+*/
+void HbAbstractEdit::updateGeometry()
+{
+    Q_D(HbAbstractEdit);
+    d->updateEditingSize();
+    HbWidget::updateGeometry();
+}
+/*!
+    Sets text alignment to \a alignment to the current text cursor.
+
+    \sa alignment textCursor setTextCursor
+*/
+void HbAbstractEdit::setAlignment(Qt::Alignment alignment)
+{
+    Q_D(HbAbstractEdit);
+    d->acceptSignalContentsChanged = false; // no text content changes.
+    QTextBlockFormat fmt;
+    fmt.setAlignment(alignment);
+    QTextCursor cursor = d->cursor;
+    cursor.mergeBlockFormat(fmt);
+    d->acceptSignalContentsChanged = true;
+    setTextCursor(cursor);
+    d->mApiProtectionFlags |= HbWidgetBasePrivate::AC_TextAlign;
+}
+
+/*!
+    Returns text alignment at the current text cursor.
+
+    \sa setAlignment()
+*/
+Qt::Alignment HbAbstractEdit::alignment() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->cursor.blockFormat().alignment();
+
+}
+
+/*!
+    Returns current flags describing on which events context menu is shown
+
+    \sa Hb::TextContextMenuFlag
+ */
+Hb::TextContextMenuFlags HbAbstractEdit::contextMenuFlags() const
+{
+    Q_D(const HbAbstractEdit);
+
+    return d->contextMenuShownOn;
+}
+
+/*!
+    Sets \a flags describing on which events context menu is shown
+    \sa Hb::TextContextMenuFlag
+ */
+void HbAbstractEdit::setContextMenuFlags(Hb::TextContextMenuFlags flags)
+{
+    Q_D(HbAbstractEdit);
+    d->contextMenuShownOn = flags;
+}
+
+/*!
+    Sets single \a flag on which event context menu is shown
+    (other flags remain unchanged)
+    \sa Hb::TextContextMenuFlag
+ */
+void HbAbstractEdit::setContextMenuFlag(Hb::TextContextMenuFlag flag)
+{
+    Q_D(HbAbstractEdit);
+    d->contextMenuShownOn|=flag;
+}
+
+/*!
+    Clears single \a flag on which event context menu is shown
+    (other flags remain unchanged)
+    \sa Hb::TextContextMenuFlag
+ */
+void HbAbstractEdit::clearContextMenuFlag(Hb::TextContextMenuFlag flag)
+{
+    Q_D(HbAbstractEdit);
+    d->contextMenuShownOn&=~flag;
+}
+
+/*!
+    Returns the reference of the anchor at the given position,
+    or an empty string if no anchor exists at that point.
+ */
+QString HbAbstractEdit::anchorAt(const QPointF &pos) const
+{
+    Q_D(const HbAbstractEdit);
+    return d->doc->documentLayout()->anchorAt(pos);
+}
+
+/*!
+    Returns the reference of the anchor the given cursor position,
+    or an empty string if no anchor exists at that position.
+ */
+QString HbAbstractEdit::anchorAt(int pos) const
+{
+    Q_D(const HbAbstractEdit);
+    QTextCursor newCursor = QTextCursor(d->doc);
+    newCursor.setPosition(pos);
+    newCursor.movePosition(QTextCursor::NextCharacter);
+    return newCursor.charFormat().anchorHref();
+}
+
+/*!
+    Sets the smiley theme to be used with the editor.
+    \sa HbSmileyTheme smileyTheme()
+ */
+void HbAbstractEdit::setSmileyTheme(const HbSmileyTheme& theme)
+{
+    Q_D(HbAbstractEdit);
+    d->smileyEngineInstance()->setTheme(theme);
+
+    HbEditorInterface editorInterface(this);
+    editorInterface.setSmileyTheme(theme);
+}
+
+
+/*!
+    Returns the smiley theme which is used by the editor.
+    \sa HbSmileyTheme setSmileyTheme()
+ */
+HbSmileyTheme HbAbstractEdit::smileyTheme() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->smileyEngineInstance()->theme();
+}
+
+/*!
+    Returns the default smiley theme.
+    \sa HbSmileyTheme resetSmileyTheme()
+ */
+HbSmileyTheme HbAbstractEdit::defaultSmileyTheme() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->smileyEngineInstance()->defaultTheme();
+}
+
+/*!
+    Convenience method to reset the smiley theme to the default.
+    \sa HbSmileyTheme defaultSmileyTheme()
+ */
+void HbAbstractEdit::resetSmileyTheme()
+{
+    HbSmileyTheme theme = defaultSmileyTheme();
+    setSmileyTheme(theme);
+    HbEditorInterface editorInterface(this);
+    editorInterface.setSmileyTheme(theme);
+
+}
+
+/*!
+    Activates or deactivates the smiley recognition in the editor.
+    \sa HbLineEdit::setText() HbLineEdit::text()
+    \sa HbTextEdit::setPlainText() HbTextEdit::toPlainText()
+    \sa HbTextEdit::setHtml() HbTextEdit::toHtml()
+ */
+void HbAbstractEdit::setSmileysEnabled(bool enabled)
+{
+    Q_D(HbAbstractEdit);
+    if(d->smileysEnabled != enabled) {
+        d->smileysEnabled = enabled;
+        HbEditorInterface editorInterface(this);
+        if(enabled) {
+            editorInterface.setSmileyTheme(d->smileyEngineInstance()->theme());
+        } else {
+            editorInterface.setSmileyTheme(HbSmileyTheme());
+        }
+    }
+}
+
+/*!
+    Return true if smiley recognition is enabled in the editor otherwise returns false.
+ */
+bool HbAbstractEdit::isSmileysEnabled() const
+{
+    Q_D(const HbAbstractEdit);
+    return d->smileysEnabled;
+}
+
+/*!
+    Sets the format dialog for the editor. If it is set zero no format menu item shown 
+ */
+void HbAbstractEdit::setFormatDialog(HbFormatDialogPointer dialog)
+{
+    Q_D(HbAbstractEdit);
+    d->formatDialog = dialog;
+}
+
+/*!
+    \reimp
+ */
+void HbAbstractEdit::polish( HbStyleParameters& params )
+{
+    Q_D(HbAbstractEdit);
+    const QString KTextAlignmentCSSName = "text-align";
+    const QString KTextColorCSSName = "color";
+
+    // ------ adding css parameters ------
+    params.addParameter(KTextAlignmentCSSName);
+
+    QPalette cssPalette = palette();
+    params.addParameter(KTextColorCSSName, cssPalette.color(QPalette::Text));
+
+    HbWidget::polish(params);
+
+    // ------ interpreting css parameters ------
+    QVariant param = params.value(KTextAlignmentCSSName);
+    if(param.canConvert(QVariant::String)) {
+        Qt::Alignment align = HbAbstractEditPrivate::alignmentFromString(param.toString());
+        if( align != 0 ) {
+            if (!(d->mApiProtectionFlags & HbWidgetBasePrivate::AC_TextAlign)) {
+                setAlignment(align);
+                d->mApiProtectionFlags &= ~HbWidgetBasePrivate::AC_TextAlign;
+            }
+        } else {
+            qWarning("Unable to read CSS parameter \"text-alignment\" in editor");
+        }
+    }
+
+    param = params.value(KTextColorCSSName);
+    if(param.canConvert(QVariant::Color)) {
+        cssPalette.setColor(QPalette::Text, param.value<QColor>());
+    }
+
+    setPalette(cssPalette);
+}
+
+/*!
+    \reimp
+ */
+QVariant HbAbstractEdit::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+    Q_D(const HbAbstractEdit);
+    if (change == QGraphicsItem::ItemScenePositionHasChanged) {
+        if (d->selectionControl) {
+            d->selectionControl->updatePrimitives();
+        }
+    }
+    return HbWidget::itemChange(change, value);
+}
+
+/*!
+  Returns the character at position pos, or a null character if the position is out of range.
+*/
+QChar HbAbstractEdit::characterAt(int pos) const
+{
+    return document()->characterAt(pos);
+}