fmradio/fmradio/src/fmradiofrequencyeditor.cpp
branchRCL_3
changeset 20 93c594350b9a
parent 0 f3d95d9c00ab
equal deleted inserted replaced
19:cce62ebc198e 20:93c594350b9a
       
     1 /*
       
     2 * Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Custom editor for editing radio frequencies.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <AknUtils.h>
       
    20 #include <barsread.h>
       
    21 #include <coemain.h>
       
    22 #include <e32base.h>
       
    23 #include <eikfctry.h>
       
    24 
       
    25 #include "fmradiofrequencyeditor.h"
       
    26 #include "fmradioengineradiosettings.h"
       
    27 #include "fmradioappui.h"
       
    28 #include "fmradiofrequencynumber.h"
       
    29 #include "fmradio.hrh"
       
    30 #include "debug.h"
       
    31 
       
    32 const TInt KNumFields = 3;        // Number of fields.
       
    33 const TInt KIntField = 0;        // Index of integer field.
       
    34 const TInt KDecField = 2;        // Index of decimal field.
       
    35 
       
    36 const TInt KFMRadioAbsoluteMinimumIntFieldValue = 0;
       
    37 const TInt KFMRadioAbsoluteMinimumDecFieldValue = 0;
       
    38 
       
    39 
       
    40 // ---------------------------------------------------------------------------
       
    41 // CFMRadioFrequencyEditor::CFMRadioFrequencyEditor
       
    42 // ---------------------------------------------------------------------------
       
    43 //
       
    44 CFMRadioFrequencyEditor::CFMRadioFrequencyEditor() :
       
    45         iMinFreq( 0 ),
       
    46         iMaxFreq( 0 ),
       
    47         iPreviousField( KErrNotFound ), 
       
    48         iTypedInDecField( EFalse ),
       
    49         iValidToReport( EFalse ),
       
    50         iDecDiv( KFMRadioFreqMultiplier ),
       
    51         iReportEditorState ( ETrue )
       
    52     {
       
    53     }
       
    54 
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // Editor is contructed via this static method by the control framework.
       
    58 // ---------------------------------------------------------------------------
       
    59 //
       
    60 SEikControlInfo CFMRadioFrequencyEditor::StaticCreateCustomEditor( 
       
    61         TInt aIdentifier )
       
    62     {
       
    63     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::StaticCreateCustomEditor") ) );
       
    64     SEikControlInfo customInfo;
       
    65     // zero all variables
       
    66     Mem::FillZ( &customInfo, sizeof( SEikControlInfo ) ); 
       
    67     if ( aIdentifier == EFMRadioFrequencyEditor )
       
    68         {
       
    69         customInfo.iControl = new CFMRadioFrequencyEditor;
       
    70         }
       
    71     return customInfo;
       
    72     }
       
    73 
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // CFMRadioFrequencyEditor::ConstructL
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 void CFMRadioFrequencyEditor::ConstructL( const TUint32 aFlags )
       
    80     {
       
    81     // Creates space for the fiels in this MFNE.
       
    82     CreateFieldArrayL( KNumFields );
       
    83 
       
    84     // RadioSettings values are so widely used in this class, that it is 
       
    85     // better to read them into member variables.
       
    86     CRadioEngine* radioEngine = static_cast<CFMRadioAppUi*>( iCoeEnv->AppUi() )->RadioEngine();
       
    87     TInt minFreq = 0;
       
    88     TInt maxFreq = 0;
       
    89     radioEngine->GetFrequencyBandRange( minFreq, maxFreq );
       
    90     iMinFreq = minFreq / KFMRadioFreqMultiplier;
       
    91     iMaxFreq = maxFreq / KFMRadioFreqMultiplier;
       
    92     iStepFreq = radioEngine->FrequencyStepSize();
       
    93     // Maximum values of fields.
       
    94     TInt maxIntFieldValue( 0 );
       
    95     TInt maxIntFreq = iMaxFreq / KFMRadioFreqMultiplier;
       
    96     while ( maxIntFieldValue < maxIntFreq )
       
    97         {
       
    98         maxIntFieldValue = maxIntFieldValue*10 + 9;
       
    99         }
       
   100     TInt maxDecFieldValue( 0 );
       
   101     TInt decimalCounter = radioEngine->DecimalCount();
       
   102     while ( decimalCounter-- )
       
   103         {
       
   104         maxDecFieldValue = maxDecFieldValue*10 + 9;
       
   105         // Calculate also the decimal divider for later use.
       
   106         iDecDiv = iDecDiv / 10;
       
   107         }
       
   108 
       
   109     // Integer field. Ownership transfers.
       
   110     CFMRadioFrequencyNumber* field = CFMRadioFrequencyNumber::NewL( *Font(), 
       
   111         KFMRadioAbsoluteMinimumIntFieldValue, maxIntFieldValue, 
       
   112         KFMRadioAbsoluteMinimumIntFieldValue, aFlags );
       
   113     field->SetDigitType( AknTextUtils::NumericEditorDigitType(), *Font() );
       
   114     AddField( field );
       
   115 
       
   116     // Decimal separator field. Ownership transfers.
       
   117     HBufC* delim = HBufC::NewLC( 1 );
       
   118     TLocale loc;
       
   119     delim->Des().Append( loc.DecimalSeparator() );
       
   120     AddField( CEikMfneSeparator::NewL( delim ) );
       
   121     CleanupStack::Pop(); // delim
       
   122 
       
   123     // Decimal field. Ownership transfers.
       
   124     field = CFMRadioFrequencyNumber::NewL( *Font(), KFMRadioAbsoluteMinimumDecFieldValue, 
       
   125         maxDecFieldValue, KFMRadioAbsoluteMinimumDecFieldValue, 
       
   126         aFlags | CEikMfneNumber::EFillWithLeadingZeros );
       
   127     field->SetDigitType( AknTextUtils::NumericEditorDigitType(), *Font() );
       
   128     AddField( field );
       
   129     }
       
   130 
       
   131 
       
   132 // ---------------------------------------------------------------------------
       
   133 // CFMRadioFrequencyEditor::~CFMRadioFrequencyEditor
       
   134 // ---------------------------------------------------------------------------
       
   135 //
       
   136 CFMRadioFrequencyEditor::~CFMRadioFrequencyEditor()
       
   137     {    
       
   138     }
       
   139 
       
   140 
       
   141 // ---------------------------------------------------------------------------
       
   142 // CFMRadioFrequencyEditor::SetFrequency
       
   143 // ---------------------------------------------------------------------------
       
   144 //
       
   145 void CFMRadioFrequencyEditor::SetFrequency( const TUint32 aFreq )
       
   146     {
       
   147     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::SetFrequency (aFreq=%d) "), aFreq ) );
       
   148     TUint32 freq = aFreq;
       
   149     if ( ( iMinFreq != 0 ) && ( iMaxFreq != 0 ) )
       
   150         {
       
   151         if ( freq < iMinFreq )
       
   152             {
       
   153             freq = iMinFreq;
       
   154             }
       
   155         else if ( freq > iMaxFreq )
       
   156             {
       
   157             freq = iMaxFreq;
       
   158             }
       
   159         else {}
       
   160         }
       
   161     TInt intVal = freq / KFMRadioFreqMultiplier;
       
   162     TInt decVal = ( freq % KFMRadioFreqMultiplier ) / iDecDiv;
       
   163     static_cast<CFMRadioFrequencyNumber*>( 
       
   164         Field( KIntField ) )->SetValue( intVal, *Font() );
       
   165     static_cast<CFMRadioFrequencyNumber*>( 
       
   166         Field( KDecField ) )->SetValue( decVal, *Font() );
       
   167     UpdateMinimumAndMaximum();
       
   168     ValidateFields();
       
   169     DrawNow();
       
   170     }
       
   171 
       
   172 
       
   173 // ---------------------------------------------------------------------------
       
   174 // Calculates the frequency from values of the fields.
       
   175 // ---------------------------------------------------------------------------
       
   176 //        
       
   177 TUint32 CFMRadioFrequencyEditor::Frequency() const
       
   178     {
       
   179     TInt intVal = static_cast<CFMRadioFrequencyNumber*>( 
       
   180         Field( KIntField ) )->Value();
       
   181     TInt decVal = static_cast<CFMRadioFrequencyNumber*>( 
       
   182         Field( KDecField ) )->Value();
       
   183     return ( KFMRadioFreqMultiplier * intVal ) + ( iDecDiv * decVal );
       
   184     }
       
   185 
       
   186 
       
   187 // ---------------------------------------------------------------------------
       
   188 // CFMRadioFrequencyEditor::SetMinimumAndMaximum
       
   189 // ---------------------------------------------------------------------------
       
   190 //
       
   191 void CFMRadioFrequencyEditor::SetMinimumAndMaximum( 
       
   192         const TUint32 aMinimumFrequency, const TUint32 aMaximumFrequency )
       
   193     {
       
   194     iMinIntValue = aMinimumFrequency / KFMRadioFreqMultiplier;
       
   195     iMaxIntValue = aMaximumFrequency / KFMRadioFreqMultiplier;
       
   196     iMinDecValue = ( aMinimumFrequency % KFMRadioFreqMultiplier ) / iDecDiv;
       
   197     iMaxDecValue = ( aMaximumFrequency % KFMRadioFreqMultiplier ) / iDecDiv;
       
   198     }
       
   199 
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 // CFMRadioFrequencyEditor::GetMinimumAndMaximum
       
   203 // ---------------------------------------------------------------------------
       
   204 //
       
   205 void CFMRadioFrequencyEditor::GetMinimumAndMaximum( TUint32& aMinimumFrequency, 
       
   206         TUint32& aMaximumFrequency ) const
       
   207     {
       
   208     aMinimumFrequency = ( KFMRadioFreqMultiplier * iMinIntValue ) + 
       
   209         ( iDecDiv*iMinDecValue );
       
   210     aMaximumFrequency = ( KFMRadioFreqMultiplier * iMaxIntValue ) + 
       
   211         ( iDecDiv * iMaxDecValue );
       
   212     }
       
   213 
       
   214 
       
   215 // ---------------------------------------------------------------------------
       
   216 // From class CCoeControl.
       
   217 // CFMRadioFrequencyEditor::ConstructFromResourceL
       
   218 // ---------------------------------------------------------------------------
       
   219 //
       
   220 void CFMRadioFrequencyEditor::ConstructFromResourceL( 
       
   221         TResourceReader& aResourceReader )
       
   222     {
       
   223     TUint32 flags = aResourceReader.ReadUint8();
       
   224     ConstructL( EAknEditorFlagDeliverVirtualKeyEventsToApplication );
       
   225     }
       
   226 
       
   227 
       
   228 // ---------------------------------------------------------------------------
       
   229 // From class CEikMfne.
       
   230 // Every key press may cause some recalculations and/or validations in 
       
   231 // the fields.
       
   232 // ---------------------------------------------------------------------------
       
   233 //
       
   234 TKeyResponse CFMRadioFrequencyEditor::OfferKeyEventL( const TKeyEvent& aKeyEvent, 
       
   235         TEventCode aType )
       
   236     {
       
   237     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::OfferKeyEventL ") ) );
       
   238     iPreviousField = CurrentField();
       
   239 
       
   240     TKeyResponse resp( EKeyWasNotConsumed );
       
   241     
       
   242     CEikMfneField* currField = Field( CurrentField() );
       
   243 
       
   244     // Check only once per key press.
       
   245     if ( aType == EEventKey )
       
   246         {
       
   247         TBool dataAltered = EFalse;
       
   248         TBool error = EFalse;
       
   249         TInt changeField = 0;
       
   250         TInt newCurrentField = CurrentField();
       
   251         
       
   252         switch ( aKeyEvent.iCode )
       
   253             {
       
   254             case '1':
       
   255             case '2':
       
   256             case '3':
       
   257             case '4':
       
   258             case '5':
       
   259             case '6':
       
   260             case '7':
       
   261             case '8':
       
   262             case '9':
       
   263             case '0':
       
   264                 {
       
   265                 currField->HandleKey( *Font(), aKeyEvent, EFalse, dataAltered, 
       
   266                     changeField );
       
   267 
       
   268                 // If after number key press we are still on decimal field 
       
   269                 // (and were before).
       
   270                 if ( ( !changeField ) && ( CurrentField() == KDecField ) )
       
   271                     {
       
   272                     // This can mean only that user has typed one number in 
       
   273                     // the decimal field and system is waiting for the other.
       
   274                     iTypedInDecField = ETrue;
       
   275                     }
       
   276                 else
       
   277                     {
       
   278                     iTypedInDecField = EFalse;
       
   279                     }
       
   280                 // If after number key press system moved to another field 
       
   281                 // (previous field was filled with numbers). 
       
   282                 if ( changeField )
       
   283                     {
       
   284                     if ( CurrentField() == KIntField )
       
   285                         {
       
   286                         // First check if the changed value is within limits.
       
   287                         error = ValidateIntField();    
       
   288                         // Calculate new minimums and maximums.
       
   289                         UpdateMinimumAndMaximum();    
       
   290                         // Now have to check also whether the other field is 
       
   291                         // within new limits.
       
   292                         ValidateDecField();            
       
   293                         }
       
   294                     else if ( CurrentField() == KDecField )
       
   295                         {
       
   296                         error = ValidateDecField();
       
   297                         }
       
   298                     else {}
       
   299                     }
       
   300                 break;
       
   301                 }
       
   302             case EKeyBackspace:        
       
   303                 {
       
   304                 // Pressing "c"-key in a field will set the field in 
       
   305                 // "typed" state.
       
   306                 currField->HandleKey( *Font(), aKeyEvent, EFalse, dataAltered, 
       
   307                     changeField );
       
   308                 if ( CurrentField() == KDecField )
       
   309                     {
       
   310                     iTypedInDecField = ETrue;
       
   311                     }
       
   312                 break;
       
   313                 }
       
   314             case EKeyLeftArrow: // fall-through intended here
       
   315             case EKeyRightArrow:
       
   316                 {
       
   317                 currField->HandleKey( *Font(), aKeyEvent, EFalse, dataAltered, 
       
   318                     changeField );
       
   319                 FillDecimalField();
       
   320                 ValidateFields();
       
   321                 // Minimums and maximums may have to be changed.
       
   322                 UpdateMinimumAndMaximum();    
       
   323                 // Validate according to new minimums and maximums.
       
   324                 ValidateFields();            
       
   325                 break;
       
   326                 }
       
   327             default:
       
   328                 {
       
   329                 break;
       
   330                 }
       
   331             }
       
   332 
       
   333         if ( changeField )
       
   334             {
       
   335             if ( CurrentField() == KIntField )
       
   336                 {
       
   337                 newCurrentField = KDecField;
       
   338                 }
       
   339             else
       
   340                 {
       
   341                 newCurrentField = KIntField;
       
   342                 }
       
   343             }
       
   344         TBuf<3> fieldText;
       
   345         TInt fieldVal = 0;
       
   346         TRAPD( err, fieldVal = static_cast<CFMRadioFrequencyNumber*>( currField )->Value() )
       
   347         if ( !err )
       
   348             {
       
   349             fieldText.Num( static_cast<TInt64>( fieldVal ) );
       
   350             }
       
   351         CEikMfne::HandleInteraction( changeField, newCurrentField,
       
   352                                      Font()->TextWidthInPixels( fieldText ),
       
   353                                      currField->HighlightType(),
       
   354                                      dataAltered,
       
   355                                      error );
       
   356 
       
   357         DrawAndReportL( EFalse );
       
   358         }
       
   359 
       
   360     return resp;
       
   361     }
       
   362 
       
   363 
       
   364 // ---------------------------------------------------------------------------
       
   365 // CFMRadioFrequencyEditor::FillDecimalField
       
   366 // ---------------------------------------------------------------------------
       
   367 //
       
   368 void CFMRadioFrequencyEditor::FillDecimalField()
       
   369     {
       
   370     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::FillDecimalField") ) );
       
   371     if ( iTypedInDecField )
       
   372         {    
       
   373         CFMRadioFrequencyNumber* field = 
       
   374             static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   375         // Multiply value by iDecDiv.
       
   376         field->SetValue( iDecDiv*field->Value(), *Font() );    
       
   377         iTypedInDecField = EFalse;
       
   378         }
       
   379     }
       
   380 
       
   381 
       
   382 // ---------------------------------------------------------------------------
       
   383 // CFMRadioFrequencyEditor::CanLeaveEditorL
       
   384 // ---------------------------------------------------------------------------
       
   385 //
       
   386 TBool CFMRadioFrequencyEditor::CanLeaveEditorL()
       
   387     {
       
   388     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::CanLeaveEditorL") ) );
       
   389     TBool ret = ETrue;
       
   390 
       
   391     FillDecimalField();
       
   392 
       
   393     if ( CurrentField() == KIntField )
       
   394         {
       
   395         // First check if the changed value is within limits.
       
   396         ret = !ValidateIntField();    
       
   397         // Calculate new minimums and maximums.
       
   398         UpdateMinimumAndMaximum();    
       
   399         // Now have to check also whether the other field is within new 
       
   400         // limits.
       
   401         ValidateDecField();            
       
   402         }
       
   403     else if ( CurrentField() == KDecField )
       
   404         {
       
   405         ret = !ValidateDecField();
       
   406         }
       
   407     else {}
       
   408 
       
   409     PrepareForFocusLossL();
       
   410 
       
   411     // Draw immediately, otherwise a wrong number is displayed in decimal 
       
   412     // field (for example: 03 instead of 30)
       
   413     DrawAndReportL( ETrue ); 
       
   414                            
       
   415     return ret;
       
   416     }
       
   417     
       
   418 // ---------------------------------------------------------------------------
       
   419 // CFMRadioFrequencyEditor::IncrementCurrentField
       
   420 // ---------------------------------------------------------------------------
       
   421 //
       
   422 void CFMRadioFrequencyEditor::IncrementCurrentField()
       
   423 	{
       
   424 	CEikMfneField* currField = Field( CurrentField() );
       
   425 	 // If user is not in the middle of typing numbers.
       
   426     if ( currField->HighlightType() == 
       
   427             CEikMfneField::EInverseVideo )
       
   428         {
       
   429         if ( CurrentField() == KIntField )
       
   430             {
       
   431             IncrementIntField();
       
   432             }
       
   433         else if ( CurrentField() == KDecField )
       
   434             {
       
   435             IncrementDecField();
       
   436             }
       
   437         else {}
       
   438         // Minimums and maximums may have to be changed.
       
   439         UpdateMinimumAndMaximum();    
       
   440         // Validate according to new minimums and maximums.
       
   441         ValidateFields();            
       
   442         }
       
   443         
       
   444     TRAP_IGNORE( DrawAndReportL( EFalse ) );
       
   445 	}
       
   446 	
       
   447 // ---------------------------------------------------------------------------
       
   448 // CFMRadioFrequencyEditor::DecrementCurrentField
       
   449 // ---------------------------------------------------------------------------
       
   450 //
       
   451 void CFMRadioFrequencyEditor::DecrementCurrentField()
       
   452 	{
       
   453 	CEikMfneField* currField = Field( CurrentField() );
       
   454 	 // If user is not in the middle of typing numbers.
       
   455     if ( currField->HighlightType() == 
       
   456             CEikMfneField::EInverseVideo )
       
   457         {
       
   458         if ( CurrentField() == KIntField )
       
   459             {
       
   460             DecrementIntField();
       
   461             }
       
   462         else if ( CurrentField() == KDecField )
       
   463             {
       
   464             DecrementDecField();
       
   465             }
       
   466         else {}
       
   467         // Minimums and maximums may have to be changed.
       
   468         UpdateMinimumAndMaximum();    
       
   469         // Validate according to new minimums and maximums.
       
   470         ValidateFields();            
       
   471         }
       
   472     TRAP_IGNORE( DrawAndReportL( EFalse ) );
       
   473 	}
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // Field decrement step is 1.
       
   477 // If field value is already at maximum, it set to minimum.
       
   478 // ---------------------------------------------------------------------------
       
   479 //
       
   480 void CFMRadioFrequencyEditor::IncrementIntField()
       
   481     {
       
   482     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::IncrementIntField") ) );
       
   483     CFMRadioFrequencyNumber* field = 
       
   484         static_cast<CFMRadioFrequencyNumber*>( Field( KIntField ) );
       
   485     CFMRadioFrequencyNumber* decField = 
       
   486         static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   487         
       
   488     if ( field->Value() < iMaxIntValue )
       
   489         {
       
   490         field->SetValue( field->Value() + 1, *Font() );
       
   491         }
       
   492     else if ( field->Value() == iMaxIntValue && decField->Value() == iMaxDecValue)
       
   493         {
       
   494         field->SetValue( iMinIntValue, *Font() );
       
   495         }
       
   496     else 
       
   497         {
       
   498         decField->SetValue( iMaxDecValue, *Font() );        
       
   499         }
       
   500     }
       
   501     
       
   502     
       
   503 // ---------------------------------------------------------------------------
       
   504 // Field decrement step is 1.
       
   505 // If field value is already at minimum, it set to maximum.
       
   506 // ---------------------------------------------------------------------------
       
   507 //
       
   508 void CFMRadioFrequencyEditor::DecrementIntField()
       
   509     {
       
   510     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::DecrementIntField") ) );
       
   511     CFMRadioFrequencyNumber* field = 
       
   512         static_cast<CFMRadioFrequencyNumber*>( Field( KIntField ) );
       
   513     CFMRadioFrequencyNumber* decField = 
       
   514         static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   515     
       
   516     if ( field->Value() > iMinIntValue )
       
   517         {
       
   518         field->SetValue( field->Value() - 1, *Font() );
       
   519         }
       
   520     else if ( field->Value() == iMinIntValue && decField->Value() == iMinDecValue)
       
   521         {
       
   522         field->SetValue( iMaxIntValue, *Font() );
       
   523         }
       
   524     else 
       
   525         {
       
   526         decField->SetValue( iMinDecValue, *Font() );
       
   527         }
       
   528     }
       
   529     
       
   530     
       
   531 // ---------------------------------------------------------------------------
       
   532 // Field inrement step is defined in RadioSettings.
       
   533 // If field value is already at maximum, integer field
       
   534 // has to be incremented and this field set to minimum.
       
   535 // ---------------------------------------------------------------------------
       
   536 //
       
   537 void CFMRadioFrequencyEditor::IncrementDecField()
       
   538     {
       
   539     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::IncrementDecField") ) );
       
   540     CFMRadioFrequencyNumber* field = 
       
   541         static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   542     if ( field->Value() < iMaxDecValue )
       
   543         {
       
   544         field->SetValue( field->Value() + iStepFreq/iDecDiv, *Font() );
       
   545         }
       
   546     else if ( field->Value() == iMaxDecValue )
       
   547         {
       
   548         IncrementIntField();
       
   549         // This is done because min of this field may change when integer 
       
   550         // field is set to it's minimum.
       
   551         UpdateMinimumAndMaximum();    
       
   552         field->SetValue( iMinDecValue, *Font() );
       
   553         }
       
   554     else {}
       
   555     }
       
   556     
       
   557     
       
   558 // ---------------------------------------------------------------------------
       
   559 // Field decrement step is defined in RadioSettings.
       
   560 // If field value is already at minimum, integer field
       
   561 // has to be decremented and this field set to maximum.
       
   562 // ---------------------------------------------------------------------------
       
   563 //
       
   564 void CFMRadioFrequencyEditor::DecrementDecField()
       
   565     {
       
   566     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::DecrementDecField") ) );
       
   567     CFMRadioFrequencyNumber* field = 
       
   568         static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   569     if ( field->Value() > iMinDecValue )
       
   570         {
       
   571         field->SetValue( field->Value() - iStepFreq/iDecDiv, *Font() );
       
   572         }
       
   573     else if ( field->Value() == iMinDecValue )
       
   574         {
       
   575         DecrementIntField();
       
   576         // This is done because max of this field may change when integer 
       
   577         // field is set to it's maximum.
       
   578         UpdateMinimumAndMaximum();    
       
   579         field->SetValue( iMaxDecValue, *Font() );
       
   580         }
       
   581     else {}
       
   582     }
       
   583 
       
   584 
       
   585 // ---------------------------------------------------------------------------
       
   586 // CFMRadioFrequencyEditor::ValidateFields
       
   587 // ---------------------------------------------------------------------------
       
   588 //
       
   589 void CFMRadioFrequencyEditor::ValidateFields()
       
   590     {
       
   591     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::ValidateFields") ) );
       
   592     ValidateIntField();
       
   593     ValidateDecField();
       
   594     }
       
   595 
       
   596 
       
   597 // ---------------------------------------------------------------------------
       
   598 // CFMRadioFrequencyEditor::ValidateIntField
       
   599 // ---------------------------------------------------------------------------
       
   600 //
       
   601 TBool CFMRadioFrequencyEditor::ValidateIntField()
       
   602     {
       
   603     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::ValidateIntField") ) );
       
   604     TBool ret = EFalse;
       
   605     
       
   606     // Check if integer field value is within limits.
       
   607     CFMRadioFrequencyNumber* field = 
       
   608         static_cast<CFMRadioFrequencyNumber*>( Field( KIntField ) );
       
   609     if ( field->Value() < iMinIntValue )
       
   610         {
       
   611         field->SetValue( iMinIntValue, *Font() );
       
   612         ret = ETrue;
       
   613         }
       
   614     else if ( field->Value() > iMaxIntValue )
       
   615         {
       
   616         field->SetValue( iMaxIntValue, *Font() );
       
   617         ret = ETrue;
       
   618         }
       
   619     else {}
       
   620 
       
   621     return ret;
       
   622     }
       
   623 
       
   624 
       
   625 // ---------------------------------------------------------------------------
       
   626 // CFMRadioFrequencyEditor::ValidateDecField
       
   627 // ---------------------------------------------------------------------------
       
   628 //
       
   629 TBool CFMRadioFrequencyEditor::ValidateDecField()
       
   630     {
       
   631     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::ValidateDecField") ) );
       
   632     TBool ret = EFalse;
       
   633 
       
   634     // Check if decimal field value is within limits.
       
   635     CFMRadioFrequencyNumber* field = 
       
   636         static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   637     if ( field->Value() < iMinDecValue )
       
   638         {
       
   639         field->SetValue( iMinDecValue, *Font() );
       
   640         ret = ETrue;
       
   641         }
       
   642     else if ( field->Value() > iMaxDecValue )
       
   643         {
       
   644         field->SetValue( iMaxDecValue, *Font() );
       
   645         ret = ETrue;
       
   646         }
       
   647     else
       
   648         {
       
   649         // Check if decimal field value is within a step.
       
   650         TInt remainder = static_cast<TUint32>( 
       
   651             ( field->Value()-iMinDecValue ) ) % ( iStepFreq/iDecDiv );
       
   652         if ( remainder != 0 )
       
   653             {
       
   654             field->SetValue( field->Value()-remainder, *Font() );
       
   655             ret = ETrue;
       
   656             }
       
   657         }
       
   658 
       
   659     return ret;
       
   660     }
       
   661 
       
   662 
       
   663 // ---------------------------------------------------------------------------
       
   664 // CFMRadioFrequencyEditor::UpdateMinimumAndMaximum
       
   665 // ---------------------------------------------------------------------------
       
   666 //
       
   667 void CFMRadioFrequencyEditor::UpdateMinimumAndMaximum()
       
   668     {
       
   669     FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyEditor::UpdateMinimumAndMaximum") ) );
       
   670     TInt minIntValue( 0 );
       
   671     TInt maxIntValue( 0 );
       
   672     TInt minDecValue( 0 );
       
   673     TInt maxDecValue( 0 );
       
   674     
       
   675     minIntValue = iMinFreq / KFMRadioFreqMultiplier;
       
   676     maxIntValue = iMaxFreq / KFMRadioFreqMultiplier;
       
   677         
       
   678     if ( ( Frequency() / KFMRadioFreqMultiplier > iMinFreq / KFMRadioFreqMultiplier ) && 
       
   679             ( Frequency() / KFMRadioFreqMultiplier < iMaxFreq / KFMRadioFreqMultiplier ) )
       
   680         {    
       
   681         // Remainder of the gap from min freq to next int value.
       
   682         minDecValue = ( ( ( KFMRadioFreqMultiplier * ( minIntValue + 1 ) ) - iMinFreq ) 
       
   683             % iStepFreq ) / iDecDiv;
       
   684         // Same kind of thing vice versa.
       
   685         maxDecValue = ( ( ( iMinFreq - ( KFMRadioFreqMultiplier * ( minIntValue ) ) ) 
       
   686             % iStepFreq ) / iDecDiv ) + KFMRadioFreqMultiplier / iDecDiv 
       
   687             - ( iStepFreq / iDecDiv );    
       
   688         }
       
   689     else if ( Frequency() / KFMRadioFreqMultiplier == iMinFreq / KFMRadioFreqMultiplier )
       
   690         {
       
   691         minDecValue = ( iMinFreq % KFMRadioFreqMultiplier ) / iDecDiv;
       
   692         // Same kind of thing vice versa.
       
   693         maxDecValue = ( ( ( iMinFreq - ( KFMRadioFreqMultiplier * ( minIntValue ) ) ) 
       
   694             % iStepFreq ) / iDecDiv ) + KFMRadioFreqMultiplier / iDecDiv 
       
   695             - ( iStepFreq / iDecDiv );
       
   696         }
       
   697     else if ( Frequency() / KFMRadioFreqMultiplier == iMaxFreq / KFMRadioFreqMultiplier )
       
   698         {
       
   699         // Remainder of the gap from min freq to next int value.
       
   700         minDecValue = ( ( ( KFMRadioFreqMultiplier * ( minIntValue + 1 ) ) - iMinFreq ) 
       
   701             % iStepFreq ) / iDecDiv;    
       
   702         maxDecValue = ( iMaxFreq % KFMRadioFreqMultiplier ) / iDecDiv;
       
   703         }
       
   704     else {}
       
   705 
       
   706     SetMinimumAndMaximum( 
       
   707         ( KFMRadioFreqMultiplier * minIntValue ) + ( iDecDiv * minDecValue ), 
       
   708         ( KFMRadioFreqMultiplier * maxIntValue ) + ( iDecDiv * maxDecValue ) );
       
   709     }
       
   710 
       
   711 
       
   712 // ---------------------------------------------------------------------------
       
   713 // CFMRadioFrequencyEditor::IsValid
       
   714 // ---------------------------------------------------------------------------
       
   715 //
       
   716 TBool CFMRadioFrequencyEditor::IsValid() const
       
   717     {
       
   718     return ( Field( CurrentField() )->HighlightType() == 
       
   719         CEikMfneField::EInverseVideo );
       
   720     }
       
   721 
       
   722 
       
   723 // ---------------------------------------------------------------------------
       
   724 // CFMRadioFrequencyEditor::IsValidToReport
       
   725 // ---------------------------------------------------------------------------
       
   726 //
       
   727 TBool CFMRadioFrequencyEditor::IsValidToReport() const
       
   728     {
       
   729     return iValidToReport;
       
   730     }
       
   731 
       
   732 
       
   733 // ---------------------------------------------------------------------------
       
   734 // CFMRadioFrequencyEditor::DrawAndReportL
       
   735 // ---------------------------------------------------------------------------
       
   736 //
       
   737 void CFMRadioFrequencyEditor::DrawAndReportL( TBool /*aForceDrawNow*/ )
       
   738     {
       
   739     //Switched to always do DrawNow() - DrawDeferred() is too slow for rapid
       
   740     //frequency changing (long press accelerates after a while)
       
   741 //    if ( !aForceDrawNow && ( DrawableWindow() && !IsBackedUp() ) )
       
   742 //        {
       
   743 //        // Flicker-free redraw.
       
   744 //        DrawDeferred();
       
   745 //        }
       
   746 //    else
       
   747 //        {
       
   748 //        DrawNow();
       
   749 //        }	
       
   750 
       
   751     DrawNow();
       
   752     
       
   753 
       
   754 	if ( iReportEditorState )
       
   755 		{
       
   756 		iValidToReport = ETrue;		
       
   757 		}
       
   758 	else
       
   759 		{
       
   760 		iValidToReport = EFalse;	
       
   761 		}		
       
   762     // Report back finally to main container.
       
   763     ReportEventL( MCoeControlObserver::EEventStateChanged );    
       
   764     iValidToReport = EFalse;
       
   765     }
       
   766 
       
   767 
       
   768 // ---------------------------------------------------------------------------
       
   769 // From class CCoeControl.
       
   770 // CFMRadioFrequencyEditor::FocusChanged
       
   771 // ---------------------------------------------------------------------------
       
   772 //
       
   773 void CFMRadioFrequencyEditor::FocusChanged( TDrawNow /*aDrawNow*/ )
       
   774     {
       
   775     if ( Field( CurrentField() )->HighlightType() == 
       
   776             CEikMfneField::EInverseVideo )
       
   777         {
       
   778         CFMRadioFrequencyNumber* field = 
       
   779             static_cast<CFMRadioFrequencyNumber*>( Field( KIntField ) );
       
   780         field->SetDigitType( AknTextUtils::NumericEditorDigitType(), 
       
   781             *Font() );
       
   782         field = NULL;
       
   783         field = static_cast<CFMRadioFrequencyNumber*>( Field( KDecField ) );
       
   784         field->SetDigitType( AknTextUtils::NumericEditorDigitType(), 
       
   785             *Font() );
       
   786         }
       
   787 
       
   788     if ( DrawableWindow() && !IsBackedUp() )
       
   789         {
       
   790         // Flicker-free redraw.
       
   791         reinterpret_cast<RWindow*>( DrawableWindow() )->Invalidate();
       
   792         }
       
   793     else
       
   794         {
       
   795         DrawNow();
       
   796         }
       
   797     }
       
   798 
       
   799 void CFMRadioFrequencyEditor::SetEditorReportState( const TBool aReport )
       
   800 	{
       
   801 	iReportEditorState = aReport;
       
   802 	}
       
   803 
       
   804 // ---------------------------------------------------------------------------
       
   805 // From class CCoeControl.
       
   806 // CFMRadioFrequencyEditor::HandlePointerEventL
       
   807 // ---------------------------------------------------------------------------
       
   808 //
       
   809 void CFMRadioFrequencyEditor::HandlePointerEventL( const TPointerEvent& aPointerEvent )
       
   810     {
       
   811     if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
   812         {
       
   813         TBool dataAltered = EFalse;
       
   814         TInt newCurrentField = CurrentField();
       
   815         TInt error = KErrNone;
       
   816     
       
   817         CEikMfneField* currField = Field( CurrentField() );
       
   818         TInt fieldWidth = iEditorFrameRect.Width() / 2;
       
   819         TRect fieldRect;
       
   820         
       
   821         if ( CurrentField() == KIntField )
       
   822             {
       
   823             newCurrentField = KDecField;
       
   824             TPoint fieldPos( iEditorFrameRect.iTl );
       
   825             fieldPos.iX += iEditorFrameRect.Width() - fieldWidth;
       
   826             fieldRect.SetRect( fieldPos, TSize( fieldWidth , iEditorFrameRect.Height() ) );
       
   827             }
       
   828         else
       
   829             {
       
   830             newCurrentField = KIntField;
       
   831             fieldRect.SetRect( iEditorFrameRect.iTl, TSize( fieldWidth , iEditorFrameRect.Height() ) );
       
   832             }
       
   833 
       
   834         if ( fieldRect.Contains( aPointerEvent.iPosition ) )
       
   835             {
       
   836             FillDecimalField();
       
   837             ValidateFields();
       
   838             // Minimums and maximums may have to be changed.
       
   839             UpdateMinimumAndMaximum();
       
   840             // Validate according to new minimums and maximums.
       
   841             ValidateFields();
       
   842 
       
   843              TBuf<3> fieldText;
       
   844              TInt fieldVal = 0;
       
   845              TRAPD( err, fieldVal = static_cast<CFMRadioFrequencyNumber*>( currField )->Value() )
       
   846              if ( !err )
       
   847                  {
       
   848                  fieldText.Num( static_cast<TInt64>( fieldVal ) );
       
   849                  }
       
   850              CEikMfne::HandleInteraction( ETrue,
       
   851                                           newCurrentField, 
       
   852                                           Font()->TextWidthInPixels( fieldText ), 
       
   853                                           currField->HighlightType(),
       
   854                                           dataAltered,
       
   855                                           error );
       
   856             }
       
   857         }
       
   858     }
       
   859 
       
   860 // ---------------------------------------------------------------------------
       
   861 // CFMRadioFrequencyEditor::SetEditorFrameRect
       
   862 // ---------------------------------------------------------------------------
       
   863 //
       
   864 void CFMRadioFrequencyEditor::SetEditorFrameRect( const TRect& aRect )
       
   865     {
       
   866     iEditorFrameRect = aRect;
       
   867     }
       
   868 
       
   869 // End of file