--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/msgeditor/viewsrc/MsgBodyControlEditor.cpp Wed Nov 03 09:52:46 2010 +0530
@@ -0,0 +1,772 @@
+/*
+* Copyright (c) 2002 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: MsgBodyControlEditor implementation
+*
+*/
+
+
+
+// ========== INCLUDE FILES ================================
+
+#include <eikenv.h> // for CEikonEnv
+#include <txtrich.h> // for CRichText
+#include <baclipb.h> // for CClipboard
+#include <AknUtils.h> // for AknUtils
+#include <ItemFinder.h> // for automatic highlight
+
+#include <applayout.cdl.h> // LAF
+#include <aknlayoutscalable_apps.cdl.h>
+
+#ifdef RD_TACTILE_FEEDBACK
+#include <touchfeedback.h>
+#endif
+
+#include "MsgEditorCommon.h" //
+#include "MsgBodyControlEditor.h" // for CMsgBodyControlEditor
+#include "MsgBaseControl.h" // for TMsgEditPermissionFlags
+#include "MsgBaseControlObserver.h" // for MMsgBaseControlObserver
+#include "MsgEditorCustomDraw.h" // for CMsgEditorCustomDraw
+#include "MsgEditor.hrh"
+#include <MmsViewer.rsg> // resouce identifiers
+
+// ========== EXTERNAL DATA STRUCTURES =====================
+
+// ========== EXTERNAL FUNCTION PROTOTYPES =================
+
+// ========== CONSTANTS ====================================
+
+// ========== MACROS =======================================
+
+// ========== LOCAL CONSTANTS AND MACROS ===================
+
+const TInt KBodyFullFormattingLength = 500;
+
+// ========== MODULE DATA STRUCTURES =======================
+
+// ========== LOCAL FUNCTION PROTOTYPES ====================
+
+// ========== LOCAL FUNCTIONS ==============================
+
+// ========== MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::CMsgBodyControlEditor
+//
+// Constructor.
+// ---------------------------------------------------------
+//
+CMsgBodyControlEditor::CMsgBodyControlEditor( const CCoeControl* aParent,
+ TUint32& aFlags,
+ MMsgBaseControlObserver* aBaseControlObserver ) :
+ CMsgExpandableControlEditor( aParent, aFlags, aBaseControlObserver ),
+ iPreviousItemStart( -1 ),
+ iPreviousItemLength( -1 )
+ {
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::~CMsgBodyControlEditor
+//
+// Destructor.
+// ---------------------------------------------------------
+//
+CMsgBodyControlEditor::~CMsgBodyControlEditor()
+ {
+ if (iItemFinder)
+ {
+ TRAP_IGNORE(iItemFinder->SetItemFinderObserverL( NULL ));
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::ConstructL
+//
+//
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::ConstructL()
+ {
+ TInt edwinFlags = ENoHorizScrolling |
+ ENoAutoSelection |
+ EWidthInPixels |
+ EAllowUndo |
+ EResizable |
+ EPasteAsPlainText;
+
+ iFlags |= EMsgControlModeDoNotDrawFrameBgContext;
+ ResolveLayouts();
+
+ /*if ( iBaseControlObserver &&
+ !iBaseControlObserver->ViewInitialized() )
+ {
+ SetSuppressFormatting( ETrue );
+ }*/
+
+ iItemFinder = CItemFinder::NewL( CItemFinder::EUrlAddress |
+ CItemFinder::EEmailAddress |
+ CItemFinder::EPhoneNumber |
+ CItemFinder::EUriScheme );
+
+ iItemFinder->AddObserver( *this );
+
+ iFocusChangedBeforeParseFinish = EFalse;
+
+ CEikRichTextEditor::ConstructL( iParentControl, 0, iMaxNumberOfChars, edwinFlags );
+ // 107-24185 : Emoticon support for SMS and MMS
+ AddFlagToUserFlags(EAvkonEnableSmileySupport);
+
+ // Both global text editor and edwin have it's own formatting layers.
+ // CEikRichTextEditor::ConstructL call will set global formatting layers
+ // into use for text. This is not correct as edwin formatting layers
+ // will hold correct formatting values. Below calls will set edwin
+ // formatting layers into use and prevent client based formatting from
+ // being based on incorrect formatting layer.
+ SetParaFormatLayer( iEikonEnv->SystemParaFormatLayerL()->CloneL() );
+ SetCharFormatLayer( iEikonEnv->SystemCharFormatLayerL()->CloneL() );
+
+ SetUpperFullFormattingLength( KBodyFullFormattingLength );
+
+ SetMaximumHeight( MsgEditorCommons::MaxBodyHeight() );
+
+ // Set the wrap width to be that of the current body text pane.
+ // This will make the formatting of text safer if it is performed
+ // before the editor has ever had SetSize() called. WrapWidth is
+ // usually set in HandleSizeChanged()
+ if ( iLayout )
+ {
+ iLayout->SetWrapWidth( iTextLayout.TextRect().Width() );
+ }
+
+ TRect dataPane = MsgEditorCommons::MsgDataPane();
+
+ TMargins8 edwinMargins;
+ edwinMargins.iTop = 0;
+ edwinMargins.iBottom = 0;
+ edwinMargins.iLeft = (TInt8)( iTextLayout.TextRect().iTl.iX - dataPane.iTl.iX );
+ edwinMargins.iRight = (TInt8)( dataPane.iBr.iX - iTextLayout.TextRect().iBr.iX );
+ SetBorderViewMargins( edwinMargins );
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::SetAndGetSizeL
+//
+// Calculates and sets the size of the control and returns new size as
+// reference aSize.
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::SetAndGetSizeL( TSize& aSize )
+ {
+ // This may change the heigh if the content has changed
+ SetSize( aSize );
+ aSize = iSize;
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::InsertCharacterL
+//
+// Inserts a character to the editor.
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::InsertCharacterL( const TChar& aCharacter )
+ {
+
+ // 107-24185 : Emoticon support for SMS and MMS
+
+ TBuf<1> text;
+ text.Append( aCharacter );
+ InsertTextL( text );
+
+ //UpdateScrollBarsL();
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::InsertTextL
+//
+// Inserts text to the editor.
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::InsertTextL( const TDesC& aText )
+ {
+ if ( iTextView )
+ {
+ TCursorSelection selection = iTextView->Selection();
+ const TInt selLength = selection.Length();
+ const TInt lower = selection.LowerPos();
+
+ if ( selLength )
+ {
+ // 107-24185 : Emoticon support for SMS and MMS, symbian call
+ InsertDeleteCharsL( lower, aText, selection );
+ }
+ else
+ {
+ InsertDeleteCharsL( selection.iCursorPos, aText, selection );
+ }
+
+ SetCursorPosL( lower + aText.Length(), EFalse );
+
+ NotifyNewFormatL();
+ }
+ else
+ {
+ iText->InsertL( 0, aText );
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::ActivateL
+//
+// This function is needed for overriding
+// CMsgExpandableControlEditor::ActivateL().
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::ActivateL()
+ {
+ if ( IsActivated() )
+ {
+ return;
+ }
+
+ CMsgExpandableControlEditor::ActivateL();
+
+ }
+
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::OfferKeyEventL
+//
+//
+// ---------------------------------------------------------
+//
+TKeyResponse CMsgBodyControlEditor::OfferKeyEventL(
+ const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ if ( IsReadOnly() )
+ {
+ switch ( aKeyEvent.iCode )
+ {
+ case EKeyDevice3:
+ {
+ if ( iFindItemEventReceived )
+ {
+ // Find item was activated by touch,
+ // no need to restore highlight
+ iFindItemEventReceived = EFalse;
+ return EKeyWasNotConsumed;
+ }
+ // fall through
+ }
+ case EKeyEnter:
+ {
+ // Restore highlight
+ const CItemFinder::CFindItemExt& item =
+ iItemFinder->CurrentItemExt();
+
+ if ( item.iItemType != CItemFinder::ENoneSelected )
+ {
+ SetSelectionL( item.iStart, item.iEnd + 1 );
+ }
+ else if ( iInitTop )
+ {
+ SetHighlightL( 0, EMsgFocusDown, ETrue );
+ }
+ else
+ {
+ SetHighlightL( TextLength(), EMsgFocusUp, ETrue );
+ }
+ return EKeyWasConsumed;
+ }
+ case EKeyUpArrow:
+ case EKeyDownArrow:
+ break;
+
+ default:
+ return CEikRichTextEditor::OfferKeyEventL( aKeyEvent, aType );
+ }
+
+ SetHighlightL( CursorPos(),
+ ( aKeyEvent.iCode == EKeyUpArrow )
+ ? EMsgFocusUp
+ : EMsgFocusDown );
+ return EKeyWasConsumed;
+ }
+ else
+ {
+ return CEikRichTextEditor::OfferKeyEventL( aKeyEvent, aType );
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::HandleFindItemEventL
+//
+// Handles finditem events.
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::HandleFindItemEventL(
+ const CItemFinder::CFindItemExt& aItem,
+ MAknItemFinderObserver::TEventFlag aEvent,
+ TUint aFlags)
+ {
+ // Body text find item was clicked, we will send simulated key event for
+ // opening context sensitive menu in AppUI::HandleKeyEvent
+ if ( MAknItemFinderObserver::EPointerEvent == aEvent )
+ {
+ TKeyEvent event;
+ event.iCode = EKeyDevice3;
+ event.iScanCode = EKeyDevice3;
+ event.iModifiers = 0;
+ event.iRepeats = 0;
+
+ iFindItemEventReceived = ETrue;
+ iCoeEnv->WsSession().SimulateKeyEvent( event );
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::HandlePointerEventL
+//
+// Handles pointer events.
+// ---------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CMsgBodyControlEditor::HandlePointerEventL( const TPointerEvent& aPointerEvent )
+ {
+ TBool forwardRequest( ETrue );
+
+ if ( IsActivated() &&
+ IsReadOnly() &&
+ ( aPointerEvent.iType == TPointerEvent::EButton1Down ||
+ aPointerEvent.iType == TPointerEvent::EButton1Up ) )
+ {
+ TPoint tapPoint( aPointerEvent.iPosition );
+ TInt docPos( TextView()->XyPosToDocPosL( tapPoint ) );
+
+ TInt start( 0 );
+ TInt length( 0 );
+ MParser* parser = iItemFinder;
+
+ TBool tappedOverTag( RichText()->CursorOverTag( docPos, parser, start, length ) );
+
+ if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
+ {
+ if ( !tappedOverTag )
+ {
+ // Reset current finditem
+ iItemFinder->ResetCurrentItem();
+ }
+ else
+ {
+ // Find item tapped, do not forward event
+ forwardRequest = EFalse;
+ }
+ }
+ }
+
+ if ( forwardRequest )
+ {
+ CMsgExpandableControlEditor::HandlePointerEventL( aPointerEvent );
+ }
+#ifdef RD_TACTILE_FEEDBACK
+ else if(aPointerEvent.iType == TPointerEvent::EButton1Down)
+ {
+ MTouchFeedback* feedback = MTouchFeedback::Instance();
+ if ( feedback )
+ {
+ feedback->InstantFeedback( this, ETouchFeedbackBasic );
+ }
+ }
+#endif // RD_TACTILE_FEEDBACK
+ }
+#else
+void CMsgBodyControlEditor::HandlePointerEventL( const TPointerEvent& /*aPointerEvent*/ )
+ {
+ }
+#endif // RD_SCALABLE_UI_V2
+
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::IsFocusChangePossibleL
+//
+//
+// ---------------------------------------------------------
+//
+TBool CMsgBodyControlEditor::IsFocusChangePossibleL(
+ TMsgFocusDirection aDirection )
+ {
+ CItemFinder::TFindDirection direction = aDirection == EMsgFocusUp
+ ? CItemFinder::ENextUp
+ : CItemFinder::ENextDown;
+
+ TInt cursorPos = CursorPos();
+ iItemFinder->ResolveAndSetItemTypeL( cursorPos );
+ TInt nextItem = iItemFinder->PositionOfNextItem( direction );
+ TPoint dummy;
+
+ if ( nextItem < KErrNone )
+ {
+ // Next item not found.
+ if ( aDirection == EMsgFocusUp )
+ {
+ return TextLayout()->FirstDocPosFullyInBand() == 0;
+ }
+ else
+ {
+ return TextLayout()->PosInBand( TextLength(),dummy );
+ }
+ }
+ else
+ {
+ // Next item found. -> Focus change not allowed.
+ return 0;
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::SetupAutomaticFindAfterFocusChangeL
+//
+//
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::SetupAutomaticFindAfterFocusChangeL( TBool aBeginning )
+ {
+ iInitTop = aBeginning;
+ if ( !iTextParsed )
+ {
+ iFocusChangedBeforeParseFinish = ETrue;
+ }
+ else
+ {
+ if ( aBeginning )
+ {
+ SetHighlightL( 0, EMsgFocusDown, ETrue );
+ }
+ else
+ {
+ SetHighlightL( TextLength(), EMsgFocusUp, ETrue );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::SetHighlightL
+//
+//
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::SetHighlightL(
+ TInt aCursorPos, TMsgFocusDirection aDirection,
+ TBool aInit /*= EFalse*/ )
+ {
+ // Use "link highlight"
+ SetHighlightStyleL( EEikEdwinHighlightLink );
+ TInt textLength = TextLength();
+
+ TCursorPosition::TMovementType movetype = aDirection == EMsgFocusUp
+ ? TCursorPosition::EFPageUp
+ : TCursorPosition::EFPageDown;
+
+ CItemFinder::TFindDirection direction = aDirection == EMsgFocusUp
+ ? CItemFinder::ENextUp
+ : CItemFinder::ENextDown;
+
+ TInt nextItem = KErrNotFound;
+ TPoint dummy;
+ if ( iTextParsed )
+ {
+ if ( aInit )
+ {
+ iItemFinder->NextItemOrScrollL( aCursorPos == 0
+ ? CItemFinder::EInitDown
+ : CItemFinder::EInitUp );
+ }
+ else
+ {
+ nextItem = iItemFinder->PositionOfNextItem( direction );
+ }
+ }
+
+ if ( nextItem > KErrNotFound )
+ {
+ if ( !aInit &&
+ !TextLayout()->PosInBand( nextItem ,dummy ) )
+ {
+ // first move one page and then set selection
+ SetCursorPosL( CursorPos(), EFalse );
+ iTextView->MoveCursorL( movetype, EFalse );
+ }
+
+ if ( TextLayout()->PosInBand( nextItem ,dummy ) )
+ {
+ // next item is visible, just change selection
+ iItemFinder->ResolveAndSetItemTypeL( nextItem );
+
+ TInt selectionLength = iItemFinder->CurrentItemExt().iEnd - iItemFinder->CurrentItemExt().iStart + 1;
+ TCursorSelection cursorSelection;
+ cursorSelection.iCursorPos = nextItem;
+ cursorSelection.iAnchorPos = nextItem + selectionLength;
+ if ( !TextLayout()->PosInBand( nextItem + selectionLength, dummy ) )
+ {
+ // Next item does not fit fully on the screen.
+ // Have to move page first.
+ SetCursorPosL( CursorPos(), EFalse );
+ iTextView->MoveCursorL( movetype, EFalse );
+ }
+
+ iTextView->SetSelectionL( cursorSelection );
+ }
+
+ }
+ else
+ {
+ if ( !aInit )
+ {
+ switch ( aDirection )
+ {
+ case EMsgFocusDown:
+ if ( !TextLayout()->PosInBand( textLength, dummy) )
+ {
+ iTextView->MoveCursorL( movetype, EFalse );
+
+ // Following is a bit tricky since MoveCursor looses
+ // selection so we have to set it again if previous
+ // selection still on the screen.
+ nextItem = iItemFinder->PositionOfNextItem(
+ CItemFinder::ENextUp );
+ if ( nextItem > KErrNotFound )
+ {
+ if ( TextLayout()->PosInBand( nextItem ,dummy ) )
+ {
+ // next item is visible, change selection
+ iItemFinder->ResolveAndSetItemTypeL( nextItem );
+
+ TInt selectionLength = iItemFinder->CurrentItemExt().iEnd - iItemFinder->CurrentItemExt().iStart + 1;
+ TCursorSelection cursorSelection;
+ cursorSelection.iCursorPos = nextItem;
+ cursorSelection.iAnchorPos = nextItem + selectionLength;
+ iTextView->SetSelectionL( cursorSelection );
+ }
+ else
+ {
+ nextItem = iItemFinder->PositionOfNextItem(
+ CItemFinder::ENextDown );
+ }
+ }
+ }
+ break;
+ default:
+ case EMsgFocusUp:
+ if ( !TextLayout()->PosInBand( 0,dummy ) )
+ {
+ iTextView->MoveCursorL( movetype, EFalse );
+ }
+ break;
+ };
+
+ }
+ }
+
+ }
+
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::CursorInLastLine
+//
+//
+// ---------------------------------------------------------
+//
+TBool CMsgBodyControlEditor::CursorInLastLine()
+ {
+ if (IsReadOnly())
+ {
+ TPoint dummy;
+ return ( iItemFinder->PositionOfNextItem( CItemFinder::ENextDown ) == KErrNotFound
+ && TextLayout()->PosInBand( TextLength(), dummy ) );
+
+ }
+ else
+ {
+ return CMsgExpandableControlEditor::CursorInLastLine();
+ }
+
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::HandleParsingComplete
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::HandleParsingComplete()
+ {
+ TRAP_IGNORE( DoHandleParsingCompleteL() );
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::DoHandleParsingCompleteL
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::DoHandleParsingCompleteL()
+ {
+ iTextParsed = ETrue;
+ // this needs to be changed so that bottom init can also be set
+ if ( iFocusChangedBeforeParseFinish )
+ {
+ iFocusChangedBeforeParseFinish = EFalse; // just to make sure this is done only once
+ if ( iInitTop )
+ {
+ SetHighlightL( 0, EMsgFocusDown, ETrue );
+ }
+ else
+ {
+ SetHighlightL( TextLength(), EMsgFocusUp, ETrue );
+ }
+
+ if ( iBaseControlObserver )
+ {
+ iBaseControlObserver->HandleBaseControlEventRequestL( NULL,
+ EMsgUpdateScrollbar );
+ }
+ }
+ else
+ {
+ // In some cases the text view is left to some
+ // strange state. Make sure the view is in sync
+ // with cursor position.
+ SetCursorPosL( CursorPos(), EFalse );
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::ResolveLayouts
+//
+//
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::ResolveLayouts()
+ {
+ TRect dataPane = MsgEditorCommons::MsgDataPane();
+
+ TAknLayoutRect msgTextPane;
+ msgTextPane.LayoutRect(
+ dataPane,
+ AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() );
+ TAknLayoutRect msgBodyPane;
+ msgBodyPane.LayoutRect(
+ msgTextPane.Rect(),
+ AknLayoutScalable_Apps::msg_body_pane().LayoutLine() );
+
+ if ( IsReadOnly() )
+ {
+ iTextLayout.LayoutText(
+ msgBodyPane.Rect(),
+ AknLayoutScalable_Apps::msg_body_pane_t1( 0 ).LayoutLine() );
+ }
+ else
+ {
+ iTextLayout.LayoutText(
+ msgBodyPane.Rect(),
+ AknLayoutScalable_Apps::msg_body_pane_t1( 1 ).LayoutLine() );
+ }
+
+
+ if ( MsgEditorCustomDraw() )
+ {
+ MsgEditorCustomDraw()->ResolveLayouts();
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::LayoutEdwin
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::LayoutEdwin()
+ {
+ TAknLayoutRect msgTextPane;
+ msgTextPane.LayoutRect( MsgEditorCommons::MsgDataPane(),
+ AknLayoutScalable_Apps::msg_text_pane( 0 ).LayoutLine() );
+
+ TAknLayoutRect msgBodyPane;
+ msgBodyPane.LayoutRect( msgTextPane.Rect(),
+ AknLayoutScalable_Apps::msg_body_pane().LayoutLine() );
+
+ TRect parentRect( msgBodyPane.Rect() );
+ parentRect.Move( 0, iParentControl->Position().iY );
+
+ DoLayoutEdwin( parentRect,
+ AknLayoutScalable_Apps::msg_body_pane_t1( 0 ).LayoutLine() );
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::PrepareFocusTransition
+//
+// Do not change focus when automatic find parsing has been finished
+// if focus transition out of this control has been performed.
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::PrepareFocusTransition()
+ {
+ if ( IsFocused() )
+ {
+ iFocusChangedBeforeParseFinish = EFalse;
+ }
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::SetTextSkinColorIdL
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::SetTextSkinColorIdL()
+ {
+ CEikEdwin::SetTextSkinColorIdL( EAknsCIQsnTextColorsCG6 );
+ }
+
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::HandleResourceChange
+//
+// Sets correct highlight extension.
+// ---------------------------------------------------------
+//
+void CMsgBodyControlEditor::HandleResourceChange( TInt aType )
+ {
+ CMsgExpandableControlEditor::HandleResourceChange( aType );
+
+ if ( aType == KAknsMessageSkinChange && MsgEditorCustomDraw() )
+ {
+ MsgEditorCustomDraw()->SkinChanged();;
+ }
+ }
+// ---------------------------------------------------------
+// CMsgBodyControlEditor::PrepareForReadOnlyL
+//
+// Sets SetItemFinderObserverL for viewers
+// ---------------------------------------------------------
+//
+
+void CMsgBodyControlEditor::PrepareForReadOnlyL( TBool aReadOnly )
+ {
+ if ( iItemFinder )
+ {
+ if ( aReadOnly )
+ {
+ iItemFinder->SetItemFinderObserverL( this );
+ }
+ else
+ {
+ iItemFinder->SetItemFinderObserverL( NULL );
+ }
+ }
+
+ CMsgExpandableControlEditor::PrepareForReadOnlyL( aReadOnly );
+ }
+
+
+// End of File