⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contactsmodule.cpp

📁 python s60 1.4.5版本的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 * ====================================================================
 * 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 + -