calendarmodule.cpp

来自「python s60 1.4.5版本的源代码」· C++ 代码 · 共 2,227 行 · 第 1/5 页

CPP
2,227
字号
  }
}


/*
 * Checks if the time value represents agenda model's null time.
 */
TBool Is_null_time(const TTime& theTime)
{
  if(AgnDateTime::TTimeToAgnDate(theTime)==AgnDateTime::NullDate()){
    return ETrue;
  }else{
    return EFalse;
  }
}


/*
 * Debug printing.
 */
void
pyprintf(const char *format, ...)
{
  va_list args;
  va_start(args,format);
  char buf[128];
  // Unfortunately Symbian doesn't seem to support the vsnprintf
  // function, which would allow us to specify the length of the
  // buffer we are writing to. As a result using this function is
  // unsafe and will lead to a buffer overflow if given an argument
  // that is too big. Do not use this function in production code.
  vsprintf(buf, format, args);    
  char buf2[128];
  sprintf(buf2, "print '%s'", buf);
  PyRun_SimpleString(buf2);
}


//////////////TYPE METHODS///////////////


/*
 * Module methods.
 */

 
/*
 * Opens the database and creates and returns a CalendarDb-object.
 *
 * open() - opens the default agenda 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 = 0;
  HBufC* filenameBuf = NULL;
  RAgendaServ* agendaServer = NULL;
  CAgnModel* agendaModel = NULL;
  if (!PyArg_ParseTuple(args, "|Us", &filename, &flag)){ 
    return NULL;
  }
  
  // Check filename length.
  if(filename && PyUnicode_GetSize(filename)>KMaxFileName){
    PyErr_SetString(PyExc_NameError, "filename too long");
    return NULL;
  }

  // Check the parameters and create new agenda file if needed.
  TRAPD(error1, {     
    if(!flag){
      if(!filename){
        filenameBuf = HBufC::NewL((&KDefaultAgendaFile)->Length());
        filenameBuf->Des().Append(KDefaultAgendaFile);
        if(!testFileExistenceL(*filenameBuf)){
          // Default file does not exist. Create it.       
          createNewAgendaFileL(*filenameBuf);
        }
      }else{
        TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), 
                          PyUnicode_GetSize(filename));
        filenameBuf = HBufC::NewL(filenamePtr.Length());
        filenameBuf->Des().Append(filenamePtr);
      }
      if(!testFileExistenceL(*filenameBuf)){
        // 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));
        filenameBuf = HBufC::NewL(filenamePtr.Length());
        filenameBuf->Des().Append(filenamePtr);
        if(!testFileExistenceL(*filenameBuf)){
          createNewAgendaFileL(*filenameBuf);
        }
      }else if(filename && flag[0] == 'n'){
        // Create a new empty file.
        TPtrC filenamePtr((TUint16*) PyUnicode_AsUnicode(filename), 
                          PyUnicode_GetSize(filename));
        filenameBuf = HBufC::NewL(filenamePtr.Length());
        filenameBuf->Des().Append(filenamePtr);
        createNewAgendaFileL(*filenameBuf);
      }else{
        // Illegal parameter combination.
        userError = 2;
      }  
    }
  });

  if(error1 != KErrNone){
    delete filenameBuf;
    return SPyErr_SetFromSymbianOSErr(error1);
  }
  if(userError == 1){
    delete filenameBuf;
    PyErr_SetString(PyExc_NameError, "file does not exist");
    return NULL;
  }
  if(userError == 2){
    delete filenameBuf;
    PyErr_SetString(PyExc_SyntaxError, "illegal parameter combination");
    return NULL;
  }

  // Open the db file.
  TRAPD(error2, {      
    agendaServer = RAgendaServ::NewL();  
    CleanupStack::PushL(agendaServer);
    agendaServer->Connect();
    CleanupClosePushL(*agendaServer); 

    agendaModel = CAgnModel::NewL(NULL);
    CleanupStack::PushL(agendaModel);
    agendaModel->SetServer(agendaServer);
    agendaModel->SetMode(CAgnEntryModel::EClient); 

    agendaModel->OpenL(filenameBuf->Des(), 
                       KDefaultTimeForEvents,
                       KDefaultTimeForAnnivs, 
                       KDefaultTimeForDayNote);

    agendaServer->WaitUntilLoaded();

    CleanupStack::Pop(); // agendaModel.
    CleanupStack::Pop(); // Close agendaServer.
    CleanupStack::Pop(); // agendaServer.
  });

  delete filenameBuf;

  if(error2 != KErrNone){
    return SPyErr_SetFromSymbianOSErr(error2);
  }

  return new_CalendarDb_object(agendaServer, agendaModel);
}


/* 
 * CalendarDb methods.
 */


/*
 * Create new CalendarDb object.
 */
extern "C" PyObject *
new_CalendarDb_object(RAgendaServ* agendaServer, CAgnModel* agendaModel)
{
  CalendarDb_object* calendarDb = 
    PyObject_New(CalendarDb_object, CalendarDb_type);
  if (calendarDb == NULL){
    delete agendaModel;
    if(agendaServer->FileLoaded()){
      agendaServer->CloseAgenda(); 
    }
    agendaServer->Close();
    delete agendaServer;
    return PyErr_NoMemory();
  }
 
  calendarDb->agendaServer = agendaServer;
  calendarDb->agendaModel = agendaModel;
  
  return (PyObject*)calendarDb;
}


/*
 * Returns calendar entry object (indicated by given unique id).
 */ 
static PyObject *
CalendarDb_getitem(CalendarDb_object *self, PyObject *key)
{
  CHECK_AGENDA_STATE_DB

  if(!PyInt_Check(key)){
    PyErr_SetString(PyExc_TypeError, "entry id must be integer");
    return NULL;
  };

  TAgnUniqueId uniqueIdObj(PyInt_AsLong(key));

  if(uniqueIdObj.IsNullId()){
    PyErr_SetString(PyExc_ValueError, "illegal entry id");
    return NULL;
  }
  return new_Entry_object(self, uniqueIdObj);  
}


/*
 * Creates new entry (but does not commit it into the database).
 */ 
static PyObject *
CalendarDb_add_entry(CalendarDb_object *self, PyObject *args)
{
  CHECK_AGENDA_STATE_DB

  TInt entryType = 0;
  if (!PyArg_ParseTuple(args, "i", &entryType)){ 
    return NULL;
  }
  
  TAgnUniqueId id;
  id.SetNullId();

  return new_Entry_object(self, id, static_cast<CAgnEntry::TType>(entryType));
}


/*
 * Removes the entry from the database.
 */ 
static PyObject *
CalendarDb_delete_entry(CalendarDb_object *self, const TAgnUniqueId& uniqueId)
{
  // pyprintf("delete %d", uniqueId); // ??? debug

  CHECK_AGENDA_STATE_DB

  TRAPD(error, {
    self->agendaModel->DeleteEntryL(self->agendaServer->GetEntryId(uniqueId));
  });

  if(error!=KErrNone){
    return SPyErr_SetFromSymbianOSErr(error);
  }

  Py_INCREF(Py_None);
  return Py_None;
}


/*
 * Deletes specified entry.
 */
static int
CalendarDb_ass_sub(CalendarDb_object *self, PyObject *key, PyObject *value)
{
  CHECK_AGENDA_STATE_DB

  PyObject* result = NULL;
 
  if(value!=NULL){
    PyErr_SetString(PyExc_NotImplementedError, "illegal usage");
    return -1; 
  }

  if(!PyInt_Check(key)){
      PyErr_SetString(PyExc_TypeError, "entry id must be integer");
      return -1;
  }

  result = CalendarDb_delete_entry(self, TAgnUniqueId(PyInt_AsLong(key)));

  if(!result){
    return -1;
  }else{
    Py_DECREF(result);
  }
  return 0;  
}


/*
 * Returns number of entries in the database.
 */
static int
CalendarDb_len(CalendarDb_object *self)
{
  CHECK_AGENDA_STATE_DB

  TInt length = -1;

  TRAPD(error, {
    length = self->agendaModel->EntryCount();
  });

  if(error != KErrNone){
    SPyErr_SetFromSymbianOSErr(error);
  }

  return length;
}


/*
 * Deallocate the calendarDb object.
 */
extern "C" {
  static void CalendarDb_dealloc(CalendarDb_object *calendarDb)
  {
    if (calendarDb->agendaModel) {
      // pyprintf("DB dealloc %d", calendarDb); // ??? debug
      delete calendarDb->agendaModel;
      calendarDb->agendaModel = NULL;
    }
    if (calendarDb->agendaServer) {
      if(calendarDb->agendaServer->FileLoaded()){
        calendarDb->agendaServer->CloseAgenda();
        
      }
      calendarDb->agendaServer->Close();
      delete calendarDb->agendaServer;
      calendarDb->agendaServer = NULL;
    }
    
    PyObject_Del(calendarDb);
  }
}


/*
 * Sets the filter to be used in the entry search.
 */
void setFilterData(TAgnFilter& filter, TInt filterData)
{
  if(filterData==0){
    return; // Use the default.
  }

  // Set the filter data.

  if(filterData & APPTS_INC_FILTER){
    filter.SetIncludeTimedAppts(ETrue);
  }else{
    filter.SetIncludeTimedAppts(EFalse);
  }

  if(filterData & EVENTS_INC_FILTER){
     filter.SetIncludeEvents(ETrue);
  }else{
     filter.SetIncludeEvents(EFalse);
  }

  if(filterData & ANNIVS_INC_FILTER){
    filter.SetIncludeAnnivs(ETrue);
  }else{
    filter.SetIncludeAnnivs(EFalse);
  }

  if(filterData & TODOS_INC_FILTER){
    filter.SetIncludeTodos(ETrue);
  }else{
    filter.SetIncludeTodos(EFalse);
  }
}


/*
 * Returns all instances (instance = entry's unique id + 
 * datetime of the specific occurrence of the entry)
 * of the given month.
 * -the month is the month (of the calendar:january, ..) 
 * the given datetime parameter belongs to (it has no 
 * matter which day of this month the datetime specifies).
 * -returns list of instances like [{"unique_id":543245, 
 * "datetime":14565645.0}, {"unique_id":653456, "datetime":14565655.0}].
 */
extern "C" PyObject *
CalendarDb_monthly_instances(CalendarDb_object* self, PyObject *args)
{
  CHECK_AGENDA_STATE_DB

  TReal month = 0;
  CAgnMonthInstanceList* monthList = NULL;
  TInt filterInt = 0;
  if (!PyArg_ParseTuple(args, "d|i", &month, &filterInt)){ 
    return NULL;
  }

  TTime monthTTime;
  pythonRealAsTTime(month, monthTTime);
  if(Check_time_validity(monthTTime)==EFalse){
    PyErr_SetString(PyExc_ValueError, "illegal date value");
    return NULL;
  }

  TTime today;
  today.HomeTime();
  TAgnFilter filter;
  setFilterData(filter, filterInt);
  TRAPD(error, {
    monthList = 
      CAgnMonthInstanceList::NewL(TTimeIntervalYears(monthTTime.DateTime().Year()), 
                                  monthTTime.DateTime().Month());
    self->agendaModel->PopulateMonthInstanceListL(monthList, filter, today);
  });

  if(error != KErrNone){
    if(monthList){
      monthList->Reset();
      delete monthList;
    }
    return SPyErr_SetFromSymbianOSErr(error);
  }

  PyObject* idList = PyList_New(monthList->Count()); 
  if(idList==NULL){
    monthList->Reset();
    delete monthList;
    return PyErr_NoMemory();
  }

  for(TInt i=0;i<monthList->Count();i++){
    TAgnInstanceId id = (*monthList)[i];
    PyObject* instanceInfo =
      Py_BuildValue("{s:i,s:d}", (const char*)(&KUniqueId)->Ptr(), 
                                 self->agendaServer->GetUniqueId(id), 
                                 (const char*)(&KDateTime)->Ptr(), 
                                 time_as_UTC_TReal(AgnDateTime::AgnDateToTTime(id.Date())));
    if(instanceInfo==NULL){
      Py_DECREF(idList);
      monthList->Reset();
      delete monthList;
      return NULL;
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?