src/NPRStationListBox.cpp
changeset 0 0049171ecffb
equal deleted inserted replaced
-1:000000000000 0:0049171ecffb
       
     1 /*
       
     2  ============================================================================
       
     3  Name	: NPRStationListBox.cpp
       
     4  Author	: Symsource
       
     5  
       
     6  Copyright (c) 2009 Symbian Foundation Ltd
       
     7  This component and the accompanying materials are made available
       
     8  under the terms of the License "Eclipse Public License v1.0"
       
     9  which accompanies this distribution, and is available
       
    10  at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
    11 
       
    12  Initial Contributors:
       
    13  - Symsource
       
    14  
       
    15  Contributors:
       
    16  - Symsource
       
    17  
       
    18  Description : Container for Series60 double style list box to show the NPR's station list
       
    19  ============================================================================
       
    20  */
       
    21 
       
    22 #include <barsread.h>
       
    23 #include <aknlists.h>
       
    24 #include <NPR_0xEEB0E481.rsg>
       
    25 
       
    26 #include "NPRStationListBox.h"
       
    27 #include "NPRStationListBoxView.h"
       
    28 #include "NPR.hrh"
       
    29 #include "NPRStation.h"
       
    30 #include "NPRAppUi.h"
       
    31 #include "NPRAppEngine.h"
       
    32 
       
    33 const TInt KFrequencyTab = 20;
       
    34 /**
       
    35  * First phase of Symbian two-phase construction. Should not 
       
    36  * contain any code that could leave.
       
    37  */
       
    38 CNPRStationListBox::CNPRStationListBox()
       
    39 	{
       
    40 	iListBox = NULL;
       
    41 	iStationArray = static_cast<CNPRAppUi*>(CEikonEnv::Static()->EikAppUi())->Engine().Stations();
       
    42 	}
       
    43 /** 
       
    44  * Destroy child controls.
       
    45  */
       
    46 CNPRStationListBox::~CNPRStationListBox()
       
    47 	{
       
    48 	delete iListBox;
       
    49 	iListBox = NULL;
       
    50 	}
       
    51 				
       
    52 /**
       
    53  * Construct the control (first phase).
       
    54  *  Creates an instance and initializes it.
       
    55  *  Instance is not left on cleanup stack.
       
    56  * @param aRect bounding rectangle
       
    57  * @param aParent owning parent, or NULL
       
    58  * @param aCommandObserver command observer
       
    59  * @return initialized instance of CNPRStationListBox
       
    60  */
       
    61 CNPRStationListBox* CNPRStationListBox::NewL( 
       
    62 		const TRect& aRect, 
       
    63 		const CCoeControl* aParent, 
       
    64 		MEikCommandObserver* aCommandObserver )
       
    65 	{
       
    66 	CNPRStationListBox* self = CNPRStationListBox::NewLC( 
       
    67 			aRect, 
       
    68 			aParent, 
       
    69 			aCommandObserver );
       
    70 	CleanupStack::Pop( self );
       
    71 	return self;
       
    72 	}
       
    73 
       
    74 /**
       
    75  * Construct the control (first phase).
       
    76  *  Creates an instance and initializes it.
       
    77  *  Instance is left on cleanup stack.
       
    78  * @param aRect The rectangle for this window
       
    79  * @param aParent owning parent, or NULL
       
    80  * @param aCommandObserver command observer
       
    81  * @return new instance of CNPRStationListBox
       
    82  */
       
    83 CNPRStationListBox* CNPRStationListBox::NewLC( 
       
    84 		const TRect& aRect, 
       
    85 		const CCoeControl* aParent, 
       
    86 		MEikCommandObserver* aCommandObserver )
       
    87 	{
       
    88 	CNPRStationListBox* self = new ( ELeave ) CNPRStationListBox();
       
    89 	CleanupStack::PushL( self );
       
    90 	self->ConstructL( aRect, aParent, aCommandObserver );
       
    91 	return self;
       
    92 	}
       
    93 			
       
    94 /**
       
    95  * Construct the control (second phase).
       
    96  *  Creates a window to contain the controls and activates it.
       
    97  * @param aRect bounding rectangle
       
    98  * @param aCommandObserver command observer
       
    99  * @param aParent owning parent, or NULL
       
   100  */ 
       
   101 void CNPRStationListBox::ConstructL( 
       
   102 		const TRect& aRect, 
       
   103 		const CCoeControl* aParent, 
       
   104 		MEikCommandObserver* aCommandObserver )
       
   105 	{
       
   106 	if ( aParent == NULL )
       
   107 	    {
       
   108 		CreateWindowL();
       
   109 	    }
       
   110 	else
       
   111 	    {
       
   112 	    SetContainerWindowL( *aParent );
       
   113 	    }
       
   114 	iFocusControl = NULL;
       
   115 	iCommandObserver = aCommandObserver;
       
   116 	InitializeControlsL();
       
   117 	SetRect( aRect );
       
   118 	ActivateL();
       
   119 	}
       
   120 			
       
   121 /**
       
   122 * Return the number of controls in the container (override)
       
   123 * @return count
       
   124 */
       
   125 TInt CNPRStationListBox::CountComponentControls() const
       
   126 	{
       
   127 	return ( int ) ELastControl;
       
   128 	}
       
   129 				
       
   130 /**
       
   131 * Get the control with the given index (override)
       
   132 * @param aIndex Control index [0...n) (limited by #CountComponentControls)
       
   133 * @return Pointer to control
       
   134 */
       
   135 CCoeControl* CNPRStationListBox::ComponentControl( TInt aIndex ) const
       
   136 	{
       
   137 	switch ( aIndex )
       
   138 		{
       
   139 	case EListBox:
       
   140 		return iListBox;
       
   141 		}
       
   142 	return NULL;
       
   143 	}
       
   144 				
       
   145 /**
       
   146  *	Handle resizing of the container. This implementation will lay out
       
   147  *  full-sized controls like list boxes for any screen size, and will layout
       
   148  *  labels, editors, etc. to the size they were given in the UI designer.
       
   149  *  This code will need to be modified to adjust arbitrary controls to
       
   150  *  any screen size.
       
   151  */				
       
   152 void CNPRStationListBox::SizeChanged()
       
   153 	{
       
   154 	CCoeControl::SizeChanged();
       
   155 	LayoutControls();
       
   156 	}
       
   157 				
       
   158 /**
       
   159  * Layout components as specified in the UI Designer
       
   160  */
       
   161 void CNPRStationListBox::LayoutControls()
       
   162 	{
       
   163 	iListBox->SetExtent( TPoint( 0, 0 ), iListBox->MinimumSize() );
       
   164 	}
       
   165 
       
   166 void CNPRStationListBox::Listen()
       
   167 	{
       
   168 	static_cast<CNPRAppUi*>(CEikonEnv::Static()->EikAppUi())->Engine().SendNPRCommandL(EPlayStationStream, KNullDesC());
       
   169 	}
       
   170 
       
   171 /**
       
   172  *	Handle key events.
       
   173  */				
       
   174 TKeyResponse CNPRStationListBox::OfferKeyEventL( 
       
   175 		const TKeyEvent& aKeyEvent, 
       
   176 		TEventCode aType )
       
   177 	{
       
   178 	if ( aKeyEvent.iCode == EKeyLeftArrow 
       
   179 		|| aKeyEvent.iCode == EKeyRightArrow )
       
   180 		{
       
   181 		// Listbox takes all events even if it doesn't use them
       
   182 		return EKeyWasNotConsumed;
       
   183 		}
       
   184 	
       
   185 	if ( iFocusControl != NULL
       
   186 		&& iFocusControl->OfferKeyEventL( aKeyEvent, aType ) == EKeyWasConsumed )
       
   187 		{
       
   188 		return EKeyWasConsumed;
       
   189 		}
       
   190 	return CCoeControl::OfferKeyEventL( aKeyEvent, aType );
       
   191 	}
       
   192 				
       
   193 /**
       
   194  *	Initialize each control upon creation.
       
   195  */				
       
   196 void CNPRStationListBox::InitializeControlsL()
       
   197 	{
       
   198 	iListBox = new ( ELeave ) CAknDoubleStyle2ListBox;
       
   199 	iListBox->SetContainerWindowL( *this );
       
   200 	TResourceReader reader;
       
   201 	iEikonEnv->CreateResourceReaderLC( reader, R_NPRSTATION_LIST_BOX_LIST_BOX);
       
   202 	iListBox->ConstructFromResourceL( reader );
       
   203 	CleanupStack::PopAndDestroy(); // reader internal state
       
   204 	// the listbox owns the items in the list and will free them
       
   205 	iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray );
       
   206     iListBox->CreateScrollBarFrameL(ETrue);
       
   207     iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOn, CEikScrollBarFrame::EAuto);
       
   208 	
       
   209 	// setup the icon array so graphics-style boxes work
       
   210 	SetupListBoxIconsL();
       
   211 	
       
   212 	// add list items
       
   213 	for(TInt i=0; i<iStationArray->Count(); i++)
       
   214 		{
       
   215 		TInt nameLength = (*iStationArray)[i]->Name().Length();
       
   216 		TBuf<64> namePlusFrequency((*iStationArray)[i]->Name());
       
   217 		if((*iStationArray)[i]->Frequency().Length()!=0)
       
   218 			{
       
   219 			for(TInt j=0; j<KFrequencyTab-nameLength;j++)
       
   220 				{
       
   221 				namePlusFrequency.Append(_L(" "));				
       
   222 				}
       
   223 			namePlusFrequency.Append((*iStationArray)[i]->Frequency());		
       
   224 			}
       
   225 	    TBuf<128> listString;
       
   226 		CreateListBoxItemL(listString, namePlusFrequency, (*iStationArray)[i]->MarketCity());
       
   227 		AddListBoxItemL(iListBox, listString);
       
   228 		}
       
   229 	
       
   230 	iListBox->SetFocus( ETrue );
       
   231 	iFocusControl = iListBox;
       
   232 	}
       
   233 
       
   234 /** 
       
   235  * Handle global resource changes, such as scalable UI or skin events (override)
       
   236  */
       
   237 void CNPRStationListBox::HandleResourceChange( TInt aType )
       
   238 	{
       
   239 	CCoeControl::HandleResourceChange( aType );
       
   240 	SetRect( iAvkonViewAppUi->View( TUid::Uid( ENPRStationListBoxViewId ) )->ClientRect() );
       
   241 	}
       
   242 				
       
   243 /**
       
   244  *	Draw container contents.
       
   245  */				
       
   246 void CNPRStationListBox::Draw( const TRect& aRect ) const
       
   247 	{
       
   248 	CWindowGc& gc = SystemGc();
       
   249 	gc.Clear( aRect );
       
   250 	}
       
   251 				
       
   252 /**
       
   253  *	Add a list box item to a list.
       
   254  */
       
   255 void CNPRStationListBox::AddListBoxItemL( 
       
   256 		CEikTextListBox* aListBox,
       
   257 		const TDesC& aString )
       
   258 	{
       
   259 	CTextListBoxModel* model = aListBox->Model();
       
   260 	CDesCArray* itemArray = static_cast< CDesCArray* > ( model->ItemTextArray() );
       
   261 	itemArray->AppendL( aString );
       
   262 	aListBox->HandleItemAdditionL();
       
   263 	}
       
   264 
       
   265 /**
       
   266  * Get the array of selected item indices, with respect to the list model.
       
   267  * The array is sorted in ascending order.
       
   268  * The array should be destroyed with two calls to CleanupStack::PopAndDestroy(),
       
   269  * the first with no argument (referring to the internal resource) and the
       
   270  * second with the array pointer.
       
   271  * @return newly allocated array, which is left on the cleanup stack;
       
   272  *	or NULL for empty list. 
       
   273  */
       
   274 RArray< TInt >* CNPRStationListBox::GetSelectedListBoxItemsLC( CEikTextListBox* aListBox )
       
   275 	{
       
   276 	CAknFilteredTextListBoxModel* model = 
       
   277 		static_cast< CAknFilteredTextListBoxModel *> ( aListBox->Model() );
       
   278 	if ( model->NumberOfItems() == 0 )
       
   279 		return NULL;
       
   280 		
       
   281 	// get currently selected indices
       
   282 	const CListBoxView::CSelectionIndexArray* selectionIndexes =
       
   283 		aListBox->SelectionIndexes();
       
   284 	TInt selectedIndexesCount = selectionIndexes->Count();
       
   285 	if ( selectedIndexesCount == 0 )
       
   286 		return NULL;
       
   287 		
       
   288 	// copy the indices and sort numerically
       
   289 	RArray<TInt>* orderedSelectedIndices = 
       
   290 		new (ELeave) RArray< TInt >( selectedIndexesCount );
       
   291 	
       
   292 	// push the allocated array
       
   293 	CleanupStack::PushL( orderedSelectedIndices );
       
   294 	
       
   295 	// dispose the array resource
       
   296 	CleanupClosePushL( *orderedSelectedIndices );
       
   297 	
       
   298 	// see if the search field is enabled
       
   299 	CAknListBoxFilterItems* filter = model->Filter();
       
   300 	if ( filter != NULL )
       
   301 		{
       
   302 		// when filtering enabled, translate indices back to underlying model
       
   303 		for ( TInt idx = 0; idx < selectedIndexesCount; idx++ )
       
   304 			{
       
   305 			TInt filteredItem = ( *selectionIndexes ) [ idx ];
       
   306 			TInt actualItem = filter->FilteredItemIndex ( filteredItem );
       
   307 			orderedSelectedIndices->InsertInOrder( actualItem );
       
   308 			}
       
   309 		}
       
   310 	else
       
   311 		{
       
   312 		// the selection indices refer directly to the model
       
   313 		for ( TInt idx = 0; idx < selectedIndexesCount; idx++ )
       
   314 			orderedSelectedIndices->InsertInOrder( ( *selectionIndexes ) [ idx ] );
       
   315 		}	
       
   316 		
       
   317 	return orderedSelectedIndices;
       
   318 	}
       
   319 
       
   320 /**
       
   321  * Delete the selected item or items from the list box.
       
   322  */
       
   323 void CNPRStationListBox::DeleteSelectedListBoxItemsL( CEikTextListBox* aListBox )
       
   324 	{
       
   325 	CAknFilteredTextListBoxModel* model = 
       
   326 		static_cast< CAknFilteredTextListBoxModel *> ( aListBox->Model() );
       
   327 	if ( model->NumberOfItems() == 0 )
       
   328 		return;
       
   329 	
       
   330 	RArray< TInt >* orderedSelectedIndices = GetSelectedListBoxItemsLC( aListBox );		
       
   331 	if ( !orderedSelectedIndices )
       
   332 		return;
       
   333 		
       
   334 	// Delete selected items from bottom up so indices don't change on us
       
   335 	CDesCArray* itemArray = static_cast< CDesCArray* > ( model->ItemTextArray() );
       
   336 	TInt currentItem = 0;
       
   337 	
       
   338 	for ( TInt idx = orderedSelectedIndices->Count(); idx-- > 0; ) 
       
   339 		{
       
   340 		currentItem = ( *orderedSelectedIndices )[ idx ];
       
   341 		itemArray->Delete ( currentItem );
       
   342 		}
       
   343 	
       
   344 	// dispose the array resources
       
   345 	CleanupStack::PopAndDestroy();
       
   346 	
       
   347 	// dispose the array pointer
       
   348 	CleanupStack::PopAndDestroy( orderedSelectedIndices );
       
   349 	
       
   350 	// refresh listbox's cursor now that items are deleted
       
   351 	AknListBoxUtils::HandleItemRemovalAndPositionHighlightL(
       
   352 		aListBox, currentItem, ETrue );
       
   353 	}
       
   354 
       
   355 /**
       
   356  *	Get the listbox.
       
   357  */
       
   358 CAknDoubleStyle2ListBox* CNPRStationListBox::ListBox()
       
   359 	{
       
   360 	return iListBox;
       
   361 	}
       
   362 
       
   363 /**
       
   364  *	Create a list box item with the given column values.
       
   365  */
       
   366 void CNPRStationListBox::CreateListBoxItemL( TDes& aBuffer, 
       
   367 		const TDesC& aMainText,
       
   368 		const TDesC& aSecondaryText )
       
   369 	{
       
   370 	_LIT ( KStringHeader, "\t%S\t%S" );
       
   371 	
       
   372 	aBuffer.Format( KStringHeader(), &aMainText, &aSecondaryText );
       
   373 	} 
       
   374 				
       
   375 /**
       
   376  *	Add an item to the list by reading the text items from the array resource
       
   377  *	and setting a single image property (if available) from an index
       
   378  *	in the list box's icon array.
       
   379  *	@param aResourceId id of an ARRAY resource containing the textual
       
   380  *	items in the columns
       
   381  *	
       
   382  */
       
   383 void CNPRStationListBox::AddListBoxResourceArrayItemL( TInt aResourceId )
       
   384 	{
       
   385 	CDesCArray* array = iCoeEnv->ReadDesCArrayResourceL( aResourceId );
       
   386 	CleanupStack::PushL( array );
       
   387 	// This is intended to be large enough, but if you get 
       
   388 	// a USER 11 panic, consider reducing string sizes.
       
   389 	TBuf<512> listString; 
       
   390 	CreateListBoxItemL( listString, ( *array ) [ 0 ], ( *array ) [ 1 ] );
       
   391 	AddListBoxItemL( iListBox, listString );
       
   392 	CleanupStack::PopAndDestroy( array );
       
   393 	} 
       
   394 				
       
   395 /**
       
   396  *	Set up the list's icon array.
       
   397  */
       
   398 void CNPRStationListBox::SetupListBoxIconsL()
       
   399 	{
       
   400 	CArrayPtr< CGulIcon >* icons = NULL;		
       
   401 	
       
   402 	if(icons != NULL)
       
   403 		{
       
   404 		iListBox->ItemDrawer()->ColumnData()->SetIconArray(icons);
       
   405 		}
       
   406 	}
       
   407 
       
   408 /** 
       
   409  *	Handle commands relating to markable lists.
       
   410  */
       
   411 TBool CNPRStationListBox::HandleMarkableListCommandL(TInt /*aCommand*/)
       
   412 	{
       
   413 	TBool result = EFalse;
       
   414 	return result;
       
   415 	}