contact.cpp
来自「在手机操作系统symbina上使用的一个脚本扩展语言的代码实现,可以参考用于自己」· C++ 代码 · 共 1,171 行 · 第 1/2 页
CPP
1,171 行
// Contact.cpp - Contacts OPX
//
// Copyright (c) 1997-2000 Symbian Ltd. All rights reserved.
#include "Contact.h"
#include "opxutil.h"
////////////////////////////////////////////////////////////////////////////////////////////
// CNTOpx class : derives from COpxBase
//
// The language extension procedures provided by this OPX
//
CPtrs::~CPtrs()
{
delete iCurrentItem;
delete iSortedIds;
delete iFoundIds;
// CContactIdArray* iGroupIds;
}
CCntOpx::~CCntOpx()
{
delete iPtrs;
delete iDbHandle;
}
void CCntOpx::CreateContactFileL(OplAPI& aOplAPI)
// create new contacts database
// COCreateContactFile:(aFileName$):
{
if (iDbHandle)
User::Leave(KOplErrAlreadyOpen);
iDbHandle = CContactDatabase::CreateL(aOplAPI.PopString());
iPtrs = new (ELeave) CPtrs();
aOplAPI.Push(0.0);
}
void CCntOpx::OpenContactFileL(OplAPI& aOplAPI)
// open contacts database
// COOpenContactFile:(aFileName$)
{
if (iDbHandle)
User::Leave(KOplErrAlreadyOpen);
iDbHandle = CContactDatabase::OpenL(aOplAPI.PopString());
iPtrs = new (ELeave) CPtrs();
aOplAPI.Push(0.0);
}
void CCntOpx::CloseContactFileL(OplAPI& aOplAPI)
// closes contacts database
// COCloseContactFile:
{
delete iDbHandle;
iDbHandle = NULL;
delete iPtrs;
iPtrs = NULL;
aOplAPI.Push(0.0);
}
void CCntOpx::SortItemsL(OplAPI& aOplAPI)
// sort contacts database
// COSortContactFile:(aKuidMapping&)
{
LeaveIfNoOpenDbL();
CArrayFix<CContactDatabase::TSortPref>* sortOrder=new(ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(3);
CleanupStack::PushL(sortOrder);
TInt32* aKUidList = aOplAPI.PopPtrInt32();
TInt count=aOplAPI.GetLong((TAny*)aKUidList);
for(TInt i=count;i>0;i--)
{
TInt tempUid=aOplAPI.GetLong((TAny*)++aKUidList);
sortOrder->AppendL(CContactDatabase::TSortPref(TUid::Uid(tempUid)));
}
iDbHandle->SortL(sortOrder);
delete iPtrs->iSortedIds;
iPtrs->iSortedIds=NULL;
iPtrs->iSortedIds=CContactIdArray::NewL(iDbHandle->SortedItemsL());
CleanupStack::Pop(); // sortOrder
aOplAPI.Push(0.0);
}
void CCntOpx::SortedItemsAtL(OplAPI& aOplAPI)
// indexes into the sorted contacts
// COSortedContactFileAt:(aIndex&):
{
LeaveIfNoOpenDbL();
TInt index = OpxUtil::CppIndex(aOplAPI.PopInt32());
if (index >= iPtrs->iSortedIds->Count())
User::Leave(KOplErrSubs);
if (index<0)
User::Leave(KOplErrSubs);
TContactItemId tempId = (*iPtrs->iSortedIds)[index];
DoCloseItemL();
DoOpenItemL(tempId);
aOplAPI.Push(0.0);
}
void CCntOpx::CompressContactFile(OplAPI& aOplAPI)
// compress contacts database
// COCompressContactFile:
{
LeaveIfNoOpenDbL();
iDbHandle->CompressL();
aOplAPI.Push(0.0);
}
void CCntOpx::CompressNeeded(OplAPI& aOplAPI)
// is a compress required
// COCompressNeeded%:
{
LeaveIfNoOpenDbL();
aOplAPI.Push((TInt16)iDbHandle->CompressRequired());
}
void CCntOpx::CountItemsL(OplAPI& aOplAPI)
// counts contacts in database
// COCountContacts&:
{
LeaveIfNoOpenDbL();
aOplAPI.Push((TInt32)iDbHandle->CountL());
}
void CCntOpx::AddNewItemL(OplAPI& aOplAPI)
// adds a new contact to database
// COAddNewContact:
{
LeaveIfNoWriteableItemL();
iDbHandle->AddNewContactL(*iPtrs->iCurrentItem);
delete iPtrs->iCurrentItem;
iPtrs->iCurrentItem=NULL;
iPtrs->iField=NULL;
aOplAPI.Push(0.0);
}
void CCntOpx::DeleteItemL(OplAPI& aOplAPI)
// deletes a contact
// CODeleteContact:
{
LeaveIfNoWriteableItemL();
iPtrs->iDeleted = ETrue;
aOplAPI.Push(0.0);
}
void CCntOpx::ReadItemL(OplAPI& aOplAPI)
// reads contact
// COReadContact:(aContactItemId&)
{
LeaveIfNoOpenDbL();
iPtrs->iCurrentItem = iDbHandle->ReadContactL(aOplAPI.PopInt32());
iPtrs->iOpenedForRead=ETrue;
aOplAPI.Push(0.0);
}
void CCntOpx::OpenItemL(OplAPI& aOplAPI)
// opens contact
// COOpenContact:(aContactItemId&)
{
LeaveIfNoOpenDbL();
if ((iPtrs->iCurrentItem) && (iPtrs->iOpenedForRead==EFalse))
User::Leave(KOplErrAlreadyOpen);
TInt contactItemId = aOplAPI.PopInt32();
DoOpenItemL(contactItemId);
aOplAPI.Push(0.0);
}
void CCntOpx::CloseItemL(OplAPI& aOplAPI)
// closes contact
// COCloseContact:
{
DoCloseItemL();
aOplAPI.Push(0.0);
}
void CCntOpx::ItemIdL(OplAPI& aOplAPI)
// returns contact ID
// COContactId&:
{
LeaveIfNoReadableItemL();
aOplAPI.Push((TInt32)iPtrs->iCurrentItem->Id());
}
void CCntOpx::SetItemHiddenL(OplAPI& aOplAPI)
// sets contact to hidden
// COSetContactHidden:(aHidden%)
{
LeaveIfNoWriteableItemL();
if (iPtrs->iOpenedForRead)
User::Leave(KErrNotSupported);
TBool hidden = OpxUtil::CppBool(aOplAPI.PopInt16());
iPtrs->iCurrentItem->SetHidden(hidden);
aOplAPI.Push(0.0);
}
void CCntOpx::SetItemSystemL(OplAPI& aOplAPI)
// sets contact to system
// COSetContactSystem:(aSystem%)
{
LeaveIfNoWriteableItemL();
if (iPtrs->iOpenedForRead)
User::Leave(KErrNotSupported);
TBool system = OpxUtil::CppBool(aOplAPI.PopInt16());
iPtrs->iCurrentItem->SetSystem(system);
aOplAPI.Push(0.0);
}
void CCntOpx::IsItemHiddenL(OplAPI& aOplAPI)
// test if contact is hidden
// COIsContactHidden%:
{
LeaveIfNoReadableItemL();
aOplAPI.Push((TInt16)iPtrs->iCurrentItem->IsHidden());
}
void CCntOpx::IsItemSystemL(OplAPI& aOplAPI)
// test if contact is system
// COIsContactSystem%:
{
LeaveIfNoReadableItemL();
aOplAPI.Push((TInt16)iPtrs->iCurrentItem->IsSystem());
}
/* not sure if this is needed
void CCntOpx::CommitItemL()
// commits contact
// COCommitContact:
{
iPtrs->LeaveIfNoOpenItemL();
iDbHandle->CommitContactL(*iPtrs->iCurrentItem);
}
*/
void CCntOpx::FindItemL(OplAPI& aOplAPI)
// finds a contact
// COFindContact&:(aString$,aUIdArrayHandle&)
{
LeaveIfNoOpenDbL();
CContactItemFieldDef* fieldDef=new(ELeave) CContactItemFieldDef;
CleanupStack::PushL(fieldDef);
TInt32* aKUidList = aOplAPI.PopPtrInt32();
TInt count=aOplAPI.GetLong((TAny*)aKUidList);
for(TInt i=count;i>0;i--)
{
TInt tempUid=aOplAPI.GetLong((TAny*)++aKUidList);
fieldDef->AppendL(TUid::Uid(tempUid));
}
TPtrC text = aOplAPI.PopString();
delete iPtrs->iFoundIds;
iPtrs->iFoundIds = NULL;
iPtrs->iFoundIds = iDbHandle->FindLC(text,fieldDef);
fieldDef->Reset();
CleanupStack::PopAndDestroy(); //fieldDef;
aOplAPI.Push((TInt32)iPtrs->iFoundIds->Count());
}
void CCntOpx::CreateItemL(OplAPI& aOplAPI)
// creates a contact
// COCreateContact:
{
LeaveIfNoOpenDbL();
TInt templateId = aOplAPI.PopInt32();
TInt itemType = aOplAPI.PopInt32();
switch (itemType)
{
case EContact:
{
//To Do: check templateId must be a template
CContactItem* copyFrom = iDbHandle->ReadContactLC(templateId);
iPtrs->iCurrentItem = CContactCard::NewL(copyFrom);
CleanupStack::PopAndDestroy(); //copyFrom
}
break;
case ETemplate:
{
//To Do: check templateId can be either a template or card
CContactItem* copyFrom = iDbHandle->ReadContactLC(templateId);
iPtrs->iCurrentItem = CContactTemplate::NewL(copyFrom);
CleanupStack::PopAndDestroy(); //copyFrom
}
break;
case EGroup:
iPtrs->iCurrentItem = CContactGroup::NewL();
break;
default:
User::Leave(KOplErrOutOfRange);
}
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldArrayAt(OplAPI& aOplAPI)
// indexs into field array
// COContactFieldArrayAt:(aIndex&)
{
LeaveIfNoReadableItemL();
TInt index = OpxUtil::CppIndex(aOplAPI.PopInt32());
CContactItemFieldSet& fields = iPtrs->iCurrentItem->CardFields();
if ((index<0) || (index>fields.Count()))
User::Leave(KOplErrSubs);
iPtrs->iField = &fields[index];
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldFind(OplAPI& aOplAPI)
// finds a field type in array
// COContactFieldFind%:(aTypeArrayHandle&)
{
LeaveIfNoReadableItemL();
CContactItemFieldSet& fields = iPtrs->iCurrentItem->CardFields();
TInt tempCount= fields.Count();
TInt32* pointer = aOplAPI.PopPtrInt32();
TInt count=aOplAPI.GetLong((TAny*)pointer);
TUid tempMappingUid =TUid::Uid(aOplAPI.GetLong((TAny*)++pointer));
TUid vCard1=TUid::Uid(aOplAPI.GetLong((TAny*)++pointer));
TUid vCard2=TUid::Uid(aOplAPI.GetLong((TAny*)++pointer));
TUid vCard3=TUid::Uid(aOplAPI.GetLong((TAny*)++pointer));
TBool found=EFalse;
TInt pos=KErrNotFound;
for(TInt jj=0;jj<count;jj++) // unreachable code here
{
if (count==2)
pos=fields.Find(tempMappingUid); // Bug Fix: In the case of a 2 item array, the 1st Item holds VCard1, but has been read into tempMappingUid
else
pos=fields.Find(tempMappingUid,vCard1);
if (pos!=KErrNotFound)
{
if (count<=3)
break;
else
{
const CContentType& tempContent=fields[pos].ContentType();
if ((count==4) && (tempContent.ContainsFieldType(vCard2)) &&
(tempContent.FieldTypeCount()==2))
break;
else if ((count==5) && (tempContent.ContainsFieldType(vCard2)) &&
(tempContent.ContainsFieldType(vCard3)) && (tempContent.FieldTypeCount()==3))
break;
else
{
TInt start=pos+1;
while ((start<tempCount) && (found==EFalse) && (pos!=KErrNotFound))
{
pos=fields.FindNext(tempMappingUid,vCard1,start);
if (pos!=KErrNotFound)
{
const CContentType& tmpContent=fields[pos].ContentType();
TInt fieldCount=tmpContent.FieldTypeCount();
if (vCard3.iUid==0)
{
if ((tmpContent.ContainsFieldType(vCard2)) && (fieldCount==(count-2)))
{
found=ETrue;
break;
}
}
else
{
if ((tmpContent.ContainsFieldType(vCard2)) && (tmpContent.ContainsFieldType(vCard3))&& (fieldCount==(count-2)))
{
found=ETrue;
break;
}
}
}
start=pos+1;
}
}
}
}
}
iPtrs->iField=NULL;
if (pos!=KErrNotFound)
aOplAPI.Push((TInt16)++pos);
else
User::Leave(KErrNotFound);
}
void CCntOpx::ContactFieldCount(OplAPI& aOplAPI)
// counts fields in field array
// COContactFieldCount&:
{
LeaveIfNoReadableItemL();
CContactItemFieldSet& fields = iPtrs->iCurrentItem->CardFields();
aOplAPI.Push((TInt32)fields.Count());
}
void CCntOpx::ContactFieldReset(OplAPI& aOplAPI)
// resets field array
// COContactFieldReset:
{
LeaveIfNoWriteableItemL();
iPtrs->iCurrentItem->CardFields().Reset();
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldAdd(OplAPI& aOplAPI)
// adds field to field array
// COContactFieldAdd:
{
LeaveIfNoWriteableItemL();
if (iPtrs->iField==NULL)
User::Leave(KOplErrGenFail);
iPtrs->iCurrentItem->AddFieldL(*(iPtrs->iField));
iPtrs->iField=NULL;
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldDelete(OplAPI& aOplAPI)
// removes field from field array
// COContactFieldDelete:
{
LeaveIfNoWriteableItemL();
if (iPtrs->iField==NULL)
User::Leave(KOplErrNotSupported);
if (iPtrs->iCurrentItem->Type()==KUidContactTemplate)
User::Leave(KOplErrAccess); // trying to delete template field
CContactItemFieldSet& fields = iPtrs->iCurrentItem->CardFields();
const CContentType& tempContentType = iPtrs->iField->ContentType();
TInt count=tempContentType.FieldTypeCount();
TInt tempCount= fields.Count();
TUid vCard1 = tempContentType.Mapping();
TUid vCard2;
TUid tempMappingUid=tempContentType.FieldType(0);
if (count > 1)
{
vCard2=tempContentType.FieldType(count-1);
}
else
{
vCard2=TUid::Uid(NULL);
}
////////////////////
TBool found=EFalse;
TInt pos=KErrNotFound;
for(TInt jj=0;jj<count;jj++) // unreachable code here
{
pos=fields.Find(tempMappingUid,vCard1);
if (pos!=KErrNotFound)
{
if (count==1)
break;
else
{
const CContentType& tempContent=fields[pos].ContentType();
if (tempContent.ContainsFieldType(vCard2))
break;
else
{
TInt start=pos+1;
while ((start<tempCount) && (found==EFalse) && (pos!=KErrNotFound))
{
pos=fields.FindNext(tempMappingUid,vCard1,start);
if (pos!=KErrNotFound)
{
const CContentType& tempContent=fields[pos].ContentType();
if (tempContent.ContainsFieldType(vCard2))
{
found=ETrue;
break;
}
}
start=pos+1;
}
}
}
}
}
if (pos!=KErrNotFound)
fields.Remove(pos);
else
User::Leave(KErrNotFound);
iPtrs->iField=NULL;
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldInsert(OplAPI& aOplAPI)
// inserts a field into field array
// COContactFieldInsert:(aIndex&)
{
LeaveIfNoWriteableItemL();
if (iPtrs->iField==NULL)
User::Leave(KOplErrNotSupported);
TInt index = OpxUtil::CppIndex(aOplAPI.PopInt32());
CContactItemFieldSet& fields = iPtrs->iCurrentItem->CardFields();
if ((index<0) || (index>fields.Count()))
User::Leave(KOplErrSubs);
fields.InsertL(index,*(iPtrs->iField));
iPtrs->iField=NULL;
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldMove(OplAPI& aOplAPI)
// moves field in field array
// COContactFieldMove:(aPosFrom&,aPosTo&)
{
LeaveIfNoWriteableItemL();
TInt indexFrom = aOplAPI.PopInt32();
if(--indexFrom<0)
User::Leave(KOplErrSubs);
TInt indexTo= aOplAPI.PopInt32();
if(--indexTo<0)
User::Leave(KOplErrSubs);
CContactItemFieldSet& fields = iPtrs->iCurrentItem->CardFields();
TInt numFields = fields.Count();
if ((indexFrom > numFields) || (indexTo > numFields))
User::Leave(KErrArgument);
fields.Move(indexFrom,indexTo);
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldCreate(OplAPI& aOplAPI)
// creates a field
// COContactFieldCreate:
{
LeaveIfNoWriteableItemL();
if (!iPtrs->iField)
iPtrs->iField=NULL;
CleanupStack::PushL(iPtrs);
iPtrs->iField=CContactItemField::NewL(KStorageTypeText);
CleanupStack::Pop(); //iPtrs
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldContent(OplAPI& aOplAPI)
// returns the content type of a field
// COContactFieldContent:(contentTypeArray&)
{
LeaveIfNoReadableItemL();
if (iPtrs->iField==NULL)
User::Leave(KOplErrNotExists);
const CContentType& tempContent = iPtrs->iField->ContentType();
TInt32 count = tempContent.FieldTypeCount();
TUid mapping = tempContent.Mapping();
TInt32* pointer = aOplAPI.PopPtrInt32();
aOplAPI.PutLong(pointer,count+2);
aOplAPI.PutLong(++pointer,mapping.iUid);
for (TInt i=0;i<count;i++)
{
aOplAPI.PutLong(++pointer,tempContent.FieldType(i).iUid);
}
aOplAPI.Push(0.0);
}
void CCntOpx::ContactFieldIsHidden(OplAPI& aOplAPI)
// returns whether field is hidden
// COContactFieldIsHidden%:
{
LeaveIfNoReadableItemL();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?