src/hbcore/vkbhosts/hbabstractvkbhost.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 #include "hbabstractvkbhost.h"
       
    26 #include "hbabstractvkbhost_p.h"
       
    27 #include "hbinputvirtualkeyboard.h"
       
    28 #include "hbinputsettingproxy.h"
       
    29 #include "hbinputmethod.h"
       
    30 #include "hbdeviceprofile.h"
       
    31 #include "hbmainwindow.h"
       
    32 #include "hbpopup.h"
       
    33 #include "hbview.h"
       
    34 
       
    35 #include <QTextEdit>
       
    36 
       
    37 const int HbAnimationTime = 200;
       
    38 const qreal HbEditorExtraMargin = 5.0;
       
    39 const qreal HbCursorLineMargin = 15.0;
       
    40 const qreal HbContainerBorderMargin = 20.0;
       
    41 const qreal HbHeightVerticalFactor = 0.5;
       
    42 const qreal HbHeightHorizFactor = 0.7;
       
    43 
       
    44 /*!
       
    45 \proto
       
    46 \class HbAbstractVkbHost
       
    47 \brief Base class for HbCore's virtual keyboard hosts.
       
    48 
       
    49 This class contains common code for HbCore's virtual keyboard hosts.
       
    50 */
       
    51 
       
    52 /// @cond
       
    53 
       
    54 HbAbstractVkbHostPrivate::HbAbstractVkbHostPrivate(HbAbstractVkbHost *myHost, QGraphicsWidget *containerWidget)
       
    55 : q_ptr(myHost),
       
    56 mCallback(0),
       
    57 mKeypad(0),
       
    58 mContainerWidget(containerWidget),
       
    59 mTimeLine(HbAnimationTime),
       
    60 mKeypadStatus(HbVkbHost::HbVkbStatusClosed),
       
    61 mKeypadOperationOngoing(false),
       
    62 mOriginalContainerPosition(QPointF(0,0)),
       
    63 mContainerMovementStartingPoint(QPointF(0, 0)),
       
    64 mContainerMovementVector(QPointF(0, 0)),
       
    65 mKeypadMovementStartingPoint(QPointF(0, 0)),
       
    66 mKeypadMovementVector(QPointF(0, 0)),
       
    67 mInputMethod(0),
       
    68 mKeypadStatusBeforeOrientationChange(HbVkbHost::HbVkbStatusClosed)
       
    69 {
       
    70 }
       
    71 
       
    72 void HbAbstractVkbHostPrivate::prepareAnimationsCommon()
       
    73 {
       
    74     if (mContainerWidget && mKeypad) {
       
    75         // If the keyboard is not already open, remember the original position.
       
    76         // That is where the container will eventually be returned to.
       
    77         if (mKeypadStatus == HbVkbHost::HbVkbStatusClosed) {
       
    78             mOriginalContainerPosition = mContainerWidget->pos();
       
    79         }
       
    80 
       
    81         // Initialize movement variables to starting values. These will
       
    82         // be fine tuned later.
       
    83         mKeypadMovementVector = QPointF(0, 0);
       
    84         mContainerMovementVector = QPointF(0, 0);
       
    85         mContainerMovementStartingPoint = mContainerWidget->pos();
       
    86         mKeypadMovementStartingPoint = mKeypad->pos();
       
    87     }
       
    88 
       
    89     mScreenSize = screenSize();
       
    90 }
       
    91 
       
    92 bool HbAbstractVkbHostPrivate::prepareContainerAnimation(HbVkbHost::HbVkbStatus status)
       
    93 {
       
    94     if (!mKeypad || !mContainerWidget || !mInputMethod || !mInputMethod->focusObject()) {
       
    95         return false;
       
    96     }
       
    97 
       
    98     if (status == HbVkbHost::HbVkbStatusOpened) {
       
    99         // Calculate the area that remains visible when the keypad is open.
       
   100         QRectF visibleArea = QRectF(0.0, 0.0, mScreenSize.width(), mScreenSize.height() - mKeypad->size().height());
       
   101 
       
   102         // Find out the container area.
       
   103         QRectF containerArea = mContainerWidget->sceneBoundingRect();
       
   104         containerArea.adjust(0.0, -HbContainerBorderMargin, 0.0, HbContainerBorderMargin);
       
   105 
       
   106         if (visibleArea.contains(containerArea)) {
       
   107             // The whole container is already inside the visible area, nothing to do.
       
   108             return false;
       
   109         }
       
   110 
       
   111         if (visibleArea.height() >= containerArea.height()) {
       
   112             // It isn't in the visible area yet but fits there. Let's move it there.
       
   113             mContainerMovementVector = QPointF(0.0, visibleArea.bottom() - containerArea.bottom());
       
   114             return true;
       
   115         }
       
   116 
       
   117         // Find out the editor bounding box and add a small margin to height.
       
   118         QRectF editorGeometry = mInputMethod->focusObject()->editorGeometry();
       
   119         editorGeometry.adjust(0.0, -HbCursorLineMargin, 0.0, HbCursorLineMargin);
       
   120 
       
   121         // Then see if the editor is already inside the visible area.
       
   122         // If it isn't, see if it would fit there.
       
   123         if (!visibleArea.contains(editorGeometry)) {
       
   124             if (editorGeometry.width() <= visibleArea.width() &&
       
   125                 editorGeometry.height() <= visibleArea.height()) {
       
   126                 // Yes, it fits into visible area, let's move it there so that
       
   127                 // the whole editor area is in use right away.
       
   128                 // First check if we want to move it to upper or lower
       
   129                 // part of the visible area.
       
   130                 if (editorGeometry.top() <= visibleArea.top()) {
       
   131                     // It goes to the upper part of the visible area.
       
   132                     mContainerMovementVector = QPointF(0.0, -editorGeometry.top());
       
   133                 } else {
       
   134                     mContainerMovementVector = QPointF(0.0, visibleArea.bottom() - editorGeometry.bottom());
       
   135                 }
       
   136 
       
   137                 return true;
       
   138             }
       
   139         }
       
   140 
       
   141         // The editor is either already inside the visible area or doesn't fit there.
       
   142         // Let's see if the cursor is visble.
       
   143         // First find out micro focus rectangle and increase the height by a small margin.
       
   144         QRectF microFocus = mInputMethod->focusObject()->microFocus();
       
   145         microFocus.setTop(microFocus.top() - HbEditorExtraMargin);
       
   146         microFocus.setBottom(microFocus.bottom() + HbEditorExtraMargin);
       
   147 
       
   148         // Check whether the cursor rectangle is inside visible area.
       
   149         if (!visibleArea.contains(microFocus)) {
       
   150             // The cursor is outside the visible area. Figure out how much and
       
   151             // to which direction the container has to be moved.
       
   152             if (microFocus.bottom() <= visibleArea.top()) {
       
   153                 // It goes to the upper part of the visible area.
       
   154                 mContainerMovementVector = QPointF(0.0, HbCursorLineMargin - microFocus.top());
       
   155             } else {
       
   156                 mContainerMovementVector = QPointF(0.0, visibleArea.bottom() - HbCursorLineMargin - microFocus.bottom());
       
   157             }
       
   158 
       
   159             return true;
       
   160         }
       
   161     } else {
       
   162         // It is going to be closed or minimized.
       
   163         mContainerMovementVector = mOriginalContainerPosition - mContainerMovementStartingPoint;
       
   164         return true;
       
   165     }
       
   166 
       
   167     return false;
       
   168 }
       
   169 
       
   170 bool HbAbstractVkbHostPrivate::prepareKeypadAnimation(HbVkbHost::HbVkbStatus status)
       
   171 {
       
   172     if (status == HbVkbHost::HbVkbStatusOpened) {
       
   173         if (mKeypadStatus == HbVkbHost::HbVkbStatusClosed) {
       
   174              // Set up keyboard open animation.
       
   175              mKeypadMovementStartingPoint.setY(mScreenSize.height());
       
   176              mKeypadMovementVector.setY(-mKeypad->size().height());
       
   177              if (!disableCursorShift()) {
       
   178                  // Initialize keypad position
       
   179                  mKeypad->setPos(mKeypadMovementStartingPoint);
       
   180              }
       
   181              return true;
       
   182          } else if (mKeypadStatus == HbVkbHost::HbVkbStatusMinimized && mCallback) {
       
   183              mKeypadMovementVector.setY(-(mKeypad->size().height() - mCallback->minimizedKeyboardSize().height()));
       
   184              return true;
       
   185          }
       
   186     } else if (status == HbVkbHost::HbVkbStatusMinimized && mCallback) {
       
   187         mKeypadMovementVector = QPointF(0, mKeypad->size().height() - mCallback->minimizedKeyboardSize().height());
       
   188     } else {
       
   189         // It is going to be closed.
       
   190         mKeypadMovementVector = QPointF(0, mKeypad->size().height());
       
   191         return true;
       
   192     }
       
   193 
       
   194     return false;
       
   195 }
       
   196 
       
   197 bool HbAbstractVkbHostPrivate::prepareAnimations(HbVkbHost::HbVkbStatus status)
       
   198 {
       
   199     prepareAnimationsCommon();
       
   200 
       
   201     return (prepareContainerAnimation(status) |
       
   202             prepareKeypadAnimation(status));
       
   203 }
       
   204 
       
   205 void HbAbstractVkbHostPrivate::connectSignals()
       
   206 {
       
   207     if (mContainerWidget) {
       
   208         q_ptr->connect(mContainerWidget, SIGNAL(yChanged()), q_ptr, SLOT(ensureCursorVisibility()));
       
   209     }
       
   210 
       
   211     HbWidget *hbWidget = qobject_cast<HbWidget*>(mContainerWidget);
       
   212     if (hbWidget) {
       
   213         HbMainWindow* mainWindow = hbWidget->mainWindow();
       
   214         if (mainWindow) {
       
   215             q_ptr->connect(mainWindow, SIGNAL(aboutToChangeOrientation()), q_ptr, SLOT(orientationAboutToChange()));
       
   216             q_ptr->connect(mainWindow, SIGNAL(orientationChanged(Qt::Orientation)), q_ptr, SLOT(orientationChanged(Qt::Orientation)));
       
   217         }
       
   218     }
       
   219 
       
   220     HbPopup *popup = qobject_cast<HbPopup*>(mContainerWidget);
       
   221     if (popup) {
       
   222         q_ptr->connect(popup, SIGNAL(aboutToHide()), q_ptr, SLOT(containerAboutToClose()));
       
   223     }
       
   224 }
       
   225 
       
   226 void HbAbstractVkbHostPrivate::disconnectSignals()
       
   227 {
       
   228     if (mContainerWidget) {
       
   229         q_ptr->disconnect(mContainerWidget, SIGNAL(yChanged()), q_ptr, SLOT(ensureCursorVisibility()));
       
   230     }
       
   231 
       
   232     HbWidget *hbWidget = qobject_cast<HbWidget*>(mContainerWidget);
       
   233     if (hbWidget) {
       
   234         HbMainWindow* mainWindow = hbWidget->mainWindow();
       
   235         if (mainWindow) {
       
   236             q_ptr->disconnect(mainWindow, SIGNAL(aboutToChangeOrientation()), q_ptr, SLOT(orientationAboutToChange()));
       
   237             q_ptr->disconnect(mainWindow, SIGNAL(orientationChanged(Qt::Orientation)), q_ptr, SLOT(orientationChanged(Qt::Orientation)));
       
   238         }
       
   239     }
       
   240 
       
   241     HbPopup *popup = qobject_cast<HbPopup*>(mContainerWidget);
       
   242     if (popup) {
       
   243         q_ptr->disconnect(popup, SIGNAL(aboutToHide()), q_ptr, SLOT(containerAboutToClose()));
       
   244     }
       
   245 }
       
   246 
       
   247 void HbAbstractVkbHostPrivate::openKeypad()
       
   248 {
       
   249     if (mContainerWidget) {
       
   250         HbMainWindow* mainWin = mainWindow();
       
   251         if (mainWin && mKeypad) {
       
   252             if (mKeypad->scene() != mainWin->scene()) {
       
   253                 // Add keypad to scene if it is not already in there.
       
   254                 mainWin->scene()->addItem(mKeypad);
       
   255             }
       
   256 
       
   257             if (mKeypadStatus != HbVkbHost::HbVkbStatusOpened) {
       
   258                 mCallback->aboutToOpen(q_ptr);
       
   259                 q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries.
       
   260             }
       
   261 
       
   262             if (prepareAnimations(HbVkbHost::HbVkbStatusOpened)) {
       
   263                 // Run the animation
       
   264                 mKeypadStatus = HbVkbHost::HbVkbStatusOpened;
       
   265                 mTimeLine.start();
       
   266             }
       
   267         }
       
   268     }
       
   269 }
       
   270 
       
   271 void HbAbstractVkbHostPrivate::closeKeypad()
       
   272 {
       
   273     // Since the keypad is already in a minimized state we should not play animation.
       
   274     if (mKeypadStatus == HbVkbHost::HbVkbStatusMinimized) {
       
   275         closeKeypadWithoutAnimation();
       
   276     }
       
   277 
       
   278     if (mKeypadStatus != HbVkbHost::HbVkbStatusClosed) {
       
   279         mCallback->aboutToClose(q_ptr);
       
   280 
       
   281         if (prepareAnimations(HbVkbHost::HbVkbStatusClosed)) {
       
   282             mKeypadStatus = HbVkbHost::HbVkbStatusClosed;
       
   283             mTimeLine.start();
       
   284         }
       
   285     }
       
   286 }
       
   287 
       
   288 void HbAbstractVkbHostPrivate::minimizeKeypad()
       
   289 {
       
   290     if (mCallback && mKeypadStatus != HbVkbHost::HbVkbStatusMinimized) {
       
   291         mCallback->aboutToClose(q_ptr);
       
   292         if (mContainerWidget) {
       
   293             if (prepareAnimations(HbVkbHost::HbVkbStatusMinimized)) {
       
   294                 mKeypadStatus = HbVkbHost::HbVkbStatusMinimized;
       
   295                 mTimeLine.start();
       
   296             }
       
   297         }
       
   298     }
       
   299 }
       
   300 
       
   301 void HbAbstractVkbHostPrivate::openKeypadWithoutAnimation()
       
   302 {
       
   303     HbMainWindow *mainWin = mainWindow();
       
   304     if (mKeypadStatus!= HbVkbHost::HbVkbStatusOpened && mKeypad && mContainerWidget && mainWin) {
       
   305         if (mKeypad->scene() != mainWin->scene()) {
       
   306             // Add item to scene if it is not already in there.
       
   307             mainWin->scene()->addItem(mKeypad);
       
   308         }
       
   309 
       
   310         if (mKeypadStatus != HbVkbHost::HbVkbStatusOpened) {
       
   311             mCallback->aboutToOpen(q_ptr);
       
   312             q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries.
       
   313         }
       
   314 
       
   315         if (prepareAnimations(HbVkbHost::HbVkbStatusOpened)) {
       
   316             if (!disableCursorShift()) {
       
   317                 // Move the container widget to keep the focused line visible.
       
   318                 mContainerWidget->setPos(mContainerWidget->pos() + mContainerMovementVector);
       
   319 
       
   320                 // Move the keypad
       
   321                 mKeypad->setPos(mKeypadMovementStartingPoint + mKeypadMovementVector);
       
   322             }
       
   323 
       
   324             mKeypadStatus = HbVkbHost::HbVkbStatusOpened;
       
   325             q_ptr->openFinished();
       
   326         }
       
   327     }
       
   328 }
       
   329 
       
   330 void HbAbstractVkbHostPrivate::openMinimizedKeypad()
       
   331 {
       
   332     // No need of any animation as this minimized keypad is very small to be a candidate for an
       
   333     // animation.
       
   334     HbMainWindow *mainWin = mainWindow();
       
   335     if (mainWin && mKeypad && mContainerWidget) {
       
   336         if (mKeypad->scene() != mainWin->scene()) {
       
   337             // Add item to scene if it is not already in there.
       
   338             mainWin->scene()->addItem(mKeypad);
       
   339         }
       
   340 
       
   341         if (mKeypadStatus != HbVkbHost::HbVkbStatusMinimized) {
       
   342             mCallback->aboutToOpen(q_ptr);
       
   343             q_ptr->resizeKeyboard(); // Make sure that the keyboard doesn't exceed given boundaries.
       
   344         }
       
   345 
       
   346         if (prepareAnimations(HbVkbHost::HbVkbStatusMinimized)) {             
       
   347             if (!disableCursorShift()) {
       
   348                 mKeypad->setPos(0.0, mScreenSize.height() - mCallback->minimizedKeyboardSize().height());
       
   349             }
       
   350             mKeypadStatus = HbVkbHost::HbVkbStatusMinimized;
       
   351             mCallback->keyboardMinimized(q_ptr);
       
   352         }
       
   353     }
       
   354 }
       
   355 
       
   356 void HbAbstractVkbHostPrivate::closeKeypadWithoutAnimation()
       
   357 {
       
   358     if (mKeypadStatus != HbVkbHost::HbVkbStatusClosed && mKeypad) {
       
   359         mCallback->aboutToClose(q_ptr);
       
   360         // Set original content widget position
       
   361         mKeypadStatus = HbVkbHost::HbVkbStatusClosed;
       
   362 
       
   363         if (!disableCursorShift()) {
       
   364             // Return the container widget to original position.
       
   365             mContainerWidget->setPos(mOriginalContainerPosition);
       
   366         }
       
   367 
       
   368         // Hide the keypad
       
   369         mKeypad->hide();
       
   370         mCallback = 0;
       
   371     }
       
   372 }
       
   373 
       
   374 void HbAbstractVkbHostPrivate::minimizeKeypadWithoutAnimation()
       
   375 {
       
   376     HbMainWindow *mainWin = mainWindow();
       
   377     if (mKeypadStatus != HbVkbHost::HbVkbStatusMinimized && mKeypad && mainWin) {
       
   378         mCallback->aboutToClose(q_ptr);
       
   379         if (mKeypad->scene() != mainWin->scene()) {
       
   380             // Add item to scene if it is not already in there.
       
   381             mainWin->scene()->addItem(mKeypad);
       
   382         }
       
   383 
       
   384         if (!disableCursorShift()) {
       
   385             // Return the container widget to original position.
       
   386             mContainerWidget->setPos(mOriginalContainerPosition);
       
   387 
       
   388             // Set the keypad to minimized position.
       
   389             mKeypad->setPos(QPointF(0.0, mScreenSize.height() - mCallback->minimizedKeyboardSize().height()));
       
   390         }
       
   391 
       
   392         mKeypadStatus = HbVkbHost::HbVkbStatusMinimized;
       
   393     }
       
   394 }
       
   395 
       
   396 void HbAbstractVkbHostPrivate::cancelAnimationAndHideVkbWidget()
       
   397 {
       
   398     if (mTimeLine.state() == QTimeLine::Running) {
       
   399         mTimeLine.stop();
       
   400 
       
   401         if (!disableCursorShift()) {
       
   402             mContainerWidget->setPos(mOriginalContainerPosition);
       
   403         }
       
   404 
       
   405         if (mKeypad) {
       
   406             mKeypad->hide();
       
   407         }
       
   408 
       
   409         // Clear possible pending call.
       
   410         mPendingCall.vkb = 0;
       
   411 
       
   412         mKeypadStatus = HbVkbHost::HbVkbStatusClosed;
       
   413     }
       
   414 }
       
   415 
       
   416 HbMainWindow *HbAbstractVkbHostPrivate::mainWindow() const
       
   417 {
       
   418     HbWidget *hbWidget = qobject_cast<HbWidget*>(mContainerWidget);
       
   419     if (hbWidget) {
       
   420         return hbWidget->mainWindow();
       
   421     }
       
   422 
       
   423     return qobject_cast<HbMainWindow*>(qApp->activeWindow());
       
   424 }
       
   425 
       
   426 QSizeF HbAbstractVkbHostPrivate::screenSize() const
       
   427 {
       
   428     HbMainWindow *mainWin = mainWindow();
       
   429     QSizeF result = static_cast<QSizeF>(HbDeviceProfile::profile(mainWin).logicalSize());
       
   430 
       
   431     // do some sanity checking for the size got from device profile
       
   432     if( result.isNull() || result.width() < 200 || result.height() < 200 ) {
       
   433         qWarning("VkbHost error: size from device profile is faulty, using fallback!");
       
   434         if (mainWin) {
       
   435             if (mainWin->orientation() == Qt::Horizontal) {
       
   436                 result.setWidth(640);
       
   437                 result.setHeight(360);
       
   438             } else {
       
   439                 result.setWidth(360);
       
   440                 result.setHeight(640);
       
   441             }
       
   442         }
       
   443     }
       
   444 
       
   445     return result;
       
   446 }
       
   447 
       
   448 bool HbAbstractVkbHostPrivate::disableCursorShift() {
       
   449 
       
   450     if (!mInputMethod
       
   451         || mainWindow()) {
       
   452         return false;
       
   453     }
       
   454 
       
   455     if ( (mainWindow()->orientation() == Qt::Horizontal)
       
   456         && (mInputMethod->inputState().inputMode() == HbInputModeHwrChinese
       
   457         || mInputMethod->inputState().inputMode() == HbInputModeHwrChineseFull) ) {
       
   458         return true;
       
   459     }
       
   460     return false;
       
   461 }
       
   462 
       
   463 
       
   464 /// @endcond
       
   465 
       
   466 
       
   467 HbAbstractVkbHost::HbAbstractVkbHost(HbWidget *containerWidget) : d_ptr(new HbAbstractVkbHostPrivate(this, containerWidget))
       
   468 {
       
   469     Q_D(HbAbstractVkbHost);
       
   470 
       
   471     setParent(containerWidget);
       
   472     HbVkbHost::attachHost(this, containerWidget);
       
   473 
       
   474     connect(&d->mTimeLine, SIGNAL(finished()), this, SLOT(animationFinished()));
       
   475     connect(&d->mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
       
   476 }
       
   477 
       
   478 HbAbstractVkbHost::HbAbstractVkbHost(QGraphicsWidget *containerWidget) : d_ptr(new HbAbstractVkbHostPrivate(this, containerWidget))
       
   479 {
       
   480     Q_D(HbAbstractVkbHost);
       
   481 
       
   482     setParent(containerWidget);
       
   483     HbVkbHost::attachHost(this, containerWidget);
       
   484 
       
   485     connect(&d->mTimeLine, SIGNAL(finished()), this, SLOT(animationFinished()));
       
   486     connect(&d->mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
       
   487 }
       
   488 
       
   489 HbAbstractVkbHost::HbAbstractVkbHost(HbAbstractVkbHostPrivate *dd) : d_ptr(dd)
       
   490 {
       
   491     Q_D(HbAbstractVkbHost);
       
   492 
       
   493     setParent(d->mContainerWidget);
       
   494     HbVkbHost::attachHost(this, d->mContainerWidget);
       
   495 
       
   496     connect(&d->mTimeLine, SIGNAL(finished()), this, SLOT(animationFinished()));
       
   497     connect(&d->mTimeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
       
   498 }
       
   499 
       
   500 HbAbstractVkbHost::~HbAbstractVkbHost()
       
   501 {
       
   502     delete d_ptr;
       
   503 }
       
   504 
       
   505 /*!
       
   506 \reimp
       
   507 */
       
   508 HbVkbHost::HbVkbStatus HbAbstractVkbHost::keypadStatus() const
       
   509 {
       
   510     Q_D(const HbAbstractVkbHost);
       
   511     return d->mKeypadStatus;
       
   512 }
       
   513 
       
   514 /*!
       
   515 \reimp
       
   516 */
       
   517 void HbAbstractVkbHost::openKeypad(HbVirtualKeyboard *vkb, HbInputMethod* owner, bool animationAllowed)
       
   518 {
       
   519     Q_D(HbAbstractVkbHost);
       
   520 
       
   521     if (owner) {
       
   522         d->mInputMethod = owner;
       
   523     }
       
   524 
       
   525     if ((d->mKeypadStatus != HbVkbStatusMinimized) && (!vkb || !owner)) {
       
   526         // The caller is opening the keypad for the first time but didn't supply
       
   527         // all the needed parameters. Null parameters are ok only if minimized
       
   528         // keypad is reopened.
       
   529         return;
       
   530     }
       
   531 
       
   532     if (d->mTimeLine.state() == QTimeLine::Running) {
       
   533         // The previous keyboard is still closing. Set the call pending and return.
       
   534         d->mPendingCall.vkb = vkb;
       
   535         d->mPendingCall.animationAllowed = animationAllowed;
       
   536         return;
       
   537     }
       
   538 
       
   539     if (!d->mKeypadOperationOngoing) {
       
   540         d->mKeypadOperationOngoing = true;
       
   541 
       
   542         if (vkb && (d->mCallback != vkb || !d->mKeypad)) {
       
   543             // This keypad is opened for the first time or it was opened before but some other keypad
       
   544             // was opened in between.
       
   545             d->mCallback = vkb;
       
   546             d->mKeypad = vkb->asGraphicsWidget();
       
   547         }
       
   548 
       
   549         if (!d->mKeypad) {
       
   550             // Keyboard widget creation failed for some reason, can't go on.
       
   551             d->mCallback = 0;
       
   552             return;
       
   553         }
       
   554 
       
   555         if (animationAllowed) {
       
   556             d->openKeypad();
       
   557         } else {
       
   558             d->openKeypadWithoutAnimation();
       
   559         }
       
   560 
       
   561         d->connectSignals();
       
   562         d->mKeypadOperationOngoing = false;
       
   563     }
       
   564 }
       
   565 
       
   566 /*!
       
   567 \reimp
       
   568 */
       
   569 void HbAbstractVkbHost::closeKeypad(bool animationAllowed)
       
   570 {
       
   571     Q_D(HbAbstractVkbHost);
       
   572 
       
   573     if (d->mKeypadStatus != HbVkbStatusClosed && !d->mKeypadOperationOngoing) {
       
   574         d->mKeypadOperationOngoing = true;
       
   575 
       
   576         if (animationAllowed) {
       
   577             d->closeKeypad();
       
   578         } else {
       
   579             d->closeKeypadWithoutAnimation();
       
   580         }
       
   581 
       
   582         d->disconnectSignals();
       
   583         d->mKeypadOperationOngoing = false;
       
   584     }
       
   585 }
       
   586 
       
   587 /*!
       
   588 \reimp
       
   589 */
       
   590 int HbAbstractVkbHost::priority() const
       
   591 {
       
   592     return 0;
       
   593 }
       
   594 
       
   595 /*!
       
   596 This slot is called every time an animation frame is drawn.
       
   597 */
       
   598 void HbAbstractVkbHost::animValueChanged(qreal value)
       
   599 {
       
   600     Q_D(HbAbstractVkbHost);
       
   601 
       
   602     if (!d->disableCursorShift()) {
       
   603         // Move the container.
       
   604         if (d->mContainerWidget) {
       
   605             d->mContainerWidget->setPos(d->mContainerMovementStartingPoint + (d->mContainerMovementVector * value));
       
   606         }
       
   607 
       
   608         // Move keypad
       
   609         if (d->mKeypad) {
       
   610             d->mKeypad->setPos(d->mKeypadMovementStartingPoint + (d->mKeypadMovementVector * value));
       
   611         }
       
   612     }
       
   613 
       
   614     if (d->mCallback) {
       
   615         d->mCallback->keyboardAnimationFrame(HbVirtualKeyboard::HbVkbAnimOpen, value);
       
   616     }
       
   617 }
       
   618 
       
   619 /*!
       
   620 \deprecated HbAbstractVkbHost::openAnimValueChanged(qreal)
       
   621     is deprecated.
       
   622 */
       
   623 void HbAbstractVkbHost::openAnimValueChanged(qreal value)
       
   624 {
       
   625     Q_UNUSED(value);
       
   626 }
       
   627 
       
   628 /*!
       
   629 \deprecated HbAbstractVkbHost::closeAnimValueChanged(qreal)
       
   630     is deprecated.
       
   631 */
       
   632 void HbAbstractVkbHost::closeAnimValueChanged(qreal value)
       
   633 {
       
   634     Q_UNUSED(value);
       
   635 }
       
   636 
       
   637 /*!
       
   638 \deprecated HbAbstractVkbHost::openFinished()
       
   639     is deprecated.
       
   640 */
       
   641 void HbAbstractVkbHost::openFinished()
       
   642 {
       
   643 }
       
   644 
       
   645 /*!
       
   646 \deprecated HbAbstractVkbHost::closeFinished()
       
   647     is deprecated.
       
   648 */
       
   649 void HbAbstractVkbHost::closeFinished()
       
   650 {
       
   651 }
       
   652 
       
   653 /*!
       
   654 This slot is called when an animation sequence is completed.
       
   655 */
       
   656 void HbAbstractVkbHost::animationFinished()
       
   657 {
       
   658     Q_D(HbAbstractVkbHost);
       
   659 
       
   660     if (d->mContainerWidget && d->mKeypad && d->mCallback && d->mInputMethod) {
       
   661         if (!d->disableCursorShift()) {
       
   662             // Make sure the container reached target position.
       
   663             d->mContainerWidget->setPos(d->mContainerMovementStartingPoint + d->mContainerMovementVector);
       
   664 
       
   665             // Make sure the keypad reached target position.
       
   666             d->mKeypad->setPos(d->mKeypadMovementStartingPoint + d->mKeypadMovementVector);
       
   667         }
       
   668 
       
   669         // Notify
       
   670         if (d->mKeypadStatus == HbVkbHost::HbVkbStatusOpened) {
       
   671             d->mCallback->keyboardOpened(this);
       
   672 
       
   673             if (d->mInputMethod->focusObject()) {
       
   674                 // This is hopefully temporary...
       
   675                 QTextEdit *textEdit = qobject_cast<QTextEdit*>(d->mInputMethod->focusObject()->object());
       
   676                 if (textEdit) {
       
   677                     textEdit->ensureCursorVisible();
       
   678                 }
       
   679             }
       
   680 
       
   681             // Make sure the keypad never steals focus.
       
   682             d->mKeypad->setFlag(QGraphicsItem::ItemIsPanel, true);
       
   683             d->mKeypad->setActive(false);
       
   684             emit keypadOpened();
       
   685         } else if (d->mKeypadStatus == HbVkbHost::HbVkbStatusMinimized) {
       
   686             d->mCallback->keyboardMinimized(this);
       
   687             emit keypadClosed();
       
   688         } else {
       
   689             // It was closed.
       
   690             d->mKeypad->hide();
       
   691             d->mCallback->keyboardClosed(this);
       
   692             emit keypadClosed();
       
   693 
       
   694             if (d->mPendingCall.vkb) {
       
   695                 // There was an open call pending. Do it now.
       
   696                 HbVirtualKeyboard *vkb = d->mPendingCall.vkb;
       
   697                 d->mPendingCall.vkb = 0;
       
   698                 openKeypad(vkb, d->mInputMethod, d->mPendingCall.animationAllowed);
       
   699             }
       
   700         }
       
   701     }
       
   702 }
       
   703 
       
   704 /*!
       
   705 \reimp
       
   706 */
       
   707 QSizeF HbAbstractVkbHost::keyboardArea() const
       
   708 {
       
   709     Q_D(const HbAbstractVkbHost);
       
   710 
       
   711     HbMainWindow *mainWindow = d->mainWindow();
       
   712     if (d->mContainerWidget && mainWindow) {
       
   713         QSizeF screenSize = d->screenSize();
       
   714 
       
   715         if (mainWindow->orientation() == Qt::Horizontal) {
       
   716             return QSizeF(screenSize.width(), screenSize.height() * HbHeightHorizFactor);
       
   717         } else {
       
   718             return QSizeF(screenSize.width(), screenSize.height() * HbHeightVerticalFactor);
       
   719         }
       
   720     }
       
   721 
       
   722     return QSizeF(0.0, 0.0);
       
   723 }
       
   724 
       
   725 /*!
       
   726 \reimp
       
   727 */
       
   728 void HbAbstractVkbHost::preferredSizeChanged(const QSizeF& newSize)
       
   729 {
       
   730     Q_UNUSED(newSize);
       
   731 }
       
   732 
       
   733 /*!
       
   734 This slot is connected to orientation change warning signal from the framework
       
   735 and notifies setting proxy. Notification will then be delivered through setting proxy to all the
       
   736 interested parties.
       
   737 */
       
   738 void HbAbstractVkbHost::orientationAboutToChange()
       
   739 {
       
   740     Q_D(HbAbstractVkbHost);
       
   741     d->mKeypadStatusBeforeOrientationChange = d->mKeypadStatus;
       
   742     HbInputSettingProxy::instance()->notifyScreenOrientationChange();
       
   743 }
       
   744 
       
   745 /*!
       
   746 This slot is connected to orientation change signal from the framework and notifies
       
   747 the setting proxy. Notification will then be froearded to other interested parties
       
   748 by the setting proxy.
       
   749 */
       
   750 void HbAbstractVkbHost::orientationChanged(Qt::Orientation orientation)
       
   751 {
       
   752     HbInputSettingProxy::instance()->setScreenOrientation(orientation);
       
   753 }
       
   754 
       
   755 /*!
       
   756 \reimp
       
   757 */
       
   758 HbVirtualKeyboard* HbAbstractVkbHost::activeKeypad() const
       
   759 {
       
   760     Q_D(const HbAbstractVkbHost);
       
   761     return d->mCallback;
       
   762 }
       
   763 
       
   764 /*!
       
   765 \reimp
       
   766 */
       
   767 void HbAbstractVkbHost::ensureCursorVisibility()
       
   768 {
       
   769     Q_D(HbAbstractVkbHost);
       
   770 
       
   771     if ((d->mTimeLine.state() == QTimeLine::Running) ||
       
   772         (d->mKeypadStatus == HbVkbStatusClosed) ||
       
   773         (d->mKeypadStatus == HbVkbStatusMinimized) ||
       
   774         !d->mContainerWidget) {
       
   775             return;
       
   776     }
       
   777 
       
   778     // This will refresh the situation if needed.
       
   779     d->openKeypad();
       
   780 }
       
   781 
       
   782 /*!
       
   783 Returns the area inside active main window view that will remain visible when the
       
   784 virtual keyboard is open.
       
   785 */
       
   786 QRectF HbAbstractVkbHost::activeViewRect() const
       
   787 {
       
   788     Q_D(const HbAbstractVkbHost);
       
   789 
       
   790     HbMainWindow *mainWindow = d->mainWindow();
       
   791     if (d->mContainerWidget && mainWindow) {
       
   792         QSizeF vpSize = d->screenSize();
       
   793         QRectF viewport = QRectF(QPointF(0.0, 0.0), QPointF(vpSize.width(), vpSize.height()));
       
   794 
       
   795         viewport.setHeight(viewport.height() - confirmedKeyboardSize().height());
       
   796         return viewport;
       
   797     }
       
   798 
       
   799     return QRectF();
       
   800 }
       
   801 
       
   802 /*!
       
   803 Returns confirmed keyboard size. The method first queries preferred keyboard
       
   804 size and then clips it against maximum allowed keyboard size. Resulting size is returned.
       
   805 */
       
   806 QSizeF HbAbstractVkbHost::confirmedKeyboardSize()const
       
   807 {
       
   808     Q_D(const HbAbstractVkbHost);
       
   809 
       
   810     if (d->mCallback && d->mKeypad) {
       
   811         QSizeF kbArea = keyboardArea();
       
   812         QSizeF confirmed = d->mCallback->preferredKeyboardSize();
       
   813 
       
   814         if (confirmed.width() > kbArea.width()) {
       
   815             confirmed.setWidth(kbArea.width());
       
   816         }
       
   817         if (confirmed.height() > kbArea.height()) {
       
   818             confirmed.setHeight(kbArea.height());
       
   819         }
       
   820 
       
   821         return QSizeF(confirmed);
       
   822     }
       
   823 
       
   824     return QSizeF();
       
   825 }
       
   826 
       
   827 /*!
       
   828 Resizes keyboard widget to its preferred size and makes sure that
       
   829 the size does not exceed the size that host is willing to give to it.
       
   830 */
       
   831 void HbAbstractVkbHost::resizeKeyboard()
       
   832 {
       
   833     Q_D(HbAbstractVkbHost);
       
   834 
       
   835     if (d->mKeypad) {
       
   836         QSizeF currentSize = d->mKeypad->size();
       
   837         QSizeF newSize = confirmedKeyboardSize();
       
   838         if (currentSize != newSize) {
       
   839             d->mKeypad->resize(newSize);
       
   840         }
       
   841     }
       
   842 }
       
   843 
       
   844 /*!
       
   845 \reimp
       
   846 */
       
   847 QRectF HbAbstractVkbHost::applicationArea() const
       
   848 {
       
   849     Q_D(const HbAbstractVkbHost);
       
   850 
       
   851     if (d->mKeypadStatus == HbVkbStatusOpened) {
       
   852         return activeViewRect();
       
   853     }
       
   854 
       
   855     return QRectF();
       
   856 }
       
   857 
       
   858 /*!
       
   859 \reimp
       
   860 */
       
   861 void HbAbstractVkbHost::minimizeKeypad(bool animationAllowed)
       
   862 {
       
   863     Q_D(HbAbstractVkbHost);
       
   864     if (d->mKeypadStatus != HbVkbStatusClosed && !d->mKeypadOperationOngoing) {
       
   865         d->mKeypadOperationOngoing = true;
       
   866 
       
   867         if (animationAllowed) {
       
   868             d->minimizeKeypad();
       
   869         } else {
       
   870             d->minimizeKeypadWithoutAnimation();
       
   871         }
       
   872 
       
   873         d->mKeypadOperationOngoing = false;
       
   874     }
       
   875 }
       
   876 
       
   877 /*!
       
   878 \reimp
       
   879 */
       
   880 void HbAbstractVkbHost::openMinimizedKeypad(HbVirtualKeyboard *vkb, HbInputMethod* owner)
       
   881 {
       
   882     Q_D(HbAbstractVkbHost);
       
   883     d->mInputMethod = owner;
       
   884 
       
   885     if (!d->mKeypadOperationOngoing) {
       
   886         d->mKeypadOperationOngoing = true;
       
   887 
       
   888         if (d->mCallback != vkb || !d->mKeypad) {
       
   889             // This keypad is opened for the first time or it was opened before but some other keypad
       
   890             // was opened in between.
       
   891             d->mCallback = vkb;
       
   892             d->mKeypad = vkb->asGraphicsWidget();
       
   893         }
       
   894 
       
   895         if (!d->mKeypad) {
       
   896             // Keyboard widget creation failed for some reason, can't go on.
       
   897             d->mCallback = 0;
       
   898             return;
       
   899         }
       
   900 
       
   901         d->openMinimizedKeypad();
       
   902         d->connectSignals();
       
   903         d->mKeypadOperationOngoing = false;
       
   904     }
       
   905 }
       
   906 
       
   907 /*!
       
   908 \reimp
       
   909 */
       
   910 HbVkbHost::HbVkbStatus HbAbstractVkbHost::keypadStatusBeforeOrientationChange() const
       
   911 {
       
   912     Q_D(const HbAbstractVkbHost);
       
   913     return d->mKeypadStatusBeforeOrientationChange;
       
   914 }
       
   915 
       
   916 /*!
       
   917 This slot is called when active HbView changes.
       
   918 */
       
   919 void HbAbstractVkbHost::currentViewChanged(HbView *view)
       
   920 {
       
   921     Q_D(HbAbstractVkbHost);
       
   922 
       
   923     if (view != d->mContainerWidget) {
       
   924         if (d->mTimeLine.state() == QTimeLine::Running) {
       
   925             d->cancelAnimationAndHideVkbWidget();
       
   926             if (d->mCallback) {
       
   927                 d->mCallback->keyboardClosed(this);
       
   928             }
       
   929             emit keypadClosed();
       
   930         } else if (d->mKeypadStatus != HbVkbStatusClosed) {
       
   931             d->closeKeypadWithoutAnimation();
       
   932         }
       
   933     }
       
   934 }
       
   935 
       
   936 /*!
       
   937 \reimp
       
   938 */
       
   939 void HbAbstractVkbHost::refresh()
       
   940 {
       
   941      Q_D(HbAbstractVkbHost);
       
   942 
       
   943      if (d->mKeypadStatus == HbVkbHost::HbVkbStatusOpened &&
       
   944          d->mTimeLine.state() != QTimeLine::Running) {
       
   945          d->prepareAnimationsCommon();
       
   946          if (d->prepareContainerAnimation(HbVkbHost::HbVkbStatusOpened)) {
       
   947              // Container status needs to be updated. Run the animation.
       
   948              d->mTimeLine.start();
       
   949          }
       
   950      }
       
   951 }
       
   952 
       
   953 // End of file