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.