messagingappbase/msgeditor/modelsrc/MsgAttachmentUtils.cpp
changeset 0 72b543305e3a
--- /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 <featmgr.h>
+#include <data_caging_path_literals.hrh>
+
+#include <eikenv.h>                 // for CEikonEnv
+#include <eikproc.h>                // for CEikProcess
+#include <gulicon.h>
+#include <apparc.h>                 // for CApaApplication
+#include <apgcli.h>                 // for RApaLsSession
+#include <apacln.h>                 // for TApaDocCleanupItem
+#include <txtetext.h>               // for CPlainText
+#include <gdi.h>
+#include <bautils.h>                // NearestLanguageFile
+
+#include <avkon.rsg>                // for R_QTN_SIZE_xx
+#include <aknlayout.cdl.h> // LAF
+#include <AknUtils.h>
+
+#include <AknCommonDialogsDynMem.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <driveinfo.h>
+#endif
+
+#include <NpdApi.h>                 // Notepad API
+#include <StringLoader.h>           // StringLoader
+
+#include <MGFetch.h>               // for MediaGallery
+
+#include <NewFileServiceClient.h>
+#include <NewFileService.hrh>
+#include <AiwCommon.h>
+
+#include "MsgEditorCommon.h"        // for KMsgEditorTempDir
+#include "MsgAttachmentUtils.h"
+#include "MsgEditorModelPanic.h"    // Panics
+#include <MsgEditorAppUi.rsg>       // 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