|
1 /* |
|
2 * Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0"" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Provides the TAknFepInputStateInitialIndicPhoneticMultitap methods. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 #include "aknfepuiinputstateinitialindicphoneticmultitap.h" |
|
29 #include "AknFepUIManagerStateInterface.h" //MAknFepUIManagerStateInterface |
|
30 #include "AknFepUIManagerWestern.h" |
|
31 #include "AknFepUiIndicEnums.h" |
|
32 #include "AknFepCaseManager.h" |
|
33 #include "AknFepUiIndicInputManager.h" |
|
34 |
|
35 #include <uikon.hrh> |
|
36 #include <PtiEngine.h> |
|
37 #include <PtiDefs.h> |
|
38 #include <aknsctdialog.h> |
|
39 #include <avkon.rsg> |
|
40 #include <AknFep.rsg> |
|
41 #include <EikEnv.h> |
|
42 #include <Aknutils.h> |
|
43 #define PHONETIC_SEPARATOR 0x2e |
|
44 |
|
45 const TUint KSpaceChar = 0x0020; |
|
46 const TUint KQuestionMark = 0x003F; |
|
47 |
|
48 #define PTI_CLEAR_CURRENTWORD( A, B ) \ |
|
49 ( A )->ClearCurrentWord(); \ |
|
50 ( B ) = ETrue; \ |
|
51 |
|
52 const TText KAknFEPLineFeedSymbol = 0x21B2; |
|
53 const TText KAknFEPMirroredLineFeedSymbol = 0x21B3; |
|
54 |
|
55 // ----------------------------------------------------------------------------- |
|
56 // TAknFepInputStateInitialIndicPhoneticMultitap::TAknFepInputStateInitialIndicPhoneticMultitap |
|
57 |
|
58 // C++ default constructor can NOT contain any code, that |
|
59 // might leave or if it is absolutely necessary then MUST be trapped. |
|
60 // ----------------------------------------------------------------------------- |
|
61 |
|
62 TAknFepInputStateInitialIndicPhoneticMultitap:: |
|
63 TAknFepInputStateInitialIndicPhoneticMultitap( MAknFepUIManagerStateInterface* aOwner, |
|
64 TInt aLanguage ) |
|
65 :TAknFepInputStateInitialMultitapBase( aOwner ) |
|
66 { |
|
67 CPtiEngine* ptiengine = iOwner->PtiEngine(); |
|
68 iIsStarKeyPressed = EFalse; |
|
69 iIndicLanguage = TLanguage(aLanguage); |
|
70 iIndicPhoneticBuffer.Zero(); |
|
71 TRAP_IGNORE( ptiengine->ActivateLanguageL(KLangHindiPhonetic, |
|
72 EPtiEngineInputModeIndicPhoneticMultitap)) |
|
73 ptiengine->SetCase( EPtiCaseLower ); |
|
74 iPreviousCommittedChar = NULL; |
|
75 } |
|
76 |
|
77 // ----------------------------------------------------------------------------- |
|
78 // TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyL |
|
79 |
|
80 // Handles the logic of Indic multitap input. This function first checks the validity |
|
81 // of the inputed text and then enters it. |
|
82 // ----------------------------------------------------------------------------- |
|
83 |
|
84 TBool TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyL( TInt aKey, |
|
85 TKeyPressLength aLength ) |
|
86 { |
|
87 TBool result = ETrue; |
|
88 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
89 CPtiEngine* ptiengine = iOwner->PtiEngine(); |
|
90 |
|
91 if(aKey == EKeyBackspace) |
|
92 { |
|
93 iIndicPhoneticBuffer.Zero(); |
|
94 iPhoneticLatinChar = 0; |
|
95 iPreviousCommittedChar = 0; |
|
96 } |
|
97 else if(fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches) |
|
98 && aKey != EPtiKey0 && aLength != ELongKeyPress) |
|
99 { |
|
100 //no matches, so just play tone |
|
101 fepMan->PlaySound(EAvkonSIDConfirmationTone); |
|
102 } |
|
103 else |
|
104 { |
|
105 if ( iData && ( iData != aKey ) && (!iIsStarKeyPressed )) |
|
106 { |
|
107 //iPrevCharacter = |
|
108 TransliterateFromLatinL(); |
|
109 PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired ) |
|
110 // = ; |
|
111 } |
|
112 iIsStarKeyPressed = EFalse; |
|
113 if ( aLength == EShortKeyPress ) |
|
114 { |
|
115 if ( aKey == EPtiKeyStar ) // Overriding Key |
|
116 { |
|
117 ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL ); |
|
118 iIsStarKeyPressed = ETrue; |
|
119 } |
|
120 else |
|
121 { |
|
122 TPtrC ptiText = ptiengine->AppendKeyPress( ( TPtiKey )aKey ); |
|
123 iPhoneticLatinChar = ptiText[0]; |
|
124 |
|
125 if (IsToTransliterate(iPhoneticLatinChar) |
|
126 && (!fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches))) |
|
127 { |
|
128 TBuf<CAknFepManager::EMaximumFepWordLength> buf; |
|
129 buf.Copy(iIndicPhoneticBuffer); |
|
130 buf.Append(ptiText); |
|
131 fepMan->NewCharacterSequenceL(buf,EIndicInputResponsePhoneticMultitapText); |
|
132 } |
|
133 else if(!IsToTransliterate(iPhoneticLatinChar)) |
|
134 { |
|
135 TChar prevcharacter(fepMan->PreviousChar()); |
|
136 |
|
137 if((fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)) && (KQuestionMark == prevcharacter)) |
|
138 { |
|
139 fepMan->RemovePreviousCharacterL(); |
|
140 fepMan->ClearFlag(CAknFepManager::EFlagNoMatches); |
|
141 ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL ); |
|
142 } |
|
143 iIndicPhoneticBuffer.Zero(); |
|
144 if(IsToTransliterate(prevcharacter) && prevcharacter != '0') |
|
145 fepMan->CommitInlineEditL(); |
|
146 fepMan->NewCharacterSequenceL(ptiText,EIndicInputResponseNone); |
|
147 } |
|
148 } |
|
149 } |
|
150 else |
|
151 { |
|
152 if(fepMan->PreviousChar() == KQuestionMark) |
|
153 { |
|
154 fepMan->RemovePreviousCharacterL(); |
|
155 } |
|
156 fepMan->ClearFlag(CAknFepManager::EFlagNoMatches); |
|
157 |
|
158 /* Long press of a Key */ |
|
159 if ( aKey == EPtiKeyStar) |
|
160 { |
|
161 |
|
162 /* Launch the SCT For Indic */ |
|
163 if( fepMan->EditorHasFreeSpace() ) |
|
164 { |
|
165 if (fepMan->IsAbleToLaunchSCT() && !fepMan->EditSubmenuInUse()) |
|
166 { |
|
167 fepMan->LaunchSpecialCharacterTableL(); |
|
168 } |
|
169 } |
|
170 } |
|
171 else |
|
172 { |
|
173 //commit the inline text |
|
174 fepMan->CommitInlineEditL(); |
|
175 //Remove one character, to remove the Latin character |
|
176 //appended because of the short key press. This is |
|
177 //because long key press results in short key press |
|
178 //and then long key press. |
|
179 fepMan->RemovePreviousCharacterL(); |
|
180 //Reset the phonetic state in FEP. So, that any further |
|
181 //phonetic conversion will start from fresh. |
|
182 iIndicPhoneticBuffer.SetLength(0); |
|
183 iPhoneticLatinChar = 0; |
|
184 iPreviousCommittedChar = 0; |
|
185 |
|
186 ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL ); |
|
187 TUint prevchar = fepMan->PreviousChar(ETrue); |
|
188 if(!((aKey == EPtiKey1) && ((0x0031 == prevchar) || (0x0967 == prevchar)) )) |
|
189 { |
|
190 TChar ch( aKey ); |
|
191 TBuf<1> buf; |
|
192 buf.Append( ch ); |
|
193 fepMan->NewCharacterSequenceL( buf, EIndicInputResponseNumber ); |
|
194 fepMan->CommitInlineEditL(); |
|
195 PTI_CLEAR_CURRENTWORD( ptiengine, iIsKeyTimerExpired ) |
|
196 } |
|
197 } |
|
198 } |
|
199 iData = aKey; |
|
200 } |
|
201 //hindi phonetic changes |
|
202 if(iPhoneticLatinChar.IsUpper()) |
|
203 { |
|
204 fepMan->HandleIndicCaseL(); |
|
205 } |
|
206 return( result ); |
|
207 } |
|
208 |
|
209 // ----------------------------------------------------------------------------- |
|
210 // TAknFepInputStateInitialIndicPhoneticMultitap::KeyTimerExpired |
|
211 |
|
212 // Handles the logic of post keytimerexpired event. This function commits |
|
213 // the inline editing text to the editor. |
|
214 // ----------------------------------------------------------------------------- |
|
215 |
|
216 void TAknFepInputStateInitialIndicPhoneticMultitap::KeyTimerExpired() |
|
217 { |
|
218 TRAP_IGNORE(HandleKeyTimerExpiryL()) |
|
219 iData = 0; |
|
220 iOwner->PtiEngine()->ClearCurrentWord(); |
|
221 if((iPreviousCommittedChar = iOwner->FepMan()->PreviousChar()) == 0x002E) |
|
222 iPreviousCommittedChar = iOwner->FepMan()->PreviousToPreviousChar(ETrue); |
|
223 iIsKeyTimerExpired = ETrue; |
|
224 } |
|
225 |
|
226 void TAknFepInputStateInitialIndicPhoneticMultitap::HandleKeyTimerExpiryL() |
|
227 { |
|
228 CPtiEngine* ptiengine = iOwner->PtiEngine(); |
|
229 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
230 if ( !(fepMan->EditorHasFreeSpace() |
|
231 || fepMan->IsFlagSet(CAknFepManager::EFlagInsideMultitapInlineEditingTransaction))) |
|
232 { |
|
233 return; |
|
234 } |
|
235 if(iData && ( IsToTransliterate(iPhoneticLatinChar) && iData != EPtiKeyStar) |
|
236 && !fepMan->IsFlagSet(CAknFepManager::EFlagNoMatches)) |
|
237 { |
|
238 TransliterateFromLatinL(); |
|
239 } |
|
240 else if ( !IsToTransliterate (iPhoneticLatinChar)) |
|
241 { |
|
242 MPtiLanguage* ptilang = ptiengine->CurrentLanguage(); |
|
243 TInt languageCode = (ptilang)? ptilang->LanguageCode() : 0; |
|
244 // Space clears Explicite halant for North Indian Languages. |
|
245 if(IsToRemoveHalantForLanguage(languageCode)) |
|
246 { |
|
247 RemoveHalantL(TLanguage(languageCode)); |
|
248 } |
|
249 ptiengine->HandleCommandL(EPtiCommandBreakSyllable, NULL ); |
|
250 fepMan->CommitInlineEditL(); |
|
251 iIndicPhoneticBuffer.Zero(); |
|
252 } |
|
253 else |
|
254 { |
|
255 iOwner->FepMan()->CommitInlineEditL(); |
|
256 iIndicPhoneticBuffer.Zero(); |
|
257 } |
|
258 } |
|
259 |
|
260 void TAknFepInputStateInitialIndicPhoneticMultitap :: TransliterateFromLatinL() |
|
261 { |
|
262 TPhoneticArg arg; |
|
263 TBuf<CAknFepManager::EMaximumFepWordLength> destinationbuf; |
|
264 destinationbuf.Zero(); |
|
265 TInt errorcode = 0; |
|
266 CPtiEngine* ptiengine = iOwner->PtiEngine(); |
|
267 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
268 MPtiLanguage* ptilang = iOwner->PtiEngine()->CurrentLanguage(); |
|
269 TInt languageCode = (ptilang)? ptilang->LanguageCode() : 0; |
|
270 |
|
271 arg.iChar = iPhoneticLatinChar; |
|
272 arg.iDest = & destinationbuf; |
|
273 errorcode = ptiengine->HandleCommandL(EPtiCommandGetPhoneticText,REINTERPRET_CAST( TAny*, &arg)); |
|
274 AknTextUtils::LanguageSpecificNumberConversion(destinationbuf); |
|
275 switch(errorcode) |
|
276 { |
|
277 case KErrNone: |
|
278 { |
|
279 if(arg.iState == EIndicSyllableStateSyllableBroken) |
|
280 { |
|
281 if(iIndicPhoneticBuffer.Length()) |
|
282 { |
|
283 fepMan->CommitInlineEditL(iIndicPhoneticBuffer, iIndicPhoneticBuffer.Length()); |
|
284 iPreviousCommittedChar = fepMan->PreviousChar(ETrue); |
|
285 iIndicPhoneticBuffer.Zero(); |
|
286 } |
|
287 } |
|
288 |
|
289 if (destinationbuf.Length()) |
|
290 { |
|
291 if(! ValidatePhoneticInputL(destinationbuf, TLanguage(languageCode))) |
|
292 { |
|
293 break; |
|
294 } |
|
295 |
|
296 fepMan->NewCharacterSequenceL(destinationbuf, |
|
297 EIndicInputResponsePhoneticMultitapText); |
|
298 |
|
299 if(TAknFepUiIndicInputManager::IsCharOther(destinationbuf[0], |
|
300 TLanguage(languageCode)) && 0x002E != destinationbuf[0]) |
|
301 { |
|
302 fepMan->CommitInlineEditL(); |
|
303 iIndicPhoneticBuffer.Zero(); |
|
304 } |
|
305 else |
|
306 { |
|
307 iIndicPhoneticBuffer.Copy(destinationbuf); |
|
308 } |
|
309 } |
|
310 } |
|
311 break; |
|
312 case KErrOverflow: |
|
313 { |
|
314 fepMan->NewCharacterSequenceL(destinationbuf,EIndicInputResponsePhoneticMultitapText); |
|
315 fepMan->CommitInlineEditL(); |
|
316 ptiengine->HandleCommandL(EPtiCommandClearPhoneticBuffer,NULL); |
|
317 } |
|
318 break; |
|
319 default: |
|
320 break; |
|
321 } |
|
322 iPhoneticLatinChar = 0; |
|
323 } |
|
324 |
|
325 TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsToRemoveHalantForLanguage(TInt aLanguage) |
|
326 { |
|
327 TBool ret = EFalse; |
|
328 switch(aLanguage) |
|
329 { |
|
330 case KLangHindiPhonetic: |
|
331 ret = ETrue; |
|
332 break; |
|
333 } |
|
334 return ret; |
|
335 } |
|
336 |
|
337 inline TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsToTransliterate(TChar& aChar) |
|
338 { |
|
339 return !(KAknFEPLineFeedSymbol == aChar || KSpaceChar == aChar); |
|
340 } |
|
341 |
|
342 TBool TAknFepInputStateInitialIndicPhoneticMultitap::ValidatePhoneticInputL(const TDes& aBuf, |
|
343 TLanguage aLanguage) |
|
344 { |
|
345 TBool ret = ETrue; |
|
346 TUint curChar = 0; |
|
347 TUint prevChar=0; |
|
348 TUint len=aBuf.Length(); |
|
349 TPtr buffer(const_cast<TText*>( aBuf.Ptr() ),len,len); |
|
350 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
351 TPtiTextCase newCase = iOwner->PtiEngine()->Case(); |
|
352 if(! iPreviousCommittedChar) |
|
353 { |
|
354 iPreviousCommittedChar = fepMan->PreviousChar(ETrue); |
|
355 } |
|
356 while(len) |
|
357 { |
|
358 if(buffer[len-1] == 0x94d) |
|
359 { |
|
360 len--; |
|
361 buffer.SetLength(len); |
|
362 continue; |
|
363 } |
|
364 else if(!curChar) |
|
365 { |
|
366 curChar = buffer[len-1] ; |
|
367 len--; |
|
368 } |
|
369 else if(!prevChar) |
|
370 { |
|
371 prevChar = buffer[len-1] ; |
|
372 len--; |
|
373 } |
|
374 else |
|
375 break; |
|
376 } |
|
377 if(!prevChar) |
|
378 prevChar = iPreviousCommittedChar; |
|
379 /* |
|
380 Multitap does not allow any fall back characters. The phonetic engine does not |
|
381 check for the fallback characters and FEP has to do it. |
|
382 */ |
|
383 //fallback character if Nukta is entered after Nukta |
|
384 if((TAknFepUiIndicInputManager::IsCharNukta(prevChar,aLanguage) && |
|
385 TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) || |
|
386 |
|
387 //fallback character if Nukta is entered after Modifier or |
|
388 //Modifier is entered after Modifier |
|
389 (TAknFepUiIndicInputManager::IsCharModifier(prevChar,aLanguage) && |
|
390 (TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage) || |
|
391 TAknFepUiIndicInputManager::IsCharModifier(curChar,aLanguage))) || |
|
392 |
|
393 //fallback character if Nukta is entered after Vowel or |
|
394 //Nukta is entered after matra |
|
395 ((TAknFepUiIndicInputManager::IsCharAnVowel(prevChar,aLanguage) || |
|
396 TAknFepUiIndicInputManager::IsCharMatra(prevChar,aLanguage)) && |
|
397 TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) || |
|
398 //fallback character if Nukta is entered after Nukta Consonant |
|
399 (TAknFepUiIndicInputManager::IsCharNuktaConsonant(prevChar,aLanguage) && |
|
400 TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) || |
|
401 |
|
402 //fallback character if Nukta entered in an empty editor |
|
403 (prevChar == PHONETIC_SEPARATOR && |
|
404 TAknFepUiIndicInputManager::IsCharNukta(curChar,aLanguage)) |
|
405 ) |
|
406 { |
|
407 TBuf<1> buffer; |
|
408 fepMan->CommitInlineEditL(iIndicPhoneticBuffer, iIndicPhoneticBuffer.Length()); |
|
409 buffer.Append(KQuestionMark); |
|
410 if(!fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) |
|
411 { |
|
412 fepMan->StartInlineEditL(); |
|
413 } |
|
414 fepMan->UpdateInlineEditL(buffer,CAknFepManager::ESingleCharacter); |
|
415 fepMan->SetFlag(CAknFepManager::EFlagNoMatches); |
|
416 ret = EFalse; |
|
417 } |
|
418 return ret; |
|
419 } |
|
420 |
|
421 TBool TAknFepInputStateInitialIndicPhoneticMultitap::IsInvalidPhoneticCharacter( |
|
422 TUint aChar, TLanguage aLanguage ) |
|
423 { |
|
424 TBool ret = EFalse; |
|
425 if(TAknFepUiIndicInputManager::IsCharNukta( aChar, aLanguage ) |
|
426 || TAknFepUiIndicInputManager::IsCharMatra( aChar, aLanguage ) |
|
427 || TAknFepUiIndicInputManager::IsCharModifier( aChar, aLanguage ) |
|
428 || TAknFepUiIndicInputManager::IsCharVirama( aChar, aLanguage )) |
|
429 { |
|
430 ret = ETrue; |
|
431 } |
|
432 return ret; |
|
433 } |
|
434 |
|
435 void TAknFepInputStateInitialIndicPhoneticMultitap::RemoveHalantL(TLanguage aLanguage) |
|
436 { |
|
437 MAknFepManagerUIInterface* fepMan = iOwner->FepMan(); |
|
438 TBool isLineFeedEntered = fepMan->IsFlagSet(CAknFepManager::EFlagLineFeedCharacter); |
|
439 if (fepMan->IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) |
|
440 { |
|
441 fepMan->CommitInlineEditL(); |
|
442 } |
|
443 |
|
444 TInt position = 0; |
|
445 |
|
446 if(TAknFepUiIndicInputManager::IsCharVirama(fepMan->PreviousChar(ETrue), aLanguage)) |
|
447 { |
|
448 position = 1; |
|
449 } |
|
450 else if(!isLineFeedEntered && |
|
451 TAknFepUiIndicInputManager::IsCharVirama(fepMan->PreviousToPreviousChar(ETrue), aLanguage)) |
|
452 { |
|
453 position = 2; |
|
454 } |
|
455 if(position) |
|
456 fepMan->RemoveTextFromEditorL( 1, position-1, EFalse ); |
|
457 if(fepMan->NextChar() == KSpaceChar) |
|
458 { |
|
459 fepMan->AlignLogicalAndVisualCursorL(TTmDocPosSpec::ELeading, EFalse); |
|
460 } |
|
461 } |
|
462 |
|
463 void TAknFepInputStateInitialIndicPhoneticMultitap::GetPhoneticLatinChar(TChar& aChar)const |
|
464 { |
|
465 aChar = iPhoneticLatinChar; |
|
466 } |
|
467 //End of File |