64 { |
64 { |
65 mShowTail = true; |
65 mShowTail = true; |
66 mShowTooltip = true; |
66 mShowTooltip = true; |
67 // A backspace in predictive means updating the engine for the delete key press |
67 // A backspace in predictive means updating the engine for the delete key press |
68 // and get the new candidate list from the engine. |
68 // and get the new candidate list from the engine. |
69 if ((mEngine->inputLength() >= 1) || selectWord()) { |
69 if ( mEngine->inputLength() >= 1 ) { |
70 //Only autocomplition part should be deleted when autocompliton part is enable and user pressed a delete key |
70 //Only autocomplition part should be deleted when autocompliton part is enable and user pressed a delete key |
71 if(false == mTailShowing) { |
71 if(false == mTailShowing) { |
72 mEngine->deleteKeyPress( this ); |
72 mEngine->deleteKeyPress( this ); |
73 } |
73 } |
74 //To prevent showing autocompletion part while deleting the characters using backspace key |
74 //To prevent showing autocompletion part while deleting the characters using backspace key |
75 mShowTail = false; |
75 mShowTail = false; |
76 mShowTooltip = false; |
76 mShowTooltip = false; |
77 if (mEngine->inputLength() > 0) { |
77 bool unused = false; |
78 bool unused = false; |
78 mEngine->updateCandidates(mBestGuessLocation, unused); |
79 mEngine->updateCandidates(mBestGuessLocation, unused); |
79 //If Input length greater or equal to one then Append the current word to candidate |
80 if (!mCandidates->count()) { |
80 if (!mCandidates->count() && mEngine->inputLength() >= 1) { |
81 mCandidates->append(mEngine->currentWord()); |
81 mCandidates->append(mEngine->currentWord()); |
82 } |
82 } |
83 } |
|
84 mCanContinuePrediction = true; |
83 mCanContinuePrediction = true; |
85 // update the editor with the new preedit text. |
84 // update the editor with the new preedit text. |
86 updateEditor(); |
85 updateEditor(); |
87 return; |
86 return; |
88 } |
87 } else { |
89 |
88 // we come here if their is no data in engine. |
90 HbInputFocusObject* focusedObject = 0; |
89 // once the word is committed, we can not bring it back to inline edit. |
91 focusedObject = mInputMethod->focusObject(); |
90 // so if the engine does not have any data, we just send backspace event to the editor. |
92 if (!focusedObject) { |
91 Q_Q(HbInputPredictionHandler); |
93 return; |
92 QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier); |
94 } |
93 q->sendAndUpdate(event); |
95 |
94 event = QKeyEvent(QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier); |
96 if ((focusedObject->inputMethodQuery(Qt::ImCursorPosition).toInt() >= 0) || focusedObject->preEditString().length()) { |
95 q->sendAndUpdate(event); |
97 QList<QInputMethodEvent::Attribute> list; |
96 return; |
98 QInputMethodEvent event(QString(), list); |
|
99 event.setCommitString(QString(), -1, 1); |
|
100 commit(event); |
|
101 } |
97 } |
102 } |
98 } |
103 |
99 |
104 void HbInputPredictionHandlerPrivate::commitAndAppendCharacter(QChar character) |
100 void HbInputPredictionHandlerPrivate::commitAndAppendCharacter(QChar character) |
105 { |
101 { |
192 } |
188 } |
193 return QList<HbKeyPressProbability>(); |
189 return QList<HbKeyPressProbability>(); |
194 } |
190 } |
195 |
191 |
196 /*! |
192 /*! |
197 This sets the selected candidate from the candidate list as the editor text. |
|
198 */ |
|
199 bool HbInputPredictionHandlerPrivate::selectWord(bool selectFromLeft) |
|
200 { |
|
201 if (!mEngine) { |
|
202 return false; |
|
203 } |
|
204 mShowTail = false; |
|
205 |
|
206 HbInputFocusObject* focusedObject = 0; |
|
207 focusedObject = mInputMethod->focusObject(); |
|
208 if(!focusedObject) { |
|
209 return false; |
|
210 } |
|
211 // No word selected, if we move next to a word on left side, select it |
|
212 int cursorPos = focusedObject->inputMethodQuery(Qt::ImCursorPosition).toInt(); |
|
213 |
|
214 QString text = focusedObject->inputMethodQuery(Qt::ImSurroundingText).toString(); |
|
215 if ((cursorPos > 0 && selectFromLeft) || (cursorPos < text.length() && !selectFromLeft)) { |
|
216 int start; |
|
217 int end; |
|
218 if (selectFromLeft && cursorPos>=1 &&!text.at(cursorPos-1).isSpace()) { |
|
219 // selecting word from left side of cursor |
|
220 end = cursorPos; |
|
221 for(start = end; start > 0; start--) { |
|
222 if (text.at(start-1).isSpace()) { |
|
223 break; |
|
224 } |
|
225 } |
|
226 } else if (!selectFromLeft && !text.at(cursorPos).isSpace()) { |
|
227 // selecting word from right side of cursor |
|
228 start = cursorPos; |
|
229 for(end = start; end < text.length(); ++end) { |
|
230 if (text.at(end).isSpace()) { |
|
231 break; |
|
232 } |
|
233 } |
|
234 } else { |
|
235 // no word in the direction where cursor is moving |
|
236 return false; |
|
237 } |
|
238 int length = end-start; |
|
239 // update internal state and editor |
|
240 if(length > 0){ |
|
241 mEngine->setWord(text.mid(start, length), this); |
|
242 } |
|
243 bool unused = false; |
|
244 mEngine->updateCandidates(mBestGuessLocation, unused); |
|
245 //With selection we can always continue predicting, even when the selection |
|
246 //is not a well predicted word. |
|
247 if (!mCandidates->count()) { |
|
248 //Here we are making sure that even if the engine does not return any candidate |
|
249 //for given input sequence, the candidate list is non-empty. In such a scenario |
|
250 //the candidate list will contain the actual selection or the exact word. |
|
251 mCandidates->append(mEngine->currentWord()); |
|
252 } |
|
253 // |
|
254 QTextCharFormat underlined; |
|
255 QList<QInputMethodEvent::Attribute> list; |
|
256 underlined.setFontUnderline(true); |
|
257 QInputMethodEvent::Attribute textstyle(QInputMethodEvent::TextFormat, 0, mEngine->inputLength(), underlined); |
|
258 list.append(textstyle); |
|
259 QInputMethodEvent event(mCandidates->at(0), list); |
|
260 event.setCommitString(QString(), (selectFromLeft ? -length : 0), length); |
|
261 focusedObject->sendEvent(event); |
|
262 return true; |
|
263 } else { |
|
264 return false; |
|
265 } |
|
266 } |
|
267 |
|
268 /*! |
|
269 This method updates the editor contents based on the candidates available in the candidate list. |
193 This method updates the editor contents based on the candidates available in the candidate list. |
270 */ |
194 */ |
271 void HbInputPredictionHandlerPrivate::updateEditor() |
195 void HbInputPredictionHandlerPrivate::updateEditor() |
272 { |
196 { |
273 Q_Q(HbInputPredictionHandler); |
197 Q_Q(HbInputPredictionHandler); |
291 } else { |
215 } else { |
292 if (mCandidates->count() > mBestGuessLocation) { |
216 if (mCandidates->count() > mBestGuessLocation) { |
293 int taillength = mCandidates->at(mBestGuessLocation).length() - mEngine->inputLength(); |
217 int taillength = mCandidates->at(mBestGuessLocation).length() - mEngine->inputLength(); |
294 if (taillength > 0 && mShowTail) { |
218 if (taillength > 0 && mShowTail) { |
295 // TODO: Color from skin should be used |
219 // TODO: Color from skin should be used |
296 QColor col = HbColorScheme::color("qtc_editor_hint_normal"); |
220 QColor col = HbColorScheme::color("qtc_input_hint_normal"); |
297 QBrush brush(col); |
221 QBrush brush(col); |
298 QTextCharFormat gray; |
222 QTextCharFormat gray; |
299 gray.setForeground(brush); |
223 gray.setForeground(brush); |
300 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, mEngine->inputLength(), taillength, gray)); |
224 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, mEngine->inputLength(), taillength, gray)); |
301 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mEngine->inputLength(), 0, 0)); |
225 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mEngine->inputLength(), 0, 0)); |
507 } |
431 } |
508 } |
432 } |
509 |
433 |
510 void HbInputPredictionHandlerPrivate::init() |
434 void HbInputPredictionHandlerPrivate::init() |
511 { |
435 { |
|
436 mEngine = NULL; |
512 HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage(); |
437 HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage(); |
513 mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language()); |
438 mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language()); |
514 if (mEngine) { |
439 if (mEngine && !mCandidates) { |
515 mCandidates = new QStringList(); |
440 mCandidates = new QStringList(); |
516 } |
441 } |
517 } |
442 } |
518 |
443 |
519 void HbInputPredictionHandlerPrivate::reset() |
444 void HbInputPredictionHandlerPrivate::reset() |
650 } |
575 } |
651 //Temporarily delete the key press |
576 //Temporarily delete the key press |
652 mEngine->deleteKeyPress(); |
577 mEngine->deleteKeyPress(); |
653 mEngine->updateCandidates(mBestGuessLocation, isCustomWord); |
578 mEngine->updateCandidates(mBestGuessLocation, isCustomWord); |
654 if (mCandidates->count()){ |
579 if (mCandidates->count()){ |
|
580 (*mCandidates)[mBestGuessLocation] = (*mCandidates)[mBestGuessLocation].left(mEngine->inputLength()); |
655 (*mCandidates)[mBestGuessLocation].append("?"); |
581 (*mCandidates)[mBestGuessLocation].append("?"); |
656 } else { |
582 } else { |
657 //Should the mBestGuessLocation not be zero. |
583 //Should the mBestGuessLocation not be zero. |
658 mBestGuessLocation = 0; |
584 mBestGuessLocation = 0; |
659 mCandidates->append(mEngine->currentWord()); |
585 mCandidates->append(mEngine->currentWord()); |