phonebookui/Phonebook2/UIControls/src/CPbk2ContactEditorDlgImpl.cpp
changeset 0 e686773b3f54
child 3 04ab22b956c2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2ContactEditorDlgImpl.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,3287 @@
+/*
+* Copyright (c) 2005-2007 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:  Phonebook 2 contact editor dialog implementation.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbk2ContactEditorDlgImpl.h"
+
+// Phonebook 2
+#include "Pbk2UIControls.hrh"
+#include "MPbk2ContactEditorStrategy.h"
+#include "CPbk2ContactEditorFieldArray.h"
+#include "MPbk2ContactEditorField.h"
+#include <MPbk2ContactEditorField2.h>
+#include "CPbk2AddItemManager.h"
+#include "Pbk2TitlePanePictureFactory.h"
+#include "TPbk2DeleteItemManager.h"
+#include <MPbk2StoreObservationRegister.h>
+#include <MPbk2ApplicationServices.h>
+#include <CPbk2PresentationContact.h>
+#include <CPbk2PresentationContactField.h>
+#include <CPbk2PresentationContactFieldCollection.h>
+#include <MPbk2FieldProperty.h>
+#include <MPbk2FieldProperty2.h>
+#include <CPbk2FieldPropertyArray.h>
+#include <Pbk2UIControls.rsg>
+#include <MPbk2ContactNameFormatter.h>
+#include <MPbk2ContactEditorExtension.h>
+#include <CPbk2StoreConfiguration.h>
+#include <CPbk2ContactRelocator.h>
+#include <MPbk2ContactEditorEventObserver.h>
+#include <MPbk2EditedContactObserver.h>
+#include <CPbk2UIExtensionManager.h>
+#include <MPbk2UIExtensionFactory.h>
+#include <MPbk2ContactEditorContactRelocator.h>
+#include <CPbk2AppUiBase.h>
+#include <CPbk2StorePropertyArray.h>
+#include <CPbk2StoreProperty.h>
+#include <MPbk2ExitCallback.h>
+#include <CPbk2IconInfoContainer.h>
+#include <CPbk2IconFactory.h>
+#include "Pbk2RingtoneCommands.h" 
+#include "Pbk2ImageCommands.h"
+#include "CPbk2ContactEditorUIAddressField.h"
+#include "MPbk2ContactEditorUIField.h"
+#include "Pbk2ContactEditorFieldFactory.h"
+#include "Pbk2AddressTools.h"
+#include "MPbk2UIField.h"
+#include "CPbk2ContactEditorRingtoneField.h"
+#include "CPbk2ContactEditorImageField.h"
+#include "CPbk2ContactEditorReadonlyField.h" 
+#include "Pbk2EditorLineIds.hrh" 
+#include <Pbk2Config.hrh>
+#include <Pbk2Commands.hrh>
+#include "Pbk2FieldProperty.hrh"
+#include "Pbk2IconId.hrh"
+#include <Pbk2UID.h>
+#include <pbk2mapcommands.hrh>
+
+// Virtual Phonebook
+#include <CVPbkContactManager.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactFieldTextData.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactFieldData.h>
+#include <MVPbkFieldType.h>
+#include <TVPbkFieldVersitProperty.h>
+#include <ccappmycardpluginrsc.rsg>
+
+#include <VPbkEng.rsg> 
+#include <VPbkFieldType.hrh>
+#include <VPbkContactStoreUris.h>
+
+// System includes
+#include <akntitle.h>
+#include <aknnavi.h>
+#include <StringLoader.h>
+#include <eikcapc.h>
+#include <barsread.h>
+#include <aknnotewrappers.h>
+#include <hlplch.h>
+#include <aknnavide.h>
+#include <akninputblock.h>
+#include <coemain.h>
+
+_LIT( KCCAppMyCardPluginResFileName, "\\resource\\ccappmycardpluginrsc.rsc");
+
+/// Unnamed namespace for local definitions
+namespace {
+
+const TInt KEditorNameFormatFlags = MPbk2ContactNameFormatter::EUseSeparator;
+
+#ifdef _DEBUG
+enum TPanicCode
+    {
+    EHandleControlStateChangeL_NullField = 1,
+    EPanic_IsControlEmptyL_OOB,
+    EPanic_EditorField_OOB
+    };
+
+void Panic(TInt aReason)
+    {
+    _LIT(KPanicText, "CPbk2ContactEditorDlgImpl");
+    User::Panic(KPanicText, aReason);
+    }
+#endif // _DEBUG
+
+/**
+ * Displays a store not available note.
+ *
+ * @param aName     Store name.
+ */
+void ShowStoreNotAvailableNoteL( const TDesC& aName )
+    {
+    if ( aName.Length() > 0 )
+        {
+        HBufC* text = StringLoader::LoadLC( R_QTN_PHOB_STORE_NOT_AVAILABLE,
+            aName );
+        CAknInformationNote* note = new ( ELeave ) CAknInformationNote;
+        note->ExecuteLD( *text );
+        CleanupStack::PopAndDestroy( text );
+        }
+    }
+
+/**
+ * Decides whether to leave or not in case of an error.
+ * Performs some filtering of errors.
+ *
+ * @param aError    Error code.
+ */
+void DecideToLeaveL( TInt aError )
+    {
+    if ( aError != KErrInUse && aError != KErrNone )
+        {
+        User::Leave( aError );
+        }
+    }
+
+} /// namespace
+
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CPbk2ContactEditorDlgImpl
+// --------------------------------------------------------------------------
+//
+CPbk2ContactEditorDlgImpl::CPbk2ContactEditorDlgImpl
+    ( TPbk2ContactEditorParams& aParams,
+      CPbk2PresentationContact& aContact,
+      CPbk2FieldPropertyArray& aFieldProperties,
+      MPbk2EditedContactObserver& aContactObserver,
+      MPbk2ContactEditorStrategy& aEditorStrategy,
+      MPbk2ContactEditorContactRelocator& aRelocator,
+      MPbk2ApplicationServices* aAppServices,
+      HBufC* aTitleText ) :
+        iParams( aParams ),
+        iEditorStrategy( aEditorStrategy ),
+        iFieldProperties( aFieldProperties ),
+        iContact( aContact ),
+        iContactObserver( aContactObserver ),
+        iRelocator( aRelocator ),
+        iEndKeyWasPressed( EFalse ),
+        iAddressViewStandalone( EFalse ),
+        iAppServices( aAppServices ),
+        iTitleText( aTitleText ),
+        iPbk2UiResource( *CCoeEnv::Static() )        
+    {
+    // Exit is approved by default
+    iExitRecord.Set( EExitApproved );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::~CPbk2ContactEditorDlgImpl
+// --------------------------------------------------------------------------
+//
+CPbk2ContactEditorDlgImpl::~CPbk2ContactEditorDlgImpl()
+    {
+    if ( iWaitFinish && iWaitFinish->IsStarted() )
+        {
+        iWaitFinish->AsyncStop();
+        }
+    delete iWaitFinish;
+    delete iInputBlock;
+    
+    if ( iSelfPtr )
+        {
+        *iSelfPtr = NULL;
+        }
+    
+    if( iAppServices )
+    	{
+    	iAppServices->StoreObservationRegister().DeregisterStoreEvents( *this );
+    	}
+    else
+    	{
+    	Phonebook2::Pbk2AppUi()->ApplicationServices().
+    	        StoreObservationRegister().DeregisterStoreEvents( *this );
+    	}
+              
+    if ( iEikonEnv && iContextMenuBar )
+        {
+        iEikonEnv->EikAppUi()->RemoveFromStack( iContextMenuBar );
+        delete iContextMenuBar;
+        }
+
+    // Restore the titlepane text
+    if (iTitlePane && iStoredTitlePaneText)
+        {
+        // iTitlePane takes ownership of iStoredTitlePaneText
+        iTitlePane->SetText(iStoredTitlePaneText);
+        }
+
+    // Reset title pane picture
+    if( iTitlePane )
+        {
+        iTitlePane->SetSmallPicture( NULL, NULL, EFalse );
+        }
+
+    // Remove empty status pane
+    if (iNaviContainer)
+        {
+        iNaviContainer->Pop();
+        }
+
+    delete iStoreContact;
+    delete iFieldFactory;
+    delete iPbk2BaseCommand;
+    delete iEditorExtension;
+    delete iUiFieldArray;
+    Release(iExtensionManager);
+        
+    if( iCommandId == EEikCmdExit || iCommandId == EAknCmdExit )
+		{	
+		CAknAppUi* appUi = static_cast<CAknAppUi*>( CCoeEnv::Static()->AppUi() );      		
+			
+		if( appUi )
+			{
+			TFileName file;
+			file.Copy( KCCAppMyCardPluginResFileName );
+			iPbk2UiResource.OpenL( file );
+		
+			HBufC* title = StringLoader::LoadLC( R_QTN_MYCARD_EDITOR_TITLE );	
+			
+			iPbk2UiResource.Close();			
+			TBool okToExit = EFalse;
+			
+			if( iTitleText && iTitleText->CompareC( title->Des() ) == 0 )
+				{
+				okToExit = ETrue;
+				}
+			
+			CleanupStack::PopAndDestroy(); // title
+								
+			if ( okToExit )
+				{
+				appUi->ProcessCommandL( EAknCmdExit );
+				}								
+			}
+		}    
+    
+	delete iTitleText;    
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2ContactEditorDlgImpl* CPbk2ContactEditorDlgImpl::NewL(
+        TPbk2ContactEditorParams& aParams,
+        CPbk2PresentationContact& aContact,
+        CPbk2FieldPropertyArray& aFieldProperties,
+        MPbk2EditedContactObserver& aContactObserver,
+        MPbk2ContactEditorStrategy& aEditorStrategy,
+        MPbk2ContactEditorContactRelocator& aRelocator)
+    {	
+    CPbk2ContactEditorDlgImpl* self =
+        new ( ELeave ) CPbk2ContactEditorDlgImpl(aParams, aContact,
+            aFieldProperties, aContactObserver,
+            aEditorStrategy, aRelocator);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2ContactEditorDlgImpl* CPbk2ContactEditorDlgImpl::NewL(
+		TPbk2ContactEditorParams& aParams,
+		CPbk2PresentationContact& aContact,
+		CPbk2FieldPropertyArray& aFieldProperties,
+		MPbk2EditedContactObserver& aContactObserver,
+		MPbk2ContactEditorStrategy& aEditorStrategy,
+		MPbk2ContactEditorContactRelocator& aRelocator,
+		MPbk2ApplicationServices* aAppServices,
+		HBufC* aTitleText )
+	{
+	CPbk2ContactEditorDlgImpl* self =
+		new ( ELeave ) CPbk2ContactEditorDlgImpl(aParams, aContact,
+			aFieldProperties, aContactObserver,
+			aEditorStrategy, aRelocator, aAppServices, aTitleText );
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ConstructL()
+    {
+    CAknDialog::ConstructL(R_PBK2_CONTACTEDITOR_MENUBAR);
+    
+    if(iParams.iActiveView != TPbk2ContactEditorParams::EEditorView)
+        {
+        iParams.iFocusedContactField = NULL;
+        }
+    if(iParams.iFocusedContactField)
+        {
+        const MVPbkFieldType* type = iParams.iFocusedContactField->BestMatchingFieldType();
+        const TArray<TVPbkFieldVersitProperty> propArr = type->VersitProperties();
+        if(propArr.Count())
+            {
+            const TVPbkFieldVersitProperty prop = propArr[0];
+            if(prop.Name() == EVPbkVersitNameADR)
+                {
+                if(prop.Parameters().Contains(EVPbkVersitParamHOME))
+                    {
+                    iParams.iActiveView = TPbk2ContactEditorParams::EEditorAddressHomeView;
+                    }
+                else if(prop.Parameters().Contains(EVPbkVersitParamWORK))
+                    {
+                    iParams.iActiveView = TPbk2ContactEditorParams::EEditorAddressOfficeView;
+                    }
+                else
+                    {
+                    iParams.iActiveView = TPbk2ContactEditorParams::EEditorAddressView;
+                    }
+                iAddressViewStandalone = ETrue;
+                iParams.iFocusedContactField = NULL;
+                }
+            }
+        }
+    
+    // Register to listen store events, so that we can close editor if
+    // iContact's store becomes unavailable.
+    
+    /*
+	 * Use iAppServices if provided. This is to enable editor use outside from pbk2 context
+	 */
+    if( iAppServices )
+    	{
+    	iAppServices->StoreObservationRegister().RegisterStoreEventsL( *this );
+    	iNameFormatter = &iAppServices->NameFormatter();
+    	}
+    else
+    	{
+    	Phonebook2::Pbk2AppUi()->ApplicationServices().
+			StoreObservationRegister().RegisterStoreEventsL( *this );
+    	iNameFormatter =
+    	        &Phonebook2::Pbk2AppUi()->ApplicationServices().NameFormatter();
+    	}
+
+   
+    StoreTitlePaneTextL();
+    ConstructContextMenuL();
+    ConstructNaviPaneL();
+
+    iExtensionManager = CPbk2UIExtensionManager::InstanceL();
+    
+    /*
+	 * Use iAppServices if provided. This is to enable editor use outside from pbk2 context
+	 */
+    CVPbkContactManager* manager = NULL;
+    if( iAppServices )
+    	{
+    	manager = &iAppServices->ContactManager();
+    	}
+    else
+    	{
+    	manager = &Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager();
+    	}
+    
+    iEditorExtension = iExtensionManager->FactoryL()->
+        CreatePbk2ContactEditorExtensionL( *manager, iContact, *this );
+
+    iFieldFactory = CPbk2ContactEditorFieldFactory::NewL(*this, *iEditorExtension);
+    iUiFieldArray = CPbk2ContactEditorFieldArray::NewL(
+    *manager, iContact, *this, *iFieldFactory, iAppServices );	
+    
+    iUseState = EUseReady;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ExecuteLD
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ExecuteLD()
+    {
+    CleanupStack::PushL( this );
+
+    // Set status pane layout to the Phonebook 2 one
+    CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
+    if (statusPane)
+        {
+        statusPane->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_USUAL);
+        }
+
+    CleanupStack::Pop( this );
+    CAknForm::ExecuteLD(R_PBK2_EDIT_MEMORY_ENTRY_DIALOG);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CreateCustomControlL
+// --------------------------------------------------------------------------
+//
+SEikControlInfo CPbk2ContactEditorDlgImpl::CreateCustomControlL(
+    TInt /*aControlType*/ )
+    {
+    iLastCreatedCustomControl = NULL;
+    SEikControlInfo control = {NULL, 0, 0};
+    iLastCreatedCustomControl = new (ELeave) CPbk2ContactEditorReadonlyField();  
+    control.iControl = iLastCreatedCustomControl; 
+    control.iTrailerTextId = 0;
+    control.iFlags = 0;
+    return control;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ContactEditorUiBuilderExtension
+// --------------------------------------------------------------------------
+//
+TAny* CPbk2ContactEditorDlgImpl::ContactEditorUiBuilderExtension( 
+    TUid /*aExtensionUid*/ )
+    {
+    //return extension point of MPbk2ContactEditorUiBuilderExtension
+    return static_cast<MPbk2ContactEditorUiBuilderExtension*>(this);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::AddCustomFieldToFormL
+// --------------------------------------------------------------------------
+//   
+CCoeControl* CPbk2ContactEditorDlgImpl::AddCustomFieldToFormL(
+    TInt aIndex,TInt aResourceId)
+    {
+    InsertLineL(aIndex, aResourceId);
+    // Return value is updated in CreateCustomControlL()
+    return iLastCreatedCustomControl;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::HandleCustomFieldCommandL
+// --------------------------------------------------------------------------
+//   
+TBool CPbk2ContactEditorDlgImpl::HandleCustomFieldCommandL(TInt aCommand )
+    {
+    ProcessCommandL( aCommand );
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ConvertCustomControlTypeToBaseControlType()
+// Provide correct base type for custom contols
+// -----------------------------------------------------------------------------
+//
+MEikDialogPageObserver::TFormControlTypes CPbk2ContactEditorDlgImpl::
+    ConvertCustomControlTypeToBaseControlType(TInt aControlType) const
+    {
+    MEikDialogPageObserver::TFormControlTypes ret = 
+        MEikDialogPageObserver::EUnknownType;
+    
+    switch(aControlType)
+        {
+        case EPbk2FieldCtrlTypeImageEditor:
+        case EPbk2FieldCtrlTypeRingtoneEditor:
+        case EPbk2FieldCtrlTypeExtAddressEditor:
+        case EPbk2FieldCtrlTypeExtAddressHomeEditor:
+        case EPbk2FieldCtrlTypeExtAddressOfficeEditor:
+        case EPbk2FieldCtrlTypeExtAssignFromMapsEditor:
+        {
+            ret = MEikDialogPageObserver::EEdwinDerived;
+            }
+            break;
+        default:
+            {
+            ret = MEikDialogPageObserver::EUnknownType;
+            }
+            break;
+        }
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::HandlePointerEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::HandlePointerEventL( 
+    const TPointerEvent& aPointerEvent )
+    {
+    //Here we can prevent recursive execution of ExecuteBaseCommandL if needed 
+    //as touch events are handled in it too. So it may case multiple callbacks to here if 
+    //user repeats the same pointer event very quickly using options menu.
+    // if(!iCommandPending) //seems that this check is not needed
+        {
+        CAknForm::HandlePointerEventL( aPointerEvent );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::HandleResourceChange
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::HandleResourceChange( TInt aType )
+    {
+    // Handle change in layout orientation
+    if ( aType == KEikDynamicLayoutVariantSwitch )
+        {
+        // Set status pane layout to the Phonebook 2 one
+        CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
+        if ( statusPane )
+            {
+            TRAP_IGNORE(
+                    statusPane->SwitchLayoutL(
+                            R_AVKON_STATUS_PANE_LAYOUT_USUAL
+                            )
+            );
+            }
+        }
+    
+    CAknForm::HandleResourceChange( aType );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::AddItemToContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::AddItemToContactL
+      ( TInt aFieldTypeResourceId,
+        const TDesC& aFieldTypeXspName, 
+        TBool aSetFocus )
+    {
+    // Store the original parameter value, since it is
+    // changed by AddFieldsL
+    TInt origParam = aFieldTypeResourceId;
+    TPtrC xSpName = aFieldTypeXspName;
+
+    CPbk2AddItemManager* addItemManager = CPbk2AddItemManager::NewL
+            (iContact, *iUiFieldArray, iParams, iAppServices );
+    CleanupStack::PushL(addItemManager);
+    CPbk2AddItemManager::TReturnValue ret = addItemManager->AddFieldsL(
+            aFieldTypeResourceId, xSpName);
+
+    if (ret.iControlId == KErrAlreadyExists)
+        {
+        // cannot add more than one of this field type
+        // find and focus that
+        TInt fieldArrayCount( iUiFieldArray->Count() );
+        for (TInt i(0); i < fieldArrayCount && ret.iControlId
+                == KErrAlreadyExists; ++i)
+            {
+            if (!iUiFieldArray->At(i).ContactEditorField())
+                {
+                continue;
+                }
+            const MVPbkFieldType* fieldType =
+                iUiFieldArray->At(i).ContactEditorField()->ContactField().
+                    BestMatchingFieldType();
+            if(fieldType && fieldType->FieldTypeResId() == aFieldTypeResourceId)
+                {
+                ret.iControlId = iUiFieldArray->At(i).ControlId();
+                }
+            }
+        }
+
+    if (ret.iControlId > 0)
+        {
+        if (aSetFocus)
+            {
+            TryChangeFocusL(ret.iControlId);
+            MPbk2ContactEditorField* editorField = iUiFieldArray->Find( ret.iControlId )->ContactEditorField();
+            MVPbkStoreContactField& storeContactField = editorField->ContactField();
+            iParams.iFocusedContactField = &storeContactField;
+            // Call this after adding or deleting lines
+            UpdatePageL( ETrue );
+            // Must be DrawNow and not DrawDeferred otherwise field label
+            // and content of the following field will be incorrect
+            DrawNow();
+            }
+        }
+    else if (ret.iControlId == KErrNotSupported && origParam == KErrNotFound)
+        {
+        iUiFieldArray->SaveFieldsL();
+        iRelocator.RelocateContactL(aFieldTypeResourceId, xSpName,
+            Pbk2ContactRelocator::EPbk2DisplayStoreDoesNotSupportQuery);
+        }
+    else if ( iParams.iActiveView == TPbk2ContactEditorParams::EEditorView )
+        {
+        switch( ret.iGruopId )
+            {
+            case EPbk2FieldGroupIdPostalAddress:
+                if(iUiFieldArray->Count())
+                    {
+                    iUiFieldArray->AddNewFieldL( ret.iGruopId );
+                    ExecuteAddressDlgL( TPbk2ContactEditorParams::EEditorAddressView );
+                    }
+                break;
+            case EPbk2FieldGroupIdHomeAddress:
+                iUiFieldArray->AddNewFieldL( ret.iGruopId );
+                ExecuteAddressDlgL( TPbk2ContactEditorParams::EEditorAddressHomeView );
+                break;
+            case EPbk2FieldGroupIdCompanyAddress:
+                iUiFieldArray->AddNewFieldL( ret.iGruopId );
+                ExecuteAddressDlgL( TPbk2ContactEditorParams::EEditorAddressOfficeView );
+                break;
+            }
+        }
+    CleanupStack::PopAndDestroy(addItemManager);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CloseWithoutSaving
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CloseWithoutSaving( TBool aInformObserver )
+    {
+    CloseDialog( 
+        MVPbkContactObserver::EContactOperationUnknown, 
+        aInformObserver );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::TryChangeFocusWithTypeIdL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::TryChangeFocusWithTypeIdL
+        ( TInt aFieldTypeResId, const TDesC& aFieldTypeXSpName )
+    {
+    const TInt count( iUiFieldArray->Count() );
+    for ( TInt i = 0; i < count; ++i )
+        {
+        if (!iUiFieldArray->At(i).ContactEditorField())
+            {
+            continue;
+            }
+        MPbk2ContactEditorField& uiEditorField =
+                *(iUiFieldArray->At(i).ContactEditorField());
+        const MVPbkFieldType* fieldType =
+            uiEditorField.ContactField().BestMatchingFieldType();
+        TInt candidate( KErrNotFound );
+        if ( fieldType )
+            {
+            candidate = fieldType->FieldTypeResId();
+            }
+
+        MPbk2FieldProperty2* fieldPropertyExtension =
+            reinterpret_cast<MPbk2FieldProperty2*>(
+                const_cast<MPbk2FieldProperty&>( uiEditorField.FieldProperty() ).
+                    FieldPropertyExtension(
+                        KMPbk2FieldPropertyExtension2Uid ) );
+        
+        if ( fieldPropertyExtension != NULL ) 
+            {
+            if ( (aFieldTypeResId == candidate ) &&
+                    !fieldPropertyExtension->XSpName().CompareF(
+                        aFieldTypeXSpName) )
+                {
+                TryChangeFocusL( uiEditorField.ControlId() );
+                MVPbkStoreContactField& storeContactField = uiEditorField.ContactField();
+                iParams.iFocusedContactField = &storeContactField;
+                // Must be DrawNow and not DrawDeferred otherwise field label
+                // and content of the following field will be incorrect
+                DrawNow();
+                break;
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::OfferKeyEventL
+// --------------------------------------------------------------------------
+//
+TKeyResponse CPbk2ContactEditorDlgImpl::OfferKeyEventL
+        ( const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+     TKeyResponse ret(EKeyWasNotConsumed);    
+
+     if(iAddressView)
+         {
+         return ret;
+         }
+     
+     /* Uncomment this code if it is necessary to enable navigation hardware keys
+      * on devices which have these keys (its Map Extension feature) 
+     if( aKeyEvent.iScanCode == EStdKeyApplicationD && aType == EEventKeyUp )
+         {
+         HandleCustomFieldCommandL(EPbk2ExtensionAssignFromMap);
+         return EKeyWasConsumed;
+         }
+             
+     if( aKeyEvent.iScanCode == EStdKeyApplicationE && aType == EEventKeyUp )
+         {
+         HandleCustomFieldCommandL(EPbk2ExtensionShowOnMap);
+         return EKeyWasConsumed;
+         }*/
+
+    // Display menu bar if the focused control doesnt consume selection keys
+    CPbk2ContactEditorArrayItem* currentField = iUiFieldArray->Find(
+            IdOfFocusControl());
+
+    if (currentField)
+        {
+        if (currentField->ContactEditorField()
+                && currentField->ContactEditorField()->ConsumesKeyEvent(
+                        aKeyEvent, aType))
+            {
+            ret = CAknForm::OfferKeyEventL(aKeyEvent, aType);
+            }
+        else if (currentField->ContactEditorUIField()
+                && currentField->ContactEditorUIField()->ConsumesKeyEvent(
+                        aKeyEvent, aType))
+            {
+            ret = CAknForm::OfferKeyEventL(aKeyEvent, aType);
+            }
+        }
+
+    if (ret != EKeyWasConsumed && aType == EEventKey && aKeyEvent.iCode
+            == EKeyOK)
+        {
+        iContextMenuBar->TryDisplayMenuBarL();
+        ret = EKeyWasConsumed;
+        }
+
+    if ( ret != EKeyWasConsumed && !iEndKeyWasPressed )
+        {
+        if ( aKeyEvent.iCode == EKeyEscape )
+            {
+            iEditorStrategy.StopQuery();
+            iEndKeyWasPressed = ETrue;
+            }
+        ret = CAknForm::OfferKeyEventL( aKeyEvent, aType );
+        if ( ret == EKeyWasConsumed && 
+            aKeyEvent.iCode != EKeyPhoneEnd && aKeyEvent.iCode != EKeyEscape )
+            {
+            UpdateCbasL();
+            }        
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::GetHelpContext
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::GetHelpContext
+        ( TCoeHelpContext& aContext ) const
+    {
+    if (iParams.iHelpContext)
+        {
+        // If external help context has been set, return it..
+        aContext = *iParams.iHelpContext;
+        }
+    else
+        {
+        // ..otherwise go with the default context
+        iEditorStrategy.GetHelpContext(aContext);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::PreLayoutDynInitL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::PreLayoutDynInitL()
+    {
+    SetEditableL(ETrue);
+
+    if (!ContactHasAddress(EPbk2FieldGroupIdPostalAddress)
+            && !ContactHasAddress(EPbk2FieldGroupIdHomeAddress)
+            && !ContactHasAddress(EPbk2FieldGroupIdCompanyAddress))
+        {
+        AddGroupFieldsL(EPbk2FieldGroupIdPostalAddress);
+        }
+    
+    if(iAddressViewStandalone)
+        {
+        AddGroupFieldsL(Pbk2AddressTools::MapViewTypeToAddress(iParams.iActiveView));
+        }
+
+    iUiFieldArray->CreateFieldsFromContactL(iParams);
+    SetAddressValidationIconsL();
+
+    // Offer button group container to extensions.
+    // This is needed here because previous settings might override extension's
+    // buttons.
+    iEditorExtension->ModifyButtonGroupContainerL(ButtonGroupContainer());
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::PostLayoutDynInitL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::PostLayoutDynInitL()
+    {
+    UpdateTitleL();
+    UpdateTitlePictureL();
+    if(iParams.iFocusedContactField)
+        {
+        const TInt count = iUiFieldArray->Count();
+        for (TInt i = 0; i < count; ++i)
+            {
+                if(iUiFieldArray->At(i).ContactEditorField())
+                {
+                MVPbkBaseContactField & field =
+                        iUiFieldArray->At(i).ContactEditorField()->ContactField();
+                if (field.IsSame(*iParams.iFocusedContactField))
+                    {
+                    UpdateCbasL(&(iUiFieldArray->At(i)));
+                    break;
+                    }
+                }
+            }
+        }
+    else if(iUiFieldArray->Count())
+        {
+        UpdateCbasL(&(iUiFieldArray->At(0)));
+        }
+    
+    // Notify relocator, that editor is ready
+    iRelocator.EditorReadyL();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetInitialCurrentLine
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::SetInitialCurrentLine()
+    {
+    TRAPD( err, ActivateFirstPageL() );
+    if(err)
+        {
+        return;
+        }
+
+    TInt focusedIndex = 0;
+    if ( iParams.iFocusedContactField )
+        {
+        const TInt count = iUiFieldArray->Count();
+        for (TInt i = 0; i < count; ++i)
+            {
+                if (iUiFieldArray->At(i).ContactEditorField())
+                {
+                MVPbkBaseContactField & field =
+                        iUiFieldArray->At(i).ContactEditorField()->ContactField();
+                if (field.IsSame(*iParams.iFocusedContactField))
+                    {
+                    focusedIndex = i;
+                    break;
+                    }
+                }
+            }
+        CAknForm::SetInitialCurrentLine();
+        iUiFieldArray->SetFocus(focusedIndex);
+        }
+    else
+        {
+        CAknForm::SetInitialCurrentLine();
+        iUiFieldArray->SetFocus(focusedIndex);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ProcessCommandL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ProcessCommandL(TInt aCommandId)
+    {
+    HideMenu();
+
+    iContextMenuBar->StopDisplayingMenuBar();
+
+    // Extensions get the command first
+    // If decide to exit already, do not handle new commands until this exit cmd clear
+    if (!iEditorExtension->ProcessCommandL(aCommandId) &&
+        !CheckBaseCommandL(aCommandId) &&
+        !CheckFieldSpecificCommandL(aCommandId) &&
+        iExitRecord.IsClear( EExitOrdered ) )
+        {
+		iCommandId = aCommandId;
+    
+        switch (aCommandId)
+            {
+            case EPbk2CmdAddItem:
+                {
+                CmdAddItemL();
+                break;
+                }
+
+            case EPbk2CmdDeleteItem:
+                {
+                CmdDeleteItemL();
+                break;
+                }
+
+            case EPbk2CmdEditItemLabel:
+                {
+                CmdEditItemLabelL();
+                break;
+                }
+#ifdef ECE_DISABLE_CONTEXT_MENU
+            case EPbk2CmdEditorContextMenu:
+                {
+                iContextMenuBar->TryDisplayMenuBarL();
+                break;
+                }
+#endif
+            case EEikCmdExit:
+            case EAknCmdExit:
+                {
+                // Exit Phonebook and if existing save 
+                // contact (happens later on in OkToExit..)
+                
+                // Escape or end key pressed.
+                // We must save changes and exit the application
+                
+                if( iParams.iActiveView == TPbk2ContactEditorParams::EEditorView || iAddressViewStandalone )
+                    {
+                    if (!iExitRecord.IsSet(EOkToExitWithoutHandlingIt))
+                        {
+                        if( OkToExitApplicationL( EAknCmdExit ) )
+                            {
+                            iExitRecord.Set(EExitOrdered);
+                            // Remove empty status pane
+                            if (iNaviContainer)
+                                {
+                                iNaviContainer->Pop();
+                                iNaviContainer = NULL;
+                                }
+    
+                            MPbk2ContactEditorEventObserver::TParams params;
+                            params.iFlags = EPbk2EditorCommandId;
+                            params.iKeyCode = EKeyEscape;
+                            params.iCommandId = EAknCmdExit;
+                            
+                            CmdDoneL(params);
+                            if ( iUseState == EUseOperatingContact ) 
+                                 {
+                                 WaitFinishL();
+                                 }
+                            }
+                        }
+                    break;    
+                    }
+                else
+                    {
+                    if (!iExitRecord.IsSet(EOkToExitWithoutHandlingIt))
+                        {
+                        iExitRecord.Set(EOkToExitWithoutHandlingIt);
+                        OkToExitApplicationL(EAknCmdExit);
+                            {
+                            // Remove empty status pane
+                            if (iNaviContainer)
+                                {
+                                iNaviContainer->Pop();
+                                iNaviContainer = NULL;
+                                }
+    
+                            MPbk2ContactEditorEventObserver::TParams params;
+                            params.iFlags = EPbk2EditorKeyCode;
+                            params.iKeyCode = EKeyEscape;
+                            params.iCommandId = EAknCmdExit;
+                            
+                            CmdDoneL(params);
+                            if ( iUseState == EUseOperatingContact ) 
+                                 {
+                                 WaitFinishL();
+                                 }
+                            }
+                        }
+                    }                                
+                
+                break;
+                }
+            case EAknCmdHelp:
+                {
+                HlpLauncher::LaunchHelpApplicationL(
+                        CCoeEnv::Static()->WsSession(),
+                        iEikonEnv->EikAppUi()->AppHelpContextL());
+                break;
+                }
+            default:
+                {
+                // Command not handled here, forward it to the app ui.
+                iEikonEnv->EikAppUi()->HandleCommandL(aCommandId);
+                break;
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CheckBaseCommandL
+// Check whether there is a base command to execute
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::CheckBaseCommandL(TInt aCommandId)
+    {
+    TBool ret(ETrue);
+    if (!iCommandPending)
+        {
+        //Prevent recursive execution of ExecuteBaseCommandL as touch events are  
+        //handled in it too. So it causes multiple callback to here if 
+        //user repeats the same pointer event very quickly.
+        iCommandPending = ETrue;
+
+        if (iPbk2BaseCommand)
+            {
+            //Cancel and delete previous possible pending command. 
+            delete iPbk2BaseCommand;
+            iPbk2BaseCommand = NULL;
+            }
+        TRAPD(err, ret = ExecuteBaseCommandL(aCommandId));
+        iCommandPending = EFalse;
+        User::LeaveIfError(err);
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ExecuteBaseCommandL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::ExecuteBaseCommandL(TInt aCommandId)
+    {
+    TBool executingCommand(ETrue);
+
+    switch (aCommandId)
+        {
+        case EPbk2CmdEditorChangeRingtone:
+            {
+            iPbk2BaseCommand = Pbk2RingtoneCommands::SetRingtoneL(
+                    &iContact.StoreContact());
+            break;
+            }
+
+        case EPbk2CmdEditorRemoveRingtone:
+            {
+            iPbk2BaseCommand = Pbk2RingtoneCommands::RemoveRingtoneL(
+                    &iContact.StoreContact());
+            break;
+            }
+
+        case EPbk2CmdEditorSelectAddress:
+            {
+            ExecuteAddressDlgL(TPbk2ContactEditorParams::EEditorAddressView);
+            return executingCommand;
+            }
+
+        case EPbk2CmdEditorSelectAddressHome:
+            {
+            ExecuteAddressDlgL(TPbk2ContactEditorParams::EEditorAddressHomeView);
+            return executingCommand;
+            }
+
+        case EPbk2CmdEditorSelectAddressOffice:
+            {
+            ExecuteAddressDlgL(
+                    TPbk2ContactEditorParams::EEditorAddressOfficeView);
+            return executingCommand;
+            }
+
+        case EPbk2CmdEditorOpen:
+            {
+            CPbk2ContactEditorArrayItem* currentField = iUiFieldArray->Find(
+                    IdOfFocusControl());
+
+            if (currentField->ContactEditorUIField())
+                {
+                TPbk2ContactEditorParams::TActiveView
+                        viewType =
+                                Pbk2AddressTools::MapCtrlTypeToViewType(
+                                        currentField->ContactEditorUIField()->UIField()->CtrlType());
+                if (viewType != TPbk2ContactEditorParams::EEditorUndefinied)
+                    {
+                    ExecuteAddressDlgL(viewType);
+                    return executingCommand;
+                    }
+                }
+            break;
+            }
+        case EPbk2CmdEditorSelectAssignFromMaps:
+            {
+            HandleCustomFieldCommandL(EPbk2ExtensionAssignFromMap);
+            break;
+            }
+
+        case EPbk2CmdEditorAddImage:
+        case EPbk2CmdEditorChangeImage:
+            {
+            iPbk2BaseCommand = Pbk2ImageCommands::SetImageL(
+                &iContact,this);
+            break;
+            }
+
+        case EPbk2CmdEditorViewImage:
+            {
+            iPbk2BaseCommand = Pbk2ImageCommands::ViewImageL(
+                    &iContact.StoreContact());
+            break;
+            }
+
+        case EPbk2CmdEditorRemoveImage:
+            {
+            iPbk2BaseCommand = Pbk2ImageCommands::RemoveImageL(&iContact);
+            break;
+            }
+
+        default:
+            {
+            executingCommand = EFalse;
+            break;
+            }
+        }
+
+    if (executingCommand)
+        {
+        CPbk2ContactEditorArrayItem* currentField = iUiFieldArray->Find(
+                IdOfFocusControl());
+
+        if (currentField && currentField->ContactEditorField())
+            {
+            TInt id = currentField->ControlId();
+            TAny
+                    * ext =
+                            currentField->ContactEditorField()->ContactEditorFieldExtension(
+                                    TUid::Uid(NULL));
+            if (id == EPbk2EditorLineRingtone)
+                {
+                CPbk2ContactEditorRingtoneField* fld =
+                        static_cast<CPbk2ContactEditorRingtoneField*> (ext);
+                fld->SetTextL();
+                }
+            else if( id == EPbk2EditorLineImage && 
+                     aCommandId == EPbk2CmdEditorRemoveImage)
+                {
+                //If image removed, no callback to ImageLoadingComplete() so do it here
+                DoImageLoadingCompleteL();
+                }
+            }
+        }
+
+    return executingCommand;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SwitchView
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ExecuteAddressDlgL(
+        TPbk2ContactEditorParams::TActiveView aActiveView)
+    {
+    if (iParams.iActiveView == TPbk2ContactEditorParams::EEditorView)
+        {
+        AddGroupFieldsL(Pbk2AddressTools::MapViewTypeToAddress(aActiveView));
+        }
+
+    iParams.iActiveView = aActiveView;
+    
+    CPbk2ContactEditorDlgImpl* adressDlg = CPbk2ContactEditorDlgImpl::NewL(
+            iParams, iContact, iFieldProperties, iContactObserver,
+            iEditorStrategy, iRelocator, iAppServices );
+    
+    iAddressView = adressDlg;
+    adressDlg->ExecuteLD();
+    iAddressView = NULL;
+    iParams.iActiveView = TPbk2ContactEditorParams::EEditorView;
+    UpdateControlsL();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::AddAddressFields
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::AddGroupFieldsL(TPbk2FieldGroupId aGroupId)
+    {
+    if (aGroupId == EPbk2FieldGroupIdNone)
+        return;
+
+    TInt count = iFieldProperties.Count();
+    for (TInt idx = 0; idx < count; idx++)
+        {
+        const MPbk2FieldProperty& fieldProp = iFieldProperties.At(idx);
+        if (fieldProp.GroupId() == aGroupId)
+            {
+            AddItemToContactL(fieldProp.FieldType().FieldTypeResId(),
+                    KNullDesC(), EFalse);
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::AreAllFieldsEmpty
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::AreAllFieldsEmpty()
+    {
+    TBool result(ETrue);
+    TInt countAll = iContact.PresentationFields().FieldCount();
+    for (TInt idx = 0; idx < countAll; idx++)
+        {
+        CPbk2PresentationContactField& field =
+                iContact.PresentationFields().At(idx);
+        
+        MVPbkContactFieldData& data = field.FieldData();
+        TInt fld = field.FieldProperty().FieldType().FieldTypeResId();        
+        if(fld != R_VPBK_FIELD_TYPE_RINGTONE && 
+           fld != R_VPBK_FIELD_TYPE_THUMBNAILPIC &&
+           fld != R_VPBK_FIELD_TYPE_CALLEROBJIMG &&
+           fld != R_VPBK_FIELD_TYPE_SYNCCLASS && 
+           fld != R_VPBK_FIELD_TYPE_TOPCONTACT) 
+            {                   
+            if(!data.IsEmpty())
+                {
+                if(data.DataType() == EVPbkFieldStorageTypeText)
+                    {
+                    HBufC* fieldText = MVPbkContactFieldTextData::Cast(data).Text().AllocL();
+                    fieldText->Des().TrimAll();                    
+                    if(fieldText->Length() > 0)
+                        {
+                        result = EFalse;
+                        }
+                    delete fieldText;                      
+                    }
+                else                
+                    {
+                    result = EFalse;
+                    }
+                }
+            }           
+        }
+    return result;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ContactHasAddress
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::ContactHasAddress(
+        TPbk2FieldGroupId aAddressGroup)
+    {
+    TInt countAll = iContact.PresentationFields().FieldCount();
+    for (TInt idx = 0; idx < countAll; idx++)
+        {
+        CPbk2PresentationContactField& field =
+                iContact.PresentationFields().At(idx);
+        if (field.FieldProperty().GroupId() == aAddressGroup)
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ClearControls
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ClearControls()
+    {
+    TInt count = iUiFieldArray->Count();
+    for (TInt idx = count - 1; idx >= 0; idx--)
+        {
+        iUiFieldArray->RemoveFieldFromUI(idx);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ContactEditorControlExtension
+// --------------------------------------------------------------------------
+//
+TAny* CPbk2ContactEditorDlgImpl::ContactEditorControlExtension(TUid /*aExtensionUid*/)
+    {
+    return static_cast<MPbk2ContactEditorControlExtension*> (this);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::UpdateControlsL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::UpdateControlsL()
+    {
+    iUiFieldArray->UpdateControlsL();
+    SetAddressValidationIconsL();
+    UpdatePageL(ETrue);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CheckFieldSpecificCommandL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::CheckFieldSpecificCommandL(TInt aCommandId)
+    {
+    TBool ret(EFalse);
+    CPbk2ContactEditorArrayItem* currentField = iUiFieldArray->Find(
+            IdOfFocusControl());
+
+    if (currentField)
+        {
+        if (currentField->ContactEditorUIField())
+            {
+            ret = currentField->ContactEditorUIField()->HandleCustomFieldCommandL(
+                        aCommandId);
+            }
+        else
+            {
+            MPbk2ContactEditorField2* tempCurrentField =
+                reinterpret_cast<MPbk2ContactEditorField2*> 
+                    (currentField->ContactEditorField()->ContactEditorFieldExtension(
+                        KMPbk2ContactEditorFieldExtension2Uid));
+            if (tempCurrentField)
+                {
+                ret = tempCurrentField->HandleCustomFieldCommandL(aCommandId);
+                }
+            }
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DynInitMenuPaneL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DynInitMenuPaneL(TInt aResourceId,
+        CEikMenuPane* aMenuPane)
+    {
+    iEditorExtension->DynInitMenuPaneL(aResourceId, aMenuPane);
+
+    if (aResourceId == R_PBK2_CONTACTEDITOR_MENUPANE ||
+        aResourceId == R_PBK2_CONTACTEDITOR_CONTEXT_MENUPANE)
+        {
+        //Label editing not anymore supported. Remove later all code
+        //related to editing labels
+        DimItem( aMenuPane,  EPbk2CmdEditItemLabel);
+        // Filter delete item away from menu for first and last name fields
+        CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+                IdOfFocusControl());
+        MPbk2ContactEditorField* currentField = current->ContactEditorField();
+        if (currentField)
+            {
+            if (currentField->FieldProperty().Flags()
+                    & KPbk2FieldFlagCanNotBeRemoved)
+                {
+                DimItem(aMenuPane, EPbk2CmdDeleteItem);
+                }
+            //Label editing not anymore supported. Remove later all code
+            //related to editing labels
+            //MVPbkStoreContactField& field = currentField->ContactField();
+            //if (!field.SupportsLabel())
+            //    {
+            //    DimItem( aMenuPane,  EPbk2CmdEditItemLabel);                
+            //    }
+            //else
+            //    {
+            //    TVPbkFieldVersitProperty prop;
+            //    prop.SetName(EVPbkVersitNameIMPP);
+            //    if (field.BestMatchingFieldType()->Matches(prop, 0))
+            //        {
+            //        DimItem( aMenuPane,  EPbk2CmdEditItemLabel);                
+            //        }
+            //    }
+            DynInitRingtoneL(aResourceId, aMenuPane, *currentField);
+            DynInitImageL(aResourceId, aMenuPane, *currentField);
+            DynInitSyncL(aResourceId, aMenuPane, *currentField);
+            }
+        else
+            {
+            DimItem(aMenuPane, EPbk2CmdDeleteItem);
+            DimItem(aMenuPane, EPbk2CmdEditorChangeRingtone);
+            DimItem(aMenuPane, EPbk2CmdEditorRemoveRingtone);
+            DimItem(aMenuPane, EPbk2CmdEditorAddImage);
+            DimItem(aMenuPane, EPbk2CmdEditorViewImage);
+            DimItem(aMenuPane, EPbk2CmdEditorChangeImage);
+            DimItem(aMenuPane, EPbk2CmdEditorRemoveImage);
+            DimItem(aMenuPane, EPbk2CmdEditorChangeSync);
+            }
+
+        DynInitAddressL(aResourceId, aMenuPane);
+        // If there are no available fields to add, do not show
+        // the add item dialog. If phone memory is in configuration
+        // this check is not needed.
+        if (!iRelocator.IsPhoneMemoryInConfigurationL())
+            {
+            CArrayPtr<const MPbk2FieldProperty>* availableFields =
+                    iContact.AvailableFieldsToAddL();
+            if (!availableFields || availableFields->Count() == 0)
+                {
+                DimItem(aMenuPane, EPbk2CmdAddItem);
+                }
+            delete availableFields;
+            }
+
+        if (aResourceId == R_PBK2_CONTACTEDITOR_MENUPANE)
+            {
+            // Hide exit, if wanted. Exit command is available only in
+            // main menu.
+            if (iParams.iFlags & TPbk2ContactEditorParams::EHideExit)
+                {
+                DimItem(aMenuPane, EAknCmdExit);
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DynInitRingtoneL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DynInitRingtoneL(
+    TInt /*aResourceId*/, 
+    CEikMenuPane* aMenuPane, 
+    MPbk2ContactEditorField& aCurrentField )
+    {
+    TInt id = aCurrentField.FieldProperty().FieldType().FieldTypeResId();  
+    
+    if(id != R_VPBK_FIELD_TYPE_RINGTONE)
+        {
+        DimItem( aMenuPane,  EPbk2CmdEditorChangeRingtone);
+        DimItem( aMenuPane,  EPbk2CmdEditorRemoveRingtone);
+        }
+    else 
+        {
+        if( aCurrentField.ContactField().FieldData().DataType() != 
+            EVPbkFieldStorageTypeText || 
+            aCurrentField.ContactField().FieldData().IsEmpty()  )
+            {
+            DimItem( aMenuPane,  EPbk2CmdEditorRemoveRingtone);
+            }
+        //Label editing not anymore supported (is dimmed in DynInitMenuPaneL)
+        //DimItem( aMenuPane,  EPbk2CmdEditItemLabel);
+        DimItem( aMenuPane,  EPbk2CmdDeleteItem);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DynInitImageL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DynInitImageL(
+    TInt /*aResourceId*/, 
+    CEikMenuPane* aMenuPane, 
+    MPbk2ContactEditorField& aCurrentField )
+    {
+    TInt id = aCurrentField.FieldProperty().FieldType().FieldTypeResId(); 
+    
+    if( id != R_VPBK_FIELD_TYPE_CALLEROBJIMG )
+        {
+        DimItem( aMenuPane,  EPbk2CmdEditorAddImage );
+        DimItem( aMenuPane,  EPbk2CmdEditorViewImage);
+        DimItem( aMenuPane,  EPbk2CmdEditorChangeImage);
+        DimItem( aMenuPane,  EPbk2CmdEditorRemoveImage);
+        }
+    else 
+        {
+        if( aCurrentField.ContactField().FieldData().DataType() == 
+            EVPbkFieldStorageTypeText && 
+            !aCurrentField.ContactField().FieldData().IsEmpty() )
+            {
+            //'View' shown even if there would be cold file name, i.e. no file 
+            //available the moment (e.g other mem card). Gallery takes care of
+            //error message. So just dim add option.
+            DimItem( aMenuPane, EPbk2CmdEditorAddImage );
+            }
+        else
+            {
+            DimItem( aMenuPane,  EPbk2CmdEditorViewImage);                    
+            DimItem( aMenuPane,  EPbk2CmdEditorChangeImage);
+            DimItem( aMenuPane,  EPbk2CmdEditorRemoveImage);
+            }
+
+        //Label editing not anymore supported (is dimmed in DynInitMenuPaneL)        
+        //DimItem( aMenuPane,  EPbk2CmdEditItemLabel);
+        DimItem( aMenuPane,  EPbk2CmdDeleteItem);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DynInitSyncL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DynInitSyncL(
+    TInt /*aResourceId*/, 
+    CEikMenuPane* aMenuPane, 
+    MPbk2ContactEditorField& aCurrentField )
+    {
+    TInt id = aCurrentField.FieldProperty().FieldType().FieldTypeResId();  
+    
+    if(id != R_VPBK_FIELD_TYPE_SYNCCLASS) 
+        {
+        DimItem( aMenuPane,  EPbk2CmdEditorChangeSync);
+        }
+    else 
+        {
+        //Label editing not anymore supported (is dimmed in DynInitMenuPaneL)
+        //DimItem( aMenuPane,  EPbk2CmdEditItemLabel);
+        }
+    }
+// CPbk2ContactEditorDlgImpl::DynInitAddressL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DynInitAddressL(TInt /*aResourceId*/,
+        CEikMenuPane* aMenuPane)
+    {
+    CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+            IdOfFocusControl());
+    if (iParams.iActiveView == TPbk2ContactEditorParams::EEditorView)
+        {
+        DimItem(aMenuPane, EPbk2ExtensionAssignFromMapSelect);
+        DimItem(aMenuPane, EPbk2ExtensionAssignFromMap);
+        if (current && current->ContactEditorUIField()
+                && Pbk2AddressTools::MapCtrlTypeToAddress(
+                        current->ContactEditorUIField()->UIField()->CtrlType())
+                        != EPbk2FieldGroupIdNone)
+            {
+            UnDimItem(aMenuPane, EPbk2CmdEditorOpen);
+            UnDimItem(aMenuPane, EPbk2CmdDeleteItem); 
+            }
+        else
+            {
+            DimItem(aMenuPane, EPbk2CmdEditorOpen);
+            }
+        }
+    else
+        {
+        if (!current || !current->ContactEditorUIField()
+                || current->ContactEditorUIField()->UIField()->CtrlType()
+                        != EPbk2FieldCtrlTypeExtAssignFromMapsEditor)
+            {
+            DimItem(aMenuPane, EPbk2ExtensionAssignFromMapSelect);
+            }
+        DimItem(aMenuPane, EPbk2CmdAddItem);
+        DimItem(aMenuPane, EPbk2CmdEditorOpen);
+        DimItem(aMenuPane, EPbk2CmdDeleteItem); 
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DimItem
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DimItem(CEikMenuPane* aMenuPane, TInt aCmd)
+    {
+    TInt pos;
+    if (aMenuPane->MenuItemExists(aCmd, pos))
+        {
+        aMenuPane->SetItemDimmed(aCmd, ETrue);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::UnDimItem
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::UnDimItem(CEikMenuPane* aMenuPane, TInt aCmd)
+    {
+    TInt pos;
+    if (aMenuPane->MenuItemExists(aCmd, pos))
+        {
+        aMenuPane->SetItemDimmed(aCmd, EFalse);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::OkToExitL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::OkToExitL(TInt aKeycode)
+    {
+    TBool ret = EFalse;
+    if( iCommandPending )
+        {
+        //When command in process prevent further processing
+        ret = EFalse;
+        }
+    else if ( iExitRecord.IsSet( EOkToExitWithoutHandlingIt ) )
+        {
+        ret = ETrue;
+        }
+    else if ( aKeycode == EAknSoftkeyDone )
+        {
+        // Done key pressed
+        MPbk2ContactEditorEventObserver::TParams params;
+        params.iFlags = EPbk2EditorKeyCode;
+        params.iKeyCode = aKeycode;
+        CmdDoneL( params );
+        }
+    else if (aKeycode == EKeyEscape || aKeycode == EEikBidCancel)
+        {
+        // this happens when service is canceled, so in this case, 
+        // do nothing but give ret ETrue, so that this object
+        // is able to be deleted later.
+        if( iServiceCanceled )
+            {
+            ret = ETrue;
+            }
+        // Escape or end key pressed.
+        // We must save changes and exit the applicatio
+        else if( !iExitRecord.IsSet( EExitOrdered ) )
+            {
+            // Remove empty status pane
+            if (iNaviContainer)
+                {
+                 iNaviContainer->Pop();
+                 iNaviContainer = NULL;
+                 }
+            if ( iStoredTitlePaneText )
+                {
+                delete iStoredTitlePaneText;
+                iStoredTitlePaneText = NULL;
+                }
+            MakeVisible( EFalse );
+            MPbk2ContactEditorEventObserver::TParams params;
+            params.iFlags = EPbk2EditorKeyCode;
+            params.iKeyCode = aKeycode;
+
+            // If the application is not allowed to hide itself in the
+            // background, end of the dialog is also end of the 
+            // application. 
+            if ( !iAvkonAppUi->ExitHidesInBackground() )
+                {
+                iExitRecord.Set( EExitOrdered );
+                
+                if( OkToExitApplicationL( EAknCmdExit ) )
+                    {
+                    params.iCommandId = EAknCmdExit;
+                    }
+                }
+            
+            CmdDoneL( params );
+            }
+        }
+    else if (aKeycode == EAknSoftkeyContextOptions)
+        {
+        // Launch context menu if the control is not popup control
+        CEikCaptionedControl* line = CurrentLine();
+        TInt type = line->iControlType;
+        TBool isPopUp = ( type == EAknCtPopupFieldText ) ||
+            ( type == EAknCtPopupField );
+        if (isPopUp)
+            {
+            CAknPopupField* ctrl =
+                static_cast<CAknPopupField*>( line->iControl );
+            ctrl->ActivateSelectionListL();
+            }
+        else
+            {
+            CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+                    IdOfFocusControl());
+            if (current && current->ContactEditorUIField())
+                {
+                TPbk2ContactEditorParams::TActiveView
+                        viewType =
+                                Pbk2AddressTools::MapCtrlTypeToViewType(
+                                        current->ContactEditorUIField()->UIField()->CtrlType());
+                if (viewType != TPbk2ContactEditorParams::EEditorUndefinied)
+                    {
+                    ExecuteAddressDlgL(viewType);
+                    return ret;
+                    }
+                else if (current->ContactEditorUIField()->UIField()->CtrlType()
+                        == EPbk2FieldCtrlTypeExtAssignFromMapsEditor)
+                    {
+                    HandleCustomFieldCommandL(EPbk2ExtensionAssignFromMap);
+                    return ret;
+                    }
+                }
+
+            iContextMenuBar->SetMenuTitleResourceId(
+                    R_PBK2_CONTACTEDITOR_CONTEXT_MENUBAR);
+            iContextMenuBar->SetMenuType(CEikMenuBar::EMenuContext);
+            iContextMenuBar->StopDisplayingMenuBar();
+            iContextMenuBar->TryDisplayMenuBarL();
+            iContextMenuBar->SetMenuTitleResourceId
+                ( R_PBK2_CONTACTEDITOR_MENUBAR );
+            iContextMenuBar->SetMenuType( CEikMenuBar::EMenuOptions );
+            }
+        }
+    else if( aKeycode == EAknSoftkeyChange ) 
+        {
+        //For custom controls (ringtone, image) msk middle key press need to be 
+        //caught here
+        CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+                IdOfFocusControl());
+        MPbk2ContactEditorField* currentField = NULL;
+        if (current)
+            {
+            currentField = current->ContactEditorField();
+            }
+
+        if (currentField)
+            {
+            TInt id = currentField->ControlId();
+            if (id == EPbk2EditorLineRingtone || id == EPbk2EditorLineImage)
+                {
+                MPbk2ContactEditorField2
+                        * tempCurrentField =
+                                reinterpret_cast<MPbk2ContactEditorField2*> (currentField->ContactEditorFieldExtension(
+                                        KMPbk2ContactEditorFieldExtension2Uid));
+                if (tempCurrentField)
+                    {
+                    tempCurrentField->HandleCustomFieldCommandL(
+                            EPbk2CmdEditorHandleCustomSelect);
+                    }
+                }
+            else
+                {
+                //For non-custom fields (sync...) forward to framework 
+                ForwardOkToExitL( aKeycode );
+                }
+            }
+        }
+    else
+        {
+        ForwardOkToExitL( aKeycode );
+        }
+
+    // Clear the exit state after usage.
+    iExitRecord.Clear( EOkToExitWithoutHandlingIt );
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ForwardOkToExitL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ForwardOkToExitL( TInt aKeycode )
+    {
+    //Prevent further execution of menu commands while a command is running.  
+    //In touch tapping RSK very quickly for ringtone gets otherwise through 
+    //when ringtone fetch command is running.
+    TBool okToSkip = iCommandPending && aKeycode != EAknSoftkeyDone && 
+                     aKeycode != EAknCmdExit && aKeycode != EAknCmdExit;  
+    if(!okToSkip)
+        {
+        CAknForm::OkToExitL( aKeycode );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::HandleControlStateChangeL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::HandleControlStateChangeL(TInt aControlId)
+    {
+    CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+            aControlId);
+    MPbk2ContactEditorField* changedField = current->ContactEditorField();
+    __ASSERT_DEBUG(changedField, Panic(EHandleControlStateChangeL_NullField));
+    if (changedField && iNameFormatter->IsTitleField(
+            changedField->ContactField()))
+        {
+        UpdateTitleL();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CreateLineL
+// --------------------------------------------------------------------------
+//
+CCoeControl* CPbk2ContactEditorDlgImpl::CreateLineL
+        ( const TDesC& aCaption, TInt aControlId, TInt aControlType )
+    {
+    return CreateLineByTypeL( aCaption, aControlId, aControlType, NULL );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::LineControl
+// --------------------------------------------------------------------------
+//
+CEikCaptionedControl* CPbk2ContactEditorDlgImpl::LineControl
+        ( TInt aControlId ) const
+    {
+    return Line( aControlId );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DeleteControl
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DeleteControl(TInt aControlId)
+    {
+    DeleteLine( aControlId );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::TryChangeFocusL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::TryChangeFocusL(TInt aControlId)
+    {
+    //Ensure current line is set before trying to change focus
+    if(!CurrentLine())
+        {
+        SetInitialCurrentLine(); 
+        }
+
+    //Attempt setting the focus
+    if ( ControlOrNull( aControlId ) )
+        {
+        TryChangeFocusToL( aControlId );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetCurrentLineCaptionL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::SetCurrentLineCaptionL(const TDesC& aText)
+    {
+    SetControlCaptionL(IdOfFocusControl(), aText);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::Control
+// --------------------------------------------------------------------------
+//
+CCoeControl* CPbk2ContactEditorDlgImpl::Control(TInt aControlId) const
+    {
+    return ControlOrNull(aControlId);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetEditableL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::SetEditableL( TBool aState )
+    {
+    CAknForm::SetEditableL( aState );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::LoadBitmapToFieldL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::LoadBitmapToFieldL
+        ( const MPbk2FieldProperty& aFieldProperty,
+          const CPbk2IconInfoContainer& aIconInfoContainer,
+          TInt aControlId )
+    {
+    CPbk2IconFactory* factory = CPbk2IconFactory::NewLC( aIconInfoContainer );
+    CEikImage* image = factory->CreateImageLC( aFieldProperty.IconId() );
+    
+    if ( image )
+        {
+        image->SetPictureOwnedExternally( EFalse );
+        image->CopyControlContextFrom( LineControl( aControlId ) );
+        image->SetContainerWindowL( *LineControl( aControlId ) );
+        image->SetNonFocusing();
+        image->SetBrushStyle( CGraphicsContext::ENullBrush );
+
+        delete LineControl( aControlId )->iBitmap;
+        LineControl( aControlId )->iBitmap = image;
+        CleanupStack::Pop( image );
+
+        TRect rect = LineControl( aControlId )->Rect();
+        rect.Resize( -1, -1 );
+        LineControl( aControlId )->SetRect( rect );
+        rect.Resize( 1, 1 );
+        LineControl( aControlId )->SetRect( rect );
+        }
+
+    CleanupStack::PopAndDestroy( factory );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ContactEditorOperationCompleted
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ContactEditorOperationCompleted
+        ( MVPbkContactObserver::TContactOpResult aResult,
+          MPbk2ContactEditorEventObserver::TParams aParams )
+    {
+    iUseState = EUseFinished;
+    
+    // Notify extensions
+    iEditorExtension->ContactEditorOperationCompleted
+        ( aResult, aParams );
+
+    switch ( aResult.iOpCode )
+        {
+        case MVPbkContactObserver::EContactOperationUnknown: // FALLTHROUGH
+            {
+            CloseDialog( aResult.iOpCode, ETrue );
+            break;
+            }
+        case MVPbkContactObserver::EContactCommit: // FALLTHROUGH
+        case MVPbkContactObserver::EContactDelete:
+            {
+            if ( aParams.iFlags & EPbk2EditorKeyCode &&
+                 aParams.iKeyCode == EAknSoftkeyDone )
+                {
+                CloseDialog( aResult.iOpCode, ETrue );
+                }
+            else if ( ( aParams.iFlags & EPbk2EditorKeyCode &&
+                        aParams.iKeyCode == EEikBidCancel ) ||
+                     ( aParams.iFlags & EPbk2EditorCommandId &&
+                       aParams.iCommandId == EEikBidCancel ) ) 
+                {
+                if( iExitRecord.IsSet( EExitOrdered ) )
+                    {
+                    ExitApplication( aResult.iOpCode, EAknCmdExit );
+                    }
+                else
+                    {
+                    CloseDialog( aResult.iOpCode, ETrue );
+                    }
+                }
+            else if ( ( aParams.iFlags & EPbk2EditorCommandId ) &&
+                        ( ( aParams.iCommandId == EEikCmdExit ) ||
+                        ( aParams.iCommandId == EAknCmdExit ) ) )
+                {
+                ExitApplication( aResult.iOpCode, aParams.iCommandId );
+                }
+            break;
+            }
+        default:
+            {
+            // Do nothing
+            break;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CloseDialog
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CloseDialog()
+	{
+    // Ignor error and close editor without further user interaction
+    MVPbkContactObserver::TContactOpResult exitResult;
+    exitResult.iExtension = NULL;
+    exitResult.iStoreContact = NULL;
+    exitResult.iOpCode = MVPbkContactObserver::EContactDelete;
+    MPbk2ContactEditorEventObserver::TParams exitParams;
+    if ( iAvkonAppUi->ExitHidesInBackground() )
+        {
+        exitParams.iCommandId = 0;
+        exitParams.iFlags = EPbk2EditorKeyCode;
+        exitParams.iKeyCode = EAknSoftkeyDone;
+        }
+    else
+        {
+        exitParams.iCommandId = EAknCmdExit;
+        exitParams.iFlags = EPbk2EditorCommandId;
+        exitParams.iKeyCode = 0;
+          
+        iExitRecord.Set( EExitApproved );
+        iExitRecord.Set( EExitOrdered );
+        }
+      
+    ContactEditorOperationCompleted(exitResult, exitParams);
+	}
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ContactEditorOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ContactEditorOperationFailed
+        ( MVPbkContactObserver::TContactOp aOpCode,
+          TInt aErrorCode, MPbk2ContactEditorEventObserver::TParams aParams,
+          MPbk2ContactEditorEventObserver::TFailParams& aFailParams )
+    {
+    iUseState = EUseReady;
+    
+    if( iEndKeyWasPressed )
+    {
+    CloseDialog();
+    }
+    else
+    {
+    // Offer the failure to the extensions first
+    iEditorExtension->ContactEditorOperationFailed(aOpCode,
+        aErrorCode, aParams, aFailParams );
+
+    // If extensions did not handle the error, handle it here
+    if ( !aFailParams.iErrorNotified )
+        {
+        CCoeEnv::Static()->HandleError( aErrorCode );
+        }
+
+    if ( aFailParams.iErrorCode != KErrNone  )
+        {
+        TPbk2RelocationQyeryPolicy policy(
+            Pbk2ContactRelocator::EPbk2DisplayNoQueries );
+
+        if ( aFailParams.iErrorCode == KErrNotSupported )
+            {
+            policy = Pbk2ContactRelocator::EPbk2DisplayStoreDoesNotSupportQuery;
+            }
+        else if ( aFailParams.iErrorCode == KErrGeneral )
+            {
+            policy = Pbk2ContactRelocator::EPbk2DisplayBasicQuery;
+            }
+        
+        TBool result( EFalse );
+        TRAPD( err, result = iRelocator.RelocateContactL( policy ) );
+        
+        if ( result )
+            {
+            // Do not close editor if contact need to relocate the first.
+            aFailParams.iCloseEditor = EFalse;
+            }
+                    
+        if ( err != KErrNone )
+            {
+            CCoeEnv::Static()->HandleError( err );
+            }
+        }
+    // Clear EExitOrdered to let next exit cmd available
+    iExitRecord.Clear(EExitOrdered);
+    if ( aFailParams.iCloseEditor )
+        {
+        CloseDialog( MVPbkContactObserver::EContactOperationUnknown, ETrue );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::RequestExitL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::RequestExitL(TInt aCommandId)
+    {
+    if (iAddressView)
+        {
+        iAddressView->RequestExitL(aCommandId);
+        }
+    
+    if ( iUseState == EUseFinished )
+        {
+        ForceExit();
+        }
+    else if ( iUseState == EUseOperatingContact  )
+        {
+        iEditorStrategy.StopQuery();
+        iExitRecord.Set( EExitApproved );
+        iExitRecord.Set( EExitOrdered );
+        }
+    else
+        { 
+        if ( aCommandId == EKeyEscape )
+            {
+            iEndKeyWasPressed = ETrue;
+            OkToExitL( EAknSoftkeyDone );
+            // If iUseState is set EUseOperatingContact by above function 
+            if ( iUseState == EUseOperatingContact )
+                {
+                WaitFinishL();
+                }
+            }
+        else
+            {
+            iExitRecord.Set( EExitApproved );
+            iExitRecord.Set( EExitOrdered );
+            MPbk2ContactEditorEventObserver::TParams params;
+            params.iFlags = EPbk2EditorCommandId;
+            params.iCommandId = aCommandId;
+            CmdDoneL( params );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ForceExit
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ForceExit()
+    {
+    iServiceCanceled = ETrue;
+    
+    if (iAddressView)
+        {
+        iAddressView->ForceExit();
+        }
+    
+    if ( iUseState == EUseOperatingContact )
+        {
+        iEditorStrategy.StopQuery();
+        iExitRecord.Set( EExitApproved );
+        iExitRecord.Set( EExitOrdered );
+        // It is ignored for dlg would exit
+        // Leave is not valuable
+        TRAP_IGNORE( WaitFinishL() );
+        }
+    else
+        {
+        iExitRecord.Set( EOkToExitWithoutHandlingIt );
+
+        TRAPD( err, TryExitL( EAknSoftkeyBack ) );
+        if ( err != KErrNone )
+            {
+            // If not nicely then use the force
+            delete this;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ResetWhenDestroyed
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ResetWhenDestroyed
+        ( MPbk2DialogEliminator** aSelfPtr )
+    {
+    iSelfPtr = aSelfPtr;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetFocus
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::SetFocus(TInt aIndex)
+    {
+    TBool found = EFalse;
+    TInt count = 0;
+    TInt idx;
+    for (idx = 0; idx < iUiFieldArray->Count(); idx++)
+        {
+        if (iUiFieldArray->At(idx).ContactEditorField())
+            {
+            if (count == aIndex)
+                {
+                found = ETrue;
+                break;
+                }
+            count++;
+            }
+        }
+    if (found)
+        {
+        iUiFieldArray->SetFocus(idx);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::NumberOfControls
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactEditorDlgImpl::NumberOfControls() const
+    {
+    TInt count = 0;
+    for (TInt idx = 0; idx < iUiFieldArray->Count(); idx++)
+        {
+        if (iUiFieldArray->At(idx).ContactEditorField())
+            {
+            count++;
+            }
+        }
+    return count;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::IndexOfCtrlType
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactEditorDlgImpl::IndexOfCtrlType(TPbk2FieldCtrlType aType,
+        TInt& aIndex) const
+    {
+    TInt ret = KErrNotFound;
+    const TInt fieldCount = iUiFieldArray->Count();
+    for (TInt i = Max(aIndex, 0); i < fieldCount; ++i)
+        {
+        if (iUiFieldArray->At(i).ContactEditorField())
+            {
+            const MPbk2FieldProperty & property =
+                    iUiFieldArray->At(i).ContactEditorField()->FieldProperty();
+            if (property.CtrlType() == aType)
+                {
+                ret = i;
+                break;
+                }
+            }
+        }
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::AreAllControlsEmpty
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::AreAllControlsEmpty() const
+    {
+    return iUiFieldArray->AreAllUiFieldsEmpty();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::IsControlEmptyL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::IsControlEmptyL(TInt aIndex) const
+    {
+    __ASSERT_DEBUG( iUiFieldArray->Count()> aIndex,
+            Panic( EPanic_IsControlEmptyL_OOB ) );
+    TBool ret = EFalse;
+    
+    // There are two types field controls in the edit dialog, one is the editor
+    // field control and the other is editor ui field control. The editor field 
+    // control are concreted field mapping to one field, it also can be divided
+    // into two types, custom control and normal control. The editor ui field 
+    // control are more like a container, currently only be used as the address
+    // container which can contain several editor field controls.
+    if ( iUiFieldArray->At(aIndex).ContactEditorField() )
+        {
+        // The custom control are special controls, like image, ring tone or date,
+        // they need use special way to judge if empty.
+        TBool empty = ETrue;
+        if( IsCustomControlEmptyL(aIndex, empty ) )
+            {
+            ret = empty;
+            }
+        // The control is normal editor field control.
+        else
+            {
+            ret = iUiFieldArray->IsEditorFieldControlEmpty( aIndex );
+            }
+        }
+    // If it's not an editor field control, judge if it's an editor ui field control.
+    else
+        {
+        // Check if contact editor ui field like address field is empty.
+        if ( iUiFieldArray->At( aIndex ).ContactEditorUIField() )
+            {
+            ret = iUiFieldArray->IsEditorUiFieldControlEmpty( aIndex );
+            }
+        }
+
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::IsCustomControlEmptyL
+//
+// Check emptiness of those fields that technically may contain data although
+// in view of user and ui are considered as empty (e.g. "Add image" text)
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::IsCustomControlEmptyL(TInt aIndex, TBool& aRet) const
+    {
+    __ASSERT_DEBUG( iUiFieldArray->Count()> aIndex,
+            Panic( EPanic_IsControlEmptyL_OOB ) );
+    TBool isCustom(EFalse);
+    if (!iUiFieldArray->At(aIndex).ContactEditorField())
+        {
+        return isCustom;
+        }
+    MPbk2ContactEditorField& currentField =
+            *(iUiFieldArray->At(aIndex).ContactEditorField());
+    TPbk2FieldCtrlType type = currentField.FieldProperty().CtrlType();
+    TAny* ext = currentField.ContactEditorFieldExtension(TUid::Uid(NULL));
+
+    if (type == EPbk2FieldCtrlTypeImageEditor && ext)
+        {
+        CPbk2ContactEditorImageField* fld =
+                static_cast<CPbk2ContactEditorImageField*> (ext);
+        aRet = fld->TextState() == CPbk2ContactEditorImageField::ENoData;
+        isCustom = ETrue;
+        }
+    else if (type == EPbk2FieldCtrlTypeRingtoneEditor && ext)
+        {
+        CPbk2ContactEditorRingtoneField* fld =
+                static_cast<CPbk2ContactEditorRingtoneField*> (ext);
+        aRet = fld->TextState() == CPbk2ContactEditorRingtoneField::ENoData;
+        isCustom = ETrue;
+        }
+    else if (type == EPbk2FieldCtrlTypeDateEditor)
+        {
+        // If contact has a date field, for index counting
+        // date editor field is considered as a custom control
+        // and it is not empty.
+        isCustom = ETrue;
+        aRet = EFalse;
+        }
+
+    return isCustom;
+    }
+// CPbk2ContactEditorDlgImpl::EditorField
+// --------------------------------------------------------------------------
+//
+MPbk2ContactEditorField& CPbk2ContactEditorDlgImpl::EditorField(TInt aIndex) const
+    {
+    __ASSERT_DEBUG( iUiFieldArray->Count()> aIndex,
+            Panic( EPanic_EditorField_OOB ) );
+
+    TBool found = EFalse;
+    TInt count = 0;
+    TInt idx;
+    for (idx = 0; idx < iUiFieldArray->Count(); idx++)
+        {
+        if (iUiFieldArray->At(idx).ContactEditorField())
+            {
+            if (count == aIndex)
+                {
+                found = ETrue;
+                break;
+                }
+            count++;
+            }
+        }
+
+    __ASSERT_DEBUG( found,
+            Panic( EPanic_EditorField_OOB ) );
+    return *(iUiFieldArray->At(idx).ContactEditorField());
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::StoreReady
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::StoreReady(MVPbkContactStore& /*aContactStore*/)
+    {
+    // Do nothing
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::StoreUnavailable
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::StoreUnavailable
+    ( MVPbkContactStore& aContactStore, TInt /*aReason*/ )
+    {
+    if ( &aContactStore == &iContact.ParentStore() )
+        {
+        /*
+		 * Use iAppServices if provided. This is to enable editor use outside from pbk2 context
+		 */
+        const CPbk2StoreProperty* property = NULL;
+        if( iAppServices )
+        	{
+        	property =
+					iAppServices->StoreProperties().FindProperty
+							( aContactStore.StoreProperties().Uri() );
+        	}
+        else
+        	{
+        	property =
+					Phonebook2::Pbk2AppUi()->ApplicationServices().
+						StoreProperties().FindProperty
+							( aContactStore.StoreProperties().Uri() );
+        	}
+        
+
+        TPtrC storeName;
+        if ( property )
+            {
+            storeName.Set( property->StoreName() );
+            }
+
+        // If this leaves the note is not shown.
+        // Cannot do anything about that
+        TRAP_IGNORE( ShowStoreNotAvailableNoteL( storeName ) );
+
+        // Close editor if store which came unavailable is iContact's store
+        iContactObserver.ContactEditingAborted();
+        // TryExitL is not called because it would call OkToExitL
+        // which is not wanted
+        delete this;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::HandleStoreEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::HandleStoreEventL(
+        MVPbkContactStore& /*aContactStore*/,
+        TVPbkContactStoreEvent /*aStoreEvent*/ )
+    {
+    // Do nothing
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::LineChangedL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::LineChangedL( TInt /*aControlId*/ )
+    {
+    SetCbaButtonsL();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::StoreTitlePaneTextL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2ContactEditorDlgImpl::StoreTitlePaneTextL()
+    {
+    CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane();
+    if (statusPane && statusPane->PaneCapabilities(
+        TUid::Uid(EEikStatusPaneUidTitle)).IsPresent())
+        {
+        iTitlePane = static_cast<CAknTitlePane*>
+            (statusPane->ControlL(TUid::Uid(EEikStatusPaneUidTitle)));
+        if (iTitlePane->Text())
+            {
+            iStoredTitlePaneText = iTitlePane->Text()->AllocL();
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::FocusedControlType
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactEditorDlgImpl::FocusedControlType()
+    {
+    CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+            IdOfFocusControl());
+    if (current && current->ContactEditorField())
+        {
+        return current->ContactEditorField()->FieldProperty().CtrlType();
+        }
+    else if (current && current->ContactEditorUIField())
+        {
+        return current->ContactEditorUIField()->UIField()->CtrlType();
+        }
+
+    return EPbk2FieldCtrlTypeNone;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ConstructContextMenuL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2ContactEditorDlgImpl::ConstructContextMenuL()
+    {
+    CEikMenuBar* newMenuBar = new ( ELeave ) CEikMenuBar();
+    CleanupStack::PushL( newMenuBar );
+    newMenuBar->ConstructL
+        ( this, NULL, R_PBK2_CONTACTEDITOR_CONTEXT_MENUBAR );
+    iEikonEnv->EikAppUi()->AddToStackL( newMenuBar, ECoeStackPriorityMenu,
+        ECoeStackFlagRefusesFocus );
+    iContextMenuBar = newMenuBar;
+    CleanupStack::Pop( newMenuBar );
+    iContextMenuBar->SetMenuType( CEikMenuBar::EMenuContext );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ConstructNaviPaneL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2ContactEditorDlgImpl::ConstructNaviPaneL()
+    {
+    CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane();
+    if (statusPane && statusPane->PaneCapabilities(TUid::Uid(
+            EEikStatusPaneUidNavi)).IsPresent())
+        {
+        // Create a default empty status pane, otherwise sync field will show
+        iNaviContainer
+                = static_cast<CAknNavigationControlContainer *> (statusPane->ControlL(
+                        TUid::Uid(EEikStatusPaneUidNavi)));
+        iNaviContainer->PushDefaultL(ETrue);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::UpdateTitleL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::UpdateTitleL()
+    {
+    if (iTitlePane)
+        {
+        HBufC* title = NULL;
+        switch (iParams.iActiveView)
+            {
+            case TPbk2ContactEditorParams::EEditorAddressView:
+            	if( !iTitleText )
+            		{
+            		title = StringLoader::LoadL(R_QTN_PHOB_HEADER_ADDRESS);
+            		}
+                break;
+            case TPbk2ContactEditorParams::EEditorAddressHomeView:
+            	if( !iTitleText )
+            		{
+            		title = StringLoader::LoadL(
+            				R_QTN_PHOB_HEADER_ADDRESS_HOME);
+            		}
+                break;
+            case TPbk2ContactEditorParams::EEditorAddressOfficeView:
+            	if( !iTitleText )
+            		{
+            		title = StringLoader::LoadL(
+            				R_QTN_PHOB_HEADER_ADDRESS_WORK);
+            		}
+                break;
+            case TPbk2ContactEditorParams::EEditorView:
+                {
+                if ( !iStoreContact )
+                    {
+                    // Create the contact once
+                    iStoreContact = iContact.StoreContact().ParentStore().CreateNewContactLC();
+                    CleanupStack::Pop();
+                    }
+                    
+                // Remove all fields before re-add
+                iStoreContact->RemoveAllFields();
+                
+                const TInt fieldCount = iUiFieldArray->Count();
+                for (TInt i = 0; i < fieldCount; ++i)
+                    {
+                    CPbk2ContactEditorArrayItem& item = iUiFieldArray->At(i);
+                    MPbk2ContactEditorField* uiField = item.ContactEditorField();
+                    if (uiField && iNameFormatter->IsTitleField(uiField->ContactField()))
+                        {
+                        HBufC* uiData = uiField->ControlTextL();
+                        if (uiData)
+                            {
+                            CleanupStack::PushL(uiData);
+                            const MVPbkFieldType& type =
+                                uiField->FieldProperty().FieldType();
+                            MVPbkStoreContactField* field = iStoreContact->CreateFieldLC(type);
+                            MVPbkContactFieldTextData::Cast(
+                                field->FieldData()).SetTextL(*uiData);
+                            iStoreContact->AddFieldL(field);
+                            CleanupStack::Pop(); // field
+                            CleanupStack::PopAndDestroy(uiData);
+                            }
+                        }
+                    }
+                if( !iTitleText )
+                	{
+                	title = iNameFormatter->GetContactTitleOrNullL(iStoreContact->Fields(),
+                			KEditorNameFormatFlags);
+                	}
+                break;
+                }
+            default:
+                break;
+            }
+        
+        // if custom title text is provided
+        if( iTitleText )
+        	{
+        	iTitlePane->SetTextL( iTitleText->Des() );
+        	}
+        else 
+        	{
+        	 if (title)
+				{
+				iTitlePane->SetText(title);
+				}
+			else
+				{
+				iTitlePane->SetTextL(iEditorStrategy.DefaultTitle());
+				}
+        	}
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::UpdateTitlePictureL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::UpdateTitlePictureL()
+    {
+    if (iTitlePane)
+        {
+        // Update picture in title pane
+        
+        /*
+		 * Use iAppServices if provided. This is to enable editor use outside from pbk2 context
+		 */
+        CEikImage* image = NULL;
+        if( iAppServices )
+        	{
+        	image =
+				Pbk2TitlePanePictureFactory::CreateTitlePanePictureLC
+					( &iContact.StoreContact(),
+							iAppServices->StoreProperties() );
+        	}
+        else
+        	{
+        	image =
+				Pbk2TitlePanePictureFactory::CreateTitlePanePictureLC
+					( &iContact.StoreContact(),
+					  Phonebook2::Pbk2AppUi()->ApplicationServices().
+						StoreProperties() );
+        	}
+        
+        
+        // ownership of the picture is transfered to title pane
+        image->SetPictureOwnedExternally( ETrue );
+        iTitlePane->SetSmallPicture(
+            image->Bitmap(), image->Mask(), image->Bitmap() != NULL );
+        // bitmap and mask from image were transfered to title pane,
+        // so image can be destroyed now
+        CleanupStack::PopAndDestroy( image );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CloseDialog
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CloseDialog(
+        MVPbkContactObserver::TContactOp aOpCode, TBool aInformObserver)
+    {
+    if (aInformObserver && iParams.iActiveView
+            == TPbk2ContactEditorParams::EEditorView || iAddressViewStandalone)
+        {
+        switch (aOpCode)
+            {
+            case MVPbkContactObserver::EContactOperationUnknown: // FALLTHROUGH
+            case MVPbkContactObserver::EContactCommit:
+                {
+                iContactObserver.ContactEditingComplete(
+                        &iContact.StoreContact());
+                break;
+                }
+            case MVPbkContactObserver::EContactDelete:
+                {
+                iContactObserver.ContactEditingDeletedContact(
+                        &iContact.StoreContact());
+                break;
+                }
+            default:
+                {
+                // Either end key was pressed or some uncommon scenario took place,
+                // abort
+                iContactObserver.ContactEditingAborted();
+                break;
+                }
+            };
+        }
+
+    // Don't save any contact data (already saved)
+    iExitRecord.Set(EOkToExitWithoutHandlingIt);
+    iExitRecord.Clear(EExitOrdered);
+
+    // Close dialog using TryExitL and returning ETrue from OkToExit
+    TInt err = KErrNone;
+        TRAP( err, TryExitL( EAknSoftkeyBack ) );
+    if (err != KErrNone)
+        {
+        // If not nicely then use the force.
+        delete this;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ExitApplication
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::ExitApplication(
+        MVPbkContactObserver::TContactOp aOpCode,
+        TInt aCommandId )
+    {
+    if ( iExitRecord.IsSet( EExitOrdered ) &&
+         iExitRecord.IsSet( EExitApproved ) )
+        {
+
+        CloseDialog( aOpCode, ETrue );
+
+        // Dialog is closed so there is nothing to do if
+        // HandleCommandL leaves. 
+		TRAP_IGNORE(CEikonEnv::Static()->EikAppUi()->HandleCommandL(aCommandId)); 
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CmdAddItemL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CmdAddItemL()
+    {
+    AddItemToContactL(KErrNotFound, KNullDesC);
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CmdDeleteItemL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CmdDeleteItemL()
+    {
+    TPbk2DeleteItemManager deleteItem( iContact, *iUiFieldArray, iAppServices );
+    if (deleteItem.DeleteFieldL(IdOfFocusControl()))
+        {
+        // Redraw using DrawNow, DrawDeferred does not get the job done
+        DrawNow();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CmdEditItemLabelL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CmdEditItemLabelL()
+    {
+    CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+            IdOfFocusControl());
+    MPbk2ContactEditorField* field = current->ContactEditorField();
+    if (field && field->ContactField().SupportsLabel())
+        {
+        // Find out the presentation contact index and then label length
+        TInt fieldIndx = iContact.PresentationFields().FindFieldIndex(
+            field->ContactField() );
+        TInt maxLabelLength = iContact.PresentationFields().
+            FieldAt( fieldIndx ).MaxLabelLength();
+
+        HBufC* textBuf = HBufC::NewLC(maxLabelLength);
+        TPtr text = textBuf->Des();
+        text.Copy(field->FieldLabel().Left(text.MaxLength()));
+        HBufC* prompt = StringLoader::LoadLC(R_QTN_FORM_PRMPT_FIELD_LABEL);
+
+        CAknTextQueryDialog* dlg = CAknTextQueryDialog::NewL(text);
+        dlg->SetMaxLength(maxLabelLength);
+        if (dlg->ExecuteLD(R_PBK2_EDIT_FIELD_LABEL_QUERY, *prompt))
+            {
+            if (text != field->FieldLabel())
+                {
+                field->SetFieldLabelL(text);
+                }
+            }
+        CleanupStack::PopAndDestroy(2); // prompt, textBuf
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::IsUIDataChanged
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::IsUIDataChanged()
+    {
+    TInt count = iUiFieldArray->Count();
+    for(TInt idx1 = 0; idx1 < count; idx1++)
+        {
+        CPbk2ContactEditorArrayItem& item = iUiFieldArray->At(idx1);
+        if(item.ContactEditorField() && item.ContactEditorField()->FieldDataChanged())
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::IsAddressValidated
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::IsAddressValidated(TPbk2FieldGroupId aGroupId)
+    {
+    CPbk2PresentationContactFieldCollection& fields = iContact.PresentationFields();
+    for(TInt idx = 0; idx < fields.FieldCount(); idx++)
+        {
+        MVPbkStoreContactField& field = fields.FieldAt(idx);
+        TInt countProps =
+            field.BestMatchingFieldType()->VersitProperties().Count();
+        TArray<TVPbkFieldVersitProperty> props =
+            field.BestMatchingFieldType()->VersitProperties();
+        for ( TInt idx2 = 0; idx2 < countProps; idx2++ )
+            {
+            if ( props[ idx2 ].Name() == EVPbkVersitNameGEO &&
+                 ( ( props[ idx2 ].Parameters().Contains( EVPbkVersitParamHOME ) &&
+                 aGroupId == EPbk2FieldGroupIdHomeAddress ) ||
+                   ( props[ idx2 ].Parameters().Contains( EVPbkVersitParamWORK ) &&
+                   aGroupId == EPbk2FieldGroupIdCompanyAddress ) ||
+                     ( !props[ idx2 ].Parameters().Contains( EVPbkVersitParamHOME ) &&
+                       !props[ idx2 ].Parameters().Contains( EVPbkVersitParamWORK ) &&
+                       aGroupId == EPbk2FieldGroupIdPostalAddress ) ) )
+                {
+                return ETrue;
+                }
+            }
+        }
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetAddressValidationIconsL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::SetAddressValidationIconsL()
+    {
+    TInt count = iUiFieldArray->Count();
+    for(TInt idx = 0; idx < count; idx++)
+        {
+        CPbk2ContactEditorArrayItem& uiItem = iUiFieldArray->At(idx);
+        MPbk2ContactEditorUIField* uiField = uiItem.ContactEditorUIField();
+        if(uiField)
+            {
+            switch(uiField->UIField()->CtrlType())
+                {
+                case EPbk2FieldCtrlTypeExtAddressEditor:
+                case EPbk2FieldCtrlTypeExtAddressHomeEditor:
+                case EPbk2FieldCtrlTypeExtAddressOfficeEditor:
+                    if(IsAddressValidated(Pbk2AddressTools::MapCtrlTypeToAddress(
+                            uiField->UIField()->CtrlType())))
+                        {
+                        TPbk2IconId iconID(TUid::Uid(KPbk2UID3), EPbk2qgn_prop_locev_map);
+                        uiField->LoadBitmapToFieldL(iconID);
+                        }
+                    else
+                        {
+                        TPbk2IconId iconID(TUid::Uid(KPbk2UID3), EPbk2qgn_prop_pb_no_valid_lm);
+                        uiField->LoadBitmapToFieldL(iconID);
+                        }
+                    break;
+                case EPbk2FieldCtrlTypeExtAssignFromMapsEditor:
+                    if(IsAddressValidated( Pbk2AddressTools::MapViewTypeToAddress(iParams.iActiveView)))
+                        {
+                          TPbk2IconId iconID(TUid::Uid(KPbk2UID3), EPbk2qgn_prop_locev_map);
+                          uiField->LoadBitmapToFieldL(iconID);
+                          }
+                      else
+                          {
+                          TPbk2IconId iconID(TUid::Uid(KPbk2UID3), EPbk2qgn_prop_pb_no_valid_lm);
+                          uiField->LoadBitmapToFieldL(iconID);
+                          }
+                    break;  
+                default:
+                    return;
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DeleteActiveAddressGeoCoords
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::DeleteActiveAddressGeoCoords()
+    {
+    CPbk2PresentationContactFieldCollection& fields = iContact.PresentationFields();
+    for(TInt idx = 0; idx < fields.FieldCount(); idx++)
+        {
+        MVPbkStoreContactField& field = fields.FieldAt(idx);
+        TInt countProps =
+            field.BestMatchingFieldType()->VersitProperties().Count();
+        TArray<TVPbkFieldVersitProperty> props =
+            field.BestMatchingFieldType()->VersitProperties();
+        for ( TInt idx2 = 0; idx2 < countProps; idx2++ )
+            {
+            if ( props[ idx2 ].Name() == EVPbkVersitNameGEO &&
+                 ( ( props[ idx2 ].Parameters().Contains( EVPbkVersitParamHOME ) &&
+                 iParams.iActiveView ==
+                   TPbk2ContactEditorParams::EEditorAddressHomeView ) ||
+                   ( props[ idx2 ].Parameters().Contains( EVPbkVersitParamWORK ) &&
+                   iParams.iActiveView ==
+                     TPbk2ContactEditorParams::EEditorAddressOfficeView ) ||
+                     ( !props[ idx2 ].Parameters().Contains( EVPbkVersitParamHOME ) &&
+                       !props[ idx2 ].Parameters().Contains( EVPbkVersitParamWORK ) &&
+                       iParams.iActiveView ==
+                         TPbk2ContactEditorParams::EEditorAddressView ) ) )
+                {
+                iContact.RemoveField(idx);
+                return;
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::CmdDoneL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::CmdDoneL(
+        MPbk2ContactEditorEventObserver::TParams& aParams)
+    {
+    // The event that "end" key is pressed is informed into 
+    // CPsu2ContactEditorExtension to do some process
+    if( iEndKeyWasPressed )
+        {
+        iEditorExtension->ProcessCommandL( EAknCmdHideInBackground );
+        }
+    
+    // Saving/deleting is asynchronic so it is never to ok exit rightaway
+    // No need to save fields when all field are empty.
+    // To estimate dialog is a contact editor or a address dialog.  
+    // If it is address dialog, then save all field.
+    if (iUseState != EUseOperatingContact)
+        {
+        if ( !iUiFieldArray->AreAllUiFieldsEmpty() 
+                || iParams.iActiveView == TPbk2ContactEditorParams::EEditorAddressView 
+                || iParams.iActiveView == TPbk2ContactEditorParams::EEditorAddressHomeView
+                || iParams.iActiveView == TPbk2ContactEditorParams::EEditorAddressOfficeView )
+            {
+            iUiFieldArray->SaveFieldsL();
+            }
+    
+        if(iParams.iActiveView != TPbk2ContactEditorParams::EEditorView && IsUIDataChanged() && 
+           IsAddressValidated(Pbk2AddressTools::MapViewTypeToAddress(iParams.iActiveView)))
+            {
+            if(iUiFieldArray->AreAllUiFieldsEmpty())
+                {
+                DeleteActiveAddressGeoCoords();
+                }
+            else
+                {
+                HBufC* prompt = StringLoader::LoadLC(R_QTN_PHOB_CONFIRM_KEEP_COORDINATES);
+                CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+                if(!dlg->ExecuteLD(R_PBK2_GENERAL_CONFIRMATION_QUERY, *prompt))
+                    {
+                    DeleteActiveAddressGeoCoords();
+                    }
+                CleanupStack::PopAndDestroy( prompt );
+                }
+            }
+        
+        TInt error(KErrNone);
+        if (iParams.iActiveView == TPbk2ContactEditorParams::EEditorView || 
+            iAddressViewStandalone)
+            {
+            // Estimate all field are empty by UI field.
+        if (( AreAllControlsEmpty() && !iAddressViewStandalone )||
+            (iAddressViewStandalone && AreAllFieldsEmpty()))
+                {
+                if (iEditorExtension->OkToDeleteContactL(aParams))
+                    {
+                    // iUseState must be set before DeleteContactL() because 
+                    // during deletion ForceExit() might be entered and needs to 
+                    // check the state to make sure operation finished.
+                    iUseState = EUseOperatingContact;
+
+                    // If Endkey is pressed, no need of query dialog in DeleteContactL()
+                    if ( iEndKeyWasPressed )
+                        {
+                        aParams.iCommandId = EEikBidCancel;
+                        }
+
+                    TRAP( error, iEditorStrategy.DeleteContactL( *this, aParams ) );
+
+                    DecideToLeaveL( error );
+                    }
+                }
+            else
+                {
+                iParams.iFocusedIndex = FocusedFieldIndexL();
+                if (iEditorExtension->OkToSaveContactL(aParams))
+                    {
+                    iUseState = EUseOperatingContact;
+                    
+                    TRAP( error, iEditorStrategy.SaveContactL( *this, aParams ) );
+                
+                    // Close the dialog if save contact fail caused by the
+                    // memory full
+                    if ( error == KErrDiskFull )
+                        {
+                        CloseDialog( MVPbkContactObserver::EContactCommit, ETrue );
+                        }
+                    
+                    DecideToLeaveL(error);
+                    }
+                else
+                    {
+                    if ( iEndKeyWasPressed )
+                        {
+                        CloseDialog();
+                        }
+                    }
+                }
+            }
+       else
+            {
+            CloseWithoutSaving(EFalse);
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::FocusedFieldIndexL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactEditorDlgImpl::FocusedFieldIndexL()
+    {
+    if( iAddressViewStandalone )
+        {
+        return KErrNotFound;
+        }
+    
+    const TInt idOfFocusedControl(IdOfFocusControl());
+    TInt fieldIndex(0);
+    const TInt count(iUiFieldArray->Count());
+    
+    for (TInt i(0); i < count; ++i)
+        {
+        CPbk2ContactEditorArrayItem& uiField = iUiFieldArray->At(i);
+
+        if(uiField.ControlId() == idOfFocusedControl)
+            {
+            if( IsControlEmptyL(i) )
+                {
+                break;
+                }
+            return fieldIndex;
+            }
+        else
+            {
+            if( !IsControlEmptyL(i) )
+                {
+                fieldIndex++;
+                }
+            }
+        }
+    return KErrNotFound;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetCbaButtonsL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorDlgImpl::SetCbaButtonsL()
+    {
+    if ( AknLayoutUtils::MSKEnabled() )
+        {
+        TBool hideMsk(EFalse);
+
+        if ( !iRelocator.IsPhoneMemoryInConfigurationL() )
+            {
+            if ( EmptyContextMenuL() )
+                {
+                hideMsk = ETrue;
+                }
+            }
+
+        ButtonGroupContainer().DimCommandByPosition(
+                CEikButtonGroupContainer::EMiddleSoftkeyPosition,
+                hideMsk );
+
+        ButtonGroupContainer().MakeCommandVisibleByPosition(
+                CEikButtonGroupContainer::EMiddleSoftkeyPosition,
+                !hideMsk );
+
+        ButtonGroupContainer().DrawDeferred();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::EmptyContextMenuL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::EmptyContextMenuL()
+    {
+    TBool empty(EFalse);
+
+    CPbk2ContactEditorArrayItem* current = iUiFieldArray->Find(
+            IdOfFocusControl());
+            
+    if( current )
+        {
+        MPbk2ContactEditorField* currentField = current->ContactEditorField();
+
+        CArrayPtr<const MPbk2FieldProperty>* availableFields =
+            iContact.AvailableFieldsToAddL();
+
+        if ( ( !currentField ||
+             ( currentField->FieldProperty().Flags()
+               & KPbk2FieldFlagCanNotBeRemoved ) ) &&
+             ( !currentField ||
+               !currentField->ContactField().SupportsLabel() ) &&
+             ( !availableFields || availableFields->Count() == 0 ) ) 
+            {
+            empty = ETrue;
+            }
+        delete availableFields;
+        }
+    else
+        {
+        empty = EFalse;
+        }
+
+    return empty;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::OkToExitApplicationL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorDlgImpl::OkToExitApplicationL
+        ( TInt aCommandId )
+    {
+    TBool okToExit = ETrue;
+
+    // If exit callback returned EFalse, the exit is cancelled
+    if ( iParams.iExitCallback &&
+         !iParams.iExitCallback->OkToExitL( aCommandId ) )
+        {
+        okToExit = EFalse;
+        }
+
+    if ( !okToExit )
+        {
+        iExitRecord.Clear( EExitApproved );
+        }
+
+    return okToExit;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::SetCbaCommandSetL
+// --------------------------------------------------------------------------
+//    
+void CPbk2ContactEditorDlgImpl::SetCbaCommandSetL( TInt aResourceId )
+    {
+    CEikButtonGroupContainer& cba = ButtonGroupContainer();
+    cba.SetCommandSetL( aResourceId );
+    iCbaCommandSet = aResourceId;
+    cba.DrawDeferred();
+    }    
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::UpdateCbasL
+// --------------------------------------------------------------------------
+//    
+void CPbk2ContactEditorDlgImpl::UpdateCbasL(CPbk2ContactEditorArrayItem* aItemToUpdate)
+    {
+    CPbk2ContactEditorArrayItem* current = aItemToUpdate;
+    if(!current)
+        {
+        current = iUiFieldArray->Find(IdOfFocusControl());
+        }
+
+    MPbk2ContactEditorField* currentField = current->ContactEditorField();
+    MPbk2ContactEditorUIField* currentUIField = current->ContactEditorUIField();
+    if ( currentField )
+        {
+        TPbk2FieldCtrlType type =
+            currentField->FieldProperty().CtrlType();
+        if (type == EPbk2FieldCtrlTypeImageEditor )
+            {
+            TInt id  = currentField->ControlId();  
+            TAny* ext = currentField->ContactEditorFieldExtension(TUid::Uid(NULL));
+            CPbk2ContactEditorImageField* fld = 
+                static_cast<CPbk2ContactEditorImageField*>(ext);
+            if(fld->TextState() == CPbk2ContactEditorImageField::ENoData)
+                {
+                if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_ADD )
+                    {
+                    SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_ADD  );   
+                    } 
+                }
+            else
+                {
+                if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_CHANGE )
+                    {
+                    SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_CHANGE  );   
+                    } 
+                }
+            }
+        else if ( type == EPbk2FieldCtrlTypeChoiceItems ||
+                  type == EPbk2FieldCtrlTypeRingtoneEditor )
+            {
+            if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_CHANGE )
+                {
+                SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_CHANGE  );   
+                } 
+            }
+        else
+            {
+#ifndef ECE_DISABLE_CONTEXT_MENU            
+            if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_CONTEXT )
+                {
+                SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_CONTEXT );
+                }
+#else
+            if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_EMPTY )
+                {
+                SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_EMPTY );
+                }
+#endif            
+            }
+        }
+   
+   if(currentUIField)
+       {
+       TPbk2FieldCtrlTypeExt type =
+           currentUIField->UIField()->CtrlType();
+       switch(type)
+           {
+           case EPbk2FieldCtrlTypeExtAddressEditor:
+           case EPbk2FieldCtrlTypeExtAddressHomeEditor:
+           case EPbk2FieldCtrlTypeExtAddressOfficeEditor:
+               if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_CHANGE )
+                   {
+                   SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_CHANGE  );   
+                   } 
+               break;
+           case EPbk2FieldCtrlTypeExtAssignFromMapsEditor:
+               if ( iCbaCommandSet != R_PBK2_SOFTKEYS_OPTIONS_DONE_SELECT )
+                   {
+                   SetCbaCommandSetL( R_PBK2_SOFTKEYS_OPTIONS_DONE_SELECT  );   
+                   } 
+               break;
+           }
+       }
+
+    // Offer button group container to extensions.
+    // This is needed here because previous settings might override extension's
+    // buttons.
+    iEditorExtension->ModifyButtonGroupContainerL(ButtonGroupContainer());
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ImageLoadingComplete
+// --------------------------------------------------------------------------
+//    
+TInt CPbk2ContactEditorDlgImpl::ImageLoadingComplete()
+    {
+    TRAPD(err,DoImageLoadingCompleteL())
+    return err;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::DoImageLoadingCompleteL
+// --------------------------------------------------------------------------
+//    
+void CPbk2ContactEditorDlgImpl::DoImageLoadingCompleteL()
+    {
+    CPbk2ContactEditorArrayItem* currentField =
+        iUiFieldArray->Find(IdOfFocusControl());
+    if (currentField && currentField->ContactEditorField())
+        {
+        TInt id  = currentField->ContactEditorField()->ControlId();  
+        TAny* ext = currentField->ContactEditorField()->ContactEditorFieldExtension(TUid::Uid(NULL));
+        if( id == EPbk2EditorLineImage )
+            {
+            CPbk2ContactEditorImageField* fld = 
+                static_cast<CPbk2ContactEditorImageField*>(ext);
+            fld->SetTextL();
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ImageLoadingFailed
+// --------------------------------------------------------------------------
+//    
+TInt CPbk2ContactEditorDlgImpl::ImageLoadingFailed() 
+    {
+    return KErrNone;
+    }
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::ImageLoadingCancelled
+// --------------------------------------------------------------------------
+//    
+TInt CPbk2ContactEditorDlgImpl::ImageLoadingCancelled() 
+    {
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorDlgImpl::WaitFinish
+// --------------------------------------------------------------------------
+//    
+void CPbk2ContactEditorDlgImpl::WaitFinishL()
+    {
+    if ( !iWaitFinish && *iSelfPtr )
+        {
+        iInputBlock = CAknInputBlock::NewLC();
+        CleanupStack::Pop( iInputBlock );
+        
+        iWaitFinish = new (ELeave) CActiveSchedulerWait();
+        iWaitFinish->Start();
+        }
+    }
+
+// End of File