📄 contactsmodule.cpp
字号:
/*
* ====================================================================
* contactsmodule.cpp
*
* Python API to Series 60 contacts database.
*
* Implements currently (21.04.2005) following Python methods and types:
*
* open()
* - open the default contacts database.
* open(<filename>)
* - open the specified contacts database.
* open(<filename>, 'c')
* - open the specified contacts database. create if does not exist.
* open(<filename>, 'n')
* - create new, empty contacts database.
*
* ContactsDb
* close()
* - close the database.
* add_contact()
* - create new contact. note that the contact is not added and saved
* into the database unless Contact.commit() is called.
* find(unicode [,tuple<int,..>])
* - return tuple that contains unique contact id:s found in the search.
* match is detected if search string is a substring of contact field data.
* if field type id:s are given in the optional tuple parameter the search
* is reduced to fields of those types (however, this "reducing" cannot
* be trusted a lot. see the c++ api documentation.)
* export_vcards(tuple<int,..>)
* - returns string object that contains specified contacts as vcards.
* import_vcards(string)
* - imports contacts that are in vcard format in the string object.
* returns tuple that contains unique id:s of imported contacts.
* field_types()
* - returns dictionary that contains some basic information of field types
* this contact database supports. key is the index of the field type
* and value is a dictionary.
* field_info(int)
* - returns detailed information of the specified field type. the parameter
* is the index of the field type (see field_types()).
*
* ContactIterator
* next()
* - returns next contact id.
*
* Contact
* entry_data()
* - returns dictionary that contains information concerning the contact
* (uniqueid, title, lastmodified).
* begin()
* - sets the contact to read-write mode.
* commit()
* - saves the changes made to the contact and sets the contact to read-only
* mode.
* rollback()
* - discards the changes made to the contact and sets the contact to
* read-only mode.
* add_field(int OR tuple<int,int>[, (value=)unicode][, (label=)unicode])
* - adds field to the contact. field type or field type and location (tuple)
* must be specified. value and label are optional parameters.
* returns the index of the field (index in the contact's field table).
* modify_field(int, [, (value=)unicode][, (label=)unicode])
* - modifies field value and/or label. field index must be specified
* (field's index in the contact's field table).
* field_info_index(int)
* - returns key/index of the field type (see field_types() and field_info())
* indicated by the given parameter (field's index in the contact's field table).
*
* FieldIterator
* next()
* - returns dictionary that contains field's data.
*
*
*
* FURTHER INFORMATION:
*
* About the values returned by field_info():
*
* fieldinfoindex
* -index/key of this field type in the dictionary returned by field_types().
* fieldname
* -this field type's default label.
* fieldid
* -field id of this field type.
* fieldlocation
* -location information of the field.
* storagetype
* -storage type of this field type. possible values:
* storage_type_text
* -text, phonenumbers, email addresses etc.
* storage_type_datetime
* -datetime values
* storage_type_store
* -binary data. reading or manipulating this type of content
* is not supported by this extension.
* storage_type_contact_item_id
* -used by agent fields. reading or manipulating this type of
* content is not supported by this extension.
* multiplicity
* -multiplicity allowed for this field type. possible values:
* field_type_multiplicity_one
* field_type_multiplicity_many
* maxlength
* -maximum data length specified for this field type.
* readonly
* -is this field read only.
* namefield
* -is this is a name field type (like first name, last name).
* usercanaddfield
* -can this field be added by user.
* editable
* -can the field be edited in Phonebook's contact editor.
* numericfield
* -is this a numeric field.
* phonenumberfield
* -is this a phone number field.
* mmsfield
* -is this is a MMS address field.
* imagefield
* -is this an image field.
* additemtext
* -the add item labeltext of the field.
*
*
* Copyright (c) 2005-2007 Nokia Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ====================================================================
*/
#include "contactsmodule.h"
//////////////GENERAL FUNCTIONS///////////////
/*
* Tests if the contact entry is a contact group.
*/
TBool IsContactGroup(CContactItem& item)
{
if(item.Type().iUid==KContactGroupTypeId){
return ETrue;
}
return EFalse;
};
//////////////TYPE METHODS///////////////
/*
* Module methods.
*/
/*
* Opens the database and creates and returns a ContactsDb-object.
*
* open() - opens the default contact database file
* open(u'filename') - opens file if it exists.
* open(u'filename', 'c') - opens file, creates if the file does not exist.
* open(u'filename', 'n') - creates new empty database file.
*/
extern "C" PyObject *
open_db(PyObject* /*self*/, PyObject *args)
{
PyObject* filename = NULL;
char* flag = NULL;
TInt userError = KErrNone;
CPbkContactEngine* contactEngine = NULL;
RFs* fileServer = NULL;
if (!PyArg_ParseTuple(args, "|Us", &filename, &flag)){
return NULL;
}
TRAPD(serverError, {
fileServer = new (ELeave) RFs;
User::LeaveIfError(fileServer->Connect());
});
if(serverError!=KErrNone){
return SPyErr_SetFromSymbianOSErr(serverError);
}
TRAPD(error, {
if(!flag){
if(!filename){
// Open default db file.
contactEngine = CPbkContactEngine::NewL(fileServer);
}else{
// Open given db file, raise exception if the file does not exist.
TBool fileExists = EFalse;
RFs fileSession;
TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), PyUnicode_GetSize(filename));
User::LeaveIfError(fileSession.Connect());
CleanupClosePushL(fileSession);
fileExists = BaflUtils::FileExists(fileSession, filenamePtr);
CleanupStack::PopAndDestroy(); // Close fileSession.
if(fileExists){
contactEngine = CPbkContactEngine::NewL(filenamePtr, EFalse, fileServer);
}else{
// File does not exist.
userError = 1;
}
}
}else{
if(filename && flag[0] == 'c'){
// Open, create if file doesn't exist.
TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), PyUnicode_GetSize(filename));
contactEngine = CPbkContactEngine::NewL(filenamePtr, EFalse, fileServer);
}else if(filename && flag[0] == 'n'){
// Create a new empty file.
TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), PyUnicode_GetSize(filename));
contactEngine = CPbkContactEngine::NewL(filenamePtr, ETrue, fileServer);
}else{
// Illegal parameter combination.
userError = 2;
}
}
});
if(error != KErrNone){
fileServer->Close();
delete fileServer;
return SPyErr_SetFromSymbianOSErr(error);
}
if(userError == 1){
fileServer->Close();
delete fileServer;
PyErr_SetString(PyExc_NameError, "file does not exist");
return NULL;
}
if(userError == 2){
fileServer->Close();
delete fileServer;
PyErr_SetString(PyExc_SyntaxError, "illegal parameter combination");
return NULL;
}
return new_ContactsDb_object(contactEngine, fileServer);
}
/*
* ContactsDb methods.
*/
/*
* Create new ContactsDb object.
*/
extern "C" PyObject *
new_ContactsDb_object(CPbkContactEngine* contactEngine, RFs* fileServer)
{
if(!contactEngine){
fileServer->Close();
delete fileServer;
PyErr_SetString(PyExc_RuntimeError, "contact engine is null");
return NULL;
}
ContactsDb_object* contactsDb =
PyObject_New(ContactsDb_object, ContactsDb_type);
if (contactsDb == NULL){
delete contactEngine;
fileServer->Close();
delete fileServer;
return PyErr_NoMemory();
}
contactsDb->contactEngine = contactEngine;
contactsDb->fileServer = fileServer;
return (PyObject*) contactsDb;
}
/*
* Deallocate ContactsDb_object.
*/
extern "C" {
static void ContactsDb_dealloc(ContactsDb_object *contactsDb)
{
delete contactsDb->contactEngine;
contactsDb->fileServer->Close();
delete contactsDb->fileServer;
PyObject_Del(contactsDb);
}
}
/*
* Test whether contact entry indicated by uniqueId exists in the database
* and creates python wrapper (Contact_object) object if it does.
*/
extern "C" PyObject *
ContactsDb_get_contact_by_id(ContactsDb_object* self, TContactItemId uniqueId)
{
ASSERT_DBOPEN
if(uniqueId == KNullContactId){
PyErr_SetString(PyExc_ValueError, "illegal contact id");
return NULL;
}
return new_Contact_object(self, uniqueId);
}
/*
* Returns some information about supported field types
* (e.g. default labels, field id:s and location id:s of
* supported field types).
*/
extern "C" PyObject *
ContactsDb_field_types(ContactsDb_object* self, PyObject* /*args*/)
{
ASSERT_DBOPEN
TInt err = 0;
const CPbkFieldsInfo& fieldsInfo = self->contactEngine->FieldsInfo();
PyObject* fieldNameDict = PyDict_New();
if (fieldNameDict == NULL){
return PyErr_NoMemory();
}
for(TInt i=0; i<fieldsInfo.Count();i++){
PyObject* infoDict =
Py_BuildValue("{s:u#,s:i,s:i}",
(const char*)(&KKeyStrFieldName)->Ptr(), fieldsInfo[i]->FieldName().Ptr(),
fieldsInfo[i]->FieldName().Length(),
(const char*)(&KKeyStrFieldId)->Ptr(), fieldsInfo[i]->FieldId(),
(const char*)(&KKeyStrFieldLocation)->Ptr(), fieldsInfo[i]->Location());
if (infoDict == NULL){
Py_DECREF(fieldNameDict);
return NULL;
}
PyObject* indexObj = Py_BuildValue("i", i);
if (indexObj == NULL){
Py_DECREF(infoDict);
Py_DECREF(fieldNameDict);
return NULL;
}
err = PyDict_SetItem(fieldNameDict, indexObj, infoDict);
Py_DECREF(indexObj);
Py_DECREF(infoDict);
if(err<0){
Py_DECREF(fieldNameDict);
return NULL;
}
}
return fieldNameDict;
}
/*
* Returns information about the field type indicated by the index.
*/
extern "C" PyObject *
ContactsDb_field_info(ContactsDb_object* self, PyObject *args)
{
ASSERT_DBOPEN
TInt index;
if (!PyArg_ParseTuple(args, "i", &index)){
return NULL;
}
const CPbkFieldsInfo& fieldsInfo = self->contactEngine->FieldsInfo();
if (index < 0 || index >= fieldsInfo.Count()){
PyErr_SetString(PyExc_IndexError, "illegal field type index");
return NULL;
}
return Py_BuildValue("{s:i,s:u#,s:i,s:i,s:i,s:i,s:i,\
s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:u#}",
"fieldinfoindex", index,
(const char*)(&KKeyStrFieldName)->Ptr(), fieldsInfo[index]->FieldName().Ptr(),
fieldsInfo[index]->FieldName().Length(),
(const char*)(&KKeyStrFieldId)->Ptr(), fieldsInfo[index]->FieldId(),
(const char*)(&KKeyStrFieldLocation)->Ptr(), fieldsInfo[index]->Location(),
"storagetype", fieldsInfo[index]->FieldStorageType(),
"multiplicity", fieldsInfo[index]->Multiplicity(),
"maxlength", fieldsInfo[index]->MaxLength(),
"readonly", fieldsInfo[index]->IsReadOnly(),
"namefield", fieldsInfo[index]->NameField(),
"usercanaddfield", fieldsInfo[index]->UserCanAddField(),
"editable", fieldsInfo[index]->IsEditable(),
"numericfield", fieldsInfo[index]->NumericField(),
"phonenumberfield", fieldsInfo[index]->IsPhoneNumberField(),
"mmsfield", fieldsInfo[index]->IsMmsField(),
"imagefield", fieldsInfo[index]->IsImageField(),
"additemtext", fieldsInfo[index]->AddItemText().Ptr(),
fieldsInfo[index]->AddItemText().Length());
}
/*
* ContactsDb_object creates new contact.
*/
extern "C" PyObject *
ContactsDb_add_contact(ContactsDb_object* self, PyObject /**args*/)
{
return new_Contact_object(self, KNullContactId);
}
/*
* ContactsDb_object deletes given contact entry from the database.
* Entry is identified using it's unique ID.
*/
extern "C" PyObject *
ContactsDb_delete_contact(ContactsDb_object* self,
TContactItemId uniqueContactID)
{
ASSERT_DBOPEN
TInt error = KErrNone;
TRAP(error, self->contactEngine->DeleteContactL(uniqueContactID));
if(error != KErrNone){
return SPyErr_SetFromSymbianOSErr(error);
}
Py_INCREF(Py_None);
return Py_None;
}
/*
* Converts tuple of field id:s to CPbkFieldIdArray.
* (note that if fieldIdTuple==NULL CPbkFieldIdArray will contain all
* field id:s [due to bug in c++ api's contact engine's FindLC method]).
*/
extern "C" CPbkFieldIdArray *
ContactsDb_getFieldIdArrayL(ContactsDb_object* self, PyObject *fieldIdTuple)
{
CPbkFieldIdArray* fieldIdArray = new (ELeave) CPbkFieldIdArray;
CleanupStack::PushL(fieldIdArray);
const CPbkFieldsInfo& fieldsInfo = self->contactEngine->FieldsInfo();
for(TInt index = 0;index<fieldsInfo.Count();index++){
fieldIdArray->AppendL(fieldsInfo[index]->FieldId());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -