--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/View/src/CPbkContactEditorDlg.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1431 @@
+/*
+* Copyright (c) 2002 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:
+* Methods for Phonebook Contact editor dialog.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkContactEditorDlg.h"
+
+#include <eikspane.h>
+#include <avkon.hrh>
+#include <akntitle.h>
+#include <aknnavi.h>
+#include <eikmenub.h>
+#include <featmgr.h>
+#include <StringLoader.h>
+#include <AknQueryDialog.h>
+#include <aknnotewrappers.h>
+#include <AknsUtils.h>
+#include <eikcapc.h>
+#include <hlplch.h>
+
+#include "CPbkThumbnailCmd.h"
+#include "CPbkContextPaneIcon.h"
+#include "CPbkContactEditorFieldArray.h"
+#include "MPbkContactEditorUiBuilder.h"
+#include <MPbkContactEditorField.h>
+#include <MPbkContactEditorControl.h>
+#include "PbkContactEditorStrategyFactory.h"
+#include "MPbkContactEditorStrategy.h"
+#include "TPbkAddItemManager.h"
+#include "CPbkThumbnailPopup.h"
+#include <PbkView.hrh>
+#include "PbkUID.h"
+#include "MPbkFieldEditorVisitor.h"
+#include "MPbkFieldEditorControl.h"
+#include "MPbkEditorOkToExitCallback.h"
+
+#include <CPbkContactEngine.h>
+#include <CPbkContactItem.h>
+#include <CPbkFieldsInfo.h>
+#include <CPbkConstants.h>
+#include <CPbkFieldData.h>
+#include <PbkView.rsg>
+#include <MPbkContactEditorExtension.h>
+#include <MPbkExtensionFactory.h>
+#include <CPbkExtGlobals.h>
+
+#include <PbkDebug.h>
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+
+/// Escape key press event
+static const TKeyEvent KEscKeyEvent = { EKeyEscape, 0, 0, 0 };
+
+#ifdef _DEBUG
+/// Panic codes for CPbkContactEditorDlg
+enum TPanicCode
+ {
+ EPanicPostCond_Constructor,
+ EPanicPreCond_ResetWhenDestroyed,
+ EPanicPreCond_CmdFetchThumbnailL,
+ EPanicPreCond_CmdRemoveThumbnailL,
+ EPanicPreCond_PreLayoutDynInitL,
+ EPanicPostCond_PreLayoutDynInitL,
+ EPanicPreCond_SetInitialCurrentLine,
+ EPanicPreCond_ContactAlreadyExistsL
+ };
+
+void Panic(TPanicCode aReason)
+ {
+ _LIT(KPanicText, "CPbkContactEditorDlg");
+ User::Panic(KPanicText, aReason);
+ }
+#endif // _DEBUG
+
+void UpdateCbasL( MPbkContactEditorField* aCurrentField,
+ CEikButtonGroupContainer& aCba )
+ {
+ if ( aCurrentField )
+ {
+ TPbkFieldEditMode editMode =
+ aCurrentField->ContactItemField().FieldInfo().EditMode();
+
+ if ( editMode == EPbkFieldEditModeSelector )
+ {
+ if ( !aCba.IsCommandInGroup(EAknSoftkeyChange) )
+ {
+ aCba.SetCommandSetL( R_PBK_SOFTKEYS_OPTIONS_DONE_CHANGE );
+ aCba.DrawDeferred();
+ }
+ }
+ else
+ {
+ if ( !aCba.IsCommandInGroup(EAknSoftkeyContextOptions) )
+ {
+ aCba.SetCommandSetL( R_PBK_SOFTKEYS_OPTIONS_DONE_CONTEXT );
+ aCba.DrawDeferred();
+ }
+ }
+ }
+ }
+
+} // namespace
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+/**
+ * Extension implementation.
+ */
+NONSHARABLE_CLASS(CPbkContactEditorDlg::CExtension) :
+ public CBase,
+ public MPbkContactEditorControl
+ {
+ public: // Constructor and destructor
+ /**
+ * Creates a new CExtension.
+ * @param aContact currently edited contact
+ */
+ static CExtension* NewL
+ (CPbkContactItem& aContact,
+ const CPbkContactEditorDlg& aParent);
+ /**
+ * Destructor
+ */
+ ~CExtension();
+
+ public: // From MPbkContactEditorExtension API
+ void DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane);
+ TBool ProcessCommandL(TInt aCommandId);
+ void PreOkToExitL(TInt aButtonId);
+ void PostOkToExitL(TInt aButtonId);
+ void SetStateModified();
+
+ public: // From MPbkContactEditorControl
+ MPbkContactEditorField* FocusedField();
+ TInt EditorCount();
+ const MPbkContactEditorField& FieldAt(TInt aFieldIndex);
+
+ private: // Implementation
+ CExtension(const CPbkContactEditorDlg& aParent);
+ void ConstructL(CPbkContactItem& aContact);
+
+ private: // Data
+ /// Ref: for creating editor extension
+ CPbkExtGlobals* iExtGlobal;
+ /// Ref: editor extension
+ MPbkContactEditorExtension* iEditorExtension;
+ /// Ref: parent editor
+ const CPbkContactEditorDlg& iParent;
+ };
+
+CPbkContactEditorDlg::CExtension::CExtension
+ (const CPbkContactEditorDlg& aParent) :
+ iParent(aParent)
+ {
+ }
+
+void CPbkContactEditorDlg::CExtension::ConstructL
+ (CPbkContactItem& aContact)
+ {
+ iExtGlobal = CPbkExtGlobals::InstanceL();
+ iEditorExtension = iExtGlobal->FactoryL().
+ CreatePbkContactEditorExtensionL(aContact, iParent.iEngine, *this);
+ }
+
+CPbkContactEditorDlg::CExtension* CPbkContactEditorDlg::CExtension::NewL
+ (CPbkContactItem& aContact,
+ const CPbkContactEditorDlg& aParent)
+ {
+ CExtension* self = new (ELeave) CExtension(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL(aContact);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CPbkContactEditorDlg::CExtension::~CExtension()
+ {
+ Release(iEditorExtension);
+ Release(iExtGlobal);
+ }
+
+void CPbkContactEditorDlg::CExtension::DynInitMenuPaneL
+ (TInt aResourceId, CEikMenuPane* aMenuPane)
+ {
+ iEditorExtension->DynInitMenuPaneL(aResourceId, aMenuPane);
+ }
+
+TBool CPbkContactEditorDlg::CExtension::ProcessCommandL(TInt aCommandId)
+ {
+ return iEditorExtension->ProcessCommandL(aCommandId);
+ }
+
+void CPbkContactEditorDlg::CExtension::PreOkToExitL(TInt aButtonId)
+ {
+ iEditorExtension->PreOkToExitL(aButtonId);
+ }
+
+void CPbkContactEditorDlg::CExtension::PostOkToExitL(TInt aButtonId)
+ {
+ iEditorExtension->PostOkToExitL(aButtonId);
+ }
+
+void CPbkContactEditorDlg::CExtension::SetStateModified()
+ {
+ iParent.iEditorStrategy->SetStateModified();
+ }
+
+MPbkContactEditorField* CPbkContactEditorDlg::CExtension::FocusedField()
+ {
+ const TInt id = iParent.IdOfFocusControl();
+ return iParent.iFieldManager->Find(id);
+ }
+
+TInt CPbkContactEditorDlg::CExtension::EditorCount()
+ {
+ return iParent.iFieldManager->EditorCount();
+ }
+
+const MPbkContactEditorField& CPbkContactEditorDlg::CExtension::
+ FieldAt(TInt aFieldIndex)
+ {
+ return iParent.iFieldManager->FieldAt(aFieldIndex);
+ }
+
+/**
+ * Editor implementation class.
+ */
+NONSHARABLE_CLASS(CPbkContactEditorDlgImpl) :
+ public CPbkContactEditorDlg,
+ private MPbkContactEditorUiBuilder
+ {
+ public: // constructor
+ /**
+ * Creates a new instance of this class.
+ * @param aEngine phonebook engine
+ * @param aContactItem contact item
+ * @param aIsNewContact defines is this new contact or not
+ * @param aFocusIndex field to focus
+ * @param AEdited edited flag
+ */
+ static CPbkContactEditorDlgImpl* NewL(
+ CPbkContactEngine& aEngine,
+ CPbkContactItem& aContactItem,
+ TBool aIsNewContact,
+ TInt aFocusIndex = -1,
+ TBool aEdited = EFalse);
+
+ /**
+ * Destructor.
+ */
+ ~CPbkContactEditorDlgImpl();
+
+ private: // from MPbkContactEditorUiBuilder
+ CCoeControl* CreateLineL(const TDesC& aCaption, TInt aControlId,
+ TInt aControlType);
+ CEikCaptionedControl* LineControl(TInt aControlId) const;
+ void DeleteControl(TInt aControlId);
+ void TryChangeFocusL(TInt aControlId);
+ void SetCurrentLineCaptionL(const TDesC& aText);
+ CCoeControl* Control(TInt aControlId) const;
+ void SetEditableL(TBool aState);
+
+ private: // from CAknForm
+ void HandleResourceChange(TInt aType);
+
+ private: // from CCoeControl
+ void FocusChanged(TDrawNow aDrawNow);
+
+ private: // implementation
+ CPbkContactEditorDlgImpl
+ (CPbkContactEngine& aEngine,
+ CPbkContactItem& aContactItem,
+ TInt aFocusIndex = -1);
+ private:
+ class CPbkIconReloaderVisitor;
+ CPbkIconReloaderVisitor* iIconReloaderVisitor;
+ };
+
+/**
+ * Editor icon reloader visitor.
+ */
+NONSHARABLE_CLASS(CPbkContactEditorDlgImpl::CPbkIconReloaderVisitor) :
+ public CBase,
+ public MPbkFieldEditorVisitor
+ {
+ public:
+ CPbkIconReloaderVisitor(MPbkContactEditorUiBuilder& aUiBuilder);
+ ~CPbkIconReloaderVisitor();
+
+ private: // From MPbkFieldEditorVisitor
+ void VisitL(MPbkFieldEditorControl& aThis);
+
+ private: // Data
+ MPbkContactEditorUiBuilder& iUiBuilder;
+ };
+
+CPbkContactEditorDlgImpl::CPbkIconReloaderVisitor::CPbkIconReloaderVisitor
+ (MPbkContactEditorUiBuilder& aUiBuilder) :
+ iUiBuilder(aUiBuilder)
+ {
+ }
+
+CPbkContactEditorDlgImpl::CPbkIconReloaderVisitor::~CPbkIconReloaderVisitor()
+ {
+ }
+
+void CPbkContactEditorDlgImpl::CPbkIconReloaderVisitor::VisitL
+ (MPbkFieldEditorControl& aThis)
+ {
+ aThis.LoadBitmapToFieldL(iUiBuilder);
+ }
+
+inline CPbkContactEditorDlgImpl::CPbkContactEditorDlgImpl(
+ CPbkContactEngine& aEngine,
+ CPbkContactItem& aContactItem,
+ TInt aFocusIndex) :
+ CPbkContactEditorDlg(aEngine, aContactItem, aFocusIndex)
+ {
+ }
+
+CPbkContactEditorDlgImpl* CPbkContactEditorDlgImpl::NewL(
+ CPbkContactEngine& aEngine,
+ CPbkContactItem& aContactItem,
+ TBool aIsNewContact,
+ TInt aFocusIndex,
+ TBool aEdited)
+ {
+ // Create the dialog
+ CPbkContactEditorDlgImpl* self = new(ELeave) CPbkContactEditorDlgImpl(
+ aEngine, aContactItem, aFocusIndex);
+ CleanupStack::PushL(self);
+ self->BaseConstructL(aIsNewContact, aEdited);
+
+ // create field managing object
+ self->iFieldManager = CPbkContactEditorFieldArray::NewL
+ (aContactItem, *self);
+
+ self->iIconReloaderVisitor = new(ELeave) CPbkIconReloaderVisitor(*self);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CPbkContactEditorDlgImpl::~CPbkContactEditorDlgImpl()
+ {
+ delete iIconReloaderVisitor;
+ }
+
+CCoeControl* CPbkContactEditorDlgImpl::CreateLineL
+ (const TDesC& aCaption,
+ TInt aControlId,
+ TInt aControlType)
+ {
+ return CreateLineByTypeL(
+ aCaption, aControlId, aControlType, NULL);
+ }
+
+CEikCaptionedControl* CPbkContactEditorDlgImpl::LineControl
+ (TInt aControlId) const
+ {
+ return Line(aControlId);
+ }
+
+void CPbkContactEditorDlgImpl::DeleteControl
+ (TInt aControlId)
+ {
+ DeleteLine(aControlId);
+ }
+
+void CPbkContactEditorDlgImpl::TryChangeFocusL
+ (TInt aControlId)
+ {
+ if (ControlOrNull(aControlId))
+ {
+ TryChangeFocusToL(aControlId);
+ }
+ }
+
+void CPbkContactEditorDlgImpl::SetCurrentLineCaptionL
+ (const TDesC& aText)
+ {
+ SetControlCaptionL(IdOfFocusControl(), aText);
+ }
+
+CCoeControl* CPbkContactEditorDlgImpl::Control
+ (TInt aControlId) const
+ {
+ return ControlOrNull(aControlId);
+ }
+
+void CPbkContactEditorDlgImpl::SetEditableL(TBool aState)
+ {
+ CPbkContactEditorDlg::SetEditableL(aState);
+ }
+
+void CPbkContactEditorDlgImpl::HandleResourceChange(TInt aType)
+ {
+ CPbkContactEditorDlg::HandleResourceChange(aType);
+
+ if (aType == KAknsMessageSkinChange)
+ {
+ TRAP_IGNORE(iFieldManager->AcceptL(*iIconReloaderVisitor));
+ }
+ else if (aType == KEikDynamicLayoutVariantSwitch)
+ {
+ // It is not bad if thumbnail showing fails
+ TRAP_IGNORE( ReloadThumbnailL() );
+ }
+ }
+
+void CPbkContactEditorDlgImpl::FocusChanged(TDrawNow /*aDrawNow*/)
+ {
+ // Thumbnail will be set as hidden if the control is not focused.
+ // all is done in ReloadThumbnailL -method.
+ // No big deal if thumbnail is not shown
+ TRAP_IGNORE(ReloadThumbnailL());
+ }
+
+
+///////////////////////////////////////////////////////////////
+/// CPbkContactEditorDlg
+
+inline CPbkContactEditorDlg::CPbkContactEditorDlg
+ (CPbkContactEngine& aEngine,
+ CPbkContactItem& aContactItem,
+ TInt aFocusIndex) :
+ iContactItem(aContactItem),
+ iEngine(aEngine),
+ iFocusIndex(aFocusIndex)
+ {
+ __ASSERT_DEBUG(!iTitlePane && !iThumbnailHandler && !iStoredTitlePaneText,
+ Panic(EPanicPostCond_Constructor));
+ }
+
+inline void CPbkContactEditorDlg::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();
+ }
+ }
+ }
+
+inline void CPbkContactEditorDlg::ConstructContextMenuL()
+ {
+ CEikMenuBar* newMenuBar = new(ELeave) CEikMenuBar();
+ CleanupStack::PushL(newMenuBar);
+ newMenuBar->ConstructL(this, NULL, R_PBK_CONTACTEDITOR_CONTEXT_MENUBAR);
+ iEikonEnv->EikAppUi()->AddToStackL(newMenuBar, ECoeStackPriorityMenu, ECoeStackFlagRefusesFocus);
+ iContextMenuBar = newMenuBar;
+ CleanupStack::Pop(newMenuBar);
+ }
+
+inline void CPbkContactEditorDlg::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();
+ }
+ }
+
+inline void CPbkContactEditorDlg::BaseConstructL
+ (TBool aIsNewContact, TBool aEdited)
+ {
+ // set feature manager in TLS
+ FeatureManager::InitializeLibL();
+
+ CAknDialog::ConstructL(R_PBK_CONTACTEDITOR_MENUBAR);
+
+ iEditorStrategy = PbkContactEditorStrategyFactory::CreateL
+ (iEngine, iContactItem, aIsNewContact);
+ if (aEdited)
+ {
+ iEditorStrategy->SetStateModified();
+ }
+
+ // check existance of syncronization field
+ if(!iContactItem.FindField(EPbkFieldIdSyncronization))
+ {
+ CPbkFieldInfo* syncFieldInfo = iEngine.FieldsInfo().Find(
+ EPbkFieldIdSyncronization);
+ if (syncFieldInfo)
+ {
+ // add syncronization field to contact - compulsory
+ iContactItem.AddFieldL(*syncFieldInfo);
+ iEditorStrategy->SetStateModified();
+ }
+ }
+
+ StoreTitlePaneTextL();
+ ConstructContextMenuL();
+ ConstructNaviPaneL();
+
+ iThumbnailHandler = CPbkThumbnailPopup::NewL(iEngine);
+ iThumbnailCmd = CPbkThumbnailCmd::NewL(iEngine, *iThumbnailHandler);
+ iExtension = CExtension::NewL(iContactItem, *this);
+ }
+
+EXPORT_C CPbkContactEditorDlg* CPbkContactEditorDlg::NewL
+ (CPbkContactEngine& aEngine,
+ CPbkContactItem& aContactItem,
+ TBool aIsNewContact,
+ TInt aFocusIndex/*=-1*/,
+ TBool aEdited/*=EFalse*/)
+ {
+ return CPbkContactEditorDlgImpl::NewL(
+ aEngine, aContactItem, aIsNewContact, aFocusIndex, aEdited);
+ }
+
+EXPORT_C void CPbkContactEditorDlg::ResetWhenDestroyed
+ (CPbkContactEditorDlg** aSelfPtr)
+ {
+ __ASSERT_DEBUG(!aSelfPtr || *aSelfPtr == this,
+ Panic(EPanicPreCond_ResetWhenDestroyed));
+ iSelfPtr = aSelfPtr;
+ }
+
+EXPORT_C void CPbkContactEditorDlg::HideExitCommand()
+ {
+ iStateFlags.Set(EHideExit);
+ }
+
+EXPORT_C void CPbkContactEditorDlg::SetExitCommandId
+ (TInt aCommandId)
+ {
+ iExitCommandId = aCommandId;
+ }
+
+CPbkContactEditorDlg::~CPbkContactEditorDlg()
+ {
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactEditorDlg::~CPbkContactEditorDlg"));
+
+ iStateFlags.Set(EUnderDestruction);
+ CloseAllPopups();
+
+ // Save unless saved yet. No other way to handle errors than ignore
+ // because exiting the dialog must always be possible.
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactEditorDlg::~CPbkContactEditorDlg(0x%x) saving"), this);
+ TRAP_IGNORE(CmdSaveL());
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING(" saved"));
+
+ // delete member data
+ delete iThumbnailHandler;
+ delete iThumbnailCmd;
+
+ if (iContextMenuBar)
+ {
+ iEikonEnv->EikAppUi()->RemoveFromStack(iContextMenuBar);
+ delete iContextMenuBar;
+ }
+
+ delete iFieldManager; // context menu bar's stack removal (above) needs field manager to be alive
+ delete iEditorStrategy;
+ delete iContextPaneIcon;
+
+ // Restore the titlepane text
+ if (iTitlePane && iStoredTitlePaneText)
+ {
+ // iTitlePane takes ownership of iStoredTitlePaneText
+ iTitlePane->SetText(iStoredTitlePaneText);
+ }
+
+ // Remove empty status pane
+ if (iNaviContainer)
+ {
+ iNaviContainer->Pop();
+ }
+ // Reset self pointer
+ if (iSelfPtr)
+ {
+ *iSelfPtr = NULL;
+ }
+ delete iExtension;
+
+ FeatureManager::UnInitializeLib();
+ }
+
+EXPORT_C TContactItemId CPbkContactEditorDlg::ExecuteLD()
+ {
+ TContactItemId ret = KNullContactId;
+ iSavedContactPtr = &ret;
+
+ // Set Phonebook icon on context pane
+ if (!iContextPaneIcon)
+ {
+ iContextPaneIcon = CPbkContextPaneIcon::NewL(*iEikonEnv);
+ }
+
+ // Set status pane layout to the Phonebook one
+ CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
+ TInt statusPaneLayout = KErrNotFound;
+ if (statusPane)
+ {
+ statusPaneLayout = statusPane->CurrentLayoutResId();
+ statusPane->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_USUAL);
+ }
+
+ CAknForm::ExecuteLD(R_PBK_EDIT_MEMORY_ENTRY_DIALOG);
+
+ if (statusPane && (statusPaneLayout != KErrNotFound))
+ {
+ statusPane->SwitchLayoutL(statusPaneLayout);
+ }
+
+ return ret;
+ }
+
+
+EXPORT_C void CPbkContactEditorDlg::SetHelpContext
+ (TCoeHelpContext aContext)
+ {
+ iHelpContext = aContext;
+ }
+
+
+/**
+ * Saves dialog's fields to contact fields and saves the contact.
+ * Command sent from class destructor.
+ */
+void CPbkContactEditorDlg::CmdSaveL()
+ {
+ if (iFieldManager)
+ {
+ // Save editor fields
+ iFieldManager->SaveFieldsL();
+ if (iFieldManager->FieldsChanged())
+ {
+ iEditorStrategy->SetStateModified();
+ }
+
+ if (iSavedContactPtr && !iFieldManager->AreAllFieldsEmpty())
+ {
+ *iSavedContactPtr = iEditorStrategy->SaveContactL();
+ }
+ }
+ }
+
+/**
+ * Command sent from OkToExitL.
+ */
+void CPbkContactEditorDlg::CmdDoneL()
+ {
+ if (iFieldManager)
+ {
+ // Save editor fields to contact item
+ iFieldManager->SaveFieldsL();
+ if (iFieldManager->FieldsChanged())
+ {
+ iEditorStrategy->SetStateModified();
+ }
+
+ if (iFieldManager->AreAllFieldsEmpty())
+ {
+ iEditorStrategy->DeleteContactL();
+ }
+
+ *iSavedContactPtr = iEditorStrategy->SaveContactL();
+ }
+ }
+
+/**
+ * Edits the focused memory items caption.
+ */
+void CPbkContactEditorDlg::CmdEditItemLabelL()
+ {
+ MPbkContactEditorField* field = iFieldManager->Find(IdOfFocusControl());
+ if (field)
+ {
+ HBufC* textBuf = HBufC::NewLC(CPbkConstants::FormEditorLength());
+ 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(CPbkConstants::FormEditorLength());
+ if (dlg->ExecuteLD(R_PBK_EDIT_FIELD_LABEL, *prompt))
+ {
+ if (text != field->FieldLabel())
+ {
+ // Assign new label leave-safely to this form and to the contact field
+ HBufC* newLabel = text.AllocLC();
+ field->SetFieldLabelL(newLabel); // takes ownership of newLabel
+ CleanupStack::Pop(newLabel);
+ iEditorStrategy->SetStateModified();
+ }
+ }
+ CleanupStack::PopAndDestroy(2); // prompt, textBuf
+ }
+ }
+
+/**
+ * Add new memory item menu command.
+ */
+void CPbkContactEditorDlg::CmdAddItemL()
+ {
+ TPbkAddItemManager manager(iContactItem, *iFieldManager);
+
+ RArray<TInt> addedFieldsControlIds;
+ CleanupClosePushL(addedFieldsControlIds);
+
+ // Query and add field(s) to the contact
+ manager.AddFieldsL(iEngine.FieldsInfo(), addedFieldsControlIds);
+
+ if (addedFieldsControlIds.Count() > 0)
+ {
+ // Activate the first added field
+ TInt focusedControlId = addedFieldsControlIds[0];
+ TryChangeFocusToL(focusedControlId);
+ iEditorStrategy->SetStateModified();
+ // must be DrawNow and not DrawDeferred
+ // otherwise field label and content of
+ // following field will be incorrect
+ DrawNow();
+ }
+ CleanupStack::PopAndDestroy(); //addedFieldsControlIds
+ }
+
+/**
+ * Deletes focused memory entry item.
+ */
+void CPbkContactEditorDlg::CmdDeleteItemL()
+ {
+ // Delete item query
+ MPbkContactEditorField* field = iFieldManager->Find(IdOfFocusControl());
+ if (field)
+ {
+ TPtrC label = field->FieldLabel();
+ HBufC* prompt = StringLoader::LoadLC(R_QTN_PHOB_QUERY_DELETE_ITEM, label);
+
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+ CleanupStack::PushL(dlg);
+ dlg->SetPromptL(*prompt);
+ CleanupStack::Pop(); // dlg
+ if(dlg->ExecuteLD(R_PBK_GENERAL_CONFIRMATION_QUERY_PBKVIEW))
+ {
+ // Notify about voice tag field deletion (unless it's SIND tag)
+ if (iContactItem.VoiceTagField() &&
+ iContactItem.VoiceTagField()->IsSame(field->ContactItemField()) &&
+ !FeatureManager::FeatureSupported(KFeatureIdSind))
+ {
+ HBufC* note = iCoeEnv->AllocReadResourceLC(R_QTN_PHOB_NOTE_VOICE_TAG_DEL);
+ CAknConfirmationNote* dlg = new(ELeave) CAknConfirmationNote(ETrue);
+ dlg->ExecuteLD(*note);
+ CleanupStack::PopAndDestroy(); // note
+ }
+
+ // Notify about speed dial field deletion
+ const TInt fieldIndex = iFieldManager->FindContactItemFieldIndex(
+ field->ContactItemField());
+ if (iEngine.IsSpeedDialAssigned(iContactItem, fieldIndex))
+ {
+ HBufC* note = iCoeEnv->AllocReadResourceLC(R_QTN_PHOB_NOTE_SPEED_DIAL_DEL);
+ CAknConfirmationNote* dlg = new(ELeave) CAknConfirmationNote(ETrue);
+ dlg->ExecuteLD(*note);
+ CleanupStack::PopAndDestroy(); // note
+ }
+
+ // Delete the field
+ iFieldManager->RemoveField(*field);
+ iEditorStrategy->SetStateModified();
+
+ // Redraw using DrawNow, DrawDeferred does not get the job done
+ DrawNow();
+ }
+
+ CleanupStack::PopAndDestroy(); // prompt
+ }
+ }
+
+/**
+ * Fetches thumbnail image from photoalbum and attaches it to this
+ * contact.
+ */
+void CPbkContactEditorDlg::CmdFetchThumbnailL()
+ {
+ //PreCond:
+ __ASSERT_DEBUG(iThumbnailCmd, Panic(EPanicPreCond_CmdFetchThumbnailL));
+
+ if (iThumbnailCmd->FetchThumbnailL(iContactItem))
+ {
+ iEditorStrategy->SetStateModified();
+ }
+ }
+
+/**
+ * Removes a thumbnail image attachment from this contact.
+ */
+void CPbkContactEditorDlg::CmdRemoveThumbnailL()
+ {
+ //PreCond:
+ __ASSERT_DEBUG(iThumbnailCmd, Panic(EPanicPreCond_CmdRemoveThumbnailL));
+
+ if (iThumbnailCmd->RemoveThumbnailL(iContactItem))
+ {
+ iEditorStrategy->SetStateModified();
+ }
+ }
+
+/**
+ * Updates the application title pane.
+ */
+void CPbkContactEditorDlg::UpdateTitlePaneL()
+ {
+ if (iTitlePane)
+ {
+ CPbkFieldDataArray* titleFields = CPbkFieldDataArray::NewL();
+ titleFields->ResetAndDestroyPushL();
+
+ const TInt fieldCount = iFieldManager->EditorCount();
+ for (TInt i = 0; i < fieldCount; ++i)
+ {
+ const MPbkContactEditorField& field = iFieldManager->FieldAt(i);
+ const TPbkFieldId fieldId = field.FieldId();
+ if (iEngine.IsTitleField(fieldId))
+ {
+ HBufC* textBuf = field.ControlTextL();
+ TPtrC text;
+ if (textBuf)
+ {
+ CleanupStack::PushL(textBuf);
+ text.Set(*textBuf);
+ }
+
+ CPbkFieldData* fieldData = CPbkFieldData::NewL(fieldId,text);
+ if (textBuf)
+ {
+ CleanupStack::PopAndDestroy(textBuf);
+ }
+ CleanupStack::PushL(fieldData);
+ titleFields->AppendL(fieldData);
+ CleanupStack::Pop(fieldData);
+ }
+ }
+
+ HBufC* newTitle = iEngine.GetContactTitleOrNullL(*titleFields);
+ CleanupStack::PopAndDestroy(); // titleFields
+
+ if (newTitle)
+ {
+ // Update title only if it doesn't contain ZWS or ZWNJ, which
+ // are a sign of incomplete typing in e.g. Hindi
+ const TChar KZeroWidthSpace(0x200b);
+ const TChar KZeroWidthNonJoiner(0x200c);
+ if ((newTitle->Locate(KZeroWidthSpace) == KErrNotFound) &&
+ (newTitle->Locate(KZeroWidthNonJoiner) == KErrNotFound))
+ {
+ iTitlePane->SetText(newTitle);
+ }
+ }
+ else
+ {
+ iTitlePane->SetTextL(iEditorStrategy->DefaultTitle());
+ }
+ }
+ }
+
+TKeyResponse CPbkContactEditorDlg::OfferKeyEventL
+ (const TKeyEvent& aKeyEvent,
+ TEventCode aType)
+ {
+ // display menu bar if the focused control doesnt consume selection keys
+ MPbkContactEditorField* field = iFieldManager->Find(IdOfFocusControl());
+ if (field && field->ConsumesKeyEvent(aKeyEvent, aType))
+ {
+ return CAknForm::OfferKeyEventL(aKeyEvent,aType);
+ }
+
+ if (aType == EEventKey && aKeyEvent.iCode == EKeyOK)
+ {
+ iContextMenuBar->TryDisplayMenuBarL();
+ return EKeyWasConsumed;
+ }
+
+ if (aType == EEventKey && aKeyEvent.iCode == EKeyEscape)
+ {
+ // See CloseAllMenusAndPopups()
+ iStateFlags.Set(EEscKeyReceived);
+ }
+
+ if (!iStateFlags.IsSet(EUnderDestruction))
+ {
+ TKeyResponse ret(EKeyWasNotConsumed);
+ ret = CAknForm::OfferKeyEventL( aKeyEvent, aType );
+ if ( !iStateFlags.IsSet(EEscKeyReceived) &&
+ ret == EKeyWasConsumed )
+ {
+ UpdateCbasL( iFieldManager->Find(IdOfFocusControl()),
+ ButtonGroupContainer() );
+ }
+ return ret;
+ }
+ else
+ {
+ return EKeyWasConsumed;
+ }
+ }
+
+void CPbkContactEditorDlg::GetHelpContext
+ (TCoeHelpContext& aContext) const
+ {
+ if (iHelpContext.iMajor.iUid)
+ {
+ // If external help context has been set, return it..
+ aContext = iHelpContext;
+ }
+ else
+ {
+ // ..otherwise go with the default context
+ aContext.iMajor.iUid = KPbkUID3;
+ iEditorStrategy->GetHelpContext(aContext);
+ }
+ }
+
+void CPbkContactEditorDlg::PreLayoutDynInitL()
+ {
+ __ASSERT_DEBUG(iFieldManager, Panic(EPanicPreCond_PreLayoutDynInitL));
+
+ SetEditableL(ETrue);
+
+ // create controls for contact items fields
+ iFieldManager->CreateFieldsFromContactL();
+
+ __ASSERT_DEBUG(iFieldManager, Panic(EPanicPostCond_PreLayoutDynInitL));
+ }
+
+void CPbkContactEditorDlg::PostLayoutDynInitL()
+ {
+ UpdateTitlePaneL();
+
+ if ( iAvkonAppUi->StatusPane()->
+ PaneCapabilities(TUid::Uid(EEikStatusPaneUidContext)).IsInCurrentLayout() )
+ {
+ iThumbnailHandler->Load(iContactItem, NULL );
+ }
+
+ // Set state to initialised (enables save from destructor)
+ iEditorStrategy->SetStateInitialized();
+ }
+
+void CPbkContactEditorDlg::SetInitialCurrentLine()
+ {
+ //PreCond:
+ __ASSERT_DEBUG(iFieldManager,
+ Panic(EPanicPreCond_SetInitialCurrentLine));
+
+ CAknForm::SetInitialCurrentLine();
+ const TInt fieldCount = iFieldManager->ContactItemFieldCount();
+ if (fieldCount > 0)
+ {
+ if (iFocusIndex < 0 || iFocusIndex >= fieldCount)
+ {
+ // In any case focus the first line
+ iFocusIndex = 0;
+ }
+ iFieldManager->SetFocusToIndex(iFocusIndex);
+ }
+ }
+
+void CPbkContactEditorDlg::ProcessCommandL
+ (TInt aCommandId)
+ {
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactEditorDlg::ProcessCommandL start"));
+
+ HideMenu();
+ iContextMenuBar->StopDisplayingMenuBar();
+
+ if ( iExtension->ProcessCommandL(aCommandId) )
+ {
+ return; // command processed
+ }
+
+ switch (aCommandId)
+ {
+ case EPbkCmdAddItem:
+ {
+ CmdAddItemL();
+ break;
+ }
+
+ case EPbkCmdDeleteItem:
+ {
+ CmdDeleteItemL();
+ break;
+ }
+
+ case EPbkCmdEditItemLabel:
+ {
+ CmdEditItemLabelL();
+ break;
+ }
+
+ case EPbkCmdFetchThumbnail:
+ {
+ CmdFetchThumbnailL();
+ break;
+ }
+
+ case EPbkCmdRemoveThumbnail:
+ {
+ CmdRemoveThumbnailL();
+ break;
+ }
+
+ case EAknCmdHelp:
+ {
+ HlpLauncher::LaunchHelpApplicationL(iEikonEnv->WsSession(),
+ iEikonEnv->EikAppUi()->AppHelpContextL());
+ break;
+ }
+
+ case EEikCmdExit: // FALLTHROUGH
+ case EAknCmdExit: // Exit calling application
+ {
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactEditorDlg::ProcessCommandL exit"));
+
+ // If exit callback returned EFalse, the exit is cancelled
+ if (iExitCallback && !iExitCallback->OkToExitL(aCommandId))
+ {
+ break;
+ }
+ const TInt exitCommandId = iExitCommandId;
+ CEikAppUi* appUi = iEikonEnv->EikAppUi();
+ // Close this dialog first
+ delete this;
+ if (exitCommandId)
+ {
+ // Exit application
+ static_cast<MEikCommandObserver*>(appUi)->ProcessCommandL(exitCommandId);
+ }
+ else
+ {
+ // Exit application
+ static_cast<MEikCommandObserver*>(appUi)->ProcessCommandL(aCommandId);
+ }
+ break;
+ }
+
+ default:
+ {
+ // Command not handled here, forward it to the app ui.
+ iEikonEnv->EikAppUi()->HandleCommandL(aCommandId);
+ break;
+ }
+ }
+
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING("CPbkContactEditorDlg::ProcessCommandL end"));
+ }
+
+void CPbkContactEditorDlg::DynInitMenuPaneL
+ (TInt aResourceId,
+ CEikMenuPane* aMenuPane)
+ {
+ iExtension->DynInitMenuPaneL(aResourceId, aMenuPane);
+
+ iEditorStrategy->DynInitMenuPaneL(aResourceId, aMenuPane);
+
+ // Options menu
+ if (aResourceId == R_CONTACTEDITOR_MENUPANE)
+ {
+ // don't show 'Exit' command if it is disabled
+ if (iStateFlags.IsSet(EHideExit))
+ {
+ aMenuPane->SetItemDimmed(EAknCmdExit,ETrue);
+ }
+
+ iThumbnailCmd->DynInitMenuPaneL(aResourceId, *aMenuPane, iContactItem);
+ }
+
+ // Common items in Options and context menus
+ if (aResourceId == R_CONTACTEDITOR_MENUPANE ||
+ aResourceId == R_PBK_CONTACTEDITOR_CONTEXT_MENUPANE)
+ {
+ // filter delete item away from menu for first and last name fields
+ // and from the syncronization field
+ MPbkContactEditorField* currentField = iFieldManager->Find(IdOfFocusControl());
+ if (currentField)
+ {
+ const TPbkFieldId fieldId = currentField->FieldId();
+ if (fieldId == EPbkFieldIdLastName || fieldId == EPbkFieldIdFirstName ||
+ fieldId == EPbkFieldIdSyncronization)
+ {
+ aMenuPane->SetItemDimmed(EPbkCmdDeleteItem, ETrue);
+ }
+ }
+ }
+ }
+
+TBool CPbkContactEditorDlg::OkToExitL(TInt aKeyCode)
+ {
+ PBK_DEBUG_PRINT(PBK_DEBUG_STRING
+ ("CPbkContactEditorDlg::OkToExitL(0x%x,%d)"), this, aKeyCode);
+
+ // editor can't be closed if this leaves
+ TRAPD(err, iExtension->PreOkToExitL(aKeyCode));
+
+ TBool ret = EFalse;
+ switch (aKeyCode)
+ {
+ case EAknSoftkeyOptions:
+ {
+ DisplayMenuL();
+ break;
+ }
+ case EAknSoftkeyDone:
+ {
+ if (!iThumbnailCmd->OkToExit())
+ {
+ // ThumbnailCmd state is not ready for exit
+ break;
+ }
+ if(iEngine.Constants()->
+ LocallyVariatedFeatureEnabled(EPbkLVCheckDuplicateEntry))
+ {
+ ret = CheckForDuplicateEntryL();
+ }
+ else
+ {
+ if (err != KErrNone)
+ {
+ // cannot affect on editor closing, but let's show
+ // that something was wrong
+ iCoeEnv->HandleError(err);
+ }
+ TRAP(err,CmdDoneL());
+ ret = ETrue;
+ }
+ break;
+ }
+ case EAknSoftkeyChange: // Fallthrough
+ case 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
+ {
+ iContextMenuBar->SetMenuTitleResourceId( R_PBK_CONTACTEDITOR_CONTEXT_MENUBAR );
+ iContextMenuBar->SetMenuType( CEikMenuBar::EMenuContext );
+ iContextMenuBar->StopDisplayingMenuBar();
+ iContextMenuBar->TryDisplayMenuBarL();
+ iContextMenuBar->SetMenuTitleResourceId( R_PBK_CONTACTEDITOR_MENUBAR );
+ iContextMenuBar->SetMenuType( CEikMenuBar::EMenuOptions );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (err == KErrNone)
+ {
+ TRAP(err, iExtension->PostOkToExitL(aKeyCode));
+ }
+ if (err != KErrNone)
+ {
+ // cannot affect on editor closing, but let's show
+ // that something was wrong
+ iCoeEnv->HandleError(err);
+ }
+ return ret;
+ }
+
+void CPbkContactEditorDlg::HandleControlStateChangeL
+ (TInt aControlId)
+ {
+ MPbkContactEditorField* changedField = iFieldManager->Find(aControlId);
+ if (changedField)
+ {
+ if ( iEngine.IsTitleField(changedField->FieldId()) )
+ {
+ UpdateTitlePaneL();
+ }
+ }
+ }
+
+/**
+ * Closes popups opened from this dialog by sending them Escape key events.
+ * @see CPbkContactEditorDlg::OfferKeyEventL
+ */
+void CPbkContactEditorDlg::CloseAllPopups()
+ {
+ const TInt KMaxAttempts = 50;
+ iStateFlags.Clear(EEscKeyReceived);
+ // Send Escape key until this dialog itself receives it
+ for (TInt attempt=0;
+ attempt < KMaxAttempts && !iStateFlags.IsSet(EEscKeyReceived);
+ ++attempt)
+ {
+ TRAP_IGNORE(iEikonEnv->SimulateKeyEventL(KEscKeyEvent,EEventKey));
+ }
+ }
+
+
+/* This function will check to see if the user entered information, coming out of the
+ * TPbkContactItemFields, matches (exactly) any entries in the contact database, based
+ * on the results of the GetContactTitle function. This function will only return what
+ * is being displayed to the user. For example, a first name of "Eric", no last name, and
+ * a company name of "Nokia" will only display "Eric" and would match an entry with
+ * just the first name of "Eric".
+ *
+ * The search has already been performed and ANY entry that matches any of the fields
+ * the user has entered (first name, last name, and/or company name) is passed into
+ * this function in the aIdArray parameter.
+ *
+ * We are checking for entries that are separate from the current entry the user is
+ * creating / editing. Therefore, if the user is editing an existing entry, we don't want
+ * to signal a match when we find that specific entry. We can check this based on the stored
+ * variable iContactItem and it's Id() function.
+ */
+TBool CPbkContactEditorDlg::DuplicateNameMatchL
+ (CContactIdArray* aIdArray)
+ {
+ TBool exactMatch = EFalse;
+ // just check the titles of the current item with the titles of each of the
+ // potentially matched items
+
+ HBufC* title = iContactItem.GetContactTitleL();
+ CleanupStack::PushL(title);
+
+ // iterate through each contact in aIdArray
+ for (TInt count = 0; count < aIdArray->Count(); count++)
+ {
+ // only continue with this check if we aren't checking our own entry. check with ID
+ if (iContactItem.Id() != (*aIdArray)[count])
+ {
+ // read the current contact
+ CPbkContactItem* contact = iEngine.ReadContactLC((*aIdArray)[count]);
+
+ // get the title of this current contact to compare
+ HBufC* contactTitle = contact->GetContactTitleL();
+ CleanupStack::PushL(contactTitle);
+
+ // now just compare the titles of this loop contact and the user-entered contact
+ if (!title->CompareF(*contactTitle))
+ {
+ exactMatch = ETrue;
+ CleanupStack::PopAndDestroy(2); // name, contact
+ break;
+ }
+ CleanupStack::PopAndDestroy(2); // name, contact
+ }
+ }
+
+ CleanupStack::PopAndDestroy(title);
+ return exactMatch;
+ }
+
+ /*
+ * This function pulls user-entered info from the dialog for firstname, lastname and companyname.
+ * We search the contact database on the first of these that is non-empty and not all spaces. If
+ * we come up with any matches, we pass this info to the function DuplicateNameMatch, which checks
+ * that all three fields match the found entries from the database search. If this is the case,
+ * we pass back an ETrue value, EFalse otherwise.
+ */
+TBool CPbkContactEditorDlg::ContactAlreadyExistsL()
+ {
+ TBool found = EFalse;
+ CContactIdArray* idArray = NULL;
+
+ CPbkFieldIdArray* findFrom = new(ELeave) CPbkFieldIdArray;
+ CleanupStack::PushL(findFrom);
+
+ // add all fields, firstname, lastname and companyname to our contact database find parameter
+ findFrom->AppendL(EPbkFieldIdFirstName);
+ findFrom->AppendL(EPbkFieldIdLastName);
+ findFrom->AppendL(EPbkFieldIdCompanyName);
+
+ // get local copies of user-filled-in contact fields' text values
+ TPbkContactItemField* firstName = iContactItem.FindField(EPbkFieldIdFirstName);
+ TPbkContactItemField* lastName = iContactItem.FindField(EPbkFieldIdLastName);
+ TPbkContactItemField* companyName = iContactItem.FindField(EPbkFieldIdCompanyName);
+
+ // this is terribly slow
+ if (firstName && !firstName->IsEmptyOrAllSpaces())
+ {
+ idArray = iEngine.FindLC(firstName->Text(), findFrom);
+ }
+ else if (lastName && !lastName->IsEmptyOrAllSpaces())
+ {
+ idArray = iEngine.FindLC(lastName->Text(), findFrom);
+ }
+ else if (companyName && !companyName->IsEmptyOrAllSpaces())
+ {
+ idArray = iEngine.FindLC(companyName->Text(), findFrom);
+ }
+ else
+ {
+ // fname, lname and cname all empty - check for other "Unnamed" entries
+ // Two unnamed contacts are considered duplicates
+ idArray = iEngine.FindLC(KNullDesC, findFrom);
+ }
+
+ // if we have at least one match, check that all fields match
+ if (idArray)
+ {
+ if (idArray->Count() > 0 && DuplicateNameMatchL(idArray))
+ {
+ found = ETrue;
+ }
+ CleanupStack::PopAndDestroy(idArray);
+ }
+
+ CleanupStack::PopAndDestroy(findFrom);
+ return found;
+ }
+
+
+TBool CPbkContactEditorDlg::CheckForDuplicateEntryL()
+ {
+ TBool retVal = ETrue;
+ TBool exitNormally = ETrue;
+
+ // Check for duplicate entry and give the user the option to
+ // save duplicate or return to enter more information.
+
+ // To perform that check, we must save the info the user has
+ // just entered (just locally, not in the contact database)
+ if (iFieldManager)
+ {
+ iFieldManager->SaveFieldsL();
+ if ( iFieldManager->FieldsChanged() )
+ {
+ iEditorStrategy->SetStateModified();
+ }
+
+ // Totally empty contacts are not checked for duplicates
+ if ( !iFieldManager->AreAllFieldsEmpty() )
+ {
+ // If contact already exists, inform the user and given them
+ // the option to add the duplicate, or go back to the screen
+ // and enter information
+ if ( ContactAlreadyExistsL() )
+ {
+ // Get contact title to display
+ HBufC* name = iContactItem.GetContactTitleL();
+ CleanupStack::PushL( name );
+
+ HBufC* prompt = StringLoader::LoadL(R_QTN_PHOB_ADD_DUPLICATE,
+ *name );
+ CleanupStack::PushL( prompt );
+
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+ CleanupStack::PushL( dlg );
+ dlg->SetPromptL( *prompt );
+ CleanupStack::Pop(); // dlg
+ // If user hits no, we'll put them back to the edit screen
+ if ( !dlg->ExecuteLD(R_PBK_GENERAL_CONFIRMATION_QUERY_PBKVIEW) )
+ {
+ exitNormally = EFalse;
+ retVal = EFalse;
+ }
+ CleanupStack::PopAndDestroy( 2 ); // prompt, name
+ }
+ }
+ }
+
+ if (exitNormally)
+ {
+ CmdDoneL(); // saving occurs here
+ retVal = ETrue;
+ }
+
+ return retVal;
+ }
+
+EXPORT_C void CPbkContactEditorDlg::SetExitCallback
+ (MPbkEditorOkToExitCallback* aCallback)
+ {
+ iExitCallback = aCallback;
+ }
+
+void CPbkContactEditorDlg::ReloadThumbnailL()
+ {
+ if ( iAvkonAppUi->StatusPane()->
+ PaneCapabilities(TUid::Uid(EEikStatusPaneUidContext)).IsInCurrentLayout() )
+ {
+ if (IsFocused())
+ {
+ if (!iThumbnailHandler)
+ {
+ iThumbnailHandler = CPbkThumbnailPopup::NewL(iEngine);
+ }
+ iThumbnailHandler->Load(iContactItem, NULL );
+ }
+ else
+ {
+ if (iThumbnailHandler)
+ {
+ iThumbnailHandler->CancelLoading();
+ }
+ }
+ }
+ }
+
+// End of File