--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/remotecontactlookup/engine/src/cpbkxrclcontactupdater.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,326 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of the class CPbkxRclContactUpdater.
+*
+*/
+
+
+#include "emailtrace.h"
+#include <pbk2rclengine.rsg>
+#include <CPbkSingleEntryFetchDlg.h>
+#include <CPbkContactEngine.h>
+#include <CPbkMemoryEntryAddItemDlg.h>
+#include <StringLoader.h>
+#include <CPbkFieldInfo.h>
+#include <CPbkFieldsInfo.h>
+#include <aknnotedialog.h>
+#include <coemain.h>
+#include <data_caging_path_literals.hrh>
+#include <bautils.h>
+
+#include "cpbkxrclcontactupdater.h"
+#include "pbkxrclutils.h"
+#include "pbkxrclengineconstants.h"
+#include "pbkxremotecontactlookuppanic.h"
+
+// Local constants
+_LIT(KPbkRomFileDrive, "z:");
+_LIT(KPbkViewResourceFile, "PbkView.rsc");
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::NewL
+// ---------------------------------------------------------------------------
+//
+CPbkxRclContactUpdater* CPbkxRclContactUpdater::NewL(
+ CPbkContactEngine& aEngine )
+ {
+ FUNC_LOG;
+ CPbkxRclContactUpdater* updater = CPbkxRclContactUpdater::NewLC( aEngine );
+ CleanupStack::Pop( updater );
+ return updater;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::NewLC
+// ---------------------------------------------------------------------------
+//
+CPbkxRclContactUpdater* CPbkxRclContactUpdater::NewLC(
+ CPbkContactEngine& aEngine )
+ {
+ FUNC_LOG;
+ CPbkxRclContactUpdater* updater =
+ new ( ELeave ) CPbkxRclContactUpdater( aEngine );
+ CleanupStack::PushL( updater );
+ updater->ConstructL();
+ return updater;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::CPbkxRclContactUpdater
+// ---------------------------------------------------------------------------
+//
+CPbkxRclContactUpdater::CPbkxRclContactUpdater( CPbkContactEngine& aEngine ) :
+ CBase(), iEngine( aEngine )
+ {
+ FUNC_LOG;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::~CPbkxRclContactUpdater
+// ---------------------------------------------------------------------------
+//
+CPbkxRclContactUpdater::~CPbkxRclContactUpdater()
+ {
+ FUNC_LOG;
+ CCoeEnv::Static()->DeleteResourceFile( iResourceFileOffset );
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CPbkxRclContactUpdater::ConstructL()
+ {
+ FUNC_LOG;
+
+ // First load Phonebook resource file so that dialog will find resources
+ CCoeEnv* coeEnv = CCoeEnv::Static();
+ TFileName resourceFile;
+ resourceFile.Copy( KPbkRomFileDrive );
+ resourceFile.Append( KDC_RESOURCE_FILES_DIR );
+ resourceFile.Append( KPbkViewResourceFile );
+
+ BaflUtils::NearestLanguageFile( coeEnv->FsSession(), resourceFile );
+
+ TRAPD( status,
+ iResourceFileOffset = coeEnv->AddResourceFileL( resourceFile ) );
+
+ if( status != KErrNone )
+ {
+ PbkxRclPanic( EPbkxRclPanicGeneral );
+ }
+ else
+ {
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::UpdateContactL
+// ---------------------------------------------------------------------------
+//
+HBufC* CPbkxRclContactUpdater::UpdateContactL( TPbkContactItemField& aField )
+ {
+ FUNC_LOG;
+
+ // first ask user to select the contact in which the field is added
+ CPbkSingleEntryFetchDlg::TParams params;
+ params.iContactView = &iEngine.AllContactsView();
+
+ CPbkSingleEntryFetchDlg* fetchDlg = CPbkSingleEntryFetchDlg::NewL( params );
+ fetchDlg->ResetWhenDestroyed( &fetchDlg );
+ TInt res = 0;
+ res = fetchDlg->ExecuteLD();
+
+ CPbkContactItem* contactItem = NULL;
+ HBufC* text = NULL;
+ if ( res != 0 && params.iSelectedEntry != KNullContactId )
+ {
+ contactItem = iEngine.OpenContactL( params.iSelectedEntry );
+ CleanupStack::PushL( contactItem );
+
+ CPbkFieldInfo& fieldInfo = aField.FieldInfo();
+ TPbkContactItemField* field = NULL;
+ if ( fieldInfo.Multiplicity() == EPbkFieldMultiplicityOne )
+ {
+ // there can be only one field of this type. query user to select
+ // a field in which data is to be saved
+ field = SelectUpdatedFieldL( *contactItem, fieldInfo );
+ }
+ else
+ {
+ // add new field to contact
+ field = &( contactItem->AddFieldL( aField.FieldInfo() ) );
+ }
+
+ if ( field != NULL )
+ {
+ if ( field->StorageType() == KStorageTypeText )
+ {
+ field->TextStorage()->SetTextL( aField.Text() );
+ }
+ else if ( field->StorageType() == KStorageTypeDateTime )
+ {
+ field->DateTimeStorage()->SetTime( aField.Time() );
+ }
+ iEngine.CommitContactL( *contactItem );
+ // build string returned to the caller
+ text = ConstructUpdatedTextL( *contactItem, *field );
+ }
+ else
+ {
+ iEngine.CloseContactL( contactItem->Id() );
+ }
+
+ CleanupStack::PopAndDestroy( contactItem );
+ }
+ return text;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::SelectUpdatedFieldL
+// ---------------------------------------------------------------------------
+//
+TPbkContactItemField* CPbkxRclContactUpdater::SelectUpdatedFieldL(
+ CPbkContactItem& aContactItem,
+ CPbkFieldInfo& aFieldInfo )
+ {
+ FUNC_LOG;
+ TPbkContactItemField* retField = NULL;
+ TInt fieldCount = 0;
+ CPbkFieldInfo* info = SelectFieldL( aFieldInfo, fieldCount );
+ while ( info != NULL && retField == NULL )
+ {
+ retField = aContactItem.AddOrReturnUnusedFieldL( *info );
+ // iterate until user selects field or cancels
+ if ( retField == NULL )
+ {
+ // there is already given field. ask user if it is ok to replace
+ // existing data
+ HBufC* dlgText = StringLoader::LoadLC(
+ R_QTN_RCL_REPLACE_EXISTING_DETAIL_NOTE,
+ info->FieldName() );
+ CAknNoteDialog* dialog = new ( ELeave ) CAknNoteDialog();
+ dialog->PrepareLC( R_RCL_CONFIRMATION_NOTE_YES_CANCEL );
+ dialog->SetTextL( *dlgText );
+
+ if ( dialog->RunLD() )
+ {
+ retField = aContactItem.FindField( *info );
+ }
+ else
+ {
+ // user cancelled dialog
+ if ( fieldCount > 1 )
+ {
+ // show select field dialog again
+ info = SelectFieldL( aFieldInfo, fieldCount );
+ }
+ else
+ {
+ // exit the loop because user refused to update existing
+ // field and there are no other choices for the fields
+ // to be updated
+ info = NULL;
+ }
+ }
+ CleanupStack::PopAndDestroy( dlgText );
+ }
+ }
+ return retField;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::ConstructUpdatedTextL
+// ---------------------------------------------------------------------------
+//
+HBufC* CPbkxRclContactUpdater::ConstructUpdatedTextL(
+ CPbkContactItem& aContactItem,
+ TPbkContactItemField& aField )
+ {
+ FUNC_LOG;
+
+ HBufC* firstName = PbkxRclUtils::FieldTextL(
+ &aContactItem,
+ EPbkFieldIdFirstName );
+ CleanupStack::PushL( firstName );
+
+ HBufC* lastName = PbkxRclUtils::FieldTextL(
+ &aContactItem,
+ EPbkFieldIdLastName );
+ CleanupStack::PushL( lastName );
+
+ RBuf name;
+ CleanupClosePushL( name );
+ // +1 comes for the space in the format
+ name.CreateL( firstName->Length() + lastName->Length() + 1 );
+
+ name.Format( KNameFormat, firstName, lastName );
+
+ CDesCArrayFlat* textArray =
+ new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+ CleanupStack::PushL( textArray );
+ textArray->AppendL( aField.FieldInfo().FieldName() );
+ textArray->AppendL( name );
+
+ HBufC* text = StringLoader::LoadL(
+ R_QTN_RCL_UPDATE_NOTE,
+ *textArray );
+
+ CleanupStack::PopAndDestroy( textArray );
+ CleanupStack::PopAndDestroy( &name );
+ CleanupStack::PopAndDestroy( lastName );
+ CleanupStack::PopAndDestroy( firstName );
+
+ return text;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbkxRclContactUpdater::SelectFieldL
+// ---------------------------------------------------------------------------
+//
+CPbkFieldInfo* CPbkxRclContactUpdater::SelectFieldL(
+ CPbkFieldInfo& aFieldInfo,
+ TInt& aFieldCount )
+ {
+ FUNC_LOG;
+ // construct possible field types
+ const CPbkFieldsInfo& fields = iEngine.FieldsInfo();
+ CArrayPtrFlat<CPbkFieldInfo>* fieldArray =
+ new ( ELeave ) CArrayPtrFlat<CPbkFieldInfo>( KArrayGranularity );
+ CleanupStack::PushL( fieldArray );
+
+ TPbkFieldLocation locs[] = {
+ EPbkFieldLocationNone,
+ EPbkFieldLocationHome,
+ EPbkFieldLocationWork };
+
+ TInt locCount = sizeof( locs ) / sizeof( TPbkFieldLocation );
+
+ for ( TInt i = 0; i < locCount; i++ )
+ {
+ CPbkFieldInfo* field = fields.Find( aFieldInfo.FieldId(), locs[i] );
+ if ( field != NULL )
+ {
+ fieldArray->AppendL( field );
+ }
+ }
+
+ aFieldCount = fieldArray->Count();
+ CPbkFieldInfo* retField = NULL;
+ if ( fieldArray->Count() == 1 )
+ {
+ retField = ( *fieldArray )[0];
+ }
+ else
+ {
+ CPbkItemTypeSelectAddToExisting* selectionDlg =
+ new ( ELeave ) CPbkItemTypeSelectAddToExisting();
+ retField = selectionDlg->ExecuteLD( *fieldArray );
+ }
+ CleanupStack::PopAndDestroy( fieldArray );
+ return retField;
+ }
+