1 /* |
|
2 * Copyright (c) 2002 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: |
|
15 * This is the implementation of the class defined in CCnvMainForm.h |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 #include <barsread.h> |
|
22 #include <eikenv.h> |
|
23 #include <eikappui.h> |
|
24 #include <eikfpne.h> |
|
25 #include <avkon.hrh> |
|
26 #include <AknPopupField.h> |
|
27 #include <aknnotewrappers.h> |
|
28 #include <eikmenup.h> |
|
29 #include <s32file.h> |
|
30 #include <ErrorUI.h> |
|
31 #include <featmgr.h> |
|
32 |
|
33 #include <hlplch.h> |
|
34 #include <csxhelp/cnv.hlp.hrh> |
|
35 |
|
36 #include <CCnvConverter.h> |
|
37 #include <TCnvCategory.h> |
|
38 #include <Converter.rsg> |
|
39 #include "Converter.hrh" |
|
40 #include "CCnvApplication.h" |
|
41 #include "CCnvMainForm.h" |
|
42 #include "CCnvRatesForm.h" |
|
43 |
|
44 #include <aknnumed.h> |
|
45 #include <f32file.h> |
|
46 #include <e32std.h> |
|
47 |
|
48 _LIT( KCnvPlusSign, "+" ); |
|
49 _LIT( KCnvMinusSign, "-" ); |
|
50 _LIT( KCnvExponentSign, "E" ); |
|
51 _LIT( KCnvDotSign, "." ); |
|
52 |
|
53 _LIT( KCnvMinusInTheMiddle, "?*-?*" ); |
|
54 _LIT( KCnvPlusInTheMiddle, "?*+?*" ); |
|
55 _LIT( KCnvExponentInTheMiddle, "?*E?*" ); |
|
56 _LIT( KCnvExponentInTheMiddleAndEnd, "?*E?*E?" ); |
|
57 |
|
58 _LIT( KConverterFilename,"UnitConverter.ini"); |
|
59 _LIT(KDelimiter, ":"); |
|
60 |
|
61 CCnvMainForm::CCnvMainForm( TBool &aAlreadyDead ) |
|
62 : iIsFullyConstructed( EFalse ), |
|
63 iHasNotifiedDiscFull( EFalse ), |
|
64 iLastUsedEditorId( EConverterEditor1 ), |
|
65 iHistoryTypeCategory( -1 ), |
|
66 iHistoryUnit1Category( -1 ), |
|
67 iHistoryUnit2Category( -1 ), |
|
68 iAlreadyDead( aAlreadyDead ) |
|
69 { |
|
70 } |
|
71 |
|
72 CCnvMainForm::~CCnvMainForm() |
|
73 { |
|
74 if( iIsFullyConstructed ) |
|
75 { |
|
76 SaveState(); |
|
77 } |
|
78 delete iModel; |
|
79 delete iConversionTimer; |
|
80 delete iErrorUI; |
|
81 iAlreadyDead = ETrue; |
|
82 |
|
83 //remove the edwin observers |
|
84 CEikFloatingPointEditor* editor1 = |
|
85 static_cast< CEikFloatingPointEditor* >( Control( EConverterEditor1 ) ); |
|
86 editor1->RemoveEdwinObserver(this); |
|
87 |
|
88 CEikFloatingPointEditor* editor2 = |
|
89 static_cast< CEikFloatingPointEditor* >( Control( EConverterEditor2 ) ); |
|
90 editor2->RemoveEdwinObserver(this); |
|
91 |
|
92 } |
|
93 |
|
94 void CCnvMainForm::ConstructL() |
|
95 { |
|
96 CAknDialog::ConstructL( R_CNV_MAINFORM_MENUBAR ); |
|
97 |
|
98 iErrorUI = CErrorUI::NewL( *iCoeEnv ); |
|
99 |
|
100 TResourceReader reader; |
|
101 iEikonEnv->CreateResourceReaderLC( reader, R_CNV_MODEL ); |
|
102 iModel = CCnvConverter::NewL( reader ); |
|
103 CleanupStack::PopAndDestroy(); // reader |
|
104 |
|
105 iConversionTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
106 |
|
107 iCurrencyCategoryId = iModel->CurrencyCategoryId(); |
|
108 iIsFullyConstructed = ETrue; |
|
109 isEdwinUpdateText = EFalse; |
|
110 |
|
111 TFileName path; |
|
112 iEikonEnv->FsSession().PrivatePath(path); |
|
113 iEikonEnv->FsSession().MkDirAll(path); |
|
114 |
|
115 } |
|
116 |
|
117 void CCnvMainForm::GetHelpContext( TCoeHelpContext& aContext ) const |
|
118 { |
|
119 aContext.iMajor = KUidCnv; |
|
120 aContext.iContext = KCNV_HLP_MAIN_STATE; |
|
121 } |
|
122 |
|
123 // Handle commands from Options menu |
|
124 void CCnvMainForm::ProcessCommandL( TInt aCommandId ) |
|
125 { |
|
126 // this hides the options menu etc. |
|
127 CAknForm::ProcessCommandL( aCommandId ); |
|
128 |
|
129 switch( aCommandId ) |
|
130 { |
|
131 case ECmdSetType: |
|
132 { |
|
133 CmdSetTypeL(); |
|
134 break; |
|
135 } |
|
136 |
|
137 case ECmdSetUnit: // FLOWTHROUGH |
|
138 case ECmdSetCurrency: |
|
139 { |
|
140 CmdSetUnitL(); |
|
141 break; |
|
142 } |
|
143 |
|
144 case ECmdRates: |
|
145 { |
|
146 CmdRatesL(); |
|
147 break; |
|
148 } |
|
149 case EAknCmdHelp: |
|
150 { |
|
151 iEikonEnv->EikAppUi()->HandleCommandL( EAknCmdHelp ); |
|
152 break; |
|
153 } |
|
154 case EEikCmdExit: |
|
155 { |
|
156 OkToExitL( EAknSoftkeyExit ); |
|
157 break; |
|
158 } |
|
159 |
|
160 default: |
|
161 { |
|
162 break; |
|
163 } |
|
164 } |
|
165 } |
|
166 |
|
167 // Takes any action required when the current line is changed to aControlId. |
|
168 void CCnvMainForm::LineChangedL( TInt aControlId ) |
|
169 { |
|
170 |
|
171 CEikButtonGroupContainer& cba = ButtonGroupContainer(); |
|
172 cba.SetCommandSetL(R_CNV_MAINFORM_SOFTKEYS); |
|
173 |
|
174 if( ( aControlId == EConverterEditor1 ) || |
|
175 ( aControlId == EConverterEditor2 ) ) |
|
176 { |
|
177 CEikFloatingPointEditor* editor = |
|
178 static_cast< CEikFloatingPointEditor* >( Control( aControlId ) ); |
|
179 |
|
180 // don't clear the selection if there is only '0' in the editor |
|
181 TBuf<KEditorTextMaxLength> editorText; |
|
182 editor->GetText(editorText); |
|
183 |
|
184 SynchronousConversionL(); |
|
185 // iActiveEditorChanged = EFalse; |
|
186 } |
|
187 else if(aControlId == EConverterUnit1Popup || |
|
188 aControlId == EConverterUnit2Popup) |
|
189 { |
|
190 |
|
191 |
|
192 // if focus is moved to unit popup from amount field |
|
193 // then try to do the conversion. |
|
194 // IsEditorValueValidL shows invalid value note if value is not valid |
|
195 TBool editorValueValid = IsEditorValueValidL(iLastUsedEditorId); |
|
196 if (editorValueValid && AreRatesValidL(ETrue)) |
|
197 { |
|
198 SynchronousConversionL(); |
|
199 } |
|
200 } |
|
201 if(aControlId == EConverterUnit1Popup || |
|
202 aControlId == EConverterUnit2Popup || |
|
203 aControlId == EConverterTypePopup) |
|
204 { |
|
205 //Makes the MSK visible |
|
206 |
|
207 cba.MakeCommandVisible(EAknSoftkeyChange,ETrue); |
|
208 |
|
209 |
|
210 } |
|
211 else if(aControlId ==EConverterEditor1 || |
|
212 aControlId ==EConverterEditor2) |
|
213 { |
|
214 |
|
215 |
|
216 //makes the MSK invisible |
|
217 |
|
218 cba.MakeCommandVisible(EAknSoftkeyChange,EFalse); |
|
219 |
|
220 } |
|
221 cba.DrawNow(); |
|
222 } |
|
223 |
|
224 void CCnvMainForm::DynInitMenuPaneL( TInt aResourceId, |
|
225 CEikMenuPane* aMenuPane ) |
|
226 { |
|
227 // When click on LSK(option), the invalid value should be set to 0. |
|
228 TInt controlId( IdOfFocusControl() ); |
|
229 if ( ( controlId == EConverterEditor1 ) || ( controlId == EConverterEditor2 ) ) |
|
230 { |
|
231 if ( EditorValueCausesHold( controlId ) || !IsVaildNumberEntered( controlId ) ) |
|
232 { |
|
233 SetFloatEditorValueL( controlId, 0.0 ); |
|
234 } |
|
235 SynchronousConversionL( EFalse ); |
|
236 } |
|
237 |
|
238 TUint currentType( iTypeCategory.CurrentValueIndex() ); |
|
239 |
|
240 if( aResourceId == R_CNV_MAINFORM_MENUPANE ) |
|
241 { |
|
242 if (!FeatureManager::FeatureSupported(KFeatureIdHelp)) |
|
243 { |
|
244 aMenuPane->SetItemDimmed(EAknCmdHelp, ETrue); |
|
245 } |
|
246 |
|
247 switch( IdOfFocusControl() ) |
|
248 { |
|
249 case EConverterUnit1Popup: |
|
250 case EConverterUnit2Popup: |
|
251 case EConverterTypePopup: |
|
252 { |
|
253 if( currentType == iCurrencyCategoryId ) |
|
254 { |
|
255 aMenuPane->SetItemDimmed( ECmdRates, EFalse ) ; |
|
256 aMenuPane->SetItemDimmed( ECmdSetType, ETrue ) ; |
|
257 aMenuPane->SetItemDimmed( ECmdSetUnit, ETrue ) ; |
|
258 } |
|
259 else |
|
260 { |
|
261 aMenuPane->SetItemDimmed( ECmdSetCurrency, ETrue ) ; |
|
262 aMenuPane->SetItemDimmed( ECmdSetType, ETrue ) ; |
|
263 aMenuPane->SetItemDimmed( ECmdSetUnit, ETrue ) ; |
|
264 aMenuPane->SetItemDimmed( ECmdRates, ETrue ) ; |
|
265 } |
|
266 break; |
|
267 } |
|
268 case EConverterEditor1: |
|
269 case EConverterEditor2: |
|
270 { |
|
271 if( currentType == iCurrencyCategoryId ) |
|
272 { |
|
273 aMenuPane->SetItemDimmed( ECmdSetType, ETrue ) ; |
|
274 aMenuPane->SetItemDimmed( ECmdSetUnit, ETrue ) ; |
|
275 aMenuPane->SetItemDimmed( ECmdRates, EFalse ); |
|
276 } |
|
277 else |
|
278 { |
|
279 aMenuPane->SetItemDimmed( ECmdSetType, ETrue ); |
|
280 aMenuPane->SetItemDimmed( ECmdRates, ETrue ); |
|
281 } |
|
282 break; |
|
283 } |
|
284 default: |
|
285 { |
|
286 break; |
|
287 } |
|
288 } |
|
289 |
|
290 if ( iTypePopupCtrl->SelectionMode() == CAknPopupField::EAknPopupFieldSelectionListMode || |
|
291 iUnit1PopupCtrl->SelectionMode() == CAknPopupField::EAknPopupFieldSelectionListMode || |
|
292 iUnit2PopupCtrl->SelectionMode() == CAknPopupField::EAknPopupFieldSelectionListMode) |
|
293 { |
|
294 aMenuPane->SetItemDimmed( ECmdSetCurrency, ETrue ); |
|
295 aMenuPane->SetItemDimmed( ECmdSetType, ETrue ); |
|
296 aMenuPane->SetItemDimmed( ECmdSetUnit, ETrue ); |
|
297 aMenuPane->SetItemDimmed( ECmdRates, ETrue ); |
|
298 } |
|
299 } |
|
300 } |
|
301 |
|
302 // Handles events to the three pop lists |
|
303 void CCnvMainForm::HandleControlEventL( CCoeControl* /*aControl*/, |
|
304 TCoeEvent aEventType ) |
|
305 { |
|
306 // We are interested only about EEventStateChanged events |
|
307 if( aEventType != EEventStateChanged ) |
|
308 { |
|
309 return; |
|
310 } |
|
311 |
|
312 TInt controlId( IdOfFocusControl() ); |
|
313 |
|
314 if( !HasReallyChanged( controlId ) ) |
|
315 { |
|
316 return; |
|
317 } |
|
318 |
|
319 switch( controlId ) |
|
320 { |
|
321 case EConverterTypePopup: |
|
322 { |
|
323 HandleCategoryChangedL(); |
|
324 break; |
|
325 } |
|
326 case EConverterUnit1Popup: |
|
327 case EConverterUnit2Popup: |
|
328 { |
|
329 HandleUnitChangedL(); |
|
330 break; |
|
331 } |
|
332 //These have been moved to OfferKeyEventL |
|
333 case EConverterEditor1: |
|
334 case EConverterEditor2: |
|
335 { |
|
336 iLastUsedEditorId = controlId; |
|
337 if( (iActiveEditorChanged)&& |
|
338 ( isEdwinNavigated == EFalse || isEdwinUpdateText ) ) // Is there any navigation (or selection) |
|
339 //happening on the editor |
|
340 { |
|
341 AsynchronousConversion(); |
|
342 } |
|
343 isEdwinNavigated = EFalse; //make the boolean false |
|
344 iActiveEditorChanged = ETrue; |
|
345 break; |
|
346 } |
|
347 |
|
348 default: |
|
349 { |
|
350 break; |
|
351 } |
|
352 } |
|
353 } |
|
354 |
|
355 TBool CCnvMainForm::SaveFormData() |
|
356 { |
|
357 // Always allow exit (data is saved in the destructor) |
|
358 return ETrue; |
|
359 } |
|
360 |
|
361 TBool CCnvMainForm::OkToExitL( TInt aButtonId ) |
|
362 { |
|
363 TBool status( CAknDialog::OkToExitL( aButtonId ) ); |
|
364 TInt controlId( IdOfFocusControl() ); |
|
365 if( status && ( aButtonId == EAknSoftkeyExit ) ) |
|
366 { |
|
367 iEikonEnv->EikAppUi()->HandleCommandL( EAknCmdExit ); |
|
368 } |
|
369 else if(aButtonId == EAknSoftkeyChange) |
|
370 { |
|
371 if (controlId == EConverterTypePopup) |
|
372 { |
|
373 CmdSetTypeL(); |
|
374 status = EFalse; |
|
375 } |
|
376 else if ((controlId == EConverterUnit1Popup) ||(controlId == EConverterUnit2Popup)) |
|
377 { |
|
378 CmdSetUnitL(); |
|
379 status = EFalse; |
|
380 } |
|
381 } |
|
382 else |
|
383 { |
|
384 status = EFalse; |
|
385 } |
|
386 return status; |
|
387 } |
|
388 |
|
389 void CCnvMainForm::PreLayoutDynInitL() |
|
390 { |
|
391 // Store pointers to the popup list controls |
|
392 // (makes further access easier/faster) |
|
393 iTypePopupCtrl = |
|
394 static_cast< CAknPopupField* >( Control( EConverterTypePopup ) ); |
|
395 iUnit1PopupCtrl = |
|
396 static_cast< CAknPopupField* >( Control( EConverterUnit1Popup ) ); |
|
397 iUnit2PopupCtrl = |
|
398 static_cast< CAknPopupField* >( Control( EConverterUnit2Popup ) ); |
|
399 |
|
400 |
|
401 // Set values for the unit category popup control |
|
402 iModel->GetCategorylistAccessor( iTypeCategory ); |
|
403 iTypePopupCtrl->SetQueryValueL( &iTypeCategory ); |
|
404 |
|
405 // Load user selections from file (if any) |
|
406 LoadStateL(); |
|
407 |
|
408 // Set initial values for the popup lists |
|
409 HandleCategoryChangedL(); |
|
410 |
|
411 InitialiseChangeHistory(); |
|
412 |
|
413 if (iUnit1Category.UnitFactor(iUnit1Category.CurrentValueIndex()) != 0.0 && |
|
414 iUnit2Category.UnitFactor(iUnit2Category.CurrentValueIndex()) != 0.0) |
|
415 { |
|
416 SynchronousConversionL(); |
|
417 } |
|
418 |
|
419 //Add wdwin observers for the two editors so that they can capture the Navigation |
|
420 //events and not do asynchronous conversion |
|
421 CEikFloatingPointEditor* editor1 = |
|
422 static_cast< CEikFloatingPointEditor* >( Control( EConverterEditor1 ) ); |
|
423 |
|
424 CEikFloatingPointEditor* editor2 = |
|
425 static_cast< CEikFloatingPointEditor* >( Control( EConverterEditor2 ) ); |
|
426 |
|
427 editor1->AddEdwinObserverL(this); |
|
428 editor2->AddEdwinObserverL(this); |
|
429 |
|
430 |
|
431 } |
|
432 |
|
433 TBool CCnvMainForm::HasReallyChanged( TInt controlId ) |
|
434 { |
|
435 TBool changed( EFalse ); |
|
436 |
|
437 switch( controlId ) |
|
438 { |
|
439 case EConverterTypePopup: |
|
440 { |
|
441 if( iTypeCategory.CurrentValueIndex() != iHistoryTypeCategory ) |
|
442 { |
|
443 changed = ETrue; |
|
444 iHistoryTypeCategory = iTypeCategory.CurrentValueIndex(); |
|
445 |
|
446 // renew iHistoryUnit1Category and iHistoryUnit2Category |
|
447 iModel->GetCategoryAccessor( iUnit1Category, iHistoryTypeCategory ); |
|
448 TUint HistoryUnit1Category; |
|
449 TUint HistoryUnit2Category; |
|
450 iUnit1Category.GetDefaultUnits( HistoryUnit1Category , HistoryUnit2Category ); |
|
451 iHistoryUnit1Category = HistoryUnit1Category; |
|
452 iHistoryUnit2Category = HistoryUnit2Category; |
|
453 } |
|
454 break; |
|
455 } |
|
456 case EConverterUnit1Popup: |
|
457 { |
|
458 if( iUnit1Category.CurrentValueIndex() != iHistoryUnit1Category ) |
|
459 { |
|
460 changed = ETrue; |
|
461 iHistoryUnit1Category = iUnit1Category.CurrentValueIndex(); |
|
462 } |
|
463 break; |
|
464 } |
|
465 case EConverterUnit2Popup: |
|
466 { |
|
467 if( iUnit2Category.CurrentValueIndex() != iHistoryUnit2Category ) |
|
468 { |
|
469 changed = ETrue; |
|
470 iHistoryUnit2Category = iUnit2Category.CurrentValueIndex(); |
|
471 } |
|
472 break; |
|
473 } |
|
474 |
|
475 case EConverterEditor1: |
|
476 case EConverterEditor2: |
|
477 { |
|
478 changed = ETrue; |
|
479 break; |
|
480 } |
|
481 |
|
482 default: |
|
483 { |
|
484 break; |
|
485 } |
|
486 } |
|
487 |
|
488 return changed; |
|
489 } |
|
490 |
|
491 void CCnvMainForm::InitialiseChangeHistory() |
|
492 { |
|
493 iHistoryTypeCategory = iTypeCategory.CurrentValueIndex(); |
|
494 iHistoryUnit1Category = iUnit1Category.CurrentValueIndex(); |
|
495 iHistoryUnit2Category = iUnit2Category.CurrentValueIndex(); |
|
496 } |
|
497 |
|
498 void CCnvMainForm::HandleCategoryChangedL() |
|
499 { |
|
500 TInt categoryId = iTypeCategory.CurrentValueIndex(); |
|
501 iModel->GetCategoryAccessor( iUnit1Category, categoryId ); |
|
502 iModel->GetCategoryAccessor( iUnit2Category, categoryId ); |
|
503 |
|
504 TUint srcUnit, dstUnit; |
|
505 iUnit1Category.GetDefaultUnits( srcUnit, dstUnit ); |
|
506 iUnit1Category.SetCurrentValueIndex( srcUnit ); |
|
507 iUnit2Category.SetCurrentValueIndex( dstUnit ); |
|
508 |
|
509 // Set arrays to popup lists and redraw them |
|
510 iUnit1PopupCtrl->SetQueryValueL( &iUnit1Category ); |
|
511 iUnit2PopupCtrl->SetQueryValueL( &iUnit2Category ); |
|
512 iUnit1PopupCtrl->DrawNow(); |
|
513 iUnit2PopupCtrl->DrawNow(); |
|
514 |
|
515 // Reset amount fields |
|
516 TReal zero( 0.0 ); |
|
517 SetFloatingPointEditorValueL( EConverterEditor1, &zero ); |
|
518 SetFloatingPointEditorValueL( EConverterEditor2, &zero ); |
|
519 |
|
520 // when category's type is temperature the editor's value can't simply set to zero |
|
521 AsynchronousConversion(); |
|
522 |
|
523 iLastUsedEditorId = EConverterEditor1; |
|
524 } |
|
525 |
|
526 void CCnvMainForm::HandleUnitChangedL() |
|
527 { |
|
528 iUnit1Category.SetDefaultUnits( iUnit1Category.CurrentValueIndex(), |
|
529 iUnit2Category.CurrentValueIndex() ); |
|
530 SynchronousConversionL(); |
|
531 } |
|
532 |
|
533 TBool CCnvMainForm::AreRatesValidL(TBool aShowNote) |
|
534 { |
|
535 TInt numInvalid( 0 ); |
|
536 if( iUnit1Category.UnitFactor( iUnit1Category.CurrentValueIndex() ) |
|
537 == 0.0 ) |
|
538 { |
|
539 numInvalid++; |
|
540 SetFloatEditorValueL( EConverterEditor1, 0.0 ); |
|
541 } |
|
542 if( iUnit2Category.UnitFactor( iUnit2Category.CurrentValueIndex() ) |
|
543 == 0.0 ) |
|
544 { |
|
545 numInvalid++; |
|
546 SetFloatEditorValueL( EConverterEditor2, 0.0 ); |
|
547 } |
|
548 |
|
549 if(numInvalid) |
|
550 { |
|
551 CancelConversion(); |
|
552 |
|
553 if (aShowNote) |
|
554 { |
|
555 TBool isPlural( EFalse ); |
|
556 if( numInvalid > 1 ) |
|
557 { |
|
558 isPlural = ETrue; |
|
559 } |
|
560 |
|
561 TInt resourceId(R_CNV_MAINFORM_NORATE ); |
|
562 if( isPlural ) |
|
563 { |
|
564 resourceId = R_CNV_MAINFORM_NORATE_PLURAL; |
|
565 } |
|
566 HBufC* label = iCoeEnv->AllocReadResourceLC( resourceId ); |
|
567 CAknErrorNote* note = new( ELeave ) CAknErrorNote; |
|
568 note->ExecuteLD( *label ); |
|
569 CleanupStack::PopAndDestroy(); // label; |
|
570 } |
|
571 return EFalse; |
|
572 } |
|
573 else |
|
574 { |
|
575 return ETrue; |
|
576 } |
|
577 } |
|
578 |
|
579 void CCnvMainForm::ShowInvalidValueNoteL(TInt aEditorId) |
|
580 { |
|
581 CancelConversion(); |
|
582 |
|
583 SetFloatEditorValueL( aEditorId, 0.0 ); |
|
584 |
|
585 HBufC* label = iCoeEnv->AllocReadResourceLC( |
|
586 R_CNV_MAINFORM_INVALIDVALUE ); |
|
587 CAknErrorNote* note = new( ELeave ) CAknErrorNote; |
|
588 note->ExecuteLD( *label ); |
|
589 CleanupStack::PopAndDestroy(); // label; |
|
590 |
|
591 SynchronousConversionL(); |
|
592 } |
|
593 |
|
594 TBool CCnvMainForm::IsEditorValueValidL( TUint aEditorId ) |
|
595 { |
|
596 TReal amount( FloatingPointEditorValue( aEditorId ) ); |
|
597 |
|
598 TReal minimum; |
|
599 if( aEditorId == EConverterEditor1 ) |
|
600 { |
|
601 minimum = iUnit1Category.UnitMinimum( |
|
602 iUnit1Category.CurrentValueIndex() ); |
|
603 } |
|
604 else |
|
605 { |
|
606 minimum = iUnit2Category.UnitMinimum( |
|
607 iUnit2Category.CurrentValueIndex() ); |
|
608 } |
|
609 |
|
610 if( amount < minimum ) |
|
611 { |
|
612 ShowInvalidValueNoteL(aEditorId); |
|
613 return EFalse; |
|
614 } |
|
615 else |
|
616 { |
|
617 return ETrue; |
|
618 } |
|
619 } |
|
620 |
|
621 TBool CCnvMainForm::EditorValueCausesHold( TUint aEditorId ) |
|
622 { |
|
623 CEikFloatingPointEditor* editor = |
|
624 static_cast< CEikFloatingPointEditor* >( Control( aEditorId ) ); |
|
625 |
|
626 if( editor->TextLength() == 0 ) |
|
627 { |
|
628 return ETrue; |
|
629 } |
|
630 |
|
631 TBuf< 12 > content; |
|
632 TLocale locale; |
|
633 |
|
634 // Not all the countries use '.' to express radix point, some use ','. |
|
635 // So use locale.DecimalSeparator() to get local symbol. |
|
636 TBuf<1> decimal; |
|
637 decimal.Append( locale.DecimalSeparator() ); |
|
638 editor->Text()->Extract( content, 0, 12 ); |
|
639 TInt contentLength( content.Length() ); |
|
640 if ( !content.Compare( KCnvPlusSign ) ) |
|
641 { |
|
642 return ETrue; |
|
643 } |
|
644 else if ( !content.Compare( KCnvMinusSign ) ) |
|
645 { |
|
646 return ETrue; |
|
647 } |
|
648 |
|
649 else if ( !content.Compare( decimal ) ) |
|
650 { |
|
651 return ETrue; |
|
652 } |
|
653 else if( contentLength > 1 && |
|
654 content[ contentLength - 1 ] == KCnvExponentSign()[ 0 ] && |
|
655 IsDigit( content[ contentLength - 2 ] ) && |
|
656 content.Match( KCnvExponentInTheMiddle ) == KErrNotFound && |
|
657 content.Match( KCnvMinusInTheMiddle ) == KErrNotFound && |
|
658 content.Match( KCnvPlusInTheMiddle ) == KErrNotFound) |
|
659 { |
|
660 // If content ends with <digit>E with no minus, plus or exponent |
|
661 // sign in the middle |
|
662 return ETrue; |
|
663 } |
|
664 else if( contentLength > 2 && |
|
665 ( content[ contentLength - 1 ] == KCnvMinusSign()[ 0 ] || |
|
666 content[ contentLength - 1 ] == KCnvPlusSign()[ 0 ] ) && |
|
667 content[ contentLength - 2 ] == KCnvExponentSign()[ 0 ] && |
|
668 IsDigit( content[ contentLength - 3 ] ) && |
|
669 content.Match( KCnvExponentInTheMiddleAndEnd ) == KErrNotFound && |
|
670 content.Match( KCnvMinusInTheMiddle ) == KErrNotFound && |
|
671 content.Match( KCnvPlusInTheMiddle ) == KErrNotFound ) |
|
672 { |
|
673 // If content ends with <digit>E[+|-] with no minus, plus or exponent |
|
674 // sign in the middle |
|
675 return ETrue; |
|
676 } |
|
677 else if(contentLength > 12 && |
|
678 content.Locate(locale.DecimalSeparator()) == contentLength - 1) |
|
679 { |
|
680 // content ends with decimal separator and there is no other |
|
681 // decimal separator |
|
682 return ETrue; |
|
683 } |
|
684 |
|
685 |
|
686 return EFalse; |
|
687 } |
|
688 |
|
689 void CCnvMainForm::CmdRatesL() |
|
690 { |
|
691 TBool wantsRelaunch; |
|
692 TBool shouldExit( EFalse ); |
|
693 TBool needsSave( EFalse ); |
|
694 do |
|
695 { |
|
696 wantsRelaunch = EFalse; |
|
697 TCnvCategory currencies; |
|
698 iModel->GetCategoryAccessor( currencies, iCurrencyCategoryId ); |
|
699 |
|
700 CCnvRatesForm* rates = new( ELeave ) CCnvRatesForm( &wantsRelaunch, |
|
701 &shouldExit, &needsSave, currencies); |
|
702 |
|
703 CleanupStack::PushL( rates ); |
|
704 rates->ConstructL(); |
|
705 CleanupStack::Pop(); // rates |
|
706 rates->ExecuteLD( R_CNV_RATESFORM ); |
|
707 } |
|
708 while( wantsRelaunch ); |
|
709 |
|
710 if( needsSave ) |
|
711 { |
|
712 SaveState(); |
|
713 } |
|
714 |
|
715 if( !shouldExit ) |
|
716 { |
|
717 // Reset the form (there might be changes in unit names..) |
|
718 HandleCategoryChangedL(); |
|
719 |
|
720 DrawNow(); |
|
721 } |
|
722 else |
|
723 { |
|
724 TryExitL( EAknSoftkeyExit ); |
|
725 } |
|
726 } |
|
727 |
|
728 void CCnvMainForm::CmdSetTypeL() |
|
729 { |
|
730 TryChangeFocusToL( EConverterTypePopup ); |
|
731 iTypePopupCtrl->ActivateSelectionListL(); |
|
732 } |
|
733 |
|
734 void CCnvMainForm::CmdSetUnitL() |
|
735 { |
|
736 switch ( IdOfFocusControl() ) |
|
737 { |
|
738 case EConverterUnit1Popup: |
|
739 { |
|
740 iUnit1PopupCtrl->ActivateSelectionListL(); |
|
741 break; |
|
742 } |
|
743 |
|
744 case EConverterUnit2Popup: |
|
745 { |
|
746 iUnit2PopupCtrl->ActivateSelectionListL(); |
|
747 break; |
|
748 } |
|
749 |
|
750 default: |
|
751 { |
|
752 break; |
|
753 } |
|
754 } |
|
755 } |
|
756 |
|
757 void CCnvMainForm::LoadStateL() |
|
758 { |
|
759 RFileReadStream in; |
|
760 |
|
761 TFileName filePath; |
|
762 TBuf<1> tempDes; |
|
763 TChar driveChar; |
|
764 User::LeaveIfError(iEikonEnv->FsSession().PrivatePath(filePath)); |
|
765 iEikonEnv->FsSession().DriveToChar(KDefaultDrive, driveChar); |
|
766 tempDes.Append(driveChar); |
|
767 filePath.Insert(0,KDelimiter); |
|
768 filePath.Insert(0,tempDes); |
|
769 filePath.Append(KConverterFilename); |
|
770 |
|
771 TInt err( in.Open( iEikonEnv->FsSession(), filePath, |
|
772 EFileRead ) ); |
|
773 |
|
774 if( !err ) |
|
775 { |
|
776 TRAP( err, iModel->InternalizeL( in ) ); |
|
777 if( !err ) |
|
778 { |
|
779 TRAP( err, iTypeCategory.SetCurrentValueIndex( in.ReadInt8L() ) ); |
|
780 } |
|
781 in.Close(); |
|
782 } |
|
783 } |
|
784 |
|
785 void CCnvMainForm::SaveState() |
|
786 { |
|
787 RFileWriteStream out; |
|
788 |
|
789 TFileName filePath; |
|
790 TBuf<1> tempDes; |
|
791 TChar driveChar; |
|
792 TRAPD(errd, iEikonEnv->FsSession().PrivatePath(filePath)); |
|
793 iEikonEnv->FsSession().DriveToChar(KDefaultDrive, driveChar); |
|
794 tempDes.Append(driveChar); |
|
795 if(!errd) |
|
796 { |
|
797 |
|
798 filePath.Insert(0,KDelimiter); |
|
799 filePath.Insert(0,tempDes); |
|
800 filePath.Append(KConverterFilename); |
|
801 } |
|
802 |
|
803 TInt err( out.Replace( iEikonEnv->FsSession(), filePath, |
|
804 EFileWrite ) ); |
|
805 |
|
806 if( !err ) |
|
807 { |
|
808 TRAP( err, iModel->ExternalizeL( out ) ); |
|
809 if( !err ) |
|
810 { |
|
811 TRAP( err, out.WriteInt8L( iTypeCategory.CurrentValueIndex() ) ); |
|
812 } |
|
813 out.Close(); |
|
814 } |
|
815 |
|
816 if( err && !iHasNotifiedDiscFull ) |
|
817 { |
|
818 TRAP_IGNORE(iErrorUI->ShowGlobalErrorNoteL( err ) ); |
|
819 iHasNotifiedDiscFull = ETrue; |
|
820 } |
|
821 } |
|
822 |
|
823 void CCnvMainForm::SynchronousConversionL( TBool aShowRateInvalideNote ) |
|
824 { |
|
825 // Don't report an "invalid value" error. Cancel conversion. |
|
826 // if the field is empty (i.e. the user has used delete/backspace) etc. |
|
827 if( EditorValueCausesHold( iLastUsedEditorId ) ) |
|
828 { |
|
829 // if one Editor is blank, set the other to 0. |
|
830 CEikFloatingPointEditor* editor = |
|
831 static_cast< CEikFloatingPointEditor* >( Control( iLastUsedEditorId ) ); |
|
832 if( editor->TextLength() == 0 ) |
|
833 { |
|
834 if( iLastUsedEditorId == EConverterEditor1) |
|
835 { |
|
836 SetFloatEditorValueL( EConverterEditor2, 0.0 ); |
|
837 } |
|
838 if( iLastUsedEditorId == EConverterEditor2) |
|
839 { |
|
840 SetFloatEditorValueL( EConverterEditor1, 0.0 ); |
|
841 } |
|
842 } |
|
843 return; |
|
844 } |
|
845 |
|
846 if ( !IsVaildNumberEntered( iLastUsedEditorId ) ) |
|
847 { |
|
848 ShowInvalidValueNoteL( iLastUsedEditorId ); |
|
849 } |
|
850 |
|
851 |
|
852 // PrepareForFocusLossL leaves if the component is not able to |
|
853 // parse the content. We trap it so that IsEditorValueValidL() |
|
854 // can check and report the situation correctly. |
|
855 TRAP_IGNORE( Control( iLastUsedEditorId )->PrepareForFocusLossL() ); |
|
856 TInt CurrentControlId( IdOfFocusControl() ); |
|
857 if( CurrentControlId == EConverterUnit1Popup ) |
|
858 { |
|
859 IsEditorValueValidL( EConverterEditor1 ); |
|
860 } |
|
861 else if (CurrentControlId == EConverterUnit2Popup) |
|
862 { |
|
863 IsEditorValueValidL( EConverterEditor2 ); |
|
864 } |
|
865 else if (CurrentControlId == EConverterEditor2 ) |
|
866 { |
|
867 if ( !IsVaildNumberEntered( EConverterEditor2 ) ) |
|
868 { |
|
869 iLastUsedEditorId = CurrentControlId; |
|
870 ShowInvalidValueNoteL( EConverterEditor2 ); |
|
871 } |
|
872 } |
|
873 else if (CurrentControlId == EConverterEditor1 ) |
|
874 { |
|
875 if ( !IsVaildNumberEntered( EConverterEditor1 ) ) |
|
876 { |
|
877 iLastUsedEditorId = CurrentControlId; |
|
878 ShowInvalidValueNoteL( EConverterEditor1 ); |
|
879 } |
|
880 } |
|
881 TReal result( 0.0 ); |
|
882 |
|
883 // send an argument to notify the AreRatesValidL() display a note dialog or not |
|
884 if (IsEditorValueValidL(iLastUsedEditorId)) |
|
885 { |
|
886 if (AreRatesValidL(aShowRateInvalideNote)) |
|
887 { |
|
888 TReal amount(FloatingPointEditorValue(iLastUsedEditorId)); |
|
889 TUint unit1(iUnit1Category.CurrentValueIndex()); |
|
890 TUint unit2(iUnit2Category.CurrentValueIndex()); |
|
891 |
|
892 // RAPD( ignored, Control( iLastUsedEditorId )->PrepareForFocusLossL() ); |
|
893 |
|
894 |
|
895 // do not reset the touch UI to standby state |
|
896 // CCoeEnv::Static()->SyncNotifyFocusObserversOfChangeInFocus(); |
|
897 |
|
898 |
|
899 // Do the calculation and change the value for the related edit field |
|
900 ValueCalculationL(unit1, unit2, amount); |
|
901 |
|
902 CEikFloatingPointEditor* editor = |
|
903 static_cast<CEikFloatingPointEditor*> (Control( |
|
904 iLastUsedEditorId)); |
|
905 TBuf<KEditorTextMaxLength> editorText; |
|
906 editor->GetText(editorText); |
|
907 |
|
908 // Use local value for different area |
|
909 TBuf<1> localeZero; |
|
910 localeZero.AppendNum(0); |
|
911 AknTextUtils::LanguageSpecificNumberConversion(localeZero); |
|
912 if (editorText.Length() > 1 && editorText[0] == localeZero[0]) |
|
913 { |
|
914 TCursorSelection sel = editor->Selection(); |
|
915 TInt removedZeroes = 0; |
|
916 // remove all leading zeroes |
|
917 while (editorText.Length() > 0 && editorText[0] |
|
918 == localeZero[0]) |
|
919 { |
|
920 editorText.Delete(0, 1); |
|
921 ++removedZeroes; |
|
922 } |
|
923 // if too many zeroes removed, insert one. |
|
924 TLocale locale; |
|
925 if (editorText.Length() == 0 || TChar(editorText[0]) |
|
926 == locale.DecimalSeparator()) |
|
927 { |
|
928 editorText.Insert(0, localeZero); |
|
929 --removedZeroes; |
|
930 } |
|
931 editor->SetTextL(&editorText); |
|
932 |
|
933 // adjust the selection accroding to removed zeroes |
|
934 TInt anchor = |
|
935 (sel.iAnchorPos - removedZeroes > 0) ? sel.iAnchorPos |
|
936 - removedZeroes : 0; |
|
937 TInt cursor = |
|
938 (sel.iCursorPos - removedZeroes > 0) ? sel.iCursorPos |
|
939 - removedZeroes : 0; |
|
940 editor->SetSelectionL(cursor, anchor); |
|
941 |
|
942 if ( !IsVaildNumberEntered( iLastUsedEditorId ) ) |
|
943 { |
|
944 ShowInvalidValueNoteL( iLastUsedEditorId ); |
|
945 } |
|
946 // notify the touch window |
|
947 editor->SetCursorPosL(cursor, ETrue); |
|
948 editor->DrawNow(); |
|
949 } |
|
950 } |
|
951 } |
|
952 } |
|
953 |
|
954 void CCnvMainForm::AsynchronousConversion() |
|
955 { |
|
956 CancelConversion(); |
|
957 TCallBack cb( TimerCallback, this ); |
|
958 iConversionTimer->Start( 750000, 0, cb ); |
|
959 } |
|
960 |
|
961 void CCnvMainForm::CancelConversion() |
|
962 { |
|
963 iConversionTimer->Cancel(); |
|
964 } |
|
965 |
|
966 TInt CCnvMainForm::TimerCallback( TAny* aMainForm ) |
|
967 { |
|
968 |
|
969 CCnvMainForm* form = reinterpret_cast< CCnvMainForm* >( aMainForm ); |
|
970 |
|
971 TRAP_IGNORE(form->SynchronousConversionL() ); |
|
972 |
|
973 form->CancelConversion(); |
|
974 |
|
975 return KErrNone; |
|
976 } |
|
977 |
|
978 |
|
979 |
|
980 // ---------------------------------------------------- |
|
981 // CCnvMainForm::OfferKeyEventL |
|
982 // Keyevent process. |
|
983 // ---------------------------------------------------- |
|
984 // |
|
985 TKeyResponse CCnvMainForm::OfferKeyEventL(const TKeyEvent& aKeyEvent, |
|
986 TEventCode aType) |
|
987 { |
|
988 |
|
989 if ( !IsFocused() ) |
|
990 { |
|
991 if (aKeyEvent.iCode == EKeyEscape) |
|
992 { |
|
993 return CAknForm::OfferKeyEventL( aKeyEvent, aType ); |
|
994 } |
|
995 return EKeyWasNotConsumed; |
|
996 } |
|
997 |
|
998 TInt controlId( IdOfFocusControl() ); |
|
999 |
|
1000 TBool hashKeyPressed = EFalse; |
|
1001 |
|
1002 // Use decimalChar instead of 46 |
|
1003 TLocale locale; |
|
1004 TChar decimalChar = locale.DecimalSeparator(); |
|
1005 if ( aKeyEvent.iScanCode == EStdKeyHash || decimalChar == TChar( aKeyEvent.iCode ) ) |
|
1006 { |
|
1007 hashKeyPressed = ETrue; |
|
1008 } |
|
1009 |
|
1010 if( hashKeyPressed ) |
|
1011 { |
|
1012 // If inputting through VKB or HWR, the event can be done only when aType is equal to EEventKey. |
|
1013 // Besides, only when inputting the dot in VKB or HWR, aKeyEvent.iScanCode is equal to decimalChar. |
|
1014 TBool VKBdotKeyPressed = EFalse; |
|
1015 if ( ( aKeyEvent.iScanCode == decimalChar ) ) |
|
1016 { |
|
1017 VKBdotKeyPressed = ETrue; |
|
1018 } |
|
1019 if ( ( aType == EEventKey) && ( !VKBdotKeyPressed ) ) |
|
1020 { |
|
1021 return EKeyWasConsumed; |
|
1022 } |
|
1023 else if( aType == EEventKeyUp) |
|
1024 { |
|
1025 TKeyEvent keyevent( aKeyEvent ); |
|
1026 aType = EEventKey; |
|
1027 keyevent.iCode = decimalChar; |
|
1028 keyevent.iModifiers = 0; |
|
1029 keyevent.iScanCode = 0; |
|
1030 keyevent.iRepeats = 0; |
|
1031 return static_cast< CEikFloatingPointEditor* >( Control( controlId ) ) |
|
1032 ->OfferKeyEventL(keyevent,aType); |
|
1033 } |
|
1034 else |
|
1035 {// |
|
1036 } |
|
1037 } |
|
1038 |
|
1039 //Not a key event this case handles the menu and exit keys |
|
1040 //when an invalid value is entered in the amount field |
|
1041 if(aType == EEventKeyDown) |
|
1042 { |
|
1043 if( ( EConverterEditor1 == controlId )|| |
|
1044 ( EConverterEditor2 == controlId ) ) |
|
1045 { |
|
1046 |
|
1047 if( (aKeyEvent.iScanCode == EStdKeyDevice0) ||//menu Key |
|
1048 (aKeyEvent.iScanCode == EStdKeyDevice1) )//Exit key |
|
1049 { |
|
1050 if( EditorValueCausesHold( controlId ) || |
|
1051 !IsVaildNumberEntered( controlId ) ) |
|
1052 { |
|
1053 SetFloatEditorValueL( controlId, 0.0); |
|
1054 } |
|
1055 //return EKeyWasNotConsumed; |
|
1056 } |
|
1057 } |
|
1058 } |
|
1059 |
|
1060 if ( aType != EEventKey ) |
|
1061 { |
|
1062 // Return EKeyWasNotConsumed if OfferKeyEventL() does not handle any event. |
|
1063 return EKeyWasNotConsumed; |
|
1064 } |
|
1065 |
|
1066 if( ( EConverterEditor1 == controlId )|| |
|
1067 ( EConverterEditor2 == controlId ) ) |
|
1068 { |
|
1069 //Just to see that -9E-99 doesnt appear when an invalid number is editor is |
|
1070 //entered in the editor |
|
1071 |
|
1072 if(aKeyEvent.iScanCode == EStdKeyUpArrow || |
|
1073 aKeyEvent.iScanCode == EStdKeyDownArrow ) |
|
1074 { |
|
1075 CancelConversion(); |
|
1076 if( EditorValueCausesHold( controlId ) ) |
|
1077 { |
|
1078 SetFloatEditorValueL( controlId, 0.0); |
|
1079 } |
|
1080 if( !IsVaildNumberEntered( controlId ) ) |
|
1081 { |
|
1082 ShowInvalidValueNoteL( controlId ); |
|
1083 } |
|
1084 } |
|
1085 |
|
1086 iLastUsedEditorId = controlId; |
|
1087 |
|
1088 //For arrow keys asynchronous conversion not required |
|
1089 // if (iActiveEditorChanged) |
|
1090 // { |
|
1091 /*if( ( aKeyEvent.iScanCode != EStdKeyRightArrow )&& |
|
1092 ( aKeyEvent.iScanCode != EStdKeyLeftArrow )&& |
|
1093 ( aKeyEvent.iScanCode != EStdKeyUpArrow )&& |
|
1094 ( aKeyEvent.iScanCode != EStdKeyDownArrow )&& |
|
1095 ( isEditKey == EFalse ) ) |
|
1096 { |
|
1097 AsynchronousConversion(); |
|
1098 }*/ |
|
1099 //} |
|
1100 |
|
1101 //iActiveEditorChanged = ETrue; |
|
1102 |
|
1103 } |
|
1104 return CAknForm::OfferKeyEventL(aKeyEvent, aType); |
|
1105 |
|
1106 } |
|
1107 |
|
1108 |
|
1109 // ---------------------------------------------------- |
|
1110 // CCnvMainForm::IsVaildNumberEntered |
|
1111 // Checks if a valid number is entered in the editor field and returns |
|
1112 // ETrue if a vaild number is entered and |
|
1113 // EFalse if an invalid number is entered |
|
1114 // ---------------------------------------------------- |
|
1115 // |
|
1116 |
|
1117 TBool CCnvMainForm::IsVaildNumberEntered( TInt aEditorId ) |
|
1118 { |
|
1119 CEikFloatingPointEditor* editor = |
|
1120 static_cast< CEikFloatingPointEditor* >( Control( aEditorId ) ); |
|
1121 |
|
1122 if ( editor->TextLength() == 0 ) |
|
1123 { |
|
1124 return EFalse; |
|
1125 } |
|
1126 |
|
1127 TReal real; |
|
1128 CAknNumericEdwin::TValidationStatus validationStatus = editor->GetValueAsReal( real ); |
|
1129 |
|
1130 // The enter number is not valid if GetValueAsReal function's return value is not EValueValid |
|
1131 if ( validationStatus != CAknNumericEdwin::EValueValid /*&& validationStatus != CAknNumericEdwin::EValueTooLarge*/ ) |
|
1132 { |
|
1133 return EFalse; |
|
1134 } |
|
1135 return ETrue; |
|
1136 } |
|
1137 |
|
1138 |
|
1139 |
|
1140 // ---------------------------------------------------- |
|
1141 // CCnvMainForm::HandleEdwinEventL |
|
1142 // Checks the Navigation events on the editor |
|
1143 // ---------------------------------------------------- |
|
1144 // |
|
1145 |
|
1146 void CCnvMainForm::HandleEdwinEventL(CEikEdwin* /*aEdwin*/,TEdwinEvent aEventType) |
|
1147 { |
|
1148 if(EEventNavigation == aEventType) |
|
1149 { |
|
1150 isEdwinNavigated = ETrue; |
|
1151 } |
|
1152 if( aEventType == EEventTextUpdate ) |
|
1153 { |
|
1154 isEdwinUpdateText = ETrue; |
|
1155 } |
|
1156 |
|
1157 } |
|
1158 |
|
1159 // ---------------------------------------------------- |
|
1160 // CCnvMainForm::IsDigit |
|
1161 // Converts the digit from any digit mode (devangiri or arabic) |
|
1162 // to western digit and checks whether it is a valid digit or not. |
|
1163 // ---------------------------------------------------- |
|
1164 // |
|
1165 TBool CCnvMainForm::IsDigit(TUint aChar) |
|
1166 { |
|
1167 TBuf<1> digit; |
|
1168 digit.Append(aChar); |
|
1169 |
|
1170 AknTextUtils::ConvertDigitsTo(digit , EDigitTypeWestern); |
|
1171 |
|
1172 TChar ch = digit[0]; |
|
1173 return ch.IsDigit(); |
|
1174 } |
|
1175 |
|
1176 // ---------------------------------------------------- |
|
1177 // CCnvMainForm::PrepareForFocusTransitionL |
|
1178 // The Uikon framework calls this function immediately before focus move. |
|
1179 // ---------------------------------------------------- |
|
1180 // |
|
1181 void CCnvMainForm::PrepareForFocusTransitionL() |
|
1182 { |
|
1183 TInt controlId( IdOfFocusControl() ); |
|
1184 if ( ( EConverterEditor1 == controlId ) || ( EConverterEditor2 == controlId ) ) |
|
1185 { |
|
1186 |
|
1187 // record the last use editor id |
|
1188 iLastUsedEditorId = controlId; |
|
1189 CancelConversion(); |
|
1190 if ( EditorValueCausesHold( controlId ) ) |
|
1191 { |
|
1192 SetFloatEditorValueL( controlId, 0.0 ); |
|
1193 } |
|
1194 |
|
1195 // Delete the radix point when there is no number behind it. |
|
1196 else if ( IsVaildNumberEntered( controlId ) ) |
|
1197 { |
|
1198 CEikFloatingPointEditor* editor = |
|
1199 static_cast<CEikFloatingPointEditor*> ( Control( controlId ) ); |
|
1200 TBuf<KEditorTextMaxLength> editorText; |
|
1201 editor->GetText( editorText ); |
|
1202 TLocale locale; |
|
1203 TInt editorLength = editorText.Length(); |
|
1204 |
|
1205 // Check if the last character is radix point. |
|
1206 if ( editorText[ editorLength - 1 ] == locale.DecimalSeparator() ) |
|
1207 { |
|
1208 editorText.Delete( editorLength - 1, 1 ); |
|
1209 editor->SetTextL( &editorText ); |
|
1210 } |
|
1211 } |
|
1212 } |
|
1213 } |
|
1214 |
|
1215 // ---------------------------------------------------- |
|
1216 // CCnvMainForm::ValueCalculation |
|
1217 // Do the calculation and change the value for the related edit field |
|
1218 // ---------------------------------------------------- |
|
1219 // |
|
1220 void CCnvMainForm::ValueCalculationL( TUint aUnit1Popup, TUint aUnit2Popup, TReal aMount ) |
|
1221 { |
|
1222 TReal result( 0.0 ); |
|
1223 // Use "LastUnit1" and "LastUnit2" to insure that the second amount don't change if the last used editor |
|
1224 // is the second and the category's units do not change. |
|
1225 static TInt LastUnit1 = -1; |
|
1226 static TInt LastUnit2 = -1; |
|
1227 |
|
1228 // According to the UI Spec: |
|
1229 // 1. If the first conversion unit field is changed, a new conversion is calculated to the |
|
1230 // second amount field of units, or vice versa. |
|
1231 // 2. If the first edit field is changed, a new conversion is calculated to the second |
|
1232 // edit field, or vice versa. |
|
1233 if ( iLastUsedEditorId == EConverterEditor1 ) |
|
1234 { |
|
1235 //the first unit is changed |
|
1236 if ( ( ( IdOfFocusControl() != EConverterEditor1 ) && ( LastUnit1 != aUnit1Popup ) ) |
|
1237 || ( IdOfFocusControl() == EConverterTypePopup ) ) |
|
1238 { |
|
1239 aMount = FloatingPointEditorValue( EConverterEditor1 ); |
|
1240 result = iUnit1Category.Convert( aUnit1Popup, aUnit2Popup, aMount ); |
|
1241 SetFloatEditorValueL( EConverterEditor2, result ); |
|
1242 } |
|
1243 //the second unit is changed |
|
1244 else if ( ( IdOfFocusControl() != EConverterEditor1 ) && ( LastUnit2 != aUnit2Popup ) ) |
|
1245 { |
|
1246 aMount = FloatingPointEditorValue( EConverterEditor2 ); |
|
1247 result = iUnit1Category.Convert( aUnit2Popup, aUnit1Popup, aMount ); |
|
1248 SetFloatEditorValueL( EConverterEditor1, result ); |
|
1249 } |
|
1250 //the first amount field is changed |
|
1251 else |
|
1252 { |
|
1253 result = iUnit1Category.Convert( aUnit1Popup, aUnit2Popup, aMount ); |
|
1254 SetFloatEditorValueL( EConverterEditor2, result ); |
|
1255 } |
|
1256 } |
|
1257 else |
|
1258 { |
|
1259 //the first unit is changed |
|
1260 if ( ( ( IdOfFocusControl() != EConverterEditor2 ) && ( LastUnit1 != aUnit1Popup ) ) |
|
1261 || ( IdOfFocusControl() == EConverterTypePopup )) |
|
1262 { |
|
1263 aMount = FloatingPointEditorValue( EConverterEditor1 ); |
|
1264 result = iUnit1Category.Convert( aUnit1Popup, aUnit2Popup, aMount ); |
|
1265 SetFloatEditorValueL( EConverterEditor2, result ); |
|
1266 } |
|
1267 //the second unit is changed |
|
1268 else if ( ( IdOfFocusControl() != EConverterEditor2 ) && ( LastUnit2 != aUnit2Popup ) ) |
|
1269 { |
|
1270 aMount = FloatingPointEditorValue( EConverterEditor2 ); |
|
1271 result = iUnit1Category.Convert( aUnit2Popup, aUnit1Popup, aMount ); |
|
1272 SetFloatEditorValueL( EConverterEditor1, result ); |
|
1273 } |
|
1274 //the second amount field is changed |
|
1275 else |
|
1276 { |
|
1277 result = iUnit1Category.Convert( aUnit2Popup, aUnit1Popup, aMount ); |
|
1278 SetFloatEditorValueL( EConverterEditor1, result ); |
|
1279 } |
|
1280 } |
|
1281 |
|
1282 // record units of the category at this time. |
|
1283 LastUnit1 = aUnit1Popup; |
|
1284 LastUnit2 = aUnit2Popup; |
|
1285 } |
|
1286 //End of file |
|