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

📄 addresslookup.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
 *
 * Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
 *
 * File: AddressLookup.c
 *
 * Release: Palm OS 5 SDK (68K) R3.
 *
 * Description:
 *     This is the Address Book's Lookup module.  This module
 *   handles looking up address book information for other apps.
 *
 *****************************************************************************/

#include <ErrorMgr.h>
#include <SoundMgr.h>
#include <StringMgr.h>
#include <TraceMgr.h>

#include <PalmUtils.h>

#include "AddressLookup.h"
#include "AddressDB.h"
#include "AddrTools.h"
#include "AddressRsc.h"
#include "AddrDefines.h"


/***********************************************************************
 *
 *   Defines
 *
 ***********************************************************************/

// Address lookup table columns
#define field1Column						0
#define field2Column						1


/***********************************************************************
 *
 *	Internal Functions
 *
 ***********************************************************************/

static Boolean			PrvLookupViewHandleEvent (LookupVariablesPtr vars);
static void				PrvLookupViewInit (LookupVariablesPtr vars);
static void				PrvLookupDrawRecordFields (LookupVariablesPtr vars, AddrDBRecordPtr record, Int16 field, RectanglePtr bounds, WChar * phoneLabelLetters);
static void				PrvLookupViewDrawRecord (void * table, Int16 row, Int16 column, RectanglePtr bounds);
static void				PrvLookupViewUpdateScrollButtons (LookupVariablesPtr vars);
static void				PrvLookupLoadTable (LookupVariablesPtr vars);
static void				PrvLookupViewScroll (LookupVariablesPtr vars, WinDirectionType direction, Boolean oneLine);
static void				PrvLookupViewSelectRecord (LookupVariablesPtr vars, UInt16 recordNum, UInt16 phoneNum);
static Boolean			PrvLookupViewLookupString (LookupVariablesPtr vars, EventType * event);
static void				PrvLookupClearLookupString ();
static Boolean			PrvLookupViewUseSelection (LookupVariablesPtr vars);
static AddressFields	PrvLookupFindPhoneField (LookupVariablesPtr vars, AddrDBRecordPtr recordP, AddressLookupFields lookupField, UInt16 phoneNum);
static Char* 			PrvLookupResizeResultString (MemHandle resultStringH, UInt16 newSize);
static MemHandle		PrvLookupCreateResultString (LookupVariablesPtr vars, UInt16 recordNum, UInt16 phoneNum);


/***********************************************************************
 *
 * FUNCTION:    Lookup
 *
 * DESCRIPTION: Present a list of records for the user to select and return
 * a string formatted to include information from the selected record.
 *
 * PARAMETERS:    params - address lookup launch command parameters
 *
 * RETURNED:    nothing
 *                The params will contain a string for the matching record.
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         Roger   7/1/96   Initial Revision
 *			  meg		2/3/99	 added beep param to vars struct...default to true
 *			  peter	09/20/00	 Disable attention indicator because title is custom.
 ***********************************************************************/
void Lookup(AddrLookupParamsType * params)
{
	Err err;
	DmOpenRef dbP;
	AddrAppInfoPtr appInfoPtr;
	UInt16      cardNo=0;
	LocalID   dbID;
	DmSearchStateType   searchState;
	FormPtr frm;
	FormPtr originalForm;
	LookupVariablesType vars;
	Boolean uniqueMatch;
	Boolean completeMatch;
	UInt16 mode;

	TraceOutput(TL(appErrorClass,"Lookup() - title = %s, pasteButtonText = %s, lookupString = %s, field1 = %hu, field2 = %hu, field2Optional = %hu, userShouldInteract = %hu, formatStringP = %s, resultStringH = %lu, uniqueID = %lu", params->title, params->pasteButtonText, params->lookupString, params->field1, params->field2, params->field2Optional, params->userShouldInteract, params->formatStringP, params->resultStringH, params->uniqueID));
	
	// Check the parameters
	ErrFatalDisplayIf(params->field1 > addrLookupListPhone &&
					  params->field1 != addrLookupNoField, "Bad Lookup request - field1");
	ErrFatalDisplayIf(params->field2 > addrLookupListPhone &&
					  params->field2 != addrLookupNoField, "Bad Lookup request - field2");


	// Find the application's data file.
	err = DmGetNextDatabaseByTypeCreator (true, &searchState, addrDBType,
										  sysFileCAddress, true, &cardNo, &dbID);
	if (err)
	{
		params->resultStringH = 0;
		return;
	}

	// Obey the secret records setting.  Also, we only need to
	// read from the database.
	if (PrefGetPreference(prefHidePrivateRecordsV33))
		mode = dmModeReadOnly;
	else
		mode = dmModeReadOnly | dmModeShowSecret;

	// Open the address database.
	dbP = DmOpenDatabase(cardNo, dbID, mode);
	if (! dbP)
	{
		params->resultStringH = 0;
		params->uniqueID = 0;
		return;
	}

	// Initialize some of the lookup variables (those needed)
	vars.params = params;
	vars.dbP = dbP;
	vars.beepOnFail = true;

	// Find how the database is sorted.
	appInfoPtr = (AddrAppInfoPtr) AddrDBAppInfoGetPtr(dbP);
	vars.sortByCompany = appInfoPtr->misc.sortByCompany;
	ToolsInitPhoneLabelLetters(appInfoPtr, vars.phoneLabelLetters);
	MemPtrUnlock(appInfoPtr);

	// Set the mappings from AddressLookupFields to AddressFields.  It is
	// necessary to initialize the mappings at runtime because static
	// global variables are not available to this launch code routine.
	vars.lookupFieldMap[addrLookupName] = name;
	vars.lookupFieldMap[addrLookupFirstName] = firstName;
	vars.lookupFieldMap[addrLookupCompany] = company;
	vars.lookupFieldMap[addrLookupAddress] = address;
	vars.lookupFieldMap[addrLookupCity] = city;
	vars.lookupFieldMap[addrLookupState] = state;
	vars.lookupFieldMap[addrLookupZipCode] = zipCode;
	vars.lookupFieldMap[addrLookupCountry] = country;
	vars.lookupFieldMap[addrLookupTitle] = title;
	vars.lookupFieldMap[addrLookupCustom1] = custom1;
	vars.lookupFieldMap[addrLookupCustom2] = custom2;
	vars.lookupFieldMap[addrLookupCustom3] = custom3;
	vars.lookupFieldMap[addrLookupCustom4] = custom4;
	vars.lookupFieldMap[addrLookupNote] = note;

	// Check to see if the lookup string is sufficient for a unique match.
	// If so we skip presenting the user a lookup dialog and just use the match.
	AddrDBLookupLookupString(vars.dbP, params->lookupString, vars.sortByCompany,
						   vars.params->field1, vars.params->field2, &vars.currentRecord, &vars.currentPhone,
						   vars.lookupFieldMap, &completeMatch, &uniqueMatch);
	if (completeMatch && uniqueMatch)
	{
		PrvLookupCreateResultString(&vars, vars.currentRecord, vars.currentPhone + firstPhoneField);
		goto Exit;
	}

	// If the user isn't allowed to select a record then return without
	// a match.
	if (!params->userShouldInteract)
	{
		params->resultStringH = 0;
		params->uniqueID = 0;
		goto Exit;
	}


	// Initialize more of the lookup variables
	vars.currentRecord = noRecord;
	vars.currentPhone = 0;
	vars.topVisibleRecord = 0;
	vars.topVisibleRecordPhone = 0;
	vars.hideSecretRecords = PrefGetPreference(prefHidePrivateRecordsV33);


	// Custom title doesn't support attention indicator.
	// Disable indicator before switching forms.
	AttnIndicatorEnable(false);

	// Remember the original form
	originalForm =  FrmGetActiveForm();

	// Initialize the dialog.
	frm = FrmInitForm (LookupView);
	vars.frm = frm;

	// Set the title
	if (params->title)
		FrmSetTitle(frm, params->title);

	// Set the paste button
	if (params->pasteButtonText)
		CtlSetLabel (FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, LookupPasteButton)), params->pasteButtonText);

	FrmSetActiveForm (frm);

	PrvLookupViewInit (&vars);

	// Enter the lookup string
	if (params->lookupString && *params->lookupString != '\0')
	{
		FldInsert (FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, LookupLookupField)), params->lookupString, StrLen(params->lookupString));
		PrvLookupViewLookupString(&vars, NULL);
	}

	FrmDrawForm (frm);

	FrmSetFocus (frm, FrmGetObjectIndex (frm, LookupLookupField));

	// Handle events until the user picks a record or cancels
	if (PrvLookupViewHandleEvent (&vars))
	{
		PrvLookupCreateResultString(&vars, vars.currentRecord, vars.currentPhone);
	}
	else
	{
		params->resultStringH = 0;
		params->uniqueID = 0;
	}

	AttnIndicatorEnable(true);		// Custom title doesn't support attention indicator.

	FrmSetFocus (frm, noFocus);
	FrmEraseForm (frm);
	FrmDeleteForm (frm);
	FrmSetActiveForm (originalForm);


Exit:
	DmCloseDatabase (dbP);
}

#pragma mark -

/***********************************************************************
 *
 * FUNCTION:    PrvLookupViewHandleEvent
 *
 * DESCRIPTION: This is the event handler for the "Lookup View"
 *              of the Address Book application.
 *
 * PARAMETERS:  vars - variables used by the lookup code.
 *
 * RETURNED:    true if a record was selected and false if not.
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         Roger   7/8/96   Initial Revision
 *			CSS		06/22/99	Standardized keyDownEvent handling
 *									(TxtCharIsHardKey, commandKeyMask, etc.)
 *
 ***********************************************************************/
Boolean PrvLookupViewHandleEvent (LookupVariablesPtr vars)
{
	EventType event;
	Boolean handled;


	while (true)
	{
		EvtGetEvent (&event, evtWaitForever);

		// Cancel if something is going to switch apps.
		if ( (event.eType == keyDownEvent)
			 &&	(!TxtCharIsHardKey(	event.data.keyDown.modifiers, event.data.keyDown.chr))
			 &&	(EvtKeydownIsVirtual(&event))
			 &&	(event.data.keyDown.chr == vchrFind))
		{
			EvtAddEventToQueue(&event);
			return false;
		}

		if (SysHandleEvent (&event))
			continue;


		handled = false;

		// Clear the lookup string because the user is selecting an item.
		if (event.eType == appStopEvent)
		{
			EvtAddEventToQueue(&event);
			return false;
		}

		else if (event.eType == tblSelectEvent)
		{
			// Doing the next call sends a fldChangedEvent which remove's the
			// table's selection.  Set a flag to not handle the event.
			PrvLookupClearLookupString ();
			vars->ignoreEmptyLookupField = true;

			handled = true;
		}

		else if (event.eType == ctlSelectEvent)
		{
			if (event.data.ctlSelect.controlID == LookupPasteButton)
				return PrvLookupViewUseSelection(vars);

			else if (event.data.ctlSelect.controlID == LookupCancelButton)
				return false;
		}

		else if (event.eType == ctlRepeatEvent)
		{
			if (event.data.ctlRepeat.controlID == LookupUpButton)
			{
				PrvLookupViewScroll (vars, winUp, false);
				PrvLookupClearLookupString ();
				// leave unhandled so the buttons can repeat
			}

			else if (event.data.ctlRepeat.controlID == LookupDownButton)
			{
				PrvLookupViewScroll (vars, winDown, false);
				PrvLookupClearLookupString ();
				// leave unhandled so the buttons can repeat
			}
		}

		else if (event.eType == keyDownEvent)
		{
			if (TxtCharIsHardKey(event.data.keyDown.modifiers, event.data.keyDown.chr))
			{
				// SysHandleEvent saw these keys and is now switching apps.
				// Leave the Lookup function.
				return false;
			}
			else if (EvtKeydownIsVirtual(&event))
			{
				if (event.data.keyDown.chr == vchrPageUp)
				{
					PrvLookupViewScroll (vars, winUp, false);
					PrvLookupClearLookupString ();
					handled = true;
				}

				else if (event.data.keyDown.chr == vchrPageDown)
				{
					PrvLookupViewScroll (vars, winDown, false);
					PrvLookupClearLookupString ();
					handled = true;
				}

				else
				{
					handled = false;
				}
			}

			else if (event.data.keyDown.chr == chrLineFeed)
			{
				return PrvLookupViewUseSelection(vars);
			}

			else
			{
				//user entered a new char...beep if it's not valid
				vars->beepOnFail = true;
				handled = PrvLookupViewLookupString(vars, &event);

				// If the field becomes empty, handle it.
				vars->ignoreEmptyLookupField = false;
			}
		}

		else if (event.eType == fldChangedEvent)
		{
			if (!(vars->ignoreEmptyLookupField &&
				  FldGetTextLength(FrmGetObjectPtr (vars->frm,
													FrmGetObjectIndex(vars->frm, LookupLookupField))) == 0))
			{
				// dont set the beep...this way, if the calling app sent in a multiple char
				// string, we only beep once even if we will remove all chars from the lookup field
				PrvLookupViewLookupString(vars, NULL);
			}

			vars->ignoreEmptyLookupField = false;
			handled = true;
		}

		// Check if the form can handle the event
		if (!handled)
			FrmHandleEvent (vars->frm, &event);
	}
}


/***********************************************************************
 *
 * FUNCTION:    PrvLookupViewInit
 *
 * DESCRIPTION: This routine initializes the "Lookup View" of the
 *              Address application.
 *
 * PARAMETERS:  vars - variables used by the lookup code.
 *
 * RETURNED:    true if the event has handle and should not be passed
 *              to a higher level handler.
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         Roger   7/9/96   Initial Revision
 *
 ***********************************************************************/
void PrvLookupViewInit (LookupVariablesPtr vars)
{
	UInt16 row;
	UInt16 rowsInTable;
	TablePtr table;
	RectangleType bounds;


	// Initialize the address list table.
	table = FrmGetObjectPtr (vars->frm, FrmGetObjectIndex (vars->frm, LookupTable));
	rowsInTable = TblGetNumberOfRows (table);
	for (row = 0; row < rowsInTable; row++)
	{
		TblSetItemStyle (table, row, field1Column, customTableItem);
		TblSetRowUsable (table, row, false);
	}

	TblSetColumnUsable (table, 0, true);


	// Set the callback routine that will draw the records.
	TblSetCustomDrawProcedure (table, field1Column, PrvLookupViewDrawRecord);


	// Load records into the address list.
	PrvLookupLoadTable (vars);


	// Turn on the cursor in the lookup field.
	//   FrmSetFocus(vars->frm, FrmGetObjectIndex (vars->frm, LookupLookupField));

	// Set the bounds of the title, so that the title will draw across the
	// entire display.
	FrmGetFormBounds(vars->frm, &bounds);
	// Note: '0' should be FrmGetObjectIndex (vars->frm, LookupTitle), but that fails
	// because frmTitleObjects do not have the resource ID stored in them.
	FrmSetObjectBounds (vars->frm, 0, &bounds);

	// Respond to an empty lookup field.
	vars->ignoreEmptyLookupField = false;
}


/***********************************************************************
 *
 * FUNCTION:    PrvLookupDrawRecordFields
 *
 * DESCRIPTION: Draws the name and phone number (plus which phone)
 * within the screen bounds passed.
 *

⌨️ 快捷键说明

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