diff -r 000000000000 -r 2f259fa3e83a uifw/AvKon/src/aknmessagequerycontrol.cpp --- /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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include "aknconsts.h" + +#include + +#include +#include "aknappui.h" + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include // 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 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* aFormatTextArray, RArray* aFormatTextLocationArray, RArray* 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 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