📄 addressautofill.c
字号:
*
* FUNCTION: AutoFillLookupSave
*
* DESCRIPTION: This routine saves the string passed to the specified
* lookup database.
*
* PARAMETERS: type - database type
* creator - database creator type
* str - string to save to lookup record
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 1/16/96 Initial Revision
*
***********************************************************************/
void AutoFillLookupSave (UInt32 type, UInt32 creator, Char * str)
{
UInt16 i;
UInt16 index;
UInt16 numRecords;
UInt32 strLen;
UInt32 time;
Boolean insert = true;
MemHandle h;
DmOpenRef dbP;
LookupRecordPtr r;
LookupRecordPtr nilP = 0;
dbP = DmOpenDatabaseByTypeCreator (type, creator, dmModeReadWrite);
if (! dbP) return;
strLen = StrLen (str);
// There is a limit on the number of entries in a lookup database,
// if we've reached that limit find the oldest entry and delete it.
numRecords = DmNumRecords (dbP);
if (numRecords >= maxLookupEntries)
{
time = ~0;
for (i = 0; i < numRecords; i++)
{
r = MemHandleLock (DmQueryRecord (dbP, i));
if (r->time < time)
{
index = i;
time = r->time;
}
MemPtrUnlock (r);
}
DmRemoveRecord(dbP, index);
}
// Check if the string passed already exist in the database, if it
// doesn't insert it. If it does, write the passed string to
// the record, the case of one or more of the character may
// changed.
index = DmFindSortPosition (dbP, str, NULL, (DmComparF *)PrvAutoFillLookupCompareRecords, 0);
if (index)
{
h = DmQueryRecord (dbP, index-1);
r = MemHandleLock (h);
if (StrCaselessCompare (str, &r->text) == 0)
{
insert = false;
index--;
}
MemPtrUnlock (r);
}
if (insert)
{
h = DmNewRecord (dbP, &index, sizeof (LookupRecordType) + strLen);
if (! h) goto exit;
DmReleaseRecord (dbP, index, true);
}
else
{
h = DmResizeRecord (dbP, index, sizeof (LookupRecordType) + strLen);
if (! h) goto exit;
}
// Copy the string passed to the record and time stamp the entry with
// the current time.
time = TimGetSeconds ();
h = DmGetRecord (dbP, index);
r = MemHandleLock (h);
DmWrite (r, OffsetOf(LookupRecordType, time), &time, sizeof (UInt32));
DmWrite (r, OffsetOf(LookupRecordType, text), str, strLen + 1);
MemPtrUnlock (r);
DmReleaseRecord (dbP, index, true);
exit:
DmCloseDatabase (dbP);
}
#pragma mark -
/***********************************************************************
*
* FUNCTION: PrvAutoFillLookupStringInList
*
* DESCRIPTION: This routine seatches a list for a the string passed.
*
* PARAMETERS: lst - pointer to a list object
* key - string to lookup record with
* indexP - to contain the record found
*
*
* RETURNED: true if a match was found.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 1/10/96 Initial Revision
*
***********************************************************************/
Boolean PrvAutoFillLookupStringInList (ListPtr lst, Char * key, UInt16 * indexP,
Boolean * uniqueP)
{
Int16 result;
Int16 numItems;
UInt16 kmin, probe, i;
Char *itemP;
Boolean match = false;
*uniqueP = false;
if ((! key) || (! *key) ) return false;
numItems = LstGetNumberOfItems (lst);
if (numItems == 0) return false;
result = 0;
kmin = probe = 0;
while (numItems > 0)
{
i = numItems / 2;
probe = kmin + i;
// Compare the a list item to the key.
itemP = LstGetSelectionText (lst, probe);
result = PrvAutoFillPartialCaselessCompare (key, itemP);
// If the date passed is less than the probe's date , keep searching.
if (result < 0)
numItems = i;
// If the date passed is greater than the probe's date, keep searching.
else if (result > 0)
{
kmin = probe + 1;
numItems = numItems - i - 1;
}
// If equal stop here! Make sure the match is unique by checking
// the item before and after the probe, if either matches then
// we don't have a unique match.
else
{
// Start by assuming we have a unique match.
match = true;
*uniqueP = true;
*indexP = probe;
// If we not have a unique match, we want to return the
// index one the first item that matches the key.
while (probe)
{
itemP = LstGetSelectionText (lst, probe-1);
if (PrvAutoFillPartialCaselessCompare (key, itemP) != 0)
break;
*uniqueP = false;
*indexP = probe-1;
probe--;
}
if (!*uniqueP) break;
if (probe + 1 < LstGetNumberOfItems (lst))
{
itemP = LstGetSelectionText (lst, probe+1);
if (PrvAutoFillPartialCaselessCompare (key, itemP) == 0)
*uniqueP = false;
}
break;
}
}
return (match);
}
/************************************************************
*
* FUNCTION: PrvAutoFillPartialCaselessCompare
*
* DESCRIPTION: Compares two strings with case and accent insensitivity.
* If all of s1 matches all or the start of s2 then
* there is a match
*
* PARAMETERS: 2 string pointers
*
* RETURNS: 0 if they match, non-zero if not
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 1/4/96 Initial Revision
* kwk 05/16/99 Use StrNCaselessCompare.
*
*************************************************************/
Int16 PrvAutoFillPartialCaselessCompare (Char * s1, Char * s2)
{
// Check for err
ErrFatalDisplayIf(s1 == NULL || s2 == NULL, "NULL string passed");
return (StrNCaselessCompare (s1, s2, StrLen (s1)));
}
/***********************************************************************
*
* FUNCTION: PrvAutoFillLookupCompareRecords
*
* DESCRIPTION: Compare two lookup records. This is a callback
* called by DmFindSortPosition.
*
* PARAMETERS: database record 1
* database record 2
*
* RETURNS: -n if record one is less (n != 0)
* n if record two is less
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 1/16/96 Initial Revision
*
***********************************************************************/
Int16 PrvAutoFillLookupCompareRecords (Char * str, LookupRecordPtr r2, Int16 UNUSED_PARAM(dummy), SortRecordInfoPtr UNUSED_PARAM(info1), SortRecordInfoPtr UNUSED_PARAM(info2), MemHandle UNUSED_PARAM(appInfoH))
{
return (StrCaselessCompare (str, &r2->text));
}
/***********************************************************************
*
* FUNCTION: PrvAutoFillSortCompareRecords
*
* DESCRIPTION: Compare two sort records.
* This is a callback called by DmQuickSort.
*
* PARAMETERS: database record 1
* database record 2
*
* RETURNS: -n if record one is less (n != 0)
* n if record two is less
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* bhall 11/8/99 Initial Revision
*
***********************************************************************/
Int16 PrvAutoFillSortCompareRecords (LookupRecordPtr r1, LookupRecordPtr r2, Int16 UNUSED_PARAM(dummy), SortRecordInfoPtr UNUSED_PARAM(info1), SortRecordInfoPtr UNUSED_PARAM(info2), MemHandle UNUSED_PARAM(appInfoH))
{
return (StrCaselessCompare (&r1->text, &r2->text));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -