uifw/AvKon/src/aknmessagequerycontrol.cpp
changeset 0 2f259fa3e83a
child 14 3320e4e6e8bb
child 18 0aa5fbdfbc30
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/aknmessagequerycontrol.cpp	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,912 @@
+/*
+* Copyright (c) 2002 - 2006 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:
+*
+*/
+
+
+// INCLUDE FILES
+#include <barsread.h>
+#include <eikenv.h>
+#include <AknPanic.h>
+#include <avkon.hrh>
+#include <avkon.rsg>
+#include <aknmessagequerycontrol.h>
+#include <aknmessagequerydialog.h>
+
+#include <eiksbfrm.h>
+#include <eikscrlb.h>
+
+#include <eikappui.h>
+
+#include <frmlaydt.h>
+#include "aknconsts.h"
+
+#include <AknsDrawUtils.h>
+
+#include <applayout.cdl.h>
+#include "aknappui.h"
+
+#include <eikrted.h>
+#include <txtrich.h> 
+#include <txtfrmat.h>
+
+#include <layoutmetadata.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+
+#include <eikdialg.h>
+#include <eikdialogext.h>
+
+#include <eikedwob.h>
+
+#include <AknTasHook.h> // for testability hooks
+class CAknMessageQueryControlExtension: public CBase, public MEikEdwinObserver
+    {
+public:
+    CAknMessageQueryControlExtension( CAknMessageQueryControl* aParent ): iParent( aParent ) {}
+        
+    /**
+    * From MEikEdwinObserver. Handles edwin events.
+    * On the scroll event, any selected link is dehighlighted.
+    */
+    void HandleEdwinEventL( CEikEdwin* /*aEdwin*/, TEdwinEvent aEventType )
+        {
+    	if( aEventType == MEikEdwinObserver::EEventScroll )
+    	    {
+    		iParent->DehighlightLink();
+    		}
+        }
+        
+    ~CAknMessageQueryControlExtension()
+        {    
+        if( iDestroyedPtr )
+            {
+            // Mark the object as destroyed.
+            *iDestroyedPtr = ETrue;
+            iDestroyedPtr = NULL;
+            }
+        }
+        
+    public:
+    
+    CAknMessageQueryControl* iParent;
+    /**
+    * @c iDestroyedPtr is used for the object destruction check.
+    * If it has non-null value, the destruction check is turned on, and
+    * the value points to a local boolean variable that keeps the destroyed state.
+    */
+    TBool* iDestroyedPtr;
+    };
+
+CAknMessageQueryControl::CAknMessageQueryControl() :
+    iTopLine( 0 ), iLinksCount( 0 ), iVisibleLinksCount( 0 ),
+    iFirstVisibleLink( -1 ), iCurPos( 0 ), iFullMessage( NULL )
+    {
+    iLinesPerPage = AknLayoutScalable_Avkon::popup_info_list_pane_t1_ParamLimits().LastRow() + 1;
+    AKNTASHOOK_ADD( this, "CAknMessageQueryControl" );
+    }
+
+CAknMessageQueryControl::~CAknMessageQueryControl()
+    {
+    AKNTASHOOK_REMOVE();
+    AknsUtils::DeregisterControlPosition( iEdwin );
+    delete iEdwin;
+    iLinkTextLocationArray.Close();
+    iLinkTextArray.Close();
+    delete iFullMessage;
+    delete iExtension;
+    }
+
+EXPORT_C void CAknMessageQueryControl::ConstructFromResourceL( TResourceReader& aReader )
+    {
+    CEikDialog* dlg;
+    MopGetObject( dlg );
+
+    if ( dlg )
+        {
+        dlg->Extension()->iPublicFlags.Set( CEikDialogExtension::EClipChildControlRect );
+        }
+    
+    TPtrC messageLabel = aReader.ReadTPtrC();
+    SetMessageTextL( &messageLabel );
+    }
+
+EXPORT_C void CAknMessageQueryControl::SetMessageTextL( TDesC* aMessage )
+    {
+    CreateEditorL();
+    iEdwin->TextLayout()->SetAmountToFormat( CTextLayout::EFFormatAllText );
+    if ( aMessage->Length() > iEdwin->UpperFullFormattingLength() )
+        iEdwin->SetUpperFullFormattingLength( aMessage->Length() ); 
+    iEdwin->SetTextL( aMessage );
+    LayoutEditorL(); 
+    
+    HBufC* msgBuf = aMessage->AllocLC();
+    TPtr message( msgBuf->Des() );
+    if( iListQLayout )
+        {
+        TruncateTextForListQLayout( message );
+        iEdwin->SetTextL( &message );
+        LayoutEditorL(); 
+        }
+
+    if ( message.Locate('\n') != KErrNotFound )
+        {
+        iEdwin->SetCursorPosL( 1, EFalse );
+        SEdwinFindModel findModel;
+        _LIT( KNChar,"\n" ); 
+        _LIT( KFChar,"\f" );
+        TBuf<1> text( KNChar );
+        TBuf<1> replaceText( KFChar );
+        findModel.iFlags = 0;
+        findModel.iText = text;
+        findModel.iReplaceText = replaceText;
+        findModel.iReplaceOption = EReplaceAll;
+        iEdwin->ReplaceAllL( &findModel );
+        }
+    CleanupStack::PopAndDestroy( msgBuf );  // After all usages of message        
+             
+    iNumberOfLines = iEdwin->TextLayout()->NumFormattedLines();
+    iTopLine = 0;
+    UpdateScrollIndicatorL();    
+    }           
+    
+void CAknMessageQueryControl::CreateEditorL()
+    {
+    delete iEdwin;
+    iEdwin = NULL;
+    iSBFrame = NULL;
+    
+    iEdwin = new ( ELeave ) CEikRichTextEditor( TGulBorder::ENone );
+    iEdwin->SetContainerWindowL( *this );
+    AknEditUtils::ConstructEditingL( iEdwin, R_AVKON_MESSAGE_QUERY_EDITOR );
+    
+    if ( !iExtension )
+        {
+        iExtension = new (ELeave) CAknMessageQueryControlExtension( this );
+        }
+    iEdwin->SetEdwinObserver( iExtension );
+    iEdwin->SetAvkonWrap( ETrue );                                  
+    iEdwin->SetFocus( EFalse );
+    iEdwin->SetNonFocusing();
+    iEdwin->EnableKineticScrollingL(ETrue);
+    }    
+    
+void CAknMessageQueryControl::LayoutEditorL()
+    {
+    TInt lines = 1;
+
+    RArray<TAknTextComponentLayout> textComponentLayoutArray;
+    for ( TInt rowIndex = 0; rowIndex < lines; rowIndex++)
+        {
+        TRAPD(error, textComponentLayoutArray.AppendL(AknLayoutScalable_Avkon::popup_info_list_pane_t1(rowIndex)));
+        if (error != KErrNone)
+            {
+            textComponentLayoutArray.Close();
+            User::Leave(error);
+            }
+        }
+
+    TRect parentRect = LayoutRect();
+    TAknLayoutRect listScrollPopupInfoPane;
+    listScrollPopupInfoPane.LayoutRect(parentRect, AknLayoutScalable_Avkon::listscroll_popup_info_pane());
+    TAknLayoutRect listPopupInfoPane;
+    listPopupInfoPane.LayoutRect(listScrollPopupInfoPane.Rect(), AknLayoutScalable_Avkon::list_popup_info_pane( 0 ));  // Variety with scroll bar
+    
+    /** The edwin rect is set totally from layout list_popup_info_pane. But
+      * AknLayoutUtils::LayoutEdwin() is still used for setting its text color and font. 
+     **/ 
+    AknLayoutUtils::LayoutEdwin( iEdwin, listPopupInfoPane.Rect(),
+        TAknTextComponentLayout::Multiline(textComponentLayoutArray), EAknsCIQsnTextColorsCG19 );
+    iEdwin->SetSuppressFormatting(ETrue);
+    iEdwin->SetRect( listPopupInfoPane.Rect() );
+    iEdwin->SetSuppressFormatting(EFalse);
+    textComponentLayoutArray.Close();
+    }    
+
+TKeyResponse CAknMessageQueryControl::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode /*aModifiers*/ )
+    {
+    TInt key( aKeyEvent.iCode );
+    if( !(key == EKeyDownArrow || key == EKeyUpArrow) )
+        return EKeyWasConsumed;
+    TBool moveDown = key == EKeyDownArrow; // Moving down?
+        
+    /* 4 transitions are possible:
+    
+    Text   -> *Link*
+    *Link* -> *Link*
+    *Link* -> Text
+    Text   -> >>Scroll page>>
+    
+    */
+    
+    // If the editor was scrolled with pen, synchronize the query's and editor's states
+    TInt editorTopLine = iEdwin->TextLayout()->FirstLineInBand();
+    if( editorTopLine != iTopLine )
+        {
+        if( LinkHighLighted() ) // Standing on a link?
+            {
+            // Synchronize to the query's position
+            iEdwin->TextView()->SetViewLineAtTopL( iTopLine + 1 );    // Uses 1-based line numbers
+            }
+        else
+            {
+            // Synchronize to the editor's position
+            iTopLine = editorTopLine;
+            UpdatePageInfo();
+            }
+        }
+        
+    SetHighlightOnL( EFalse );  // Dehighlight the old link    
+        
+    // Move to the following position    
+    iCurPos += moveDown? 1 : -1;
+    if( iCurPos < 1 || iPositionsCount -1  <= iCurPos ) // Beyond the allowed range
+        {
+        if( CanScrollPage( moveDown ) )
+            {
+            iTopLine += moveDown? iLinesPerPage - 1 : 1 - iLinesPerPage;
+            if( iTopLine >= iNumberOfLines - iLinesPerPage)
+                {
+                iTopLine = iNumberOfLines - iLinesPerPage;
+                }
+            if( iTopLine < 0)
+                {
+                iTopLine = 0;
+                }
+            iEdwin->MoveDisplayL( moveDown? TCursorPosition::EFPageDown : TCursorPosition::EFPageUp );
+            int lastPageLink = -1;
+            if( iFirstVisibleLink > -1 )
+            	lastPageLink = moveDown?
+            	    (iFirstVisibleLink + iVisibleLinksCount - 1): iFirstVisibleLink;
+            UpdatePageInfo();
+            if( lastPageLink > -1 && iFirstVisibleLink > -1 )
+                {
+                if( moveDown )
+                    {
+                	iCurPos = 1;
+                	while( lastPageLink-- >= iFirstVisibleLink )
+                	    {
+                		iCurPos++;
+                	    }
+                    }
+                
+                else
+                    {
+                    iCurPos = iPositionsCount - 2;
+                    while( lastPageLink++ <= iFirstVisibleLink + iVisibleLinksCount - 1 )
+                        {
+                    	iCurPos--;
+                        }	
+                    }
+            	
+                }
+            else
+                {
+            	iCurPos = moveDown? 1 : iPositionsCount - 2;   // Proceed to top or bottom of the following page
+                }
+            }
+        else
+            {
+            iCurPos = moveDown? iPositionsCount - 1 : 0;    // Return to bottom or top of the current page
+            }
+        }
+    
+    SetHighlightOnL( ETrue );   // Highlight the new link
+    
+        
+    UpdateScrollIndicatorL();
+    return( EKeyWasConsumed );
+    }
+
+void CAknMessageQueryControl::SizeChanged()
+    {
+    TRAP_IGNORE( DoSizeChangedL() );
+    }
+
+
+TSize CAknMessageQueryControl::MinimumSize()
+    {
+    const TRect rect( LayoutRect() );
+    TAknLayoutRect listScrollPopupInfoPane;
+    listScrollPopupInfoPane.LayoutRect(rect, AknLayoutScalable_Avkon::listscroll_popup_info_pane());
+
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+        return TSize( rect.Width(), listScrollPopupInfoPane.Rect().Height() );
+        }
+    else
+        {
+        return listScrollPopupInfoPane.Rect().Size();
+        }
+    } 
+
+
+TRect CAknMessageQueryControl::LayoutRect() const
+    {
+    TInt lines = iNumberOfLines > iLinesPerPage ? iLinesPerPage : iNumberOfLines;
+    
+    lines--;
+    if ( lines < 0 ) 
+        {
+        lines = 0;    
+        }
+
+    TInt variety = 0;
+    AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation();
+    if (cbaLocation == AknLayoutUtils::EAknCbaLocationRight)
+        { // Variety numbers for right CBA are 6-11
+        variety = lines + 6;
+        }
+    else if (cbaLocation == AknLayoutUtils::EAknCbaLocationLeft)
+        { // Variety numbers for left CBA are 12-17
+        variety = lines + 12;
+        }
+    else // bottom
+        {
+        variety = lines;
+        }
+
+    TRect appRect = iAvkonAppUi->ApplicationRect();
+    TAknLayoutRect applicationWindow;
+    applicationWindow.LayoutRect(appRect, AknLayoutScalable_Avkon::application_window(0));    
+    TRect mainPane;
+    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EPopupParent, mainPane );
+    
+    TAknLayoutRect layout;
+    layout.LayoutRect( mainPane, AknLayoutScalable_Avkon::popup_query_sat_info_window( variety ) );
+    TRect rect( layout.Rect() );
+
+    return TRect( TPoint(0, 0), rect.Size() );
+    }
+
+// Get component controls into a table
+const TInt KMaxMessageQueryControls = 2;
+static TInt ComponentControls(CCoeControl* aEditor,
+    CEikScrollBarFrame* aScrollBarFrame,
+    CCoeControl* aControls[KMaxMessageQueryControls])
+    {
+    TInt i = 0;
+    if (aEditor)
+        {
+        aControls[i++] = aEditor;
+        }
+    // Non-window owning acroll bar
+    if (aScrollBarFrame && aScrollBarFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
+        {
+        aControls[i++] = aScrollBarFrame->GetScrollBarHandle(
+            CEikScrollBar::EVertical);
+        }
+    return i;
+    }
+
+TInt CAknMessageQueryControl::CountComponentControls() const
+    {
+     CCoeControl* unused[KMaxMessageQueryControls];
+     return ComponentControls(iEdwin, iSBFrame, unused);
+    }
+
+
+CCoeControl* CAknMessageQueryControl::ComponentControl( TInt aIndex ) const
+    {
+     CCoeControl* controls[KMaxMessageQueryControls];
+     TInt cnt = ComponentControls(iEdwin, iSBFrame, controls);
+     if (aIndex < cnt)
+        {
+        return controls[aIndex];
+        }
+    else
+        {
+        return NULL;
+        }
+    }         
+
+// This method is needed to set correct initial value to scroll indicator.
+void CAknMessageQueryControl::ActivateL()
+    {
+    CCoeControl::ActivateL();
+    UpdateScrollIndicatorL();
+    }
+
+void CAknMessageQueryControl::UpdateScrollIndicatorL()
+    {
+    if ( iNumberOfLines <= iLinesPerPage )
+        {
+        return;
+        }
+    
+    if ( !iSBFrame )
+        {
+        // edwin will make scrollbar and also observe it
+        iSBFrame = iEdwin->CreateScrollBarFrameL();
+
+        // Check which type of scrollbar is to be shown
+        iSBFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue, EFalse );
+        iSBFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EDoubleSpan );
+        iSBFrame->DrawBackground( EFalse, EFalse );
+        iSBFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff,
+                CEikScrollBarFrame::EAuto );
+        }
+    
+    iEdwin->UpdateScrollBarsL();    
+    }
+
+EXPORT_C void CAknMessageQueryControl::Draw( const TRect& /*aRect*/ ) const
+    {
+    if ( iListQLayout )
+    	{
+        return;
+        }
+
+    CWindowGc& gc=SystemGc(); 
+    TRect messageQueryControlRect( Rect() );
+    TRect popupRect(LayoutRect());
+
+    TRect backgroundRect(messageQueryControlRect.iTl, popupRect.iBr);    
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
+
+    TRegionFix<4> clipReg;
+    clipReg.AddRect( backgroundRect );
+    
+    if ( iEdwin )
+        {
+        clipReg.SubRect( iEdwin->Rect() );
+        }
+    
+    gc.SetClippingRegion( clipReg );
+    AknsDrawUtils::Background( skin, cc, this, gc, backgroundRect, 
+            KAknsDrawParamNoClearUnderImage );
+    gc.CancelClippingRegion();
+    }
+
+TInt CAknMessageQueryControl::CurrentLink() const
+    {
+    if( 0 < iCurPos && iCurPos < iPositionsCount - 1 ) // The current position is on a link
+        {
+        return iCurPos - 1 + iFirstVisibleLink;
+        }
+    else    // No link is active
+        {
+        return -1;
+        }
+    }
+
+EXPORT_C TBool CAknMessageQueryControl::LinkHighLighted() const
+    {
+    return CurrentLink() > -1;
+    }
+
+void CAknMessageQueryControl::SetHighlightOnL( TBool aOn )
+    {
+    if( !LinkHighLighted() )
+        return;
+    iCharFormatMask.ClearAll();
+    if ( iEdwin && iEdwin->TextLength() > 0 &&
+        iLinkTextArray.Count() > 0 && iLinkTextArray[CurrentLink()]->Length() > 0 )
+        {
+        iCharFormatMask.SetAttrib( EAttFontHighlightStyle );
+        iCharFormatMask.SetAttrib( EAttFontHighlightColor );
+        if ( aOn )
+            {
+            iCharFormat.iFontPresentation.iHighlightStyle = TFontPresentation::EFontHighlightNormal;
+            
+            TRgb color = AKN_LAF_COLOR( 244 );
+            AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), color, KAknsIIDQsnHighlightColors, EAknsCIQsnHighlightColorsCG1 ); 
+            iCharFormat.iFontPresentation.iHighlightColor = color;
+            
+            color = AKN_LAF_COLOR( 210 );
+            AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), color, KAknsIIDQsnHighlightColors, EAknsCIQsnHighlightColorsCG3 );                    
+	        iCharFormat.iFontPresentation.iTextColor = color;           
+            }
+        else
+            {
+            iCharFormat.iFontPresentation.iHighlightStyle = TFontPresentation::EFontHighlightNone;
+            }
+
+        if ( iLinksCount > 0 )
+            {
+            iEdwin->RichText()->ApplyCharFormatL( iCharFormat, iCharFormatMask, ( iLinkTextLocationArray )[CurrentLink()], ( iLinkTextArray )[CurrentLink()]->Length() );
+            }
+
+        iEdwin->DrawNow();
+        }
+    }
+    
+TBool CAknMessageQueryControl::CanScrollPage( TBool aMoveDown )
+    {
+    if( iNumberOfLines <= iLinesPerPage )    // Only one page
+        return EFalse;
+    if( aMoveDown )
+        return iTopLine < iNumberOfLines - iLinesPerPage;
+    else
+        return iTopLine > 0;
+    }    
+
+TBool CAknMessageQueryControl::IsLinkVisible( TInt aIndex ) const
+    {
+    if ( aIndex >= iLinksCount )
+        {
+        return EFalse;
+        }
+    TInt linkLine( iEdwin->TextLayout()->GetLineNumber( iLinkTextLocationArray[aIndex] ) );
+    if ( iTopLine <= linkLine && linkLine < iTopLine + iLinesPerPage )
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+void CAknMessageQueryControl::UpdatePageInfo()
+    {
+    TBool firstFound( EFalse );
+    iVisibleLinksCount = 0;
+    iFirstVisibleLink = -1;
+    
+    // Update visible links
+    for( TInt count = 0; count < iLinksCount; count++ )
+        {
+        if( IsLinkVisible( count ) )
+            {
+            iVisibleLinksCount++;
+            if( !firstFound )
+                {
+                iFirstVisibleLink = count;
+                firstFound = ETrue;
+                }
+            }
+        else if( firstFound )   // All visible links have been already found
+            {
+            break;
+            }
+        }
+    
+    // Update number of cursor positions
+    if( iVisibleLinksCount > 0 )
+        {
+        iPositionsCount = iVisibleLinksCount + 2;
+        }
+    else
+        {
+        iPositionsCount = 1;
+        }
+    }
+    
+void CAknMessageQueryControl::SetListQLayout(TBool aListQLayout)
+    {
+    iListQLayout = aListQLayout;
+    }
+
+    
+void CAknMessageQueryControl::SetMessageTextWithFormattingL( TDesC* aMessage, RArray<TDesC*>* aFormatTextArray, RArray<TInt>* aFormatTextLocationArray, RArray<TMsgQueryTag>* aFormatTypeArray )
+    {
+    if( iListQLayout )
+        User::Leave( KErrNotSupported );  // Links in the list query layout are not supported
+    CreateEditorL();
+    iEdwin->TextLayout()->SetAmountToFormat( CTextLayout::EFFormatAllText );
+    if ( aMessage->Length() > iEdwin->UpperFullFormattingLength() )
+        iEdwin->SetUpperFullFormattingLength( aMessage->Length() ); 
+    iEdwin->RichText()->DeleteL( 0, iEdwin->RichText()->DocumentLength() );
+    iEdwin->RichText()->InsertL ( 0, *aMessage );
+                
+    // Initialize link data
+    for ( TInt count = 0; count < aFormatTypeArray->Count(); count++ )
+        {
+        if ( (*aFormatTypeArray)[count] == EMsgQueryLink )
+            {
+            // Add the link location and text keeping the arrays sorted on the location
+            TInt location = (*aFormatTextLocationArray)[count];
+            iLinkTextLocationArray.InsertInOrder( location );
+            TInt index = iLinkTextLocationArray.FindInOrder( location );
+            iLinkTextArray.Insert( (*aFormatTextArray)[count], index );
+            }
+        }
+    iLinksCount = iLinkTextLocationArray.Count();
+
+    iCharFormatMask.ClearAll();    
+    
+    // Set link font
+    if (aMessage->Length() > 0)
+        {
+        // Set font color and underlining
+       	for (TInt count = 0; count < iLinksCount; count++)
+	        {    
+	        if ((iLinkTextLocationArray )[count] != KErrNotFound)
+	            {
+	            iCharFormatMask.SetAttrib( EAttFontUnderline );
+	            iCharFormatMask.SetAttrib( EAttColor );
+	            iCharFormat.iFontPresentation.iUnderline = EUnderlineOn;
+	            
+	            TRgb color = AKN_LAF_COLOR( 210 );
+                AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), color, KAknsIIDQsnHighlightColors, EAknsCIQsnHighlightColorsCG3 );
+                    
+	            iCharFormat.iFontPresentation.iTextColor = color;
+	            
+	            iEdwin->RichText()->ApplyCharFormatL(iCharFormat, iCharFormatMask, (iLinkTextLocationArray)[count], ((iLinkTextArray )[count])->Length());
+	            }            
+	        }     
+        
+        iCharFormatMask.ClearAll();
+        
+        // Set font boldness
+        for ( TInt count = 0; count < aFormatTextLocationArray->Count(); count++ )
+	        {    
+	        if ((*aFormatTextLocationArray)[count] != KErrNotFound && (*aFormatTypeArray)[count] == EMsgQueryBold)
+	            {
+	            iCharFormatMask.SetAttrib( EAttFontStrokeWeight );
+	            iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
+	            iEdwin->RichText()->ApplyCharFormatL( iCharFormat, iCharFormatMask, (*aFormatTextLocationArray)[count], (*aFormatTextArray )[count]->Length() );
+	            }
+	        }
+	    }
+        
+    LayoutEditorL();
+    
+    if ( aMessage->Locate( '\n' ) != KErrNotFound )
+        {
+        iEdwin->SetCursorPosL( 1, EFalse );
+        SEdwinFindModel findModel;
+        _LIT( KNChar,"\n" ); 
+        _LIT( KFChar,"\f" );
+        TBuf<1> text( KNChar );
+        TBuf<1> replaceText( KFChar );
+        findModel.iFlags = 0;
+        findModel.iText = text;
+        findModel.iReplaceText = replaceText;
+        findModel.iReplaceOption = EReplaceAll;
+        iEdwin->ReplaceAllL( &findModel );
+        }
+        
+    iNumberOfLines = iEdwin->TextLayout()->NumFormattedLines();
+    iTopLine = 0;
+    iCurPos = 0;   // Page top, no link selected
+    
+    UpdatePageInfo();
+    UpdateScrollIndicatorL();
+    }
+
+
+/**
+ * CAknMessageQueryControl::HandlePointerEventL()
+ *
+ * Transfers pointerevent to editor control.
+ * Checks for the object destruction after the pointer event handling.
+ */
+void CAknMessageQueryControl::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+    {
+    TBool highlightBefore = LinkHighLighted();
+    /**
+    * The local @c destroyed variable keeps track of the object destroyed state.
+    */
+    TBool destroyed = EFalse;
+    
+    iExtension->iDestroyedPtr = &destroyed;
+
+    // Call default implementation of HandlePointerEventL to transfer event to correct control.
+    CAknControl::HandlePointerEventL( aPointerEvent );
+
+    if ( !destroyed )
+        {
+        iExtension->iDestroyedPtr = NULL;
+        }
+    else
+        {
+        return;
+        }
+    
+    TBool highlightAfter = LinkHighLighted();
+    if( aPointerEvent.iType == TPointerEvent::EButton1Down && 
+        highlightBefore == highlightAfter && highlightAfter )
+        {
+        DehighlightLink();
+        }
+    }
+
+//----------------------------------------------------------------------------------
+// CAknMessageQueryControl::LinkTapped()
+// Checks if a link is tapped and hightlights it. 
+//----------------------------------------------------------------------------------
+//
+
+TBool CAknMessageQueryControl::LinkTappedL( TInt aPos )
+    {
+    if ( iLinksCount <= 0 )
+        {
+        return EFalse; 
+        }
+    /** There can be 3 possible results.
+    1. The link is found and it's a new link.
+    2. The link is found, but it's the current link.
+    3. The link was not found at the tapped position. 
+    */
+    TInt oldLink = CurrentLink();
+    TInt linkPos = 0; 
+    for ( TInt count = 0; count < iLinksCount; count++ )
+        {
+        linkPos = iLinkTextLocationArray[count];
+        if ( linkPos <= aPos && aPos < linkPos + iLinkTextArray[count]->Length() ) // The tapped link found
+            {
+            if ( oldLink != count ) // A new link
+                {
+                TInt editorTopLine = iEdwin->TextLayout()->FirstLineInBand();
+                if( iTopLine != editorTopLine ) // User scrolled with the pen
+                    {
+                    // Synchronize query's top line with editor's one
+                    iTopLine = editorTopLine;
+                    UpdatePageInfo();
+                    }
+                SetCurPosL( count - iFirstVisibleLink + 1 ); 
+                }
+            return ETrue; 
+            }
+        }
+    DehighlightLink();
+    return EFalse; 
+    }
+
+
+TBool CAknMessageQueryControl::SetCurPosL( TInt aCurPos )
+    {
+    if( aCurPos < 0 || aCurPos >= iPositionsCount )
+        return EFalse;
+    SetHighlightOnL( EFalse );  // Dehighlight the old link
+    iCurPos = aCurPos;
+    SetHighlightOnL( ETrue );     // Highlight the new link
+    return ETrue;
+    }
+    
+void CAknMessageQueryControl::DehighlightLink()
+    {
+    if ( !LinkHighLighted() )
+        {
+        return; 
+        }
+    TRAP_IGNORE( SetHighlightOnL( EFalse ) );  // Dehighlight the old link
+    iCurPos = 0;    // Move the cursor to the top of the page
+    // Update the softkey labels (set them to "Ok - Cancel")
+    CAknMessageQueryDialog* dlg;
+    MopGetObject( dlg );
+    if ( dlg )
+        {
+        dlg->UpdateSoftkeyLabels();
+        }
+    }
+
+TBool CAknMessageQueryControl::ScrollBarGrabbing()
+    {
+    CCoeControl* grabbingComponent = GrabbingComponent();
+
+    TBool grabbing = EFalse;
+    if (grabbingComponent)
+        {
+        grabbing = iSBFrame && iSBFrame->GetScrollBarHandle(
+            CEikScrollBar::EVertical) == grabbingComponent;
+        }
+    return grabbing;
+    }
+
+void CAknMessageQueryControl::TruncateTextForListQLayout( TDes& aMessage )
+    {
+    if( !iListQLayout )
+        return;
+
+    delete iFullMessage;
+    iFullMessage = NULL;
+    iFullMessage = aMessage.AllocL();
+    TInt maxLines = 3;  // Should be AknLayoutScalable_Apps::loc_type_pane_t1_ParamLimits().LastRow();
+    TInt lastLineBegin = iEdwin->TextLayout()->FirstCharOnLine( maxLines );       
+    TInt lastLineEnd = iEdwin->TextLayout()->FirstCharOnLine( maxLines + 1 );       
+    if( lastLineEnd < aMessage.Length() )
+        {
+        const CFont* font = AknLayoutUtils::FontFromId(
+            AknLayoutScalable_Avkon::popup_info_list_pane_t1( 0 ).Font() );
+        TInt ellipsisPosInLastLine = font->TextCount( aMessage.Mid( lastLineBegin, lastLineEnd - lastLineBegin ),
+            iEdwin->LayoutWidth() - font->CharWidthInPixels( KEllipsis ) ) - 1;
+        aMessage = aMessage.LeftTPtr( lastLineBegin + ellipsisPosInLastLine );
+        aMessage.Append( KEllipsis );
+        }
+    }
+
+void CAknMessageQueryControl::DoSizeChangedL()
+    {
+    if ( iListQLayout )
+        {
+        iLinesPerPage = 3;  // Should be AknLayoutScalable_Apps::loc_type_pane_t1_ParamLimits().LastRow();
+        HBufC* msgBuf = iFullMessage->AllocLC() ;
+        TPtr message( msgBuf->Des() );
+        iEdwin->SetTextL( &message );
+        LayoutEditorL(); 
+        TruncateTextForListQLayout( message );
+        iEdwin->SetTextL( &message );
+        CleanupStack::PopAndDestroy( msgBuf );  // After all usages of message        
+        iNumberOfLines = iEdwin->TextLayout()->NumFormattedLines();
+        }
+    else
+        {
+        iLinesPerPage = AknLayoutScalable_Avkon::popup_info_list_pane_t1_ParamLimits().LastRow() + 1;    
+        }    
+    
+    TInt lines = iNumberOfLines > iLinesPerPage ? iLinesPerPage : iNumberOfLines;
+    if (lines <= 0)
+        {
+        return;
+        }
+
+    RArray<TAknTextComponentLayout> textComponentLayoutArray;
+    for ( TInt rowIndex = 0; rowIndex < lines; rowIndex++)
+        {
+        TRAPD(error, textComponentLayoutArray.AppendL(AknLayoutScalable_Avkon::popup_info_list_pane_t1(rowIndex)));
+        if (error != KErrNone)
+            {
+            if (rowIndex == 0)
+                {
+                // Give up! textComponentLayoutArray does not contain any items.
+                textComponentLayoutArray.Close();
+                return; // Layout will fail...
+                }
+            }
+        }
+
+    TAknLayoutRect listScrollPopupInfoPane;
+    listScrollPopupInfoPane.LayoutRect( LayoutRect(), AknLayoutScalable_Avkon::listscroll_popup_info_pane() );
+    TRect listScrollPopupInfoPaneRect( listScrollPopupInfoPane.Rect() );
+    CAknPopupHeadingPane* heading = NULL;
+    if( iListQLayout )
+    	{
+    	CAknListQueryDialog* dlg;
+    	MopGetObject( dlg );
+    	if( dlg )
+    		{
+    		heading = dlg->QueryHeading();
+    		}    	
+    	}
+    else
+    	{
+    	CEikDialog* dlg;
+        MopGetObject( dlg );
+        if( dlg )
+        	{
+        	heading = (CAknPopupHeadingPane*)dlg->ControlOrNull(EAknMessageQueryHeaderId); 
+        	}        
+    	}
+    if( heading && heading->PromptText() == KNullDesC )
+        {
+        TAknLayoutRect headingPaneLayout;
+        headingPaneLayout.LayoutRect( LayoutRect(), AknLayoutScalable_Avkon::heading_pane_cp5() );
+        listScrollPopupInfoPaneRect.Move( 0, -1 * headingPaneLayout.Rect().Height() );
+        }
+    TAknLayoutRect listPopupInfoPane;    
+    listPopupInfoPane.LayoutRect( listScrollPopupInfoPaneRect, AknLayoutScalable_Avkon::list_popup_info_pane( 0 ) );  // Variety with scroll bar    
+    
+    
+    /** The edwin rect is set totally from layout list_popup_info_pane. But
+      * AknLayoutUtils::LayoutEdwin() is still used for setting its text color and font. 
+     **/ 
+    TAknMultiLineTextLayout multilineLayout = TAknTextComponentLayout::Multiline(textComponentLayoutArray);
+    AknLayoutUtils::LayoutEdwin( iEdwin, listPopupInfoPane.Rect(),
+        multilineLayout, EAknsCIQsnTextColorsCG19 );
+    //iEdwin->SetRect( listPopupInfoPane.Rect() );
+    textComponentLayoutArray.Close();
+    
+    iEdwin->SetBorder( TGulBorder::ENone );
+    iEdwin->SetFocus( EFalse );
+    AknsUtils::RegisterControlPosition( iEdwin );
+    
+    iNumberOfLines = iEdwin->TextLayout()->NumFormattedLines();
+    
+    UpdateScrollIndicatorL();
+    }
+//  End of File