emailcontacts/remotecontactlookup/engine/src/cpbkxrclcontactupdater.cpp
branchRCL_3
changeset 16 4ce476e64c59
parent 13 0396474f30f5
child 17 8592a65ad3fb
equal deleted inserted replaced
13:0396474f30f5 16:4ce476e64c59
     1 /*
       
     2 * Copyright (c) 2008 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:  Implementation of the class CPbkxRclContactUpdater.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "emailtrace.h"
       
    20 #include <pbkxrclengine.rsg>
       
    21 #include <CPbkSingleEntryFetchDlg.h>
       
    22 #include <CPbkContactEngine.h>
       
    23 #include <CPbkMemoryEntryAddItemDlg.h>
       
    24 #include <StringLoader.h>
       
    25 #include <CPbkFieldInfo.h>
       
    26 #include <CPbkFieldsInfo.h>
       
    27 #include <aknnotedialog.h>
       
    28 #include <pbkxrclengine.rsg>
       
    29 #include <coemain.h>
       
    30 #include <data_caging_path_literals.hrh>
       
    31 #include <bautils.h>
       
    32 
       
    33 #include "cpbkxrclcontactupdater.h"
       
    34 #include "pbkxrclutils.h"
       
    35 #include "pbkxrclengineconstants.h"
       
    36 #include "pbkxremotecontactlookuppanic.h"
       
    37 
       
    38 // Local constants
       
    39 _LIT(KPbkRomFileDrive, "z:");
       
    40 _LIT(KPbkViewResourceFile, "PbkView.rsc");
       
    41 
       
    42 // ======== MEMBER FUNCTIONS ========
       
    43 
       
    44 // ---------------------------------------------------------------------------
       
    45 // CPbkxRclContactUpdater::NewL
       
    46 // ---------------------------------------------------------------------------
       
    47 //
       
    48 CPbkxRclContactUpdater* CPbkxRclContactUpdater::NewL(
       
    49     CPbkContactEngine& aEngine )
       
    50     {
       
    51     FUNC_LOG;
       
    52     CPbkxRclContactUpdater* updater = CPbkxRclContactUpdater::NewLC( aEngine );
       
    53     CleanupStack::Pop( updater );
       
    54     return updater;
       
    55     }
       
    56 
       
    57 // ---------------------------------------------------------------------------
       
    58 // CPbkxRclContactUpdater::NewLC
       
    59 // ---------------------------------------------------------------------------
       
    60 //
       
    61 CPbkxRclContactUpdater* CPbkxRclContactUpdater::NewLC(
       
    62     CPbkContactEngine& aEngine )
       
    63     {
       
    64     FUNC_LOG;
       
    65     CPbkxRclContactUpdater* updater = 
       
    66         new ( ELeave ) CPbkxRclContactUpdater( aEngine );
       
    67     CleanupStack::PushL( updater );
       
    68     updater->ConstructL();
       
    69     return updater;
       
    70     }
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 // CPbkxRclContactUpdater::CPbkxRclContactUpdater
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 CPbkxRclContactUpdater::CPbkxRclContactUpdater( CPbkContactEngine& aEngine ) :
       
    77     CBase(), iEngine( aEngine )
       
    78     {
       
    79     FUNC_LOG;
       
    80     }
       
    81 
       
    82 // ---------------------------------------------------------------------------
       
    83 // CPbkxRclContactUpdater::~CPbkxRclContactUpdater
       
    84 // ---------------------------------------------------------------------------
       
    85 //
       
    86 CPbkxRclContactUpdater::~CPbkxRclContactUpdater()
       
    87     {
       
    88     FUNC_LOG;
       
    89     CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset );
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // CPbkxRclContactUpdater::ConstructL
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 void CPbkxRclContactUpdater::ConstructL()
       
    97     {
       
    98     FUNC_LOG;
       
    99 
       
   100     // First load Phonebook resource file so that dialog will find resources
       
   101     CCoeEnv* coeEnv = CCoeEnv::Static();
       
   102     TFileName resourceFile;
       
   103     resourceFile.Copy( KPbkRomFileDrive );
       
   104     resourceFile.Append( KDC_RESOURCE_FILES_DIR );
       
   105     resourceFile.Append( KPbkViewResourceFile );    
       
   106     
       
   107     BaflUtils::NearestLanguageFile( coeEnv->FsSession(), resourceFile );
       
   108     
       
   109     TRAPD( status,
       
   110             iResourceFileOffset = coeEnv->AddResourceFileL( resourceFile ) );
       
   111     
       
   112     if( status != KErrNone )
       
   113         {
       
   114         PbkxRclPanic( EPbkxRclPanicGeneral );       
       
   115         }
       
   116     else 
       
   117         {
       
   118         }
       
   119     }
       
   120 
       
   121 // ---------------------------------------------------------------------------
       
   122 // CPbkxRclContactUpdater::UpdateContactL
       
   123 // ---------------------------------------------------------------------------
       
   124 //
       
   125 HBufC* CPbkxRclContactUpdater::UpdateContactL( TPbkContactItemField& aField )
       
   126     {
       
   127     FUNC_LOG;
       
   128 
       
   129     // first ask user to select the contact in which the field is added
       
   130     CPbkSingleEntryFetchDlg::TParams params;
       
   131     params.iContactView = &iEngine.AllContactsView();
       
   132 
       
   133     CPbkSingleEntryFetchDlg* fetchDlg = CPbkSingleEntryFetchDlg::NewL( params );
       
   134     fetchDlg->ResetWhenDestroyed( &fetchDlg );
       
   135     TInt res = 0;
       
   136     res = fetchDlg->ExecuteLD();
       
   137 
       
   138     CPbkContactItem* contactItem = NULL;
       
   139     HBufC* text = NULL;
       
   140     if ( res != 0 && params.iSelectedEntry != KNullContactId )
       
   141         {
       
   142         contactItem = iEngine.OpenContactL( params.iSelectedEntry );
       
   143         CleanupStack::PushL( contactItem );
       
   144         
       
   145         CPbkFieldInfo& fieldInfo = aField.FieldInfo();
       
   146         TPbkContactItemField* field = NULL;
       
   147         if ( fieldInfo.Multiplicity() == EPbkFieldMultiplicityOne )
       
   148             {
       
   149             // there can be only one field of this type. query user to select
       
   150             // a field in which data is to be saved
       
   151             field = SelectUpdatedFieldL( *contactItem, fieldInfo );
       
   152             }
       
   153         else
       
   154             {
       
   155             // add new field to contact
       
   156             field = &( contactItem->AddFieldL( aField.FieldInfo() ) );
       
   157             }
       
   158         
       
   159         if ( field != NULL )
       
   160             {
       
   161             if ( field->StorageType() == KStorageTypeText )
       
   162                 {
       
   163                 field->TextStorage()->SetTextL( aField.Text() );
       
   164                 }
       
   165             else if ( field->StorageType() == KStorageTypeDateTime )
       
   166                 {
       
   167                 field->DateTimeStorage()->SetTime( aField.Time() );
       
   168                 }
       
   169             iEngine.CommitContactL( *contactItem );
       
   170             // build string returned to the caller
       
   171             text = ConstructUpdatedTextL( *contactItem, *field );
       
   172             }
       
   173         else
       
   174             {
       
   175             iEngine.CloseContactL( contactItem->Id() );
       
   176             }
       
   177         
       
   178         CleanupStack::PopAndDestroy( contactItem );
       
   179         }
       
   180     return text;
       
   181     }
       
   182 
       
   183 // ---------------------------------------------------------------------------
       
   184 // CPbkxRclContactUpdater::SelectUpdatedFieldL
       
   185 // ---------------------------------------------------------------------------
       
   186 //
       
   187 TPbkContactItemField* CPbkxRclContactUpdater::SelectUpdatedFieldL(
       
   188     CPbkContactItem& aContactItem,
       
   189     CPbkFieldInfo& aFieldInfo )
       
   190     {
       
   191     FUNC_LOG;
       
   192     TPbkContactItemField* retField = NULL;
       
   193     TInt fieldCount = 0;
       
   194     CPbkFieldInfo* info = SelectFieldL( aFieldInfo, fieldCount );
       
   195     while ( info != NULL && retField == NULL )
       
   196         {
       
   197         retField = aContactItem.AddOrReturnUnusedFieldL( *info );
       
   198         // iterate until user selects field or cancels
       
   199         if ( retField == NULL )
       
   200             {
       
   201             // there is already given field. ask user if it is ok to replace
       
   202             // existing data
       
   203             HBufC* dlgText = StringLoader::LoadLC( 
       
   204                 R_QTN_RCL_REPLACE_EXISTING_DETAIL_NOTE,
       
   205                 info->FieldName() );
       
   206             CAknNoteDialog* dialog = new ( ELeave ) CAknNoteDialog();
       
   207             dialog->PrepareLC( R_RCL_CONFIRMATION_NOTE_YES_CANCEL );
       
   208             dialog->SetTextL( *dlgText );
       
   209             
       
   210             if ( dialog->RunLD() )
       
   211                 {
       
   212                 retField = aContactItem.FindField( *info );
       
   213                 }
       
   214             else
       
   215                 {
       
   216                 // user cancelled dialog
       
   217                 if ( fieldCount > 1 )
       
   218                     {
       
   219                     // show select field dialog again
       
   220                     info = SelectFieldL( aFieldInfo, fieldCount );
       
   221                     }
       
   222                 else
       
   223                     {
       
   224                     // exit the loop because user refused to update existing 
       
   225                     // field and there are no other choices for the fields
       
   226                     // to be updated
       
   227                     info = NULL;
       
   228                     }
       
   229                 }
       
   230             CleanupStack::PopAndDestroy( dlgText );
       
   231             }
       
   232         }
       
   233     return retField;
       
   234     }
       
   235 
       
   236 // ---------------------------------------------------------------------------
       
   237 // CPbkxRclContactUpdater::ConstructUpdatedTextL
       
   238 // ---------------------------------------------------------------------------
       
   239 //
       
   240 HBufC* CPbkxRclContactUpdater::ConstructUpdatedTextL(
       
   241     CPbkContactItem& aContactItem,
       
   242     TPbkContactItemField& aField )
       
   243     {
       
   244     FUNC_LOG;
       
   245 
       
   246     HBufC* firstName = PbkxRclUtils::FieldTextL( 
       
   247         &aContactItem, 
       
   248         EPbkFieldIdFirstName );
       
   249     CleanupStack::PushL( firstName );
       
   250     
       
   251     HBufC* lastName = PbkxRclUtils::FieldTextL( 
       
   252         &aContactItem, 
       
   253         EPbkFieldIdLastName );
       
   254     CleanupStack::PushL( lastName );
       
   255     
       
   256     RBuf name;
       
   257     CleanupClosePushL( name );
       
   258     // +1 comes for the space in the format
       
   259     name.CreateL( firstName->Length() + lastName->Length() + 1 );
       
   260     
       
   261     name.Format( KNameFormat, firstName, lastName );
       
   262            
       
   263     CDesCArrayFlat* textArray = 
       
   264         new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
       
   265     CleanupStack::PushL( textArray );
       
   266     textArray->AppendL( aField.FieldInfo().FieldName() );
       
   267     textArray->AppendL( name );
       
   268     
       
   269     HBufC* text = StringLoader::LoadL( 
       
   270         R_QTN_RCL_UPDATE_NOTE,
       
   271         *textArray );
       
   272     
       
   273     CleanupStack::PopAndDestroy( textArray );
       
   274     CleanupStack::PopAndDestroy( &name );
       
   275     CleanupStack::PopAndDestroy( lastName );
       
   276     CleanupStack::PopAndDestroy( firstName );
       
   277     
       
   278     return text;
       
   279     }
       
   280 
       
   281 // ---------------------------------------------------------------------------
       
   282 // CPbkxRclContactUpdater::SelectFieldL
       
   283 // ---------------------------------------------------------------------------
       
   284 //
       
   285 CPbkFieldInfo* CPbkxRclContactUpdater::SelectFieldL(
       
   286     CPbkFieldInfo& aFieldInfo,
       
   287     TInt& aFieldCount )
       
   288     {
       
   289     FUNC_LOG;
       
   290     // construct possible field types
       
   291     const CPbkFieldsInfo& fields = iEngine.FieldsInfo();
       
   292     CArrayPtrFlat<CPbkFieldInfo>* fieldArray = 
       
   293         new ( ELeave ) CArrayPtrFlat<CPbkFieldInfo>( KArrayGranularity );
       
   294     CleanupStack::PushL( fieldArray );
       
   295 
       
   296     TPbkFieldLocation locs[] = { 
       
   297         EPbkFieldLocationNone, 
       
   298         EPbkFieldLocationHome,
       
   299         EPbkFieldLocationWork };
       
   300 
       
   301     TInt locCount = sizeof( locs ) / sizeof( TPbkFieldLocation );
       
   302 
       
   303     for ( TInt i = 0; i < locCount; i++ )
       
   304         {
       
   305         CPbkFieldInfo* field = fields.Find( aFieldInfo.FieldId(), locs[i] );
       
   306         if ( field != NULL )
       
   307             {
       
   308             fieldArray->AppendL( field );
       
   309             }
       
   310         }
       
   311     
       
   312     aFieldCount = fieldArray->Count();
       
   313     CPbkFieldInfo* retField = NULL;
       
   314     if ( fieldArray->Count() == 1 )
       
   315         {
       
   316         retField = ( *fieldArray )[0];
       
   317         }
       
   318     else
       
   319         {
       
   320         CPbkItemTypeSelectAddToExisting* selectionDlg = 
       
   321             new ( ELeave ) CPbkItemTypeSelectAddToExisting();
       
   322         retField = selectionDlg->ExecuteLD( *fieldArray );
       
   323         }
       
   324     CleanupStack::PopAndDestroy( fieldArray );
       
   325     return retField;
       
   326     }
       
   327