This is Event.m in view mode; [Download] [Up]
//
// Event.m
// Copyright (c) 1988, 1989, 1990 by Jiro Nakamura
// All rights reserved
//
// Implementation definition of class Event. Event handles
// the database management of Cassandra.
//
// RCS Information
// Revision Number-> $Revision: 2.11 $
// Last Revised-> $Date: 91/11/01 17:24:00 $
//
static char rcsid[] = "$Id: Event.m,v 2.11 91/11/01 17:24:00 jiro Exp Locker: jiro $";
#import "Event.h"
#import <objc/objc.h>
#import <strings.h>
#import <appkit/Panel.h> /* for NXRunAlertPanel */
#import "cass.h"
#import "calendar.h"
#import "Global.h"
#import "misc.h"
#import <sys/types.h>
#import <sys/stat.h>
// Defining DEBUG for Event can sometimes get very screen messy
// since Cassandra uses it so often
#ifdef DEBUG
#undef DEBUG
#define DEBUG2
#endif
#define VERSION_15 1
#define EVENT_VERSION 1
int fgeti( int *i , FILE *fp)
{
char buffer[10];
if( fgets(buffer, 10, fp) == NULL || strlen( buffer ) < 1)
{
*i = 0;
return -1;
}
*i = atoi(buffer);
return 0;
}
@implementation Event
+ newAt:(const char*) eFile
{
self = [super new];
[self initOurStuff:eFile];
return self;
}
- initOurStuff: (const char *) eFile // used to set our-own default values
{
strcpy(eventFile,eFile);
eventType = 0;
priority = 50;
destroy = snoozeNo = snoozeInt = 0;
anniversary = annvSpecial = 0;
present = next = previous = 0;
strcpy(alarmSound, ALARMSOUND);
strcpy(msg,"empty");
return self;
}
+ new
{
fprintf(stderr,"This (+new for Event) should never be called!\n");
fprintf(stderr,"%s\n", rcsid); // dumb reference to rcsid, so
// we avoid a compiler warning.
self = [super new];
return self;
}
- free
{
#ifdef DEBUG
fprintf(stderr,"Event.m:Free ->Closing event!\n");
#endif
[super free];
return nil;
}
//
//
// Messages that affect how the file is stored on disk
//
//
- default: sender
{
present = 0;
previous = next = -1;
destroy = 1;
anniversary = annvSpecial = snoozeInt = snoozeNo = priority = 0;
ts.tm_sec = ts.tm_min = ts.tm_hour = 0;
ts.tm_mday = ts.tm_mon = ts.tm_year = 0;
ts.tm_wday = ts.tm_yday = ts.tm_isdst = 0;
alarmAction = playSound;
strcpy(msg, "");
strcpy(alarmSound,[global alarmSound]);
return self;
}
- readEvent: (EFileLink) here /* read itself from the event file */
{
FILE * source;
static char errormsg[128], buffer[255];
char *tp; // temporary pointer
struct stat statBuf;
int tmp;
#ifdef DEBUG
fprintf(stderr, "------------------------\n"
"[Event readEvent: %d]\n",here);
#endif
if( here < 0)
{
NXRunAlertPanel("File Seek Error",
"Cannot seek to a negative number.",
"OK",NULL,NULL);
strcpy(msg, "Illegal event/link value....");
return nil;
}
/* Let's first check to make sure we aren't reading an empty file */
stat( eventFile, &statBuf);
if( statBuf.st_size < 100) // It can not be this short
{
strcpy(msg, CASSANDRAVERSION);
next = previous = 0;
present = here;
[self writeEvent: here];
fprintf(stderr, "%s: Event list not initialized. "
"Initializing....\n",
PROGNAME);
return nil;
}
sprintf(errormsg, "Error occured while trying to read event file %s",
eventFile);
source = fileOpen(eventFile, "r+",errormsg);
sprintf(errormsg, "An fatal error occured when we were trying "
"to seek to event number %d for reading event "
"file %s.\n This program has crashed.",
here, eventFile);
if( fileSeek(source, here, errormsg) == NULL)
{
next = previous = -1;
present = here;
return nil;
}
fgeti(&present, source);
if( present != here)
{
fprintf(stderr,
"%s: File header gives %d instead of %d.\n",
PROGNAME , present, here);
fprintf(stderr,
"%s: We've most probably run out off the end of %s.\n",
PROGNAME, [global eventFile]);
next = previous = -1;
present = here;
fclose(source);
return nil;
}
else
{
fgeti(&previous, source);
fgeti(&next, source);
}
fgeti( &tmp, source);
version = tmp / 100;
eventType = tmp % 100;
fgets( buffer, 10, source);
fgeti( &priority, source);
switch( version)
{
case VERSION_15:
fgeti( &annvSpecial, source);
fgeti( &anniversary, source);
break;
case 0:
default:
fgeti( &destroy, source);
fgeti( &anniversary, source);
break;
}
#ifdef DEBUG2
fprintf(stderr, "%s Event: Version = %d, ",
PROGNAME, version);
fprintf(stderr, "Anniv. = %03d, ", anniversary);
fprintf(stderr, "AnnivSpecial = %03d\n", annvSpecial);
#endif
fgeti( &snoozeNo, source);
fgeti( &snoozeInt, source);
fgets( buffer, 10, source);
fgets( buffer, 10, source);
fgeti( &ts.tm_sec, source);
fgeti( &ts.tm_min, source);
fgeti( &ts.tm_hour, source);
fgeti( &ts.tm_mday, source);
fgeti( &ts.tm_mon, source);
fgeti( &ts.tm_year, source);
switch( version)
{
case VERSION_15:
fgeti( &duration, source);
fgeti( &tmp, source);
alarmAction = tmp;
fgeti( &ts.tm_isdst, source);
break;
case 0:
default:
fgeti( &ts.tm_wday, source);
fgeti( &ts.tm_yday, source);
fgeti( &ts.tm_isdst, source);
break;
}
fgets( alarmSound, 100, source); // We gotta strip the final
tp = rindex( alarmSound, '\n'); // newline and replace it with
if( tp != NULL) // a NULL character.
*tp = '\0';
fgets( buffer, 10, source);
fgets( buffer, 10, source);
fgets( buffer, 10, source);
fgets( buffer, 10, source);
fgets(msg,MESSAGE_SIZE,source);
ts.tm_wday = wday(ts.tm_mday, ts.tm_mon+1, 1900+ts.tm_year);
ts.tm_yday = yday(ts.tm_mday, ts.tm_mon+1, ts.tm_year+1900);
fixTmStructure( &ts);
switch( version)
{
case VERSION_15:
break;
default:
case 0:
switch( alarmSound[0] )
{
case '-': // don't play alarm
strcpy(buffer, alarmSound);
strcpy(alarmSound, buffer+1);
alarmAction = nothing;
break;
case '?':
strcpy(buffer, alarmSound);
strcpy(alarmSound, buffer+1);
alarmAction = playAndDeleteSound;;
break;
case '!':
strcpy(buffer, alarmSound);
strcpy(alarmSound, buffer+1);
alarmAction = runCommand;
break;
}
break;
}
if( msg[0] == ';')
{
char buf[MESSAGE_SIZE];
strcpy(buf, msg);
strcpy(msg, buf+1);
showMessage = FALSE;
}
else
showMessage = TRUE;
fclose(source);
return self;
}
- firstEvent
{
#ifdef DEBUG
fprintf(stderr,"Reading in the first event.\n");
#endif
[self readEvent : 0];
if( [self next] == 0)
return self;
[self readEvent : [self next]];
return self;
}
- writeEvent: (EFileLink) here
/* write itself into the event file using present as its index */
{
FILE *source;
char errormsg[256], bufAlarm[256], bufMessage[256];
if( here < 0)
{
NXRunAlertPanel( "Write Error",
"We can't write to a negative event number.",
"OK",NULL,NULL);
return nil;
}
#ifdef DEBUG
fprintf(stderr, "------------------------\n"
"[Event writeEvent: %d]: Opening event with "
"<%s>!\n",here, eventFile);
#endif
sprintf(errormsg, "Fatal error when trying to write to event file %s",
eventFile);
source = fileOpen(eventFile, "r+",errormsg);
sprintf(errormsg, "%s: An fatal error occured when we were trying to "
"seek to event number %d for writing in event file %s.\n"
" This program has crashed.", PROGNAME, here, eventFile);
fileSeek(source, here, errormsg);
present = here;
if( ts.tm_year > 1900)
ts.tm_year -= 1900;
strcpy(bufAlarm, alarmSound);
if( showMessage == FALSE)
{
strcpy(bufMessage, ";");
strcat(bufMessage, msg);
}
else
strcpy(bufMessage, msg);
#ifdef DEBUG2
fprintf(stderr, "%s Event: wAnniversary = %d, ",
PROGNAME, anniversary);
fprintf(stderr, "wAnniversarySpecial = %d\n", annvSpecial);
#endif
if(fprintf( source,
"%d\n%d\n%d\n"
"%d\n\n"
"%d\n%d\n%d\n"
"%d\n%d\n"
"\n\n"
"%d\n%d\n%d\n"
"%d\n%d\n%d\n"
"%d\n%d\n%d\n"
"%s\n\n"
"\n\n\n"
"%s\n",
present, previous, next,
EVENT_VERSION * 100 + eventType,
priority, annvSpecial, anniversary,
snoozeNo, snoozeInt,
ts.tm_sec, ts.tm_min, ts.tm_hour,
ts.tm_mday, ts.tm_mon, ts.tm_year,
duration, alarmAction, ts.tm_isdst,
bufAlarm, bufMessage) == -1)
{
fprintf(stderr, "%s: Event.m: Error occured writing file.",
PROGNAME);
strcpy(msg, "Error occured in writing out Elink number.\n\n");
fclose(source);
return nil;
}
#ifdef DEBUG
fprintf(stderr, "%s: Wrote out Efilelink.\n Here=%d,"
"Previous = %d, Next=%d\n", PROGNAME,
here, previous, next);
fprintf(stderr, "%s: Date: time = %d:%d, day= %d, "
"month = %d, year = %d.\n\n",PROGNAME,
ts.tm_hour, ts.tm_min, ts.tm_mday, ts.tm_mon,
ts.tm_year);
fprintf(stderr,"%s: AlarmSound =%s\n", PROGNAME, bufAlarm);
#endif
fclose(source);
return self;
}
- (EFileLink) insertEvent
{
return [self insertEventFrom : 1];
}
/* insert itself into the file with current day as index */
/* and starting from <here> in searching for a open deleted space */
- (EFileLink) insertEventFrom : (EFileLink) here
{
id event, step;
int loop;
// First things first, we must check the format of our time structure
// since we have given other functions full freedom to scew it up
fixTmStructure( &ts);
event = [Event newAt:eventFile];
step = [Event newAt:eventFile];
[event readEvent:0];
for( [event readEvent: [event next]];
[event present] != 0 && timeCompare([event time], &ts) < 0;
[event readEvent:[event next]])
{
#ifdef DEBUG
fprintf(stderr, "From %d looping onto %d\n",
[event present],[event next]);
#endif
}
if( timeCompare([event time], &ts) == 0 )
{
if( NXRunAlertPanel("Scheduling Conflict?",
"You have another "
"scheduled event at that time. Should I insert this "
"event anyway?", "Insert anyway", "Cancel it",
NULL) == 0 )
[event free];
[step free];
return 0;
}
#ifdef DEBUG
fprintf(stderr, "inserting between %d <- event -> %d.\n",
[event previous], [event present]);
#endif
previous = [event previous];
next = [event present];
[step setNext: 0];
for( loop = here; !([step next] == -1 && [step previous] == -1); [step readEvent: loop++])
{
#ifdef DEBUG
fprintf(stderr, "reading at %d.\n",loop);
#endif
}
present = [step present];
[self writeEvent: present];
[step readEvent: previous];
[step setNext : present];
[step writeEvent:previous];
[step readEvent: next];
[step setPrevious : present];
[step writeEvent:next];
[step free];
[event free];
#ifdef DEBUG
fprintf(stderr,"successfully inserted %d <- %d -> %d\n\n",[self previous],[self present], [self next]);
#endif
return( [self present] );
}
/* delete itself from the file with present as index */
- deleteEvent : (EFileLink) here
{
id previousEvent, nextEvent;
#ifdef DEBUG
fprintf(stderr, "Deleting <%d>\n\n",here);
#endif
if( here <= 0)
{
NXRunAlertPanel(NULL,"You cannot delete link 0 or below. OK?",
"Shucks...",NULL,NULL);
fprintf(stderr,"Can't delete the header. Here = %d.\n\n",
here);
return nil;
}
previousEvent= [Event newAt: eventFile];
nextEvent = [Event newAt:eventFile];
[previousEvent readEvent :here];
if( ( [previousEvent previous] == -1 ) ||
( [previousEvent next] == -1 ) )
{
/* link was already deleted, so we can't delete it..... */
strcpy(msg, "Can't delete link because it's already been "
"deleted!?!\n\n");
return nil;
}
/* Set the previous_link of the next link */
/* to the one of the previous one */
[nextEvent readEvent :[previousEvent next]];
[nextEvent setPrevious : [previousEvent previous]];
[nextEvent writeEvent :[previousEvent next]];
/* do the same confusing spiel for previous */
[nextEvent readEvent :[previousEvent previous] ];
[nextEvent setNext : [previousEvent next]];
[nextEvent writeEvent :[previousEvent previous] ];
/* cancel out the header to finally kill it */
/* and write it out */
[previousEvent setNext : -1];
[previousEvent setPrevious :-1];
[previousEvent writeEvent :here];
#ifdef DEBUG
fprintf(stderr, "Record %d successfully deleted.\n\n",
here);
#endif
[previousEvent free];
[nextEvent free];
return self;
}
/* delete if it is not an anniversary event, update otherwise */
- (int) murderEvent : (EFileLink) here
{
Event *event;
#ifdef DEBUG
fprintf(stderr,"Arrggh! Help! I'm getting murdered! "
"(says Event <%d>)\n\n",
here);
#endif
event = [Event newAt :eventFile];
[event readEvent : here]; // Read the event in
[event deleteEvent : here]; // Delete the event
if( (int) ([event anniversary]/100) == 0) // No anniversary
return -1;
[event setTime: fixAnniversary( [event time], [event anniversary],
[event annvSpecial])];
// Fix the next event time and reinsert it
// Use the same EFilelink space that we deleted, this saves
// us time and maybe some confusion
return( [event insertEventFrom:here] );
}
- setMday : (int) x { ts.tm_mday = x; return self; }
- setMon: (int) x { ts.tm_mon = x; return self; }
- setYear: (int) x { ts.tm_year = x; return self; }
- setHour: (int) x { ts.tm_hour = x; return self; }
- setMin: (int) x { ts.tm_min = x; return self; }
- setSec: (int) x { ts.tm_sec = x; return self; }
- setDestroy : (int) dst { destroy = dst; return self; }
- setAnniversary : (int) anv { anniversary = anv; return self; }
- setAnnvSpecial : (int) anvS { annvSpecial = anvS; return self; }
- setSnoozeNo : (int) sn { snoozeNo = sn; return self; }
- setSnoozeInt : (int) si { snoozeInt = si; return self; }
- setPriority : (int) si { priority = si; return self; }
- setAlarmSound : (const char *) aS { strcpy(alarmSound,aS); return self; }
- setShowMessage: (BOOL) aFlag { showMessage = aFlag; return self; }
- setMessage : (const char *) message { strcpy( msg, message); return self; }
- setWday : (int) wd { ts.tm_wday = wd; return self; }
- setYday : (int) yd { ts.tm_yday = yd; return self; }
- setPresent : (EFileLink) apresent { present = apresent; return self; }
- setPrevious : (EFileLink) aprevious { previous =aprevious; return self; }
- setNext : (EFileLink) anext { next = anext; return self; }
- setTime : (struct tm *) time { ts = *time; return self; }
- setPlayAlarm: (BOOL) aFlag { alarmAction = playSound; return self; }
- setMailPerson:(BOOL) aFlag { alarmAction = mailPerson; return self; }
- setRunCommand: (BOOL) aFlag { alarmAction = runCommand; return self; }
- setDeleteSound: (BOOL) aFlag { alarmAction = playAndDeleteSound;
return self; }
- setAlarmAction: (int) aa { alarmAction = aa; return self; }
- (EFileLink) present { return present; }
- (EFileLink) previous { return previous; }
- (EFileLink) next { return next; }
- (char *) message { return msg; }
- (const char *) alarmSound { return alarmSound; }
- (BOOL) deleteSound { return alarmAction == playAndDeleteSound; }
- (BOOL) playAlarm { return (alarmAction == playAndDeleteSound ||
alarmAction == playSound) ; }
- (BOOL) runCommand { return alarmAction == runCommand; }
- (BOOL) mailPerson { return alarmAction == mailPerson; }
- (BOOL) showMessage { return showMessage; }
- (int) alarmAction { return alarmAction; }
- (int) anniversary { return anniversary; }
- (int) annvSpecial { return annvSpecial; }
- (int) destroy { return destroy; }
- (int) hour { return (ts.tm_hour); }
- (int) mday; { return( ts.tm_mday); }
- (int) min { return(ts.tm_min); }
- (int) mon { return (ts.tm_mon); }
- (int) priority { return priority; }
- (int) sec { return(ts.tm_sec); }
- (int) snoozeInt { return snoozeInt; }
- (int) snoozeNo { return snoozeNo; }
- (int) wday { return ts.tm_wday; }
- (int) yday { return ts.tm_yday; }
- (int) year { return (ts.tm_year); }
- (struct tm *) time { return &ts; }
@end
struct tm *fixAnniversary( struct tm *time, int mode, int sub)
{
#ifdef DEBUG
fprintf(stderr,"Fixing weekly special: %s, %d, %d\n",
ascMyTime(time, YES, NO),
mode, sub);
#endif
switch( (int) mode / 100)
{
/* Don't worry about overflows as we add intervals to */
/* our dates, insertEvent is smart enough to handle it */
case 0:
return time; /* No anniversary */
case 1: /* If it is a day anniversary */
time->tm_mday+= (mode - 100);
break;
case 2: /* Weekly anniversary */
time -> tm_mday += ((mode - 200) * 7 );
break;
case 3: /* Monthly anniversary */
time-> tm_mon += (mode - 300);
break;
case 4: /* Yearly anniversary */
time -> tm_year += (mode - 400);
break;
case 5: /* Special weekly */
default:
fprintf(stderr,
"%s: I do not recognize "
"anniversary event: %d.\n",
PROGNAME,
mode);
return time;
}
fixTmStructure( time);
return time;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.