@@ -115,6 +115,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
115
115
m_formatRetriever(0 ),
116
116
m_pointerHandler(0 ),
117
117
m_hasTempPreeditString(false ),
118
+ m_cachedCursorAndAnchorPosition(-1 ),
118
119
m_splitViewResizeBy(0 ),
119
120
m_splitViewPreviousWindowStates(Qt::WindowNoState)
120
121
{
@@ -158,9 +159,18 @@ void QCoeFepInputContext::reset()
158
159
}
159
160
// Store a copy of preedit text, if prediction is active and input context is reseted.
160
161
// This is to ensure that we can replace preedit string after losing focus to FEP manager's
161
- // internal sub-windows.
162
- if (m_cachedPreeditString.isEmpty () && !(currentHints & Qt::ImhNoPredictiveText))
162
+ // internal sub-windows. Additionally, store the cursor position if there is no selected text.
163
+ // This allows input context to replace preedit strings if they are not at the end of current
164
+ // text.
165
+ if (m_cachedPreeditString.isEmpty () && !(currentHints & Qt::ImhNoPredictiveText)) {
163
166
m_cachedPreeditString = m_preeditString;
167
+ if (focusWidget ()) {
168
+ int cursor = focusWidget ()->inputMethodQuery (Qt::ImCursorPosition).toInt ();
169
+ int anchor = focusWidget ()->inputMethodQuery (Qt::ImAnchorPosition).toInt ();
170
+ if (cursor == anchor)
171
+ m_cachedCursorAndAnchorPosition = cursor;
172
+ }
173
+ }
164
174
commitCurrentString (true );
165
175
}
166
176
@@ -196,6 +206,7 @@ void QCoeFepInputContext::setFocusWidget(QWidget *w)
196
206
void QCoeFepInputContext::widgetDestroyed (QWidget *w)
197
207
{
198
208
m_cachedPreeditString.clear ();
209
+ m_cachedCursorAndAnchorPosition = -1 ;
199
210
200
211
// Make sure that the input capabilities of whatever new widget got focused are queried.
201
212
CCoeControl *ctrl = w->effectiveWinId ();
@@ -981,6 +992,7 @@ void QCoeFepInputContext::StartFepInlineEditL(const TDesC& aInitialInlineText,
981
992
return ;
982
993
983
994
m_cachedPreeditString.clear ();
995
+ m_cachedCursorAndAnchorPosition = -1 ;
984
996
985
997
commitTemporaryPreeditString ();
986
998
@@ -1039,8 +1051,16 @@ void QCoeFepInputContext::UpdateFepInlineTextL(const TDesC& aNewInlineText,
1039
1051
QString newPreeditString = qt_TDesC2QString (aNewInlineText);
1040
1052
QInputMethodEvent event (newPreeditString, attributes);
1041
1053
if (!m_cachedPreeditString.isEmpty ()) {
1042
- event.setCommitString (QLatin1String (" " ), -m_cachedPreeditString.length (), m_cachedPreeditString.length ());
1054
+ int cursorPos = w->inputMethodQuery (Qt::ImCursorPosition).toInt ();
1055
+ // Predicted word is either replaced from the end of the word (normal case),
1056
+ // or from stored location, if the predicted word is either in the beginning of,
1057
+ // or in the middle of already committed word.
1058
+ int diff = cursorPos - m_cachedCursorAndAnchorPosition;
1059
+ int replaceLocation = (diff != m_cachedPreeditString.length ()) ? diff : m_cachedPreeditString.length ();
1060
+
1061
+ event.setCommitString (QLatin1String (" " ), -replaceLocation, m_cachedPreeditString.length ());
1043
1062
m_cachedPreeditString.clear ();
1063
+ m_cachedCursorAndAnchorPosition = -1 ;
1044
1064
} else if (newPreeditString.isEmpty () && m_preeditString.isEmpty ()) {
1045
1065
// In Symbian world this means "erase last character".
1046
1066
event.setCommitString (QLatin1String (" " ), -1 , 1 );
@@ -1138,6 +1158,10 @@ void QCoeFepInputContext::SetCursorSelectionForFepL(const TCursorSelection& aCur
1138
1158
1139
1159
int pos = aCursorSelection.iAnchorPos ;
1140
1160
int length = aCursorSelection.iCursorPos - pos;
1161
+ if (m_cachedCursorAndAnchorPosition != -1 ) {
1162
+ pos = m_cachedCursorAndAnchorPosition;
1163
+ length = 0 ;
1164
+ }
1141
1165
1142
1166
QList<QInputMethodEvent::Attribute> attributes;
1143
1167
attributes << QInputMethodEvent::Attribute (QInputMethodEvent::Selection, pos, length, QVariant ());
@@ -1155,6 +1179,13 @@ void QCoeFepInputContext::GetCursorSelectionForFep(TCursorSelection& aCursorSele
1155
1179
1156
1180
int cursor = w->inputMethodQuery (Qt::ImCursorPosition).toInt () + m_preeditString.size ();
1157
1181
int anchor = w->inputMethodQuery (Qt::ImAnchorPosition).toInt () + m_preeditString.size ();
1182
+
1183
+ // If the position is stored, use that value, so that word replacement from proposed word
1184
+ // lists are added to the correct position.
1185
+ if (m_cachedCursorAndAnchorPosition != -1 ) {
1186
+ cursor = m_cachedCursorAndAnchorPosition;
1187
+ anchor = m_cachedCursorAndAnchorPosition;
1188
+ }
1158
1189
QString text = w->inputMethodQuery (Qt::ImSurroundingText).value <QString>();
1159
1190
int combinedSize = text.size () + m_preeditString.size ();
1160
1191
if (combinedSize < anchor || combinedSize < cursor) {
0 commit comments