--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/CPbk2ContactEditorEditContact.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,415 @@
+/*
+* 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 strategy for editing contact.
+*
+*/
+
+
+#include "CPbk2ContactEditorEditContact.h"
+
+// Phonebook 2
+#include "CPbk2InputAbsorber.h"
+#include <Pbk2UIControls.rsg>
+#include <TPbk2ContactEditorParams.h>
+#include <CPbk2PresentationContact.h>
+#include <CPbk2GeneralConfirmationQuery.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <MPbk2ApplicationServices.h>
+#include <MPbk2AppUi.h>
+#include <csxhelp/phob.hlp.hrh>
+#include <Pbk2UID.h>
+#include <MPbk2ContactEditorEventObserver.h>
+#include <CPbk2ApplicationServices.h>
+
+// Virtual Phonebook
+#include <MVPbkContactStore.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkFieldType.h>
+#include <MVPbkContactFieldData.h>
+#include <VPbkEng.rsg>
+
+// System includes
+#include <avkon.rsg>
+#include <eikon.hrh>
+
+
+#ifdef _DEBUG
+
+/// Unnamed namespace for local definitions
+namespace {
+
+enum TPanicCode
+ {
+ ESaveContactL_PreCond,
+ EContactOperationCompleted_PreCond,
+ EContactOperationFailed_PreCond,
+ EDeleteContactL_PreCond
+ };
+
+void Panic( TInt aReason )
+ {
+ _LIT( KPanicText, "CPbk2ContactEditorEditContact");
+ User::Panic(KPanicText, aReason);
+ }
+
+} /// namespace
+
+#endif // _DEBUG
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::CPbk2ContactEditorEditContact
+// --------------------------------------------------------------------------
+//
+inline CPbk2ContactEditorEditContact::CPbk2ContactEditorEditContact(
+ CPbk2PresentationContact* aContact) :
+ CActive(CActive::EPriorityStandard),
+ iContact(aContact)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::~CPbk2ContactEditorEditContact
+// --------------------------------------------------------------------------
+//
+CPbk2ContactEditorEditContact::~CPbk2ContactEditorEditContact()
+ {
+ Cancel();
+ delete iIdleDelete;
+ delete iInputAbsorber;
+ if( iAppServices )
+ {
+ Release( iAppServices );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2ContactEditorEditContact::ConstructL()
+ {
+ iContact->AddSupportedTemplateFieldsL();
+ iInputAbsorber = CPbk2InputAbsorber::NewL(R_AVKON_SOFTKEYS_OPTIONS_DONE);
+
+ /*
+ * In social phonebook case, this class is used outside from Pbk2 context
+ * which causes that Pbk2AppUi is not valid
+ */
+ iAppServices = CPbk2ApplicationServices::InstanceL();
+ iNameFormatter = &iAppServices->NameFormatter();
+
+ //Is empty when create edit dialog
+ iIsEmpty = IsActualContactEmpty();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2ContactEditorEditContact* CPbk2ContactEditorEditContact::NewL
+ ( TPbk2ContactEditorParams& /*aParams*/,
+ CPbk2PresentationContact* aContact )
+ {
+ CPbk2ContactEditorEditContact* self =
+ new ( ELeave ) CPbk2ContactEditorEditContact( aContact );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::RunL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::RunL()
+ {
+ MPbk2ContactEditorEventObserver* observer = iObserver;
+ iObserver = NULL;
+ observer->ContactEditorOperationCompleted
+ ( iLatestResult, iEditorParams );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::DoCancel
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::DoCancel()
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::RunError
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactEditorEditContact::RunError( TInt /*aError*/ )
+ {
+ // No leaving code in RunL
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::SaveContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::SaveContactL
+ ( MPbk2ContactEditorEventObserver& aObserver,
+ MPbk2ContactEditorEventObserver::TParams& aParams )
+ {
+ __ASSERT_DEBUG(!iObserver || iObserver == &aObserver,
+ Panic(ESaveContactL_PreCond));
+
+ // If we have already observer then we have also delete or commit
+ // operation under construction
+ if ( !iObserver )
+ {
+ iObserver = &aObserver;
+ iEditorParams = aParams;
+ iContact->CommitL(*this);
+ iInputAbsorber->Wait();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::DeleteContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::DeleteContactL(
+ MPbk2ContactEditorEventObserver& aObserver,
+ MPbk2ContactEditorEventObserver::TParams& aParams)
+ {
+ __ASSERT_DEBUG(!iObserver || iObserver == &aObserver,
+ Panic(EDeleteContactL_PreCond));
+
+ // If we have already observer then we have also delete or commit
+ // operation under construction
+ if ( !iObserver )
+ {
+ iObserver = &aObserver;
+ iEditorParams = aParams;
+ // If the "end key" was pressed the confirmation query is not shown, the
+ // contact is deleted straight away.
+ if ( iEditorParams.iFlags & MPbk2ContactEditorEventObserver::EPbk2EditorKeyCode
+ && ( iEditorParams.iKeyCode == EKeyEscape || iEditorParams.iKeyCode == EEikBidCancel ) )
+ {
+ iContact->DeleteL(*this);
+ iInputAbsorber->Wait();
+ }
+ else
+ {
+ // Delete the contact if the real contact in store is empty
+ if (iIsEmpty || iEditorParams.iCommandId == EEikBidCancel)
+ {
+ iContact->DeleteL(*this);
+ }
+ else
+ {
+ iQuery = CPbk2GeneralConfirmationQuery::NewL();
+ TInt ret = iQuery->ExecuteLD(*iContact, R_QTN_QUERY_COMMON_CONF_DELETE);
+
+ // iQuery could be stopped and set null by StopQuery()
+ if ( iQuery )
+ {
+ iQuery = NULL;
+
+ if (ret)
+ {
+ iContact->DeleteL(*this);
+ }
+ else
+ {
+ CancelDeleteL();
+ }
+ }
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::DefaultTitle
+// --------------------------------------------------------------------------
+//
+const TDesC& CPbk2ContactEditorEditContact::DefaultTitle() const
+ {
+ return iNameFormatter->UnnamedText();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::SwitchContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::SwitchContactL
+ (CPbk2PresentationContact* aContact)
+ {
+ iContact = aContact;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::GetHelpContext
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::GetHelpContext
+ ( TCoeHelpContext &aContext ) const
+ {
+ aContext.iMajor.iUid = KPbk2UID3;
+ aContext.iContext = KHLP_CCA_EDITOR;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::StopQuery
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorEditContact::StopQuery()
+ {
+ TBool ret = EFalse;
+ if ( iQuery )
+ {
+ ret = ETrue;
+ iQuery->StopQuery();
+ iQuery = NULL;
+
+ CancelDeleteL();
+ }
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::ContactOperationCompleted
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::ContactOperationCompleted
+ ( MVPbkContactObserver::TContactOpResult aResult )
+ {
+ __ASSERT_DEBUG(iObserver &&
+ aResult.iOpCode == MVPbkContactObserver::EContactCommit ||
+ aResult.iOpCode == MVPbkContactObserver::EContactDelete,
+ Panic(EContactOperationCompleted_PreCond));
+
+ iInputAbsorber->StopWait();
+ iLatestResult = aResult;
+
+ // We have to notify success asynchronously, because the
+ // all contacts view needs some time to get restructured
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::ContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::ContactOperationFailed
+ ( MVPbkContactObserver::TContactOp aOpCode,
+ TInt aErrorCode, TBool aErrorNotified )
+ {
+ __ASSERT_DEBUG(iObserver, Panic(EContactOperationFailed_PreCond));
+
+ iInputAbsorber->StopWait();
+ MPbk2ContactEditorEventObserver* observer = iObserver;
+ iObserver = NULL;
+
+ MPbk2ContactEditorEventObserver::TFailParams failParams;
+ failParams.iCloseEditor = EFalse;
+ failParams.iErrorNotified = aErrorNotified;
+ failParams.iErrorCode = KErrNone;
+
+ observer->ContactEditorOperationFailed
+ ( aOpCode, aErrorCode, iEditorParams, failParams );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::IdleDeleteCallBack
+// --------------------------------------------------------------------------
+//
+TInt CPbk2ContactEditorEditContact::IdleDeleteCallBack(TAny* aSelf)
+ {
+ static_cast<CPbk2ContactEditorEditContact*>(aSelf)->HandleIdleDelete();
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::HandleIdleDelete
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::HandleIdleDelete()
+ {
+ iInputAbsorber->StopWait();
+ MPbk2ContactEditorEventObserver* observer = iObserver;
+ iObserver = NULL;
+ MVPbkContactObserver::TContactOpResult result;
+ // Send commit event, since contact was not deleted. Nor it was
+ // commited, but lets emulate commit.
+ result.iOpCode = MVPbkContactObserver::EContactCommit;
+ result.iStoreContact = NULL;
+ result.iExtension = NULL;
+ observer->ContactEditorOperationCompleted( result, iEditorParams );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::CancelDeleteL
+// --------------------------------------------------------------------------
+//
+void CPbk2ContactEditorEditContact::CancelDeleteL()
+ {
+ // Notify caller asynchronously about delete cancellation
+ if (!iIdleDelete)
+ {
+ iIdleDelete = CIdle::NewL(CActive::EPriorityStandard);
+ }
+ else
+ {
+ iIdleDelete->Cancel();
+ }
+ iIdleDelete->Start(TCallBack(&IdleDeleteCallBack, this));
+ iInputAbsorber->Wait();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2ContactEditorEditContact::IsActualContactEmpty
+// check the actual store contact this contact maps to
+// return true if the real contact in store is empty
+// --------------------------------------------------------------------------
+//
+TBool CPbk2ContactEditorEditContact::IsActualContactEmpty()
+ {
+ TInt fieldCount = iContact->Fields().FieldCount();
+ const MVPbkStoreContactFieldCollection& fieldSet = iContact->Fields();
+ for (TInt i=0; i < fieldCount; ++i)
+ {
+ const MVPbkStoreContactField& field = fieldSet.FieldAt(i);
+
+ //Skip field check for image,ringtone and Syncronization fields
+ const MVPbkFieldType* fieldType = field.BestMatchingFieldType();
+ TInt fieldTypeId = fieldType->FieldTypeResId();
+ if (fieldTypeId != R_VPBK_FIELD_TYPE_RINGTONE &&
+ fieldTypeId != R_VPBK_FIELD_TYPE_THUMBNAILPIC &&
+ fieldTypeId != R_VPBK_FIELD_TYPE_CALLEROBJIMG &&
+ fieldTypeId != R_VPBK_FIELD_TYPE_SYNCCLASS)
+ {
+ if (!field.FieldData().IsEmpty())
+ {
+ // There was a field, which was not empty (or all spaces),
+ // that's enough for us, the contact gets sent
+ return EFalse;
+ }
+ }
+ }
+ return ETrue;
+ }
+
+// End of File