--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/ncseditor.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,689 @@
+/*
+* 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: This file implements class CNcsEditor.
+*
+*/
+
+
+
+#include "emailtrace.h"
+#include <avkon.hrh>
+#include <aknenv.h> // CAknEnv
+#include <txtrich.h>
+#include <txtglobl.h>
+#include <AknUtils.h> // AknLayoutUtils
+#include <AknsConstants.h>
+#include <AknsUtils.h>
+#include <AknsSkinInstance.h>
+#include <aknedsts.h>
+#include <AknsBasicBackgroundControlContext.h>
+
+#include "ncseditor.h"
+#include "ncsutility.h"
+#include "ncscustomdraw.h"
+#include "ncseditorcustomdraw.h"
+
+// ========================= MEMBER FUNCTIONS ==================================
+
+// ---------------------------------------------------------------------------
+// constructor
+// ---------------------------------------------------------------------------
+//
+CNcsEditor::CNcsEditor( MNcsFieldSizeObserver* aSizeObserver,
+ TBool aHeaderField,
+ TNcsEditorUsage aEditorUsage ) :
+ MNcsControl( aSizeObserver ),
+ iPreviousFontHeight( -1 ),
+ iPreviousLineSpacingInTwips( -1 ),
+ // Platform layout change
+ iHeaderField( aHeaderField ),
+ iNcsFontType ( NcsUtility::ENcsHeaderDetailFont ),
+ iEditorUsage( aEditorUsage ),
+ iRealRect( 0, 0, 0, 0 )
+ {
+ FUNC_LOG;
+ }
+
+// ---------------------------------------------------------------------------
+// second phase constructor
+// ---------------------------------------------------------------------------
+//
+void CNcsEditor::ConstructL( const CCoeControl* aParent,
+ TInt aNumberOfLines,
+ TInt aTextLimit )
+ {
+ FUNC_LOG;
+ CEikRichTextEditor::ConstructL( aParent, aNumberOfLines, aTextLimit,
+ CEikEdwin::EAvkonEditor | CEikEdwin::EResizable |
+ CEikEdwin::ENoAutoSelection | CEikEdwin::EInclusiveSizeFixed |
+ CEikEdwin::ENoHorizScrolling | CEikRichTextEditor::EPasteAsPlainText );
+
+ iGlobalCharFormat = CCharFormatLayer::NewL();
+ iGlobalCharFormat->SetBase( GlobalText()->GlobalCharFormatLayer() );
+ GlobalText()->SetGlobalCharFormat( iGlobalCharFormat );
+ }
+
+// -----------------------------------------------------------------------------
+// destructor
+// -----------------------------------------------------------------------------
+//
+CNcsEditor::~CNcsEditor()
+ {
+ FUNC_LOG;
+ // <cmail> Platform layout change
+ delete iBgContext;
+ // </cmail>
+ delete iGlobalCharFormat;
+
+ if ( iEditorCustomDrawer )
+ {
+ delete iEditorCustomDrawer;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::OpenVirtualKeyBoardL()
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::OpenVirtualKeyBoardL()
+ {
+ FUNC_LOG;
+ MCoeFepAwareTextEditor_Extension1* fepAwareTextEditor(
+ InputCapabilities().FepAwareTextEditor()->Extension1() );
+ CAknEdwinState* state( NULL );
+ if ( fepAwareTextEditor )
+ {
+ state = static_cast<CAknEdwinState*>(
+ fepAwareTextEditor->State( KNullUid ) );
+ }
+ if (state)
+ {
+ state->ReportAknEdStateEventL(
+ MAknEdStateObserver::EAknActivatePenInputRequest );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::GetLineRectL() const
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::GetLineRectL( TRect& aLineRect ) const
+ {
+ FUNC_LOG;
+ TPoint position;
+ iLayout->DocPosToXyPosL( CursorPos(), position );
+ iLayout->GetLineRect( position.iY, aLineRect );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::CursorLineNumber() const
+// -----------------------------------------------------------------------------
+//
+TInt CNcsEditor::CursorLineNumber() const
+ {
+ FUNC_LOG;
+ TInt ret = iLayout->GetLineNumber( CursorPos() );
+ ret++;
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::CursorPosition() const
+// -----------------------------------------------------------------------------
+//
+TInt CNcsEditor::CursorPosition() const
+ {
+ FUNC_LOG;
+ // Return the position of the cursor relative
+ // to the top of the control (in pixels)
+ TPoint position;
+ TInt cp = CursorPos();
+ TRAP_IGNORE( iLayout->DocPosToXyPosL( cp , position ) );
+ position.iY += iLayout->PixelsAboveBand();
+ return position.iY;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::OfferKeyEventL() const
+// -----------------------------------------------------------------------------
+//
+TKeyResponse CNcsEditor::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ FUNC_LOG;
+ TKeyResponse ret( EKeyWasNotConsumed );
+ if( aKeyEvent.iCode == EKeyDelete && CursorPos() == TextLength() )
+ {
+ ClearSelectionL();
+ return EKeyWasConsumed;
+ }
+ else
+ {
+ ret = CEikRichTextEditor::OfferKeyEventL( aKeyEvent, aType );
+ }
+
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::SetTextL
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::SetTextL( const TDesC* aDes )
+ {
+ FUNC_LOG;
+ CEikEdwin::SetTextL( aDes );
+ if ( ( *aDes ).Compare( KNullDesC ) == 0 )
+ {
+ // when text is emptied, set text color again
+ SetTextColorL( iTextColor );
+ UpdateFontSize();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::SetRect
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::SetRect( const TRect& aRect )
+ {
+ FUNC_LOG;
+ //CCoeControl::SetRect( aRect );
+ CEikRichTextEditor::SetRect( aRect );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::HandleResourceChange
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::HandleResourceChange( TInt aType )
+ {
+ FUNC_LOG;
+ CEikRichTextEditor::HandleResourceChange( aType );
+
+ if ( aType == KAknsMessageSkinChange )
+ {
+ // S60 skin support
+ UpdateGraphics();
+ UpdateFontSize();
+ UpdateColors();
+ if ( iCustomDrawer )
+ {
+ iCustomDrawer->UpdateColors();
+ }
+ }
+ else if ( aType == KEikMessageColorSchemeChange )
+ {
+ UpdateFontSize();
+ UpdateColors();
+ if ( iCustomDrawer )
+ {
+ iCustomDrawer->UpdateColors();
+ }
+ }
+ else if ( aType == KEikMessageZoomChange )
+ {
+ UpdateFontSize();
+ }
+
+ if ( iEditorCustomDrawer )
+ {
+ iEditorCustomDrawer->UpdateLayout( GetLayout() );
+ }
+ }
+
+//<cmail> Platform layout change
+// -----------------------------------------------------------------------------
+// CNcsEditor::CreateCustomDrawL
+// -----------------------------------------------------------------------------
+//
+/*
+CLafEdwinCustomDrawBase* CNcsEditor::CreateCustomDrawL()
+ {
+ CLafEdwinCustomDrawBase* drawer = CEikEdwin::CreateCustomDrawL();
+ iCustomDrawer = new ( ELeave ) CNcsCustomDraw(
+ static_cast<CEikonEnv*>( ControlEnv() )->LafEnv(),
+ *this,
+ drawer,
+ this,
+ iHeaderField );
+ iCustomDrawer->UpdateColors();
+ return iCustomDrawer;
+ }
+*/
+// </cmail>
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::SetupEditorL()
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::SetupEditorL()
+ {
+ FUNC_LOG;
+ // <cmail> Added text view creation.
+ // In S60 5.0 we end up here before this control is "activated". Normally
+ // text view is created in CEikGlobalTextEditor::ActivateL
+ // Find out why this problem doesn't exist in Freestyle/S60 3.2.3.
+ if ( !iTextView )
+ {
+ CreateTextViewL();
+ }
+ // </cmail>
+
+ // <cmail> Platform layout change
+ //TextLayout()->RestrictScrollToTopsOfLines( EFalse );
+ // </cmail>
+
+ // Set the cursor position to initialize the edit control
+ SetCursorPosL(0,EFalse);
+ UpdateFontSize();
+ UpdateColors();
+ // <cmail> S60 skin support
+ UpdateGraphics();
+ // </cmail>
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::LineCount() const
+// -----------------------------------------------------------------------------
+//
+TInt CNcsEditor::LineCount() const
+ {
+ FUNC_LOG;
+ TInt lineCount = iLayout->GetLineNumber( TextLength() );
+ lineCount++;
+ return lineCount;
+ }
+
+TInt CNcsEditor::ScrollableLines() const
+ {
+ FUNC_LOG;
+ TRect lineRect;
+ // First get the rect for one line
+ iLayout->GetLineRect(0, lineRect);
+ TRect rect = Rect();
+ TInt lines = rect.Height()/lineRect.Height();
+ return lines;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::PositionChanged() const
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::PositionChanged()
+ {
+ FUNC_LOG;
+ if( iTextView )
+ {
+ TRect displayRect=iBorder.InnerRect(Rect());
+ displayRect=iMargins.InnerRect(displayRect);
+ iTextView->SetViewRect(displayRect);
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::TextHeight() const
+// -----------------------------------------------------------------------------
+//
+TInt CNcsEditor::TextHeight() const
+ {
+ FUNC_LOG;
+ return iLayout->FormattedHeightInPixels();
+ }
+
+#ifdef _DEBUG
+// Is is meant for debugging.
+// Break here to see what the values are.
+void CNcsEditor::DebugDump()
+ {
+ FUNC_LOG;
+ TInt bandHeight = iLayout->BandHeight();
+ TInt firstDocPosFullyInBad = iLayout->FirstDocPosFullyInBand();
+ TInt firstLineInBand = iLayout->FirstLineInBand();
+ TInt pixelsAboveBand = iLayout->PixelsAboveBand();
+ }
+#endif
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::SetTextColorL()
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::SetTextColorL( TLogicalRgb aColor )
+ {
+ FUNC_LOG;
+ TCharFormat charFormat;
+ charFormat.iFontPresentation.iTextColor = aColor;
+ TCharFormatMask charFormatMask;
+ charFormatMask.SetAttrib( EAttColor );
+ iGlobalCharFormat->SetL( charFormat, charFormatMask );
+ GlobalText()->SetGlobalCharFormat( iGlobalCharFormat );
+ NotifyNewFormatL();
+ }
+
+TBool CNcsEditor::HasSemicolonAtTheEndL() const
+{
+ HBufC* text = GetTextInHBufL();
+
+ TBool result(EFalse);
+ if ( text && text->Right(1).Compare(_L(";") ) == 0 )
+ {
+ result = ETrue;
+ }
+ delete text;
+ text = NULL;
+
+ return result;
+}
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::TrimmedTextLength()
+// -----------------------------------------------------------------------------
+//
+TInt CNcsEditor::TrimmedTextLength()
+ {
+ FUNC_LOG;
+ HBufC* text = NULL;
+ TRAP_IGNORE( text = GetTextInHBufL() );
+ TInt length = 0;
+ if ( text )
+ {
+ text->Des().TrimAll();
+ length = text->Des().Length();
+ delete text;
+ }
+ return length;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::EditObserver()
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::EditObserver( TInt aStart, TInt aExtent )
+ {
+ FUNC_LOG;
+ CEikRichTextEditor::EditObserver( aStart, aExtent );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::UpdateColors
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::UpdateColors()
+ {
+ FUNC_LOG;
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+ // <cmail> S60 Skin support
+ const TInt error( AknsUtils::GetCachedColor( skin, iTextColor,
+ KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6 ) );
+ if ( error )
+ {
+ iTextColor = KRgbBlack;
+ }
+
+ // </cmail>
+ TRAP_IGNORE( SetTextColorL( iTextColor ) );
+ }
+
+// <cmail>
+// -----------------------------------------------------------------------------
+// CNcsEditor::SetNcsFontType
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::SetNcsFontType( NcsUtility::TNcsLayoutFont aFontType )
+ {
+ FUNC_LOG;
+ iNcsFontType = aFontType;
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::UpdateFontSize
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::UpdateFontSize()
+ {
+ FUNC_LOG;
+ /*TCharFormat charFormat;
+ TCharFormatMask charFormatMask;
+
+ TNcsMeasures m = NcsUtility::Measures();
+
+ // <cmail>
+ CFont* editorFont = NULL;
+
+ TRAPD( err, editorFont = NcsUtility::GetNearestFontL(
+ EAknLogicalFontPrimarySmallFont,
+ m.iEditorFontHeightPx)
+ );
+
+ if( err == KErrNone )
+ {
+ */
+
+ TRAP_IGNORE( UpdateFontL() );
+// CEikonEnv::Static()->ScreenDevice()->ReleaseFont( editorFont );
+// }
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::UpdateFontL
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::UpdateFontL()
+ {
+ FUNC_LOG;
+ TCharFormat charFormat;
+ TCharFormatMask charFormatMask;
+ charFormat.iFontSpec = NcsUtility::GetLayoutFont( Rect(), iNcsFontType )->FontSpecInTwips();
+ charFormat.iFontPresentation.iTextColor = iTextColor;
+ charFormatMask.SetAttrib(EAttColor);
+ charFormatMask.SetAttrib(EAttFontTypeface);
+ charFormatMask.SetAttrib(EAttFontHeight);
+ iGlobalCharFormat->SetL(charFormat, charFormatMask);
+ GlobalText()->SetGlobalCharFormat( iGlobalCharFormat );
+ }
+
+// </cmail>
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::UpdateGraphics
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::UpdateGraphics()
+ {
+ TRAP_IGNORE( DoUpdateGraphicsL() );
+ }
+
+// -----------------------------------------------------------------------------
+// CNcsEditor::DoUpdateGraphicsL
+// -----------------------------------------------------------------------------
+//
+void CNcsEditor::DoUpdateGraphicsL()
+ {
+ // <cmail> S60 Skin support
+ delete iBgContext;
+ iBgContext = NULL;
+
+ TSize mainPaneSize;
+ AknLayoutUtils::LayoutMetricsSize(
+ AknLayoutUtils::EMainPane, mainPaneSize );
+
+ iBgContext = CAknsBasicBackgroundControlContext::NewL(
+ //KAknsIIDQgnFsGrafEmailContent,
+ KAknsIIDQsnBgAreaMain,
+ TRect( mainPaneSize ),
+ EFalse );
+
+ SetSkinBackgroundControlContextL( iBgContext );
+ // </cmail>
+ }
+
+// ---------------------------------------------------------------------------
+// CNcsEditor::GetLabelText
+// ---------------------------------------------------------------------------
+//
+const TDesC& CNcsEditor::GetLabelText() const
+ {
+ return KNullDesC;
+ }
+
+// <cmail> Platform layout change
+// ---------------------------------------------------------------------------
+// CNcsEditor::LayoutLineCount
+// ---------------------------------------------------------------------------
+//
+TInt CNcsEditor::LayoutLineCount() const
+ {
+ return IsVisible() ? LineCount() : 0;
+ }
+// </cmail> Platform layout change
+
+// ---------------------------------------------------------------------------
+// CNcsEditor::GetNumChars
+// ---------------------------------------------------------------------------
+//
+TInt CNcsEditor::GetNumChars() const
+ {
+ FUNC_LOG;
+ TInt cnt = iLayout->DocumentLength();
+ return cnt;
+ }
+
+TInt CNcsEditor::GetLineHeightL() const
+ {
+ FUNC_LOG;
+ TPoint pos;
+ TRect rect;
+ iLayout->DocPosToXyPosL(0, pos);
+ iLayout->GetLineRect(pos.iY,rect);
+ return rect.Height();
+ }
+
+TInt CNcsEditor::DocumentLength() const
+ {
+ FUNC_LOG;
+ return iLayout->DocumentLength();
+ }
+
+TInt CNcsEditor::PixelsAboveBand() const
+ {
+ FUNC_LOG;
+ return iLayout->PixelsAboveBand();
+ }
+
+TInt CNcsEditor::ChangeBandTopL(TInt aPixels)
+ {
+ FUNC_LOG;
+ TInt px = aPixels;
+ return iLayout->ChangeBandTopL(px);
+ }
+
+void CNcsEditor::ActivateL()
+ {
+ if ( IsActivated() )
+ {
+ return;
+ }
+
+ CEikRichTextEditor::ActivateL();
+
+ if ( !iEditorCustomDrawer && iEditorUsage != ENcsEditorDefault )
+ {
+ TAknTextComponentLayout layout;
+ if ( iEditorUsage == ENcsEditorBody )
+ {
+ layout = AknLayoutScalable_Apps::list_cmail_body_pane_t1();
+ }
+ else if ( iEditorUsage == ENcsEditorAddress ||
+ iEditorUsage == ENcsEditorSubject )
+ {
+ layout = AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1( KHeaderDetailTextPaneVariety );
+ }
+
+ // Swap the custom drawer to our own to show text lines.
+ const MFormCustomDraw* customDraw = TextLayout()->CustomDraw();
+
+ iEditorCustomDrawer = CNcsEditorCustomDraw::NewL( customDraw, this, GetLayout() );
+
+ TextLayout()->SetCustomDraw( iEditorCustomDrawer );
+ }
+ }
+
+//<cmail>
+void CNcsEditor::SetRealRect( TRect aRect )
+ {
+ iRealRect = aRect;
+ }
+
+void CNcsEditor::Draw( const TRect& /*aRect*/ ) const
+ {
+ if ( iTextView )
+ {
+ CWindowGc& gc=SystemGc();
+ TRect viewRect( iTextView->ViewRect() );
+ if( iRealRect.Height() > 0 )
+ {
+ if( !( viewRect.iTl.iY > iRealRect.iBr.iY || viewRect.iBr.iY < iRealRect.iTl.iY ) )
+ {
+ TrappedDraw( iRealRect );
+ }
+ }
+ else
+ {
+ TrappedDraw( viewRect );
+ }
+
+
+ #ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
+ // Workaround for clipping rect problem in multiline queries with text
+ // entries. Because of differences between CRemoteGc and CWindowGc,
+ // parts of the query wouldn't be drawn by CRemoteGc. The Reset() call
+ // is to cancel the clipping rect. For some reason, CancelClippingRect()
+ // and CancelClippingRegion() don't work.
+ gc.Reset();
+ #endif
+ }
+ }
+
+void CNcsEditor::FormatAllTextNowL()
+ {
+ NotifyNewFormatL();
+ iTextView->FinishBackgroundFormattingL();
+ }
+//</cmail>
+
+TAknTextComponentLayout CNcsEditor::GetLayout()
+ {
+ TAknTextComponentLayout layout;
+
+ if ( iEditorUsage == ENcsEditorBody )
+ {
+ layout = AknLayoutScalable_Apps::list_cmail_body_pane_t1();
+ }
+ else if ( iEditorUsage == ENcsEditorAddress ||
+ iEditorUsage == ENcsEditorSubject )
+ {
+ layout = AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1( KHeaderDetailTextPaneVariety );
+ }
+
+ return layout;
+ }
+
+
+void CNcsEditor::UpdateCustomDrawer()
+ {
+ if ( iEditorCustomDrawer )
+ {
+ iEditorCustomDrawer->UpdateLayout( GetLayout() );
+ }
+ }