--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/bium/src/biou.cpp Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,1368 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: biou implementation
+*
+*/
+
+
+
+
+#include "biou.h" // Class declarations
+#include "bium.pan" // Panic codes
+#include "bium.hrh" // Resource Ids
+
+#include <bium.rsg> // Resources
+#include <apgcli.h>
+#include <eikon.hrh>
+#include <mtmuidef.hrh>
+#include <MTMStore.h>
+#include <msvuids.h> // KUidMsvLocalServiceMtm
+#include <MtmExtendedCapabilities.hrh> // for KMtmUiNewMessageAction...
+#include <Muiumsginfo.h>
+#include <Muiumsginfo.hrh>
+#include <smuthdr.h>
+#include <MuiuMsvUiServiceUtilities.h>
+#include <mmsvattachmentmanagersync.h>
+#include <mmsvattachmentmanager.h>
+#include <biouids.h> // KUidBIOMessageTypeMtm...
+#include <bif.h> // KUidBioUseDefaultApp, KUidBioUseNoApp
+#include <MsgBioUids.h> // KMsgBioUidPictureMsg
+#include <aknnotewrappers.h> // CAknInformationNote
+#include <StringLoader.h> // StringLoader
+#include <mmsgbiocontrol.h>
+#include <textresolver.h>
+#include <gmsModel.h>
+
+
+// Data types
+class TBioData
+ {
+public:
+ TUid iTypeUid;
+ TBool iHasParser;
+ TUid iAppUid;
+ TFileName iEditorFileName;
+ };
+
+// Constants
+_LIT(KBiouMtmUiResourceFile,"bium");
+const TInt KParseAndEditOpPriority = CActive::EPriorityStandard;
+const TInt KArrayGranularity = 8;
+
+const TInt KBiumParserWappLeaveFirst = -617;
+const TInt KBiumParserWappLeaveLast = -601;
+
+// this should always be same as KBspInvalidMessage in bsp.h
+const TInt KBiumParserBspLeave1 = -500;
+
+// this should always be same as KBspSmartMessageInvalidToken in bsp.h
+const TInt KBiumParserBspLeave2 = -501;
+
+const TUid KBiouMtmUiSMSViewerAppUid={0x100058BD}; // Uid for SMS Viewer application
+
+// This is cloned from smuthdr.cpp, KUidMsvSMSHeaderStream
+const TUid KBiumUidMsvSMSHeaderStream = {0x10001834};
+
+// maximum amount of characters used for GSM message subject
+const TInt KMaxSubjectLength = 30;
+
+const TInt KTypeStringLength = 32;
+
+// Reserve 3 chars for ' ', '<' and '>'.
+const TInt KCharacterReserve = 3;
+
+_LIT(KNotDefinedBium,"@todo Not defined. BIUM.");
+
+GLDEF_C void Panic(TBioUiPanic aPanic)
+ {
+ _LIT(KPanicName,"BioUi");
+ User::Panic(KPanicName, aPanic);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::NewL
+// -----------------------------------------------------------------------------
+//
+CBioMtmUi* CBioMtmUi::NewL(CBaseMtm& aBaseMtm,
+ CRegisteredMtmDll& aRegisteredMtmDll)
+ {
+ CBioMtmUi* self=new(ELeave) CBioMtmUi(aBaseMtm, aRegisteredMtmDll);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CBioMtmUi
+// -----------------------------------------------------------------------------
+//
+CBioMtmUi::CBioMtmUi(CBaseMtm& aBaseMtm, CRegisteredMtmDll& aRegisteredMtmDll)
+ : CBaseMtmUi(aBaseMtm, aRegisteredMtmDll)
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::ConstructL()
+ {
+ // --- Make sure base class correctly constructed ---
+ CBaseMtmUi::ConstructL();
+
+ // For Crystal 6.0, msg editors are standalone.
+ // Don't run them embedded, and don't wait for them to exit.
+ iFlags=EMtmUiFlagEditorNoWaitForExit;
+
+ // Read in data from BIF
+ ResetAndLoadBioDataL();
+
+ iErrorResolver = CTextResolver::NewL(*iCoeEnv);
+
+ iBifObserver=CBifChangeObserver::NewL(*this,iCoeEnv->FsSession());
+ iBifObserver->Start();
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::~CBioMtmUi
+// -----------------------------------------------------------------------------
+//
+CBioMtmUi::~CBioMtmUi()
+ {
+ delete iBioData;
+ delete iErrorResolver;
+ if(iBifObserver)
+ {
+ iBifObserver->Cancel();
+ }
+ delete iBifObserver;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ResetAndLoadBioDataL
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::ResetAndLoadBioDataL()
+ {
+ // Reset
+ delete iBioData;
+ iBioData = NULL;
+
+ // --- Load in only the data we need from BioDatabase ---
+ iBioData = new(ELeave) CArrayFixFlat<TBioData>(KArrayGranularity);
+ CBIODatabase* bioDatabase = CBIODatabase::NewLC(iCoeEnv->FsSession());
+ TBioData bioData;
+
+ const TInt bifCount = bioDatabase->BIOCount();
+ iBioData->SetReserveL(bifCount); // this can be left out
+ for(TInt bifIndex = 0;bifIndex<bifCount;bifIndex++)
+ {
+ bioData.iTypeUid = (bioDatabase->BifReader(bifIndex)).MessageTypeUid();
+ bioData.iHasParser = (
+ (bioDatabase->BifReader(bifIndex)).MessageParserName().Length() > 0 ) ?
+ ETrue :
+ EFalse;
+ bioData.iAppUid = (bioDatabase->BifReader(bifIndex)).MessageAppUid();
+ // Only resolve filename when we have to...
+ bioData.iEditorFileName = KNullDesC;
+ iBioData->AppendL(bioData);
+ }
+
+ CleanupStack::PopAndDestroy(bioDatabase); // bioDatabase
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::HandleBifChangeL
+// from MBifChangeObserver
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::HandleBifChangeL(TBifChangeEvent /*aEvent*/, TUid /*aBioId*/)
+ {
+ ResetAndLoadBioDataL();
+ }
+
+//
+// Entry creation
+//
+// Not supported as BIO messages can not be sent.
+CMsvOperation* CBioMtmUi::CreateL(const TMsvEntry& /*aEntry*/,
+ CMsvEntry& /*aParent*/, TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::OpenL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::OpenL(TRequestStatus& aStatus)
+ {
+ //
+ // Validate context
+ CheckEntryL(BaseMtm().Entry().Entry());
+
+ //
+ // Context must be a BIO message, so view it..
+ return ViewL(aStatus);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::OpenL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::OpenL(
+ TRequestStatus& aStatus, const CMsvEntrySelection& aSelection)
+ {
+ // Set up context as 1st message in selection
+ BaseMtm().SwitchCurrentEntryL(aSelection.At(0));
+ return OpenL(aStatus); // View message
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CloseL
+// Not supported as you can only close services and BIO does not have services.
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::CloseL(TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ // Execution should not get here. This keeps compiler happy.
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CloseL
+// Not supported as you can only close services and BIO does not have services.
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::CloseL(
+ TRequestStatus& /*aStatus*/, const CMsvEntrySelection& /*aSelection*/)
+ {
+ User::Leave(KErrNotSupported);
+ // Execution should not get here. This keeps compiler happy.
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::EditL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::EditL(TRequestStatus& aStatus)
+ {
+ // Will leave if context is not a BIO message
+ CheckEntryL(BaseMtm().Entry().Entry());
+ return LaunchApplicationL(aStatus,EFalse);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::EditL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::EditL(
+ TRequestStatus& aStatus, const CMsvEntrySelection& aSelection)
+ {
+ // Set up context as 1st message in selection
+ BaseMtm().SwitchCurrentEntryL(aSelection.At(0));
+ return EditL(aStatus);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ViewL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::ViewL(TRequestStatus& aStatus)
+ {
+ // Will leave if context is not a BIO message
+ CheckEntryL(BaseMtm().Entry().Entry());
+ return LaunchApplicationL(aStatus,ETrue);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ViewL
+// Views only first in the selection
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::ViewL(
+ TRequestStatus& aStatus,const CMsvEntrySelection& aSelection)
+ {
+ // Set up context as 1st message in selection
+ BaseMtm().SwitchCurrentEntryL(aSelection.At(0));
+ return ViewL(aStatus);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CancelL
+// Currently this function only used to suspend messages queued for sending.
+// Can't send BIO messages, so can't cancel them either.
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::CancelL(
+ TRequestStatus& /*aStatus*/, const CMsvEntrySelection& /*aSelection*/)
+ {
+ User::Leave(KErrNotSupported);
+ // Execution should not get here. This keeps compiler happy.
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CopyToL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::CopyToL(const CMsvEntrySelection& /*aSelection*/,
+ TRequestStatus& /*aStatus*/)
+ {
+ // Context should be MTM folder/service to copy to
+ User::Leave(KErrNotSupported);
+ // Execution should not get here. This keeps compiler happy.
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::MoveToL
+// Not supported as BIO folders are not supported.
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::MoveToL(const CMsvEntrySelection& /*aSelection*/,
+ TRequestStatus& /*aStatus*/)
+ {
+ // Context should be MTM folder/service to move to
+ User::Leave(KErrNotSupported);
+ // Execution should not get here. This keeps compiler happy.
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CopyFromL
+// Not supported as BIO folders are not supported.
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::CopyFromL(const CMsvEntrySelection& /*aSelection*/,
+ TMsvId /*aTargetId*/, TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::MoveFromL
+// Not supported as BIO folders are not supported.
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::MoveFromL(const CMsvEntrySelection& /*aSelection*/,
+ TMsvId /*aTargetId*/, TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ReplyL
+// Not supported as BIO does not support sending of messages
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::ReplyL(TMsvId /*aDestination*/,
+ TMsvPartList /*aPartlist*/, TRequestStatus& /*aCompletionStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ForwardL
+// Not supported as BIO does not support sending of messages
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::ForwardL(TMsvId /*aDestination*/,
+ TMsvPartList /*aPartList*/, TRequestStatus& /*aCompletionStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::DeleteFromL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::DeleteFromL(const CMsvEntrySelection& /*aSelection*/,
+ TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::DeleteServiceL
+// Bio services not supported
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::DeleteServiceL(const TMsvEntry& /*aService*/,
+ TRequestStatus& /*aStatus*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL; // Execution should not get here. This keeps compiler happy.
+ }
+
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::QueryCapability
+// RTTI functions
+// -----------------------------------------------------------------------------
+//
+TInt CBioMtmUi::QueryCapability(TUid aCapability, TInt& aResponse)
+ {
+ if (aCapability.iUid == KUidMsvMtmQueryMessageInfo )
+ {
+ aResponse = ETrue;
+ return KErrNone;
+ }
+ return CBaseMtmUi::QueryCapability(aCapability, aResponse);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::InvokeAsyncFunctionL
+// -----------------------------------------------------------------------------
+//
+// RTTI functions
+CMsvOperation* CBioMtmUi::InvokeAsyncFunctionL(TInt aFunctionId,
+ const CMsvEntrySelection& aSelection, TRequestStatus& aCompletionStatus,
+ TDes8& aParameter)
+ {
+ if(aFunctionId == KMtmUiFunctionMessageInfo)
+ return ShowMessageInfoL(aCompletionStatus, aParameter);
+
+ return CBaseMtmUi::InvokeAsyncFunctionL(
+ aFunctionId, aSelection, aCompletionStatus, aParameter);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ShowMessageInfoL
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::ShowMessageInfoL(TRequestStatus& aCompletionStatus,
+ TDes8& /*aParameter*/)
+//
+// gathers the data to populate the info data array from the mtm and then
+// uses the messge info dialog class to display the data;
+// only used for viewing bio messages, the smum mtm is actually used for
+// creating bio messages
+//
+ {
+ BaseMtm().LoadMessageL();
+ const TMsvEntry& tentry=BaseMtm().Entry().Entry();
+
+ TMsgInfoMessageInfoData infoData;
+
+ //show subject if GMS message (picture message)
+ if (tentry.iBioType == KMsgBioUidPictureMsg.iUid)
+ {
+ HBufC* gmsTitle = ExtractTitleFromGMSBodyL(BaseMtm().Body(),
+ KMaxSubjectLength);
+ CleanupStack::PushL(gmsTitle);
+ infoData.iSubject.Set(*gmsTitle);
+ }
+
+ //date
+ infoData.iDateTime = tentry.iDate;
+
+ //type
+ TInt resourceId( KErrNotFound );
+
+ if ( tentry.iBioType == KMsgBioUidVCard.iUid ||
+ tentry.iBioType == KMsgBioUidCompBusCard.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_BUSINESS_CARD;
+ }
+ else if ( tentry.iBioType == KMsgBioUidVCalendar.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_CALENDAR;
+ }
+ else if ( tentry.iBioType == KMsgBioUidIAC.iUid ||
+ tentry.iBioType == KMsgBioUidWmlBrSettings.iUid ||
+ tentry.iBioType == KMsgBioUidWVSettings.iUid )
+ {
+ resourceId = R_QTN_SM_TITLE_CONFIGURATION;
+ }
+ else if ( tentry.iBioType == KMsgBioUidPictureMsg.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_GMS;
+ }
+ else if ( tentry.iBioType == KMsgBioUidEmailNotif.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_EMAIL_NOTIFICATION;
+ }
+ else if ( tentry.iBioType == KMsgBioUidRingingTone.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_RINGING_TONE;
+ }
+ else if ( tentry.iBioType == KMsgBioUidOperatorLogo.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_OPERATOR_LOGO;
+ }
+ else if ( tentry.iBioType == KMsgBioUidSyncML.iUid )
+ {
+ resourceId = R_QTN_SM_INFO_SYNC_PROFILE;
+ }
+ else
+ {
+ // Don't change the resourceId
+ }
+
+ TBuf<KTypeStringLength> typeString;
+ if ( resourceId != KErrNotFound )
+ {
+ HBufC* type = iEikonEnv->AllocReadResourceLC( resourceId );
+ typeString = *type;
+ infoData.iType.Set( typeString );
+ CleanupStack::PopAndDestroy( type );
+ }
+ else
+ {
+ infoData.iType.Set(tentry.iDescription);
+ }
+
+ //from
+ HBufC* from = CreateFromTextLC(BaseMtm().Entry());
+ infoData.iFrom.Set(*from);
+
+ CMsgInfoMessageInfoDialog* infoDialog = CMsgInfoMessageInfoDialog::NewL();
+ infoDialog->ExecuteLD(infoData,CMsgInfoMessageInfoDialog::EBiosViewer);
+ CleanupStack::PopAndDestroy(from);
+ if (tentry.iBioType == KMsgBioUidPictureMsg.iUid)
+ {
+ CleanupStack::PopAndDestroy(); //gmsTitle
+ }
+ return CMsvCompletedOperation::NewL(Session(), KUidMsvLocalServiceMtm,
+ KNullDesC8, KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ExtractTitleFromGMSBodyL
+// -----------------------------------------------------------------------------
+//
+HBufC* CBioMtmUi::ExtractTitleFromGMSBodyL(const CRichText& aBody,
+ TInt aMaxLength)
+ {
+ CGmsModel* model = CGmsModel::NewL(CCoeEnv::Static()->FsSession(),
+ KErrCorrupt);
+ CleanupStack::PushL(model);
+ model->ImportGMSL(aBody);
+ HBufC* text = model->TextAsHBufC16LC();
+ HBufC* result = NULL;
+ if (text->Length() <= aMaxLength)
+ {
+ result = text->AllocL();
+ }
+ else
+ {
+ // length is greater than max
+ result = text->Left(aMaxLength).AllocL();
+ }
+ CleanupStack::PopAndDestroy(text);
+ CleanupStack::PopAndDestroy(model);
+ return result;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ShowInvalidMsgNote
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::ShowInvalidMsgNote() const
+ {
+ TRAP_IGNORE(
+ {
+ CAknInformationNote* note = new (ELeave) CAknInformationNote;
+ HBufC* text =
+ StringLoader::LoadLC(R_QTN_MCE_INFO_MESSAGE_NOT_OPENED);
+ note->ExecuteLD(*text);
+ CleanupStack::PopAndDestroy(text);
+ } );
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ShowSystemErrorNote
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::ShowSystemErrorNote(TInt aError) const
+ {
+ TRAP_IGNORE(
+ {
+ const TDesC& error = iErrorResolver->ResolveErrorString( aError );
+ CAknErrorNote* note = new (ELeave) CAknErrorNote();
+ note->ExecuteLD(error);
+ } );
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::InvokeSyncFunctionL
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::InvokeSyncFunctionL(TInt aFunctionId,
+ const CMsvEntrySelection& aSelection, TDes8& aParameter)
+ {
+ //
+ // Delegate to client MTM
+ CBaseMtmUi::InvokeSyncFunctionL(aFunctionId, aSelection, aParameter);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::GetResourceFileName
+// Utility
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::GetResourceFileName(TFileName& aFileName) const
+ {
+ aFileName=KBiouMtmUiResourceFile;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::GetProgress
+// Progress interpretation
+// -----------------------------------------------------------------------------
+//
+TInt CBioMtmUi::GetProgress(
+ const TDesC8& aProgress,
+ TBuf<EProgressStringMaxLen>& aReturnString,
+ TInt& aTotalEntryCount, TInt& aEntriesDone,
+ TInt& aCurrentEntrySize, TInt& aCurrentBytesTrans) const
+ {
+ TInt error=KErrNone;
+
+ //
+ // Intialise return data...
+ aReturnString.Zero();
+ aReturnString.Append(KNotDefinedBium);
+ aTotalEntryCount=0;
+ aEntriesDone=0;
+ aCurrentEntrySize=0;
+ aCurrentBytesTrans=0;
+
+ if (!aProgress.Length())
+ return KErrNone;
+
+ const TInt progressType=ProgressType(aProgress);
+
+ // Handle any extra Engine/Local specific stuff
+ if(IsLocalProgress(progressType))
+ {
+ //
+ // Unpack the progress
+ TPckgBuf<TBioUiProgress> paramPack;
+ paramPack.Copy(aProgress);
+ TBioUiProgress progress(paramPack());
+
+ error=progress.iError;
+ }
+ else
+ {
+ //
+ // Unpack the progress
+ TPckgBuf<TBioProgress> paramPack;
+ paramPack.Copy(aProgress);
+ TBioProgress progress(paramPack());
+
+ error=progress.iErrorCode;
+ }
+
+ return error;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::ProgressType
+// -----------------------------------------------------------------------------
+//
+// Decode progress type from progress package
+TInt CBioMtmUi::ProgressType(const TDesC8& aProgress) const
+ {
+ TPckgC<TInt> type(0); // Progress type is the first TInt in the buffer.
+ type.Set(aProgress.Left(sizeof(TInt)));
+ const TInt progressType = type();
+
+ __ASSERT_DEBUG( IsEngineProgress(progressType) ||
+ IsLocalProgress(progressType), Panic(EBioMtmUiUnknownOperation));
+
+ return progressType;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::IsLocalProgress
+// Check if progress is local engine side
+// -----------------------------------------------------------------------------
+//
+TBool CBioMtmUi::IsLocalProgress(TInt aProgressType) const
+ {
+ return(aProgressType==TBioUiProgress::EBioMtmUiEditing ||
+ aProgressType==TBioUiProgress::EBioMtmUiParseAndEdit);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::IsEngineProgress
+// Check if progress is from engine side
+// (ie. if it is of type TBioUiProgress)
+// -----------------------------------------------------------------------------
+//
+TBool CBioMtmUi::IsEngineProgress(TInt aProgressType) const
+ {
+ return(aProgressType==TBioProgress::EBiosWaiting ||
+ aProgressType==TBioProgress::EBiosCreating ||
+ aProgressType==TBioProgress::EBiosParsing ||
+ aProgressType==TBioProgress::EBiosProcessing);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::DisplayProgressSummary
+// Progress interpretation and display
+// -----------------------------------------------------------------------------
+//
+TInt CBioMtmUi::DisplayProgressSummary(const TDesC8& aProgress) const
+ {
+ TInt err = KErrNone;
+
+ if (!aProgress.Length())
+ return KErrNone;
+
+ const TInt progressType=ProgressType(aProgress);
+
+ if(IsEngineProgress(progressType))
+ {
+ //
+ // Handle Engine side progress
+ TPckgBuf<TBioProgress> paramPack;
+ paramPack.Copy(aProgress);
+ TBioProgress progress(paramPack());
+ err = progress.iErrorCode;
+ if (err == KErrNone)
+ {
+ return KErrNone;
+ }
+
+ // These are the leave codes that originate from the symbian
+ // parsers and one other parser.
+ if (err == KErrMsgBioMessageNotValid
+ || (KBiumParserWappLeaveFirst <= err && err <= KBiumParserWappLeaveLast)
+ || err == KBiumParserBspLeave1
+ || err == KBiumParserBspLeave2)
+ {
+ ShowInvalidMsgNote();
+ }
+ else
+ {
+ ShowSystemErrorNote(err);
+ }
+ }
+ else
+ {
+ //
+ // Handle UI side progress
+ TPckgBuf<TBioUiProgress> paramPack;
+ paramPack.Copy(aProgress);
+ TBioUiProgress progress(paramPack());
+ err = progress.iError;
+ if (err == KErrNone)
+ {
+ return KErrNone;
+ }
+ if (err == KErrMsgBioMessageNotValid)
+ {
+ ShowInvalidMsgNote();
+ }
+ else if( err != KLeaveWithoutAlert )
+ {
+ ShowSystemErrorNote(err);
+ }
+ }
+ return err;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::LaunchApplicationL
+// Utility specific to CBioMtmUi
+// -----------------------------------------------------------------------------
+//
+CMsvOperation* CBioMtmUi::LaunchApplicationL(
+ TRequestStatus& aStatus,TBool aReadOnly )
+ {
+ const TMsvEntry& tentry=BaseMtm().Entry().Entry();
+
+ // Locate BioData for given bio message type
+ TUid msgTypeUid={tentry.iBioType};
+ const TInt bioDataCount=iBioData->Count();
+
+ TBioData* bioData=NULL;
+
+
+ for(TInt n=0;n<bioDataCount;n++)
+ {
+ if((iBioData->At(n)).iTypeUid==msgTypeUid)
+ {
+ bioData=&(iBioData->At(n));
+ break;
+ }
+ }
+
+ // If we have no data for this bio message type then complete.
+ if(!bioData)
+ {
+ //the TBioUiProgress transmits the error code to
+ //DisplayProgressSummary(..) to be handled there
+ TBioUiProgress progress;
+ progress.iType=TBioUiProgress::EBioMtmUiParseAndEdit;
+ progress.iError=KErrMsgBioMessageNotValid;
+ TPckgBuf<TBioUiProgress> progressPckg(progress);
+
+ // Mark entry as read
+ CMsvEntry* entry = Session().GetEntryL(tentry.Id());
+ CleanupStack::PushL(entry);
+ TMsvEntry tEntry(entry->Entry());
+ tEntry.SetUnread(EFalse);
+ tEntry.SetNew(EFalse);
+ entry->ChangeL(tEntry);
+ CleanupStack::PopAndDestroy(entry);
+ return CMsvCompletedOperation::NewL(
+ Session(),
+ Type(),
+ progressPckg,
+ KMsvLocalServiceIndexEntryId,
+ aStatus, KErrNone);
+ }
+
+ // If requested to launch default app, then set correct uid
+ if(bioData->iAppUid == KUidBioUseDefaultApp)
+ {
+ bioData->iAppUid = KBiouMtmUiSMSViewerAppUid;
+ }
+
+ // If app filename has not been resolved AND we need to resolve it,
+ // then try to resolve it now
+ if(bioData->iEditorFileName==KNullDesC &&
+ bioData->iAppUid!=KUidBioUseNoApp)
+ {
+ RApaLsSession appList;
+ User::LeaveIfError(appList.Connect());
+ CleanupClosePushL(appList);
+ TApaAppInfo info;
+ TInt err = appList.GetAppInfo(info,bioData->iAppUid);
+ CleanupStack::PopAndDestroy(); // appList
+ if(err!=KErrNone)
+ {
+ TBufC8<1> buf;
+ // Mark as read
+ CMsvEntry* entry = Session().GetEntryL(tentry.Id());
+ CleanupStack::PushL(entry);
+ TMsvEntry tEntry(entry->Entry());
+ tEntry.SetUnread(EFalse);
+ tEntry.SetNew(EFalse);
+ entry->ChangeL(tEntry);
+ CleanupStack::PopAndDestroy(entry);
+ return CMsvCompletedOperation::NewL(
+ Session(),
+ Type(),
+ buf,
+ KMsvLocalServiceIndexEntryId,
+ aStatus, KErrNone);
+ }
+ bioData->iEditorFileName = info.iFullName;
+ }
+
+ if ( tentry.iMtmData3 == 0 ) //Entry not parsed yet
+ {
+ if ( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL(
+ Session(),
+ tentry.iSize ) )
+ {
+ User::Leave( KErrDiskFull );
+ }
+ }
+
+ //
+ // Parse message (if needed) then launch application (if needed)...
+ //
+ TBuf8<1> blankParams;
+ CMsvEntrySelection* sel=new(ELeave) CMsvEntrySelection();
+ CleanupStack::PushL(sel);
+ // Message Server will use UID of 1st message to load in MTM server.
+ sel->AppendL(tentry.Id());
+ // BIO Server MTM will use 2nd message to actually parse.
+ sel->AppendL(tentry.Id());
+
+ //
+ // Create parameters for parseAndEdit operation
+ TParseAndEditParams params;
+ if(bioData->iAppUid==KUidBioUseNoApp)
+ {
+ // If we have not been asked to launch an app
+ params.iLaunchApp=EFalse;
+ // Set the entry id also here. Needed in SetEntryReadAndOldL.
+ params.iEditorParams.iId=tentry.Id();
+ }
+ else
+ {
+ params.iLaunchApp=ETrue;
+ params.iPreferEmbedded = (
+ Preferences() & EMtmUiFlagEditorPreferEmbedded );
+ params.iEditorFileName=bioData->iEditorFileName;
+ // Kick off app with current context id
+ params.iEditorParams.iId=tentry.Id();
+ params.iEditorParams.iFlags |= (
+ Preferences() &
+ EMtmUiFlagEditorPreferEmbedded ?
+ EMsgLaunchEditorEmbedded :
+ 0 );
+
+ params.iEditorParams.iFlags |= (
+ Preferences() & EMtmUiFlagEditorNoWaitForExit ?
+ 0 :
+ EMsgLaunchEditorThenWait );
+
+ params.iEditorParams.iSpecialAppId = bioData->iAppUid;
+ if(aReadOnly)
+ params.iEditorParams.iFlags|=EMsgReadOnly;
+ }
+
+ // Create ParseAndEdit operation
+ CParseAndEditOp* parseAndEdit =
+ CParseAndEditOp::NewL( Session(), aStatus, params );
+ CleanupStack::PushL( parseAndEdit );
+
+ //
+ // Create Parse or ParseAndProcess operation,
+ // for giving to ParseAndEdit operation
+ // Check that message is of correct type for calling Bio Server MTM,
+ // if it's not then there is not much we can do
+ // (so create a completed operation).
+ // This condition also ensures that we do not parse messages
+ // which are due for sending.
+ CMsvOperation* parseOp;
+ if(tentry.iMtm==KUidBIOMessageTypeMtm && bioData->iHasParser)
+ {
+ if(params.iLaunchApp)
+ parseOp=CBaseMtmUi::InvokeAsyncFunctionL(KBiosMtmParse,
+ *sel,parseAndEdit->RequestStatus(),blankParams);
+ else
+ parseOp=CBaseMtmUi::InvokeAsyncFunctionL(KBiosMtmParseThenProcess,
+ *sel,parseAndEdit->RequestStatus(),blankParams);
+ }
+ else
+ {
+ //the TBioUiProgress transmits the error code to
+ //DisplayProgressSummary(..) to be handled there
+ TBioUiProgress progress;
+ if(bioData->iEditorFileName==KNullDesC
+ && bioData->iAppUid==KUidBioUseNoApp
+ && ( ! bioData->iHasParser )
+ && bioData->iTypeUid != KUidBioUseNoApp)
+ {
+ progress.iError=KErrMsgBioMessageNotValid;
+ }
+ else
+ {
+ progress.iError=KErrNone;
+ }
+ progress.iType=TBioUiProgress::EBioMtmUiParseAndEdit;
+ TPckgBuf<TBioUiProgress> progressPckg(progress);
+ parseOp = CMsvCompletedOperation::NewL(
+ Session(),
+ KUidBIOMessageTypeMtm,
+ progressPckg,
+ KMsvNullIndexEntryId,
+ parseAndEdit->RequestStatus() );
+ }
+
+ // Pass 'parse' operation to 'parse and edit' operation
+ parseAndEdit->SetParseOpL(parseOp);
+
+ CleanupStack::Pop(parseAndEdit); // parseAndEdit
+ CleanupStack::PopAndDestroy(sel); // sel
+
+ return parseAndEdit;
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CheckEntryL
+// Entry validation
+// Leaves with KErrNotSupported if entry is not a message of the BIO MTM.
+// -----------------------------------------------------------------------------
+//
+void CBioMtmUi::CheckEntryL(const TMsvEntry& aEntry) const
+ {
+ // Note: Sending Bio messages will have Mtm type of
+ // the transport type for sending.
+ // Instead Sending Bio messages will have iBioType as non-zero.
+
+ if(aEntry.iType.iUid!=KUidMsvMessageEntryValue ||
+ (aEntry.iBioType==0 && aEntry.iMtm!=KUidBIOMessageTypeMtm))
+ User::Leave(KErrNotSupported);
+ }
+
+// -----------------------------------------------------------------------------
+// CBioMtmUi::CreateFromTextLC
+// Both name and number are shown if they are known.
+// Otherwise only the number is shown.
+// Number is always known, except for IR & BT.
+// -----------------------------------------------------------------------------
+//
+HBufC* CBioMtmUi::CreateFromTextLC(CMsvEntry& aEntry) const
+ {
+ CMsvStore* store = aEntry.ReadStoreL();
+ CleanupStack::PushL(store);
+ TBool smsBased;
+ HBufC* toFromSmsBuf;
+ if (store->IsPresentL(KBiumUidMsvSMSHeaderStream))
+ {
+ smsBased = ETrue;
+ CPlainText* nullString = CPlainText::NewL();
+ CleanupStack::PushL(nullString);
+ CSmsHeader* smsHeader = CSmsHeader::NewL(CSmsPDU::ESmsDeliver, *nullString);
+ CleanupStack::PushL(smsHeader);
+ smsHeader->RestoreL(*store);
+ toFromSmsBuf = smsHeader->Message().SmsPDU().ToFromAddress().AllocL();
+ CleanupStack::PopAndDestroy(2, nullString); // smsHeader nullString
+ }
+ else
+ {
+ smsBased = EFalse;
+ toFromSmsBuf = KNullDesC().AllocL();
+ }
+ CleanupStack::PopAndDestroy(store);
+ CleanupStack::PushL(toFromSmsBuf);
+ HBufC* result;
+ TPtrC details(aEntry.Entry().iDetails);
+ if (smsBased)
+ {
+ TPtr toFromSmsPtr(toFromSmsBuf->Des());
+ toFromSmsPtr.Trim();
+
+ // Does the iDetails have a name or number? Do a comparison in order to
+ // find out.
+ TBool detailsIsNumber = details.Compare(toFromSmsPtr) == 0;
+ if (detailsIsNumber)
+ {
+ // ...which means that the name was not known when the message arrived.
+ // We're not going to fetch it now.
+ // Show the number.
+ result = details.AllocL();
+ }
+ else
+ {
+ // The iDetails contains the matched name. Concatenate the name and
+ // toFromSmsBuf which contains the number.
+ result = HBufC::NewL(
+ details.Length() + KCharacterReserve + toFromSmsBuf->Length());
+ TPtr resultPtr(result->Des());
+ _LIT(KBiumChSpace, " ");
+ _LIT(KBiumChLeft, "<");
+ _LIT(KBiumChRight, ">");
+ resultPtr.Append(details);
+ resultPtr.Append(KBiumChSpace);
+ resultPtr.Append(KBiumChLeft);
+ resultPtr.Append(*toFromSmsBuf);
+ resultPtr.Append(KBiumChRight);
+ }
+ }
+ else
+ {
+ // It is either IR or BT, so use the iDetails text.
+ result = aEntry.Entry().iDetails.AllocL();
+ }
+ CleanupStack::PopAndDestroy(toFromSmsBuf);
+ CleanupStack::PushL(result);
+ return result;
+ }
+
+
+//******************************************************************************
+//******************************************************************************
+//
+// class CParseAndEditOp
+//
+// Operation encapsulating the parse operation
+// and the launch application operation.
+//
+//******************************************************************************
+//******************************************************************************
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::NewL
+// Construction
+// -----------------------------------------------------------------------------
+//
+CParseAndEditOp* CParseAndEditOp::NewL(
+ CMsvSession& aMsvSession, TRequestStatus& aObserverRequestStatus,
+ const TParseAndEditParams& aParams)
+ {
+ CParseAndEditOp* self =
+ new(ELeave) CParseAndEditOp(
+ aMsvSession,aObserverRequestStatus,aParams );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::CParseAndEditOp
+// -----------------------------------------------------------------------------
+//
+CParseAndEditOp::CParseAndEditOp(
+ CMsvSession& aMsvSession,TRequestStatus& aObserverRequestStatus,
+ const TParseAndEditParams& aParams)
+ : CMsvOperation(aMsvSession,
+ KParseAndEditOpPriority,aObserverRequestStatus),
+ iState(EStateIdle),iParams(aParams)
+ {
+ iLocalProgress.iType=TBioUiProgress::EBioMtmUiParseAndEdit;
+ iLocalProgress.iError=KErrNone;
+
+ CActiveScheduler::Add(this);
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::ConstructL
+// Construction
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::ConstructL()
+ {
+ iMtmStore=CMtmStore::NewL(iMsvSession);
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::~CParseAndEditOp
+// Destruction
+// -----------------------------------------------------------------------------
+//
+CParseAndEditOp::~CParseAndEditOp()
+ {
+ Cancel();
+ delete iOperation;
+ delete iMtmStore;
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::ProgressL
+// -----------------------------------------------------------------------------
+//
+const TDesC8& CParseAndEditOp::ProgressL()
+ {
+ if(iOperation)
+ return iOperation->ProgressL();
+
+ iLocalProgressPckg=iLocalProgress;
+ return iLocalProgressPckg;
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::RequestStatus
+// Enquiry
+// -----------------------------------------------------------------------------
+//
+TRequestStatus& CParseAndEditOp::RequestStatus()
+ {
+ return iStatus;
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::SetParseOpL
+// Setup and kick off operation
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::SetParseOpL(CMsvOperation* aOp)
+ {
+ __ASSERT_DEBUG(aOp, Panic(EBioMtmUiNullOperation));
+ __ASSERT_DEBUG(!iOperation, Panic(EBioMtmUiOperationAlreadyExists));
+ iOperation = aOp;
+ iMtm = iOperation->Mtm();
+ iState = EStateParsing;
+ SetActive();
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::DoCancel
+// from CActive
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::DoCancel()
+ {
+ if(iOperation)
+ iOperation->Cancel();
+ CompleteObserver();
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::RunL
+// from CActive
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::RunL()
+ {
+ __ASSERT_DEBUG(iOperation,Panic(EBioMtmUiOperationDoesNotExist));
+
+ switch(iState)
+ {
+ case EStateParsing: // The parse has completed.
+ {
+ TBuf<CBaseMtmUi::EProgressStringMaxLen> bufNotUsed1;
+ TInt intNotUsed2;
+ TInt intNotUsed3;
+ TInt intNotUsed4;
+ TInt intNotUsed5;
+ CBaseMtmUi& mtmUi=iMtmStore->GetMtmUiLC(KUidBIOMessageTypeMtm);
+ const TInt err=mtmUi.GetProgress(iOperation->FinalProgress(),
+ bufNotUsed1,intNotUsed2,intNotUsed3,
+ intNotUsed4,intNotUsed5);
+ CleanupStack::PopAndDestroy(); // (release cleanup item for mtmUi)
+ if(KErrNone==err && iParams.iLaunchApp)
+ DoEditL();
+ else
+ {
+ SetEntryReadAndOldL(iParams.iEditorParams.iId);
+ CompleteObserver();
+ }
+ }
+ break;
+ case EStateEditing: // Edit has completed.
+ DeleteMessageAttachmentL(iParams.iEditorParams.iId);
+ CompleteObserver();
+ break;
+
+ default:;// To prevent warning enumeration value
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::RunError
+// from CActive
+// RunError will get called if our RunL leaves
+// -----------------------------------------------------------------------------
+//
+TInt CParseAndEditOp::RunError(TInt aError)
+ {
+ delete iOperation; // So that we will report our local progress
+ iOperation=NULL;
+ iLocalProgress.iError = aError;
+ CompleteObserver();
+ return KErrNone; // the Bio MTM UI will handle the error
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::DoEditL
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::DoEditL()
+ {
+ delete iOperation;
+ iOperation=NULL;
+
+ TBioUiProgress progress;
+ progress.iType=TBioUiProgress::EBioMtmUiEditing;
+ progress.iError=KErrNone;
+ TPckgBuf<TBioUiProgress> progressPckg(progress);
+
+ iOperation = MsgEditorLauncher::LaunchEditorApplicationL(
+ iMsvSession,
+ iMtm,
+ iStatus,
+ iParams.iEditorParams,
+ iParams.iEditorFileName,
+ progressPckg);
+
+ iState = EStateEditing;
+ SetActive();
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::CompleteObserver
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::CompleteObserver()
+ {
+ TRequestStatus* status = &iObserverRequestStatus;
+ TInt err;
+ if (iOperation)
+ {
+ err = iOperation->iStatus.Int();
+ }
+ else
+ {
+ err = iLocalProgress.iError;
+ }
+
+ User::RequestComplete(status, err);
+ iState = EStateComplete;
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::SetEntryReadAndOldL
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::SetEntryReadAndOldL(TMsvId aEntryId)
+ {
+ CMsvEntry* entry = iMsvSession.GetEntryL(aEntryId);
+ CleanupStack::PushL(entry);
+ TMsvEntry tEntry(entry->Entry());
+ tEntry.SetUnread(EFalse);
+ tEntry.SetNew(EFalse);
+ entry->ChangeL(tEntry);
+ CleanupStack::PopAndDestroy(entry);
+ }
+
+// -----------------------------------------------------------------------------
+// CParseAndEditOp::DeleteMessageAttachmentL
+// -----------------------------------------------------------------------------
+//
+void CParseAndEditOp::DeleteMessageAttachmentL(TMsvId aEntryId)
+ {
+ CMsvEntry* entry = NULL;
+ TRAPD(err,entry = iMsvSession.GetEntryL(aEntryId));
+
+ if(err == KErrNone)
+ {
+ CleanupStack::PushL(entry); // 1st push
+ TMsvEntry tEntry = entry->Entry();
+ TBool readOnly = tEntry.ReadOnly();
+ tEntry.SetReadOnly(EFalse);
+ entry->ChangeL(tEntry);
+ CMsvStore* store = entry->EditStoreL();
+ CleanupStack::PushL(store); // 2nd push
+ if(store->AttachmentManagerL().AttachmentCount() > 0)
+ {
+ store->AttachmentManagerExtensionsL().RemoveAttachmentL(0);
+ store->CommitL();
+ }
+ if(store->IsPresentL(KUidMsvBIODataStream))
+ {
+ store->Remove(KUidMsvBIODataStream);
+ store->CommitL();
+ }
+ TMsvEntry tEntryNew = entry->Entry();
+ tEntryNew.SetReadOnly(readOnly);
+ tEntryNew.iMtmData3 = 0; // EBioMsgNotParsed in bioop.h
+ entry->ChangeL(tEntryNew);
+ CleanupStack::PopAndDestroy(store);
+ CleanupStack::PopAndDestroy(entry);
+ }
+ // we ignore error if attachment was not found
+ else if(err != KErrNotFound)
+ {
+ User::LeaveIfError(err);
+ }
+
+ }
+
+
+// end of file