|
1 /* |
|
2 * Copyright (c) 2008 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: Keymappings etc. customized for Series 60. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <CVPbkContactLinkArray.h> |
|
21 #include <MVPbkContactLink.h> |
|
22 #include <CVPbkContactManager.h> |
|
23 #include <MVPbkStoreContact.h> |
|
24 #include <MVPbkContactOperationBase.h> |
|
25 #include <MVPbkContactFieldData.h> |
|
26 #include <MVPbkContactFieldTextData.h> |
|
27 |
|
28 #include <CPbk2SortOrderManager.h> |
|
29 #include <Pbk2ContactNameFormatterFactory.h> |
|
30 #include <MPbk2ContactNameFormatter.h> |
|
31 |
|
32 // Avkon dialog for info notes |
|
33 #include <aknnotewrappers.h> |
|
34 |
|
35 // for fetching contacts from phonebook |
|
36 #include <CPbk2StoreConfiguration.h> |
|
37 #include <MVPbkStoreContact.h> |
|
38 #include <CVPbkContactLinkArray.h> |
|
39 #include <MVPbkContactFieldTextData.h> |
|
40 #include <MVPbkContactStoreList.h> |
|
41 #include <CVPbkContactManager.h> |
|
42 |
|
43 // aiw used to invoke phonebook |
|
44 #include <AiwContactSelectionDataTypes.h> |
|
45 |
|
46 // phone client API classes for starting phone call |
|
47 #include <AiwCommon.h> |
|
48 #include <aiwdialdata.h> |
|
49 #include <aiwdialdataext.h> |
|
50 |
|
51 // FeatureManager::FeatureSupported(KFeatureIdThai) used in SetInitialInputModeL |
|
52 #include <featmgr.h> |
|
53 // CAknExtendedInputCapabilities for extended input capabilities |
|
54 #include <aknextendedinputcapabilities.h> |
|
55 |
|
56 #include <StringLoader.h> |
|
57 |
|
58 |
|
59 #include <eikenv.h> |
|
60 #include <eikappui.h> |
|
61 #include <coecntrl.h> |
|
62 |
|
63 #include <EIKCOCTL.rsg> |
|
64 |
|
65 #include <aknenv.h> |
|
66 #include <AknUtils.h> |
|
67 #include <AknSettingCache.h> |
|
68 |
|
69 #include <aknappui.h> |
|
70 |
|
71 #include <AknsUtils.h> |
|
72 |
|
73 #include <j2me/jdebug.h> |
|
74 |
|
75 #include "CMIDKeyDecoder.h" |
|
76 #include "CMIDEdwinUtils.h" |
|
77 |
|
78 #include <lcdui.rsg> |
|
79 |
|
80 #undef TRAP_INSTRUMENTATION_LEAVE |
|
81 #define TRAP_INSTRUMENTATION_LEAVE(aResult) DEBUG_INT2("In CMIDEdwin.cpp, trapped method was called at line %D and got exception %D", __LINE__, aResult); |
|
82 |
|
83 CMIDEdwinUtils* CMIDEdwinUtils::NewL(MMIDTextBox* aTextBox, const TChar aDecimalSeparator) |
|
84 { |
|
85 CMIDEdwinUtils* utils = new(ELeave) CMIDEdwinUtils(aTextBox, aDecimalSeparator); |
|
86 CleanupStack::PushL(utils); |
|
87 utils->ConstructL(); |
|
88 CleanupStack::Pop(utils); |
|
89 return utils; |
|
90 } |
|
91 |
|
92 CMIDEdwinUtils::CMIDEdwinUtils(MMIDTextBox* aTextBox, const TChar aDecimalSeparator) |
|
93 : iTextBox(aTextBox), iDecimalSeparator(aDecimalSeparator) |
|
94 {} |
|
95 |
|
96 void CMIDEdwinUtils::ConstructL() |
|
97 { |
|
98 } |
|
99 |
|
100 /** |
|
101 * Checks whether the given text is valid within the given constraints. |
|
102 * When the contents of the TextBox are set PROGRAMMATICALLY (parameter aActualContents |
|
103 * is true), constraint validity is checked more strictly, as some constraints |
|
104 * allow certain strings while the user is typing but not as the actual contents. |
|
105 */ |
|
106 TBool CMIDEdwinUtils::ConstraintsValidForText(const TDesC& aText,TUint aConstraints, TBool aActualContents) |
|
107 { |
|
108 TUint constraint = aConstraints & MMIDTextField::EConstraintMask; |
|
109 if (constraint == MMIDTextField::EAny) |
|
110 return ETrue; |
|
111 // |
|
112 TBool valid = ETrue; |
|
113 switch (constraint) |
|
114 { |
|
115 case MMIDTextField::EMailAddr: |
|
116 case MMIDTextField::EUrl: |
|
117 valid = IsTextValid(aText); |
|
118 break; |
|
119 case MMIDTextField::ENumeric: |
|
120 if (aActualContents) |
|
121 { |
|
122 valid = IsJavaInteger(aText); |
|
123 } |
|
124 else |
|
125 { |
|
126 valid = IsNumeric(aText); |
|
127 } |
|
128 break; |
|
129 case MMIDTextField::EPhoneNumber: |
|
130 valid = CMIDEdwinUtils::IsPhoneNumber(aText); |
|
131 break; |
|
132 case MMIDTextField::EDecimal: |
|
133 if (aActualContents) |
|
134 { |
|
135 valid = IsJavaFloatingPointLiteral(aText); |
|
136 } |
|
137 else |
|
138 { |
|
139 valid = IsDecimal(aText, iDecimalSeparator); |
|
140 } |
|
141 break; |
|
142 default: |
|
143 ASSERT(EFalse); |
|
144 } |
|
145 return valid; |
|
146 } |
|
147 |
|
148 TBool CMIDEdwinUtils::ConstraintsValidForInsertedTextL(const TDesC& aText, const TDesC& aTextToInsert, TInt aPos, TUint aConstraints, TBool aActualContents) |
|
149 { |
|
150 HBufC* text = HBufC::NewL(aText.Length() + aTextToInsert.Length()); |
|
151 TPtr ptr = text->Des(); |
|
152 ptr.Copy(aText); |
|
153 ptr.Insert(aPos,aTextToInsert); |
|
154 TBool valid = ConstraintsValidForText(ptr, aConstraints, aActualContents); |
|
155 delete text; |
|
156 return valid; |
|
157 } |
|
158 |
|
159 |
|
160 TBool CMIDEdwinUtils::IsHotKeyL(const TKeyEvent& aKeyEvent, CCoeEnv* aCoeEnv) |
|
161 { |
|
162 TBuf<24> buf; |
|
163 if (aKeyEvent.iModifiers & EModifierShift) |
|
164 { |
|
165 aCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS); |
|
166 } |
|
167 else |
|
168 { |
|
169 aCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_CTRL_HOTKEYS); |
|
170 } |
|
171 const TInt ret=buf.Locate(TChar(aKeyEvent.iCode+'a'-1)); |
|
172 switch (ret) |
|
173 { |
|
174 case CEikEdwin::EHotKeyCut: |
|
175 case CEikEdwin::EHotKeyCopy: |
|
176 case CEikEdwin::EHotKeyPaste: |
|
177 case CEikEdwin::EHotKeyUndo: |
|
178 case CEikEdwin::EHotKeyFind: |
|
179 case CEikEdwin::EHotKeyInsertChar: |
|
180 return ETrue; |
|
181 default: |
|
182 return EFalse; |
|
183 } |
|
184 } |
|
185 |
|
186 TBool CMIDEdwinUtils::IsNavigationKey(const TKeyEvent& aKeyEvent) |
|
187 { |
|
188 switch (aKeyEvent.iCode) |
|
189 { |
|
190 case EKeyDownArrow: |
|
191 case EKeyUpArrow: |
|
192 case EKeyLeftArrow: |
|
193 case EKeyRightArrow: |
|
194 case EKeyBackspace: |
|
195 case EKeyDelete: |
|
196 case EKeyEscape: |
|
197 case EKeyPageUp: |
|
198 case EKeyPageDown: |
|
199 case EKeyHome: |
|
200 case EKeyEnd: |
|
201 return ETrue; |
|
202 default: |
|
203 return EFalse; |
|
204 } |
|
205 } |
|
206 |
|
207 TBool CMIDEdwinUtils::IsPhoneNumber(const TDesC& aText) |
|
208 { |
|
209 TInt pos = aText.Length(); |
|
210 for (; pos>0;) |
|
211 { |
|
212 TChar ch((aText)[--pos]); |
|
213 // allow also digits in non-western numbers |
|
214 if (IsNumeric(ch)) |
|
215 continue; |
|
216 |
|
217 switch (ch) |
|
218 { |
|
219 case '+': |
|
220 case '*': |
|
221 case '#': |
|
222 case 'p': |
|
223 case 'w': |
|
224 break; |
|
225 default: |
|
226 return EFalse; |
|
227 } |
|
228 } |
|
229 return ETrue; |
|
230 } |
|
231 |
|
232 /** |
|
233 * Tests whether a typed string is a legal NUMERIC string. This test is more |
|
234 * loose than that in IsJavaInteger(), as "-" is a |
|
235 * legal text value during typing but not when set programmatically. |
|
236 */ |
|
237 TBool CMIDEdwinUtils::IsNumeric(const TDesC& aText) |
|
238 { |
|
239 TInt length = aText.Length(); |
|
240 TInt pos = length; |
|
241 for (; pos>0;) |
|
242 { |
|
243 TChar ch((aText)[--pos]); |
|
244 // |
|
245 if (IsNumeric(ch)) |
|
246 continue; |
|
247 // |
|
248 switch (ch) |
|
249 { |
|
250 case '-': |
|
251 if (pos != 0) |
|
252 return EFalse; |
|
253 break; |
|
254 default: |
|
255 return EFalse; |
|
256 } |
|
257 } |
|
258 return ETrue; |
|
259 } |
|
260 |
|
261 /** |
|
262 * Tests whether a character is legal number, correct values |
|
263 * are 0-9 and all language variants (arabic etc.) |
|
264 */ |
|
265 TBool CMIDEdwinUtils::IsNumeric(const TChar& aChar) |
|
266 { |
|
267 return ((aChar >= '0' && aChar <= '9') // Western |
|
268 || (aChar >= 0x0660 && aChar <= 0x0669) // Arabic-Indic |
|
269 || (aChar >= 0x06F0 && aChar <= 0x06F9) // Extended Arabic-Indic |
|
270 || (aChar >= 0x0966 && aChar <= 0x096F) // Devanagari |
|
271 || (aChar >= 0xFF10 && aChar <= 0xFF19) // Fullwidth |
|
272 ); |
|
273 } |
|
274 |
|
275 /** |
|
276 * Tests whether the given string is a legal NUMERIC string when set |
|
277 * programmatically. |
|
278 * |
|
279 * According to the Java API spec, a string cannot be parsed into an int if: |
|
280 * Any character of the string is not a digit of the specified radix, |
|
281 * except that the first character may be a minus sign '-' ('\u002D') |
|
282 * provided that the string is longer than length 1. |
|
283 */ |
|
284 TBool CMIDEdwinUtils::IsJavaInteger(const TDesC& aText) |
|
285 { |
|
286 if (!IsNumeric(aText)) |
|
287 { |
|
288 return EFalse; |
|
289 } |
|
290 // additional test #1: "-" is illegal |
|
291 if (aText.Length() == 1) |
|
292 { |
|
293 if ((aText.Locate(TChar('-')) == 0)) |
|
294 { |
|
295 return EFalse; |
|
296 } |
|
297 } |
|
298 return ETrue; |
|
299 } |
|
300 |
|
301 /** |
|
302 * Tests whether a typed text is a valid one. |
|
303 */ |
|
304 TBool CMIDEdwinUtils::IsTextValid(const TDesC& aText) |
|
305 { |
|
306 TInt pos = aText.Length(); |
|
307 while (pos-- > 0) |
|
308 { |
|
309 TChar ch((aText)[ pos ]); |
|
310 |
|
311 // IsValidChar function will check chars over 255 |
|
312 if (!IsValidChar(ch.GetNumericValue()) || ch == 0x7f) |
|
313 { |
|
314 return EFalse; |
|
315 } |
|
316 } |
|
317 |
|
318 return ETrue; |
|
319 } |
|
320 |
|
321 /** |
|
322 * Tests whether a char is a valid. Tests only characters over 255 |
|
323 */ |
|
324 TBool CMIDEdwinUtils::IsValidChar(TInt aChar) const |
|
325 { |
|
326 TBool ret(ETrue); |
|
327 |
|
328 // Tests only characters over 255 |
|
329 if (aChar >= 0xFF) |
|
330 { |
|
331 // 0x20AC - Unicode for euro sign |
|
332 if (aChar == 0x20AC || aChar == CEditableText::EParagraphDelimiter || |
|
333 aChar == CEditableText::ELineBreak) |
|
334 { |
|
335 ret = ETrue; |
|
336 } |
|
337 else |
|
338 { |
|
339 ret = EFalse; |
|
340 } |
|
341 } |
|
342 |
|
343 return ret; |
|
344 } |
|
345 |
|
346 /** |
|
347 * Tests whether a typed string is a legal DECIMAL string. This test is more |
|
348 * loose than that in IsJavaFloatingPointLiteral(), as ".", "-" and "-." are |
|
349 * legal text values during typing but not when set programmatically. |
|
350 */ |
|
351 TBool CMIDEdwinUtils::IsDecimal(const TDesC& aText, const TChar aDecimalSeparator) |
|
352 { |
|
353 TInt length = aText.Length(); |
|
354 TInt pos = length; |
|
355 for (; pos>0;) |
|
356 { |
|
357 TChar ch((aText)[--pos]); |
|
358 // |
|
359 if (ch.IsDigit()) |
|
360 { |
|
361 continue; |
|
362 } |
|
363 else if (ch == '-') |
|
364 { |
|
365 if (pos != 0) |
|
366 return EFalse; |
|
367 } |
|
368 else if (ch == aDecimalSeparator) |
|
369 { |
|
370 if (aText.Locate(aDecimalSeparator) != aText.LocateReverse(aDecimalSeparator)) |
|
371 return EFalse; |
|
372 } |
|
373 else |
|
374 { |
|
375 return EFalse; |
|
376 } |
|
377 } |
|
378 return ETrue; |
|
379 } |
|
380 |
|
381 /** |
|
382 * Tests whether the given string is a legal DECIMAL string when set |
|
383 * programmatically. |
|
384 */ |
|
385 TBool CMIDEdwinUtils::IsJavaFloatingPointLiteral(const TDesC& aText) |
|
386 { |
|
387 if (!IsDecimal(aText, '.')) |
|
388 { |
|
389 return EFalse; |
|
390 } |
|
391 // additional test #1: "." and "-" are illegal |
|
392 if (aText.Length() == 1) |
|
393 { |
|
394 if ((aText.Locate(TChar('.')) == 0) || (aText.Locate(TChar('-')) == 0)) |
|
395 { |
|
396 return EFalse; |
|
397 } |
|
398 } |
|
399 // additional test #2: "-." is illegal |
|
400 if (aText.Length() == 2) |
|
401 { |
|
402 if ((aText.Locate(TChar('-')) == 0) && (aText.Locate(TChar('.')) == 1)) |
|
403 { |
|
404 return EFalse; |
|
405 } |
|
406 } |
|
407 return ETrue; |
|
408 } |
|
409 |
|
410 void CMIDEdwinUtils::RemoveNonPhoneNumberChars(HBufC* buf) |
|
411 { |
|
412 TPtr text = buf->Des(); |
|
413 for (TInt pos=0; pos < text.Length();) |
|
414 { |
|
415 TChar ch((text)[pos]); |
|
416 // allow also digits in non-western numbers |
|
417 if (IsNumeric(ch)) |
|
418 { |
|
419 ++pos; |
|
420 continue; |
|
421 } |
|
422 |
|
423 switch (ch) |
|
424 { |
|
425 case '+': |
|
426 case '*': |
|
427 case '#': |
|
428 case 'p': |
|
429 case 'w': |
|
430 ++pos; |
|
431 continue; |
|
432 } |
|
433 text.Delete(pos, 1); |
|
434 } |
|
435 } |
|
436 |
|
437 /** Converts from java format text to localized (visible) format. |
|
438 @see ConvertToLocalizedDecimalLC() */ |
|
439 HBufC* CMIDEdwinUtils::ConvertToLocalizedLC(const TDesC& aText, TUint aConstraints) |
|
440 { |
|
441 HBufC* text = NULL; |
|
442 if ((aConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal) |
|
443 { |
|
444 text = ConvertToLocalizedDecimalLC(aText); |
|
445 } |
|
446 else |
|
447 { |
|
448 text = aText.AllocLC(); |
|
449 TBool supportLineBreaks(ETrue); |
|
450 |
|
451 // Convert breaks if needed if constraints that do not allow line |
|
452 // breaks. |
|
453 if (aConstraints & MMIDTextField::EUrl || |
|
454 aConstraints & MMIDTextField::EMailAddr) |
|
455 { |
|
456 // Line breaks are not supported |
|
457 supportLineBreaks = EFalse; |
|
458 } |
|
459 |
|
460 CMIDUtils::MapJavaToETextChars(text, supportLineBreaks); |
|
461 } |
|
462 return text; |
|
463 } |
|
464 |
|
465 /** Converts decimal point, if any, to a localized decimal separator. */ |
|
466 HBufC* CMIDEdwinUtils::ConvertToLocalizedDecimalLC(const TDesC& aText) |
|
467 { |
|
468 HBufC* buf = aText.AllocLC(); |
|
469 TPtr text = buf->Des(); |
|
470 TInt pos = buf->Length(); |
|
471 for (; pos>0;) |
|
472 { |
|
473 TText& ch = text[--pos]; |
|
474 if (ch == '.') |
|
475 ch = (TText)iDecimalSeparator; |
|
476 } |
|
477 return buf; |
|
478 } |
|
479 |
|
480 /** Converts localized decimal separator, if any, to a decimal point. */ |
|
481 void CMIDEdwinUtils::ConvertFromLocalizedDecimal(HBufC* buf) |
|
482 { |
|
483 TPtr text = buf->Des(); |
|
484 TInt pos = buf->Length(); |
|
485 for (; pos>0;) |
|
486 { |
|
487 TText& ch = text[--pos]; |
|
488 if (ch == (TText)iDecimalSeparator) |
|
489 ch = '.'; |
|
490 } |
|
491 } |
|
492 |
|
493 |
|
494 TLanguage CMIDEdwinUtils::SelectLanguage(TInt aCharSubset, |
|
495 TLanguage aDefaultLanguage) |
|
496 { |
|
497 TLanguage language = CAknEnv::Static()->SettingCache().InputLanguage(); |
|
498 if (IsLanguageInCharSubset(language, aCharSubset)) |
|
499 { |
|
500 return language; // global input language |
|
501 } |
|
502 language = User::Language(); |
|
503 if (IsLanguageInCharSubset(language, aCharSubset)) |
|
504 { |
|
505 return language; // display language |
|
506 } |
|
507 return aDefaultLanguage; // given default |
|
508 } |
|
509 |
|
510 /** |
|
511 * Returns ETrue if the given language belongs to the given MIDP character subset. |
|
512 */ |
|
513 TBool CMIDEdwinUtils::IsLanguageInCharSubset(TLanguage aLanguage, TInt aCharSubset) |
|
514 { |
|
515 switch (aLanguage) |
|
516 { |
|
517 // Cyrillic languages: |
|
518 case ELangBulgarian: |
|
519 case ELangRussian: |
|
520 case ELangSerbian: |
|
521 case ELangUkrainian: |
|
522 return (aCharSubset == EMidpUcbCyrillic); |
|
523 |
|
524 // Arabic languages: |
|
525 case ELangArabic: |
|
526 case ELangFarsi: |
|
527 case ELangUrdu: |
|
528 return (aCharSubset == EMidpUcbArabic); |
|
529 |
|
530 // Traditional Chinese languages, support latin, too: |
|
531 case ELangTaiwanChinese: |
|
532 case ELangHongKongChinese: |
|
533 return (aCharSubset == EMidpIsTraditionalHanzi || |
|
534 aCharSubset == EMidpIsLatin); |
|
535 // Devanagari script languages |
|
536 case ELangHindi: |
|
537 case ELangMarathi: |
|
538 return (aCharSubset == EMidpUcbDevanagari); |
|
539 |
|
540 // Single languages that belong to other character subsets than latin |
|
541 case ELangHebrew: |
|
542 case ELangGreek: |
|
543 case ELangVietnamese: // not yet in 3.0 |
|
544 case ELangThai: |
|
545 return (aCharSubset == EMidpCharSubsetNone); |
|
546 |
|
547 // All the rest are latin languages; Japanese and Simplified Chinese |
|
548 // included here, because they support latin, too |
|
549 default: |
|
550 return (aCharSubset == EMidpIsLatin); |
|
551 } |
|
552 } |
|
553 /** |
|
554 * Returns ETrue if number conversion is needed. |
|
555 */ |
|
556 TBool CMIDEdwinUtils::IsNumberConversionNeeded(TInt aConstraints) |
|
557 { |
|
558 TUint constraint = aConstraints & MMIDTextField::EConstraintMask; |
|
559 if (constraint == 0) |
|
560 return AknTextUtils::DigitModeQuery(AknTextUtils::EDigitModeEditorDefault); |
|
561 else if ((constraint == MMIDTextField::ENumeric |
|
562 || constraint == MMIDTextField::EDecimal |
|
563 || constraint == MMIDTextField::EPhoneNumber |
|
564 ) && AknTextUtils::DigitModeQuery(AknTextUtils::EDigitModeNumberEditor) |
|
565 ) |
|
566 return ETrue; |
|
567 else if ((constraint == MMIDTextField::EMailAddr |
|
568 || constraint == MMIDTextField::EUrl |
|
569 ) && AknTextUtils::DigitModeQuery(AknTextUtils::EDigitModeNumberEditor) |
|
570 ) |
|
571 return ETrue; |
|
572 |
|
573 return EFalse; |
|
574 } |
|
575 |
|
576 void CMIDEdwinUtils::CreatePhoneCallL(TInt aTextLength, RWsSession aWsSession, CEikEdwin* aEdwin) |
|
577 { |
|
578 if (aTextLength == 0 || aTextLength > AIWDialDataExt::KMaximumPhoneNumberLength) |
|
579 { |
|
580 return; // silently ignore empty or too long number |
|
581 } |
|
582 |
|
583 /* |
|
584 * Get the current window group. Needed to activate the current app window |
|
585 * @note Temporary. This might not necessarily be the front-most window group, |
|
586 * as window groups can disable keyboard focus. |
|
587 */ |
|
588 RWsSession wsSession = aWsSession; |
|
589 TInt currWindowGroup = wsSession.GetFocusWindowGroup(); |
|
590 |
|
591 // ask for confirmation (as required by MIDP) |
|
592 CCallConfirmationDialog* dlg = CCallConfirmationDialog::NewL(aEdwin->GetTextInHBufL()->Des()); |
|
593 |
|
594 if (!dlg->ExecuteLD(R_MIDP_CONFIRMATION_DIALOG)) |
|
595 return; |
|
596 |
|
597 // Create service handler instance |
|
598 CAiwServiceHandler* aiwServiceHandler = CAiwServiceHandler::NewLC(); // cleanup stack 1 |
|
599 |
|
600 // Create AIW interest |
|
601 RCriteriaArray interest; |
|
602 CleanupClosePushL(interest); // cleanup stack 2 |
|
603 CAiwCriteriaItem* criteria = CAiwCriteriaItem::NewLC( |
|
604 KAiwCmdCall, KAiwCmdCall, |
|
605 _L8("*")); // cleanup stack 3 |
|
606 TUid base; |
|
607 base.iUid = KAiwClassBase; |
|
608 criteria->SetServiceClass(base); |
|
609 User::LeaveIfError(interest.Append(criteria)); |
|
610 |
|
611 // attach to AIW interest |
|
612 aiwServiceHandler->AttachL(interest); |
|
613 |
|
614 // create dial data |
|
615 CAiwDialData* dialData = CAiwDialData::NewLC(); // cleanup stack 4 |
|
616 |
|
617 // define call parameters |
|
618 dialData->SetCallType(CAiwDialData::EAIWVoice); // voice call |
|
619 |
|
620 // Use GetTextL to convert allow conversion of non-western numbers |
|
621 HBufC* phoneNumber = iTextBox->GetTextL(); // get the phone number |
|
622 CleanupStack::PushL(phoneNumber); // cleanup stack 5 in case something leaves |
|
623 dialData->SetPhoneNumberL(*phoneNumber); |
|
624 |
|
625 // the window group where it switches to after the phone call |
|
626 dialData->SetWindowGroup(currWindowGroup); |
|
627 |
|
628 CAiwGenericParamList& paramList = aiwServiceHandler->InParamListL(); |
|
629 dialData->FillInParamListL(paramList); |
|
630 |
|
631 // Execute AIW command with notification callback |
|
632 aiwServiceHandler->ExecuteServiceCmdL(KAiwCmdCall, paramList, |
|
633 aiwServiceHandler->OutParamListL(), |
|
634 0, NULL); |
|
635 |
|
636 // detach from AIW interest |
|
637 aiwServiceHandler->DetachL(interest); |
|
638 |
|
639 // aiwServiceHandler, interest, criteria, dialData, phoneNumber |
|
640 CleanupStack::PopAndDestroy(5); |
|
641 |
|
642 aiwServiceHandler = NULL; |
|
643 phoneNumber = NULL; |
|
644 } |
|
645 |
|
646 void CMIDEdwinUtils::SetInitialInputModeL(const TDesC& aCharacterSubset, TUint aConstraints, TInt& aInitialCurrentCase, |
|
647 TInt& aInitialCurrentInputMode, TLanguage& aInitialCurrentLanguage) |
|
648 { |
|
649 TInt initialCurrentCase = 0; |
|
650 TInt initialCurrentInputMode = 0; |
|
651 TLanguage initialCurrentLanguage = ELangTest; // 0 |
|
652 |
|
653 TUint constraint = aConstraints & MMIDTextField::EConstraintMask; |
|
654 if (constraint == MMIDTextField::EAny || |
|
655 constraint == MMIDTextField::EMailAddr || |
|
656 constraint == MMIDTextField::EUrl) |
|
657 { |
|
658 if (aCharacterSubset.Length() == 0) |
|
659 { |
|
660 // null: default input mode |
|
661 initialCurrentLanguage = CAknEnv::Static()->SettingCache().InputLanguage(); |
|
662 initialCurrentCase = EAknEditorTextCase; |
|
663 } |
|
664 else if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0) |
|
665 { |
|
666 // MIDP_UPPERCASE_LATIN |
|
667 // ignored if INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY |
|
668 if (!(aConstraints & MMIDTextField::EInitialCapsWordSentence || |
|
669 aConstraints & MMIDTextField::EInitialCapsWord) || |
|
670 constraint != MMIDTextField::EAny) |
|
671 { |
|
672 initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsLatin, ELangEnglish); |
|
673 initialCurrentInputMode = EAknEditorTextInputMode; |
|
674 initialCurrentCase = EAknEditorUpperCase; |
|
675 } |
|
676 } |
|
677 else if (aCharacterSubset.Compare(KMidpLowercaseLatin) == 0) |
|
678 { |
|
679 // MIDP_LOWERCASE_LATIN |
|
680 // ignored if INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY |
|
681 if (!(aConstraints & MMIDTextField::EInitialCapsWordSentence || |
|
682 aConstraints & MMIDTextField::EInitialCapsWord) || |
|
683 constraint != MMIDTextField::EAny) |
|
684 { |
|
685 initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsLatin, ELangEnglish); |
|
686 initialCurrentInputMode = EAknEditorTextInputMode; |
|
687 initialCurrentCase = EAknEditorLowerCase; |
|
688 } |
|
689 } |
|
690 else if (aCharacterSubset.Compare(KUcbBasicLatin) == 0 || |
|
691 aCharacterSubset.Compare(KIsLatin) == 0) |
|
692 { |
|
693 // UCB_BASIC_LATIN, IS_LATIN |
|
694 initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsLatin, ELangEnglish); |
|
695 initialCurrentInputMode = EAknEditorTextInputMode; |
|
696 initialCurrentCase = EAknEditorTextCase; |
|
697 } |
|
698 else if (aCharacterSubset.Compare(KIsLatinDigits) == 0) |
|
699 { |
|
700 // IS_LATIN_DIGITS |
|
701 initialCurrentInputMode = EAknEditorNumericInputMode; |
|
702 } |
|
703 else if (aCharacterSubset.Compare(KUcbArabic) == 0) |
|
704 { |
|
705 // UCB_ARABIC |
|
706 initialCurrentLanguage = ELangArabic; |
|
707 } |
|
708 else if (aCharacterSubset.Compare(KUcbHebrew) == 0) |
|
709 { |
|
710 // UCB_HEBREW |
|
711 initialCurrentLanguage = ELangHebrew; |
|
712 } |
|
713 else if (aCharacterSubset.Compare(KUcbGreek) == 0) |
|
714 { |
|
715 // UCB_GREEK |
|
716 initialCurrentLanguage = ELangGreek; |
|
717 initialCurrentCase = EAknEditorTextCase; |
|
718 } |
|
719 else if (aCharacterSubset.Compare(KUcbCyrillic) == 0) |
|
720 { |
|
721 // UCB_CYRILLIC |
|
722 initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpUcbCyrillic, ELangRussian); |
|
723 initialCurrentCase = EAknEditorTextCase; |
|
724 } |
|
725 else if (aCharacterSubset.Compare(KUcbDevanagari) == 0) |
|
726 { |
|
727 // UCB_DEVANAGARI |
|
728 initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpUcbDevanagari, ELangHindi); |
|
729 } |
|
730 else if (aCharacterSubset.Compare(KUcbThai) == 0) |
|
731 { |
|
732 // UCB_THAI |
|
733 if (FeatureManager::FeatureSupported(KFeatureIdThai)) |
|
734 { |
|
735 initialCurrentLanguage = ELangThai; |
|
736 } |
|
737 } |
|
738 else if (aCharacterSubset.Compare(KIsSimplifiedHanzi) == 0) |
|
739 { |
|
740 // IS_SIMPLIIFED_HANZI |
|
741 if (FeatureManager::FeatureSupported(KFeatureIdChinese)) |
|
742 { |
|
743 initialCurrentLanguage = ELangPrcChinese; |
|
744 } |
|
745 } |
|
746 else if (aCharacterSubset.Compare(KIsTraditionalHanzi) == 0) |
|
747 { |
|
748 // IS_TRADITIONAL_HANZI |
|
749 if (FeatureManager::FeatureSupported(KFeatureIdChinese)) |
|
750 { |
|
751 initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsTraditionalHanzi, |
|
752 ELangTest); // No suitable default for initial input language |
|
753 } |
|
754 } |
|
755 else if (aCharacterSubset.Compare(KUcbKatakana) == 0) |
|
756 { |
|
757 // UCB_KATAKANA |
|
758 if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
759 { |
|
760 initialCurrentLanguage = ELangJapanese; |
|
761 initialCurrentInputMode = EAknEditorFullWidthKatakanaInputMode; |
|
762 } |
|
763 } |
|
764 else if (aCharacterSubset.Compare(KUcbHiragana) == 0 || |
|
765 aCharacterSubset.Compare(KIsKanji) == 0) |
|
766 { |
|
767 // UCB_HIRAGANA, IS_KANJI |
|
768 if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
769 { |
|
770 initialCurrentLanguage = ELangJapanese; |
|
771 initialCurrentInputMode = EAknEditorHiraganaKanjiInputMode; |
|
772 } |
|
773 } |
|
774 else if (aCharacterSubset.Compare(KIsHalfwidthKatakana) == 0) |
|
775 { |
|
776 // IS_HALFWIDTH_KATAKANA |
|
777 if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
778 { |
|
779 initialCurrentLanguage = ELangJapanese; |
|
780 initialCurrentInputMode = EAknEditorKatakanaInputMode; |
|
781 } |
|
782 } |
|
783 else if (aCharacterSubset.Compare(KIsFullwidthDigits) == 0) |
|
784 { |
|
785 // IS_FULLWIDTH_DIGITS |
|
786 if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
787 { |
|
788 initialCurrentLanguage = ELangJapanese; |
|
789 initialCurrentInputMode = EAknEditorFullWidthNumericInputMode; |
|
790 } |
|
791 } |
|
792 else if (aCharacterSubset.Compare(KIsFullwidthLatin) == 0) |
|
793 { |
|
794 // IS_FULLWIDTH_LATIN |
|
795 if (FeatureManager::FeatureSupported(KFeatureIdJapanese)) |
|
796 { |
|
797 initialCurrentLanguage = ELangJapanese; |
|
798 initialCurrentInputMode = EAknEditorFullWidthTextInputMode; |
|
799 } |
|
800 } |
|
801 else if (aCharacterSubset.Compare(KXNokiaVietnamese) == 0) |
|
802 { |
|
803 // X_NOKIA_VIETNAMESE |
|
804 initialCurrentLanguage = ELangVietnamese; |
|
805 initialCurrentInputMode = EAknEditorTextInputMode; |
|
806 initialCurrentCase = EAknEditorTextCase; |
|
807 } |
|
808 else if (aCharacterSubset.Compare(KXNokiaUrdu) == 0) |
|
809 { |
|
810 // X_NOKIA_URDU |
|
811 initialCurrentLanguage = ELangUrdu; |
|
812 initialCurrentInputMode = EAknEditorTextInputMode; |
|
813 } |
|
814 else if (aCharacterSubset.Compare(KXNokiaFarsi) == 0) |
|
815 { |
|
816 // X_NOKIA_FARSI |
|
817 initialCurrentLanguage = ELangFarsi; |
|
818 initialCurrentInputMode = EAknEditorTextInputMode; |
|
819 } |
|
820 |
|
821 aInitialCurrentCase = initialCurrentCase; |
|
822 aInitialCurrentInputMode = initialCurrentInputMode; |
|
823 aInitialCurrentLanguage = initialCurrentLanguage; |
|
824 } |
|
825 } |
|
826 |
|
827 void CMIDEdwinUtils::SetFEPModeAndCharFormat(TUint aConstraints, CEikEdwin* aEdwin) |
|
828 { |
|
829 // by default, allow all case modes |
|
830 aEdwin->SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes); |
|
831 aEdwin->SetAknEditorCase(EAknEditorTextCase); |
|
832 if (aEdwin->TextView()) |
|
833 { |
|
834 //This sets secret editors as one liners. |
|
835 //This is disabled because secret editors convert paragraph delimiters |
|
836 //in spaces and because the line wrapping works differently depending |
|
837 //on wheather the temporary char is displayed or the '*' is displayed. |
|
838 TRAP_IGNORE(aEdwin->SetWordWrapL(aConstraints & MMIDTextField::EPassword ? EFalse : ETrue)); |
|
839 } |
|
840 |
|
841 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
842 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() & |
|
843 EAknEditorFlagEnablePartialScreen); |
|
844 #else |
|
845 aEdwin->SetAknEditorFlags(EAknEditorFlagDefault); |
|
846 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
847 aEdwin->SetAknEditorSpecialCharacterTable(-1); |
|
848 // handle all constraints and the PASSWORD modifier |
|
849 TUint constraint = aConstraints & MMIDTextField::EConstraintMask; |
|
850 if ((constraint == MMIDTextField::EAny) && (aConstraints & MMIDTextField::EPassword)) |
|
851 { |
|
852 constraint = MMIDTextField::EPassword; |
|
853 } |
|
854 |
|
855 switch (constraint) |
|
856 { |
|
857 case MMIDTextField::EAny: |
|
858 aEdwin->SetAknEditorAllowedInputModes(EAknEditorTextInputMode | EAknEditorNumericInputMode); |
|
859 aEdwin->SetAknEditorInputMode(EAknEditorTextInputMode); |
|
860 // Calling AknEditorCurrentInputMode during construction caused problems in Chinese |
|
861 |
|
862 // handle other modifiers |
|
863 if ((aConstraints & MMIDTextField::ENonPredictive) || (aConstraints & MMIDTextField::ESensitive)) |
|
864 { |
|
865 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() | |
|
866 EAknEditorFlagNoT9 | |
|
867 EAknEditorFlagDeliverVirtualKeyEventsToApplication); |
|
868 } |
|
869 else |
|
870 { |
|
871 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() | |
|
872 EAknEditorFlagDeliverVirtualKeyEventsToApplication); |
|
873 } |
|
874 if ((aConstraints & MMIDTextField::EInitialCapsWordSentence) || (aConstraints & MMIDTextField::EInitialCapsWord)) |
|
875 { |
|
876 aEdwin->SetAknEditorCurrentCase(EAknEditorTextCase); |
|
877 } |
|
878 aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_SPECIAL_CHARACTER_TABLE_DIALOG); |
|
879 break; |
|
880 case MMIDTextField::EMailAddr: |
|
881 case MMIDTextField::EUrl: |
|
882 case MMIDTextField::EPassword: |
|
883 // set auto capitalization off, permit only UpperCase and LowerCase modes |
|
884 aEdwin->SetAknEditorPermittedCaseModes(EAknEditorUpperCase | EAknEditorLowerCase); |
|
885 |
|
886 aEdwin->SetAknEditorAllowedInputModes(EAknEditorTextInputMode | EAknEditorNumericInputMode); |
|
887 aEdwin->SetAknEditorInputMode(EAknEditorTextInputMode); |
|
888 aEdwin->SetAknEditorCurrentInputMode(EAknEditorTextInputMode); |
|
889 aEdwin->SetAknEditorCase(EAknEditorLowerCase); |
|
890 aEdwin->SetAknEditorCurrentCase(EAknEditorLowerCase); |
|
891 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() | |
|
892 EAknEditorFlagNoT9 | |
|
893 EAknEditorFlagDeliverVirtualKeyEventsToApplication); |
|
894 aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_SPECIAL_CHARACTER_TABLE_DIALOG); |
|
895 break; |
|
896 case MMIDTextField::ENumeric: |
|
897 { |
|
898 aEdwin->SetAknEditorCase(EAknSCTNumeric); |
|
899 aEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode); |
|
900 aEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode); |
|
901 aEdwin->SetAknEditorCurrentInputMode(EAknEditorNumericInputMode); |
|
902 aEdwin->SetAknEditorNumericKeymap(EAknEditorPlainNumberModeKeymap); |
|
903 //Disable SCT |
|
904 CAknExtendedInputCapabilities* extendedInputCapabilities = NULL; |
|
905 aEdwin->MopGetObject(extendedInputCapabilities); |
|
906 if (extendedInputCapabilities) |
|
907 { |
|
908 extendedInputCapabilities->SetCapabilities( |
|
909 extendedInputCapabilities->Capabilities() | |
|
910 CAknExtendedInputCapabilities::EDisableSCT); |
|
911 } |
|
912 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() | |
|
913 EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | |
|
914 EAknEditorFlagUseSCTNumericCharmap | |
|
915 EAknEditorFlagDeliverVirtualKeyEventsToApplication); |
|
916 aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_NUMERIC_MODE_DIALOG); |
|
917 } |
|
918 break; |
|
919 case MMIDTextField::EDecimal: |
|
920 aEdwin->SetAknEditorCase(EAknSCTNumeric); |
|
921 aEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode); |
|
922 aEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode); |
|
923 aEdwin->SetAknEditorCurrentInputMode(EAknEditorNumericInputMode); |
|
924 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() | |
|
925 EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | |
|
926 EAknEditorFlagUseSCTNumericCharmap | |
|
927 EAknEditorFlagDeliverVirtualKeyEventsToApplication); |
|
928 aEdwin->SetAknEditorNumericKeymap(EAknEditorPlainNumberModeKeymap); |
|
929 if (iDecimalSeparator == ',') |
|
930 { |
|
931 aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_DECIMAL_MODE_WITH_COMMA_DIALOG); |
|
932 } |
|
933 else |
|
934 { |
|
935 aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_DECIMAL_MODE_DIALOG); |
|
936 } |
|
937 break; |
|
938 case MMIDTextField::EPhoneNumber: |
|
939 aEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode); |
|
940 aEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode); |
|
941 aEdwin->SetAknEditorCurrentInputMode(EAknEditorNumericInputMode); |
|
942 aEdwin->SetAknEditorFlags(aEdwin->AknEdwinFlags() | |
|
943 EAknEditorFlagFixedCase | EAknEditorFlagNoT9 | |
|
944 EAknEditorFlagDeliverVirtualKeyEventsToApplication); |
|
945 aEdwin->SetAknEditorNumericKeymap(EAknEditorStandardNumberModeKeymap); |
|
946 break; |
|
947 } |
|
948 |
|
949 // make changes take effect |
|
950 TRAP_IGNORE(aEdwin->NotifyEditorStateObserverOfStateChangeL()); |
|
951 |
|
952 } |
|
953 |
|
954 // --------------------------------------------------------------------------- |
|
955 // CMIDEdwinUtils::CropToSingleLine |
|
956 // --------------------------------------------------------------------------- |
|
957 // |
|
958 void CMIDEdwinUtils::CropToSingleLine(TDes& aText) |
|
959 { |
|
960 DEBUG_STR("CMIDEdwinUtils::CropToSingleLine +, aText=%S", aText); |
|
961 |
|
962 TInt index = aText.Length(); |
|
963 while (index-- > 0) |
|
964 { |
|
965 TChar ch((aText)[ index ]); |
|
966 TChar::TCategory category = ch.GetCategory(); |
|
967 |
|
968 // CR or LF character |
|
969 if (ch == 0x0D || ch == 0x0A || |
|
970 category == TChar::EZlCategory || category == TChar::EZpCategory) |
|
971 { |
|
972 aText.Delete(index, 1); |
|
973 } |
|
974 } |
|
975 |
|
976 DEBUG_STR("CMIDEdwinUtils::CropToSingleLine -, aText=%S", aText); |
|
977 } |
|
978 |
|
979 // --------------------------------------------------------------------------- |
|
980 // CMIDEdwinUtils::ConvertToUnicodeBreaks |
|
981 // --------------------------------------------------------------------------- |
|
982 // |
|
983 void CMIDEdwinUtils::ConvertToUnicodeBreaks(TDes& aText) |
|
984 { |
|
985 DEBUG_STR("CMIDEdwinUtils::ConvertToUnicodeBreaks +, aText=%S", aText); |
|
986 |
|
987 const TInt length = aText.Length(); |
|
988 TText* ptr = const_cast < TText* >(aText.Ptr()); |
|
989 TInt index = 0; |
|
990 |
|
991 while (index < length) |
|
992 { |
|
993 if (ptr[ index ] == 0x0D || ptr[ index ] == 0x0A) |
|
994 { |
|
995 break; |
|
996 } |
|
997 |
|
998 index++; |
|
999 } |
|
1000 |
|
1001 TText prevChar = 0; |
|
1002 TInt finalLength = index; |
|
1003 |
|
1004 while (index < length) |
|
1005 { |
|
1006 TText ch = ptr[ index ]; |
|
1007 |
|
1008 if (ch != 0x0D && ch != 0x0A) |
|
1009 { |
|
1010 ptr[ finalLength++ ] = ch; |
|
1011 } |
|
1012 else |
|
1013 { |
|
1014 // Do not modify valid line breaks (CRLF) |
|
1015 if (!(ch == 0x0A && prevChar == 0x0D)) |
|
1016 { |
|
1017 ptr[ finalLength++ ] = CEditableText::EParagraphDelimiter; |
|
1018 } |
|
1019 } |
|
1020 |
|
1021 prevChar = ch; |
|
1022 index++; |
|
1023 } |
|
1024 |
|
1025 aText.SetLength(finalLength); |
|
1026 |
|
1027 DEBUG_STR("CMIDEdwinUtils::ConvertToUnicodeBreaks -, aText=%S", aText); |
|
1028 } |
|
1029 |
|
1030 /*************************************************************************** |
|
1031 * |
|
1032 * Class CPasswordBoxGlobalText |
|
1033 * |
|
1034 ****************************************************************************/ |
|
1035 |
|
1036 CPasswordBoxGlobalText::CPasswordBoxGlobalText(const CParaFormatLayer* aGlobalParaLayer, |
|
1037 const CCharFormatLayer* aGlobalCharLayer, |
|
1038 CEikEdwin& aTextComponent) |
|
1039 : CGlobalText(aGlobalParaLayer,aGlobalCharLayer), iTextComponent(aTextComponent), iClearCharPos(-1) |
|
1040 {} |
|
1041 |
|
1042 void CPasswordBoxGlobalText::ConstructL() |
|
1043 { |
|
1044 CGlobalText::ConstructL(CEditableText::ESegmentedStorage,CEditableText::EDefaultTextGranularity); |
|
1045 |
|
1046 iTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
|
1047 iClearText = HBufC::NewL(CEditableText::EDefaultTextGranularity); |
|
1048 } |
|
1049 |
|
1050 CPasswordBoxGlobalText::~CPasswordBoxGlobalText() |
|
1051 { |
|
1052 delete iClearText; |
|
1053 delete iTimer; |
|
1054 } |
|
1055 |
|
1056 /** */ |
|
1057 void CPasswordBoxGlobalText::Reset() |
|
1058 { |
|
1059 if (iTimer->IsActive()) |
|
1060 { //commit any previous character before deleting or else we |
|
1061 // may crash in the timer callback when trying to replace an uncommited |
|
1062 // but already deleted char |
|
1063 TRAP_IGNORE(DoTimerCallbackL(EFalse)); |
|
1064 } |
|
1065 // clear local (hidden) copy |
|
1066 TPtr ptr = iClearText->Des(); |
|
1067 ptr.SetLength(0); |
|
1068 |
|
1069 CGlobalText::Reset(); |
|
1070 } |
|
1071 |
|
1072 /** |
|
1073 * Support for pasting in the TextBox with PASSWORD constraint. The normal insertion |
|
1074 * mechanism is not used in the paste operation, so it must be handled separately |
|
1075 * here. This is an overriden method that stores the pasted chars to the local |
|
1076 * store and puts masked chars (*) to the visible store (in super class). |
|
1077 */ |
|
1078 TInt CPasswordBoxGlobalText::PasteFromStoreL(const CStreamStore& aStore,const CStreamDictionary& aDictionary,TInt aPos) |
|
1079 { |
|
1080 // 1. Paste clipboard text (to visible text) |
|
1081 TInt numCharsPasted = CGlobalText::PasteFromStoreL(aStore, aDictionary, aPos); |
|
1082 // 2. Insert the pasted text to the local clear text store |
|
1083 TPtrC ptr = Read(aPos, numCharsPasted); |
|
1084 SaveClearTextL(aPos, ptr); |
|
1085 // 3. Mask the visible text |
|
1086 for (int i = 0; i < numCharsPasted; i++) |
|
1087 { |
|
1088 TPtrC charToProcess = Read(aPos+i, 1); |
|
1089 TChar replaceChar = KPasswordEchoChar; |
|
1090 if (charToProcess[0] == CEditableText::EParagraphDelimiter) |
|
1091 { |
|
1092 replaceChar = ' '; |
|
1093 } |
|
1094 CGlobalText::DeleteL(aPos+i,1); |
|
1095 CGlobalText::InsertL(aPos+i, replaceChar); |
|
1096 } |
|
1097 return numCharsPasted; |
|
1098 } |
|
1099 |
|
1100 /** Insert a single character. First of all save the character in the clear text by |
|
1101 calling SaveClearTextL(). Then if the character is a paragraph delimiter insert a space. |
|
1102 Otherwise if we are in alpha mode insert the clear character and start the timer. Otherwise |
|
1103 insert the asterisks. */ |
|
1104 void CPasswordBoxGlobalText::InsertL(TInt aPos, const TChar& aChar) |
|
1105 { |
|
1106 TBuf<1> buf; |
|
1107 buf.Append(aChar); |
|
1108 SaveClearTextL(aPos, buf); |
|
1109 |
|
1110 if (aChar == CEditableText::EParagraphDelimiter) |
|
1111 { |
|
1112 CGlobalText::InsertL(aPos, ' '); |
|
1113 } |
|
1114 else if (iTextComponent.AknEditorCurrentInputMode() & KInputModesRequiringFeedbackWithSingleChar) |
|
1115 { |
|
1116 if (iTimer->IsActive() && iClearCharPos != aPos) |
|
1117 { //commit any previous character in a different position |
|
1118 DoTimerCallbackL(ETrue); |
|
1119 } |
|
1120 else |
|
1121 { //or restart the timer if the char is in the same position (multi-tap looping) |
|
1122 iTimer->Cancel(); |
|
1123 } |
|
1124 |
|
1125 CGlobalText::InsertL(aPos, aChar); |
|
1126 if (!iRejectNextKey) //For example the Enter key will be rejected |
|
1127 { |
|
1128 iClearCharPos = aPos; |
|
1129 iTimer->Start(KPasswordCharTimeout, KPasswordCharTimeout, TCallBack(TimerCallback, this)); |
|
1130 } |
|
1131 else |
|
1132 { |
|
1133 iRejectNextKey = EFalse; |
|
1134 } |
|
1135 } |
|
1136 else |
|
1137 { |
|
1138 CGlobalText::InsertL(aPos, KPasswordEchoChar); |
|
1139 } |
|
1140 } |
|
1141 |
|
1142 /** Insert one or more characters. If inserting only one character rely |
|
1143 on InsertL() accepting only one char. Otherwise, save the clear text by |
|
1144 calling SaveClearTextL(). Then for every character either insert an asterisk |
|
1145 or a space if the character is a space delimiter. Note: this method is |
|
1146 called at start-up so it makes no sense to show a temporary clear character. */ |
|
1147 void CPasswordBoxGlobalText::InsertL(TInt aPos,const TDesC& aBuf) |
|
1148 { |
|
1149 if (aBuf.Length() == 1) |
|
1150 { |
|
1151 CPasswordBoxGlobalText::InsertL(aPos, aBuf[0]); |
|
1152 } |
|
1153 else if (aBuf.Length() > 1 && (iTextComponent.AknEditorCurrentInputMode() & KInputModesRequiringFeedbackWithString)) |
|
1154 { |
|
1155 // When writing in kanji or hiragana input mode, the characters are entered in |
|
1156 // sequences. Insert the sequence char by char so that the user will see the last |
|
1157 // character temporarily for feedback. |
|
1158 for (TInt i = 0; i < aBuf.Length(); i++) |
|
1159 { |
|
1160 InsertL(aPos + i, aBuf[i]); |
|
1161 } |
|
1162 } |
|
1163 else |
|
1164 { |
|
1165 SaveClearTextL(aPos, aBuf); |
|
1166 |
|
1167 for (TInt i = 0; i < aBuf.Length(); i++) |
|
1168 { |
|
1169 if (aBuf[i] == CEditableText::EParagraphDelimiter) |
|
1170 { |
|
1171 CGlobalText::InsertL(aPos + i, ' '); |
|
1172 } |
|
1173 else |
|
1174 { |
|
1175 CGlobalText::InsertL(aPos + i, KPasswordEchoChar); |
|
1176 } |
|
1177 } |
|
1178 } |
|
1179 } |
|
1180 |
|
1181 /** Delete one or more chars, this makes sure our clear text stays |
|
1182 in sync. */ |
|
1183 TBool CPasswordBoxGlobalText::DeleteL(TInt aPos,TInt aLength) |
|
1184 { |
|
1185 if (iTimer->IsActive()) |
|
1186 { //commit any previous character before deleting or else we |
|
1187 // may crash in the timer callback when trying to replace an uncommited |
|
1188 // but already deleted char |
|
1189 DoTimerCallbackL(EFalse); |
|
1190 } |
|
1191 |
|
1192 TPtr ptr = iClearText->Des(); |
|
1193 ptr.Delete(aPos, aLength); |
|
1194 |
|
1195 return CGlobalText::DeleteL(aPos, aLength); |
|
1196 } |
|
1197 |
|
1198 /** This method is called by edwin when returning text to the user via |
|
1199 a GetText() call. We make sure we return the clear text instead of the |
|
1200 asterisks used by edwin. */ |
|
1201 void CPasswordBoxGlobalText::Extract(TDes& aBuf,TInt aPos) const |
|
1202 { |
|
1203 aBuf.SetLength(0); |
|
1204 aBuf.Append(iClearText->Mid(aPos)); |
|
1205 } |
|
1206 |
|
1207 /** This method is called by edwin when returning text to the user via |
|
1208 a GetText() call. We make sure we return the clear text instead of the |
|
1209 asterisks used by edwin. */ |
|
1210 void CPasswordBoxGlobalText::Extract(TDes& aBuf,TInt aPos,TInt aLength) const |
|
1211 { |
|
1212 aBuf.SetLength(0); |
|
1213 aBuf.Append(iClearText->Mid(aPos, aLength)); |
|
1214 } |
|
1215 |
|
1216 /** We save our clear text. We reallocate if not enough memory. */ |
|
1217 void CPasswordBoxGlobalText::SaveClearTextL(TInt aPos,const TDesC& aBuf) |
|
1218 { |
|
1219 ASSERT(iClearText); |
|
1220 TPtr ptr = iClearText->Des(); |
|
1221 |
|
1222 TInt totalLength = ptr.Length() + aBuf.Length(); |
|
1223 if (totalLength > ptr.MaxLength()) |
|
1224 { |
|
1225 iClearText = iClearText->ReAllocL(totalLength); |
|
1226 ptr.Set(iClearText->Des()); |
|
1227 } |
|
1228 |
|
1229 ptr.Insert(aPos,aBuf); |
|
1230 } |
|
1231 |
|
1232 /** The timer callback, see DoTimerCallbackL() */ |
|
1233 TInt CPasswordBoxGlobalText::TimerCallback(TAny* aThis) |
|
1234 { |
|
1235 CPasswordBoxGlobalText* self = STATIC_CAST(CPasswordBoxGlobalText*, aThis); |
|
1236 ASSERT(self); |
|
1237 |
|
1238 TRAPD(err, self->DoTimerCallbackL(ETrue)); |
|
1239 return err; |
|
1240 } |
|
1241 |
|
1242 /** It is time to remove the temporary clear character. Do a delete at iClearCharPos and |
|
1243 then insert an asterisk at this position. Then we need to notify the edwin to update its |
|
1244 characters, NotifyNewFormatL(). Note: this is only needed when inserting a char from the |
|
1245 special char table or when holding a key down so that a number is inserted even if in alpha |
|
1246 input mode. Otherwise you do not notice the differece as edwin update its text anyway when |
|
1247 commiting a fep transaction after a timeout that is just about longer than our timeout. |
|
1248 */ |
|
1249 void CPasswordBoxGlobalText::DoTimerCallbackL(TBool aNotifyFormat) |
|
1250 { |
|
1251 iTimer->Cancel(); |
|
1252 |
|
1253 ASSERT(iClearCharPos != -1 && (DocumentLength() > iClearCharPos)); //udeb builds only |
|
1254 if (iClearCharPos != -1 && (DocumentLength() > iClearCharPos)) //prevent crash in urel builds |
|
1255 { |
|
1256 CGlobalText::DeleteL(iClearCharPos,1); |
|
1257 CGlobalText::InsertL(iClearCharPos, KPasswordEchoChar); |
|
1258 |
|
1259 DEBUG_INT("CMIDEdwin::DoTimerCallbackL, skip NotifiyNewFormatL = %D", aNotifyFormat); |
|
1260 // NotifyNewFormat can not be called after a char deletion or when the |
|
1261 // text editor does not have a view assosiated with it. The latter happens |
|
1262 // when text is set to the field before it is shown. |
|
1263 // |
|
1264 if (aNotifyFormat && iTextComponent.TextView()) |
|
1265 { |
|
1266 iTextComponent.NotifyNewFormatL(); |
|
1267 } |
|
1268 iTextComponent.DrawDeferred(); |
|
1269 } |
|
1270 } |
|
1271 |
|
1272 |
|
1273 /*************************************************************************** |
|
1274 * |
|
1275 * Class CCallConfirmationDialog |
|
1276 * |
|
1277 ****************************************************************************/ |
|
1278 |
|
1279 CCallConfirmationDialog* CCallConfirmationDialog::NewL(const TDesC& aNumber, const TTone& aTone) |
|
1280 { |
|
1281 CCallConfirmationDialog* self = new(ELeave) CCallConfirmationDialog(aTone); |
|
1282 CleanupStack::PushL(self); |
|
1283 self->ConstructL(aNumber); |
|
1284 CleanupStack::Pop(self); |
|
1285 return self; |
|
1286 } |
|
1287 |
|
1288 CCallConfirmationDialog::CCallConfirmationDialog(const TTone aTone) |
|
1289 : CAknQueryDialog(aTone), iResources(*CCoeEnv::Static()) |
|
1290 { |
|
1291 } |
|
1292 |
|
1293 CCallConfirmationDialog::~CCallConfirmationDialog() |
|
1294 { |
|
1295 iResources.Close(); |
|
1296 } |
|
1297 |
|
1298 TKeyResponse CCallConfirmationDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) |
|
1299 { |
|
1300 if (aType == EEventKey && aKeyEvent.iCode == EKeyYes) |
|
1301 { |
|
1302 TryExitL(EKeyYes); |
|
1303 return EKeyWasConsumed; |
|
1304 } |
|
1305 else |
|
1306 { |
|
1307 return CAknDialog::OfferKeyEventL(aKeyEvent, aType); |
|
1308 } |
|
1309 } |
|
1310 |
|
1311 TBool CCallConfirmationDialog::OkToExitL(TInt aButtonId) |
|
1312 { |
|
1313 if (EKeyYes == aButtonId) |
|
1314 { |
|
1315 return ETrue; |
|
1316 } |
|
1317 else |
|
1318 { |
|
1319 TBool retValue(CAknDialog::OkToExitL(aButtonId)); |
|
1320 return retValue; |
|
1321 } |
|
1322 } |
|
1323 |
|
1324 TInt CCallConfirmationDialog::MappedCommandId(TInt aButtonId) |
|
1325 { |
|
1326 switch (aButtonId) |
|
1327 { |
|
1328 case EKeyYes: |
|
1329 return EKeyYes; |
|
1330 default : |
|
1331 return CEikDialog::MappedCommandId(aButtonId); |
|
1332 } |
|
1333 } |
|
1334 |
|
1335 void CCallConfirmationDialog::ConstructL(const TDesC& aNumber) |
|
1336 { |
|
1337 HBufC* bufNumber = aNumber.AllocLC(); |
|
1338 TPtr bufNumberPtr = bufNumber->Des(); |
|
1339 AknTextUtils::DisplayTextLanguageSpecificNumberConversion(bufNumberPtr); |
|
1340 HBufC* prompt = StringLoader::LoadLC(R_MIDP_QUEST_CALL_NUMBER, bufNumberPtr); |
|
1341 SetPromptL(*prompt); |
|
1342 CleanupStack::PopAndDestroy(2); // bufNumber, prompt |
|
1343 } |
|
1344 |
|
1345 |
|
1346 /** |
|
1347 * class CMIDAiwPbk2Client |
|
1348 */ |
|
1349 CMIDAiwPbk2Client* CMIDAiwPbk2Client::NewL(MMIDTextBox& aEdwin) |
|
1350 { |
|
1351 CMIDAiwPbk2Client* self = new(ELeave) CMIDAiwPbk2Client(aEdwin); |
|
1352 CleanupStack::PushL(self); |
|
1353 self->ConstructL(); |
|
1354 CleanupStack::Pop(self); |
|
1355 return self; |
|
1356 } |
|
1357 |
|
1358 void CMIDAiwPbk2Client::ConstructL() |
|
1359 { |
|
1360 iServiceHandler = CAiwServiceHandler::NewL(); |
|
1361 |
|
1362 //attach interest |
|
1363 iServiceHandler->AttachL(R_PBK2_CONTACT_SELECTION_INTEREST); |
|
1364 |
|
1365 //create contact manager with same configuration like in current phonebook |
|
1366 CPbk2StoreConfiguration* configuration = CPbk2StoreConfiguration::NewL(); |
|
1367 CleanupStack::PushL(configuration); |
|
1368 |
|
1369 CVPbkContactStoreUriArray* uriArray = configuration->CurrentConfigurationL(); |
|
1370 CleanupStack::PushL(uriArray); |
|
1371 |
|
1372 iContactManager = CVPbkContactManager::NewL(*uriArray); |
|
1373 |
|
1374 CleanupStack::PopAndDestroy(uriArray); |
|
1375 |
|
1376 CleanupStack::PopAndDestroy(configuration); |
|
1377 } |
|
1378 |
|
1379 |
|
1380 CMIDAiwPbk2Client::CMIDAiwPbk2Client(MMIDTextBox& aEdwin): iEdwin(aEdwin) |
|
1381 { |
|
1382 } |
|
1383 |
|
1384 CMIDAiwPbk2Client::~CMIDAiwPbk2Client() |
|
1385 { |
|
1386 delete iServiceHandler; |
|
1387 delete iContactManager; |
|
1388 delete iFetchedLinks; |
|
1389 } |
|
1390 |
|
1391 /** |
|
1392 * Entry point |
|
1393 */ |
|
1394 void CMIDAiwPbk2Client::FetchFromPhoneBookL(TInt aCmdId) |
|
1395 { |
|
1396 iCmdId = aCmdId; |
|
1397 //open contact stores |
|
1398 iContactManager->ContactStoresL().OpenAllL(*this); |
|
1399 } |
|
1400 |
|
1401 |
|
1402 /** |
|
1403 * Open contact stores callback methods |
|
1404 */ |
|
1405 void CMIDAiwPbk2Client::StoreReady(MVPbkContactStore&) |
|
1406 { |
|
1407 } |
|
1408 void CMIDAiwPbk2Client::StoreUnavailable(MVPbkContactStore& , TInt) |
|
1409 { |
|
1410 } |
|
1411 void CMIDAiwPbk2Client::HandleStoreEventL(MVPbkContactStore& , TVPbkContactStoreEvent) |
|
1412 { |
|
1413 } |
|
1414 |
|
1415 /** |
|
1416 * Stores are sucesfully open |
|
1417 */ |
|
1418 void CMIDAiwPbk2Client::OpenComplete() |
|
1419 { |
|
1420 TRAPD(err, OpenCompleteL()); |
|
1421 |
|
1422 if (err != KErrNone) |
|
1423 { |
|
1424 DEBUG_INT("CMIDAiwPbk2Client::OpenComplete - Exception. Error = %d", err); |
|
1425 } |
|
1426 } |
|
1427 /** |
|
1428 * Stores are sucesfully open |
|
1429 */ |
|
1430 void CMIDAiwPbk2Client::OpenCompleteL() |
|
1431 { |
|
1432 |
|
1433 CAiwGenericParamList& paramList = iServiceHandler->InParamListL(); |
|
1434 //single item fetch |
|
1435 TRAPD(err, |
|
1436 paramList.AppendL( |
|
1437 TAiwGenericParam( |
|
1438 EGenericParamContactSelectionData, |
|
1439 TAiwVariant(TAiwSingleItemSelectionDataV1Pckg(TAiwSingleItemSelectionDataV1(). |
|
1440 SetAddressSelectType((TAiwAddressSelectType)iCmdId). |
|
1441 SetFlags(0)))))); |
|
1442 |
|
1443 if (err != KErrNone) |
|
1444 { |
|
1445 DEBUG_INT("CMIDAiwPbk2Client::OpenComplete - Exception from paramList.AppendL. Error = %d", err); |
|
1446 } |
|
1447 |
|
1448 //execute service with handlenotify observer |
|
1449 TRAP(err, |
|
1450 iServiceHandler->ExecuteServiceCmdL(KAiwCmdSelect, paramList, |
|
1451 iServiceHandler->OutParamListL(), |
|
1452 0, this)); |
|
1453 |
|
1454 if (err != KErrNone) |
|
1455 { |
|
1456 DEBUG_INT("CMIDAiwPbk2Client::OpenComplete - Exception from ExecuteServiceCmdL. Error = %d", err); |
|
1457 } |
|
1458 |
|
1459 } |
|
1460 |
|
1461 /** |
|
1462 * Retrieving of single contact suceeded |
|
1463 */ |
|
1464 void CMIDAiwPbk2Client::VPbkSingleContactOperationComplete(MVPbkContactOperationBase&, MVPbkStoreContact* aContact) |
|
1465 { |
|
1466 |
|
1467 delete iRetrieveOperation; |
|
1468 iRetrieveOperation = NULL; |
|
1469 |
|
1470 MVPbkStoreContactField* field = aContact->Fields().RetrieveField(*iCurrentLink); |
|
1471 |
|
1472 TPtrC text = MVPbkContactFieldTextData::Cast(field->FieldData()).Text(); |
|
1473 |
|
1474 TRAPD(err, iEdwin.SetTextL(text)); |
|
1475 if (err != KErrNone) |
|
1476 { |
|
1477 DEBUG_INT("CMIDAiwPbk2Client::VPbkSingleContactOperationComplete - Exception from Edwin.SetTextL. Error = %d", err); |
|
1478 } |
|
1479 |
|
1480 delete aContact; |
|
1481 |
|
1482 } |
|
1483 |
|
1484 /** |
|
1485 * Retrieving of single contact failed |
|
1486 */ |
|
1487 void CMIDAiwPbk2Client::VPbkSingleContactOperationFailed(MVPbkContactOperationBase&, TInt) |
|
1488 { |
|
1489 delete iRetrieveOperation; |
|
1490 iRetrieveOperation = NULL; |
|
1491 } |
|
1492 |
|
1493 /** |
|
1494 * AiwNotify callback |
|
1495 */ |
|
1496 TInt CMIDAiwPbk2Client::HandleNotifyL(TInt aCmdId, TInt aEventId, |
|
1497 CAiwGenericParamList& aEventParamList, const CAiwGenericParamList&) |
|
1498 { |
|
1499 if (aCmdId == KAiwCmdSelect && aEventId == KAiwEventCompleted) |
|
1500 { |
|
1501 TInt index = 0 ; |
|
1502 const TAiwGenericParam* param = aEventParamList.FindFirst(index, EGenericParamContactLinkArray); |
|
1503 if (param) |
|
1504 { |
|
1505 TPtrC8 contactLinks = param->Value().AsData(); |
|
1506 |
|
1507 iFetchedLinks = iContactManager->CreateLinksLC(contactLinks); |
|
1508 CleanupStack::Pop(); |
|
1509 |
|
1510 iCurrentLink = &iFetchedLinks->At(index); |
|
1511 |
|
1512 iRetrieveOperation = iContactManager->RetrieveContactL(*iCurrentLink, *this); |
|
1513 |
|
1514 } |
|
1515 } |
|
1516 // other status do not interests us, just continue till eventcompleted |
|
1517 return 1; |
|
1518 } |
|
1519 |
|
1520 |
|
1521 // End of File |