diff -r 000000000000 -r 8466d47a6819 emailuis/emailui/src/FreestyleEmailUiMsgDetailsVisualiser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailuis/emailui/src/FreestyleEmailUiMsgDetailsVisualiser.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,1812 @@ +/* +* Copyright (c) 2007 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 : FreestyleEmailUi message details view implementation +* Version : %version: 44 % +* +*/ + + + +// SYSTEM INCLUDES +#include "emailtrace.h" +#include +#include +#include +#include +#include +#include +#include +// SF +#include +#include +#include +#include +// +#include +// + +// +#include "CFSMailMessage.h" +#include "CFSMailClient.h" +// + +#include "FSEmailBuildFlags.h" +// +#include "cfsccontactactionmenu.h" +#include "mfsccontactactionmenumodel.h" +// + +// +#include "fstreelist.h" +#include "fstreevisualizerbase.h" +#include "fstreeplainonelinenodedata.h" +#include "fstreeplainonelinenodevisualizer.h" +#include "fstreeplainonelineitemdata.h" +#include "fstreeplainonelineitemvisualizer.h" +#include "fstreeplaintwolineitemdata.h" +#include "fstreeplaintwolineitemvisualizer.h" +#include +// + +// INTERNAL INCLUDES +#include "FreestyleEmailUiAppui.h" +#include "FreestyleEmailUiMsgDetailsControl.h" +#include "FreestyleEmailUiMsgDetailsModel.h" +#include "FreestyleEmailUiMsgDetailsVisualiser.h" +#include "FreestyleEmailUi.hrh" +#include "FreestyleEmailUiLayoutHandler.h" +#include "FreestyleEmailUiTextureManager.h" +#include "FreestyleEmailUiUtilities.h" +#include "FreestyleEmailUiShortcutBinding.h" +#include "FreestyleEmailUiContactHandler.h" +#include "FSDelayedLoader.h" + + +CFSEmailUiMsgDetailsVisualiser* CFSEmailUiMsgDetailsVisualiser::NewL( CAlfEnv& aEnv, + CAlfControlGroup& aControlGroup, + CFreestyleEmailUiAppUi& aAppUi ) + { + FUNC_LOG; + CFSEmailUiMsgDetailsVisualiser* self = CFSEmailUiMsgDetailsVisualiser::NewLC(aEnv, aControlGroup, aAppUi ); + CleanupStack::Pop(self); + return self; + } + +CFSEmailUiMsgDetailsVisualiser* CFSEmailUiMsgDetailsVisualiser::NewLC( CAlfEnv& aEnv, + CAlfControlGroup& aControlGroup, + CFreestyleEmailUiAppUi& aAppUi ) +{ + FUNC_LOG; + CFSEmailUiMsgDetailsVisualiser* self = new (ELeave) CFSEmailUiMsgDetailsVisualiser( aEnv, aAppUi, aControlGroup ); + CleanupStack::PushL(self); + self->ConstructL(); + return self; +} + +void CFSEmailUiMsgDetailsVisualiser::ConstructL() + { + FUNC_LOG; + + BaseConstructL( R_FSEMAILUI_MAIL_DETAILS_VIEW ); + + iFirstStartCompleted = EFalse; + + } + +// CFSEmailUiMsgDetailsVisualiser::DoFirstStartL() +// Purpose of this function is to do first start only when msg details is +// really needed to be shown. Implemented to make app startuo faster. +void CFSEmailUiMsgDetailsVisualiser::DoFirstStartL() + { + FUNC_LOG; + iControl = CFSEmailUiMsgDetailsControl::NewL( iEnv, *this ); + iModel = new (ELeave) CFSEmailUiMsgDetailsModel(); + + UpdateListSizeAttributes(); + + iParentLayout = CAlfDeckLayout::AddNewL( *iControl ); + iParentLayout->SetFlags( EAlfVisualFlagLayoutUpdateNotification ); + iParentLayout->SetRect( iScreenRect ); + + iTreeVisualizer = CFsTreeVisualizerBase::NewL(iControl, *iParentLayout); + iTreeVisualizer->SetItemExpansionDelay( iAppUi.LayoutHandler()->ListItemExpansionDelay() ); + iTreeVisualizer->SetScrollTime( iAppUi.LayoutHandler()->ListScrollingTime() ); + iTreeVisualizer->SetFadeInEffectTime( iAppUi.LayoutHandler()->ListFadeInEffectTime() ); + iTreeVisualizer->SetFadeOutEffectTime( iAppUi.LayoutHandler()->ListFadeOutEffectTime() ); + + iTreeList = CFsTreeList::NewL( *iTreeVisualizer, iEnv ); + iTreeList->HideListL(); + iTreeList->SetLoopingType( EFsTreeListLoopingJumpToFirstLast ); + iTreeList->SetScrollbarVisibilityL( EFsScrollbarAuto ); + iTreeList->SetIndentationL( 0 ); + + // Compared to S60 3.2.3 in S60 5.0 Alf offers the key events in + // opposite order. + ControlGroup().AppendL( iControl ); + ControlGroup().AppendL( iTreeList->TreeControl() ); + // + + // Touch + iTreeList->AddObserverL(*this); + // + + // Set page up and page down keys + iTreeVisualizer->AddCustomPageUpKey( EStdKeyPageUp ); + iTreeVisualizer->AddCustomPageDownKey( EStdKeyPageDown ); + iTreeVisualizer->SetItemsAlwaysExtendedL( ETrue ); + + iAppUi.LayoutHandler()->SetListMarqueeBehaviour( iTreeList ); + + iFirstStartCompleted = ETrue; + } + +CFSEmailUiMsgDetailsVisualiser::CFSEmailUiMsgDetailsVisualiser( CAlfEnv& aEnv, CFreestyleEmailUiAppUi& aAppUi, CAlfControlGroup& aControlGroup ) + : CFsEmailUiViewBase(aControlGroup, aAppUi), + iEnv(aEnv), + iFirstViewActivation( ETrue ), + iExpandCollapseMode( EExpandAll ), + // video call + iVideoCall( EFalse ) + // + { + FUNC_LOG; + } + +CFSEmailUiMsgDetailsVisualiser::~CFSEmailUiMsgDetailsVisualiser() + { + FUNC_LOG; + delete iModel; + iModel = NULL; + + delete iPreviousTitleText; + iPreviousTitleText = NULL; + + delete iViewedMsg; + iViewedMsg = NULL; + + delete iNoDisplayNameAvailableText; + iNoDisplayNameAvailableText = NULL; + + delete iNoEmailAddressAvailableText; + iNoEmailAddressAvailableText = NULL; + + delete iTreeList; + iTreeList = NULL; + + iNodeIds.Close(); + } + +TUid CFSEmailUiMsgDetailsVisualiser::Id() const + { + FUNC_LOG; + return MsgDetailsViewId; + } + +// Toolbar +/*void CFSEmailUiMsgDetailsVisualiser::DoActivateL(const TVwsViewId& aPrevViewId, + TUid aCustomMessageId, + const TDesC8& aCustomMessage)*/ +void CFSEmailUiMsgDetailsVisualiser::ChildDoActivateL( + const TVwsViewId& aPrevViewId, TUid aCustomMessageId, + const TDesC8& aCustomMessage) +// Toolbar + { + FUNC_LOG; + if ( !iFirstStartCompleted ) + { + DoFirstStartL(); + } + + UpdateListSizeAttributes(); + iParentLayout->SetRect( iScreenRect ); + + if ( aCustomMessageId == KStartMsgDetailsReturnToPrevious ) + { + // Fisrt handle special case where we are returning to msg details view, + // so we don't need to recreate list contents, just refresh the view + if ( iViewedMsg ) // Safety check + { + // Set title bar text to "Message/Meeting details" + ChangeTitleBarTextL( ETrue ); + + // Hide list and switch this view as active + iTreeList->HideListL(); + + // Then just refresh the list as in dynamic variant switch, + // because screen orientation might have changed + HandleDynamicVariantSwitchL( EScreenLayoutChanged ); + } + } + else + { + // This is the "normal" case, so we need to recreate the list contents + + // Store previous view ID + iPreviousViewUid = aPrevViewId.iViewUid; + + TMsgDetailsActivationData subView; + TPckgBuf viewData( subView ); + viewData.Copy( aCustomMessage ); + subView = viewData(); + + delete iViewedMsg; + iViewedMsg = NULL; + + iViewedMsg = iAppUi.GetMailClient()->GetMessageByUidL( subView.iMailBoxId, subView.iFolderId, subView.iMessageId, EFSMsgDataEnvelope ); + CFSMailBox* mailBox = iAppUi.GetMailClient()->GetMailBoxByUidL( subView.iMailBoxId ); + CleanupStack::PushL( mailBox ); + if ( mailBox && TFsEmailUiUtility::IsRemoteLookupSupported( *mailBox ) ) + { + iRCLSupported = ETrue; + } + else + { + iRCLSupported = EFalse; + } + CleanupStack::PopAndDestroy( mailBox ); + + if( iFirstViewActivation ) + { + iTreeVisualizer->SetMenuIcon( iAppUi.FsTextureManager()->TextureByIndex( EListControlMenuIcon ) ); + // S60 skin support + //iTreeVisualizer->SetBackgroundTextureL( iAppUi.FsTextureManager()->TextureByIndex( EBackgroundTextureMailList ) ); + // + + CAlfBrush* selectorBrush = iAppUi.FsTextureManager()->ListSelectorBrushL(); + iTreeVisualizer->SetSelectorPropertiesL( selectorBrush, 1.0, CFsTreeVisualizerBase::EFsSelectorMoveSmoothly ); + + iFirstViewActivation = EFalse; + } + + if ( iViewedMsg ) // Safety check + { + // Set title bar text to "Message/Meeting details" + ChangeTitleBarTextL( ETrue ); + + iTreeList->HideListL(); + + // By default we expand all nodes, if parameters doesn't state + // something else + iExpandCollapseMode = EExpandAll; + if ( aCustomMessageId == KStartMsgDetailsToTo ) + { + iExpandCollapseMode = ECollapseAllExceptTo; + } + else if ( aCustomMessageId == KStartMsgDetailsToCc ) + { + iExpandCollapseMode = ECollapseAllExceptCc; + } + else if ( aCustomMessageId == KStartMsgDetailsToBcc ) + { + iExpandCollapseMode = ECollapseAllExceptBcc; + } + + iParentLayout->SetRect( iScreenRect ); + ClearMsgDetailsModelL(); + + UpdateMsgDetailsModelL(); + iTreeList->ShowListL(); + } + } + // Touch + iTreeList->SetFocusedL(ETrue); + // + } + +void CFSEmailUiMsgDetailsVisualiser::ChildDoDeactivate() + { + FUNC_LOG; + if ( !iAppUi.AppUiExitOngoing() ) + { + if ( iTreeList->IsFocused() ) + { + TRAP_IGNORE( { + iTreeList->SetFocusedL(EFalse); + iTreeList->SetFocusedItemL(KFsTreeNoneID); + } ); + } + iTreeVisualizer->NotifyControlVisibilityChange( EFalse ); + } + } + +void CFSEmailUiMsgDetailsVisualiser::PrepareForExit() + { + delete iViewedMsg; + iViewedMsg = NULL; + } + + +void CFSEmailUiMsgDetailsVisualiser::ChangeTitleBarTextL( TBool aViewStarted ) + { + FUNC_LOG; + if ( iFirstStartCompleted ) // Safety + { + if ( aViewStarted ) + { + // Store previous application title text + delete iPreviousTitleText; + iPreviousTitleText = NULL; + iPreviousTitleText = iAppUi.TitlePaneTextL().AllocL(); + + HBufC* titleText = NULL; + if( iViewedMsg->IsFlagSet( EFSMsgFlag_CalendarMsg ) ) + { + titleText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_MEETING_HEADING ); + } + else + { + titleText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_HEADING ); + } + + iAppUi.SetTitlePaneTextL( *titleText ); + + CleanupStack::PopAndDestroy( titleText ); + } + else + { + if ( iPreviousTitleText ) + { + iAppUi.SetTitlePaneTextL( *iPreviousTitleText ); // Set application title text back + } + } + } + } + +void CFSEmailUiMsgDetailsVisualiser::LaunchActionMenuL() + { + FUNC_LOG; + CFSEmailUiActionMenu::RemoveAllL(); + + RFsEActionMenuIdList itemList; + itemList.AppendL(FsEActionMenuCall); + // video call + itemList.AppendL( FsEActionMenuCallVideo ); + // + itemList.AppendL(FsEActionMenuCreateMessage); + itemList.AppendL(FsEActionMenuContactDetails); + itemList.AppendL(FsEActionMenuAddToContacts); + if ( iRCLSupported ) + { + itemList.AppendL(FsEActionMenuRemoteLookup); + } + CFSEmailUiActionMenu::AddCustomItemsL( itemList ); + itemList.Close(); + + // Touch + TActionMenuCustomItemId itemId = CFSEmailUiActionMenu::ExecuteL( EFscCustom, 0, this ); + // + + HandleActionMenuCommandL( itemId ); + } + +void CFSEmailUiMsgDetailsVisualiser::HandleActionMenuCommandL( TActionMenuCustomItemId itemId ) + { + FUNC_LOG; + switch( itemId ) + { + case FsEActionMenuCall: + { + CallToFocusedItemL(); + } + break; + // video call + case FsEActionMenuCallVideo: // Video Call + { + iVideoCall = ETrue; + CallToFocusedItemL(); + } + break; + // + case FsEActionMenuCreateMessage: + { + CreateMessageToFocusedItemL(); + } + break; + + case FsEActionMenuContactDetails: + { + ShowContactDetailsForFocusedItemL(); + } + break; + + case FsEActionMenuAddToContacts: + { + AddFocusedItemToContactsL(); + } + break; + + case FsEActionMenuRemoteLookup: + { + LaunchRemoteLookupForFocusedItemL(); + } + break; + } + } + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::GetEmailAddressForFocusedItem +// Returns email address of the focused list item. NULL returned if not found. +// ----------------------------------------------------------------------------- +CFSMailAddress* CFSEmailUiMsgDetailsVisualiser::GetEmailAddressForFocusedItem() const + { + FUNC_LOG; + CFSMailAddress* foundEmailAddress = NULL; + CFSEmailUiMsgDetailsItem* item = iModel->ItemByListId( iTreeList->FocusedItem() ); + if( item ) + { + foundEmailAddress = item->iMailAddress; + } + return foundEmailAddress; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::GetEmailAddressForFocusedItem +// Returns email address of the focused list item. NULL returned if not found. +// ----------------------------------------------------------------------------- +TDesC* CFSEmailUiMsgDetailsVisualiser::GetEmailAddressForFocusedItemAsTDes() const + { + FUNC_LOG; + TDesC* foundEmailAddress = NULL; + CFSMailAddress* address = GetEmailAddressForFocusedItem(); + if( address ) + { + foundEmailAddress = &address->GetEmailAddress(); + } + return foundEmailAddress; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::SendEmailToFocusedItemL +// +// Open composer and set the focused item as recipient, if valid email address +// is available. Return ETrue if valid email address was found, EFalse if not. +// ----------------------------------------------------------------------------- +TBool CFSEmailUiMsgDetailsVisualiser::SendEmailToFocusedItemL() const + { + FUNC_LOG; + TBool addrFound = EFalse; + CFSMailAddress* address = GetEmailAddressForFocusedItem(); + if( address ) + { + iAppUi.LaunchEditorL( address ); + addrFound = ETrue; + } + return addrFound; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::CallToFocusedItemL +// ----------------------------------------------------------------------------- +void CFSEmailUiMsgDetailsVisualiser::CallToFocusedItemL() + { + FUNC_LOG; + TDesC* email = GetEmailAddressForFocusedItemAsTDes(); + if( email ) + { + CFSMailClient* mailClient = iAppUi.GetMailClient(); + CFSMailBox* mailBox = mailClient->GetMailBoxByUidL( iViewedMsg->GetMailBoxId() ); + CleanupStack::PushL( mailBox ); + + // video call + if ( iVideoCall ) + { + iVideoCall = EFalse; + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->SetVideoCall( ETrue ); + } + // + + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCallToContactByEmailL( *email, + iAppUi.GetActiveMailbox(), this, EFalse ); + + CleanupStack::PopAndDestroy( mailBox ); + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::CreateMessageToFocusedItemL +// ----------------------------------------------------------------------------- +void CFSEmailUiMsgDetailsVisualiser::CreateMessageToFocusedItemL() const + { + FUNC_LOG; + TDesC* email = GetEmailAddressForFocusedItemAsTDes(); + if( email ) + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->FindAndCreateMsgToContactByEmailL( *email, iAppUi.GetActiveMailbox() ); + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::LaunchRemoteLookupForFocusedItemL +// ----------------------------------------------------------------------------- +void CFSEmailUiMsgDetailsVisualiser::LaunchRemoteLookupForFocusedItemL() const + { + FUNC_LOG; + CFSEmailUiMsgDetailsItem* item = iModel->ItemByListId( iTreeList->FocusedItem() ); + if( !item ) + { + return; + } + CFSMailAddress* address = item->iMailAddress; + if( !address ) + { + return; + } + TDesC* queryString = &address->GetEmailAddress(); + if( !queryString ) + { + queryString = &address->GetDisplayName(); + if( !queryString ) + { + return; + } + } + + // this method assumes that remote lookup is available with current plugin. + CFSMailClient* mailClient = iAppUi.GetMailClient(); + CFSMailBox* mailBox = mailClient->GetMailBoxByUidL( iViewedMsg->GetMailBoxId() ); + CleanupStack::PushL( mailBox ); + + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->LaunchRemoteLookupWithQueryL( *mailBox, *queryString ); + + CleanupStack::PopAndDestroy( mailBox ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::AddFocusedItemToContactsL +// ----------------------------------------------------------------------------- +void CFSEmailUiMsgDetailsVisualiser::AddFocusedItemToContactsL() const + { + FUNC_LOG; + TDesC* email = GetEmailAddressForFocusedItemAsTDes(); + if( email ) + { + TAddToContactsType aType; + //Query to "update existing" or "Create new" --> EFALSE = user choosed "cancel" + if ( CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddtoContactsQueryL( aType ) ) + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->AddToContactL( + *email, EContactUpdateEmail, aType ); + } + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::ShowContactDetailsForFocusedItemL +// ----------------------------------------------------------------------------- +void CFSEmailUiMsgDetailsVisualiser::ShowContactDetailsForFocusedItemL() const + { + FUNC_LOG; + TDesC* email = GetEmailAddressForFocusedItemAsTDes(); + if( email ) + { + CFsDelayedLoader::InstanceL()->GetContactHandlerL()->ShowContactDetailsL( + *email, EContactUpdateEmail, NULL ); + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMsgDetailsVisualiser::CopyFocusedItemToClipboardL +// ----------------------------------------------------------------------------- +void CFSEmailUiMsgDetailsVisualiser::CopyFocusedItemToClipboardL() const + { + FUNC_LOG; + CFSEmailUiMsgDetailsItem* item = iModel->ItemByListId( iTreeList->FocusedItem() ); + if (item) + { + CFSMailAddress* address = item->iMailAddress; + TDesC* text = item->iText; + if ( address ) + { + TDesC* clipBoardText = &address->GetEmailAddress(); + if( !clipBoardText || + (clipBoardText && clipBoardText->Length() == 0) ) + { + clipBoardText = &address->GetDisplayName(); + if( !clipBoardText ) + { + return; + } + } + TFsEmailUiUtility::CopyToClipboardL( *clipBoardText ); + } + else if( text ) + { + TFsEmailUiUtility::CopyToClipboardL( *text ); + } + } + } + +// ----------------------------------------------------------------------------- +// Action menu is available for items that has iMailAddress set in model. +// ----------------------------------------------------------------------------- +TBool CFSEmailUiMsgDetailsVisualiser::HasFocusedItemActionMenu() const + { + FUNC_LOG; + CFSEmailUiMsgDetailsItem* item = iModel->ItemByListId( iTreeList->FocusedItem() ); + if( item && item->iMailAddress ) + { + const TDesC* displayName = &item->iMailAddress->GetDisplayName(); + const TDesC* emailAddress = &item->iMailAddress->GetEmailAddress(); + + if ( (displayName && displayName->Length()) || + (emailAddress && emailAddress->Length()) ) + { + return ETrue; + } + } + return EFalse; + } + +void CFSEmailUiMsgDetailsVisualiser::SetMskL() + { + FUNC_LOG; + if ( iFirstStartCompleted ) // Safety + { + TFsTreeItemId curId = iTreeList->FocusedItem(); + + if ( iTreeList->IsNode( curId ) ) + { + if ( iTreeList->IsExpanded( curId ) ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_COLLAPSE ); + } + else + { + ChangeMskCommandL( R_FSE_QTN_MSK_EXPAND ); + } + } + else // non-node item + { + if( GetEmailAddressForFocusedItem() ) + { + ChangeMskCommandL( R_FSE_QTN_MSK_COMPOSE ); + } + else + { + ChangeMskCommandL( R_FSE_QTN_MSK_EMPTY ); + } + } + } + } + +TBool CFSEmailUiMsgDetailsVisualiser::OfferEventL(const TAlfEvent& aEvent) + { + FUNC_LOG; + TBool result = EFalse; + SetMskL(); + if ( aEvent.IsKeyEvent() && aEvent.Code() == EEventKey ) + { + 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; + } + + switch ( scanCode ) + { + case EStdKeyDevice3: // CENTER CLICK + case EStdKeyEnter: // ENTER + { + // Send email to focused item. Set the event as consumed if + // valid email address was found and composer was opened with + // that email address as recipent. If email address was not + // found, offer the event to list by not consuming it. + result = SendEmailToFocusedItemL(); + } + break; + + case EStdKeyYes: + { + CallToFocusedItemL(); + result = ETrue; + } + break; + + case EStdKeyRightArrow: + { + // Show action toolbar if the item has action menu. + if( HasFocusedItemActionMenu() ) + { + LaunchActionMenuL(); + result = ETrue; + } + else + { + result = EFalse; + } + } + break; + + default: + // Check keyboard shortcuts. + TInt shortcutCommand = + iAppUi.ShortcutBinding().CommandForShortcutKey( aEvent.KeyEvent(), + CFSEmailUiShortcutBinding::EContextMailDetails ); + if ( shortcutCommand != KErrNotFound ) + { + HandleCommandL( shortcutCommand ); + result = ETrue; + } + break; + } + } + else if (aEvent.IsPointerEvent()) + { + result = iTreeList->TreeControl()->OfferEventL(aEvent); + } + + return result; + } + +// --------------------------------------------------------------------------- +// 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 CFSEmailUiMsgDetailsVisualiser::OperationCompleteL( + TContactHandlerCmd /*aCmd*/, const RPointerArray& /*aContacts*/ ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// From MFSEmailUiContactHandlerObserver +// Handles error in contact handler operation. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::OperationErrorL( TContactHandlerCmd /*aCmd*/, + TInt /*aError*/ ) + { + FUNC_LOG; + } + +void CFSEmailUiMsgDetailsVisualiser::DynInitMenuPaneL(TInt aResourceId, CEikMenuPane* aMenuPane) + { + FUNC_LOG; + + if ( aResourceId == R_FSEMAILUI_MAILDETAILS_MENUPANE ) + { + if ( FeatureManager::FeatureSupported( KFeatureIdFfCmailIntegration ) ) + { + // remove help support in pf5250 + aMenuPane->SetItemDimmed( EFsEmailUiCmdHelp, ETrue); + } + + // Hide "actions" option if currently focused item doesn't have action menu + aMenuPane->SetItemDimmed( EFsEmailUiCmdMailActions, !HasFocusedItemActionMenu() ); + // Hide "copy to clipboard" option if there is nothing to copy on the focused row + CFSEmailUiMsgDetailsItem* item = iModel->ItemByListId( iTreeList->FocusedItem() ); + if ( !item ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCopyToClipboard, ETrue ); + } + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsCollapseAll, AllNodesCollapsed() ); + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsExpandAll, AllNodesExpanded() ); + } + + if ( aResourceId == R_FSEMAILUI_MAILDETAILS_SUBMENU_ACTIONS ) + { + TInt pos( 0 ); + if ( !iRCLSupported && aMenuPane->MenuItemExists( EFsEmailUiCmdActionsRemoteLookup ,pos) ) + { + aMenuPane->SetItemDimmed( EFsEmailUiCmdActionsRemoteLookup, ETrue ); + } + } + + // Add shortcut hints + iAppUi.ShortcutBinding().AppendShortcutHintsL( *aMenuPane, + CFSEmailUiShortcutBinding::EContextMailDetails ); + } + +void CFSEmailUiMsgDetailsVisualiser::HandleCommandL( TInt aCommand ) + { + FUNC_LOG; + switch(aCommand) + { + case EAknSoftkeyBack: + { + if ( !iAppUi.ViewSwitchingOngoing() ) + { + ChangeTitleBarTextL( EFalse ); + iAppUi.ReturnToPreviousViewL(); + } + } + break; + + case EFsEmailUiCmdActionsCopyToClipboard: + { + CopyFocusedItemToClipboardL(); + } + break; + case EFsEmailUiCmdCollapse: + { + TFsTreeItemId focId1 = iTreeList->FocusedItem(); + iTreeList->CollapseNodeL(focId1); + ChangeMskCommandL( R_FSE_QTN_MSK_EXPAND); + } + break; + + case EFsEmailUiCmdExpand: + { + TFsTreeItemId focId2 = iTreeList->FocusedItem(); + iTreeList->ExpandNodeL(focId2); + ChangeMskCommandL( R_FSE_QTN_MSK_COLLAPSE); + } + break; + // Options menu commands + case EFsEmailUiCmdActionsCollapseAll: + { + TFsTreeItemId prevId = iTreeList->FocusedItem(); + prevId = GetRootParent( prevId ); + iTreeVisualizer->CollapseAllL(); + if ( prevId != KFsTreeRootID && prevId != KFsTreeNoneID ) + { + iTreeVisualizer->SetFocusedItemL( prevId ); + } + } + break; + + case EFsEmailUiCmdActionsExpandAll: + { + TFsTreeItemId prevId = iTreeList->FocusedItem(); + iTreeVisualizer->ExpandAllL(); + if ( prevId != KFsTreeRootID && prevId != KFsTreeNoneID ) + { + iTreeVisualizer->SetFocusedItemL( prevId ); + } + } + break; + + case EFsEmailUiCmdActionsCall: + { + CallToFocusedItemL(); + } + break; + // video call + case EFsEmailUiCmdActionsCallVideo: + { + iVideoCall = ETrue; + CallToFocusedItemL(); + } + break; + // + case EFsEmailUiCmdActionsCreateMessage: + { + CreateMessageToFocusedItemL(); + } + break; + + case EFsEmailUiCmdComposeTo: + { + SendEmailToFocusedItemL(); + } + break; + + case EFsEmailUiCmdActionsContactDetails: + { + ShowContactDetailsForFocusedItemL(); + } + break; + + case EFsEmailUiCmdActionsAddContact: + { + AddFocusedItemToContactsL(); + } + break; + + case EFsEmailUiCmdActionsRemoteLookup: + { + LaunchRemoteLookupForFocusedItemL(); + } + break; + + case EFsEmailUiCmdHelp: + { + TFsEmailUiUtility::LaunchHelpL( KFSE_HLP_LAUNCHER_GRID ); + } + break; + + case EFsEmailUiCmdExit: + { + // + iTreeList->SetFocusedL(EFalse); + // + iAppUi.Exit(); + } + break; + + case EFsEmailUiCmdActionsCollapseExpandAllToggle: + { + ShortcutCollapseExpandAllToggleL(); + } + break; + + case EFsEmailUiCmdGoToTop: + { + GoToTopL(); + } + break; + + case EFsEmailUiCmdGoToBottom: + { + GoToBottomL(); + } + 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; + + default: + break; + } + } + + +void CFSEmailUiMsgDetailsVisualiser::ClearMsgDetailsModelL() + { + FUNC_LOG; + iTreeList->RemoveAllL(); + iModel->RemoveAll(); + + iNodeIds.Reset(); + iToNodeId = iCcNodeId = iBccNodeId = KFsTreeNoneID; + } + +void CFSEmailUiMsgDetailsVisualiser::UpdateMsgDetailsModelL() + { + FUNC_LOG; + // If there are lots of items under some node, then the list drawing + // might become very slow because of scroll bar updating. So we deny + // the list refresh during the construction. List refresh is still + // allowed in case of node insert, as there aren't that many nodes, + // and it will keep the scroll bar roughly in the map. + iAllowListRefreshInInsert = ETrue; + iExpandAndHighlightNextNode = EFalse; + + // Append lines to the model + AppendFromLinesL(); + AppendSubjectLinesL(); + + if( iExpandCollapseMode == ECollapseAllExceptTo ) + { + iExpandAndHighlightNextNode = ETrue; + } + AppendToLinesL(); + + if( iExpandCollapseMode == ECollapseAllExceptCc ) + { + iExpandAndHighlightNextNode = ETrue; + } + AppendCcLinesL(); + + if( iExpandCollapseMode == ECollapseAllExceptBcc ) + { + iExpandAndHighlightNextNode = ETrue; + } + AppendBccLinesL(); + AppendSizeLinesL(); + AppendSentLinesL(); + AppendPriorityLinesL(); + // Allow list (scroll bar) refresh for last item(s) + //iAllowListRefreshInInsert = ETrue; + AppendMessageTypeLinesL(); + } + +void CFSEmailUiMsgDetailsVisualiser::CreateOneLinePlainItemLC2( const TDesC& aItemDataBuff, + CFsTreePlainOneLineItemData* &aItemData, + CFsTreePlainOneLineItemVisualizer* &aItemVisualizer ) + { + FUNC_LOG; + aItemData = CFsTreePlainOneLineItemData::NewL(); + CleanupStack::PushL( aItemData ); + aItemData->SetDataL( aItemDataBuff ); + + aItemVisualizer = CFsTreePlainOneLineItemVisualizer::NewL(*iTreeList->TreeControl()); + CleanupStack::PushL( aItemVisualizer ); + aItemVisualizer->SetExtendable( EFalse ); // One line items are obviously not extendable + + SetItemVisualizerCommonProperties( *aItemVisualizer ); + } + +void CFSEmailUiMsgDetailsVisualiser::CreateTwoLinePlainItemLC2( const TDesC& aPrimaryDataBuff, + const TDesC& aSecondaryDataBuff, + CFsTreePlainTwoLineItemData* &aItemData, + CFsTreePlainTwoLineItemVisualizer* &aItemVisualizer ) + { + FUNC_LOG; + aItemData = CFsTreePlainTwoLineItemData::NewL(); + CleanupStack::PushL( aItemData ); + aItemData->SetDataL( aPrimaryDataBuff ); + aItemData->SetSecondaryDataL( aSecondaryDataBuff ); + + aItemVisualizer = CFsTreePlainTwoLineItemVisualizer::NewL(*iTreeList->TreeControl()); + CleanupStack::PushL( aItemVisualizer ); + aItemVisualizer->SetExtendable( ETrue ); // All two line items are extendable + aItemVisualizer->SetMenu( NULL ); + + SetItemVisualizerCommonProperties( *aItemVisualizer ); + } + +void CFSEmailUiMsgDetailsVisualiser::SetItemVisualizerCommonProperties( MFsTreeItemVisualizer& aItemVisualizer ) + { + FUNC_LOG; + aItemVisualizer.SetSize(TSize(iScreenRect.Width(), iListItemHeight)); + aItemVisualizer.SetExtendedSize(TSize(iScreenRect.Width(), 2*iListItemHeight)); + + // Set correct skin text colors for the list items + TRgb focusedColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor(); + TRgb normalColor = iAppUi.LayoutHandler()->ListNormalStateTextSkinColor(); + aItemVisualizer.SetFocusedStateTextColor( focusedColor ); + aItemVisualizer.SetNormalStateTextColor( normalColor ); + + // Set font size + aItemVisualizer.SetFontHeight( iAppUi.LayoutHandler()->ListItemFontHeightInTwips() ); + } + +void CFSEmailUiMsgDetailsVisualiser::CreatePlainNodeLC2( const TDesC& aItemDataBuff, + CFsTreePlainOneLineNodeData* &aItemData, + CFsTreePlainOneLineNodeVisualizer* &aNodeVisualizer ) + { + 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(*iTreeList->TreeControl()); + CleanupStack::PushL( aNodeVisualizer ); + + SetNodeVisualizerProperties( *aNodeVisualizer ); + + // Gradient background for headings + CAlfBrush *titleDividerBgBrush = iAppUi.FsTextureManager()->TitleDividerBgBrushL(); + aNodeVisualizer->SetBackgroundBrush( titleDividerBgBrush ); + } + +void CFSEmailUiMsgDetailsVisualiser::SetNodeVisualizerProperties( MFsTreeItemVisualizer& aNodeVisualizer ) + { + FUNC_LOG; + aNodeVisualizer.SetSize(TSize(iScreenRect.Width(), iListNodeHeight)); + + // Set correct skin text colors for the list items + TRgb focusedColor = iAppUi.LayoutHandler()->ListFocusedStateTextSkinColor(); + TRgb normalColor = iAppUi.LayoutHandler()->ListNodeTextColor(); + aNodeVisualizer.SetFocusedStateTextColor( focusedColor ); + aNodeVisualizer.SetNormalStateTextColor( normalColor ); + + // Set font size + aNodeVisualizer.SetFontHeight( iAppUi.LayoutHandler()->ListItemFontHeightInTwips() ); + // Set node bolded + aNodeVisualizer.SetTextBold( ETrue ); + + // Temporary fix for EASV-7GJFVD + //aNodeVisualizer.SetBackgroundColorL( iAppUi.LayoutHandler()->ListNodeBackgroundColor() ); + + } + +TFsTreeItemId CFSEmailUiMsgDetailsVisualiser::AppendHeadingToListL( TInt aResourceId ) + { + FUNC_LOG; + CFsTreePlainOneLineNodeData* plainNodeData; + CFsTreePlainOneLineNodeVisualizer* plainNodeVisualizer; + + HBufC* headingText = StringLoader::LoadLC( aResourceId ); + + CreatePlainNodeLC2( *headingText, plainNodeData, plainNodeVisualizer ); + + TFsTreeItemId nodeId = iTreeList->InsertNodeL( *plainNodeData, *plainNodeVisualizer, KFsTreeRootID); + CleanupStack::Pop( 2 ); // plainNodeData & plainNodeVisualizer + + // Set the node expanded/collapsed according to the member variables + if( nodeId != KFsTreeNoneID ) // Safety check + { + if( iExpandCollapseMode == EExpandAll ) + { + // The "normal" case, expand all and keep the first one highlighted + iTreeList->ExpandNodeL( nodeId ); + } + else if( iExpandAndHighlightNextNode ) + { + // View opened to To, Cc or Bcc field and we just added the + // corresponding node, so expand and focus it + iTreeList->ExpandNodeL( nodeId ); + iTreeVisualizer->SetFocusedItemL( nodeId ); + } + else + { + // View opened to To, Cc or Bcc field but we added some other + // node, so collapse it + iTreeList->CollapseNodeL( nodeId ); + } + } + // Reset the node expanding and highlighting flag + iExpandAndHighlightNextNode = EFalse; + + CleanupStack::PopAndDestroy(headingText); + + return nodeId; + } + +TFsTreeItemId CFSEmailUiMsgDetailsVisualiser::AppendOneLineItemToListL( const TDesC& aItemData, TFsTreeItemId aParentNode ) + { + FUNC_LOG; + CFsTreePlainOneLineItemData* plainItemData; + CFsTreePlainOneLineItemVisualizer* plainItemVisualizer; + + CreateOneLinePlainItemLC2( aItemData, plainItemData, plainItemVisualizer ); + + TFsTreeItemId itemId = iTreeList->InsertItemL( *plainItemData, *plainItemVisualizer, aParentNode, KErrNotFound, iAllowListRefreshInInsert ); + CleanupStack::Pop( 2 ); // plainItemData & plainItemVisualizer + + return itemId; + } + +TFsTreeItemId CFSEmailUiMsgDetailsVisualiser::AppendTwoLineItemToListL( const TDesC& aPrimaryDataBuff, + const TDesC& aSecondaryDataBuff, + TFsTreeItemId aParentNode, + TBool aItemHasActionMenu /*= EFalse*/ ) + { + FUNC_LOG; + CFsTreePlainTwoLineItemData* plainItemData; + CFsTreePlainTwoLineItemVisualizer* plainItemVisualizer; + + CreateTwoLinePlainItemLC2( aPrimaryDataBuff, aSecondaryDataBuff, plainItemData, plainItemVisualizer ); + + if ( aItemHasActionMenu ) + { + plainItemVisualizer->SetFlags( plainItemVisualizer->Flags() | KFsTreeListItemHasMenu ); + } + + plainItemVisualizer->SetFlags(plainItemVisualizer->Flags() & ~KFsTreeListItemManagedLayout); + + TFsTreeItemId itemId = iTreeList->InsertItemL( *plainItemData, *plainItemVisualizer, aParentNode, KErrNotFound, iAllowListRefreshInInsert ); + CleanupStack::Pop( 2 ); // plainItemData & plainItemVisualizer + + return itemId; + } + +TFsTreeItemId CFSEmailUiMsgDetailsVisualiser::AppendDateTimeItemToListL( const TDesC& aPrimaryDataBuff, + const TDesC& aSecondaryDataBuff, + const TDesC& aDateTimeDataBuff, + TFsTreeItemId aParentNode ) + { + FUNC_LOG; + CFsTreePlainTwoLineItemData* plainItemData; + CFsTreePlainTwoLineItemVisualizer* plainItemVisualizer; + + CreateTwoLinePlainItemLC2( aPrimaryDataBuff, aSecondaryDataBuff, plainItemData, plainItemVisualizer ); + + plainItemData->SetDateTimeDataL( aDateTimeDataBuff ); + plainItemVisualizer->SetExtendable( EFalse ); + + TFsTreeItemId itemId = iTreeList->InsertItemL( *plainItemData, *plainItemVisualizer, aParentNode, KErrNotFound, iAllowListRefreshInInsert ); + CleanupStack::Pop( 2 ); // plainItemData & plainItemVisualizer + + return itemId; + } + +TBool CFSEmailUiMsgDetailsVisualiser::GetDisplayNameAndEmailAddressL( CFSMailAddress* aAddressData, TDesC* &aDisplayName, TDesC* &aEmailAddress ) + { + FUNC_LOG; + aDisplayName = &aAddressData->GetDisplayName(); + aEmailAddress = &aAddressData->GetEmailAddress(); + TInt notFoundCount(0); + + // If display name is not set, then the plugins seem to set it to be same + // as email address. So there's no safe way to know wheter the display name + // is set or not. Best quess is that if display name is the same as email + // address, then there are no display name available. + if ( !aDisplayName || ( aDisplayName->Length() == 0 ) || ( *aDisplayName == *aEmailAddress ) ) + { + // Internal variable used to store the text to avoid problems with ownership handling + if( !iNoDisplayNameAvailableText ) + { + iNoDisplayNameAvailableText = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_DISPLAY_NAME ); + } + + aDisplayName = iNoDisplayNameAvailableText; + notFoundCount++; + } + if ( !aEmailAddress || ( aEmailAddress->Length() == 0 ) ) + { + // Internal variable used to store the text to avoid problems with ownership handling + if( !iNoEmailAddressAvailableText ) + { + iNoEmailAddressAvailableText = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_EMAIL_ADDRESS ); + } + + aEmailAddress = iNoEmailAddressAvailableText; + notFoundCount++; + } + + // If both display name and email address are empty, return EFalse + if( notFoundCount > 1 ) + { + return EFalse; + } + else + { + return ETrue; + } + } + +void CFSEmailUiMsgDetailsVisualiser::AppendFromLinesL() + { + FUNC_LOG; + TFsTreeItemId nodeId; + if( iViewedMsg->IsFlagSet( EFSMsgFlag_CalendarMsg ) ) + { + nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_ORGANIZER ); + } + else + { + nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_FROM ); + } + iNodeIds.Append( nodeId ); + + CFSMailAddress* fromAddress = iViewedMsg->GetSender(); + // If CFSMailAddress not available, show "No sender info available" + if( fromAddress == NULL ) + { + HBufC* noSender = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SENDER_INFO_AVAILABLE ); + AppendOneLineItemToListL( *noSender, nodeId ); + CleanupStack::PopAndDestroy( noSender ); + } + else + { + TDesC* displayName( NULL ); + TDesC* emailAddress( NULL ); + if( GetDisplayNameAndEmailAddressL( fromAddress, displayName, emailAddress ) ) + { + TFsTreeItemId itemId = AppendTwoLineItemToListL( *displayName, *emailAddress, nodeId, ETrue ); + iModel->AppendL( itemId, fromAddress ); + } + else + { + HBufC* noSender = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SENDER_INFO_AVAILABLE ); + AppendOneLineItemToListL( *noSender, nodeId ); + CleanupStack::PopAndDestroy( noSender ); + } + } + } + +void CFSEmailUiMsgDetailsVisualiser::AppendSubjectLinesL() + { + FUNC_LOG; + TFsTreeItemId nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_SUBJECT ); + iNodeIds.Append( nodeId ); + + TDesC* subject = &iViewedMsg->GetSubject(); + if ( subject == NULL || subject->Length() <= 0 ) + { + HBufC* noSubject = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_SUBJECT ); + AppendOneLineItemToListL( *noSubject, nodeId ); + CleanupStack::PopAndDestroy( noSubject ); + } + else + { + HBufC* subjectText = TFsEmailUiUtility::CreateSubjectTextLC( iViewedMsg ); + TFsTreeItemId itemId = AppendOneLineItemToListL( *subjectText, nodeId ); + CleanupStack::PopAndDestroy( subjectText ); + iModel->AppendL( itemId, subject ); + } + } + +// Duplicate code in AppendToLinesL/AppendCcLinesL/AppendBccLinesL, create +// one generic function that can be used from all of these functions +void CFSEmailUiMsgDetailsVisualiser::AppendToLinesL() + { + FUNC_LOG; + if( iViewedMsg->IsFlagSet( EFSMsgFlag_CalendarMsg ) ) + { + iToNodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_REQUIRED ); + } + else + { + iToNodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_TO ); + } + iNodeIds.Append( iToNodeId ); + + RPointerArray& toArray = iViewedMsg->GetToRecipients(); + TInt toArrayCount = toArray.Count(); + if ( toArrayCount ) + { + for ( TInt i=0 ; iAppendL( itemId, toAddress ); + } + } + } + else + { + //Laske To- ja Cc-vastaanottajat yhteensä ja näytä tämä vain jos kumpiakaan ei ole yhtään + HBufC* noToText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_NO_VISIBLE_RECIPIENTS ); + AppendOneLineItemToListL( *noToText, iToNodeId ); + CleanupStack::PopAndDestroy( noToText ); + } + } + +void CFSEmailUiMsgDetailsVisualiser::AppendCcLinesL() + { + FUNC_LOG; + RPointerArray& ccArray = iViewedMsg->GetCCRecipients(); + TInt ccArrayCount = ccArray.Count(); + + if ( ccArrayCount ) + { + if( iViewedMsg->IsFlagSet( EFSMsgFlag_CalendarMsg ) ) + { + iCcNodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_OPTIONAL ); + } + else + { + iCcNodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_CC ); + } + iNodeIds.Append( iCcNodeId ); + + for ( TInt i=0 ; iAppendL( itemId, ccAddress ); + } + } + } + } + +void CFSEmailUiMsgDetailsVisualiser::AppendBccLinesL() + { + FUNC_LOG; + // Get message's parent folder + TFSMailMsgId folderId = iViewedMsg->GetFolderId(); + TFSMailMsgId mailboxId = iViewedMsg->GetMailBoxId(); + CFSMailFolder* folder = iAppUi.GetMailClient()->GetFolderByUidL( mailboxId, folderId ); + + // Show bcc field only if message's parent folder is some outgoing folder, + // so basically outbox, drafts or sent items. + TBool showBcc( EFalse ); + if( folder ) + { + TInt folderType = folder->GetFolderType(); + + switch( folderType ) + { + case EFSOutbox: + case EFSDraftsFolder: + case EFSSentFolder: + { + showBcc = ETrue; + } + break; + + case EFSInbox: + case EFSDeleted: + default: + break; + } + } + delete folder; + + if( showBcc ) + { + RPointerArray& bccArray = iViewedMsg->GetBCCRecipients(); + TInt bccArrayCount = bccArray.Count(); + + if ( bccArrayCount ) + { + iBccNodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_BCC ); + iNodeIds.Append( iBccNodeId ); + + for ( TInt i=0 ; iAppendL( itemId, bccAddress ); + } + } + } + } + } + +void CFSEmailUiMsgDetailsVisualiser::AppendSizeLinesL() + { + FUNC_LOG; + TFsTreeItemId nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_SIZE_HEADER ); + iNodeIds.Append( nodeId ); + + // Gets the full content size (in bytes) + TUint msgSize = iViewedMsg->ContentSize(); + + HBufC* sizeText = TFsEmailUiUtility::CreateSizeDescLC( msgSize, ETrue ); + + AppendOneLineItemToListL( *sizeText, nodeId ); + CleanupStack::PopAndDestroy( sizeText ); + } + +void CFSEmailUiMsgDetailsVisualiser::AppendSentLinesL() + { + FUNC_LOG; + TFsTreeItemId nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_SENT ); + iNodeIds.Append( nodeId ); + + HBufC* dateFromMsg = TFsEmailUiUtility::DateTextFromMsgLC( iViewedMsg ); + HBufC* dateText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_DATE_U, *dateFromMsg ); + + AppendOneLineItemToListL( *dateText, nodeId ); + + CleanupStack::PopAndDestroy( dateText ); + CleanupStack::PopAndDestroy( dateFromMsg ); + + ////////////////////////// + HBufC* timeFromMsg = TFsEmailUiUtility::TimeTextFromMsgLC( iViewedMsg ); + HBufC* timeText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_TIME_U, *timeFromMsg ); + + AppendOneLineItemToListL( *timeText, nodeId ); + + CleanupStack::PopAndDestroy( timeText ); + CleanupStack::PopAndDestroy( timeFromMsg ); + } + +void CFSEmailUiMsgDetailsVisualiser::AppendPriorityLinesL() + { + FUNC_LOG; + TFsTreeItemId nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_PRIORITY ); + iNodeIds.Append( nodeId ); + + HBufC* priorityText( NULL ); + if ( iViewedMsg->IsFlagSet( EFSMsgFlag_Important ) ) + { + priorityText = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_PRIORITY_HIGH ); + } + else if ( iViewedMsg->IsFlagSet( EFSMsgFlag_Low ) ) + { + priorityText = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_PRIORITY_LOW ); + } + else + { + priorityText = StringLoader::LoadL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_PRIORITY_NORMAL ); + } + + CleanupStack::PushL( priorityText ); + AppendOneLineItemToListL( *priorityText, nodeId ); + CleanupStack::PopAndDestroy( priorityText ); + } + +void CFSEmailUiMsgDetailsVisualiser::AppendMessageTypeLinesL() + { + FUNC_LOG; + TFsTreeItemId nodeId = AppendHeadingToListL( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_MSG_TYPE ); + iNodeIds.Append( nodeId ); + + HBufC* msgType; + if( iViewedMsg->IsFlagSet( EFSMsgFlag_CalendarMsg ) ) + { + msgType = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_MSG_TYPE_MEETING ); + } + else + { + msgType = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_MSG_DETAILS_MSG_TYPE_EMAIL ); + } + + AppendOneLineItemToListL( *msgType, nodeId ); + CleanupStack::PopAndDestroy( msgType ); + } + +void CFSEmailUiMsgDetailsVisualiser::HandleDynamicVariantSwitchL( CFsEmailUiViewBase::TDynamicSwitchType /*aType*/ ) + { + FUNC_LOG; + if ( iFirstStartCompleted ) // Safety + { + iTreeList->HideListL(); + UpdateListSizeAttributes(); + iParentLayout->SetRect( iScreenRect ); + for ( TInt i = 0; i < iNodeIds.Count(); i++ ) + { + MFsTreeItemVisualizer& vis = iTreeList->ItemVisualizer( iNodeIds[i] ); + SetNodeVisualizerProperties( vis ); + SetChildVisualizersProperties( iNodeIds[i] ); + } + iTreeList->ShowListL(); + } + } + +// --------------------------------------------------------------------------- +// Sets tree item visualizer properties for all the childs of the given node +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::SetChildVisualizersProperties( TFsTreeItemId aNodeId ) + { + FUNC_LOG; + TUint childrenCount = iTreeList->CountChildren( aNodeId ); + for( TInt i = 0; i < childrenCount; ++i ) + { + TFsTreeItemId childId = iTreeList->Child( aNodeId, i ); + MFsTreeItemVisualizer& vis = iTreeList->ItemVisualizer( childId ); + SetItemVisualizerCommonProperties( vis ); + } + } + +// --------------------------------------------------------------------------- +// Update list size members variables +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::UpdateListSizeAttributes() + { + FUNC_LOG; + if ( iFirstStartCompleted ) // Safety + { + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, iScreenRect ); + iScreenRect.SetRect( 0, 0, iScreenRect.Width(), iScreenRect.Height() ); + + iListItemHeight = iAppUi.LayoutHandler()->OneLineListItemHeight(); + iListNodeHeight = iAppUi.LayoutHandler()->OneLineListNodeHeight(); + } + } + +// --------------------------------------------------------------------------- +// Collapse nodes except the specified one (used when starting the list in +// specific loaction) +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::CollapseNodesExceptL( TFsTreeItemId aExcludedNode ) + { + FUNC_LOG; + for( TInt i = 0; i < iNodeIds.Count(); i++ ) + { + if( iNodeIds[i] != aExcludedNode ) + { + iTreeList->CollapseNodeL( iNodeIds[i] ); + } + } + } + +// --------------------------------------------------------------------------- +// If there is one or more expanded nodes, collapses all nodes. +// Otherwise expands all nodes. +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::ShortcutCollapseExpandAllToggleL() + { + FUNC_LOG; + TBool collapseAllNodes( EFalse ); + for( TInt i=0 ; iIsExpanded( iNodeIds[i] ) ) + { + collapseAllNodes = ETrue; + break; + } + } + + if( collapseAllNodes ) + { + HandleCommandL( EFsEmailUiCmdActionsCollapseAll ); + } + else + { + HandleCommandL( EFsEmailUiCmdActionsExpandAll ); + } + } + +// --------------------------------------------------------------------------- +// Moves the focus to the topmost item +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::GoToTopL() + { + FUNC_LOG; + if ( iNodeIds.Count() ) + { + TFsTreeItemId topId = iNodeIds[0]; + iTreeVisualizer->SetFocusedItemL( topId ); + } + } + +// --------------------------------------------------------------------------- +// Moves the focus to the bottommost item +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::GoToBottomL() + { + FUNC_LOG; + if ( iNodeIds.Count() ) + { + TFsTreeItemId bottomId = iNodeIds[ iNodeIds.Count()-1 ]; + TInt childCount = iTreeList->CountChildren(bottomId); + if ( childCount && iTreeList->IsExpanded(bottomId) ) + { + // Focus the last child of the bottom node if the node is expanded. + bottomId = iTreeList->Child( bottomId, childCount-1 ); + } + iTreeVisualizer->SetFocusedItemL( bottomId ); + } + } + + +// --------------------------------------------------------------------------- +// Recursive function to get the root parent of given item +// --------------------------------------------------------------------------- +// +TFsTreeItemId CFSEmailUiMsgDetailsVisualiser::GetRootParent( const TFsTreeItemId aItemId ) const + { + FUNC_LOG; + TFsTreeItemId parentId = iTreeList->Parent( aItemId ); + // If current item's parent is KFsTreeRootID, return its id + if( parentId == KFsTreeRootID || parentId == KFsTreeNoneID ) + { + return aItemId; + } + else + { + // Get the root parent recursively + return GetRootParent( parentId ); + } + } + + +// --------------------------------------------------------------------------- +// Tells if all expandable nodes are collapsed +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMsgDetailsVisualiser::AllNodesCollapsed() const + { + FUNC_LOG; + TFsTreeItemId itemId = KFsTreeNoneID; + TInt count = iTreeList->CountChildren(KFsTreeRootID); + + // If top level is collapsed, then everything is collapsed. There's no need + // to crawl any deeper in the tree hierarchy. + for ( TInt i=0 ; iChild( KFsTreeRootID, i ); + if ( iTreeList->IsNode(itemId) && + iTreeList->IsExpanded(itemId) ) + { + return EFalse; + } + } + + return ETrue; + } + +// --------------------------------------------------------------------------- +// Tells if all expandable nodes are expanded +// --------------------------------------------------------------------------- +// +TBool CFSEmailUiMsgDetailsVisualiser::AllNodesExpanded( TFsTreeItemId aParentNodeId ) const + { + FUNC_LOG; + // We must crawl through the whole tree to see, if there are any collapsed nodes + // at any level. We do this with recursive depth-first-search. + + TFsTreeItemId itemId = KFsTreeNoneID; + TInt count = iTreeList->CountChildren(aParentNodeId); + + for ( TInt i=0 ; iChild( aParentNodeId, i ); + if ( iTreeList->IsNode(itemId) ) + { + if ( !iTreeList->IsExpanded(itemId) || + !AllNodesExpanded(itemId) ) + { + return EFalse; + } + } + } + + return ETrue; + } + +// Touch +// --------------------------------------------------------------------------- +// Process a treelist event +// --------------------------------------------------------------------------- +// +void CFSEmailUiMsgDetailsVisualiser::TreeListEventL( const TFsTreeListEvent aEvent, + const TFsTreeItemId /*aId*/ ) + { + switch (aEvent) + { + case EFsTreeListItemTouchAction: + { + if (TFsTreeItemId focId1 = iTreeList->FocusedItem()) + { + if (iTreeList->IsNode(focId1)) + { + if (iTreeList->IsExpanded(focId1)) + { + HandleCommandL(EFsEmailUiCmdCollapse); + } + else + { + HandleCommandL(EFsEmailUiCmdExpand); + } + } + else + { + SendEmailToFocusedItemL(); + } + } + break; + } + case EFsTreeListItemTouchLongTap: + { + // Show action toolbar if the item has action menu. + if( HasFocusedItemActionMenu() ) + { + LaunchActionMenuL(); + } + break; + } + case EFsTreeListItemWillGetFocused: + { + SetMskL(); + break; + } + } + } + + +TPoint CFSEmailUiMsgDetailsVisualiser::ActionMenuPosition() + { + TAlfRealRect focusRect; + TFsTreeItemId listItemId = iTreeList->FocusedItem(); + iTreeList->GetItemDisplayRectTarget(listItemId, focusRect); + return focusRect.iTl; + } +// + +void CFSEmailUiMsgDetailsVisualiser::GetParentLayoutsL( RPointerArray& aLayoutArray ) const + { + aLayoutArray.AppendL( iParentLayout ); + } +