diff -r 000000000000 -r 094583676ce7 wvuing/wvuiave/AppSrc/CCAUiMessageUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/wvuiave/AppSrc/CCAUiMessageUtils.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,1254 @@ +/* +* Copyright (c) 2006 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: UI utils for message handling +* +*/ + + + +// INCLUDE FILES +#include "CCAUiMessageUtils.h" +#include "IMDialogUtils.h" +#include "ChatDebugPrint.h" +#include "ChatDefinitions.h" +#include "CAArrayUtils.h" +#include "imutils.h" + +#include "MCAConversationMessage.h" +#include "mcablockchecker.h" + + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "impsbuilddefinitions.h" +#include "chatdebugassert.h" + +#include "MCAConversationPC.h" +#include "IMMessageUtilsPC.h" +#include +#include +// The Settings have been moved to Cenrep (also retained in the Resource file), +// so the enums for keys and central repository header is added here +#include "VariantKeys.h" + +#ifdef RD_IMAGEPREVIEW +#include + + +#endif // RD_IMAGEPREVIEW + +// CONSTANTS + +_LIT8( KMimeTypeJpeg, "image/jpeg" ); +_LIT8( KMimeTypeGif, "image/gif" ); +_LIT8( KMimeTypeEmpty, "" ); +// From ICL documentation: +// "all decoder plugins also support thumbnail decodes with ratios of 1:2, 1:4 and 1:8." +const TInt KDecodeScaleRatioMin = 2; +const TInt KDecodeScaleRatioMax = 8; + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::CCAUiMessageUtils +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CCAUiMessageUtils::CCAUiMessageUtils( MCABlockChecker* aBlockChecker ) + : CActive( CActive::EPriorityLow ), iBlockChecker( aBlockChecker ) + { + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CCAUiMessageUtils::ConstructL() + { + User::LeaveIfError( iApaSession.Connect() ); + + // create dochandler + iDocHandler = CDocumentHandler::NewL(); + iDocHandler->SetExitObserver( this ); + } + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CCAUiMessageUtils* CCAUiMessageUtils::NewLC( MCABlockChecker* aBlockChecker /*= NULL*/ ) + { + CCAUiMessageUtils* self = new( ELeave ) CCAUiMessageUtils( aBlockChecker ); + + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + + +// Destructor +CCAUiMessageUtils::~CCAUiMessageUtils() + { + Cancel(); + + delete iDecoder; + delete iSelectedNames; + + delete iDocHandler; + iApaSession.Close(); + if ( iWait.IsStarted() ) + { + iWait.AsyncStop(); + } + } + +//----------------------------------------------------------------------------- +// CCAUiMessageUtils::RunL +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAUiMessageUtils::RunL() + { + if ( iWait.IsStarted() ) + { + iWait.AsyncStop(); + } + } + +//----------------------------------------------------------------------------- +// CCAUiMessageUtils::DoCancel +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +void CCAUiMessageUtils::DoCancel() + { + iDecoder->Cancel(); + } + +//----------------------------------------------------------------------------- +// CCAUiMessageUtils::RunError +// ( Other items commented in header ) +//----------------------------------------------------------------------------- +TInt CCAUiMessageUtils::RunError( TInt aError ) + { + if ( IsActive() ) + { + iStatus = aError; + Cancel(); + } + + if ( aError == KErrNoMemory ) + { + CActiveScheduler::Current()->Error( KErrNoMemory ); + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::SendNewFileL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCAUiMessageUtils::SendNewFileL( TNewServiceFileType aFileType, + MCAConversationPC& aMessageRWInterfacePC, + const TDesC& aSender /*= KNullDesC*/, + const MDesCArray* aScreenNames /*= NULL*/, + TBool aIsWhisperAllowed /*= ETrue*/ ) + { + // show the list of recipients first + if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) ) + { + // cancelled + return; + } + + // only one file will be created + CDesCArray* fileNames = new( ELeave )CDesCArrayFlat( 1 ); + CleanupStack::PushL( fileNames ); + CNewFileServiceClient* newFile = NewFileServiceFactory::NewClientL(); + CleanupStack::PushL( newFile ); + + CAiwGenericParamList* params = CAiwGenericParamList::NewLC(); + +// CEikonEnv::Static()->SetSystem( ETrue ); + + CHAT_DP_TXT( "Starting new file service.." ); + TBool okToSend = EFalse; + TRAPD( err, okToSend = + newFile->NewFileL( *fileNames, params, aFileType, EFalse ) ); + if ( err ) + { +// // restore state +// CEikonEnv::Static()->SetSystem( EFalse ); + User::LeaveIfError( err ); + } + + if ( okToSend ) + { + // we got new file, let's send it + CHAT_DP_TXT( "..got new file, sending it" ); + + DoSendFileL( *fileNames, aMessageRWInterfacePC, aSender ); + + } + + CleanupStack::PopAndDestroy( 3, fileNames ); // params, newFile, fileNames + CHAT_DP_TXT( "Send new file done.." ); + } + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::SendImageL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCAUiMessageUtils::SendImageL( + MCAConversationPC& aMessageRWInterfacePC, + const TDesC& aSender /* = KNullDesC */, + const MDesCArray* aScreenNames /* = NULL */, + TBool aIsWhisperAllowed /*= ETrue*/ ) + { + TBool ok( EFalse ); + // show the list of recipients first + if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) ) + { + // cancelled + return; + } + while ( !ok ) + { + // only one image can be selected at the moment + CDesCArray* files = new( ELeave )CDesCArrayFlat( 1 ); + CleanupStack::PushL( files ); + + HBufC* softkey = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_SOFTKEY_SELECT ); + + iBeginVerifySelection = EFalse; + + // This rd flag is for testing purposes only. +#ifndef RD_SEND_NOT_SUPPORTED_CONTENT + // only one image can be selected (EFalse) + if ( MGFetch::RunL( *files, EImageFile , EFalse, *softkey, KNullDesC, this ) ) +#else + if ( MGFetch::RunL( *files, EAnyMediaFile, EFalse, *softkey, KNullDesC, this ) ) +#endif //RD_SEND_NOT_SUPPORTED_CONTENT + { + // verify the selected image + iBeginVerifySelection = ETrue; + TBool verify = VerifySelectionL( files ); + + if ( !verify ) + { + CleanupStack::PopAndDestroy( softkey ); // softkey + CleanupStack::PopAndDestroy( files ); // files + continue; + } + +#ifdef RD_IMAGEPREVIEW + // + // Open image preview + // + if ( files->MdcaCount() == 1 ) // We can only open 1 image + { + HBufC* skSelect = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_SOFTKEY_SELECT ); + HBufC* skBack = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_SOFTKEY_BACK ); + + this->SetNavigationPaneDimmed( ETrue ); + + TInt res = ImagePreview::ShowImageL( files->MdcaPoint( 0 ), + *skSelect, *skBack ); + + this->SetNavigationPaneDimmed( EFalse ); + CleanupStack::PopAndDestroy( 2 ); // skSelect, skBack + ( res == EAknSoftkeyCancel ) ? ( ok = EFalse ) : ( ok = ETrue ); + } + else + { + // Invalid number of images + __CHAT_ASSERT_DEBUG( EFalse ); + } +#endif //RD_IMAGEPREVIEW + + if ( ok ) + { + // send files + DoSendFileL( *files, aMessageRWInterfacePC, aSender ); + + } + CleanupStack::PopAndDestroy( 2 ); // files, softkey + + } + else + { + // user canceled + CleanupStack::PopAndDestroy( 2 ); // files, softkey + ok = ETrue; + } + } //end of while + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::SendFileL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::SendFileL( + const MDesCArray& aFileNames, + MCAConversationPC& aMessageRWInterfacePC, + const TDesC& aSender /*= KNullDesC*/, + const MDesCArray* aScreenNames /*= NULL*/ ) + { + // show the list of recipients first + if ( ! SelectRecipientsL( aScreenNames ) ) + { + // cancelled + return; + } + + DoSendFileL( aFileNames, aMessageRWInterfacePC, aSender ); + + } + + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::SendNewFileL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCAUiMessageUtils::SendNewFileL( TNewServiceFileType aFileType, + MCAGroupPC& aMessageRWInterfacePC, + const TDesC& aSender /*= KNullDesC*/, + const MDesCArray* aScreenNames /*= NULL*/, + TBool aIsWhisperAllowed /*= ETrue*/ ) + { + // show the list of recipients first + if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) ) + { + // cancelled + return; + } + + // only one file will be created + CDesCArray* fileNames = new( ELeave )CDesCArrayFlat( 1 ); + CleanupStack::PushL( fileNames ); + CNewFileServiceClient* newFile = NewFileServiceFactory::NewClientL(); + CleanupStack::PushL( newFile ); + + CAiwGenericParamList* params = CAiwGenericParamList::NewLC(); + + CHAT_DP_TXT( "Starting new file service.." ); + if ( newFile->NewFileL( *fileNames, params, aFileType, EFalse ) ) + { + + // we got new file, let's send it + CHAT_DP_TXT( "..got new file, sending it" ); + + DoSendFileL( *fileNames, aMessageRWInterfacePC, aSender ); + + } + + CleanupStack::PopAndDestroy( 3, fileNames ); // params, newFile, fileNames + CHAT_DP_TXT( "Send new file done.." ); + } + +// ----------------------------------------------------------------------------- +// CCAUiMessageUtils::SendImageL +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CCAUiMessageUtils::SendImageL( + MCAGroupPC& aMessageRWInterfacePC, + const TDesC& aSender /* = KNullDesC */, + const MDesCArray* aScreenNames /* = NULL */, + TBool aIsWhisperAllowed /*= ETrue*/ ) + { + TBool ok( EFalse ); + // show the list of recipients first + if ( ! SelectRecipientsL( aScreenNames, aIsWhisperAllowed ) ) + { + // cancelled + return; + } + + while ( !ok ) + { + // only one image can be selected at the moment + CDesCArray* files = new( ELeave )CDesCArrayFlat( 1 ); + CleanupStack::PushL( files ); + + HBufC* softkey = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_SOFTKEY_SELECT ); + + iBeginVerifySelection = EFalse; + + // This rd flag is for testing purposes only. +#ifndef RD_SEND_NOT_SUPPORTED_CONTENT + // only one image can be selected (EFalse) + if ( MGFetch::RunL( *files, EImageFile, EFalse, *softkey, KNullDesC, this ) ) +#else + if ( MGFetch::RunL( *files, EAnyMediaFile, EFalse, *softkey, KNullDesC, this ) ) +#endif //RD_SEND_NOT_SUPPORTED_CONTENT + { + // verify the selected image + iBeginVerifySelection = ETrue; + TBool verify = VerifySelectionL( files ); + + if ( !verify ) + { + CleanupStack::PopAndDestroy( softkey ); // softkey + CleanupStack::PopAndDestroy( files ); // files + continue; + } + +#ifdef RD_IMAGEPREVIEW + // + // Open image preview + // + if ( files->MdcaCount() == 1 ) // We can only open 1 image + { + HBufC* skSelect = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_SOFTKEY_SELECT ); + HBufC* skBack = CCoeEnv::Static()->AllocReadResourceLC( + R_TEXT_SOFTKEY_BACK ); + + this->SetNavigationPaneDimmed( ETrue ); + + TInt res = ImagePreview::ShowImageL( files->MdcaPoint( 0 ), + *skSelect, *skBack ); + + this->SetNavigationPaneDimmed( EFalse ); + + CleanupStack::PopAndDestroy( 2 ); // skSelect, skBack + ( res == EAknSoftkeyCancel ) ? ( ok = EFalse ) : ( ok = ETrue ); + } + else + { + // Invalid number of images + __CHAT_ASSERT_DEBUG( EFalse ); + } +#endif //RD_IMAGEPREVIEW + + if ( ok ) + { + // send files + DoSendFileL( *files, aMessageRWInterfacePC, aSender ); + + } + CleanupStack::PopAndDestroy( 2 ); // files, softkey + + } + else + { + // user canceled + CleanupStack::PopAndDestroy( 2 ); // files, softkey + ok = ETrue; + } + } //end of while + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::SendFileL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::SendFileL( + const MDesCArray& aFileNames, + MCAGroupPC& aMessageRWInterfacePC, + const TDesC& aSender /*= KNullDesC*/, + const MDesCArray* aScreenNames /*= NULL*/ ) + { + // show the list of recipients first + if ( ! SelectRecipientsL( aScreenNames ) ) + { + // cancelled + return; + } + + DoSendFileL( aFileNames, aMessageRWInterfacePC, aSender ); + + } + + +// --------------------------------------------------------- +// CCAUiMessageUtils::SelectRecipientsL +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCAUiMessageUtils::SelectRecipientsL( const MDesCArray* aScreenNames, + TBool aIsWhisperAllowed /*= ETrue*/ ) + { + delete iSelectedNames; + iSelectedNames = NULL; + + // check if we're sending a group message and whispering is allowed. + // in that case, group members are in aScreenNames array + + const MDesCArray* screenNames = aScreenNames; + + if ( screenNames && aIsWhisperAllowed ) + { + TInt count( screenNames->MdcaCount() ); + if ( count > 0 ) + { + // insert "All" to top of the list + HBufC* all = CCoeEnv::Static()->AllocReadResourceLC( + R_QTN_CHAT_SEND_FILE_TO_ALL ); + HBufC* title = CCoeEnv::Static()->AllocReadResourceLC( + R_QTN_CHAT_SEND_FILE_TO ); + + // we have some screennames.. + CDesCArray* lst = CAArrayUtils::CloneArrayLC( *screenNames ); + lst->Sort(); + lst->InsertL( 0, *all ); + + // show query + iSelectedNames = + IMDialogUtils::MultiselectionListQueryDialogL( *lst, *title ); + + CleanupStack::PopAndDestroy( 2, title ); // lst, title + if ( ! iSelectedNames ) + { + // cancel + CleanupStack::PopAndDestroy( all ); + return EFalse; // not accepted + } + + if ( iSelectedNames->Count() > 0 ) + { + TInt pos; + if ( iSelectedNames->Find( *all, pos ) == 0 ) + { + // "All" selected, send message with + // empty array of screennames + iSelectedNames->Reset(); + } + } + CleanupStack::PopAndDestroy( all ); + } + else + { + // possibly the user is in group by himself + // => send to all. + delete iSelectedNames; + iSelectedNames = NULL; + iSelectedNames = new( ELeave ) CDesCArrayFlat( 1 ); + iSelectedNames->Reset(); + } + } + else if ( !aIsWhisperAllowed ) + { + // Whispering not allowed + // Send message with empty array of screennames + if ( !iSelectedNames ) + { + iSelectedNames = new( ELeave ) CDesCArrayFlat( 1 ); + } + iSelectedNames->Reset(); + } + + return ETrue; // was accepted + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::OpenObjectL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::OpenObjectL( MCAConversationMessage& aMsg ) + { + CHAT_DP( D_CHAT_LIT( "*OpenObject: opening.." ) ); + TEnumsPC::TContentProcessState state = aMsg.ContentProcessState(); + + switch ( state ) + { + case TEnumsPC::EThumbnailReady: + { + if ( aMsg.MessagerType() != TEnumsPC::EMessageSent ) + { + + if ( aMsg.ContentData().Length() == 0 ) + { + //In case there is only a thumbnail available in the buffer, because the real + //image file is deleted because of lack of memory + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEM_LOW_IMAGE_OPEN ); + return; + } + else + { + if ( aMsg.IsImageSaved() ) + { + //In case there is only a thumbnail available in the buffer, because user + //has saved the image + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEM_LOW_IMAGE_OPEN_SAVED ); + return; + } + } + } + else + { + //In case there is only a thumbnail available in the buffer, because user + //sent it by himself + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEM_LOW_IMAGE_OPEN_SAVED ); + return; + } + + break; + } + + case TEnumsPC::EContentCorrupted: + { + // => corrupted + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_CORRUPTED ); + return; + } + + case TEnumsPC::EContentNotSupported: + case TEnumsPC::EContentNotSupportedDrm: + { + // => unsupported + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_UNSUPPORTED ); + return; + } + + default: + { + break; + } + } + + + // save to a temporary file + HBufC* tempFileName = HBufC::NewMaxLC( KMaxPath ); + TPtr tempFileNamePtr( tempFileName->Des() ); + + HBufC* fileName = NULL; + + // Check if there is filename defined in message + const TDesC& origName = aMsg.Text(); + if ( origName.Length() > 0 ) + { + TParse parser; + User::LeaveIfError( parser.Set( origName, NULL, NULL ) ); + TPtrC ptr = parser.Name(); + fileName = ptr.AllocLC(); + tempFileNamePtr.SetLength( 0 ); + tempFileNamePtr.Insert( 0, *fileName ); + } + else + { + fileName = CCoeEnv::Static()->AllocReadResourceLC( + R_QTN_CHAT_UNNAMED_FILE ); + } + + TPtr fileNamePtr( fileName->Des() ); + + TDataType type( aMsg.MimeType() ); + RFile tempFile; + CleanupClosePushL( tempFile ); + + CHAT_DP( D_CHAT_LIT( "*OpenObject: creating temporary file %S" ), + &fileNamePtr ); + iDocHandler->SaveTempFileL( aMsg.ContentData(), type, fileNamePtr, + tempFile ); + iDocHandler->GetPath( tempFileNamePtr ); + CHAT_DP( D_CHAT_LIT( "*OpenObject: created temporary file to %S" ), + &tempFileNamePtr ); + + // check rights + if ( !IMUtils::FileProtectedL( tempFileNamePtr ) ) + { + // Create parameters to allow IV do saving + CAiwGenericParamList* params = CAiwGenericParamList::NewL(); + CleanupStack::PushL( params ); + TAiwGenericParam saveParam( EGenericParamAllowSave ); + params->AppendL( saveParam ); + // start the document + TRAPD( err, iDocHandler->OpenFileEmbeddedL( tempFile, type, *params ) ); + if ( err == KErrNone ) + { + // and wait for exit + CHAT_DP( D_CHAT_LIT( "*OpenObject: launched OpenFileEmbeddedL,\ + waiting for complete.. " ) ); + + if ( ! iWait.IsStarted() ) + { + iWait.Start(); // CSI: 10 # iWait is not an active object + } + } + else + { + CHAT_DP( D_CHAT_LIT( "*OpenObject: OpenFileEmbeddedL left with %d " ), + err ); + CActiveScheduler::Current()->Error( err ); + } + CleanupStack::PopAndDestroy( params ); + } + else + { + // content is protected + IMDialogUtils::DisplayInformationNoteL( + R_QTN_DRM_NOT_ALLOWED ); + } + + // delete temporary file + CleanupStack::PopAndDestroy( 2, fileName ); // tempFile.Close(), fileName + CHAT_DP( D_CHAT_LIT( "*OpenObject: deleting %S" ), &tempFileNamePtr ); + RFs& fs = CCoeEnv::Static()->FsSession(); + fs.Delete( *tempFileName ); + + CleanupStack::PopAndDestroy( tempFileName ); + CHAT_DP( D_CHAT_LIT( "*OpenObject: done" ) ); + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::SaveObjectL +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCAUiMessageUtils::SaveObjectL( MCAConversationMessage& aMsg ) + { + CHAT_DP( D_CHAT_LIT( "*SaveObject: saving.." ) ); + if ( aMsg.ContentData().Length() == 0 ) + { + // No content + return KErrGeneral; + } + + // Check if there is filename defined in message + HBufC* fileName = NULL; + const TDesC& origName = aMsg.Text(); + + if ( origName.Length() > 0 ) + { + TParse parser; + User::LeaveIfError( parser.Set( origName, NULL, NULL ) ); + TPtrC ptr = parser.Name(); + fileName = parser.Name().AllocLC(); + } + else + { + fileName = HBufC::NewLC( 0 ); + } + + TDataType type( aMsg.MimeType() ); + RFile tempFile; + CleanupClosePushL( tempFile ); + + // First save to temp file + iDocHandler->SaveTempFileL( aMsg.ContentData(), type, *fileName, tempFile ); + TFileName tempFileName; + TInt err = KErrNone; + tempFile.Name( tempFileName ); + iDocHandler->GetPath( tempFileName ); + + // Copy temp file, asks user drive for copying and leaves if free space + // on requested drive is below or will fall below critical level + if ( origName.Length() > 0 ) + { + err = iDocHandler->CopyL( tempFile, *fileName, type, KEntryAttNormal ); + } + else + { + err = iDocHandler->CopyL( tempFile, KNullDesC, type, KEntryAttNormal ); + } + + //fix - refer Ui Spec Approved Version 1.0 + //(Instant Messaging NG 001 151006.pdf) + //Section 10.2.10 Pg 131 - + //"In case user has saved the image already or sent it + //by himself, this option(save) is not available." + if ( err == KErrNone ) + { + aMsg.SetImageAsSaved( ETrue ); + } + CleanupStack::PopAndDestroy( 2, fileName ); // tempFile.Close(), fileName + + // Delete temp file + RFs& fs = CCoeEnv::Static()->FsSession(); + fs.Delete( tempFileName ); + + return err; + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::HandleServerAppExit +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::HandleServerAppExit( TInt aReason ) + { + iServerAppExitReason = aReason; + if ( iWait.IsStarted() ) + { + iWait.AsyncStop(); + } + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::VerifySelectionL +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCAUiMessageUtils::VerifySelectionL( const MDesCArray* aSelectedFiles ) + { + if ( !iBeginVerifySelection ) + { + return ETrue; + } + + TBool ok( EFalse ); + TBool protectedCount( 0 ); + TBool corruptedImage( EFalse ); + +#ifndef RD_SEND_NOT_SUPPORTED_CONTENT + if ( aSelectedFiles ) + { + TInt count( aSelectedFiles->MdcaCount() ); + for ( TInt i( 0 ); i < count; ++i ) + { + TUid dummyUid( KNullUid ); + TDataType dataType; + TPtrC filename( aSelectedFiles->MdcaPoint( i ) ); + User::LeaveIfError( iApaSession.AppForDocument( + filename, + dummyUid, dataType ) ); + + //Mime type is empty for non image files (e.g book marks) + // so retrun false + if ( dataType.Des8().CompareF( KMimeTypeEmpty ) == 0 ) + { + return EFalse; + } + + if ( dataType.Des8().CompareF( KMimeTypeJpeg ) == 0 || + dataType.Des8().CompareF( KMimeTypeGif ) == 0 ) + { + // selected object is gif or jpeg + if ( !IMUtils::FileProtectedL( filename ) ) + { + // if not protected => image is ok + ok = ETrue; + } + else + { + ++protectedCount; + } + } + + // try to open and decode picture to make sure it's + // not corrupted. + + delete iDecoder; + iDecoder = NULL; + + TInt params( CImageDecoder::EOptionNone +#ifndef RD_30_COMPATIBILITY_MODE + | CImageDecoder::EPreferFastDecode +#endif + ); + + TRAPD( err, iDecoder = CImageDecoder::FileNewL( + CEikonEnv::Static()->FsSession(), filename, + static_cast( params ) ) ); + + if ( err == KErrNone ) + { + // file seems ok, try to decode image + CFbsBitmap* bitmap = new ( ELeave ) CFbsBitmap(); + CleanupStack::PushL( bitmap ); + + TFrameInfo frame = iDecoder->FrameInfo(); + TSize decodeSize( DecodeSize( frame.iOverallSizeInPixels ) ); + + TInt bitmaperr = + bitmap->Create( decodeSize, frame.iFrameDisplayMode ); + + if ( bitmaperr ) + { + CHAT_DP( D_CHAT_LIT( "CCAUiMessageUtils::VerifySelectionL:\ + Unable to create bitmap (%d)" ), bitmaperr ); + CActiveScheduler::Current()->Error( bitmaperr ); + CleanupStack::PopAndDestroy( bitmap ); + return EFalse; + } + // start converting + iDecoder->Convert( &iStatus, *bitmap ); + if ( !IsActive() ) + { + SetActive(); + } + + // and wait until it's finished + if ( !iWait.IsStarted() ) + { + iWait.Start(); // CSI: 10 # iWait is not an active object + } + + TInt statuscode = iStatus.Int(); + CleanupStack::PopAndDestroy( bitmap ); + + if ( statuscode == KErrCorrupt ) + { + CHAT_DP_TXT( "CCAUiMessageUtils::VerifySelectionL\ + corrupted: decode failed" ); + corruptedImage = ETrue; + } + + delete iDecoder; + iDecoder = NULL; + } + else + { + // something wrong with opening file + // -> assume corrupt + corruptedImage = ETrue; + } + } + } + else + { + return ok; + } +#else + ok = ETrue; +#endif //RD_SEND_NOT_SUPPORTED_CONTENT + + if ( protectedCount > 0 ) + { + // some of the files were protected + IMDialogUtils::DisplayQueryDialogL( + protectedCount == 1 ? + R_QTN_DRM_INFO_SEND_FORBID_ONE : + R_QTN_DRM_INFO_SEND_FORBID_SOME ); + } + else if ( corruptedImage ) + { + IMDialogUtils::DisplayQueryDialogL( R_QTN_MMS_UPLOAD_INFO_CORRUPTED ); + ok = EFalse; // don't allow selection of this image + } + else if ( !ok && aSelectedFiles->MdcaCount() != 0 ) + { + // not ok, show note + IMDialogUtils::DisplayQueryDialogL( R_QTN_MMS_INFO_OBJ_NOT_SUPP_SEND ); + } + return ok; + } + + +// --------------------------------------------------------- +// CCAUiMessageUtils::DecodeSize +// (other items were commented in a header). +// --------------------------------------------------------- +// +TSize CCAUiMessageUtils::DecodeSize( const TSize& aSize ) + { + // 1:1 is always valid ratio for decode scaling + TInt lastValidRatio( 1 ); + for ( TInt ratio( KDecodeScaleRatioMin ); ratio <= KDecodeScaleRatioMax; ratio <<= 1 ) + { + if ( aSize.iWidth % ratio + aSize.iHeight % ratio == 0 ) + { + // this ratio is valid + lastValidRatio = ratio; + } + } + + // return the size scaled with correct ratio + return TSize( aSize.iWidth / lastValidRatio, + aSize.iHeight / lastValidRatio ); + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::ForwardContentMessageL +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCAUiMessageUtils::ForwardContentMessageL( + const MCAConversationMessage& aMessage, + const TDesC& aRecipient, + const MDesCArray* aScreenNames, + MCAConversationPC& aMessageRWInterfacePC, + TBool aIsWhisperingAllowed, + const TDesC& aSender /*= KNullDesC*/ ) + { + // picture was forwarded + if ( aMessage.ContentType() == TEnumsPC::EContentPicture ) + { + // Check image state and DRM. + // We should not get corrupted or DRM files at this point, + // but it's better to make sure of it. + TBool isProtected( IMUtils::ContentProtectedL( aMessage.ContentData() ) ); + + TEnumsPC::TContentProcessState state = + aMessage.ContentProcessState(); + if ( state == TEnumsPC::EContentCorrupted ) + { + // => corrupted + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_CORRUPTED ); + // Message was handled as best as we could + return ETrue; + } + else if ( state == TEnumsPC::EContentNotSupported || + state == TEnumsPC::EContentNotSupportedDrm || + isProtected ) + { + // => unsupported + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_UNSUPPORTED ); + // Message was handled as best as we could + return ETrue; + } + + // Image seems to be ok, so let's continue forwarding. + + // show the list of recipients first + if ( aScreenNames ) + { + if ( !SelectRecipientsL( aScreenNames, aIsWhisperingAllowed ) ) + { + // cancelled. Return true because it needs to seem that + // we handled the message. + return ETrue; + } + } + else + { + // this has to be Null when sending a PtoP message. + delete iSelectedNames; + iSelectedNames = NULL; + } + + IMMessageUtilsPC::SendMessageL( + aMessage, + aRecipient, + aMessageRWInterfacePC, + iSelectedNames, + aSender ) ; + + // message handled succesfully + return ETrue; + } + + // We handle only pictures here, so message was not handled. + return EFalse; + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::ForwardContentMessageL +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCAUiMessageUtils::ForwardContentMessageL( + const MCAConversationMessage& aMessage, + const TDesC& aRecipient, + const MDesCArray* aScreenNames, + MCAGroupPC& aMessageRWInterfacePC, + TBool aIsWhisperingAllowed, + const TDesC& aSender /*= KNullDesC*/ ) + { + // picture was forwarded + if ( aMessage.ContentType() == TEnumsPC::EContentPicture ) + { + // Check image state and DRM. + // We should not get corrupted or DRM files at this point, + // but it's better to make sure of it. + TBool isProtected( IMUtils::ContentProtectedL( aMessage.ContentData() ) ); + + TEnumsPC::TContentProcessState state = + aMessage.ContentProcessState(); + if ( state == TEnumsPC::EContentCorrupted ) + { + // => corrupted + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_CORRUPTED ); + // Message was handled as best as we could + return ETrue; + } + else if ( state == TEnumsPC::EContentNotSupported || + state == TEnumsPC::EContentNotSupportedDrm || + isProtected ) + { + // => unsupported + IMDialogUtils::DisplayInformationNoteL( R_QTN_CHAT_MEDIA_UNSUPPORTED ); + // Message was handled as best as we could + return ETrue; + } + + // Image seems to be ok, so let's continue forwarding. + + // show the list of recipients first + if ( aScreenNames ) + { + if ( !SelectRecipientsL( aScreenNames, aIsWhisperingAllowed ) ) + { + // cancelled. Return true because it needs to seem that + // we handled the message. + return ETrue; + } + } + else + { + // this has to be Null when sending a PtoP message. + delete iSelectedNames; + iSelectedNames = NULL; + } + + IMMessageUtilsPC::SendMessageL( + aMessage, + aRecipient, + aMessageRWInterfacePC, + iSelectedNames, + aSender ) ; + + // message handled succesfully + return ETrue; + } + + // We handle only pictures here, so message was not handled. + return EFalse; + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::DoSendFileL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::DoSendFileL( + const MDesCArray& aFileNames, + MCAConversationPC& aMsgRWInterface, + const TDesC& aSender /*= KNullDesC*/ ) + { + + TDataType dataType; + TPtrC8 mimeType; + TBool sendOption; + + // check file before it will be sent. + if ( CheckFileL( aFileNames, dataType, mimeType, sendOption ) ) + { + TPtrC fileName( aFileNames.MdcaPoint( 0 ) ); + IMMessageUtilsPC::SendFileL( aMsgRWInterface, + iSelectedNames, + sendOption, + fileName, + mimeType, + KNullDesC8, + aSender ); + } + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::DoSendFileL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::DoSendFileL( + const MDesCArray& aFileNames, + MCAGroupPC& aMsgRWInterface, + const TDesC& aSender /*= KNullDesC*/ ) + { + TDataType dataType; + TPtrC8 mimeType; + TBool sendOption; + + // check file before it will be sent. + if ( CheckFileL( aFileNames, dataType, mimeType, sendOption ) ) + { + TPtrC fileName( aFileNames.MdcaPoint( 0 ) ); + IMMessageUtilsPC::SendFileL( aMsgRWInterface, + iSelectedNames, + sendOption, + fileName, + mimeType, + KNullDesC8, + aSender ); + } + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::CheckFileL +// (other items were commented in a header). +// --------------------------------------------------------- +// +TBool CCAUiMessageUtils::CheckFileL( const MDesCArray& aFileNames, TDataType& aDataType, TPtrC8& aMimeType, TBool& aSendOption ) + { + if ( aFileNames.MdcaCount() == 0 ) + return EFalse; + + // Check if recipient is blocked + if ( iBlockChecker ) + { + iBlockChecker->CheckBlockedL(); + } + + TPtrC fileName( aFileNames.MdcaPoint( 0 ) ); + TUid dummyUid( KNullUid ); + +#ifndef RD_SEND_NOT_SUPPORTED_CONTENT + + if ( IMUtils::FileProtectedL( fileName ) ) + return EFalse; + + // not drm-protected + User::LeaveIfError( iApaSession.AppForDocument( fileName, + dummyUid, + aDataType ) ); + aMimeType.Set( aDataType.Des8() ); + aSendOption = EFalse; + + return ETrue; +#else + + TInt err( iApaSession.AppForDocument( fileName, dummyUid, aDataType ) ); + if ( err == KErrNone ) + aMimeType.Set( aDataType.Des8() ); + else + aMimeType.Set( KMimeTypeJpeg ); + + if ( !IMUtils::FileProtectedL( fileName ) ) + aSendOption = EFalse; + else + aSendOption = ETrue; + + return ETrue; +#endif //RD_SEND_NOT_SUPPORTED_CONTENT + } + +// --------------------------------------------------------- +// CCAUiMessageUtils::SetNaviPaneDimmed +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAUiMessageUtils::SetNavigationPaneDimmed( TBool aDimmed ) + { + CEikStatusPane* statusPane = CEikonEnv::Static()->AppUiFactory()->StatusPane(); + CCoeControl* control = statusPane->ControlL( TUid::Uid( EEikStatusPaneUidNavi ) ); + CAknNavigationControlContainer* navipane = static_cast( control ); + statusPane->SetDimmed( aDimmed ); + } + +// End of File