phonebookui/Phonebook2/ServerApplication/src/CPbk2PrepareSingleAssignPhase.cpp
branchRCL_3
changeset 20 f4a778e096c2
child 21 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/ServerApplication/src/CPbk2PrepareSingleAssignPhase.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,642 @@
+/*
+* 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 prepare single assign phase.
+*
+*/
+
+
+#include "CPbk2PrepareSingleAssignPhase.h"
+
+// Phonebook 2
+#include "MPbk2ServicePhaseObserver.h"
+#include "CPbk2ServerAppAppUi.h"
+#include "Pbk2ContactAssignerFactory.h"
+#include "TPbk2AssignNoteService.h"
+#include "MPbk2SelectFieldProperty.h"
+#include "Pbk2ServerApp.hrh"
+#include "CPbk2KeyEventDealer.h"
+#include <TPbk2DestructionIndicator.h>
+#include <MPbk2ApplicationServices.h>
+#include <Pbk2ServerApp.rsg>
+
+// Virtual Phonebook
+#include <MVPbkContactLink.h>
+#include <CVPbkContactLinkArray.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactStoreProperties.h>
+#include <VPbkContactStoreUris.h>
+
+
+using namespace Pbk2ContactRelocator;
+
+/// Unnamed namespace for local definitions
+namespace {
+
+#ifdef _DEBUG
+
+enum TPanicCode
+    {
+    ENullPointer,
+    ELogicRelocation
+    };
+
+void Panic(TPanicCode aReason)
+    {
+    _LIT( KPanicText, "CPbk2PrepareSingleAssignPhase" );
+    User::Panic( KPanicText, aReason );
+    }
+
+#endif // _DEBUG
+
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::CPbk2PrepareSingleAssignPhase
+// --------------------------------------------------------------------------
+//
+CPbk2PrepareSingleAssignPhase::CPbk2PrepareSingleAssignPhase
+        ( MPbk2ServicePhaseObserver& aObserver,
+          MVPbkStoreContact* aStoreContact,
+          MPbk2SelectFieldProperty* aSelectFieldProperty,
+          TInt aSelectFieldResult, TInt& aFieldIndex, TUint& aNoteFlags,
+          TUint aRelocationFlags ) :
+            CActive( EPriorityIdle ),
+            iObserver( aObserver ),
+            iStoreContact( aStoreContact ),
+            iSelectFieldResult( aSelectFieldResult ),
+            iSelectFieldProperty( aSelectFieldProperty ),
+            iFieldIndex( aFieldIndex ),
+            iNoteFlags( aNoteFlags ),
+            iRelocationFlags( aRelocationFlags )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::~CPbk2PrepareSingleAssignPhase
+// --------------------------------------------------------------------------
+//
+CPbk2PrepareSingleAssignPhase::~CPbk2PrepareSingleAssignPhase()
+    {
+    Cancel();
+    delete iContactRelocator;
+    delete iStoreContact;
+    delete iResults;
+    delete iDealer;
+
+    if ( iDestroyedPtr )
+        {
+        *iDestroyedPtr = ETrue;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2PrepareSingleAssignPhase::ConstructL()
+    {
+    iEikEnv = CEikonEnv::Static();
+
+    iDealer = CPbk2KeyEventDealer::NewL( *this );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2PrepareSingleAssignPhase* CPbk2PrepareSingleAssignPhase::NewL
+        ( MPbk2ServicePhaseObserver& aObserver,
+          MVPbkStoreContact* aStoreContact,
+          MPbk2SelectFieldProperty* aSelectFieldProperty,
+          TInt aSelectFieldResult, TInt& aFieldIndex, TUint& aNoteFlags,
+          TUint aRelocationFlags  )
+    {
+    CPbk2PrepareSingleAssignPhase* self =
+        new ( ELeave ) CPbk2PrepareSingleAssignPhase
+            ( aObserver, aStoreContact, aSelectFieldProperty,
+              aSelectFieldResult, aFieldIndex, aNoteFlags,
+              aRelocationFlags );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::LaunchServicePhaseL
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::LaunchServicePhaseL()
+    {
+    IssueRequest();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::CancelServicePhase
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::CancelServicePhase()
+    {
+    delete iContactRelocator;
+    iContactRelocator = NULL;
+
+    iObserver.PhaseCanceled( *this );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::RequestCancelL
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::RequestCancelL( TInt aExitCommandId )
+    {
+    delete iContactRelocator;
+    iContactRelocator = NULL;
+
+    // Withdraw our key event agent so that it does not react to
+    // app shutter's escape key event simulation
+    delete iDealer;
+    iDealer = NULL;
+
+   if ( aExitCommandId == EEikBidCancel )
+        {
+        iObserver.PhaseAborted( *this );
+        }
+    else
+        {
+        iObserver.PhaseCanceled( *this );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::AcceptDelayed
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::AcceptDelayedL
+        ( const TDesC8& /*aContactLinkBuffer*/ )
+    {
+    // Nothing to do
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::DenyDelayed
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::DenyDelayedL
+        ( const TDesC8& /*aContactLinkBuffer*/ )
+    {
+    // Nothing to do
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::Results
+// --------------------------------------------------------------------------
+//
+MVPbkContactLinkArray* CPbk2PrepareSingleAssignPhase::Results() const
+    {
+    return iResults;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::ExtraResultData
+// --------------------------------------------------------------------------
+//
+TInt CPbk2PrepareSingleAssignPhase::ExtraResultData() const
+    {
+    return KErrNotSupported;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::TakeStoreContact
+// --------------------------------------------------------------------------
+//
+MVPbkStoreContact* CPbk2PrepareSingleAssignPhase::TakeStoreContact()
+    {
+    MVPbkStoreContact* contact = iStoreContact;
+    iStoreContact = NULL;
+    return contact;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::FieldContent
+// --------------------------------------------------------------------------
+//
+HBufC* CPbk2PrepareSingleAssignPhase::FieldContent() const
+    {
+    return NULL;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::RunL
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::RunL()
+    {
+    PrepareForAssignL();
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::RunError
+// --------------------------------------------------------------------------
+//
+TInt CPbk2PrepareSingleAssignPhase::RunError( TInt aError )
+    {
+    if ( aError != KErrDied )
+        {
+        // If this is destroyed it is not safe to use iObserver anymore
+        iObserver.PhaseError( *this, aError );
+        }
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2SelectCreateNewPropertyPhase::DoCancel
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::DoCancel()
+    {
+    // Nothing to do
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::ContactRelocatedL
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::ContactRelocatedL
+        ( MVPbkStoreContact* aRelocatedContact )
+    {
+    delete iStoreContact;
+    iStoreContact = aRelocatedContact;
+
+    AppendResultL( iStoreContact );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::ContactRelocationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::ContactRelocationFailed
+        ( TInt aReason, MVPbkStoreContact* aContact )
+    {
+    delete aContact;
+
+    if ( aReason != KErrCancel )
+        {
+        iObserver.PhaseError( *this, aReason );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::ContactsRelocationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::ContactsRelocationFailed
+        ( TInt /*aReason*/, CVPbkContactLinkArray* /*aContacts*/ )
+    {
+    // The code should never enter here
+    __ASSERT_DEBUG( EFalse, Panic( ELogicRelocation ) );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::RelocationProcessComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::RelocationProcessComplete()
+    {
+    // Next phase is select single property
+    iObserver.PreviousPhase( *this );
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::Pbk2ProcessKeyEventL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2PrepareSingleAssignPhase::Pbk2ProcessKeyEventL
+        ( const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    TBool ret = EFalse;
+
+    if ( aType == EEventKey && aKeyEvent.iCode == EKeyEscape )
+        {
+        iObserver.PhaseOkToExit( *this, EEikBidCancel );
+        ret = ETrue;
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::RelocateContactL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2PrepareSingleAssignPhase::RelocateContactL
+        ( Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aPolicy,
+          TBool& aThisDestroyed )
+    {
+    delete iContactRelocator;
+    iContactRelocator = NULL;
+    iContactRelocator = CPbk2ContactRelocator::NewL();
+
+    MVPbkStoreContact* contact = iStoreContact;
+    iStoreContact = NULL;
+
+    // Asynchronously relocate the contact
+    TBool relocate = iContactRelocator->RelocateContactL
+        ( contact, *this, aPolicy, iRelocationFlags );
+
+    if ( !aThisDestroyed )
+        {
+        if ( !relocate )
+            {
+            // Cancel
+            TPbk2AssignNoteService noteService;
+            noteService.ShowInformationNoteL
+                ( R_QTN_PHOB_NOTE_DETAIL_NOT_ADDED );
+            }
+        else
+            {
+            // User accepted relocation
+            if ( !iContactRelocator->IsPhoneMemoryInConfigurationL() )
+                {
+                // Note is shown only if phone memory is not in configuration
+                iNoteFlags = KPbk2NoteFlagOneContactRelocated;
+                }
+            }
+        }
+
+    return relocate;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::QueryForDataReplaceL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2PrepareSingleAssignPhase::QueryForDataReplaceL()
+    {
+    TInt ret = KErrNone;
+
+    TBool thisDestroyed = EFalse;
+    iDestroyedPtr = &thisDestroyed;
+    TPbk2DestructionIndicator indicator
+        ( &thisDestroyed, iDestroyedPtr );
+
+    CPbk2ServerAppAppUi& appUi = static_cast<CPbk2ServerAppAppUi&>
+        ( *iEikEnv->EikAppUi() );
+
+    // Query for data replace
+    TPbk2AssignNoteService noteService;
+    TInt queryResult = noteService.ShowReplaceDetailQueryL
+        ( appUi.ApplicationServices().NameFormatter(), *iStoreContact );
+
+
+    if ( !thisDestroyed && !queryResult )
+        {
+        // User didn't agree to replace data
+        if ( IsContactFromPhoneMemoryL( *iStoreContact ) )
+            {
+            TPbk2AssignNoteService noteService;
+            noteService.ShowInformationNoteL
+                ( R_QTN_PHOB_NOTE_DETAIL_NOT_ADDED );
+
+            ret = KErrCancel;
+            }
+        else
+            {
+            TPbk2ContactRelocationQueryPolicy relocationPolicy =
+                EPbk2DisplayBasicQuery;
+
+            if ( RelocateContactL( relocationPolicy, thisDestroyed ) )
+                {
+                ret = KErrNotReady;
+                }
+            else
+                {
+                ret = KErrCancel;
+                }
+            }
+        }
+
+
+    if ( thisDestroyed )
+        {
+        ret = KErrDied;
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::QueryForRelocationL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2PrepareSingleAssignPhase::QueryForRelocationL()
+    {
+    TInt ret = KErrCancel;
+
+    TBool thisDestroyed = EFalse;
+    iDestroyedPtr = &thisDestroyed;
+    TPbk2DestructionIndicator indicator
+        ( &thisDestroyed, iDestroyedPtr );
+
+    if ( iSelectFieldProperty->SelectedFieldType() )
+        {
+        CPbk2ServerAppAppUi& appUi = static_cast<CPbk2ServerAppAppUi&>
+            ( *iEikEnv->EikAppUi() );
+
+        TPbk2AssignNoteService noteService;
+        noteService.ShowCanNotAddDetailNoteL
+            ( appUi.ApplicationServices().NameFormatter(), *iStoreContact );
+        }
+
+    if ( IsContactFromPhoneMemoryL( *iStoreContact ) )
+        {
+        TPbk2AssignNoteService noteService;
+        noteService.ShowInformationNoteL
+            ( R_QTN_PHOB_NOTE_DETAIL_NOT_ADDED );
+        }
+    else
+        {
+        TPbk2ContactRelocationQueryPolicy relocationPolicy =
+            EPbk2DisplayStoreDoesNotSupportQuery;
+
+        if ( RelocateContactL( relocationPolicy, thisDestroyed ) )
+            {
+            ret = KErrNotReady;
+            }
+        }
+
+    if ( thisDestroyed )
+        {
+        ret = KErrDied;
+        }
+
+    return ret;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::PrepareForAssignL
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::PrepareForAssignL()
+    {
+    CPbk2ServerAppAppUi& appUi = static_cast<CPbk2ServerAppAppUi&>
+        ( *iEikEnv->EikAppUi() );
+
+    switch( iSelectFieldResult )
+        {
+        case KErrNone:
+            // leave iFieldIndex intact.
+            {
+            iObserver.NextPhase( *this );
+            break;
+            }
+        case KErrNotFound:
+            {
+            iFieldIndex = KErrNotFound;
+            iObserver.NextPhase( *this );
+            break;
+            }
+        case KErrPathNotFound:
+            {
+            TInt fieldIndex = iSelectFieldProperty->SelectedFieldIndex();
+            if ( fieldIndex > KErrNotFound )
+                {
+                iFieldIndex = fieldIndex;
+                }
+            iObserver.NextPhase( *this );
+            break;
+            }
+        case KErrAlreadyExists:
+            {
+            TInt result = QueryForDataReplaceL();
+            if ( result == KErrNone )
+                {
+                iFieldIndex = iSelectFieldProperty->SelectedFieldIndex();
+                iObserver.NextPhase( *this );
+                }
+            else if ( result == KErrCancel )
+                {
+                iObserver.PhaseCanceled( *this );
+                }
+            else if ( result == KErrNotReady )
+                {
+                // Contact relocation took place, do not inform observer yet
+                }
+            else if ( result == KErrDied )
+                {
+                // This has been destroyed, do nothing
+                }
+            else
+                {
+                iObserver.PhaseError( *this, result );
+                }
+            break;
+            }
+        case KErrNotSupported:
+            {
+            TInt result = QueryForRelocationL();
+            if ( result == KErrCancel )
+                {
+                iObserver.PhaseCanceled( *this );
+                }
+            else if ( result == KErrNotReady )
+                {
+                // Contact relocation took place, do not inform observer yet
+                }
+            else if ( result == KErrDied )
+                {
+                // This has been destroyed, do nothing
+                }
+            else
+                {
+                iObserver.PhaseError( *this, result );
+                }
+            break;
+            }
+        case KErrAbort:
+            {
+            iObserver.PhaseAborted( *this );
+            break;
+            }
+        case KErrCancel: // FALLTHROUGH
+        default:
+            {
+            iObserver.PhaseCanceled( *this );
+            }
+        };
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::IsContactFromPhoneMemoryL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2PrepareSingleAssignPhase::IsContactFromPhoneMemoryL
+        ( const MVPbkStoreContact& aStoreContact )
+    {
+    TBool result = EFalse;
+
+    TVPbkContactStoreUriPtr phoneMemoryUri
+        ( VPbkContactStoreUris::DefaultCntDbUri() );
+
+    TVPbkContactStoreUriPtr contactUri =
+        aStoreContact.ParentStore().StoreProperties().Uri();
+
+    if ( contactUri.Compare(
+            phoneMemoryUri,
+            TVPbkContactStoreUriPtr::EContactStoreUriAllComponents ) == 0 )
+        {
+        result = ETrue;
+        }
+
+    return result;
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::AppendResultL
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::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 );
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CPbk2PrepareSingleAssignPhase::IssueRequest
+// --------------------------------------------------------------------------
+//
+void CPbk2PrepareSingleAssignPhase::IssueRequest()
+    {
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrNone );
+    SetActive();
+    }
+
+// End of File