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

📄 addrtools.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 4 页
字号:
	Int16		lowPriNameWidth;
	Char 		fieldSeparatorStr[kMaxSeparatorStrLen+1];
	Int16 	fieldSeparatorLen;

	ToolsSetupSeparators(name1, name2, fieldSeparatorStr, &fieldSeparatorLen, priorityIsName1);
					
	// Check if both names fit
	totalWidth = name1Width + (name2 ? fieldSeparatorWidth : 0) + name2Width;

	// If we are supposed to center the names then move in the x position
	// by the amount that centers the text
	if (center && (nameExtent > totalWidth))
	{
		*x += (nameExtent - totalWidth) / 2;
	}

	// Special case if only name1 is given
	if (name2 == NULL)
	{
		// Draw name portion that fits in extent
		FntCharsInWidth(name1, (Int16*)&nameExtent, &name1Length, &ignored);
		if (inTitle)
			WinDrawInvertedChars(name1, name1Length, *x, y);
		else
			WinDrawChars(name1, name1Length, *x, y);
		// Add width of characters actually drawn
		*x += FntCharsWidth(name1, name1Length);
		return;
	}

	// Remove name separator width
	nameExtent -= fieldSeparatorWidth;

	// Test if both names fit
	if ((name1Width + name2Width) <= nameExtent)
	{
		name1MaxWidth = name1Width;
		name2MaxWidth = name2Width;
	}
	else
	{
		// They dont fit. One or both needs truncation
		// Establish name priorities and their allowed widths
		// Change this to alter the ratio of the low and high priority name spaces
		Int16	highPriMaxWidth = (nameExtent * 2) / 3;	// 1/3 to low and 2/3 to high
		Int16	lowPriMaxWidth = nameExtent - highPriMaxWidth;

		// Save working copies of names and widths based on priority
		if (priorityIsName1)
		{
			// Priority is name1
			//			highPriName = name1;
			highPriNameWidth = name1Width;
			lowPriName = name2;
			lowPriNameWidth = name2Width;
		}
		else
		{
			// Priority is name2
			//			highPriName = name2;
			highPriNameWidth = name2Width;
			lowPriName = name1;
			lowPriNameWidth = name1Width;
		}

		// Does high priority name fit in high priority max width?
		if (highPriNameWidth > highPriMaxWidth)
		{
			// No. Look for word break in low priority name
			Char * spaceP = StrChr(lowPriName, spaceChr);
			if (spaceP != NULL)
			{
				// Found break. Set low priority name width to break width
				lowPriNameWidth = FntCharsWidth(lowPriName, spaceP - lowPriName);
				// Reclaim width from low pri name width to low pri max width, if smaller
				if (lowPriNameWidth < lowPriMaxWidth)
				{
					lowPriMaxWidth = lowPriNameWidth;
					// Set new high pri max width
					highPriMaxWidth = nameExtent - lowPriMaxWidth;
				}
			}
		}
		else
		{
			// Yes. Adjust maximum widths
			highPriMaxWidth = highPriNameWidth;
			lowPriMaxWidth = nameExtent - highPriMaxWidth;
		}

		// Convert priority widths back to name widths
		if (priorityIsName1)
		{
			// Priority is name1
			name1Width = highPriNameWidth;
			name2Width = lowPriNameWidth;
			name1MaxWidth = highPriMaxWidth;
			name2MaxWidth = lowPriMaxWidth;
		}
		else
		{
			// Priority is name2
			name1Width = lowPriNameWidth;
			name2Width = highPriNameWidth;
			name1MaxWidth = lowPriMaxWidth;
			name2MaxWidth = highPriMaxWidth;
		}
	}

	// Does name1 fit in its maximum width?
	if (name1Width > name1MaxWidth)
	{
		// No. Draw it to max width minus the ellipsis
		name1Width = name1MaxWidth - shortenedFieldWidth;
		FntCharsInWidth(name1, &name1Width, &name1Length, &ignored);
		if (inTitle)
			WinDrawInvertedChars(name1, name1Length, *x, y);
		else
			WinDrawChars(name1, name1Length, *x, y);
		*x += name1Width;

		// Draw ellipsis
		if (inTitle)
			WinDrawInvertedChars(shortenedFieldString, shortenedFieldLength, *x, y);
		else
			WinDrawChars(shortenedFieldString, shortenedFieldLength, *x, y);
		*x += shortenedFieldWidth;
	}
	else
	{
		// Yes. Draw name1 within its width
		FntCharsInWidth(name1, &name1Width, &name1Length, &ignored);
		if (inTitle)
			WinDrawInvertedChars(name1, name1Length, *x, y);
		else
			WinDrawChars(name1, name1Length, *x, y);
		*x += name1Width;
	}

	// Draw name separator
	if (inTitle)
		WinDrawInvertedChars(fieldSeparatorStr, fieldSeparatorLen, *x, y);
	else
		WinDrawChars(fieldSeparatorStr, fieldSeparatorLen, *x, y);
	*x += fieldSeparatorWidth;

	// Draw name2 within its maximum width
	FntCharsInWidth(name2, &name2MaxWidth, &name2Length, &ignored);
	if (inTitle)
		WinDrawInvertedChars(name2, name2Length, *x, y);
	else
		WinDrawChars(name2, name2Length, *x, y);
	*x += name2MaxWidth;
}


/***********************************************************************
 *
 * FUNCTION:    ToolsDrawRecordNameAndPhoneNumber
 *
 * DESCRIPTION: Draws the name and phone number (plus which phone)
 *					 within the screen bounds passed.
 *
 * PARAMETERS:  record - record to draw
 *              bounds - bounds of the draw region
 *              phoneLabelLetters - the first letter of each phone label
 *              sortByCompany - true if the database is sorted by company
 *              unnamedRecordStringPtr - string to use for unnamed records
 *
 * RETURNED:    x coordinate where phone number starts
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			roger	6/21/95		Initial Revision
 *			peter	5/09/00		Added result and eliminated destructive change to bounds
 *			fpa		11/02/00	Added unnamedRecordStringH parameter in order to prevent memory leaks
 *
 ***********************************************************************/
Int16 ToolsDrawRecordNameAndPhoneNumber(AddrDBRecordPtr record, RectanglePtr bounds, WChar * phoneLabelLetters, Boolean sortByCompany, Char **unnamedRecordStringPtr, MemHandle* unnamedRecordStringH)
{
	Int16 x, y, phoneX, widthWithoutPhoneLabel;
	UInt16 phoneLabel;
	Int16 fieldSeparatorWidth;
	Int16 shortenedFieldWidth;
	Char * name1;
	Char * name2;
	Char * phone;
	Int16 name1Length;
	Int16 name2Length;
	Int16 phoneLength;
	Int16 name1Width;
	Int16 name2Width;
	Int16 phoneWidth;
	UInt16 nameExtent;
	Boolean ignored;
	Boolean name1HasPriority;
	UInt8 phoneLabelWidth;
	const Int16 phoneColumnWidth = maxPhoneColumnWidth;
	Char 		fieldSeparatorStr[kMaxSeparatorStrLen+1];
	Int16 	fieldSeparatorLen;


	x = bounds->topLeft.x;
	y = bounds->topLeft.y;

	phoneLabelWidth = ToolsGetPhoneLabelWidth() - 1;	// remove the blank trailing column
	widthWithoutPhoneLabel = bounds->extent.x - (phoneLabelWidth + 1);

	name1HasPriority = ToolsDetermineRecordName(record, &shortenedFieldWidth, &fieldSeparatorWidth, sortByCompany, &name1, &name1Length, &name1Width, &name2, &name2Length, &name2Width, unnamedRecordStringPtr, unnamedRecordStringH, widthWithoutPhoneLabel);


	phone = record->fields[phone1 + record->options.phones.displayPhoneForList];
	if (phone)
	{
		// Only show text from the first line in the field
		phoneWidth = widthWithoutPhoneLabel;
		phoneLength = phoneWidth;         // more characters than we can expect
		FntCharsInWidth (phone, &phoneWidth, &phoneLength, &ignored);
	}
	else
	{
		phoneLength = 0;
		phoneWidth = 0;
	}
	phoneX = bounds->topLeft.x + widthWithoutPhoneLabel - phoneWidth;

	// Set up the separators for the drawing
	ToolsSetupSeparators(name1, name2, fieldSeparatorStr, &fieldSeparatorLen, name1HasPriority);

	if (widthWithoutPhoneLabel >= name1Width + (name2 ? fieldSeparatorWidth : 0) +
		name2Width + (phone ? spaceBetweenNamesAndPhoneNumbers : 0) + phoneWidth)
	{
		// we can draw it all!
		WinDrawChars(name1, name1Length, x, y);
		x += name1Width;

		// Is there a second name?
		if (name2)
		{
			if (name1)
			{
				WinDrawChars(fieldSeparatorStr, fieldSeparatorLen, x, y);
				x += fieldSeparatorWidth;
			}

			// draw name2
			WinDrawChars(name2, name2Length, x, y);
			x += name2Width;
		}

		if (phone)
			WinDrawChars(phone, phoneLength, phoneX, y);
	}
	else
	{
		// Shortened math (970812 maf)
		nameExtent = widthWithoutPhoneLabel - min(phoneWidth, phoneColumnWidth);

		// Leave some space between names and numbers if there is a phone number
		if (phone)
			nameExtent -= spaceBetweenNamesAndPhoneNumbers;

		ToolsDrawRecordName (name1, name1Length, name1Width, name2, name2Length, name2Width,
						nameExtent, &x, y, shortenedFieldWidth, fieldSeparatorWidth, false,
						name1HasPriority || !sortByCompany, false);

		if (phone)
		{
			x += spaceBetweenNamesAndPhoneNumbers;
			nameExtent = x - bounds->topLeft.x;

			// Now draw the phone number
			if (widthWithoutPhoneLabel - nameExtent >= phoneWidth)
				// We can draw it all
				WinDrawChars(phone, phoneLength, phoneX, y);
			else
			{
				// The phone number should be right justified instead of using
				// x from above because the string printed may be shorter
				// than we expect (CharsInWidth chops off space chars).
				phoneWidth = widthWithoutPhoneLabel - nameExtent - shortenedFieldWidth;
				FntCharsInWidth(phone, &phoneWidth, &phoneLength, &ignored);
				phoneX = bounds->topLeft.x + widthWithoutPhoneLabel - shortenedFieldWidth - phoneWidth;
				WinDrawChars(phone, phoneLength, phoneX, y);

				WinDrawChars(shortenedFieldString, shortenedFieldLength,
							 bounds->topLeft.x + widthWithoutPhoneLabel - shortenedFieldWidth, y);
			}
		}
	}


	if (phone)
	{
		// Draw the first letter of the phone field label
		phoneLabel = GetPhoneLabel(record, firstPhoneField +
								   record->options.phones.displayPhoneForList);

		// find out if the first letter of the phone label is an O(ther) or
		// E(mail). If it is email don't draw the letter. If it is other, and the
		// contents of the phone field is not a number, don't draw the letter.
		if ( phoneLabel != emailLabel )
		{
			if ( (phoneLabel != otherLabel) || PrvToolsPhoneIsANumber (phone) )
			{
				WinDrawChar (phoneLabelLetters[phoneLabel], 
							  bounds->topLeft.x + widthWithoutPhoneLabel + 1 + ((phoneLabelWidth -
																				 (FntWCharWidth(phoneLabelLetters[phoneLabel]) - 1)) >> 1), y);//lint !e702
			}
		}
	}

	return phoneX;
}


/***********************************************************************
 *
 * FUNCTION:    ToolsGetLabelColumnWidth
 *
 * DESCRIPTION: Calculate the width of the widest field label plus a ':'.
 *
 * PARAMETERS:  appInfoPtr  - pointer to the app info block for field labels
 *              labelFontID - font
 *
 * RETURNED:    width of the widest label.
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         art   1/30/98   Initial Revision
 *         vsm   1/15/03   Use ": " instead of ':' + 1 as the suffix string
 *						   whose width is added on to the label width since
 *						   that is what is used by the record view.
 ***********************************************************************/
UInt16 ToolsGetLabelColumnWidth (AddrAppInfoPtr appInfoPtr, FontID labelFontID)
{
	Int16		i;
	UInt16	labelWidth;     // Width of a field label
	UInt16	columnWidth;    // Width of the label column (fits all label)
	FontID	curFont;
	Char *	label;


	// Calculate column width of the label column which is used by the Record View and the
	// Edit View.
	curFont = FntSetFont (labelFontID);

	columnWidth = 0;

	for (i = firstAddressField; i < lastLabel; i ++)
	{
		label = appInfoPtr->fieldLabels[i];
		labelWidth = FntCharsWidth(label, StrLen(label));
		columnWidth = max(columnWidth, labelWidth);
	}
	columnWidth += 1+ FntCharsWidth(": ", 2);

	FntSetFont (curFont);

	if (columnWidth > maxLabelColumnWidth)
		columnWidth = maxLabelColumnWidth;

	return columnWidth;
}


/***********************************************************************
 *
 * FUNCTION:    ToolsLeaveForm
 *
 * DESCRIPTION: Leaves the current popup form and returns to the prior one.
 *
 * PARAMETERS:  formID  - resource id of form to return to
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         roger   6/30/95   Initial Revision
 *
 ***********************************************************************/
void ToolsLeaveForm  ()
{
	FormPtr frm;

	frm = FrmGetActiveForm();
	FrmEraseForm (frm);
	FrmDeleteForm (frm);
	FrmSetActiveForm (FrmGetFirstForm ());
}



/***********************************************************************
 *
 * FUNCTION:    ToolsChangeCategory
 *
 * DESCRIPTION: This routine updates the global varibles that keep track
 *              of category information.
 *
 * PARAMETERS:  category  - new category (index)
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         art   6/5/95      Initial Revision
 *
 ***********************************************************************/
void ToolsChangeCategory (UInt16 category)
{
	CurrentCategory = category;
	TopVisibleRecord = 0;
}


/***********************************************************************
 *
 * FUNCTION:    ToolsSeekRecord
 *
 * DESCRIPTION: Given the index of a to do record, this routine scans
 *              forewards or backwards for displayable to do records.
 *
 * PARAMETERS:  indexP  - pointer to the index of a record to start from;
 *                        the index of the record sought is returned in
 *                        this parameter.
 *
 *              offset  - number of records to skip:
 *                           0 - mean seek from the current record to the
 *                             next display record, if the current record is
 *                             a display record, its index is retuned.
 *                         1 - mean seek foreward, skipping one displayable
 *                             record
 *                        -1 - means seek backwards, skipping one
 *                             displayable record
 *
 *
 * RETURNED:    false is return if a displayable record was not found.
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         art   6/5/95      Initial Revision
 *
 ***********************************************************************/
Boolean ToolsSeekRecord (UInt16 * indexP, Int16 offset, Int16 direction)
{
	DmSeekRecordInCategory (AddrDB, indexP, offset, direction, CurrentCategory);
	if (DmGetLastErr()) return (false);

	return (true);
}


/***********************************************************************
 *
 * FUNCTION:    ToolsDirtyRecord
 *
 * DESCRIPTION: Mark a record dirty (modified).  Record marked dirty
 *              will be synchronized.
 *
 * PARAMETERS:
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         art   6/5/95      Initial Revision
 *
 ***********************************************************************/
void ToolsDirtyRecord (UInt16 index)
{
	UInt16      attr;

	DmRecordInfo (AddrDB, index, &attr, NULL, NULL);
	attr |= dmRecAttrDirty;
	DmSetRecordInfo (AddrDB, index, &attr, NULL);
}

⌨️ 快捷键说明

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