|
1 /* |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Definition of the class CESMRNcsPopupListBox |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "emailtrace.h" |
|
19 #include "cesmrncspopuplistbox.h" |
|
20 |
|
21 #include <eikclbd.h> |
|
22 #include <AknsLayeredBackgroundControlContext.h> |
|
23 #include <StringLoader.h> // StringLoader |
|
24 #include <ct/rcpointerarray.h> |
|
25 |
|
26 //text truncation |
|
27 #include <AknBidiTextUtils.h>//line wrapping and mirroring |
|
28 #include <aknlayoutscalable_apps.cdl.h> //xml layout data for applications |
|
29 #include <aknlayoutscalable_avkon.cdl.h> //xml layout data of avkon components |
|
30 |
|
31 #include <esmrgui.rsg> |
|
32 |
|
33 #include "cesmrncsemailaddressobject.h" |
|
34 #include "cesmrcontacthandler.h" |
|
35 #include "cesmrlayoutmgr.h" |
|
36 |
|
37 namespace { // codescanner::namespace |
|
38 const TInt KItemExtraHeight = 8; |
|
39 const TInt KEdge (8); |
|
40 const TInt KScrollbarWidth (6); |
|
41 const TInt KListBoxDrawMargin (4); |
|
42 //drop down list colors since we have no official LAF |
|
43 #define KWhite TRgb( 255,255,255 ) |
|
44 #define KGraySelectable TRgb( 30,30,30 ) |
|
45 #define KGrayNoEmail TRgb( 215,215,215 ) |
|
46 #define KGrayBackground TRgb( 140,140,140 ) |
|
47 #define KSelectorFallbackColor TRgb( 0,200,200 ) |
|
48 } |
|
49 |
|
50 // ======== MEMBER FUNCTIONS ======== |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CESMRNcsPopupListBox::NewL |
|
54 // ----------------------------------------------------------------------------- |
|
55 // |
|
56 CESMRNcsPopupListBox* CESMRNcsPopupListBox::NewL( const CCoeControl* aParent, |
|
57 CESMRContactHandler& aContactHandler ) |
|
58 { |
|
59 FUNC_LOG; |
|
60 CESMRNcsPopupListBox* self = new (ELeave) CESMRNcsPopupListBox( aContactHandler ); |
|
61 CleanupStack::PushL(self); |
|
62 self->ConstructL( aParent ); |
|
63 CleanupStack::Pop( self ); |
|
64 return self; |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CESMRNcsPopupListBox::CESMRNcsPopupListBox |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 CESMRNcsPopupListBox::CESMRNcsPopupListBox( CESMRContactHandler& aContactHandler ) |
|
72 : |
|
73 iContactHandler( aContactHandler ) |
|
74 { |
|
75 FUNC_LOG; |
|
76 //do nothing |
|
77 } |
|
78 |
|
79 // ----------------------------------------------------------------------------- |
|
80 // CESMRNcsPopupListBox::ConstructL |
|
81 // ----------------------------------------------------------------------------- |
|
82 // |
|
83 void CESMRNcsPopupListBox::ConstructL( const CCoeControl* aParent ) |
|
84 { |
|
85 FUNC_LOG; |
|
86 CEikTextListBox::ConstructL( aParent, CEikListBox::EPopout ); |
|
87 |
|
88 CEikTextListBox::SetBorder( TGulBorder::EWithOutline| |
|
89 TGulBorder::EAddTwoPixels| |
|
90 TGulBorder::EAddOneRoundingPixel ); |
|
91 |
|
92 CreateScrollBarFrameL(); |
|
93 |
|
94 const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont ); |
|
95 CEikTextListBox::SetItemHeightL( font->HeightInPixels() + KItemExtraHeight ); |
|
96 |
|
97 iBaseBackroundContext = CAknsBasicBackgroundControlContext::NewL( |
|
98 KAknsIIDQgnFsGrafEmailContent, |
|
99 Rect(), |
|
100 EFalse ); |
|
101 } |
|
102 |
|
103 // ----------------------------------------------------------------------------- |
|
104 // CESMRNcsPopupListBox::InitAndSearchL |
|
105 // ----------------------------------------------------------------------------- |
|
106 // |
|
107 void CESMRNcsPopupListBox::InitAndSearchL( const TDesC& aText ) |
|
108 { |
|
109 FUNC_LOG; |
|
110 RCPointerArray<CESMRClsItem> matchingArray; // Empty array |
|
111 CleanupClosePushL( matchingArray ); |
|
112 SetSearchTextL( aText ); |
|
113 OperationCompleteL( ESearchContacts, &matchingArray ); |
|
114 CleanupStack::PopAndDestroy( &matchingArray ); |
|
115 } |
|
116 |
|
117 // --------------------------------------------------------------------------- |
|
118 // CESMRNcsPopupListBox::~CESMRNcsPopupListBox |
|
119 // --------------------------------------------------------------------------- |
|
120 // |
|
121 CESMRNcsPopupListBox::~CESMRNcsPopupListBox() |
|
122 { |
|
123 FUNC_LOG; |
|
124 delete iBaseBackroundContext; |
|
125 iMatchingArray.ResetAndDestroy(); |
|
126 |
|
127 delete iItemTextsArray; |
|
128 delete iCurrentSearchText; |
|
129 } |
|
130 |
|
131 // ----------------------------------------------------------------------------- |
|
132 // CESMRNcsPopupListBox::CreateItemDrawerL |
|
133 // ----------------------------------------------------------------------------- |
|
134 // |
|
135 void CESMRNcsPopupListBox::CreateItemDrawerL() |
|
136 { |
|
137 FUNC_LOG; |
|
138 CESMRNcsListItemDrawer* drawer = new (ELeave) CESMRNcsListItemDrawer( *this ); |
|
139 iItemDrawer = drawer; |
|
140 } |
|
141 |
|
142 // ----------------------------------------------------------------------------- |
|
143 // CESMRNcsPopupListBox::MopSupplyObject |
|
144 // ----------------------------------------------------------------------------- |
|
145 // |
|
146 TTypeUid::Ptr CESMRNcsPopupListBox::MopSupplyObject(TTypeUid aId) |
|
147 { |
|
148 FUNC_LOG; |
|
149 if ( aId.iUid == MAknsControlContext::ETypeId ) |
|
150 { |
|
151 return MAknsControlContext::SupplyMopObject( aId, iBaseBackroundContext ); |
|
152 } |
|
153 return CCoeControl::MopSupplyObject( aId ); |
|
154 } |
|
155 |
|
156 // ----------------------------------------------------------------------------- |
|
157 // CESMRNcsPopupListBox::SizeChanged |
|
158 // ----------------------------------------------------------------------------- |
|
159 // |
|
160 void CESMRNcsPopupListBox::SizeChanged() |
|
161 { |
|
162 FUNC_LOG; |
|
163 CEikTextListBox::SizeChanged(); |
|
164 iBaseBackroundContext->SetRect( Rect() ); |
|
165 } |
|
166 |
|
167 // ----------------------------------------------------------------------------- |
|
168 // CNcsPopupListBox::OfferKeyEventL |
|
169 // ----------------------------------------------------------------------------- |
|
170 // |
|
171 TKeyResponse CESMRNcsPopupListBox::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType ) |
|
172 { |
|
173 FUNC_LOG; |
|
174 TKeyResponse ret( EKeyWasNotConsumed ); |
|
175 if( aKeyEvent.iCode == EKeyDownArrow ) |
|
176 { |
|
177 MoveRemoteLookupItemL( ERemoteLookupItemDown ); |
|
178 iView->MoveCursorL( CListBoxView::ECursorNextItem, CListBoxView::ENoSelection ); |
|
179 ret = EKeyWasConsumed; |
|
180 } |
|
181 else if( aKeyEvent.iCode == EKeyUpArrow ) |
|
182 { |
|
183 TBool stay = EFalse; |
|
184 // Move cursor separator line over |
|
185 if( CurrentItemIndex() - 1 > 0 && CurrentItemIndex() - 1 == iRMLUItemPosition ) |
|
186 { |
|
187 MoveRemoteLookupItemL( ERemoteLookupItemUp ); |
|
188 iView->MoveCursorL( CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection ); |
|
189 stay = ETrue; |
|
190 } |
|
191 |
|
192 MoveRemoteLookupItemL( ERemoteLookupItemUp ); |
|
193 iView->MoveCursorL( CListBoxView::ECursorPreviousItem, CListBoxView::ENoSelection ); |
|
194 if( stay ) |
|
195 { |
|
196 MoveRemoteLookupItemL( ERemoteLookupItemDown ); |
|
197 |
|
198 iView->MoveCursorL( CListBoxView::ECursorNextItem, CListBoxView::ENoSelection ); |
|
199 } |
|
200 |
|
201 |
|
202 ret = EKeyWasConsumed; |
|
203 } |
|
204 |
|
205 if( ret == EKeyWasNotConsumed ) |
|
206 { |
|
207 ret = CEikListBox::OfferKeyEventL( aKeyEvent, aType ); |
|
208 } |
|
209 // call HandleItemAdditionL just in case. There might be changes on remote lookup item place. |
|
210 // The call is here, because we don't want to have extra redraw events when the popuplist |
|
211 // is not fully updated. |
|
212 HandleItemAdditionL(); |
|
213 return ret; |
|
214 } |
|
215 |
|
216 // --------------------------------------------------------------------------- |
|
217 // CESMRNcsPopupListBox::OperationCompleteL |
|
218 // --------------------------------------------------------------------------- |
|
219 // |
|
220 void CESMRNcsPopupListBox::OperationCompleteL( |
|
221 TContactHandlerCmd /*aCmd*/, |
|
222 const RPointerArray<CESMRClsItem>* aMatchingItems ) |
|
223 { |
|
224 FUNC_LOG; |
|
225 if ( aMatchingItems ) |
|
226 { |
|
227 iMatchingArray.ResetAndDestroy(); |
|
228 // Replace old matcing items. |
|
229 |
|
230 for ( TInt ii = 0; ii < aMatchingItems->Count(); ++ii ) |
|
231 { |
|
232 if ( (*aMatchingItems)[ii] ) |
|
233 { |
|
234 CESMRClsItem* item = (*aMatchingItems)[ii]->CloneLC(); |
|
235 iMatchingArray.AppendL( item ); |
|
236 CleanupStack::Pop( item ); |
|
237 } |
|
238 } |
|
239 SetListItemsFromArrayL(); |
|
240 } |
|
241 } |
|
242 |
|
243 // --------------------------------------------------------------------------- |
|
244 // CESMRNcsPopupListBox::OperationErrorL |
|
245 // --------------------------------------------------------------------------- |
|
246 // |
|
247 void CESMRNcsPopupListBox::OperationErrorL( TContactHandlerCmd /*aCmd*/, |
|
248 TInt /*aError*/ ) |
|
249 { |
|
250 FUNC_LOG; |
|
251 //no errors handled here |
|
252 } |
|
253 |
|
254 // ----------------------------------------------------------------------------- |
|
255 // CESMRNcsPopupListBox::SetSearchTextL |
|
256 // ----------------------------------------------------------------------------- |
|
257 // |
|
258 void CESMRNcsPopupListBox::SetSearchTextL( const TDesC& aText ) |
|
259 { |
|
260 FUNC_LOG; |
|
261 delete iCurrentSearchText; |
|
262 iCurrentSearchText = NULL; // to remove code scanner warning |
|
263 iCurrentSearchText = aText.AllocL(); |
|
264 iContactHandler.SearchMatchesL( aText, this ); |
|
265 |
|
266 if(!iRemoteLookupSupported) |
|
267 { |
|
268 iRemoteLookupSupported = iContactHandler.RemoteLookupSupportedL(); |
|
269 } |
|
270 } |
|
271 |
|
272 // ----------------------------------------------------------------------------- |
|
273 // CESMRNcsPopupListBox::ReturnCurrentEmailAddressLC |
|
274 // ----------------------------------------------------------------------------- |
|
275 // |
|
276 CESMRNcsEmailAddressObject* CESMRNcsPopupListBox::ReturnCurrentEmailAddressLC() |
|
277 { |
|
278 FUNC_LOG; |
|
279 CESMRNcsEmailAddressObject* addressObject = NULL; |
|
280 |
|
281 if( iMatchingArray.Count() > 0 ) |
|
282 { |
|
283 CESMRClsItem* clsItem = NULL; |
|
284 if( iRemoteLookupSupported ) |
|
285 { |
|
286 clsItem =iMatchingArray[CurrentItemIndex()-1]; // -1 because of iRMLUItemPosition |
|
287 } |
|
288 else |
|
289 { |
|
290 clsItem =iMatchingArray[CurrentItemIndex()]; // no iRMLUItemPosition |
|
291 } |
|
292 addressObject= CESMRNcsEmailAddressObject::NewL( clsItem->DisplayName(), clsItem->EmailAddress() ); |
|
293 CleanupStack::PushL( addressObject ); |
|
294 if ( clsItem->MultipleEmails() ) |
|
295 { |
|
296 addressObject->SetDisplayFull( ETrue ); |
|
297 } |
|
298 } |
|
299 |
|
300 return addressObject; |
|
301 } |
|
302 |
|
303 // ----------------------------------------------------------------------------- |
|
304 // CESMRNcsPopupListBox::SetPopupMaxRectL |
|
305 // ----------------------------------------------------------------------------- |
|
306 // |
|
307 void CESMRNcsPopupListBox::SetPopupMaxRectL( const TRect& aPopupMaxRect ) |
|
308 { |
|
309 FUNC_LOG; |
|
310 iPopupMaxRect = aPopupMaxRect; |
|
311 SetPopupHeightL(); |
|
312 } |
|
313 |
|
314 // ----------------------------------------------------------------------------- |
|
315 // CESMRNcsPopupListBox::IsPopupEmpty |
|
316 // ----------------------------------------------------------------------------- |
|
317 // |
|
318 TBool CESMRNcsPopupListBox::IsPopupEmpty() const |
|
319 { |
|
320 FUNC_LOG; |
|
321 if( Model()->NumberOfItems() > 0 ) |
|
322 { |
|
323 return EFalse; |
|
324 } |
|
325 |
|
326 return ETrue; |
|
327 } |
|
328 |
|
329 // ----------------------------------------------------------------------------- |
|
330 // CESMRNcsPopupListBox::IsRemoteLookupItemSelected |
|
331 // ----------------------------------------------------------------------------- |
|
332 // |
|
333 TBool CESMRNcsPopupListBox::IsRemoteLookupItemSelected() const |
|
334 { |
|
335 FUNC_LOG; |
|
336 if( CurrentItemIndex() == iRMLUItemPosition && iRemoteLookupSupported ) |
|
337 { |
|
338 return ETrue; |
|
339 } |
|
340 |
|
341 return EFalse; |
|
342 } |
|
343 |
|
344 // ----------------------------------------------------------------------------- |
|
345 // CESMRNcsPopupListBox::CurrentPopupClsItemsArray |
|
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 const RPointerArray<CESMRClsItem>& CESMRNcsPopupListBox::CurrentPopupClsItemsArray() const |
|
349 { |
|
350 return iMatchingArray; |
|
351 } |
|
352 |
|
353 // ----------------------------------------------------------------------------- |
|
354 // CESMRNcsPopupListBox::RMLUItemPosition |
|
355 // ----------------------------------------------------------------------------- |
|
356 // |
|
357 TInt CESMRNcsPopupListBox::RMLUItemPosition() const |
|
358 { |
|
359 FUNC_LOG; |
|
360 return iRMLUItemPosition; |
|
361 } |
|
362 |
|
363 // ----------------------------------------------------------------------------- |
|
364 // CESMRNcsPopupListBox::SetListItemsFromArrayL |
|
365 // ----------------------------------------------------------------------------- |
|
366 // |
|
367 void CESMRNcsPopupListBox::SetListItemsFromArrayL() |
|
368 { |
|
369 FUNC_LOG; |
|
370 // Create totally new text array |
|
371 Reset(); |
|
372 CreateTextArrayAndSetToTheListboxL(); |
|
373 |
|
374 // append texts to text array |
|
375 for( TInt i=0; i < iMatchingArray.Count(); i++ ) |
|
376 { |
|
377 iItemTextsArray->AppendL( iMatchingArray[i]->FullTextL() ); |
|
378 } |
|
379 |
|
380 // Update rmlu item |
|
381 SetRemoteLookupItemFirstToTheListL(); |
|
382 |
|
383 HandleItemAdditionL(); |
|
384 |
|
385 if( iItemTextsArray && iItemTextsArray->Count() > 0 ) |
|
386 { |
|
387 SetCurrentItemIndex( 0 ); |
|
388 } |
|
389 |
|
390 if ( Observer() ) |
|
391 { |
|
392 Observer()->HandleControlEventL( this, |
|
393 MCoeControlObserver::EEventStateChanged ); |
|
394 } |
|
395 |
|
396 if( IsVisible() ) |
|
397 { |
|
398 SetPopupHeightL(); |
|
399 DrawDeferred(); |
|
400 } |
|
401 } |
|
402 |
|
403 // ----------------------------------------------------------------------------- |
|
404 // CESMRNcsPopupListBox::SetPopupHeightL |
|
405 // ----------------------------------------------------------------------------- |
|
406 // |
|
407 void CESMRNcsPopupListBox::SetPopupHeightL() |
|
408 { |
|
409 FUNC_LOG; |
|
410 TInt totalHeight = CalcHeightBasedOnNumOfItems( Model()->NumberOfItems() ); |
|
411 TRect rect = iPopupMaxRect; |
|
412 |
|
413 ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn ); |
|
414 |
|
415 //shrink listbox if less than max area needed to show items |
|
416 if( rect.Height() >= totalHeight ) |
|
417 { |
|
418 ScrollBarFrame()->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOff ); |
|
419 |
|
420 //latch listbox on top of the editorfield |
|
421 TRect fieldArea = Parent()->Rect(); |
|
422 |
|
423 if ( rect.iBr.iY < fieldArea.iBr.iY ) |
|
424 { |
|
425 rect.Move(0, (rect.Height() - totalHeight) ); |
|
426 } |
|
427 |
|
428 rect.SetHeight( totalHeight ); |
|
429 } |
|
430 |
|
431 UpdateScrollBarsL(); |
|
432 SetRect( rect ); |
|
433 } |
|
434 |
|
435 // ----------------------------------------------------------------------------- |
|
436 // CESMRNcsPopupListBox::SetRemoteLookupItemFirstToTheListL |
|
437 // ----------------------------------------------------------------------------- |
|
438 // |
|
439 void CESMRNcsPopupListBox::SetRemoteLookupItemFirstToTheListL() |
|
440 { |
|
441 FUNC_LOG; |
|
442 if( iRemoteLookupSupported ) |
|
443 { |
|
444 HBufC* rmluText = StringLoader::LoadLC( R_MEET_REQ_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText ); |
|
445 |
|
446 iItemTextsArray->InsertL( 0, *rmluText ); |
|
447 CleanupStack::PopAndDestroy( rmluText ); |
|
448 iRMLUItemPosition = 0; |
|
449 } |
|
450 else |
|
451 { |
|
452 iRMLUItemPosition = -1; |
|
453 } |
|
454 } |
|
455 |
|
456 // ----------------------------------------------------------------------------- |
|
457 // CESMRNcsPopupListBox::MoveRemoteLookupItemL |
|
458 // ----------------------------------------------------------------------------- |
|
459 // |
|
460 void CESMRNcsPopupListBox::MoveRemoteLookupItemL( TRemoteLookupItemMoveDirection aDirection ) |
|
461 { |
|
462 FUNC_LOG; |
|
463 if( iRemoteLookupSupported ) |
|
464 { |
|
465 TInt newRMLUItemIndex = -1; |
|
466 TInt newCurrentItem = -1; |
|
467 if( aDirection == ERemoteLookupItemUp && |
|
468 iView->CurrentItemIndex() == iView->TopItemIndex() ) |
|
469 { |
|
470 newRMLUItemIndex = iRMLUItemPosition - 1; |
|
471 newCurrentItem = CurrentItemIndex() - 1; |
|
472 } |
|
473 else if( aDirection == ERemoteLookupItemDown && |
|
474 iView->CurrentItemIndex() == iView->BottomItemIndex() ) |
|
475 { |
|
476 newRMLUItemIndex = iRMLUItemPosition + 1; |
|
477 newCurrentItem = CurrentItemIndex() + 1; |
|
478 } |
|
479 |
|
480 |
|
481 if( ItemExists ( newCurrentItem ) ) |
|
482 { |
|
483 iItemTextsArray->Delete( iRMLUItemPosition ); |
|
484 |
|
485 HBufC* rmluText = StringLoader::LoadLC( R_MEET_REQ_EDITOR_ADDRESS_LIST_REMOTE_LOOKUP_SEARCH, *iCurrentSearchText ); |
|
486 |
|
487 iItemTextsArray->InsertL( newRMLUItemIndex, *rmluText ); |
|
488 CleanupStack::PopAndDestroy( rmluText ); |
|
489 iRMLUItemPosition = newRMLUItemIndex; |
|
490 } |
|
491 } |
|
492 } |
|
493 |
|
494 // ----------------------------------------------------------------------------- |
|
495 // CESMRNcsPopupListBox::CreateTextArrayAndSetToTheListboxL |
|
496 // ----------------------------------------------------------------------------- |
|
497 // |
|
498 void CESMRNcsPopupListBox::CreateTextArrayAndSetToTheListboxL() |
|
499 { |
|
500 FUNC_LOG; |
|
501 if( iItemTextsArray ) |
|
502 { |
|
503 delete iItemTextsArray; |
|
504 iItemTextsArray = NULL; |
|
505 } |
|
506 |
|
507 const TInt KItemTextArrayLen = 8; |
|
508 |
|
509 if( !iItemTextsArray ) |
|
510 { |
|
511 iItemTextsArray = new ( ELeave ) CDesCArraySeg( KItemTextArrayLen ); |
|
512 // Set the popup list data |
|
513 Model()->SetItemTextArray( iItemTextsArray ); |
|
514 Model()->SetOwnershipType( ELbmDoesNotOwnItemArray ); |
|
515 } |
|
516 } |
|
517 |
|
518 // ----------------------------------------------------------------------------- |
|
519 // CESMRNcsPopupListBox::InitialiseL |
|
520 // ----------------------------------------------------------------------------- |
|
521 // |
|
522 void CESMRNcsPopupListBox::Initialise(CESMRLayoutManager* aLayout) |
|
523 { |
|
524 FUNC_LOG; |
|
525 static_cast<CESMRNcsListItemDrawer*>( iItemDrawer )->SetLayoutManager(aLayout); |
|
526 } |
|
527 |
|
528 // ----------------------------------------------------------------------------- |
|
529 // CESMRNcsListItemDrawer::CESMRNcsListItemDrawer |
|
530 // ----------------------------------------------------------------------------- |
|
531 // |
|
532 CESMRNcsListItemDrawer::CESMRNcsListItemDrawer( CESMRNcsPopupListBox& aListBox ) |
|
533 :CListItemDrawer(), |
|
534 iListBox(aListBox) |
|
535 { |
|
536 FUNC_LOG; |
|
537 // Store a GC for later use |
|
538 iGc = &CCoeEnv::Static()->SystemGc(); |
|
539 SetGc(iGc); |
|
540 } |
|
541 |
|
542 // ----------------------------------------------------------------------------- |
|
543 // CESMRNcsListItemDrawer::DrawActualItemL |
|
544 // ----------------------------------------------------------------------------- |
|
545 // |
|
546 void CESMRNcsListItemDrawer::DrawActualItem( TInt aItemIndex, |
|
547 const TRect& aActualItemRect, TBool aItemIsCurrent, |
|
548 TBool aViewIsEmphasized, TBool aViewIsDimmed, |
|
549 TBool aItemIsSelected ) const |
|
550 { |
|
551 FUNC_LOG; |
|
552 TRAP_IGNORE( DoDrawActualItemL( aItemIndex, |
|
553 aActualItemRect, |
|
554 aItemIsCurrent, |
|
555 aViewIsEmphasized, |
|
556 aViewIsDimmed, |
|
557 aItemIsSelected ) ) |
|
558 } |
|
559 |
|
560 // ----------------------------------------------------------------------------- |
|
561 // CESMRNcsListItemDrawer::SetLayoutManager |
|
562 // ----------------------------------------------------------------------------- |
|
563 // |
|
564 void CESMRNcsListItemDrawer::SetLayoutManager(CESMRLayoutManager* aLayout) |
|
565 { |
|
566 FUNC_LOG; |
|
567 iLayout = aLayout; |
|
568 } |
|
569 |
|
570 // ----------------------------------------------------------------------------- |
|
571 // CESMRNcsListItemDrawer::DoDrawActualItemL |
|
572 // ----------------------------------------------------------------------------- |
|
573 // |
|
574 void CESMRNcsListItemDrawer::DoDrawActualItemL( TInt aItemIndex, |
|
575 const TRect& aActualItemRect, TBool aItemIsCurrent, |
|
576 TBool /*aViewIsEmphasized*/, TBool /*aViewIsDimmed*/, |
|
577 TBool /*aItemIsSelected*/ ) const |
|
578 { |
|
579 FUNC_LOG; |
|
580 // Get reference to curren popup cls item list. |
|
581 const RPointerArray<CESMRClsItem>& clsItemArray = iListBox.CurrentPopupClsItemsArray(); |
|
582 TInt rmluPosition = iListBox.RMLUItemPosition(); |
|
583 |
|
584 // Sets all the attributes, like font, text color and background color. |
|
585 const CFont* font = AknLayoutUtils::FontFromId( EAknLogicalFontPrimarySmallFont ); |
|
586 iGc->UseFont(font); |
|
587 |
|
588 // We have to draw the item in layered fashion in order to do the skin |
|
589 // First clear the backround by drawing a solid rect. |
|
590 iGc->SetPenColor( KGrayBackground ); |
|
591 iGc->SetBrushColor( KGrayBackground ); |
|
592 iGc->SetPenStyle(CGraphicsContext::ESolidPen); |
|
593 iGc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
594 |
|
595 // Now draw the highlight |
|
596 if( aItemIsCurrent ) |
|
597 { |
|
598 if (iLayout) |
|
599 { |
|
600 CFbsBitmap* selector = NULL; |
|
601 CFbsBitmap* selectorMask = NULL; |
|
602 |
|
603 // highlight bitmap target rect: |
|
604 TRect rect( aActualItemRect ); |
|
605 |
|
606 TSize corner(KEdge, KEdge); |
|
607 iLayout->GetSkinBasedBitmap( |
|
608 KAknsIIDQgnFsListCornerTl, selector, selectorMask, corner ); |
|
609 |
|
610 //adjust selector size for if scrollbar is on screen |
|
611 if (iListBox.ScrollBarFrame()->ScrollBarVisibility(CEikScrollBar::EVertical) == |
|
612 CEikScrollBarFrame::EOn) |
|
613 { |
|
614 rect.SetWidth( (rect.Width() - KScrollbarWidth) ); |
|
615 } |
|
616 |
|
617 if( selector && selectorMask) |
|
618 { |
|
619 //corner TL |
|
620 iGc->BitBltMasked( |
|
621 rect.iTl, selector, corner, selectorMask, EFalse ); |
|
622 |
|
623 //side L |
|
624 TSize side(KEdge, (rect.Height() - 2 * KEdge) ); |
|
625 iLayout->GetSkinBasedBitmap( |
|
626 KAknsIIDQgnFsListSideL, selector, selectorMask, side ); |
|
627 iGc->BitBltMasked( TPoint(rect.iTl.iX, rect.iTl.iY + KEdge), |
|
628 selector, side, selectorMask, EFalse ); |
|
629 |
|
630 //corner BL |
|
631 iLayout->GetSkinBasedBitmap( |
|
632 KAknsIIDQgnFsListCornerBl, selector, selectorMask, corner ); |
|
633 iGc->BitBltMasked( |
|
634 TPoint(rect.iTl.iX, rect.iTl.iY + KEdge + side.iHeight), |
|
635 selector, corner, selectorMask, EFalse ); |
|
636 |
|
637 //top |
|
638 TSize top( (rect.Width() - 2 * KEdge) , KEdge); |
|
639 iLayout->GetSkinBasedBitmap( |
|
640 KAknsIIDQgnFsListSideT, selector, selectorMask, top ); |
|
641 iGc->BitBltMasked( TPoint(rect.iTl.iX + KEdge, rect.iTl.iY), |
|
642 selector, top, selectorMask, EFalse ); |
|
643 |
|
644 //center |
|
645 TSize center( top.iWidth, side.iHeight); |
|
646 iLayout->GetSkinBasedBitmap( |
|
647 KAknsIIDQgnFsListCenter, selector, selectorMask, center ); |
|
648 iGc->BitBltMasked( |
|
649 TPoint(rect.iTl.iX + KEdge, rect.iTl.iY + KEdge), |
|
650 selector, center, selectorMask, EFalse ); |
|
651 |
|
652 //bottom |
|
653 iLayout->GetSkinBasedBitmap( |
|
654 KAknsIIDQgnFsListSideB, selector, selectorMask, top ); |
|
655 iGc->BitBltMasked( |
|
656 TPoint(rect.iTl.iX + KEdge, rect.iTl.iY + side.iHeight + KEdge), |
|
657 selector, top, selectorMask, EFalse ); |
|
658 |
|
659 //corner TR |
|
660 iLayout->GetSkinBasedBitmap( |
|
661 KAknsIIDQgnFsListCornerTr, selector, selectorMask, corner ); |
|
662 iGc->BitBltMasked( |
|
663 TPoint(rect.iTl.iX + KEdge + top.iWidth, rect.iTl.iY), |
|
664 selector, corner, selectorMask, EFalse ); |
|
665 |
|
666 //side R |
|
667 iLayout->GetSkinBasedBitmap( |
|
668 KAknsIIDQgnFsListSideR, selector, selectorMask, side ); |
|
669 iGc->BitBltMasked( |
|
670 TPoint(rect.iTl.iX + KEdge + top.iWidth, rect.iTl.iY + KEdge), |
|
671 selector, side, selectorMask, EFalse ); |
|
672 |
|
673 //corner Br |
|
674 iLayout->GetSkinBasedBitmap( |
|
675 KAknsIIDQgnFsListCornerBr, selector, selectorMask, corner ); |
|
676 iGc->BitBltMasked( |
|
677 TPoint(rect.iTl.iX + KEdge + top.iWidth, |
|
678 rect.iTl.iY + KEdge + side.iHeight), |
|
679 selector, corner, selectorMask, EFalse ); |
|
680 } |
|
681 else |
|
682 { |
|
683 iGc->SetBrushColor( KSelectorFallbackColor ); |
|
684 } |
|
685 |
|
686 delete selector; |
|
687 delete selectorMask; |
|
688 } |
|
689 else |
|
690 { |
|
691 iGc->SetBrushColor( KSelectorFallbackColor ); |
|
692 } |
|
693 } |
|
694 else |
|
695 { |
|
696 iGc->DrawRect(aActualItemRect); |
|
697 } |
|
698 |
|
699 if(aItemIsCurrent) |
|
700 { |
|
701 iGc->SetPenColor( KWhite ); |
|
702 } |
|
703 else |
|
704 { |
|
705 iGc->SetPenColor( KGraySelectable ); |
|
706 } |
|
707 |
|
708 iGc->SetPenStyle(CGraphicsContext::ESolidPen); |
|
709 iGc->SetBrushStyle(CGraphicsContext::ENullBrush); |
|
710 TInt topToBaseline = ( aActualItemRect.Height() - font->HeightInPixels() ) / 2 |
|
711 + font->AscentInPixels(); |
|
712 |
|
713 TPtrC itemText = iListBox.Model()->ItemText( aItemIndex ); |
|
714 |
|
715 // Construct bidirectional text object |
|
716 TBidiText* bidiText = TBidiText::NewL( itemText, 1 ); |
|
717 CleanupStack::PushL( bidiText ); |
|
718 bidiText->WrapText( aActualItemRect.Width(), *font, NULL ); |
|
719 TPoint leftBase = aActualItemRect.iTl + TPoint( 0, topToBaseline ); |
|
720 leftBase.iX += KListBoxDrawMargin; |
|
721 |
|
722 // check if we are drawing remote lookup item or contact match |
|
723 if ( rmluPosition == aItemIndex ) |
|
724 { |
|
725 iGc->SetUnderlineStyle( EUnderlineOff ); |
|
726 bidiText->DrawText( *iGc, leftBase ); |
|
727 } |
|
728 else |
|
729 { |
|
730 // if list has rmlu item change item index right |
|
731 if ( rmluPosition >= 0 ) |
|
732 { |
|
733 --aItemIndex; |
|
734 aItemIndex = Max( 0, aItemIndex ); |
|
735 } |
|
736 |
|
737 // change color to gray if match doesn't have email address. |
|
738 if ( clsItemArray[aItemIndex]->EmailAddress().Compare( KNullDesC ) == 0 ) |
|
739 { |
|
740 iGc->SetPenColor( KGrayNoEmail ); |
|
741 iGc->SetBrushColor( KGrayNoEmail ); |
|
742 } |
|
743 |
|
744 // We know the text contains RTL script if the display string is not just |
|
745 // truncated version of the original string. |
|
746 TPtrC dispText = bidiText->DisplayText(); |
|
747 TInt compLength = dispText.Length() - 1; // -1 to omit the truncation character |
|
748 TBool textContainsRtl = |
|
749 ( itemText.Left(compLength) != dispText.Left(compLength) ); |
|
750 |
|
751 const RArray<TPsMatchLocation>& underlines = clsItemArray[aItemIndex]->Highlights(); |
|
752 |
|
753 if ( underlines.Count() > 0 && !textContainsRtl ) |
|
754 { |
|
755 TInt i = 0; |
|
756 TBool partsLeft = ETrue; |
|
757 TInt currentTextStart = 0; |
|
758 TInt currentTextLength = 0; |
|
759 |
|
760 while ( partsLeft ) |
|
761 { |
|
762 if ( currentTextStart < underlines[i].index ) |
|
763 { |
|
764 // draw letters to the start of the underlined part |
|
765 currentTextLength = underlines[i].index - currentTextStart; |
|
766 DrawPartOfItem( aActualItemRect, *font, currentTextStart, currentTextLength, itemText, |
|
767 EFalse, topToBaseline ); |
|
768 } |
|
769 else if ( currentTextStart == underlines[i].index ) |
|
770 { |
|
771 // draw underlined letters |
|
772 currentTextLength = underlines[i].length; |
|
773 |
|
774 DrawPartOfItem( aActualItemRect, *font, currentTextStart, currentTextLength, itemText, |
|
775 ETrue, topToBaseline ); |
|
776 i++; |
|
777 } |
|
778 else |
|
779 { |
|
780 // This is here, because PCS Engine might give you duplicate match entries, |
|
781 // in this case we're not advancing text but we'll skip that match |
|
782 currentTextLength = 0; |
|
783 i++; |
|
784 } |
|
785 // update text start point |
|
786 currentTextStart += currentTextLength; |
|
787 |
|
788 if ( i >= underlines.Count() ) |
|
789 { |
|
790 partsLeft = EFalse; |
|
791 // draw rest of the letters, if there are any after the last underlined part |
|
792 if ( currentTextStart < itemText.Length() ) |
|
793 { |
|
794 currentTextLength = itemText.Length() - currentTextStart; |
|
795 DrawPartOfItem( aActualItemRect, *font, currentTextStart, currentTextLength, itemText, |
|
796 EFalse, topToBaseline ); |
|
797 } |
|
798 } |
|
799 } |
|
800 } |
|
801 else |
|
802 { |
|
803 iGc->SetUnderlineStyle( EUnderlineOff ); |
|
804 bidiText->DrawText( *iGc, leftBase ); |
|
805 } |
|
806 } |
|
807 CleanupStack::PopAndDestroy( bidiText ); |
|
808 } |
|
809 |
|
810 // ----------------------------------------------------------------------------- |
|
811 // CESMRNcsListItemDrawer::DrawPartOfItem |
|
812 // ----------------------------------------------------------------------------- |
|
813 void CESMRNcsListItemDrawer::DrawPartOfItem( const TRect& aItemRect, const CFont& aFont, |
|
814 TInt aStartPos, TInt aLength, const TDesC& aDes, |
|
815 TBool aUnderlined, TInt aBaselineOffsetFromTop ) const |
|
816 { |
|
817 FUNC_LOG; |
|
818 if( aUnderlined ) |
|
819 { |
|
820 iGc->SetUnderlineStyle( EUnderlineOn ); |
|
821 } |
|
822 else |
|
823 { |
|
824 iGc->SetUnderlineStyle( EUnderlineOff ); |
|
825 } |
|
826 TRect currentTextRect( aItemRect ); |
|
827 TInt pixels = aFont.TextWidthInPixels( aDes.Left( aStartPos ) ); |
|
828 currentTextRect.iTl.iX = currentTextRect.iTl.iX + pixels + KListBoxDrawMargin; |
|
829 |
|
830 //adjust selector size for if scrollbar is on screen |
|
831 if (iListBox.ScrollBarFrame()->ScrollBarVisibility(CEikScrollBar::EVertical) == |
|
832 CEikScrollBarFrame::EOn) |
|
833 { |
|
834 currentTextRect.iBr.iX = currentTextRect.iBr.iX - KListBoxDrawMargin - KScrollbarWidth; |
|
835 } |
|
836 else |
|
837 { |
|
838 currentTextRect.iBr.iX = currentTextRect.iBr.iX - KListBoxDrawMargin; |
|
839 } |
|
840 |
|
841 iGc->DrawText( aDes.Mid( aStartPos, aLength ), currentTextRect, aBaselineOffsetFromTop ); |
|
842 |
|
843 } |
|
844 |
|
845 |
|
846 |
|
847 // End of File |
|
848 |