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