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