|
1 /* |
|
2 * Copyright (c) 1997-2001 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 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <eikfpne.h> |
|
20 |
|
21 #include <e32math.h> |
|
22 #include <eikpanic.h> |
|
23 #include <barsread.h> |
|
24 #include <eikenv.h> |
|
25 #include <eikon.hrh> |
|
26 #include <eikctl.rsg> |
|
27 #include <AknUtils.h> |
|
28 #include <AknDef.h> |
|
29 |
|
30 #include <AknTasHook.h> |
|
31 const TInt KMaxFloatAndFixedNumberOfDigits = 32; |
|
32 |
|
33 |
|
34 |
|
35 TInt TenToThePower(TInt n)// mostly, n small, eg 2, so integer arithmetic more efficient than real |
|
36 { |
|
37 TInt ret=1; |
|
38 while (n--) |
|
39 ret*=10; |
|
40 return (ret); |
|
41 } |
|
42 |
|
43 |
|
44 const TInt KFloatingPointEditorDefaultEdwinFlags = |
|
45 EEikEdwinNoLineOrParaBreaks | |
|
46 EEikEdwinAutoSelection; |
|
47 |
|
48 const TInt KFixedPointEditorDefaultEdwinFlags = |
|
49 EEikEdwinNoLineOrParaBreaks | |
|
50 EEikEdwinAutoSelection ; |
|
51 |
|
52 // class CEikFloatingPointEditor //////////////////////////////////////////////////////////// |
|
53 |
|
54 EXPORT_C CEikFloatingPointEditor::CEikFloatingPointEditor() |
|
55 { |
|
56 iEdwinInternalFlags=ENumericCharacters; |
|
57 AKNTASHOOK_ADD( this, "CEikFloatingPointEditor" ); |
|
58 } |
|
59 |
|
60 EXPORT_C void CEikFloatingPointEditor::ConstructL(const TReal& aMin,const TReal& aMax,TInt aTextLimit) |
|
61 { |
|
62 |
|
63 // Enforce absolute maximum digits on ediwn |
|
64 TInt maxDigits = aTextLimit; |
|
65 if((maxDigits==0) || (maxDigits>KMaxFloatAndFixedNumberOfDigits)) |
|
66 maxDigits = KMaxFloatAndFixedNumberOfDigits; |
|
67 |
|
68 SetMinMax(aMin,aMax); |
|
69 CEikEdwin::ConstructL(KFloatingPointEditorDefaultEdwinFlags,aTextLimit,maxDigits,1); |
|
70 SetAknEditorNumericKeymap(EAknEditorConverterNumberModeKeymap); |
|
71 SetAknEditorAllowedInputModes(EAknEditorNumericInputMode); |
|
72 SetAknEditorInputMode(EAknEditorNumericInputMode); |
|
73 SetAknEditorSpecialCharacterTable(0); |
|
74 } |
|
75 |
|
76 EXPORT_C void CEikFloatingPointEditor::PrepareForFocusLossL() |
|
77 { |
|
78 |
|
79 TReal value; |
|
80 TValidationStatus validationStatus = GetValueAsReal(value); |
|
81 |
|
82 TReal* pReal=NULL; |
|
83 |
|
84 switch (validationStatus) |
|
85 { |
|
86 case EValueValid: |
|
87 iValue = value; |
|
88 break; |
|
89 |
|
90 case EValueTooSmall: |
|
91 pReal=(&iMin); |
|
92 break; |
|
93 |
|
94 case EValueTooLarge: |
|
95 pReal=(&iMax); |
|
96 break; |
|
97 |
|
98 case EValueNotParsed: |
|
99 case EEmpty: |
|
100 pReal=(&iMin); |
|
101 break; |
|
102 }; |
|
103 |
|
104 if (validationStatus != EValueValid) |
|
105 { |
|
106 SetValueL(pReal); |
|
107 User::Leave(KLeaveWithoutAlert); |
|
108 } |
|
109 } |
|
110 |
|
111 EXPORT_C TCoeInputCapabilities CEikFloatingPointEditor::InputCapabilities() const |
|
112 { |
|
113 TCoeInputCapabilities inputCapabilities = CEikEdwin::InputCapabilities(); |
|
114 inputCapabilities.SetCapabilities(TCoeInputCapabilities::EWesternNumericReal|TCoeInputCapabilities::ENavigation); |
|
115 return inputCapabilities; |
|
116 } |
|
117 |
|
118 EXPORT_C TKeyResponse CEikFloatingPointEditor::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
119 { |
|
120 TKeyEvent keyEvent(aKeyEvent); |
|
121 TEventCode eventCode(aType); |
|
122 |
|
123 return CAknNumericEdwin::OfferKeyEventL(keyEvent, eventCode); |
|
124 } |
|
125 |
|
126 EXPORT_C void CEikFloatingPointEditor::ConstructFromResourceL(TResourceReader& aReader) |
|
127 { |
|
128 TInt textLimit=aReader.ReadUint16(); |
|
129 TReal min=aReader.ReadReal64(); |
|
130 TReal max=aReader.ReadReal64(); |
|
131 TReal defaultValue=aReader.ReadReal64(); // does not work with queries !!! |
|
132 ConstructL(min,max,textLimit); |
|
133 // added to give a default value, to work with forms. Unsure if this is desirable. |
|
134 if ((min>defaultValue)||(defaultValue>max)) |
|
135 defaultValue=min; |
|
136 SetValueL(&defaultValue); |
|
137 } |
|
138 |
|
139 EXPORT_C CAknNumericEdwin::TValidationStatus CEikFloatingPointEditor::GetValueAsReal( TReal& aValue ) |
|
140 { |
|
141 TValidationStatus state = EValueNotParsed; |
|
142 |
|
143 // Normalise text to western, so that Tlex will work |
|
144 TBuf<KMaxFloatAndFixedNumberOfDigits> text; |
|
145 GetText(text); |
|
146 AknTextUtils::ConvertDigitsTo(text, EDigitTypeWestern); |
|
147 |
|
148 // Use TextLength() for this test, because stray paragraph marks may lurk in the TPtrC buffer |
|
149 if ( TextLength() == 0 ) |
|
150 { |
|
151 state = EEmpty; |
|
152 } |
|
153 else |
|
154 { |
|
155 TLex lex( text ); |
|
156 |
|
157 if ( lex.Val(aValue) == KErrNone && lex.Remainder().Length() == 0 ) |
|
158 { |
|
159 state = EValueValid; |
|
160 |
|
161 // Test the range: |
|
162 if ( aValue < iMin ) |
|
163 { |
|
164 state = EValueTooSmall; |
|
165 } |
|
166 else if ( aValue > iMax ) |
|
167 { |
|
168 state = EValueTooLarge; |
|
169 } |
|
170 } |
|
171 else |
|
172 { |
|
173 state = EValueNotParsed; |
|
174 } |
|
175 |
|
176 } |
|
177 |
|
178 return state; |
|
179 |
|
180 } |
|
181 |
|
182 EXPORT_C TReal CEikFloatingPointEditor::Value() const |
|
183 { |
|
184 return iValue;// assumes model already checked for validity |
|
185 } |
|
186 |
|
187 EXPORT_C void CEikFloatingPointEditor::SetValueL(const TReal* aValue) |
|
188 { |
|
189 if (!aValue) |
|
190 { |
|
191 SetTextL(NULL); |
|
192 return; |
|
193 } |
|
194 |
|
195 iValue=*aValue; |
|
196 // !! Now check for validity? |
|
197 TBuf<EAknMaxIntegerDigits> des; |
|
198 TRealFormat format(iTextLimit); |
|
199 format.iType|=KAllowThreeDigitExp; |
|
200 des.Num(iValue,format); |
|
201 |
|
202 AknTextUtils::ConvertDigitsTo(des, AknTextUtils::NumericEditorDigitType()); |
|
203 |
|
204 SetTextL(&des); |
|
205 if ( !(iEdwinUserFlags&ENoAutoSelection) ) |
|
206 { |
|
207 SetCursorPosL(des.Length(), ETrue); |
|
208 } |
|
209 else |
|
210 { |
|
211 SetCursorPosL(des.Length(), EFalse); |
|
212 } |
|
213 DrawNow(); |
|
214 } |
|
215 |
|
216 EXPORT_C void CEikFloatingPointEditor::SetMinMax(TReal aMin,TReal aMax) |
|
217 { |
|
218 iMin=aMin; |
|
219 iMax=aMax; |
|
220 __ASSERT_DEBUG(iMin<=iMax, Panic(EEikPanicInvalidBounds) ); |
|
221 } |
|
222 |
|
223 EXPORT_C void CEikFloatingPointEditor::GetMinMax(TReal& aMin, TReal& aMax) const |
|
224 { |
|
225 aMin=iMin; |
|
226 aMax=iMax; |
|
227 } |
|
228 |
|
229 EXPORT_C void CEikFloatingPointEditor::HandleResourceChange(TInt aType) |
|
230 { |
|
231 if(aType==KEikInputLanguageChange) |
|
232 { |
|
233 // get and set the same value will refresh the edwin text on a locale change |
|
234 TReal value; |
|
235 if( GetValueAsReal(value) == CAknNumericEdwin::EValueValid) |
|
236 { |
|
237 TRAP_IGNORE(SetValueL(&value)); |
|
238 } |
|
239 } |
|
240 CAknNumericEdwin::HandleResourceChange(aType); |
|
241 } |
|
242 |
|
243 EXPORT_C void CEikFloatingPointEditor::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
244 { |
|
245 CAknNumericEdwin::HandlePointerEventL(aPointerEvent); |
|
246 } |
|
247 |
|
248 EXPORT_C void* CEikFloatingPointEditor::ExtensionInterface( TUid /*aInterface*/ ) |
|
249 { |
|
250 return NULL; |
|
251 } |
|
252 |
|
253 EXPORT_C void CEikFloatingPointEditor::Reserved_3() |
|
254 {} |
|
255 |
|
256 // class CEikFixedPointEditor /////////////////////////////////////////////////////////////////// |
|
257 |
|
258 EXPORT_C CEikFixedPointEditor::CEikFixedPointEditor() |
|
259 { |
|
260 iEdwinInternalFlags=ENumericCharacters; |
|
261 } |
|
262 |
|
263 EXPORT_C void CEikFixedPointEditor::ConstructL(TInt aMin,TInt aMax) |
|
264 { |
|
265 SetMinMax(aMin,aMax); |
|
266 iTextLimit=RequiredNumberOfCharacters(); |
|
267 |
|
268 SetAknEditorNumericKeymap(EAknEditorConverterNumberModeKeymap); |
|
269 SetAknEditorAllowedInputModes(EAknEditorNumericInputMode); |
|
270 SetAknEditorInputMode(EAknEditorNumericInputMode); |
|
271 SetAknEditorSpecialCharacterTable(0); |
|
272 |
|
273 CEikEdwin::ConstructL(KFixedPointEditorDefaultEdwinFlags,iTextLimit,iTextLimit,1); |
|
274 } |
|
275 |
|
276 EXPORT_C void CEikFixedPointEditor::ConstructFromResourceL(TResourceReader& aReader) |
|
277 { |
|
278 iDecimalPlaces=aReader.ReadUint16(); |
|
279 TInt min=aReader.ReadInt32(); |
|
280 TInt max=aReader.ReadInt32(); |
|
281 TInt defaultValue = aReader.ReadInt32(); |
|
282 |
|
283 __ASSERT_DEBUG(min<=max, Panic(EEikPanicInvalidBounds) ); |
|
284 |
|
285 ConstructL(min, max ); |
|
286 |
|
287 // added to give a default value, to work with forms. Unsure if this is desirable. |
|
288 if ((min>defaultValue)||(defaultValue>max)) |
|
289 defaultValue=min; |
|
290 SetValueL(&defaultValue); |
|
291 } |
|
292 |
|
293 |
|
294 |
|
295 EXPORT_C CAknNumericEdwin::TValidationStatus CEikFixedPointEditor::GetValueAsInteger( TInt& aValue ) |
|
296 { |
|
297 TValidationStatus state = EValueNotParsed; |
|
298 // Normalise text to western, so that Tlex will work |
|
299 TBuf<KMaxFloatAndFixedNumberOfDigits> text; |
|
300 GetText(text); |
|
301 AknTextUtils::ConvertDigitsTo(text, EDigitTypeWestern); |
|
302 |
|
303 // Use TextLength() for this test, because stray paragraph marks may lurk in the TPtrC buffer |
|
304 if ( TextLength() == 0 ) |
|
305 { |
|
306 state = EEmpty; |
|
307 } |
|
308 else |
|
309 { |
|
310 TLex lex( text ); |
|
311 TReal real; |
|
312 if ( lex.Val( real ) == KErrNone ) |
|
313 { |
|
314 state = EValueValid; |
|
315 real*=TenToThePower(iDecimalPlaces); |
|
316 real+=(real>0)?0.5:(-0.5); |
|
317 Math::Int((TInt32&)iValue, real); |
|
318 |
|
319 // Test the range: |
|
320 if ( iValue < iMin ) |
|
321 { |
|
322 state = EValueTooSmall; |
|
323 } |
|
324 else if ( iValue > iMax ) |
|
325 { |
|
326 state = EValueTooLarge; |
|
327 } |
|
328 else |
|
329 { |
|
330 aValue = iValue; |
|
331 } |
|
332 } |
|
333 else |
|
334 { |
|
335 state = EValueNotParsed; |
|
336 } |
|
337 |
|
338 } |
|
339 |
|
340 return state; |
|
341 |
|
342 } |
|
343 |
|
344 TInt CEikFixedPointEditor::RequiredNumberOfCharacters() const |
|
345 { |
|
346 TInt absMax=(iMax >= -iMin) ? iMax : -iMin; |
|
347 TInt numberOfCharacters=0; |
|
348 while (absMax!=0) |
|
349 { |
|
350 ++numberOfCharacters; |
|
351 absMax/=10; |
|
352 } |
|
353 if (numberOfCharacters<iDecimalPlaces+1) |
|
354 numberOfCharacters=iDecimalPlaces+1;// if bounds ensure leading digits will be zero, still need enough characters |
|
355 ++numberOfCharacters;// one character for the decimal point |
|
356 if (iMin<0) |
|
357 ++numberOfCharacters;// one character for the minus sign |
|
358 return numberOfCharacters; |
|
359 } |
|
360 |
|
361 EXPORT_C void CEikFixedPointEditor::PrepareForFocusLossL() |
|
362 { |
|
363 TBuf<KMaxFloatAndFixedNumberOfDigits> string; |
|
364 GetText(string); |
|
365 |
|
366 // Convert to western so that TLex works |
|
367 AknTextUtils::ConvertDigitsTo(string, EDigitTypeWestern); |
|
368 TLex lex(string); |
|
369 TReal real; |
|
370 TInt err=lex.Val(real); |
|
371 if (err==KErrGeneral || err==KErrArgument || lex.Remainder().Length()) |
|
372 { |
|
373 // Change value to minimum |
|
374 SetValueL( &iMin ); |
|
375 User::Leave( KErrNone ); |
|
376 } |
|
377 real*=TenToThePower(iDecimalPlaces); |
|
378 real+=(real>0)?0.5:(-0.5); |
|
379 Math::Int((TInt32&)iValue, real); |
|
380 if (iValue<iMin) |
|
381 { |
|
382 SetValueL( &iMin ); |
|
383 User::Leave( KErrNone ); |
|
384 } |
|
385 else if (iValue>iMax) |
|
386 { |
|
387 SetValueL( &iMax ); |
|
388 User::Leave( KErrNone ); |
|
389 } |
|
390 } |
|
391 |
|
392 |
|
393 EXPORT_C TCoeInputCapabilities CEikFixedPointEditor::InputCapabilities() const |
|
394 { |
|
395 TCoeInputCapabilities inputCapabilities = CEikEdwin::InputCapabilities(); |
|
396 inputCapabilities.SetCapabilities(TCoeInputCapabilities::EWesternNumericReal|TCoeInputCapabilities::ENavigation); |
|
397 return inputCapabilities; |
|
398 } |
|
399 |
|
400 EXPORT_C TInt CEikFixedPointEditor::Value() const |
|
401 { |
|
402 return iValue; |
|
403 } |
|
404 |
|
405 EXPORT_C void CEikFixedPointEditor::SetValueL(const TInt* aValue) |
|
406 { |
|
407 if (!aValue) |
|
408 { |
|
409 SetTextL(NULL); |
|
410 return; |
|
411 } |
|
412 iValue=*aValue; |
|
413 // |
|
414 TRealFormat format(iTextLimit,iDecimalPlaces); |
|
415 format.iType|=KDoNotUseTriads; |
|
416 // |
|
417 TReal real=(TReal)iValue; |
|
418 real/=TenToThePower(iDecimalPlaces); |
|
419 TBuf<KMaxFloatAndFixedNumberOfDigits> string; |
|
420 string.Num(real,format); |
|
421 |
|
422 AknTextUtils::ConvertDigitsTo(string, AknTextUtils::NumericEditorDigitType()); |
|
423 |
|
424 SetTextL(&string); |
|
425 DrawNow(); |
|
426 } |
|
427 |
|
428 EXPORT_C void CEikFixedPointEditor::SetMinMax(TInt aMin, TInt aMax) |
|
429 { |
|
430 iMin=aMin; |
|
431 iMax=aMax; |
|
432 __ASSERT_DEBUG(iMin<=iMax, Panic(EEikPanicInvalidBounds) ); |
|
433 } |
|
434 |
|
435 EXPORT_C void CEikFixedPointEditor::GetMinMax(TInt& aMin, TInt& aMax) const |
|
436 { |
|
437 aMin=iMin; |
|
438 aMax=iMax; |
|
439 } |
|
440 |
|
441 EXPORT_C void CEikFixedPointEditor::SetDecimalPlaces(TInt aDecimalPlaces) |
|
442 { |
|
443 iDecimalPlaces=aDecimalPlaces; |
|
444 } |
|
445 |
|
446 EXPORT_C TInt CEikFixedPointEditor::DecimalPlaces() const |
|
447 { |
|
448 return iDecimalPlaces; |
|
449 } |
|
450 |
|
451 EXPORT_C TKeyResponse CEikFixedPointEditor::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
452 { |
|
453 TKeyEvent keyEvent(aKeyEvent); |
|
454 TEventCode eventCode(aType); |
|
455 |
|
456 return CAknNumericEdwin::OfferKeyEventL(keyEvent, eventCode); |
|
457 } |
|
458 |
|
459 EXPORT_C void CEikFixedPointEditor::HandleResourceChange(TInt aType) |
|
460 { |
|
461 if(aType==KEikInputLanguageChange) |
|
462 { |
|
463 // get and set the same value will refresh the edwin text on a locale change |
|
464 TInt value; |
|
465 if( GetValueAsInteger(value) == CAknNumericEdwin::EValueValid) |
|
466 { |
|
467 TRAP_IGNORE(SetValueL(&value)); |
|
468 } |
|
469 } |
|
470 CAknNumericEdwin::HandleResourceChange(aType); |
|
471 } |
|
472 |
|
473 EXPORT_C void CEikFixedPointEditor::HandlePointerEventL(const TPointerEvent& aPointerEvent) |
|
474 { |
|
475 CAknNumericEdwin::HandlePointerEventL(aPointerEvent); |
|
476 } |
|
477 |
|
478 EXPORT_C void* CEikFixedPointEditor::ExtensionInterface( TUid /*aInterface*/ ) |
|
479 { |
|
480 return NULL; |
|
481 } |
|
482 |
|
483 EXPORT_C void CEikFixedPointEditor::Reserved_3() |
|
484 {} |