diff -r 6385c4c93049 -r 8e6fa1719340 pushmtm/ViewerSrc/PushViewerMsgEdAppUi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pushmtm/ViewerSrc/PushViewerMsgEdAppUi.cpp Wed Sep 01 12:31:04 2010 +0100 @@ -0,0 +1,677 @@ +/* +* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: Application Ui member definitions. +* +*/ + + + +// INCLUDE FILES + +#include "PushViewerMsgEdAppUi.h" +#include "PushViewerDoc.h" +#include "PushViewerDef.h" +#include "PushViewerPanic.h" +#include "PushMtmUtil.h" +#include "PushViewer.hrh" +#include "PushMtmLog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __SERIES60_HELP +// Context-Sensitve Help File +#include +#include +#endif // __SERIES60_HELP + +#include "eikon.hrh" + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::CPushViewerMsgEdAppUi +// --------------------------------------------------------- +// +CPushViewerMsgEdAppUi::CPushViewerMsgEdAppUi() + { + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::~CPushViewerMsgEdAppUi +// --------------------------------------------------------- +// +CPushViewerMsgEdAppUi::~CPushViewerMsgEdAppUi() + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::~CPushViewerMsgEdAppUi") + delete iView; + iView = NULL; + delete iContext; + iContext = NULL; + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::~CPushViewerMsgEdAppUi") + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::ConstructL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::ConstructL() + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::ConstructL") + + CMsgEditorAppUi::ConstructL(); + + if ( !iEikonEnv->StartedAsServerApp( ) ) + { + // If the app was not started as server app, + // we can call PrepareLaunchL + Document()->PrepareToLaunchL( this ); + } + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::ConstructL") + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::ConstructBodyTextL +// --------------------------------------------------------- +// +TInt CPushViewerMsgEdAppUi::ConstructBodyTextL + ( CMsgBodyControl& aBodyControl1, CMsgBodyControl& aBodyControl2 ) const + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::ConstructBodyTextL"); + + HBufC* staticText = iEikonEnv->AllocReadResourceLC + ( R_PUSHVIEWER_MAINPANE_TEXT ); + + TPtrC renderedTextPtr( *staticText ); // Static text by default. + TPtrC renderedHrefPtr( KNullDesC ); + + if ( Model().PushMsgType() == KUidWapPushMsgSI.iUid ) + { + CSIPushMsgEntry* si = STATIC_CAST( CSIPushMsgEntry*, &Model() ); + + const TPtrC text = si->Text(); + if ( text.Length() ) + { + renderedTextPtr.Set( text ); + } + else + { + renderedTextPtr.Set( *staticText ); + } + + const TPtrC url = si->Url(); + if ( url.Length() ) + { + renderedHrefPtr.Set( url ); + } + } + else if ( Model().PushMsgType() == KUidWapPushMsgSL.iUid ) + { + CSLPushMsgEntry* sl = STATIC_CAST( CSLPushMsgEntry*, &Model() ); + + const TPtrC url = sl->Url(); + if ( url.Length() ) + { + renderedHrefPtr.Set( url ); + } + } + else + { + User::Leave( KErrNotSupported ); + } + + // The message goes to the first body control by default, but + // if it does not fit into one screen, then first comes the href. + + aBodyControl1.InsertTextL( renderedTextPtr ); + + CMsgBodyControl* controlContainingTheUrl = NULL; + TInt indexOfHrefControl = KErrNotFound; + + // Add the href + if ( renderedHrefPtr.Length() == 0 ) + { + // No href. + controlContainingTheUrl = NULL; + iAvkonAppUi->Cba()->SetCommandSetL( R_PUSHVIEWER_SOFTKEYS ); + iAvkonAppUi->Cba()->DrawNow(); + } + else + { + aBodyControl2.InsertTextL( renderedHrefPtr ); + controlContainingTheUrl = &aBodyControl2; + indexOfHrefControl = 1; // Zero based. + } + + aBodyControl1.SetPlainTextMode( ETrue ); + aBodyControl2.SetPlainTextMode( ETrue ); + + // Switch on URL highlighting. We use FindItem for it - + // otherwise Find Item has no other role! + if ( controlContainingTheUrl != NULL ) + { + if ( controlContainingTheUrl->ItemFinder() ) + { + controlContainingTheUrl-> + ItemFinder()->SetFindModeL( CItemFinder::EUrlAddress ); + controlContainingTheUrl-> + SetupAutomaticFindAfterFocusChangeL( ETrue ); + } + controlContainingTheUrl->Editor().SetAlignment( EAknEditorAlignCenter ); + } + + CleanupStack::PopAndDestroy( staticText ); // staticText + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::ConstructBodyTextL"); + return indexOfHrefControl; + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::ConstructViewL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::ConstructViewL() + { + CMsgEditorView* newView = CMsgEditorView::NewL + ( *this, CMsgEditorView::EMsgReadOnly ); + delete iView; + iView = newView; + + // Let two body controls: one for the message text and one for the Href + + // There is already one by default - get a pointer to it. + CMsgBodyControl* bodyControl1 = REINTERPRET_CAST( CMsgBodyControl*, + iView->ControlById( EMsgComponentIdBody ) ); + + // Create the second: + CMsgBodyControl* bodyControl2 = CMsgBodyControl::NewL( iView ); + CleanupStack::PushL( bodyControl2 ); + iView->AddControlL( bodyControl2, + /*aControlId*/EMyMsgComponentIdBody, + /*aIndex*/1, + /*aFormComponent*/EMsgBody ); + CleanupStack::Pop( bodyControl2 ); // bodyControl2 + + TInt indexOfHrefControl = ConstructBodyTextL( *bodyControl1, *bodyControl2 ); + + // Construct the view. + TInt controlIdForFocus = indexOfHrefControl==1?EMyMsgComponentIdBody:EMsgComponentIdBody; + iView->ExecuteL( ClientRect(), controlIdForFocus ); + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::HandleKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CPushViewerMsgEdAppUi::HandleKeyEventL + ( const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + PUSHLOG_WRITE_FORMAT + ("CPushViewerMsgEdAppUi::HandleKeyEventL <%d>",aKeyEvent.iCode) + // Check for iView and iContext objects are created before Handle + if ( (NULL == iView) || (NULL == iContext) ) + { + return (EKeyWasConsumed); + } + + if ( aType == EEventKey ) + { + switch ( aKeyEvent.iCode ) + { + + case EKeyDevice3: + { + // Selection key pressed. Behave as "Load service" if there is + // service to download. + const TMsvEntry& context = Model().Entry(); + if ( CPushMtmUtil::Attrs( context ) & EPushMtmAttrHasHref ) + { + HandleCommandL( EPushViewerCmdLoadService ); + } + break; + } + + case EKeyLeftUpArrow: // Northwest + case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyLeftArrow: // West + case EKeyLeftDownArrow: // Southwest + case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge + { + HandleCommandL( EPushViewerCmdPreviousMessage ); + break; + } + + case EKeyRightUpArrow: // Northeast + case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyRightArrow: // East + case EKeyRightDownArrow: // Southeast + case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge + { + HandleCommandL( EPushViewerCmdNextMessage ); + break; + } + + case EKeyBackspace : + { + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + if ( dlg->ExecuteLD + ( R_PUSHVIEWER_ENTRY_DELETE_CONFIRM ) == EAknSoftkeyYes ) + { + DeleteAndExitL(); + } + break; + } + + default: + { + iView->OfferKeyEventL( aKeyEvent, aType ); + break; + } + + } + } + + return EKeyWasConsumed; + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::DynInitMenuPaneL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::DynInitMenuPaneL( TInt aMenuId, + CEikMenuPane* aMenuPane ) + { + if ( aMenuId == R_PUSHVIEWER_OPTIONS_MENU_PANE ) + { + // Remove EPushViewerCmdLoadService if the current message + // does not contain URL. + CPushMsgEntryBase& modelBase = Model(); + if ( Model().PushMsgType() == KUidWapPushMsgSI.iUid ) + { + CSIPushMsgEntry& si = (CSIPushMsgEntry&)modelBase; + if ( !si.Url().Length() ) + { + aMenuPane->DeleteMenuItem( EPushViewerCmdLoadService ); + Cba()->SetCommandSetL( R_PUSHVIEWER_SOFTKEYS ); + } + } + else if ( Model().PushMsgType() == KUidWapPushMsgSL.iUid ) + { + CSLPushMsgEntry& sl = (CSLPushMsgEntry&)modelBase; + __ASSERT_DEBUG( sl.Url().Length() != 0, + ViewerPanic( EPushViewerPanSlEmptyHref ) ); + if ( !sl.Url().Length() ) + { + aMenuPane->DeleteMenuItem( EPushViewerCmdLoadService ); + Cba()->SetCommandSetL( R_PUSHVIEWER_SOFTKEYS ); + } + } + } + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::Model +// --------------------------------------------------------- +// +CPushMsgEntryBase& CPushViewerMsgEdAppUi::Model() const + { + PUSHLOG_WRITE_FORMAT("CPushViewerMsgEdAppUi::Model <%x>",iContext) + return *iContext; + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::PushDoc +// --------------------------------------------------------- +// +CPushViewerDocument& CPushViewerMsgEdAppUi::PushDoc() const + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::PushDoc") + return REINTERPRET_CAST( CPushViewerDocument&, *Document() ); + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::PushDoc") + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::UpdateNaviPaneL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::UpdateNaviPaneL() + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::UpdateNaviPaneL") + + CEikImage* image = new (ELeave) CEikImage; + CleanupStack::PushL( image ); + + // Read image from resource. + // + TResourceReader reader; + iCoeEnv->CreateResourceReaderLC( reader, R_PUSHVIEWER_NAVI_IMAGE ); + image->ConstructFromResourceL( reader ); + CleanupStack::PopAndDestroy(); // reader + + CMsgEditorAppUi::UpdateNaviPaneL( image->Bitmap(), image->Mask() ); + image->SetPictureOwnedExternally( ETrue ); + + CleanupStack::PopAndDestroy(); // image + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::UpdateNaviPaneL") + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::IsExpired +// --------------------------------------------------------- +// +TBool CPushViewerMsgEdAppUi::IsExpired() + { + TBool ret( EFalse ); + + if ( Document()->Entry().iBioType == KUidWapPushMsgSI.iUid ) + { + CSIPushMsgEntry* si = STATIC_CAST( CSIPushMsgEntry*, iContext ); + // Check expiration if expiration time was set. + if ( si->Expires() != Time::NullTTime() ) + { + TTime today; + today.UniversalTime(); + if ( si->Expires() < today ) + { + ret = ETrue; + } + } + } + + return ret; + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::DoMsgSaveExitL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::DoMsgSaveExitL() + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::DoMsgSaveExitL"); + + Exit( EAknSoftkeyBack ); + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::DoMsgSaveExitL") + }; + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::NotifyAndExitL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::NotifyAndExitL( TInt aResId ) + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::NotifyAndExitL"); + + HBufC* noteText = iCoeEnv->AllocReadResourceLC( aResId ); + CAknInformationNote* note = new (ELeave) CAknInformationNote( ETrue ); + note->ExecuteLD( *noteText ); + CleanupStack::PopAndDestroy( noteText ); // noteText + + // Close the application. + if ( !IsAppShutterRunning() ) + { + PUSHLOG_WRITE(" RunAppShutter") + RunAppShutter(); + } + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::NotifyAndExitL"); + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::LaunchViewL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::LaunchViewL() + { + __ASSERT_ALWAYS( Document()->Entry().iMtm == KUidMtmWapPush, + ViewerPanic( EPushViewerPanBadMtmType ) ); + + // Construct model. + CPushMsgEntryBase* newContext = NULL; + const TInt32 bioType( Document()->Entry().iBioType ); + + if ( bioType == KUidWapPushMsgSI.iUid ) + { + newContext = CSIPushMsgEntry::NewL(); + } + else if ( bioType == KUidWapPushMsgSL.iUid ) + { + newContext = CSLPushMsgEntry::NewL(); + } + else if ( bioType == KUidWapPushMsgMultiPart.iUid ) + { +#ifdef __TEST_MULTIPART_SUPP + newContext = CMultiPartPushMsgEntry::NewL(); +#else // __TEST_MULTIPART_SUPP + User::Leave( KErrNotSupported ); +#endif // __TEST_MULTIPART_SUPP + } + else + { + __ASSERT_DEBUG( EFalse, ViewerPanic( EPushViewerPanBadPushType ) ); + User::Leave( KErrNotSupported ); + } + + CleanupStack::PushL( newContext ); + newContext->RetrieveL( Document()->Session(), Document()->Entry().Id() ); + delete iContext; + iContext = NULL; + iContext = newContext; + CleanupStack::Pop( newContext ); // newContext + + // Construct view. + UpdateNaviPaneL(); + ConstructViewL(); + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::HandleEntryChangeL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::HandleEntryChangeL() + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::HandleEntryChangeL"); + + + // We have to act only in case of such changes where the content + // of the message changes, not only the unread/read flag. + // The content handlers and the Push subsystem behave so that + // the content is changed only when the entry becomes 'unread', + // except one case where the CH changes the content, but the + // message becomes 'read' (SL-execute-high). In this case + // a flag indicates that the content was changed. + + // Get an up-to-date entry and check the necessary flags: + TMsvEntry tEntry; + TMsvId service; + TMsvId entryId = Document()->Entry().Id(); + CMsvSession& msvSession = Document()->Session(); + User::LeaveIfError( msvSession.GetEntry( entryId, service, tEntry ) ); + TBool isChangeToUnread = tEntry.Unread(); + TBool contentChangedFlagSet = + CPushMtmUtil::Attrs( tEntry ) & EPushMtmReadButContentChanged; + + if ( !isChangeToUnread && !contentChangedFlagSet ) + { + // Nothing to do. Somebody just set it as read. + PUSHLOG_WRITE(" Content not changed"); + } + else + { + // Show note about the message changes & close the application. + NotifyAndExitL( R_PUSHVIEWER_INFO_REPLACED ); + } + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::HandleEntryChangeL") + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::HandleEntryDeletedL +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::HandleEntryDeletedL() + { + PUSHLOG_ENTERFN("CPushViewerMsgEdAppUi::HandleEntryDeletedL"); + // Check for iView and iContext objects are created before Handle + if ( (NULL == iView) || (NULL == iContext)) + { + return; + } + // Show note about the message deletion & close the application. + NotifyAndExitL( R_PUSHVIEWER_INFO_DELETED ); + + PUSHLOG_LEAVEFN("CPushViewerMsgEdAppUi::HandleEntryDeletedL") + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::GetHelpContextForControl +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::GetHelpContextForControl + ( TCoeHelpContext& /*aContext*/ ) const + { + } + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::HandleCommandL +// See DynInitMenuPaneL() to see which commands are valid +// on a given type of item. +// --------------------------------------------------------- +// +void CPushViewerMsgEdAppUi::HandleCommandL( TInt aCommand ) + { + PUSHLOG_WRITE_FORMAT("CPushViewerMsgEdAppUi::HandleCommandL <%d>",aCommand) + // Check for iView and iContext objects are created before Handle + if ( (NULL == iView) || (NULL == iContext)) + { + return; + } + switch ( aCommand ) + { + case EPushViewerCmdLoadService: + { + if ( IsExpired() ) + { + // The entry is expired. + HBufC* value = + iCoeEnv->AllocReadResourceLC( R_PUSHVIEWER_EXPIRED_NOTE ); + CAknInformationNote* note = + new (ELeave) CAknInformationNote( ETrue ); + note->ExecuteLD( *value ); + CleanupStack::PopAndDestroy( value ); // value + + // Delete the expired message and exit. + DeleteAndExitL(); + } + else + { + PushDoc().IssueLoadServiceL(); + } + break; + } + + case EPushViewerCmdDelete: + { + CAknQueryDialog* dlg = CAknQueryDialog::NewL(); + if ( dlg->ExecuteLD + ( R_PUSHVIEWER_ENTRY_DELETE_CONFIRM ) == EAknSoftkeyYes ) + { + DeleteAndExitL(); + } + break; + } + + case EPushViewerCmdMessageInfo: + { + PushDoc().IssueMessageInfoL(); + break; + } + + case EPushViewerCmdPreviousMessage: + { + if ( IsNextMessageAvailableL( EFalse ) ) + { + NextMessageL( EFalse ); + } + break; + } + + case EPushViewerCmdNextMessage: + { + if ( IsNextMessageAvailableL( ETrue ) ) + { + NextMessageL( ETrue ); + } + break; + } + +#ifdef __SERIES60_HELP + + case EPushViewerCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL + ( iEikonEnv->WsSession(), AppHelpContextL() ); + break; + } + +#endif //__SERIES60_HELP + + case EPushViewerCmdBack: + case EPushViewerCmdExit: + { + DoMsgSaveExitL(); + break; + } + + default: + { + break; + } + } + } + +#ifdef __SERIES60_HELP + +// --------------------------------------------------------- +// CPushViewerMsgEdAppUi::HelpContextL +// --------------------------------------------------------- +// +CArrayFix* CPushViewerMsgEdAppUi::HelpContextL() const + { + CArrayFix* contexts = new (ELeave) CArrayFixFlat( 1 ); + CleanupStack::PushL( contexts ); + TCoeHelpContext help( TUid::Uid( EUidPushViewerApp ), KWPUSH_HLP_VIEWER ); + contexts->AppendL( help ); + CleanupStack::Pop(); // contexts + return contexts; + } + +#endif // __SERIES60_HELP + +// End of file. +