|
1 /* |
|
2 =============================================================================================== |
|
3 Name : NPRListBox.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 single large style list box to show the NPR's main options |
|
19 =============================================================================================== |
|
20 */ |
|
21 |
|
22 #include <barsread.h> |
|
23 #include <stringloader.h> |
|
24 #include <aknlists.h> |
|
25 #include <eikenv.h> |
|
26 #include <akniconarray.h> |
|
27 #include <eikclbd.h> |
|
28 #include <aknviewappui.h> |
|
29 #include <eikappui.h> |
|
30 #include <NPR_0xEEB0E481.rsg> |
|
31 |
|
32 #include "NPRListBox.h" |
|
33 #include "NPRListBoxView.h" |
|
34 #include "NPR.hrh" |
|
35 #include "NPRAppUi.h" |
|
36 #include "NPRAppEngine.h" |
|
37 |
|
38 _LIT(KNPR_0xEEB0E481File, "\\resource\\apps\\NPR_0xEEB0E481.mif"); |
|
39 _LIT ( KStringHeader, "%d\t%S" ); |
|
40 |
|
41 /** |
|
42 * First phase of Symbian two-phase construction. Should not |
|
43 * contain any code that could leave. |
|
44 */ |
|
45 CNPRListBox::CNPRListBox() |
|
46 { |
|
47 iListBox = NULL; |
|
48 } |
|
49 |
|
50 /** |
|
51 * Destroy child controls. |
|
52 */ |
|
53 CNPRListBox::~CNPRListBox() |
|
54 { |
|
55 delete iListBox; |
|
56 iListBox = NULL; |
|
57 } |
|
58 |
|
59 /** |
|
60 * Construct the control (first phase). |
|
61 * Creates an instance and initializes it. |
|
62 * Instance is not left on cleanup stack. |
|
63 * @param aRect bounding rectangle |
|
64 * @param aParent owning parent, or NULL |
|
65 * @param aCommandObserver command observer |
|
66 * @return initialized instance of CNPRListBox |
|
67 */ |
|
68 CNPRListBox* CNPRListBox::NewL(const TRect& aRect, const CCoeControl* aParent, MEikCommandObserver* aCommandObserver ) |
|
69 { |
|
70 CNPRListBox* self = CNPRListBox::NewLC(aRect, aParent, aCommandObserver); |
|
71 CleanupStack::Pop( self ); |
|
72 return self; |
|
73 } |
|
74 |
|
75 /** |
|
76 * Construct the control (first phase). |
|
77 * Creates an instance and initializes it. |
|
78 * Instance is left on cleanup stack. |
|
79 * @param aRect The rectangle for this window |
|
80 * @param aParent owning parent, or NULL |
|
81 * @param aCommandObserver command observer |
|
82 * @return new instance of CNPRListBox |
|
83 */ |
|
84 CNPRListBox* CNPRListBox::NewLC(const TRect& aRect, const CCoeControl* aParent, MEikCommandObserver* aCommandObserver) |
|
85 { |
|
86 CNPRListBox* self = new (ELeave) CNPRListBox(); |
|
87 CleanupStack::PushL(self); |
|
88 self->ConstructL(aRect, aParent, aCommandObserver); |
|
89 return self; |
|
90 } |
|
91 |
|
92 /** |
|
93 * Construct the control (second phase). |
|
94 * Creates a window to contain the controls and activates it. |
|
95 * @param aRect bounding rectangle |
|
96 * @param aCommandObserver command observer |
|
97 * @param aParent owning parent, or NULL |
|
98 */ |
|
99 void CNPRListBox::ConstructL(const TRect& aRect, const CCoeControl* aParent, MEikCommandObserver* aCommandObserver) |
|
100 { |
|
101 if ( aParent == NULL ) |
|
102 { |
|
103 CreateWindowL(); |
|
104 } |
|
105 else |
|
106 { |
|
107 SetContainerWindowL( *aParent ); |
|
108 } |
|
109 iFocusControl = NULL; |
|
110 iCommandObserver = aCommandObserver; |
|
111 InitializeControlsL(); |
|
112 SetRect( aRect ); |
|
113 ActivateL(); |
|
114 } |
|
115 |
|
116 /** |
|
117 * Return the number of controls in the container (override) |
|
118 * @return count |
|
119 */ |
|
120 TInt CNPRListBox::CountComponentControls() const |
|
121 { |
|
122 return ( int ) ELastControl; |
|
123 } |
|
124 |
|
125 /** |
|
126 * Get the control with the given index (override) |
|
127 * @param aIndex Control index [0...n) (limited by #CountComponentControls) |
|
128 * @return Pointer to control |
|
129 */ |
|
130 CCoeControl* CNPRListBox::ComponentControl( TInt aIndex ) const |
|
131 { |
|
132 switch ( aIndex ) |
|
133 { |
|
134 case EListBox: |
|
135 return iListBox; |
|
136 } |
|
137 return NULL; |
|
138 } |
|
139 |
|
140 /** |
|
141 * Handle resizing of the container. This implementation will lay out |
|
142 * full-sized controls like list boxes for any screen size, and will layout |
|
143 * labels, editors, etc. to the size they were given in the UI designer. |
|
144 * This code will need to be modified to adjust arbitrary controls to |
|
145 * any screen size. |
|
146 */ |
|
147 void CNPRListBox::SizeChanged() |
|
148 { |
|
149 CCoeControl::SizeChanged(); |
|
150 LayoutControls(); |
|
151 } |
|
152 |
|
153 /** |
|
154 * Layout components as specified in the UI Designer |
|
155 */ |
|
156 void CNPRListBox::LayoutControls() |
|
157 { |
|
158 iListBox->SetExtent( TPoint( 0, 0 ), iListBox->MinimumSize() ); |
|
159 } |
|
160 |
|
161 /** |
|
162 * Handle key events. |
|
163 */ |
|
164 TKeyResponse CNPRListBox::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType) |
|
165 { |
|
166 if ( aKeyEvent.iCode == EKeyLeftArrow |
|
167 || aKeyEvent.iCode == EKeyRightArrow ) |
|
168 { |
|
169 return EKeyWasNotConsumed; |
|
170 } |
|
171 |
|
172 if ( aKeyEvent.iCode == EKeyDevice3) |
|
173 { |
|
174 TInt index = CurrentItemIndex(); |
|
175 switch(index) |
|
176 { |
|
177 case ENews: |
|
178 { |
|
179 SendNewsQueryL(); |
|
180 break; |
|
181 } |
|
182 case EStations: |
|
183 { |
|
184 static_cast<CNPRAppUi*>(CEikonEnv::Static()->EikAppUi())->ActivateLocalViewL(TUid::Uid(ENPRSearchStationListBoxViewId)); |
|
185 break; |
|
186 } |
|
187 case EPrograms: |
|
188 case EPlaylist: |
|
189 case ESettings: |
|
190 break; |
|
191 default: |
|
192 break; |
|
193 } |
|
194 } |
|
195 |
|
196 if ( iFocusControl != NULL |
|
197 && iFocusControl->OfferKeyEventL( aKeyEvent, aType ) == EKeyWasConsumed ) |
|
198 { |
|
199 return EKeyWasConsumed; |
|
200 } |
|
201 return CCoeControl::OfferKeyEventL( aKeyEvent, aType ); |
|
202 } |
|
203 |
|
204 /** |
|
205 * Initialize each control upon creation. |
|
206 */ |
|
207 void CNPRListBox::InitializeControlsL() |
|
208 { |
|
209 iListBox = new ( ELeave ) CAknSingleLargeStyleListBox; |
|
210 iListBox->SetContainerWindowL( *this ); |
|
211 TResourceReader reader; |
|
212 iEikonEnv->CreateResourceReaderLC( reader, R_NPRLIST_BOX_LIST_BOX ); |
|
213 iListBox->ConstructFromResourceL( reader ); |
|
214 CleanupStack::PopAndDestroy(); // reader internal state |
|
215 |
|
216 // the listbox owns the items in the list and will free them |
|
217 iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray ); |
|
218 |
|
219 // setup the icon array so graphics-style boxes work |
|
220 SetupListBoxIconsL(); |
|
221 |
|
222 // add list items |
|
223 AddListBoxResourceArrayItemL( R_NPRLIST_BOX_LISTBOX_ITEM1, |
|
224 EListBoxNpr_0xeeb0e481Qgn_menu_nprIndex ); |
|
225 AddListBoxResourceArrayItemL( R_NPRLIST_BOX_LISTBOX_ITEM2, |
|
226 EListBoxNpr_0xeeb0e481Qgn_menu_nprIndex ); |
|
227 AddListBoxResourceArrayItemL( R_NPRLIST_BOX_LISTBOX_ITEM3, |
|
228 EListBoxNpr_0xeeb0e481Qgn_menu_nprIndex ); |
|
229 AddListBoxResourceArrayItemL( R_NPRLIST_BOX_LISTBOX_ITEM4, |
|
230 EListBoxNpr_0xeeb0e481Qgn_menu_nprIndex ); |
|
231 AddListBoxResourceArrayItemL( R_NPRLIST_BOX_LISTBOX_ITEM5, |
|
232 EListBoxNpr_0xeeb0e481Qgn_menu_nprIndex ); |
|
233 |
|
234 iListBox->SetFocus( ETrue ); |
|
235 iFocusControl = iListBox; |
|
236 } |
|
237 |
|
238 /** |
|
239 * Handle global resource changes, such as scalable UI or skin events (override) |
|
240 */ |
|
241 void CNPRListBox::HandleResourceChange( TInt aType ) |
|
242 { |
|
243 CCoeControl::HandleResourceChange( aType ); |
|
244 SetRect( iAvkonViewAppUi->View( TUid::Uid( ENPRListBoxViewId ) )->ClientRect() ); |
|
245 } |
|
246 |
|
247 /** |
|
248 * Draw container contents. |
|
249 */ |
|
250 void CNPRListBox::Draw(const TRect& aRect) const |
|
251 { |
|
252 CWindowGc& gc = SystemGc(); |
|
253 gc.Clear( aRect ); |
|
254 } |
|
255 |
|
256 /** |
|
257 * Add a list box item to a list. |
|
258 */ |
|
259 void CNPRListBox::AddListBoxItemL( |
|
260 CEikTextListBox* aListBox, |
|
261 const TDesC& aString ) |
|
262 { |
|
263 CTextListBoxModel* model = aListBox->Model(); |
|
264 CDesCArray* itemArray = static_cast< CDesCArray* > ( model->ItemTextArray() ); |
|
265 itemArray->AppendL( aString ); |
|
266 aListBox->HandleItemAdditionL(); |
|
267 } |
|
268 |
|
269 /** |
|
270 * Get the array of selected item indices, with respect to the list model. |
|
271 * The array is sorted in ascending order. |
|
272 * The array should be destroyed with two calls to CleanupStack::PopAndDestroy(), |
|
273 * the first with no argument (referring to the internal resource) and the |
|
274 * second with the array pointer. |
|
275 * @return newly allocated array, which is left on the cleanup stack; |
|
276 * or NULL for empty list. |
|
277 */ |
|
278 RArray< TInt >* CNPRListBox::GetSelectedListBoxItemsLC( CEikTextListBox* aListBox ) |
|
279 { |
|
280 CAknFilteredTextListBoxModel* model = |
|
281 static_cast< CAknFilteredTextListBoxModel *> ( aListBox->Model() ); |
|
282 if ( model->NumberOfItems() == 0 ) |
|
283 return NULL; |
|
284 |
|
285 // get currently selected indices |
|
286 const CListBoxView::CSelectionIndexArray* selectionIndexes = |
|
287 aListBox->SelectionIndexes(); |
|
288 TInt selectedIndexesCount = selectionIndexes->Count(); |
|
289 if ( selectedIndexesCount == 0 ) |
|
290 return NULL; |
|
291 |
|
292 // copy the indices and sort numerically |
|
293 RArray<TInt>* orderedSelectedIndices = |
|
294 new (ELeave) RArray< TInt >( selectedIndexesCount ); |
|
295 |
|
296 // push the allocated array |
|
297 CleanupStack::PushL( orderedSelectedIndices ); |
|
298 |
|
299 // dispose the array resource |
|
300 CleanupClosePushL( *orderedSelectedIndices ); |
|
301 |
|
302 // see if the search field is enabled |
|
303 CAknListBoxFilterItems* filter = model->Filter(); |
|
304 if ( filter != NULL ) |
|
305 { |
|
306 // when filtering enabled, translate indices back to underlying model |
|
307 for ( TInt idx = 0; idx < selectedIndexesCount; idx++ ) |
|
308 { |
|
309 TInt filteredItem = ( *selectionIndexes ) [ idx ]; |
|
310 TInt actualItem = filter->FilteredItemIndex ( filteredItem ); |
|
311 orderedSelectedIndices->InsertInOrder( actualItem ); |
|
312 } |
|
313 } |
|
314 else |
|
315 { |
|
316 // the selection indices refer directly to the model |
|
317 for ( TInt idx = 0; idx < selectedIndexesCount; idx++ ) |
|
318 orderedSelectedIndices->InsertInOrder( ( *selectionIndexes ) [ idx ] ); |
|
319 } |
|
320 |
|
321 return orderedSelectedIndices; |
|
322 } |
|
323 |
|
324 /** |
|
325 * Delete the selected item or items from the list box. |
|
326 */ |
|
327 void CNPRListBox::DeleteSelectedListBoxItemsL( CEikTextListBox* aListBox ) |
|
328 { |
|
329 CAknFilteredTextListBoxModel* model = |
|
330 static_cast< CAknFilteredTextListBoxModel *> ( aListBox->Model() ); |
|
331 if ( model->NumberOfItems() == 0 ) |
|
332 return; |
|
333 |
|
334 RArray< TInt >* orderedSelectedIndices = GetSelectedListBoxItemsLC( aListBox ); |
|
335 if ( !orderedSelectedIndices ) |
|
336 return; |
|
337 |
|
338 // Delete selected items from bottom up so indices don't change on us |
|
339 CDesCArray* itemArray = static_cast< CDesCArray* > ( model->ItemTextArray() ); |
|
340 TInt currentItem = 0; |
|
341 |
|
342 for ( TInt idx = orderedSelectedIndices->Count(); idx-- > 0; ) |
|
343 { |
|
344 currentItem = ( *orderedSelectedIndices )[ idx ]; |
|
345 itemArray->Delete ( currentItem ); |
|
346 } |
|
347 |
|
348 // dispose the array resources |
|
349 CleanupStack::PopAndDestroy(); |
|
350 |
|
351 // dispose the array pointer |
|
352 CleanupStack::PopAndDestroy( orderedSelectedIndices ); |
|
353 |
|
354 // refresh listbox's cursor now that items are deleted |
|
355 AknListBoxUtils::HandleItemRemovalAndPositionHighlightL( |
|
356 aListBox, currentItem, ETrue ); |
|
357 } |
|
358 |
|
359 /** |
|
360 * Get the listbox. |
|
361 */ |
|
362 CAknSingleLargeStyleListBox* CNPRListBox::ListBox() |
|
363 { |
|
364 return iListBox; |
|
365 } |
|
366 |
|
367 /** |
|
368 * Create a list box item with the given column values. |
|
369 */ |
|
370 void CNPRListBox::CreateListBoxItemL( TDes& aBuffer, |
|
371 TInt aIconIndex, |
|
372 const TDesC& aMainText ) |
|
373 { |
|
374 aBuffer.Format( KStringHeader(), aIconIndex, &aMainText ); |
|
375 } |
|
376 |
|
377 /** |
|
378 * Add an item to the list by reading the text items from the array resource |
|
379 * and setting a single image property (if available) from an index |
|
380 * in the list box's icon array. |
|
381 * @param aResourceId id of an ARRAY resource containing the textual |
|
382 * items in the columns |
|
383 * @param aIconIndex the index in the icon array, or -1 |
|
384 */ |
|
385 void CNPRListBox::AddListBoxResourceArrayItemL( TInt aResourceId, TInt aIconIndex ) |
|
386 { |
|
387 CDesCArray* array = iCoeEnv->ReadDesCArrayResourceL( aResourceId ); |
|
388 CleanupStack::PushL( array ); |
|
389 // This is intended to be large enough, but if you get |
|
390 // a USER 11 panic, consider reducing string sizes. |
|
391 TBuf<512> listString; |
|
392 CreateListBoxItemL( listString, aIconIndex, ( *array ) [ 0 ] ); |
|
393 AddListBoxItemL( iListBox, listString ); |
|
394 CleanupStack::PopAndDestroy( array ); |
|
395 } |
|
396 |
|
397 /** |
|
398 * Set up the list's icon array. |
|
399 */ |
|
400 void CNPRListBox::SetupListBoxIconsL() |
|
401 { |
|
402 /* |
|
403 CArrayPtr< CGulIcon >* icons = NULL; |
|
404 icons = new (ELeave) CAknIconArray( 1 ); |
|
405 CleanupStack::PushL( icons ); |
|
406 CGulIcon* icon; |
|
407 // for EListBoxNpr_0xeeb0e481Qgn_menu_nprIndex |
|
408 icon = LoadAndScaleIconL( |
|
409 KNPR_0xEEB0E481File, EMbmNpr_0xeeb0e481Qgn_menu_npr, -1, |
|
410 NULL, EAspectRatioPreserved ); |
|
411 CleanupStack::PushL( icon ); |
|
412 icons->AppendL( icon ); |
|
413 CleanupStack::Pop( icon ); |
|
414 CleanupStack::Pop( icons ); |
|
415 |
|
416 if ( icons != NULL ) |
|
417 { |
|
418 iListBox->ItemDrawer()->ColumnData()->SetIconArray( icons ); |
|
419 } |
|
420 */ |
|
421 } |
|
422 |
|
423 /** |
|
424 * Handle commands relating to markable lists. |
|
425 */ |
|
426 TBool CNPRListBox::HandleMarkableListCommandL(TInt /*aCommand*/) |
|
427 { |
|
428 return EFalse; |
|
429 } |
|
430 |
|
431 /** |
|
432 * This routine loads and scales a bitmap or icon. |
|
433 * |
|
434 * @param aFileName the MBM or MIF filename |
|
435 * @param aBitmapId the bitmap id |
|
436 * @param aMaskId the mask id or -1 for none |
|
437 * @param aSize the TSize for the icon, or NULL to use real size |
|
438 * @param aScaleMode one of the EAspectRatio* enums when scaling |
|
439 * |
|
440 */ |
|
441 CGulIcon* CNPRListBox::LoadAndScaleIconL( |
|
442 const TDesC& aFileName, |
|
443 TInt aBitmapId, |
|
444 TInt aMaskId, |
|
445 TSize* aSize, |
|
446 TScaleMode aScaleMode ) |
|
447 { |
|
448 CFbsBitmap* bitmap; |
|
449 CFbsBitmap* mask; |
|
450 AknIconUtils::CreateIconL( bitmap, mask, aFileName, aBitmapId, aMaskId ); |
|
451 |
|
452 TSize size; |
|
453 if ( aSize == NULL ) |
|
454 { |
|
455 // Use size from the image header. In case of SVG, |
|
456 // we preserve the image data for a while longer, since ordinarily |
|
457 // it is disposed at the first GetContentDimensions() or SetSize() call. |
|
458 AknIconUtils::PreserveIconData( bitmap ); |
|
459 AknIconUtils::GetContentDimensions( bitmap, size ); |
|
460 } |
|
461 else |
|
462 { |
|
463 size = *aSize; |
|
464 } |
|
465 |
|
466 AknIconUtils::SetSize( bitmap, size, aScaleMode ); |
|
467 AknIconUtils::SetSize( mask, size, aScaleMode ); |
|
468 |
|
469 if ( aSize == NULL ) |
|
470 { |
|
471 AknIconUtils::DestroyIconData( bitmap ); |
|
472 } |
|
473 |
|
474 return CGulIcon::NewL( bitmap, mask ); |
|
475 } |
|
476 |
|
477 TInt CNPRListBox::CurrentItemIndex() |
|
478 { |
|
479 return iListBox->CurrentItemIndex(); |
|
480 } |
|
481 |
|
482 void CNPRListBox::SendNewsQueryL() |
|
483 { |
|
484 static_cast<CNPRAppUi*>(CEikonEnv::Static()->EikAppUi())->Engine().SendNPRCommandL(ENewsCmd, KNullDesC()); |
|
485 } |