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 + -
显示快捷键?