uifw/eikctl/src/EIKFPNE.CPP
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     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 	{}