mobilemessaging/smsui/viewersrc/MsgSmsViewerAppUi.cpp
changeset 0 72b543305e3a
child 2 0bf1d54f37d9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/smsui/viewersrc/MsgSmsViewerAppUi.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,3065 @@
+/*
+* Copyright (c) 2002 - 2009 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:  
+*     Sms Viewer Application UI
+*
+*/
+
+
+
+// INCLUDE FILES
+
+// UIKON/AVKON
+#include <akntitle.h>                   // CAknTitlePane
+#include <eikmenub.h>                   // CEikMenuBar
+#include <aknnotewrappers.h>            // AknNoteWrappers
+#include <txtrich.h>                    // Rich text ed
+#include <aknnavide.h>              // CAknNavigationDecorator
+// messaging editors
+#include <MsgBodyControl.h>             // CMsgBodyControl
+#include <eikrted.h>                    // CEikRichTextEditor
+#include <MsgEditorView.h>              // CMsgEditorView
+#include <MsgAddressControl.h>          // CMsgAddressControl
+#include <msgbiobodycontrol.h>          // CMsgBioBodyControl
+#include <MsgBioUids.h>                 // smart message type uids
+#include <msgbiocontrol.h>              // CMsgBioControl
+#include <CGmsWrapper.h>                // CGmsWrapper
+#include <MsgNaviPaneControl.h>
+// messaging
+#include <smuthdr.h>                    // CSmsHeader
+#include <smsclnt.h>                    // CSmsClientMtm
+#include <MsgFolderSelectionDialog.h>   // CMsgFolderSelectionDialog
+#include <MuiuMsvProgressReporterOperation.h>  // CMsvProgressReporterOperation
+#include <MtmExtendedCapabilities.hrh>	// function id of MessageInfo
+#include <MuiuOperationWait.h>              // MuiuOperationWait
+#include <mtclreg.h>
+#include <mtuireg.h>
+#include <mtmdef.h>
+#include <akninputblock.h>				// CAknInputBlock
+#include <MuiuMsvUiServiceUtilities.h>  // DiskSpaceBelowCriticalLevelL
+#include <muiumsvuiserviceutilitiesinternal.h>
+#include <messagingvariant.hrh>         // Local variation flags
+#include <smumutil.h>                   // SmumUtil
+#include <csmsemailfields.h>            // CSmsEmailFields
+#include <msgtextutils.h>
+// phone
+#include <commonphoneparser.h>          // Common phone number validity checker
+// resources
+#include <SmsViewer.rsg>                // resouce identifiers
+#include <msgeditor.mbg>                // bitmaps
+// local
+#include "MsgSmsViewer.hrh"             // application specific commands
+#include "MsgSmsViewerDoc.h"            // CMsgSmsViewerDocument
+#include "MsgSmsViewerAppUi.h"          // CMsgSmsViewerAppUi
+// Find item
+#include <FindItemmenu.rsg>             // find item resources
+#include <finditemmenu.h>               // CFindItemMenu
+#include <finditemdialog.h>             // CFindItemDialog
+#include <finditem.hrh>
+#include <ItemFinder.h>
+// Creating contact card via AIW
+#include <AiwServiceHandler.h>          // CAiwServiceHandler
+#include <AiwContactAssignDataTypes.h>  // AiwContactAssign
+// general
+#include <StringLoader.h>               // StringLoader
+#include <featmgr.h>                    // FeatureManager
+#include <SenduiMtmUids.h>
+#include <sendui.h>
+#include <CMessageData.h>               // for SendUi
+#include <data_caging_path_literals.hrh>
+#include <AknIconUtils.h>
+#include <centralrepository.h>
+#include <messaginginternalcrkeys.h>
+#include <CommonUiInternalCRKeys.h>
+#include <coreapplicationuisdomainpskeys.h>
+
+
+// help
+#include <csxhelp/sms.hlp.hrh>          // sms help context ids 
+#include <csxhelp/smart.hlp.hrh>
+#include <hlplch.h>                     // for HlpLauncher 
+
+#include <msgvoipextension.h>
+
+#include <MsgEditorAppUiExtension.h>// for iMsgEditorAppUiExtension
+#include <MsgEditorSettingCacheUpdatePlugin.h>
+
+//Skinnable Title pane icon
+#include <AknStatuspaneUtils.h>     // AknStatuspaneUtils
+#include <aknlayoutscalable_apps.cdl.h>
+#include <aknlayoutscalable_avkon.cdl.h>
+#include <AknsUtils.h>
+#include <muiu.mbg>           // title icon
+#ifdef RD_MSG_FAST_PREV_NEXT
+#include <MuiuMessageIterator.h>
+#endif
+
+#ifdef RD_SCALABLE_UI_V2
+#include <aknnavide.h>              // pen support on navi pane
+#include <AknNaviObserver.h>        // pen support of volume control of navi pane
+#include <akntoolbar.h>     
+#include <eikcolib.h>		//Added for touchbar support
+#endif
+#include <aknclearer.h>     // CAknLocalScreenClearer
+// CONSTANTS
+
+// Sms Viewer Uid 
+const TUid KUidSmsViewer ={0x100058BD};
+// GMS Viewer Uid
+const TUid KUidGMSViewer ={0x101F4CDA};
+// Sms Mtm Service Uid
+const TUid KUidSmsMtm = {0x1000102c};
+// First free id
+const TInt EMsgImageControlId = EMsgComponentIdFirstFreeEditorSpecificId;
+
+// Size approxamations
+// TMsvEntry itself
+const TInt KApproxEmptyTMsvEntrySize = 200; // atleast when SC included to entry (Outbox)
+// Recipients
+const TInt KApproxRecipientSize = 80; // manually entered ~50 & fetched ~70
+// GMS msg with full 120 chars and whole picture (no recipients)
+const TInt KApproxFullGMS = 450; // full of text and whole picture
+
+_LIT( KSmsBitmapFileName, "muiu.mif" );
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+CMsgSmsViewerAppUi::CMsgSmsViewerAppUi()
+    {
+    // Put constructor code into function InitMembers() as it's
+    // also called to prepare the viewer to show a new message.
+    InitMembers();
+    }
+
+// Initialize data members into a default state. Called from a constructor
+// and when a sms is loaded into a viewer to replace a current one.
+void CMsgSmsViewerAppUi::InitMembers()
+    {
+    // Initialize variables that cannot be zeroed or are initialized to a
+    // non-zero value.
+
+    // iFullyConstructed is only initialized in construction
+    
+    iNumber.Zero();
+    iRecipientstring.Zero();
+
+    // Initialize flags
+    Mem::FillZ( &iFlags, sizeof(iFlags) );
+
+    iControlId = 0;
+    iClass0CBA = NULL;
+    iFindItemMenu = NULL;
+    iAiwServiceHandler = NULL;
+    iGmsModel = NULL;
+    iSmsHeader = NULL;
+    iViewerOperation = NULL;
+    iMsgVoIPExtension  = NULL;
+    iSendUi = NULL;
+    iCenRepSession = NULL;
+    iNotifier = NULL;
+    }
+
+// Symbian OS default constructor can leave.
+void CMsgSmsViewerAppUi::ConstructL()
+    {
+    CMsgEditorAppUi::ConstructL();
+
+    ConstructMembersL();
+
+	if( !iEikonEnv->StartedAsServerApp( ) )
+        { // If the app was not started as server app, we can call PrepareLaunchL
+        Document()->PrepareToLaunchL( this );
+        }        
+    }   
+
+// ConstructL() without calling base class construct
+void CMsgSmsViewerAppUi::ConstructMembersL()
+    {
+    // Prepare FeatureManager, read values to members and uninitialize FeatureManager
+    FeatureManager::InitializeLibL();
+    if ( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+        {
+        iFlags.iHelpFeatureSupported = ETrue;
+        }
+    // SMSGms variation flags
+    if ( FeatureManager::FeatureSupported( KFeatureIdSmartmsgSMSGmsMessageReceiving ) )
+        {
+        iFlags.iSmartMsgSmsGmsMessageReceiving = ETrue;
+        }
+    if ( FeatureManager::FeatureSupported( KFeatureIdSmartmsgSMSGmsMessageSendingSupported ) )
+        {
+        iFlags.iSmartMsgSmsGmsMessageSending = ETrue;
+        }
+    if ( FeatureManager::FeatureSupported( KFeatureIdAudioMessaging ) )
+        {
+        iFlags.iAudioMsgSupported = ETrue;
+        }
+    FeatureManager::UnInitializeLib();
+    
+    //check unieditor restricted reply mode
+    TInt features = 0;
+    CRepository* repository = CRepository::NewLC( KCRUidMuiuVariation );   
+    repository->Get( KMuiuUniEditorFeatures, features );
+    CleanupStack::PopAndDestroy( repository );
+    iFlags.iSmsRestrictedMode = ( features & KUniEditorFeatureIdRestrictedReplySms );
+		repository = NULL;
+	
+	//check autolock mode
+    TInt value( KErrNotFound ); 
+    RProperty::Get( KPSUidCoreApplicationUIs, KCoreAppUIsAutolockStatus, value );
+    if ( value > EAutolockOff )
+        {
+        iFlags.iAutoLockEnabled = ETrue;
+        }
+    iMsgVoIPExtension = CMsgVoIPExtension::NewL();
+
+    // Local variation flags
+    if ( SmumUtil::CheckEmailOverSmsSupportL() )
+        { // Email supported
+        iFlags.iEmailFeatureSupported = ETrue;
+        }
+    //Middle softkey
+    MenuBar()->SetContextMenuTitleResourceId( R_SMSV_CONTEXTMENUBAR );        
+  	// Set path of bitmap file
+  	TParse fileParse;
+  	fileParse.Set( KSmsBitmapFileName, &KDC_APP_BITMAP_DIR, NULL );
+    
+  	
+    iAppIcon = AknsUtils::CreateGulIconL( 
+        AknsUtils::SkinInstance(), 
+        KAknsIIDQgnPropMceSmsTitle,
+        fileParse.FullName(),
+        EMbmMuiuQgn_prop_mce_sms_title,
+        EMbmMuiuQgn_prop_mce_sms_title_mask );
+        
+            
+	iScreenClearer = CAknLocalScreenClearer::NewLC( EFalse );
+	CleanupStack::Pop( iScreenClearer );    
+    iTypeMsg = CSmsPDU::ESmsDeliver; //for successful launch save the PDU Type.
+
+
+    
+    }
+
+// Destructor
+CMsgSmsViewerAppUi::~CMsgSmsViewerAppUi()
+    {
+    // Put destructor code into function DestructMembers() as it's
+    // also called to prepare the viewer to show a new message.
+    DestructMembers();
+    }
+
+// Destruct data members. Called from a destructor and when a sms
+// is loaded into a viewer to replace a current one.
+void CMsgSmsViewerAppUi::DestructMembers()
+    {
+    // If operation is still active we must cancel it before exit
+    if ( iViewerOperation ) 
+        {
+        iViewerOperation->Cancel();
+        }
+    delete iViewerOperation;
+    iViewerOperation = NULL;
+    delete iFindItemMenu;
+    iFindItemMenu = NULL;
+    delete iSendUi;
+    iSendUi = NULL;    
+    delete iAiwServiceHandler;
+    iAiwServiceHandler = NULL;    
+    delete iGmsModel;
+    iGmsModel = NULL;
+    delete iSmsHeader;
+    iSmsHeader = NULL;
+
+    if( iNotifier )
+        {
+        iNotifier->StopListening();
+        delete iNotifier;
+        iNotifier = NULL;
+        }
+    delete iCenRepSession; // don't delete before notifier
+    iCenRepSession = NULL;
+    delete iMsgVoIPExtension;
+    iMsgVoIPExtension = NULL;
+    // AppUi doesn't own iClass0CBA, so it's deleted elsewhere 
+	#ifdef RD_SCALABLE_UI_V2
+	if(iToolbar)
+		{
+    	delete iToolbar;
+    	iToolbar = NULL;
+    	static_cast<CEikAppUiFactory*>( 
+                CEikonEnv::Static()->AppUiFactory() )->SetViewFixedToolbar( NULL );
+  		}
+	#endif	
+    delete iAppIcon;
+    iAppIcon = NULL;
+    delete iScreenClearer;
+    iScreenClearer = NULL;
+    }
+
+#ifdef RD_MSG_FAST_PREV_NEXT
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::EntryChangedL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::EntryChangedL()
+    {
+    // First call to EntryChangedL() comes before LaunchViewL() has been called by
+    // document.
+    if ( !iFullyConstructed )
+        return;
+
+    if( iMsgNaviDirection == KErrNotFound )
+        {
+        // Clear and redraw all controls
+        iView->ResetControls();
+        iView->DrawNow();
+        
+        DestructMembers();
+        InitMembers();
+        delete iView; iView = NULL;
+        ConstructMembersL();
+        LaunchViewL();
+        }
+    else
+        {
+        QuicklaunchViewL();
+        }
+    
+    // Note: In smum (sms mtm UI), file smsu.cpp. Message is marked as read in
+    // sim in case it's class 2 sms stored in sim. It is referenced as a fix to
+    // an error SPAN-6B7K33. That piece of code could be executed here but is
+    // left out because all sim messages are shown as read by default in sim folder
+    // anyways.
+    }
+#endif // RD_MSG_FAST_PREV_NEXT
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::Document
+// (other items were commented in a header).
+// ---------------------------------------------------------
+CMsgSmsViewerDocument* CMsgSmsViewerAppUi::Document() const
+    {
+    return STATIC_CAST( CMsgSmsViewerDocument*, CMsgEditorAppUi::Document());
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::LaunchViewL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::LaunchViewL()
+    {
+    CAknInputBlock::NewLC();
+    // get hands on entry
+    TMsvEntry msvEntry1;
+    
+    TRAPD( error, msvEntry1 = Document()->Entry() );
+    
+    if( error != KErrNone )
+        {
+        //Something wrong. Exit here
+        DoMsgSaveExitL();
+        return;
+        }
+    
+#ifdef RD_SCALABLE_UI_V2
+    if ((!iToolbar)&& (AknLayoutUtils::PenEnabled() && !msvEntry1.iBioType && !iFlags.iGms) )
+    	{
+    	CEikAppUiFactory* appUiFactory = static_cast<CEikAppUiFactory*>( iEikonEnv->AppUiFactory() );
+        CAknToolbar* oldFixedToolbar = appUiFactory->CurrentFixedToolbar();
+
+        	iToolbar = CAknToolbar::NewL( R_SMSVIEWER_APP_TOOLBAR );
+        	iToolbar->SetToolbarObserver( this );
+        
+
+        if ( oldFixedToolbar != iToolbar )
+            {
+            oldFixedToolbar->SetToolbarVisibility( EFalse );    
+            }
+        
+        appUiFactory->SetViewFixedToolbar( iToolbar );    	
+        iToolbar->SetToolbarVisibility( ETrue, EFalse ); 
+	    }
+	    
+	//handling the case of iToolbar already created [delete the toolbar incase of biomsgs]
+	else if((iToolbar)&&(AknLayoutUtils::PenEnabled() && msvEntry1.iBioType && iFlags.iGms)) 
+		{
+		    delete iToolbar;
+    		iToolbar = NULL;
+		}
+	
+#endif	
+    // Creating view (exits app immediately if fails)
+    iView = CMsgEditorView::NewL( *this, CMsgEditorView::EMsgReadOnly );
+    // get hands on entry
+    const CMsgSmsViewerDocument* doc = Document();
+    TMsvEntry msvEntry = doc->Entry();
+    
+    // Getting sender/receiver to From/To-field
+    // (just copies the content of iDetails to To/From-field,
+    // should work also with IR-messages...)
+    
+    //Copy only 50 chars with extremely long names
+    iRecipientstring = msvEntry.iDetails.Left( KPhCltNameBufferLength );  
+
+    __ASSERT_DEBUG(msvEntry.Id() != 
+         KMsvNullIndexEntryId, Panic( EMsgSmsNoMessage ));
+
+    iFlags.iGms = (msvEntry.iBioType == KMsgBioUidPictureMsg.iUid);
+
+    // Instead of using Sms Mtm load the entry's values
+    // using store. This is because Sms Viewer is also used
+    // by bio messages and then sms mtm can't be used...
+    CPlainText* nullString = CPlainText::NewL();
+    CleanupStack::PushL( nullString );
+    iSmsHeader = CSmsHeader::NewL( CSmsPDU::ESmsDeliver, *nullString );
+    CMsvStore* store = doc->CurrentEntry().ReadStoreL();
+    CleanupStack::PushL(store);
+  
+    // This TRAPping is needed to find out if the entry's store has
+    // KUidMsvSMSHeaderStream. If it hasn't, we're most propably dealing
+    // with non sms message and we can assume it is received message.
+    TRAPD( err, iSmsHeader->RestoreL( *store ));
+
+    // Check if we are dealing with E-mail sms message
+    // We use TP-PID as the only validation rule
+    CSmsPDU& pdu = iSmsHeader->Message().SmsPDU();
+	if( pdu.ProtocolIdentifierPresent() )
+		{
+		if(	pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking &&
+			pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice &&
+			pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail )
+			{
+			iFlags.iIsEmailMessage = ETrue;
+			}
+		}
+
+    if (err == KErrNone)
+        {// Yes, it is sms based message
+
+        // Original longish LaunchViewL-function is splitted to 3 parts;
+        // LaunchViewL, SmsBasedMsgHandlingL & LaunchBioViewL
+        SmsBasedMsgHandlingL( msvEntry.iBioType, store );
+        }
+    else
+        {// No, this is not a sms and sms pdu can't be checked. However
+        // this is most propably _received_ IR or BT message.
+        iFlags.iIrBt = ETrue;
+        iControlId = EMsgComponentIdFrom;
+        iView->AddControlFromResourceL( 
+            R_SMSV_FROM, 
+            EMsgAddressControl, 
+            EMsgAppendControl, 
+            EMsgHeader);
+        }
+    CleanupStack::PopAndDestroy( 2 ); //store, nullString
+
+    // Tests if Bio message
+    if ( msvEntry.iBioType && !iFlags.iGms ) 
+        {
+		// parse the number if wappush
+		if( msvEntry.iBioType == KMsgBioProvisioningMessage.iUid )
+		    {
+			    TPtrC tempNumber( msvEntry.iDetails );
+			    if(CommonPhoneParser::IsValidPhoneNumber( 
+			    	tempNumber, CommonPhoneParser::ESMSNumber ))
+			    {
+			    	iNumber = tempNumber;
+			    }	    	
+		    }
+        // Original longish LaunchViewL-function is split into 3 parts;
+        // LaunchViewL, SmsBasedMsgHandlingL & LaunchBioViewL
+        LaunchBioViewL( msvEntry );
+        }
+    
+    // Fill address ctrl
+    if ( !iFlags.iIsEmailMessage && KErrNotFound != iNumber.Match( iRecipientstring ) )
+        {
+        iRecipientstring = KNullDesC;
+        }
+    CMsgBaseControl* addressBase = iView->ControlById( iControlId );
+    CMsgAddressControl* addressControl = STATIC_CAST( CMsgAddressControl*, addressBase );
+
+    MVPbkContactLink* link= NULL;
+    addressControl->AddRecipientL( 
+        iRecipientstring,
+        iNumber,
+        ETrue,
+        link );
+
+    // Message indication ( e.g. 2/32 )
+#ifdef RD_MSG_NAVIPANE_IMPROVEMENT
+    // Fetch pointer to the default navi pane control
+    iNaviPane = static_cast<CAknNavigationControlContainer*>
+        ( StatusPane( )->ControlL(  TUid::Uid( EEikStatusPaneUidNavi ) ) );
+     
+    if( !iNaviDecorator )
+        {
+        CreateViewerNaviPaneL( Document()->Entry().iDate, EMsgEditorMsgPriorityNormal, ETrue );    
+        iNaviPane->PushL( *iNaviDecorator );  // <- This has nothing to do with cleanup-stack!    
+        }
+    else
+        {
+        //We end up here when fast msg opening is enabled
+        CMsgNaviPaneControl* naviControl = static_cast<CMsgNaviPaneControl*>
+            ( iNaviDecorator->DecoratedControl() );
+        naviControl->SetTimeIndicatorL( Document()->Entry().iDate, ETrue );
+        naviControl->SetNavigationIndicatorL( Document()->Session(), Document()->Entry() );
+        }
+    
+#else
+	UpdateNaviPaneL();
+#endif
+	//remove buttons from navipane
+	if( iNaviDecorator && iClass0CBA )
+	    {
+	    iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, ETrue );
+   	    iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, ETrue );
+	    } 
+#ifdef RD_SCALABLE_UI_V2
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+       	iNaviDecorator->SetNaviDecoratorObserver( this );
+       	if ( iToolbar )
+       		{
+       		//By Default make take touchbar invisible, dimmed and disabled
+       		iToolbar->SetToolbarVisibility(EFalse, EFalse);
+       		iToolbar->SetDimmed(ETrue);
+       		iToolbar->DisableToolbarL( ETrue );
+
+       		//Test that message type is normal SMS
+       		if ( !iFlags.iBioMsg && !iFlags.iGms) 
+       			{
+       			//Enable the touchbar, make it visible and undimmed
+       			iToolbar->DisableToolbarL( EFalse );
+       			iToolbar->SetDimmed(EFalse);
+       			iToolbar->SetToolbarVisibility(ETrue, EFalse);
+
+               	// default state, nothing dimmed. Uncomment the below lines only if necessary to force set it dim again
+                 /*
+               		iToolbar->SetItemDimmed(ESmsViewerToolbarReply, EFalse, EFalse);
+               		iToolbar->SetItemDimmed(ESmsViewerToolbarForward, EFalse, EFalse);
+               		iToolbar->SetItemDimmed(ESmsViewerToolbarDelete, EFalse, ETrue);
+                 */
+
+            	//What buttons to dim
+           		switch ( iSmsHeader->Type() )
+               		{
+                	
+                		//Received Message
+                		case CSmsPDU::ESmsDeliver:
+                		//Nothing dimmed, unless sender unknown
+                			if (msvEntry.iDetails.Length() == 0 )
+                				iToolbar->SetItemDimmed(ESmsViewerToolbarReply, ETrue, ETrue);
+                				
+                			//Or not valid
+                			if (!iFlags.iValidSenderNumber)
+                				iToolbar->SetItemDimmed(ESmsViewerToolbarReply, ETrue, ETrue);               					
+                			break;
+                	
+                		//Sent Message
+                		case CSmsPDU::ESmsSubmit:
+                			//Dim the reply button, we would be replying to ourselves
+                			iToolbar->SetItemDimmed(ESmsViewerToolbarReply, ETrue, ETrue);
+                			break;
+                		
+                		//Some other cases we might consider dimming
+               			//ESmsSubmitReport SMS-SUBMIT-REPORT, sent from SC to MS
+                		//ESmsStatusReport SMS-STATUS-REQUEST, sent from SC to MS
+                		//ESmsCommand      SMS-COMMAND, sent from MS to SC	
+                		//ESmsDeliverReport SMS-DELIVER-REPORT, sent from MS to SC
+                		
+                		//TODO Necessary?
+                		default:
+                			Panic( EMsgSmsViewerUnknownSmsPduType );
+                			break;
+
+                		}	// Switch
+            		}	// if ( !iFlags.iBioMsg && !iFlags.iGms) 
+            	}	// if ( iToolbar )
+            }     // if ( AknLayoutUtils::PenEnabled() ) 	
+#endif	
+    // set focus
+    iView->ExecuteL( ClientRect(), iControlId );
+
+    SetTitleIconL();
+		iFullyConstructed = ETrue;
+		
+		if ( !iFlags.iBioMsg && !iFlags.iGms )
+    {
+        // Read the value of automatic highlight sd-key
+        ReadAutoHlSharedDataValueAndSetNotifyL();
+        // Set the state of automatic highlighting for sms
+        SetAutomaticHighlightL( iFlags.iAutomaticHlValue );
+    }
+    
+    else 
+    {
+    	if ( iView && iView->ItemFinder() ) 
+    		{
+    	    iView->ItemFinder()->SetFindModeL( CItemFinder::ENoneSelected );
+    		}
+    	
+    }
+		
+		delete iScreenClearer;
+    iScreenClearer = NULL;
+    CleanupStack::PopAndDestroy();// CAknInputBlock
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::SmsBasedMsgHandlingL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::SmsBasedMsgHandlingL( 
+    TInt32 aBioType, CMsvStore* aStore )
+    {
+    // Initialize the richtext object...
+    CParaFormatLayer* paraFormat = iEikonEnv->SystemParaFormatLayerL(); // <- pointer only
+    CCharFormatLayer* charFormat = iEikonEnv->SystemCharFormatLayerL(); // <- pointer only
+    CRichText* textBody = CRichText::NewL( paraFormat, charFormat );
+    CleanupStack::PushL( textBody );
+    // ...and read bodytext
+    aStore->RestoreBodyTextL( *textBody );
+    
+    if ( !aBioType || iFlags.iGms)
+        {
+        // message is ordinary sms message or Picture Message
+        // so, let's get message body to viewer. 
+        CMsgBaseControl* baseControl = iView->ControlById( 
+            EMsgComponentIdBody );
+        CMsgBodyControl* bodyControl = STATIC_CAST( 
+            CMsgBodyControl*, 
+            baseControl );
+        
+        if ( !iFlags.iGms )
+            { // normal sms
+            //the Title-pane text
+            HBufC* text = StringLoader::LoadLC( R_QTN_TITLE_SMS, iCoeEnv );
+            CAknTitlePane* title = STATIC_CAST( 
+                CAknTitlePane*, 
+                StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle )));
+            title->SetTextL( *text );
+            CleanupStack::PopAndDestroy(); // text
+            
+            CMsgTextUtils::ConvertLineBreaksL( *textBody, CMsgTextUtils::ECRLFtoLF );
+            
+            // body text
+            bodyControl->SetTextContentL( *textBody );
+            
+            // Class 0 handling...
+            TSmsDataCodingScheme::TSmsClass smsClass;
+            if ( iSmsHeader->Message().SmsPDU().Class( smsClass ) 
+                && smsClass == TSmsDataCodingScheme::ESmsClass0 )
+                {
+                // Create new softkeys
+                iClass0CBA = Cba(); // <- pointer only
+                if (iClass0CBA) 
+                    { // iClass0CBA shouldn't be NULL, but if....
+                    iClass0CBA->SetCommandSetL( R_SMSVIEWER_CLASS0_SOFTKEYS_OPTIONS_EXIT__CONTEXTOPTIONS );  
+                    //Middle softkey
+    				MenuBar()->SetContextMenuTitleResourceId( R_SMSV_OPTIONSCONTEXTMENUBAR_CLASS0 );           
+                    MenuBar()->SetMenuTitleResourceId( R_SMSV_OPTIONSMENUBAR_CLASS0 );        
+                    MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions);     
+                    }
+                }
+            }
+        else
+            { // picture message
+            iGmsModel = CGmsWrapper::NewL(iCoeEnv->FsSession());
+            iGmsModel->LoadMsgL(*textBody);
+            bodyControl->SetTextContentL(*iGmsModel->GetTextLC());
+            CleanupStack::PopAndDestroy(); // CRichText instance
+            iGmsModel->AddPictureControlToViewL(*iView, EMsgImageControlId);
+            iGmsModel->SetPictureMsgTitleL(*StatusPane(),
+                R_QTN_SM_TITLE_PICTURE_MESSAGE);
+            }
+
+        bodyControl->SetPlainTextMode( ETrue );
+        }
+    CleanupStack::PopAndDestroy(); //textBody
+    
+    // Deciding between To/From text in address control
+    const CSmsPDU::TSmsPDUType pduType = iSmsHeader->Type();
+    switch ( pduType )
+        {
+        case CSmsPDU::ESmsDeliver:
+            {
+            // Setting from-control
+            iControlId = EMsgComponentIdFrom;
+            iView->AddControlFromResourceL( 
+                R_SMSV_FROM, 
+                EMsgAddressControl, 
+                EMsgAppendControl, 
+                EMsgHeader );
+            // take the number and verify it
+            iNumber = iSmsHeader->FromAddress();
+            if ( !iFlags.iIsEmailMessage )
+                {
+                iFlags.iValidSenderNumber = CommonPhoneParser::IsValidPhoneNumber(
+                    iNumber, CommonPhoneParser::ESMSNumber );
+
+                if( !iFlags.iValidSenderNumber && iMsgVoIPExtension->IsVoIPSupported() )
+                    {
+                    if( MsvUiServiceUtilities::IsValidEmailAddressL( iNumber ) )
+                        {
+                        iFlags.iValidSenderNumber = ETrue;
+                        iFlags.iVoIPNumber = ETrue;
+                        }
+                    }
+                // Replypath indication
+                if ( iSmsHeader->Deliver().ReplyPath() )
+                    {
+                    iView->AddControlFromResourceL( 
+                        R_SMSV_REPLYPATH, 
+                        EMsgExpandableControl, 
+                        EMsgAppendControl, 
+                        EMsgHeader );
+                
+                    HBufC* text = StringLoader::LoadLC( R_QTN_SMS_HEADING_REPLY_PATH, iCoeEnv );
+                    CRichText& replyPath = STATIC_CAST(CMsgExpandableControl*, 
+                        iView->ControlById(EMsgComponentIdCc))->TextContent();
+                    replyPath.Reset();
+                    replyPath.InsertL( 0, *text ); 
+                    CleanupStack::PopAndDestroy(); // text
+                    }
+                }
+            else
+                {
+                iFlags.iValidSenderNumber =
+                    MsvUiServiceUtilities::IsValidEmailAddressL(
+                        iRecipientstring );
+                }
+            }
+            break;
+        case CSmsPDU::ESmsSubmit:
+            // Setting To-control
+            iControlId = EMsgComponentIdTo;
+            iView->AddControlFromResourceL( 
+                R_SMSV_TO, 
+                EMsgAddressControl, 
+                EMsgAppendControl, 
+                EMsgHeader );
+            // take the number
+            iNumber = iSmsHeader->FromAddress();
+            break;
+        default:
+#if defined ( _DEBUG )
+            Panic( EMsgSmsViewerUnknownSmsPduType );
+#else
+            User::Leave( KErrNotSupported );
+#endif
+            break;
+        }
+    // If we are dealing with Email message
+    // we add subject control for Email type subject
+    if ( iFlags.iIsEmailMessage )
+        {
+        TPtrC subj( iSmsHeader->EmailFields().Subject() );
+        if ( subj.Length() )
+            {
+            // Add subject control
+            AddSubjectControlL();
+            // Set the Subject field text accordigly
+            SetSubjectL( subj );
+            }
+        }
+    iTypeMsg = pduType; //for successful launch save the PDU Type.
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::LaunchBioViewL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::LaunchBioViewL( const TMsvEntry& aTMsvEntry )
+    {
+    // Picture Messages are not handled as Bio in this class.
+    __ASSERT_DEBUG(!iFlags.iGms, Panic(EMsgSmsNotForGms));
+
+    // Load in BioControl
+    const TUid bioType={ aTMsvEntry.iBioType };
+    CMsgBioBodyControl* bioBody = NULL;
+    bioBody = CMsgBioBodyControl::NewL(
+        *this,
+        bioType,
+        aTMsvEntry.Id(),
+        EMsgBioViewerMode,
+        Document()->Session()); //since this is the viewer application
+    CleanupStack::PushL( bioBody );
+    
+    // Remove default body control and replace with Bio Control
+    iView->DeleteControlL( EMsgComponentIdBody );
+    iView->AddControlL(
+        bioBody, 
+        EMsgComponentIdBody,
+        EMsgAppendControl, 
+        EMsgBody );
+    CleanupStack::Pop(); // bioBody
+    
+    //the Title-pane text
+    HBufC* text = bioBody->HeaderTextL();
+    CleanupStack::PushL( text );
+    CAknTitlePane* title = STATIC_CAST( 
+        CAknTitlePane*, 
+        StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle )));
+    title->SetTextL( *text );
+    CleanupStack::PopAndDestroy(); // text
+    
+    //current message is bio message
+    iFlags.iBioMsg = ETrue;
+    
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::AddBioCommandsToMenuL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::AddBioCommandsToMenuL( 
+    CEikMenuPane* aMenuPane )
+    {
+    BioBody().SetMenuCommandSetL( *aMenuPane );
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::OptionsMenuPermissionsBioL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TUint32 CMsgSmsViewerAppUi::OptionsMenuPermissionsBioL()
+    {
+    __ASSERT_DEBUG( iFlags.iBioMsg, Panic( EMsgSmsBioNotActive ));
+    return BioBody().BioControl().OptionMenuPermissionsL();
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DynInitMenuPaneL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DynInitMenuPaneL(
+    TInt aMenuId, 
+    CEikMenuPane* aMenuPane )
+    {
+    // Confirm app is running properly
+    if ( !Document()->IsLaunched())
+        {
+        // If not, hide everything and return
+        TInt amountOfItems = aMenuPane->NumberOfItemsInPane();
+        if ( amountOfItems )
+            {
+            aMenuPane->DeleteBetweenMenuItems( 0, amountOfItems-1 );
+            return;
+            }
+        }
+    // Init all needed objects
+    // Creation delayed to speed up the
+    // viewer's opening process
+    if( !iSendUi )
+        {
+        iSendUi = CSendUi::NewL();
+        }
+    if ( !iFindItemMenu )
+        {
+        // Tests if normal message
+        if ( !iFlags.iBioMsg || !iFlags.iGms ) 
+            {
+            // Prepare FindItem
+            iFindItemMenu = CFindItemMenu::NewL( EFindItemMenuPlaceHolder );
+            iFindItemMenu->AttachItemFinderMenuL( R_SMSV_OPTIONSMENUPANE );
+            }
+        }
+
+    // ...then construct the menu itself. There are two menu-resources,
+    // one for contextmenu and one for normal optionsmenu. 
+    switch ( aMenuId )
+        {
+        case R_SMSV_REPLY_MENU:
+            {           			            
+	            TSendingCapabilities dummy;
+	            
+				//hide normal short message
+				aMenuPane->SetItemDimmed(
+	                    ESmsViewerReplyNormal, ETrue);
+				//hide mms
+	            aMenuPane->SetItemDimmed(
+	                    ESmsViewerReplyViaMms, ETrue); 	                    
+
+	            //if Audio msg supported
+	            if ( iFlags.iAudioMsgSupported )
+	                {
+	                aMenuPane->SetItemDimmed(
+	                    ESmsViewerReplyViaAudio, EFalse);
+	                }
+                
+            // If this is from email and email settings are defined
+            // we allow the user to reply via E-mail
+            if ( iFlags.iIsEmailMessage &&
+            	 iSendUi->ValidateServiceL( KSenduiMtmSmtpUid, dummy ) )
+                {
+                aMenuPane->SetItemDimmed(
+                    ESmsViewerReplyViaEmail, EFalse);
+                }
+            // If this is from PS number normal reply is dimmed    
+            if ( iFlags.iVoIPNumber )
+                {
+                aMenuPane->SetItemDimmed(
+                    ESmsViewerReplyViaEmail, EFalse);
+                aMenuPane->SetItemDimmed(
+                    ESmsViewerReplyNormal, ETrue);
+                aMenuPane->SetItemDimmed(
+                    ESmsViewerCreateCC, ETrue);    
+                }    
+            }
+            break;
+        case R_SMSV_OPTIONSMENUPANE: 
+            {
+            //hide aiw menu item for calender,
+            aMenuPane->SetItemDimmed( KAiwCmdSaveToCalendar, ETrue );
+            
+            if ( !iFlags.iBioMsg )
+                { // Normal sms or picture msg
+                DynInitNonBioOptionsMenuL( aMenuPane );
+                }
+            else
+                { // Smart (BIO) msg
+                DynInitBioOptionsMenuL( aMenuId, aMenuPane );
+                }
+            if ( iFlags.iBioMsg || iFlags.iGms )                
+                {
+                aMenuPane->SetItemDimmed( ESmsViewerSubmenuZoomCommands, ETrue );                
+                }
+            }
+            break;
+        case R_SMSV_CONTEXTMENUPANE:
+            {
+            if ( !iFlags.iBioMsg )
+                { // Normal sms or picture msg
+                DynInitNonBioContextMenuL( aMenuPane );
+                }
+            else
+                { // Smart (BIO) msg
+                DynInitBioContextMenuL( aMenuPane );
+                }
+            }                
+            break;
+        case R_FINDITEMMENU_MENU:
+            {
+            iFindItemMenu->DisplayFindItemCascadeMenuL( *aMenuPane );
+            }
+            break;
+        case R_SMSV_OPTIONSMENUPANE_CLASS0:
+            {
+            TPtrC senderNumber = KNullDesC();
+            if ( iFlags.iValidSenderNumber )
+                {
+                senderNumber.Set( iNumber );
+                }
+            //if autolock enabled, hide finditem-menu
+            if ( iFlags.iAutoLockEnabled )
+                {
+                aMenuPane->DeleteMenuItem( EFindItemMenuPlaceHolder );
+                }
+            else
+	            {              
+	            iFindItemMenu->AddItemFindMenuL( 
+                IsBodyFocused() ? iView->ItemFinder() : 0,
+                aMenuPane, EFindItemMenuPlaceHolder,
+                senderNumber, 
+                iRecipientstring.Length() != 0 ? ETrue : EFalse,
+                EFalse );
+                }
+            }
+            break;
+         case R_SMSV_OPTIONSCONTEXTMENUPANE_CLASS0:
+            {
+            TPtrC senderNumber = KNullDesC();
+            if ( iFlags.iValidSenderNumber )
+                {
+                senderNumber.Set( iNumber );
+                }
+            //if autolock enabled, hide finditem-menu
+            if ( iFlags.iAutoLockEnabled )
+                {
+                aMenuPane->DeleteMenuItem( EFindItemContextMenuPlaceHolder );
+                }
+            else
+	            {              
+	            iFindItemMenu->AddItemFindMenuL( 
+                IsBodyFocused() ? iView->ItemFinder() : 0,
+                aMenuPane, EFindItemContextMenuPlaceHolder,
+                senderNumber, 
+                iRecipientstring.Length() != 0 ? ETrue : EFalse,
+                ETrue );
+                }
+            }
+            break;
+        case R_SMSVIEWER_ZOOM_SUBMENU:
+            {
+            TInt zoomLevel = KErrGeneral;
+            iMsgEditorAppUiExtension->
+                iSettingCachePlugin.GetValue( KAknLocalZoomLayoutSwitch, zoomLevel );
+            switch ( zoomLevel )
+                {
+                case EAknUiZoomAutomatic:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeAutomatic,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                case EAknUiZoomNormal:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeNormal,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                case EAknUiZoomSmall:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeSmall,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                case EAknUiZoomLarge:
+                    aMenuPane->SetItemButtonState( EMsgDispSizeLarge,
+                                     EEikMenuItemSymbolOn );
+                    break;
+                default:
+                    break;
+                }
+            }
+            break;
+        default:
+            if ( iFlags.iBioMsg || iFlags.iGms )
+                {// for BIO & GMS; create contact card menu
+                // If it's AIW sub-menu, let AIW initialize it
+                InitAiwContactCardSubMenuL( aMenuPane );
+                }
+            else
+                {// for normal SMS; update the finder menu
+                if( iFlags.iVoIPNumber )
+                    {
+                    iFindItemMenu->SetSenderDescriptorType( CItemFinder::EEmailAddress );
+                    }
+                iFindItemMenu->UpdateItemFinderMenuL( aMenuId, aMenuPane );
+                }
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DynInitNonBioOptionsMenuL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DynInitNonBioOptionsMenuL( CEikMenuPane* aMenuPane )
+    {
+    if ( !iFlags.iGms )
+        { // normal sms
+    
+         //hide submenu if only item is "via message" or restricted mode ON
+        TSendingCapabilities dummy; 
+        if( iFlags.iSmsRestrictedMode ||
+        	( !iFlags.iAudioMsgSupported && 
+        	!iFlags.iVoIPNumber &&
+        	!(iFlags.iIsEmailMessage &&
+	            	 iSendUi->ValidateServiceL( KSenduiMtmSmtpUid, dummy )) ))
+        	{       
+			aMenuPane->DeleteMenuItem( ESmsViewerReply );
+			aMenuPane->SetItemDimmed( ESmsViewerReplyNoSubMenu, EFalse );
+        	}        	
+
+        // add automatic highlight menus
+        TPtrC senderNumber = KNullDesC();
+        if ( iFlags.iIsEmailMessage ) // SMS originating address is email address 
+            {  
+            senderNumber.Set( iRecipientstring );
+            iFindItemMenu->SetSenderDescriptorType( CItemFinder::EEmailAddress );
+            }            
+        else 
+            {// SMS originating adddress is Phone number
+            if ( iFlags.iValidSenderNumber )
+                {
+                senderNumber.Set( iNumber );
+                }
+            }
+        //Added to remove Copy-option when sender number is not valid (for example it has alphabets)    
+        if ( iFlags.iValidSenderNumber || IsBodyFocused() )
+        	{
+	        if( !iFlags.iVoIPNumber )
+	            {
+	            iFindItemMenu->SetSenderHighlightStatus( 
+	                iView->ControlById( EMsgComponentIdFrom ) == iView->FocusedControl() );
+	            iFindItemMenu->SetSenderDisplayText( senderNumber );
+	            iFindItemMenu->AddItemFindMenuL( 
+	                IsBodyFocused() ? iView->ItemFinder() : 0,
+	                aMenuPane, EFindItemMenuPlaceHolder,
+	                senderNumber, 
+	                iFlags.iIsEmailMessage ? EFalse : ( iRecipientstring.Length() != 0 ) );
+	            }
+	        else
+	            {
+	            iFindItemMenu->SetSenderHighlightStatus( 
+	                iView->ControlById( EMsgComponentIdFrom ) == iView->FocusedControl() );
+	            iFindItemMenu->SetSenderDisplayText( senderNumber );
+	            iFindItemMenu->AddItemFindMenuL( 
+	                IsBodyFocused() ? iView->ItemFinder() : 0,
+	                aMenuPane, EFindItemMenuPlaceHolder,
+	                senderNumber, 
+	                ETrue );
+	            }
+            }
+        else //Not valid sender number, dim the find item
+        	{
+        	aMenuPane->SetItemDimmed( EFindItemMenuPlaceHolder, ETrue);
+        	}
+            
+        // not needed in automatic highlight
+        aMenuPane->SetItemDimmed( ESmsViewerCallBack, ETrue );
+        aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+        }
+    else
+        { // GMS
+        // dim automatic highlight items
+        aMenuPane->SetItemDimmed( EFindItemMenuPlaceHolder, ETrue );
+        
+        // not supported in unified editor
+        aMenuPane->SetItemDimmed( ESmsViewerForward, ETrue );
+        
+        //dim the Add to Contacts menu if the number is already in address book
+        if (iRecipientstring.Length() != 0)
+        	{
+        	//Number is already in address book
+        	aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+        	}
+        
+		}
+
+    // Remove "Call back to sender", "reply" and "create cc" from
+    // menu, if this is a sent message or sender number is unusable
+    if ( iControlId == EMsgComponentIdTo || !iFlags.iValidSenderNumber )
+        {
+        aMenuPane->SetItemDimmed( ESmsViewerReply, ETrue );
+        if ( iFlags.iGms )
+            { // "create cc" and "call back to sender" valid only Gms
+            aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+            aMenuPane->SetItemDimmed( ESmsViewerCallBack, ETrue );
+            }
+        }
+    else if ( iFlags.iValidSenderNumber && iFlags.iGms )
+        {
+        // Number usable, request Phonebook2 to add menu items (AIW)
+        InitAiwContactCardMenuL( R_SMSV_OPTIONSMENUPANE, aMenuPane );
+        }
+    else
+        { // Lint
+        }    
+    
+    if ( iFlags.iVoIPNumber )
+        {
+        aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+        aMenuPane->SetItemDimmed( ESmsViewerReply, ETrue );
+        aMenuPane->SetItemDimmed( ESmsViewerForward, ETrue );
+        }
+    else
+        { // Lint
+        }
+
+    // Help handling
+    aMenuPane->SetItemDimmed( EAknCmdHelp, !iFlags.iHelpFeatureSupported );
+    }
+    
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DynInitNonBioContextMenuL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DynInitNonBioContextMenuL( CEikMenuPane* aMenuPane )
+    {
+    // Remove "Call back to sender" and "reply" from
+    // menu, if this is a sent message or sender number is not usable
+    
+    // if not GMS, dim following              
+    if ( !iFlags.iGms )
+        { // Sms
+        // add automatic highlight menus
+        TPtrC senderNumber = KNullDesC();
+        if ( iFlags.iIsEmailMessage ) // SMS originating address is email address 
+            {  
+            senderNumber.Set( iRecipientstring );
+            iFindItemMenu->SetSenderDescriptorType( CItemFinder::EEmailAddress );
+            }            
+        else 
+            {// SMS originating adddress is Phone number
+            if ( iFlags.iValidSenderNumber )
+                {
+                senderNumber.Set( iNumber );
+                }
+            }
+        if( !iFlags.iVoIPNumber )
+            {
+            iFindItemMenu->SetSenderHighlightStatus( 
+                iView->ControlById( EMsgComponentIdFrom ) == iView->FocusedControl() );
+            iFindItemMenu->SetSenderDisplayText( senderNumber );
+            iFindItemMenu->AddItemFindMenuL( 
+                IsBodyFocused() ? iView->ItemFinder() : 0,
+                aMenuPane, EFindItemContextMenuPlaceHolder,
+                senderNumber, 
+                iFlags.iIsEmailMessage ? EFalse : ( iRecipientstring.Length() != 0 ),
+                ETrue );
+            }
+        else
+            {
+            iFindItemMenu->SetSenderHighlightStatus( 
+                iView->ControlById( EMsgComponentIdFrom ) == iView->FocusedControl() );
+            iFindItemMenu->SetSenderDisplayText( senderNumber );
+            iFindItemMenu->AddItemFindMenuL( 
+                IsBodyFocused() ? iView->ItemFinder() : 0,
+                aMenuPane, EFindItemContextMenuPlaceHolder,
+                senderNumber, 
+                ETrue,
+                ETrue );
+            }
+        }
+    else 
+        { // Gms
+        // dim automatic highlight items
+        aMenuPane->SetItemDimmed( EFindItemContextMenuPlaceHolder, ETrue );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DynInitBioOptionsMenuL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DynInitBioOptionsMenuL(
+    TInt aMenuId,
+    CEikMenuPane* aMenuPane )
+    {
+    // dim automatic highlight items
+    aMenuPane->SetItemDimmed( EFindItemMenuPlaceHolder, ETrue );
+    //dim the Add to Contacts menu if the number is already in address book
+    if (iRecipientstring.Length() != 0)
+    	{
+    	//Number is already in address book
+    	aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+    	}
+    
+    if ( iControlId == EMsgComponentIdTo ) // Sent item
+        {
+        aMenuPane->SetItemDimmed( ESmsViewerCallBack, ETrue );
+        aMenuPane->SetItemDimmed( ESmsViewerReply, ETrue );
+        aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+        aMenuPane->SetItemDimmed( ESmsViewerForward, ETrue );
+        }
+    else // Inbox item
+        {
+        AddBioCommandsToMenuL( aMenuPane );
+
+        TUint32 permBio = OptionsMenuPermissionsBioL();        
+        
+        if ( !iFlags.iValidSenderNumber )
+            {
+            aMenuPane->SetItemDimmed( ESmsViewerCallBack, ETrue );
+            aMenuPane->SetItemDimmed( ESmsViewerReply, ETrue );
+            aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+            }
+        else // Sender number is valid, check does biocontrol accept options
+            {
+            if ( !( permBio & EMsgBioReply ) )
+                {
+                aMenuPane->SetItemDimmed( ESmsViewerReply, ETrue );
+                }
+        
+            if ( !( permBio & EMsgBioCallBack ) || iFlags.iIrBt )
+                {
+                aMenuPane->SetItemDimmed( ESmsViewerCallBack, ETrue );
+                }
+
+            if ( !( permBio & EMsgBioCreateCC) )
+                {
+                aMenuPane->SetItemDimmed( ESmsViewerCreateCC, ETrue );
+                }
+            else
+                {
+                // Request Phonebook2 to add menu items (AIW)
+                InitAiwContactCardMenuL( aMenuId, aMenuPane );
+                }
+            }
+
+        if ( !( permBio & EMsgBioForward ) )
+            {
+            aMenuPane->SetItemDimmed( ESmsViewerForward, ETrue );
+            }
+
+        if ( !( permBio & EMsgBioDelete ))
+            {
+            aMenuPane->SetItemDimmed( ESmsViewerDelete, ETrue );
+            }
+
+        if ( !( permBio & EMsgBioMessInfo ))
+            {
+            aMenuPane->SetItemDimmed( ESmsViewerMessInfo, ETrue );
+            }
+
+        if ( !( permBio & EMsgBioMove ))
+            {
+            aMenuPane->SetItemDimmed( ESmsViewerMove, ETrue );
+            }
+        
+        // Help-handling
+        aMenuPane->SetItemDimmed( EAknCmdHelp, !iFlags.iHelpFeatureSupported || !( permBio & EMsgBioHelp ));
+        
+        if ( permBio & EMsgBioFindItem ) // This used to be else if. Mistake?
+            {
+            iFindItemMenu->DisplayFindItemMenuItemL( *aMenuPane, ESmsViewerCreateCC );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DynInitBioContextMenuL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DynInitBioContextMenuL( CEikMenuPane* aMenuPane )
+    {
+    // dim automatic highlight items
+    aMenuPane->SetItemDimmed( EFindItemContextMenuPlaceHolder, ETrue );
+
+    if ( iControlId == EMsgComponentIdTo )
+        {
+        //aMenuPane->SetItemDimmed( ESmsViewerReply, ETrue );
+        }
+    else
+        {
+        AddBioCommandsToMenuL( aMenuPane );
+
+        if ( !(OptionsMenuPermissionsBioL() & EMsgBioDelete )) 
+            {
+            //aMenuPane->SetItemDimmed( ESmsViewerDelete, ETrue );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::HandleCommandL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::HandleCommandL(TInt aCommand )
+    {
+
+    if ( aCommand != EEikCmdExit && !iFullyConstructed )
+    	{
+    	return;
+    	}
+    
+        
+    // is it find item command
+    if ( iFindItemMenu && iFindItemMenu->CommandIsValidL( aCommand ) && !iFlags.iGms && !iFlags.iBioMsg )
+        {
+        iFindItemMenu->HandleItemFinderCommandL( aCommand );
+        return;
+        }
+    
+    // Are we dealing with bio-message?
+    if ( iFlags.iBioMsg ) 
+        {
+        // let the biocontrol handle the command and check
+        // whether it was handled.
+        if ( aCommand==EAknCmdHelp )
+            {
+            LaunchHelpL();
+            return;
+            }
+
+        if ( Document( )->IsLaunched( ) && BioBody().HandleBioCommandL( aCommand ))
+            {
+            return;// Bio control has handled the command.
+            }
+        }
+    
+    // find item
+    if ( iFindItemMenu && iFindItemMenu->CommandIsValidL( aCommand ) && ( iFlags.iGms || iFlags.iBioMsg ))
+        {
+        DoSearchL( aCommand );
+        }
+    
+    switch ( aCommand )
+        {
+        case ESmsViewerReplyNormal:	//normal sms
+            CheckDiskAndReplyForwardL( EFalse );
+			if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+                {
+                Exit( EAknSoftkeyClose );
+                }
+            break;
+        case ESmsViewerReplyViaMms:
+            DoReplyViaL( ESmsViewerReplyViaMms );
+			if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+                {
+                Exit( EAknSoftkeyClose );
+                }
+            break;
+        case ESmsViewerReplyViaEmail:
+            DoReplyViaL( ESmsViewerReplyViaEmail );
+            if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+                {
+                Exit( EAknSoftkeyClose );
+                }
+            break;
+        case ESmsViewerReplyViaAudio:
+            DoReplyViaL( ESmsViewerReplyViaAudio );
+            if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+                {
+                Exit( EAknSoftkeyClose );
+                }
+            break;
+        case ESmsViewerReplyNoSubMenu:  //unieditor, submenu hidden 
+            CheckDiskAndReplyForwardL( EFalse );
+            if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+                {
+                Exit( EAknSoftkeyClose );
+            	}
+            break;
+        case ESmsViewerReplyViaMessage:  //unieditor
+            CheckDiskAndReplyForwardL( EFalse );
+			if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+                {
+                Exit( EAknSoftkeyClose );
+                }
+            break;
+        case ESmsViewerForward:
+            CheckDiskAndReplyForwardL( ETrue );
+			if (!(iEditorBaseFeatures & EStayInViewerAfterReply))
+				{
+				Exit( EAknSoftkeyClose );
+				}
+            break;
+        case ESmsViewerDelete:
+            DoFileDeleteL();
+            break;
+        case ESmsViewerMove:
+            DoMoveEntryL();
+            break;
+        case ESmsViewerSave:
+            SaveClass0SmsL( ETrue );
+            Exit( EAknSoftkeyClose );
+            break;
+        case ESmsViewerCallBack:
+            DoCallBackToSenderL();
+            break;
+        case ESmsViewerCreateCCNew:
+            // FALLTHROUGH
+        case ESmsViewerCreateCCExisting:
+            DoCreateContactCardL( aCommand );
+            break;
+        case ESmsViewerMessInfo:
+            DoMessageInfoL();
+            break;
+        case EAknSoftkeyBack:
+            Exit( EAknSoftkeyClose );
+            break;
+        case EEikCmdExit:
+            // system exit
+            DoMsgSaveExitL();
+            break;
+        case EAknSoftkeyExit: // called only with class 0 exit
+            DeleteAndExitL();
+            break;
+        case EAknCmdHelp:
+            LaunchHelpL();
+            break;
+        case EMsgDispSizeAutomatic:
+        case EMsgDispSizeLarge:
+        case EMsgDispSizeNormal:
+        case EMsgDispSizeSmall:
+            HandleLocalZoomChangeL( (TMsgCommonCommands)aCommand );
+            break;
+        default:
+            break;
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::BodyEditor
+// (other items were commented in a header).
+// ---------------------------------------------------------
+CEikRichTextEditor& CMsgSmsViewerAppUi::BodyEditor() const
+    {
+     __ASSERT_DEBUG(  !iFlags.iBioMsg, Panic(EMsgSmsNotAllowedForBio));
+    return STATIC_CAST( CMsgBodyControl*, iView->ControlById( EMsgComponentIdBody ))->Editor();
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::BioBody
+// (other items were commented in a header).
+// ---------------------------------------------------------
+CMsgBioBodyControl& CMsgSmsViewerAppUi::BioBody() const
+    {
+    __ASSERT_DEBUG( iFlags.iBioMsg, Panic( EMsgSmsBioBodyOnlyForBio )); 
+    return *STATIC_CAST( CMsgBioBodyControl*, iView->ControlById( EMsgComponentIdBody ));
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::FirstFreeCommand
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TInt CMsgSmsViewerAppUi::FirstFreeCommand() const
+    {
+    return ESmsViewerFirstFreeCmdId;
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::RequestHandleCommandL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TInt CMsgSmsViewerAppUi::RequestHandleCommandL(
+    TMsgCommands /*aCommand*/ )
+    {
+    //Not used at the moment.
+    return KErrNotSupported;
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::IsCommandSupported
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TBool CMsgSmsViewerAppUi::IsCommandSupported(
+    TMsgCommands /*aCommand*/ ) const
+    {
+    //Nothing supported at the moment.
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::IsBodyFocused
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TBool CMsgSmsViewerAppUi::IsBodyFocused() const
+    {
+    return (( iView->ControlById( EMsgComponentIdBody )) 
+        == iView->FocusedControl()); 
+    }
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::IsSenderFocused
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TBool CMsgSmsViewerAppUi::IsSenderFocused() const
+    {
+    return (( iView->ControlById( EMsgComponentIdFrom )) 
+        == iView->FocusedControl()); 
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::HandleKeyEventL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TKeyResponse CMsgSmsViewerAppUi::HandleKeyEventL(
+    const TKeyEvent& aKeyEvent, 
+    TEventCode aType )
+    {
+    
+    // Confirm app is running properly
+    if ( iView && ( aType == EEventKey ) && Document()->IsLaunched())
+        { 
+        // react with all sms classes
+        switch ( aKeyEvent.iCode )
+            {
+            case EKeyUpArrow:
+            case EKeyDownArrow:
+                {
+                // Base-editor handles scrolling
+                iView->OfferKeyEventL( aKeyEvent, aType );
+                return EKeyWasConsumed;
+                }
+            case EKeyDevice3:
+            case EKeyEnter:	
+                {// Selection-key checking (Context sensitive menu)
+                // (with Class 0 just show the menu)
+                if ( !iClass0CBA )
+                    {
+                    MenuBar()->SetMenuTitleResourceId( R_SMSV_CONTEXTMENUBAR );
+                    MenuBar()->SetMenuType(CEikMenuBar::EMenuContext);
+                    }
+                MenuBar()->TryDisplayMenuBarL();
+                if ( !iClass0CBA )
+                    {
+                    MenuBar()->SetMenuTitleResourceId( R_SMSV_OPTIONSMENUBAR );
+                    MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions);
+                    }
+                return EKeyWasConsumed;
+                }
+                case EKeyYes:
+	                {// Send-key checking
+	                if ( !iFlags.iIrBt && !iFlags.iBioMsg && !iFlags.iGms && !iFlags.iIsEmailMessage &&
+	                			!iFlags.iAutoLockEnabled )
+	                    { // normal sms
+	                    DoHandleSendKeyL();
+	                    }
+	                else if ( iFlags.iValidSenderNumber && !iFlags.iIrBt && !iFlags.iIsEmailMessage 
+	                		&& !iFlags.iAutoLockEnabled )
+	                    { // bio / gms - sms
+	                    TBool okToQuery( ETrue );
+	                    // Is it biocontrol?
+	                    if ( iFlags.iBioMsg )
+	                        {
+	                        TUint32 permBio = OptionsMenuPermissionsBioL();
+	                        okToQuery = ( permBio & EMsgBioCallBack ) ? ETrue : EFalse ;
+	                        }
+	                    // Launch confirmation query and start calling
+	                    if ( okToQuery )
+	                        {
+	                        if ( iMsgVoIPExtension && 
+	                            iMsgVoIPExtension->IsPreferredTelephonyVoIP() &&
+	                            iMsgVoIPExtension->VoIPProfilesExistL() )
+	                            {
+	                            MsvUiServiceUtilitiesInternal::InternetCallToSenderQueryL( iNumber, iRecipientstring, ETrue );  
+	                            }
+	                        else
+	                            {
+	                            MsvUiServiceUtilitiesInternal::CallToSenderQueryL( iNumber, iRecipientstring, ETrue );
+	                            }
+	                        }
+	                    }
+	                }
+            
+            default:
+                break;
+            }
+        
+        if ( !iClass0CBA ) // ignore following events if class 0 sms
+            {
+            switch ( aKeyEvent.iCode )
+                {
+                case EKeyRightArrow:
+                    {// Show next message if possible
+                    if ( IsNextMessageAvailableL( ETrue ))
+                        {
+                        NextMessageL( ETrue );
+                        return EKeyWasConsumed;
+                        }
+                    }
+                    break;
+                case EKeyLeftArrow:
+                    { // Show prev message if possible
+                    if ( IsNextMessageAvailableL( EFalse ))
+                        {
+                        NextMessageL( EFalse );
+                        return EKeyWasConsumed;
+                        }
+                    }
+                    break;
+                case EKeyBackspace:
+                    {
+                    DoFileDeleteL();
+	                return EKeyWasConsumed;
+	                }
+                default:
+                    break;
+                }
+            }
+        else
+            { // class 0
+            return EKeyWasConsumed;
+            }
+        }
+    else // App is not running properly yet
+        {
+        return EKeyWasConsumed;
+        }
+    
+    return EKeyWasNotConsumed; 
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoMsgSaveExitL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DoMsgSaveExitL() 
+    {
+    // exit in anycase
+    Exit();
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoFileDeleteL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DoFileDeleteL()
+    {
+    // Load the texts from resources
+    HBufC* text = StringLoader::LoadLC( R_QTN_QUERY_COMMON_CONF_DELETE_ME, iCoeEnv );
+    
+    // Confirm from user deletion of message and delete if needed.
+    CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+    if ( dlg->ExecuteLD( R_DELETEMSGCONF_QUERY, *text ))
+        {
+        DeleteAndExitL();        
+        }
+
+    CleanupStack::PopAndDestroy(); // text, confText
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoMoveEntryL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DoMoveEntryL()
+    {
+    CMsvEntry& entry = Document()->CurrentEntry();
+    TMsvEntry msvEntry( entry.Entry());
+   
+    // When going in to SelectFolder-dialog folderId is
+    // the folder where message is, but when coming
+    // out (if selection done) it has the value of destination 
+    // folder.
+    TMsvId folderId = msvEntry.Parent();
+    HBufC* text = StringLoader::LoadLC( R_QTN_MCE_MOVE_MOVE_TO, iCoeEnv );
+    
+    // Launch moving-dialog and proceed if ok-returned
+    TBool moveIt = CMsgFolderSelectionDialog::SelectFolderL( folderId, *text );
+    CleanupStack::PopAndDestroy(); // text
+    if ( moveIt )
+        {
+        MoveMessageEntryL( folderId );
+        Exit( EAknSoftkeyClose );
+        }
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::DoSearchL
+// (other items were commented in a header).
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::DoSearchL( TInt aCommand )
+    {
+    __ASSERT_DEBUG(!iFlags.iBioMsg, Panic(EMsgSmsNotAllowedForBio));
+    CFindItemDialog* dlg;
+    
+    CMsgBodyControl* ctrl = STATIC_CAST( CMsgBodyControl*, 
+        iView->ControlById(
+        EMsgComponentIdBody ));
+    
+    dlg =  CFindItemDialog::NewL( 
+        ctrl->TextContent().Read( 0 ), 
+        iFindItemMenu->SearchCase( aCommand) );
+    
+    dlg->ExecuteLD();
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::DoCallBackToSenderL
+// (other items were commented in a header).
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::DoCallBackToSenderL()
+    {
+    if ( iFlags.iValidSenderNumber )
+        {
+        MsvUiServiceUtilitiesInternal::CallToSenderQueryL( iNumber, iRecipientstring );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoCreateContactCardL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DoCreateContactCardL( TInt aCommand )
+    {
+    CAiwGenericParamList& inList = iAiwServiceHandler->InParamListL();
+    InitAiwContactCardParamL( inList );
+    // Callback is not specified as we are not interested in the outcome of the assign
+    // operation.
+    iAiwServiceHandler->ExecuteMenuCmdL( aCommand, inList,
+        iAiwServiceHandler->OutParamListL(), 0, NULL);
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::OpCompleted
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::OpCompleted(
+    CMsvSingleOpWatcher& aOpWatcher,
+    TInt aCompletionCode )
+    {
+    CMsvOperation* op = &aOpWatcher.Operation();
+    // Must be trapped because calls Leaving function
+    TRAP_IGNORE( DoOperationCompletedL( op, aCompletionCode ) );// Ignored as non critical block
+    // The only operation
+    delete iViewerOperation;
+    iViewerOperation = NULL;
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::DoOperationCompletedL
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::DoOperationCompletedL(
+    CMsvOperation* aOperation,
+    TInt aCompletionCode )
+    {
+    __ASSERT_DEBUG( aOperation, Panic( EMsgSmsNullPointer ) );
+    if ( aOperation && aCompletionCode == EEikCmdExit )
+        {
+        CAknAppUi::ProcessCommandL( EAknCmdExit );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoMessageInfoL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DoMessageInfoL()
+    {
+    __ASSERT_DEBUG( !iViewerOperation, Panic( EMsgSmsNullPointer ) );
+    CMsvEntrySelection* selection = NULL; // Not used by KMtmUiFunctionMessageInfo
+    CAknInputBlock::NewLC();
+    CBaseMtmUi& uiMtm = Document()->MtmUiL();
+    TBuf8<1> dummy;
+    CMsvSingleOpWatcher* singleOpWatcher = CMsvSingleOpWatcher::NewL( *this );
+    CleanupStack::PushL( singleOpWatcher );
+
+    CMsvOperation* op = uiMtm.InvokeAsyncFunctionL(
+                                KMtmUiFunctionMessageInfo, 
+                                *selection, 
+                                singleOpWatcher->iStatus, 
+                                dummy );
+    iViewerOperation = singleOpWatcher;
+    CleanupStack::Pop( 1 ); // singleOpWatcher
+    singleOpWatcher->SetOperation( op );
+
+    CleanupStack::PopAndDestroy( 1 );// CAknInputBlock
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::ForwardGmsL
+// (other items were commented in a header).
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::ForwardGmsL(TMsvId aTarget)
+    {
+    DoFwdRepGmsL(aTarget, ETrue);
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::ReplyGmsL
+// (other items were commented in a header).
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::ReplyGmsL(TMsvId aTarget)
+    {
+    DoFwdRepGmsL(aTarget, EFalse);
+    }
+    
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::DoFwdRepGmsL
+// (other items were commented in a header).
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::DoFwdRepGmsL(TMsvId aTarget, TBool aForward)
+    {
+    CMsgEditorDocument& document = *Document();
+    TMsvId origMsgId = document.Entry().Id();
+
+    // Change the MTM type of msg temporarily
+    CMsvEntry* entry = 
+        document.Session().GetEntryL(origMsgId);
+    CleanupStack::PushL(entry);
+
+    TMsvEntry tentry(entry->Entry());
+    const TUid OrigMtmUid = tentry.iMtm;
+    tentry.iMtm = KUidSmsMtm;
+        
+    // Trap errors, so we can try to restore the original MTM Uid
+    TRAPD(err, 
+        {
+        entry->ChangeL(tentry);
+        document.SetEntryWithoutNotificationL(origMsgId);
+        
+        if (aForward)
+            {
+            ForwardL(aTarget);
+            }
+        else
+            {
+            ReplyL(aTarget);
+            }
+        
+        });
+    // Restore original Mtm Uid
+    tentry = entry->Entry();
+    tentry.iMtm = OrigMtmUid;
+    entry->ChangeL(tentry);
+    document.SetEntryWithoutNotificationL(origMsgId);
+    
+    User::LeaveIfError(err);
+    CleanupStack::PopAndDestroy(entry);    
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::SaveClass0SmsL
+// (other items were commented in a header).
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::SaveClass0SmsL( TBool aShowNotes )
+    {
+    if ( aShowNotes )
+        { // Show global "Saved"-note
+        HBufC* text = StringLoader::LoadLC( R_QTN_MCE_CONF_MESSAGE_SAVED, iCoeEnv );
+        CAknGlobalNote* note = CAknGlobalNote::NewLC();
+        note->ShowNoteL( EAknGlobalConfirmationNote, *text );
+        CleanupStack::PopAndDestroy( 2 ); // note, text
+        }
+    
+    // Get handle to entry
+    const CMsgSmsViewerDocument* doc = Document();
+    CMsvEntry& entry = doc->CurrentEntry();
+    TMsvEntry msvEntry( entry.Entry());
+    
+    // Read values from TMsvEntry
+    HBufC* details = msvEntry.iDetails.AllocLC();
+    HBufC* description = msvEntry.iDescription.AllocLC();
+    
+    // Ensure entry is not read only
+    msvEntry.SetReadOnly( EFalse );
+    entry.ChangeL( msvEntry );
+    
+    // Set class from 0 to 1 and save
+    CMsvStore* msvstore = entry.EditStoreL();
+    CleanupStack::PushL( msvstore );
+    iSmsHeader->Message().SmsPDU().SetClass(
+        ETrue, TSmsDataCodingScheme::ESmsClass1 );
+    iSmsHeader->StoreL( *msvstore );
+    msvstore->Commit();
+    CleanupStack::PopAndDestroy(); // msvstore
+    
+    // Put values back to TMsvEntry
+    msvEntry.iDetails.Set( *details );
+    msvEntry.iDescription.Set( *description );
+    
+    // Change entry back to read only and ensure it's visible
+    msvEntry.SetReadOnly( ETrue );
+    msvEntry.SetInPreparation( EFalse );
+    msvEntry.SetVisible( ETrue );
+    entry.ChangeL( msvEntry );
+    CleanupStack::PopAndDestroy( 2 ); // details, description
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::ApproximateReplyForwardSize
+// (other items were commented in a header).
+// ---------------------------------------------------------
+TInt CMsgSmsViewerAppUi::ApproximateReplyForwardSize( TBool aForward )
+    {
+    //
+    // Approximate size
+    TInt approximatedSize = 0;
+    if ( aForward )
+        { // yes, forward
+        if ( iFlags.iGms )
+            { // picture msg
+            approximatedSize = KApproxEmptyTMsvEntrySize + KApproxFullGMS; 
+            }
+        else
+            { // normal sms
+            approximatedSize = KApproxEmptyTMsvEntrySize + STATIC_CAST( CMsgBodyControl*, iView->ControlById( EMsgComponentIdBody ))->Editor().TextLength()*2; // multiplied because of unicode saving
+            }
+        }
+    else
+        { // no, reply (same for normal sms and gms)
+        approximatedSize = KApproxEmptyTMsvEntrySize + KApproxRecipientSize;
+        }
+
+    return approximatedSize;
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::CheckDiskAndReplyForwardL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::CheckDiskAndReplyForwardL( TBool aForward )
+    {
+    //
+    // Check disk
+    if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL( 
+    	Document()->Session(),
+        ApproximateReplyForwardSize( aForward  ))) 
+        {
+        User::Leave( KErrDiskFull );
+        }
+
+    //to reduce flickering during closing
+	if (!(iEditorBaseFeatures & EStayInViewerAfterReply ))
+        {
+        iView->MakeVisible( EFalse );
+        }
+        
+    TRAPD(err, DoReplyFwdL( aForward ));
+    if(!(err == KErrNone) )
+        {
+        iView->MakeVisible( ETrue );
+        }    
+    
+    }
+    
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoReplyFwdL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::DoReplyFwdL( TBool aForward )
+    {
+    // Actual forward / reply
+    // Are we forwarding...
+    if ( aForward )
+        { //...yes, forwarding
+        if ( iFlags.iGms )
+            {
+            ForwardGmsL( Document()->DefaultMsgFolder());
+            }
+        else
+            {
+            ForwardL( Document()->DefaultMsgFolder());
+            }
+        }
+    else
+        { //...no, we're replying
+        if ( iFlags.iGms )
+            {
+            ReplyGmsL( Document()->DefaultMsgFolder());
+            }
+        else
+            {
+            ReplyL( Document()->DefaultMsgFolder());
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::HandleEntryDeletedL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::HandleEntryDeletedL()
+    {
+    Exit( EAknSoftkeyClose );
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::LaunchHelpL
+// launch help using context
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::LaunchHelpL()
+    {
+    if ( iFlags.iHelpFeatureSupported )
+        {
+        // activate Help application
+        CArrayFix<TCoeHelpContext>* helpContext = AppHelpContextL();
+        HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), helpContext );
+        }
+    }
+
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::HelpContextL
+// returns help context
+// ----------------------------------------------------
+CArrayFix<TCoeHelpContext>* CMsgSmsViewerAppUi::HelpContextL() const
+    {
+    // Check if not bio message or picture message
+    if ( !iFlags.iBioMsg && !iFlags.iGms )
+        {
+        // sms editor and sms viewer use same help file, in which 
+        // sms editor id is used
+        return CreateHelpContextArrayL(
+            TCoeHelpContext( KUidSmsViewer, KSMS_HLP_VIEWER()));
+        }
+    
+    // Help context of picture message
+    // GMS xhtml-help is now under smartmessaging
+    else if ( iFlags.iGms )
+        {
+        return CreateHelpContextArrayL(
+            TCoeHelpContext( KUidGMSViewer, KSMART_HLP_GMSVIEWER()));
+        }
+    
+    // Help context of bio messages
+    else
+        {
+        TCoeHelpContext bioControlHelpContext;
+        BioBody().BioControl().GetHelpContext( bioControlHelpContext );
+        if ( !bioControlHelpContext.IsNull())
+            {
+            return CreateHelpContextArrayL( bioControlHelpContext );
+            }
+        // if help context not available for bio control
+        else
+            {
+            return NULL;
+            }
+        }
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::CreateHelpContextArrayL
+// 
+// ----------------------------------------------------
+CArrayFix<TCoeHelpContext>* CMsgSmsViewerAppUi::CreateHelpContextArrayL( const TCoeHelpContext& aHelpContext ) const
+    {
+    CArrayFix<TCoeHelpContext>* r = new(ELeave) CArrayFixFlat<TCoeHelpContext>(1);
+    CleanupStack::PushL(r);
+    r->AppendL(aHelpContext);
+    CleanupStack::Pop(r);
+    return r;
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::DoHandleSendKeyL
+// 
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::DoHandleSendKeyL()
+    {
+    if ( !iMsgVoIPExtension )
+        {
+        return;
+        }
+    
+    TPtrC number = KNullDesC();
+    TPtrC alias = KNullDesC();
+    TPtrC focusedAddr = KNullDesC();
+	TBool dailerDisabled = EFalse;
+    // sender-number
+    if ( iFlags.iValidSenderNumber )
+        {
+        number.Set( *&iNumber );
+        if ( iRecipientstring.Length() )
+            {
+            alias.Set( *&iRecipientstring );
+            }
+         if(IsSenderFocused())
+         {
+         	//Disabling the SendKey Event handling by Avkon
+    		iAvkonAppUi->SetKeyEventFlags( CAknAppUiBase::EDisableSendKeyShort |  CAknAppUiBase::EDisableSendKeyLong );
+    		dailerDisabled = ETrue;	
+         }
+        }
+
+    if ( IsBodyFocused() && iView->ItemFinder( ) )
+        {
+        const CItemFinder::CFindItemExt& item =
+            iView->ItemFinder( )->CurrentItemExt( );
+        if (    item.iItemDescriptor
+            &&  (   item.iItemType == CItemFinder::EPhoneNumber
+                ||  item.iItemType == CItemFinder::EEmailAddress ) )
+            {
+            //Dialer is opened when creating a VoIP call from SMS via Call creation key
+            //Disabling the SendKey Event handling by Avkon
+            iAvkonAppUi->SetKeyEventFlags( CAknAppUiBase::EDisableSendKeyShort |  CAknAppUiBase::EDisableSendKeyLong );
+            dailerDisabled = ETrue;
+            focusedAddr.Set( *(item.iItemDescriptor) );
+            }
+        }
+
+		if(dailerDisabled)
+		{
+    MsvUiServiceUtilitiesInternal::InternetOrVoiceCallServiceL( 
+            *iMsgVoIPExtension,
+            number,
+            alias,
+            focusedAddr,
+            ETrue,
+            iEikonEnv );    
+     }  
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::SetAutomaticHighlightL
+// 
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::SetAutomaticHighlightL( const TBool aSwitchON )
+    {
+    __ASSERT_DEBUG( !iFlags.iGms, Panic( EMsgSmsNotForGms ) );
+    __ASSERT_DEBUG( !iFlags.iBioMsg, Panic( EMsgSmsNotAllowedForBio ) );
+    if ( iView->ItemFinder() )
+        {
+        // content highlight
+        if ( aSwitchON )
+            { // switch ON
+            iView->ItemFinder()->SetFindModeL( 
+                CItemFinder::EPhoneNumber |
+                CItemFinder::EUrlAddress |
+                CItemFinder::EEmailAddress );
+            }
+        else
+            { // switch OFF
+            iView->ItemFinder()->SetFindModeL( 
+                CItemFinder::ENoneSelected );
+            }
+        // header highlight     
+        if ( iControlId != EMsgComponentIdTo && iFlags.iValidSenderNumber )
+            {
+             static_cast<CMsgAddressControl*>
+                 (iView->ControlById( iControlId ))->SetAddressFieldAutoHighlight( aSwitchON );
+
+            }
+        }
+    }
+
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::ReadAutoHlSharedDataValueL
+// 
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::ReadAutoHlSharedDataValueAndSetNotifyL()
+    {
+    __ASSERT_DEBUG( !iFlags.iGms, Panic( EMsgSmsNotForGms ) );
+    __ASSERT_DEBUG( !iFlags.iBioMsg, Panic( EMsgSmsNotAllowedForBio ) );
+    if ( iFlags.iAutomaticHlInitialized )
+        return;
+    // Create the session
+    iCenRepSession = CRepository::NewL( KCRUidCommonUi );
+    if( iCenRepSession )
+        {
+        // Get the value of AutomaticHighlight key
+        TBool value = ETrue;
+        iCenRepSession->Get( KCuiAutomaticHighlight, value );
+        iFlags.iAutomaticHlValue = value;
+        // Create the notifer
+        iNotifier = 
+            CCenRepNotifyHandler::NewL( 
+                *this, *iCenRepSession, CCenRepNotifyHandler::EIntKey,
+                KCuiAutomaticHighlight );
+        // Start listening
+        iNotifier->StartListeningL();       
+        }
+    iFlags.iAutomaticHlInitialized = ETrue; // Done once per viewer
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgSmsViewerAppUi::HandleNotifyInt
+// ----------------------------------------------------------------------------    
+//
+void CMsgSmsViewerAppUi::HandleNotifyInt( 
+    TUint32  /*aId*/, 
+    TInt aNewValue )
+    {   
+    // Notifies changes on KCuiAutomaticHighlight
+    iFlags.iAutomaticHlValue = aNewValue;
+    TRAP_IGNORE( SetAutomaticHighlightL( aNewValue ) ); 
+    }
+
+// ----------------------------------------------------------------------------
+// CMsgSmsViewerAppUi::HandleNotifyError
+// ----------------------------------------------------------------------------    
+//
+void CMsgSmsViewerAppUi::HandleNotifyError( 
+    TUint32 /*aId*/, 
+    TInt /* aError */, 
+    CCenRepNotifyHandler* /* aHandler */ )
+    {
+    // Remove session and notifier
+    if( iNotifier )
+        {
+        iNotifier->StopListening();       
+        delete iNotifier;
+        iNotifier = NULL;
+        }
+    delete iCenRepSession;    
+    iCenRepSession = NULL;
+    }
+        
+// ----------------------------------------------------
+// CMsgSmsViewerAppUi::DoReplyViaL
+// 
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::DoReplyViaL( TInt aCase )
+    {
+    __ASSERT_DEBUG( iControlId != 
+        EMsgComponentIdTo, Panic( EMsgSmsNoSuchComponent ) );
+
+    CMessageData* msgData = CMessageData::NewL();
+    CleanupStack::PushL( msgData );    
+    CMsgAddressControl* addressControl = 
+        static_cast<CMsgAddressControl*> ( iView->ControlById( iControlId ) );
+    if ( addressControl )
+        {
+        CMsgRecipientArray& recs = *addressControl->GetRecipientsL();
+        TInt count(recs.Count());
+        for (TInt index = 0; index < count; index++)
+            {
+            if ( iFlags.iIsEmailMessage )
+                {
+                msgData->AppendToAddressL( 
+	                *recs.At( index )->Name(),
+	                KNullDesC() );
+                //sender->AppendL( *recs.At( index )->Name() );
+                //alias->AppendL( KNullDesC() );
+                }
+            else
+                {
+                msgData->AppendToAddressL( 
+	                *recs.At( index )->Address(),
+	                *recs.At( index )->Name() );
+                }
+            }
+        }
+	// Via MMS, Email, Audio or to Unieditor
+    TUid mtmUid;
+    switch( aCase )
+		{
+		case ESmsViewerReplyViaMms:
+			mtmUid = KSenduiMtmMmsUid;
+            break;
+        case ESmsViewerReplyViaEmail:
+			mtmUid = KSenduiMtmSmtpUid;
+            break;	
+		case ESmsViewerReplyViaAudio:
+			mtmUid = KSenduiMtmAudioMessageUid;
+            break;
+        case ESmsViewerReplyViaMessage:	//unieditor
+			mtmUid = KSenduiMtmUniMessageUid;
+            break;            
+        default:
+            __ASSERT_DEBUG( EFalse, Panic( EMsgSmsNoSuchMtmUid ) );
+            mtmUid = KSenduiMtmUniMessageUid; // suppress compiler warning
+            break;
+		}    
+    
+    
+    if ( iFlags.iEmailSubjectControlPresent )
+        {
+        if ( SubjectControl()->TextContent().DocumentLength() )
+            {
+            HBufC* buf = SubjectControl()->Editor().GetTextInHBufL();
+            CleanupStack::PushL( buf );
+            TInt length = buf->Length();
+            HBufC* replyFormat = StringLoader::LoadLC( R_QTN_SMS_REPLYFORMAT, iCoeEnv );
+
+            _LIT( KSmsSubjectFormat, "%S" );
+            TInt formatPos = replyFormat->Find( KSmsSubjectFormat );
+	    	TInt foundInSubj = KErrNotFound;
+		    if ( formatPos > 0 )
+                {
+                // -1 to avoid % in the string
+			    foundInSubj = buf->FindF( replyFormat->Left( formatPos-1 ) );
+                }
+            HBufC* newSubject = NULL;
+		    //append only when it is not in the beginning of the subject line or not found.
+		    if ( foundInSubj==KErrNotFound || foundInSubj )
+			    {
+			    // Create a buffer large enough to hold the re-formated subject - need
+		        // to subtract two from the prefix length (the %S).
+		        length += replyFormat->Length() - 2;
+		        newSubject = HBufC::NewLC(length);
+		        TPtr ptr( newSubject->Des() );
+		        // Format the reply subject
+		        ptr.Format( replyFormat->Des(), buf );
+			    }
+            else
+                {
+                newSubject = buf->Des().AllocLC();
+                }
+            msgData->SetSubjectL( newSubject );
+            //CleanupStack::Pop( ); // newSubject
+            CleanupStack::PopAndDestroy( 3 ); // buf, replyFormat, newSubject
+            //CleanupStack::PushL( newSubject );
+            }
+        }        
+    iSendUi->CreateAndSendMessageL( mtmUid, msgData );
+    CleanupStack::PopAndDestroy( msgData ); // msgData
+    }
+    
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::AddSubjectControlL()
+//
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::AddSubjectControlL()
+    {
+    // Sanity
+    __ASSERT_DEBUG( iView, Panic( EMsgSmsNullPointer ) );
+    if ( !iFlags.iEmailSubjectControlPresent )
+        {
+        iView->AddControlFromResourceL( R_SMS_VIEWER_SUBJECT,
+                EMsgExpandableControl, EMsgAppendControl, EMsgHeader );
+        // Mark the control creation
+        iFlags.iEmailSubjectControlPresent = ETrue;
+        }
+    }
+    
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::SetSubjectL()
+//  
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::SetSubjectL(const TDesC& aText)
+    {
+    CMsgExpandableControl* subjectControl = SubjectControl();
+    if (subjectControl)
+        {
+        CRichText& subject = subjectControl->TextContent();
+        subject.Reset();
+        subject.InsertL( 0, aText );
+        }
+    }
+
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::SubjectControl()
+//  
+// ----------------------------------------------------
+CMsgExpandableControl* CMsgSmsViewerAppUi::SubjectControl() const
+    {
+    __ASSERT_DEBUG( iFlags.iEmailSubjectControlPresent, Panic( EMsgSmsNullPointer ));
+    return STATIC_CAST(CMsgExpandableControl*, 
+            iView->ControlById(EMsgComponentIdSubject));
+    }
+
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::InitAiwContactCardMenuL
+//  
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::InitAiwContactCardMenuL( TInt aMenuId,
+    CEikMenuPane* aMenuPane )
+    {
+    if ( !iAiwServiceHandler)
+        {
+        // Create AIW service handler and attach to contact card menu item
+        iAiwServiceHandler = CAiwServiceHandler::NewL();
+        iAiwServiceHandler->AttachMenuL( aMenuId,
+            R_SMSV_AIW_CONTACT_INTEREST );
+        }
+
+    // This menu should contain AIW menu placeholder
+    __ASSERT_DEBUG( iAiwServiceHandler->IsAiwMenu( aMenuId ),
+        Panic( EMsgSmsAiwMenu ) );
+
+    CAiwGenericParamList& inList = iAiwServiceHandler->InParamListL();
+    InitAiwContactCardParamL( inList );
+    iAiwServiceHandler->InitializeMenuPaneL( *aMenuPane, aMenuId,
+        ESmsViewerCreateCCNew, inList );
+    }
+
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::InitAiwContactCardSubMenuL
+//  
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::InitAiwContactCardSubMenuL( CEikMenuPane* aMenuPane )
+    {
+    // If menu is AIW sub-menu, AIW will initialize it
+    if ( iAiwServiceHandler &&
+         iAiwServiceHandler->HandleSubmenuL( *aMenuPane ) )
+        {
+        // We assume AIW inserts at most 2 items into the submenu.
+        // ESmsViewerCreateCCNew and ESmsViewerCreateCCExisting.
+        // Otherwise command codes will overlap
+#ifdef _DEBUG
+        const TInt KMaxItems = 2;
+        __ASSERT_ALWAYS( aMenuPane->NumberOfItemsInPane() <=
+            KMaxItems, Panic( EMsgSmsAiwMenu ) );
+#endif
+        }
+    }
+
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::InitAiwContactCardParamL()
+//  
+// ----------------------------------------------------
+void CMsgSmsViewerAppUi::InitAiwContactCardParamL(
+    CAiwGenericParamList& aParamList ) const
+    {
+    using namespace AiwContactAssign;
+
+    TAiwGenericParam param( EGenericParamContactAssignData );
+    TAiwSingleContactAssignDataV1 assignData;
+    assignData.SetFlags( 0 );
+    param.Value().Set( TAiwSingleContactAssignDataV1Pckg( assignData ) );
+    aParamList.AppendL( param );
+
+    // Phone number
+    param.Reset();
+    param.SetSemanticId( EGenericParamPhoneNumber );
+    param.Value().Set( iNumber );
+    aParamList.AppendL( param );
+    }
+
+#ifdef RD_SCALABLE_UI_V2
+#ifndef RD_MSG_NAVIPANE_IMPROVEMENT
+
+// -----------------------------------------------------------------------------
+// handles the touch-ui related control events for next/previous message
+// -----------------------------------------------------------------------------
+//
+void CMsgSmsViewerAppUi::HandleNaviDecoratorEventL( TInt aEventID )     
+    {
+    if( AknLayoutUtils::PenEnabled() &&
+        IsNextMessageAvailableL( aEventID == EAknNaviDecoratorEventRightTabArrow ) )
+        {
+        /* no need for separate checks for right and left arrows
+            because IsNextMessageAvailableL() and NextMessageL
+            are called with the truth-value of the same comparison */
+        NextMessageL( aEventID == EAknNaviDecoratorEventRightTabArrow );
+        }
+    }
+#else
+void CMsgSmsViewerAppUi::HandleNaviDecoratorEventL( TInt /* aEventID */)
+    {
+    }       
+#endif // !RD_MSG_NAVIPANE_IMPROVEMENT
+#else
+void CMsgSmsViewerAppUi::HandleNaviDecoratorEventL( TInt /* aEventID */)
+    {
+    }
+#endif
+
+#ifdef RD_MSG_FAST_PREV_NEXT
+// ----------------------------------------------------
+//  CMsgSmsViewerAppUi::CanFastOpenL
+// ----------------------------------------------------
+TBool CMsgSmsViewerAppUi::CanFastOpenL( const CMessageIterator& aIterator )
+    {
+    // Only sms messages can be fast opened. Bio message open is performed
+    // using bio mtm-server which parses the message before viewer is opened.
+    // Picture and configuration bio-messages seem to work without parsing by
+    // bio mtm-server. Vcards however do not work as there is no vcard attachment
+    // expected by the viewer unless message is parsed by the server first.
+    // Also, allow fast open only if currently sms is open. This ensures that
+    // the viewer is entered through sms mtm ui and before sms messages are viewed
+    // (CSmsMtmUi::CheckAndEnsureSmsServiceOkL() is executed).
+    TBool retVal = EFalse;
+    TMsvEntry msvEntry = Document()->Entry();
+    if( msvEntry.iMtm.iUid == KSenduiMtmSmsUidValue &&
+        aIterator.CurrentMessage().iMtm.iUid == KSenduiMtmSmsUidValue &&
+        !msvEntry.iBioType )
+        {
+        retVal = ETrue;
+        }
+    return retVal;
+    }
+#endif
+
+// ---------------------------------------------------------
+// OfferToolbarEventL
+// ---------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CMsgSmsViewerAppUi::OfferToolbarEventL( TInt aCommand )
+    {
+    switch ( aCommand )
+        {
+        case ESmsViewerToolbarReply:
+                HandleCommandL( ESmsViewerReplyViaMessage );
+            break;
+        case ESmsViewerToolbarForward:
+            HandleCommandL( ESmsViewerForward );
+            break;
+        case ESmsViewerToolbarDelete:
+            HandleCommandL( ESmsViewerDelete );
+            break;
+        }
+    }
+
+#endif
+
+// ---------------------------------------------------------
+// CAudioMessageAppUi::HandleResourceChangeL
+// ---------------------------------------------------------
+//
+
+void CMsgSmsViewerAppUi::HandleResourceChangeL( TInt aType )
+    {
+     // Base class call must be first
+    CMsgEditorAppUi::HandleResourceChangeL(aType);
+    
+    if ( aType == KAknsMessageSkinChange )
+        {
+        if ( iAppIcon )
+            {
+            delete iAppIcon;
+            iAppIcon = NULL;
+            }
+    
+        // Set path of bitmap file
+  	    TParse fileParse;
+  	    fileParse.Set( KSmsBitmapFileName, &KDC_APP_BITMAP_DIR, NULL );
+    
+        iAppIcon = AknsUtils::CreateGulIconL( 
+            AknsUtils::SkinInstance(), 
+            KAknsIIDQgnPropMceSmsTitle,
+            fileParse.FullName(),
+            EMbmMuiuQgn_prop_mce_sms_title,
+            EMbmMuiuQgn_prop_mce_sms_title_mask );
+        SetTitleIconL();   
+        }
+     
+    }
+
+
+// ---------------------------------------------------------
+// CAudioMessageAppUi::SetTitleIconL
+// ---------------------------------------------------------
+//
+void CMsgSmsViewerAppUi::SetTitleIconL()
+    {
+    SetTitleIconSize();
+    
+    // Create duplicates of the icon to be used
+    CFbsBitmap* bitmap = new( ELeave ) CFbsBitmap();
+    CleanupStack::PushL( bitmap );
+    //SetTitleIconSizeL(bitmap);
+    
+    
+    CFbsBitmap* bitmapMask = new( ELeave ) CFbsBitmap();
+    CleanupStack::PushL( bitmapMask );
+    
+    User::LeaveIfError( bitmap->Duplicate( iAppIcon->Bitmap()->Handle() ) );
+    User::LeaveIfError( bitmapMask->Duplicate( iAppIcon->Mask()->Handle() ) );
+    
+    CAknTitlePane* iTitlePane = STATIC_CAST( 
+            CAknTitlePane*, 
+            StatusPane()->ControlL( TUid::Uid( EEikStatusPaneUidTitle )));
+
+    iTitlePane->SetSmallPicture( bitmap, bitmapMask, ETrue );
+    iTitlePane->DrawNow();
+    
+    CleanupStack::Pop( bitmapMask );
+    CleanupStack::Pop( bitmap );
+    }
+
+
+// ---------------------------------------------------------
+// CAudioMessageAppUi::SetTitleIconSize
+//
+// Sets the correct size from LAF for title icon
+// ---------------------------------------------------------
+//
+void CMsgSmsViewerAppUi::SetTitleIconSize()
+    {
+    TRect mainPane;
+    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::ETitlePane, mainPane );
+    TAknLayoutRect titleIconPaneLayoutRect;
+    
+    if ( AknStatuspaneUtils::StaconPaneActive() )
+        {
+        titleIconPaneLayoutRect.LayoutRect( 
+            mainPane,
+            AknLayoutScalable_Avkon::title_pane_stacon_g1( 0 ).LayoutLine() );
+        }
+    else
+        {
+        titleIconPaneLayoutRect.LayoutRect( 
+            mainPane,
+            AknLayoutScalable_Avkon::title_pane_g2( 0 ).LayoutLine() );
+        }
+    
+    TSize iconSize = titleIconPaneLayoutRect.Rect().Size();
+    AknIconUtils::SetSize( iAppIcon->Bitmap(), iconSize, EAspectRatioPreserved );
+    }    
+    
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::EditorObserver
+// ---------------------------------------------------------
+//
+void CMsgSmsViewerAppUi::EditorObserver( TMsgEditorObserverFunc aFunc, TAny* aArg1,
+  TAny* aArg2, TAny* aArg3 )
+    {
+    TRAP_IGNORE( DoEditorObserverL( aFunc,aArg1,aArg2,aArg3 ) );
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::DoEditorObserverL
+// ---------------------------------------------------------
+//
+void CMsgSmsViewerAppUi::DoEditorObserverL( TMsgEditorObserverFunc aFunc, TAny* aArg1,
+  TAny* aArg2, TAny*/* aArg3*/ )
+    {
+    
+        switch ( aFunc )
+        {
+         	    
+#ifdef RD_SCALABLE_UI_V2	    
+	    case MMsgEditorObserver::EMsgControlPointerEvent:
+            {
+           	CMsgBaseControl* control = static_cast<CMsgBaseControl*>( aArg1 );
+            if(control)
+	          	{
+	            	TInt id = control->ControlId();	            
+								if(id == EMsgComponentIdFrom && iFlags.iValidSenderNumber)
+									{     
+									//disable dialer
+									iAvkonAppUi->SetKeyEventFlags( 
+				    					CAknAppUiBase::EDisableSendKeyShort | 
+				    					CAknAppUiBase::EDisableSendKeyLong ); 								
+									}
+								else            
+									{
+	                	//enable dialer
+									iAvkonAppUi->SetKeyEventFlags( 0x00);
+									}
+	            	}
+            }
+ 		break;
+        
+#endif //RD_SCALABLE_UI_V2  
+			default:
+				break;         
+        }
+ 
+    }  
+
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::QuicklaunchViewL
+// This is quick launch based on already existing view. Hence this function should  
+// be called only for Proper SMS Text message for fast and optimized navigation.
+// In case called for any bio-type messages, this will leave with KErrCancel so that 
+// caller will TRAP the leave and call LaunchViewL() for complete launch.
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::QuicklaunchViewL()
+    {
+    CAknInputBlock::NewLC();
+    
+    /* Reset iFullyConstructed to false to avoid any irrational behaviours during quick launch
+     * And set back to true at the end of this function
+     */
+    iFullyConstructed = EFalse;
+
+    // get hands on entry
+    const CMsgSmsViewerDocument* doc = Document();
+    TMsvEntry msvEntry = doc->Entry();
+    if ( msvEntry.iBioType )
+        {
+        /* If in case, any bio SMS while fast navigation, then leave immediately, so that MCE will 
+         * handle the navigation.
+         * Leave with correct code, so that MsgEditorAppUi will perform the appropriate action to 
+         * ensure the next/prev entry is launched from MCE.
+         */
+        User::Leave( KErrCancel );
+        }
+    
+    /* Reset all the necessary flags before proceeding further
+     * Other flags are either feature support types or based on bio-SMS types and hence 
+     * no need to set/reset here
+     */
+    iFlags.iIsEmailMessage = EFalse;
+    iFlags.iValidSenderNumber = EFalse;
+    iFlags.iVoIPNumber = EFalse;
+    SetAutomaticHighlightL( EFalse );
+    
+    // Getting sender/receiver to From/To-field
+    // (just copies the content of iDetails to To/From-field,
+    // should work also with IR-messages...)
+
+    //Copy only 50 chars with extremely long names
+    iRecipientstring = msvEntry.iDetails.Left( KPhCltNameBufferLength );  
+
+    __ASSERT_DEBUG(msvEntry.Id() != 
+         KMsvNullIndexEntryId, Panic( EMsgSmsNoMessage ));
+
+    // Instead of using Sms Mtm, load the entry's values
+    // using store. This is because Sms Viewer is also used
+    // by bio messages and then sms mtm can't be used...
+    CPlainText* nullString = CPlainText::NewL();
+    CleanupStack::PushL( nullString );
+    delete iSmsHeader;
+    iSmsHeader = CSmsHeader::NewL( CSmsPDU::ESmsDeliver, *nullString );
+    CMsvStore* store = doc->CurrentEntry().ReadStoreL();
+    CleanupStack::PushL(store);
+
+    // This TRAPping is needed to find out if the entry's store has
+    // KUidMsvSMSHeaderStream. If it hasn't, we're most propably dealing
+    // with non sms message and we can assume it is received message.
+    TRAPD( err, iSmsHeader->RestoreL( *store ));
+
+    // Check if we are dealing with E-mail sms message
+    // We use TP-PID as the only validation rule
+    CSmsPDU& pdu = iSmsHeader->Message().SmsPDU();
+    if( pdu.ProtocolIdentifierPresent() )
+        {
+        if( pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking &&
+            pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice &&
+            pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail )
+            {
+            iFlags.iIsEmailMessage = ETrue;
+            }
+        }
+
+    if (err == KErrNone)
+        {
+        /* Yes, it is sms based message.
+         * Quick SMS msg handler shall set the body text and required control field without adding/removing
+         *  any controls everytime unless required(if absent/present across different messages).
+         */
+        QuickSmsMsgNaviHandlingL( store );
+        }
+    else
+        {
+        /* Something wrong. Ideally this part of the code should not be hit. 
+         * This is not a sms and sms pdu can't be checked. 
+         * However this is most propably _received_ IR or BT message.
+         */
+        iFlags.iIrBt = ETrue;
+        iControlId = EMsgComponentIdFrom;
+        }
+    CleanupStack::PopAndDestroy( 2 ); //store, nullString
+
+    // Fill address ctrl
+    if ( !iFlags.iIsEmailMessage && KErrNotFound != iNumber.Match( iRecipientstring ) )
+        {
+        iRecipientstring = KNullDesC;
+        }
+
+    CMsgBaseControl* addressBase = iView->ControlById( iControlId );
+    CMsgAddressControl* addressControl = STATIC_CAST( CMsgAddressControl*, addressBase );
+
+    MVPbkContactLink* link= NULL;
+    addressControl->Reset();
+    addressControl->AddRecipientL( 
+        iRecipientstring,
+        iNumber,
+        ETrue,
+        link );
+
+    // Message indication ( e.g. 2/32 )
+#ifdef RD_MSG_NAVIPANE_IMPROVEMENT
+    // Fetch pointer to the default navi pane control
+    iNaviPane = static_cast<CAknNavigationControlContainer*>
+        ( StatusPane( )->ControlL(  TUid::Uid( EEikStatusPaneUidNavi ) ) );
+     
+    if( !iNaviDecorator )
+        {
+        CreateViewerNaviPaneL( Document()->Entry().iDate, EMsgEditorMsgPriorityNormal, ETrue );    
+        iNaviPane->PushL( *iNaviDecorator );  // <- This has nothing to do with cleanup-stack!    
+        }
+    else
+        {
+        //We end up here when fast msg opening is enabled
+        CMsgNaviPaneControl* naviControl = static_cast<CMsgNaviPaneControl*>
+            ( iNaviDecorator->DecoratedControl() );
+        naviControl->SetTimeIndicatorL( Document()->Entry().iDate, ETrue );
+        naviControl->SetNavigationIndicatorL( Document()->Session(), Document()->Entry() );
+        }
+
+#else
+    UpdateNaviPaneL();
+#endif
+    //remove buttons from navipane
+    if( iNaviDecorator && iClass0CBA )
+        {
+        iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ELeftButton, ETrue );
+        iNaviDecorator->SetScrollButtonDimmed( CAknNavigationDecorator::ERightButton, ETrue );
+        }
+
+#ifdef RD_SCALABLE_UI_V2
+    if ( AknLayoutUtils::PenEnabled() )
+        {
+        if ( iToolbar )
+            {
+            //What buttons to dim
+            switch ( iSmsHeader->Type() )
+                {                    
+                //Received Message(Inbox navigation)
+                case CSmsPDU::ESmsDeliver:
+                    {
+                    //Dim reply item if sender is unknown
+                    if (msvEntry.iDetails.Length() == 0 || !iFlags.iValidSenderNumber )
+                        {
+                        iToolbar->SetItemDimmed(ESmsViewerToolbarReply, ETrue, ETrue);
+                        }
+                    else
+                        {
+                        iToolbar->SetItemDimmed(ESmsViewerToolbarReply, EFalse, ETrue);
+                        }
+                    
+                    break;
+                    }
+                
+                //Sent Message (Sent folder navigation)
+                case CSmsPDU::ESmsSubmit:
+                    {
+                    //Dim the reply button, we would be replying to ourselves
+                    iToolbar->SetItemDimmed(ESmsViewerToolbarReply, ETrue, ETrue);
+                    break;
+                    }
+
+                default:
+                    {
+                    Panic( EMsgSmsViewerUnknownSmsPduType );
+                    break;
+                    }
+                }   // Switch
+            }   // if ( iToolbar )
+        }     // if ( AknLayoutUtils::PenEnabled() )
+#endif /* RD_SCALABLE_UI_V2 */
+    //Reset the focus to "from address" feild
+    iView->SetFocus( iControlId );
+    
+    // Set the state of automatic highlighting for sms
+    SetAutomaticHighlightL( iFlags.iAutomaticHlValue );
+    
+    iFullyConstructed = ETrue;
+    CleanupStack::PopAndDestroy();// CAknInputBlock
+    }
+
+// ---------------------------------------------------------
+// CMsgSmsViewerAppUi::QuickSmsMsgNaviHandlingL
+// This will set the body text and update the control fields if any changes
+// as compared to previous SMS message. 
+// This function is called only for non-bio text messages for fast preview during navigation
+// ---------------------------------------------------------
+void CMsgSmsViewerAppUi::QuickSmsMsgNaviHandlingL( CMsvStore* aStore )
+    {
+    // Initialize the richtext object...
+    CParaFormatLayer* paraFormat = iEikonEnv->SystemParaFormatLayerL(); // <- pointer only
+    CCharFormatLayer* charFormat = iEikonEnv->SystemCharFormatLayerL(); // <- pointer only
+    CRichText* textBody = CRichText::NewL( paraFormat, charFormat );
+    CleanupStack::PushL( textBody );
+    // ...and read bodytext
+    aStore->RestoreBodyTextL( *textBody );
+    
+    // message is ordinary sms message
+    // so, let's get message body to viewer. 
+    CMsgBaseControl* baseControl = iView->ControlById( EMsgComponentIdBody );
+    CMsgBodyControl* bodyControl = STATIC_CAST( CMsgBodyControl*, baseControl );
+    
+    CMsgTextUtils::ConvertLineBreaksL( *textBody, CMsgTextUtils::ECRLFtoLF );
+	//First resetting the body control content
+    bodyControl->Reset();
+    // Set body text and update the screen
+    bodyControl->SetTextContentL( *textBody );
+    bodyControl->SetPlainTextMode( ETrue );
+    bodyControl->SetCursorPosL( 0 );
+    bodyControl->DrawNow();
+    CleanupStack::PopAndDestroy(); //textBody
+    
+    // Class 0 handling...
+    TSmsDataCodingScheme::TSmsClass smsClass;
+    if ( iSmsHeader->Message().SmsPDU().Class( smsClass ) 
+        && smsClass == TSmsDataCodingScheme::ESmsClass0 )
+        {
+        // Create new softkeys
+        iClass0CBA = Cba(); // <- pointer only
+        if (iClass0CBA) 
+            { // iClass0CBA shouldn't be NULL, but if....
+            iClass0CBA->SetCommandSetL( R_SMSVIEWER_CLASS0_SOFTKEYS_OPTIONS_EXIT__CONTEXTOPTIONS );  
+            //Middle softkey
+            MenuBar()->SetContextMenuTitleResourceId( R_SMSV_OPTIONSCONTEXTMENUBAR_CLASS0 );           
+            MenuBar()->SetMenuTitleResourceId( R_SMSV_OPTIONSMENUBAR_CLASS0 );        
+            MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions);     
+            }
+        }
+    else if ( iClass0CBA ) 
+        {
+        //menubar and CBA is reset to the default resource. 
+        //if iClass0CBA is not NULL, then resource id has been changed, hence needs to be reset 
+        //setting the CBA to default
+        iClass0CBA->SetCommandSetL( R_SMSVIEWER_SOFTKEYS_OPTIONS_BACK__CONTEXTOPTIONS );
+        //Since CBA is set to default iClass0CBA is set NULL
+        iClass0CBA = NULL; 
+        //Setting the menubar to default
+        MenuBar()->SetContextMenuTitleResourceId( R_SMSV_CONTEXTMENUBAR  );           
+        MenuBar()->SetMenuTitleResourceId( R_SMSV_OPTIONSMENUBAR );        
+        MenuBar()->SetMenuType(CEikMenuBar::EMenuOptions);
+        }
+    
+    // Deciding between To/From text in address control
+    const CSmsPDU::TSmsPDUType pduType = iSmsHeader->Type();
+    switch ( pduType )
+        {
+        case CSmsPDU::ESmsDeliver:
+            {
+            // Setting from-control
+            iControlId = EMsgComponentIdFrom;
+            if(pduType!= iTypeMsg)
+                {
+                	iView->DeleteControlL(EMsgComponentIdTo);
+                	iView->AddControlFromResourceL( 
+                	R_SMSV_FROM, 
+                	EMsgAddressControl, 
+                	EMsgAppendControl, 
+                	EMsgHeader );
+                }            
+            // take the number and verify it
+            iNumber = iSmsHeader->FromAddress();
+            if ( !iFlags.iIsEmailMessage )
+                {
+                iFlags.iValidSenderNumber = CommonPhoneParser::IsValidPhoneNumber(
+                    iNumber, CommonPhoneParser::ESMSNumber );
+
+                if( !iFlags.iValidSenderNumber && iMsgVoIPExtension->IsVoIPSupported() )
+                    {
+                    if( MsvUiServiceUtilities::IsValidEmailAddressL( iNumber ) )
+                        {
+                        iFlags.iValidSenderNumber = ETrue;
+                        iFlags.iVoIPNumber = ETrue;
+                        }
+                    }
+                
+                // Replypath indication
+                CMsgExpandableControl* replyPathControl = STATIC_CAST(CMsgExpandableControl*,
+                        iView->ControlById(EMsgComponentIdCc));
+                if ( iSmsHeader->Deliver().ReplyPath() )
+                    {
+                    if( !replyPathControl )
+                        {
+                        iView->AddControlFromResourceL( 
+                            R_SMSV_REPLYPATH, 
+                            EMsgExpandableControl, 
+                            EMsgAppendControl, 
+                            EMsgHeader );
+                        }
+                
+                    HBufC* text = StringLoader::LoadLC( R_QTN_SMS_HEADING_REPLY_PATH, iCoeEnv );
+                    CRichText& replyPath = STATIC_CAST(CMsgExpandableControl*, 
+                        iView->ControlById(EMsgComponentIdCc))->TextContent();
+                    replyPath.Reset();
+                    replyPath.InsertL( 0, *text ); 
+                    CleanupStack::PopAndDestroy(); // text
+                    }
+                else if( replyPathControl )
+                    {
+                    // No reply path in curr SMS, if there was one in prev, remove the control
+                    iView->DeleteControlL( EMsgComponentIdCc );
+                    }
+                }
+            else
+                {
+                iFlags.iValidSenderNumber =
+                    MsvUiServiceUtilities::IsValidEmailAddressL(
+                        iRecipientstring );
+                }
+            }
+            break;
+        case CSmsPDU::ESmsSubmit:
+            // Setting To-control
+            iControlId = EMsgComponentIdTo;
+            if(pduType!= iTypeMsg)
+              {
+                iView->DeleteControlL(EMsgComponentIdFrom);
+                iView->AddControlFromResourceL( 
+                R_SMSV_TO, 
+                EMsgAddressControl, 
+                EMsgAppendControl, 
+                EMsgHeader );
+              }            
+            // take the number
+            iNumber = iSmsHeader->FromAddress();
+            break;
+        default:
+#if defined ( _DEBUG )
+            Panic( EMsgSmsViewerUnknownSmsPduType );
+#else
+            User::Leave( KErrNotSupported );
+#endif
+            break;
+        }
+    // If we are dealing with Email message
+    // we add subject control for Email type subject
+    if ( iFlags.iIsEmailMessage )
+        {
+        TPtrC subj( iSmsHeader->EmailFields().Subject() );
+        if ( subj.Length() )
+            {
+            // Add subject control if not present
+            AddSubjectControlL();
+            // Set the Subject field text accordigly
+            SetSubjectL( subj );
+            }
+        }
+    else if( iFlags.iEmailSubjectControlPresent  && SubjectControl() )
+        {
+        //remove subject control if in case prev messages is email over SMS message with subject
+        iView->DeleteControlL( EMsgComponentIdSubject );
+        iFlags.iEmailSubjectControlPresent = EFalse;
+        }
+    iTypeMsg = pduType; //for successful launch save the PDU Type.
+    }
+
+//  End of File