phonebookui/Phonebook2/UIControls/src/CPbk2AddItemToContactDlg.cpp
branchRCL_3
changeset 20 f4a778e096c2
child 21 9da50d567e3c
equal deleted inserted replaced
19:5b6f26637ad3 20:f4a778e096c2
       
     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 add new contact field to a contact dialog.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <CPbk2AddItemToContactDlg.h>
       
    20 
       
    21 // Phonebook 2
       
    22 #include <TPbk2AddItemDialogParams.h>
       
    23 #include <TPbk2AddItemWrapper.h>
       
    24 #include <Pbk2UIControls.rsg>
       
    25 #include <CPbk2IconArray.h>
       
    26 #include <TPbk2AppIconId.h>
       
    27 #include <CPbk2UIExtensionManager.h>
       
    28 #include <MPbk2UIExtensionIconSupport.h>
       
    29 #include <MPbk2AppUi.h>
       
    30 #include <CPbk2ServiceManager.h>
       
    31 #include <MPbk2ApplicationServices.h>
       
    32 #include <MPbk2ApplicationServices2.h>
       
    33 #include "CPbk2IconInfo.h"
       
    34 #include <aknlayoutscalable_avkon.cdl.h>
       
    35 #include <MPbk2ApplicationServices.h>
       
    36 
       
    37 // System includes
       
    38 #include <aknPopup.h>
       
    39 #include <aknlists.h>
       
    40 #include <barsread.h>
       
    41 
       
    42 
       
    43 /// Unnamed namespace for local definitions
       
    44 namespace {
       
    45 
       
    46 const TInt KMaxListBoxBufferSize = 128;
       
    47 _LIT(KListBoxIconFormat, "%d\t");
       
    48 
       
    49 #ifdef _DEBUG
       
    50 
       
    51 enum TPanicCode
       
    52     {
       
    53     EPanicPreCond_ResetWhenDestroyed = 1
       
    54     };
       
    55 
       
    56 void Panic( TInt aReason )
       
    57     {
       
    58     _LIT( KPanicText, "CPbk2AddItemToContactDlg" );
       
    59     User::Panic( KPanicText, aReason );
       
    60     }
       
    61 
       
    62 #endif // _DEBUG
       
    63 
       
    64 
       
    65 /**
       
    66  * Phonebook 2 list box model for add item wrappers.
       
    67  */
       
    68 NONSHARABLE_CLASS(CModel) : public CBase,
       
    69                             public MDesCArray
       
    70     {
       
    71     public: // Construction
       
    72 
       
    73         /**
       
    74          * Constructor.
       
    75          *
       
    76          * @param aArray        An array of wrappers.
       
    77          * @param aIconArray    Icon array.
       
    78          * @return  A new instance of this class.
       
    79          */
       
    80         CModel(
       
    81                 RArray<TPbk2AddItemWrapper>& aArray,
       
    82                 CPbk2IconArray& aIconArray );
       
    83 
       
    84     public: // From MDesCArray
       
    85         TInt MdcaCount() const;
       
    86         TPtrC16 MdcaPoint(
       
    87                 TInt aIndex ) const;
       
    88 
       
    89     private: // Implementation
       
    90         static TInt Compare(
       
    91                 const TPbk2AddItemWrapper& aLhs,
       
    92                 const TPbk2AddItemWrapper& aRhs );
       
    93 
       
    94     private: // Data
       
    95         /// Ref: Array of TPbk2AddItemWrapper objects to show
       
    96         RArray<TPbk2AddItemWrapper>& iArray;
       
    97         /// Own: Buffer for formatting a list box row text
       
    98         mutable TBuf16<KMaxListBoxBufferSize> iBuffer;
       
    99         /// Ref: Icons for field types
       
   100         CPbk2IconArray& iIconArray;
       
   101     };
       
   102 
       
   103 // --------------------------------------------------------------------------
       
   104 // CModel::CModel
       
   105 // --------------------------------------------------------------------------
       
   106 //
       
   107 CModel::CModel(RArray<TPbk2AddItemWrapper>& aArray,
       
   108     CPbk2IconArray& aIconArray) :
       
   109         iArray(aArray),
       
   110         iIconArray(aIconArray)
       
   111     {
       
   112     iArray.Sort(TLinearOrder<TPbk2AddItemWrapper>(CModel::Compare));
       
   113     }
       
   114 
       
   115 // --------------------------------------------------------------------------
       
   116 // CModel::MdcaCount
       
   117 // --------------------------------------------------------------------------
       
   118 //
       
   119 TInt CModel::MdcaCount() const
       
   120     {
       
   121     return iArray.Count();
       
   122     }
       
   123 
       
   124 // --------------------------------------------------------------------------
       
   125 // CModel::MdcaPoint
       
   126 // --------------------------------------------------------------------------
       
   127 //
       
   128 TPtrC16 CModel::MdcaPoint( TInt aIndex ) const
       
   129     {
       
   130     // Insert icon index
       
   131     TInt iconIndex = iIconArray.FindIcon(iArray[aIndex].IconId());
       
   132     if (iconIndex < 0)
       
   133         {
       
   134         // If icon is not found by Id fall back to empty icon
       
   135         iconIndex = iIconArray.FindIcon(
       
   136             TPbk2AppIconId(EPbk2qgn_prop_nrtyp_empty));
       
   137         }
       
   138 
       
   139     iBuffer.Format(KListBoxIconFormat, iconIndex);
       
   140     const TDesC& fieldName = iArray[aIndex].Label();
       
   141     const TInt chars = Min(iBuffer.MaxLength() - iBuffer.Length(),
       
   142         fieldName.Length());
       
   143     iBuffer.Append(fieldName.Left(chars));
       
   144     return iBuffer;
       
   145     }
       
   146 
       
   147 // --------------------------------------------------------------------------
       
   148 // CModel::Compare
       
   149 // --------------------------------------------------------------------------
       
   150 //
       
   151 TInt CModel::Compare(   const TPbk2AddItemWrapper& aLhs,
       
   152         const TPbk2AddItemWrapper& aRhs )
       
   153     {
       
   154     return aLhs.AddItemOrdering() - aRhs.AddItemOrdering();
       
   155     }
       
   156 
       
   157 } /// namespace
       
   158 
       
   159 // --------------------------------------------------------------------------
       
   160 // CPbk2AddItemToContactDlg::CPbk2AddItemToContactDlg
       
   161 // --------------------------------------------------------------------------
       
   162 //
       
   163 inline CPbk2AddItemToContactDlg::CPbk2AddItemToContactDlg( MPbk2ApplicationServices* aAppServices ) :
       
   164 	iAppServices( aAppServices )
       
   165     {
       
   166     // Do nothing
       
   167     }
       
   168 
       
   169 // --------------------------------------------------------------------------
       
   170 // CPbk2AddItemToContactDlg::~CPbk2AddItemToContactDlg
       
   171 // --------------------------------------------------------------------------
       
   172 //
       
   173 CPbk2AddItemToContactDlg::~CPbk2AddItemToContactDlg()
       
   174     {
       
   175     // Tells ExecuteLD this object has been destroyed
       
   176     if (iDestroyedPtr)
       
   177         {
       
   178         *iDestroyedPtr = ETrue;
       
   179         }
       
   180 
       
   181     if ( iSelfPtr )
       
   182         {
       
   183         *iSelfPtr = NULL;
       
   184         }
       
   185 
       
   186     if ( iPopup )
       
   187         {
       
   188         iPopup->CancelPopup();
       
   189         }
       
   190 
       
   191     delete iListBox;
       
   192     }
       
   193 
       
   194 // --------------------------------------------------------------------------
       
   195 // CPbk2AddItemToContactDlg::NewL
       
   196 // --------------------------------------------------------------------------
       
   197 //
       
   198 EXPORT_C CPbk2AddItemToContactDlg* CPbk2AddItemToContactDlg::NewL()
       
   199     {
       
   200     CPbk2AddItemToContactDlg* self = new(ELeave) CPbk2AddItemToContactDlg();
       
   201     return self;
       
   202     }
       
   203 
       
   204 // --------------------------------------------------------------------------
       
   205 // CPbk2AddItemToContactDlg::NewL
       
   206 // --------------------------------------------------------------------------
       
   207 //
       
   208 EXPORT_C CPbk2AddItemToContactDlg* CPbk2AddItemToContactDlg::NewL(
       
   209 	MPbk2ApplicationServices* aAppServices )
       
   210     {
       
   211     CPbk2AddItemToContactDlg* self = new(ELeave) CPbk2AddItemToContactDlg( aAppServices );
       
   212     return self;
       
   213     }
       
   214 
       
   215 // --------------------------------------------------------------------------
       
   216 // CPbk2AddItemToContactDlg::ExecuteLD
       
   217 // --------------------------------------------------------------------------
       
   218 //
       
   219 EXPORT_C TInt CPbk2AddItemToContactDlg::ExecuteLD
       
   220         ( RArray<TPbk2AddItemWrapper>& aAddItems,
       
   221           const TPbk2AddItemDialogParams* aParams /*= NULL*/ )
       
   222     {
       
   223     CleanupStack::PushL( this );
       
   224 
       
   225     TBool thisDestroyed = EFalse;
       
   226     iDestroyedPtr = &thisDestroyed;
       
   227 
       
   228     PreparePopupL( aAddItems, aParams );
       
   229     TInt result = ExecutePopupL( aParams );
       
   230 
       
   231     if ( thisDestroyed )
       
   232         {
       
   233         // This object has been destroyed
       
   234         CleanupStack::Pop( this );
       
   235         }
       
   236     else
       
   237         {
       
   238         CleanupStack::PopAndDestroy( this );
       
   239         }
       
   240 
       
   241     return result;
       
   242     }
       
   243 
       
   244 // --------------------------------------------------------------------------
       
   245 // CPbk2AddItemToContactDlg::RequestExitL
       
   246 // --------------------------------------------------------------------------
       
   247 //
       
   248 void CPbk2AddItemToContactDlg::RequestExitL( TInt /*aCommandId*/ )
       
   249     {
       
   250     if ( iPopup )
       
   251         {
       
   252         iPopup->CancelPopup();
       
   253         }
       
   254     }
       
   255 
       
   256 // --------------------------------------------------------------------------
       
   257 // CPbk2AddItemToContactDlg::ForceExit
       
   258 // --------------------------------------------------------------------------
       
   259 //
       
   260 void CPbk2AddItemToContactDlg::ForceExit()
       
   261     {
       
   262     delete this;
       
   263     }
       
   264 
       
   265 // --------------------------------------------------------------------------
       
   266 // CPbk2AddItemToContactDlg::ResetWhenDestroyed
       
   267 // --------------------------------------------------------------------------
       
   268 //
       
   269 void CPbk2AddItemToContactDlg::ResetWhenDestroyed
       
   270         ( MPbk2DialogEliminator** aSelfPtr )
       
   271     {
       
   272     __ASSERT_DEBUG(!aSelfPtr || *aSelfPtr == this,
       
   273         Panic( EPanicPreCond_ResetWhenDestroyed ) );
       
   274 
       
   275     iSelfPtr = aSelfPtr;
       
   276     }
       
   277 
       
   278 // --------------------------------------------------------------------------
       
   279 // CPbk2AddItemToContactDlg::PreparePopupL
       
   280 // --------------------------------------------------------------------------
       
   281 //
       
   282 void CPbk2AddItemToContactDlg::PreparePopupL
       
   283         ( RArray<TPbk2AddItemWrapper>& aAddItems,
       
   284           const TPbk2AddItemDialogParams* aParams )
       
   285     {
       
   286     // Create a list box
       
   287     delete iListBox;
       
   288     iListBox = NULL;
       
   289     iListBox = static_cast<CEikFormattedCellListBox*>
       
   290         ( EikControlFactory::CreateByTypeL
       
   291                 ( EAknCtSingleGraphicPopupMenuListBox ).iControl );
       
   292 
       
   293     TInt cbaResource = R_AVKON_SOFTKEYS_OK_CANCEL__OK;
       
   294     if (aParams && aParams->iCbaResource)
       
   295         {
       
   296         cbaResource = aParams->iCbaResource;
       
   297         }
       
   298 
       
   299     // Create a popup list
       
   300     if ( iPopup )
       
   301         {
       
   302         iPopup->CancelPopup();
       
   303         iPopup = NULL;
       
   304         }
       
   305     iPopup = CAknPopupList::NewL( iListBox,
       
   306         cbaResource, AknPopupLayouts::EMenuGraphicWindow );
       
   307 
       
   308     if ( aParams && aParams->iTitle && aParams->iTitle->Length() > 0 )
       
   309         {
       
   310         iPopup->SetTitleL( *aParams->iTitle );
       
   311         }
       
   312 
       
   313     // Init list box
       
   314     iListBox->ConstructL( iPopup, CEikListBox::ELeftDownInViewRect );
       
   315     iListBox->CreateScrollBarFrameL( ETrue );
       
   316     iListBox->ScrollBarFrame()->SetScrollBarVisibilityL
       
   317         ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
       
   318 
       
   319     // Create icon array
       
   320     TResourceReader reader;
       
   321     CCoeEnv::Static()->CreateResourceReaderLC
       
   322         ( reader, R_PBK2_FIELDTYPE_ICONS );
       
   323     CPbk2IconArray* iconArray = CPbk2IconArray::NewL(reader);
       
   324     CleanupStack::PopAndDestroy(); // reader
       
   325     CleanupStack::PushL( iconArray );
       
   326     
       
   327     //Calculate preferred size for xsp service icons 
       
   328     TRect mainPane;
       
   329     AknLayoutUtils::LayoutMetricsRect(
       
   330         AknLayoutUtils::EMainPane, mainPane );
       
   331     TAknLayoutRect listLayoutRect;
       
   332     listLayoutRect.LayoutRect(
       
   333         mainPane,
       
   334         AknLayoutScalable_Avkon::list_single_graphic_pane_g2(0).LayoutLine() );
       
   335     TSize size(listLayoutRect.Rect().Size());
       
   336     
       
   337     MPbk2ApplicationServices2* servicesExtension = NULL ;
       
   338     
       
   339     /*
       
   340 	 * Use iAppServices if provided. This is to enable editor use outside from pbk2 context
       
   341 	 */
       
   342 	if( iAppServices )
       
   343 		{
       
   344 		servicesExtension = reinterpret_cast<MPbk2ApplicationServices2*>
       
   345 			( iAppServices->MPbk2ApplicationServicesExtension( KMPbk2ApplicationServicesExtension2Uid ) );
       
   346 		}
       
   347 	else
       
   348 		{
       
   349 		// Add xsp service icons
       
   350 		servicesExtension =
       
   351 			reinterpret_cast<MPbk2ApplicationServices2*>
       
   352 				( Phonebook2::Pbk2AppUi()->ApplicationServices().
       
   353 					MPbk2ApplicationServicesExtension(
       
   354 						KMPbk2ApplicationServicesExtension2Uid ) );               
       
   355 		}
       
   356 	
       
   357     CPbk2ServiceManager& servMan = servicesExtension->ServiceManager();
       
   358     const CPbk2ServiceManager::RServicesArray& services = servMan.Services();
       
   359     TUid uid;
       
   360     uid.iUid = KPbk2ServManId;
       
   361     for ( TInt i = 0; i < services.Count(); i++ )
       
   362         {
       
   363         const CPbk2ServiceManager::TService& service = services[i];
       
   364         if ( service.iBitmapId && service.iBitmap )
       
   365             {
       
   366         	AknIconUtils::SetSize(
       
   367         	           service.iBitmap,
       
   368         	           size );
       
   369         	AknIconUtils::SetSize(
       
   370         	           service.iMask,
       
   371         	           size );            
       
   372             TPbk2IconId id = TPbk2IconId( uid, services[i].iBitmapId );
       
   373             CPbk2IconInfo* info = CPbk2IconInfo::NewLC(
       
   374             	id, services[i].iBitmap, services[i].iMask, size );
       
   375             iconArray->AppendIconL(info);
       
   376             CleanupStack::Pop(info);
       
   377             }
       
   378         }
       
   379 
       
   380     // Add icons from UI extensions
       
   381     CPbk2UIExtensionManager* extManager =
       
   382         CPbk2UIExtensionManager::InstanceL();
       
   383     extManager->PushL();
       
   384     extManager->IconSupportL().AppendExtensionIconsL( *iconArray );
       
   385     CleanupStack::PopAndDestroy(); // extManager
       
   386     CleanupStack::Pop( iconArray );
       
   387 
       
   388     // Set icon array
       
   389     iListBox->ItemDrawer()->ColumnData()->SetIconArray( iconArray );
       
   390 
       
   391     // Create listbox model
       
   392     CModel* listBoxModel = new(ELeave) CModel( aAddItems, *iconArray );
       
   393     iListBox->Model()->SetItemTextArray(listBoxModel);
       
   394     iListBox->Model()->SetOwnershipType(ELbmOwnsItemArray);
       
   395     
       
   396     }
       
   397 
       
   398 // --------------------------------------------------------------------------
       
   399 // CPbk2AddItemToContactDlg::ExecutePopupL
       
   400 // --------------------------------------------------------------------------
       
   401 //
       
   402 TInt CPbk2AddItemToContactDlg::ExecutePopupL
       
   403         ( const TPbk2AddItemDialogParams* aParams )
       
   404     {
       
   405     TInt result = KErrCancel;
       
   406 
       
   407     if ( aParams && aParams->iSelectionIndex >= 0 )
       
   408         {
       
   409         // Silent mode, the selection has already been made
       
   410         // Result is the same index as was given in parameters,
       
   411         // the aAddItems array got sorted when creating the list box model
       
   412         // so the returned index value is valid now
       
   413         result = aParams->iSelectionIndex;
       
   414         }
       
   415     else
       
   416         {
       
   417         // iDestroyedPtr points to ExecuteLD's thisDestroyed local variable,
       
   418         // and we need another destruction check here. We cannot copy the
       
   419         // solution from ExecuteLD since making iDestroyedPtr point to a
       
   420         // local variable defined in this function rather than the
       
   421         // variable of ExecuteLD causes the destructor change the value of
       
   422         // a variable that is out of scope and it will lead to a crash
       
   423         // eventually. So thisDestroyed now points to the
       
   424         // ExecuteLD::thisDestroyed and it is still in scope in destructor.
       
   425         TBool* thisDestroyed = iDestroyedPtr;
       
   426 
       
   427         TBool popupAccepted = iPopup->ExecuteLD();
       
   428         iPopup = NULL;
       
   429 
       
   430         if ( popupAccepted && *thisDestroyed == EFalse )
       
   431             {
       
   432             // Retrieve and return selection
       
   433             TInt index = iListBox->CurrentItemIndex();
       
   434             if ( index >= KErrNone )
       
   435                 {
       
   436                 result = index;
       
   437                 }
       
   438             }
       
   439         }
       
   440 
       
   441     return result;
       
   442     }
       
   443 
       
   444 // End of File