fmradio/fmradio/src/fmradioscanlocalstationscontainer.cpp
changeset 0 f3d95d9c00ab
child 8 f73067c3e563
--- /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