#include /* * $Author: tom $ * $Date: 2016/11/20 20:06:42 $ * $Revision: 1.99 $ */ #define YEAR2INDEX(year) (((year) >= 1900) ? ((year) - 1900) : (year)) /* * Declare file local variables. */ static const char *monthsOfTheYear[] = { "NULL", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static int daysOfTheMonth[] = { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /* * Declare file local prototypes. */ static int getMonthLength (int year, int month); static int getMonthStartWeekday (int year, int month); static time_t getCurrentTime (CDKCALENDAR *calendar); static void verifyCalendarDate (CDKCALENDAR *calendar); static void incrementCalendarDay (CDKCALENDAR *calendar, int adjust); static void decrementCalendarDay (CDKCALENDAR *calendar, int adjust); static void incrementCalendarMonth (CDKCALENDAR *calendar, int adjust); static void decrementCalendarMonth (CDKCALENDAR *calendar, int adjust); static void incrementCalendarYear (CDKCALENDAR *calendar, int adjust); static void decrementCalendarYear (CDKCALENDAR *calendar, int adjust); static void drawCDKCalendarField (CDKCALENDAR *calendar); DeclareCDKObjects (CALENDAR, Calendar, setCdk, Int); /* * This creates a calendar widget. */ CDKCALENDAR *newCDKCalendar (CDKSCREEN *cdkscreen, int xplace, int yplace, const char *title, int day, int month, int year, chtype dayAttrib, chtype monthAttrib, chtype yearAttrib, chtype highlight, boolean Box, boolean shadow) { /* *INDENT-EQLS* */ CDKCALENDAR *calendar = 0; int parentWidth = getmaxx (cdkscreen->window); int parentHeight = getmaxy (cdkscreen->window); int boxWidth = 24; int boxHeight = 11; int xpos = xplace; int ypos = yplace; int x; struct tm *dateInfo; time_t clck; const char *dayname = "Su Mo Tu We Th Fr Sa "; /* *INDENT-OFF* */ static const struct { int from; int to; } bindings[] = { { 'T', KEY_HOME }, { 't', KEY_HOME }, { 'n', KEY_NPAGE }, { CDK_FORCHAR, KEY_NPAGE }, { 'p', KEY_PPAGE }, { CDK_BACKCHAR, KEY_PPAGE }, }; /* *INDENT-ON* */ if ((calendar = newCDKObject (CDKCALENDAR, &my_funcs)) == 0) return (0); setCDKCalendarBox (calendar, Box); boxWidth = setCdkTitle (ObjOf (calendar), title, boxWidth); boxHeight += TitleLinesOf (calendar); /* * Make sure we didn't extend beyond the dimensions of the window. */ boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth); boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight); /* Rejustify the x and y positions if we need to. */ alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight); /* Create the calendar window. */ calendar->win = newwin (boxHeight, boxWidth, ypos, xpos); /* Is the window null? */ if (calendar->win == 0) { destroyCDKObject (calendar); return (0); } keypad (calendar->win, TRUE); /* Set some variables. */ calendar->xOffset = (boxWidth - 20) / 2; calendar->fieldWidth = boxWidth - 2 * (1 + BorderOf (calendar)); /* Set months and days names */ for (x = 0; x < MAX_MONTHS; x++) { calendar->MonthName[x] = copyChar (monthsOfTheYear[x]); } calendar->DayName = copyChar (dayname); /* *INDENT-EQLS* Set the rest of the widget values. */ ScreenOf (calendar) = cdkscreen; calendar->parent = cdkscreen->window; calendar->shadowWin = 0; calendar->xpos = xpos; calendar->ypos = ypos; calendar->boxWidth = boxWidth; calendar->boxHeight = boxHeight; calendar->day = day; calendar->month = month; calendar->year = year; calendar->dayAttrib = dayAttrib; calendar->monthAttrib = monthAttrib; calendar->yearAttrib = yearAttrib; calendar->highlight = highlight; calendar->width = boxWidth; initExitType (calendar); ObjOf (calendar)->acceptsFocus = TRUE; ObjOf (calendar)->inputWindow = calendar->win; calendar->shadow = shadow; calendar->labelWin = subwin (calendar->win, 1, calendar->fieldWidth, ypos + TitleLinesOf (calendar) + 1, xpos + 1 + BorderOf (calendar)); if (calendar->labelWin == 0) { destroyCDKObject (calendar); return (0); } calendar->fieldWin = subwin (calendar->win, 7, 20, ypos + TitleLinesOf (calendar) + 3, xpos + calendar->xOffset); if (calendar->fieldWin == 0) { destroyCDKObject (calendar); return (0); } setCDKCalendarBox (calendar, Box); calendar->marker = typeCallocN (chtype, CALENDAR_LIMIT); if (calendar->marker == 0) { destroyCDKObject (calendar); return (0); } /* If the day/month/year values were 0, then use today's date. */ if ((calendar->day == 0) && (calendar->month == 0) && (calendar->year == 0)) { time (&clck); dateInfo = gmtime (&clck); /* *INDENT-EQLS* */ calendar->day = dateInfo->tm_mday; calendar->month = dateInfo->tm_mon + 1; calendar->year = dateInfo->tm_year + 1900; } /* Verify the dates provided. */ verifyCalendarDate (calendar); /* Determine which day the month starts on. */ calendar->weekDay = getMonthStartWeekday (calendar->year, calendar->month); /* If a shadow was requested, then create the shadow window. */ if (shadow) { calendar->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1); } /* Setup the key bindings. */ for (x = 0; x < (int)SIZEOF (bindings); ++x) bindCDKObject (vCALENDAR, calendar, (chtype)bindings[x].from, getcCDKBind, (void *)(long)bindings[x].to); registerCDKObject (cdkscreen, vCALENDAR, calendar); return (calendar); } /* * This function lets the user play with this widget. */ time_t activateCDKCalendar (CDKCALENDAR *calendar, chtype *actions) { /* *INDENT-EQLS* */ chtype input = 0; boolean functionKey; time_t ret = -1; /* Draw the widget. */ drawCDKCalendar (calendar, ObjOf (calendar)->box); if (actions == 0) { for (;;) { input = (chtype)getchCDKObject (ObjOf (calendar), &functionKey); /* Inject the character into the widget. */ ret = injectCDKCalendar (calendar, input); if (calendar->exitType != vEARLY_EXIT) { return ret; } } } else { int length = chlen (actions); int x = 0; /* Inject each character one at a time. */ for (x = 0; x < length; x++) { ret = injectCDKCalendar (calendar, actions[x]); if (calendar->exitType != vEARLY_EXIT) { return ret; } } } return ret; } /* * This injects a single character into the widget. */ static int _injectCDKCalendar (CDKOBJS *object, chtype input) { CDKCALENDAR *widget = (CDKCALENDAR *)object; /* Declare local variables. */ int ppReturn = 1; int ret = unknownInt; bool complete = FALSE; /* Set the exit type. */ setExitType (widget, 0); /* Refresh the widget field. */ drawCDKCalendarField (widget); /* Check if there is a pre-process function to be called. */ if (PreProcessFuncOf (widget) != 0) { /* Call the pre-process function. */ ppReturn = PreProcessFuncOf (widget) (vCALENDAR, widget, PreProcessDataOf (widget), input); } /* Should we continue? */ if (ppReturn != 0) { /* Check a predefined binding. */ if (checkCDKObjectBind (vCALENDAR, widget, input) != 0) { checkEarlyExit (widget); complete = TRUE; } else { switch (input) { case KEY_UP: decrementCalendarDay (widget, 7); break; case KEY_DOWN: incrementCalendarDay (widget, 7); break; case KEY_LEFT: decrementCalendarDay (widget, 1); break; case KEY_RIGHT: incrementCalendarDay (widget, 1); break; case KEY_NPAGE: incrementCalendarMonth (widget, 1); break; case 'N': incrementCalendarMonth (widget, 6); break; case KEY_PPAGE: decrementCalendarMonth (widget, 1); break; case 'P': decrementCalendarMonth (widget, 6); break; case '-': decrementCalendarYear (widget, 1); break; case '+': incrementCalendarYear (widget, 1); break; case KEY_HOME: setCDKCalendarDate (widget, -1, -1, -1); break; case KEY_ESC: setExitType (widget, input); complete = TRUE; break; case KEY_ERROR: setExitType (widget, input); complete = TRUE; break; case KEY_TAB: case KEY_ENTER: setExitType (widget, input); ret = (int)getCurrentTime (widget); complete = TRUE; break; case CDK_REFRESH: eraseCDKScreen (ScreenOf (widget)); refreshCDKScreen (ScreenOf (widget)); break; } } /* Should we do a post-process? */ if (!complete && (PostProcessFuncOf (widget) != 0)) { PostProcessFuncOf (widget) (vCALENDAR, widget, PostProcessDataOf (widget), input); } } if (!complete) { setExitType (widget, 0); } ResultOf (widget).valueInt = ret; return (ret != unknownInt); } /* * This moves the calendar field to the given location. */ static void _moveCDKCalendar (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag) { CDKCALENDAR *calendar = (CDKCALENDAR *)object; /* *INDENT-EQLS* */ int currentX = getbegx (calendar->win); int currentY = getbegy (calendar->win); int xpos = xplace; int ypos = yplace; int xdiff = 0; int ydiff = 0; /* * If this is a relative move, then we will adjust where we want * to move to. */ if (relative) { xpos = getbegx (calendar->win) + xplace; ypos = getbegy (calendar->win) + yplace; } /* Adjust the window if we need to. */ alignxy (WindowOf (calendar), &xpos, &ypos, calendar->boxWidth, calendar->boxHeight); /* Get the difference. */ xdiff = currentX - xpos; ydiff = currentY - ypos; /* Move the window to the new location. */ moveCursesWindow (calendar->win, -xdiff, -ydiff); moveCursesWindow (calendar->fieldWin, -xdiff, -ydiff); moveCursesWindow (calendar->labelWin, -xdiff, -ydiff); moveCursesWindow (calendar->shadowWin, -xdiff, -ydiff); /* Touch the windows so they 'move'. */ refreshCDKWindow (WindowOf (calendar)); /* Redraw the window, if they asked for it. */ if (refresh_flag) { drawCDKCalendar (calendar, ObjOf (calendar)->box); } } /* * This draws the calendar widget. */ static void _drawCDKCalendar (CDKOBJS *object, boolean Box) { CDKCALENDAR *calendar = (CDKCALENDAR *)object; int headerLen = (int)strlen (calendar->DayName); int colLen = (6 + headerLen) / 7; int col; /* Is there a shadow? */ if (calendar->shadowWin != 0) { drawShadow (calendar->shadowWin); } /* Box the widget if asked. */ if (Box) { drawObjBox (calendar->win, ObjOf (calendar)); } drawCdkTitle (calendar->win, object); /* Draw in the day-of-the-week header. */ for (col = 0; col < 7; ++col) { int src = colLen * ((col + (calendar->weekBase % 7)) % 7); int dst = colLen * col; writeChar (calendar->win, calendar->xOffset + dst, TitleLinesOf (calendar) + 2, calendar->DayName + src, HORIZONTAL, 0, colLen); } wrefresh (calendar->win); drawCDKCalendarField (calendar); } /* * This draws the month field. */ static void drawCDKCalendarField (CDKCALENDAR *calendar) { /* *INDENT-EQLS* */ char *monthName = calendar->MonthName[calendar->month]; int monthLength = getMonthLength (calendar->year, calendar->month); int yearIndex = YEAR2INDEX (calendar->year); int day; int row, col; int save_y = -1; int save_x = -1; char temp[30]; day = (1 - calendar->weekDay + (calendar->weekBase % 7)); if (day > 0) day -= 7; for (row = 1; row <= 6; row++) { for (col = 0; col < 7; col++) { if (day >= 1 && day <= monthLength) { int xpos = col * 3; int ypos = row; chtype marker = calendar->dayAttrib; sprintf (temp, "%02d", day); if (calendar->day == day) { marker = calendar->highlight; save_y = (ypos + getbegy (calendar->fieldWin) - getbegy (InputWindowOf (calendar))); save_x = 1; } else { marker |= getCDKCalendarMarker (calendar, day, calendar->month, yearIndex); } writeCharAttrib (calendar->fieldWin, xpos, ypos, temp, marker, HORIZONTAL, 0, 2); } day++; } } wrefresh (calendar->fieldWin); /* Draw the month in. */ if (calendar->labelWin != 0) { int yearLen = 0; sprintf (temp, "%s %d,", monthName, calendar->day); writeChar (calendar->labelWin, 0, 0, temp, HORIZONTAL, 0, (int)strlen (temp)); wclrtoeol (calendar->labelWin); /* Draw the year in. */ sprintf (temp, "%d", calendar->year); yearLen = (int)strlen (temp); writeChar (calendar->labelWin, calendar->fieldWidth - yearLen, 0, temp, HORIZONTAL, 0, yearLen); wmove (calendar->labelWin, 0, 0); wrefresh (calendar->labelWin); } else if (save_y >= 0) { wmove (InputWindowOf (calendar), save_y, save_x); wrefresh (InputWindowOf (calendar)); } } /* * This sets multiple attributes of the widget. */ void setCDKCalendar (CDKCALENDAR *calendar, int day, int month, int year, chtype dayAttrib, chtype monthAttrib, chtype yearAttrib, chtype highlight, boolean Box) { setCDKCalendarDate (calendar, day, month, year); setCDKCalendarDayAttribute (calendar, dayAttrib); setCDKCalendarMonthAttribute (calendar, monthAttrib); setCDKCalendarYearAttribute (calendar, yearAttrib); setCDKCalendarHighlight (calendar, highlight); setCDKCalendarBox (calendar, Box); } /* * This sets the date and some attributes. */ void setCDKCalendarDate (CDKCALENDAR *calendar, int day, int month, int year) { /* Declare local variables. */ struct tm *dateInfo; time_t clck; /* * Get the current dates and set the default values for * the day/month/year values for the calendar. */ time (&clck); dateInfo = gmtime (&clck); /* Set the date elements if we need too. */ /* *INDENT-EQLS* */ calendar->day = (day == -1 ? dateInfo->tm_mday : day); calendar->month = (month == -1 ? dateInfo->tm_mon + 1 : month); calendar->year = (year == -1 ? dateInfo->tm_year + 1900 : year); /* Verify the date information. */ verifyCalendarDate (calendar); /* Get the start of the current month. */ calendar->weekDay = getMonthStartWeekday (calendar->year, calendar->month); } /* * This returns the current date on the calendar. */ void getCDKCalendarDate (CDKCALENDAR *calendar, int *day, int *month, int *year) { /* *INDENT-EQLS* */ (*day) = calendar->day; (*month) = calendar->month; (*year) = calendar->year; } /* * This sets the attribute of the days in the calendar. */ void setCDKCalendarDayAttribute (CDKCALENDAR *calendar, chtype attribute) { calendar->dayAttrib = attribute; } chtype getCDKCalendarDayAttribute (CDKCALENDAR *calendar) { return calendar->dayAttrib; } /* * This sets the attribute of the month names in the calendar. */ void setCDKCalendarMonthAttribute (CDKCALENDAR *calendar, chtype attribute) { calendar->monthAttrib = attribute; } chtype getCDKCalendarMonthAttribute (CDKCALENDAR *calendar) { return calendar->monthAttrib; } /* * This sets the attribute of the year in the calendar. */ void setCDKCalendarYearAttribute (CDKCALENDAR *calendar, chtype attribute) { calendar->yearAttrib = attribute; } chtype getCDKCalendarYearAttribute (CDKCALENDAR *calendar) { return calendar->yearAttrib; } /* * This sets the attribute of the highlight box. */ void setCDKCalendarHighlight (CDKCALENDAR *calendar, chtype highlight) { calendar->highlight = highlight; } chtype getCDKCalendarHighlight (CDKCALENDAR *calendar) { return calendar->highlight; } /* * This sets the box attibute of the widget. */ void setCDKCalendarBox (CDKCALENDAR *calendar, boolean Box) { ObjOf (calendar)->box = Box; ObjOf (calendar)->borderSize = Box ? 1 : 0; } boolean getCDKCalendarBox (CDKCALENDAR *calendar) { return ObjOf (calendar)->box; } /* * This sets the background attribute of the widget. */ static void _setBKattrCalendar (CDKOBJS *object, chtype attrib) { if (object != 0) { CDKCALENDAR *widget = (CDKCALENDAR *)object; wbkgd (widget->win, attrib); wbkgd (widget->fieldWin, attrib); if (widget->labelWin != 0) { wbkgd (widget->labelWin, attrib); } } } /* * This erases the calendar widget. */ static void _eraseCDKCalendar (CDKOBJS *object) { if (validCDKObject (object)) { CDKCALENDAR *calendar = (CDKCALENDAR *)object; eraseCursesWindow (calendar->labelWin); eraseCursesWindow (calendar->fieldWin); eraseCursesWindow (calendar->win); eraseCursesWindow (calendar->shadowWin); } } /* * This destroys the calendar object pointer. */ static void _destroyCDKCalendar (CDKOBJS *object) { if (object != 0) { CDKCALENDAR *calendar = (CDKCALENDAR *)object; int x; cleanCdkTitle (object); freeChar (calendar->DayName); for (x = 0; x < MAX_MONTHS; x++) { freeChar (calendar->MonthName[x]); } freeChecked (calendar->marker); /* Free up the window pointers. */ deleteCursesWindow (calendar->labelWin); deleteCursesWindow (calendar->fieldWin); deleteCursesWindow (calendar->shadowWin); deleteCursesWindow (calendar->win); /* Clean the key bindings. */ cleanCDKObjectBindings (vCALENDAR, calendar); /* Unregister the object. */ unregisterCDKObject (vCALENDAR, calendar); } } /* * This sets a marker on the calendar. */ void setCDKCalendarMarker (CDKCALENDAR *calendar, int day, int month, int year, chtype marker) { int yearIndex = YEAR2INDEX (year); chtype oldmarker = getCDKCalendarMarker (calendar, day, month, year); /* Check to see if a marker has not already been set. */ if (oldmarker != 0) { CALENDAR_CELL (calendar, day, month, yearIndex) = oldmarker | A_BLINK; } else { CALENDAR_CELL (calendar, day, month, yearIndex) = marker; } } chtype getCDKCalendarMarker (CDKCALENDAR *calendar, int day, int month, int year) { chtype result = 0; year = YEAR2INDEX (year); if (calendar->marker != 0) result = CALENDAR_CELL (calendar, day, month, year); return result; } /* * This sets a marker on the calendar. */ void removeCDKCalendarMarker (CDKCALENDAR *calendar, int day, int month, int year) { int yearIndex = YEAR2INDEX (year); CALENDAR_CELL (calendar, day, month, yearIndex) = 0; } /* * This function sets the month name. */ void setCDKCalendarMonthsNames (CDKCALENDAR *calendar, CDK_CSTRING2 months) { int x; for (x = 1; x < MAX_MONTHS; x++) { freeChar (calendar->MonthName[x]); calendar->MonthName[x] = copyChar (months[x]); } } /* * This function sets the day's name. */ void setCDKCalendarDaysNames (CDKCALENDAR *calendar, const char *days) { freeChar (calendar->DayName); calendar->DayName = copyChar (days); } /* * This makes sure that the dates provided exist. */ static void verifyCalendarDate (CDKCALENDAR *calendar) { int monthLength; /* Make sure the given year is not less than 1900. */ if (calendar->year < 1900) { calendar->year = 1900; } /* Make sure the month is within range. */ if (calendar->month > 12) { calendar->month = 12; } if (calendar->month < 1) { calendar->month = 1; } /* Make sure the day given is within range of the month. */ monthLength = getMonthLength (calendar->year, calendar->month); if (calendar->day < 1) { calendar->day = 1; } if (calendar->day > monthLength) { calendar->day = monthLength; } } /* * This returns what day of the week the month starts on. */ static int getMonthStartWeekday (int year, int month) { struct tm Date; /* *INDENT-EQLS* Set the tm structure correctly. */ Date.tm_sec = 0; Date.tm_min = 0; Date.tm_hour = 10; Date.tm_mday = 1; Date.tm_mon = month - 1; Date.tm_year = YEAR2INDEX (year); Date.tm_isdst = 1; /* Call the mktime function to fill in the holes. */ if (mktime (&Date) == (time_t) - 1) { return 0; } return Date.tm_wday; } /* * This function returns a 1 if it's a leap year and 0 if it's not. */ static int isLeapYear (int year) { int result = 0; if ((year % 4) == 0) { if ((year % 100) == 0) { if ((year % 400) == 0) { result = 1; } } else { result = 1; } } return result; } /* * This increments the current day by the given value. */ static void incrementCalendarDay (CDKCALENDAR *calendar, int adjust) { int monthLength = getMonthLength (calendar->year, calendar->month); /* Make sure we adjust the day correctly. */ if (adjust + calendar->day > monthLength) { /* Have to increment the month by one. */ calendar->day = calendar->day + adjust - monthLength; incrementCalendarMonth (calendar, 1); } else { calendar->day += adjust; drawCDKCalendarField (calendar); } } /* * This decrments the current day by the given value. */ static void decrementCalendarDay (CDKCALENDAR *calendar, int adjust) { /* Make sure we adjust the day correctly. */ if (calendar->day - adjust < 1) { int monthLength; /* Set the day according to the length of the month. */ if (calendar->month == 1) { /* Make sure we aren't going past the year limit. */ if (calendar->year == 1900) { const char *mesg[] = { "Error", "Can not go past the year 1900" }; Beep (); popupLabel (ScreenOf (calendar), (CDK_CSTRING2)mesg, 2); return; } monthLength = getMonthLength (calendar->year - 1, 12); } else { monthLength = getMonthLength (calendar->year, calendar->month - 1); } calendar->day = monthLength - (adjust - calendar->day); /* Have to decrement the month by one. */ decrementCalendarMonth (calendar, 1); } else { calendar->day -= adjust; drawCDKCalendarField (calendar); } } /* * This increments the current month by the given value. */ static void incrementCalendarMonth (CDKCALENDAR *calendar, int adjust) { int monthLength; /* Are we at the end of the year. */ if (calendar->month + adjust > 12) { calendar->month = (calendar->month + adjust) - 12; calendar->year++; } else { calendar->month += adjust; } /* Get the length of the current month. */ monthLength = getMonthLength (calendar->year, calendar->month); if (calendar->day > monthLength) { calendar->day = monthLength; } /* Get the start of the current month. */ calendar->weekDay = getMonthStartWeekday (calendar->year, calendar->month); /* Redraw the calendar. */ eraseCDKCalendar (calendar); drawCDKCalendar (calendar, ObjOf (calendar)->box); } /* * This decrements the current month by the given value. */ static void decrementCalendarMonth (CDKCALENDAR *calendar, int adjust) { int monthLength; /* Are we at the end of the year. */ if (calendar->month <= adjust) { if (calendar->year == 1900) { const char *mesg[] = { "Error", "Can not go past the year 1900" }; Beep (); popupLabel (ScreenOf (calendar), (CDK_CSTRING2)mesg, 2); return; } else { calendar->month = 13 - adjust; calendar->year--; } } else { calendar->month -= adjust; } /* Get the length of the current month. */ monthLength = getMonthLength (calendar->year, calendar->month); if (calendar->day > monthLength) { calendar->day = monthLength; } /* Get the start of the current month. */ calendar->weekDay = getMonthStartWeekday (calendar->year, calendar->month); /* Redraw the calendar. */ eraseCDKCalendar (calendar); drawCDKCalendar (calendar, ObjOf (calendar)->box); } /* * This increments the current year by the given value. */ static void incrementCalendarYear (CDKCALENDAR *calendar, int adjust) { /* Increment the year. */ calendar->year += adjust; /* If we are in Feb make sure we don't trip into voidness. */ if (calendar->month == 2) { int monthLength = getMonthLength (calendar->year, calendar->month); if (calendar->day > monthLength) { calendar->day = monthLength; } } /* Get the start of the current month. */ calendar->weekDay = getMonthStartWeekday (calendar->year, calendar->month); /* Redraw the calendar. */ eraseCDKCalendar (calendar); drawCDKCalendar (calendar, ObjOf (calendar)->box); } /* * This decrements the current year by the given value. */ static void decrementCalendarYear (CDKCALENDAR *calendar, int adjust) { /* Make sure we don't go out of bounds. */ if (calendar->year - adjust < 1900) { const char *mesg[] = { "Error", "Can not go past the year 1900" }; Beep (); popupLabel (ScreenOf (calendar), (CDK_CSTRING2)mesg, 2); return; } /* Decrement the year. */ calendar->year -= adjust; /* If we are in Feb make sure we don't trip into voidness. */ if (calendar->month == 2) { int monthLength = getMonthLength (calendar->year, calendar->month); if (calendar->day > monthLength) { calendar->day = monthLength; } } /* Get the start of the current month. */ calendar->weekDay = getMonthStartWeekday (calendar->year, calendar->month); /* Redraw the calendar. */ eraseCDKCalendar (calendar); drawCDKCalendar (calendar, ObjOf (calendar)->box); } /* * This returns the length of the current month. */ static int getMonthLength (int year, int month) { int monthLength = daysOfTheMonth[month]; if (month == 2) { monthLength += isLeapYear (year); } return monthLength; } /* * This returns what day of the week the month starts on. */ static time_t getCurrentTime (CDKCALENDAR *calendar) { struct tm Date, *dateInfo; time_t clck; /* Determine the current time and determine if we are in DST. */ time (&clck); dateInfo = gmtime (&clck); /* *INDENT-EQLS* Set the tm structure correctly. */ Date.tm_sec = 0; Date.tm_min = 0; Date.tm_hour = 0; Date.tm_mday = calendar->day; Date.tm_mon = calendar->month - 1; Date.tm_year = YEAR2INDEX (calendar->year); Date.tm_isdst = dateInfo->tm_isdst; /* Call the mktime function to fill in the holes. */ return mktime (&Date); } static void _focusCDKCalendar (CDKOBJS *object) { CDKCALENDAR *widget = (CDKCALENDAR *)object; drawCDKFScale (widget, ObjOf (widget)->box); } static void _unfocusCDKCalendar (CDKOBJS *object) { CDKCALENDAR *widget = (CDKCALENDAR *)object; drawCDKFScale (widget, ObjOf (widget)->box); } dummyRefreshData (Calendar) dummySaveData (Calendar)