diff -r ebe688cedc25 -r 7fdbb852d323 messagingappbase/msgeditor/modelsrc/MsgEditorDocument.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingappbase/msgeditor/modelsrc/MsgEditorDocument.cpp Wed Sep 01 12:31:54 2010 +0100 @@ -0,0 +1,654 @@ +/* +* 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: MsgEditorDocument implementation +* +*/ + + + +// ========== INCLUDE FILES ================================ + +#include +#include // MTM UI base +#include + +#include // for TEditorParameters +#include // for CMuiuOperationWait + +#include "MsgEditorDocument.h" // module header +#include "MsgEditorModelPanic.h" // Panics +#include "MsgEditorLauncher.h" +#include "MsgEditorModel.h" // Model +#include "MsgEditorModelObserver.h" // MMsgEditorModelObserver +#include "MsgAttachmentModel.h" +#include "MsgEditorAppUi.h" // MsgEditorAppUi + +// ========== EXTERNAL DATA STRUCTURES ===================== + +// ========== EXTERNAL FUNCTION PROTOTYPES ================= + +// ========== CONSTANTS ==================================== + +const TInt KOperationGranularity = 4; + +// ========== MACROS ======================================= + +// ========== LOCAL CONSTANTS AND MACROS =================== + +// ========== MODULE DATA STRUCTURES ======================= + +// ========== LOCAL FUNCTION PROTOTYPES ==================== + +// ========== LOCAL FUNCTIONS ============================== + +// ========== MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------- +// CMsgEditorDocument::CMsgEditorDocument +// +// Constructor. +// --------------------------------------------------------- +// +EXPORT_C CMsgEditorDocument::CMsgEditorDocument( CEikApplication& aApp ) : + CEikDocument( aApp ) + { + } + +// --------------------------------------------------------- +// CMsgEditorDocument::~CMsgEditorDocument +// +// Destructor. +// --------------------------------------------------------- +// +EXPORT_C CMsgEditorDocument::~CMsgEditorDocument() + { + if ( iOpWatchers ) + { + iOpWatchers->ResetAndDestroy(); + } + delete iOpWatchers; + delete iModel; + delete iAttachmentModel; + iAttachmentModel = NULL; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::SetEntryWithoutNotificationL +// +// Set given entry to be current context. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::SetEntryWithoutNotificationL( TMsvId aId ) + { + __ASSERT_DEBUG( ( &( iModel->Session() ) != NULL ), Panic( ENoSession ) ); + + iModel->SetEntryL( aId ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::SetEntryL +// +// Set given entry to be current context and notifies after change. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::SetEntryL( TMsvId aId ) + { + SetEntryWithoutNotificationL( aId ); +#ifdef RD_MSG_FAST_PREV_NEXT + SetMsgAsReadL(); +#endif + EntryChangedL(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::Entry +// +// Return context. +// --------------------------------------------------------- +// +EXPORT_C const TMsvEntry& CMsgEditorDocument::Entry() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + + return iModel->Entry(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::Session +// +// Return session. +// --------------------------------------------------------- +// +EXPORT_C CMsvSession& CMsgEditorDocument::Session() const + { + __ASSERT_DEBUG( iModel, Panic( ENoSession ) ); + + return iModel->Session(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::CurrentEntry +// +// Returns CMsvEntry of the current context. +// --------------------------------------------------------- +// +EXPORT_C CMsvEntry& CMsgEditorDocument::CurrentEntry() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + + return iModel->Mtm().Entry(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::Mtm +// +// Returns the current Mtm. +// --------------------------------------------------------- +// +EXPORT_C CBaseMtm& CMsgEditorDocument::Mtm() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + + return iModel->Mtm(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::MtmUi +// +// to be deprecated +// --------------------------------------------------------- +// +EXPORT_C CBaseMtmUi& CMsgEditorDocument::MtmUi() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + CBaseMtmUi* retVal = NULL; + TRAP_IGNORE( retVal = &(iModel->MtmUiL() ) ); + return *retVal; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::MtmUiData +// +// to be deprecated +// --------------------------------------------------------- +// +EXPORT_C CBaseMtmUiData& CMsgEditorDocument::MtmUiData() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + CBaseMtmUiData* retVal = NULL; + TRAP_IGNORE( retVal = &(iModel->MtmUiDataL() ) ); + return *retVal; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::MtmUiL +// +// Returns the current MtmUi. +// --------------------------------------------------------- +// +EXPORT_C CBaseMtmUi& CMsgEditorDocument::MtmUiL() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + + return iModel->MtmUiL(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::MtmUiDataL +// +// Returns the current MtmUiData. +// --------------------------------------------------------- +// +EXPORT_C CBaseMtmUiData& CMsgEditorDocument::MtmUiDataL() const + { + __ASSERT_DEBUG( HasModel(), Panic( ENoMessageEntry ) ); + + return iModel->MtmUiDataL(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::PrepareMtmL +// +// Loads client and ui mtm's. Set clietn mtm +// to have some context +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::PrepareMtmL( const TUid aMtmType ) + { + iModel->PrepareMtmL( aMtmType ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::RestoreL +// +// Called (by the environment) when editor or viewer is opened embedded. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::RestoreL( + const CStreamStore& aStore, + const CStreamDictionary& aStreamDic ) + { + TEditorParameters params; + RStoreReadStream stream; + + stream.OpenLC( aStore, aStreamDic.At( KUidMsvEditorParameterValue ) ); + params.InternalizeL( stream ); + CleanupStack::PopAndDestroy(); // stream + + LaunchParametersL( params ); + EntryChangedL(); + PrepareToLaunchL( static_cast( iAppUi ) ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::HasModel +// +// Check if model is already created. +// --------------------------------------------------------- +// +EXPORT_C TBool CMsgEditorDocument::HasModel() const + { + return ( iModel && NULL != &( iModel->Mtm() ) ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::ConstructL +// +// 2nd phase constructor. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::ConstructL() + { + iModel = new ( ELeave ) CMsgEditorModel(); + iModel->ConstructL(); + iOpWatchers = new ( ELeave ) CSingleOpWatchers( KOperationGranularity ); + + iAttachmentModel = CreateNewAttachmentModelL( EFalse ); + iAttachmentModel->SetObserver( this ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::PrepareToLaunchL +// +// Calls LaunchView() function after all pre-launch steps are completed. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::PrepareToLaunchL( + MMsgEditorLauncher* aLauncher ) + { + __ASSERT_DEBUG( iModel, Panic( ENoMessageEntry ) ); + + iModel->iLaunchWait--; + + if ( iModel->iLaunchWait <= 0 ) + { + __ASSERT_DEBUG( aLauncher, Panic( EViewNotReady ) ); + + aLauncher->LaunchViewL(); + iLaunched = ETrue; + } + } + +// --------------------------------------------------------- +// CMsgEditorDocument::LaunchParametersL +// +// Handle command line parameters. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::LaunchParametersL( + const TEditorParameters& aParameters ) + { + iLaunchFlags = aParameters.iFlags; + + iModel->Wait(); + + if ( aParameters.iFlags & EMsgCreateMessageToService ) + { + // Create new message in given folder/service. + const TMsvId id = CreateNewL( aParameters.iId, DefaultMsgFolder() ); + SetEntryWithoutNotificationL( id ); + } + else if ( aParameters.iFlags & EMsgCreateNewMessage ) + { + // create new in folder. + const TMsvId id = CreateNewL(DefaultMsgService(), aParameters.iId); + SetEntryWithoutNotificationL(id); + } + else if ( aParameters.iFlags & EMsgForwardMessage || + aParameters.iFlags & EMsgReplyToMessageSender || + aParameters.iFlags & EMsgReplyToMessageAll ) + { + + const TMsvId id = ChangeContextL( aParameters ); + + // Save priority of forwarded message from original entry as + // entry is changed on SetEntryWithoutNotificationL + TMsvPriority priority( EMsvMediumPriority ); + if( aParameters.iFlags & EMsgForwardMessage ) + { + priority = Entry().Priority(); + } + + SetEntryWithoutNotificationL( id ); + + TBool changeEntry = EFalse; + TMsvEntry tEntry = Entry(); + + // Set saved priority for new entry. + tEntry.SetPriority( priority ); + + if ( tEntry.Visible() ) + { + tEntry.SetVisible( EFalse ); + changeEntry = ETrue; + } + + if ( !tEntry.InPreparation() ) + { + tEntry.SetInPreparation( ETrue ); + changeEntry = ETrue; + } + + if ( changeEntry ) + { + CurrentEntry().ChangeL( tEntry ); + } + } + else + { + // Open editor using the given message id. + const TMsvId preparedId = PrepareContextL( aParameters.iId ); + SetEntryWithoutNotificationL( preparedId ); + } + + __ASSERT_DEBUG( HasModel(), Panic( ENoMessage ) ); + + SetMsgAsReadL(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::ChangeContextL +// +// Handles existing messages (typically opened from Drafts). +// This function can be overriden by inherited class if some +// preprocessing is needed for the message. +// +// Default implementation just returns the given context. +// --------------------------------------------------------- +// +EXPORT_C TMsvId CMsgEditorDocument::PrepareContextL( const TMsvId aContext ) + { + return aContext; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::ChangeContextL +// +// Handles reply and forward messages, change current message context to +// be context of replied or forwarded message. +// --------------------------------------------------------- +// +EXPORT_C TMsvId CMsgEditorDocument::ChangeContextL( + const TEditorParameters& aParameters ) + { + SetEntryWithoutNotificationL( aParameters.iId ); + + CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); + + CMsvOperation* oper = NULL; + + const TMsvPartList parts = aParameters.iPartList; + const TMsvId dest = aParameters.iDestinationFolderId; + + if ( aParameters.iFlags & EMsgReplyToMessageSender || + aParameters.iFlags & EMsgReplyToMessageAll ) + { + oper = CreateReplyL( dest, parts, wait->iStatus ); + } + else if (aParameters.iFlags & EMsgForwardMessage) + { + oper = CreateForwardL( dest, parts, wait->iStatus ); + } + + __ASSERT_ALWAYS( oper != NULL, Panic( ENoMessage ) ); + + CleanupStack::PushL( oper ); + + wait->Start(); + + const TMsvId id = GetOperId( *oper ); + + if ( id < 0 ) + { + User::Leave( id ); + } + + CleanupStack::PopAndDestroy( 2 ); // oper, wait + + return id; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::CreateReplyL +// +// +// --------------------------------------------------------- +// +EXPORT_C CMsvOperation* CMsgEditorDocument::CreateReplyL( + TMsvId aDest, TMsvPartList aParts, TRequestStatus& aStatus ) + { + return Mtm().ReplyL( aDest, aParts, aStatus ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::CreateForwardL +// +// +// --------------------------------------------------------- +// +EXPORT_C CMsvOperation* CMsgEditorDocument::CreateForwardL( + TMsvId aDest, TMsvPartList aParts, TRequestStatus& aStatus ) + { + return Mtm().ForwardL( aDest, aParts, aStatus ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::AddSingleOperationL +// +// Adds operation into operation queque. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::AddSingleOperationL( + CMsvOperation* aOperation, CMsvSingleOpWatcher* aSopWatch ) + { + __ASSERT_DEBUG( aSopWatch != NULL, Panic( ENullPointer ) ); + __ASSERT_DEBUG( aOperation != NULL, Panic( ENullPointer ) ); + + aSopWatch->SetOperation( aOperation ); + iOpWatchers->AppendL( aSopWatch ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::OpCompleted +// +// Is called when operation is completed. If operation is found, handler is called. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::OpCompleted( + CMsvSingleOpWatcher& aOpWatcher, TInt aCompletionCode ) + { + __ASSERT_DEBUG( iOpWatchers != NULL, Panic( ENullPointer ) ); + + const TInt count = iOpWatchers->Count(); + TInt i = 0; + + for ( ; i < count; i++ ) + { + // looking for right operation in array. + if ( ( (*iOpWatchers)[i] ) == &aOpWatcher ) + { + break; + } + } + + if ( i >= count ) + { + // Although invalid operation is an error, we do not + // want to panic for that in product - since it not supposed + // to seem anyhow to user (Is this true?) + + __ASSERT_DEBUG( EFalse, Panic( EInvalidOperation ) ); + return ; + } + + if ( aCompletionCode != KErrNone ) + { + __ASSERT_DEBUG( HasModel(), Panic( ENullPointer ) ); + + TRAP_IGNORE( MtmUi().DisplayProgressSummary( (*iOpWatchers)[i]->Operation().ProgressL() ) ); + } + + // Operation has completed, remove watcher and operation (watcher owns operation) + // NOTE: Have to delete the watcher first, as the array does not call delete. + delete (*iOpWatchers)[i]; + + iOpWatchers->Delete( i ); + iOpWatchers->Compress(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::MediaAvailable +// +// Return the current (or latest known) state of the message storage. +// If this function returns EFalse, then it's likely that operations +// saving or restoring message entries will fail. +// --------------------------------------------------------- +// +EXPORT_C TBool CMsgEditorDocument::MediaAvailable() const + { + return iModel->MediaAvailable(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::SetEditorModelObserver +// +// Define editor model observer. There can be only one editor model +// observer defined at any time, so this function just changes the +// current observer. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::SetEditorModelObserver( + MMsgEditorModelObserver* aObs ) + { + iModel->SetModelObserver( aObs ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::GetOperId +// +// Returns TMsvId (new message id) of given CMsvOperation. +// +// Given operation class must return the id of the new +// message entry with FinalProgress(). +// --------------------------------------------------------- +// +EXPORT_C TMsvId CMsgEditorDocument::GetOperId( CMsvOperation& aOperation ) + { + TMsvId temp; + TPckgC < TMsvId > paramPack( temp ); + const TDesC8& progress = aOperation.FinalProgress(); + paramPack.Set( progress ); + return paramPack(); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::AttachmentModel +// +// Returns reference to attachment model. +// --------------------------------------------------------- +// +EXPORT_C CMsgAttachmentModel& CMsgEditorDocument::AttachmentModel() const + { + return *iAttachmentModel; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::NotifyChanges +// +// Default implementation panics with EMsgInheritedFunctionMissing. +// --------------------------------------------------------- +// +EXPORT_C void CMsgEditorDocument::NotifyChanges( + TMsgAttachmentCommand /*aCommand*/, CMsgAttachmentInfo* /*aAttachmentInfo*/ ) + { + __ASSERT_DEBUG( EFalse, Panic( EMsgInheritedFunctionMissing ) ); + } + + +// --------------------------------------------------------- +// CMsgEditorDocument::GetAttachmentFileL +// +// Default implementation leaves with KErrNotSupported +// --------------------------------------------------------- +// +EXPORT_C RFile CMsgEditorDocument::GetAttachmentFileL( TMsvAttachmentId /*aId*/ ) + { + User::Leave( KErrNotSupported ); + RFile dummy; + return dummy; + } + +// --------------------------------------------------------- +// CMsgEditorDocument::CreateNewAttachmentModelL +// +// +// --------------------------------------------------------- +// +EXPORT_C CMsgAttachmentModel* CMsgEditorDocument::CreateNewAttachmentModelL( + TBool aReadOnly ) + { + return CMsgAttachmentModel::NewL( aReadOnly ); + } + +// --------------------------------------------------------- +// CMsgEditorDocument::SetMsgAsReadL +// +// --------------------------------------------------------- +// +void CMsgEditorDocument::SetMsgAsReadL() + { + iLaunchFlags &= ~EMsgUnreadMessage; + + // Unset unread flag + // Can be done since viewers should not lock entries + if ( Entry().Unread() || Entry().New() ) + { + if ( Entry().Unread() ) + { + iLaunchFlags |= EMsgUnreadMessage; + } + TMsvEntry entry = Entry(); // create a copy + + entry.SetUnread( EFalse ); + entry.SetNew( EFalse ); + + // Asynchronous version used because entry may be remote. + CMsvSingleOpWatcher* watch = CMsvSingleOpWatcher::NewLC( *this ); + CMsvOperation* op = CurrentEntry().ChangeL( entry, watch->iStatus ); + CleanupStack::Pop(); // watch; + AddSingleOperationL( op, watch ); + } + } + +// End of File