Remove "All rights reserved" line from license headers.
[profile/ivi/qtdeclarative.git] / src / qtquick1 / graphicsitems / qdeclarativetextinput.cpp
index 271595a..32dd65e 100644 (file)
@@ -1,8 +1,7 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
 **
 ** This file is part of the QtDeclarative module of the Qt Toolkit.
 **
@@ -35,6 +34,7 @@
 **
 **
 **
+**
 ** $QT_END_LICENSE$
 **
 ****************************************************************************/
@@ -48,6 +48,7 @@
 #include <QValidator>
 #include <QTextCursor>
 #include <QApplication>
+#include <QtGui/QInputPanel>
 #include <QFontMetrics>
 #include <QPainter>
 #include <QTextBoundaryFinder>
@@ -413,7 +414,11 @@ bool QDeclarative1TextInputPrivate::determineHorizontalAlignment()
     if (hAlignImplicit) {
         // if no explicit alignment has been set, follow the natural layout direction of the text
         QString text = control->text();
-        bool isRightToLeft = text.isEmpty() ? QApplication::keyboardInputDirection() == Qt::RightToLeft : text.isRightToLeft();
+        if (text.isEmpty())
+            text = control->preeditAreaText();
+        bool isRightToLeft = text.isEmpty()
+                ? qApp->inputPanel()->inputDirection() == Qt::RightToLeft
+                : text.isRightToLeft();
         return setHAlign(isRightToLeft ? QDeclarative1TextInput::AlignRight : QDeclarative1TextInput::AlignLeft);
     }
     return false;
@@ -556,7 +561,7 @@ QRect QDeclarative1TextInput::cursorRectangle() const
     Q_D(const QDeclarative1TextInput);
     QRect r = d->control->cursorRect();
     // Scroll and make consistent with TextEdit
-    // QLineControl inexplicably adds 1 to the height and horizontal padding
+    // QWidgetLineControl inexplicably adds 1 to the height and horizontal padding
     // for unicode direction markers.
     r.adjust(5 - d->hscroll, 0, -4 - d->hscroll, -1);
     return r;
@@ -900,7 +905,7 @@ void QDeclarative1TextInput::setEchoMode(QDeclarative1TextInput::EchoMode echo)
     Q_D(QDeclarative1TextInput);
     if (echoMode() == echo)
         return;
-    d->control->setEchoMode((QLineControl::EchoMode)echo);
+    d->control->setEchoMode(echo);
     d->updateInputMethodHints();
     q_textChanged();
     emit echoModeChanged(echoMode());
@@ -992,7 +997,7 @@ void QDeclarative1TextInput::createCursor()
     QDeclarative_setParent_noEvent(d->cursorItem, this);
     d->cursorItem->setParentItem(this);
     d->cursorItem->setX(d->control->cursorToX());
-    d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
+    d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QWidgetLineControl's +1 which is not consistent with Text.
 }
 
 /*!
@@ -1058,10 +1063,12 @@ void QDeclarative1TextInputPrivate::focusChanged(bool hasFocus)
     Q_Q(QDeclarative1TextInput);
     focused = hasFocus;
     q->setCursorVisible(hasFocus && scene && scene->hasFocus());
-    if(q->echoMode() == QDeclarative1TextInput::PasswordEchoOnEdit && !hasFocus)
-        control->updatePasswordEchoEditing(false);//QLineControl sets it on key events, but doesn't deal with focus events
-    if (!hasFocus)
+    if(!hasFocus && control->passwordEchoEditing())
+        control->updatePasswordEchoEditing(false);//QWidgetLineControl sets it on key events, but doesn't deal with focus events
+    if (!hasFocus) {
+        control->commitPreedit();
         control->deselect();
+    }
     QDeclarativeItemPrivate::focusChanged(hasFocus);
 }
 
@@ -1119,13 +1126,13 @@ Handles the given mouse \a event.
 void QDeclarative1TextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarative1TextInput);
-    if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick))
-        return;
-    if (d->selectByMouse) {
+    if (d->selectByMouse && event->button() == Qt::LeftButton) {
         int cursor = d->xToPos(event->pos().x());
         d->control->selectWordAtPos(cursor);
         event->setAccepted(true);
     } else {
+        if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonDblClick))
+            return;
         QDeclarative1PaintedItem::mouseDoubleClickEvent(event);
     }
 }
@@ -1133,8 +1140,9 @@ void QDeclarative1TextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *eve
 void QDeclarative1TextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarative1TextInput);
-    if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress))
-        return;
+
+    d->pressPos = event->pos();
+
     if(d->focusOnPress){
         bool hadActiveFocus = hasActiveFocus();
         forceActiveFocus();
@@ -1152,8 +1160,10 @@ void QDeclarative1TextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
     if (d->selectByMouse) {
         setKeepMouseGrab(false);
         d->selectPressed = true;
-        d->pressPos = event->pos();
     }
+    if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonPress))
+        return;
+
     bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse;
     int cursor = d->xToPos(event->pos().x());
     d->control->moveCursor(cursor, mark);
@@ -1163,12 +1173,20 @@ void QDeclarative1TextInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
 void QDeclarative1TextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
 {
     Q_D(QDeclarative1TextInput);
-    if (d->sendMouseEventToInputContext(event, QEvent::MouseMove))
-        return;
+
     if (d->selectPressed) {
         if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance())
             setKeepMouseGrab(true);
-        moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode);
+
+        if (d->control->composeMode()) {
+            // start selection
+            int startPos = d->xToPos(d->pressPos.x());
+            int currentPos = d->xToPos(event->pos().x());
+            if (startPos != currentPos)
+                d->control->setSelection(startPos, currentPos - startPos);
+        } else {
+            moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode);
+        }
         event->setAccepted(true);
     } else {
         QDeclarative1PaintedItem::mouseMoveEvent(event);
@@ -1198,7 +1216,16 @@ void QDeclarative1TextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
         }
     }
     d->clickCausedFocus = false;
-    d->control->processEvent(event);
+#ifndef QT_NO_CLIPBOARD
+    if (QGuiApplication::clipboard()->supportsSelection()) {
+        if (event->button() == Qt::LeftButton) {
+            d->control->copy(QClipboard::Selection);
+        } else if (!isReadOnly() && event->button() == Qt::MidButton) {
+            d->control->deselect();
+            d->control->insert(QGuiApplication::clipboard()->text(QClipboard::Selection));
+        }
+    }
+#endif
     if (!event->isAccepted())
         QDeclarative1PaintedItem::mouseReleaseEvent(event);
 }
@@ -1210,28 +1237,12 @@ bool QDeclarative1TextInputPrivate::sendMouseEventToInputContext(
     if (event->widget() && control->composeMode()) {
         int tmp_cursor = xToPos(event->pos().x());
         int mousePos = tmp_cursor - control->cursor();
-        if (mousePos < 0 || mousePos > control->preeditAreaText().length()) {
-            mousePos = -1;
-            // don't send move events outside the preedit area
-            if (eventType == QEvent::MouseMove)
-                return true;
-        }
-
-        QInputContext *qic = event->widget()->inputContext();
-        if (qic) {
-            QMouseEvent mouseEvent(
-                    eventType,
-                    event->widget()->mapFromGlobal(event->screenPos()),
-                    event->screenPos(),
-                    event->button(),
-                    event->buttons(),
-                    event->modifiers());
-            // may be causing reset() in some input methods
-            qic->mouseHandler(mousePos, &mouseEvent);
-            event->setAccepted(mouseEvent.isAccepted());
-        }
-        if (!control->preeditAreaText().isEmpty())
+        if (mousePos >= 0 && mousePos <= control->preeditAreaText().length()) {
+            if (eventType == QEvent::MouseButtonRelease) {
+                qApp->inputPanel()->invokeAction(QInputPanel::Click, mousePos);
+            }
             return true;
+        }
     }
 #else
     Q_UNUSED(event);
@@ -1254,30 +1265,20 @@ bool QDeclarative1TextInput::sceneEvent(QEvent *event)
 
 bool QDeclarative1TextInput::event(QEvent* ev)
 {
+#ifndef QT_NO_SHORTCUT
     Q_D(QDeclarative1TextInput);
-    //Anything we don't deal with ourselves, pass to the control
-    bool handled = false;
-    switch(ev->type()){
-        case QEvent::KeyPress:
-        case QEvent::KeyRelease://###Should the control be doing anything with release?
-        case QEvent::InputMethod:
-        case QEvent::GraphicsSceneMousePress:
-        case QEvent::GraphicsSceneMouseMove:
-        case QEvent::GraphicsSceneMouseRelease:
-        case QEvent::GraphicsSceneMouseDoubleClick:
-            break;
-        default:
-            handled = d->control->processEvent(ev);
+
+    if (ev->type() == QEvent::ShortcutOverride) {
+        d->control->processShortcutOverrideEvent(static_cast<QKeyEvent *>(ev));
+        return ev->isAccepted();
     }
-    if(!handled)
-        handled = QDeclarative1PaintedItem::event(ev);
-    return handled;
+#endif
+    return QDeclarative1PaintedItem::event(ev);
 }
 
 void QDeclarative1TextInput::geometryChanged(const QRectF &newGeometry,
                                   const QRectF &oldGeometry)
 {
-    Q_D(QDeclarative1TextInput);
     if (newGeometry.width() != oldGeometry.width()) {
         updateSize();
         updateCursorRectangle();
@@ -1355,11 +1356,11 @@ void QDeclarative1TextInput::drawContents(QPainter *p, const QRect &r)
     p->setRenderHint(QPainter::TextAntialiasing, true);
     p->save();
     p->setPen(QPen(d->color));
-    int flags = QLineControl::DrawText;
+    int flags = QWidgetLineControl::DrawText;
     if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
-        flags |= QLineControl::DrawCursor;
+        flags |= QWidgetLineControl::DrawCursor;
     if (d->control->hasSelectedText())
-            flags |= QLineControl::DrawSelections;
+            flags |= QWidgetLineControl::DrawSelections;
     QPoint offset = QPoint(0,0);
     QFontMetrics fm = QFontMetrics(d->font);
     QRect br(boundingRect().toRect());
@@ -1388,10 +1389,11 @@ QVariant QDeclarative1TextInput::inputMethodQuery(Qt::InputMethodQuery property)
     case Qt::ImCursorPosition:
         return QVariant(d->control->cursor());
     case Qt::ImSurroundingText:
-        if (d->control->echoMode() == PasswordEchoOnEdit && !d->control->passwordEchoEditing())
+        if (d->control->echoMode() == PasswordEchoOnEdit
+            && !d->control->passwordEchoEditing())
             return QVariant(displayText());
         else
-            return QVariant(text());
+            return QVariant(d->control->realText());
     case Qt::ImCurrentSelection:
         return QVariant(selectedText());
     case Qt::ImMaximumTextLength:
@@ -1729,9 +1731,8 @@ void QDeclarative1TextInput::moveCursorSelection(int pos, SelectionMode mode)
     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 TextInput. On other platforms
-    the panels are automatically opened when TextInput element gains active focus. Input panels are
+    By default the opening of input panels follows the platform style.
+    The panels are automatically opened when TextInput 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
@@ -1763,11 +1764,10 @@ void QDeclarative1TextInput::moveCursorSelection(int pos, SelectionMode mode)
 */
 void QDeclarative1TextInput::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);
+                qApp->inputPanel()->show();
             }
         }
     }
@@ -1780,9 +1780,8 @@ void QDeclarative1TextInput::openSoftwareInputPanel()
     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 TextInput. On other platforms
-    the panels are automatically opened when TextInput element gains active focus. Input panels are
+    By default the opening of input panels follows the platform style.
+    The panels are automatically opened when TextInput 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
@@ -1814,12 +1813,10 @@ void QDeclarative1TextInput::openSoftwareInputPanel()
 */
 void QDeclarative1TextInput::closeSoftwareInputPanel()
 {
-    QEvent event(QEvent::CloseSoftwareInputPanel);
     if (qApp) {
-        QEvent event(QEvent::CloseSoftwareInputPanel);
         if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) {
             if (view->scene() && view->scene() == scene()) {
-                QApplication::sendEvent(view, &event);
+                qApp->inputPanel()->hide();
             }
         }
     }
@@ -1918,6 +1915,7 @@ void QDeclarative1TextInput::cursorPosChanged()
 void QDeclarative1TextInput::updateCursorRectangle()
 {
     Q_D(QDeclarative1TextInput);
+    d->determineHorizontalAlignment();
     d->updateHorizontalScroll();
     updateRect();//TODO: Only update rect between pos's
     updateMicroFocus();
@@ -1989,7 +1987,7 @@ void QDeclarative1TextInput::updateSize(bool needsRedraw)
     Q_D(QDeclarative1TextInput);
     int w = width();
     int h = height();
-    setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
+    setImplicitHeight(d->control->height()-1); // -1 to counter QWidgetLineControl's +1 which is not consistent with Text.
     setImplicitWidth(d->calculateTextWidth());
     setContentsSize(QSize(width(), height()));//Repaints if changed
     if(w==width() && h==height() && needsRedraw){