src/hbplugins/inputmethods/touchinput/hbinputpredictionqwertyhandler.cpp
changeset 6 c3690ec91ef8
parent 5 627c4a0fd0e7
child 7 923ff622b8b9
equal deleted inserted replaced
5:627c4a0fd0e7 6:c3690ec91ef8
       
     1 
     1 /****************************************************************************
     2 /****************************************************************************
     2 **
     3 **
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     5 ** All rights reserved.
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
     6 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
    25 #include <QTimer>
    26 #include <QTimer>
    26 #include <hbinputmethod.h>
    27 #include <hbinputmethod.h>
    27 #include <hbinputkeymapfactory.h>
    28 #include <hbinputkeymapfactory.h>
    28 #include <hbinputpredictionengine.h>
    29 #include <hbinputpredictionengine.h>
    29 #include <hbinputbutton.h>
    30 #include <hbinputbutton.h>
    30 
    31 #include <QTextCharFormat>
       
    32 #include <HbColorScheme>
    31 #include "hbinputpredictionqwertyhandler.h"
    33 #include "hbinputpredictionqwertyhandler.h"
    32 #include "hbinputpredictionhandler_p.h"
    34 #include "hbinputpredictionhandler_p.h"
    33 #include "hbinputabstractbase.h"
    35 #include "hbinputabstractbase.h"
    34 
    36 
    35 class HbInputPredictionQwertyHandlerPrivate: public HbInputPredictionHandlerPrivate
    37 class HbInputPredictionQwertyHandlerPrivate: public HbInputPredictionHandlerPrivate
    42 
    44 
    43 public:
    45 public:
    44     bool buttonPressed(const QKeyEvent *event);
    46     bool buttonPressed(const QKeyEvent *event);
    45     bool buttonReleased(const QKeyEvent *event);
    47     bool buttonReleased(const QKeyEvent *event);
    46     void init();
    48     void init();
       
    49     void updateEditor();
       
    50     void commitSecondaryWord();
       
    51     QString getCommitString();
       
    52     void showExactWordPopupIfNeeded();
    47 
    53 
    48 public:
    54 public:
    49     int mButton;    
    55     int mButton;    
    50     HbFnState mFnState;
    56     HbFnState mFnState;
    51     bool mExactPopupLaunched;    
    57     bool mExactPopupLaunched;    
       
    58     bool mShowExactWordInTooltip;
       
    59     int mPrimaryCandidateIndex;
       
    60     int mSecondaryCandidateIndex;
       
    61     int mTypingCorrectionLevel;
       
    62     HbTypingCorrectionLevel mCorrectionLevel;
    52 };
    63 };
    53 
    64 
    54 HbInputPredictionQwertyHandlerPrivate::HbInputPredictionQwertyHandlerPrivate()
    65 HbInputPredictionQwertyHandlerPrivate::HbInputPredictionQwertyHandlerPrivate()
    55 :mButton(0),    
    66 :mButton(0),    
    56     mFnState(HbFnOff),
    67     mFnState(HbFnOff),
   275 void HbInputPredictionQwertyHandler::exactWordPopupClosed()
   286 void HbInputPredictionQwertyHandler::exactWordPopupClosed()
   276 {
   287 {
   277     commitExactWord();
   288     commitExactWord();
   278 }
   289 }
   279 
   290 
       
   291 void HbInputPredictionQwertyHandler::exactWordSelected()
       
   292 {
       
   293     Q_D(HbInputPredictionQwertyHandler);    
       
   294     d->commitSecondaryWord();
       
   295 }
       
   296 
   280 void HbInputPredictionQwertyHandler::sctCharacterSelected(QString character)
   297 void HbInputPredictionQwertyHandler::sctCharacterSelected(QString character)
   281 {	
   298 {	
   282     HbInputPredictionHandler::sctCharacterSelected(character);
   299     HbInputPredictionHandler::sctCharacterSelected(character);
   283 }
   300 }
   284 
   301 
   315  
   332  
   316         if(false == mTailShowing && true == mExactPopupLaunched) {
   333         if(false == mTailShowing && true == mExactPopupLaunched) {
   317                 mEngine->deleteKeyPress();
   334                 mEngine->deleteKeyPress();
   318                 mEngine->updateCandidates(mBestGuessLocation);
   335                 mEngine->updateCandidates(mBestGuessLocation);
   319         }
   336         }
   320         if (true == mExactPopupLaunched) {			
   337 
   321             mBestGuessLocation = 0 ;
   338         mBestGuessLocation = 0 ;
   322         }
       
   323         //When there is a deletion of key press, no need to update the candidate list
       
   324         //This is because deletion should not cause reprediction.
       
   325         if(mCandidates->count() && (mCandidates->count()>mBestGuessLocation) && false == mTailShowing && false == mExactPopupLaunched) {
   339         if(mCandidates->count() && (mCandidates->count()>mBestGuessLocation) && false == mTailShowing && false == mExactPopupLaunched) {
   326             QString currentWord = mCandidates->at(mBestGuessLocation);
   340             QString currentWord = mCandidates->at(mBestGuessLocation);
   327             if(currentWord.length() > mEngine->inputLength()) {
   341             if(currentWord.length() > mEngine->inputLength()) {
   328                 //chop off the autocompletion part
   342                 //chop off the autocompletion part
   329                 currentWord = currentWord.left(mEngine->inputLength());
   343                 currentWord = currentWord.left(mEngine->inputLength());
   357         q->sendAndUpdate(event);
   371         q->sendAndUpdate(event);
   358         return;
   372         return;
   359     }
   373     }
   360 }
   374 }
   361 
   375 
       
   376 void HbInputPredictionQwertyHandler::setPrimaryCandidateMode(HbPrimaryCandidateMode mode)
       
   377 {
       
   378     Q_D(HbInputPredictionQwertyHandler);
       
   379     if(mode == HbPrimaryCandidateModeExactTyping) {
       
   380         d->mShowExactWordInTooltip = false;
       
   381     } else {
       
   382         d->mShowExactWordInTooltip = true;
       
   383     }
       
   384     // we need to close the exact word popup when this happens.
       
   385     d->mInputMethod->closeExactWordPopup();
       
   386     d->mExactPopupLaunched = false;
       
   387 }
       
   388 
       
   389 void HbInputPredictionQwertyHandlerPrivate::updateEditor()
       
   390 {
       
   391     Q_Q(HbInputPredictionQwertyHandler);
       
   392     if (!mEngine) {
       
   393         return;
       
   394     }
       
   395     HbInputFocusObject *focusedObject = 0;
       
   396     QList<QInputMethodEvent::Attribute> list;
       
   397     focusedObject = mInputMethod->focusObject();
       
   398     QTextCharFormat underlined;    
       
   399     underlined.setFontUnderline(true);
       
   400 
       
   401     Q_ASSERT(focusedObject);
       
   402     if (mEngine->inputLength() == 0) {
       
   403         QInputMethodEvent event(QString(), list);
       
   404         q->sendAndUpdate(event);
       
   405     } else {
       
   406         if (mCandidates->count() > 0) {
       
   407             // index of the candidate that is shown on the typing line
       
   408             mPrimaryCandidateIndex = mBestGuessLocation;
       
   409             // index of the candidate that is shown in the tooltip (if any)
       
   410             mSecondaryCandidateIndex = 0;    
       
   411             QString bestGuessWord = mCandidates->at(mBestGuessLocation);
       
   412             QString exactTypedWord = mCandidates->at(0);
       
   413             bool hasAutocompletionPart = (bestGuessWord.length() > exactTypedWord.length()) && (bestGuessWord.left(exactTypedWord.length()) == exactTypedWord);            
       
   414             // when we are showing the autocompletion part we generally do not show the tooltip,
       
   415             // both primary and secondary candidates are the same.
       
   416             if(hasAutocompletionPart && mAutocompletionEnabled && mShowTail) {
       
   417                 mPrimaryCandidateIndex = mSecondaryCandidateIndex = mBestGuessLocation;                
       
   418             }
       
   419             // in case of exact tying, exact typed word in the primary candidate
       
   420             // and the best predicted word is the secondary candidate
       
   421             if(!mShowExactWordInTooltip && !(hasAutocompletionPart && mAutocompletionEnabled)) {
       
   422                 mPrimaryCandidateIndex = 0;
       
   423                 mSecondaryCandidateIndex = mBestGuessLocation;
       
   424             }
       
   425             if (hasAutocompletionPart && mShowTail && mAutocompletionEnabled) {
       
   426                 // showing the word with auto completion
       
   427                 int taillength = bestGuessWord.length() - exactTypedWord.length();
       
   428                 // TODO: Color from skin should be used
       
   429                 QColor col = HbColorScheme::color("qtc_input_hint_normal");
       
   430                 QBrush brush(col);
       
   431                 // underline formatting is applied to only the input length part of the word
       
   432                 QInputMethodEvent::Attribute textstyle(QInputMethodEvent::TextFormat, 0, mEngine->inputLength(), underlined);
       
   433                 list.append(textstyle);
       
   434 
       
   435                 QTextCharFormat gray;
       
   436                 gray.setForeground(brush);
       
   437                 if((focusedObject->object())->inherits("QGraphicsWebView") || (focusedObject->object())->inherits("QWebView")) {
       
   438                     //QGraphicsWebView does not handle partial input length formatting well. Causes crash, a temporary fix provided,
       
   439                     //This makes the whole text field grey insted of just the auto-completion part. Anyways, it does not cause crash.
       
   440                     //This should be treated as a work around till QGraphicsWebView is fixed.
       
   441                     list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, QInputMethodEvent::TextFormat, gray));
       
   442                 } else {
       
   443                     list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, mEngine->inputLength(), taillength, gray));
       
   444                 }				
       
   445                 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mEngine->inputLength(), 0, 0));
       
   446                 // the best guess word is sent to the editor
       
   447                 QInputMethodEvent event(bestGuessWord, list);
       
   448                 focusedObject->sendEvent(event);
       
   449                 mTailShowing = true;
       
   450             } else {
       
   451                 QInputMethodEvent::Attribute textstyle(QInputMethodEvent::TextFormat, 0, mCandidates->at(mPrimaryCandidateIndex).length(), underlined);
       
   452                 list.append(textstyle);
       
   453                 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mCandidates->at(mPrimaryCandidateIndex).length(), 0, 0));
       
   454                 QInputMethodEvent event(mCandidates->at(mPrimaryCandidateIndex), list);
       
   455                 focusedObject->sendEvent(event);
       
   456                 mTailShowing = false;
       
   457             }
       
   458 
       
   459             if (mShowTooltip && mPrimaryCandidateIndex != mSecondaryCandidateIndex) {                
       
   460                 q->processExactWord(mCandidates->at(mSecondaryCandidateIndex));
       
   461             } else {
       
   462                 QString empty;
       
   463                 q->processExactWord(empty);
       
   464             }
       
   465         } else {
       
   466             QInputMethodEvent event(QString(""), list);
       
   467             focusedObject->sendEvent(event);
       
   468         }
       
   469     }
       
   470 }
       
   471 
       
   472 void HbInputPredictionQwertyHandlerPrivate::commitSecondaryWord()
       
   473 {
       
   474     if(mCandidates->count()>mSecondaryCandidateIndex) {
       
   475         QString commitString = mCandidates->at(mSecondaryCandidateIndex);
       
   476         commit(commitString, true, false);
       
   477     }
       
   478 }
       
   479 
       
   480 void HbInputPredictionQwertyHandlerPrivate::showExactWordPopupIfNeeded()
       
   481 {
       
   482     Q_Q(HbInputPredictionHandler);
       
   483     if (mShowTooltip && mCandidates->count() > mPrimaryCandidateIndex && mCandidates->at(0).mid(0, mEngine->inputLength()) \
       
   484         != mCandidates->at(mPrimaryCandidateIndex).mid(0, mEngine->inputLength())) {                
       
   485         q->processExactWord(mCandidates->at(mSecondaryCandidateIndex));
       
   486     } else {
       
   487         QString empty;
       
   488         q->processExactWord(empty);
       
   489     }
       
   490 }
       
   491 
       
   492 QString HbInputPredictionQwertyHandlerPrivate::getCommitString()
       
   493 {
       
   494     QString commitString;
       
   495     if(mCandidates->count() <= mPrimaryCandidateIndex) {
       
   496         commitString = mCandidates->at(0);
       
   497     } else {
       
   498         commitString = mCandidates->at(mPrimaryCandidateIndex);
       
   499     }
       
   500     return commitString;
       
   501 }
       
   502 
       
   503 void HbInputPredictionQwertyHandler::setTypingCorrectionLevel(HbTypingCorrectionLevel correctionLevel)
       
   504 {
       
   505     Q_D(HbInputPredictionQwertyHandler);
       
   506     HbPredictionEngine::HbErrorCorrectionLevel errorCorrectionLevel = HbPredictionEngine::HbErrorCorrectionLevelMedium;
       
   507     if(d->mCorrectionLevel == correctionLevel) {
       
   508         return;
       
   509     }
       
   510     d->mCorrectionLevel = correctionLevel;
       
   511     switch(correctionLevel) {
       
   512         case HbTypingCorrectionLevelLow:
       
   513             errorCorrectionLevel = HbPredictionEngine::HbErrorCorrectionLevelLow;
       
   514             break;
       
   515         case HbTypingCorrectionLevelMedium:
       
   516             errorCorrectionLevel = HbPredictionEngine::HbErrorCorrectionLevelMedium;
       
   517             break;
       
   518         case HbTypingCorrectionLevelHigh:
       
   519             errorCorrectionLevel = HbPredictionEngine::HbErrorCorrectionLevelHigh;
       
   520             break;
       
   521         default:
       
   522             break;
       
   523     }
       
   524     if(d->mEngine) {
       
   525         d->mEngine->setErrorCorrectionLevel(errorCorrectionLevel);
       
   526     }
       
   527 }
       
   528 
   362 //EOF
   529 //EOF