/*
* 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 server app contact data assign phase.
*
*/
#include "CPbk2SingleAssignDataPhase.h"
// Phonebook 2
#include "MPbk2ServicePhaseObserver.h"
#include "CPbk2ServerAppAppUi.h"
#include "MPbk2ContactAssigner.h"
#include "Pbk2ContactAssignerFactory.h"
#include "CPbk2ContactEditorOperator.h"
#include "MPbk2SelectFieldProperty.h"
#include "TPbk2AssignNoteService.h"
#include "Pbk2ServerApp.hrh"
#include <MPbk2DialogEliminator.h>
#include <TPbk2DestructionIndicator.h>
#include <CPbk2StoreConfiguration.h>
#include <MPbk2ApplicationServices.h>
#include <Pbk2UIControls.rsg>
#include <Pbk2ServerApp.rsg>
// Virtual Phonebook
#include <MVPbkContactLink.h>
#include <CVPbkContactLinkArray.h>
#include <MVPbkContactOperationBase.h>
#include <MVPbkStoreContact.h>
#include <MVPbkContactStore.h>
#include <CVPbkContactManager.h>
#include <MVPbkContactStoreProperties.h>
#include <VPbkContactStoreUris.h>
#include <CVPbkContactStoreUriArray.h>
// System includes
#include <AiwContactAssignDataTypes.h>
using namespace AiwContactAssign;
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::CPbk2SingleAssignDataPhase
// --------------------------------------------------------------------------
//
CPbk2SingleAssignDataPhase::CPbk2SingleAssignDataPhase
( MPbk2ServicePhaseObserver& aObserver,
MVPbkStoreContact* aStoreContact,
MPbk2SelectFieldProperty* aSelectedFieldProperty,
TInt aSelectedFieldIndex, HBufC* aDataBuffer, TInt aMimeType,
TCoeHelpContext aHelpContext,
TUint aAssignFlags, TUint aNoteFlags ) :
iObserver( aObserver ),
iStoreContact( aStoreContact ),
iSelectedFieldIndex( aSelectedFieldIndex ),
iSelectedFieldProperty( aSelectedFieldProperty ),
iDataBuffer( aDataBuffer ),
iMimeType( aMimeType ),
iHelpContext( aHelpContext ),
iAssignFlags( aAssignFlags ),
iNoteFlags( aNoteFlags ),
iEikEnv( CEikonEnv::Static() )
{
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::~CPbk2SingleAssignDataPhase
// --------------------------------------------------------------------------
//
CPbk2SingleAssignDataPhase::~CPbk2SingleAssignDataPhase()
{
if ( iContactEditorEliminator )
{
iContactEditorEliminator->ForceExit();
}
delete iResults;
delete iContactDataAssigner;
delete iStoreContact;
if ( iDestroyedPtr )
{
*iDestroyedPtr = ETrue;
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::NewL
// --------------------------------------------------------------------------
//
CPbk2SingleAssignDataPhase* CPbk2SingleAssignDataPhase::NewL
( MPbk2ServicePhaseObserver& aObserver,
MVPbkStoreContact* aStoreContact,
MPbk2SelectFieldProperty* aSelectedFieldProperty,
TInt aSelectedFieldIndex, HBufC* aDataBuffer, TInt aMimeType,
TCoeHelpContext aHelpContext,
TUint aAssignFlags, TUint aNoteFlags )
{
CPbk2SingleAssignDataPhase* self =
new ( ELeave ) CPbk2SingleAssignDataPhase
( aObserver, aStoreContact, aSelectedFieldProperty,
aSelectedFieldIndex, aDataBuffer, aMimeType, aHelpContext,
aAssignFlags, aNoteFlags );
return self;
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::LaunchServicePhaseL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::LaunchServicePhaseL()
{
DoAssignDataL();
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::CancelServicePhase
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::CancelServicePhase()
{
if ( iContactEditorEliminator )
{
// Changes won't be saved here.
iContactEditorEliminator->ForceExit();
}
// Notify observer to complete its message.
iObserver.PhaseCanceled( *this );
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::RequestCancelL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::RequestCancelL( TInt aExitCommandId )
{
if ( iContactEditorEliminator )
{
// Do not notify observer about abortion here, we must let
// contact editor to do it. Otherwise the changes would not be saved.
iContactEditorEliminator->RequestExitL( aExitCommandId );
}
else
{
if ( aExitCommandId == EEikBidCancel )
{
iObserver.PhaseAborted( *this );
}
else
{
iObserver.PhaseCanceled( *this );
}
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::AcceptDelayed
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::AcceptDelayedL
( const TDesC8& /*aContactLinkBuffer*/ )
{
// Nothing to do
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::Results
// --------------------------------------------------------------------------
//
MVPbkContactLinkArray* CPbk2SingleAssignDataPhase::Results() const
{
return iResults;
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::ExtraResultData
// --------------------------------------------------------------------------
//
TInt CPbk2SingleAssignDataPhase::ExtraResultData() const
{
return iSelectedFieldIndex;
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::TakeStoreContact
// --------------------------------------------------------------------------
//
MVPbkStoreContact* CPbk2SingleAssignDataPhase::TakeStoreContact()
{
MVPbkStoreContact* contact = iStoreContact;
iStoreContact = NULL;
return contact;
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::FieldContent
// --------------------------------------------------------------------------
//
HBufC* CPbk2SingleAssignDataPhase::FieldContent() const
{
return NULL;
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::AssignComplete
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::AssignComplete
( MPbk2ContactAssigner& /*aAssigner*/, TInt aIndex )
{
// aIndex is KErrNotSupported from CPbk2ContactEmptyDataAssigner
// but iSelectedFieldIndex may still be set previously.
if (aIndex == KErrNotSupported)
{
aIndex = iSelectedFieldIndex;
}
TRAPD( err, HandleContactDataAssignedL( aIndex ) );
if ( err != KErrNone )
{
// HandleContactDataAssignedL will leave with KErrDied if
// this was destroyed, then we will not inform observer
// since iObserver is no more. Syslib's CBaActiveScheduler leaves
// with KLeaveExit (in certain situations, e.g. pressing End key
// with delete-dialog open when assigning empty contact.
if ( err != KErrDied && err != KLeaveExit )
{
iObserver.PhaseError( *this, err );
}
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::AssignFailed
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::AssignFailed
( MPbk2ContactAssigner& /*aAssigner*/, TInt aErrorCode )
{
iObserver.PhaseError( *this, aErrorCode );
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::ContactOperationCompleted
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::ContactOperationCompleted
( TContactOpResult aResult )
{
TInt err = KErrNone;
if ( aResult.iOpCode == EContactLock )
{
TRAP( err, DoAssignDataL() );
}
else if ( aResult.iOpCode == EContactCommit )
{
TRAP( err, FinalizeL( iStoreContact ) );
}
if ( err != KErrNone )
{
iObserver.PhaseError( *this, err );
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::ContactOperationFailed
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::ContactOperationFailed
( TContactOp /*aOpCode*/, TInt aErrorCode, TBool /*aErrorNotified*/ )
{
// Locking or committing the contact failed
iObserver.PhaseError( *this, aErrorCode );
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::ContactEditingComplete
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::ContactEditingComplete
( MVPbkStoreContact* aEditedContact )
{
delete iStoreContact;
iStoreContact = aEditedContact;
TRAPD( err, FinalizeL( iStoreContact ) );
if ( err != KErrNone )
{
iObserver.PhaseError( *this, err );
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::ContactEditingDeletedContact
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::ContactEditingDeletedContact
( MVPbkStoreContact* aEditedContact )
{
delete iStoreContact;
iStoreContact = aEditedContact;
// Reset note flags
iNoteFlags |= KPbk2NoteFlagContactDeleted;
// Finalize, but with no results to append
TRAPD( err, FinalizeL( NULL ) );
if ( err != KErrNone )
{
iObserver.PhaseError( *this, err );
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::ContactEditingAborted
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::ContactEditingAborted()
{
iObserver.PhaseAborted( *this );
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::OkToExitL
// --------------------------------------------------------------------------
//
TBool CPbk2SingleAssignDataPhase::OkToExitL( TInt aCommandId )
{
return iObserver.PhaseOkToExit( *this, aCommandId );
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::DoAssignDataL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::DoAssignDataL()
{
const MVPbkFieldType* fieldType = NULL;
MVPbkStoreContactField* field = NULL;
if ( iSelectedFieldProperty )
{
fieldType = iSelectedFieldProperty->SelectedFieldType();
if ( iSelectedFieldIndex >= KErrNone )
{
field = &iStoreContact->Fields().FieldAt( iSelectedFieldIndex );
}
}
CPbk2ServerAppAppUi& appUi = static_cast<CPbk2ServerAppAppUi&>
( *iEikEnv->EikAppUi() );
delete iContactDataAssigner;
iContactDataAssigner = NULL;
iContactDataAssigner =
Pbk2ContactAssignerFactory::CreateContactDataAssignerL
( *this, iMimeType, fieldType,
appUi.ApplicationServices().ContactManager(),
appUi.ApplicationServices().FieldProperties() );
iContactDataAssigner->AssignDataL
( *iStoreContact, field, fieldType, iDataBuffer );
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::HandleContactDataAssignedL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::HandleContactDataAssignedL( TInt aIndex )
{
TInt index = aIndex;
// If desired, open editor
if ( !( iAssignFlags & EDoNotOpenEditor ) )
{
if ( iAssignFlags & ECreateNewContact )
{
// If we created a new contact, set focus to first field
index = KErrNotFound;
}
TBool thisDestroyed = EFalse;
iDestroyedPtr = &thisDestroyed;
TPbk2DestructionIndicator indicator
( &thisDestroyed, iDestroyedPtr );
CPbk2ContactEditorOperator* editorOperator =
CPbk2ContactEditorOperator::NewLC( *this, *this );
iContactEditorEliminator = editorOperator;
iContactEditorEliminator->ResetWhenDestroyed
( &iContactEditorEliminator );
editorOperator->OpenEditorL(
iStoreContact, index, iAssignFlags, iHelpContext );
// index is updated when editor is closed.
iSelectedFieldIndex = index;
CleanupStack::PopAndDestroy(); // operator
if ( thisDestroyed )
{
// The calling code excepts us to leave with KErrDied if
// this was destroyed
User::Leave( KErrDied );
}
}
else
{
iStoreContact->CommitL( *this );
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::AppendResultL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::AppendResultL
( const MVPbkStoreContact* aStoreContact )
{
if ( aStoreContact )
{
// Add the contact link to the result array
MVPbkContactLink* link = aStoreContact->CreateLinkLC();
if ( link )
{
if ( !iResults )
{
iResults = CVPbkContactLinkArray::NewL();
}
CleanupStack::Pop(); // aStoreContact->CreateLinkLC()
iResults->AppendL( link );
}
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::DisplayNotesL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::DisplayNotesL()
{
TPbk2AssignNoteService noteService;
CPbk2ServerAppAppUi& appUi = static_cast<CPbk2ServerAppAppUi&>
( *iEikEnv->EikAppUi() );
if ( !(iNoteFlags & KPbk2NoteFlagContactDeleted)
&&!(iAssignFlags & EskipInfoNotes) )
{
// Show note if new contact was created
if ( iNoteFlags & KPbk2NoteFlagOneContactCreated )
{
if ( IsContactInSelectedMemoryL( *iStoreContact ) )
{
noteService.ShowInformationNoteL
( R_QTN_PHOB_NOTE_CONTACT_CREATED );
}
else
{
TVPbkContactStoreUriPtr contactUri =
iStoreContact->ParentStore().StoreProperties().Uri();
CPbk2StorePropertyArray& array =
appUi.ApplicationServices().StoreProperties();
noteService.ShowInformationNoteL
( R_QTN_PHOB_NOTE_CONTACT_HIDDEN, contactUri, array );
}
}
// Show note if existing contact was updated
else
{
if ( iNoteFlags & KPbk2NoteFlagOneContactRelocated )
{
CPbk2StorePropertyArray& array =
appUi.ApplicationServices().StoreProperties();
TVPbkContactStoreUriPtr store
( VPbkContactStoreUris::DefaultCntDbUri() );
noteService.ShowInformationNoteL
( R_QTN_PHOB_NOTE_CONTACT_HIDDEN, store, array );
}
else
{
noteService.ShowInformationNoteL
( R_QTN_PHOB_NOTE_CONTACT_UPDATED );
}
}
}
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::IsContactInSelectedMemoryL
// --------------------------------------------------------------------------
//
TBool CPbk2SingleAssignDataPhase::IsContactInSelectedMemoryL
( MVPbkStoreContact& aContact )
{
TBool result( EFalse );
TVPbkContactStoreUriPtr contactUri =
aContact.ParentStore().StoreProperties().Uri();
CPbk2ServerAppAppUi& appUi = static_cast<CPbk2ServerAppAppUi&>
( *iEikEnv->EikAppUi() );
CVPbkContactStoreUriArray* currentConfig =
appUi.ApplicationServices().StoreConfiguration().
CurrentConfigurationL();
CleanupStack::PushL( currentConfig );
if ( currentConfig->IsIncluded( contactUri ) )
{
result = ETrue;
}
CleanupStack::PopAndDestroy( currentConfig );
return result;
}
// --------------------------------------------------------------------------
// CPbk2SingleAssignDataPhase::FinalizeL
// --------------------------------------------------------------------------
//
void CPbk2SingleAssignDataPhase::FinalizeL
( const MVPbkStoreContact* aStoreContact )
{
AppendResultL( aStoreContact );
DisplayNotesL();
iObserver.NextPhase( *this );
}
// End of File