--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fmradio/fmradio/src/fmradioscanlocalstationscontainer.cpp Tue Feb 02 00:17:10 2010 +0200
@@ -0,0 +1,606 @@
+/*
+* Copyright (c) 2008 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: Implementation of the class CFMRadioScanLocalStationsContainer
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32math.h>
+#include <AknsSkinInstance.h>
+#include <AknsUtils.h>
+#include <AknsDrawUtils.h>
+#include <AknsBasicBackgroundControlContext.h>
+#include <akntoolbar.h>
+#include <gulutil.h>
+#include <w32std.h>
+#include <fmradio.rsg>
+#include <StringLoader.h>
+#include <eiklabel.h>
+#include <AknWaitDialog.h>
+#include <eikclbd.h>
+#include <AknIconArray.h>
+#include <gulicon.h>
+#include <fmradiouids.h>
+
+#if defined __SERIES60_HELP || defined FF_S60_HELPS_IN_USE
+#include "radio.hlp.hrh"
+#endif
+#include "fmradioapp.h"
+#include "fmradioappui.h"
+#include "fmradioscanlocalstationscontainer.h"
+#include "fmradioscanlocalstationsview.h"
+
+// CONSTANTS
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ----------------------------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::CFMRadioScanLocalStationsContainer
+// Default constructor
+// ----------------------------------------------------------------------------
+//
+CFMRadioScanLocalStationsContainer::CFMRadioScanLocalStationsContainer( CRadioEngine& aRadioEngine ):
+ iRadioEngine( aRadioEngine )
+ {
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::NewL
+// Two-phase constructor of CFMRadioScanLocalStationsContainer
+// ---------------------------------------------------------
+//
+CFMRadioScanLocalStationsContainer* CFMRadioScanLocalStationsContainer::NewL( const TRect& aRect, CRadioEngine& aRadioEngine )
+ {
+ CFMRadioScanLocalStationsContainer* self = new (ELeave) CFMRadioScanLocalStationsContainer( aRadioEngine );
+ CleanupStack::PushL( self );
+ self->ConstructL( aRect );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+//
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::ConstructL
+// EPOC two phased constructor
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::ConstructL( const TRect& aRect )
+ {
+ // check the layout orientation
+ CFMRadioAppUi* appUi = static_cast<CFMRadioAppUi*>( iCoeEnv->AppUi() );
+ TBool isLandscape = appUi->IsLandscapeOrientation();
+ CreateWindowL();
+
+ // Create the new context with image: KAknsIIDQsnBgAreaMain, and parent absolute layout is not used.
+ iBackground = CAknsBasicBackgroundControlContext::NewL(KAknsIIDQsnBgAreaMain, Rect(), EFalse );
+ iSkin = AknsUtils::SkinInstance();
+
+ // Instantiate a listbox for the channel list
+ iChannelList = new ( ELeave ) CAknSingleNumberStyleListBox();
+ iControls.Append( iChannelList );
+ iChannelList->SetContainerWindowL( *this );
+ iChannelList->SetListBoxObserver( this );
+ iChannelList->ConstructL( this, CEikListBox::ELoopScrolling | EAknListBoxSelectionList ); // Looped list
+ // Create scrollbars
+ iChannelList->CreateScrollBarFrameL( ETrue );
+
+ CAknIconArray* radioTypeIcons = NULL;
+ radioTypeIcons = new ( ELeave ) CAknIconArray( 2 );
+ CleanupStack::PushL( radioTypeIcons );
+ radioTypeIcons->AppendFromResourceL( R_FMRADIO_CHANNEL_LIST_ICON_ARRAY );
+ // The following line really takes the ownership -- must be the last item
+ // there, as if leaves and the object is in cleanupstack, problems arise.
+ // (Cleanup stack corruption!)
+ // Set the icon array for this list. List takes ownership of the array.
+ iChannelList->ItemDrawer()->ColumnData()->SetIconArray( radioTypeIcons );
+ CleanupStack::Pop( radioTypeIcons );
+
+ // Array for channels
+ iChannelItemArray = new( ELeave ) CDesCArrayFlat( KMaxNumberOfChannelListItems );
+ InitializeChannelListL();
+ SetRect( aRect );
+
+ CFMRadioScanLocalStationsView* searchStationsView = static_cast<CFMRadioScanLocalStationsView*> ( appUi->View( KFMRadioScanLocalStationsViewId ) );
+
+ ActivateL();
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::~CFMRadioScanLocalStationsContainer
+// Class destructor
+// ----------------------------------------------------
+//
+CFMRadioScanLocalStationsContainer::~CFMRadioScanLocalStationsContainer()
+ {
+ iControls.ResetAndDestroy();
+ delete iChannelItemArray;
+ if ( iBackground )
+ {
+ delete iBackground;
+ iBackground = NULL;
+ }
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::InitializeChannelListL
+// Create the channel list (initially all spots are set as empty)
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::InitializeChannelListL()
+ {
+ iChannelList->Reset();
+ iChannelItemArray->Reset();
+ iChannelList->ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
+ // Pass the array to the listbox model and set the ownership type
+ iChannelList->Model()->SetItemTextArray( (MDesCArray*) iChannelItemArray );
+ iChannelList->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
+ iChannelList->HandleItemAdditionL();
+ DrawDeferred();
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::UpdateChannelListContentL
+// Update the content of the channel at aIndex with the
+// values specified
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::UpdateChannelListContentL( TInt aIndex, const TDesC& aInfoText, TInt aChannelFrequency, TBool aNowPlaying, TBool aInfoTextPlacement )
+ {
+ TBuf<KLengthOfChannelItemString> textChannelItem;
+ TBuf<KLengthOfChIndexStringChList> textChIndex;
+ TBuf<KLengthOfChannelItemIconIndexString> textChIconIndex;
+
+ //textChIndex.Format( KChIndexFormatChList, aIndex+1 ); // One over index
+ textChIndex.SetLength( 0 );
+
+ textChIconIndex.Format( KChIconIndexFormatChList, KNowPlayingIconIndexChList ) ;
+ //Update to display Devnagari numbers for Text Index.
+ //AknTextUtils::LanguageSpecificNumberConversion(textChIndex);
+ textChannelItem.Append( textChIndex );
+ textChannelItem.Append( KColumnListSeparator );
+
+ TReal frequency = static_cast<TReal>( aChannelFrequency / static_cast<TReal>( KHzConversionFactor ));
+ // Gets locale decimal separator automatically
+ TRealFormat format(KFrequencyMaxLength, iRadioEngine.DecimalCount() );
+ TBuf<30> frequencyString;
+ frequencyString.Num( frequency, format );
+
+ HBufC* listItemString = NULL;
+ if ( aInfoTextPlacement ) // frequency and PS name
+ {
+ const TInt granularity = 2;
+
+ CDesCArray* stringsArray = new ( ELeave ) CDesCArrayFlat( granularity );
+ CleanupStack::PushL( stringsArray );
+ stringsArray->AppendL( frequencyString );
+ stringsArray->AppendL( aInfoText );
+
+ listItemString = StringLoader::LoadL( R_QTN_FMRADIO_SINGLE_FREQ_NAME, *stringsArray, iEikonEnv );
+ CleanupStack::PopAndDestroy( stringsArray );
+ CleanupStack::PushL( listItemString );
+ }
+ else // frequency
+ {
+ listItemString = StringLoader::LoadLC( R_QTN_FMRADIO_SINGLE_FREQ, frequencyString, iEikonEnv );
+ }
+
+ // Update for display of Hindi Devnagari Numbers
+ TPtr listItemStringPtr = listItemString->Des();
+ AknTextUtils::LanguageSpecificNumberConversion( listItemStringPtr );
+
+ textChannelItem.Append( *listItemString );
+ CleanupStack::PopAndDestroy( listItemString );
+
+ // Set 'Now Playing' icon to the channel item
+ textChannelItem.Append( KColumnListSeparator );
+
+ if ( aNowPlaying )
+ {
+ textChannelItem.Append( textChIconIndex );
+ }
+
+ if( aIndex <= ( iChannelItemArray->Count() - 1 ) )
+ {
+ iChannelItemArray->Delete( aIndex );
+ iChannelList->HandleItemRemovalL();
+ iChannelItemArray->InsertL( aIndex, textChannelItem );
+ }
+ else
+ {
+ iChannelItemArray->AppendL( textChannelItem );
+ }
+ iChannelList->HandleItemAdditionL(); // Update list
+ iChannelList->UpdateScrollBarsL();
+ iChannelList->DrawDeferred();
+ }
+
+
+// --------------------------------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::InsertScannedChannelToListL
+// --------------------------------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::InsertScannedChannelToListL( TInt aIndex, TInt aChannelFrequency )
+ {
+ TBuf<KLengthOfChannelItemString> textChannelItem;
+ TBuf<KLengthOfChIndexStringChList> textChIndex;
+
+ textChannelItem.Append( textChIndex );
+ textChannelItem.Append( KColumnListSeparator );
+
+ TReal frequency = static_cast<TReal>( aChannelFrequency / static_cast<TReal>( KHzConversionFactor ));
+ // Gets locale decimal separator automatically
+ TRealFormat format(KFrequencyMaxLength, iRadioEngine.DecimalCount() );
+ TBuf<30> frequencyString;
+ frequencyString.Num( frequency, format );
+
+ HBufC* listItemString = listItemString = StringLoader::LoadLC( R_QTN_FMRADIO_SINGLE_FREQ, frequencyString, iEikonEnv );
+ // Update for display of Hindi Devnagari Numbers
+ TPtr listItemStringPtr = listItemString->Des();
+ AknTextUtils::LanguageSpecificNumberConversion( listItemStringPtr );
+ textChannelItem.Append( *listItemString );
+ CleanupStack::PopAndDestroy( listItemString );
+
+ // Set 'Now Playing' icon to the channel item
+ textChannelItem.Append( KColumnListSeparator );
+
+ if ( aIndex <= ( iChannelItemArray->Count() - 1 ) )
+ {
+ iChannelItemArray->InsertL( aIndex, textChannelItem );
+ }
+ else
+ {
+ iChannelItemArray->AppendL( textChannelItem );
+ }
+
+ iChannelList->HandleItemAdditionL(); // Update list
+ iChannelList->UpdateScrollBarsL();
+ iChannelList->DrawDeferred();
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::RemoveChannelListContentL
+//
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::RemoveChannelListContentL( TInt aIndex )
+ {
+ if ( aIndex < iChannelItemArray->Count() )
+ {
+ iChannelItemArray->Delete( aIndex );
+ iChannelList->HandleItemRemovalL();
+ iChannelList->UpdateScrollBarsL();
+
+ TInt channelCount = iChannelItemArray->Count();
+ // check if the last channel is saved and update current item
+ if ( aIndex == channelCount && channelCount > 0 )
+ {
+ iChannelList->SetCurrentItemIndex( channelCount - 1 );
+ }
+ iChannelList->DrawDeferred();
+ }
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::UpdateNowPlayingIconL
+// Displays 'Now Playing' icon in the current selected channel item.
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::UpdateNowPlayingIconL( TInt aNewIndex, TInt aOldIndex )
+ {
+ HideNowPlayingIconL( aOldIndex, EFalse );
+
+ if ( aNewIndex >= 0 && aNewIndex < iChannelItemArray->Count() )
+ {
+ TBuf<KLengthOfChannelItemIconIndexString> textChIconIndex;
+ textChIconIndex.Format( KChIconIndexFormatChList, KNowPlayingIconIndexChList );
+ HBufC* channelItem = HBufC::NewLC( KLengthOfChannelItemString );
+ channelItem->Des().Copy( iChannelItemArray->MdcaPoint( aNewIndex ) );
+ TPtr ptr( channelItem->Des() );
+ ptr.Append( textChIconIndex ); // Add icon index
+
+ iChannelItemArray->InsertL( aNewIndex, *channelItem );
+ CleanupStack::PopAndDestroy( channelItem );
+ iChannelList->HandleItemAdditionL(); // Update list
+ iChannelItemArray->Delete( aNewIndex + 1 );
+ iChannelList->HandleItemRemovalL();
+ iChannelList->UpdateScrollBarsL();
+ }
+ // required for fast channel browsing
+ iChannelList->DrawNow();
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::HideNowPlayingIconL
+// Hides 'Now Playing' icon from the last selected channel.
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::HideNowPlayingIconL( TInt aIndex, TBool aDraw )
+ {
+ if ( aIndex >= 0 && aIndex < iChannelItemArray->Count() )
+ {
+ HBufC* channelItem = HBufC::NewLC( KLengthOfChannelItemString );
+ channelItem->Des().Copy( iChannelItemArray->MdcaPoint( aIndex ) );
+ TPtr ptr( channelItem->Des() );
+
+ TBuf<KLengthOfChannelItemIconIndexString> textChIconIndex;
+ TPtrC iconIndexPtr( textChIconIndex );
+ TInt err = TextUtils::ColumnText( iconIndexPtr, 2, &ptr );
+
+ if ( iconIndexPtr.Length() > 0 )
+ {
+ ptr.Delete( ptr.Length() - iconIndexPtr.Length(), iconIndexPtr.Length() ); // Remove icon index
+ iChannelItemArray->InsertL( aIndex, *channelItem );
+ iChannelList->HandleItemAdditionL(); // Update list
+ iChannelItemArray->Delete( aIndex + 1 );
+ iChannelList->HandleItemRemovalL();
+ iChannelList->UpdateScrollBarsL();
+
+ }
+ CleanupStack::PopAndDestroy( channelItem );
+ if ( aDraw )
+ {
+ iChannelList->DrawDeferred();
+ }
+ }
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::SetFaded
+// Fades the entire window and controls in the window owned
+// by this container control.
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::SetFaded( TBool aFaded )
+ {
+ iFadeStatus = aFaded;
+ Window().SetFaded( aFaded, RWindowTreeNode::EFadeIncludeChildren );
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::UpdateLastListenedChannel
+// Updates channel index - the highlighted channel in the list.
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::UpdateLastListenedChannel( TInt aIndex )
+ {
+ if ( aIndex < iChannelItemArray->Count() &&
+ aIndex > -1 )
+ {
+ iLastChIndex = aIndex;
+
+ iChannelList->SetCurrentItemIndex( iLastChIndex );
+ iChannelList->ScrollToMakeItemVisible( iLastChIndex );
+ DrawDeferred();
+ }
+
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::CurrentlySelectedChannel
+// Returns the index of the selected channel item from the
+// channel list.
+// ----------------------------------------------------
+//
+TInt CFMRadioScanLocalStationsContainer::CurrentlySelectedChannel() const
+ {
+ return iChannelList->CurrentItemIndex(); // Index of selected channel
+ }
+
+// ----------------------------------------------------
+// CFMRadioScanLocalStationsContainer::HandleListBoxEventL
+// For handling listbox-, in this case, channel list events.
+// The event equals to selecting a channel item from the list.
+// ----------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::HandleListBoxEventL( CEikListBox* /*aListBox*/,
+ TListBoxEvent aEventType )
+ {
+ // Check the event generated by keypress and report the event,
+ // Also check for Pen Enabled touch screen event
+ switch ( aEventType )
+ {
+ case EEventEnterKeyPressed:
+ case EEventItemSingleClicked: // new event for item activation
+ {
+ ReportEventL( MCoeControlObserver::EEventStateChanged );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::HandleResourceChange
+// -----------------------------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::HandleResourceChange( TInt aType )
+ {
+ CCoeControl::HandleResourceChange( aType );
+ if ( aType == KEikDynamicLayoutVariantSwitch )
+ {
+ SizeChanged();
+ }
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::SizeChanged
+// Called by framework when the view size is changed
+// ---------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::SizeChanged()
+ {
+ iChannelList->SetRect( Rect() );
+
+ if ( iBackground )
+ {
+ iBackground->SetRect( Rect() );
+ }
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::CountComponentControls
+// Return the number of controls in the window owned by this container
+// ---------------------------------------------------------
+//
+TInt CFMRadioScanLocalStationsContainer::CountComponentControls() const
+ {
+ return iControls.Count();
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::ComponentControl
+// Return the control corresponding to the specified index
+// ---------------------------------------------------------
+//
+CCoeControl* CFMRadioScanLocalStationsContainer::ComponentControl( TInt aIndex ) const
+ {
+ return STATIC_CAST( CCoeControl*, iControls[aIndex] );
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::OfferKeyEventL
+// Allow the channel list to process key events
+// ---------------------------------------------------------
+//
+TKeyResponse CFMRadioScanLocalStationsContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+ TEventCode aType )
+ {
+ TKeyResponse response = EKeyWasNotConsumed;
+
+ switch ( aKeyEvent.iCode )
+ {
+ case EKeyLeftArrow:
+ case EKeyRightArrow:
+ return EKeyWasNotConsumed;
+
+ case EKeyUpArrow:
+ case EKeyDownArrow:
+ response = iChannelList->OfferKeyEventL( aKeyEvent, aType );
+ if (response == EKeyWasConsumed)
+ {
+ ReportEventL( MCoeControlObserver::EEventRequestFocus );
+ }
+ return response;
+
+
+ default:
+ switch ( aKeyEvent.iScanCode ) //we need to use the scan code, because we need to process the event wrt the keyUp and keyDown action
+ {
+ case EKeyboardKey1: // Timed key
+ case EKeyboardKey2: // Normal keys
+ case EKeyboardKey3:
+ case EKeyboardKey4:
+ case EKeyboardKey5:
+ case EKeyboardKey6:
+ case EKeyboardKey7:
+ case EKeyboardKey8:
+ case EKeyboardKey9:
+ case EKeyboardKey0:
+ return EKeyWasNotConsumed;
+ default:
+ break;
+ }
+ break;
+ }
+ return iChannelList->OfferKeyEventL( aKeyEvent, aType );
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::Draw
+// Redraw the window owned by this container
+// ---------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::Draw( const TRect& aRect ) const
+ {
+ CWindowGc& gc = SystemGc();
+ gc.Clear();
+
+ if ( iBackground )
+ {
+ if ( !AknsDrawUtils::Background( iSkin, iBackground, this, gc, aRect) )
+ {
+ // The background was not drawn
+ iBackground->UpdateContext();
+ }
+ }
+ // Fade if needed
+ Window().SetFaded( iFadeStatus, RWindowTreeNode::EFadeIncludeChildren );
+ }
+
+// ---------------------------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::GetHelpContext
+// Gets Help
+// ---------------------------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::GetHelpContext( TCoeHelpContext& aContext ) const
+ {
+#if defined __SERIES60_HELP || defined FF_S60_HELPS_IN_USE
+ aContext.iMajor = TUid::Uid( KUidFMRadioApplication );
+ aContext.iContext = KFMRADIO_HLP_SEARCH;
+#endif
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::FocusChanged(TDrawNow aDrawNow)
+// ---------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::FocusChanged( TDrawNow aDrawNow )
+ {
+ CCoeControl::FocusChanged( aDrawNow );
+ if ( iChannelList )
+ {
+ iChannelList->SetFocus( IsFocused(), aDrawNow );
+ }
+ }
+
+// --------------------------------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::ResetChannelListL
+// Sets toolbar visibility
+// --------------------------------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::ResetChannelListL()
+ {
+ iChannelItemArray->Reset();
+ iChannelList->ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff );
+ iChannelList->HandleItemRemovalL();
+ iChannelList->DrawDeferred();
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::SetStationListEmptyTextL
+// ---------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::SetStationListEmptyTextL( const TDesC& aText )
+ {
+ iChannelList->View()->SetListEmptyTextL( aText );
+ }
+
+// ---------------------------------------------------------
+// CFMRadioScanLocalStationsContainer::HandlePointerEventL
+// ---------------------------------------------------------
+//
+void CFMRadioScanLocalStationsContainer::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ // don't handle any pointer events if view is faded
+ if ( !iFadeStatus )
+ {
+ CCoeControl::HandlePointerEventL( aPointerEvent );
+ }
+ }
+
+// End of File