📄 dateday.c
字号:
* ---- ---- -----------
* art 7/16/95 Initial Revision
*
***********************************************************************/
static void RepeatSetDateTrigger (DateType endDate)
{
Char* label;
ListPtr lst;
ControlPtr ctl;
lst = GetObjectPtr (RepeatEndOnList);
ctl = GetObjectPtr (RepeatEndOnTrigger);
label = (Char *)CtlGetLabel (ctl); // OK to cast; we call CtlSetLabel
if (DateToInt (endDate) == apptNoEndDate)
{
StrCopy (label, LstGetSelectionText (lst, repeatNoEndDateItem));
LstSetSelection (lst, noEndDateItem);
}
else
{
// Format the end date into a string.
DateToDOWDMFormat (endDate.month,
endDate.day,
endDate.year + firstYear,
ShortDateFormat, label);
// DateToAscii (endDate.month,
// endDate.day,
// endDate.year + firstYear,
// LongDateFormat, label);
LstSetSelection (lst, repeatChooseDateItem);
}
CtlSetLabel (ctl, label);
}
/***********************************************************************
*
* FUNCTION: RepeatGetUIValues
*
* DESCRIPTION: This routine gets the current repeat settings of the
* ui gadgets in the repeat dialog box
*
*
* PARAMETERS: frm - pointer to the repeat dialog
* repeatP - RepeatInfoType structure (fill-in by this routine)
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 7/10/95 Initial Revision
*
***********************************************************************/
static void RepeatGetUIValues (FormPtr frm, RepeatInfoPtr repeatP)
{
UInt16 freq;
UInt16 i;
UInt16 id;
UInt16 index;
Char* str;
DetailsPtr details;
// Get the block that contains the details of the current record.
details = RepeatDetailsP;
// Get the repeat type.
index = FrmGetControlGroupSelection (frm, RepeatTypeGroup);
id = FrmGetObjectId (frm, index);
if (id == RepeatYearly)
repeatP->repeatType = repeatYearly;
else if (id <= RepeatWeekly)
{
repeatP->repeatType = (RepeatType) (id - RepeatNone);
}
else
{
index = FrmGetControlGroupSelection (frm, RepeatByGroup);
id = FrmGetObjectId (frm, index);
if (id == RepeatByDayPushButon)
repeatP->repeatType = repeatMonthlyByDay;
else
repeatP->repeatType = repeatMonthlyByDate;
}
// Get the repeat end date.
repeatP->repeatEndDate = RepeatEndDate;
// Get the repeat frequency.
str = FldGetTextPtr (GetObjectPtr (RepeatFrequenceField));
if (str) freq = StrAToI (str);
else freq = 0;
if (freq)
repeatP->repeatFrequency = freq;
else
repeatP->repeatFrequency = 1;
// Get the start day of week. If the original repeat type, that is the
// repeat type when the dialog was first displayed, is weekly then
// use the start date in the repeat info (the unedit data), otherwise
// use the current start of week.
if (repeatP->repeatType == repeatWeekly)
{
if (details->repeat.repeatType == repeatWeekly)
repeatP->repeatStartOfWeek = details->repeat.repeatStartOfWeek;
else
repeatP->repeatStartOfWeek = StartDayOfWeek;
}
// For all other repeat types, the repeatStartOfWeek field is meaningless.
else
repeatP->repeatStartOfWeek = 0;
// If the repeat type is weekly, get the day of the week the event
// repeats on.
if (repeatP->repeatType == repeatWeekly)
{
repeatP->repeatOn = 0;
index = FrmGetObjectIndex (frm, RepeatDayOfWeek1PushButton);
for (i = 0; i < daysInWeek ; i++)
{
if (FrmGetControlValue (frm, index +
((i - RepeatStartOfWeek + daysInWeek) % daysInWeek)))
repeatP->repeatOn |= (1 << i);
}
}
// If the repeat type is monthly by day, get the day of the month (ex:
// fisrt Friday) of the start date of the event.
else if (repeatP->repeatType == repeatMonthlyByDay)
{
if (details->repeat.repeatType == repeatMonthlyByDay)
repeatP->repeatOn = details->repeat.repeatOn;
else
repeatP->repeatOn = DayOfMonth (details->when.date.month,
details->when.date.day,
details->when.date.year + firstYear);
}
// For all other repeat types, the repeatOn field is meaningless.
else
{
repeatP->repeatOn = 0;
}
}
/***********************************************************************
*
* FUNCTION: RepeatSetUIValues
*
* DESCRIPTION: This routine sets the current repeat settings of the
* ui gadgets in the repeat dialog box
*
* PARAMETERS: frm - pointer to the Repeat Dialog
* repeatP - pointer to a RepeatInfoType structure.
*
* RETURNED: nothing
*
* HISTORY:
* 07/10/95 art Created by Art Lamb
* 08/03/99 kwk Copy label ptrs when shifting day-of-week pushbutton titles,
* not just the first byte of each label.
*
***********************************************************************/
static void RepeatSetUIValues (FormPtr frm, RepeatInfoPtr repeatP)
{
UInt16 i;
UInt16 id;
UInt16 oldFreq;
MemHandle freqH;
Char* freqP;
Boolean on;
FieldPtr fld;
// Set the selection of the "repeat type" push button group.
id = repeatP->repeatType + RepeatNone;
if (repeatP->repeatType > repeatMonthlyByDay)
id--;
FrmSetControlGroupSelection (frm, RepeatTypeGroup, id);
// Set the frequency field
if (repeatP->repeatType != repeatNone)
{
fld = GetObjectPtr (RepeatFrequenceField);
freqH = FldGetTextHandle (fld);
if (freqH)
{
freqP = MemHandleLock (freqH);
oldFreq = StrAToI (freqP);
}
else
{
freqH = MemHandleNew (maxFrequenceFieldLen);
freqP = MemHandleLock (freqH);
oldFreq = 0;
}
if (oldFreq != repeatP->repeatFrequency)
{
StrIToA (freqP, repeatP->repeatFrequency);
FldSetTextHandle (fld, freqH);
if (FrmVisible (FrmGetActiveForm ()))
{
FldEraseField (fld);
FldDrawField (fld);
}
}
MemHandleUnlock (freqH);
}
// Set the selection of the "repeat on" push button groups.
if (repeatP->repeatType == repeatWeekly)
{
// If the appointment has a different start-day-of-week than
// the dialog-box's current start-day-of-week, rearrange the
// labels on the days-of-week push buttons.
// Note that this will only handle button-label shifts of one day.
if (StartDayOfWeek != RepeatStartOfWeek)
{
const Char* sundayLabel = CtlGetLabel (GetObjectPtr (RepeatDayOfWeek1PushButton));
for (id = RepeatDayOfWeek1PushButton; id < RepeatDayOfWeek7PushButton; id++)
{
CtlSetLabel(GetObjectPtr(id), CtlGetLabel(GetObjectPtr(id + 1)));
}
CtlSetLabel(GetObjectPtr(RepeatDayOfWeek7PushButton), sundayLabel);
RepeatStartOfWeek = StartDayOfWeek;
}
// Turn on the push buttons for the days the appointment repeats on.
for (i = 0; i < daysInWeek; i++)
{
on = ((repeatP->repeatOn & (1 << i) ) != 0);
id = RepeatDayOfWeek1PushButton +
((i - RepeatStartOfWeek + daysInWeek) % daysInWeek);
CtlSetValue (GetObjectPtr (id), on);
}
}
// Set the selection of the "repeat by" push button groups.
if (repeatP->repeatType == repeatMonthlyByDate)
FrmSetControlGroupSelection (frm, RepeatByGroup, RepeatByDatePushButon);
else
FrmSetControlGroupSelection (frm, RepeatByGroup, RepeatByDayPushButon);
// Set the "end on" trigger label and popup list selection.
if (repeatP->repeatType != repeatNone)
{
RepeatSetDateTrigger (repeatP->repeatEndDate);
}
}
/***********************************************************************
*
* FUNCTION: RepeatDrawDescription
*
* DESCRIPTION: This routine draws the text description of the current
* repeat type and frequency.
*
* The description is created from a template string. The
* repeat type and frequency determines which template is
* used. The template may contain one or more of the
* following token:
* ^d - day name (ex: Monday)
* ^f - frequency
* ^x - day of the month ordinal number (ex: 1st - 31th)
* ^m - month name (ex: July)
* ^w - week ordinal number (1st, 2nd, 3rd, 4th, or last)
*
* PARAMETERS: frm - pointer to the repeat dialog box
*
* RETURNED: nothing
*
* HISTORY:
* 07/06/95 art Created by Art Lam
* 03/02/99 grant Only do week ordinal substitution in the repeatMonthlyByDay case
* 08/04/99 kwk Use explicit string resources for days/months/years versus
* borrowing from system, so we can localize properly.
* 10/21/99 gap Remove rectangle drawing from proc. Now a gadget in form.
* 11/05/99 gap Always use full day of week name when repeat.repeatType is repeatMonthlyByDay.
*
***********************************************************************/
static void RepeatDrawDescription (FormPtr frm)
{
UInt8 repeatOn;
UInt16 i;
UInt16 len;
UInt16 freq;
UInt16 dayOfWeek;
UInt16 templateId;
UInt16 repeatOnCount = 0;
Char* descP;
Char* resP;
Char* saveResP;
MemHandle descH;
MemHandle resH;
FieldPtr fld;
DetailsPtr details;
RepeatInfoType repeat;
// Get the block that contains the details of the current record.
details = RepeatDetailsP;
fld = GetObjectPtr (RepeatDescField);
FldEraseField (fld);
// Get the current setting of the repeat ui gadgets.
RepeatGetUIValues (frm, &repeat);
// Determine which template string to use. The template string is
// used to format the description string. Note that we could add
// a soft constant which tells us whether we need to use different
// strings for freq == 1 case (depends on language), thus saving space.
freq = repeat.repeatFrequency;
switch (repeat.repeatType)
{
case repeatNone:
templateId = repeatNoneStrID;
break;
case repeatDaily:
if (freq == 1)
// "Every day"
templateId = everyDayRepeatStrID;
else
// "Every [other | 2nd | 3rd...] day"
templateId = dailyRepeatStrID;
break;
case repeatWeekly:
if (freq == 1)
// "Every week on [days of week]"
templateId = everyWeekRepeat1DayStrID;
else
templateId = weeklyRepeat1DayStrID;
// Generate offset to appropriate string id,
// based on # of days that we need to append.
for (i = 0; i < daysInWeek; i++)
{
if (repeat.repeatOn & (1 << i) ) repeatOnCount++;
}
templateId += (repeatOnCount - 1);
break;
case repeatMonthlyByDate:
if (freq == 1)
// "The ^w ^d of every month"
templateId = everyMonthByDateRepeatStrID;
else
templateId = monthtlyByDateRepeatStrID;
break;
case repeatMonthlyByDay:
if (freq == 1)
templateId = everyMonthByDayRepeatStrID;
else
templateId = monthtlyByDayRepeatStrID;
break;
case repeatYearly:
if (freq == 1)
templateId = everyYearRepeatStrID;
else
templateId = yearlyRepeatStrID;
break;
default:
ErrNonFatalDisplay("Unknown repeat type");
break;
}
// Allocate a block to hold the description and copy the template
// string into it.
resH = DmGetResource (strRsc, templateId);
resP = MemHandleLock (resH);
descH = MemHandleNew (MemPtrSize(resP));
descP = MemHandleLock (descH);
StrCopy (descP, resP);
MemHandleUnlock (resH);
// Substitute the month name string for the month name token.
resH = DmGetResource (strRsc, repeatMonthNamesStrID);
resP = MemHandleLock (resH);
for (i = 1; i < details->when.date.month; i++)
resP = StrChr (resP, spaceChr) + 1;
len = (UInt16) (StrChr (resP, spaceChr) - resP);
descP = SubstituteStr (descP, monthNameToken, resP, len);
MemHandleUnlock (resH);
// Substitute the day name string for the day name token.
if ( (repeatOnCount == 1) || (repeat.repeatType == repeatMonthlyByDay) )
templateId = repeatFullDOWNamesStrID;
else
templateId = repeatShortDOWNamesStrID;
resH = DmGetResource (strRsc, templateId);
resP = MemHandleLock (resH);
if (repeat.repeatType == repeatWeekly)
{
dayOfWeek = repeat.repeatStartOfWeek;
repeatOn = repeat.repeatOn;
saveResP = resP;
while (StrStr (descP, dayNameToken))
{
for (i = 0; i < daysInWeek; i++)
{
if (repeatOn & (1 << dayOfWeek) )
{
repeatOn &= ~(1 << dayOfWeek);
break;
}
dayOfWeek = (dayOfWeek + 1 + daysInWeek) % daysInWeek;
}
resP = saveResP;
for (i = 0; i < dayOfWeek; i++)
resP = StrChr (resP, spaceChr) + 1;
len = (UInt16) (StrChr (resP, spaceChr) - resP);
descP = SubstituteStr (descP, dayNameToken, resP, len);
}
}
else
{
dayOfWeek = DayOfWeek (details->when.date.month, details->when.date.day,
details->when.date.year + firstYear);
for (i = 0; i < dayOfWeek; i++)
resP = StrChr (resP, spaceChr) + 1;
len = (UInt16) (StrChr (resP, spaceChr) - resP);
descP = SubstituteStr (descP, dayNameToken, resP, len);
}
MemHandleUnlock (resH);
// Substitute the repeat frequency string for the frequency token. Note that
// we do something special for 2nd (other), since the gender of 'other' changes
// for some languages, depending on whether the next word is day, month, week,
// or year.
if (freq == 2)
{
Char otherFreqName[16];
UInt16 index = (UInt16)repeat.repeatType - (UInt16)repeatNone;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -