diff -r d189ee25cf9d -r 3533d4323edc emailuis/emailui/src/FreestyleEmailUiMailListVisualiser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailuis/emailui/src/FreestyleEmailUiMailListVisualiser.cpp Wed Sep 01 12:28:57 2010 +0100 @@ -0,0 +1,8854 @@ +/* +* Copyright (c) 2009 - 2010 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: This file implements classes CFSEmailUiMailListVisualiser, CMailListUpdater, CMsgMovedNoteTimer, CDateChangeTimer. +* +*/ + + +// SYSTEM INCLUDES +#include "emailtrace.h" +#include +#include +#include +#include +#include +#include +#include "cfsmailclient.h" +#include "cfsmailbox.h" +#include "cfsmailfolder.h" +#include "fscontrolbar.h" +#include "fscontrolbuttoninterface.h" +#include "fstreelist.h" +#include "fstreevisualizerbase.h" +#include "fstreeplainonelinenodedata.h" +#include "fstreeplainonelinenodevisualizer.h" +#include "fstreeplaintwolineitemdata.h" +#include "fstreeplaintwolineitemvisualizer.h" +#include "cfsmailcommon.h" +#include "ceuiemaillisttouchmanager.h" +#include "FSEmailBuildFlags.h" +#include "cfsccontactactionmenu.h" +#include "mfsccontactactionmenumodel.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "esmailsettingspluginuids.hrh" +#include "esmailsettingsplugin.h" +#include "mfsmailbrandmanager.h" +#include +#include +#include +#include +#include +// Meeting request +#include +#include "cesmricalviewer.h" +#include +#include + +// INTERNAL INCLUDES +#include "FreestyleEmailUiUtilities.h" +#include "FreestyleEmailUiLiterals.h" +#include "FreestyleEmailUiLayoutHandler.h" +#include "FreestyleEmailUiMailListModel.h" +#include "FreestyleEmailUiMailListVisualiser.h" +#include "FreestyleEmailUiFileSystemInfo.h" +#include "FreestyleEmailUiAppui.h" +#include "FreestyleEmailUi.hrh" +#include "FreestyleEmailUiTextureManager.h" +#include "FreestyleEmailUiMailListControl.h" +#include "FreestyleEmailUiStatusIndicator.h" +#include "freestyleemailcenrephandler.h" +#include "FreestyleEmailUiFolderListVisualiser.h" +#include "FreestyleEmailUiShortcutBinding.h" +#include "FreestyleEmailUiMsgDetailsVisualiser.h" +#include "FreestyleEmailDownloadInformationMediator.h" +#include "FreestyleEmailUiContactHandler.h" +#include "FreestyleEmailUiLauncherGridVisualiser.h" +#include "FreestyleEmailUiHtmlViewerView.h" +#include "FSDelayedLoader.h" +#include "FSEmail.pan" + +#include "ipsplgcommon.h" +#include "cemailsettingsextension.h" + +// CONST VALUES +const TInt KControlBarTransitionTime = 250; +const TInt KMaxPreviewPaneLength = 60; +const TInt KMsgUpdaterTimerDelay = 2500000; // Time to update list, 2,5sec +const TInt KNewMailTimerDelay = 20; // sleeping timer to start processing new messages +const TInt KSortTimerDelay = 40; // sleeping timer to start sorting ( delay should be longer than abowe ) +const TInt KSortCountdown = 5; // number how many times will be tried do start sorting when it's forbidden +const TInt KNewMailMaxBatch = 7; // number of new mails inserted into list at once +static const TInt KMsgDeletionWaitNoteAmount = 5; +_LIT( KMissingPreviewDataMarker, "..." ); + +static const TInt KMaxItemsFethed = 1000; +static const TInt KCMsgBlock = 15; +static const TInt KCMsgBlockSort = 50; + +// --------------------------------------------------------------------------- +// Generic method for deleting a pointer and setting it NULL. +// --------------------------------------------------------------------------- +// +template void SafeDelete(T*& ptr) + { + delete ptr; + ptr = NULL; + } + +// TDeleteTask +// Task class for deleting mail +// --------------------------------------------------------------------------- +// Class definition +// --------------------------------------------------------------------------- +template struct TDeleteTask + { + +public: + + typedef void ( T::*TDeleteMethod )( const RFsTreeItemIdList& aEntries ); + +public: + + TDeleteTask(T& aObject, TDeleteMethod aMethod); + ~TDeleteTask(); + void ExecuteL(); + RFsTreeItemIdList& Entries(); + void Reset(); + +private: + + T& iObject; + TDeleteMethod iMethod; + RFsTreeItemIdList iEntries; + + }; + +// --------------------------------------------------------------------------- +// TDeleteTask::TDeleteTask +// --------------------------------------------------------------------------- +// +template TDeleteTask::TDeleteTask( T& aObject, TDeleteMethod aMethod ) + : iObject(aObject), iMethod(aMethod) + { + } + +// --------------------------------------------------------------------------- +// TDeleteTask::~TDeleteTask +// --------------------------------------------------------------------------- +// +template TDeleteTask::~TDeleteTask() + { + iEntries.Close(); + } + +// --------------------------------------------------------------------------- +// TDeleteTask::ExecuteL +// --------------------------------------------------------------------------- +// +template void TDeleteTask::ExecuteL() + { + (iObject.*iMethod)(iEntries); + Reset(); + } + +// --------------------------------------------------------------------------- +// TDeleteTask::Entries +// --------------------------------------------------------------------------- +// +template RFsTreeItemIdList& TDeleteTask::Entries() + { + return iEntries; + } + +// --------------------------------------------------------------------------- +// TDeleteTask::Reset +// --------------------------------------------------------------------------- +// +template void TDeleteTask::Reset() + { + iEntries.Reset(); + } + + +// CMailListModelUpdater + + +// --------------------------------------------------------------------------- +// CMailListModelUpdater::NewL +// --------------------------------------------------------------------------- +// +CMailListModelUpdater* CMailListModelUpdater::NewL() + { + CMailListModelUpdater* self = new (ELeave) CMailListModelUpdater(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------------------------- +// CMailListModelUpdater::ConstructL +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::ConstructL() + { + User::LeaveIfError( iTimer.CreateLocal() ); + } + +// --------------------------------------------------------------------------- +// CMailListModelUpdater::CMailListModelUpdater +// --------------------------------------------------------------------------- +// +CMailListModelUpdater::CMailListModelUpdater() : CActive(EPriorityStandard) + { + CActiveScheduler::Add(this); + iBlockSize = KCMsgBlock; + } + +// --------------------------------------------------------------------------- +// CMailListModelUpdater::~CMailListModelUpdater +// --------------------------------------------------------------------------- +// +CMailListModelUpdater::~CMailListModelUpdater() + { + iObserver = NULL; + Cancel(); + iSorting.Close(); + iTimer.Close(); + } + +// --------------------------------------------------------------------------- +// Returns arrays for sorting parameters. Updater owns the arrays because +// it has to stay alive as long as the iterator is being used. +// --------------------------------------------------------------------------- +// +RArray& CMailListModelUpdater::Sorting() + { + iSorting.Reset(); + return iSorting; + } + +// --------------------------------------------------------------------------- +// Update the mail list model from given iterator. Update progress will be +// informed to the observer. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::UpdateModelL(MObserver& aObserver, + MFSMailIterator* aIterator, TInt aBlockSize) + { + Cancel(); + iObserver = &aObserver; + iIterator = aIterator; + Signal(EInitialize); + iBlockSize = aBlockSize; + } + +// --------------------------------------------------------------------------- +// Internal method. Sets new state and signals itself. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::Signal(TState aState, TInt /*aError*/) + { + const TInt KDelayInMicroSeconds = 5 * 1000; // 5 ms + + // timer used to get CAknWaitDialog animation working + iState = aState; + iTimer.After(iStatus, KDelayInMicroSeconds); + SetActive(); + + + //iState = aState; + //iStatus = KRequestPending; + //SetActive(); + //TRequestStatus* status = &iStatus; + //User::RequestComplete(status, aError); + } + +// --------------------------------------------------------------------------- +// Initialization state. Reset update and call UpdateBeginL() for the observer. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::InitializeL() + { + iParentId = KFsTreeRootID; + iId = TFSMailMsgId(); + iItemsFetched = 0; + iObserver->UpdateBeginL(); + Signal(EFetch); + } + +// --------------------------------------------------------------------------- +// Fetch state. Fetch next messages and if there is more messages signal +// fetch state again OR proceed to finalizing state. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::FetchL() + { + TInt blockSize = iBlockSize; + if ( iItemsFetched == 0 ) + { + blockSize = KCMsgBlock; + } + + RPointerArray messages(blockSize); + CleanupClosePushL(messages); + + const TBool moreMessages(iIterator->NextL(iId, blockSize, messages)); + + if (messages.Count() > 0) + { + iItemsFetched += messages.Count(); + iId = messages[messages.Count() - 1]->GetMessageId(); + iObserver->UpdateProgressL(iParentId, messages); + } + + CleanupStack::PopAndDestroy(); // messages.Close() + + if (moreMessages && iItemsFetched < KMaxItemsFethed) + { + Signal(EFetch); + } + else + { + Signal(EFinalize); + } + } + +// --------------------------------------------------------------------------- +// Finalizing state. Notify observer that model update has been done and +// free the resources. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::FinalizeL() + { + iObserver->UpdateCompleteL(); + Reset(); + } + +// --------------------------------------------------------------------------- +// If the state is anything but EIdle, returns ETrue. +// --------------------------------------------------------------------------- +// +TBool CMailListModelUpdater::IsUpdating() const + { + return iState > EIdle; + } + +// --------------------------------------------------------------------------- +// Reset the state to EIdle and free resources. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::Reset() + { + iSorting.Reset(); + SafeDelete(iIterator); + iState = EIdle; + } + +// --------------------------------------------------------------------------- +// Active objects RunL() +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::RunL() + { + const TInt error(iStatus.Int()); + if (!error) + { + switch (iState) + { + case EInitialize: + InitializeL(); + break; + case EFetch: + FetchL(); + break; + case EFinalize: + default: + FinalizeL(); + break; + } + } + else + { + User::Leave(error); // causes RunError to be called + } + } + +// --------------------------------------------------------------------------- +// Update has been cancelled. Inform the observer and free resources. +// --------------------------------------------------------------------------- +// +void CMailListModelUpdater::DoCancel() + { + if (iObserver) + { + iObserver->UpdateCancelled(IsUpdating()); + } + Reset(); + + iTimer.Cancel(); + } +// --------------------------------------------------------------------------- +// CMailListModelUpdater::RunError +// --------------------------------------------------------------------------- +// +TInt CMailListModelUpdater::RunError(TInt aError) + { + if ( aError != KErrNone ) + { + TRAP_IGNORE( iObserver->UpdateErrorL( aError ) ); + } + + return aError; + } + + + + + +// --------------------------------------------------------------------------- +// Static constructor. +// --------------------------------------------------------------------------- +// +CFSEmailUiMailListVisualiser* CFSEmailUiMailListVisualiser::NewL(CAlfEnv& aEnv, + CFreestyleEmailUiAppUi* aAppUi, + CAlfControlGroup& aMailListControlGroup ) + { + FUNC_LOG; + CFSEmailUiMailListVisualiser* self = CFSEmailUiMailListVisualiser::NewLC(aEnv, aAppUi, aMailListControlGroup ); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Static constructor. +// --------------------------------------------------------------------------- +// +CFSEmailUiMailListVisualiser* CFSEmailUiMailListVisualiser::NewLC(CAlfEnv& aEnv, + CFreestyleEmailUiAppUi* aAppUi, + CAlfControlGroup& aMailListControlGroup) + { + FUNC_LOG; + CFSEmailUiMailListVisualiser* self = + new (ELeave) CFSEmailUiMailListVisualiser( aEnv, aAppUi, aMailListControlGroup ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Second phase constructor. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ConstructL() + { + FUNC_LOG; + + BaseConstructL( R_FSEMAILUI_MAIL_LIST_VIEW ); + + iMailListModelUpdater = CMailListModelUpdater::NewL(); + + // Don't construct this anywhere else than here. + // Don't delete this until in the destructor to avoid NULL checks. + iModel = CFSEmailUiMailListModel::NewL( &iAppUi ); + + // Set list as initial focused control + iFocusedControl = EMailListComponent; + iThisViewActive = EFalse; + iSkinChanged = EFalse; + + iFirstStartCompleted = EFalse; + + iAsyncCallback = new (ELeave) CAsyncCallBack( CActive::EPriorityStandard ); + iAsyncRedrawer = new (ELeave) CAsyncCallBack( CActive::EPriorityLow ); + iLastFocus = EFalse; + iDeleteTask = new (ELeave) TDeleteTask (*this, HandleDeleteTaskL); + + iNewMailTimer = CFSEmailUiGenericTimer::NewL( this ); + iSortTimer = CFSEmailUiGenericTimer::NewL( this ); + iSortState = ESortNone; + + iTouchFeedBack = MTouchFeedback::Instance(); + } + +// --------------------------------------------------------------------------- +// Second phase constructor. +// --------------------------------------------------------------------------- +// +// CFSEmailUiMailListVisualiser::DoFirstStartL() +// Purpose of this function is to do first start things only when list is +// really needed to be shown. Implemented to make app startuo faster. +void CFSEmailUiMailListVisualiser::DoFirstStartL() + { + FUNC_LOG; + // Create mail list updater timer + iMailListUpdater = CMailListUpdater::NewL( this ); + + // Set initial sort criteria + iCurrentSortCriteria.iField = EFSMailSortByDate; + iCurrentSortCriteria.iOrder = EFSMailDescending; + + // Create screen control and anchor layout + iMailListControl = CFreestyleEmailUiMailListControl::NewL( iEnv, this ); + iScreenAnchorLayout = CAlfAnchorLayout::AddNewL( *iMailListControl ); + iScreenAnchorLayout->SetFlags(EAlfVisualFlagAutomaticLocaleMirroringEnabled); + + iTouchManager = CEUiEmailListTouchManager::NewL(*this); + + // Create control bar control and append to control group and anchor layout + iControlBarControl = CFsControlBar::NewL( iEnv ); + iControlBarControl->AddObserverL( *this ); + iControlBarControl->AddObserverL( *iTouchManager ); + + CreateControlBarLayoutL(); + SetMailListLayoutAnchors(); + + iControlBarControl->SetSelectorTransitionTimeL( KControlBarTransitionTime ); + iControlBarControl->ClearBackgroundColor(); + iControlBarLayout = CAlfDeckLayout::AddNewL( *iControlBarControl, iScreenAnchorLayout ); + iControlBarVisual = iControlBarControl->Visual(); + + // Create list and append to control group and anchor layout + + iListLayout = CAlfDeckLayout::AddNewL( *iMailListControl, iScreenAnchorLayout ); + iMailTreeListVisualizer = CFsTreeVisualizerBase::NewL(iMailListControl, *iListLayout); + iMailTreeListVisualizer->SetFlipState( iKeyboardFlipOpen ); + iMailTreeListVisualizer->SetFocusVisibility( iFocusVisible ); + iMailList = CFsTreeList::NewL(*iMailTreeListVisualizer, iEnv ); + + // Set mark type and icon + iMailList->SetMarkTypeL( CFsTreeList::EFsTreeListMultiMarkable ); + iMailList->SetIndentationL(0); + + ControlGroup().AppendL( iMailListControl ); + ControlGroup().AppendL( iControlBarControl ); + ControlGroup().AppendL( iMailList->TreeControl() ); + + iTreeItemArray.Reset(); + + // Set empty text + HBufC* emptyText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_EMPTY_MSG_LIST_TEXT ); + iMailTreeListVisualizer->SetEmptyListTextL( *emptyText ); + CleanupStack::PopAndDestroy( emptyText ); + + iFocusedTextColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor(); + iNormalTextColor = iAppUi.LayoutHandler()->ListNormalStateTextSkinColor(); + iNodeTextColor = iAppUi.LayoutHandler()->ListNodeTextColor(); + iMailTreeListVisualizer->RootNodeVisualizer()->SetNormalStateTextColor( iNormalTextColor ); + + // Set page up and page down keys + iMailTreeListVisualizer->AddCustomPageUpKey( EStdKeyPageUp ); + iMailTreeListVisualizer->AddCustomPageDownKey( EStdKeyPageDown ); + + // Set selector brushes + CAlfBrush* listSelectorBrush = iAppUi.FsTextureManager()->ListSelectorBrushL(); // not owned + iMailTreeListVisualizer->SetSelectorPropertiesL( listSelectorBrush, 1.0, CFsTreeVisualizerBase::EFsSelectorMoveSmoothly ); + + CAlfBrush* cbSelectorBrush = iAppUi.FsTextureManager()->NewCtrlBarSelectorBrushLC(); + iControlBarControl->SetSelectorImageL( cbSelectorBrush ); + CleanupStack::Pop( cbSelectorBrush ); // ownership transferred to control bar + + iNewEmailText = StringLoader::LoadL( R_COMMAND_AREA_NEW_EMAIL ); + + // Set menu, mark and background icons + iMailTreeListVisualizer->SetMarkIcon( iAppUi.FsTextureManager()->TextureByIndex( EListControlMarkIcon ) ); + iMailTreeListVisualizer->SetMenuIcon( iAppUi.FsTextureManager()->TextureByIndex( EListControlMenuIcon ) ); + iMailList->AddObserverL( *this ); + iMailList->AddObserverL( *iTouchManager ); + // Initializing the default stylus long tap popup menu + if( !iStylusPopUpMenu ) + { + TPoint point( 0, 0 ); + iStylusPopUpMenu = CAknStylusPopUpMenu::NewL( this , point ); + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC( reader, + R_STYLUS_POPUP_MENU_MESSAGE_LIST_VIEW ); + iStylusPopUpMenu->ConstructFromResourceL( reader ); + CleanupStack::PopAndDestroy(); // reader + } + + iAppUi.LayoutHandler()->SetListMarqueeBehaviour( iMailList ); + + iDateChangeTimer = CDateChangeTimer::NewL( *this ); + iDateChangeTimer->Start(); + + UpdateMailListSettingsL(); + + iMailList->SetIndentationL(0); + iMailList->SetLoopingType( EFsTreeListLoopingDisabled ); + iMailTreeListVisualizer->SetItemExpansionDelay( iAppUi.LayoutHandler()->ListItemExpansionDelay() ); + iMailList->SetScrollTime( iAppUi.LayoutHandler()->ListScrollingTime(), 0.5 ); + + iFirstStartCompleted = ETrue; + } + + +// --------------------------------------------------------------------------- +// Constructor. +// --------------------------------------------------------------------------- +// +CFSEmailUiMailListVisualiser::CFSEmailUiMailListVisualiser( CAlfEnv& aEnv, + CFreestyleEmailUiAppUi* aAppUi, CAlfControlGroup& aMailListControlGroup ) + : CFsEmailUiViewBase( aMailListControlGroup, *aAppUi ), + iEnv( aEnv ), + iListMarkItemsState( ETrue ), //Initlly list has no markings + iMoveToFolderOngoing( EFalse ), + iConsumeStdKeyYes_KeyUp( EFalse ), // use to prevent Call application execution if call for contact processed + iMailOpened( EFalse ), + iMarkingMode( EFalse ), + iMarkingModeWaitingToExit( EFalse ), + iMarkingModeTextVisual( NULL ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// +CFSEmailUiMailListVisualiser::~CFSEmailUiMailListVisualiser() + { + FUNC_LOG; +/* + if (iExtension) + { + iAppUi.GetMailClient()->ReleaseExtension(iExtension); + } +*/ + SafeDelete(iMailListModelUpdater); + SafeDelete(iMailFolder); + delete iTouchManager; + delete iStylusPopUpMenu; + delete iMailList; + delete iNewEmailText; + + // Don't construct this anywhere else than in constructor. + // Don't delete anywhere else thatn here to avoid NULL checks. + delete iModel; + + delete iDeleteTask; + DeleteSortWaitNote(); + delete iNewMailTimer; + delete iSortTimer; + iNewMailIds.Close(); + } + +void CFSEmailUiMailListVisualiser::PrepareForExit() + { + FUNC_LOG; + iMailListModelUpdater->Cancel(); + if ( iMsgNoteTimer ) + { + // delete also cancels timer + SafeDelete(iMsgNoteTimer); + } + if ( iDateChangeTimer ) + { + // delete also cancels timer + SafeDelete(iDateChangeTimer); + } + if ( iMailListUpdater ) + { + // delete also cancels timer + SafeDelete(iMailListUpdater); + } + if ( iAsyncRedrawer ) + { + SafeDelete(iAsyncRedrawer); + } + if ( iAsyncCallback ) + { + SafeDelete(iAsyncCallback); + } + if ( iMailList ) + { + iMailList->RemoveObserver( *this ); + } + if ( iControlBarControl ) + { + iControlBarControl->RemoveObserver( *this ); + } + + if ( iNewMailTimer ) + { + // delete also cancels timer + SafeDelete( iNewMailTimer ); + } + + if ( iSortTimer ) + { + // delete also cancels timer + SafeDelete( iSortTimer ); + } + + SafeDelete(iMailFolder); + iTreeItemArray.Reset(); + // Reset, not delete to avoid NULL checks. + iModel->Reset(); + // Resources freed, new start required + iFirstStartCompleted = EFalse; + } + +// --------------------------------------------------------------------------- +// Returns reference to mail list. +// --------------------------------------------------------------------------- +// +CFsTreeList& CFSEmailUiMailListVisualiser::GetMailList() + { + FUNC_LOG; + return *iMailList; + } + +// --------------------------------------------------------------------------- +// @see CMailListModelUpdater::MObserver::UpdateErrorL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateErrorL(TInt aError) + { + FUNC_LOG; + + DeleteSortWaitNote(); + User::Leave(aError); + } + +// --------------------------------------------------------------------------- +// @see CMailListModelUpdater::MObserver::UpdateBeginL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateBeginL() + { + FUNC_LOG; + iMailList->BeginUpdate(); + iMailList->RemoveAllL(); + iTreeItemArray.Reset(); + iModel->Reset(); + iMailList->EndUpdateL(); + + SetListAndCtrlBarFocusL(); + } + +// --------------------------------------------------------------------------- +// @see CMailListModelUpdater::MObserver::UpdateProgressL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateProgressL(TFsTreeItemId& aParentId, RPointerArray& aMessages) + { + FUNC_LOG; + + const TInt itemsInModel(iModel->Count()); + CreateModelItemsL(aMessages); + RefreshListItemsL(aParentId, itemsInModel, iModel->Count()); + } + +// --------------------------------------------------------------------------- +// @see CMailListModelUpdater::MObserver::UpdateCompleteL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateCompleteL() + { + FUNC_LOG; + TBool sorting = EFalse; + if ( iSortWaitNote ) + { + sorting = ETrue; + } + DeleteSortWaitNote(); + + if ( !iModel->Count() ) + { + iFocusedControl = EControlBarComponent; + } + else + { + iFocusedControl = EMailListComponent; + if (iMailList->FocusedItem() == KFsTreeNoneID) + { + iMailList->SetFocusedItemL( iTreeItemArray[0].iListItemId ); + } + } + SetListAndCtrlBarFocusL(); + + if( !CheckAutoSyncSettingL() && !sorting ) + { + iAppUi.StartMonitoringL(); + } + + TIMESTAMP( "Locally stored messages fetched for message list" ); + } + +// --------------------------------------------------------------------------- +// @see CMailListModelUpdater::MObserver::UpdateCancelled +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateCancelled(const TBool aForceRefresh) + { + FUNC_LOG; + + iForceRefresh = aForceRefresh; + DeleteSortWaitNote(); + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::DeleteSortWaitNote +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DeleteSortWaitNote() + { + if ( iSortWaitNote ) + { + TRAP_IGNORE( iSortWaitNote->ProcessFinishedL() ); + iSortWaitNote = NULL; + } + } + + +// --------------------------------------------------------------------------- +// Asynchronous mail list model sort. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SortMailListModelAsyncL() + { + FUNC_LOG; + + DeleteSortWaitNote(); + + TBool ret = UpdateMailListModelAsyncL( KCMsgBlockSort ); + if ( ret ) + { + TFsEmailUiUtility::ShowWaitNoteL( iSortWaitNote, R_FSE_WAIT_SORTING_TEXT, EFalse, ETrue ); + } + } + +// --------------------------------------------------------------------------- +// Asynchronous mail list model update. +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::UpdateMailListModelAsyncL(TInt aBlockSize) + { + FUNC_LOG; + TBool ret = EFalse; + if ( iMailFolder ) + { + TFSMailDetails details( EFSMsgDataEnvelope ); + RArray& sorting(iMailListModelUpdater->Sorting()); + sorting.AppendL( iCurrentSortCriteria ); + if ( iCurrentSortCriteria.iField != EFSMailSortByDate ) + { + // Add date+descending as secondary sort criteria if primary field is something else than date + TFSMailSortCriteria secondarySortCriteria; + secondarySortCriteria.iField = EFSMailSortByDate; + secondarySortCriteria.iOrder = EFSMailDescending; + sorting.AppendL( secondarySortCriteria ); + } + // List all or maximum number of messages + iMailListModelUpdater->UpdateModelL(*this, iMailFolder->ListMessagesL(details, sorting), aBlockSize); + ret = ETrue; + } + else + { + UpdateCompleteL(); + } + + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateMailListModelL() + { + FUNC_LOG; + // Make sure asynchronous update is not going on + iMailListModelUpdater->Cancel(); + // Reset model with each update + iModel->Reset(); + if ( iMailFolder ) + { + // Update folder if provided, otherwise use current folder + RPointerArray folderMessages( KCMsgBlock ); + CleanupClosePushL( folderMessages ); + + RPointerArray tempFolderMessages( KCMsgBlock ); + CleanupClosePushL( tempFolderMessages ); + + TFSMailDetails details( EFSMsgDataEnvelope ); + RArray sorting; + CleanupClosePushL( sorting ); + sorting.Append( iCurrentSortCriteria ); + if ( iCurrentSortCriteria.iField != EFSMailSortByDate ) + { + // Add date+descending as secondary sort criteria if primary field is something else than date + TFSMailSortCriteria secondarySortCriteria; + secondarySortCriteria.iField = EFSMailSortByDate; + secondarySortCriteria.iOrder = EFSMailDescending; + sorting.Append( secondarySortCriteria ); + } + + // List all or maximum number of messages + MFSMailIterator* iterator = iMailFolder->ListMessagesL( details, sorting ); + CleanupDeletePushL( iterator ); // standard CleanupStack::PushL does not work with non-C-class pointer + + // Use iterator to get messages in peaces of KCMsgBlock to avoid OOM in FSStore + TFSMailMsgId dummy; + TBool moreMessagesToFollow = iterator->NextL( dummy, KCMsgBlock, folderMessages ); + for ( TInt i = KCMsgBlock; i < KMaxItemsFethed && moreMessagesToFollow ; i += KCMsgBlock ) + { + tempFolderMessages.Reset(); + moreMessagesToFollow = iterator->NextL( folderMessages[i-1]->GetMessageId(), KCMsgBlock, tempFolderMessages ); + for ( TInt a=0 ; a& aMessages ) + { + FUNC_LOG; + // New Items + CFSEmailUiMailListModelItem* newItem(NULL); + + // Draw first separator if there are messages. + if ( aMessages.Count() && iNodesInUse == EListControlSeparatorEnabled ) + { + if (iModel->Count()) + { + CFSMailMessage* nextMessage = aMessages[0]; + CFSEmailUiMailListModelItem* previousMessage(static_cast(iModel->Item(iModel->Count() - 1))); + if ( previousMessage ) // Safety + { + TBool needANewDivider = + !MessagesBelongUnderSameSeparatorL( previousMessage->MessagePtr(), *nextMessage ); + if ( needANewDivider ) + { + newItem = CreateSeparatorModelItemLC( *nextMessage ); + iModel->AppendL( newItem ); + CleanupStack::Pop( newItem ); + } + } + } + else + { + newItem = CreateSeparatorModelItemLC( *aMessages[0] ); + iModel->AppendL( newItem ); + CleanupStack::Pop( newItem ); + } + } + + // Start appending items + for (int i = 0; i < aMessages.Count(); i++) + { + CFSMailMessage* curMessage = aMessages[i]; + if ( curMessage ) + { + newItem = CFSEmailUiMailListModelItem::NewL( curMessage, ETypeMailItem ); + CleanupStack::PushL( newItem ); + iModel->AppendL( newItem ); + CleanupStack::Pop( newItem ); + + // Append new separator if needed + if ( i != aMessages.Count()-1 && iNodesInUse == EListControlSeparatorEnabled ) + { + CFSMailMessage* nextMessage = aMessages[i+1]; // This msg is next in the list + + if ( nextMessage ) + { + TBool needANewDivider = + !MessagesBelongUnderSameSeparatorL( *curMessage, *nextMessage ); + if ( needANewDivider ) + { + newItem = CreateSeparatorModelItemLC( *nextMessage ); + iModel->AppendL( newItem ); + CleanupStack::Pop( newItem ); + } + } + } + } + } + } + +// --------------------------------------------------------------------------- +// CreateSeparatorModelItemLC +// Create separator model item for the given message. Separator text depends +// on active sorting mode. +// --------------------------------------------------------------------------- +// +CFSEmailUiMailListModelItem* CFSEmailUiMailListVisualiser::CreateSeparatorModelItemLC( CFSMailMessage& aMessage ) const + { + FUNC_LOG; + CFSEmailUiMailListModelItem* separator = + CFSEmailUiMailListModelItem::NewL( &aMessage, ETypeSeparator ); + CleanupStack::PushL( separator ); + + HBufC* separatorText = NULL; + + switch ( iCurrentSortCriteria.iField ) + { + case EFSMailSortByFlagStatus: + { + if ( aMessage.IsFlagSet( EFSMsgFlag_FollowUp ) ) + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_FOLLOW_UP ); + } + else if ( aMessage.IsFlagSet( EFSMsgFlag_FollowUpComplete ) ) + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_FLAG_COMPLETE ); + } + else + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_NO_FLAG ); + } + } + break; + case EFSMailSortByPriority: + { + if ( aMessage.IsFlagSet( EFSMsgFlag_Important ) ) + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_PRIO_HIGH ); + } + else if ( aMessage.IsFlagSet( EFSMsgFlag_Low ) ) + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_PRIO_LOW ); + } + else + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_PRIO_NORMAL ); + } + } + break; + case EFSMailSortByRecipient: + case EFSMailSortBySender: + { + TInt folderType(EFSInbox); + if( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + TBool useRecipient = ( folderType == EFSSentFolder || + folderType == EFSDraftsFolder || + folderType == EFSOutbox ); + + CFSMailAddress* fromAddress(0); + // Check address based on whether we are using recipient or sender sort + if ( useRecipient ) + { + RPointerArray& toArray = aMessage.GetToRecipients(); + if ( toArray.Count() ) + { + fromAddress = toArray[0]; + } + } + else + { + fromAddress = aMessage.GetSender(); + } + TDesC* diplayName(0); + if ( fromAddress ) + { + diplayName = &fromAddress->GetDisplayName(); + } + + if ( fromAddress && diplayName && diplayName->Length() != 0 ) + { + separatorText = diplayName->AllocLC(); + } + else if ( fromAddress && fromAddress->GetEmailAddress().Length() != 0 ) + { + separatorText = fromAddress->GetEmailAddress().AllocLC(); + } + else + { + if ( useRecipient ) + { + separatorText = KNullDesC().AllocLC(); + } + else + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SENDER_INFO_AVAILABLE ); + } + } + // Get rid of possible unwanted characters in display name + if ( separatorText ) + { + TFsEmailUiUtility::StripDisplayName( *separatorText ); + } + } + break; + case EFSMailSortByAttachment: + { + if ( aMessage.IsFlagSet( EFSMsgFlag_Attachments ) ) + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_ATTACHMENTS ); + } + else + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_NO_ATTACHMENTS ); + } + } + break; + case EFSMailSortByUnread: + { + if ( aMessage.IsFlagSet( EFSMsgFlag_Read ) ) + { + separatorText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SEPARATOR_READ_MSGS ); + } + else + { + separatorText = StringLoader::LoadLC(R_FREESTYLE_EMAIL_UI_SEPARATOR_UNREAD_MSGS); + } + } + break; + case EFSMailSortBySubject: + { + separatorText = TFsEmailUiUtility::CreateSubjectWithoutLocalisedPrefixLC( &aMessage ); + } + break; + case EFSMailSortByDate: + { + TBool eventToday = EFalse; + TBool eventYesterday = EFalse; + HBufC* weekDay = TFsEmailUiUtility::WeekDayTextFromMsgLC( &aMessage, ETrue, EFalse, eventToday, eventYesterday ); + if ( eventToday || eventYesterday ) + { + separatorText = weekDay; + } + else + { + HBufC* dateTextFromMsg = TFsEmailUiUtility::DateTextFromMsgLC( &aMessage ); + separatorText = HBufC::NewL( weekDay->Length() + + KSpace().Length() + + dateTextFromMsg->Length() ); + separatorText->Des().Append( *weekDay ); + separatorText->Des().Append( KSpace ); + separatorText->Des().Append( *dateTextFromMsg ); + CleanupStack::PopAndDestroy( dateTextFromMsg ); + CleanupStack::PopAndDestroy( weekDay ); + CleanupStack::PushL( separatorText ); + } + } + break; + default: + { + separatorText = KNullDesC().AllocLC(); + } + break; + } + + separator->SetSeparatorTextL( *separatorText ); + CleanupStack::PopAndDestroy( separatorText ); + + return separator; + } + +// --------------------------------------------------------------------------- +// MessagesBelongUnderSameSeparatorL +// Checks if the given messages belong under the same title divider. This +// depends on the currect sorting mode. +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::MessagesBelongUnderSameSeparatorL( + const CFSMailMessage& aMessage1, + const CFSMailMessage& aMessage2 ) const + { + FUNC_LOG; + return CFSEmailUiMailListModel::MessagesBelongUnderSameSeparatorL( aMessage1, + aMessage2, + iCurrentSortCriteria.iField ); + } + +// --------------------------------------------------------------------------- +// InsertNewMessagesL +// Gets new message items from the framework using the given IDs and inserts +// them in the correct place within the mail list. Both model and tree list +// are updated during this function. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::InsertNewMessagesL( const RArray& aMessages ) + { + FUNC_LOG; + iModel->SetSortCriteria( iCurrentSortCriteria ); + + // Do complete refresh in case the list is not currently correctly ordered + // (alternatively, we could first reorder the existing items and then insert + // the new ones) + if ( iListOrderMayBeOutOfDate ) + { + if ( iMailListUpdater ) + { + if ( iMailListUpdater->IsActive() ) + { + iMailListUpdater->Stop(); + } + iMailListUpdater->StartL(); + } + } + // Otherwise, just add the new items to correct places. + else + { + // Set extended status before inserting messages + SetMailListItemsExtendedL(); + TInt count(0); + count = aMessages.Count(); + + for ( TInt i = 0 ; i < count ; ++i ) + { + // Make sure we don't add duplicate items. + TInt existingIdx = ItemIndexFromMessageId( aMessages[i] ); + if ( existingIdx < 0 ) + { + iNewMailIds.Append( aMessages[ i ] ); + } + } + + // start timer only when all conditions are met: + // timer isn`t already active + // there are new mails in the array + // timer event isn`t processing + // sorting timer isn't running + if ( !iNewMailTimer->IsActive() && iNewMailIds.Count() && + iNewMailTimer->iStatus != KErrInUse && iSortState == ESortNone ) + { + iNewMailTimer->Start( KNewMailTimerDelay ); + } + } + } + + +// --------------------------------------------------------------------------- +// TimerEventL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::TimerEventL( CFSEmailUiGenericTimer* aTriggeredTimer ) + { + + if( aTriggeredTimer == iSortTimer ) + { + switch ( iSortState ) + { + case ESortNone: + { + iSortTryCount = 0; + iSortState = ESortRequested; + break; + } + case ESortRequested: + { + if( !iNewMailTimer->IsActive() && iNewMailTimer->iStatus != KErrInUse ) + { + // Size sorting does not use nodes, so disable those, otherwise check from CR + iNodesInUse = iAppUi.GetCRHandler()->TitleDividers(); + SetSortButtonTextAndIconL(); + + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + iControlBarControl->SetFocusByIdL( iSortButtonId ); + + SortMailListModelAsyncL(); // sort can take long time + SetMskL(); + iSortState = ESortStarted; + } + else + { + iSortTryCount = 0; + iSortState = ESortPostponed; + iNewMailTimer->Stop(); // stop mail timer + } + break; + } + case ESortPostponed: + { + if ( !iNewMailTimer->IsActive() && iNewMailTimer->iStatus != KErrInUse ) + { + iSortState = ESortRequested; // start request again + } + else + { + iSortTryCount++; + } + if( iSortTryCount >= KSortCountdown )// repeat a few times + { + iSortTryCount = 0; // reset + iSortState = ESortStartError; // can't start sorting some error + } + break; + } + case ESortStarted: + { + if ( !iSortWaitNote )// it will restart the timer elsewhere (see below) + { + iSortState = ESortCompleted; + } + break; + } + case ESortStartError: + case ESortCompleted: + { + if( !iNewMailTimer->IsActive() ) + { + // refresh the whole mail list if list was sorted + if(iSortState != ESortStartError ) + { + RefreshL(); + } + // stop sorting process + iSortState = ESortNone; + iSortTimer->Stop(); + // restart if more messages available + if ( iNewMailIds.Count() ) + { + iNewMailTimer->Start( KNewMailTimerDelay ); + } + return; + } + iNewMailTimer->Stop(); + break; + } + default : + { + // do nothing + } + } + // start timer again + if ( !iSortTimer->IsActive() ) + { + iSortTimer->Start( KSortTimerDelay ); + } + } + + if( aTriggeredTimer == iNewMailTimer ) + { + TInt count = Min( KNewMailMaxBatch, iNewMailIds.Count() ); + CFSMailClient* mailClient = iAppUi.GetMailClient(); + + // Enter critical section + // Because CFSMailClient::GetMessageByUidL can use CActiveSchedulerWait + // to ensure that only one TimerEventL method is processed at time + // CFSEmailUiGenericTimer`s iStatus will be used as mutex + iNewMailTimer->iStatus = KErrInUse; + iModel->SetSortCriteria(iCurrentSortCriteria); + + for ( TInt i = 0; i < count; i++ ) + { + // stop synchronization if mail list is being sorted + if( iSortState != ESortNone || iSortWaitNote ) + { + iNewMailTimer->iStatus = KErrNone; + iNewMailTimer->Stop(); + return; // leave method + } + + CFSMailMessage* msgPtr = mailClient->GetMessageByUidL( iAppUi.GetActiveMailboxId(), + iMailFolder->GetFolderId(), + iNewMailIds[ 0 ], + EFSMsgDataEnvelope ); + if ( msgPtr != NULL ) + { + __ASSERT_DEBUG( FolderId() == msgPtr->GetFolderId(), User::Invariant() ); + CleanupStack::PushL( msgPtr ); + //first item - show scrollbar + //last item - update scrollbar + TBool allowRefresh = ( i == 0 || i == count - 1 ); + InsertNewMessageL( msgPtr, allowRefresh ); + CleanupStack::Pop( msgPtr ); // ownership transferred to model + } + // pop processed id from the queue, this is single thread operation + iNewMailIds.Remove( 0 ); + } + + // End critical section + iNewMailTimer->iStatus = KErrNone; + + // if timer stoped then restart if more messages available + if ( iNewMailIds.Count() && ! iNewMailTimer->IsActive() && iSortState == ESortNone ) + { + iNewMailTimer->Start( KNewMailTimerDelay ); + } + }//iNewMailTimer + } + +// --------------------------------------------------------------------------- +// InsertNewMessageL +// Creates a single new message item to the model and tree list from the given +// message pointer. Ownership of the message is transferred. Also new +// separator item is created if necessary. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::InsertNewMessageL( CFSMailMessage* aNewMessage, const TBool aAllowRefresh ) + { + FUNC_LOG; + // Use simple heuristic rule: if the first item is highlighted before the new + // item is added, the highlight is forced to remain on the (possibly new) first + // item. Otherwise the highligh stays on the same item as before. + TBool firstItemWasFocused = + ( iTreeItemArray.Count() && iTreeItemArray[0].iListItemId == iMailList->FocusedItem() ); + + CFSEmailUiMailListModelItem* newItem = + CFSEmailUiMailListModelItem::NewLC( aNewMessage, ETypeMailItem ); + TInt idx = KErrNotFound; + TFsTreeItemId parentId = KFsTreeRootID; + TInt childIdx = KErrNotFound; + TInt moveViewPortPosition = 0; + + if ( !iNodesInUse ) + { + // Simple case: nodes are not in use. Just insert to correct place under root node. + idx = iModel->GetInsertionPointL( *newItem ); + childIdx = idx; + } + else + { + // More complicated case: nodes are in use. + TInt parentIdx = KErrNotFound; + idx = iModel->GetInsertionPointL( *newItem, childIdx, parentIdx ); + + CFSEmailUiMailListModelItem* parentNode = NULL; + if ( parentIdx < 0 ) + { + // Suitable parent node for the new item was not found and has to be created. + parentNode = CreateSeparatorModelItemLC( *aNewMessage ); + iModel->InsertL( parentNode, idx ); + CleanupStack::Pop( parentNode ); + idx++; // The originally found index was used for the new node and the new item will reside in the next index + + // To insert the node item to the tree list, we need to figure out the index of the + // new node under the root node. If the new item is not the last item in the list, + // then the insertion location currently contains the node in front of which the new + // node is inserted. + if ( idx == iModel->Count() ) + { + InsertNodeItemL( idx-1, KErrNotFound, aAllowRefresh ); // append + } + else + { + CFSEmailUiMailListModelItem* nextNode = + static_cast( iModel->Item(idx) ); + TFsTreeItemId nextNodeId = nextNode->CorrespondingListId(); + TInt nodeIdxUnderRoot = iMailList->ChildIndex( KFsTreeRootID, nextNodeId ); + InsertNodeItemL( idx-1, nodeIdxUnderRoot, aAllowRefresh ); + } + moveViewPortPosition += iAppUi.LayoutHandler()->OneLineListItemHeight(); + } + else + { + // Suitable parent node exists and was found + parentNode = static_cast( iModel->Item(parentIdx) ); + } + parentId = parentNode->CorrespondingListId(); + } + + // Insert the model item + iModel->InsertL( newItem, idx ); + CleanupStack::Pop( newItem ); + + // Insert the tree list item + TPoint viewPortCenterPos = iMailTreeListVisualizer->ViewPosition(); + TPoint viewPortTopPos = iMailTreeListVisualizer->ViewPortTopPosition(); + TInt itemPos = iMailTreeListVisualizer->GetItemWorldPosition( idx ); + TBool refresh = viewPortTopPos.iY != 0 && itemPos < viewPortCenterPos.iY; + + if( refresh ) + { + InsertListItemL( idx, parentId, childIdx, EFalse ); + // viewPort update needed + moveViewPortPosition += iAppUi.LayoutHandler()->TwoLineListItemHeight(); // add mail item height + viewPortCenterPos.iY += moveViewPortPosition; + iMailTreeListVisualizer->ViewPositionChanged( viewPortCenterPos, EFalse, 1 ); + } + else + { + InsertListItemL( idx, parentId, childIdx, aAllowRefresh ); + } + + // Move focus after insertion if necessary + if ( firstItemWasFocused ) + { + TFsTreeItemId firstItemId = iMailList->Child( KFsTreeRootID, 0 ); + TFsTreeItemId focusedId = iMailList->FocusedItem(); + + if ( firstItemId != focusedId ) + { + // Set the first item as focused and set + // list/ctrl bar focus according iFocusedControl + // + //iMailList->SetFocusedItemL( firstItemId ); + iMailTreeListVisualizer->SetFocusedItemL( firstItemId, EFalse ); + // + SetListAndCtrlBarFocusL(); + } + } + } + +// --------------------------------------------------------------------------- +// HighlightedIndex +// This function return highlighted inxed +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::HighlightedIndex() const + { + FUNC_LOG; + TFsTreeItemId focusedId = static_cast( iMailList->FocusedItem() ); + // Map id to the index in model + TInt ret( KErrNotFound ); + if ( focusedId != KFsTreeNoneID ) + { + for ( TInt i=0; i= 0 ) + { + iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[aWantedIndex].iListItemId ); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::NewEmailsInModelL() const + { + FUNC_LOG; + // + TInt newCount(0); + for ( TInt i=0; iCount();i++) + { + CFSEmailUiMailListModelItem* item = + static_cast(iModel->Item(i)); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + if ( !item->MessagePtr().IsFlagSet(EFSMsgFlag_Read) ) + { + newCount++; + } + } + } + return newCount; + // + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::EmailsInModelL() const + { + FUNC_LOG; + // + TInt ret(0); + for ( TInt i=0; iCount(); i++ ) + { + CFSEmailUiMailListModelItem* item = + static_cast(iModel->Item(i)); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + ret++; + } + } + return ret; + // + } + + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TUid CFSEmailUiMailListVisualiser::Id() const + { + FUNC_LOG; + return MailListId; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ChildDoActivateL(const TVwsViewId& aPrevViewId, + TUid aCustomMessageId, + const TDesC8& aCustomMessage) + { + FUNC_LOG; + TIMESTAMP( "Opening message list view" ); + + if (iMarkingModeWaitingToExit) + { + if ( iAppUi.CurrentActiveView()->Id() == MailListId ) + { + iMarkingModeWaitingToExit = EFalse; + TRAP_IGNORE( ExitMarkingModeL() ); + } + } + + iShowReplyAll = EFalse; + + if ( !iFirstStartCompleted ) + { + DoFirstStartL(); + } + // set when editor was called so reset is needed i.e. here (Called by DoActivate) + iMailOpened = EFalse; + + // Make sure that pending popup is not displayd + if ( iAppUi.FolderList().IsPopupShown() ) + { + iAppUi.FolderList().HidePopupL(); + } + DisableMailList( EFalse ); + + // inform baseView if view entered with forward navigation + TBool forwardNavigation = EFalse; + if ( aCustomMessageId != KStartListReturnToPreviousFolder && + aCustomMessageId != TUid::Uid(KMailSettingsReturnFromPluginSettings) ) + { + ViewEntered( aPrevViewId ); + forwardNavigation = ETrue; + } + + if( iAppUi.CurrentFixedToolbar() ) + { + iAppUi.CurrentFixedToolbar()->SetToolbarVisibility( EFalse ); + } + + // Set control bar and list layout size always in activation + TRect clientRect = iAppUi.ClientRect(); + iScreenAnchorLayout->SetSize( clientRect.Size() ); + SetMailListLayoutAnchors(); + //if the view is already active don't update the icons so they won't "blink" + //when the view is activated. + if(!iThisViewActive) + { + ScaleControlBarL(); + + // Set icons on toolbar + iAppUi.FsTextureManager()->ClearTextureByIndex( EListControlBarMailboxDefaultIcon ); + iFolderListButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListControlBarMailboxDefaultIcon ) ); + iAppUi.FsTextureManager()->ClearTextureByIndex( EListTextureCreateNewMessageIcon ); + iNewEmailButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListTextureCreateNewMessageIcon ) ); + iAppUi.FsTextureManager()->ClearTextureByIndex( GetSortButtonTextureIndex() ); + iSortButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( GetSortButtonTextureIndex() ) ); + + SetListAndCtrlBarFocusL(); + } + + FadeOut(EFalse); // we can show now CAlfVisuals from CurrentView (to show Folders before updating emails) + + // Update mail list settings and date formats, is done every time + // the user might have changed these in settings, so the list needs to refresh + // Store previous modes + TInt prevListMode = iListMode; + TInt prevNodesmode = iNodesInUse; + TAknUiZoom prevZoomLevel = iCurrentZoomLevel; + STimeDateFormats prevDateFormats = MailListTimeDateSettings(); + + // Get new settings and list drawing modes + CAknEnv::Static()->GetCurrentGlobalUiZoom( iCurrentZoomLevel ); + UpdateMailListSettingsL(); + UpdateMailListTimeDateSettings(); + + // Check for changed settings, in that case a complete list refresh is needed + TRefreshState refreshState = ERefreshNone; + if (aCustomMessageId == KStartListWithFolderIdFromHomeScreen) + { + refreshState = EFocusChangeNeeded; + } + + if ( iSkinChanged + || iDateChanged + || iListMode != prevListMode + || iNodesInUse != prevNodesmode + || iCurrentZoomLevel != prevZoomLevel + || prevDateFormats.iDateFormat != iDateFormats.iDateFormat + || prevDateFormats.iTimeFormat != iDateFormats.iTimeFormat + || prevDateFormats.iAmPmPosition != iDateFormats.iAmPmPosition + || prevDateFormats.iDateSeparator.GetNumericValue() != iDateFormats.iDateSeparator.GetNumericValue() + || prevDateFormats.iTimeSeparator.GetNumericValue() != iDateFormats.iTimeSeparator.GetNumericValue() ) + { + refreshState = EFullRefreshNeeded; + iSkinChanged = EFalse; + iDateChanged = EFalse; + } + + // Store previously used mailbox and folder IDs + TFSMailMsgId prevMailBoxId = iAppUi.GetActiveMailboxId(); + TFSMailMsgId prevFolderId = FolderId(); + + CFSMailClient* mailClient = iAppUi.GetMailClient(); + User::LeaveIfNull( mailClient ); // we can't go on if no mail client is available + + // FIGURE OUT WHICH FOLDER TO ACTIVATE + TMailListActivationData activationData; + + // Opening folder given in custom message + if ( aCustomMessage.Length() ) + { + TPckgBuf viewData; + viewData.Copy( aCustomMessage ); + activationData = viewData(); + } + + // Returning to previous folder + if ( aCustomMessageId == KStartListReturnToPreviousFolder || + aCustomMessageId == TUid::Uid(KMailSettingsReturnFromPluginSettings) ) + { + activationData.iMailBoxId = prevMailBoxId; + activationData.iFolderId = prevFolderId; + } + + // Proper mailbox ID is not given in custom message. Try using MSV session. + if ( activationData.iMailBoxId.IsNullId() ) + { + CMsvSession* msvSession = iAppUi.GetMsvSession(); + CFSMailBox* mailBox = NULL; + + if ( msvSession ) + { + // MSV id is passed to us in aCustomMessageId when activation happens by email key + if ( aCustomMessageId != TUid::Null() ) + { + // + TInt error = KErrNone; + TRAP( error, mailBox = TFsEmailUiUtility::GetMailboxForMtmIdL( *mailClient, *msvSession, aCustomMessageId.iUid ) ); + // + if ( mailBox ) + { + activationData.iMailBoxId = mailBox->GetId(); + delete mailBox; + mailBox = NULL; + } + } + + // Try to get MCE default mailbox if we still haven't got any other box + if ( activationData.iMailBoxId.IsNullId() ) + { + // + TInt error = KErrNone; + TRAP( error, mailBox = TFsEmailUiUtility::GetMceDefaultMailboxL( *mailClient, *msvSession ) ); + // + if ( mailBox ) + { + activationData.iMailBoxId = mailBox->GetId(); + delete mailBox; + mailBox = NULL; + } + } + } + + } + + // If still no mailbox then use first from the list of the framework + if ( activationData.iMailBoxId.IsNullId() ) + { + TFSMailMsgId id; + RPointerArray mailboxes; + CleanupResetAndDestroyClosePushL( mailboxes ); + mailClient->ListMailBoxes( id, mailboxes ); + if ( mailboxes.Count() > 0 ) + { + activationData.iMailBoxId = mailboxes[0]->GetId(); + } + CleanupStack::PopAndDestroy( &mailboxes ); + } + + + // Check if we got any mailbox + if ( activationData.iMailBoxId.IsNullId() ) + { + // could not get mailbox so leave + User::Leave( KErrGeneral ); + } + else + { + // Set the active mailbox of AppUi. Do this also when mailbox hasn't actually + // changed to do the autoconnect when necessary and to verify that the previously + // active mailbox is still valid. + // Leave is caused if mailbox is no longer available, and BaseView will take care + // of the error handling. + iAppUi.SetActiveMailboxL( activationData.iMailBoxId, forwardNavigation ); + + // we got mailbox but no folder has been given => use Inbox + if ( activationData.iFolderId.IsNullId() || + activationData.iFolderId.Id() == 0 ) + { + activationData.iFolderId = iAppUi.GetActiveBoxInboxId(); + } + } + + // NOW WE HAVE A VALID MAILBOX AND FOLDER ID. + // Tries to create an extension for the Ozone plugin + CreateExtensionL(); + + // if mailbox changed stop timer driven insertion of new mails into list + if ( activationData.iMailBoxId != prevMailBoxId ) + { + iNewMailTimer->Cancel(); + iSortTimer->Cancel(); // stop sorting timer + iNewMailIds.Reset(); + } + + // CHECK IF MODEL NEEDS TO BE UPDATED + if ( activationData.iMailBoxId != prevMailBoxId || + activationData.iFolderId != prevFolderId || + activationData.iRequestRefresh || + iForceRefresh ) + { + iForceRefresh = EFalse; + // Set initial sort criteria when folder is changed + iCurrentSortCriteria.iField = EFSMailSortByDate; + iCurrentSortCriteria.iOrder = EFSMailDescending; + SetSortButtonTextAndIconL(); + + SafeDelete(iMailFolder); + TRAP_IGNORE( iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( + activationData.iMailBoxId, activationData.iFolderId ) ); + if ( !iMailFolder ) + { + if ( forwardNavigation ) + { + iAppUi.StartMonitoringL(); + } + // Safety, try to revert back to standard folder inbox + TFSMailMsgId inboxId = iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSInbox ); + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( activationData.iMailBoxId, inboxId ); + } + HBufC* newFolderName = CreateFolderNameLC( iMailFolder ); + iFolderListButton->SetTextL( *newFolderName ); + CleanupStack::PopAndDestroy( newFolderName ); + iMailList->SetFocusedItemL( KFsTreeNoneID ); + refreshState = EFullRefreshNeeded; + } + + // Set mailbox name to status pane + SetMailboxNameToStatusPaneL(); + + // Set branded watermark and mailbox icon + SetBrandedListWatermarkL(); + SetBrandedMailBoxIconL(); + + // Check sync icon timer and sync status + ConnectionIconHandling(); + + // REBUILD TREE LIST IF NECESSARY + if ( refreshState == EFullRefreshNeeded ) + { + // Try to maintain previously active item if possible. + // This is of course not possible if folder has changed. + TFSMailMsgId focused = MsgIdFromListId( iMailList->FocusedItem() ); + + // Clear any previous items from the screen and then make the view visible + iMailList->BeginUpdate(); + iMailList->RemoveAllL(); + iTreeItemArray.Reset(); + iModel->Reset(); + iMailList->EndUpdateL(); + iMailList->ShowListL(); + + // If coming from wizard use synchronous list updating + if (activationData.iReturnAfterWizard) + { + UpdateMailListModelL(); + } + else + { + UpdateMailListModelAsyncL( KCMsgBlockSort ); + } + } + else if(refreshState == EFocusChangeNeeded) + {//Move focus to the beginning of the list + TInt firstIndex(0); + TFsTreeItemId firstItemId(KFsTreeNoneID); + if ( iMailList->CountChildren( KFsTreeRootID ) ) + { + firstItemId = iMailList->Child( KFsTreeRootID, firstIndex ); + } + iMailTreeListVisualizer->SetFocusedItemL( firstItemId, EFalse ); + //if the view is already active don't update the list so it won't "blink" + //when the view is activated. + if(!iThisViewActive) + { + iMailList->ShowListL(); + } + } + // THE CORRECT FOLDER IS ALREADY OPEN. CHECK IF SOME PARTIAL UPDATE IS NEEDED. + else + { + iMailList->ShowListL(); + TBool manualSync = CheckAutoSyncSettingL(); + if (forwardNavigation && !manualSync) + { + iAppUi.StartMonitoringL(); + } + SetListAndCtrlBarFocusL(); // ShowListL() makes list focused and this may need to be reverted + if ( aCustomMessageId == TUid::Uid(KMailSettingsReturnFromPluginSettings) ) + { + // Better to refresh launcher grid view because mailbox branding might be changed. + iAppUi.LauncherGrid().SetRefreshNeeded(); + } + // Check the validity of focused message, it may be deleted or + // reply/forward, read/unread status might have changed in editor or viewer + UpdateItemAtIndexL( HighlightedIndex() ); + SetMskL(); + } + + iCurrentClientRect = clientRect; + iThisViewActive = ETrue; + + //emailindicator handling, is removed from 9.2 + //TRAP_IGNORE(TFsEmailStatusPaneIndicatorHandler::StatusPaneMailIndicatorHandlingL( activationData.iMailBoxId.Id())); + + //Update mailbox widget index status in homescreen + TFsEmailUiUtility::ToggleEmailIconL(EFalse, activationData.iMailBoxId ); + + iShiftDepressed = EFalse; // clear state just in case + + // Inform MR observer if needed, special MR case, returning from attachment list + iAppUi.MailViewer().CompletePendingMrCommand(); + + // Make sure that correct component is set to focused. + if ( iFocusedControl == EMailListComponent ) + { + SetTreeListFocusedL(); + } + else + { + SetControlBarFocusedL(); + iControlBarControl->MakeSelectorVisible( iAppUi.IsFocusShown() ); + } + UpdateButtonTextsL(); + FocusVisibilityChange( iAppUi.IsFocusShown() ); + iAppUi.ShowTitlePaneConnectionStatus(); + TIMESTAMP( "Message list view opened" ); + } + +// --------------------------------------------------------------------------- +// Sets status bar layout +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetStatusBarLayout() + { + TInt res = R_AVKON_STATUS_PANE_LAYOUT_USUAL_FLAT; + if( Layout_Meta_Data::IsLandscapeOrientation() ) + { + // landscape must use different layout + res = R_AVKON_STATUS_PANE_LAYOUT_USUAL_EXT; + } + + if ( StatusPane()->CurrentLayoutResId() != res ) + { + TRAP_IGNORE( + StatusPane()->SwitchLayoutL( res )); + } + } + + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ChildDoDeactivate() + { + FUNC_LOG; + if (iMailListModelUpdater) + { + iMailListModelUpdater->Cancel(); + } + if ( !iAppUi.AppUiExitOngoing() ) + { + TRAP_IGNORE( { + iMailList->HideListL(); + iMailList->SetFocusedL( EFalse ); + } ); + iMailTreeListVisualizer->NotifyControlVisibilityChange( EFalse ); + } + iThisViewActive = EFalse; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +CFSEmailUiMailListModel* CFSEmailUiMailListVisualiser::Model() + { + FUNC_LOG; + return iModel; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TFSMailMsgId CFSEmailUiMailListVisualiser::FolderId() + { + FUNC_LOG; + TFSMailMsgId folderId; // constructs null ID + if ( iMailFolder ) + { + folderId = iMailFolder->GetFolderId(); + } + return folderId; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane) + { + FUNC_LOG; + CompletePendingRefresh(); + + // Get the list of items which will be targetted by the actions menu commands + RFsTreeItemIdList targetEntries; + CleanupClosePushL( targetEntries ); + GetActionsTargetEntriesL( targetEntries ); + + TBool supportsMoving = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder ); + TBool supportsFlag = TFsEmailUiUtility::IsFollowUpSupported( *iAppUi.GetActiveMailbox() ); + + TInt currentFolderType = KErrNotFound; + if ( iMailFolder ) + { + currentFolderType = iMailFolder->GetFolderType(); + } + + if ( aResourceId == R_FSEMAILUI_MAILLIST_MARKING_MODE_MENUPANE ) + { + if (!CountMarkedItemsL()) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeDelete, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnread, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeRead, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeMove, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeFollowUp, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeMarkAll, EFalse ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnmarkAll, ETrue ); + } + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeDelete, EFalse ); + if ( AreAllMarkedItemsUnreadL() ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnread, ETrue ); + } + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnread, EFalse ); + } + if ( AreAllMarkedItemsReadL() ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeRead, ETrue ); + } + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeRead, EFalse ); + } + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeMove, !supportsMoving ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeFollowUp, !supportsFlag ); + if ( AreAllItemsMarked() ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeMarkAll, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnmarkAll, EFalse ); + } + else if ( AreAllItemsUnmarked() ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeMarkAll, EFalse ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnmarkAll, ETrue ); + } + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeMarkAll, EFalse ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingModeUnmarkAll, EFalse ); + } + } + } + + // MAIN MENU *************************************************************************** + if ( aResourceId == R_FSEMAILUI_MAILLIST_MENUPANE ) + { + // Saves a focus visibility. + iLastFocus = EFalse; + if( iFocusedControl == EMailListComponent && IsFocusShown() ) + { + iLastFocus = ETrue; + } + if (FeatureManager::FeatureSupported( KFeatureIdFfCmailIntegration )) + { + // remove help support in pf5250 + aMenuPane->SetItemDimmed( EFsEmailUiCmdHelp, ETrue); + } + + // Checks if a device has a keyboard or not. + if( !iLastFocus ) + { + // Hide all the normal email message specific actions + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReply, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMailActions, ETrue); + } + else + { + CFSMailMessage* targetMessage = NULL; + if ( targetEntries.Count() == 1 ) + { + targetMessage = &MsgPtrFromListIdL( targetEntries[0] ); + } + + // Hide the irrelevant reply / reply all / forward commands + TInt numRecipients(0); + if ( targetMessage ) + { + //Get # of recipients + numRecipients = TFsEmailUiUtility::CountRecipientsSmart( iAppUi, targetMessage ); + } + // All reply/forward options are hidden when multiple marked messages or folder is outbox or drafts + if ( targetEntries.Count() != 1 || + currentFolderType == EFSOutbox || + currentFolderType == EFSDraftsFolder ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReply, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsForward, ETrue ); + } + + // Reply all is hidden also when the single target message has multiple recipients + else if ( !targetMessage || numRecipients <= 1 ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsReplyAll, ETrue ); + } + } + + // EMPTY LIST, MOST OPTIONS ARE HIDDEN + if ( !iModel->Count() || !iMailFolder ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdMailActions, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdSearch, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkingMode, ETrue ); + } + + // FOLDER SPECIFIC COMMAND HIDING + // "Clear deleted folder" command is available only in Deleted folder + if ( currentFolderType != EFSDeleted || !iModel->Count() ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsEmptyDeleted, ETrue ); + } + + CConnectionStatusQueryExtension::TConnectionStatus connetionStatus; + iAppUi.GetConnectionStatusL( connetionStatus ); + if ( connetionStatus == CConnectionStatusQueryExtension::ESynchronizing ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdSync, ETrue ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelSync, EFalse ); + } + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdSync, EFalse ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdCancelSync, ETrue ); + } + } + + // MAIN MENU *************************************************************************** + + + // ACTIONS SUBMENU ********************************************************************* + if ( aResourceId == R_FSEMAILUI_MAILLIST_SUBMENU_MAIL_ACTIONS ) + { + // COMMON PART OF ACTIONS SUBMENU + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsRead, !IsMarkAsReadAvailableL() ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, !IsMarkAsUnreadAvailableL() ); + + if ( !supportsMoving || !iMailFolder ) // Hide move from actions if not supported + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMove, ETrue ); + } + else + { + // Moving supported, show/hide moving options depending on the current folder + // Check for outbox case + if ( currentFolderType == EFSOutbox ) + { + // moving from outbox is not allowed otherwise + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMove, ETrue ); + } + // Handle rest of the folders + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsMove, EFalse ); + } + } + + TInt markedCount = CountMarkedItemsL(); + + // Hide expand/collapse all when not applicable + if ( iNodesInUse == EListControlSeparatorDisabled || !iModel->Count() ) + { + aMenuPane->SetItemDimmed(EFsEmailUiCmdActionsCollapseAll, ETrue); + aMenuPane->SetItemDimmed(EFsEmailUiCmdActionsExpandAll, ETrue); + } + else + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, AllNodesCollapsed() ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, AllNodesExpanded() ); + } + + // Hide followup flagging if not applicable + if ( !supportsFlag || !targetEntries.Count() ) + { + aMenuPane->SetItemDimmed(EFsEmailUiCmdActionsFlag, ETrue); + } + + // Some commands are hidden in the outbox and drafts folders + if ( currentFolderType == EFSOutbox || + currentFolderType == EFSDraftsFolder ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsFlag, ETrue ); + } + } + // ACTIONS SUBMENU ********************************************************************* + + CleanupStack::PopAndDestroy( &targetEntries ); + + // Add shortcut hints + iAppUi.ShortcutBinding().AppendShortcutHintsL( *aMenuPane, + CFSEmailUiShortcutBinding::EContextMailList ); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::MarkAllItemsL() + { + FUNC_LOG; + if ( iTreeItemArray.Count() ) + { + for ( TInt i=0;iIsNode(iTreeItemArray[i].iListItemId ) ) + { + iMailList->MarkItemL( iTreeItemArray[i].iListItemId, ETrue ); + } + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UnmarkAllItemsL() + { + FUNC_LOG; + for ( TInt i=0 ; iIsNode(iTreeItemArray[i].iListItemId) ) + { + iMailList->MarkItemL( iTreeItemArray[i].iListItemId, EFalse ); + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::CountMarkedItemsL() + { + FUNC_LOG; + RFsTreeItemIdList markedEntries; + CleanupClosePushL( markedEntries ); + iMailList->GetMarkedItemsL( markedEntries ); + TInt count = markedEntries.Count(); + CleanupStack::PopAndDestroy( &markedEntries ); + return count; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::AreAllItemsMarked() + { + FUNC_LOG; + + TBool ret(ETrue); + + if ( iTreeItemArray.Count() ) + { + for ( TInt i=0;iIsNode(iTreeItemArray[i].iListItemId ) && + !iMailList->IsMarked( iTreeItemArray[i].iListItemId )) + { + ret = EFalse; + break; + } + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::AreAllItemsUnmarked() + { + FUNC_LOG; + + TBool ret(ETrue); + + if ( iTreeItemArray.Count() ) + { + for ( TInt i=0;iIsNode(iTreeItemArray[i].iListItemId ) && + iMailList->IsMarked( iTreeItemArray[i].iListItemId )) + { + ret = EFalse; + break; + } + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::AreAllMarkedItemsReadL() + { + FUNC_LOG; + + TBool ret(ETrue); + + if ( iTreeItemArray.Count() ) + { + for ( TInt i=0;iIsNode(iTreeItemArray[i].iListItemId ) && + iMailList->IsMarked( iTreeItemArray[i].iListItemId )) + { + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item(i) ); + if ( item ) // Safety + { + CFSMailMessage* confirmedMsgPtr(0); + confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL(iAppUi.GetActiveMailboxId(), + iMailFolder->GetFolderId(), item->MessagePtr().GetMessageId(), EFSMsgDataEnvelope ); + TBool isReadMessage = confirmedMsgPtr->IsFlagSet( EFSMsgFlag_Read ); + delete confirmedMsgPtr; + if ( !isReadMessage ) + { + ret = EFalse; + break; + } + } + } + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::AreAllMarkedItemsUnreadL() + { + FUNC_LOG; + + TBool ret(ETrue); + + if ( iTreeItemArray.Count() ) + { + for ( TInt i=0;iIsNode(iTreeItemArray[i].iListItemId ) && + iMailList->IsMarked( iTreeItemArray[i].iListItemId )) + { + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item(i) ); + if ( item ) // Safety + { + CFSMailMessage* confirmedMsgPtr(0); + confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL(iAppUi.GetActiveMailboxId(), + iMailFolder->GetFolderId(), item->MessagePtr().GetMessageId(), EFSMsgDataEnvelope ); + TBool isReadMessage = confirmedMsgPtr->IsFlagSet( EFSMsgFlag_Read ); + delete confirmedMsgPtr; + if ( isReadMessage ) + { + ret = EFalse; + break; + } + } + } + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::GetMarkedMessagesL( RArray& aMessageIDs ) const + { + FUNC_LOG; + aMessageIDs.Reset(); + + RFsTreeItemIdList markedEntries; + CleanupClosePushL( markedEntries ); + iMailList->GetMarkedItemsL( markedEntries ); + + for ( TInt i=0 ; i& aMessageIDs ) + { + FUNC_LOG; + for ( TInt i=0 ; i= 0 ) + { + iMailList->MarkItemL( iTreeItemArray[index].iListItemId, ETrue ); + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ExitMarkingModeL() + { + FUNC_LOG; + // Hide marking mode text on the place of drop down menus + RemoveMarkingModeTitleTextL(); + iMarkingMode = EFalse; + UnmarkAllItemsL(); + // Change softkeys back to normal + SetViewSoftkeysL( R_FREESTYLE_EMAUIL_UI_SK_OPTIONS_BACK ); + // Change options menu back to normal + CEikMenuBar* menu = iAppUi.CurrentActiveView()->MenuBar(); + menu->StopDisplayingMenuBar(); + menu->SetMenuTitleResourceId(R_FSEMAILUI_MAILLIST_MENUBAR); + // Change background back to normal + DisplayMarkingModeBgL( EFalse ); + // Display drop down menu buttons + iControlBarControl->SetRectL( iAppUi.LayoutHandler()->GetControlBarRect() ); + iNewEmailButton->SetDimmed( EFalse ); + iFolderListButton->SetDimmed( EFalse ); + iSortButton->SetDimmed( EFalse ); + ScaleControlBarL(); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::EnterMarkingModeL() + { + FUNC_LOG; + iMarkingMode = ETrue; + iListMarkItemsState = ETrue; // shift-scrolling does marking after one item is marked + HandleCommandL( EFsEmailUiCmdActionsExpandAll ); + // Change softkeys for marking mode + SetViewSoftkeysL( R_FREESTYLE_EMAUIL_UI_SK_OPTIONS_CANCEL ); + // Change options menu for marking mode + CEikMenuBar* menu = iAppUi.CurrentActiveView()->MenuBar(); + menu->StopDisplayingMenuBar(); + menu->SetMenuTitleResourceId(R_FSEMAILUI_MAILLIST_MENUBAR_MARKING_MODE); + // Change background to marking mode + DisplayMarkingModeBgL( ETrue ); + // Hide drop down menu buttons + iNewEmailButton->SetDimmed(); + iFolderListButton->SetDimmed(); + iSortButton->SetDimmed(); + if( !Layout_Meta_Data::IsLandscapeOrientation() ) + { + TRect rect(0,0,0,0); + iControlBarControl->SetRectL( rect ); + // Display marking mode text on the place of drop down menus + DisplayMarkingModeTitleTextL(); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RefreshMarkingModeL() + { + FUNC_LOG; + if ( iMarkingMode ) + { + // Hide drop down menu buttons + if( !Layout_Meta_Data::IsLandscapeOrientation() ) + { + TRect rect(0,0,0,0); + iControlBarControl->SetRectL( rect ); + DisplayMarkingModeTitleTextL(); + } + else + { + iControlBarControl->SetRectL( iAppUi.LayoutHandler()->GetControlBarRect() ); + iNewEmailButton->SetDimmed(); + iFolderListButton->SetDimmed(); + iSortButton->SetDimmed(); + RemoveMarkingModeTitleTextL(); + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DisplayMarkingModeTitleTextL() + { + FUNC_LOG; + if (!iMarkingModeTextVisual) + { + const TRect sortButtonRect( iAppUi.LayoutHandler()->GetControlBarSortButtonRect() ); + const TRect newMailButtonRect( iAppUi.LayoutHandler()->GetControlBarNewEmailButtonRect() ); + + iMarkingModeTextRect = TRect( newMailButtonRect.iTl, sortButtonRect.iBr ); + iMarkingModeTextParentLayout = CAlfDeckLayout::AddNewL( *iMailListControl ); + iMarkingModeTextParentLayout->SetFlags( EAlfVisualFlagManualLayout ); + iMarkingModeTextParentLayout->SetRect( iMarkingModeTextRect ); + + iMarkingModeTextContentLayout = CAlfAnchorLayout::AddNewL( *iMailListControl, iMarkingModeTextParentLayout ); + + iMarkingModeTextVisual = CAlfTextVisual::AddNewL( *iMailListControl, iMarkingModeTextContentLayout ); + iMarkingModeTextVisual->SetWrapping( CAlfTextVisual::ELineWrapTruncate ); + if ( AknLayoutUtils::LayoutMirrored() ) + { + iMarkingModeTextVisual->SetAlign( EAlfAlignHRight, EAlfAlignVCenter ); + } + else + { + iMarkingModeTextVisual->SetAlign( EAlfAlignHLeft, EAlfAlignVCenter ); + } + iMarkingModeTextVisual->SetStyle( EAlfTextStyleTitle ); + TRgb color = iAppUi.LayoutHandler()->ListNodeTextColor(); + iMarkingModeTextVisual->SetColor ( color ); + if( !Layout_Meta_Data::IsLandscapeOrientation() ) + { + HBufC* msg = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MARKINGMODE ); + iMarkingModeTextVisual->SetTextL( *msg ); + CleanupStack::PopAndDestroy( msg ); + } + else + { + iMarkingModeTextVisual->SetTextL( KNullDesC ); + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RemoveMarkingModeTitleTextL() + { + FUNC_LOG; + if (iMarkingModeTextVisual) + { + iMarkingModeTextVisual->SetTextL( KNullDesC ); + iMarkingModeTextVisual->RemoveAndDestroyAllD(); + iMarkingModeTextVisual = NULL; + iMarkingModeTextContentLayout->RemoveAndDestroyAllD(); + iMarkingModeTextContentLayout = NULL; + iMarkingModeTextParentLayout->RemoveAndDestroyAllD(); + iMarkingModeTextParentLayout = NULL; + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DisplayMarkingModeBgL( TBool aDisplay ) + { + FUNC_LOG; + if (aDisplay) + { + CAlfBrush* brush = iAppUi.FsTextureManager()->NewMailListMarkingModeBgBrushLC(); + iMailTreeListVisualizer->SetBackgroundBrushL( brush ); + CleanupStack::Pop( brush ); + } + else + { + iMailTreeListVisualizer->ClearBackground(); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RefreshL( TFSMailMsgId* aFocusToMessage ) + { + FUNC_LOG; + iMailList->RemoveAllL(); + iTreeItemArray.Reset(); + + // when we get refresh mail list updates should be fully enabled + iMailOpened = EFalse; + + RefreshListItemsL(); + + if ( !iModel->Count() ) + { + iFocusedControl = EControlBarComponent; + // If focus is not visible, hide selector + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + } + else + { + // Try to keep the previous list item if focused message ptr is given, + // and it's not NULL id + if ( aFocusToMessage && !aFocusToMessage->IsNullId() ) + { + TInt idx = ItemIndexFromMessageId( *aFocusToMessage ); + if ( idx >= 0 ) + { + TFsTreeItemId itemId = iTreeItemArray[idx].iListItemId; + iMailList->SetFocusedItemL( itemId ); + // If contorl bar is focused, we need to hide + // focus then. + if( iFocusedControl == EControlBarComponent ) + { + iMailTreeListVisualizer->UpdateItemL( itemId ); + } + } + } + } + + SetListAndCtrlBarFocusL(); + SetMskL(); + + iListOrderMayBeOutOfDate = EFalse; + } + +void CFSEmailUiMailListVisualiser::RefreshOrderL() + { + FUNC_LOG; + if ( iTreeItemArray.Count() ) + { + TInt itemIdxUnderNode = -1; + TInt nodeIdx = -1; + TFsTreeItemId parentNodeId = KFsTreeRootID; + + //iMailList->HideListL( EFalse, EFalse ); + TFsTreeItemId prevFocus = iMailList->FocusedItem(); + iMailList->SetFocusedItemL( iTreeItemArray[0].iListItemId ); // Try to prevent over indexing in generic list + + // iTreeItemArray is recreated on reordering. + iTreeItemArray.Reset(); + SMailListItem mailListItem; + + for ( TInt i = 0 ; i < iModel->Count() ; ++i ) + { + CFSEmailUiMailListModelItem* item = static_cast( iModel->Item(i) ); + TFsTreeItemId itemId = item->CorrespondingListId(); + + if ( item->ModelItemType() == ETypeSeparator ) + { + nodeIdx++; + itemIdxUnderNode = -1; + parentNodeId = itemId; + if ( iMailList->ChildIndex( itemId, KFsTreeRootID ) != nodeIdx ) + { + iMailList->MoveItemL( itemId, KFsTreeRootID, nodeIdx ); + } + } + else + { + itemIdxUnderNode++; + if ( iMailList->Parent(itemId) != parentNodeId || + iMailList->ChildIndex( parentNodeId, itemId ) != itemIdxUnderNode ) + { + iMailList->MoveItemL( itemId, parentNodeId, itemIdxUnderNode ); + } + } + + mailListItem.iListItemId = itemId; + mailListItem.iTreeItemData = &iMailList->ItemData(itemId); + mailListItem.iTreeItemVisualiser = &iMailList->ItemVisualizer(itemId); + iTreeItemArray.AppendL( mailListItem ); + } + + iMailList->SetFocusedItemL( prevFocus ); + //iMailList->ShowListL( EFalse, EFalse ); + } + iListOrderMayBeOutOfDate = EFalse; + } + +// --------------------------------------------------------------------------- +// Start refresh list items asynchronously +// +// --------------------------------------------------------------------------- +// +// +void CFSEmailUiMailListVisualiser::RefreshDeferred( TFSMailMsgId* aFocusToMessage /*= NULL*/ ) + { + FUNC_LOG; + if ( aFocusToMessage ) + { + iMsgToFocusAfterRedraw = *aFocusToMessage; + } + else + { + // SetNullId sets just the null id flag, + // so we need to null the actual id manually + iMsgToFocusAfterRedraw.SetId( 0 ); + iMsgToFocusAfterRedraw.SetNullId(); + } + + if ( iAsyncRedrawer ) + { + TCallBack asyncRefresh( DoRefresh, this ); + iAsyncRedrawer->Cancel(); + iAsyncRedrawer->Set( asyncRefresh ); + iAsyncRedrawer->CallBack(); + } + } + +// --------------------------------------------------------------------------- +// Static wrapper function for RefreshL() to enable asynchronous calling +// +// --------------------------------------------------------------------------- +// +// +TInt CFSEmailUiMailListVisualiser::DoRefresh( TAny* aSelfPtr ) + { + FUNC_LOG; + CFSEmailUiMailListVisualiser* self = + static_cast< CFSEmailUiMailListVisualiser* >( aSelfPtr ); + TRAPD( err, self->RefreshL( &self->iMsgToFocusAfterRedraw ) ); + return err; + } + +// --------------------------------------------------------------------------- +// Force any pending refresh event to be completed immediately +// +// --------------------------------------------------------------------------- +// +// +void CFSEmailUiMailListVisualiser::CompletePendingRefresh() + { + FUNC_LOG; + + if ( iAsyncRedrawer && iAsyncRedrawer->IsActive() ) + { + iAsyncRedrawer->Cancel(); + DoRefresh( this ); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RefreshListItemsL() + { + FUNC_LOG; + // IMPLEMENTATION OF FILLING UP THE LIST + TFsTreeItemId latestNodeId = KFsTreeRootID; // items will go under root node if no other nodes found in the model + CFSEmailUiMailListModelItem* item( NULL ); + SetMailListItemsExtendedL(); + + TInt count(0); + count = iModel->Count(); + for ( TInt i=0; i < count; i++ ) + { + item = static_cast(iModel->Item(i)); + + const TBool allowRefresh(i == 0 || (i == count - 1)); + + // Append separator item text into the list + if ( item && item->ModelItemType() == ETypeSeparator ) + { + latestNodeId = InsertNodeItemL( i, KErrNotFound, allowRefresh ); + } + // Append mail item into the list + else if ( item && item->ModelItemType() == ETypeMailItem ) + { + InsertListItemL( i, latestNodeId, KErrNotFound, allowRefresh ); + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RefreshListItemsL(TFsTreeItemId& aLatestNodeId, const TInt aStartIndex, const TInt aEndIndex) + { + FUNC_LOG; + // IMPLEMENTATION OF FILLING UP THE LIST + iMailList->BeginUpdate(); + CFSEmailUiMailListModelItem* item( NULL ); + if (aLatestNodeId == KFsTreeRootID && !aStartIndex) + { + iMailList->RemoveAllL(); + iTreeItemArray.Reset(); + SetMailListItemsExtendedL(); + } + for ( TInt i = aStartIndex; i < aEndIndex; i++ ) + { + item = static_cast(iModel->Item(i)); + // Append separator item text into the list + if ( item && item->ModelItemType() == ETypeSeparator ) + { + aLatestNodeId = InsertNodeItemL( i, KErrNotFound, EFalse ); + } + // Append mail item into the list + else if ( item && item->ModelItemType() == ETypeMailItem ) + { + InsertListItemL( i, aLatestNodeId, KErrNotFound, EFalse ); + } + } + iMailList->EndUpdateL(); + } + +void CFSEmailUiMailListVisualiser::SetMailListItemsExtendedL() + { + FUNC_LOG; + // Set items always extended in double line preview on mode. + if ( iListMode == EListControlTypeDoubleLinePreviewOn || + iListMode == EListControlTypeDoubleLinePreviewOff ) + { + if ( iMailTreeListVisualizer ) + { + iMailTreeListVisualizer->SetItemsAlwaysExtendedL( ETrue ); + } + } + else + { + // Set the extendedability and extended size + if ( iMailTreeListVisualizer ) + { + iMailTreeListVisualizer->SetItemsAlwaysExtendedL( EFalse ); + } + } + } + + +// --------------------------------------------------------------------------- +// Create and insert one list node item according to given model item. +// Omitting the argument aChildIdx causes the new node to be appended as last +// child of the root node. +// --------------------------------------------------------------------------- +// +TFsTreeItemId CFSEmailUiMailListVisualiser::InsertNodeItemL( TInt aModelIndex, + TInt aChildIndex, + const TBool aAllowRefresh ) + { + FUNC_LOG; + TFsTreeItemId nodeId; + CFsTreePlainOneLineNodeData* plainNodeData(0); + CFsTreePlainOneLineNodeVisualizer* plainNodeVisualizer(0); + + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(aModelIndex) ); + + CreatePlainNodeL( item->SeparatorText(), plainNodeData, plainNodeVisualizer ); + CleanupStack::PushL( plainNodeData ); + CleanupStack::PushL( plainNodeVisualizer ); + // Set text aling for western or A&H layout + plainNodeVisualizer->SetTextAlign( EAlfAlignHLocale ); + //new node is expanded + plainNodeVisualizer->SetExpanded( ETrue ); + + // In mail list, scrollbar does not need to be updated after node, since node is always followed by item + if ( aChildIndex >= 0 ) + { + nodeId = iMailList->InsertNodeL( *plainNodeData, *plainNodeVisualizer, KFsTreeRootID, aChildIndex, aAllowRefresh ); + } + else + { + nodeId = iMailList->InsertNodeL( *plainNodeData, *plainNodeVisualizer, KFsTreeRootID, KErrNotFound, aAllowRefresh ); + } + + CleanupStack::Pop( 2, plainNodeData ); + + SMailListItem mailListItem; + mailListItem.iListItemId = nodeId; + mailListItem.iTreeItemData = plainNodeData; + mailListItem.iTreeItemVisualiser = plainNodeVisualizer; + iTreeItemArray.InsertL( mailListItem, aModelIndex ); + item->AddCorrespondingListId( nodeId ); + + return nodeId; + } + +// --------------------------------------------------------------------------- +// Create and insert one list item according the given model item. The item is +// added under the given node. Omitting the argument aChildIdx causes the new +// item to be appended as last child of the node. +// --------------------------------------------------------------------------- +// +TFsTreeItemId CFSEmailUiMailListVisualiser::InsertListItemL( TInt aModelIndex, + TFsTreeItemId aParentNodeId, + TInt aChildIdx, /*= KErrNotFound*/ + TBool aAllowRefresh /*= ETrue*/ ) + { + FUNC_LOG; + CFsTreePlainTwoLineItemData* itemData = NULL; + CFsTreePlainTwoLineItemVisualizer* itemVisualizer = NULL; + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(aModelIndex) ); + + // Create data + itemData = CFsTreePlainTwoLineItemData::NewL(); + CleanupStack::PushL(itemData); + + // Read the data from the message + UpdateItemDataL( itemData, &item->MessagePtr() ); + + // Set placeholder for body preview + itemData->SetPreviewPaneDataL( KMissingPreviewDataMarker ); + + // Create item visualiser + itemVisualizer = CFsTreePlainTwoLineItemVisualizer::NewL( + *iMailList->TreeControl() ); + CleanupStack::PushL( itemVisualizer ); + + itemVisualizer->SetTextAlign( EAlfAlignHLocale ); + + TBool previewOn = ( iListMode == EListControlTypeDoubleLinePreviewOn || + iListMode == EListControlTypeSingleLinePreviewOn ); + itemVisualizer->SetPreviewPaneOn( previewOn ); + itemVisualizer->SetExtendable( ETrue ); + + // Set correct skin text colors for the list items + itemVisualizer->SetFocusedStateTextColor( iFocusedTextColor ); + itemVisualizer->SetNormalStateTextColor( iNormalTextColor ); + + // Set font height + itemVisualizer->SetFontHeight( iAppUi.LayoutHandler()->ListItemFontHeightInTwips() ); + + //Update icons and text bolding + //DOES NOT update the item - will be drawn automatically (if needed) during InsertItemL + UpdateMsgIconAndBoldingL( itemData, itemVisualizer, &item->MessagePtr() ); + + // Insert or append under the given node + TFsTreeItemId itemId(0); + itemId = iMailList->InsertItemL( *itemData, *itemVisualizer, aParentNodeId, aChildIdx, aAllowRefresh ); + + // The visualizer and data are now owned by the iMailList and should be removed from + // the cleanup stack + CleanupStack::Pop( itemVisualizer ); + CleanupStack::Pop( itemData ); + + // Insert corresponding item to iTreeItemArray + SMailListItem mailListItem; + mailListItem.iListItemId = itemId; + mailListItem.iTreeItemData = itemData; + mailListItem.iTreeItemVisualiser = itemVisualizer; + iTreeItemArray.InsertL( mailListItem, aModelIndex ); + item->AddCorrespondingListId( itemId ); + + // Updating the preview pane must be handled separately in this case; + // generic logic in TreeListEvent handler doesn't work while we are + // still in the middle of adding the item. + if ( iMailList->FocusedItem() == itemId ) + { + UpdatePreviewPaneTextIfNecessaryL( itemId, ETrue ); + } + + return itemId; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +HBufC* CFSEmailUiMailListVisualiser::GetListFirstTextLineL( const CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + HBufC* ret( NULL ); + + TDesC* displayName( NULL ); + TDesC* emailAddress( NULL ); + + TInt folderType( EFSInbox ); + if( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + + // Use sender in all other folders than outbox, sent, and drafts + if ( folderType != EFSOutbox && + folderType != EFSSentFolder && + folderType != EFSDraftsFolder ) + { + CFSMailAddress* fromAddress = aMsgPtr->GetSender(); + if ( fromAddress ) + { + displayName = &fromAddress->GetDisplayName(); + emailAddress = &fromAddress->GetEmailAddress(); + + if ( displayName && displayName->Length() != 0 ) + { + ret = displayName->AllocL(); + } + else if ( emailAddress && emailAddress->Length() != 0 ) + { + ret = emailAddress->AllocL(); + } + } + else // no fromAddress in that case we show "(No sender info available)", + // in case sender sends MR to himself/herself + { + ret = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SENDER_INFO_AVAILABLE); + } + } + // Use first recipient in case of outgoing folders + else // folderType == EFSOutbox || folderType == EFSSentFolder || folderType == EFSDraftsFolder + { + CFSMailMessage* msgPtr = const_cast( aMsgPtr ); // there's no const function in FW to get recipient data + RPointerArray& toArray = msgPtr->GetToRecipients(); + if ( toArray.Count() ) + { + CFSMailAddress* toAddress = toArray[0]; // Use first + if ( toAddress ) + { + displayName = &toAddress->GetDisplayName(); + emailAddress = &toAddress->GetEmailAddress(); + + if ( displayName && displayName->Length() ) + { + ret = displayName->AllocL(); + } + else if ( emailAddress && emailAddress->Length() ) + { + ret = emailAddress->AllocL(); + } + } + } + } + + // Allocate empty string if everything else fails + if ( !ret ) + { + ret = KNullDesC().AllocL(); + } + + // Drop out unwanted characters from display name such as <> and "" + TFsEmailUiUtility::StripDisplayName( *ret ); + + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateItemDataL( CFsTreePlainTwoLineItemData* aData, const CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + // Set first line of data + HBufC* firstLineText = GetListFirstTextLineL( aMsgPtr ); + if ( firstLineText ) + { + CleanupStack::PushL( firstLineText ); + aData->SetDataL( *firstLineText ); + CleanupStack::PopAndDestroy( firstLineText ); + } + else + { + aData->SetDataL( KNullDesC ); + } + + // Set second line of data + HBufC* subjectText = TFsEmailUiUtility::CreateSubjectTextLC( aMsgPtr ); + aData->SetSecondaryDataL( *subjectText ); + CleanupStack::PopAndDestroy( subjectText ); + + // Set time item in mail + HBufC* timeText = NULL; + if ( iCurrentSortCriteria.iField == EFSMailSortByDate ) + { + timeText = TFsEmailUiUtility::ListMsgTimeTextFromMsgLC( aMsgPtr, iNodesInUse ); + } + else + { + // Use dates also in other sort criterias that sort by date. + timeText = TFsEmailUiUtility::ListMsgTimeTextFromMsgLC( aMsgPtr, EFalse ); + } + aData->SetDateTimeDataL( *timeText ); + CleanupStack::PopAndDestroy( timeText ); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdatePreviewPaneTextForItemL( TInt aListItemId, CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + if ( aMsgPtr && ( iListMode == EListControlTypeSingleLinePreviewOn || + iListMode == EListControlTypeDoubleLinePreviewOn ) ) + { + CFsTreePlainTwoLineItemData* twoLineItemData = static_cast( ItemDataFromItemId( aListItemId ) ); + UpdatePreviewPaneTextForItemL( twoLineItemData, aMsgPtr ); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdatePreviewPaneTextForItemL( + CFsTreePlainTwoLineItemData* aTwoLineItemData, CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + // Preview pane data update + if ( aTwoLineItemData && aMsgPtr && ( iListMode == EListControlTypeSingleLinePreviewOn || + iListMode == EListControlTypeDoubleLinePreviewOn ) ) + { + TBool previewSet = EFalse; + CFSMailMessagePart* textPart = aMsgPtr->PlainTextBodyPartL(); + CleanupStack::PushL( textPart ); + if ( textPart && ( textPart->FetchLoadState() == EFSPartial || + textPart->FetchLoadState() == EFSFull ) ) + { + TInt previewSize = Min( KMaxPreviewPaneLength, textPart->FetchedContentSize() ); + HBufC* plainTextData16 = HBufC::NewLC( previewSize ); + TPtr textPtr = plainTextData16->Des(); + + // Getting the content needs to be trapped as it seems to leave in some error cases + // at least with IMAP + TRAP_IGNORE( textPart->GetContentToBufferL( textPtr, 0 ) ); // Zero is start offset + // Crop out line feed, paragraph break, and tabulator + TFsEmailUiUtility::FilterListItemTextL( textPtr ); + + if ( textPtr.Length() ) + { + aTwoLineItemData->SetPreviewPaneDataL( *plainTextData16 ); + previewSet = ETrue; + } + + CleanupStack::PopAndDestroy( plainTextData16 ); + } + + // Display message size in preview pane if we got no body content + if ( !previewSet ) + { + TUint contentSize = aMsgPtr->ContentSize(); + HBufC* sizeDesc = TFsEmailUiUtility::CreateSizeDescLC( contentSize ); + HBufC* msgSizeText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_PREV_PANE_MSG_SIZE, *sizeDesc ); + aTwoLineItemData->SetPreviewPaneDataL( *msgSizeText ); + CleanupStack::PopAndDestroy( msgSizeText ); + CleanupStack::PopAndDestroy( sizeDesc ); + } + CleanupStack::PopAndDestroy( textPart ); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdatePreviewPaneTextIfNecessaryL( TFsTreeItemId aListItemId, TBool aUpdateItem ) + { + FUNC_LOG; + if ( iFirstStartCompleted && aListItemId != KFsTreeNoneID ) + { + if ( iListMode == EListControlTypeSingleLinePreviewOn || + iListMode == EListControlTypeDoubleLinePreviewOn ) + { + if ( !iMailList->IsNode( aListItemId ) ) + { + TInt idx = ModelIndexFromListId( aListItemId ); + if ( idx != KErrNotFound ) + { + CFsTreePlainTwoLineItemData* data = + static_cast( iTreeItemArray[idx].iTreeItemData ); + if ( data->PreviewPaneData() == KMissingPreviewDataMarker ) + { + CFSEmailUiMailListModelItem* modelItem = + static_cast( iModel->Item(idx) ); + if ( modelItem ) // For safety + { + CFSMailMessage& msgRef = modelItem->MessagePtr(); + UpdatePreviewPaneTextForItemL( aListItemId, &msgRef ); + if ( aUpdateItem ) + { + iMailTreeListVisualizer->UpdateItemL( aListItemId ); + } + } + } + } + } + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::CreatePlainNodeL( const TDesC* aItemDataBuff, + CFsTreePlainOneLineNodeData* &aItemData, + CFsTreePlainOneLineNodeVisualizer* &aNodeVisualizer ) const + { + FUNC_LOG; + aItemData = CFsTreePlainOneLineNodeData::NewL(); + CleanupStack::PushL( aItemData ); + + aItemData->SetDataL( *aItemDataBuff ); + aItemData->SetIconExpanded( iAppUi.FsTextureManager()->TextureByIndex( EListTextureNodeExpanded )); + aItemData->SetIconCollapsed( iAppUi.FsTextureManager()->TextureByIndex( EListTextureNodeCollapsed )); + aNodeVisualizer = CFsTreePlainOneLineNodeVisualizer::NewL(*iMailList->TreeControl()); + CleanupStack::PushL( aNodeVisualizer ); + TInt nodeHeight = iAppUi.LayoutHandler()->OneLineListNodeHeight(); + // use cached client rect instead of iAppUi.ClientRect() to save time + // ASSERT in debug to be sure that rects are these same + __ASSERT_DEBUG( iAppUi.ClientRect() == iCurrentClientRect, User::Invariant() ); + aNodeVisualizer->SetSize( TSize(iCurrentClientRect.Width(), nodeHeight) ); + aNodeVisualizer->SetExtendable(EFalse); + // Set correct skin text colors for the list items + aNodeVisualizer->SetFocusedStateTextColor( iFocusedTextColor ); + aNodeVisualizer->SetNormalStateTextColor( iNodeTextColor ); + // Set font height + aNodeVisualizer->SetFontHeight( iAppUi.LayoutHandler()->ListItemFontHeightInTwips() ); + // Set font always bolded in nodes + aNodeVisualizer->SetTextBold( ETrue ); + + // + CAlfBrush* titleDividerBgBrush = + iAppUi.FsTextureManager()->TitleDividerBgBrushL(); + // ownership is not transfered + aNodeVisualizer->SetBackgroundBrush( titleDividerBgBrush ); + // + + CleanupStack::Pop( aNodeVisualizer ); + CleanupStack::Pop( aItemData ); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleDynamicVariantSwitchL( + CFsEmailUiViewBase::TDynamicSwitchType aType ) + { + FUNC_LOG; + CFsEmailUiViewBase::HandleDynamicVariantSwitchL( aType ); + + if ( iFirstStartCompleted ) // Safety + { + if ( aType == EScreenLayoutChanged ) + { + SetStatusBarLayout(); + UpdateButtonTextsL(); + } + + if ( aType == ESkinChanged ) + { + UpdateThemeL(); + } + else + { + iAppUi.FsTextureManager()->ClearTextureByIndex( EListControlBarMailboxDefaultIcon ); + iFolderListButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListControlBarMailboxDefaultIcon ) ); + iAppUi.FsTextureManager()->ClearTextureByIndex( EListTextureCreateNewMessageIcon ); + iNewEmailButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListTextureCreateNewMessageIcon ) ); + iAppUi.FsTextureManager()->ClearTextureByIndex( GetSortButtonTextureIndex() ); + iSortButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( GetSortButtonTextureIndex() ) ); + + iMailTreeListVisualizer->HideList(); + // screen layout changed + iCurrentClientRect = iAppUi.ClientRect(); + iScreenAnchorLayout->SetSize( iCurrentClientRect.Size() ); + SetMailListLayoutAnchors(); + // Set branded watermark + SetBrandedListWatermarkL(); + iMailTreeListVisualizer->ShowListL(); + + ScaleControlBarL(); + SetBrandedMailBoxIconL(); + } + // Update the folder/sort popup layout in case it happened to be open + if ( iAppUi.FolderList().IsPopupShown() ) + { + iAppUi.FolderList().HandleDynamicVariantSwitchL( aType ); + } + } + if (iMarkingMode) + { + RefreshMarkingModeL(); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleDynamicVariantSwitchOnBackgroundL( + CFsEmailUiViewBase::TDynamicSwitchType aType ) + { + FUNC_LOG; + CFsEmailUiViewBase::HandleDynamicVariantSwitchOnBackgroundL( aType ); + if ( aType == ESkinChanged ) + { + UpdateThemeL(); + } + else if ( aType == EScreenLayoutChanged ) + { + UpdateButtonTextsL(); + } + } + +// --------------------------------------------------------------------------- +// Update texts for command area buttons +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateButtonTextsL() + { + if ( !Layout_Meta_Data::IsLandscapeOrientation() ) + { + // No texts in portrait mode + iNewEmailButton->SetTextL( KNullDesC() ); + iSortButton->SetTextL( KNullDesC() ); + } + else + { + // Set button text if necessary + HBufC* buttonText = GetSortButtonTextLC(); + if ( buttonText ) + { + iSortButton->SetTextL( *buttonText ); + CleanupStack::PopAndDestroy( buttonText ); + } + + iNewEmailButton->SetTextL( *iNewEmailText ); + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::HitTest( + const CAlfControl& aControl, const TPoint& aPoint ) const + { + FUNC_LOG; + TBool contains( EFalse ); + const TInt visualCount( aControl.VisualCount() ); + for( TInt index( 0 ); index < visualCount && !contains; ++index ) + { + TRect rect( aControl.Visual( index ).DisplayRectTarget() ); + if( rect.Contains( aPoint ) ) + { + contains = ETrue; + } + } + return contains; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::HandleArrowEventInPortraitL( + const TInt aScancode, + const TAlfEvent& aEvent, + const TBool aShiftState ) + { + FUNC_LOG; + TBool result( EFalse ); + + if( aScancode == EStdKeyLeftArrow ) + { + if( ( iControlBarControl ) && + ( iFocusedControl == EMailListComponent ) ) + { + // Move focus to control bar (focused button is + // sort button). + HandleCommandL( EFsEmailUiCmdGoToSwitchSorting ); + result = ETrue; + } + else if( ( iControlBarControl ) && + ( iFocusedControl == EControlBarComponent ) ) + { + TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() ); + if ( focusedButtonId == iNewEmailButtonId ) + { + // Change focus to mail list if there are any + // emails in it. + if( iModel->Count() ) + { + iFocusedControl = EMailListComponent; + result = EFalse; + } + // Leave focus to control bar because there are no + // mails in mail list. + else + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + iFocusedControl = EControlBarComponent; + result = ETrue; // Do not set focus to empty list + } + } + else + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + iFocusedControl = EControlBarComponent; + result = EFalse; + } + } + else + { + iFocusedControl = EMailListComponent; + result = EFalse; + } + SetMskL(); + } + else if( aScancode == EStdKeyRightArrow ) + { + // Show toolbar if there is data on the list + const TInt modelCount( iModel->Count() ); + TBool focusShown( IsFocusShown() ); + + // If control bar is focused. + if( ( iControlBarControl ) && + ( iFocusedControl == EControlBarComponent ) ) + { + TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() ); + + // If sort button is focused and there are mails in mail + // list then focus is moved to mail list, otherwise + // leave focus to control bar + if( focusedButtonId == iSortButtonId ) + { + if ( modelCount > 0 ) // Check for empty folder + { + iFocusedControl = EMailListComponent; + result = EFalse; + } + else + { + iFocusedControl = EControlBarComponent; + iControlBarControl->MakeSelectorVisible( focusShown ); + result = ETrue; // Do not set focus to empty list + } + } + else + { + iFocusedControl = EControlBarComponent; + iControlBarControl->MakeSelectorVisible( focusShown ); + result = EFalse; + } + } + else if( ( iControlBarControl ) && + ( iFocusedControl == EMailListComponent ) ) + { + HandleCommandL( EFsEmailUiCmdGoToSwitchNewEmail ); + result = ETrue; + } + else + { + iFocusedControl = EMailListComponent; + result = EFalse; + } + SetMskL(); + } + else if( aScancode == EStdKeyDownArrow ) + { + const TInt itemCount( iModel->Count() ); + if ( iFocusedControl == EMailListComponent ) + { + result = iMailList->TreeControl()->OfferEventL( aEvent ); + if ( aShiftState ) + { + DoScrollMarkUnmarkL(); // marking is done after moving the cursor + } + } + else if( ( iFocusedControl == EControlBarComponent ) && + ( itemCount == 0 ) ) + { + result = ETrue; // Do not set focus to empty list + } + else if( ( iFocusedControl == EControlBarComponent ) && + ( itemCount > 0 ) ) + { + iFocusedControl = EMailListComponent; + + result = iMailList->TreeControl()->OfferEventL(aEvent); + if ( aShiftState ) + { + DoScrollMarkUnmarkL(); // marking is done after moving the cursor + } + } + else + { + result = EFalse; + } + SetMskL(); + } + else if( aScancode == EStdKeyUpArrow ) + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + if ( iFocusedControl == EMailListComponent ) + { + if ( HighlightedIndex() == 0 ) + { + HandleCommandL( EFsEmailUiCmdGoToSwitchFolder ); + result = ETrue; + } + else + { + result = iMailList->TreeControl()->OfferEventL( aEvent ); + if ( aShiftState ) + { + // marking is done after moving the cursor + DoScrollMarkUnmarkL(); + } + SetMskL(); + } + } + else if( iFocusedControl == EControlBarComponent ) + { + result = ETrue; + } + else + { + result = EFalse; + } + } + + return result; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::HandleArrowEventInLandscapeL( + const TInt aScancode, + const TAlfEvent& aEvent, + const TBool aShiftState ) + { + FUNC_LOG; + TBool result( EFalse ); + if( aScancode == EStdKeyRightArrow ) + { + if ( iFocusedControl == EMailListComponent ) + { + HandleCommandL( EFsEmailUiCmdGoToSwitchFolder ); + result = ETrue; + } + else if( iFocusedControl == EControlBarComponent ) + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + result = ETrue; + } + } + else if( aScancode == EStdKeyLeftArrow ) + { + if ( iFocusedControl == EControlBarComponent ) + { + const TInt modelCount( iModel->Count() ); + if( modelCount > 0 ) + { + iFocusedControl = EMailListComponent; + result = iMailList->TreeControl()->OfferEventL( aEvent ); + if( aShiftState ) + { + // marking is done after moving the cursor + DoScrollMarkUnmarkL(); + } + } + else + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + // Do not set focus to empty list + result = ETrue; + } + } + else if( iFocusedControl == EMailListComponent ) + { + result = iMailList->TreeControl()->OfferEventL( aEvent ); + if ( aShiftState ) + { + // marking is done after moving the cursor + DoScrollMarkUnmarkL(); + } + } + SetMskL(); + } + if( aScancode == EStdKeyUpArrow ) + { + if( iFocusedControl == EMailListComponent ) + { + result = iMailList->TreeControl()->OfferEventL( aEvent ); + if ( aShiftState ) + { + // marking is done after moving the cursor + DoScrollMarkUnmarkL(); + } + } + else if( iFocusedControl == EControlBarComponent ) + { + TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() ); + if ( focusedButtonId == iNewEmailButtonId ) + { + // Change focus to mail list if there are any + // mails in it. + if( iModel->Count() > 0 ) + { + iFocusedControl = EMailListComponent; + result = EFalse; + } + // Leave focus to control bar because there are no + // mails in mail list. + else + { + // Do not set focus to empty list + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + result = ETrue; + } + } + else + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + result = static_cast( iControlBarControl )->OfferEventL( aEvent ); + } + } + SetMskL(); + } + else if( aScancode == EStdKeyDownArrow ) + { + if( iFocusedControl == EMailListComponent ) + { + result = iMailList->TreeControl()->OfferEventL( aEvent ); + if( aShiftState ) + { + // marking is done after moving the cursor + DoScrollMarkUnmarkL(); + } + } + else if( iFocusedControl == EControlBarComponent ) + { + const TInt modelCount( iModel->Count() ); + TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() ); + // If sort button is focused and there are mails in mail + // list then focus is moved to mail list, otherwise + // leave focus to control bar + if( focusedButtonId == iSortButtonId ) + { + if ( modelCount > 0 ) // Check for empty folder + { + iFocusedControl = EMailListComponent; + result = EFalse; + } + else + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + result = ETrue; // Do not set focus to empty list + } + } + else + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + result = static_cast( iControlBarControl )->OfferEventL( aEvent ); + } + } + SetMskL(); + } + + return result; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateThemeL(const TBool aSystemUpdate) + { + iSkinChanged = iSkinChanged || aSystemUpdate; + + iFocusedTextColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor(); + iNormalTextColor = iAppUi.LayoutHandler()->ListNormalStateTextSkinColor(); + iNodeTextColor = iAppUi.LayoutHandler()->ListNodeTextColor(); + + iNewEmailButton->SetNormalTextColor( iNormalTextColor ); + iNewEmailButton->SetFocusedTextColor( iFocusedTextColor ); + + iFolderListButton->SetNormalTextColor( iNormalTextColor ); + iFolderListButton->SetFocusedTextColor( iFocusedTextColor ); + + iSortButton->SetNormalTextColor( iNormalTextColor ); + iSortButton->SetFocusedTextColor( iFocusedTextColor ); + + //sometimes theme wasn't properly refreshed on buttons, this helps + iNewEmailButton->HideButton(); + iNewEmailButton->ShowButtonL(); + + iFolderListButton->HideButton(); + iFolderListButton->ShowButtonL(); + + iSortButton->HideButton(); + iSortButton->ShowButtonL(); + } + +// --------------------------------------------------------------------------- +// HandleForegroundEventL +// Function checks in foregroundevent that whether settings have changed and +// If there is a need to refresh the list. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleForegroundEventL( TBool aForeground ) + { + FUNC_LOG; + if( iMailFolder ) + { + //emailindicator handling, is removed from 9.2 + //TRAP_IGNORE(TFsEmailStatusPaneIndicatorHandler::StatusPaneMailIndicatorHandlingL( iMailFolder->GetMailBoxId().Id())); + //Update mailbox widget index status in homescreen + TFsEmailUiUtility::ToggleEmailIconL(EFalse, iMailFolder->GetMailBoxId() ); + } + + if ( aForeground && iFirstStartCompleted ) // Safety + { + // Update mail list settings and date formats, is done every time + // the user might have changed these in settings, so the list needs to refresh + // Store previous modes + TInt prevListMode = iListMode; + TInt prevNodesmode = iNodesInUse; + TAknUiZoom prevZoomLevel = iCurrentZoomLevel; + STimeDateFormats prevDateFormats = MailListTimeDateSettings(); + + // Get new settings and list drawing modes + CAknEnv::Static()->GetCurrentGlobalUiZoom( iCurrentZoomLevel ); + UpdateMailListSettingsL(); + UpdateMailListTimeDateSettings(); + + // Check sync icon timer and sync status + ConnectionIconHandling(); + + // Updates the folder list's size after the screensaver + iAppUi.FolderList().HandleForegroundEventL(); + + // Check for changed settings, in that case a complete list refresh is needed + if ( iSkinChanged + || iDateChanged + || iListMode != prevListMode + || iNodesInUse != prevNodesmode + || iCurrentZoomLevel != prevZoomLevel + || prevDateFormats.iDateFormat != iDateFormats.iDateFormat + || prevDateFormats.iTimeFormat != iDateFormats.iTimeFormat + || prevDateFormats.iAmPmPosition != iDateFormats.iAmPmPosition + || prevDateFormats.iDateSeparator != iDateFormats.iDateSeparator + || prevDateFormats.iTimeSeparator != iDateFormats.iTimeSeparator ) + { + // Store the list of marked items. The markings are erased when the list + // is repopulated and, hence, the markings need to be reset after the + // refreshing is done. The marked items must be identified by the message + // ID rather than with the list ID because refreshing may change the list IDs. + RArray markedMessages; + CleanupClosePushL( markedMessages ); + GetMarkedMessagesL( markedMessages ); + // Store the message ID of the focused item + TFSMailMsgId msgIdBeforeRefresh = MsgIdFromListId( iMailList->FocusedItem() ); + TFsTreeItemId firstVisibleListId = iMailTreeListVisualizer->FirstVisibleItem(); + TInt modelFirstIndexBeforeUpdate = ModelIndexFromListId( firstVisibleListId ); + TInt highlightedIndexBeforeUpdate = HighlightedIndex(); + TInt modelCountBeforeUpdate = iModel->Count(); + + UpdateMailListModelL(); + if ( markedMessages.Count() ) + { + RefreshL( &msgIdBeforeRefresh ); + // Restore the marking status + MarkMessagesIfFoundL( markedMessages ); + } + else + { + RefreshDeferred( &msgIdBeforeRefresh ); + } + CleanupStack::PopAndDestroy( &markedMessages ); + iSkinChanged = EFalse; // Toggle handled + iDateChanged = EFalse; // Toggle handled + } + if (iMarkingMode) + { + RefreshMarkingModeL(); + } + } + } + + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleCommandL( TInt aCommand ) + { + FUNC_LOG; + TIMESTAMP( "Message list command for handling" ); + CompletePendingRefresh(); + + // custom command handling for launching plugin settings + if ( EFsEmailUiCmdSettingsBaseCommandId <= aCommand + && EFsEmailUiCmdSettingsBaseCommandIdMax > aCommand ) + { + CESMailSettingsPlugin::TSubViewActivationData activationData; + activationData.iAccount = iAppUi.GetActiveMailbox()->GetId(); + // which settings plugin subview will be activated + TInt selectedCommand = aCommand - EFsEmailUiCmdSettingsBaseCommandId; + activationData.iSubviewId = selectedCommand; + + TUid pluginUid = iAppUi.GetActiveMailbox()->GetSettingsUid(); + + // If plugin view does not exist, create and register it to app ui. + if ( !iAppUi.View( pluginUid ) ) + { + CESMailSettingsPlugin* plugin = CESMailSettingsPlugin::NewL( pluginUid ); + CleanupStack::PushL( plugin ); + iAppUi.AddViewL( plugin ); // Ownership is transferred. + CleanupStack::Pop( plugin ); + } + TUid messageId = TUid::Uid( CESMailSettingsPlugin::EActivateMailSettingsSubview ); + const TPckgBuf pluginMessagePkg( activationData ); + + StatusPane()->SwitchLayoutL( R_AVKON_STATUS_PANE_LAYOUT_USUAL ); + iAppUi.EnterPluginSettingsViewL( pluginUid, messageId, pluginMessagePkg ); + } + + // Many commands may be targetted either to the focused item or to the marked item(s). + // Get list of marked or focused items. + RFsTreeItemIdList actionTargetItems; + CleanupClosePushL( actionTargetItems ); + GetActionsTargetEntriesL( actionTargetItems ); + + // Check if the focus needs to be removed. + if ( ( iStylusPopUpMenuVisible ) && + ( aCommand == KErrCancel || + aCommand == EFsEmailUiCmdActionsDelete || + aCommand == EFsEmailUiCmdMarkAsRead || + aCommand == EFsEmailUiCmdMarkAsUnread || + aCommand == EFsEmailUiCmdActionsMove || + aCommand == EFsEmailUiCmdActionsMoveMessage || + aCommand == EFsEmailUiCmdMarkingModeFromPopUp || + aCommand == EFsEmailUiCmdActionsCollapseAll || + aCommand == EFsEmailUiCmdActionsExpandAll ) ) + { + // We end up here if the user selects an option from the pop up menu + // or exits the menu by tapping outside of it's area. + // Remove the focus from a list item if an item is focused. + iStylusPopUpMenuVisible = EFalse; + iAppUi.SetFocusVisibility( EFalse ); + } + + switch( aCommand ) + { + case EAknSoftkeyOpen: + { + TIMESTAMP( "Open email selected from message list" ); + if( !iAppUi.IsFocusShown() ) + { + iAppUi.SetFocusVisibility( ETrue ); + break; + } + } + case EAknSoftkeySelect: + { + TIMESTAMP( "Open email selected from message list" ); + if ( iFocusedControl == EMailListComponent ) + { + CFSEmailUiMailListModelItem* item = dynamic_cast(iModel->Item(HighlightedIndex())); + // MAIL ITEM; OPEN MAIL + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailMessage* messagePtr = &item->MessagePtr(); + if ( messagePtr ) + { + OpenHighlightedMailL(); + } + } + } + } + break; + case EAknSoftkeyChange: + { + if( !iAppUi.IsFocusShown() ) + { + iAppUi.SetFocusVisibility( ETrue ); + break; + } + if( iFocusedControl == EControlBarComponent ) + { + TInt focusedButtonId = iControlBarControl->GetFocusedButton()->Id(); + if ( focusedButtonId == iFolderListButtonId ) + { + // + //Set touchmanager not active for preventing getting events. + DisableMailList(ETrue); + // + iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton ); + } + else if( focusedButtonId == iSortButtonId ) + { + TFSFolderType folderType; + if( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + else + { + folderType = EFSInbox; + } + // Sorting set possible even for empty mailbox + // Show sort if model has data. + //if ( iModel->Count() ) + // { + // + // + //Set touchmanager not active for preventing getting events. + DisableMailList(ETrue); + // + iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton ); + // + // } + // + } + } + } + break; + case EAknSoftkeyBack: + if ( !iAppUi.ViewSwitchingOngoing() ) + { + NavigateBackL(); + } + break; + case EAknSoftkeyCancel: + if (iMarkingMode) + { + ExitMarkingModeL(); + } + break; + case EEikCmdExit: + case EAknSoftkeyExit: + case EFsEmailUiCmdExit: + TIMESTAMP( "Exit selected from message list" ); + iAppUi.Exit(); + break; + case EFsEmailUiCmdCalActionsReplyAsMail: + case EFsEmailUiCmdActionsReply: + { + TIMESTAMP( "Reply to selected from message list" ); + ReplyL( NULL ); // Function will check marked/highlighted msg + } + break; + case EFsEmailUiCmdActionsReplyAll: + { + TIMESTAMP( "Reply to all selected from message list" ); + ReplyAllL( NULL ); // Function will check marked/highlighted msg + } + break; + case EFsEmailUiCmdCalActionsForwardAsMail: + case EFsEmailUiCmdActionsForward: + { + TIMESTAMP( "Forward selected from message list" ); + ForwardL( NULL ); // Function will check marked/highlighted msg + } + break; + case EFsEmailUiCmdActionsCallSender: + { + if ( !iAppUi.ViewSwitchingOngoing() ) + { + if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox && + iMailFolder->GetFolderType() != EFSDraftsFolder ) + { + // Calling can happen only when there's exactly one message marked or in focus + if ( actionTargetItems.Count() == 1 ) + { + CFSMailMessage& message = MsgPtrFromListIdL( actionTargetItems[0] ); + CFSMailAddress* fromAddress = message.GetSender(); + TDesC* mailAddress(0); + if ( fromAddress ) + { + mailAddress = &fromAddress->GetEmailAddress(); + } + if ( mailAddress && mailAddress->Length() ) + { + if ( iMailFolder->GetFolderType() == EFSSentFolder ) + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( + *mailAddress, iAppUi.GetActiveMailbox(), this, EFalse ); + } + else + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( + *mailAddress, iAppUi.GetActiveMailbox(), this, ETrue ); + } + } + } + } + } + } + break; + case EFsEmailUiCmdMarkAsRead: + { + // Change status of marked or highlighted + if ( CountMarkedItemsL() ) + { + ChangeReadStatusOfMarkedL( ETrue ); + } + else + { + ChangeReadStatusOfHighlightedL( ETrue ); + } + } + break; + case EFsEmailUiCmdMarkAsUnread: + { + // Change status of marked or highlighted + if ( CountMarkedItemsL() ) + { + ChangeReadStatusOfMarkedL( EFalse ); + } + else + { + ChangeReadStatusOfHighlightedL( EFalse ); + } + } + break; + case EFsEmailUiCmdGoToTop: + { + // Safety check, ignore command if the list is empty + if( iTreeItemArray.Count() ) + { + if ( iFocusedControl != EMailListComponent ) + { + iFocusedControl = EMailListComponent; + iMailList->SetFocusedL( ETrue ); + iControlBarControl->SetFocusL( EFalse ); + } + // No need to check for nodes as in move to bottom. + iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[0].iListItemId ); + } + } + break; + case EFsEmailUiCmdGoToBottom: + { + // Safety check, ignore command if the list is empty + if( iTreeItemArray.Count() ) + { + if ( iFocusedControl != EMailListComponent ) + { + iFocusedControl = EMailListComponent; + iMailList->SetFocusedL( ETrue ); + iControlBarControl->SetFocusL( EFalse ); + } + + TFsTreeItemId bottomItem = iTreeItemArray[iTreeItemArray.Count()-1].iListItemId; + TFsTreeItemId parentItem = ParentNode( bottomItem ); // parent node of the bottom item + + // Check whether the parent is node and is collapsed + if ( parentItem>0 && !iMailList->IsExpanded( parentItem ) ) + { + bottomItem = parentItem; + } + iMailTreeListVisualizer->SetFocusedItemL( bottomItem ); + } + } + break; + case EFsEmailUiCmdPageUp: + { + TKeyEvent simEvent = { EKeyPageUp, EStdKeyPageUp, 0, 0 }; + iCoeEnv->SimulateKeyEventL( simEvent, EEventKey ); + } + break; + case EFsEmailUiCmdPageDown: + { + TKeyEvent simEvent = { EKeyPageDown, EStdKeyPageDown, 0, 0 }; + iCoeEnv->SimulateKeyEventL( simEvent, EEventKey ); + } + break; + case EFsEmailUiCmdActionsDeleteCalEvent: + case EFsEmailUiCmdActionsDelete: + { + TIMESTAMP( "Delete to selected from message list" ); + TInt index = HighlightedIndex(); + CFSEmailUiMailListModelItem* item = + dynamic_cast( + iModel->Item( index ) ); + + // If selected item is separator (divider) mark/unmark all messages + // under it. + + // Delete message only if mail list component is focused + // or if there are some marked items + TInt markedItems( CountMarkedItemsL() ); + const TBool isNode(iMailList->IsNode(iMailList->FocusedItem())); + if (iFocusedControl == EMailListComponent || markedItems + || isNode) + { + DeleteMessagesL(); + } + } + break; + case EFsEmailUiCmdCompose: + { + // Switching to another view can take some time and this view + // can still receive some commands - so ignore them. + if ( iAppUi.CurrentActiveView() == this ) + { + TIMESTAMP( "Create new message selected from message list" ); + CreateNewMsgL(); + } + } + break; + case EFsEmailUiCmdMessageDetails: + { + // Message details can be viewed only when there's exactly one message marked or in focus + if ( actionTargetItems.Count() == 1 ) + { + CFSMailMessage& message = MsgPtrFromListIdL( actionTargetItems[0] ); + TMsgDetailsActivationData msgDetailsData; + msgDetailsData.iMailBoxId = iAppUi.GetActiveMailboxId(); + msgDetailsData.iFolderId = FolderId(); + msgDetailsData.iMessageId = message.GetMessageId(); + const TPckgBuf pkgOut( msgDetailsData ); + iAppUi.EnterFsEmailViewL( MsgDetailsViewId, KStartMsgDetailsToBeginning, pkgOut ); + } + } + break; + case EFsEmailUiCmdSettingsGlobal: + { + iAppUi.EnterFsEmailViewL( GlobalSettingsViewId ); + } + break; + case EFsEmailUiCmdSettingsService: + case EFsEmailUiCmdSettingsMailbox: + { + CESMailSettingsPlugin::TSubViewActivationData activationData; + activationData.iAccount = iAppUi.GetActiveMailbox()->GetId(); + activationData.iSubviewId = 0; + if ( EFsEmailUiCmdSettingsService == aCommand ) + { + activationData.iSubviewId = 1; + } + + TUid pluginUid = iAppUi.GetActiveMailbox()->GetSettingsUid(); + // register plugin view if not exists so that activation can be made + if ( !iAppUi.View( pluginUid ) ) + { + CESMailSettingsPlugin* plugin = CESMailSettingsPlugin::NewL( pluginUid ); + CleanupStack::PushL( plugin ); + iAppUi.AddViewL( plugin ); + CleanupStack::Pop( plugin ); + } + TUid messageId = TUid::Uid( CESMailSettingsPlugin::EActivateMailSettingsSubview ); + const TPckgBuf pluginMessagePkg( activationData ); + iAppUi.EnterPluginSettingsViewL( pluginUid, messageId, pluginMessagePkg ); + } + break; + case EFsEmailUiCmdOpen: + case EFsEmailUiCmdActionsOpen: + { + TIMESTAMP( "Open email selected from message list" ); + if ( iFocusedControl == EMailListComponent ) + { + // Opening can happen only when there's exactly one message marked or in focus + if ( actionTargetItems.Count() == 1 ) + { + OpenMailItemL( actionTargetItems[0] ); + } + } + } + break; + case EFsEmailUiCmdActionsFlag: + { + SetMessageFollowupFlagL(); + } + break; + case EFsEmailUiCmdActionsCollapseAll: + // Safety check, ignore command if the list is empty + if( iMailList->Count() ) + { + CollapseAllNodesL(); + } + break; + case EFsEmailUiCmdActionsExpandAll: + // Safety check, ignore command if the list is empty + if( iMailList->Count() ) + { + ExpandAllNodesL(); + } + break; + case EFsEmailUiCmdCollapse: + if( !iAppUi.IsFocusShown() ) + { + iAppUi.SetFocusVisibility( ETrue ); + break; + } + // Safety check, ignore command if the list is empty + if( iMailList->Count() ) + { + ExpandOrCollapseL(); + } + break; + case EFsEmailUiCmdExpand: + if( !iAppUi.IsFocusShown() ) + { + iAppUi.SetFocusVisibility( ETrue ); + break; + } + // Safety check, ignore command if the list is empty + if( iMailList->Count() ) + { + ExpandOrCollapseL(); + } + break; + case EFsEmailUiCmdSearch: + { + TSearchListActivationData tmp; + tmp.iMailBoxId = iAppUi.GetActiveMailbox()->GetId(); + const TPckgBuf pkgOut( tmp ); + iAppUi.EnterFsEmailViewL( SearchListViewId, KStartNewSearch, pkgOut ); + } + break; +// Prevent Download Manager opening with attachments +// case EFsEmailUiCmdDownloadManager: +// iAppUi.EnterFsEmailViewL( DownloadManagerViewId ); +// break; +// + case EFsEmailUiCmdMarkingModeFromPopUp: + { + EnterMarkingModeL(); + // Mark current item first + TInt focusedItem = iMailList->FocusedItem(); + if ( focusedItem > 0 && iFocusedControl == EMailListComponent ) + { + CFSEmailUiMailListModelItem* item = dynamic_cast(iModel->Item(HighlightedIndex())); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + iMailList->MarkItemL( iMailList->FocusedItem(), ETrue ); + } + else if ( item && item->ModelItemType() == ETypeSeparator ) + { + TInt index = HighlightedIndex(); + MarkItemsUnderSeparatorL( ETrue, index ); + } + } + } + break; + case EFsEmailUiCmdMarkingMode: + { + EnterMarkingModeL(); + } + break; + case EFsEmailUiCmdMarkingModeDelete: + { + DeleteMessagesL(); + } + break; + case EFsEmailUiCmdMarkingModeUnread: + { + ChangeReadStatusOfMarkedL( EFalse ); + ExitMarkingModeL(); + } + break; + case EFsEmailUiCmdMarkingModeRead: + { + ChangeReadStatusOfMarkedL( ETrue ); + ExitMarkingModeL(); + } + break; + case EFsEmailUiCmdMarkingModeFollowUp: + { + SetMessageFollowupFlagL(); + } + break; + case EFsEmailUiCmdMarkingModeMarkAll: + { + MarkAllItemsL(); + } + break; + case EFsEmailUiCmdMarkingModeUnmarkAll: + { + UnmarkAllItemsL(); + } + break; + case EFsEmailUiCmdReadEmail: + { + iAppUi.StartReadingEmailsL(); + } + break; + case EFsEmailUiCmdSync: + { + TBool supportsSync = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaSupportsSync ); + if ( supportsSync ) + { + // If synchronizing is ongoing and a new sync is started we ignore it + if( !GetLatestSyncState() ) + { + iAppUi.SyncActiveMailBoxL(); + // Sync was started by the user + ManualMailBoxSync( ETrue ); + } + } + else + { + //POP3 synchronise + iAppUi.DoAutoConnectL(); + } + } + break; + case EFsEmailUiCmdCancelSync: + { + if ( GetLatestSyncState() ) + { + iAppUi.StopActiveMailBoxSyncL(); + } + } + break; + case EFsEmailUiCmdGoOffline: + { + iAppUi.GetActiveMailbox()->GoOfflineL(); + } + break; + case EFsEmailUiCmdGoOnline: + { + CFSMailBox* mb = iAppUi.GetActiveMailbox(); + mb->GoOnlineL(); + } + break; + case EFsEmailUiCmdHelp: + { + + TFsEmailUiUtility::LaunchHelpL( KFSE_HLP_LAUNCHER_GRID ); + } + break; + + + case EFsEmailUiCmdActionsAddContact: + { + // contact can be got from message only when there's exactly one target message + if ( actionTargetItems.Count() == 1 && iMailFolder ) + { + CFSMailMessage& message = MsgPtrFromListIdL( actionTargetItems[0] ); + + CFSMailAddress* addressToBeStored(0); + TInt folderType = iMailFolder->GetFolderType(); + // Use first to recepient in outbox, drafts and sent if found. + if ( folderType == EFSOutbox || folderType == EFSDraftsFolder || folderType == EFSSentFolder ) + { + RPointerArray& toArray = message.GetToRecipients(); + if ( toArray.Count() ) + { + addressToBeStored = toArray[0]; + } + } + // Use sender in all other "normal" folders + else + { + addressToBeStored = message.GetSender(); + } + TDesC* emailAddressText(0); + if ( addressToBeStored ) + { + emailAddressText = &addressToBeStored->GetEmailAddress(); + } + if ( emailAddressText && emailAddressText->Length() ) + { + TAddToContactsType type; + //Query to "update existing" or "Create new" --> EFALSE = user choosed "cancel" + if ( CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddtoContactsQueryL( type ) ) + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddToContactL( + *emailAddressText, EContactUpdateEmail, type, this ); + } + } + } + } + break; + case EFsEmailUiCmdMarkingModeMove: + { + iMarkingModeWaitingToExit = ETrue; + } + // Flow through + case EFsEmailUiCmdActionsMove: + case EFsEmailUiCmdActionsMoveMessage: + { + TFSMailMsgId folderID; + folderID.SetNullId(); // Selection is popped up with NULL + MoveMsgsToFolderL( folderID ); + } + break; + case EFsEmailUiCmdActionsMoveToDrafts: + { + MoveMessagesToDraftsL(); + } + break; + case EFsEmailUiCmdActionsCopyMessage: + { + } + break; + case EFsEmailUiCmdActionsCollapseExpandAllToggle: + { + ShortcutCollapseExpandAllToggleL(); + } + break; + case EFsEmailUiCmdMarkAsReadUnreadToggle: + { + ShortcutReadUnreadToggleL(); + } + break; + case EFsEmailUiCmdGoToSwitchFolder: + { + iControlBarControl->SetFocusByIdL( iFolderListButtonId ); + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + } + break; + case EFsEmailUiCmdGoToSwitchSorting: + { + iControlBarControl->SetFocusByIdL( iSortButtonId ); + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + } + break; + case EFsEmailUiCmdGoToSwitchNewEmail: + { + iControlBarControl->SetFocusByIdL( iNewEmailButtonId ); + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + break; + } + case EFsEmailUiCmdCalActionsAccept: + case EFsEmailUiCmdCalActionsTentative: + case EFsEmailUiCmdCalActionsDecline: + case EFsEmailUiCmdCalRemoveFromCalendar: + { + if ( actionTargetItems.Count() == 1 ) + { + TInt mrItemIdx = ModelIndexFromListId( actionTargetItems[0] ); + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item(mrItemIdx) ); + if ( item && item->MessagePtr().IsFlagSet( EFSMsgFlag_CalendarMsg ) ) + { + // Respond to meeting request + if ( iAppUi.MrViewerInstanceL() && iAppUi.MrViewerInstanceL()->CanViewMessage( item->MessagePtr() ) ) + { + ChangeReadStatusOfHighlightedL( ETrue ); + iAppUi.MailViewer().HandleMrCommandL( aCommand, + iAppUi.GetActiveMailbox()->GetId(), + FolderId(), + item->MessagePtr().GetMessageId() ); + } + } + } + } + break; + case EFsEmailUiCmdActionsEmptyDeleted: + { + // + if ( iMailFolder && iMailFolder->GetFolderType() == EFSDeleted && + iModel->Count() != 0 ) + // + { + TBool okToDelete( EFalse ); + HBufC* msg = StringLoader::LoadLC( R_FREESTYLE_EMAIL_QUERY_NOTE_PERMANENTLY_DELETE ); + CAknQueryDialog *queryNote = new ( ELeave ) CAknQueryDialog(); + CleanupStack::PushL( queryNote ); + queryNote->SetPromptL( *msg ); + CleanupStack::Pop( queryNote ); + CleanupStack::PopAndDestroy( msg ); + okToDelete = queryNote->ExecuteLD( R_FSEMAIL_QUERY_DIALOG ); + if ( okToDelete ) + { + // Empty deleted items folder + RArray msgIds; + CleanupClosePushL( msgIds ); + for ( TInt i=0 ; iCount();i++ ) + { + CFSEmailUiMailListModelItem* item = + static_cast(iModel->Item(i)); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + msgIds.Append( item->MessagePtr().GetMessageId() ); + } + } + TFSMailMsgId folderId = FolderId(); + TFSMailMsgId mailBox = iAppUi.GetActiveMailbox()->GetId(); + iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, folderId, msgIds ); + RemoveMsgItemsFromListIfFoundL( msgIds ); + CleanupStack::PopAndDestroy( &msgIds ); + } + } + } + break; + case EFsEmailUiCmdSettings: + { + TInt tmp = 0; + const TPckgBuf pkgBuf( tmp ); + iAppUi.EnterFsEmailViewL( SettingsViewId, + TUid::Uid(KMailSettingsOpenMainList), pkgBuf ); + } + break; + + + default: + break; + } // switch ( aCommand ) + CleanupStack::PopAndDestroy( &actionTargetItems ); + TIMESTAMP( "Message list selected operation done" ); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::MoveMsgsToFolderL( const TFSMailMsgId& aDestinationFolderId ) + { + FUNC_LOG; + TInt ret(KErrGeneral); + RFsTreeItemIdList targetEntries; + CleanupClosePushL( targetEntries ); + GetActionsTargetEntriesL( targetEntries ); + TBool supportsMove = iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder ); + // Moving is not possible, if there are no items or the focus is on separator and + // there are no marked items. In outbox, moving is allowed only to the drafts folder; + // folder selection popup is not allowed. + // These have to be checked before launching the folder view. + if ( targetEntries.Count() && supportsMove ) + { + TBool outbox = (iMailFolder && iMailFolder->GetFolderType() == EFSOutbox); + + if ( !(outbox && aDestinationFolderId.IsNullId()) ) + { + // If destination folder is not set, it needs to be asked messages are moved after callbak + if ( aDestinationFolderId.IsNullId() ) + { + // Activate folder selection view and handle moving after callback gets destination + RemoveMarkingModeTitleTextL(); + iMoveToFolderOngoing = ETrue; + TFolderListActivationData folderListData; + folderListData.iCallback = this; + if(iMailFolder) // Coverity error fix , assuming that inbox is best bet for safe data. + { + folderListData.iSourceFolderType = iMailFolder->GetFolderType(); + } + else + { + folderListData.iSourceFolderType = EFSInbox; + } + const TPckgBuf pkgOut( folderListData ); + if ( targetEntries.Count() == 1 ) + { + iAppUi.EnterFsEmailViewL( FolderListId, KFolderListMoveMessage, pkgOut ); + } + else + { + iAppUi.EnterFsEmailViewL( FolderListId, KFolderListMoveMessages, pkgOut ); + } + ret = KErrNotReady; + } + // Destination folder is set, move message(s) immediately + else + { + iMoveToFolderOngoing = EFalse; + // Get message IDs from target list IDs + RArray msgIds; + CleanupClosePushL( msgIds ); + for ( TInt i = 0 ; i < targetEntries.Count() ; i++) + { + msgIds.Append( MsgIdFromListId( targetEntries[i] ) ); + } + + if ( iMailFolder && msgIds.Count() ) // Something to move + { + // check that source and destination are different + if( iMailFolder->GetFolderId() != aDestinationFolderId ) + { + // Trap is needed because protocol might return KErrNotSupported + // If move away from current folder is not supprted + TRAPD( errMove, iAppUi.GetActiveMailbox()->MoveMessagesL( msgIds, iMailFolder->GetFolderId(), aDestinationFolderId ) ); + if ( errMove != KErrNotSupported ) + { + if ( errMove == KErrNone ) + { + RemoveMsgItemsFromListIfFoundL( msgIds ); + if ( !iMsgNoteTimer ) + { + iMsgNoteTimer = CMsgMovedNoteTimer::NewL( &iAppUi, this ); + } + iMsgNoteTimer->Cancel(); + iMsgNoteTimer->Start( msgIds.Count(), aDestinationFolderId ); + ret = KErrNone; + } + else + { + User::Leave(errMove); + } + } + } + } + CleanupStack::PopAndDestroy( &msgIds ); + } + } + } + CleanupStack::PopAndDestroy( &targetEntries ); + return ret; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::MoveMessagesToDraftsL() + { + FUNC_LOG; + if ( iMailFolder && iMailFolder->GetFolderType() == EFSOutbox ) // Move to drafts should only be available from outbox, safety + { + MoveMsgsToFolderL( iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSDraftsFolder ) ); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::CollapseAllNodesL() + { + FUNC_LOG; + // Safety check, ignore command if the list is empty + if ( iMailList->Count() > 0 ) + { + iMailTreeListVisualizer->CollapseAllL(); + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ExpandAllNodesL() + { + FUNC_LOG; + // Safety check, ignore command if the list is empty + if ( iMailList->Count() > 0 ) + { + TFsTreeItemId prevId = iMailList->FocusedItem(); + iMailTreeListVisualizer->ExpandAllL(); + iMailTreeListVisualizer->SetFocusedItemL( prevId ); + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ExpandOrCollapseL() + { + FUNC_LOG; + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item( HighlightedIndex() ) ); + if ( item && item->ModelItemType() == ETypeSeparator ) + { + if ( iMailList->IsExpanded( iMailList->FocusedItem() ) ) + { + //ChangeMskCommandL( R_FSE_QTN_MSK_COLLAPSE ); + iMailList->CollapseNodeL( iMailList->FocusedItem() ); + } + else + { + //ChangeMskCommandL( R_FSE_QTN_MSK_EXPAND ); + iMailList->ExpandNodeL( iMailList->FocusedItem() ); + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetMessageFollowupFlagL() + { + FUNC_LOG; + if ( TFsEmailUiUtility::IsFollowUpSupported( *iAppUi.GetActiveMailbox() ) ) + { + RFsTreeItemIdList targetItems; + CleanupClosePushL( targetItems ); + GetActionsTargetEntriesL( targetItems ); + + // If there are marked or focused item(s) + if ( targetItems.Count() ) + { + // Convert list IDs to message IDs because it's possible that list refresh + // causes list IDs to change while the flag dialog is open + RArray< TFSMailMsgId > targetMsgIds; + CleanupClosePushL( targetMsgIds ); + for ( TInt i = 0 ; i < targetItems.Count() ; ++i ) + { + TFSMailMsgId msgId = MsgIdFromIndex( ModelIndexFromListId( targetItems[i] ) ); + targetMsgIds.AppendL( msgId ); + } + + TFollowUpNewState newFollowUpState = EFollowUpNoChanges; + if ( TFsEmailUiUtility::RunFollowUpListDialogL( newFollowUpState ) ) + { + // Update the target messages + for ( TInt i = 0 ; i < targetMsgIds.Count() ; ++i ) + { + // Confirm that message is still in the list after selection has closed + TInt itemIndex = ItemIndexFromMessageId( targetMsgIds[i] ); + CFSEmailUiMailListModelItem* modelItem = + static_cast( iModel->Item( itemIndex ) ); + CFSMailMessage* confirmedPtr = NULL; // owned by the model + if ( modelItem ) + { + confirmedPtr = &modelItem->MessagePtr(); + } + if ( confirmedPtr ) + { + // Store flags to confirmed pointer for saving + TInt currentFlags = confirmedPtr->GetFlags(); + switch ( newFollowUpState ) + { + case EFollowUp: + { + confirmedPtr->SetFlag( EFSMsgFlag_FollowUp ); + confirmedPtr->ResetFlag( EFSMsgFlag_FollowUpComplete ); + } + break; + case EFollowUpComplete: + { + confirmedPtr->SetFlag( EFSMsgFlag_FollowUpComplete ); + confirmedPtr->ResetFlag( EFSMsgFlag_FollowUp ); + } + break; + case EFollowUpClear: + { + confirmedPtr->ResetFlag( EFSMsgFlag_FollowUp | EFSMsgFlag_FollowUpComplete ); + } + break; + } + + TInt newFlags = confirmedPtr->GetFlags(); + if ( newFlags != currentFlags ) + { + // Save confirmed message + confirmedPtr->SaveMessageL(); + + // Update flag icon + UpdateMsgIconAndBoldingL( itemIndex ); + + // In case we are in flag sort mode, resetting the flag may cause the list order to be out of date. + if ( iCurrentSortCriteria.iField == EFSMailSortByFlagStatus ) + { + iListOrderMayBeOutOfDate = ETrue; + } + } + } + } + if ( iMarkingMode ) + { + ExitMarkingModeL(); + } + } + CleanupStack::PopAndDestroy( &targetMsgIds ); + } + CleanupStack::PopAndDestroy( &targetItems ); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetViewSoftkeysL( TInt aResourceId ) + { + FUNC_LOG; + Cba()->SetCommandSetL( aResourceId ); + Cba()->DrawDeferred(); + } + +// --------------------------------------------------------------------------- +// Method to set Middle SoftKey +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetMskL() + { + FUNC_LOG; + // If there is no keyboard present, than Msk buttom must not be shown + if ( iAppUi.ShortcutBinding().KeyBoardType() == + CFSEmailUiShortcutBinding::ENoKeyboard ) + { + return; + } + // Get the mail list count + TInt listCount(0); + if ( iMailList ) + { + listCount = iMailList->Count(); + } + + if ( iFocusedControl == EControlBarComponent ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_CHANGE ); // change - switch focus on + } + else if ( iFocusedControl == EMailListComponent ) + { + if ( listCount ) // Safety check + { + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item(HighlightedIndex()) ); + // SHIFT DEPRESSED. SELECTION KEY DOES MARK/UNMARK + if ( iShiftDepressed ) + { + // Nodes may not be marked + if ( iMailList->IsNode( iMailList->FocusedItem() ) ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY ); // nothing + } + else + { + if ( iMailList->IsMarked( iMailList->FocusedItem() ) ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_UNMARK ); // unmark item + } + else + { + ChangeMskCommandL( R_FSE_QTN_MSK_MARK ); // mark item + } + } + } + else + { + // MAIL ITEM; OPEN MAIL + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailMessage* messagePtr = &item->MessagePtr(); + if ( messagePtr ) + { + if ( iMailFolder && iMailFolder->GetFolderType() == EFSOutbox ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_OPEN_BLOCKED ); // blocked email opening + } + else + { + ChangeMskCommandL( R_FSE_QTN_MSK_OPEN ); // open email + } + } + } + + // SEPARAOR ITEM; COLLAPSE / EXPAND NODE + else if ( item && item->ModelItemType() == ETypeSeparator ) + { + if( iMailList->IsNode( iMailList->FocusedItem() ) ) + { + if ( iMailList->IsExpanded( iMailList->FocusedItem() ) ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_COLLAPSE ); // collapse folder + } + else + { + ChangeMskCommandL( R_FSE_QTN_MSK_EXPAND ); // expand folder + } + } + } + } + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::OfferEventL( const TAlfEvent& aEvent ) + { + FUNC_LOG; + TBool result( EFalse ); + + if ( !aEvent.IsKeyEvent() ) + { + // Only handle key events + if ( aEvent.IsPointerEvent() ) + { + if( aEvent.PointerDown() ) + { + // If pointer down event was made on control bar area + // focus needs to be changed to control bar control, if it + // didn't already have focus. + if( HitTest( *iControlBarControl, aEvent.PointerEvent().iPosition ) ) + { + if( iFocusedControl != EControlBarComponent ) + { + SetControlBarFocusedL(); + } + } + else + { + // If pointer down event was not made on control bar area + // then focus need to be set to mail list component, if it + // didn't already have focus. If mail list is empty, then + // focus is hidden and control bar stays as a focused item. + if( ( iFocusedControl != EMailListComponent ) && + ( iMailList->Count() > 0 ) ) + { + SetTreeListFocusedL(); + } + else + { + iAppUi.SetFocusVisibility( EFalse ); + } + } + } + + // Offer event to focused control. + if( iFocusedControl == EMailListComponent ) + { + result = iMailList->TreeControl()->OfferEventL( aEvent ); + } + else // iFocusedControl == EControlBarComponent + { + result = static_cast( + iControlBarControl )->OfferEventL( aEvent ); + } + } + return result; + } + + TInt scanCode = aEvent.KeyEvent().iScanCode; + // Swap right and left controls in mirrored layout + if ( AknLayoutUtils::LayoutMirrored() ) + { + if ( scanCode == EStdKeyRightArrow ) + { + scanCode = EStdKeyLeftArrow; + } + else if ( scanCode == EStdKeyLeftArrow ) + { + scanCode = EStdKeyRightArrow; + } + } + + // Toggle mark items state when shift key is pressed or released + if ( iFocusedControl == EMailListComponent && + ( scanCode == EStdKeyLeftShift || + scanCode == EStdKeyRightShift || + scanCode == EStdKeyHash ) ) + { + if ( aEvent.Code() == EEventKeyDown ) + { + iShiftDepressed = ETrue; + iOtherKeyPressedWhileShiftDepressed = EFalse; + if ( iModel->Count() && iMailList->IsMarked( iMailList->FocusedItem() ) ) + { + iListMarkItemsState = EFalse; // Unmark state + } + else + { + iListMarkItemsState = ETrue; // Mark items state + } + } + else if ( aEvent.Code() == EEventKeyUp ) + { + iShiftDepressed = EFalse; + } + } + + // If any other key event is gained while hash is depressed, the hash key is used only + // as shift and not as individual key. + if ( iShiftDepressed && scanCode && + scanCode != EStdKeyHash && scanCode != EStdKeyLeftShift && scanCode != EStdKeyRightShift ) + { + iOtherKeyPressedWhileShiftDepressed = ETrue; + } + + // MSK label can now be updated when shift key has been handled + SetMskL(); + // On KeyUp of EStdKeyYes usually Call application is called - prevent it + if ( iConsumeStdKeyYes_KeyUp && (aEvent.Code() == EEventKeyUp )) + { + iConsumeStdKeyYes_KeyUp = EFalse; // in case call button was consumed elsewhere first key up enables calling Call application + if ( EStdKeyYes == scanCode) + { + result = ETrue; // consume not to switch to Call application when call to contact was processed + return result; + } + } + + if ( aEvent.IsKeyEvent() && aEvent.Code() == EEventKey ) + { + TBool shiftState = ( aEvent.KeyEvent().iModifiers & EModifierShift ); + + // Do the (un)marking if in shift state and suitable key is received + if ( shiftState ) + { + switch ( aEvent.KeyEvent().iScanCode ) + { + case EStdKeyDownArrow: + case EStdKeyUpArrow: + { + DoScrollMarkUnmarkL(); + result = EFalse; // event is not consumed yet, because it must also move the cursor + } + break; + case EStdKeyEnter: + case EStdKeyDevice3: + { + if ( !aEvent.KeyEvent().iRepeats ) // no repeated (un)marking by holding selection key depressed + { + // The selection key always toggles the marking state of the current item. + // It also toggles the scroll marking/unmarking state. + if ( iModel->Count() ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( HighlightedIndex() ) ); + + if ( item && item->ModelItemType() == ETypeMailItem ) // Separators are not markable + { + if ( iMailList->IsMarked( iMailList->FocusedItem() ) ) + { + iMailList->MarkItemL( iMailList->FocusedItem(), EFalse ); + iListMarkItemsState = EFalse; + } + else + { + iMailList->MarkItemL( iMailList->FocusedItem(), ETrue ); + iListMarkItemsState = ETrue; + } + } + } + } + result = ETrue; // shift + selection is always consumed + } + break; + default: + break; + } + + } + + // If event not handled by now + if ( !result ) + { + // Handle possible focus visibility change + if ( ( scanCode == EStdKeyRightArrow ) || + ( scanCode == EStdKeyLeftArrow ) || + ( scanCode == EStdKeyUpArrow ) || + ( scanCode == EStdKeyDownArrow ) || + ( scanCode == EStdKeyEnter ) || + ( scanCode == EStdKeyDeviceA ) || + ( scanCode ==EStdKeyDevice3 ) ) + { + // If the focus was not active already, ignore the key press + if( !iAppUi.SetFocusVisibility( ETrue ) ) + { + return ETrue; + } + } + + switch ( scanCode ) + { + case EStdKeyDevice3: // CENTER CLICK + case EStdKeyEnter: // ENTER EITHER SELECTS ITEM IN TOOLBAR OR OPENS MAIL + case EStdKeyNkpEnter: + case EAknSoftkeySelect: + { + SetMskL(); + if ( iFocusedControl == EMailListComponent ) + { + TInt modelCount( modelCount = iModel->Count() ); + if ( modelCount ) // Safety check + { + if (iMarkingMode) + { + //Do not open mail or expand/collapse separator in marking mode + DoHandleListItemOpenL(); + } + else + { + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item( HighlightedIndex() ) ); + // MAIL ITEM; OPEN MAIL + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailMessage* messagePtr = &item->MessagePtr(); + if ( messagePtr ) + { + TIMESTAMP( "Open email selected from message list" ); + OpenHighlightedMailL(); + return EKeyWasConsumed; + } + } + // SEPARAOR ITEM; COLLAPSE / EXPAND NODE + else if ( item && item->ModelItemType() == ETypeSeparator ) + { + ExpandOrCollapseL(); + return EKeyWasConsumed; + } + } + } + } + else + { + TInt focusedButtonId( iControlBarControl->GetFocusedButton()->Id() ); + if ( focusedButtonId == iNewEmailButtonId ) + { + HandleCommandL(EFsEmailUiCmdCompose); + } + else if ( focusedButtonId == iFolderListButtonId ) + { + // Set touchmanager not active for preventing getting events. + DisableMailList( ETrue ); + iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton ); + } + else if ( focusedButtonId == iSortButtonId ) + { + TFSFolderType folderType; + if( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + else + { + folderType = EFSInbox; + } + // Show sort if model has data. + if ( iModel->Count() ) + { + // Set touchmanager not active for preventing getting events. + DisableMailList(ETrue); + iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton ); + } + else + { + // hide selector focus if popup is not opened + // and selection was not made via HW-keys + iControlBarControl->MakeSelectorVisible( + IsFocusShown() ); + } + } + return ETrue; // iControlBar->OfferEventL( aEvent ); + } + } + break; + case EStdKeyLeftArrow: + case EStdKeyRightArrow: + case EStdKeyDownArrow: + case EStdKeyUpArrow: + { + if( Layout_Meta_Data::IsLandscapeOrientation() ) + { + result = HandleArrowEventInLandscapeL( scanCode, + aEvent, shiftState ); + } + else + { + result = HandleArrowEventInPortraitL( scanCode, + aEvent, shiftState ); + } + break; + } + case EStdKeyYes: + { + if ( !iAppUi.ViewSwitchingOngoing() ) + { + if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox && + iMailFolder->GetFolderType() != EFSDraftsFolder ) + { + TInt modelCount = iModel->Count(); + if ( modelCount ) // Safety check + { + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item( HighlightedIndex() ) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailAddress* fromAddress = item->MessagePtr().GetSender(); + TDesC* mailAddress(0); + if ( fromAddress ) + { + mailAddress = &fromAddress->GetEmailAddress(); + } + if ( mailAddress && mailAddress->Length() ) + { + if ( iMailFolder->GetFolderType() == EFSSentFolder ) + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( + *mailAddress, iAppUi.GetActiveMailbox(), this, EFalse ); + } + else + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( + *mailAddress, iAppUi.GetActiveMailbox(), this, ETrue ); + } +// consume following KyUp event to prevent execution of Call application when call to contact processing + iConsumeStdKeyYes_KeyUp = result = ETrue; + } + } + } + } + } + } + break; + case EStdKeyHash: + { + // Consume hash key events before they go to our shortcut framework. We do not want + // to react to those until the in the key up event. There hash key works as mark/unmark shortcut only + // if it hasn't been used as shift modifier. + result = ETrue; + } + break; + // Backspace (C key) must be handled on Key-Down instead of Key-Up + // ( this was the reason that deleted two emails from opened mail in viewer ) + case EStdKeyBackspace: + { + TInt shortcutCommand = iAppUi.ShortcutBinding().CommandForShortcutKey( aEvent.KeyEvent(), + CFSEmailUiShortcutBinding::EContextMailList ); + + if ( shortcutCommand != KErrNotFound ) + { + HandleCommandL( shortcutCommand ); + result = ETrue; + } + else result = EFalse; + } + break; + default: + { + if ( iFocusedControl == EMailListComponent ) + { + result = iMailList->TreeControl()->OfferEventL(aEvent); + } + else + { + result = EFalse; + } + } + break; + } + } + } + else if ( aEvent.IsKeyEvent() && aEvent.Code() == EEventKeyUp ) + { + // Check keyboard shortcuts on key up events. These can't be checked on key event + // because half-QWERTY keyboad has shortcuts also on shift and chr keys which do + // no send any key events, only key down and key up. + TInt shortcutCommand = + iAppUi.ShortcutBinding().CommandForShortcutKey( aEvent.KeyEvent(), + CFSEmailUiShortcutBinding::EContextMailList ); + + // Hash/shift key of ITU-T and half-QWERTY keyboards is an exception case to other + // shortcuts: it is handled only if it hasn't been used as shift modifier + if ( (scanCode == EStdKeyHash || scanCode == EStdKeyLeftShift || scanCode == EStdKeyRightShift) && + iOtherKeyPressedWhileShiftDepressed ) + { + shortcutCommand = KErrNotFound; + } + + // block Backspace (C key) handle on Key-Up + if ( scanCode == EStdKeyBackspace ) + { + shortcutCommand = KErrNotFound; // handled on Key-Down, see above + } + + if ( shortcutCommand != KErrNotFound ) + { + HandleCommandL( shortcutCommand ); + result = ETrue; + } + else + { + result = EFalse; + } + } + + return result; + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::DoHandleListItemOpenL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DoHandleListItemOpenL() + { + FUNC_LOG; + if ( 0 < iModel->Count() ) // Safety check + { + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item( HighlightedIndex() ) ); + if ( iMarkingMode ) + { + // In marking mode. Mark/unmark it instead of opening it. + if ( item && item->ModelItemType() == ETypeMailItem ) + { + if (iMailList->IsMarked( iMailList->FocusedItem() )) + { + iMailList->MarkItemL( iMailList->FocusedItem(), EFalse ); + } + else + { + iMailList->MarkItemL( iMailList->FocusedItem(), ETrue ); + } + } + else if ( item && item->ModelItemType() == ETypeSeparator ) + { + TInt index = HighlightedIndex(); + if ( AreAllItemsMarkedUnderSeparatorL( index ) ) + { + MarkItemsUnderSeparatorL( EFalse, index ); + } + else + { + MarkItemsUnderSeparatorL( ETrue, index ); + } + } + } + else if ( iAppUi.CurrentActiveView() == this ) + { + + // MAIL ITEM; OPEN MAIL + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailMessage* messagePtr = &item->MessagePtr(); + if ( messagePtr ) + { + TIMESTAMP( "Open email selected from message list" ); + OpenHighlightedMailL(); + } + + // Give feedback to user (vibration) + iTouchFeedBack->InstantFeedback(ETouchFeedbackBasic); + } + // SEPARATOR ITEM; COLLAPSE / EXPAND NODE + else if ( item && item->ModelItemType() == ETypeSeparator ) + { + ExpandOrCollapseL(); + SetMskL(); + } + } + } + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::DoHandleControlBarOpenL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DoHandleControlBarOpenL( TInt aControlBarButtonId ) + { + FUNC_LOG; + + if ( aControlBarButtonId == iNewEmailButtonId ) + { + HandleCommandL(EFsEmailUiCmdCompose); + } + else if ( aControlBarButtonId == iFolderListButtonId ) + { + //FOLDERLIST + //Set touchmanager not active for preventing getting events. + DisableMailList(ETrue); + iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton ); + } + else if ( aControlBarButtonId == iSortButtonId ) + { + //SORTLIST + TFSFolderType folderType; + if ( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + else + { + folderType = EFSInbox; + } + // we can't show sort list when sorting is active + if ( iModel->Count() && iSortState == ESortNone ) + { + //Set touchmanager not active for preventing getting events. + DisableMailList(ETrue); + iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton ); + } + else + { + // hide selector focus if popup is not opened and selection was not + // made via HW-keys + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + } + } + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::DoHandleListItemLongTapL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DoHandleListItemLongTapL( const TPoint& aPoint ) + { + FUNC_LOG; + + if ( 0 < iModel->Count() ) // Safety check + { + if ( iMarkingMode ) + { + iMailTreeListVisualizer->SetFocusVisibility( EFalse ); + TInt currentFocusState = iMailList->IsFocused(); + iMailList->SetFocusedL( EFalse ); + iMailList->SetFocusedL( currentFocusState ); + CFSEmailUiMailListModelItem* item = + dynamic_cast( iModel->Item( HighlightedIndex() ) ); + // In marking mode. Mark/unmark it instead of open popup. + if ( item && item->ModelItemType() == ETypeMailItem ) + { + if (iMailList->IsMarked( iMailList->FocusedItem() )) + { + iMailList->MarkItemL( iMailList->FocusedItem(), EFalse ); + } + else + { + iMailList->MarkItemL( iMailList->FocusedItem(), ETrue ); + } + } + else if ( item && item->ModelItemType() == ETypeSeparator ) + { + TInt index = HighlightedIndex(); + if ( AreAllItemsMarkedUnderSeparatorL( index ) ) + { + MarkItemsUnderSeparatorL( EFalse, index ); + } + else + { + MarkItemsUnderSeparatorL( ETrue, index ); + } + } + } + else + { + LaunchStylusPopupMenuL( aPoint ); + } + } + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::GetFocusedControl +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::GetFocusedControl() const + { + FUNC_LOG; + return iFocusedControl; + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::SetControlBarFocusedL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetControlBarFocusedL() + { + FUNC_LOG; + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + SetMskL(); + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::SetTreeListFocusedL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetTreeListFocusedL() + { + FUNC_LOG; + iFocusedControl = EMailListComponent; + iMailList->SetFocusedL( ETrue ); + iControlBarControl->SetFocusL( EFalse ); + SetMskL(); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::FlipStateChangedL +// ----------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::FlipStateChangedL( TBool aKeyboardFlipOpen ) + { + FUNC_LOG; + CFsEmailUiViewBase::FlipStateChangedL( aKeyboardFlipOpen ); + iMailTreeListVisualizer->SetFlipState( iKeyboardFlipOpen ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::HandleTimerFocusStateChange +// ----------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::FocusVisibilityChange( TBool aVisible ) + { + FUNC_LOG; + + CFsEmailUiViewBase::FocusVisibilityChange( aVisible ); + + if( iFocusedControl == EControlBarComponent ) + { + iControlBarControl->MakeSelectorVisible( aVisible ); + } + + if ( iStylusPopUpMenuVisible && !aVisible ) + { + // Do not allow to remove the focus from a list element if the pop up + // menu was just launched. + return; + } + + iMailTreeListVisualizer->SetFocusVisibility( aVisible ); + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::DisableMailList +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DisableMailList( TBool aValue ) + { + FUNC_LOG; + iTouchManager->SetDisabled( aValue ); + iControlBarControl->EnableTouch( (aValue) ? EFalse : ETrue ); + } +// + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ShortcutCollapseExpandAllToggleL() + { + FUNC_LOG; + if ( !AllNodesCollapsed() ) + { + CollapseAllNodesL(); + } + else + { + ExpandAllNodesL(); + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::AllNodesCollapsed() const + { + FUNC_LOG; + for ( TInt i=0;iIsNode( iTreeItemArray[i].iListItemId ) ) + { + if ( iMailList->IsExpanded( iTreeItemArray[i].iListItemId ) ) + { + return EFalse; + } + } + } + + return ETrue; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::AllNodesExpanded() const + { + FUNC_LOG; + for ( TInt i=0;iIsNode( iTreeItemArray[i].iListItemId ) ) + { + if ( !iMailList->IsExpanded( iTreeItemArray[i].iListItemId ) ) + { + return EFalse; + } + } + } + + return ETrue; + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::IsMarkAsReadAvailableL() +// Function checks if mark as read option should be available for user +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::IsMarkAsReadAvailableL() const + { + FUNC_LOG; + TBool available = EFalse; + + // In outbox the mark as read is always inavailable + if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox ) + { + RFsTreeItemIdList targetEntries; + CleanupClosePushL( targetEntries ); + GetActionsTargetEntriesL( targetEntries ); + + // Mark as read is available if at least one of the target entries is unread + for ( TInt i = 0 ; i < targetEntries.Count() ; ++i ) + { + const CFSMailMessage& message = MsgPtrFromListIdL( targetEntries[i] ); + if ( !message.IsFlagSet(EFSMsgFlag_Read) ) + { + available = ETrue; + break; + } + } + + CleanupStack::PopAndDestroy( &targetEntries ); + } + + return available; + } + +// --------------------------------------------------------------------------- +// CFSEmailUiMailListVisualiser::IsMarkAsUnreadAvailableL() +// Function checks if mark as unread option should be available for user +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::IsMarkAsUnreadAvailableL() const + { + FUNC_LOG; + TBool available = EFalse; + + // In outbox the mark as unread is always inavailable + if ( iMailFolder && iMailFolder->GetFolderType() != EFSOutbox ) + { + RFsTreeItemIdList targetEntries; + CleanupClosePushL( targetEntries ); + GetActionsTargetEntriesL( targetEntries ); + + // Mark as unread is available if at least one of the target entries is read + for ( TInt i = 0 ; i < targetEntries.Count() ; ++i ) + { + const CFSMailMessage& message = MsgPtrFromListIdL( targetEntries[i] ); + if ( message.IsFlagSet(EFSMsgFlag_Read) ) + { + available = ETrue; + break; + } + } + + CleanupStack::PopAndDestroy( &targetEntries ); + } + + return available; + } + +// --------------------------------------------------------------------------- +// Utility function to get list of entries which will be targeted by the +// Actions menu commands. The list contains either marked entries or the +// focused message entry or is empty. +// --------------------------------------------------------------------------- +void CFSEmailUiMailListVisualiser::GetActionsTargetEntriesL( RFsTreeItemIdList& aListItems ) const + { + FUNC_LOG; + if ( iMailList ) + { + iMailList->GetMarkedItemsL( aListItems ); + + // If there are no marked entries the command target is the focused item. + if ( !aListItems.Count() ) + { + TFsTreeItemId focusedId = iMailList->FocusedItem(); + if ( iFocusedControl == EMailListComponent && + focusedId != KFsTreeNoneID && + !iMailList->IsNode( focusedId ) ) + { + aListItems.AppendL( focusedId ); + } + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ShortcutReadUnreadToggleL() + { + FUNC_LOG; + // Setting the read status is not possible in outbox + // + if ( iModel->Count() && iMailFolder && iMailFolder->GetFolderType() != EFSOutbox ) + // + { + RFsTreeItemIdList targetEntries; + CleanupClosePushL( targetEntries ); + GetActionsTargetEntriesL( targetEntries ); + TInt targetCount = targetEntries.Count(); + + // figure out are we marking items as read or unread + TBool toggleAsRead(ETrue); + for ( TInt i=0 ; iSetFocusedL( ETrue ) ); + break; + } + case EEventFocusGained: + { + break; + } + case EEventButtonPressed: + { + // Handle 2 control buttons + if ( aData == iFolderListButtonId ) + { + } + else if ( aData == iSortButtonId ) + { + } + break; + } + case EEventFocusVisibilityChanged: + { + // Hide focus after button release + iAppUi.SetFocusVisibility( EFalse ); + break; + } + default: + { + // No need to handle other events + break; + } + } + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::CreateControlBarLayoutL() + { + FUNC_LOG; + iControlBarControl->SetRectL( iAppUi.LayoutHandler()->GetControlBarRect() ); + + // New email button + iNewEmailButtonId = iControlBarControl->AddButtonL( ECBTypeOneLineLabelIconA ); + iNewEmailButton = iControlBarControl->ButtonById( iNewEmailButtonId ); + const TRect mailButtonRect( iAppUi.LayoutHandler()->GetControlBarNewEmailButtonRect() ); + iNewEmailButton->SetPos( mailButtonRect.iTl ); + iNewEmailButton->SetSize( mailButtonRect.Size() ); + ControlGroup().AppendL(iNewEmailButton->AsAlfControl()); + + // Folder list button + iFolderListButtonId = iControlBarControl->AddButtonL( ECBTypeOneLineLabelIconA ); + iFolderListButton = iControlBarControl->ButtonById( iFolderListButtonId ); + const TRect folderButtonRect( iAppUi.LayoutHandler()->GetControlBarFolderListButtonRect() ); + iFolderListButton->SetPos( folderButtonRect.iTl ); + iFolderListButton->SetSize( folderButtonRect.Size() ); + ControlGroup().AppendL(iFolderListButton->AsAlfControl()); + + // Sort order button + iSortButtonId = iControlBarControl->AddButtonL( ECBTypeOneLineLabelIconA ); + iSortButton = iControlBarControl->ButtonById( iSortButtonId ); + const TRect sortButtonRect( iAppUi.LayoutHandler()->GetControlBarSortButtonRect() ); + iSortButton->SetPos( sortButtonRect.iTl ); + iSortButton->SetSize( sortButtonRect.Size() ); + ControlGroup().AppendL(iSortButton->AsAlfControl()); +// + + // Set the text alignment according the layout + TAlfAlignHorizontal horizontalAlign = EAlfAlignHLeft; + if ( AknLayoutUtils::LayoutMirrored() ) + { + horizontalAlign = EAlfAlignHRight; + } + + // Icons and sort button text + iFolderListButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListControlBarMailboxDefaultIcon ) ); + iNewEmailButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListTextureCreateNewMessageIcon ) ); + SetSortButtonTextAndIconL(); + + iNewEmailButton->SetElemAlignL( + ECBElemIconA, + EAlfAlignHCenter, + EAlfAlignVCenter ); + + iFolderListButton->SetElemAlignL( + ECBElemLabelFirstLine, + horizontalAlign, + EAlfAlignVCenter ); + iSortButton->SetElemAlignL( + ECBElemLabelFirstLine, + horizontalAlign, + EAlfAlignVCenter ); + iSortButton->SetElemAlignL( + ECBElemIconA, + EAlfAlignHCenter, + EAlfAlignVCenter ); + + // Show the buttons + iNewEmailButton->ShowButtonL(); + iFolderListButton->ShowButtonL(); + iSortButton->ShowButtonL(); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ScaleControlBarL() + { + FUNC_LOG; + + if( !Layout_Meta_Data::IsLandscapeOrientation() && iMarkingMode) + { + // No control bar buttons in portrait marking mode + return; + } + + TRect screenRect = iAppUi.ClientRect(); + + // First set pos, widht and height + iControlBarControl->SetRectL( iAppUi.LayoutHandler()->GetControlBarRect() ); + + const TRect newEmailButtonRect( iAppUi.LayoutHandler()->GetControlBarNewEmailButtonRect() ); + //Add comments by luo gen(e0645320) + //The position of button should be set according to the size of button, so set size first + iNewEmailButton->SetSize( newEmailButtonRect.Size() ); + iNewEmailButton->SetPos( newEmailButtonRect.iTl ); + + const TRect folderButtonRect( iAppUi.LayoutHandler()->GetControlBarFolderListButtonRect() ); + iFolderListButton->SetSize( folderButtonRect.Size() ); + iFolderListButton->SetPos( folderButtonRect.iTl ); + + const TRect sortButtonRect( iAppUi.LayoutHandler()->GetControlBarSortButtonRect() ); + iSortButton->SetSize( sortButtonRect.Size() ); + iSortButton->SetPos( sortButtonRect.iTl ); + + TInt var = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0; + TAknLayoutText textLayout; + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + textLayout.LayoutText(TRect(0,0,0,0), AknLayoutScalable_Apps::cmail_ddmenu_btn02_pane_t2(0)); + } + else + { + textLayout.LayoutText(TRect(0,0,0,0), AknLayoutScalable_Apps::main_sp_fs_ctrlbar_ddmenu_pane_t1(var)); + } + iNewEmailButton->SetTextFontL( textLayout.Font()->FontSpecInTwips() ); + iFolderListButton->SetTextFontL( textLayout.Font()->FontSpecInTwips() ); + iSortButton->SetTextFontL( textLayout.Font()->FontSpecInTwips() ); + + UpdateThemeL(EFalse); + + iNewEmailButton->ShowButtonL(); + iFolderListButton->ShowButtonL(); + iSortButton->ShowButtonL(); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetSortButtonTextAndIconL() + { + FUNC_LOG; + + // Set button text if necessary + HBufC* buttonText = GetSortButtonTextLC(); + + if ( !Layout_Meta_Data::IsLandscapeOrientation() ) + { + if ( buttonText ) + { + buttonText->Des().Zero(); + } + } + + if ( buttonText ) + { + iSortButton->SetTextL( *buttonText ); + } + CleanupStack::PopAndDestroy( buttonText ); + + iSortButton->SetIconL( + iAppUi.FsTextureManager()->TextureByIndex( GetSortButtonTextureIndex() ), + ECBElemIconA ); + + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +TFSEmailUiTextures CFSEmailUiMailListVisualiser::GetSortButtonTextureIndex() + { + FUNC_LOG; + + TFSEmailUiTextures textureIndex( ETextureFirst ); + switch ( iCurrentSortCriteria.iField ) + { + case EFSMailSortBySubject: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListSubjectDescTexture : + ESortListSubjectAscTexture; + } + break; + case EFSMailSortByAttachment: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListAttachmentDescTexture : + ESortListAttachmentAscTexture; + } + break; + case EFSMailSortByFlagStatus: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListFollowDescTexture : + ESortListFollowAscTexture; + } + break; + case EFSMailSortByRecipient: + case EFSMailSortBySender: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListSenderDescTexture : + ESortListSenderAscTexture; + } + break; + case EFSMailSortByPriority: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListPriorityDescTexture : + ESortListPriorityAscTexture; + } + break; + case EFSMailSortByUnread: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListUnreadDescTexture : + ESortListUnreadAscTexture; + } + break; + case EFSMailSortByDate: + default: + { + textureIndex = iCurrentSortCriteria.iOrder == EFSMailAscending ? + ESortListDateDescTexture : + ESortListDateAscTexture; + } + break; + } + return textureIndex; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +HBufC* CFSEmailUiMailListVisualiser::GetSortButtonTextLC() + { + FUNC_LOG; + HBufC* buttonText( 0 ); + + switch ( iCurrentSortCriteria.iField ) + { + case EFSMailSortBySubject: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_SUBJECT ); + } + break; + case EFSMailSortByAttachment: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_ATTACHMENT ); + } + break; + case EFSMailSortByFlagStatus: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_FLAG ); + } + break; + case EFSMailSortByRecipient: + case EFSMailSortBySender: + { + TFSFolderType folderType( EFSInbox ); + if( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + switch( folderType ) + { + case EFSSentFolder: + case EFSDraftsFolder: + case EFSOutbox: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_RECIPIENT ); + } + break; + default: + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_SENDER ); + break; + } + } + break; + case EFSMailSortByPriority: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_PRIORITY ); + } + break; + case EFSMailSortByUnread: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_UNREAD ); + } + break; + case EFSMailSortByDate: + default: + { + buttonText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_SORT_BY_DATE ); + } + break; + } + return buttonText; + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SetMailListLayoutAnchors() + { + FUNC_LOG; + // Set anchors so that list leaves space for control bar + iScreenAnchorLayout->SetAnchor(EAlfAnchorTopLeft, 0, + EAlfAnchorOriginLeft, EAlfAnchorOriginTop, + EAlfAnchorMetricRelativeToSize, EAlfAnchorMetricRelativeToSize, + TAlfTimedPoint(0, 0 )); + iScreenAnchorLayout->SetAnchor(EAlfAnchorBottomRight, 0, + EAlfAnchorOriginLeft, EAlfAnchorOriginTop, + EAlfAnchorMetricRelativeToSize, EAlfAnchorMetricAbsolute, + TAlfTimedPoint(1, iAppUi.LayoutHandler()->ControlBarHeight() )); + + // Platform layout changes + TRect listRect = iAppUi.LayoutHandler()->GetListRect(); + // Set anchors so that list leaves space for control bar + if( Layout_Meta_Data::IsMirrored() ) + { + TInt tlX = listRect.iTl.iX; + TInt brX = listRect.iBr.iX; + + listRect.iTl.iX = AknLayoutScalable_Avkon::Screen().LayoutLine().iW - brX; + listRect.iBr.iX = AknLayoutScalable_Avkon::Screen().LayoutLine().iW - tlX; + } + iScreenAnchorLayout->SetAnchor(EAlfAnchorTopLeft, 1, + EAlfAnchorOriginLeft, EAlfAnchorOriginTop, + EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute, + TAlfTimedPoint(listRect.iTl.iX, listRect.iTl.iY)); + iScreenAnchorLayout->SetAnchor(EAlfAnchorBottomRight, 1, + EAlfAnchorOriginLeft, EAlfAnchorOriginTop, + EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute, + TAlfTimedPoint(listRect.iBr.iX, listRect.iBr.iY)); + // Platform layout changes + + // Set anchors for connection icon + + // Platform layout changes + TRect connectionIconRect( iAppUi.LayoutHandler()->GetControlBarConnectionIconRect() ); + const TPoint& tl( connectionIconRect.iTl ); + iScreenAnchorLayout->SetAnchor(EAlfAnchorTopLeft, 2, + EAlfAnchorOriginLeft, EAlfAnchorOriginTop, + EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute, + TAlfTimedPoint( tl.iX, tl.iY )); + const TPoint& br( connectionIconRect.iBr ); + iScreenAnchorLayout->SetAnchor(EAlfAnchorBottomRight, 2, + EAlfAnchorOriginLeft, EAlfAnchorOriginTop, + EAlfAnchorMetricAbsolute, EAlfAnchorMetricAbsolute, + TAlfTimedPoint( br.iX, br.iY )); + // Platform layout changes + + iScreenAnchorLayout->UpdateChildrenLayout(); + } + +// --------------------------------------------------------------------------- +// +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ChangeReadStatusOfHighlightedL( TBool aRead ) + { + FUNC_LOG; + ChangeReadStatusOfIndexL( aRead, HighlightedIndex() ); + } + +// --------------------------------------------------------------------------- +// ChangeReadStatusOfMarkedL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ChangeReadStatusOfMarkedL( TBool aRead ) + { + FUNC_LOG; + RFsTreeItemIdList markedEntries; + CleanupClosePushL( markedEntries ); + iMailList->GetMarkedItemsL( markedEntries ); + for ( TInt i=0; i + if ( iModel->Count() ) + // + { + CFSEmailUiMailListModelItem* selectedItem = + static_cast( iModel->Item( aIndex )); + if ( selectedItem ) // Safety + { + CFSMailMessage& msgPtr = selectedItem->MessagePtr(); + TBool msgWasReadBefore = msgPtr.IsFlagSet( EFSMsgFlag_Read ); + if ( aRead != msgWasReadBefore ) + { + if ( aRead ) + { + // Send flags, local and server + msgPtr.SetFlag( EFSMsgFlag_Read ); + } + else + { + // Send flags, local and server + msgPtr.ResetFlag( EFSMsgFlag_Read ); + } + msgPtr.SaveMessageL(); // Save flag + + // Switch icon to correct one if mail list is visible + TBool needRefresh = ( iAppUi.CurrentActiveView()->Id() == MailListId ); + UpdateMsgIconAndBoldingL( aIndex, needRefresh); + + if ( iCurrentSortCriteria.iField == EFSMailSortByUnread ) + { + // Attribute affecting the current sorting order has been changed. + // Thus, the list order may now be incorrect. + iListOrderMayBeOutOfDate = ETrue; + } + } + } + } + } + +// --------------------------------------------------------------------------- +// DeleteMessagesL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DeleteMessagesL() + { + FUNC_LOG; + const TInt markedCount(CountMarkedItemsL()); + const TFsTreeItemId focusedId(iMailList->FocusedItem()); + + // Delete either marked items or the focused one + if (markedCount) + { + DeleteMarkedMessagesL(); + } + else if (iMailList->IsNode(focusedId)) + { + DeleteMessagesUnderNodeL(focusedId); + } + else + { + DeleteFocusedMessageL(); + } + + // Set highlight to control bar if no items after delete + // + if ( iModel->Count() == 0 ) + // + { + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + iControlBarControl->SetFocusL(); + } + } + +// --------------------------------------------------------------------------- +// UpdateItemAtIndexL +// Reload message pointer from mail client and update list item contents to +// match it. Item is removed if it isn't valid anymore. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateItemAtIndexL( TInt aIndex ) + { + FUNC_LOG; + // + + if ( aIndex >= 0 && aIndex < iModel->Count() ) + // + { + CFSEmailUiMailListModelItem* modelItem = + static_cast( Model()->Item( aIndex ) ); + if ( modelItem && modelItem->ModelItemType() == ETypeMailItem ) + { + // This is beacause message deleted event migh have occured. + CFSMailMessage* confirmedMsgPtr = NULL; + TRAP_IGNORE( confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iAppUi.GetActiveMailboxId(), + iMailFolder->GetFolderId(), + modelItem->MessagePtr().GetMessageId() , + EFSMsgDataEnvelope ) ); + if( aIndex < iTreeItemArray.Count() ) + { + if ( confirmedMsgPtr ) + { + const SMailListItem& item = iTreeItemArray[aIndex]; + // Replace message pointer in model with newly fetched one + Model()->ReplaceMessagePtr( aIndex, confirmedMsgPtr ); + + // Update the list item contents and formating to match the message pointer + CFsTreePlainTwoLineItemData* itemData = + static_cast( item.iTreeItemData ); + CFsTreePlainTwoLineItemVisualizer* itemVis = + static_cast( item.iTreeItemVisualiser ); + + UpdateItemDataL( itemData, confirmedMsgPtr ); + UpdatePreviewPaneTextForItemL( itemData, confirmedMsgPtr ); + UpdateMsgIconAndBoldingL( itemData, itemVis, confirmedMsgPtr ); + iMailTreeListVisualizer->UpdateItemL( item.iListItemId ); + } + else + { + // No confirmed message for highlighted, remove from list also + iMailList->RemoveL( iTreeItemArray[aIndex].iListItemId ); // remove from list + iTreeItemArray.Remove( aIndex ); // remove from internal array. + iModel->RemoveAndDestroy( aIndex ); // Remove from model + if ( iNodesInUse ) + { + RemoveUnnecessaryNodesL(); + } + } + } + } + } + } + +// --------------------------------------------------------------------------- +// CheckValidityOfHighlightedMsgL +// Check validity of highlighted msg, and remove from list if needed +// Typically called after view is returned from editot or viewer. +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::CheckValidityOfHighlightedMsgL() + { + FUNC_LOG; + TBool ret(EFalse); + // + if ( iModel->Count() ) + // + { + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item( HighlightedIndex() ) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + // This is beacause message deleted event migh have occured. + CFSMailMessage* confirmedMsgPtr = NULL; + TRAP_IGNORE( confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL( iAppUi.GetActiveMailboxId(), + iMailFolder->GetFolderId(), + item->MessagePtr().GetMessageId() , + EFSMsgDataEnvelope ) ); + if ( confirmedMsgPtr ) + { + ret = ETrue; + delete confirmedMsgPtr; + confirmedMsgPtr = NULL; + } + else + { + // No confirmed message for highlighted, remove from list also + ret = EFalse; + SMailListItem item; + item.iListItemId = iMailList->FocusedItem(); + TInt IndexToBeDestroyed = iTreeItemArray.Find( item ); + iTreeItemArray.Remove( IndexToBeDestroyed ); // remove from internal array. + iModel->RemoveAndDestroy( IndexToBeDestroyed ); // Remove from model + iMailList->RemoveL( iMailList->FocusedItem() ); // remove from list + if ( iNodesInUse ) + { + RemoveUnnecessaryNodesL(); + } + } + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// UpdateMsgIconAndBoldingL +// Updates our own message object with the data from a given message object. +// The messages are matched with the message ID. +// --------------------------------------------------------------------------- +void CFSEmailUiMailListVisualiser::UpdateMsgIconAndBoldingL( CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + // + if ( aMsgPtr && iModel->Count() ) + // + { + TInt mailItemIdx = ItemIndexFromMessageId( aMsgPtr->GetMessageId() ); + if ( mailItemIdx >= 0 ) + { + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item( mailItemIdx ) ); + + if ( item ) // For safety + { + // Update all flags + TUint32 prevFlags = item->MessagePtr().GetFlags(); + TUint32 newFlags = aMsgPtr->GetFlags(); + if ( prevFlags != newFlags ) + { + item->MessagePtr().ResetFlag( prevFlags ); + item->MessagePtr().SetFlag( newFlags ); + + // Save changed flags in internal model array + item->MessagePtr().SaveMessageL(); + } + + // Update the list item graphics + UpdateMsgIconAndBoldingL( mailItemIdx ); + } + } + } + } + +// --------------------------------------------------------------------------- +// UpdateMsgIconAndBoldingL +// Updates list item at given index to match the state of the message object +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateMsgIconAndBoldingL( TInt aListIndex, TBool aRefreshItem ) + { + FUNC_LOG; + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item(aListIndex) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailMessage* msgPtr = &item->MessagePtr(); + CFsTreePlainTwoLineItemData* itemData = + static_cast( iTreeItemArray[aListIndex].iTreeItemData ); + CFsTreePlainTwoLineItemVisualizer* itemVis = + static_cast( iTreeItemArray[aListIndex].iTreeItemVisualiser ); + + UpdateMsgIconAndBoldingL( itemData, itemVis, msgPtr ); + + //refresh item if requested + if ( aRefreshItem ) + { + iMailTreeListVisualizer->UpdateItemL( iTreeItemArray[aListIndex].iListItemId ); + } + } + } + +// --------------------------------------------------------------------------- +// UpdateMsgIconAndBoldingL +// Updates list item at given index to match the state of the message object +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateMsgIconAndBoldingL( CFsTreePlainTwoLineItemData* aItemData, + CFsTreePlainTwoLineItemVisualizer* aItemVis, + CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + + if ( aItemData && aItemVis && aMsgPtr ) + { + CAlfTexture* itemTexture = &TFsEmailUiUtility::GetMsgIcon( aMsgPtr, *iAppUi.FsTextureManager() ); + aItemData->SetIcon( *itemTexture ); + TInt variety( Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0 ); + CAlfTextStyle& textStyle = + iAppUi.LayoutHandler()->FSTextStyleFromLayoutL( + AknLayoutScalable_Apps::list_single_dyc_row_text_pane_t1( variety ) ); + const TBool isNotRead( !aMsgPtr->IsFlagSet( EFSMsgFlag_Read ) ); + textStyle.SetBold( isNotRead ); + aItemVis->SetTextBold( isNotRead ); + aItemVis->SetTextStyleId ( textStyle.Id() ); + // Set follow up flag icon + if ( aMsgPtr->IsFlagSet( EFSMsgFlag_FollowUp ) ) + { + aItemData->SetFlagIcon( iAppUi.FsTextureManager()->TextureByIndex( EFollowUpFlagList ) ); + aItemVis->SetFlagIconVisible( ETrue ); + } + else if ( aMsgPtr->IsFlagSet( EFSMsgFlag_FollowUpComplete ) ) + { + aItemData->SetFlagIcon( iAppUi.FsTextureManager()->TextureByIndex( EFollowUpFlagCompleteList ) ); + aItemVis->SetFlagIconVisible( ETrue ); + } + else + { + aItemVis->SetFlagIconVisible( EFalse ); + } + } + } + +// --------------------------------------------------------------------------- +// RemoveMsgItemsFromListIfFoundL +// Message removing from list if found. Does not panic or return found status. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RemoveMsgItemsFromListIfFoundL( const RArray& aEntryIds ) + { + FUNC_LOG; + + TBool itemFound = EFalse; + for ( TInt i=0 ; i= 0 ) + { + iMailList->RemoveL( iTreeItemArray[idx].iListItemId ); // remove from list + iTreeItemArray.Remove( idx ); // remove from internal array. + iModel->RemoveAndDestroy( idx ); // Remove from model + itemFound = ETrue; + } + } + } + + if ( !itemFound ) + { + return; // no items to be removed + } + + if ( iNodesInUse ) + { + RemoveUnnecessaryNodesL(); + } + + // Set highligh to control bar if no items left after + // deleted items have been revoved from the list + // Otherwise mail list takes care of highlight + // + if ( iModel->Count() == 0 ) + // + { + iFocusedControl = EControlBarComponent; + iMailList->SetFocusedL( EFalse ); + iControlBarControl->SetFocusL(); + } + } + +// --------------------------------------------------------------------------- +// DeleteFocusedMessageL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DeleteFocusedMessageL() + { + FUNC_LOG; + TInt currentItemIndex = HighlightedIndex(); + if ( Model()->Count() ) + { + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item(currentItemIndex) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + CFSMailMessage& messagePtr = item->MessagePtr(); + // Delete message from framework, and perform internal housekeeping + TFSMailMsgId msgId = messagePtr.GetMessageId(); + RArray msgIds; + CleanupClosePushL( msgIds ); + msgIds.Append( msgId ); + TFSMailMsgId folderId = FolderId(); + TFSMailMsgId mailBox = iAppUi.GetActiveMailbox()->GetId(); + iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, folderId, msgIds ); + RemoveMsgItemsFromListIfFoundL( msgIds ); + CleanupStack::PopAndDestroy( &msgIds ); + } + } + } + +// --------------------------------------------------------------------------- +// DeleteMessagesUnderNodeL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DeleteMessagesUnderNodeL( + const TFsTreeItemId aNodeId) + { + FUNC_LOG; + iModel->GetItemIdsUnderNodeL(aNodeId, iDeleteTask->Entries()); + ConfirmAndStartDeleteTaskL(iDeleteTask); + } + +// --------------------------------------------------------------------------- +// DeleteMarkedMessagesL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DeleteMarkedMessagesL() + { + FUNC_LOG; + iMailList->GetMarkedItemsL(iDeleteTask->Entries()); + ConfirmAndStartDeleteTaskL(iDeleteTask); + } + +// --------------------------------------------------------------------------- +// ConfirmAndStartDeleteTaskL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::ConfirmAndStartDeleteTaskL( + TDeleteTask* aTask ) + { + FUNC_LOG; + const RFsTreeItemIdList& entries(aTask->Entries()); + if (entries.Count()) + { + if (ConfirmDeleteL(entries.Count(), entries[0])) + { + ExitMarkingModeL(); + if (entries.Count() > KMsgDeletionWaitNoteAmount) + { + TFsEmailUiUtility::ShowWaitNoteL(iDeletingWaitNote, + R_FSE_WAIT_DELETING_TEXT, EFalse, ETrue); + } + if (iAsyncCallback) + { + // Call actual deletion asynchronously because we must give wait + // note time to show up before deletion begins. + iAsyncCallback->Cancel(); + iAsyncCallback->Set(TCallBack(DoExecuteDeleteTask, aTask)); + iAsyncCallback->CallBack(); + } + } + else + { + aTask->Reset(); + } + } + } + +// --------------------------------------------------------------------------- +// DoExecuteDeleteTask +// +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::DoExecuteDeleteTask( TAny* aSelfPtr ) + { + FUNC_LOG; + TRAPD( error, + reinterpret_cast*>(aSelfPtr)->ExecuteL() ); + return error; + } + +// --------------------------------------------------------------------------- +// HandleDeleteTaskL +// This is called asynchronously by ConfirmAndStartDeleteTaskL +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleDeleteTaskL( const RFsTreeItemIdList& aEntries ) + { + FUNC_LOG; + // Close wait note if it was used + if ( iDeletingWaitNote ) + { + TRAPD( result, HandleDeleteTaskLeavingCodeL(aEntries) ); + // closing the "Deleting" dialog message should not be skipped by leaving + TRAP_IGNORE( iDeletingWaitNote->ProcessFinishedL() ); + if ( KErrNone != result ) + { + // Handle error. + User::Leave( result ); + } + } + else + { + HandleDeleteTaskLeavingCodeL( aEntries ); + } + } + +// --------------------------------------------------------------------------- +// original code HandleDeleteTaskL which may leave - help function to enable +// calling iDeletingWaitNote->ProcessFinishedL() +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleDeleteTaskLeavingCodeL( const RFsTreeItemIdList& aEntries ) + { + FUNC_LOG; + TFSMailMsgId folderId = FolderId(); + TFSMailMsgId mailBox = iAppUi.GetActiveMailboxId(); + RArray msgIds; + CleanupClosePushL( msgIds ); + for ( TInt i = aEntries.Count() - 1; i >= 0; i-- ) + { + msgIds.AppendL( MsgIdFromListId( aEntries[i] ) ); + } + + // Clear the focused item to avoid repeated selection of a new focused + // item, unnecessary scrolling of the viewport, etc. + iMailTreeListVisualizer->SetFocusedItemL( KFsTreeNoneID ); + + iMailList->BeginUpdate(); + iAppUi.GetMailClient()->DeleteMessagesByUidL( mailBox, folderId, msgIds ); + // Remove from mail list if not already removed by mailbox events + RemoveMsgItemsFromListIfFoundL( msgIds ); + iMailList->EndUpdateL(); + + CleanupStack::PopAndDestroy(); // msgIds.Close() + } + +// --------------------------------------------------------------------------- +// ConfirmDeleteL +// +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMailListVisualiser::ConfirmDeleteL(const TInt aItemCount, + const TFsTreeItemId aItemId) const + { + FUNC_LOG; + TBool result(ETrue); + if (iAppUi.GetCRHandler()->WarnBeforeDelete()) + { + HBufC* noteText(NULL); + // The note depends on the amount and type of message(s) + if (aItemCount == 1) + { + const CFSMailMessage& msgPtr(MsgPtrFromListIdL(aItemId)); + HBufC* msgSubject = TFsEmailUiUtility::CreateSubjectTextLC( + &msgPtr); + if (msgPtr.IsFlagSet(EFSMsgFlag_CalendarMsg)) + { + noteText = StringLoader::LoadL( + R_FREESTYLE_EMAIL_DELETE_CALEVENT_NOTE, *msgSubject); + } + else + { + noteText = StringLoader::LoadL( + R_FREESTYLE_EMAIL_DELETE_MAIL_NOTE, *msgSubject); + } + CleanupStack::PopAndDestroy(msgSubject); + CleanupStack::PushL(noteText); + } + else // markedEntries.Count() > 1 + { + noteText = StringLoader::LoadLC( + R_FREESTYLE_EMAIL_DELETE_N_MAILS_NOTE, aItemCount); + } + + // Show the note + result = TFsEmailUiUtility::ShowConfirmationQueryL(*noteText); + CleanupStack::PopAndDestroy(noteText); + } + return result; + } + +// --------------------------------------------------------------------------- +// RemoveUnnecessaryNodesL +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::RemoveUnnecessaryNodesL() + { + FUNC_LOG; + RArray nodesToBeRemoved; + CleanupClosePushL( nodesToBeRemoved ); + for ( TInt i=0;iIsNode( iTreeItemArray[i].iListItemId ) ) + { + if ( iMailList->CountChildren( iTreeItemArray[i].iListItemId ) == 0) + { + nodesToBeRemoved.Append( iTreeItemArray[i].iListItemId ); + } + } + } + // Remove from the list itself and from iTreeItemArray + for ( TInt a = 0; a < nodesToBeRemoved.Count(); a++ ) + { + iMailList->RemoveL( nodesToBeRemoved[a] ); + SMailListItem item; + item.iListItemId = nodesToBeRemoved[a]; + TInt IndexToBeDestroyed = iTreeItemArray.Find( item ); + iTreeItemArray.Remove( IndexToBeDestroyed ); // remove from internal array. + // Remove from model + iModel->RemoveAndDestroy( IndexToBeDestroyed ); + } + CleanupStack::PopAndDestroy( &nodesToBeRemoved ); + } + +// --------------------------------------------------------------------------- +// MsgIdFromIndex +// Helper function to get message id from list index +// --------------------------------------------------------------------------- +// +TFSMailMsgId CFSEmailUiMailListVisualiser::MsgIdFromIndex( TInt aItemIdx ) const + { + FUNC_LOG; + TFSMailMsgId msgId; // constructs null ID + // + if ( 0 <= aItemIdx && aItemIdx < iModel->Count() ) + // + { + CFSEmailUiMailListModelItem* item = + static_cast(iModel->Item(aItemIdx)); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + msgId = item->MessagePtr().GetMessageId(); + } + } + + return msgId; + } + +// --------------------------------------------------------------------------- +// MsgIdFromListId +// Get message ID corresponding given list ID. If the list ID is for a node, +// the message ID of its first child is returned +// --------------------------------------------------------------------------- +// +TFSMailMsgId CFSEmailUiMailListVisualiser::MsgIdFromListId( TFsTreeItemId aListId ) const + { + FUNC_LOG; + TFSMailMsgId msgId; // constructs null ID + + if ( aListId != KFsTreeNoneID ) + { + // Find corresponding message from the model + const TInt modelCount( iModel->Count() ); + for( TInt i( 0 ) ; i < modelCount ; ++i ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( i ) ); + if ( item && aListId == item->CorrespondingListId() ) + { + msgId = item->MessagePtr().GetMessageId(); + // if list id points to separator + // set flag on. This is made for improving focus handling. + if( item->ModelItemType() == ETypeSeparator ) + { + msgId.SetSeparator( ETrue ); + } + break; + } + } + } + + return msgId; + } + +// --------------------------------------------------------------------------- +// MsgPtrFromListIdL +// +// --------------------------------------------------------------------------- +// +CFSMailMessage& CFSEmailUiMailListVisualiser::MsgPtrFromListIdL( TFsTreeItemId aListId ) + { + FUNC_LOG; + TInt index = ModelIndexFromListId( aListId ); + if ( index >= 0 ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(index) ); + return item->MessagePtr(); + } + else + { + // Leave if no message found. As the function returns a reference, it is not + // possible to return any meaningful null value. + User::Leave( KErrNotFound ); + } + + CFSMailMessage* dummy = NULL; + return *dummy; // to surpress warning about missing return value; this is not really ever run + } + +// --------------------------------------------------------------------------- +// MsgPtrFromListIdL +// +// --------------------------------------------------------------------------- +// +const CFSMailMessage& CFSEmailUiMailListVisualiser::MsgPtrFromListIdL( TFsTreeItemId aListId ) const + { + FUNC_LOG; + TInt index = ModelIndexFromListId( aListId ); + if ( index >= 0 ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(index) ); + return item->MessagePtr(); + } + else + { + // Leave if no message found. As the function returns a reference, it is not + // possible to return any meaningful null value. + User::Leave( KErrNotFound ); + } + + const CFSMailMessage* dummy = NULL; + return *dummy; // to surpress warning about missing return value; this is not really ever run + } + +// --------------------------------------------------------------------------- +// ItemDataFromItemId +// Function returns a valid pointer to list item data based on item id +// --------------------------------------------------------------------------- +// +MFsTreeItemData* CFSEmailUiMailListVisualiser::ItemDataFromItemId( TFsTreeItemId aItemId ) + { + FUNC_LOG; + MFsTreeItemData* itemData = NULL; + if ( aItemId != KFsTreeNoneID ) + { + itemData = &iMailList->ItemData( aItemId ); + } + return itemData; + } + +// --------------------------------------------------------------------------- +// ItemVisualiserFromItemId +// Function returns a valid pointer to list item visualiser based on item id +// --------------------------------------------------------------------------- +// +MFsTreeItemVisualizer* CFSEmailUiMailListVisualiser::ItemVisualiserFromItemId( TFsTreeItemId aItemId ) + { + FUNC_LOG; + MFsTreeItemVisualizer* itemVis = NULL; + if ( aItemId != KFsTreeNoneID ) + { + itemVis = &iMailList->ItemVisualizer( aItemId ); + } + return itemVis; + } + +// --------------------------------------------------------------------------- +// ItemIndexFromMessageId +// Function returns list index based on message pointer. KErrNotFound if +// ID is not included in the list +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::ItemIndexFromMessageId( const TFSMailMsgId& aMessageId ) const + { + FUNC_LOG; + TInt idx = KErrNotFound; + + // Check first the special case; if searched id is null id, there's no + // point to loop the whole list. There shouldn't be any null id's in + // the model anyway. There is currently also an error in FW's equality + // operator implementation; it doesn't check the iNullId flag at all. + if( !aMessageId.IsNullId() ) + { + const TInt modelCount( iModel->Count() ); + for ( TInt i( 0 ); i < modelCount ; ++i ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( i ) ); + // when the item is a separator check whether its MessagePtr is valid (actually it's a reference) + if( item && &(item->MessagePtr()) != NULL) + { + if ( aMessageId == item->MessagePtr().GetMessageId() ) + { + TModelItemType itemType = item->ModelItemType(); + TBool separator( aMessageId.IsSeparator() ); + + // Because separator and the first message after separator + // have same message id, we need to separate these cases + // and that is made with separator flag which is stored to + // TFSMailMsgId object. If separator flag is on item need to be + // separator if it is not on item needs to be mail item. + if( ( separator && itemType == ETypeSeparator ) || + ( !separator && itemType == ETypeMailItem ) ) + { + idx = i; + break; + } + } + } + } + } + return idx; + } + +// --------------------------------------------------------------------------- +// NextMessageIndex +// Function returns next message index from highlighted index +// KErrNotFound if there is no next message +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::NextMessageIndex( TInt aCurMsgIdx ) const + { + FUNC_LOG; + TInt idx = KErrNotFound; + for ( TInt i=aCurMsgIdx+1 ; iCount() ; i++ ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(i) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + idx = i; + break; + } + } + + return idx; + } + +// --------------------------------------------------------------------------- +// PreviousMessageIndex +// Function returns previous message index from highlighted index +// KErrNotFound if there is no previous message +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::PreviousMessageIndex( TInt aCurMsgIdx ) const + { + FUNC_LOG; + TInt idx( KErrNotFound ); + if ( aCurMsgIdx < iModel->Count() ) + { + for ( TInt i=aCurMsgIdx-1 ; i>=0 ; i-- ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(i) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + idx = i; + break; + } + } + } + return idx; + } + +// --------------------------------------------------------------------------- +// ModelIndexFromListId +// Function returns a model index corresponding the given tree list item ID +// --------------------------------------------------------------------------- +// +TInt CFSEmailUiMailListVisualiser::ModelIndexFromListId( TFsTreeItemId aItemId ) const + { + FUNC_LOG; + TInt ret = KErrNotFound; + const TInt count = iModel->Count(); + for ( TInt i=0; i < count; i++ ) + { + const CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item(i) ); + if ( item && aItemId == item->CorrespondingListId() ) + { + ret = i; + break; + } + } + return ret; + } + +// --------------------------------------------------------------------------- +// FolderSelectedL +// Folder list selection callback. Function updates list when folder is changed +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::FolderSelectedL( + TFSMailMsgId aSelectedFolderId, + TFSEmailUiCtrlBarResponse aResponse ) + { + FUNC_LOG; + // hide selector if keys are not pressed + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + if ( iMoveToFolderOngoing ) + { + iMoveToFolderOngoing = EFalse; + switch ( aResponse ) + { + case EFSEmailUiCtrlBarResponseCancel: + if ( iMarkingMode ) + { + DisplayMarkingModeTitleTextL(); + } + iMarkingModeWaitingToExit = EFalse; + SetMskL(); + return; + case EFSEmailUiCtrlBarResponseSelect: + { + MoveMsgsToFolderL( aSelectedFolderId ); + SetMskL(); + } + break; + default: + break; + } + } + else + { + // Ignore if cancel selected + switch ( aResponse ) + { + case EFSEmailUiCtrlBarResponseSwitchList: + { + TFSFolderType folderType; + if ( iMailFolder ) + { + folderType = iMailFolder->GetFolderType(); + } + else + { + folderType = EFSInbox; + } + iControlBarControl->SetFocusByIdL( iSortButtonId ); + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + + // Sorting empty mail list disabled + // Show sort list only if mail list is not empty + if ( iModel->Count() ) + { + iAppUi.ShowSortListInPopupL( iCurrentSortCriteria, folderType, this, iSortButton ); + } + } + return; + case EFSEmailUiCtrlBarResponseCancel: + iMarkingModeWaitingToExit = EFalse; + SetMskL(); + // Touch + //Set touchmanager back to active + DisableMailList(EFalse); + // + return; + case EFSEmailUiCtrlBarResponseSelect: + SetMskL(); + // Touch + //Set touchmanager back to active + DisableMailList(EFalse); + // + default: + break; + } + + if ( !iMailFolder || ( iMailFolder && iMailFolder->GetFolderId() != aSelectedFolderId ) ) + { + iMailListModelUpdater->Cancel(); + iNewMailTimer->Cancel(); + iNewMailIds.Reset(); + SafeDelete(iMailFolder); + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( iAppUi.GetActiveMailboxId(), aSelectedFolderId ); + + if ( !iMailFolder ) + { + // Do nothing if can't get the folder object + return; + } + + // Set new text to folder button in control bar + HBufC* newFolderName = CreateFolderNameLC( iMailFolder ); + iFolderListButton->SetTextL( *newFolderName ); + CleanupStack::PopAndDestroy( newFolderName ); + + // Set initial sort criteria when folder has changed + iCurrentSortCriteria.iField = EFSMailSortByDate; + iCurrentSortCriteria.iOrder = EFSMailDescending; + // reload node state because in file sort mode this is disabled even when globally enabled + iNodesInUse = iAppUi.GetCRHandler()->TitleDividers(); + SetSortButtonTextAndIconL(); + + // Update the mail list contents + UpdateMailListModelL(); + RefreshL(); + } + iFocusedControl = EControlBarComponent; + SetListAndCtrlBarFocusL(); + iMoveToFolderOngoing = EFalse; + } + SetMskL(); + } + +// --------------------------------------------------------------------------- +// MailboxSelectedL +// Mailbox selection callback. Function updates list when mailbox is changed +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::MailboxSelectedL( TFSMailMsgId aSelectedMailboxId ) + { + FUNC_LOG; + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + //Set touchmanager back to active + DisableMailList(EFalse); + iAppUi.SetActiveMailboxL( aSelectedMailboxId ); + iMailListModelUpdater->Cancel(); + SafeDelete(iMailFolder); + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( iAppUi.GetActiveMailboxId(), iAppUi.GetActiveBoxInboxId() ); + + // Set initial sort criteria when folder has changed + iCurrentSortCriteria.iField = EFSMailSortByDate; + iCurrentSortCriteria.iOrder = EFSMailDescending; + // reload node state because in file sort mode this is disabled even when globally enabled + iNodesInUse = iAppUi.GetCRHandler()->TitleDividers(); + SetSortButtonTextAndIconL(); + + // Set folder name to the control bar button + HBufC* newFolderName = CreateFolderNameLC( iMailFolder ); + iFolderListButton->SetTextL( *newFolderName ); + CleanupStack::PopAndDestroy( newFolderName ); + + // Set mailbox name and icons + SetMailboxNameToStatusPaneL(); + SetBrandedListWatermarkL(); + SetBrandedMailBoxIconL(); + + // Update model + UpdateMailListModelL(); + iMailList->RemoveAllL(); + RefreshDeferred(); + + // Check sync icon timer and sync status + ConnectionIconHandling(); + iFocusedControl = EControlBarComponent; + } + +// --------------------------------------------------------------------------- +// FolderButtonRect +// Getter for folder button rectangle. Folder popup needs to get this +// information when screen layout changes. +// --------------------------------------------------------------------------- +// +TRect CFSEmailUiMailListVisualiser::FolderButtonRect() + { + FUNC_LOG; + const TPoint& buttonPos = iFolderListButton->Pos().Target(); + const TPoint& buttonSize = iFolderListButton->Size().Target(); + TRect buttonRect( buttonPos, buttonSize.AsSize() ); + return buttonRect; + } + +// --------------------------------------------------------------------------- +// SortOrderChangedL +// Sort order selection callback. Function updates list when sorting is changed +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::SortOrderChangedL( + TFSMailSortField aSortField, TFSEmailUiCtrlBarResponse aResponse ) + { + FUNC_LOG; + // Ignore if cancel selected + switch( aResponse ) + { + case EFSEmailUiCtrlBarResponseSwitchList: + { + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + iControlBarControl->SetFocusByIdL( iFolderListButtonId ); + iAppUi.ShowFolderListInPopupL( FolderId(), this, iFolderListButton ); + } + return; + case EFSEmailUiCtrlBarResponseCancel: + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + SetMskL(); + // Touch + //Set touchmanager back to active + DisableMailList(EFalse); + return; + + case EFSEmailUiCtrlBarResponseSelect: + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + //Set touchmanager back to active + DisableMailList(EFalse); + // + default: + break; + } + + // Check is the selected sort field same as the previous one + if( iCurrentSortCriteria.iField == aSortField ) + { + // If same sort field selected, switch the sorting order + if( iCurrentSortCriteria.iOrder == EFSMailAscending ) + { + iCurrentSortCriteria.iOrder = EFSMailDescending; + } + else + { + iCurrentSortCriteria.iOrder = EFSMailAscending; + } + } + else if ( aSortField == EFSMailSortBySubject || + aSortField == EFSMailSortBySender || + aSortField == EFSMailSortByUnread || // + aSortField == EFSMailSortByRecipient ) + { + iCurrentSortCriteria.iOrder = EFSMailAscending; + } + else + { + iCurrentSortCriteria.iOrder = EFSMailDescending; + } + + iCurrentSortCriteria.iField = aSortField; + iModel->SetSortCriteria(iCurrentSortCriteria); + + // rest of the code moved to TimerEventL ( iSortTimer part ) + // used also in DoHandleControlBarOpenL to prevent SortList reopening + iSortState = ESortRequested; + iSortTimer->Start( KSortTimerDelay ); + } + +// --------------------------------------------------------------------------- +// SortButtonRect +// Getter for sort button rectangle. Sort popup needs to get this +// information when screen layout changes. +// --------------------------------------------------------------------------- +// +TRect CFSEmailUiMailListVisualiser::SortButtonRect() + { + FUNC_LOG; + const TPoint& buttonPos = iSortButton->Pos().Target(); + const TPoint& buttonSize = iSortButton->Size().Target(); + TRect buttonRect( buttonPos, buttonSize.AsSize() ); + return buttonRect; + } + +// --------------------------------------------------------------------------- +// OpenHighlightedMailL +// Function opens highlighted mail either to internal viewer or to mrui if +// message type is meeting +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::OpenHighlightedMailL() + { + FUNC_LOG; + OpenMailItemL( iMailList->FocusedItem() ); + } + +// --------------------------------------------------------------------------- +// OpenHighlightedMailL +// Function opens given mail item either to internal viewer or to mrui if +// message type is meeting +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::OpenMailItemL( TFsTreeItemId aMailItem ) + { + FUNC_LOG; + TInt idx = ModelIndexFromListId( aMailItem ); + if ( idx >= 0 ) + { + CFSEmailUiMailListModelItem* item = + static_cast( Model()->Item(idx) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + // First make sure that the highlighted message really exists in the store + // Get confirmed msg ptr + CFSMailMessage* confirmedMsgPtr(0); + confirmedMsgPtr = iAppUi.GetMailClient()->GetMessageByUidL(iAppUi.GetActiveMailboxId(), + iMailFolder->GetFolderId(), item->MessagePtr().GetMessageId(), EFSMsgDataEnvelope ); + if ( confirmedMsgPtr ) + { + iMailOpened = ETrue; + + ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY ); + // Pointer confirmed, store Id and delete not needed anymore + TFSMailMsgId confirmedId = confirmedMsgPtr->GetMessageId(); + TBool isCalMessage = confirmedMsgPtr->IsFlagSet( EFSMsgFlag_CalendarMsg ); + TBool isReadMessage = confirmedMsgPtr->IsFlagSet( EFSMsgFlag_Read ); + delete confirmedMsgPtr; + // Open to editor from drafts + if ( iMailFolder->GetFolderType() == EFSDraftsFolder ) + { + if ( !isCalMessage ) // Open only normal messages for now + { + TEditorLaunchParams params; + params.iMailboxId = iAppUi.GetActiveMailboxId(); + params.iActivatedExternally = EFalse; + params.iMsgId = confirmedId; + params.iFolderId = iMailFolder->GetFolderId(); + iAppUi.LaunchEditorL( KEditorCmdOpen, params ); + } + else + { + //Try to open to editor if support for that is needed + } + } + else if ( iMailFolder->GetFolderType() == EFSOutbox ) + { + TFsEmailUiUtility::ShowErrorNoteL( R_FREESTYLE_EMAIL_UI_OPEN_FROM_OUTBOX_NOTE, ETrue ); + } + else + { + THtmlViewerActivationData htmlData; + htmlData.iActivationDataType = THtmlViewerActivationData::EMailMessage; + htmlData.iMailBoxId = iAppUi.GetActiveMailbox()->GetId(); + htmlData.iFolderId = FolderId(); + htmlData.iMessageId = confirmedId; + TPckgBuf pckgData( htmlData ); + + // Change read status only if needed + if ( !isReadMessage ) + { + ChangeReadStatusOfHighlightedL( ETrue ); + } + + // Opening viewer seems to take more time than other views, + // so we do longer fade out in this case + SetNextTransitionOutLong( ETrue ); + + iAppUi.EnterFsEmailViewL( HtmlViewerId, KHtmlViewerOpenNew, pckgData ); + } + } + } + } + } + +// --------------------------------------------------------------------------- +// From MFSEmailUiContactHandlerObserver +// The ownership of the CLS items in the contacts array is transferred to the +// observer, and they must be deleted by the observer. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::OperationCompleteL( + TContactHandlerCmd /*aCmd*/, const RPointerArray& /*aContacts*/ ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// From MFSEmailUiContactHandlerObserver +// Handles error in contact handler operation. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::OperationErrorL( TContactHandlerCmd /*aCmd*/, + TInt /*aError*/ ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// NotifyDateChangedL +// Called when CDateChangeTimer completes. This happens when either when date +// changes or when user alters the system time. Redraws the list to ensure +// that time stamp texts in emails and nodes are up-to-date. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::NotifyDateChangedL() + { + FUNC_LOG; + iDateChanged = ETrue; + if ( iAppUi.IsForeground() ) + { + HandleForegroundEventL(ETrue); + } + } + +// --------------------------------------------------------------------------- +// CreateFolderNameLC +// Creates folder name from folder ptr. Localised if standard folder. +// --------------------------------------------------------------------------- +// +HBufC* CFSEmailUiMailListVisualiser::CreateFolderNameLC( const CFSMailFolder* aFolder ) const + { + FUNC_LOG; + TInt resourceId(0); + HBufC* ret(0); + if ( !aFolder || aFolder->GetFolderId().IsNullId() ) + { + // INBOX FOR NULL ID + resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_INBOX; + } + else + { + TInt folderType = aFolder->GetFolderType(); + switch ( folderType ) + { + case EFSInbox: + { + resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_INBOX; + } + break; + case EFSOutbox: + { + resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_OUTBOX; + } + break; + case EFSDraftsFolder: + { + resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_DRAFTS; + } + break; + case EFSSentFolder: + { + resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_SENT; + } + break; + case EFSDeleted: + { + resourceId = R_FREESTYLE_EMAIL_UI_DROPDOWN_LIST_DELETED; + } + break; + default: + // Not a standard folder + break; + } + } + if ( resourceId ) + { + ret = StringLoader::LoadLC( resourceId ); + } + else + { + ret = aFolder->GetFolderName().AllocLC(); + } + return ret; + } + +// --------------------------------------------------------------------------- +// LaunchStylusPopupMenuL +// Function launches avkon stylus popup menu based on the selected message item/items +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::LaunchStylusPopupMenuL( const TPoint& aPoint ) + { + // Irrelevant items for focused mail list item get dimmed at runtime + + // Check mail list item's type + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( HighlightedIndex() ) ); + if ( item ) + { + if ( item->ModelItemType() == ETypeMailItem ) + { + // Add mark as read / unread options + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, !IsMarkAsUnreadAvailableL() ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsRead, !IsMarkAsReadAvailableL() ); + + // Check support for object mail iten moving + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsMoveMessage, + !(iAppUi.GetActiveMailbox()->HasCapability( EFSMBoxCapaMoveToFolder ) + && iMailFolder->SupportsMoveFromL( iMailFolder->GetFolderType() ) ) ); + + // Hide / show follow up + TBool supportsFlag = TFsEmailUiUtility::IsFollowUpSupported( *iAppUi.GetActiveMailbox() ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsFlag, !supportsFlag ); + + // Hide collapse / expand all + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, ETrue ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, ETrue ); + } + else if ( item->ModelItemType() == ETypeSeparator ) + { + // Hide mark as read / unread options + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsUnread, ETrue ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdMarkAsRead, ETrue ); + + // Hide move & follow up + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsMoveMessage, ETrue ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsFlag, ETrue ); + + // Hide collapse / expand all when applicable + if ( iNodesInUse == EListControlSeparatorDisabled || !iModel->Count() ) + { + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, ETrue ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, ETrue ); + } + else + { + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, AllNodesCollapsed() ); + iStylusPopUpMenu->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, AllNodesExpanded() ); + } + } + } + + // Set the position for the popup + TPoint point(aPoint.iX, aPoint.iY + 45); + iStylusPopUpMenu->SetPosition( point, CAknStylusPopUpMenu::EPositionTypeRightBottom ); + + // Display the popup and set the flag to indicate that the menu was + // launched. + iStylusPopUpMenu->ShowMenu(); + iStylusPopUpMenuVisible = ETrue; + } + +// --------------------------------------------------------------------------- +// CreateNewMsgL +// Launches editor. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::CreateNewMsgL() + { + FUNC_LOG; + TEditorLaunchParams params; + params.iMailboxId = iAppUi.GetActiveMailboxId(); + params.iActivatedExternally = EFalse; + iAppUi.LaunchEditorL( KEditorCmdCreateNew, params ); + } + +void CFSEmailUiMailListVisualiser::ReplyL( CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + // Replying not possible from drafts folder + if ( iMailFolder && iMailFolder->GetFolderType() != EFSDraftsFolder ) + { + DoReplyForwardL( KEditorCmdReply, aMsgPtr ); + } + } + +void CFSEmailUiMailListVisualiser::ReplyAllL( CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + // Replying all not possible from drafts folder + if ( iMailFolder && iMailFolder->GetFolderType() != EFSDraftsFolder ) + { + DoReplyForwardL( KEditorCmdReplyAll, aMsgPtr ); + } + } + +void CFSEmailUiMailListVisualiser::ForwardL( CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + DoReplyForwardL( KEditorCmdForward, aMsgPtr ); + } + +// --------------------------------------------------------------------------- +// DoReplyForwardL +// Launches editor with either reply all forward command +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::DoReplyForwardL( TEditorLaunchMode aMode, CFSMailMessage* aMsgPtr ) + { + FUNC_LOG; + // Reply, reply all, and forward commands are inavailable in the outbox + // + if ( iModel->Count() && iMailFolder && iMailFolder->GetFolderType() != EFSOutbox ) + // + { + CFSMailMessage* messagePointer = aMsgPtr; + if ( !messagePointer ) + { + RFsTreeItemIdList targetEntries; + CleanupClosePushL( targetEntries ); + GetActionsTargetEntriesL( targetEntries ); + // action is possible only when there's exactly one marked or focused mail item + if ( targetEntries.Count() == 1 ) + { + messagePointer = &MsgPtrFromListIdL( targetEntries[0] ); + } + CleanupStack::PopAndDestroy( &targetEntries ); + } + if ( messagePointer ) + { + // Opening editor is slower than opening most other views. + // Use longer transition effect to mask this. + SetNextTransitionOutLong( ETrue ); + + TEditorLaunchParams params; + params.iMailboxId = iAppUi.GetActiveMailboxId(); + params.iActivatedExternally = EFalse; + params.iMsgId = messagePointer->GetMessageId(); + iAppUi.LaunchEditorL( aMode, params ); + } + } + } + +// --------------------------------------------------------------------------- +// HandleMailBoxEventL +// Mailbox event handler, responds to events sent by the plugin. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::HandleMailBoxEventL( TFSMailEvent aEvent, + TFSMailMsgId aMailboxId, TAny* aParam1, TAny* aParam2, TAny* aParam3 ) + { + FUNC_LOG; + + // Complete any pending asynchronous redrawing before handling the event + // to make sure that all the arrays are in consistent state + CompletePendingRefresh(); + + // Handle the event + if ( iFirstStartCompleted && + aMailboxId == iAppUi.GetActiveMailboxId() ) // Safety, in list events that only concern active mailbox are handled + { + if ( aEvent == TFSEventFoldersDeleted ) + { + // Check whether the current folder gets deleted + // Change mail item icon or read status + RArray* removedEntries = static_cast*>( aParam1 ); + if ( iMailFolder && removedEntries && removedEntries->Count() ) + { + TFSMailMsgId currentFolderId = iMailFolder->GetFolderId(); + for ( TInt i = 0; i < removedEntries->Count(); i++ ) + { + TFSMailMsgId entryId = (*removedEntries)[i]; + if ( entryId == currentFolderId ) + { + // Current folder deleted, try to revert back to standard folder inbox. + iMailListModelUpdater->Cancel(); + SafeDelete(iMailFolder); + TFSMailMsgId inboxId = iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSInbox ); + if ( !inboxId.IsNullId() ) + { + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, inboxId ); + UpdateMailListModelL(); + RefreshL(); + HBufC* newFolderName = CreateFolderNameLC( iMailFolder ); + iFolderListButton->SetTextL( *newFolderName ); + CleanupStack::PopAndDestroy( newFolderName ); + } + else + { + // No standard folder inbox, go back to grid as a last option + HandleCommandL( EAknSoftkeyBack ); + } + break; + } + } + } + } + else if ( aEvent == TFSEventMailboxRenamed ) + { + if ( iThisViewActive ) + { + SetMailboxNameToStatusPaneL(); + } + } + else if ( (aEvent == TFSEventMailDeleted || aEvent == TFSEventMailDeletedFromViewer) && iMailFolder ) // Added iMailFolder null safety check + { + // Change mail item icon or read status + RArray* removedEntries = static_cast*>(aParam1); + if ( removedEntries && removedEntries->Count() ) + { + TFSMailMsgId* parentFolderId = static_cast( aParam2 ); + TFSMailMsgId currentFolderId = iMailFolder->GetFolderId(); + if ( parentFolderId && ( *parentFolderId == currentFolderId ) ) + { + // Refresh mailfolder to get correct actual data + /* + iMailListModelUpdater->Cancel(); + SafeDelete(iMailFolder); + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, currentFolderId ); + */ + RemoveMsgItemsFromListIfFoundL( *removedEntries ); + } + } + } + else if ( aEvent == TFSEventNewMail ) + { + // Switch to standardfolder inbox if we have null folderid. + // This is usually the case with first time sync. + if ( FolderId().IsNullId() ) + { + // Refresh mailfolder to standard folder inbox in case of zero id + iMailListModelUpdater->Cancel(); + SafeDelete(iMailFolder); + TFSMailMsgId inboxId = iAppUi.GetActiveMailbox()->GetStandardFolderId( EFSInbox ); + if ( !inboxId.IsNullId() ) + { + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, inboxId ); + // Check that mailfolder fetching succeeded + if ( iMailFolder ) + { + HBufC* newFolderName = CreateFolderNameLC( iMailFolder ); + iFolderListButton->SetTextL( *newFolderName ); + CleanupStack::PopAndDestroy( newFolderName ); + } + } + } + // Null pointer check is needed here because of special cases such as new mail + // creation in POP/IMAP before first sync where folder does not exists + if ( iMailFolder ) + { + RArray* newMessages = static_cast< RArray* >( aParam1 ); + TFSMailMsgId* parentFolderId = static_cast( aParam2 ); + TFSMailMsgId currentFolderId = iMailFolder->GetFolderId(); + // Update the mail list only if the event is related to the currently open folder + if ( *parentFolderId == currentFolderId ) + { + InsertNewMessagesL( *newMessages ); + } + } + } + else if ( aEvent == TFSEventMailMoved && iMailFolder ) // Added iMailFolder null safety check + { + // If message was moved FROM this folder, just remove the entry from the list. + // If message is moved TO this folder, update the list completely. + // Otherwise, the event does not have an influence on the current folder. + RArray* entries = static_cast< RArray* >( aParam1 ); + TFSMailMsgId* toFolderId = static_cast( aParam2 ); + TFSMailMsgId* fromFolderId = static_cast( aParam3 ); + TFSMailMsgId currentFolderId = iMailFolder->GetFolderId(); + + if ( toFolderId && ( currentFolderId == *toFolderId ) ) + { + InsertNewMessagesL( *entries ); + } + else if ( fromFolderId && ( currentFolderId == *fromFolderId ) ) + { + // Refresh mailfolder to get correct actual data + /* + iMailListModelUpdater->Cancel(); + SafeDelete(iMailFolder); + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, currentFolderId ); + */ + RemoveMsgItemsFromListIfFoundL( *entries ); + } + else + { + // event is not related to the current folder => do nothing + } + } + else if ( aEvent == TFSEventMailChanged && iMailFolder ) // Added iMailFolder null safety check + { + //if ( !iMailOpened ) // do not handle mail changed while viewer/editor is open. This may cause flickering + { + // Change mail item icon or read status + RArray* entries = static_cast*>( aParam1 ); + TFSMailMsgId* parentFolderId = static_cast( aParam2 ); + TFSMailMsgId currentFolderId = iMailFolder->GetFolderId(); + if ( *parentFolderId == currentFolderId ) + { + // Refresh mailfolder to get correct actual data + /* + iMailListModelUpdater->Cancel(); + SafeDelete(iMailFolder); + iMailFolder = iAppUi.GetMailClient()->GetFolderByUidL( aMailboxId, currentFolderId ); + */ + for ( TInt i=0 ; iCount() ; i++ ) + { + TFSMailMsgId msgId = (*entries)[i]; + TInt idx = ItemIndexFromMessageId( msgId ); + if ( idx != KErrNotFound ) + { + UpdateItemAtIndexL( idx ); + } + } + } + } + } + else if ( aEvent == TFSEventMailboxSyncStateChanged ) + { + TSSMailSyncState* newSyncState = static_cast( aParam1 ); + if ( newSyncState != 0 && *newSyncState != 0 ) + { + switch ( *newSyncState ) + { + case StartingSync: + { + //If sync was started by user, show the synchronisation indicator + if ( iManualMailBoxSync ) + { + ManualMailBoxSync(EFalse); + } + } + break; + + case SyncCancelled: + { + //If sync was started by user, show the synchronisation indicator + if ( iManualMailBoxSync ) + { + ManualMailBoxSync(EFalse); + } + } + break; + + } + } + } + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::TreeListEventL( const TFsTreeListEvent aEvent, + const TFsTreeItemId aId, + const TPoint& /*aPoint*/ ) + { + FUNC_LOG; + switch( aEvent ) + { + case EFsTreeListItemWillGetFocused: + { + if( aId != KFsTreeNoneID ) + { + UpdatePreviewPaneTextIfNecessaryL( aId, EFalse ); + } + break; + } + case EFsTreeListItemTouchFocused: + { + break; + } + case EFsFocusVisibilityChange: + { + iAppUi.SetFocusVisibility( EFalse ); + break; + } + default: + { + // Do not handle other events + break; + } + + } + } + +// --------------------------------------------------------------------------- +// UpdateMailListSettingsL +// Function reads and updates mail list specific settings from the cen rep +// --------------------------------------------------------------------------- +// +void CFSEmailUiMailListVisualiser::UpdateMailListSettingsL() + { + FUNC_LOG; + if ( iAppUi.GetCRHandler() ) + { + iNodesInUse = iAppUi.GetCRHandler()->TitleDividers(); + TInt lineValue = iAppUi.GetCRHandler()->MessageListLayout(); + TInt bodyPreviewValue = iAppUi.GetCRHandler()->BodyPreview(); + if ( lineValue == 1 ) // 1-line layouts + { + if ( bodyPreviewValue == 0 ) + { + iListMode = EListControlTypeSingleLinePreviewOff; + } + else + { + iListMode = EListControlTypeSingleLinePreviewOn; + } + } + else // + { + if ( bodyPreviewValue == 0 ) + { + iListMode = EListControlTypeDoubleLinePreviewOff; + } + else + { + iListMode = EListControlTypeDoubleLinePreviewOn; + } + } + } + else + { + iNodesInUse = EListControlSeparatorDisabled; + iListMode = EListControlTypeDoubleLinePreviewOff; + } + } + +void CFSEmailUiMailListVisualiser::UpdateMailListTimeDateSettings() + { + FUNC_LOG; + TLocale currentLocaleSettings; + iDateFormats.iTimeFormat = currentLocaleSettings.TimeFormat(); + iDateFormats.iDateFormat = currentLocaleSettings.DateFormat(); + iDateFormats.iAmPmPosition = currentLocaleSettings.AmPmSymbolPosition(); + // Second time separartor + iDateFormats.iTimeSeparator = currentLocaleSettings.TimeSeparator( 1 ); + // Second date separartor + iDateFormats.iDateSeparator = currentLocaleSettings.DateSeparator( 1 ); + } + +STimeDateFormats CFSEmailUiMailListVisualiser::MailListTimeDateSettings() + { + FUNC_LOG; + return iDateFormats; + } + + +void CFSEmailUiMailListVisualiser::SetMailboxNameToStatusPaneL() + { + FUNC_LOG; + iAppUi.SetActiveMailboxNameToStatusPaneL(); + } + +void CFSEmailUiMailListVisualiser::SetBrandedMailBoxIconL() + { + FUNC_LOG; + // Get and draw branded mailbox icon + MFSMailBrandManager& brandManager = iAppUi.GetMailClient()->GetBrandManagerL(); + CGulIcon* mailBoxIcon(0); + TRAPD( err, mailBoxIcon = brandManager.GetGraphicL( EFSMailboxIcon, iAppUi.GetActiveMailboxId() ) ); + if ( err == KErrNone && mailBoxIcon ) + { + CleanupStack::PushL( mailBoxIcon ); + // + TInt iconSize( iAppUi.LayoutHandler()->GetControlBarMailboxIconRect().Width() ); + TSize defaultIconSize ( iconSize, iconSize ); + // + AknIconUtils::SetSize(mailBoxIcon->Bitmap(), defaultIconSize); + AknIconUtils::SetSize(mailBoxIcon->Mask(), defaultIconSize); + // Create texture into TextureManager, If not already existing + iAppUi.FsTextureManager()->CreateBrandedMailboxTexture( mailBoxIcon, + iAppUi.GetActiveMailboxId().PluginId(), + iAppUi.GetActiveMailboxId().Id(), + defaultIconSize ); + // Get branded mailbox icon + iMailBoxIconTexture = &iAppUi.FsTextureManager()->TextureByMailboxIdL( iAppUi.GetActiveMailboxId().PluginId(), + iAppUi.GetActiveMailboxId().Id(), + defaultIconSize ); + iFolderListButton->SetIconL( *iMailBoxIconTexture ); + CleanupStack::PopAndDestroy( mailBoxIcon ); + } + else + { + iFolderListButton->SetIconL( iAppUi.FsTextureManager()->TextureByIndex( EListControlBarMailboxDefaultIcon ) ); + } + } + + +void CFSEmailUiMailListVisualiser::SetBrandedListWatermarkL() + { + FUNC_LOG; + MFSMailBrandManager& brandManager = iAppUi.GetMailClient()->GetBrandManagerL(); + CGulIcon* mailBoxWatermarkIcon(0); + TRAPD( err, mailBoxWatermarkIcon = brandManager.GetGraphicL( EFSWatermark, iAppUi.GetActiveMailboxId() ) ); + if ( err == KErrNone && mailBoxWatermarkIcon ) + { + CleanupStack::PushL( mailBoxWatermarkIcon ); + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect ); + TInt xPos = mainPaneRect.iBr.iX/100*40; // 40% of main pane width + TInt yPos = mainPaneRect.iBr.iY/100*40; // 40% of main pane height + TSize defaultWaterMarkSize(xPos,yPos); + AknIconUtils::SetSize(mailBoxWatermarkIcon->Bitmap(), defaultWaterMarkSize); + AknIconUtils::SetSize(mailBoxWatermarkIcon->Mask(), defaultWaterMarkSize); + if ( !iMailBoxWatermarkTexture ) + { + // iMailBoxWatermarkTexture = CAlfTexture::NewL( *iEnv, Id() ); // DOLATER - Replaced by line below, creates blank texture until UploadL's replaced by something + iMailBoxWatermarkTexture = &CAlfStatic::Env().TextureManager().BlankTexture(); + } + // DOLATER - Gone from Alfred, needs to be replaced with something + //iMailBoxWatermarkTexture->UploadL( *mailBoxWatermarkIcon->Bitmap(), mailBoxWatermarkIcon->Mask() ); + CleanupStack::PopAndDestroy( mailBoxWatermarkIcon ); + TPoint watermarkPosition( mainPaneRect.iBr.iX-xPos-20, mainPaneRect.iBr.iY-yPos-20 ); + iMailTreeListVisualizer->SetWatermarkPos( watermarkPosition ); + iMailTreeListVisualizer->SetWatermarkSize( defaultWaterMarkSize ); + iMailTreeListVisualizer->SetWatermarkOpacity( 0.3 ); + iMailTreeListVisualizer->SetWatermarkL( iMailBoxWatermarkTexture ); + } + else + { + // Not found, hide watermark + iMailTreeListVisualizer->SetWatermarkOpacity( 0 ); + } + } + +TFsTreeItemId CFSEmailUiMailListVisualiser::ParentNode( TFsTreeItemId aItemId ) const + { + FUNC_LOG; + if ( iNodesInUse ) + { + TFsTreeItemId parentNodeId = iMailList->Parent( aItemId ); + if ( iMailList->IsNode( parentNodeId ) ) + { + return parentNodeId; + } + } + return KErrNotFound; + } + +TBool CFSEmailUiMailListVisualiser::DoScrollMarkUnmarkL() + { + FUNC_LOG; + TBool ret = EFalse; + + if ( !iMarkingMode ) + { + EnterMarkingModeL(); + } + + // + if ( iFocusedControl == EMailListComponent && iModel->Count() ) + // + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( HighlightedIndex() ) ); + + if ( item && item->ModelItemType() == ETypeMailItem ) // Separators are not markable + { + if ( !iListMarkItemsState ) + { + iMailList->MarkItemL( iMailList->FocusedItem(), EFalse ); + } + else + { + iMailList->MarkItemL( iMailList->FocusedItem(), ETrue ); + } + ret = ETrue; + } + } + + return ret; + } + +// Mark / unmark all items under current separator +void CFSEmailUiMailListVisualiser::MarkItemsUnderSeparatorL( TBool aMarked, TInt aSeparatorId ) + { + FUNC_LOG; + + if ( iTreeItemArray.Count() ) + { + // Find all items under wanted separator. + for ( TInt i = aSeparatorId + 1; i < iTreeItemArray.Count(); i++ ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( i ) ); + + // Mark / unmark mail items. + if ( item && + item->ModelItemType() == ETypeMailItem && + !iMailList->IsNode( iTreeItemArray[i].iListItemId ) ) + { + iMailList->MarkItemL( iTreeItemArray[i].iListItemId, aMarked ); + } + else + { + // Stop iteration since another iterator was reached. + break; + } + } + } + } + +// Check if all items under current separator are marked +TBool CFSEmailUiMailListVisualiser::AreAllItemsMarkedUnderSeparatorL( TInt aSeparatorId ) + { + FUNC_LOG; + + TBool ret(ETrue); + + if ( iTreeItemArray.Count() ) + { + // Find all items under wanted separator. + for ( TInt i = aSeparatorId + 1; i < iTreeItemArray.Count(); i++ ) + { + CFSEmailUiMailListModelItem* item = + static_cast( iModel->Item( i ) ); + + // Mark / unmark mail items. + if ( item && + item->ModelItemType() == ETypeMailItem && + !iMailList->IsNode( iTreeItemArray[i].iListItemId ) ) + { + if ( !iMailList->IsMarked( iTreeItemArray[i].iListItemId )) + { + // Att least one unmarked item found + ret = EFalse; + break; + } + } + else + { + // Stop iteration since another iterator was reached. + break; + } + } + } + return ret; + } + +// Navigation functions, used mainly from viewer +TBool CFSEmailUiMailListVisualiser::IsNextMsgAvailable( TFSMailMsgId aCurrentMsgId, + TFSMailMsgId& aFoundNextMsgId, + TFSMailMsgId& aFoundNextMsgFolder ) const + { + FUNC_LOG; + TBool ret(EFalse); + TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId ); + if ( curIdx >= 0 ) + { + TInt nextIdx = NextMessageIndex(curIdx); + if ( nextIdx >= 0 ) + { + ret = ETrue; + aFoundNextMsgId = MsgIdFromIndex(nextIdx); + aFoundNextMsgFolder = iMailFolder->GetFolderId(); + } + } + + return ret; + } + +TBool CFSEmailUiMailListVisualiser::IsPreviousMsgAvailable( TFSMailMsgId aCurrentMsgId, + TFSMailMsgId& aFoundPreviousMsgId, + TFSMailMsgId& aFoundPrevMsgFolder ) const + { + FUNC_LOG; + TBool ret(EFalse); + TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId ); + if ( curIdx >= 0 ) + { + TInt prevIdx = PreviousMessageIndex(curIdx); + if ( prevIdx >= 0 ) + { + ret = ETrue; + aFoundPreviousMsgId = MsgIdFromIndex(prevIdx); + aFoundPrevMsgFolder = iMailFolder->GetFolderId(); + } + } + + return ret; + } + +TInt CFSEmailUiMailListVisualiser::MoveToNextMsgL( TFSMailMsgId aCurrentMsgId, TFSMailMsgId& aFoundNextMsgId ) + { + FUNC_LOG; + TInt ret(KErrNotFound); + + TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId ); + TInt nextIdx = NextMessageIndex( curIdx ); + + if ( curIdx >= 0 && nextIdx >= 0 ) + { + // Focus the new message + // + iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[nextIdx].iListItemId, EFalse ); + // + ChangeReadStatusOfHighlightedL( ETrue ); + + aFoundNextMsgId = MsgIdFromIndex( nextIdx ); + ret = KErrNone; + } + if ( ret == KErrNone ) + { + OpenHighlightedMailL(); + } + return ret; + } + +TInt CFSEmailUiMailListVisualiser::MoveToPreviousMsgL( TFSMailMsgId aCurrentMsgId, TFSMailMsgId& aFoundPreviousMsgId ) + { + FUNC_LOG; + TInt ret(KErrNotFound); + + TInt curIdx = ItemIndexFromMessageId( aCurrentMsgId ); + TInt prevIdx = PreviousMessageIndex( curIdx ); + + if ( curIdx >= 0 && prevIdx >= 0 ) + { + // Focus the new message + // + iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[prevIdx].iListItemId, EFalse ); + // + ChangeReadStatusOfHighlightedL( ETrue ); + aFoundPreviousMsgId = MsgIdFromIndex( prevIdx ); + ret = KErrNone; + } + + if ( ret == KErrNone ) + { + OpenHighlightedMailL(); + } + return ret; + } + +TInt CFSEmailUiMailListVisualiser::MoveToPreviousMsgAfterDeleteL( TFSMailMsgId aFoundPreviousMsgId ) + { + FUNC_LOG; + TInt ret(KErrNotFound); + + TInt idx = ItemIndexFromMessageId( aFoundPreviousMsgId ); + if ( idx >= 0 ) + { + // Focus the previous message + iMailTreeListVisualizer->SetFocusedItemL( iTreeItemArray[idx].iListItemId, EFalse ); + ChangeReadStatusOfHighlightedL( ETrue ); + ret = KErrNone; + } + + if ( ret == KErrNone ) + { + OpenHighlightedMailL(); + } + + return ret; + } + +void CFSEmailUiMailListVisualiser::ManualMailBoxSync( TBool aManualMailBoxSync ) + { + FUNC_LOG; + iManualMailBoxSync = aManualMailBoxSync; + } + +TBool CFSEmailUiMailListVisualiser::GetLatestSyncState() + { + FUNC_LOG; + CFSMailBox* activeMailbox = iAppUi.GetActiveMailbox(); + + TBool ret = EFalse; + + if ( activeMailbox ) + { + TSSMailSyncState latestSyncstate = activeMailbox->CurrentSyncState(); + if(latestSyncstate == InboxSyncing || + latestSyncstate == StartingSync || + latestSyncstate == EmailSyncing || + latestSyncstate == OutboxSyncing || + latestSyncstate == SentItemsSyncing || + latestSyncstate == DraftsSyncing || + latestSyncstate == CalendarSyncing || + latestSyncstate == ContactsSyncing || + latestSyncstate == TasksSyncing || + latestSyncstate == NotesSyncing || + latestSyncstate == FilesSyncing || + latestSyncstate == DataSyncStarting ) + { + ret = ETrue; + } + } + + return ret; + } + +void CFSEmailUiMailListVisualiser::ConnectionIconHandling() + { + FUNC_LOG; + iAppUi.UpdateTitlePaneConnectionStatus(); + } + +void CFSEmailUiMailListVisualiser::SetListAndCtrlBarFocusL() + { + FUNC_LOG; + if ( iFocusedControl == EMailListComponent ) + { + iMailList->SetFocusedL( ETrue ); + iControlBarControl->SetFocusL( EFalse ); + } + else + { + if( iStylusPopUpMenuVisible ) + { + return; + } + + iMailList->SetFocusedL( EFalse ); + TInt focusedBtnId = KErrNotFound; + MFsControlButtonInterface* focusedBtn = iControlBarControl->GetFocusedButton(); + if ( focusedBtn ) + { + focusedBtnId = focusedBtn->Id(); + } + iControlBarControl->SetFocusL( ETrue ); + if ( focusedBtnId != KErrNotFound ) + { + iControlBarControl->SetFocusByIdL( focusedBtnId ); + } + iControlBarControl->MakeSelectorVisible( IsFocusShown() ); + } + } + +void CFSEmailUiMailListVisualiser::GetParentLayoutsL( RPointerArray& aLayoutArray ) const + { + aLayoutArray.AppendL( iScreenAnchorLayout ); + aLayoutArray.AppendL( iControlBarControl->Visual() ); + } + +// hide or show CAlfVisuals ( used for activation or deactivation ) +void CFSEmailUiMailListVisualiser::FadeOut(TBool aDirectionOut) + { + FUNC_LOG; + TAlfTimedValue timedValue( 0, 0 ); + if ( !aDirectionOut ) + { + timedValue.SetTarget( 1, 0 ); + } + if ( iScreenAnchorLayout != NULL ) + { + iScreenAnchorLayout->SetOpacity( timedValue ); + } + if (iControlBarControl && iControlBarControl->Visual() != NULL ) + { + iControlBarControl->Visual()->SetOpacity( timedValue ); + } + } + +// Sets aActiveMailboxId and aActiveFolderId from iMailFolder if available +TInt CFSEmailUiMailListVisualiser::GetActiveFolderId(TFSMailMsgId& aActiveMailboxId, TFSMailMsgId& aActiveFolderId) const + { + if (iMailFolder != NULL) + { + aActiveMailboxId = iMailFolder->GetMailBoxId(); + aActiveFolderId = iMailFolder->GetFolderId(); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +void CFSEmailUiMailListVisualiser::CreateExtensionL() + { + CFSMailBox* box = iAppUi.GetActiveMailbox(); + CEmailExtension* ext=NULL; + if (box) + { + ext = box->ExtensionL( KEmailMailboxStateExtensionUid ); + } + if (ext) + { + iExtension = reinterpret_cast( ext ); + iExtension->SetStateDataProvider( this ); + } + } + +TBool CFSEmailUiMailListVisualiser::CheckAutoSyncSettingL() + { + CEmailExtension* ext=NULL; + TBool manualSync = EFalse; + CFSMailBox* box = iAppUi.GetActiveMailbox(); + if (box) + { + ext = box->ExtensionL( KEmailSettingExtensionUid ); + if (ext) + { + CEmailSettingsExtension* extension = reinterpret_cast( ext ); + extension->SetMailBoxId(box->GetId()); + manualSync = extension->IsSetL(EmailSyncInterval); + box->ReleaseExtension(extension); + } + } + return manualSync; + } + +////////////////////////////////////////////////////////////////// +// Class implementation CMailListUpdater +/////////////////////////////////////////////////////////////////// + + +// ----------------------------------------------------------------------------- +// CMailListUpdater::NewL +// NewL function. Returns timer object. +// ----------------------------------------------------------------------------- +// +CMailListUpdater* CMailListUpdater::NewL( CFSEmailUiMailListVisualiser* aMailListVisualiser ) + { + FUNC_LOG; + CMailListUpdater* self = new (ELeave) CMailListUpdater( aMailListVisualiser ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMailListUpdater::~CMailListUpdater +// D'tor +// ----------------------------------------------------------------------------- +// +CMailListUpdater::~CMailListUpdater() + { + FUNC_LOG; + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CMailListUpdater::CMailListUpdater +// C'tor +// ----------------------------------------------------------------------------- +// +CMailListUpdater::CMailListUpdater( CFSEmailUiMailListVisualiser* aMailListVisualiser ) + : CTimer( EPriorityStandard ), + iMailListVisualiser( aMailListVisualiser ) + { + FUNC_LOG; + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CMailListUpdater::RunL +// Timer trigger function. +// ----------------------------------------------------------------------------- +// +void CMailListUpdater::RunL() + { + FUNC_LOG; + if ( iIsSorting ) + { + iMailListVisualiser->UpdateMailListModelL(); + iMailListVisualiser->RefreshL(); + // Sorting is completed + iIsSorting = EFalse; + // Dismiss wait note. + if ( iWaitNote ) + { + iWaitNote->ProcessFinishedL(); + } + } + else + { + // Store the list of marked items. The markings are erased when the list + // is repopulated and, hence, the markings need to be reset after the + // refreshing is done. The marked items must be identified by the message + // ID rather than with the list ID because refreshing may change the list IDs. + RArray markedMessages; + CleanupClosePushL( markedMessages ); + iMailListVisualiser->GetMarkedMessagesL( markedMessages ); + + // Store the message ID of the focused item + TFSMailMsgId msgIdBeforeRefresh; + TFsTreeItemId firstVisibleListId = iMailListVisualiser->iMailTreeListVisualizer->FirstVisibleItem(); + TInt modelFirstIndexBeforeUpdate = iMailListVisualiser->ModelIndexFromListId( firstVisibleListId ); + TInt highlightedIndexBeforeUpdate = iMailListVisualiser->HighlightedIndex(); + TInt modelCountBeforeUpdate = iMailListVisualiser->iModel->Count(); + if ( iMailListVisualiser->iModel->Count() ) + { + CFSEmailUiMailListModelItem* item = + static_cast(iMailListVisualiser->iModel->Item( highlightedIndexBeforeUpdate ) ); + if ( item && item->ModelItemType() == ETypeMailItem ) + { + msgIdBeforeRefresh = item->MessagePtr().GetMessageId(); + } + } + + iMailListVisualiser->UpdateMailListModelL(); + iMailListVisualiser->RefreshL( &msgIdBeforeRefresh ); + + // Focus is set to last focused item. After this, try to keep the same first item that previous + // Check how many messages have been added + TInt modelIndexDifference = highlightedIndexBeforeUpdate-modelFirstIndexBeforeUpdate; // 0 or more + if ( modelIndexDifference < 0 ) + { + modelIndexDifference = 0; // safety + } + TInt toBeFirstIdx = iMailListVisualiser->HighlightedIndex() - modelIndexDifference; + CFSEmailUiMailListModelItem* toBeFirstVisItem = + static_cast( iMailListVisualiser->iModel->Item(toBeFirstIdx) ); + if ( toBeFirstVisItem ) + { + // + iMailListVisualiser->iMailTreeListVisualizer->SetFirstVisibleItemL( toBeFirstVisItem->CorrespondingListId() ); + // + } + + // Restore the marking status + iMailListVisualiser->MarkMessagesIfFoundL( markedMessages ); + CleanupStack::PopAndDestroy( &markedMessages ); + } + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CMailListUpdater::Start +// Timer starting function. +// ----------------------------------------------------------------------------- +// +void CMailListUpdater::StartL( TBool aIsSorting ) + { + FUNC_LOG; + if ( iWaitNote ) + { + iWaitNote->ProcessFinishedL(); + } + + iIsSorting = aIsSorting; + Cancel(); + if ( iIsSorting ) + { + // Start wait note + TFsEmailUiUtility::ShowWaitNoteL( iWaitNote, R_FSE_WAIT_SORTING_TEXT, EFalse, ETrue ); + After( 10 ); // Update shortly after selection has been made. + } + else + { + // Mail added update + After( KMsgUpdaterTimerDelay ); // Update after 1,5 seconds + } + } + +// ----------------------------------------------------------------------------- +// CMailListUpdater::Stop +// Timer stopping function +// ----------------------------------------------------------------------------- +// +void CMailListUpdater::Stop() + { + FUNC_LOG; + Cancel(); + } + + + +////////////////////////////////////////////////////////////////// +// Class implementation CMsgMovedNoteTimer +/////////////////////////////////////////////////////////////////// + + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::NewL +// NewL function. Returns timer object. +// ----------------------------------------------------------------------------- +// +CMsgMovedNoteTimer* CMsgMovedNoteTimer::NewL( CFreestyleEmailUiAppUi* aAppUi, CFSEmailUiMailListVisualiser* aMailListVisualiser ) + { + FUNC_LOG; + CMsgMovedNoteTimer* self = new (ELeave) CMsgMovedNoteTimer( aAppUi, aMailListVisualiser ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::CMsgMovedNoteTimer +// D'tor +// ----------------------------------------------------------------------------- +// +CMsgMovedNoteTimer::~CMsgMovedNoteTimer() + { + FUNC_LOG; + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CMailListUpdater::CMailListUpdater +// C'tor +// ----------------------------------------------------------------------------- +// +CMsgMovedNoteTimer::CMsgMovedNoteTimer( CFreestyleEmailUiAppUi* aAppUi, CFSEmailUiMailListVisualiser* aMailListVisualiser ) + : CTimer( EPriorityStandard ), + iAppUi( aAppUi), + iMailListVisualiser( aMailListVisualiser ) + { + FUNC_LOG; + CActiveScheduler::Add( this ); + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::RunL +// Timer trigger function. +// ----------------------------------------------------------------------------- +// +void CMsgMovedNoteTimer::RunL() + { + FUNC_LOG; + TFsEmailUiUtility::DisplayMsgsMovedNoteL( iMsgCount, iDestinationFolderId, EFalse ); + Cancel(); + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::Start +// Timer starting function. +// ----------------------------------------------------------------------------- +// +void CMsgMovedNoteTimer::Start( TInt aMsgCount, const TFSMailMsgId aDestinationFolderId ) + { + FUNC_LOG; + Cancel(); + iMsgCount = aMsgCount, + iDestinationFolderId = aDestinationFolderId; + TInt viewSlideinTime = iAppUi->LayoutHandler()->ViewSlideEffectTime(); + if ( viewSlideinTime == 0 ) + { + viewSlideinTime = 100; + } + After( viewSlideinTime ); + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::Stop +// Timer stopping function +// ----------------------------------------------------------------------------- +// +void CMsgMovedNoteTimer::Stop() + { + FUNC_LOG; + Cancel(); + } + + +////////////////////////////////////////////////////////////////// +// Class implementation CDateChnageTimer +/////////////////////////////////////////////////////////////////// + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::NewL +// Two phased constructor +// ----------------------------------------------------------------------------- +// +CDateChangeTimer* CDateChangeTimer::NewL( CFSEmailUiMailListVisualiser& aMailListVisualiser ) + { + FUNC_LOG; + CDateChangeTimer* self = new ( ELeave ) CDateChangeTimer( aMailListVisualiser ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::CDateChangeTimer +// First phase constructor +// ----------------------------------------------------------------------------- +// +CDateChangeTimer::CDateChangeTimer( CFSEmailUiMailListVisualiser& aMailListVisualiser ) + : CTimer( EPriorityStandard ), iMailListVisualiser( aMailListVisualiser ) + { + FUNC_LOG; + CActiveScheduler::Add( this ); + iDayCount = DayCount(); + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::~CDateChangeTimer +// Destructor +// ----------------------------------------------------------------------------- +// +CDateChangeTimer::~CDateChangeTimer() + { + FUNC_LOG; + // no implementation needed + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::Start +// Request event at 00:00 tomorrow +// ----------------------------------------------------------------------------- +// +void CDateChangeTimer::Start() + { + FUNC_LOG; + TTime now; + now.HomeTime(); + + // Construct target time + TTime eventTime = now + TTimeIntervalDays( 1 ); + TDateTime eventDateTime = eventTime.DateTime(); + eventDateTime.SetHour(0); + eventDateTime.SetMinute(0); + eventDateTime.SetSecond(0); + eventDateTime.SetMicroSecond(0); + eventTime = TTime( eventDateTime ); + + // Issue the request + At( eventTime ); + } + +// ----------------------------------------------------------------------------- +// CMsgMovedNoteTimer::RunL +// Function gets called when system time reaches the 00:00 in the next day or +// when the system time has been changed by the user. Both cases can be handled +// in the same way. +// ----------------------------------------------------------------------------- +// +void CDateChangeTimer::RunL() + { + FUNC_LOG; + + if (iStatus.Int() != KErrNone) + { + INFO_1("### CDateChangeTimer::RunL (err=%d) ###", iStatus.Int()); + } + + + TBool dayChanged = EFalse; + TInt dayCount = DayCount(); + if (dayCount != iDayCount) + { + + iDayCount = dayCount; + dayChanged = ETrue; + } + + + if ( KErrCancel == iStatus.Int() ) + { + ; + } + else if ( KErrAbort == iStatus.Int() ) // System time changed + { + if (dayChanged) + { + TRAP_IGNORE( iMailListVisualiser.NotifyDateChangedL() ); + } + Start(); + } + else // interval is over + { + // Update mail list and reissue the request for timer event + TRAP_IGNORE( iMailListVisualiser.NotifyDateChangedL() ); + Start(); + } + + } + + +TInt CDateChangeTimer::DayCount() + { + TTime now; + now.HomeTime(); + TTime minTime = Time::MinTTime(); + TTimeIntervalDays days = now.DaysFrom(minTime); + return days.Int(); + } + + + + + + + +