📄 tododb.c
字号:
if (item->description)
size += StrLen (item->description);
if (item->note)
size += StrLen (item->note);
// Allocate a chunk in the database for the new record.
recordH = (MemHandle)DmNewHandle(dbP, size);
if (recordH == NULL)
return dmErrMemError;
// Pack the the data into the new record.
recordP = MemHandleLock (recordH);
DmWrite(recordP, (UInt32)&nilP->dueDate, &item->dueDate, sizeof(nilP->dueDate));
DmWrite(recordP, (UInt32)&nilP->priority, &item->priority, sizeof(nilP->priority));
offset = (UInt32)&nilP->description;
if (item->description)
{
DmStrCopy(recordP, offset, item->description);
offset += StrLen (item->description) + 1;
}
else
{
DmWrite(recordP, offset, &zero, 1);
offset++;
}
if (item->note)
DmStrCopy(recordP, offset, item->note);
else
DmWrite(recordP, offset, &zero, 1);
sortInfo.attributes = category;
sortInfo.uniqueID[0] = 0;
sortInfo.uniqueID[1] = 0;
sortInfo.uniqueID[2] = 0;
// Determine the sort position of the new record.
newIndex = ToDoFindSortPosition (dbP, recordP, &sortInfo);
MemPtrUnlock (recordP);
// Insert the record.
err = DmAttachRecord(dbP, &newIndex, recordH, 0);
if (err)
MemHandleFree(recordH);
else
{
*index = newIndex;
// Set the category.
DmRecordInfo (dbP, newIndex, &attr, NULL, NULL);
attr &= ~dmRecAttrCategoryMask;
attr |= category;
DmSetRecordInfo (dbP, newIndex, &attr, NULL);
}
return err;
}
/***********************************************************************
*
* FUNCTION: ToDoInsertNewRecord
*
* DESCRIPTION: This routine creates a new record and inserts it after
* the specified position. The new record is assigned the
* same priority and due date as the record it is
* inserted after.
*
* PARAMETERS: database pointer
* database record
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 5/1/95 Initial Revision
*
***********************************************************************/
Err ToDoInsertNewRecord (DmOpenRef dbP, UInt16 * index)
{
UInt8 priority;
ToDoDBRecordPtr rec;
ToDoDBRecordPtr newRec;
MemHandle recH;
MemHandle newRecH;
Err err;
UInt16 size;
ToDoDBRecordPtr nilP=0;
UInt16 zero=0;
UInt16 newIndex;
UInt16 category;
UInt16 attr;
// Make a new chunk
size = sizeof (ToDoDBRecord) + 1;
newRecH = DmNewHandle (dbP, size);
if (! newRecH) return dmErrMemError;
// Get the record that the new record will be inserted after.
recH = DmQueryRecord (dbP, *index);
ErrFatalDisplayIf (!recH, "Error inserting new to do record");
rec = MemHandleLock (recH);
// Get the category of the current record.
DmRecordInfo (dbP, *index, &attr, NULL, NULL);
category = (attr & dmRecAttrCategoryMask);
// Set the priority and the due date of the new record to the same
// values as the record we're inserting after. This will insure
// that the records are in the proper sort order.
newRec = (ToDoDBRecord *) MemHandleLock (newRecH);
DmWrite(newRec, (UInt32)&nilP->dueDate, &rec->dueDate, sizeof(rec->dueDate));
priority = rec->priority & priorityOnly;
DmWrite(newRec, (UInt32)&nilP->priority, &priority, sizeof(rec->priority));
// Description is 1 byte, plus add extra byte for note field
DmWrite(newRec, (UInt32)&nilP->description, &zero, 2);
MemPtrUnlock (rec);
// Attach in place
newIndex = *index + 1;
err = DmAttachRecord(dbP, &newIndex, newRecH, 0);
if (err)
{
MemHandleFree(newRecH);
}
else
{
MemPtrUnlock (newRec);
// Set the category of the new record.
DmRecordInfo (dbP, newIndex, &attr, NULL, NULL);
attr |= category;
DmSetRecordInfo (dbP, newIndex, &attr, NULL);
*index = newIndex;
}
#if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL
ECToDoDBValidate (dbP);
#endif
return err;
}
/************************************************************
*
* FUNCTION: ToDoChangeSortOrder
*
* DESCRIPTION: Change the ToDo Database's sort order
*
* PARAMETERS: database pointer
* TRUE if sort by company
*
* RETURNS: nothing
*
* CREATED: 1/17/95
*
* BY: Roger Flores
*
*************************************************************/
Err ToDoChangeSortOrder(DmOpenRef dbP, UInt8 sortOrder)
{
ToDoAppInfoPtr appInfoP;
ToDoAppInfoPtr nilP = 0;
UInt16 dirtyAppInfo;
appInfoP = MemHandleLock (ToDoGetAppInfo (dbP));
if (appInfoP->sortOrder != sortOrder)
{
dirtyAppInfo = appInfoP->dirtyAppInfo | toDoSortByPriorityDirty;
DmWrite(appInfoP, (UInt32)&nilP->dirtyAppInfo, &dirtyAppInfo, sizeof(appInfoP->dirtyAppInfo));
DmWrite(appInfoP, (UInt32)&nilP->sortOrder, &sortOrder, sizeof(appInfoP->sortOrder));
DmInsertionSort(dbP, (DmComparF *) &ToDoCompareRecords, (Int16) sortOrder);
}
MemPtrUnlock (appInfoP);
return 0;
}
/************************************************************
*
* FUNCTION: ToDoSort
*
* DESCRIPTION: Sort the appointment database.
*
* PARAMETERS: database record
*
* RETURNS: nothing
*
* CREATED: 10/17/95
*
* BY: Art Lamb
*
*************************************************************/
void ToDoSort (DmOpenRef dbP)
{
int sortOrder;
sortOrder = ToDoGetSortOrder (dbP);
DmInsertionSort(dbP, (DmComparF *) &ToDoCompareRecords, (Int16) sortOrder);
}
/************************************************************
*
* FUNCTION: ToDoChangeRecord
*
* DESCRIPTION: Change a record in the ToDo Database
*
* PARAMETERS: database pointer
* database index
* database record
* changed fields
*
* RETURNS: ##0 if successful, errorcode if not
*
* CREATED: 1/14/95
*
* BY: Roger Flores
*
* COMMENTS: Records are not stored with extra padding - they
* are always resized to their exact storage space. This avoids
* a database compression issue. The code works as follows:
*
*
*************************************************************/
Err ToDoChangeRecord(DmOpenRef dbP, UInt16 *index,
ToDoRecordFieldType changedField, const void * data)
{
Err err;
Int16 cLen;
UInt16 attr;
UInt16 curSize;
UInt16 newSize;
UInt16 newIndex;
UInt8 priority;
UInt32 offset;
Char * c;
MemHandle recordH=0;
ToDoDBRecord temp;
ToDoDBRecordPtr src;
ToDoDBRecordPtr nilP = 0;
SortRecordInfoType sortInfo;
// Get the record which we are going to change
recordH = DmQueryRecord(dbP, *index);
src = MemHandleLock (recordH);
// If the record is being change such that its sort position will
// change, move the record to its new sort position.
if ( (changedField == toDoPriority) ||
(changedField == toDoDueDate) ||
(changedField == toDoCategory) )
{
MemSet (&sortInfo, sizeof (sortInfo), 0);
DmRecordInfo (dbP, *index, &attr, NULL, NULL);
sortInfo.attributes = attr;
if (changedField == toDoPriority)
{
temp.priority = *(UInt16 *) data;
temp.dueDate = src->dueDate;
sortInfo.attributes = attr;
}
else if (changedField == toDoDueDate)
{
temp.priority = src->priority;
temp.dueDate = *((DatePtr)data);
sortInfo.attributes = attr;
}
else
{
temp.priority = src->priority;
temp.dueDate = src->dueDate;
sortInfo.attributes = *(UInt16 *) data;
}
newIndex = ToDoFindSortPosition (dbP, &temp, &sortInfo);
DmMoveRecord (dbP, *index, newIndex);
if (newIndex > *index) newIndex--;
*index = newIndex;
}
if (changedField == toDoPriority)
{
priority = *(UInt16 *) data | (src->priority & completeFlag);
DmWrite (src, (UInt32)&nilP->priority, &priority, sizeof(src->priority));
goto exit;
}
if (changedField == toDoComplete)
{
priority = (*(UInt16 *) data << 7) | (src->priority & priorityOnly);
DmWrite (src, (UInt32)&nilP->priority, &priority, sizeof(src->priority));
goto exit;
}
if (changedField == toDoDueDate)
{
DmWrite (src, (UInt32)&nilP->dueDate, data, sizeof(src->dueDate));
goto exit;
}
if (changedField == toDoCategory)
{
attr = (attr & ~dmRecAttrCategoryMask) | *(UInt16 *) data;
DmSetRecordInfo (dbP, newIndex, &attr, NULL);
goto exit;
}
// Calculate the size of the changed record. First,
// find the size of the data used from the old record.
newSize = sizeof (DateType) + 1;
newSize += StrLen((Char *) data) + 1;
c = &src->description;
cLen = StrLen(c) + 1;
if (changedField != toDoDescription)
newSize += cLen;
if (changedField != toDoNote)
{
c += cLen;
newSize += StrLen(c) + 1;
}
// Change the description field.
if (changedField == toDoDescription)
{
// If the new description is longer, expand the record.
curSize = MemPtrSize (src);
if (newSize > curSize)
{
MemPtrUnlock (src);
err = MemHandleResize (recordH, newSize);
if (err) return (err);
src = MemHandleLock (recordH);
}
// Move the note field.
offset = sizeof(DateType) + 1 + StrLen (data) + 1;
c = &src->description;
c += StrLen(c) + 1;
DmWrite (src, offset, c, StrLen(c) + 1);
// Write the new description field.
offset = sizeof(DateType) + 1;
DmStrCopy (src, offset, data);
// If the new description is shorter, shrink the record.
if (newSize < curSize)
MemHandleResize (recordH, newSize);
goto exit;
}
// Change the note field
if (changedField == toDoNote)
{
offset = sizeof(DateType) + 1 + StrLen((Char *)&src->description) + 1;
MemPtrUnlock (src);
err = MemHandleResize (recordH, newSize);
if (err) return (err);
src = MemHandleLock (recordH);
DmStrCopy (src, offset, data);
goto exit;
}
exit:
MemPtrUnlock (src);
#if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL
ECToDoDBValidate (dbP);
#endif
return 0;
}
/***********************************************************************
*
* FUNCTION: ToDoSetDBBackupBit
*
* DESCRIPTION: This routine sets the backup bit on the given database.
* This is to aid syncs with non Palm software.
* If no DB is given, open the app's default database and set
* the backup bit on it.
*
* PARAMETERS: dbP - the database to set backup bit,
* can be NULL to indicate app's default database
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* grant 4/1/99 Initial Revision
*
***********************************************************************/
void ToDoSetDBBackupBit(DmOpenRef dbP)
{
DmOpenRef localDBP;
LocalID dbID;
UInt16 cardNo;
UInt16 attributes;
// Open database if necessary. If it doesn't exist, simply exit (don't create it).
if (dbP == NULL)
{
localDBP = DmOpenDatabaseByTypeCreator (toDoDBType, sysFileCToDo, dmModeReadWrite);
if (localDBP == NULL) return;
}
else
{
localDBP = dbP;
}
// now set the backup bit on localDBP
DmOpenDatabaseInfo(localDBP, &dbID, NULL, NULL, &cardNo, NULL);
DmDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
attributes |= dmHdrAttrBackup;
DmSetDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
// close database if necessary
if (dbP == NULL)
{
DmCloseDatabase(localDBP);
}
}
/***********************************************************************
*
* FUNCTION: ToDoGetDatabase
*
* DESCRIPTION: Get the application's database. Open the database if it
* exists, create it if neccessary.
*
* PARAMETERS: *dbPP - pointer to a database ref (DmOpenRef) to be set
* mode - how to open the database (dmModeReadWrite)
*
* RETURNED: Err - zero if no error, else the error
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* jmp 10/04/99 Initial Revision
*
***********************************************************************/
Err ToDoGetDatabase (DmOpenRef *dbPP, UInt16 mode)
{
Err error = 0;
DmOpenRef dbP;
UInt16 cardNo;
LocalID dbID;
*dbPP = NULL;
// Find the application's data file. If it doesn't exist create it.
dbP = DmOpenDatabaseByTypeCreator (toDoDBType, sysFileCToDo, mode);
if (!dbP)
{
error = DmCreateDatabase (0, toDoDBName, sysFileCToDo, toDoDBType, false);
if (error)
return error;
dbP = DmOpenDatabaseByTypeCreator(toDoDBType, sysFileCToDo, mode);
if (!dbP)
return (1);
// Set the backup bit. This is to aid syncs with non Palm software.
ToDoSetDBBackupBit(dbP);
error = ToDoAppInfoInit (dbP);
if (error)
{
DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL);
DmCloseDatabase(dbP);
DmDeleteDatabase(cardNo, dbID);
return error;
}
}
*dbPP = dbP;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -