diff -r 000000000000 -r 72b543305e3a mobilemessaging/smsui/viewersrc/MsgSmsViewerAppUi.cpp --- /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 // CAknTitlePane +#include // CEikMenuBar +#include // AknNoteWrappers +#include // Rich text ed +#include // CAknNavigationDecorator +// messaging editors +#include // CMsgBodyControl +#include // CEikRichTextEditor +#include // CMsgEditorView +#include // CMsgAddressControl +#include // CMsgBioBodyControl +#include // smart message type uids +#include // CMsgBioControl +#include // CGmsWrapper +#include +// messaging +#include // CSmsHeader +#include // CSmsClientMtm +#include // CMsgFolderSelectionDialog +#include // CMsvProgressReporterOperation +#include // function id of MessageInfo +#include // MuiuOperationWait +#include +#include +#include +#include // CAknInputBlock +#include // DiskSpaceBelowCriticalLevelL +#include +#include // Local variation flags +#include // SmumUtil +#include // CSmsEmailFields +#include +// phone +#include // Common phone number validity checker +// resources +#include // resouce identifiers +#include // bitmaps +// local +#include "MsgSmsViewer.hrh" // application specific commands +#include "MsgSmsViewerDoc.h" // CMsgSmsViewerDocument +#include "MsgSmsViewerAppUi.h" // CMsgSmsViewerAppUi +// Find item +#include // find item resources +#include // CFindItemMenu +#include // CFindItemDialog +#include +#include +// Creating contact card via AIW +#include // CAiwServiceHandler +#include // AiwContactAssign +// general +#include // StringLoader +#include // FeatureManager +#include +#include +#include // for SendUi +#include +#include +#include +#include +#include +#include + + +// help +#include // sms help context ids +#include +#include // for HlpLauncher + +#include + +#include // for iMsgEditorAppUiExtension +#include + +//Skinnable Title pane icon +#include // AknStatuspaneUtils +#include +#include +#include +#include // title icon +#ifdef RD_MSG_FAST_PREV_NEXT +#include +#endif + +#ifdef RD_SCALABLE_UI_V2 +#include // pen support on navi pane +#include // pen support of volume control of navi pane +#include +#include //Added for touchbar support +#endif +#include // 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( + 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( 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 + ( 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 + ( 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* helpContext = AppHelpContextL(); + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), helpContext ); + } + } + + +// ---------------------------------------------------- +// CMsgSmsViewerAppUi::HelpContextL +// returns help context +// ---------------------------------------------------- +CArrayFix* 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* CMsgSmsViewerAppUi::CreateHelpContextArrayL( const TCoeHelpContext& aHelpContext ) const + { + CArrayFix* r = new(ELeave) CArrayFixFlat(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 + (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 ( 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( 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 + ( 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 + ( 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