diff -r a3a1ae9acec6 -r da5135c61bad meetingrequest/mrgui/mrfieldbuildercommon/src/cmrattachmentui.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mrgui/mrfieldbuildercommon/src/cmrattachmentui.cpp Wed Mar 31 21:08:33 2010 +0300 @@ -0,0 +1,634 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + + // TODO: Launch attachment view + // read attachments from calentry and populate the listbox + } + +// --------------------------------------------------------------------------- +// 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 ) + { + // TODO: Add suitable note to cesmrglobalnote.cpp + 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 +