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

📄 addrtools.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
 *
 * 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(&param);
		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 + -