diff -r 7d48bed6ce0c -r 987c9837762f cbs/cbsui/UiSrc/CCbsUiMsgViewContainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbs/cbsui/UiSrc/CCbsUiMsgViewContainer.cpp Wed Sep 01 12:15:03 2010 +0100 @@ -0,0 +1,754 @@ +/* +* Copyright (c) 2002-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: Implementation of CCbsUiMsgViewContainer class. +* +* +*/ + + +// INCLUDES +#include // for feature flags +#include +#include // enum TAknLayoutId +#include // for iAvkonEnv +#include // AknLayoutUtils +#include // FFS critical level check +#include +#include +#include +#include +#include +#include +#include // Multiline_Message_writing_texts_Line_3 +#include // TAknLayoutScalableParameterLimits +#include // list_single_mce_message_pane_ParamLimits().iRows +#include // KEikDynamicLayoutVariantSwitch +#include // KAknsMessageSkinChange +#include +#include // CAknsBasicBackgroundControlContext +#include // MAknsSkinInstance +#include // AknsDrawUtils +#include +#include "CbsUiId.h" +#include +#include "CCbsUIMsgViewContainer.h" +#include "CCbsUIMsgView.h" +#include "Cbsuiapp.hrh" +#include "CbsUiPanic.h" +#include + + + +// LOCAL CONSTANTS AND MACROS +const TInt KEditorNumOfLines = 7; +const TInt KFirstScreen = 0; +const TInt KOneScreen = 1; +const TInt KMsgNumberOfControls = 1; +const TInt KMsgControlIndexEditor = 0; + + +// ================= MEMBER FUNCTIONS ======================= + +// C++ default constructor can NOT contain any code, that +// might leave. +CCbsUiMsgViewContainer::CCbsUiMsgViewContainer( CCbsUiMsgView& aMsgView ) +: iMsgView(aMsgView) + { + } + +// Symbian OS default constructor can leave. +void CCbsUiMsgViewContainer::ConstructL( const TRect& aRect ) + { + CreateWindowL(); + SetMopParent(&iMsgView); + + iEditor = CreateEditorL(); + SetReadOnly(ETrue); + + SetRect(aRect); + + // for Skin Support, Create background control context: + iBackGroundControlContext = CAknsBasicBackgroundControlContext::NewL( + KAknsIIDQsnBgAreaMain, // Default mainpane skinning + Rect(), // Layout to the entire client rect + EFalse ); + if ( iBackGroundControlContext ) + { + iEditor->SetSkinBackgroundControlContextL( iBackGroundControlContext ); + } + } + + +// Two-phased constructor. +CCbsUiMsgViewContainer* CCbsUiMsgViewContainer::NewL( CCbsUiMsgView& aMsgView, + const TRect& aRect ) + { + CCbsUiMsgViewContainer* self = new (ELeave) + CCbsUiMsgViewContainer(aMsgView); + + CleanupStack::PushL(self); + self->ConstructL(aRect); + CleanupStack::Pop(); + return self; + } + +// Destructor +CCbsUiMsgViewContainer::~CCbsUiMsgViewContainer() + { + delete iBackGroundControlContext; + delete iEditor; + delete iSBFrame; + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::CountComponentControls +// +// +// --------------------------------------------------------- +// +TInt CCbsUiMsgViewContainer::CountComponentControls() const + { + TInt countScrollBarComponents( 0 ); + if ( iSBFrame ) + { + countScrollBarComponents = iSBFrame->CountComponentControls(); + } + return KMsgNumberOfControls + countScrollBarComponents; + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::ComponentControl +// +// +// --------------------------------------------------------- +// +CCoeControl* CCbsUiMsgViewContainer::ComponentControl( TInt aIndex ) const + { + CCoeControl* control = NULL; + + TInt countScrollBarComponents( 0 ); + if ( iSBFrame ) + { + countScrollBarComponents = iSBFrame->CountComponentControls(); + } + + switch ( aIndex ) + { + case KMsgControlIndexEditor: + control = iEditor; + break; + default: + if ( iSBFrame + && aIndex >= KMsgNumberOfControls + && aIndex < countScrollBarComponents + KMsgNumberOfControls ) + { + control = iSBFrame->ComponentControl( aIndex - KMsgNumberOfControls ); + } + else + { + control = NULL; + } + break; + } + return control; + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::OfferKeyEventL +// +// +// --------------------------------------------------------- +// +TKeyResponse CCbsUiMsgViewContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent, + TEventCode /*aType*/ ) + { + __ASSERT_DEBUG( iEditor, CbsUiPanic(EEditorNullError) ); + + switch ( aKeyEvent.iCode ) + { + case EKeyLeftArrow: + { + if( AknLayoutUtils::LayoutMirrored() ) + { + iMsgView.MoveToNextMessageL(); + } + else + { + iMsgView.MoveToPreviousMessageL(); + } + break; + } + case EKeyRightArrow: + { + if( AknLayoutUtils::LayoutMirrored() ) + { + iMsgView.MoveToPreviousMessageL(); + } + else + { + iMsgView.MoveToNextMessageL(); + } + break; + } + case EKeyUpArrow : + { + ScrollMessageUpL(); + break; + } + case EKeyDownArrow: + { + ScrollMessageDownL(); + break; + } + case EKeyOK: + { + iMsgView.ProcessCommandL( ECbsUiappCmdOkKey ); + break; + } + case EKeyBackspace: + { + iMsgView.ProcessCommandL( ECbsUiappCmdMsgMenuDelete ); + break; + } + default: + { + break; + } + } + + return EKeyWasConsumed; + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::UpdateMessageL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::UpdateMessageL( const TDesC& aMessage ) + { + SetData16L(aMessage); + + InitializeMessageInfoL(); + + CreateScrollBarFrameL(); + UpdateScrollIndicatorL(); + + iEditor->DrawNow(); + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::SizeChanged +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::SizeChanged() + { + if ( iEditor ) + { + TRAPD( ignore, iEditor->SelectAllL() ); // This is needed before calling layoutedwin! + if( ignore ) + { + ignore = KErrNone; //Prevent ARMV5 compilation varning + } + if ( AknLayoutUtils::ScalableLayoutInterfaceAvailable() ) + { + TAknLayoutScalableParameterLimits scalbleParamLimits; + scalbleParamLimits = AknLayoutScalable_Apps::list_single_mce_message_pane_ParamLimits(); + AknLayoutUtils::LayoutEdwin( iEditor, Rect(), AppLayout::Multiline_Message_writing_texts_Line_3(scalbleParamLimits.LastRow() ) ); + } + else + { + AknLayoutUtils::LayoutEdwin( iEditor, Rect(), AppLayout::Multiline_Message_writing_texts_Line_3( KEditorNumOfLines ) ); + } + if ( iBackGroundControlContext ) + { + TRAPD( ignore, iEditor->SetSkinBackgroundControlContextL( iBackGroundControlContext ) ); + if( ignore ) + { + ignore = KErrNone; //Prevent ARMV5 compilation varning + } + } + iEditor->DrawNow(); + } + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewConctainer::CreateEditorL +// +// +// --------------------------------------------------------- +// +CEikRichTextEditor* CCbsUiMsgViewContainer::CreateEditorL() const + { + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC(reader, R_MSG_READER); + + CEikRichTextEditor* editor = new (ELeave) CEikRichTextEditor; + CleanupStack::PushL( editor ); + editor->SetContainerWindowL(*this); + editor->ConstructFromResourceL( reader ); + CleanupStack::Pop(); // editor + CleanupStack::PopAndDestroy(); // reader + + __ASSERT_DEBUG( editor, CbsUiPanic(EEditorNullError) ); + + return editor; + } + +// --------------------------------------------------------- +// CCbsUiMsgViewConctainer::Draw +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::Draw( const TRect& aRect ) const + { + CWindowGc& aGc = SystemGc(); + + // for clearing gap between editor and the view rect + if ( IsReadyToDraw() ) + { + aGc.SetBrushColor( AKN_LAF_COLOR (0) ); + DrawUtils::ClearBetweenRects( aGc, aRect, iEditor->Rect() ); + if ( iBackGroundControlContext ) + {//Draw the skin background + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + AknsDrawUtils::Background( skin, iBackGroundControlContext, this, aGc, aRect ); + } + } + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::InitializeMessageInfoL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::InitializeMessageInfoL() + { + + iEditor->TextLayout()->SetAmountToFormat( CTextLayout::EFFormatAllText ); + + iEditor->CreateTextViewL(); + iEditor->NotifyNewFormatL(); + TInt numberOfLines = iEditor->TextLayout()->NumFormattedLines(); + + if ( AknLayoutUtils::ScalableLayoutInterfaceAvailable() ) + { + TInt linesInScreen; + TAknLayoutScalableParameterLimits scalbleParamLimits; + scalbleParamLimits = AknLayoutScalable_Apps::list_single_mce_message_pane_ParamLimits(); + linesInScreen = scalbleParamLimits.LastRow(); + iNumberOfScreens = ( numberOfLines - 1 ) / linesInScreen + 1; + } + else + { + iNumberOfScreens = ( numberOfLines - 1 ) / KEditorNumOfLines + 1; + } + + iCurrentScreen = KFirstScreen; + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::CreateScrollBarFrameL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::CreateScrollBarFrameL() + { + if ( !iSBFrame ) + { + iSBFrame = new (ELeave) CEikScrollBarFrame( iEditor, this, ETrue ); + } + + CAknAppUiBase* appUi = static_cast( iEikonEnv->EikAppUi() ); + if ( AknLayoutUtils::DefaultScrollBarType( appUi ) == CEikScrollBarFrame::EDoubleSpan ) + { + // For EDoubleSpan type scrollbar + iSBFrame->CreateDoubleSpanScrollBarsL( EFalse, EFalse ); // non-window owning scrollbar + iSBFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EDoubleSpan ); + iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff,CEikScrollBarFrame::EAuto ); + TAknWindowLineLayout scrollPane = AknLayoutScalable_Apps::scroll_pane_cp017().LayoutLine(); + AknLayoutUtils::LayoutVerticalScrollBar( iSBFrame, Rect(), scrollPane ); + } + else + { + // For EArrowHead type scrollbar + iSBFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EArrowHead ); + iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff,CEikScrollBarFrame::EAuto ); + } + ActivateL(); + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::UpdateScrollIndicatorL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::UpdateScrollIndicatorL() const + { + if ( !iSBFrame ) + { + return; + } + + + TEikScrollBarModel hSbarModel; + TEikScrollBarModel vSbarModel; + vSbarModel.iThumbSpan = 1; + + vSbarModel.iThumbPosition = iCurrentScreen; // where is the position + // how many items + // if there is only one screen we don't need scroll bars (= 0) + + if ( iNumberOfScreens == KOneScreen ) + { + vSbarModel.iScrollSpan = 0; + iSBFrame->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EOff ); + } + else + { + vSbarModel.iScrollSpan = iNumberOfScreens; + iSBFrame->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, + CEikScrollBarFrame::EAuto ); + } + + if ( iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan ) + { + // For EDoubleSpan type scrollbar + TAknDoubleSpanScrollBarModel hDsSbarModel( hSbarModel ); + TAknDoubleSpanScrollBarModel vDsSbarModel( vSbarModel ); + + TEikScrollBarFrameLayout layout; + layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant; + TRect inclusiveRect( Rect( ) ); // We need to have two of these variables + TRect clientRect( Rect( ) ); + + iSBFrame->TileL( &hDsSbarModel, &vDsSbarModel, clientRect, inclusiveRect, layout ); + iSBFrame->SetVFocusPosToThumbPos( vSbarModel.iThumbPosition ); + } + else + { + iSBFrame->Tile( &vSbarModel ); + iSBFrame->SetVFocusPosToThumbPos( vSbarModel.iThumbPosition ); + } + iSBFrame->DrawScrollBarsNow(); + + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::UpdateCurrentScreen +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::UpdateCurrentScreen( TBool aIncrease ) + { + if ( aIncrease ) + { + if ( iCurrentScreen < iNumberOfScreens - 1 ) + { + iCurrentScreen++; + } + } + else + { + if ( iCurrentScreen > KFirstScreen ) + { + iCurrentScreen--; + } + } + + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::SetReadOnly +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::SetReadOnly( TBool aReadOnly ) + { + __ASSERT_DEBUG(iEditor, CbsUiPanic(EErrNullPointer) ); + iEditor->SetReadOnly(aReadOnly); + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::SetDataContentL +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::SetDataContentL( CRichText& aText ) + { + iEditor->SetDocumentContentL(aText); + iEditor->SelectAllL(); // This is needed before calling layoutedwin! + + + if ( AknLayoutUtils::ScalableLayoutInterfaceAvailable() ) + { + TAknLayoutScalableParameterLimits scalbleParamLimits; + scalbleParamLimits = AknLayoutScalable_Apps::list_single_mce_message_pane_ParamLimits(); + AknLayoutUtils::LayoutEdwin( iEditor, Rect(), AppLayout::Multiline_Message_writing_texts_Line_3(scalbleParamLimits.LastRow() ) ); + } + else + { + AknLayoutUtils::LayoutEdwin( iEditor, Rect(), AppLayout::Multiline_Message_writing_texts_Line_3( KEditorNumOfLines ) ); + } + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::SetData16L +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::SetData16L( const TDesC& aBuf ) + { + __ASSERT_DEBUG(aBuf.Length() > 0, CbsUiPanic(EErrInvalidValue) ); + + CParaFormatLayer* globalParaLayer = CParaFormatLayer::NewL(); + CleanupStack::PushL(globalParaLayer); + + CCharFormatLayer* globalCharLayer = NULL; + TRgb textColor; + + TCharFormat charFormat; + TCharFormatMask formatMask; + + ( reinterpret_cast< CGlobalText* >( iEditor->Text() ) ) + ->GetCharFormat( charFormat, formatMask, 0, 0 ); + + TInt error = AknsUtils::GetCachedColor( + AknsUtils::SkinInstance(), + textColor, + KAknsIIDQsnTextColors, + EAknsCIQsnTextColorsCG6 ); + + if ( error != KErrNone ) + { + textColor = KRgbBlack; + } + + charFormat.iFontPresentation.iTextColor = textColor; + formatMask.SetAll(); + + globalCharLayer = CCharFormatLayer::NewL( charFormat, formatMask ); + CleanupStack::PushL( globalCharLayer ); + + CRichText* richText = CRichText::NewL( globalParaLayer, globalCharLayer ); + CleanupStack::PushL( richText ); + + TInt length( aBuf.Size() / 2 ); + + for (TInt i = 0; i < length; i++) + { + if ( aBuf[i] == EKeyLineFeed ) + { + richText->InsertL( i, CEditableText::EParagraphDelimiter ); + } + else + { + richText->InsertL( i, aBuf[i] ); + } + } + + SetDataContentL( *richText ); + + iEditor->SetCharFormatLayer( globalCharLayer ); + + CleanupStack::PopAndDestroy(); // richText + CleanupStack::Pop(); // globalCharLayer + CleanupStack::PopAndDestroy(); // globalParaLayer + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::GetEditor +// +// +// --------------------------------------------------------- +// +CRichText* CCbsUiMsgViewContainer::GetEditor() const + { + __ASSERT_DEBUG(iEditor->RichText()->LdDocumentLength() > 0, + CbsUiPanic(EErrInvalidValue) ); + + return iEditor->RichText(); + } + + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::CopyToClipboard +// +// +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::CopyToClipboardL() const + { + TInt msgLength; + + msgLength = iEditor->TextLength(); + if ( SysUtil::FFSSpaceBelowCriticalLevelL( &iCoeEnv->FsSession(), 2 * msgLength ) ) + { + User::Leave( KErrDiskFull ); + } + + CPlainText* plainText = CPlainText::NewL(); + + CleanupStack::PushL(plainText); + plainText->InsertL( 0, iEditor->RichText()->Read(0) ); + plainText->ConvertAllFieldsToText(); + + CClipboard* cb = CClipboard::NewForWritingLC( iCoeEnv->FsSession() ); + plainText->CopyToStoreL( + cb->Store(), + cb->StreamDictionary(), + 0, + plainText->DocumentLength() ); + + cb->CommitL(); + CleanupStack::PopAndDestroy(2); //cb, plainText + } + + +// ---------------------------------------------------- +// CCbsUiMsgViewContainer::HandleResourceChange +// +// +// ---------------------------------------------------- +void CCbsUiMsgViewContainer::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + if( aType == KEikDynamicLayoutVariantSwitch ) + { + TRAPD( ignore, iMsgView.HandleRectChangeInContainerL() ); + if ( iBackGroundControlContext ) + { + iBackGroundControlContext->SetRect( Rect() ); + } + + if( ignore ) + { + ignore = KErrNone; //Prevent ARMV5 compilation varning + } + } + else + { + if( ( aType == KAknsMessageSkinChange ) && ( iBackGroundControlContext ) ) + { + TRAPD( ignore, iEditor->SetSkinBackgroundControlContextL( iBackGroundControlContext ) ); + if( ignore ) + { + ignore = KErrNone; //Prevent ARMV5 compilation varning + } + } + } + + } + + +// ---------------------------------------------------- +// CCbsUiMsgViewContainer::HandleScrollEventL +// ---------------------------------------------------- +void CCbsUiMsgViewContainer::HandleScrollEventL( CEikScrollBar* aScrollBar, + TEikScrollEvent aEventType ) + { + switch( aEventType ) + { + case EEikScrollUp: + case EEikScrollPageUp: + { + ScrollMessageUpL(); + break; + } + case EEikScrollDown: + case EEikScrollPageDown: + { + ScrollMessageDownL(); + break; + } + case EEikScrollThumbDragVert: + { + if( aScrollBar->ThumbPosition() > iCurrentScreen ) + { + ScrollMessageDownL(); + } + else if ( aScrollBar->ThumbPosition() < iCurrentScreen ) + { + ScrollMessageUpL(); + } + break; + } + default: + break; + } + } + +// ---------------------------------------------------- +// CCbsUiMsgViewContainer::ScrollMessageUpL +// ---------------------------------------------------- +void CCbsUiMsgViewContainer::ScrollMessageUpL() + { + if( iCurrentScreen > 0 ) + { + iEditor->MoveDisplayL( TCursorPosition::EFPageUp ); + iEditor->MoveDisplayL( TCursorPosition::EFLineUp ); + UpdateCurrentScreen( EFalse ); + UpdateScrollIndicatorL(); + } + } + +// ---------------------------------------------------- +// CCbsUiMsgViewContainer::ScrollMessageDownL +// ---------------------------------------------------- +void CCbsUiMsgViewContainer::ScrollMessageDownL() + { + if( iCurrentScreen < iNumberOfScreens-1 ) + { + iEditor->MoveDisplayL( TCursorPosition::EFPageDown ); + iEditor->MoveDisplayL( TCursorPosition::EFLineDown ); + UpdateCurrentScreen( ETrue ); + UpdateScrollIndicatorL(); + } + } + +// --------------------------------------------------------- +// CCbsUiMsgViewContainer::GetHelpContext +// +// Gets the control's help context. +// --------------------------------------------------------- +// +void CCbsUiMsgViewContainer::GetHelpContext( TCoeHelpContext& aContext ) const + { + aContext.iMajor = TUid::Uid(KUidCbsUiappDef); + aContext.iContext = KCBS_HLP_MSG; + } + + +// End of File