--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/MMCExtension/src/CPmuCopyToDriveCmd.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,656 @@
+/*
+* 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 MMC UI extension copy to MMC command.
+*
+*/
+
+
+#include "CPmuCopyToMmcCmd.h"
+
+// Phonebook 2
+#include <MPbk2ContactUiControl.h>
+#include <MPbk2ApplicationServices.h>
+#include <MPbk2AppUi.h>
+#include <MPbk2ContactNameFormatter.h>
+#include <MPbk2CommandObserver.h>
+#include <Pbk2ProcessDecoratorFactory.h>
+#include <MPbk2ProcessDecorator.h>
+#include <TPbk2CopyContactsResults.h>
+#include <Pbk2MmcUIRes.rsg>
+#include <CPbk2DriveSpaceCheck.h>
+
+// Virtual Phonebook
+#include <MVPbkContactOperationBase.h>
+#include <MVPbkStoreContact.h>
+#include <CVPbkVCardEng.h>
+#include <CVPbkContactManager.h>
+#include <CVPbkContactLinkArray.h>
+
+// System includes
+#include <pathinfo.h>
+#include <StringLoader.h>
+#include <aknnotewrappers.h>
+
+#include <AknCommonDialogsDynMem.h>
+#include <CAknMemorySelectionDialogMultiDrive.h>
+#include <driveinfo.h>
+
+// Debug Header
+#include <Pbk2Debug.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+_LIT( KPbk2VCardFileExtension, ".vcf" );
+_LIT( KInvalidFileNameChars, "?*<>/\"|\\:" );
+_LIT( KNumberFormat, "%d" );
+_LIT( KOpeningParenthesis, "(" );
+_LIT( KClosingParenthesis, ")" );
+_LIT( KZero, "0" );
+const TInt KOneContact = 1;
+
+/**
+ * Removes invalid characters from given descriptor.
+ *
+ * @param aPtr The descriptor to inspect.
+ */
+void RemoveInvalidCharacters( TPtr& aPtr )
+ {
+ for ( TInt i = aPtr.Length() - 1; i >= 0; --i )
+ {
+ TChar ch = aPtr[i];
+ if ( KInvalidFileNameChars().Locate( ch ) != KErrNotFound )
+ {
+ aPtr.Delete( i, 1 ); // ch is not a valid character
+ }
+ }
+ }
+
+enum TPmuCopyToMmcCmdState
+ {
+ EPmuCopyToMmcCmdStartProcess,
+ EPmuCopyToMmcCmdDeleteOldEntries,
+ EPmuCopyToMmcCmdRun,
+ EPmuCopyToMmcCmdComplete,
+ EPmuCopyToMmcCmdCancel
+ };
+
+#ifdef _DEBUG
+
+enum TPanicCode
+ {
+ EPanic_CopyNextL_OOB = 1,
+ EPanic_OperationComplete_PreCond,
+ EPanic_ShowResultsL_PreCond
+ };
+
+void Panic( TPanicCode aPanic )
+ {
+ _LIT( KPanicCat, "CPmuCopyToMmcCmd" );
+ User::Panic( KPanicCat(), aPanic );
+ }
+
+#endif // _DEBUG
+
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::CPmuCopyToMmcCmd
+// --------------------------------------------------------------------------
+//
+CPmuCopyToMmcCmd::CPmuCopyToMmcCmd( MPbk2ContactUiControl& aUiControl ) :
+ CActive( EPriorityStandard ),
+ iUiControl( &aUiControl )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::~CPmuCopyToMmcCmd
+// --------------------------------------------------------------------------
+//
+CPmuCopyToMmcCmd::~CPmuCopyToMmcCmd()
+ {
+ Cancel();
+
+ if ( iUiControl )
+ {
+ iUiControl->RegisterCommand( NULL );
+ }
+
+ iWriteStream.Close();
+ delete iFileMan;
+ delete iDecorator;
+ delete iStoreContact;
+ delete iPreviousContact;
+ delete iContactLinks;
+ delete iVCardEngine;
+ delete iDriveSpaceCheck;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::NewL
+// --------------------------------------------------------------------------
+//
+CPmuCopyToMmcCmd* CPmuCopyToMmcCmd::NewL( MPbk2ContactUiControl& aUiControl )
+ {
+ CPmuCopyToMmcCmd* self = new ( ELeave ) CPmuCopyToMmcCmd( aUiControl );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPmuCopyToMmcCmd::ConstructL()
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING("CPmuCopyToDriveCmd::ConstructL"));
+
+ iVCardEngine = CVPbkVCardEng::NewL
+ ( Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager() );
+
+ iContactLinks = iUiControl->SelectedContactsOrFocusedContactL();
+
+ iDecorator = Pbk2ProcessDecoratorFactory::CreateProgressDialogDecoratorL
+ ( R_PMU_COPY_PROGRESS_NOTE, ETrue );
+ iDecorator->SetObserver( *this );
+
+ iUiControl->RegisterCommand( this );
+
+ // set the default contacts path
+ iContactsPath = PathInfo::MemoryCardContactsPath();
+
+ iDriveSpaceCheck = CPbk2DriveSpaceCheck::NewL
+ ( CCoeEnv::Static()->FsSession() );
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::RunL
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::RunL()
+ {
+ switch( iState )
+ {
+ case EPmuCopyToMmcCmdStartProcess:
+ {
+ iDecorator->ProcessStartedL(iContactLinks->Count());
+
+ if ( iDeleteOldEntries )
+ {
+ iState = EPmuCopyToMmcCmdDeleteOldEntries;
+ IssueRequest();
+ }
+ else
+ {
+ Phonebook2::Pbk2AppUi()->ApplicationServices().
+ ContactManager().FsSession().MkDirAll
+ ( iContactsPath );
+
+ iState = EPmuCopyToMmcCmdRun;
+ IssueRequest();
+ }
+ break;
+ }
+ case EPmuCopyToMmcCmdDeleteOldEntries:
+ {
+ DeleteOldEntriesL();
+ Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager().
+ FsSession().MkDirAll( iContactsPath );
+ break;
+ }
+ case EPmuCopyToMmcCmdRun:
+ {
+ if (iFileMan)
+ {
+ delete iFileMan;
+ iFileMan = NULL;
+ }
+
+ if (iStoreContact)
+ {
+ HBufC* fileName = CreateFileNameLC(*iStoreContact);
+ iWriteStream.Create( Phonebook2::Pbk2AppUi()->
+ ApplicationServices().ContactManager().FsSession(),
+ *fileName, EFileWrite );
+ iExportOperation = iVCardEngine->ExportVCardForSyncL(
+ iWriteStream, *iStoreContact, *this );
+ CleanupStack::PopAndDestroy(fileName);
+ }
+ else if (iCurrentIndex < iContactLinks->Count())
+ {
+ TRAPD( err, CopyNextL() );
+ if( err != KErrNone )
+ User::LeaveIfError( HandleError( err ) );
+ }
+ else
+ {
+ iState = EPmuCopyToMmcCmdComplete;
+ IssueRequest();
+ }
+ break;
+ }
+ case EPmuCopyToMmcCmdComplete:
+ {
+ // Copy complete, decorator calls processdismissed
+ iDecorator->ProcessStopped();
+ break;
+ }
+ default:
+ {
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::DoCancel
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::DoCancel()
+ {
+ iState = EPmuCopyToMmcCmdCancel;
+
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+ delete iExportOperation;
+ iExportOperation = NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::RunError
+// --------------------------------------------------------------------------
+//
+TInt CPmuCopyToMmcCmd::RunError( TInt aError )
+ {
+ return HandleError( aError );
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ExecuteLD
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::ExecuteLD()
+ {
+ CleanupStack::PushL( this );
+
+ // Show memory selection dialog if multiple drives available.
+ if ( ShowMemorySelectionDialogL() )
+ {
+ // User selected a drive
+ ShowConfirmationQueryL();
+ }
+ else // If user cancelled the selection
+ {
+ iCommandObserver->CommandFinished( *this );
+ }
+ CleanupStack::Pop( this );
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::AddObserver
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::AddObserver( MPbk2CommandObserver& aObserver )
+ {
+ iCommandObserver = &aObserver;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ResetUiControl
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::ResetUiControl( MPbk2ContactUiControl& aUiControl )
+ {
+ if ( iUiControl == &aUiControl )
+ {
+ iUiControl = NULL;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ProcessDismissed
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::ProcessDismissed( TInt /*aCancelCode*/ )
+ {
+ Cancel();
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+ delete iExportOperation;
+ iExportOperation = NULL;
+
+ // It is a not big deal if result note is not shown to user
+ TRAP_IGNORE( ShowResultsL() );
+ if ( iUiControl )
+ {
+ iUiControl->UpdateAfterCommandExecution();
+ }
+ iCommandObserver->CommandFinished( *this );
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::VPbkSingleContactOperationComplete
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::VPbkSingleContactOperationComplete
+ ( MVPbkContactOperationBase& aOperation,
+ MVPbkStoreContact* aContact )
+ {
+ __ASSERT_DEBUG( iDecorator, Panic( EPanic_OperationComplete_PreCond ));
+
+ if ( &aOperation == iRetrieveOperation )
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+
+ iStoreContact = aContact;
+ }
+ else if ( &aOperation == iExportOperation )
+ {
+ delete iExportOperation;
+ iExportOperation = NULL;
+
+ // After the copying take the contact pointer,
+ // because if this was last contact we need it in result note
+ delete iPreviousContact;
+ iPreviousContact = iStoreContact; // iPreviousContact takes ownership
+ iStoreContact = NULL;
+
+ iWriteStream.Close();
+
+ // Copy next and update progressbar
+ ++iCurrentIndex;
+ ++iCountOfContacts;
+ iDecorator->ProcessAdvance( 1 );
+ }
+ IssueRequest();
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::VPbkSingleContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::VPbkSingleContactOperationFailed
+ ( MVPbkContactOperationBase& aOperation, TInt /*aError*/ )
+ {
+ if (&aOperation == iRetrieveOperation)
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+ }
+ else if (&aOperation == iExportOperation)
+ {
+ delete iExportOperation;
+ iExportOperation = NULL;
+ delete iStoreContact;
+ iStoreContact = NULL;
+ }
+
+ // Copy next
+ ++iCurrentIndex;
+ IssueRequest();
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::NotifyFileManStarted
+// --------------------------------------------------------------------------
+//
+MFileManObserver::TControl CPmuCopyToMmcCmd::NotifyFileManStarted()
+ {
+ if ( iState == EPmuCopyToMmcCmdCancel )
+ {
+ return MFileManObserver::EAbort;
+ }
+ return MFileManObserver::EContinue;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::NotifyFileManOperation
+// --------------------------------------------------------------------------
+//
+MFileManObserver::TControl CPmuCopyToMmcCmd::NotifyFileManOperation()
+ {
+ if ( iState == EPmuCopyToMmcCmdCancel )
+ {
+ return MFileManObserver::EAbort;
+ }
+ return MFileManObserver::EContinue;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::CopyNextL
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::CopyNextL()
+ {
+ __ASSERT_DEBUG( iContactLinks->Count() > iCurrentIndex,
+ Panic( EPanic_CopyNextL_OOB ) );
+
+ //Check free storage space
+ iDriveSpaceCheck->SetStore( iContactsPath );
+ iDriveSpaceCheck->DriveSpaceCheckL();
+
+ iRetrieveOperation = Phonebook2::Pbk2AppUi()->ApplicationServices().
+ ContactManager().RetrieveContactL
+ ( iContactLinks->At( iCurrentIndex ), *this );
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::IssueRequest
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::IssueRequest()
+ {
+ if ( !IsActive() )
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ SetActive();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::CreateFileNameLC
+// --------------------------------------------------------------------------
+//
+HBufC* CPmuCopyToMmcCmd::CreateFileNameLC
+ ( const MVPbkStoreContact& aContact ) const
+ {
+ HBufC* title = Phonebook2::Pbk2AppUi()->ApplicationServices().
+ NameFormatter().GetContactTitleL( aContact.Fields(), 0 );
+
+ CleanupStack::PushL(title);
+ TPtr titlePtr = title->Des();
+
+ RemoveInvalidCharacters(titlePtr);
+
+ TBool fileNameFound = EFalse;
+ TInt number = 0;
+ TFileName fileName;
+ while (!fileNameFound)
+ {
+ fileName.Zero();
+ fileName.Append( iContactsPath );
+ fileName.Append(titlePtr);
+
+ if (number > 0)
+ {
+ fileName.Append(KOpeningParenthesis);
+ if (number < 10)
+ {
+ fileName.Append(KZero);
+ }
+ fileName.AppendFormat(KNumberFormat, number);
+ fileName.Append(KClosingParenthesis);
+ }
+
+ fileName.Append(KPbk2VCardFileExtension);
+
+ TEntry entry;
+ TInt err = Phonebook2::Pbk2AppUi()->ApplicationServices().
+ ContactManager().FsSession().Entry(fileName, entry);
+ if (err == KErrNotFound)
+ {
+ fileNameFound = ETrue;
+ }
+ else
+ {
+ User::LeaveIfError( err );
+ ++number;
+ }
+ }
+ CleanupStack::PopAndDestroy(title);
+
+ return fileName.AllocLC();
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::DeleteOldEntriesL
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::DeleteOldEntriesL()
+ {
+ iFileMan = CFileMan::NewL( Phonebook2::Pbk2AppUi()->
+ ApplicationServices().ContactManager().FsSession(), this );
+ User::LeaveIfError( iFileMan->Delete(
+ iContactsPath,
+ CFileMan::ERecurse, iStatus ) );
+ iState = EPmuCopyToMmcCmdRun;
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ShowConfirmationQueryL
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::ShowConfirmationQueryL()
+ {
+ HBufC* prompt = StringLoader::LoadLC(R_QTN_PHOB_QUERY_REMOVE_ALL_CONTACTS);
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+
+ TInt result = dlg->ExecuteLD
+ (R_PHONEBOOK2_CONFIRM_DELETE_EXISTING_CONTACTS, *prompt);
+ CleanupStack::PopAndDestroy(prompt);
+ iDeleteOldEntries = (result != 0);
+
+ iState = EPmuCopyToMmcCmdStartProcess;
+ IssueRequest();
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ShowMemorySelectionDialogL
+// --------------------------------------------------------------------------
+//
+TBool CPmuCopyToMmcCmd::ShowMemorySelectionDialogL()
+ {
+ TBool driveSelected( EFalse );
+
+ TDriveNumber selectedMem;
+ CAknMemorySelectionDialogMultiDrive* dlg =
+ CAknMemorySelectionDialogMultiDrive::NewL(
+ ECFDDialogTypeSelect,
+ R_PHONEBOOK2_MEMORY_SELECTION_DIALOG,
+ EFalse,
+ AknCommonDialogsDynMem::EMemoryTypeMMCExternal |
+ AknCommonDialogsDynMem::EMemoryTypeInternalMassStorage );
+ CleanupStack::PushL( dlg );
+ driveSelected = dlg->ExecuteL( selectedMem );
+ CleanupStack::PopAndDestroy(); // dlg
+
+ // If user selected a drive
+ if ( driveSelected )
+ {
+ TInt err = PathInfo::GetFullPath( iContactsPath,
+ selectedMem,
+ PathInfo::EMemoryCardContactsPath );
+ User::LeaveIfError( err );
+ }
+
+ return driveSelected;
+ }
+
+// --------------------------------------------------------------------------
+// CPmuCopyToMmcCmd::ShowResultsL
+// --------------------------------------------------------------------------
+//
+void CPmuCopyToMmcCmd::ShowResultsL()
+ {
+ const TInt contactCount = iContactLinks->Count();
+ if (contactCount == KOneContact)
+ {
+ HBufC* title = NULL;
+
+ // If we do not have iPreviousContact, then probably coping is failed
+ if ( iPreviousContact )
+ {
+ title = Phonebook2::Pbk2AppUi()->ApplicationServices().
+ NameFormatter().GetContactTitleL( iPreviousContact->Fields(),
+ MPbk2ContactNameFormatter::EPreserveLeadingSpaces);
+ CleanupStack::PushL(title);
+ }
+ else if ( iStoreContact )
+ {
+ // If we still have iStoreContact, then retrieve is atleast
+ // completed and we can show note.
+ title = Phonebook2::Pbk2AppUi()->ApplicationServices().
+ NameFormatter().GetContactTitleL( iStoreContact->Fields(),
+ MPbk2ContactNameFormatter::EPreserveLeadingSpaces );
+ CleanupStack::PushL(title);
+ }
+
+ if ( title )
+ {
+ TPbk2CopyContactsResults results( iCountOfContacts, *title );
+ results.SetOneContactCopiedTextRes
+ ( R_QTN_PBCOP_NOTE_CONTACT_COPIED_PB2 );
+ results.SetOneContactNotCopiedTextRes
+ ( R_QTN_PBCOP_NOTE_ENTRY_NOT_COPIED );
+ results.ShowNoteL();
+
+ CleanupStack::PopAndDestroy( title );
+ }
+ }
+ else
+ {
+ TPbk2CopyContactsResults results(
+ iCountOfContacts, iContactLinks->Count());
+ results.ShowNoteL();
+ }
+ }
+
+TInt CPmuCopyToMmcCmd::HandleError( TInt aError )
+ {
+ TInt err = aError;
+
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+ delete iExportOperation;
+ iExportOperation = NULL;
+
+ // if there are already copied contacts, dont show error
+ if( iCountOfContacts )
+ err = KErrNone;
+
+ if ( iDecorator )
+ {
+ iDecorator->ProcessStopped();
+ }
+
+ return err;
+ }
+
+// End of File