fmradio/fmradio/src/fmradiofrequencynumber.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:30:32 +0100
branchRCL_3
changeset 20 93c594350b9a
parent 0 f3d95d9c00ab
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201031 Kit: 201035

/*
* Copyright (c) 2000 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Frequency number handling for manual tuning dialog
*
*/


// INCLUDE FILES

#include	<aknappui.h>
#include	<aknsoundsystem.h>
#include	<AknTextDecorationMetrics.h>
#include	<numberconversion.h>
#include	<EIKCTL.rsg>

#include    "fmradiofrequencynumber.h"
#include 	"debug.h"

// ================= MEMBER FUNCTIONS =======================

// C++ default constructor can NOT contain any code, that
// might leave.
//
CFMRadioFrequencyNumber::CFMRadioFrequencyNumber(TInt aMinimumValue, TInt aMaximumValue, TUint32 aFlags)
	: iMinimumValue(aMinimumValue), iMaximumValue(aMaximumValue), iFlags(aFlags)
	{
	// Get maximum number of digits.
	TBuf<16> maxText;
	maxText.AppendNum(static_cast<TInt64>(aMaximumValue));
	iMaxDigits = maxText.Length();
	}

// EPOC default constructor can leave.
void CFMRadioFrequencyNumber::ConstructL(const CFont& aFont, TInt aInitialValue)
    {
    FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::ConstructL") ) );
	// Init text field containing the value.
	iText = HBufC::NewL(iMaxDigits);
	SetValue(aInitialValue, aFont);
    }

// Two-phased constructor.
CFMRadioFrequencyNumber* CFMRadioFrequencyNumber::NewL(const CFont& aFont, TInt aMinimumValue, TInt aMaximumValue, TInt aInitialValue, TUint32 aFlags)
    {
    FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::NewL") ) );
    CFMRadioFrequencyNumber* self = new (ELeave) CFMRadioFrequencyNumber(aMinimumValue, aMaximumValue, aFlags);
    CleanupStack::PushL(self);
    self->ConstructL(aFont, aInitialValue);
    CleanupStack::Pop();
    return self;
    }

    
// Destructor
CFMRadioFrequencyNumber::~CFMRadioFrequencyNumber()
    {
    delete iText;
    }

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::MaximumWidthInPixels
// TInt addedWith is calculated same way than in TInt CEikMfneField::AdditionalWidthForHighlights, 
// which is public but not exported method.
// (other items were commented in a header).
// ---------------------------------------------------------
//
TInt CFMRadioFrequencyNumber::MaximumWidthInPixels(const CFont& aFont, TBool /*aShrinkToMinimumSize*/)
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::MaximumWidthInPixels") ) );
	TInt addedWidth = 0;
    if ( IsEditable() )
        {
        TInt rightHighlight = 0;
        TAknTextDecorationMetrics metrics( &aFont );
        // Width is increased only by leftHighlight.  This is a compromise in that glyphs already have 
        // spacing within them to achieve character spacing. This spacing is generally (for numbers) on the right. 
        metrics.GetLeftAndRightMargins( addedWidth, rightHighlight ); // rightHighlight is not used
        }

	return (iMaxDigits * TFindWidthOfWidestDigitType(iDigitType).MaximumWidthInPixels(aFont)) + addedWidth;
	}


// ---------------------------------------------------------
// CFMRadioFrequencyNumber::InputCapabilities
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
TCoeInputCapabilities CFMRadioFrequencyNumber::InputCapabilities() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::InputCapabilities") ) );
	return TCoeInputCapabilities::EWesternNumericIntegerPositive;
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::Text
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
const TDesC& CFMRadioFrequencyNumber::Text() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::Text") ) );

	if (iFlags & EIsUninitialised)
		{
		return KNullDesC();
		}

	return *iText;
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::SetValue
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CFMRadioFrequencyNumber::SetValue(TInt aValue, const CFont& aFont)
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::SetValue") ) );
	iFlags &= ~EIsUninitialised;
	TPtr text = iText->Des();
	text.SetLength(0);
	TInt firstUnsetCharacter = text.Length();
	text.SetLength(firstUnsetCharacter + iMaxDigits);
	TInt lastUnsetCharacter = text.Length() - 1;

	if (aValue == 0)
		{
		text[lastUnsetCharacter--] = TText(iDigitType);
		}
	else
		{
		for (; aValue; aValue/=10)
			{	
			text[lastUnsetCharacter--] = (TText)(TText(iDigitType) + (aValue%10));
			}
		}
	
	if (lastUnsetCharacter >= firstUnsetCharacter)
		{
		if (iFlags & EFillWithLeadingZeros)
			{
			while (lastUnsetCharacter >= firstUnsetCharacter)
				{
				text[lastUnsetCharacter--] = TText(iDigitType);
				}
			}
		else
			{
			text.Delete(firstUnsetCharacter, (lastUnsetCharacter + 1) - firstUnsetCharacter);
			}
		}

	if (iFlags & EPreserveOldWidthBeforeEditing)
		{
		iMinimumWidthInPixels = aFont.TextWidthInPixels(Text());
		}
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::Value
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
TInt CFMRadioFrequencyNumber::Value() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::Value") ) );
    if (iText->Length() == 0)
        {
        CAknKeySoundSystem* soundPlayer = (static_cast<CAknAppUi*>(CEikonEnv::Static()->AppUi()))->KeySounds();
		if (soundPlayer)
			{
			soundPlayer->PlaySound(EAvkonSIDWarningTone); 
			}
		CBaActiveScheduler::LeaveNoAlert();
        }

    return ValueFromText();
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::IsValid
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CFMRadioFrequencyNumber::IsValid() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::IsValid") ) );
	return (iText->Length() != 0);
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::IsEditable
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
TBool CFMRadioFrequencyNumber::IsEditable() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::IsEditable") ) );
	return ETrue;
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::HighlightType
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
CEikMfneField::THighlightType CFMRadioFrequencyNumber::HighlightType() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::HighlightType") ) );
	return (iFlags & EIsBeingEditedWithCursor) ? ECursor : EInverseVideo;
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::HandleKey
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CFMRadioFrequencyNumber::HandleKey(const CFont& /*aFont*/, const TKeyEvent& aKeyEvent, TBool /*aInterpretLeftAndRightAsEarEvents*/, TBool& aDataAltered, TInt& aHighlightIncrement)
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::HandleKey") ) );
	TChar ch = aKeyEvent.iCode;
	TPtr text = iText->Des();
	TInt textLength = text.Length();
	
	switch (ch)
		{
		case EKeyLeftArrow:
		case EKeyRightArrow:
			{
			HandleLeftOrRightArrow(ch, aDataAltered, aHighlightIncrement);	
			break;
			}
		case EKeyBackspace:
			{
			if (textLength)
				{
				iFlags |= EIsBeingEditedWithCursor;
				text.SetLength(textLength-1);
				aDataAltered = ETrue;
				iFlags &= ~EIsUninitialised;
				}
			break;
			}
		default:
			{
			// Number key:
			if (ch.GetNumericValue() != KErrNotFound)
				{
				if (~iFlags & EIsBeingEditedWithCursor)
					{
					// If only one number field, do not change to cursor mode.
					if (iMaxDigits > 1)
						{
						iFlags |=  EIsBeingEditedWithCursor;
						}
					text.SetLength(0);
					}

				TBuf<1> normCh;
				normCh.Append(ch);
				NumberConversion::ConvertDigits(normCh, iDigitType);
				text.Append(normCh[0]);
				aDataAltered = ETrue;
				iFlags &= ~EIsUninitialised;
				if (iText->Length() >= iMaxDigits)
					{
					aHighlightIncrement = 1;
					}
				}
			break;
			}
		}
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::HandleDeHighlight
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CFMRadioFrequencyNumber::HandleDeHighlight(const CFont& aFont, CEikonEnv& aEikonEnv, TBool& aDataAltered, TBool& aError)
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::HandleDeHighlight") ) );
	iFlags &= ~EIsBeingEditedWithCursor;

	if (iText->Length() == 0)
		{
		SetValue(iMaximumValue, aFont);
		aDataAltered = ETrue;
		aError = ETrue;
		aEikonEnv.InfoMsg(R_EIK_TBUF_NO_NUMBER_ENTERED);
		return;
		}

	TInt value = ValueFromText();
	TBuf<128> oldText = *iText;
	TBool unInit = iFlags & EIsUninitialised;
	SetValue(value, aFont);

	if (oldText != *iText)
		{
		aDataAltered = ETrue;
		}
	else
		{
		if (unInit)
			{
			iFlags |= EIsUninitialised;
			}
		else
			{
			iFlags &= ~EIsUninitialised;
			}
		}
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::ValueFromText
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
TInt CFMRadioFrequencyNumber::ValueFromText() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::ValueFromText") ) );
	if (!iText->Length())
		{
		return iMinimumValue;
		}

	TInt i = 0;
	TInt valueFromText = 0;
	TInt textLength = iText->Length();

	for (; i<textLength; ++i)
		{
		TText digit = (*iText)[i];
		valueFromText = (valueFromText * 10) + (TInt)(digit - TText(iDigitType));
		}

	return valueFromText;
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::SetDigitType
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
void CFMRadioFrequencyNumber::SetDigitType(TDigitType aDigitType, const CFont& aFont)
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::SetDigitType") ) );
	TInt value = Value();
	iDigitType = aDigitType;
	SetValue(value, aFont);
	}

// ---------------------------------------------------------
// CFMRadioFrequencyNumber::DigitType
// ?implementation_description
// (other items were commented in a header).
// ---------------------------------------------------------
//
TDigitType CFMRadioFrequencyNumber::DigitType() const
	{
	FTRACE( FPrint( _L(" *** FM Radio -- CFMRadioFrequencyNumber::DigitType") ) );
	return iDigitType;
	}

//  End of File