📄 addrtools.c
字号:
/******************************************************************************
*
* Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
*
* File: AddrTools.c
*
* Release: Palm OS 5 SDK (68K) R3.
*
* Description:
* This is the place for all misc functions
*
*****************************************************************************/
#include <Form.h>
#include <StringMgr.h>
#include <ErrorMgr.h>
#include <NotifyMgr.h>
#include <TextMgr.h>
#include <FontSelect.h>
#include <KeyMgr.h>
#include <TimeMgr.h>
#include <Helper.h>
#include <HelperServiceClass.h>
#include <TraceMgr.h>
#include <PalmUtils.h>
#include <PalmLocale.h>
#include "AddrCustom.h"
#include "AddressDB.h"
#include "AddressRsc.h"
#include "AddrTools.h"
#include "Address.h"
#include "AddressTransfer.h"
#include "AddrDefines.h"
#include "UIResources.h"
#include "Address.h"
/***********************************************************************
*
* Defines
*
***********************************************************************/
// Max length for first name field
#define maxNameLength 255
#define maxDuplicatedIndString 20
// Maximum label column width in Edit and Record views.
// (Would be nice if this was based on window size or screen size, do 1/2 screen for now)
#define maxLabelColumnWidth 80
#define maxPhoneColumnWidth 82 // (415)-000-0000x...
/***********************************************************************
*
* Internal Functions
*
***********************************************************************/
static Boolean PrvToolsPhoneIsANumber( Char* phone );
static void PrvToolsGetListFieldsLayout(ListLayoutFieldMapType * layoutMapP, Boolean sortByCompany );
static Boolean PrvToolsGetSeparatorString(UInt16 resID, Char* destStringP, Int16 *len);
/***********************************************************************
*
* FUNCTION:
* ToolsIsDialerPresent
*
* DESCRIPTION:
* This routine check if a dialer is present
* Once check has been made, a global stores this info so that further
* callss are immediate
*
* PARAMETERS:
* none
*
* RETURNED:
* true if a dialer is present
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* aro 6/12/00 Initial Revision
*
***********************************************************************/
Boolean ToolsIsDialerPresent( void )
{
if (!DialerPresentChecked)
{
SysNotifyParamType param;
HelperNotifyEventType details;
HelperNotifyValidateType validate;
param.notifyType = sysNotifyHelperEvent;
param.broadcaster = sysFileCAddress;
param.notifyDetailsP = &details;
param.handled = false;
details.version = kHelperNotifyCurrentVersion;
details.actionCode = kHelperNotifyActionCodeValidate;
details.data.validateP = &validate;
validate.serviceClassID = kHelperServiceClassIDVoiceDial;
validate.helperAppID = 0;
SysNotifyBroadcast(¶m);
if (param.handled)
DialerPresent = true;
else
DialerPresent = false;
DialerPresentChecked = true;
}
return DialerPresent;
}
/***********************************************************************
*
* FUNCTION: ToolsSetDBAttrBits
*
* 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
* bhall 7/9/99 made non-static for access in AddressAutoFill.c
*
***********************************************************************/
void ToolsSetDBAttrBits(DmOpenRef dbP, UInt16 attrBits)
{
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 (addrDBType, sysFileCAddress, 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 |= attrBits;
DmSetDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
// close database if necessary
if (dbP == NULL)
{
DmCloseDatabase(localDBP);
}
}
/***********************************************************************
*
* FUNCTION: ToolsCreateDefaultDatabase
*
* DESCRIPTION: This routine creates the default database from the
* saved image in a resource in the application.
*
* PARAMETERS: none
*
* RETURNED: 0 - if no error
* otherwise appropriate error value
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vivek 8/17/00 Initial Revision
*
***********************************************************************/
Err ToolsCreateDefaultDatabase(void)
{
MemHandle resH;
DmOpenRef dbP;
Err error = errNone;
// Attempt to get our default data image and create our
// database.
resH = DmGetResource(sysResTDefaultDB, sysResIDDefaultDB);
if (resH)
{
error = DmCreateDatabaseFromImage(MemHandleLock(resH));
// Set the backup bit on the new database.
if (!error)
ToolsSetDBAttrBits(NULL, dmHdrAttrBackup);
MemHandleUnlock(resH);
DmReleaseResource(resH);
}
// If there is no default data, or we had a problem creating it,
// then attempt to create an empty database.
if (!resH || error)
{
error = AddrDBGetDatabase (&dbP, dmModeReadWrite);
if (!error)
DmCloseDatabase(dbP);
}
return error;
}
/***********************************************************************
*
* FUNCTION: ToolsRegisterLocaleChangingNotification
*
* DESCRIPTION: Register for NotifyMgr notifications for locale chagning.
* DOLATER : This function and the one above can be rolled into one.
*
*
* PARAMETERS: nothing
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* vivek 8/01/00 Initial Revision
*
***********************************************************************/
void ToolsRegisterLocaleChangingNotification(void)
{
UInt16 cardNo;
LocalID dbID;
Err err;
err = SysCurAppDatabase(&cardNo, &dbID);
ErrNonFatalDisplayIf(err != errNone, "can't get app db info");
if(err == errNone)
{
err = SysNotifyRegister(cardNo, dbID, sysNotifyLocaleChangedEvent,
NULL, sysNotifyNormalPriority, NULL);
#if EMULATION_LEVEL == EMULATION_NONE
ErrNonFatalDisplayIf((err != errNone) && (err != sysNotifyErrDuplicateEntry), "can't register");
#endif
}
return;
}
/***********************************************************************
*
* FUNCTION: ToolsDetermineRecordName
*
* DESCRIPTION: Determines an address book record's name. The name
* varies based on which fields exist and what the sort order is.
*
* PARAMETERS: name1, name2 - first and seconds names to draw
* name1Length, name2Length - length of the names in chars
* name1Width, name2Width - width of the names when drawn
* nameExtent - the space the names must be drawn in
* *x, y - where the names are drawn
* shortenedFieldWidth - the width in the current font
*
*
* RETURNED: x is set after the last char drawn
* Boolean - name1/name2 priority based on sortByCompany
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 06/20/95 Initial Revision
* frigino 08/13/97 Added priority return value
* fpa 11/02/00 Added unnamedRecordStringH parameter in order to prevent memory leaks
*
***********************************************************************/
Boolean ToolsDetermineRecordName (AddrDBRecordPtr recordP, Int16 *shortenedFieldWidth, Int16 *fieldSeparatorWidth,
Boolean sortByCompany, Char **name1, Int16 *name1Length, Int16 *name1Width,
Char **name2, Int16 *name2Length, Int16 *name2Width, Char **unnamedRecordStringPtr,
MemHandle* unnamedRecordStringH, Int16 nameExtent)
{
ListLayoutFieldMapType layoutMap;
UInt16 fieldNameChoice;
Boolean ignored;
Boolean name1HasPriority;
Char fieldSeparatorStr[kMaxSeparatorStrLen+1];
Int16 fieldSeparatorLen;
Int16 altFieldNum;
// DOLATER - vsm 2002-10-08 - Why not just use the ellipsis character for the shortened width ?
*name1 = NULL;
*name2 = NULL;
if ( unnamedRecordStringH != NULL )
*unnamedRecordStringH = NULL;
PrvToolsGetListFieldsLayout(&layoutMap, sortByCompany);
fieldNameChoice = 0;
if (sortByCompany)
{
// When sorting by company, always treat name2 as priority.
name1HasPriority = false;
while (*name1 == NULL &&
layoutMap.fieldNameChoiceList[fieldNameChoice] != addressFieldsCount)
{
*name1 = recordP->fields[layoutMap.fieldNameChoiceList[fieldNameChoice++]];
}
// When sorting by company, treat name2 as priority if we
// succeed in getting the company name as the name1
// Did we get the company name?
if (fieldNameChoice > 1) {
// No. We got a last name, first name, or nothing. Priority switches to name1
name1HasPriority = true;
}
while (*name2 == NULL &&
layoutMap.fieldNameChoiceList[fieldNameChoice] != addressFieldsCount)
{
*name2 = recordP->fields[layoutMap.fieldNameChoiceList[fieldNameChoice++]];
}
if (*name1 == NULL && *name2 == NULL)
{
altFieldNum = 0;
// If we have an alternate field then try that field.
while (*name1 == NULL &&
layoutMap.altFieldNameChoiceList[altFieldNum] != addressFieldsCount)
{
*name1 = recordP->fields[layoutMap.altFieldNameChoiceList[altFieldNum++]];
}
*name2 = NULL;
}
}
else
{
// When not sorting by company, always treat name1 as priority.
name1HasPriority = true;
while (*name1 == NULL &&
layoutMap.fieldNameChoiceList[fieldNameChoice] != addressFieldsCount)
{
*name1 = recordP->fields[layoutMap.fieldNameChoiceList[fieldNameChoice++]];
}
if (*name1 == NULL)
{
altFieldNum = 0;
// If we have an alternate field then try that field.
while (*name1 == NULL &&
layoutMap.altFieldNameChoiceList[altFieldNum] != addressFieldsCount)
{
*name1 = recordP->fields[layoutMap.altFieldNameChoiceList[altFieldNum++]];
}
*name2 = NULL;
}
else
{
while (*name2 == NULL &&
layoutMap.fieldNameChoiceList[fieldNameChoice] != addressFieldsCount)
{
*name2 = recordP->fields[layoutMap.fieldNameChoiceList[fieldNameChoice++]];
}
}
}
if (*name1)
{
// Only show text from the first line in the field
*name1Length = nameExtent; // longer than possible
*name1Width = nameExtent; // wider than possible
FntCharsInWidth (*name1, name1Width, name1Length, &ignored); //lint !e64
}
else
{
if (*name1 == NULL)
{
// Set the name to the unnamed string
if (*unnamedRecordStringPtr == NULL)
{
*unnamedRecordStringH = DmGetResource(strRsc, UnnamedRecordStr);
*unnamedRecordStringPtr = MemHandleLock(*unnamedRecordStringH);
}
// The unnamed string is assumed to be well chosen to not need clipping.
*name1 = *unnamedRecordStringPtr;
*name1Length = StrLen(*unnamedRecordStringPtr);
*name1Width = FntCharsWidth (*unnamedRecordStringPtr, *name1Length);
}
}
if (*name2)
{
// Only show text from the first line in the field
*name2Length = nameExtent; // longer than possible
*name2Width = nameExtent; // wider than possible
FntCharsInWidth (*name2, name2Width, name2Length, &ignored);//lint !e64
}
else
{
*name2Length = 0;
*name2Width = 0;
}
ToolsSetupSeparators(*name1, *name2, fieldSeparatorStr, &fieldSeparatorLen, name1HasPriority);
*shortenedFieldWidth = FntCharsWidth(shortenedFieldString, shortenedFieldLength);
*fieldSeparatorWidth = FntCharsWidth (fieldSeparatorStr, fieldSeparatorLen);
// Return priority status
return name1HasPriority;
}
/***********************************************************************
*
* FUNCTION: ToolsDrawRecordName
*
* DESCRIPTION: Draws an address book record name. It is used
* for the lookup and note view.
*
* PARAMETERS: name1, name2 - first and seconds names to draw
* name1Length, name2Length - length of the names in chars
* name1Width, name2Width - width of the names when drawn
* nameExtent - the space the names must be drawn in
* *x, y - where the names are drawn
* shortenedFieldWidth - the width in the current font
*
*
* RETURNED: x is set after the last char drawn
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 6/20/95 Initial Revision
* frigino 970813 Rewritten. Now includes a variable ratio for
* name1/name2 width allocation, a prioritization
* parameter, and a word break search to allow
* reclaiming of space from the low priority name.
*
***********************************************************************/
void ToolsDrawRecordName (Char * name1, Int16 name1Length, Int16 name1Width,
Char * name2, Int16 name2Length, Int16 name2Width, Int16 nameExtent,
Int16 *x, Int16 y, Int16 shortenedFieldWidth, Int16 fieldSeparatorWidth,
Boolean center, Boolean priorityIsName1, Boolean inTitle)
{
Int16 name1MaxWidth;
Int16 name2MaxWidth;
Boolean ignored;
Int16 totalWidth;
// Char * highPriName;
Char * lowPriName;
Int16 highPriNameWidth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -