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

📄 addredit.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************
 *
 * Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
 *
 * File: AddrEdit.c
 *
 * Release: Palm OS 5 SDK (68K) R3.
 *
 * Description:
 *   This is the Address Book application's edit form module.
 *
 *****************************************************************************/

#include <TraceMgr.h>
#include <TextMgr.h>
#include <ErrorMgr.h>
#include <StringMgr.h>
#include <AboutBox.h>
#include <Category.h>
#include <Graffiti.h>
#include <Menu.h>
#include <UIResources.h>

#include <PalmUtils.h>

#include "AddrEdit.h"

#include "AddrDialList.h"
#include "Address.h"
#include "AddressAutoFill.h"
#include "AddressRsc.h"
#include "AddrDefines.h"
#include "AddrTools.h"
#include "AddrDetails.h"
#include "AddrNote.h"
#include "AddressTransfer.h"

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

#define addrEditLabelFont	stdFont
#define addrEditBlankFont	stdFont

#define noFieldIndex		0xff

// Address edit table's rows and columns
#define editLabelColumn		0
#define editDataColumn		1

#define spaceBeforeDesc		2

#define editLastFieldIndex	17

#define isPhoneField(f)		(f >= firstPhoneField && f <= lastPhoneField)

#define editInvalidRow		((UInt16) 0xFFFF)

#define kAutoFillConstantID	1800
#define kDontUseAutoFill	0

#define ADDR_FOCUS_FIX

/***********************************************************************
 *
 *   Global variables
 *
 ***********************************************************************/

static UInt16				CurrentFieldIndex;

// global to remember the row of the last tapped tel label
static UInt16				CurrentTableRow;

// The following structure maps row in the edit table to fields in the
// address record.  This controls the order in which fields are edited.
// Valid after PrvEditInit.
static const AddressFields* FieldMap;
static MemHandle			FieldMapH;

// Valid after PrvEditInit
static Char * EditPhoneListChoices[numPhoneLabels];

// Global flag that indicates whether auto-fill should be active
// 0 == do not use autofill; 1 == use autofill
static UInt32				UseAutoFill = 0;

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

static void		PrvEditInit( FormPtr frmP, Boolean leaveDataLocked );
static void		PrvEditInitTableRow( FormType* frmP, TablePtr table, UInt16 row, UInt16 fieldIndex, Int16 rowHeight, FontID fontID, AddrDBRecordPtr record, AddrAppInfoPtr appInfoPtr );
static Boolean	PrvEditHandleSelectField (Int16 row, Int16 column);
static void		PrvEditRestoreEditState( FormType* frmP );
static void		PrvEditSetGraffitiMode (FieldPtr fld, UInt16 currentField);
static Err		PrvEditGetRecordField (void * table, Int16 row, Int16 /*column*/, Boolean editing, MemHandle * textH, Int16 * textOffset, Int16 * textAllocSize, FieldPtr fld);
static Boolean	PrvEditSaveRecordField (void * table, Int16 row, Int16 /*column*/);
static UInt16	PrvEditSaveRecord ();
static void		PrvEditSelectCategory (void);
static void		PrvEditUpdateScrollers (FormPtr frmP, UInt16 bottomFieldIndex, Boolean lastItemClipped);
static UInt16	PrvEditGetFieldHeight (TablePtr table, UInt16 fieldIndex, Int16 columnWidth, Int16 maxHeight, AddrDBRecordPtr record, FontID * fontIdP);
static void		PrvEditDrawBusinessCardIndicator (FormPtr formP);
static void		PrvEditResizeDescription (EventType * event);
static void		PrvEditScroll (WinDirectionType direction);
static void		PrvEditNextField (WinDirectionType direction);
static void		PrvEditUpdateCustomFieldLabels( FormType* frmP);
static void		PrvEditUpdateDisplay( UInt16 updateCode );
static Boolean	PrvEditDoCommand (UInt16 command);
static Boolean	PrvEditAutoFill (EventPtr event);
static void		PrvEditDialCurrent( void );
#ifdef ADDR_FOCUS_FIX
static void		PrvEditLoadTable( FormType* frmP, Boolean doFocusFix );
#else
static void		PrvEditLoadTable( FormType* frmP );
#endif

/***********************************************************************
 *
 * FUNCTION:    EditHandleEvent
 *
 * DESCRIPTION: This routine is the event handler for the "Edit View"
 *              of the Address Book application.
 *
 * PARAMETERS:  event  - a pointer to an EventType structure
 *
 * RETURNED:    true if the event was handled and should not be passed
 *              to a higher level handler.
 *
 *	HISTORY:
 *		Name	Date		Description
 *		----	----		-----------
 *		art		06/05/95	Created by Art Lamb.
 *		kwk		07/29/99	Unlock FieldMap in frmCloseEvent block.
 *		jmp		09/17/99	Use NewNoteView instead of NoteView.
 *		fpa		10/23/00	Fixed bug #27480 - Font Style: The default font
 *							setting did not get refresh in the Address Edit
 *							View when entering text in the last name field
 *							after you entered the first name and tap done
 *		gap		10/27/00	change the command bar initialization to allow field
 *							code to add cut, copy, paste, & undo commands as 
 *							appropriate rather than adding a fixed set of selections.
 *
 ***********************************************************************/
Boolean EditHandleEvent (EventType * event)
{
	FormType* frmP;
	TablePtr tableP;
	Boolean handled = false;
	Int16 row;
	UInt32 numLibs;


	
	switch (event->eType)
	{
		case frmOpenEvent:
		{
			UInt16 tableIndex;
			FieldPtr fldP;
	
			TraceOutput(TL(appErrorClass, "EditHandleEvent() - frmOpenEvent"));
			frmP = FrmGetActiveForm ();
#ifdef ADDR_FOCUS_FIX
			CurrentFieldIndex = EditRowIDWhichHadFocus;
#else /* not ADDR_FOCUS_FIX */
#endif /* not ADDR_FOCUS_FIX */
			PrvEditInit (frmP, true);
			tableIndex = FrmGetObjectIndex(frmP, EditTable);
			tableP = FrmGetObjectPtr (frmP, tableIndex);
	
			// Make sure the field which will get the focus is visible
			while (!TblFindRowID (tableP, EditRowIDWhichHadFocus, &row))
			{
				TopVisibleFieldIndex = EditRowIDWhichHadFocus;
				CurrentFieldIndex = EditRowIDWhichHadFocus;
#ifdef ADDR_FOCUS_FIX
				PrvEditLoadTable(frmP, true);
#else /* not ifdef ADDR_FOCUS_FIX */
				PrvEditLoadTable(frmP);
#endif /* not ifdef ADDR_FOCUS_FIX */
			}
			FrmDrawForm (frmP);
			PrvEditDrawBusinessCardIndicator (frmP);
	
			// Now set the focus.
			FrmSetFocus(frmP, tableIndex);
			TblGrabFocus (tableP, row, editDataColumn);
			fldP = TblGetCurrentField(tableP);
			FldGrabFocus (fldP);
	
			// If NumCharsToHilite is not 0, then we know that we are displaying
			// a duplicated message for the first time and we must hilite the last
			// NumCharsToHilite of the field (first name) to indicate the modification
			// to that duplicated field.
			if (NumCharsToHilite > 0)
			{
				EditFieldPosition = FldGetTextLength (fldP);
	
				// Now hilite the chars added.
				FldSetSelection (fldP, EditFieldPosition - NumCharsToHilite, EditFieldPosition);
				NumCharsToHilite = 0;
			}
	
			FldSetInsPtPosition (fldP, EditFieldPosition);
	
			PriorAddressFormID = FrmGetFormId (frmP);
			
			// Simulate a tap in last name field in order to fix bug #27480
			PrvEditHandleSelectField(EditRowIDWhichHadFocus - TopVisibleFieldIndex, 1);
			
			handled = true;
			break;
		}
	
		case frmCloseEvent:
		{
			AddrAppInfoPtr appInfoPtr;
	
			TraceOutput(TL(appErrorClass, "EditHandleEvent() - frmCloseEvent"));
			// Check if the record is empty and should be deleted.  This cannot
			// be done earlier because if the record is deleted there is nothing
			// to display in the table.
			PrvEditSaveRecord ();
	
			// We need to unlock the block containing the phone labels.
			appInfoPtr = (AddrAppInfoPtr) AddrDBAppInfoGetPtr(AddrDB);
			MemPtrUnlock(appInfoPtr);	// Call to AddrAppInfoGetPtr did a lock
			MemPtrUnlock(appInfoPtr);   // Unlock lock in PrvEditInit
	
			// We need to unlock the FieldMap resource, which was also locked
			// in PrvEditInit.
			MemHandleUnlock(FieldMapH);
			DmReleaseResource(FieldMapH);
			FieldMap = 0;
			break;
		}
	
		case tblEnterEvent:
			// if a phone label is tapped: store current 
			if (isPhoneField(FieldMap[TblGetRowID(event->data.tblEnter.pTable, event->data.tblEnter.row)]))
			{
				CurrentTableRow = event->data.tblEnter.row;
			}
			break;
			
		case winExitEvent:
		case tblExitEvent:
			TraceOutput(TL(appErrorClass, "EditHandleEvent() - winExitEvent (%us)", CurrentFieldIndex));
			// if we exits a window and a phone label was tapped: redraw the associated row
			// to replace the semicolon character
			if (CurrentTableRow != editInvalidRow)
			{
				tableP = ToolsGetFrmObjectPtr(FrmGetActiveForm(), EditTable);
				TblMarkRowInvalid(tableP, CurrentTableRow);
				TblRedrawTable(tableP);				
				CurrentTableRow = editInvalidRow;
			}
			break;
			
		case tblSelectEvent:
			TraceOutput(TL(appErrorClass, "EditHandleEvent() - tblSelectEvent"));
			// Select the field if it's different than the one selected before.  This means the selection
			// is on a different row or the selection is a phone label.
			if (CurrentFieldIndex != TblGetRowID (event->data.tblSelect.pTable, event->data.tblSelect.row) ||
				(event->data.tblSelect.column == editLabelColumn && isPhoneField(FieldMap[
																						  TblGetRowID(event->data.tblSelect.pTable, event->data.tblSelect.row)])))
				PrvEditHandleSelectField (event->data.tblSelect.row, event->data.tblSelect.column);
			
			CurrentTableRow = editInvalidRow;
			break;
			
		case ctlSelectEvent:
			TraceOutput(TL(appErrorClass, "EditHandleEvent() - ctlSelectEvent - controlID = %hu", event->data.ctlSelect.controlID));
			switch (event->data.ctlSelect.controlID)
			{
				case EditCategoryTrigger:
					PrvEditSelectCategory ();
					PrvEditRestoreEditState(FrmGetActiveForm());	// DOLATER: Can cause problems when no field is editable
					handled = true;
					break;
		
				case EditDoneButton:
					FrmGotoForm (ListView);
					handled = true;
					break;
		
				case EditDetailsButton:
					FrmPopupForm (DetailsDialog);
					handled = true;
					break;
		
				case EditNoteButton:
					if (NoteViewCreate())
					{
						RecordNeededAfterEditView = true;
						FrmGotoForm (NewNoteView);
					}
					handled = true;
					break;
				default:
					break;
			}
			break;
	
		case ctlRepeatEvent:
			switch (event->data.ctlRepeat.controlID)
			{
				case EditUpButton:
					PrvEditScroll (winUp);
					// leave unhandled so the buttons can repeat
					break;
		
				case EditDownButton:
					PrvEditScroll (winDown);
					// leave unhandled so the buttons can repeat
					break;
				default:
					break;
			}
			break;
	
		case menuEvent:
			return PrvEditDoCommand (event->data.menu.itemID);
	
		case menuCmdBarOpenEvent:
		{
			FieldType* fldP;
			UInt16 startPos, endPos;

			fldP = TblGetCurrentField(ToolsGetObjectPtr(EditTable));
			if (fldP)
				FldGetSelection(fldP, &startPos, &endPos);

			if ((fldP) && (startPos == endPos))  // there's no highlighted text
			{
				// Call directly the Field event handler so that edit buttons are added if applicable
				FldHandleEvent(fldP, event);
				
				MenuCmdBarAddButton(menuCmdBarOnRight, BarDeleteBitmap, menuCmdBarResultMenuItem, EditRecordDeleteRecordCmd, 0);
				MenuCmdBarAddButton(menuCmdBarOnLeft, BarBeamBitmap, menuCmdBarResultMenuItem, EditRecordBeamRecordCmd, 0);

				// Prevent the field package to add edit buttons again
				event->data.menuCmdBarOpen.preventFieldButtons = true;
			}
			else if (fldP == NULL)	// there is no active text field (none have cursor visible)
			{
				MenuCmdBarAddButton(menuCmdBarOnLeft, BarDeleteBitmap, menuCmdBarResultMenuItem, EditRecordDeleteRecordCmd, 0);
				MenuCmdBarAddButton(menuCmdBarOnLeft, BarBeamBitmap, menuCmdBarResultMenuItem, EditRecordBeamRecordCmd, 0);

				// Prevent the field package to add edit buttons again
				event->data.menuCmdBarOpen.preventFieldButtons = true;
			}
			else
			{
			// When there is a selection range of text (ie startPos != endPos)
			// fall through to the field code to add the appropriate cut, copy, 
			// paste, and undo selections to the command bar.
				event->data.menuCmdBarOpen.preventFieldButtons = false;
			}
			
			// don't set handled to true; this event must fall through to the system.
			break;
		}
	
		case menuOpenEvent:
			if(!ToolsIsDialerPresent())
				MenuHideItem(EditRecordDialCmd);

			if (ExgGetRegisteredApplications(NULL, &numLibs, NULL, NULL, exgRegSchemeID, exgSendScheme) || !numLibs)
				MenuHideItem(EditRecordSendRecordCmd);
			else
				MenuShowItem(EditRecordSendRecordCmd);
			// don't set handled = true
			break;
	
		case fldHeightChangedEvent:
			TraceOutput(TL(appErrorClass, "EditHandleEvent() - fldHeightChangedEvent"));
			PrvEditResizeDescription (event);
			handled = true;
			break;
	
		case keyDownEvent:
			if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr))
			{
				TblReleaseFocus(ToolsGetObjectPtr(EditTable));
				TopVisibleRecord = 0;      // Same as when app switched to
				CurrentFieldIndex = noFieldIndex;
				FrmGotoForm (ListView);
				return (true);
			}
			else if (EvtKeydownIsVirtual(event))
			{
				switch (event->data.keyDown.chr)
				{
					case vchrPageUp:
						PrvEditScroll (winUp);
						handled = true;
						break;
		
					case vchrPageDown:
						PrvEditScroll (winDown);
						handled = true;
						break;
		
					case vchrNextField:
						PrvEditNextField (winDown);
						handled = true;
						break;
		
					case vchrPrevField:
						PrvEditNextField (winUp);
						handled = true;
						break;
		
					case vchrSendData:
						// Make sure the field being edited is saved
						frmP = FrmGetActiveForm ();
						tableP = ToolsGetFrmObjectPtr(frmP, EditTable);
						TblReleaseFocus(tableP);
		
						MenuEraseStatus (0);
						TransferSendRecord(AddrDB, CurrentRecord, exgBeamPrefix, NoDataToBeamAlert);
						handled = true;
						break;
		
					default:
						break;
				}
			}

⌨️ 快捷键说明

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