meetingrequest/mrgui/mrfieldbuildercommon/src/cmrattachmentui.cpp
branchRCL_3
changeset 25 3533d4323edc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrgui/mrfieldbuildercommon/src/cmrattachmentui.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,631 @@
+/*
+* Copyright (c) 2009 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: Attachment fetch utility class for event viewers and editors
+*
+*/
+
+#include "cmrattachmentui.h"
+#include "cmrattachmentprogressinfo.h"
+#include "mesmrcalentry.h"
+#include "cmrfilemanager.h"
+#include "cmrgrid.h"
+#include "cesmrglobalnote.h"
+#include "esmrhelper.h"
+
+#include <MGFetch.h>
+#include <aknlistquerydialog.h>
+#include <sysutil.h>
+#include <calattachment.h>
+#include <NpdApi.h>
+#include <AknCommonDialogsDynMem.h>
+#include <apparc.h>
+#include <esmrgui.rsg>
+#include <apgcli.h>
+#include <apmrec.h>
+#include <CommonContentPolicy.h>
+#include <ct/rcpointerarray.h>
+#include <aknnotewrappers.h>
+#include <StringLoader.h>
+
+#include "emailtrace.h"
+
+namespace // codescanner::namespace
+	{
+	_LIT8( KUnknownDatatype, "unknown");
+	
+	const TInt KTempTextFileNameLength( 20 );
+	_LIT( KTextFilenameExtension, ".txt" );
+	
+    /**
+     * Check if the character is illegal for the filename
+     */
+	TBool IsIllegalChar(const TUint aChar)
+	    {
+	    return (
+	        aChar == '*'  ||
+	        aChar == '\\' ||
+	        aChar == '<'  ||
+	        aChar == '>'  ||
+	        aChar == ':'  ||
+	        aChar == '.'  ||
+	        aChar == '"'  ||
+	        aChar == '/'  ||
+	        aChar == '|'  ||
+	        aChar == '?'  ||
+	        aChar == CEditableText::EParagraphDelimiter  ||
+	        aChar == CEditableText::ELineBreak  ||
+	        aChar <  ' ' );
+	    }
+
+	/**
+	 * Get the file name by making use of the content
+	 */
+	void GetFileNameFromBuffer( TFileName& aFileName,
+	            const TDesC& aBuffer, TInt aMaxLength, const TDesC* aExt /*= NULL*/ )
+	    {
+	    if(aExt!=NULL)
+	        {
+	        aMaxLength -= aExt->Length();
+	        }
+
+	    TInt len = aBuffer.Length();
+	    TInt max = Min( len, aMaxLength );
+	    aFileName.Zero();
+
+	    TInt cc = 0;
+	    TUint ch;
+	    TUint ch1 = 0;
+	    TBool spaces = EFalse;
+	    for( TInt i = 0; i < len && cc < max; i++ )
+	        {
+	        ch = aBuffer[i];
+
+	        // ignore spaces from beginning of the buffer until first
+	        // non-space is encountered.
+	        if( !spaces && ch != ' ' )
+	            {
+	            spaces = ETrue;
+	            }
+
+	        if(i>0)
+	            {
+	            ch1 = aBuffer[i-1];
+	            }
+
+	        // strip illegal chars away.
+	        // checks also if previous and current chars are '.'
+	        if( spaces && !IsIllegalChar(ch) )
+	            {
+	            if( !( i > 0 && ch == '.' && ch1 == '.' ) )
+	                {
+	                aFileName.Append( ch );
+	                cc++;
+	                }
+	            }
+	        }
+
+	    aFileName.Trim();
+
+	    // If filename is empty at this point, do not append extension either.
+	    // Instead, empty filename is returned so that caller can use whatever
+	    // default name
+	    if( aFileName.Length() > 0 && aExt != NULL )
+	        {
+	        aFileName.Append(*aExt);
+	        }
+	    }
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CMRAttachmentUi* CMRAttachmentUi::NewL()
+	{
+    FUNC_LOG;
+    
+	CMRAttachmentUi* self = new ( ELeave ) CMRAttachmentUi();
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CMRAttachmentUi::LaunchFetchUi( MESMRCalEntry& aEntry )
+	{
+    FUNC_LOG;
+    
+	iEntry = &aEntry;
+
+	TInt error( KErrNone );
+	TRAP( error, DoLaunchFetchUiL() );
+	return error;
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CMRAttachmentUi::LaunchViewerUi( MESMRCalEntry& aEntry )
+	{
+    FUNC_LOG;
+    
+	iEntry = &aEntry;
+	TInt error( KErrNone );
+	TRAP( error, DoLaunchViewerUiL() );
+	return error;
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CMRAttachmentUi::~CMRAttachmentUi()
+	{
+    FUNC_LOG;
+    
+	delete iFilesToCopy;
+	delete iFilesToAdd;
+	delete iManager;
+	delete iProgress;
+	iFsSession.Close();
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CMRAttachmentUi::SetObserver( MMRAttachmentUiObserver& aObserver )
+	{
+    FUNC_LOG;
+    
+	iObserver = &aObserver;
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TAttachmentOpResult CMRAttachmentUi::LatestOperationResult()
+	{
+    FUNC_LOG;
+    
+	TAttachmentOpResult result;
+	result.iFiles = &(iManager->CopiedFiles());
+	return result;
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+CMRAttachmentUi::CMRAttachmentUi()
+	{
+    FUNC_LOG;
+    
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CMRAttachmentUi::ConstructL()
+	{
+    FUNC_LOG;
+    
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CMRAttachmentUi::DoLaunchFetchUiL()
+	{
+    FUNC_LOG;
+    
+	TMediaFileType type = ResolveAttachmentTypeL();
+	
+	if ( ENoMediaFile != type )
+	    {
+        // Create array of descriptors for the selected files
+        iFilesToCopy = new ( ELeave ) CDesCArrayFlat( 5 );
+        iFilesToAdd = new ( ELeave ) CDesCArrayFlat( 1 );
+        TBool retval( EFalse );
+        HBufC* buf = NULL;
+        // Connect session
+        User::LeaveIfError( iFsSession.Connect() );
+        User::LeaveIfError( iFsSession.ShareProtected() );
+    
+        if( type == EPresentationsFile )
+            {
+            buf = CNotepadApi::FetchMemoL();
+            if( buf )
+                {
+                CleanupStack::PushL(buf);
+    
+                TFileName filename;
+                TInt max = KTempTextFileNameLength;
+    
+                // first try to create filename from memo text.
+                GetFileNameFromBuffer( filename, *buf, max, &KTextFilenameExtension );
+    
+                TFileName tempPath;
+                User::LeaveIfError( ESMRHelper::CreateAndAppendPrivateDirToFileName( tempPath ) );
+                tempPath.Append( filename );
+    
+                // check the file name for validity and possible name duplicates.
+                TInt err = CApaApplication::GenerateFileName( iFsSession, tempPath );
+    
+                if( err == KErrNone )
+                    {
+                    // write buffer to text file
+                    CPlainText* text = CPlainText::NewL();
+                    CleanupStack::PushL( text );
+                    text->InsertL( 0, *buf );
+                    text->ExportAsTextL( tempPath, CPlainText::EOrganiseByParagraph, 0 );
+                    CleanupStack::PopAndDestroy( text );
+                    iFilesToAdd->AppendL( tempPath );
+                    }
+    
+                CleanupStack::PopAndDestroy( buf );
+                }
+            }
+        else if( type == EAnyMediaFile )
+            {
+            TInt supportedTypes = AknCommonDialogsDynMem::EMemoryTypePhone |
+                                  AknCommonDialogsDynMem::EMemoryTypeInternalMassStorage |
+                                  AknCommonDialogsDynMem::EMemoryTypeMMCExternal;
+    
+            TFileName filename;
+            retval = AknCommonDialogsDynMem::RunSelectDlgLD( supportedTypes,
+                                                       filename,
+                                                       R_MR_ATTACHMENT_MEMORY_SELECTION_DIALOG,
+                                                       /*aFilter*/NULL,
+                                                       /*aVerifier*/this );
+            if( retval )
+                {
+                iFilesToCopy->AppendL( filename );
+                }
+            }
+        else
+            {
+            // Open the dialog. 
+             retval = MGFetch::RunL(
+                *iFilesToCopy, // When dialog is closed, fileArray contains selected files
+                type, // Displays only media files of type aMediaType
+                ETrue,		// single or multiple file selection
+                this		// Pointer to class implementing MMGFetchVerifier;
+                        // when user has selected file(s),
+                        // MMGFetchVerifier::VerifySelectionL is called.
+                );
+            }
+    
+        TInt index(0);
+        while ( index < iFilesToCopy->MdcaCount() )
+            {
+            TPtrC filename( iFilesToCopy->MdcaPoint(index) );
+            if ( IsDuplicateNameL( filename ) )
+                {
+                iFilesToCopy->Delete( index );
+                
+                //though attachment is aleady attached to this entry, show the info note for this info.
+                CAknInformationNote* note = new ( ELeave ) CAknInformationNote(ETrue);
+                HBufC* cannotAttach = StringLoader::LoadLC( 
+                        R_QTN_MEET_REQ_INFO_ALREADY_ATTACHED );
+                note->ExecuteLD( *cannotAttach );
+                CleanupStack::PopAndDestroy( cannotAttach );                
+                }
+            else 
+                {
+                ++index;
+                }
+            }
+        
+        // Start copy
+        if( iFilesToCopy->MdcaCount() > 0 )
+            {
+            // Count files to be copied
+            iFileCount = iFilesToCopy->Count();
+            if( iFileCount > 0 )
+                {
+                StartCopyOpL();
+                }
+            }
+        // Add directly to CCalAttachment, no copy needed
+        else if( iFilesToAdd->MdcaCount() > 0 )
+            {
+            UpdateEntryL();
+            }
+	    }
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CMRAttachmentUi::StartCopyOpL()
+	{
+    FUNC_LOG;
+    
+	// Fetch the first filename from the array
+	TInt size( 0 );
+	for( TInt i = 0; i < iFileCount; ++i )
+		{
+		const TDesC& originalPath = (*iFilesToCopy)[i];
+		TEntry entry;
+		User::LeaveIfError( iFsSession.Entry( originalPath,entry ) );
+		// Count total size for the progressbar
+		size += entry.iSize;
+		}
+
+	if( !iManager )
+		{
+		iManager = CMRFileManager::NewL(iFsSession);
+		}
+	if( !iProgress )
+		{
+		iProgress = CMRAttachmentProgressInfo::NewL( *iManager, *this );
+		}
+	// Give total size to progress bar
+	// Set progressbar as a observer to copy operation
+	iProgress->StartProgressNoteL( size );
+
+    // Check if there is space available
+    if( !SysUtil::FFSSpaceBelowCriticalLevelL( &iFsSession, size ) )
+    	{
+		iManager->SetObserver( *iProgress );
+		iManager->CopyFilesL( *iFilesToCopy );
+    	}
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CMRAttachmentUi::UpdateEntryL()
+	{
+    FUNC_LOG;
+    
+	MDesC16Array* fileArray = NULL;
+	if( iFilesToAdd->MdcaCount() > 0  )
+		{
+		fileArray = iFilesToAdd;
+		}
+	else
+		{
+		fileArray = &iManager->CopiedFiles();
+		}
+
+	TInt fileCount( fileArray->MdcaCount() );
+
+	for( TInt i = 0; i < fileCount; ++i )
+		{
+		const TDesC& fileName( fileArray->MdcaPoint(i) );
+		// When copy done add attachment File handles to calentry
+		RFile fileHandle;
+		User::LeaveIfError( fileHandle.Open( 
+		        iFsSession, fileName, EFileWrite ) );
+		CleanupClosePushL( fileHandle );
+		// create attachment and add to calendar entry
+		CCalAttachment* attachment = CCalAttachment::NewFileL( fileHandle );
+		
+        RApaLsSession apaSession;
+        TDataRecognitionResult dataType;
+        User::LeaveIfError(apaSession.Connect());
+        apaSession.RecognizeData(fileHandle, dataType);
+        apaSession.Close();
+        
+        TPtrC8 contentType( dataType.iDataType.Des8() );
+        
+        if ( contentType.Length() )
+            {
+            attachment->SetMimeTypeL( contentType );
+            }
+        else
+            {
+            attachment->SetMimeTypeL( KUnknownDatatype );
+            }
+		
+		CleanupStack::PopAndDestroy( &fileHandle );
+		CleanupStack::PushL( attachment );
+		// set attachment properties
+		const TDesC& filenameOriginal = iFilesToCopy->MdcaPoint( i );
+		TFileName label;
+		TParse parser;
+		parser.Set( filenameOriginal , NULL, NULL );
+		label.Append( parser.NameAndExt() );
+		attachment->SetLabelL( label );
+			
+		
+		
+		iEntry->Entry().AddAttachmentL( *attachment ); // calEntry takes ownership
+		CleanupStack::Pop( attachment );
+		}
+
+	if( iObserver )
+		{
+		iObserver->AttachmentOperationCompleted( *iFilesToCopy );
+		}
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CMRAttachmentUi::DoLaunchViewerUiL()
+	{
+    FUNC_LOG;
+    
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+TMediaFileType CMRAttachmentUi::ResolveAttachmentTypeL()
+	{
+    FUNC_LOG;
+    
+	TMediaFileType type = ENoMediaFile;
+	TInt selectedOption( 0 );
+    
+	if ( CMRGrid::ExecuteL( selectedOption ) )
+        {
+        switch( selectedOption )
+            {
+            case 0:
+                type = EImageFile;
+                break;
+            case 1:
+                type = EVideoFile;
+                break;
+            case 2:
+                type = EMusicFile;
+                break;
+            case 3:
+                type = EPresentationsFile;
+                break;
+            case 4:
+                type = EAnyMediaFile;
+                break;
+    
+            default:
+                break;
+            }
+        }
+	
+	return type;
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::AttachmentOperationCompleted
+// ---------------------------------------------------------------------------
+//
+void CMRAttachmentUi::DialogDismissedL( TInt /*aButtonId*/ )
+	{
+    FUNC_LOG;
+    
+	// Called whent the copy process has ended
+	UpdateEntryL();
+	}
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::VerifySelectionL
+// ---------------------------------------------------------------------------
+//
+TBool CMRAttachmentUi::VerifySelectionL( const MDesCArray* aSelectedFiles )
+    {
+    FUNC_LOG;
+    
+    TInt fileCount = aSelectedFiles->MdcaCount();
+    TBool isProtected = EFalse;
+    for( TInt i = 0; i < fileCount; ++i )
+        {
+        const TDesC& originalPath = aSelectedFiles->MdcaPoint( i );
+        RFile selected;
+        User::LeaveIfError( selected.Open( 
+                iFsSession, originalPath, EFileRead ) );
+        CleanupClosePushL( selected );
+        isProtected =  FileDrmProtectedL( selected );
+        CleanupStack::PopAndDestroy();
+        if ( isProtected )
+            {
+            break;
+            }
+        }
+    // Protected file returns verification fail and 
+    // unprotected file returns verification ok
+    return !isProtected;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::OkToExitL
+// ---------------------------------------------------------------------------
+//
+TBool CMRAttachmentUi::OkToExitL( 
+        const TDesC& aDriveAndPath, 
+        const TEntry& aEntry )
+    {
+    FUNC_LOG;
+    
+    TFileName path;
+    path = aDriveAndPath;
+    path.Append( aEntry.iName );
+    
+    RFile selected;
+    User::LeaveIfError( selected.Open( iFsSession, path, EFileRead ) );
+    CleanupClosePushL( selected );
+    TBool isProtected = FileDrmProtectedL( selected );
+    CleanupStack::PopAndDestroy();
+
+    // Protected file returns not ok to exit and 
+    // unprotected file returns ok to exit
+    return !isProtected;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::FileDrmProtectedL
+// ---------------------------------------------------------------------------
+//
+TBool CMRAttachmentUi::FileDrmProtectedL( RFile& aFile )
+    {
+    FUNC_LOG;
+    
+    TBool isProtected( EFalse );
+    CCommonContentPolicy* ccp = CCommonContentPolicy::NewLC();      
+    isProtected = ccp->IsClosedFileL( aFile );
+    if ( isProtected )
+            {
+            CESMRGlobalNote::ExecuteL
+                                ( CESMRGlobalNote::EESMRAlarmAlreadyPassed );
+            }
+    CleanupStack::PopAndDestroy( ccp );
+    return isProtected;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRAttachmentUi::IsDuplicateNameL
+// ---------------------------------------------------------------------------
+//
+TBool CMRAttachmentUi::IsDuplicateNameL(
+        const TDesC& aSelectedFile )
+    {               
+    FUNC_LOG;
+    
+    CCalEntry& entry( iEntry->Entry() );
+    
+    TInt attachmentCount = entry.AttachmentCountL();
+    
+    TBool matchNotFound( ETrue );
+    if( attachmentCount )
+        {
+        TParsePtrC fileNameParser(aSelectedFile);
+        TPtrC parsedFileName = fileNameParser.NameAndExt();
+
+        for(TInt index = 0; index < attachmentCount && matchNotFound; ++index)
+            {     
+            CCalAttachment* attachment = entry.AttachmentL(index);
+            matchNotFound = parsedFileName.Compare( attachment->Label() ); 
+            }
+        }
+    
+    return !matchNotFound; 
+    }
+
+// End of file
+