--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIControls/src/Pbk2ImageCommands.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,626 @@
+/*
+* 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 ringing tone commands.
+*
+*/
+
+
+// INCLUDES
+
+// Phonebook 2
+#include <e32base.h>
+#include "Pbk2ImageCommands.h"
+#include "MPbk2ImageFieldObserver.h"
+#include "MPbk2BaseCommand.h"
+
+#include <MVPbkContactFieldTextData.h>
+#include <CPbk2AppUiBase.h>
+#include <MPbk2ApplicationServices.h>
+#include <TPbk2StoreContactAnalyzer.h>
+#include "CPbk2ImageManager.h"
+#include "CPbk2DrmManager.h"
+#include <MPbk2ImageOperationObservers.h> // MPbk2ImageSetObserver
+#include <MMGFetchVerifier.h> // MMGFetchVerifier
+
+#include <RPbk2LocalizedResourceFile.h>
+#include "Pbk2DataCaging.hrh"
+#include "Pbk2PresentationUtils.h"
+#include <Pbk2CommonUi.rsg>
+#include <Pbk2UIControls.rsg>
+#include <Pbk2Commands.rsg>
+
+#include <MPbk2ImageOperationObservers.h> // MPbk2ImageSetObserver
+#include <AknServerApp.h> // MAknServerAppExitObserver
+
+// VPbk includes
+#include <MVPbkStoreContact.h>
+#include <MVPbkStoreContactField.h>
+#include <CVPbkContactManager.h>
+#include <TVPbkFieldTypeMapping.h>
+#include <MVPbkFieldType.h>
+#include <VPbkEng.rsg>
+
+// System includes
+#include <barsread.h>
+#include <coemain.h>
+#include <AknWaitDialog.h>
+#include <aknnotewrappers.h>
+#include <StringLoader.h>
+#include <MGFetch.h>
+#include <DocumentHandler.h> // CDocumentHandler
+#include <apmstd.h> // TDataType
+#include <Pbk2CmdExtRes.rsg>
+#include <sysutil.h>
+#include <CPbk2ApplicationServices.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+ const TInt KSelectedFilesDefaultGranularity = 1;
+
+#ifdef _DEBUG
+
+enum TPanicCode
+ {
+ EPanicPreCond_NULL_Contact = 1
+ };
+
+void Panic( TPanicCode aPanic )
+ {
+ _LIT( KPanicCat, "MPbk2ImageCommands" );
+ User::Panic( KPanicCat, aPanic );
+ }
+
+#endif // _DEBUG
+
+// --------------------------------------------------------------------------
+// ImageFieldTypeL
+// --------------------------------------------------------------------------
+//
+inline const MVPbkFieldType* ImageFieldTypeL(
+ MPbk2ApplicationServices& aApplicationServices )
+ {
+ return aApplicationServices.ContactManager().
+ FieldTypes().Find( R_VPBK_FIELD_TYPE_CALLEROBJIMG );
+ }
+
+// --------------------------------------------------------------------------
+// ThumbnailFieldTypeL
+// --------------------------------------------------------------------------
+//
+inline const MVPbkFieldType* ThumbnailFieldTypeL(
+ MPbk2ApplicationServices& aApplicationServices )
+ {
+ return aApplicationServices.ContactManager().
+ FieldTypes().Find( R_VPBK_FIELD_TYPE_THUMBNAILPIC );
+ }
+
+// --------------------------------------------------------------------------
+// Set image operation.
+// Uses asynchronous operation of CPbk2ImageManager to set image.
+// MMGFetchVerifier implemented to perform DRM check for select image dialog.
+// --------------------------------------------------------------------------
+//
+NONSHARABLE_CLASS( CSetImageCmd ):
+ public CBase,
+ public MPbk2BaseCommand,
+ private MPbk2ImageSetObserver,
+ private MMGFetchVerifier
+ {
+ public:
+ static CSetImageCmd* NewL();
+ ~CSetImageCmd();
+
+ void ExecuteL( MVPbkStoreContact* aContact,MPbk2ImageFieldObserver* aObserver );
+
+ private: // from MPbkImageSetObserver
+ void Pbk2ImageSetComplete(
+ MPbk2ImageOperation& aOperation);
+ void Pbk2ImageSetFailed(
+ MPbk2ImageOperation& aOperation,
+ TInt aError);
+
+ private: // from MMGFetchVerifier
+ TBool VerifySelectionL(
+ const MDesCArray* aSelectedFiles);
+ private:
+ CSetImageCmd();
+ void ConstructL();
+ void Cancel();
+ void DismissWaitNote();
+ void SetImageRefL( MVPbkStoreContact* aContact,
+ const TDesC& aFileName);
+
+ private:
+ /// Own: image set operation
+ MPbk2ImageOperation* iImageOperation;
+ /// Own: wait note dialog
+ CAknWaitDialog* iWaitNote;
+ /// Own: DRM support
+ CPbk2DrmManager* iDrmManager;
+ const MVPbkFieldType* iThumbnailFieldType;
+ /// Own: Image manager
+ CPbk2ImageManager* iImageManager;
+
+ // Own
+ HBufC* iImageFilename;
+
+ // Not own
+ MVPbkStoreContact* iContact;
+ MPbk2ImageFieldObserver* iObserver;
+ // Ref:
+ CPbk2ApplicationServices* iServices;
+ };
+
+CSetImageCmd* CSetImageCmd::NewL()
+ {
+ CSetImageCmd* self = new(ELeave) CSetImageCmd();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CSetImageCmd::~CSetImageCmd()
+ {
+ Cancel();
+ delete iImageFilename;
+ delete iDrmManager;
+ delete iImageManager;
+ Release( iServices );
+ }
+
+void CSetImageCmd::ExecuteL( MVPbkStoreContact* aContact,MPbk2ImageFieldObserver* aObserver )
+ {
+ iObserver=aObserver;
+ CDesCArray* selectedFile = new(ELeave) CDesCArrayFlat(
+ KSelectedFilesDefaultGranularity );
+ CleanupStack::PushL( selectedFile );
+ TBool res( EFalse );
+
+ // run image fetch dialog
+ res = MGFetch::RunL( *selectedFile,
+ EImageFile,
+ EFalse, /* multiselection */
+ this /* provide MMGFetchVerifier interface to check DRM */);
+
+ if ( res && selectedFile->Count() > 0 )
+ {
+ if (iWaitNote==NULL)
+ {
+ iWaitNote =new(ELeave) CAknWaitDialog(reinterpret_cast<CEikDialog**>( &iWaitNote ),ETrue );
+ }
+ // doesn't delete waitNote
+ iWaitNote->ExecuteLD( R_QTN_GEN_NOTE_FETCHING );
+
+ TPtrC fileName = (*selectedFile)[0];
+
+ // delete old filename
+ delete iImageFilename;
+ iImageFilename=NULL;
+ // store these for later use
+ iImageFilename=fileName.AllocL();
+ iContact=aContact;
+
+
+ // write data to thumbnail field
+ iImageOperation =
+ iImageManager->SetImageAsyncL(
+ *aContact, *iThumbnailFieldType, *this, fileName );
+
+ }
+
+ CleanupStack::PopAndDestroy( selectedFile );
+ }
+
+CSetImageCmd::CSetImageCmd()
+ {
+ }
+
+void CSetImageCmd::ConstructL()
+ {
+ /*
+ * In Social phonebook case, the contact editor (that uses this class) is launched outside of pbk2 context.
+ * Then the Pbk2AppUi is not valid.
+ */
+ iServices = CPbk2ApplicationServices::InstanceL();
+ iImageManager = CPbk2ImageManager::NewL( iServices->ContactManager() );
+
+ iThumbnailFieldType = ThumbnailFieldTypeL(*iServices);
+ iDrmManager = CPbk2DrmManager::NewL();
+
+ }
+
+void CSetImageCmd::Cancel()
+ {
+ delete iWaitNote;
+ iWaitNote = NULL;
+ delete iImageOperation;
+ iImageOperation = NULL;
+ if (iObserver)
+ {
+ iObserver->ImageLoadingCancelled();
+ }
+ }
+
+void CSetImageCmd::DismissWaitNote()
+ {
+ // ProcessFinishedL initiate iWaitNote destruction
+ // and iWaitNote is set to NULL during CAknWaitDialog destruction
+ TRAPD( err, iWaitNote->ProcessFinishedL() );
+ if ( err != KErrNone )
+ {
+ delete iWaitNote;
+ iWaitNote = NULL;
+ }
+ }
+
+void CSetImageCmd::Pbk2ImageSetComplete
+ ( MPbk2ImageOperation& /*aOperation*/ )
+ {
+
+ // set the image reference after image has been loaded.
+ SetImageRefL( iContact, iImageFilename->Des() );
+
+ delete iImageOperation;
+ iImageOperation = NULL;
+ DismissWaitNote();
+ if (iObserver)
+ {
+ iObserver->ImageLoadingComplete();
+ }
+
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SetImageCmd::Pbk2ImageSetFailed
+// --------------------------------------------------------------------------
+//
+void CSetImageCmd::Pbk2ImageSetFailed
+ ( MPbk2ImageOperation& /*aOperation*/, TInt aError )
+ {
+ delete iImageOperation;
+ iImageOperation = NULL;
+ DismissWaitNote();
+ if (iObserver)
+ {
+ iObserver->ImageLoadingFailed();
+ }
+
+ if ( aError != KErrNone )
+ {
+ CCoeEnv::Static()->HandleError( aError );
+ }
+ }
+
+void CSetImageCmd::SetImageRefL( MVPbkStoreContact* aContact,
+ const TDesC& aFileName)
+ {
+ CVPbkContactManager& manager = iServices->ContactManager();
+
+ TPbk2StoreContactAnalyzer analyzer(
+ manager,
+ aContact );
+ TInt fieldIndex = analyzer.HasFieldL( R_PHONEBOOK2_IMAGE_SELECTOR );
+
+ MVPbkStoreContactField* field;
+ if ( fieldIndex != KErrNotFound )
+ {
+ // If filename has been set and the contact has the field
+ // field should be updated.
+ field = &aContact->Fields().FieldAt( fieldIndex );
+ MVPbkContactFieldTextData::Cast( field->FieldData() ).
+ SetTextL( aFileName );
+ }
+ else if ( aFileName.Length() > 0 )
+ {
+ const MVPbkFieldType* imageFieldType = ImageFieldTypeL(*iServices);
+
+ // Contact does not have the field, so create new one.
+ field = aContact->CreateFieldLC( *imageFieldType );
+ MVPbkContactFieldTextData::Cast( field->FieldData() ).
+ SetTextL( aFileName );
+ aContact->AddFieldL( field );
+ CleanupStack::Pop(); // field
+ }
+ }
+
+// --------------------------------------------------------------------------
+// DRM check for image fetch dialog
+// --------------------------------------------------------------------------
+//
+TBool CSetImageCmd::VerifySelectionL
+ (const MDesCArray* aSelectedFiles)
+ {
+ TBool result = EFalse;
+ if ( aSelectedFiles && aSelectedFiles->MdcaCount() > 0 )
+ {
+ // DRM for phonebook image fetch
+ TPtrC fileName = aSelectedFiles->MdcaPoint( 0 );
+ TBool isProtected( ETrue );
+ User::LeaveIfError(
+ iDrmManager->IsProtectedFile( fileName, isProtected ) );
+ if ( isProtected )
+ {
+ RPbk2LocalizedResourceFile resFile( *CCoeEnv::Static() );
+ resFile.OpenLC(
+ KPbk2RomFileDrive,
+ KDC_RESOURCE_FILES_DIR,
+ Pbk2PresentationUtils::PresentationResourceFile() );
+ // show user copyright note
+ HBufC* prompt =
+ CCoeEnv::Static()->AllocReadResourceLC( R_PBK2_QTN_DRM_NOT_ALLOWED );
+ CAknInformationNote* dlg = new(ELeave) CAknInformationNote( ETrue );
+ dlg->ExecuteLD( *prompt );
+ CleanupStack::PopAndDestroy( 2 ); // resFile, prompt
+ }
+ else
+ {
+ result = ETrue;
+ }
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// Starts external image viewer via doc.handler and waits for its exit
+// --------------------------------------------------------------------------
+//
+NONSHARABLE_CLASS( CViewImageCmd ):
+ public CBase,
+ public MPbk2BaseCommand,
+ private MAknServerAppExitObserver
+ {
+ public:
+ static CViewImageCmd* NewL();
+ ~CViewImageCmd();
+
+ void ExecuteL( MVPbkStoreContact* aContact );
+
+ private: // from MAknServerAppExitObserver
+ void HandleServerAppExit(
+ TInt aReason );
+ private:
+ CViewImageCmd();
+ void ConstructL();
+ void ShowImageNotOpenedNoteL();
+
+ private:
+ /// Own: Document handler for image opening
+ CDocumentHandler* iDocHandler; /// Own: wait note dialog
+ TFileName iFileName;
+ CPbk2ApplicationServices* iServices;
+ };
+
+CViewImageCmd* CViewImageCmd::NewL()
+ {
+ CViewImageCmd* self = new(ELeave) CViewImageCmd();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CViewImageCmd::CViewImageCmd()
+ {
+ }
+
+void CViewImageCmd::ConstructL()
+ {
+ iDocHandler = CDocumentHandler::NewL();
+ iDocHandler->SetExitObserver( this );
+
+ /*
+ * In Social phonebook case, the contact editor (that uses this class) is launched outside of pbk2 context.
+ * Then the Pbk2AppUi is not valid.
+ */
+ iServices = CPbk2ApplicationServices::InstanceL();
+ }
+
+CViewImageCmd::~CViewImageCmd()
+ {
+ delete iDocHandler;
+ Release( iServices );
+ }
+
+void CViewImageCmd::HandleServerAppExit( TInt aReason )
+ {
+ // make base call first
+ MAknServerAppExitObserver::HandleServerAppExit( aReason );
+ }
+
+void CViewImageCmd::ShowImageNotOpenedNoteL()
+ {
+ HBufC* prompt = StringLoader::LoadLC( R_QTN_ALBUM_ERR_FORMAT_UNKNOWN );
+ CAknInformationNote* dlg = new ( ELeave ) CAknInformationNote( ETrue );
+ dlg->ExecuteLD( *prompt );
+ CleanupStack::PopAndDestroy( prompt );
+ }
+
+void CViewImageCmd::ExecuteL( MVPbkStoreContact* aContact )
+ {
+ CVPbkContactManager& manager = iServices->ContactManager();
+
+ TPbk2StoreContactAnalyzer analyzer(
+ manager,
+ aContact );
+ TInt fieldIndex = analyzer.HasFieldL( R_PHONEBOOK2_IMAGE_SELECTOR );
+
+ if( fieldIndex != KErrNotFound )
+ {
+ // retrieve field pointer and its current text for call
+ MVPbkStoreContactField& field =
+ aContact->Fields().FieldAt( fieldIndex );
+ iFileName.Copy(
+ MVPbkContactFieldTextData::Cast( field.FieldData() ).Text() );
+
+ // empty datatype for automatic recognization
+ TDataType dataType;
+
+ TRAPD( error, iDocHandler->OpenFileEmbeddedL( iFileName, dataType ) );
+
+ // KErrNotReady, when no mmc inserted
+ // KErrNotFound, when image is deleted
+ if ( error == KErrNotFound || error == KErrUnderflow
+ || error == KErrCorrupt
+ || error == KErrNotReady )
+ {
+ // if the image has been deleted from Image Gallery
+ // or it is corrupted, show a note instead of leave
+ ShowImageNotOpenedNoteL();
+ }
+ }
+ }
+} /// namespace
+
+// --------------------------------------------------------------------------
+// MPbk2ImageCommands::SetImageL
+// --------------------------------------------------------------------------
+//
+MPbk2BaseCommand* Pbk2ImageCommands::SetImageL(
+ MVPbkStoreContact* aContact, MPbk2ImageFieldObserver* aObserver )
+ {
+ __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_NULL_Contact ) );
+
+ RFs fs = CCoeEnv::Static()->FsSession();
+ if ( SysUtil::FFSSpaceBelowCriticalLevelL( &fs ) )
+ {
+ User::Leave( KErrDiskFull );
+ }
+
+ CSetImageCmd* cmd = CSetImageCmd::NewL();
+ CleanupStack::PushL( cmd );
+ cmd->ExecuteL( aContact , aObserver);
+ CleanupStack::Pop();
+
+ return cmd;
+ }
+
+// --------------------------------------------------------------------------
+// MPbk2ImageCommands::ViewImageL
+// --------------------------------------------------------------------------
+//
+MPbk2BaseCommand* Pbk2ImageCommands::ViewImageL(
+ MVPbkStoreContact* aContact )
+ {
+ __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_NULL_Contact ) );
+
+ CViewImageCmd* cmd = CViewImageCmd::NewL();
+ CleanupStack::PushL( cmd );
+ cmd->ExecuteL( aContact );
+ CleanupStack::Pop();
+
+ return cmd;
+ }
+
+// --------------------------------------------------------------------------
+// MPbk2ImageCommands::RemoveImageL
+// --------------------------------------------------------------------------
+//
+MPbk2BaseCommand* Pbk2ImageCommands::RemoveImageL(
+ MVPbkStoreContact* aContact )
+ {
+ __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_NULL_Contact ) );
+
+ // If Social phonebook is enabled, the contact editor (that uses this class)
+ // is launched outside of pbk2 context. Then the Pbk2AppUi is not valid.
+ MPbk2ApplicationServices& services = *CPbk2ApplicationServices::InstanceLC();
+
+ CPbk2ImageManager* imageManager = CPbk2ImageManager::NewL(
+ services.ContactManager() );
+ CleanupStack::PushL( imageManager );
+
+ if( CAknQueryDialog::NewL()->ExecuteLD(
+ R_PHONEBOOK2_REMOVE_IMAGE_CONFIRMATION_DIALOG ) )
+ {
+ TPbk2StoreContactAnalyzer analyzer(
+ services.ContactManager(), aContact );
+ TInt imageIndex = analyzer.HasFieldL( R_PHONEBOOK2_IMAGE_SELECTOR );
+
+ if ( imageIndex != KErrNotFound )
+ {
+ //aContact->RemoveField( imageIndex );
+ //Instead of above we don't remove the field, just zero it's data
+ MVPbkContactFieldData& data(aContact->Fields().
+ FieldAt( imageIndex ).FieldData());
+ MVPbkContactFieldTextData::Cast( data ).SetTextL(KNullDesC);
+ }
+
+ const MVPbkFieldType* thumbFieldType = ThumbnailFieldTypeL(services);
+ imageManager->RemoveImage( *aContact, *thumbFieldType );
+ }
+ CleanupStack::PopAndDestroy( imageManager );
+
+ CleanupStack::PopAndDestroy(); // services
+
+ return NULL; // synchronous operation
+ }
+
+// --------------------------------------------------------------------------
+// MPbk2ImageCommands::IsImageFieldL
+// --------------------------------------------------------------------------
+//
+TBool Pbk2ImageCommands::IsImageFieldL(
+ const MVPbkStoreContactField& aField )
+ {
+ /*
+ * In Social phonebook case, the contact editor (that uses this class) is launched outside of pbk2 context.
+ * Then the Pbk2AppUi is not valid.
+ */
+ CPbk2ApplicationServices* services = CPbk2ApplicationServices::InstanceL();
+ TPbk2StoreContactAnalyzer analyzer(
+ services->ContactManager(),
+ NULL );
+ Release( services );
+
+ return analyzer.IsFieldTypeIncludedL(
+ aField, R_PHONEBOOK2_IMAGE_SELECTOR );
+ }
+
+// --------------------------------------------------------------------------
+// MPbk2ImageCommands::IsImageFieldL
+// --------------------------------------------------------------------------
+//
+TBool Pbk2ImageCommands::IsThumbnailFieldL(
+ const MVPbkStoreContactField& aField )
+ {
+ /*
+ * In Social phonebook case, the contact editor (that uses this class) is launched outside of pbk2 context.
+ * Then the Pbk2AppUi is not valid.
+ */
+ CPbk2ApplicationServices* services = CPbk2ApplicationServices::InstanceL();
+ TPbk2StoreContactAnalyzer analyzer(
+ services->ContactManager(),
+ NULL );
+ Release( services );
+
+ return analyzer.IsFieldTypeIncludedL(
+ aField, R_PHONEBOOK2_THUMBNAIL_SELECTOR );
+ }
+
+// --------------------------------------------------------------------------
+// MPbk2ImageCommands::IsImageFieldValidL
+// --------------------------------------------------------------------------
+//
+TBool Pbk2ImageCommands::IsImageFieldValidL(
+ const MVPbkStoreContactField& aField )
+ {
+ const MVPbkContactFieldTextData& textData =
+ MVPbkContactFieldTextData::Cast( aField.FieldData() );
+ TEntry ignore;
+ return CCoeEnv::Static()->FsSession().Entry( textData.Text(), ignore ) == KErrNone;
+ }
+
+// End of File