/*
* Copyright (c) 2008 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: Definition for the common base class for all FsEmailUi views.
* The class is not intended for instantation.
*
*/
// <cmail> SF
#include "emailtrace.h"
#include <alf/alfcontrolgroup.h>
#include <alf/alfvisual.h>
// </cmail>
#include <eikbtgpc.h>
#include "FreestyleEmailUiViewBase.h"
#include "FreestyleEmailUiAppui.h"
#include "FreestyleEmailUiLayoutHandler.h"
#include "FreestyleEmailUiStatusIndicator.h"
#include "FSEmail.pan"
// <cmail> Toolbar
#include <AknUtils.h>
#include <akntoolbar.h>
#include <FreestyleEmailUi.rsg>
#include <aknlayoutscalable_avkon.cdl.h>
#include <layoutmetadata.cdl.h>
// </cmail> Toolbar
// ---------------------------------------------------------------------------
//
CFsEmailUiViewBase::CFsEmailUiViewBase( CAlfControlGroup& aControlGroup,
CFreestyleEmailUiAppUi& aAppUi )
: iControlGroup( aControlGroup ), iAppUi( aAppUi )
{
FUNC_LOG;
// Set control groups to ignore input by default
iControlGroup.SetAcceptInput( EFalse );
iKeyboardFlipOpen = aAppUi.IsFlipOpen();
}
// ---------------------------------------------------------------------------
//
TUid CFsEmailUiViewBase::Id() const
{
FUNC_LOG;
// This must be overriden by the inherited class
__ASSERT_DEBUG( EFalse, Panic(EFSEmailUiBaseViewMethodNotOverriden) );
return TUid::Null();
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::DoActivateL( const TVwsViewId& aPrevViewId,
TUid aCustomMessageId,
const TDesC8& aCustomMessage )
{
FUNC_LOG;
SetViewActive( ETrue );
SetStatusBarLayout();
iAppUi.StatusPane()->DrawNow();
iFocusVisible = iAppUi.IsFocusShown();
// fix view stack in case of external activation
if ( aPrevViewId.iAppUid != KFSEmailUiUid )
{
iActiveMailboxBeforeExternalActivation = iAppUi.GetActiveMailboxId();
iAppUi.ViewActivatedExternallyL( Id() );
}
// hide previous view
CFsEmailUiViewBase* previousView = iAppUi.PreviousActiveView();
TBool pluginSettingsActive = iAppUi.IsPluginSettingsViewActive();
if ( pluginSettingsActive )
{
iAppUi.ReturnFromPluginSettingsView();
}
else if ( previousView )
{
// In case of external activation, hide previous control group
// before view activation to avoid screen flickering
if ( aPrevViewId.iAppUid != KFSEmailUiUid )
{
previousView->DeactivateControlGroup();
}
previousView->DoTransition( ETrue ); // fade out prev view
}
// Clear the flag of long transition effect
SetNextTransitionOutLong( EFalse );
// Clear status pane indicators
CCustomStatuspaneIndicators* indicators =
iAppUi.GetStatusPaneIndicatorContainer();
if ( indicators )
{
indicators->ClearStatusPaneFlags();
indicators->HideStatusPaneIndicators();
}
UpdateToolbarL();
// Make sure Alfred display is of correct size (there is some problems with toolbar)
iAppUi.AlfEnv().PrimaryDisplay().ForceSetVisibleArea(iAppUi.ClientRect());
// Finally call child classes activation method
TRAPD( error, ChildDoActivateL(aPrevViewId, aCustomMessageId, aCustomMessage) );
if ( !error )
{
//view history have to be updated once again when email is sent to background when in plugin settings and composer is activated externaly
//when composer view will be deactivated it wiil call NavigateBack;
if (pluginSettingsActive && iAppUi.CurrentActiveView()->Id() == MailEditorId)
{
iAppUi.ReturnFromPluginSettingsView();
}
// View activated succesfully
DoTransition( EFalse );
if ( !iAppUi.SwitchingToBackground() )
{
// Change visible control group
// having here DoTransition caused grid transparency when app left from listview
ActivateControlGroup();
}
else
{
// View activated but Mail application is switching to background.
// Mail application was invoked from other app and now we`re going back
// to this other app. We have to force, that after going back to Mail
// application, ActivateControlGroup will be invoked in
// HandleAppForegroundEventL method
iWasActiveControlGroup = ETrue;
}
}
else
{
// In case of error, navigate to the previous view
DeactivateControlGroup();
NavigateBackL();
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::UpdateToolbarL()
{
FUNC_LOG;
if (AknLayoutUtils::PenEnabled())
{
if (HasToolbar())
{
const TInt resourceId(ToolbarResourceId());
RArray<TInt> dimmedItems;
CleanupClosePushL(dimmedItems);
GetInitiallyDimmedItemsL(resourceId, dimmedItems);
CAknToolbar* toolbar(CAknToolbar::NewL(resourceId));
for (TInt i = 0; i < dimmedItems.Count(); i++)
{
toolbar->SetItemDimmed(dimmedItems[i], ETrue, EFalse);
}
CleanupStack::PopAndDestroy(); // dimmedItems.Close()
toolbar->SetToolbarObserver(this);
SetToolbar(toolbar);
ShowToolbar();
}
else
{
HideToolbar();
}
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::GetInitiallyDimmedItemsL(
const TInt /*aResourceId*/, RArray<TInt>& aDimmedItems ) const
{
FUNC_LOG;
aDimmedItems.Reset();
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::HideToolbar()
{
FUNC_LOG;
if (AknLayoutUtils::PenEnabled())
{
CAknToolbar* toolbar(Toolbar());
if (toolbar)
{
//toolbar->SetToolbarVisibility(EFalse);
// Call MakeVisible directly because SetToolbarVisibility never
// actually hides fixed toolbar.
toolbar->MakeVisible(EFalse);
}
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::ShowToolbar()
{
FUNC_LOG;
if (AknLayoutUtils::PenEnabled())
{
CAknToolbar* toolbar(Toolbar());
if (toolbar)
{
toolbar->SetToolbarVisibility(ETrue);
}
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::SetToolbarItemDimmed( const TInt aCommandId, const TBool aDimmed )
{
FUNC_LOG;
if (AknLayoutUtils::PenEnabled())
{
CAknToolbar* toolbar(Toolbar());
if (toolbar)
{
toolbar->SetItemDimmed(aCommandId, aDimmed, ETrue);
}
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::DoDeactivate()
{
FUNC_LOG;
SetViewActive( EFalse );
HideToolbar();
// Make control group ignore input and hide it if it's not already fading out.
DeactivateControlGroup();
// do view specific deactivation
ChildDoDeactivate();
// Return to another app in case this view was activated externally
if ( iSendToBackgroundOnDeactivation )
{
iSendToBackgroundOnDeactivation = EFalse;
// Try to bring calling external app into foreground if found
TApaTaskList taskList( iEikonEnv->WsSession() );
TApaTask prevAppTask = taskList.FindApp( iPreviousAppUid );
TApaTask fsEmailTask = taskList.FindApp( KFSEmailUiUid );
if ( prevAppTask.Exists() )
{
prevAppTask.BringToForeground();
}
if ( fsEmailTask.Exists() && iPreviousAppUid != KMessageReaderUid )
{
fsEmailTask.SendToBackground();
}
iAppUi.SetSwitchingToBackground( EFalse );
}
}
// ---------------------------------------------------------------------------
// virtual function to hide or show CAlfVisuals ( used for activation or deactivation )
//
void CFsEmailUiViewBase::FadeOut( TBool /* aDirectionOut */ )
{
FUNC_LOG;
// should be overriden ( if needed ) to use polymorphism
// to hide or show CAlfVisuals used in views
}
// ---------------------------------------------------------------------------
// Check if transition effects are enabled and run the effect if needed.
// if not enabled it calls FadeOut virtual methods only
//
void CFsEmailUiViewBase::DoTransition( TBool aDirectionOut )
{
FUNC_LOG;
if ( iAppUi.LayoutHandler() && iAppUi.LayoutHandler()->ViewFadeEffectActive() )
{
DoTransitionEffect( aDirectionOut );
}
else
{
// FadeOut method should be overridden and use by polymorphism only when needed
FadeOut( aDirectionOut ); // used for hide/show visuals without transition time
}
}
// ---------------------------------------------------------------------------
// Inheriting Alfred views can override these functions, if they need to do
// some special tricks for transition effects
//
void CFsEmailUiViewBase::DoTransitionEffect( TBool aDirectionOut )
{
FUNC_LOG;
RPointerArray<CAlfVisual> layoutArray;
TRAP_IGNORE( GetParentLayoutsL( layoutArray ) );
// For views that return valid parent layout(s), use the fade effect,
// for all other views, use the showing/hiding of control groups
for ( TInt i = 0 ; i < layoutArray.Count() ; i++ )
{
// Returned parent layout might be NULL, if view construction is not
// fully completed
if ( layoutArray[i] != NULL )
{
// Ensure the view is invisible before doing fade in (because views
// are automatically visible rigt after construction)
if ( !aDirectionOut )
{
FadeVisual( layoutArray[i], ETrue, ETrue );
}
FadeVisual( layoutArray[i], aDirectionOut );
}
}
layoutArray.Close();
}
// ---------------------------------------------------------------------------
// Inheriting Alfred views should override this and return their parent
// layout(s) in array given as parameter. Default implementation
// does nothing, so then the array is empty.
//
void CFsEmailUiViewBase::GetParentLayoutsL( RPointerArray<CAlfVisual>& /*aLayoutArray*/ ) const
{
FUNC_LOG;
}
// ---------------------------------------------------------------------------
// Fade given Alfred visual
//
void CFsEmailUiViewBase::FadeVisual(
CAlfVisual* aVisual,
TBool aFadeDirectionOut,
TBool aImmediate /*= EFalse*/)
{
FUNC_LOG;
// Check that we are not exiting and is fade effect activated
if ( !iAppUi.AppUiExitOngoing() )
{
TInt effectTime = 0;
if ( !aImmediate && iAppUi.LayoutHandler() )
{
if( aFadeDirectionOut )
{
effectTime = iAppUi.LayoutHandler()->ViewFadeOutEffectTime();
}
else
{
effectTime = iAppUi.LayoutHandler()->ViewFadeInEffectTime();
}
}
if ( aFadeDirectionOut && IsNextTransitionOutLong() )
{
effectTime = effectTime * 2;
}
// Initialize for out fading
TAlfTimedValue timedValue( 0, effectTime );
// Check value and initialze for in fading if set
if ( !aFadeDirectionOut )
{
timedValue.SetTarget( 1, effectTime );
}
aVisual->SetOpacity( timedValue );
}
}
// ---------------------------------------------------------------------------
// Used to indicate that the next out transition effect should be long
// (some long opening view is opened next)
//
void CFsEmailUiViewBase::SetNextTransitionOutLong( TBool aLongTransitionOut )
{
FUNC_LOG;
iIsNextTransitionEffectOutLong = aLongTransitionOut;
}
// ---------------------------------------------------------------------------
//
TBool CFsEmailUiViewBase::IsNextTransitionOutLong()
{
FUNC_LOG;
return iIsNextTransitionEffectOutLong;
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::ActivateControlGroup( TInt aDelay /*= 0*/ )
{
FUNC_LOG;
if ( !iAppUi.AppUiExitOngoing() )
{
TAlfGroupCommand showCmd( ControlGroup(), EAlfOpShow, &iAppUi.Display() );
iAppUi.AlfEnv().Send( showCmd, aDelay );
ControlGroup().SetAcceptInput( ETrue );
// Status indicator is "always on top" while visible
/*if ( iAppUi.StatusIndicator() && iAppUi.StatusIndicator()->IsVisible() )
{
CAlfControlGroup& indicatorGroup = iAppUi.AlfEnv().ControlGroup( KStatusIndicatorDisplayGroup );
TAlfGroupCommand indicShowCmd( indicatorGroup, EAlfOpShow, &iAppUi.Display() );
iAppUi.AlfEnv().Send( indicShowCmd, 0 );
indicatorGroup.SetAcceptInput( EFalse );
}*/
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::DeactivateControlGroup( TInt aDelay /*= 0*/ )
{
FUNC_LOG;
const TReal32 KDelta = 0.01; // floating point comparison tolerance
if ( !iAppUi.AppUiExitOngoing() )
{
ControlGroup().SetAcceptInput( EFalse );
// Hide the control group immediately only if it's not already faded or
// fading out. This is to not interfere with the cross fading effect.
RPointerArray<CAlfVisual> layoutArray;
TRAP_IGNORE( GetParentLayoutsL( layoutArray ) );
TInt layoutCount = layoutArray.Count();
TInt fadingCount = 0;
for ( TInt i = 0 ; i < layoutCount ; ++i )
{
CAlfVisual* layout = layoutArray[i];
if ( layout && layout->Opacity().Target() < KDelta )
{
fadingCount++;
}
}
layoutArray.Close();
if ( !layoutCount || fadingCount != layoutCount )
{
iAppUi.AlfEnv().CancelCommands( &ControlGroup(), EAlfOpShow );
TAlfGroupCommand hideCmd( ControlGroup(), EAlfOpHide, &iAppUi.Display() );
iAppUi.AlfEnv().Send( hideCmd, aDelay );
}
}
}
// ---------------------------------------------------------------------------
//
CAlfControlGroup& CFsEmailUiViewBase::ControlGroup()
{
FUNC_LOG;
return iControlGroup;
}
// ---------------------------------------------------------------------------
// Handles application foreground events.
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::HandleAppForegroundEventL( TBool aForeground )
{
FUNC_LOG;
HandleForegroundEventL(aForeground);
if ( aForeground )
{
// Activate control group in case the view was activated when
// application was being sent to background, and the control group
// was left inactive.
if( iWasActiveControlGroup )
{
const TInt KActivationDelay = 200; // ms
ActivateControlGroup( KActivationDelay );
iWasActiveControlGroup = EFalse;
}
}
else if ( !iWasActiveControlGroup ) // If activation of control group isn`t forced
{
// Mail application is switching to background.
// Remember state of control group to restore it when Mail goes foreground.
iWasActiveControlGroup = ControlGroup().AcceptInput();
}
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::HandleDynamicVariantSwitchL( TDynamicSwitchType aType )
{
FUNC_LOG;
// <cmail> Toolbar
switch (aType)
{
case EScreenLayoutChanged:
UpdateToolbarL();
break;
}
// </cmail> Toolbar
// Inherited classes should override this to react to skin and layout changes
#ifdef __WINSCW__
// For emulator testing: landscape mode is "flip open"
FlipStateChangedL( Layout_Meta_Data::IsLandscapeOrientation() );
#endif
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::HandleDynamicVariantSwitchOnBackgroundL( TDynamicSwitchType /*aType*/ )
{
FUNC_LOG;
// Inherited classes should override this to react to skin and layout changes
// which happen while the view is on background
#ifdef __WINSCW__
// For emulator testing: landscape mode is "flip open"
FlipStateChangedL( Layout_Meta_Data::IsLandscapeOrientation() );
#endif
}
// ---------------------------------------------------------------------------
//
TBool CFsEmailUiViewBase::IsNextMsgAvailable( TFSMailMsgId /*aCurrentMsgId*/,
TFSMailMsgId& /*aFoundNextMsgId*/,
TFSMailMsgId& /*aFoundNextMsgFolderId*/ ) const
{
FUNC_LOG;
return EFalse;
}
// ---------------------------------------------------------------------------
//
TBool CFsEmailUiViewBase::IsPreviousMsgAvailable( TFSMailMsgId /*aCurrentMsgId*/,
TFSMailMsgId& /*aFoundPreviousMsgId*/,
TFSMailMsgId& /*aFoundPrevMsgFolderId*/ ) const
{
FUNC_LOG;
return EFalse;
}
// ---------------------------------------------------------------------------
//
TInt CFsEmailUiViewBase::MoveToNextMsgL( TFSMailMsgId /*aCurrentMsgId*/,
TFSMailMsgId& /*aFoundNextMsgId*/ )
{
FUNC_LOG;
return KErrNotFound;
}
// ---------------------------------------------------------------------------
//
TInt CFsEmailUiViewBase::MoveToPreviousMsgL( TFSMailMsgId /*aCurrentMsgId*/,
TFSMailMsgId& /*aFoundPreviousMsgId*/ )
{
FUNC_LOG;
return KErrNotFound;
}
// ---------------------------------------------------------------------------
//
TInt CFsEmailUiViewBase::MoveToPreviousMsgAfterDeleteL( TFSMailMsgId /*aFoundPreviousMsgId*/ )
{
FUNC_LOG;
return KErrNotFound;
}
//---------------------------------------------------------------------------
// Concrete view class may override
//---------------------------------------------------------------------------
void CFsEmailUiViewBase::PrepareExitL()
{
FUNC_LOG;
}
//---------------------------------------------------------------------------
// CFsEmailUiViewBase::FlipStateChangedL
//---------------------------------------------------------------------------
void CFsEmailUiViewBase::FlipStateChangedL( TBool aKeyboardFlipOpen )
{
FUNC_LOG;
iKeyboardFlipOpen = aKeyboardFlipOpen;
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::HandleForegroundEventL( TBool /*aForeground*/ )
{
FUNC_LOG;
}
// ---------------------------------------------------------------------------
//
void CFsEmailUiViewBase::ViewEntered( const TVwsViewId& aPrevViewId )
{
FUNC_LOG;
iPreviousAppUid = aPrevViewId.iAppUid;
}
// ---------------------------------------------------------------------------
// CFsEmailUiViewBase::NavigateBackL
// ---------------------------------------------------------------------------
void CFsEmailUiViewBase::NavigateBackL()
{
FUNC_LOG;
if ( !iAppUi.ViewSwitchingOngoing() )
{
TUid prevView = iAppUi.ReturnToPreviousViewL();
if ( iPreviousAppUid != KFSEmailUiUid && iPreviousAppUid != KNullUid )
{
// Email app should be hidden once the view gets deactivated. Note that hiding
// should not happen before control group switching is over because that
// may cause views of other Alfred apps to get distorted.
if( !iAppUi.EmbeddedAppIsPreviousApp() ) // if previous app is embedded app,
//do not need hide FSEmail app when previous app view gets deactivated.
{
iSendToBackgroundOnDeactivation = ETrue;
iAppUi.SetSwitchingToBackground( ETrue );
}
else
{
// Set flag to false for judging if previous app is embedded when editor exit.
iAppUi.SetEmbeddedAppToPreviousApp( EFalse );
}
// Re-activate previously active mailbox if it got changed in the external activation.
// As an exception, if previous view is the laucher grid, the previously active
// mailbox does not need to be reactivated. This prevents unnecessary mailbox switching
// when mailbox is entered from home screen, user returns with Back, and enters the same
// mailbox again.
if ( prevView != AppGridId &&
iActiveMailboxBeforeExternalActivation != iAppUi.GetActiveMailboxId() &&
!iActiveMailboxBeforeExternalActivation.IsNullId() )
{
iAppUi.SetActiveMailboxL( iActiveMailboxBeforeExternalActivation, EFalse );
}
}
}
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::ChangeMskCommandL
// Utility function to change the command ID and label on the middle soft key
// -----------------------------------------------------------------------------
void CFsEmailUiViewBase::ChangeMskCommandL( TInt aLabelResourceId )
{
FUNC_LOG;
CEikButtonGroupContainer* cba = Cba();
if ( cba )
{
cba->SetCommandL( CEikButtonGroupContainer::EMiddleSoftkeyPosition,
aLabelResourceId );
cba->DrawDeferred();
}
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::HasToolbar
// Method to check whether the view has toolbar defined or not.
// -----------------------------------------------------------------------------
TBool CFsEmailUiViewBase::HasToolbar() const
{
FUNC_LOG;
return ToolbarResourceId() != R_FREESTYLE_EMAIL_UI_TOOLBAR_BLANK;
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::ToolbarResourceId
//
// -----------------------------------------------------------------------------
TInt CFsEmailUiViewBase::ToolbarResourceId() const
{
FUNC_LOG;
return R_FREESTYLE_EMAIL_UI_TOOLBAR_BLANK;
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::OfferToolbarEventL
// -----------------------------------------------------------------------------
void CFsEmailUiViewBase::OfferToolbarEventL( TInt /*aCommand*/ )
{
FUNC_LOG;
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::SetViewActive
// -----------------------------------------------------------------------------
void CFsEmailUiViewBase::SetViewActive( const TBool aActive )
{
FUNC_LOG;
iViewActive = aActive;
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::IsViewActive
// -----------------------------------------------------------------------------
TBool CFsEmailUiViewBase::IsViewActive() const
{
FUNC_LOG;
return iViewActive;
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::IsFocusShown
// -----------------------------------------------------------------------------
TBool CFsEmailUiViewBase::IsFocusShown()
{
return iFocusVisible;
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::SetStatusBarLayout
// -----------------------------------------------------------------------------
void CFsEmailUiViewBase::SetStatusBarLayout()
{
if ( StatusPane()->CurrentLayoutResId() != R_AVKON_STATUS_PANE_LAYOUT_USUAL )
{
TRAP_IGNORE( StatusPane()->SwitchLayoutL(R_AVKON_STATUS_PANE_LAYOUT_USUAL));
}
}
// -----------------------------------------------------------------------------
// CFsEmailUiViewBase::HandleTimerFocusStateChange
// -----------------------------------------------------------------------------
void CFsEmailUiViewBase::FocusVisibilityChange( TBool aVisible )
{
iFocusVisible = aVisible;
}
// end of file