--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pushmtm/ViewerSrc/PushViewerMsgEdAppUi.cpp Mon Mar 30 12:49:49 2009 +0300
@@ -0,0 +1,678 @@
+/*
+* 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 <CSIPushMsgEntry.h>
+#include <CSLPushMsgEntry.h>
+#include <PushViewer.rsg>
+#include <aknmessagequerydialog.h>
+#include <AknQueryDialog.h>
+#include <MsgEditorView.h>
+#include <MsgBodyControl.h>
+#include <txtrich.h>
+#include <txtfrmat.h>
+#include <txtfmlyr.h>
+#include <gdi.h>
+#include <bldvariant.hrh>
+#include <eikrted.h>
+#include <barsread.h>
+#include <AknNoteWrappers.h>
+#ifdef __SERIES60_HELP
+// Context-Sensitve Help File
+#include <hlplch.h>
+#include <csxhelp/wpush.hlp.hrh>
+#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<TCoeHelpContext>* CPushViewerMsgEdAppUi::HelpContextL() const
+ {
+ CArrayFix<TCoeHelpContext>* contexts = new (ELeave) CArrayFixFlat<TCoeHelpContext>( 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.
+