phonebookui/Phonebook2/UIControls/src/CPbk2SelectFieldDlg.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2005-2007 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:  Phonebook 2 field selection dialog.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CPbk2SelectFieldDlg.h"
       
    20 
       
    21 // Phonebook 2
       
    22 #include "MPbk2ControlKeyObserver.h"
       
    23 #include "MPbk2ClipListBoxText.h"
       
    24 #include <CPbk2IconArray.h>
       
    25 #include <CPbk2PresentationContactFieldCollection.h>
       
    26 #include <CPbk2StorePropertyArray.h>
       
    27 #include <CPbk2UIExtensionManager.h>
       
    28 #include <MPbk2UIExtensionIconSupport.h>
       
    29 #include <Pbk2UIControls.rsg>
       
    30 #include <CPbk2PresenceIconInfo.h>
       
    31 #include "CPbk2FieldAnalyzer.h"
       
    32 #include <CPbk2ApplicationServices.h>
       
    33 
       
    34 // Virtual Phonebook
       
    35 #include <CVPbkContactManager.h>
       
    36 #include <MVPbkContactStore.h>
       
    37 #include <MVPbkBaseContact.h>
       
    38 #include <MVPbkContactLink.h>
       
    39 
       
    40 // System includes
       
    41 #include <avkon.rsg>
       
    42 #include <aknPopup.h>
       
    43 #include <aknlists.h>
       
    44 #include <eikclbd.h>
       
    45 #include <calslbs.h>
       
    46 #include <barsread.h>
       
    47 #include <MPbk2AppUi.h>
       
    48 #include "CPbk2IconInfo.h"
       
    49 #include <CPbk2ServiceManager.h>
       
    50 #include <MPbk2ApplicationServices.h>
       
    51 #include <MPbk2ApplicationServices2.h>
       
    52 #include <aknlayoutscalable_avkon.cdl.h>
       
    53 
       
    54 /// Unnamed namespace for local definitions
       
    55 namespace {
       
    56 
       
    57 //uid for presence icons
       
    58 const TInt32 KPbk2PrecenceIconsId = 0x2001E63D;
       
    59 
       
    60 #ifdef _DEBUG
       
    61 enum TPanicCode
       
    62     {
       
    63     EPanicPostCond_Constructor = 1,
       
    64     EPanicPreCond_ExecuteLD,
       
    65     EPanicPreCond_AttemptExitL,
       
    66     EPanicPreCond_ResetWhenDestroyed
       
    67     };
       
    68 
       
    69 void Panic(TPanicCode aReason)
       
    70     {
       
    71     _LIT(KPanicText, "CPbkSelectFieldDlg");
       
    72     User::Panic(KPanicText, aReason);
       
    73     }
       
    74 #endif // _DEBUG
       
    75 
       
    76 
       
    77 /**
       
    78  * Creates and returns an icon array with Phonebook 2
       
    79  * default and extension icons.
       
    80  *
       
    81  * @param aPresenceIconsArray Presence icons array
       
    82  * @return  An array filled with icons.
       
    83  */
       
    84 CPbk2IconArray* CreateListBoxIconArrayL(
       
    85     const TArray<CPbk2PresenceIconInfo*>* aPresenceIconsArray,
       
    86     RArray<CPbk2FieldListBoxModel::TPresenceIconPosInIconArray>&
       
    87         aPresenceIconsPos )
       
    88     {
       
    89     // Create icon array
       
    90     TResourceReader reader;
       
    91     CCoeEnv::Static()->CreateResourceReaderLC( reader,
       
    92         R_PBK2_FIELDTYPE_ICONS );
       
    93     CPbk2IconArray* iconArray = CPbk2IconArray::NewL( reader );
       
    94     CleanupStack::PushL( iconArray );
       
    95     
       
    96     //Calculate preferred size for xsp service icons 
       
    97     TRect mainPane;
       
    98     AknLayoutUtils::LayoutMetricsRect(
       
    99         AknLayoutUtils::EMainPane, mainPane );
       
   100     TAknLayoutRect listLayoutRect;
       
   101     listLayoutRect.LayoutRect(
       
   102         mainPane,
       
   103         AknLayoutScalable_Avkon::list_single_graphic_pane_g1(0).LayoutLine() );
       
   104     TSize size(listLayoutRect.Rect().Size());
       
   105       
       
   106     // Add xsp service icons
       
   107     CPbk2ApplicationServices* appServices =
       
   108         CPbk2ApplicationServices::InstanceLC();
       
   109     MPbk2ApplicationServices2* servicesExtension = 
       
   110         reinterpret_cast<MPbk2ApplicationServices2*>
       
   111             ( appServices->MPbk2ApplicationServicesExtension(
       
   112                     KMPbk2ApplicationServicesExtension2Uid ) );
       
   113     CleanupStack::PopAndDestroy(); // appServices
       
   114     CPbk2ServiceManager& servMan = servicesExtension->ServiceManager();
       
   115     const CPbk2ServiceManager::RServicesArray& services = servMan.Services();
       
   116     TUid uid;
       
   117     uid.iUid = KPbk2ServManId;
       
   118     for ( TInt i = 0; i < services.Count(); i++ )
       
   119         {
       
   120         const CPbk2ServiceManager::TService& service = services[i];
       
   121         if ( service.iBitmapId && service.iBitmap )
       
   122             {
       
   123         	AknIconUtils::SetSize(
       
   124         	           service.iBitmap,
       
   125         	           size );
       
   126         	AknIconUtils::SetSize(
       
   127         	           service.iMask,
       
   128         	           size );
       
   129             
       
   130             TPbk2IconId id = TPbk2IconId( uid, services[i].iBitmapId );
       
   131             CPbk2IconInfo* info = CPbk2IconInfo::NewLC(
       
   132                 id, services[i].iBitmap, services[i].iMask, size );
       
   133             iconArray->AppendIconL(info);
       
   134             CleanupStack::Pop(info);
       
   135             }
       
   136         }    
       
   137 
       
   138     // Add icons from UI extensions
       
   139     CPbk2UIExtensionManager* extManager = CPbk2UIExtensionManager::InstanceL();
       
   140     extManager->PushL();
       
   141     extManager->IconSupportL().AppendExtensionIconsL( *iconArray );
       
   142     CleanupStack::PopAndDestroy(); // extManager
       
   143     
       
   144     // add presence icons if exist
       
   145     if ( aPresenceIconsArray != NULL )
       
   146         {
       
   147         TUid presenceIconsUid;
       
   148         presenceIconsUid.iUid = KPbk2PrecenceIconsId;
       
   149         TInt count = aPresenceIconsArray->Count();
       
   150         for ( TInt j = 0; j < count; j++ )
       
   151             {
       
   152             TPbk2IconId presenceIconId = TPbk2IconId( presenceIconsUid, j );
       
   153             CPbk2IconInfo* presenceIconInfo = CPbk2IconInfo::NewLC(
       
   154                 presenceIconId,
       
   155                 aPresenceIconsArray->operator[](j)->IconBitmap(),
       
   156                 aPresenceIconsArray->operator[](j)->IconBitmapMask(),
       
   157                 size );
       
   158             iconArray->AppendIconL( presenceIconInfo );
       
   159             CleanupStack::Pop( presenceIconInfo );
       
   160             
       
   161             // save presence icon position
       
   162             CPbk2FieldListBoxModel::TPresenceIconPosInIconArray presenceIconPos( 
       
   163                 aPresenceIconsArray->operator[](j)->ServiceName() );
       
   164             presenceIconPos.iIconId = presenceIconId;
       
   165             aPresenceIconsPos.AppendL( presenceIconPos );
       
   166             }
       
   167         }
       
   168     
       
   169     CleanupStack::Pop( iconArray );
       
   170     CleanupStack::PopAndDestroy(); // reader
       
   171 
       
   172     return iconArray;
       
   173     }
       
   174 
       
   175 } /// namespace
       
   176 
       
   177 
       
   178 /**
       
   179  * Specialized popup list class.
       
   180  */
       
   181 NONSHARABLE_CLASS( CPbk2SelectFieldDlg::CPopupList ) :
       
   182         public CAknPopupList
       
   183     {
       
   184     public: // Interface
       
   185 
       
   186         /**
       
   187          * Like CAknPopupList::NewL.
       
   188          * @see CAknPopupList::NewL
       
   189          */
       
   190         static CPopupList* NewL(
       
   191                 CEikListBox* aListBox,
       
   192                 TInt aCbaResource,
       
   193                 AknPopupLayouts::TAknPopupLayouts aType =
       
   194                     AknPopupLayouts::EMenuWindow );
       
   195 
       
   196         /**
       
   197          * Sets the listbox item to focus initially.
       
   198          * By default focus is on the first item.
       
   199          *
       
   200          * @param aFocusIndex  Index of the listbox item to focus initially.
       
   201          */
       
   202         inline void SetInitialFocus(
       
   203                 TInt aFocusIndex );
       
   204 
       
   205         /**
       
   206          * Like CAknPopupList::AttemptExitL.
       
   207          * @see CAknPopupList::AttemptExitL
       
   208          */
       
   209         inline void AttemptExitL(
       
   210                 TBool aAccept );
       
   211 
       
   212     private: // From CAknPopupList
       
   213         void SetupWindowLayout(
       
   214                 AknPopupLayouts::TAknPopupLayouts aType );
       
   215         
       
   216         TKeyResponse OfferKeyEventL(
       
   217                 const TKeyEvent& aKeyEvent,TEventCode aType );
       
   218 
       
   219     private: // Implementation
       
   220         inline CPopupList();
       
   221 
       
   222     private: // Data
       
   223         /// Own: Focus index
       
   224         TInt iFocusIndex;
       
   225     };
       
   226 
       
   227 /**
       
   228  * Specialized listbox class.
       
   229  */
       
   230 NONSHARABLE_CLASS( CPbk2SelectFieldDlg::CListBox ) :
       
   231         public CAknDoubleGraphicPopupMenuStyleListBox,
       
   232         public MPbk2ClipListBoxText
       
   233     {
       
   234     public: // Interface
       
   235 
       
   236         /**
       
   237          * Constructor.
       
   238          */
       
   239         inline CListBox();
       
   240 
       
   241         /**
       
   242          * Sets the observer.
       
   243          *
       
   244          * @param aKeyObserver      The observer to set.
       
   245          */
       
   246         inline void SetObserver(
       
   247                 MPbk2ControlKeyObserver* aKeyObserver );
       
   248 
       
   249         /**
       
   250          * Returns CONE environment.
       
   251          *
       
   252          * @return  CONE environment.
       
   253          */
       
   254         inline CCoeEnv* CoeEnv();
       
   255 
       
   256     private: // From CAknDoubleGraphicPopupMenuStyleListBox
       
   257         TKeyResponse OfferKeyEventL(
       
   258             const TKeyEvent& aKeyEvent,
       
   259             TEventCode aType );
       
   260 
       
   261     private: // From MPbk2ClipListBoxText
       
   262         TBool ClipFromBeginning(
       
   263             TDes& aBuffer,
       
   264             TInt aItemIndex,
       
   265             TInt aSubCellNumber );
       
   266 
       
   267     private: // Data
       
   268         /// Ref: Observer
       
   269         MPbk2ControlKeyObserver* iKeyObserver;
       
   270     };
       
   271 
       
   272 
       
   273 // --------------------------------------------------------------------------
       
   274 // CPbk2SelectFieldDlg::CListBox::CPopupList
       
   275 // --------------------------------------------------------------------------
       
   276 //
       
   277 inline CPbk2SelectFieldDlg::CPopupList::CPopupList() :
       
   278         iFocusIndex( KErrNotFound )
       
   279     {
       
   280     }
       
   281 
       
   282 // --------------------------------------------------------------------------
       
   283 // CPbk2SelectFieldDlg::CListBox::NewL
       
   284 // --------------------------------------------------------------------------
       
   285 //
       
   286 CPbk2SelectFieldDlg::CPopupList* CPbk2SelectFieldDlg::CPopupList::NewL
       
   287         ( CEikListBox* aListBox,  TInt aCbaResource,
       
   288           AknPopupLayouts::TAknPopupLayouts aType )
       
   289     {
       
   290     CPopupList* self = new ( ELeave ) CPopupList();
       
   291     CleanupStack::PushL( self );
       
   292     self->ConstructL( aListBox, aCbaResource, aType );
       
   293     CleanupStack::Pop( self );
       
   294     return self;
       
   295     }
       
   296 
       
   297 // --------------------------------------------------------------------------
       
   298 // CPbk2SelectFieldDlg::CListBox::SetInitialFocus
       
   299 // --------------------------------------------------------------------------
       
   300 //
       
   301 inline void CPbk2SelectFieldDlg::CPopupList::SetInitialFocus
       
   302         ( TInt aFocusIndex )
       
   303     {
       
   304     iFocusIndex = aFocusIndex;
       
   305     }
       
   306 
       
   307 // --------------------------------------------------------------------------
       
   308 // CPbk2SelectFieldDlg::CPopupList::AttemptExitL
       
   309 // --------------------------------------------------------------------------
       
   310 //
       
   311 inline void CPbk2SelectFieldDlg::CPopupList::AttemptExitL( TBool aAccept )
       
   312     {
       
   313     CAknPopupList::AttemptExitL( aAccept );
       
   314     }
       
   315 
       
   316 // --------------------------------------------------------------------------
       
   317 // CPbk2SelectFieldDlg::CListBox::SetupWindowLayout
       
   318 // --------------------------------------------------------------------------
       
   319 //
       
   320 void CPbk2SelectFieldDlg::CPopupList::SetupWindowLayout
       
   321         ( AknPopupLayouts::TAknPopupLayouts aType )
       
   322     {
       
   323     // Call base class
       
   324     CAknPopupList::SetupWindowLayout( aType );
       
   325     // Set initial focus
       
   326     if ( iFocusIndex >= 0 )
       
   327         {
       
   328         ListBox()->SetCurrentItemIndex( iFocusIndex );
       
   329         }
       
   330     }
       
   331 
       
   332 // --------------------------------------------------------------------------
       
   333 // CPbk2SelectFieldDlg::CListBox::OfferKeyEventL
       
   334 // --------------------------------------------------------------------------
       
   335 //
       
   336 TKeyResponse CPbk2SelectFieldDlg::CPopupList::OfferKeyEventL
       
   337         (const TKeyEvent& aKeyEvent, TEventCode aType)
       
   338     {
       
   339     // The focus can display after clicking on navigation key and MSK key.
       
   340     // Then, both LSK and RSK should be visible.
       
   341     // Check whether LSK is hidden, if yes, make it visible
       
   342     if ( !ButtonGroupContainer()->IsCommandVisible( EAknSoftkeySelect ) )
       
   343     	{
       
   344         // Whether navigation key or MSK key is pressed.
       
   345     	if ( aKeyEvent.iCode == EKeyUpArrow  
       
   346           || aKeyEvent.iCode == EKeyDownArrow 
       
   347           || aKeyEvent.iCode == EKeyDevice3 )
       
   348             {
       
   349             ButtonGroupContainer()->MakeCommandVisible( EAknSoftkeySelect, ETrue );
       
   350             }
       
   351     	}
       
   352     TKeyResponse response = ListBox()->OfferKeyEventL( aKeyEvent, aType );
       
   353     return response;
       
   354     }
       
   355 
       
   356 // --------------------------------------------------------------------------
       
   357 // CPbk2SelectFieldDlg::CListBox::CListBox
       
   358 // --------------------------------------------------------------------------
       
   359 //
       
   360 inline CPbk2SelectFieldDlg::CListBox::CListBox()
       
   361     {
       
   362     }
       
   363 
       
   364 // --------------------------------------------------------------------------
       
   365 // CPbk2SelectFieldDlg::CListBox::SetObserver
       
   366 // --------------------------------------------------------------------------
       
   367 //
       
   368 inline void CPbk2SelectFieldDlg::CListBox::SetObserver
       
   369         ( MPbk2ControlKeyObserver* aKeyObserver )
       
   370     {
       
   371     iKeyObserver = aKeyObserver;
       
   372     }
       
   373 
       
   374 // --------------------------------------------------------------------------
       
   375 // CPbk2SelectFieldDlg::CListBox::CoeEnv
       
   376 // --------------------------------------------------------------------------
       
   377 //
       
   378 inline CCoeEnv* CPbk2SelectFieldDlg::CListBox::CoeEnv()
       
   379     {
       
   380     return iCoeEnv;
       
   381     }
       
   382 
       
   383 // --------------------------------------------------------------------------
       
   384 // CPbk2SelectFieldDlg::CListBox::OfferKeyEventL
       
   385 // --------------------------------------------------------------------------
       
   386 //
       
   387 TKeyResponse CPbk2SelectFieldDlg::CListBox::OfferKeyEventL
       
   388         ( const TKeyEvent& aKeyEvent, TEventCode aType )
       
   389     {
       
   390     TKeyResponse ret = EKeyWasNotConsumed;
       
   391 
       
   392     if ( iKeyObserver &&
       
   393          iKeyObserver->Pbk2ControlKeyEventL( aKeyEvent,aType )
       
   394             == EKeyWasConsumed )
       
   395         {
       
   396         ret = EKeyWasConsumed;
       
   397         }
       
   398     else
       
   399         {
       
   400         ret = CAknDoubleGraphicPopupMenuStyleListBox::OfferKeyEventL
       
   401             ( aKeyEvent, aType );
       
   402         }
       
   403 
       
   404     return ret;
       
   405     }
       
   406 
       
   407 // --------------------------------------------------------------------------
       
   408 // CPbk2SelectFieldDlg::CListBox::ClipFromBeginning
       
   409 // --------------------------------------------------------------------------
       
   410 //
       
   411 TBool CPbk2SelectFieldDlg::CListBox::ClipFromBeginning
       
   412         ( TDes& aBuffer, TInt aItemIndex, TInt aSubCellNumber )
       
   413     {
       
   414     return AknTextUtils::ClipToFit
       
   415         ( aBuffer, AknTextUtils::EClipFromBeginning, this,
       
   416           aItemIndex, aSubCellNumber );
       
   417     }
       
   418 
       
   419 // --------------------------------------------------------------------------
       
   420 // CPbk2SelectFieldDlg::CPbk2SelectFieldDlg
       
   421 // --------------------------------------------------------------------------
       
   422 //
       
   423 CPbk2SelectFieldDlg::CPbk2SelectFieldDlg()
       
   424     {
       
   425     __ASSERT_DEBUG(
       
   426         !iListBox && !iPopupList && !iKeyObserver && !iDestroyedPtr,
       
   427         Panic(EPanicPostCond_Constructor));
       
   428     }
       
   429 
       
   430 // --------------------------------------------------------------------------
       
   431 // CPbk2SelectFieldDlg::~CPbk2SelectFieldDlg
       
   432 // --------------------------------------------------------------------------
       
   433 //
       
   434 CPbk2SelectFieldDlg::~CPbk2SelectFieldDlg()
       
   435     {
       
   436     if ( iSelfPtr )
       
   437         {
       
   438         *iSelfPtr = NULL;
       
   439         }
       
   440     if ( iDestroyedPtr )
       
   441         {
       
   442         *iDestroyedPtr = ETrue;
       
   443         }
       
   444     if ( iPopupList )
       
   445         {
       
   446         iPopupList->CancelPopup();
       
   447         }
       
   448     
       
   449     delete iFieldAnalyzer;
       
   450     delete iListBox;
       
   451     iFieldCollectionArray.ResetAndDestroy();
       
   452     iPresenceIconsPos.Reset();
       
   453     
       
   454     delete iContactLink;
       
   455     }
       
   456 
       
   457 // --------------------------------------------------------------------------
       
   458 // CPbk2SelectFieldDlg::StoreReady
       
   459 // --------------------------------------------------------------------------
       
   460 //
       
   461 void CPbk2SelectFieldDlg::StoreReady( 
       
   462         MVPbkContactStore& /*aContactStore*/ )
       
   463     {
       
   464     }
       
   465 
       
   466 // --------------------------------------------------------------------------
       
   467 // CPbk2SelectFieldDlg::StoreUnavailable
       
   468 // --------------------------------------------------------------------------
       
   469 //
       
   470 void CPbk2SelectFieldDlg::StoreUnavailable( 
       
   471         MVPbkContactStore& /*aContactStore*/, 
       
   472         TInt /*aReason*/ )
       
   473     {
       
   474     }
       
   475 
       
   476 // --------------------------------------------------------------------------
       
   477 // CPbk2SelectFieldDlg::HandleStoreEventL
       
   478 // --------------------------------------------------------------------------
       
   479 //
       
   480 void CPbk2SelectFieldDlg::HandleStoreEventL( 
       
   481         MVPbkContactStore& /*aContactStore*/, 
       
   482         TVPbkContactStoreEvent aStoreEvent )
       
   483     {
       
   484     if ( iContactLink && 
       
   485             aStoreEvent.iContactLink &&
       
   486             aStoreEvent.iContactLink->IsSame( *iContactLink ) )
       
   487         {
       
   488         switch( aStoreEvent.iEventType )
       
   489             {
       
   490             case TVPbkContactStoreEvent::EContactDeleted:
       
   491                 {
       
   492                 iPopupList->CancelPopup();
       
   493                 break;
       
   494                 }
       
   495                 
       
   496             default:
       
   497                 break;
       
   498             }
       
   499         }
       
   500     }
       
   501 
       
   502 // --------------------------------------------------------------------------
       
   503 // CPbk2SelectFieldDlg::ExecuteLCD
       
   504 // --------------------------------------------------------------------------
       
   505 //
       
   506 const MVPbkStoreContactField* CPbk2SelectFieldDlg::ExecuteLCD
       
   507         ( MVPbkStoreContactFieldCollection& aFieldCollection,
       
   508           RPointerArray<CVPbkFieldFilter>& aFieldCollectionArray,
       
   509           const TArray<CPbk2PresenceIconInfo*>* aPresenceIconsArray,
       
   510           const CVPbkContactManager& aContactManager,
       
   511           const MPbk2FieldPropertyArray& aFieldProperties,
       
   512           TInt aCbaResourceId, 
       
   513           VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector aCommMethod,
       
   514           const TDesC& aHeading /*=KNullDesC*/,
       
   515           TInt aFocusIndex /*=KErrNotFound*/ )
       
   516     {
       
   517     __ASSERT_DEBUG(!iListBox && !iPopupList, Panic(EPanicPreCond_ExecuteLD));
       
   518 
       
   519     // "D" function semantics
       
   520     CleanupStack::PushL( this );
       
   521     TBool thisDestroyed = EFalse;
       
   522     // Destructor will set thisDestroyed to ETrue if this object is destroyed
       
   523     iDestroyedPtr = &thisDestroyed;
       
   524 
       
   525     CPbk2PresentationContactFieldCollection* fields =
       
   526         CPbk2PresentationContactFieldCollection::NewL(
       
   527             aFieldProperties,
       
   528             aFieldCollection,
       
   529             aFieldCollection.ParentStoreContact() );
       
   530     CleanupStack::PushL( fields );
       
   531 
       
   532     if ( aFocusIndex != KErrNotFound )
       
   533         {
       
   534         // The focus index is from store contact field order and
       
   535         // we have to map it to presentation contact field order
       
   536         MVPbkStoreContactField* initiallyFocusedField =
       
   537             aFieldCollection.FieldAtLC( aFocusIndex );
       
   538         for ( TInt i( 0 ); i < fields->FieldCount(); ++i )
       
   539             {
       
   540             if ( fields->FieldAt( i ).IsSame( *initiallyFocusedField ) )
       
   541                 {
       
   542                 // Fix the focus index to match with
       
   543                 // presentation contact fields
       
   544                 aFocusIndex = i;
       
   545                 break;
       
   546                 }
       
   547             }
       
   548         CleanupStack::PopAndDestroy(); // initiallyFocusedField
       
   549         }
       
   550 
       
   551     // Create presentation fields for additional contacts
       
   552     if ( aFieldCollectionArray.Count() > 0 )
       
   553         {
       
   554         TInt count = aFieldCollectionArray.Count();
       
   555         for( TInt i = 0; i < count; i++ )
       
   556             {
       
   557             CPbk2PresentationContactFieldCollection* xspFields =
       
   558                 CPbk2PresentationContactFieldCollection::NewL(
       
   559                     aFieldProperties,
       
   560                     *aFieldCollectionArray[i],
       
   561                     aFieldCollectionArray[i]->ParentStoreContact() );
       
   562             CleanupStack::PushL( xspFields );
       
   563 
       
   564             iFieldCollectionArray.AppendL( xspFields );
       
   565             CleanupStack::Pop(); //xspFields
       
   566             }
       
   567         }
       
   568 
       
   569     // Create list box
       
   570     CreateListBoxL( *fields, aPresenceIconsArray, aContactManager, 
       
   571         aFieldProperties, aCbaResourceId, aHeading, aFocusIndex, aCommMethod );
       
   572                     
       
   573     // Show the list query, if there are more than 1 field in the listbox
       
   574     TInt dlgResult = 0;
       
   575     if ( iListBoxModel->MdcaCount() > 1 )
       
   576         {
       
   577         MVPbkBaseContact& contact = fields->ParentContact();
       
   578         MVPbkContactLink* link = contact.CreateLinkLC();
       
   579         MVPbkContactStore& store = link->ContactStore();
       
   580         store.OpenL( *this );
       
   581         delete iContactLink;
       
   582         iContactLink = link;
       
   583         CleanupStack::Pop(); // link
       
   584         
       
   585         TRAPD( err, dlgResult = iPopupList->ExecuteLD() );
       
   586         store.Close( *this );
       
   587         
       
   588         if ( !thisDestroyed )
       
   589             {
       
   590             iPopupList = NULL;
       
   591             }
       
   592         if ( err != KErrNone )
       
   593             {
       
   594             User::Leave( err );
       
   595             }
       
   596         }
       
   597    else
       
   598        {
       
   599        dlgResult = 1; // simulate user's selection
       
   600        delete iPopupList;
       
   601        iPopupList = NULL;
       
   602        }
       
   603 
       
   604     // Get the return value
       
   605     MVPbkStoreContactField* result = NULL;
       
   606     if ( thisDestroyed )
       
   607         {
       
   608         // This object has been destroyed
       
   609         CleanupStack::PopAndDestroy( fields );
       
   610         CleanupStack::Pop();  // this
       
   611         }
       
   612     else
       
   613         {
       
   614         if ( dlgResult )
       
   615             {
       
   616             TInt index = iListBoxModel->GetModelIndex(
       
   617                 iListBox->CurrentItemIndex() );
       
   618             if ( index < fields->FieldCount() )
       
   619                 {
       
   620                 // field from the main contact
       
   621                 result = fields->FieldAt( index ).CloneLC();
       
   622                 CleanupStack::Pop();
       
   623                 }
       
   624             else if ( iFieldCollectionArray.Count() > 0 )
       
   625                 {
       
   626                 // field from the addiotnal contact
       
   627                 TInt offset = fields->FieldCount();
       
   628                 for ( TInt i = 0; i < iFieldCollectionArray.Count(); i++ )
       
   629                     {
       
   630                     TInt xspFieldCount = iFieldCollectionArray.operator[](i)->
       
   631                         FieldCount();
       
   632                     if ( index < offset + xspFieldCount )
       
   633                         {
       
   634                         // selected field belongs to iFieldCollectionArray[i] contact
       
   635                         result = iFieldCollectionArray.operator[](i)->FieldAt(
       
   636                             index - offset ).CloneLC();
       
   637                         CleanupStack::Pop();
       
   638                         break;
       
   639                         }
       
   640                     else
       
   641                         {
       
   642                         offset += xspFieldCount;
       
   643                         }
       
   644                     }
       
   645                 }
       
   646             }
       
   647         CleanupStack::PopAndDestroy( fields );
       
   648         CleanupStack::PopAndDestroy(); // this
       
   649         }
       
   650 
       
   651     CleanupDeletePushL( result );
       
   652     return result;
       
   653     }
       
   654 
       
   655 // --------------------------------------------------------------------------
       
   656 // CPbk2SelectFieldDlg::SetObserver
       
   657 // --------------------------------------------------------------------------
       
   658 //
       
   659 void CPbk2SelectFieldDlg::SetObserver
       
   660         ( MPbk2ControlKeyObserver* aKeyObserver )
       
   661     {
       
   662     iKeyObserver = aKeyObserver;
       
   663     }
       
   664 
       
   665 // --------------------------------------------------------------------------
       
   666 // CPbk2SelectFieldDlg::AttemptExitL
       
   667 // --------------------------------------------------------------------------
       
   668 //
       
   669 void CPbk2SelectFieldDlg::AttemptExitL( TBool aAccept )
       
   670     {
       
   671     __ASSERT_DEBUG( iPopupList, Panic( EPanicPreCond_AttemptExitL ) );
       
   672     iPopupList->MakeVisible( EFalse );
       
   673     iPopupList->AttemptExitL( aAccept );
       
   674     }
       
   675 
       
   676 // --------------------------------------------------------------------------
       
   677 // CPbk2SelectFieldDlg::ResetWhenDestroyed
       
   678 // --------------------------------------------------------------------------
       
   679 //
       
   680 void CPbk2SelectFieldDlg::ResetWhenDestroyed
       
   681         ( CPbk2SelectFieldDlg** aSelfPtr )
       
   682     {
       
   683     __ASSERT_DEBUG(!aSelfPtr || *aSelfPtr==this,
       
   684         Panic(EPanicPreCond_ResetWhenDestroyed));
       
   685 
       
   686     iSelfPtr = aSelfPtr;
       
   687     }
       
   688 
       
   689 // --------------------------------------------------------------------------
       
   690 // CPbk2SelectFieldDlg::CreateListBoxL
       
   691 // --------------------------------------------------------------------------
       
   692 //
       
   693 void CPbk2SelectFieldDlg::CreateListBoxL
       
   694         ( const CPbk2PresentationContactFieldCollection& aFieldCollection,
       
   695           const TArray<CPbk2PresenceIconInfo*>* aPresenceIconsArray,
       
   696           const CVPbkContactManager& aContactManager,
       
   697           const MPbk2FieldPropertyArray& aFieldProperties,
       
   698           TInt aCbaResourceId, const TDesC& aHeading,
       
   699           TInt aFocusIndex,
       
   700           VPbkFieldTypeSelectorFactory::TVPbkContactActionTypeSelector aCommMethod)
       
   701     {
       
   702     // Create a list box
       
   703     iListBox = new(ELeave) CListBox;
       
   704 
       
   705     // Create a popup list
       
   706     CPopupList* popupList = CPopupList::NewL(
       
   707         iListBox,
       
   708         aCbaResourceId,
       
   709         AknPopupLayouts::EMenuDoubleLargeGraphicWindow );
       
   710     CleanupStack::PushL( popupList );
       
   711 
       
   712     // Init list box
       
   713     iListBox->ConstructL( popupList, CEikListBox::ELeftDownInViewRect );
       
   714     iListBox->SetObserver( iKeyObserver );
       
   715 
       
   716     // Set title of popuplist
       
   717     if ( aHeading.Length() > 0 )
       
   718         {
       
   719         popupList->SetTitleL( aHeading );
       
   720         }
       
   721 
       
   722     // There is no focus at the initial phase, hence, LSK is not necessary.
       
   723     popupList->ButtonGroupContainer()->MakeCommandVisible( EAknSoftkeySelect, EFalse );
       
   724 
       
   725     // Create icon array
       
   726     CPbk2IconArray* iconArray = CreateListBoxIconArrayL( aPresenceIconsArray,
       
   727         iPresenceIconsPos );
       
   728     iListBox->ItemDrawer()->ColumnData()->SetIconArray( iconArray );
       
   729 
       
   730     // Create list box model
       
   731     HBufC* timeFormat =
       
   732         iListBox->CoeEnv()->AllocReadResourceLC( R_QTN_DATE_USUAL );
       
   733 
       
   734     iFieldAnalyzer = CPbk2FieldAnalyzer::NewL( const_cast<CVPbkContactManager&>( aContactManager ) );
       
   735     
       
   736     CPbk2FieldListBoxModel::TParams params( 
       
   737         aFieldCollection,
       
   738         aContactManager,
       
   739         aFieldProperties,
       
   740         *timeFormat,
       
   741         *iconArray,
       
   742         iFieldAnalyzer,
       
   743         NULL,
       
   744         ETrue,
       
   745 		aCommMethod );
       
   746     CPbk2FieldListBoxModel* listBoxModel = CPbk2FieldListBoxModel::NewL(
       
   747         params, &iFieldCollectionArray.Array(), &iPresenceIconsPos.Array() );
       
   748     CleanupStack::PushL( listBoxModel );
       
   749     listBoxModel->FormatFieldsL();
       
   750     CleanupStack::Pop( listBoxModel );
       
   751     CleanupStack::PopAndDestroy();  // timeFormat
       
   752     listBoxModel->SetClipper( *iListBox );
       
   753     iListBox->Model()->SetItemTextArray( listBoxModel );
       
   754     iListBox->Model()->SetOwnershipType( ELbmOwnsItemArray );
       
   755     iListBox->Reset();
       
   756 
       
   757     if ( aFocusIndex >= 0 && aFocusIndex <
       
   758             iListBox->Model()->NumberOfItems() )
       
   759         {
       
   760         popupList->SetInitialFocus( aFocusIndex );
       
   761         }
       
   762 
       
   763     iListBox->CreateScrollBarFrameL( ETrue );
       
   764     iListBox->ScrollBarFrame()->SetScrollBarVisibilityL(
       
   765         CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
       
   766 
       
   767     CleanupStack::Pop();  // listBox
       
   768     iPopupList = popupList;
       
   769     
       
   770     iListBoxModel = listBoxModel;
       
   771     }
       
   772 
       
   773 // End of File