sendas.cpp

来自「在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己」· C++ 代码 · 共 927 行 · 第 1/2 页

CPP
927
字号
// SendAs.cpp - for SendAs OPX
//
// Copyright (c) 1999-2002 Symbian Ltd. All rights reserved.
//
// NOTE:	This OPX is based on the functionality found in the file
//			//EPOC/development/crystal/6.0/sendui/normSRC/Sendnorm.cpp
//
//			Original versions kept in step until Revision 19 of the above.
//			This OPX was given a major re-write on 24/07/2001 to bring the
//			code/approach in line with newer versions of the above file. For
//			some reason CSendAs is no longer used, with most of the sending
//			functionality being re-implemented.

#include <eikon.hrh>
#include <eikenv.h>
#include <eikhkeyt.h>
#include <w32std.h>
#include <bautils.h>
#include <mtuireg.h>
#include <mtmuibas.h>
#include <mtudreg.h>
#if defined(__UIQ__)
#include <QMappExtInterface.h>
#include <eikappui.h>
#else
#include <mtmstore.h>
#include <muiuServ.h>
#include <MTMExtendedCapabilities.hrh>
#endif
#include <mtmuids.h>
#include <msvapi.h>
#include <mtudcbas.h>
//
#include <MTUD.HRH> // EMtudCommandSendAs
#include <MSVIDS.H> // KMsvGlobalOutBoxIndexEntryId, etc.
#include <coeutils.h>
#include <txtrich.h>
#include <s32mem.h>
//
#include <IrcMtm.h>
//
#include <eikfutil.h>
//
#include "opxutil.h"
#include "sendasopx.h"

const TInt KSendingMtmGranularity		= 5;
const TInt KHotkeysGranularity			= 5;
const TInt KFileNamesArrayGranularity	= 5;
const TInt KAddressArrayGranularity		= 5;
const TInt32 KHotkeyStartValue			= 1;

const TUid KUidMsgTypeIR = {0x100053A4}; // See #include <irobutil.h>
const TInt KRichTextStoreGranularity = 512;

COpxSendAsEngine* COpxSendAsEngine::NewL()
	{
	COpxSendAsEngine* This=new(ELeave) COpxSendAsEngine();
	CleanupStack::PushL(This);
	This->ConstructL();
	CleanupStack::Pop();
	return This;
	}

COpxSendAsEngine::COpxSendAsEngine()
	:
#if !defined(__UIQ__)
	iSendingMtms(KSendingMtmGranularity),
#endif
	iHotkeysArray(KHotkeysGranularity),
	iCurrentChosenMtmUid(KNullUid)
	{
	}

void COpxSendAsEngine::ConstructL()
	{
	iSession = CMsvSession::OpenSyncL(*this);
#if !defined(__UIQ__)
	iMtmStore = CMtmStore::NewL(*iSession);
#endif
	iUiDataRegistry = CMtmUiDataRegistry::NewL(*iSession);
	iClientRegistry = CClientMtmRegistry::NewL(*iSession);
	iScannedAlready=EFalse;
	iStore = CBufStore::NewL(KRichTextStoreGranularity);
	}

COpxSendAsEngine::~COpxSendAsEngine()
	{
#if !defined(__UIQ__)
	delete iMtmStore;
#else
	delete iUiMtmData;
#endif
	delete iUiDataRegistry;
	delete iStore;
	delete iClientRegistry;
	delete iSession; // delete Session last after all things which use it

	delete iBody;
	delete iAttachmentFileNamesArray;
	delete iRealAddressesArray;
	delete iSubject;
	}

void COpxSendAsEngine::ScanMtmsL()
	{
#if !defined(__UIQ__)
	iSendingMtms.Reset();
#endif
	iHotkeysArray.Reset();
	iNextAvailableHotkey=KHotkeyStartValue;

	const TInt count = iUiDataRegistry->NumRegisteredMtmDlls();
	for (TInt cc = 0; cc < count; cc++)
		{
		TUid mtmTypeUid = iUiDataRegistry->MtmTypeUid(cc);
#if defined(__UIQ__)
		CBaseMtmUiData& uiData = *iUiDataRegistry->NewMtmUiDataLayerL(mtmTypeUid);
#else
		CBaseMtmUiData& uiData = iMtmStore->MtmUiDataL(mtmTypeUid);
#endif
		TInt response;
		TUid canSend = {KUidMtmQueryCanSendMsgValue};
		TInt err = uiData.QueryCapability(canSend, response);
		if (err != KErrNotSupported)
			User::LeaveIfError(err);
		if (err == KErrNone)
			{
			// Can send messages of this type
			TBool found = EFalse;
			for (TInt dd = 0; dd < iSendingMtms.Count(); ++dd)
				{
				if (iSendingMtms[dd].iUid == mtmTypeUid)
					{
					// Already have this MTM
					found = ETrue;
					break;
					}
				}
			if (!found)
				{
				const CArrayFix<CBaseMtmUiData::TMtmUiFunction>& funcs = uiData.MtmSpecificFunctions();
				for (TInt i = funcs.Count() - 1; i >= 0; i--)
					{
#if defined(__UIQ__)					
					if (funcs.At(i).iFlags & EMtudCommandSendAs)	//***** change iFlags to iFunctionType when the MTMs are corrected
						{
						found = ETrue;
						break;
						}
#else
					CBaseMtmUiData::TMtmUiFunction func = funcs.At(i);
					if (func.iFlags & EMtudCommandSendAs)	//***** change iFlags to iFunctionType when the MTMs are corrected
						{
						iSendingMtms.AppendL(TUidNameInfo(mtmTypeUid, func.iCaption));
						found = ETrue;
						break;
						}
#endif
					}
				if (!found)
					{
					// no info available for caption - use the human readable name
#if defined(__UIQ__)
					TPtrC name(iUiDataRegistry->RegisteredMtmDllInfo(mtmTypeUid).HumanReadableName());
					iSendingMtms.Append(TUidNameInfo(mtmTypeUid, name));
#else
					iSendingMtms.AppendL(TUidNameInfo(mtmTypeUid, iUiDataRegistry->RegisteredMtmDllInfo(mtmTypeUid).HumanReadableName()));
#endif
					}
				// Now set the hotkey for this MTM
#if defined(__UIQ__)
				iHotkeysArray.AppendL(iNextAvailableHotkey++);
#else
				iHotkeysArray.AppendL(iNextAvailableHotkey++);
#endif
				}
			}
		}
#if !defined(__UIQ__)
	iSendingMtms.Sort(ECmpFolded);
#endif
	iScannedAlready=ETrue;
	}

TInt COpxSendAsEngine::NumberOfMtmsL()
	{
	ScanIfNeededL();
	return iSendingMtms.Count();
	}

TBool COpxSendAsEngine::DoesMtmHaveCapabilityL(const TInt aIndex, TSendingCapabilities aRequiredCapabilities)
	{
	ScanIfNeededL();
	if ((aIndex<0) || (aIndex>=iSendingMtms.Count()))
		{
		User::Leave(KOplErrOutOfRange);
		}

	TUid mtmTypeUid = iSendingMtms[aIndex].iUid;
#if defined(__UIQ__)
	delete iUiMtmData;
	iUiMtmData =NULL;
	iUiMtmData= iUiDataRegistry->NewMtmUiDataLayerL(mtmTypeUid);//=iMtmStore->MtmUiDataL(mtmTypeUid);
	CBaseMtmUiData& mtmUiData=*iUiMtmData;
#else
	CBaseMtmUiData& mtmUiData = iMtmStore->MtmUiDataL(mtmTypeUid);
#endif
	TInt response = 0;

	// Check to see first if any valid accounts (if required) are setup
	TMsvEntry serviceEntry;
	serviceEntry.iType.iUid = KUidMsvServiceEntryValue;
	serviceEntry.iMtm = mtmTypeUid;
	CMsvEntry* rootEntry = iSession->GetEntryL(KMsvRootIndexEntryId);
	CleanupStack::PushL(rootEntry);

	TInt validAccounts = ETrue;
#if defined(__UIQ__)
	const TUid KUidQueryNeedsAccountButCannotCreate={0};
#else
	const TUid KUidQueryNeedsAccountButCannotCreate={KUidQueryNeedsAccountButCannotCreateValue};
#endif
	if ((mtmUiData.CanCreateEntryL(rootEntry->Entry(), serviceEntry, response)) ||
		(mtmUiData.QueryCapability(KUidQueryNeedsAccountButCannotCreate, response) == KErrNone))
		{
		CMsvEntrySelection* accounts = NULL;
#if !defined(__UIQ__)
		accounts = MsvUiServiceUtilities::GetListOfAccountsWithMTML(*iSession, mtmTypeUid, ETrue); 
#endif
		if (!accounts || accounts->Count() == 0)
			validAccounts = EFalse;
		delete accounts;
		}
	CleanupStack::PopAndDestroy(rootEntry);
	
	if (!validAccounts)
		return EFalse; // If no valid accounts, can't use MTM hence capability check is redundant

	// If we get to here, accounts are valid so there is the possibility to send messages - 
	// carry on and check the capabilities as passed.
	if (aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsAttachments)
		{
		if (mtmUiData.QueryCapability(KUidMtmQuerySupportAttachments, response) != KErrNone)
			return EFalse;
		}
	
	if (aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsBodyText)
		{
		if (mtmUiData.QueryCapability(KUidMtmQuerySupportedBody, response) != KErrNone)
			return EFalse;
		}

	if (aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsBioSending)
		{
		if (mtmUiData.QueryCapability(KUidMsvQuerySupportsBioMsg, response) != KErrNone)
			return EFalse;
		}
	
	if (aRequiredCapabilities.iFlags & TSendingCapabilities::ESupportsAttachmentsOrBodyText)
		{
		if ((mtmUiData.QueryCapability(KUidMtmQuerySupportAttachments, response) != KErrNone) &&
			(mtmUiData.QueryCapability(KUidMtmQuerySupportedBody, response) != KErrNone))
			return EFalse;
		}

	return ETrue;
	}

TPtrC COpxSendAsEngine::CascNameForMtmL(const TInt aIndex)
	{
	ScanIfNeededL();
	if ((aIndex<0) || (aIndex>=iSendingMtms.Count()))
		{
		User::Leave(KOplErrOutOfRange);
		}
	return iSendingMtms[aIndex].iName;
	}

TInt32 COpxSendAsEngine::HotkeyForMtmL(const TInt aIndex)
	{
	ScanIfNeededL();
	if ((aIndex<0) || (aIndex>=iSendingMtms.Count()))
		{
		User::Leave(KOplErrOutOfRange);
		}
	return iHotkeysArray[aIndex];
	}

TInt32 COpxSendAsEngine::NextAvailableHotkeyL()
	{
	ScanIfNeededL();
	return iNextAvailableHotkey;
	}

TInt32 COpxSendAsEngine::UidForMtmL(const TInt aIndex)
	{
	ScanIfNeededL();
	if ((aIndex<0) || (aIndex>=iSendingMtms.Count()))
		{
		User::Leave(KOplErrOutOfRange);
		}
	return iSendingMtms[aIndex].iUid.iUid;
	}

void COpxSendAsEngine::PrepareMessageL(const TInt aIndex)
	{
	ScanIfNeededL();
	if ((aIndex<0) || (aIndex>=iSendingMtms.Count()))
		{
		User::Leave(KOplErrOutOfRange);
		}
	iCurrentChosenMtmUid=iSendingMtms[aIndex].iUid;
	}

void COpxSendAsEngine::SetSubjectL(const TDesC& aSubject)
	{
	ScanIfNeededL();
	if (iCurrentChosenMtmUid==KNullUid)
		User::Leave(KOplErrNotExists);

#if defined(__UIQ__)
	delete iUiMtmData;
	iUiMtmData =NULL;
	iUiMtmData= iUiDataRegistry->NewMtmUiDataLayerL(iCurrentChosenMtmUid);//=iMtmStore->MtmUiDataL(mtmTypeUid);
	CBaseMtmUiData& mtmUiData=*iUiMtmData;
#else
	CBaseMtmUiData& mtmUiData = iMtmStore->MtmUiDataL(iCurrentChosenMtmUid);
#endif
	TInt response = 0;
	if (mtmUiData.QueryCapability(KUidMtmQuerySupportSubject, response) == KErrNone)
		{
		if(iSubject)
			{
			delete iSubject;
			iSubject=NULL;
			}
		iSubject=HBufC::NewL(aSubject.Length());
		*iSubject=aSubject;
		}
	else
		User::Leave(KOplErrNotSupported);
	}

void COpxSendAsEngine::AddFileL(const TFileName& aFileName)
	{
	ScanIfNeededL();
	if (iCurrentChosenMtmUid==KNullUid)
		User::Leave(KOplErrNotExists);

#if defined(__UIQ__)
	delete iUiMtmData;
	iUiMtmData =NULL;
	iUiMtmData= iUiDataRegistry->NewMtmUiDataLayerL(iCurrentChosenMtmUid);//=iMtmStore->MtmUiDataL(mtmTypeUid);
	CBaseMtmUiData& mtmUiData=*iUiMtmData;
#else
	CBaseMtmUiData& mtmUiData = iMtmStore->MtmUiDataL(iCurrentChosenMtmUid);
#endif
	TInt response = 0;
	if (mtmUiData.QueryCapability(KUidMtmQuerySupportAttachments, response) == KErrNone)
		{
		if(!iAttachmentFileNamesArray)
			iAttachmentFileNamesArray = new(ELeave) CDesCArrayFlat(KFileNamesArrayGranularity);
		iAttachmentFileNamesArray->AppendL(aFileName);
		}
	else
		User::Leave(KOplErrNotSupported);
	}

void COpxSendAsEngine::AddRecipientL(const TDesC& aAddress)
	{
	ScanIfNeededL();
	if (iCurrentChosenMtmUid==KNullUid)
		User::Leave(KOplErrNotExists);

	if(!iRealAddressesArray)
		iRealAddressesArray = new(ELeave) CDesCArrayFlat(KAddressArrayGranularity);
	iRealAddressesArray->AppendL(aAddress);
	}

void COpxSendAsEngine::LaunchSendL(OplAPI& /*aOplAPI*/)
	{
	ScanIfNeededL();
	if (iCurrentChosenMtmUid==KNullUid)
		User::Leave(KOplErrNotExists);

	// Create message
	CBaseMtm* mtm = iClientRegistry->NewMtmL(iCurrentChosenMtmUid);
	CleanupStack::PushL(mtm);

	CMsvEntry* draftEntry = iSession->GetEntryL(KMsvDraftEntryId);
	mtm->SetCurrentEntryL(draftEntry); // mtm takes ownership (and handles CleanupStack)
#if defined(__UIQ__)
	CMsvDefaultServices* defServices=new (ELeave) CMsvDefaultServices;
	CleanupStack::PushL(defServices);
	CMsvEntry* rootEntry=mtm->Session().GetEntryL(KMsvRootIndexEntryId);
	CleanupStack::PushL(rootEntry);
	CMsvStore* rootStore= rootEntry->ReadStoreL();
	CleanupStack::PushL(rootStore);
	defServices->RestoreL(*rootStore);
	TMsvId service =0;
	defServices->DefaultService(iCurrentChosenMtmUid,service);
	CleanupStack::PopAndDestroy(2,rootEntry),
	CleanupStack::PopAndDestroy(defServices);
#else
	TMsvId service = MsvUiServiceUtilities::DefaultServiceForMTML(*iSession, iCurrentChosenMtmUid, ETrue);
#endif
	mtm->CreateMessageL(service);

	// Begin setting the message data
	TInt loop;
	if (iRealAddressesArray)
		{
		TInt count = iRealAddressesArray->MdcaCount();
		for (loop = 0; loop < count; loop++)
			{
			if (iRealAddressesArray->MdcaPoint(loop).Length() > 0) 
				mtm->AddAddresseeL(iRealAddressesArray->MdcaPoint(loop));
			}
		}

//	if (aBioTypeUid != KNullUid)
//		mtm->BioTypeChangedL(aBioTypeUid);

	if (iBody)
		SetBodyDuringSendingL(mtm, *iBody);

	if (iSubject)
		mtm->SetSubjectL(*iSubject);

	if (iAttachmentFileNamesArray)
		{
		if (iCurrentChosenMtmUid == KUidMsgTypeIR)
			AddIrAttachmentsL(mtm, iAttachmentFileNamesArray);
		else
			{
			TFileName directory;
			TMsvId attachId;
			TParse dest;
			for (loop = iAttachmentFileNamesArray->MdcaCount() - 1; loop >= 0; loop--)
				{
				mtm->CreateAttachmentL(attachId, directory);
				const TDesC& attachment = iAttachmentFileNamesArray->MdcaPoint(loop);
				dest.Set(directory, &attachment, NULL);
				User::LeaveIfError(EikFileUtils::CopyFile(attachment, dest.FullName()));

				CMsvEntry* newEntry = iSession->GetEntryL(attachId);
				CleanupStack::PushL(newEntry);

				// Store the attachment name in iDetails of the attachment entry
				TMsvEntry attachmentEntry = newEntry->Entry();
				const TDesC& attachmentName = dest.NameAndExt();
				attachmentEntry.iDetails.Set(attachmentName);

				TEntry attEntry;
				if (newEntry->Session().FileSession().Entry(dest.FullName(), attEntry) == KErrNone)
						attachmentEntry.iSize = attEntry.iSize;

				newEntry->ChangeL(attachmentEntry);
				CleanupStack::PopAndDestroy(newEntry);
				}
			}
		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?