diff -r 000000000000 -r 72b543305e3a messagingappbase/msgeditor/modelsrc/MsgAttachmentUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingappbase/msgeditor/modelsrc/MsgAttachmentUtils.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,649 @@ +/* +* Copyright (c) 2002 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: MsgAttachmentUtils implementation +* +*/ + + + +// ========== INCLUDE FILES ================================ + +#include +#include + +#include // for CEikonEnv +#include // for CEikProcess +#include +#include // for CApaApplication +#include // for RApaLsSession +#include // for TApaDocCleanupItem +#include // for CPlainText +#include +#include // NearestLanguageFile + +#include // for R_QTN_SIZE_xx +#include // LAF +#include + +#include + +#ifdef RD_MULTIPLE_DRIVE +#include +#endif + +#include // Notepad API +#include // StringLoader + +#include // for MediaGallery + +#include +#include +#include + +#include "MsgEditorCommon.h" // for KMsgEditorTempDir +#include "MsgAttachmentUtils.h" +#include "MsgEditorModelPanic.h" // Panics +#include // resouce identifiers + +// ========== EXTERNAL DATA STRUCTURES ===================== + +// ========== EXTERNAL FUNCTION PROTOTYPES ================= + +// ========== CONSTANTS ==================================== + +const TInt KMsgAttaFileNameLength = 20; +_LIT( KTxtAttaFilenameExtension, ".txt" ); +_LIT( KMsgEditorAppUiResourceFileName, "msgeditorappui.rsc" ); + +_LIT( KMsgEditorTempDir, ":\\system\\temp\\msgeditor_temp\\" ); + +const TInt KLocalKilo = 1024; + +const TUid KUidCamcorder = { 0x101F857A }; +const TUid KUidVoiceRec = { 0x100058CA }; +//const TUid KUidCamera = { 0x1000593F }; + +// ========== MACROS ======================================= + +// ========== LOCAL CONSTANTS AND MACROS =================== + +// ========== MODULE DATA STRUCTURES ======================= + +// ========== LOCAL FUNCTION PROTOTYPES ==================== + +// ========== LOCAL FUNCTIONS ============================== + +// ========== MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchFile +// --------------------------------------------------------- +// +EXPORT_C TBool MsgAttachmentUtils::FetchFileL ( + TMsgAttachmentFetchType aType, + TFileName& aFileName, + TBool aCheckDiskSpace ) + { + return FetchFileL( aType, aFileName, KNullUid, aCheckDiskSpace ); + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchFile +// --------------------------------------------------------- +// +EXPORT_C TBool MsgAttachmentUtils::FetchFileL ( + TMsgAttachmentFetchType aType, + TFileName& aFileName, + const TUid& /*aAppUid*/, + TBool aCheckDiskSpace ) + { + TBool result = EFalse; + CDesCArrayFlat* files = new ( ELeave ) CDesC16ArrayFlat( 1 ); + CleanupStack::PushL( files ); + result = FetchFileL( aType, aFileName, *files, aCheckDiskSpace, EFalse, NULL ); + CleanupStack::PopAndDestroy( ); //files + return result; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchFile +// --------------------------------------------------------- +// +EXPORT_C TBool MsgAttachmentUtils::FetchFileL ( + TMsgAttachmentFetchType aType, + TFileName& aFileName, + CDesCArray& aSelectedFiles, + TBool aCheckDiskSpace, + TBool aMultiSelect, + MMGFetchVerifier* aVerifier ) + { + TBool result = FetchFileL( aType, aSelectedFiles, NULL, aCheckDiskSpace, aMultiSelect, aVerifier ); + if ( aSelectedFiles.MdcaCount() ) + { + aFileName.Zero(); + aFileName = aSelectedFiles.MdcaPoint( 0 ); + } + return result; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchFile +// --------------------------------------------------------- +// +EXPORT_C TBool MsgAttachmentUtils::FetchFileL ( + TMsgAttachmentFetchType aType, + CDesCArray& aSelectedFiles, + CAiwGenericParamList* aParams, + TBool /*aCheckDiskSpace*/, + TBool aMultiSelect, + MMGFetchVerifier* aVerifier ) + { + TBool result = EFalse; + + switch ( aType ) + { + case EImage: + { + result = FetchExistingL( EImageFile, aSelectedFiles, aMultiSelect, aVerifier ); + break; + } + case EAudio: + { + result = FetchExistingL( EAudioFile, aSelectedFiles, aMultiSelect, aVerifier ); + break; + } + case EVideo: + { + result = FetchExistingL( EVideoFile, aSelectedFiles, aMultiSelect, aVerifier ); + break; + } + case ENewAudio: + { + result = FetchNewL( ENewFileServiceAudio, aSelectedFiles, aParams, aMultiSelect ); + break; + } + case ENewImage: + { + result = FetchNewL( ENewFileServiceImage, aSelectedFiles, aParams, aMultiSelect ); + break; + } + case ENewVideo: + { + result = FetchNewL( ENewFileServiceVideo, aSelectedFiles, aParams, aMultiSelect ); + break; + } + case ENote: + { + result = FetchNoteL( aSelectedFiles ); + break; + } + case ESVG: + { + result = FetchExistingL( EPresentationsFile, aSelectedFiles, aMultiSelect, aVerifier ); + break; + } + default: + { + break; + } + } + + return result; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchExistingL +// +// +// --------------------------------------------------------- + +TBool MsgAttachmentUtils::FetchExistingL( TMediaFileType aFileType, + CDesCArray& aSelectedFiles, + TBool aMultiSelect, + MMGFetchVerifier* aVerifier ) + + { + return MGFetch::RunL( aSelectedFiles, aFileType, aMultiSelect, aVerifier ); + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchNoteL +// +// +// --------------------------------------------------------- +TBool MsgAttachmentUtils::FetchNoteL( CDesCArray& aSelectedFiles ) + { + TBool result = EFalse; + CEikonEnv* eikonEnv = CEikonEnv::Static(); + + // get memo content from notepad to buffer. + HBufC* title = eikonEnv->AllocReadResourceLC( R_QTN_NMAKE_FETCH_MEMO_PRMPT ); + HBufC* buf = CNotepadApi::FetchMemoL( title ); + CleanupStack::PopAndDestroy( title ); + + if ( buf ) + { + CleanupStack::PushL( buf ); + + RFs& fs = eikonEnv->FsSession(); + + TFileName filename; + TInt max = KMsgAttaFileNameLength; + + // first try to create filename from memo text. + MsgAttachmentUtils::GetFileNameFromBuffer ( + filename, *buf, max, &KTxtAttaFilenameExtension ); + + if ( filename.Length() == 0 ) + { + eikonEnv->ReadResourceL( filename, R_QTN_MMS_NO_NAME_FOR_FILE ); + filename.Append( KTxtAttaFilenameExtension ); + } + + TFileName pathname; + GetMsgEditorTempPath( pathname, &filename ); + + // check the file name for validity and possible name duplicates. + TInt err = CApaApplication::GenerateFileName( fs, pathname ); + + if ( err == KErrNone ) + { + // write buffer to text file (unicode). + CPlainText* text = CPlainText::NewL(); + CleanupStack::PushL( text ); + text->InsertL( 0, *buf ); + text->ExportAsTextL( pathname, CPlainText::EOrganiseByParagraph, 0 ); + CleanupStack::PopAndDestroy( text ); + aSelectedFiles.AppendL( pathname ); + result = ETrue; + } + + CleanupStack::PopAndDestroy( buf ); + } + return result; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchNewL +// +// +// --------------------------------------------------------- +TBool MsgAttachmentUtils::FetchNewL( TNewServiceFileType aType, + CDesCArray& aSelectedFiles, + CAiwGenericParamList* aParams, + TBool aMultiSelect ) + { + TBool result = EFalse; + CNewFileServiceClient* fileClient = NewFileServiceFactory::NewClientL(); + CleanupStack::PushL( fileClient ); + + TUid appUid = KUidCamcorder; + switch ( aType ) + { + case ENewFileServiceImage: + case ENewFileServiceVideo: + { + appUid = KUidCamcorder; + break; + } + case ENewFileServiceAudio: + { + appUid = KUidVoiceRec; + break; + } + default: + User::Leave( KErrArgument ); + break; + } + + result = fileClient->NewFileL( + appUid, + aSelectedFiles, + aParams, + aType, + aMultiSelect ); + CleanupStack::PopAndDestroy( fileClient ); // params + return result; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::FetchAnyFileL +// +// +// --------------------------------------------------------- +EXPORT_C TBool MsgAttachmentUtils::FetchAnyFileL( TFileName& aFileName, + CCoeEnv& aCoeEnv, + MAknFileSelectionObserver* aVerifier, + MAknFileFilter* aFilter ) + { + TBool result( EFalse ); + TInt resourceFileOffset( -1 ); + + if ( !aCoeEnv.IsResourceAvailableL( R_MEB_MEMORY_SELECTION_DIALOG ) ) + { + TParse parse; + parse.Set( KMsgEditorAppUiResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL ); + + TFileName fileName( parse.FullName() ); + BaflUtils::NearestLanguageFile( aCoeEnv.FsSession(), fileName ); + + resourceFileOffset = aCoeEnv.AddResourceFileL( fileName ); + } + + TInt supportedTypes = AknCommonDialogsDynMem::EMemoryTypePhone | + AknCommonDialogsDynMem::EMemoryTypeInternalMassStorage | + AknCommonDialogsDynMem::EMemoryTypeMMCExternal; + + result = AknCommonDialogsDynMem::RunSelectDlgLD( supportedTypes, + aFileName, + R_MEB_MEMORY_SELECTION_DIALOG, + aFilter, + aVerifier ); + + if ( resourceFileOffset != -1 ) + { + aCoeEnv.DeleteResourceFile( resourceFileOffset ); + } + + return result; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::CombineIconsL +// +// +// --------------------------------------------------------- +// +EXPORT_C CFbsBitmap* MsgAttachmentUtils::CombineIconsL( + const CFbsBitmap* aFirstBmp, + const CFbsBitmap* aSecondBmp, + const CFbsBitmap* aSecondBmpMask ) + { + __ASSERT_DEBUG( aFirstBmp, Panic( ENullPointer ) ); + + // Resolve icon layout + TRect mainPane; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPane ); + TAknLayoutRect listPaneLayout; + listPaneLayout.LayoutRect( + mainPane, + AknLayout::list_gen_pane( 0 ) ); + TAknLayoutRect doubleGraphicLayout; + doubleGraphicLayout.LayoutRect( + listPaneLayout.Rect(), + AknLayout::list_double_large_graphic_pane_list_double2_large_graphic_pane_list_single_big_large_graphic_pane( 0 ) ); + TAknLayoutRect iconLayout; + iconLayout.LayoutRect( + doubleGraphicLayout.Rect(), + AknLayout::List_pane_elements__double_large_graphic__Line_8() ); + + TInt cleanupCount = 0; + + TDisplayMode dispMode = aFirstBmp->DisplayMode(); + if ( dispMode == EGray2 ) + { + // Convert hard masks to soft masks: + CFbsBitmap* temp = InvertBitmapL( aFirstBmp ); + CleanupStack::PushL( temp ); + aFirstBmp = temp; + cleanupCount++; + dispMode = EGray256; + } + + // Create target bitmap, device and gc + CFbsBitmap* bmp = new ( ELeave ) CFbsBitmap(); + CleanupStack::PushL( bmp ); + User::LeaveIfError( bmp->Create( iconLayout.Rect().Size(), dispMode ) ); + CFbsBitmapDevice* pBmpDev = CFbsBitmapDevice::NewL( bmp ); + CleanupStack::Pop(); // bmp + CleanupStack::PushL( pBmpDev ); + CBitmapContext* pBmpCtx = NULL; + User::LeaveIfError( pBmpDev->CreateBitmapContext( pBmpCtx ) ); + CleanupStack::PushL( pBmpCtx ); + + // Clear the target bitmap. + // Black background for soft masks + pBmpCtx->SetBrushColor( ( dispMode == EGray256 ) + ? KRgbBlack + : KRgbWhite ); + pBmpCtx->Clear(); + + // First draw the source bitmap... + const TSize bmpSize1( aFirstBmp->SizeInPixels() ); + const TPoint origin1( + ( iconLayout.Rect().Width() - bmpSize1.iWidth ) / 2, + ( iconLayout.Rect().Height() - bmpSize1.iHeight ) / 2 ); + + pBmpCtx->BitBlt( origin1, aFirstBmp ); + + if ( aSecondBmp ) + { + if ( aSecondBmp->DisplayMode() == EGray2 ) + { + // Convert hard masks to soft masks: + CFbsBitmap* temp = InvertBitmapL( aSecondBmp ); + CleanupStack::PushL( temp ); + aSecondBmp = temp; + cleanupCount++; + } + + // ...then draw the other bitmap on top. + const TSize bmpSize2( aSecondBmp->SizeInPixels() ); + const TPoint origin2( 0, iconLayout.Rect().Height() - bmpSize2.iHeight ); + + if ( !aSecondBmpMask ) + { + pBmpCtx->BitBlt( origin2, aSecondBmp ); + } + else + { + pBmpCtx->BitBltMasked( + origin2, + aSecondBmp, + TRect( bmpSize2 ), + aSecondBmpMask, + ETrue ); + } + } + + // Cleanup. + CleanupStack::PopAndDestroy( 2 ); // pBmpDev, pBmpCtx + CleanupStack::PopAndDestroy( cleanupCount ); + + // Return the new bitmap. + return bmp; + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::InvertBitmapL +// +// +// --------------------------------------------------------- +// +CFbsBitmap* MsgAttachmentUtils::InvertBitmapL( const CFbsBitmap* aBitmap ) + { + // Create target bitmap, device and gc + CFbsBitmap* bmp = new ( ELeave ) CFbsBitmap(); + CleanupStack::PushL( bmp ); + User::LeaveIfError( bmp->Create( aBitmap->SizeInPixels(), aBitmap->DisplayMode() ) ); + CFbsBitmapDevice* pBmpDev = CFbsBitmapDevice::NewL( bmp ); + CleanupStack::Pop(); // bmp + CleanupStack::PushL( pBmpDev ); + CBitmapContext* pBmpCtx = NULL; + User::LeaveIfError( pBmpDev->CreateBitmapContext( pBmpCtx ) ); + CleanupStack::Pop(); // pBmpDev + + // Set drawing mode to "NOTPEN" -> bitmap will be inverted + pBmpCtx->SetDrawMode( CGraphicsContext::EDrawModeNOTPEN ); + pBmpCtx->BitBlt( TPoint( 0, 0 ), aBitmap ); + + // Cleanup. + delete pBmpCtx; + delete pBmpDev; + + // Return the new bitmap. + return bmp; + } + + +// --------------------------------------------------------- +// MsgAttachmentUtils::FileSizeToStringL +// +// +// --------------------------------------------------------- +// +EXPORT_C void MsgAttachmentUtils::FileSizeToStringL( + TDes& aTarget, TInt aFileSize, TBool aKilobytesMinimum /*= EFalse*/ ) + { + TInt fileSize = aFileSize; + TInt resId = R_QTN_SIZE_B; + + if ( aKilobytesMinimum || aFileSize >= KLocalKilo ) + { + resId = R_QTN_SIZE_KB; + fileSize /= KLocalKilo; + if ( aFileSize % KLocalKilo ) + { + fileSize++; + } + } + + HBufC *buf = StringLoader::LoadLC( resId, fileSize ); + aTarget.Zero(); + aTarget.Append( *buf ); + + CleanupStack::PopAndDestroy( buf ); + } + +//---------------------------------------------------------------------------- +// from: TBool CImRecvConvert::IsIllegalChar(const TUint aChar) +//---------------------------------------------------------------------------- +LOCAL_C TBool IsIllegalChar(const TUint aChar) + { + return ( + aChar == '*' || + aChar == '\\' || + aChar == '<' || + aChar == '>' || + aChar == ':' || + aChar == '.' || + aChar == '"' || + aChar == '/' || + aChar == '|' || + aChar == '?' || + aChar == CEditableText::EParagraphDelimiter || + aChar == CEditableText::ELineBreak || + aChar < ' ' ); + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::GetFileNameFromBuffer +// +// +// --------------------------------------------------------- +// +EXPORT_C void MsgAttachmentUtils::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 ); + + __ASSERT_DEBUG( max > 0, Panic( EMsgZeroLength ) ); + + 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 s/he has for it. + if ( aFileName.Length() > 0 && aExt != NULL ) + { + aFileName.Append( *aExt ); + } + } + +// --------------------------------------------------------- +// MsgAttachmentUtils::GetMsgEditorTempPath +// +// Returns temp path used by msg editors and optionally +// appends file name to it. +// --------------------------------------------------------- +// +EXPORT_C void MsgAttachmentUtils::GetMsgEditorTempPath( + TFileName& aTempPath, + const TDesC* aFileName /*= NULL*/ ) + { + TInt driveNumber( EDriveD ); + +#ifdef RD_MULTIPLE_DRIVE + if ( DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRam, driveNumber ) != KErrNone ) + { + DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, driveNumber ); + } +#endif + + TChar driveCharacter; + CEikonEnv::Static()->FsSession().DriveToChar( driveNumber, driveCharacter ); + + aTempPath.Append( driveCharacter ); + aTempPath.Append( KMsgEditorTempDir ); + + if ( aFileName ) + { + aTempPath.Append( *aFileName ); + } + } + +// End of File