home *** CD-ROM | disk | FTP | other *** search
- /* Event handling routines for Reminder */
-
- /* $Id: Events.c,v 1.14 1993/04/18 21:54:08 Matti_Rintala Exp $ */
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <time.h>
-
- #include <exec/types.h>
- #include <exec/lists.h>
-
- #include <exec/exec.h>
- #include <libraries/reqtools.h>
-
- #ifdef __SASC
- #include <proto/exec.h>
- #include <proto/reqtools.h>
- #endif
-
- #ifdef _DCC
- #include <clib/exec_protos.h>
- #include <clib/reqtools_protos.h>
- #endif
-
- #include "Globals.h"
- #include "CalcDate.h"
- #include "Events.h"
-
- static int checkdate(void);
- static void makeentry(char *entry, short day, short month, short year,
- short wday, const char *text);
-
- static int AddEventlist(struct EventNode *newevent);
-
- /* Eventlist holds the event database, initially empty */
- static struct List Eventlist = {
- (struct Node *)&Eventlist.lh_Tail,
- NULL,
- (struct Node *)&Eventlist.lh_Head
- };
-
- static time_t today; /* Date of current day (initialized in LoadEvents) */
-
- static void DeleteEventlist(void);
-
- /* InitEvents initializes the events database */
- struct List *InitEvents(void) {
-
- /* Only ensure that Eventlist is deleted on exit */
- atexit(DeleteEventlist);
-
- /* Return pointer to Eventlist */
- return &Eventlist;
- }
-
- static void DeleteEventlist(void) {
-
- struct EventNode *node;
-
- while ((node = (struct EventNode *)RemTail(&Eventlist)) != NULL)
- free(node);
-
- eventno = 0; /* There are no events now */
-
- }
-
- /* NewEvent makes a new, clear event */
- void NewEvent(void) {
-
- /* Ask for confirmation if event in gadgets has been edited */
- if (edited) {
- if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
- "_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
- RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
- TAG_END)) {
- /* If user does not want to abandon changes */
- return;
- }
- }
-
- /* Initialize all variables */
- day = month = year = wday = before = after = 0;
- autodelete = FALSE; grouped = FALSE;
- swdaytxt = NULL;
- mode = AREXXNMODE;
- text[0] = arexxport[0] = arexxcom[0] = '\0';
- event = ~0; /* No event selected */
-
- edited = FALSE; /* Nothing edited now */
- }
-
- /* AddEvent adds a new event to list */
- struct List *AddEvent(void) {
-
- struct EventNode *newevent;
-
- /* Check that the date is correct */
- if (!checkdate()) {
- /* If not, tell the user that */
- rtEZRequestTags("Cannot add event,\ninvalid date.", "OK", NULL, NULL,
- RT_LockWindow, (Tag)TRUE, TAG_END);
- /* Return with unchanged list */
- return &Eventlist;
- }
-
- /* Make a new list node */
- if ((newevent = malloc(sizeof(struct EventNode))) == NULL) {
- rtEZRequestTags("Cannot get memory\nfor new event!", "OK", NULL, NULL,
- RT_LockWindow, (Tag)TRUE, TAG_END);
- return &Eventlist;
- }
-
- /* Generate entry text */
- makeentry(newevent->entry, day, month, year, wday, text);
- newevent->node.ln_Name = newevent->entry;
-
- /* Set Acknowledgement date to 1-Jan-1990 */
- newevent->aday = 1; newevent->amonth = 1; newevent->ayear = 1990;
-
- /* Set other fields from globals */
- newevent->day = day; newevent->month = month; newevent->year = year;
- newevent->wday = wday;
- newevent->before = before; newevent->after = after;
- newevent->autodelete = autodelete;
- strncpy(newevent->text, text, TEXTLEN);
- strncpy(newevent->arexxcom, arexxcom, AREXXCOMLEN);
- strncpy(newevent->arexxport, arexxport, AREXXPORTLEN);
- newevent->mode = mode | (grouped ? GROUPEDMASK : 0);
-
- /* Add new entry */
- event = AddEventlist(newevent);
-
- changed = 1; /* Database has changed */
- eventno++; /* One more event now exists */
-
- edited = FALSE; /* Nothing has been edited now */
-
- /* Return pointer to list */
- return &Eventlist;
- }
-
- /* Getevent gets data from selected event */
- int GetEvent(void) {
-
- struct EventNode *node;
- int i;
-
- /* Ask for confirmation if event in gadgets has been edited */
- if (edited) {
- if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
- "_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
- RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
- TAG_END)) {
- /* If user does not want to abandon changes */
- return FALSE;
- }
- }
-
- /* First find the appropriate node */
- node = (struct EventNode *)Eventlist.lh_Head;
- for (i = 0 ; i < event; i++)
- node = (struct EventNode *)node->node.ln_Succ;
-
- /* Then get the appropriate data */
- wday = node->wday; day = node->day; month = node->month; year = node->year;
- before = node->before; after = node->after;
- autodelete = node->autodelete;
- strncpy(text, node->text, TEXTLEN);
- strncpy(arexxcom, node->arexxcom, AREXXCOMLEN);
- strncpy(arexxport, node->arexxport, AREXXPORTLEN);
- mode = node->mode & ~GROUPEDMASK;
- grouped = ((node->mode & GROUPEDMASK) != 0);
-
- edited = FALSE; /* Nothing has been edited */
-
- return TRUE;
- }
-
- /* UpdateEvent updates an existing event */
- struct List *UpdateEvent(void) {
-
- struct EventNode *node;
- int i;
-
- /* First find the appropriate node */
- node = (struct EventNode *)Eventlist.lh_Head;
- for (i = 0 ; i < event; i++)
- node = (struct EventNode *)node->node.ln_Succ;
-
- /* Remove the node from EventList */
- Remove((struct Node *)node);
- eventno--;
-
- /* Generate entry text */
- makeentry(node->entry, day, month, year, wday, text);
- node->node.ln_Name = node->entry;
-
- /* Set Acknowledgement date to 1-Jan-1990 */
- node->aday = 1; node->amonth = 1; node->ayear = 1990;
-
- /* Set other fields from globals */
- node->day = day; node->month = month; node->year = year;
- node->wday = wday;
- node->before = before; node->after = after;
- node->autodelete = autodelete;
- strncpy(node->text, text, TEXTLEN);
- strncpy(node->arexxcom, arexxcom, AREXXCOMLEN);
- strncpy(node->arexxport, arexxport, AREXXPORTLEN);
- node->mode = mode | (grouped ? GROUPEDMASK : 0);
-
- /* Add event back to list */
- event = AddEventlist(node);
- eventno++;
-
- changed = 1; /* Database has changed */
-
- edited = FALSE; /* Nothing has been edited */
-
- return &Eventlist;
- }
-
- /* RemoveEvent removes an existing event */
- struct List *RemoveEvent(void) {
-
- struct EventNode *node;
- int i;
-
- /* First find the appropriate node */
- node = (struct EventNode *)Eventlist.lh_Head;
- for (i = 0 ; i < event; i++)
- node = (struct EventNode *)node->node.ln_Succ;
-
- /* Remove the node */
- Remove((struct Node *)node);
-
- /* Free the memory */
- free(node);
-
- changed = 1; /* Database has changed */
- eventno--; /* Now there are one less events */
-
- return &Eventlist;
- }
-
- /* LoadEvents loads the event database from file. It returns TRUE if it fails. */
- int LoadEvents(const char *filename) {
-
- FILE *infile;
- struct EventNode *node;
-
- /* Get todays date */
- gettoday(&today);
-
- /* Try to open the file */
- if ((infile = fopen(filename, "rb")) == NULL)
- return TRUE;
-
- /* Skip the timestamp */
- fseek(infile, sizeof(time_t), SEEK_SET);
-
- /* Read events from file */
- while (TRUE) {
- /* Get memory for event */
- if ((node = malloc(sizeof(struct EventNode))) == NULL) {
- rtEZRequestTags("Insufficient memory!", "OK", NULL, NULL,
- RT_LockWindow, (Tag)TRUE, TAG_END);
- break;
- }
-
- /* Read event part of it from file */
- while (TRUE) {
- fread(SAVEADDR(node), 1, SAVELEN(node), infile);
- /* If end-of-file occurred, stop looping */
- if (feof(infile))
- break;
- /* Stop looping also, if event is not deleted */
- if (node->mode != DELETEDMODE)
- break;
- else
- changed = 2; /* Deleted entrys should be swept away */
- }
- /* If end-of-file occurred, stop looping */
- if (feof(infile))
- break;
-
- /* Check mode (for database files generated with Reminder V1.00) */
- if ((node->mode & ~GROUPEDMASK) != AREXXCMODE &&
- (node->mode & ~GROUPEDMASK) != AREXXSMODE &&
- (node->mode & ~GROUPEDMASK) != AREXXNMODE) {
- /* Invalid mode, use No ARexx, no grouping and empty Port and Com fields */
- node->mode = AREXXNMODE;
- node->arexxcom[0] = node->arexxport[0] = '\0';
- }
-
- /* Calculate entry text */
- makeentry(node->entry, node->day, node->month, node->year, node->wday,
- node->text);
-
- /* Set name of event and add it to Eventlist */
- node->node.ln_Name = node->entry;
- AddEventlist(node);
- eventno++; /* One more event */
- }
-
- /* Free the extra node left (freeing NULL is allowed) */
- free(node);
-
- fclose(infile);
-
- return FALSE;
- }
-
- /* SaveEvents saves event database to file. It returns TRUE if it fails. */
- int SaveEvents(const char *filename) {
-
- FILE *outfile;
- struct EventNode *node;
- BOOL success = TRUE;
- struct tm tm_stamp = {0, 0, 0, 1, 0, 90, 0, 0, 0};
- time_t stamp;
-
- /* First try to open the file */
- if ((outfile = fopen(filename, "wb")) == NULL)
- return 1;
-
- /* Write timestamp for 1.1.1990 */
- stamp = mktime(&tm_stamp);
- if (fwrite(&stamp, 1, sizeof(time_t), outfile) != sizeof(time_t)) {
- success = FALSE;
- }
- else {
- node = (struct EventNode *)Eventlist.lh_Head;
- for (; node->node.ln_Succ != NULL;
- node = (struct EventNode *)node->node.ln_Succ) {
- /* Write the node information to file */
- if (fwrite(SAVEADDR(node), 1, SAVELEN(node), outfile) != SAVELEN(node)) {
- /* If failed, abort */
- success = FALSE;
- break;
- }
- }
- }
-
- /* Close the file and exit */
- fclose(outfile);
-
- return !success;
- }
-
-
-
- static short monthlist[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
- /* checkdate checks that the date is valid */
- static int checkdate(void) {
-
- short testyear, testmonth;
- /* Check month */
- if (month > 12)
- return 0;
-
- /* If day is ANY, date is ok */
- if (day == 0)
- return 1;
-
- /* Get appropiate values for test variables */
- if (year == 0) testyear = 1996; /* Leap year */
- else testyear = year;
-
- if (month == 0) testmonth = 1; /* Month with 31 days */
- else testmonth = month;
-
- /* Check day */
- if (day > (monthlist[testmonth-1] + ((testmonth == 2 && testyear%4 == 0) ?
- ((testyear%400 == 0) ? 0 : 1) :
- 0)))
- return 0;
-
- return 1;
- }
-
- /* makeentry makes an appropriate entry line for Eventlist gadget */
- static void makeentry(char *entrystart, short day, short month, short year,
- short wday, const char *text) {
-
- char *entry = entrystart;
-
- /* Start with day of the week */
- /* If we have a non-repeating date with ANY weekday, show the weekday + colon */
- if (day != 0 && month != 0 && year != 0 && wday == 0) {
- strncpy(entry, wdayabbrv+4*weekday(day, month, year), 3);
- entry += 3;
- *entry++ = ':';
- }
- else {
- strncpy(entry, wdayabbrv+4*wday, 3);
- entry += 3; /* Skip the day */
- *entry++ = ' ';
- }
-
- /* If day is ANY, use **, otherwise the day number */
- if (day == 0) {
- *entry++ = '*';
- *entry++ = '*';
- }
- else {
- sprintf(entry, "%02d", day);
- entry += 2; /* Skip over the number */
- }
-
- *entry++ = '-';
- /* Then month name */
- strncpy(entry, monthabbrv+4*month, 3);
- entry += 3; /* Skip over month */
- *entry++ = '-';
-
- /* Then year */
- if (year == 0) {
- *entry++ = '*';
- *entry++ = '*';
- *entry++ = '*';
- *entry++ = '*';
- }
- else {
- sprintf(entry, "%4d", year);
- entry += 4; /* Skip over year */
- }
-
- *entry++ = ' ';
-
- /* Then copy rest with text */
- strncpy(entry, text, ENTRYLEN-(entry-entrystart));
- }
-
- /* AddEventlist finds the correct place for event and adds it to list.
- It returns the place of the event in the list */
- static int AddEventlist(struct EventNode *newevent) {
-
- int i;
- struct EventNode *node;
-
- /* Calculate next occurrence of event */
- makedate(&newevent->next_date, &today, newevent->day, newevent->month,
- newevent->year, newevent->wday);
-
- /* Find place for event, starting form the head of list */
- node = (struct EventNode *)Eventlist.lh_Head;
- for (i = 0; i < eventno; i++, node = (struct EventNode *)node->node.ln_Succ) {
- /* If event is earlier than this, add new event before it */
- if (newevent->next_date < node->next_date) {
- Insert(&Eventlist, (struct Node *)newevent, node->node.ln_Pred);
- return i; /* Return place of event */
- }
- }
-
- /* If we got this far, event must be added to the end of the list */
- AddTail(&Eventlist, (struct Node *)newevent);
- return eventno; /* Event is the last one */
- }
-
-