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

📄 datedb.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 5 页
字号:
		case repeatMonthlyByDate:
			// Compute the number of months
			months = ((end.year - start.year) * monthsInYear) + (end.month - start.month);
			
			// if the end day is too early in the last month, don't include that month
			if (end.day < start.day)
				months--;
			
			daysTotal = months / freq + 1;	// repeats once every freq months
			break;
		
		
		// Yearly repeating appointment.
		case repeatYearly:
			years = end.year - start.year;
			
			// if the end day is too early in the last year, don't include that year
			if (end.month < start.month
					|| (end.month == start.month && end.day < start.day))
				years--;
			
			daysTotal = years / freq + 1;		// repeats once every freq years
			break;
		
		default:
			daysTotal = 1;
			break;
		}
	
	ErrNonFatalDisplayIf(daysTotal == 0, "event repeats on 0 days");
	ErrNonFatalDisplayIf(daysTotal < 0, "event repeats on negative days");
	if (daysTotal <= 0)  daysTotal = 1;
	
	return (daysTotal);
}


/***********************************************************************
 *
 * FUNCTION:    ApptHasMultipleOccurences
 *
 * DESCRIPTION: Does the given appointment occur more than once?
 *
 *		This function compares the repeat info and the exception list for
 *		an appointment to determine if it has more than one visible (non-excepted)
 *		occurence.
 *		The decision is based solely on the number of times the appointment
 *		repeats versus the number of exceptions.
 *
 * PARAMETERS:  ApptDBRecordPtr apptRecP - the appointment to examine
 *
 * RETURNED:    true if the appointment occurs more than once
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			grant	3/2/99	Initial Revision
 *
 ***********************************************************************/
Boolean ApptHasMultipleOccurences(ApptDBRecordPtr apptRecP)
{
	Int32 totalRepeats;
	Int32 numExceptions;
	
	ErrFatalDisplayIf(apptRecP == NULL, "no appointment");

	// if the appointment does not repeat, then it can't occur more than once
	if (!apptRecP->repeat)  return false;
	
	totalRepeats = CountTotalRepeats(apptRecP);
	if (apptRecP->exceptions)
		numExceptions = apptRecP->exceptions->numExceptions;
	else
		numExceptions = 0;
	
	if (totalRepeats == apptNoEndDate)  return true;
	if ((totalRepeats - numExceptions) > 1)  return true;
	
	return false;
}


/***********************************************************************
 *
 * FUNCTION:    ApptListCompare
 *
 * DESCRIPTION: This routine compares two entries in the appointment list, 
 *              it's called by ApptGetAppointments via the quick sort 
 *              routine.
 *
 * PARAMETERS:  a     - a pointer to an entry in the appointment list
 *					 b     - a pointer to an entry in the appointment list
 *              extra - extra data passed to quick sort - not used
 *
 * RETURNED:    if a1 > a2  returns a positive int
 *              if a1 < a2  returns a negative int
 *              if a1 = a2  returns zero
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	6/15/95		Initial Revision
 *
 ***********************************************************************/
static Int16 ApptListCompare (ApptInfoPtr a1, ApptInfoPtr  a2, Int32 extra)
{
#pragma unused (extra)

	Int16 result;
	
	result = TimeCompare (a1->startTime, a2->startTime);
	if (result == 0)
		{
		result = TimeCompare (a1->endTime, a2->endTime);
		}
	return result;
}


/***********************************************************************
 *
 * FUNCTION:    ApptGetAppointments
 *
 * DESCRIPTION: This routine returns a list of appointments that are on 
 *              the date specified
 *
 * PARAMETERS:  dbP    - pointer to the database
 *              date   - date to search for
 *              countP - number of appointments on the specified 
 *                       day (returned value)
 *
 * RETURNED:    handle of the appointment list (ApptInfoType)
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	6/15/95		Initial Revision
 *
 ***********************************************************************/
#if 0
VoidHand ApptGetAppointments (DmOpenRef dbP, DateType date, UInt16* countP)
{
	Err	error;
	Int16	result;
	Int16	count = 0;
	UInt16	recordNum;
	Boolean repeats;
	MemHandle recordH;
	MemHandle apptListH;
	ApptInfoPtr apptList;
	ApptDBRecordType apptRec;
	ApptPackedDBRecordPtr r;

	// Allocated a block to hold the appointment list.
	apptListH = MemHandleNew (sizeof (ApptInfoType) * apptMaxPerDay);
	ErrFatalDisplayIf(!apptListH, "Out of memory");
	if (! apptListH) return (0);

	apptList = MemHandleLock (apptListH);
	

	// Find the first non-repeating appointment of the day.
	if (ApptFindFirst (dbP, date, &recordNum))
		{
		while (count < apptMaxPerDay)
			{
			// Check if the appointment is on the date passed, if it is 
			// add it to the appointment list.		
			recordH = DmQueryRecord (dbP, recordNum);
			r = MemHandleLock (recordH);
			result = DateCompare (r->when.date, date);

			if (result == 0)
				{
				// Add the record to the appoitment list.
				apptList[count].startTime = r->when.startTime;				
				apptList[count].endTime = r->when.endTime;				
				apptList[count].recordNum = recordNum;	
				count++;
				}
			MemHandleUnlock (recordH);
			if (result != 0) break;

			// Get the next record.
			error = DmSeekRecordInCategory (dbP, &recordNum, 1, dmSeekForward, dmAllCategories);
			if (error == dmErrSeekFailed) break;
			}
		}


	// Add the repeating appointments to the list.  Repeating appointments
	// are stored at the beginning of the database.
	recordNum = 0;
	while (count < apptMaxPerDay)
		{
		recordH = DmQueryNextInCategory (dbP, &recordNum, dmAllCategories);
		if (! recordH) break;
		
		r = (ApptPackedDBRecordPtr) MemHandleLock (recordH);
		
		repeats = (r->flags.repeat != 0);
		if (repeats)
			{
			ApptUnpack (r, &apptRec);
			if (ApptRepeatsOnDate (&apptRec, date))
				{
				// Add the record to the appoitment list.
				apptList[count].startTime = r->when.startTime;				
				apptList[count].endTime = r->when.endTime;				
				apptList[count].recordNum = recordNum;	
				count++;
				}
			}
		MemHandleUnlock (recordH);

		// If the record has no repeating info we've reached the end of the 
		// repeating appointments.
		if (! repeats) break;
		
		 recordNum++;
		}

	
	// Sort the list by start time.
	SysInsertionSort (apptList, count, sizeof (ApptInfoType), ApptListCompare, 0L);
	

	// If there are no appointments on the specified day, free the appointment
	// list.
	if (count == 0)
		{
		MemPtrFree (apptList);
		apptListH = 0;
		}

	// Resize the appointment list block to release any unused space.
	else
		{
		MemHandleUnlock (apptListH);
		MemHandleResize (apptListH, count * sizeof (ApptInfoType));
		}

	*countP = count;
	return (apptListH);
}
#endif


/***********************************************************************
 *
 * FUNCTION:    ApptGetAlarmTime
 *
 * DESCRIPTION: This routine determines the date and time of an alarm for
 *				the event passed.  Depending on the search direction specified,
 *				it will return either the time of the next occurrence of the alarm 
 *				to fire, or the time of the most recently triggered alarm.
 *
 * PARAMETERS:  apptRec     - pointer to an appointment record
 *              currentTime - current date and time in seconds
 *					 searchForward - designates whether to find the next (true) or 
 *										most recent (false) occurrence of an event.
 *
 * RETURNED:    date and time of the alarm, in seconds, or zero if there
 *              is no alarm
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			art	6/20/95	Initial Revision
 *			gap	9/25/00	Add capability to search backwards for the most
 *								recent occurrence of the event (needed for attention
 *								manager support)
 *			gap	10/17/00	small optimization - removed advance calculation
 *								out of while loop as we only need to do this once.
 *								also, add advance to current time in order to
 *								correctly position the start of a backward search in
 *								order to take into account the advance time.
 *
 ***********************************************************************/
UInt32 ApptGetAlarmTime (ApptDBRecordPtr apptRec, UInt32 currentTime, Boolean searchForward)
{
	UInt32				advance;
	UInt32				alarmTime;
	DateType				repeatDate;
	DateTimeType		curDateTime;
	DateTimeType		apptDateTime;

	if (!apptRec->alarm)
		return apptNoTime;

	// Non-repeating appointment?
	if (! apptRec->repeat)
		{
		// An alarm on an untimed event triggers at midnight.
		if (TimeToInt (apptRec->when->startTime) == apptNoTime)
			{
			apptDateTime.minute = 0;
			apptDateTime.hour = 0;
			}
		else
			{
			apptDateTime.minute = apptRec->when->startTime.minutes;
			apptDateTime.hour = apptRec->when->startTime.hours;
			}
		apptDateTime.second = 0;
		apptDateTime.day = apptRec->when->date.day;
		apptDateTime.month = apptRec->when->date.month;
		apptDateTime.year = apptRec->when->date.year + firstYear;



		// Compute the time of the alarm by adjusting the date and time 
		// of the appointment by the length of the advance notice.
		advance = apptRec->alarm->advance;
		switch (apptRec->alarm->advanceUnit)
			{
			case aauMinutes:
				advance *= minutesInSeconds;
				break;
			case aauHours:
				advance *= hoursInSeconds;
				break;
			case aauDays:
				advance *= daysInSeconds;
				break;
			}

		alarmTime = TimDateTimeToSeconds (&apptDateTime) - advance;
		
		if (searchForward)
			{
			if (alarmTime >= currentTime)
				return (alarmTime);
			else
				return (0);
			}
		else
			{
			if (alarmTime <= currentTime)
				return (alarmTime);
			else
				return (0);
			}
		}


	// Repeating appointment.

	// calculate the appointment alarm advance time.
	switch (apptRec->alarm->advanceUnit)
		{
		case aauMinutes:
			advance = (UInt32) apptRec->alarm->advance * minutesInSeconds;
			break;
		case aauHours:
			advance = (UInt32) apptRec->alarm->advance * hoursInSeconds;
			break;
		case aauDays:
			advance = (UInt32) apptRec->alarm->advance * daysInSeconds;
			break;
		}
	
	// if searchin backwards, adjust the start point of 
	// the search to account for the alarm advance time.
	if (!searchForward)
		TimSecondsToDateTime (currentTime+advance, &curDateTime);
	else
		TimSecondsToDateTime (currentTime, &curDateTime);
	
	repeatDate.year = curDateTime.year - firstYear;
	repeatDate.month = curDateTime.month;
	repeatDate.day = curDateTime.day;
	
	while (ApptNextRepeat (apptRec, &repeatDate, searchForward))
		{
		// An alarm on an untimed event triggers at midnight.
		if (TimeToInt (apptRec->when->startTime) == apptNoTime)
			{
			apptDateTime.minute = 0;
			apptDateTime.hour = 0;
			}
		else
			{
			apptDateTime.minute = apptRec->when->startTime.minutes;
			apptDateTime.hour = apptRec->when->startTime.hours;
			}
		apptDateTime.second = 0;
		apptDateTime.day = repeatDate.day;
		apptDateTime.month = repeatDate.month;
		apptDateTime.year = repeatDate.year + firstYear;

		// Compute the time of the alarm by adjusting the date and time 
		// of the appointment by the length of the advance notice.
		alarmTime = TimDateTimeToSeconds (&apptDateTime) - advance;
		
		if (searchForward)
			{
			if (alarmTime >= currentTime)
				return (alarmTime);

			DateAdjust (&repeatDate, 1);
			} 
		else
			{
			if (alarmTime <= currentTime)
				return (alarmTime);

			DateAdjust (&repeatDate, -1);
			} 
		}
		
	return (0);
}


/***********************************************************************
 *
 * FUNCTION:    ApptAlarmMunge
 *
 * DESCRIPTION: Helper routine for ApptAlarmMunger. Process one appointment.
 *
 * PARAMETERS:  inDbR			- reference to open database
 *					 inPackedRecordP - pointer to packed record in storage heap
 *					 inAlarmStart	- first valid alarm time
 *					 inAlarmStop	- last valid alarm time
 *					 inOutEarliestAlarmP - ???
 *					 outAudibleP	- true if alarm sound should play, nil is ok
 *
 * RETURNED:    nothing
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			peter	3/22/00	Initial Revision. Based on existing code from
 *								ApptAlarmMunger.
 *			gap	06/06/00	Only increment the alarm counter variable (numAlarms)
 *								when a new alarm is added to the alarms as opposed to
 *								every time an alarm is processed.  Can result in a 
 *								Fatal Alert "Error Querying Record" if count does not
 *								match the number of alarms in list and just the right
 *								value happens to reside in the memory following the
 *								actual list contents.
 *
 ***********************************************************************/
static void ApptAlarmMunge (
	ApptPackedDBRecordPtr	inPackedRecordP,
	UInt16						inRecordNum,
	UInt32						inAlarmStart,
	UInt32						inAlarmStop,
	AlarmPostingDataPtr		inPostingAlarmData,
	UInt32 *						inOutEarliestAlarmP)
{
	ApptDBRecordType			apptRec;
	UInt32						alarmTime;
	UInt32 						uniqueID;
	AttnLevelType 				attnLevel;
	AttnFlagsType 				attnFlags;

	if ( inPackedRecordP->flags.alarm )
		{
		ApptUnpack (inPackedRecordP, &apptRec);
		
		// Get the first alarm on or after inAlarmStart
		alarmTime = ApptGetAlarmTime (&apptRec, inAlarmStart, true);
		
		// If in range, add the alarm to the output
		if ( alar

⌨️ 快捷键说明

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