This is AddEvent.m in view mode; [Download] [Up]
// // AddEvent.m // Copyright (c) 1989, 1990, 1991 by Jiro Nakamura // All rights reserved // // Handles the window that allows the user to add events. // Also is the superclass of EventEdit, which lets the user edit events // // by Jiro Nakamura (jiro@shaman.com) // // RCS Information // Revision Number-> $Revision: 2.15 $ // Last Revised-> $Date: 91/11/01 17:23:32 $ // static char rcsid[] = "$Id: AddEvent.m,v 2.15 91/11/01 17:23:32 jiro Exp Locker: jiro $"; #import "AddEvent.h" #import "Global.h" #import "Cassandra.h" #import "calendar.h" #import <libc.h> #import <strings.h> // for rindex() and strcpy() #import <sys/file.h> // for access() #import <appkit/Application.h> #import <appkit/Button.h> #import <appkit/Form.h> #import <appkit/Matrix.h> #import <appkit/Panel.h> // for NXRunAlertPanel #import <appkit/OpenPanel.h> // for OpenPanel #define RADIO_WEEK 0 #define RADIO_MON 1 #define RADIO_MDAY 2 #define RADIO_YEAR 3 #define RADIO_HOUR 4 #define RADIO_MIN 5 static char *frequencyChar[4] = {"day","week","month","year"}; static char *alarmExtensions[] = ALARMEXTENSIONS; @implementation AddEvent /* The main reason for the following method is just to avoid warnings * about rcsid being unreferenced... Garance/Jul 28/94 */ - (const char *) returnRcsid { return rcsid; } - open: sender { ev = [Event newAt: [global eventFile]]; [self resetDefaultValues : self]; return self; } - close { if( [self isDocEdited] && [self isVisible]) { #ifdef DEBUG fprintf(stderr,"Add/Edit Event window about to close." "Checking save.\n"); #endif if (NXRunAlertPanel("Changes not saved", "You have made changes to this window. " "Do you really want to throw them out?", "Dump them","Cancel",NULL) == 0 ) return self; } [self setDocEdited: FALSE]; [super close]; [ev free]; return self; } - startOver:sender { [self resetDefaultValues: self]; return self; } - resetDefaultValues:sender { static struct tm time; time = *timeNow(); [ev setTime: &time]; [ev setSec: 0]; [ev setSnoozeInt: 0]; [ev setSnoozeNo: 0]; [ev setPriority: 50]; [ev setDestroy: 1]; // Destroy not supported after v0.92 [ev setAnniversary: 0]; [ev setMessage: "Empty Message"]; [ev setAlarmSound: [global alarmSound]]; [ev setPlayAlarm: [global playAlarm]]; [ev setShowMessage: TRUE]; [self displayValues: sender]; [self displayValues: self]; [monthForm selectTextAt:0]; [dateRadioMatrix selectCellAt: 0: RADIO_MDAY]; return self; } - displayValues:sender { int temp, temp2; [self displayDate: self]; if( [ev priority] < 10) [priorityRadioMatrix selectCellAt: 0: 0]; else { if( [ev priority] <= 90) [priorityRadioMatrix selectCellAt: 0:1]; else [priorityRadioMatrix selectCellAt: 0:2]; } [messageForm setStringValue: [ev message] at:0]; [messageButton setState: [ev showMessage]]; [self message: self]; [alarmSoundForm setStringValue: [ev alarmSound] at:0]; switch( [ev alarmAction] ) { case 1: // playSound case 2: // playAndDeleteSound [alarmSoundRadioMatrix selectCellAt: 0 : 0]; break; case 3: // runCommand [alarmSoundRadioMatrix selectCellAt: 1 : 0]; break; case 0: // nothing default: [alarmSoundRadioMatrix selectCellAt: 2 : 0]; break; } [self sound: self]; if( [ev snoozeNo] > 0) { [snoozeIntForm setIntValue: [ev snoozeInt] at:0]; [snoozeNoForm setIntValue: [ev snoozeNo] at:0]; [snoozeButton setState: TRUE]; } else { [snoozeIntForm setIntValue: 5 at:0]; [snoozeNoForm setIntValue: 6 at:0]; [snoozeButton setState: FALSE]; } [self snooze: self]; temp = [ev anniversary] % 100; temp2 = [ev anniversary] / 100 - 1; if( temp2 <= 0) temp2 = 0; [anniversaryForm setIntValue: ((temp == 0) ? 1 : temp) at:0]; [anniversaryRadioMatrix selectCellAt: 0 : temp2]; [anniversaryButton setState: ( [ev anniversary] > 0)]; [self anniversary:self]; [self makeKeyAndOrderFront : self]; // The window is new [self setDocEdited: FALSE]; return self; } - displayDate: sender { int temp; char min[5]; extern const char *shortMonths[12]; if( [global militaryTime]) { [hourForm setIntValue: [ev hour]]; [amPmButton setEnabled: FALSE]; [amPmButton setState: AM]; } else { temp = [ev hour]; if( temp > 12 ) temp -= 12; if( temp == 0 ) temp = 12; [hourForm setIntValue: temp at:0]; [amPmButton setEnabled: TRUE]; if( [ev hour] >= 12) [amPmButton setState: PM]; else [amPmButton setState: AM]; } sprintf(min,"%02d",[ev min]); [minuteForm setStringValue: min at:0]; [dayForm setIntValue: [ev mday] at:0]; [monthForm setStringValue: shortMonths[([ev mon])] at: 0]; [yearForm setIntValue : ([ev year]+ 1900) at:0]; [self updateTestDate : [ev time]]; return self; } - dateUp: sender { struct tm *displayTime; if( (displayTime = [self getDate: self]) == NULL) return self; switch( [dateRadioMatrix selectedCol]) { case RADIO_WEEK: displayTime->tm_mday += 7; break; case RADIO_MON: displayTime->tm_mon ++; break; case RADIO_MDAY: displayTime->tm_mday ++; break; case RADIO_YEAR: displayTime->tm_year ++; break; case RADIO_HOUR: displayTime->tm_hour ++; break; case RADIO_MIN: displayTime->tm_min ++; break; } fixTmStructure( displayTime); [ev setTime: displayTime]; [self displayDate: self]; [self setDocEdited: TRUE]; return self; } - dateDown: sender { struct tm *displayTime; if( (displayTime = [self getDate: self]) == NULL) return self; switch( [dateRadioMatrix selectedCol]) { case RADIO_WEEK: displayTime->tm_mday -= 7; break; case RADIO_MON: displayTime->tm_mon --; break; case RADIO_MDAY: displayTime->tm_mday --; break; case RADIO_YEAR: displayTime->tm_year --; break; case RADIO_HOUR: displayTime->tm_hour --; break; case RADIO_MIN: displayTime->tm_min --; break; } fixTmStructure( displayTime); [ev setTime: displayTime]; [self displayDate: self]; [self setDocEdited: TRUE]; return self; } - anniversary:sender { BOOL aFlag; #ifdef DEBUG fprintf(stderr,"Anniversary button pressed. State = %d\n", [anniversaryButton state]); #endif aFlag = [anniversaryButton state]; [anniversaryRadioMatrix setEnabled: aFlag]; [anniversaryForm setEnabled: aFlag]; [everyTextField setEnabled: aFlag]; [anniversaryUpButton setEnabled: aFlag]; [anniversaryUpButton setIcon: (aFlag?RIGHTARROW:DISABLEDRIGHTARROW)]; [anniversaryDownButton setEnabled: aFlag]; [anniversaryDownButton setIcon: (aFlag?LEFTARROW:DISABLEDLEFTARROW)]; if( aFlag ) [anniversaryForm selectTextAt: 0]; [self anniversaryFinished: self]; return self; } - anniversaryUp: sender { [anniversaryForm setIntValue: ([anniversaryForm intValueAt:0] +1) at:0]; [self anniversaryFinished: self]; return self; } - anniversaryDown: sender { int temp; temp = [anniversaryForm intValueAt: 0] - 1; if( temp > 1) [anniversaryForm setIntValue: temp at:0]; else [anniversaryForm setIntValue: 1 at:0]; [self anniversaryFinished: self]; return self; } - snooze: sender { BOOL aFlag; // the state of the snooze button #ifdef DEBUG fprintf(stderr, "Snooze button pressed. State = %d\n", [snoozeButton state]); #endif aFlag = [snoozeButton state]; [snoozeNoForm setEnabled: aFlag]; [snoozeIntForm setEnabled: aFlag]; [snoozeTimesTextField setEnabled: aFlag]; [snoozeMinutesTextField setEnabled: aFlag]; [snoozeIntUpButton setEnabled: aFlag]; [snoozeIntUpButton setIcon: aFlag?RIGHTARROW:DISABLEDRIGHTARROW]; [snoozeIntDownButton setEnabled: aFlag]; [snoozeIntDownButton setIcon: aFlag?LEFTARROW:DISABLEDLEFTARROW]; [snoozeNoUpButton setEnabled: aFlag]; [snoozeNoUpButton setIcon: aFlag?RIGHTARROW:DISABLEDRIGHTARROW]; [snoozeNoDownButton setEnabled: aFlag]; [snoozeNoDownButton setIcon: aFlag?LEFTARROW:DISABLEDLEFTARROW]; if( aFlag ) [snoozeIntForm selectTextAt:0]; [self snoozeFinished: self]; return self; } - snoozeIntUp: sender { [snoozeIntForm setIntValue: ([snoozeIntForm intValueAt: 0] + 1) at:0]; [self snoozeFinished: self]; return self; } - snoozeIntDown: sender { int temp; temp = [snoozeIntForm intValueAt: 0] - 1; if( temp > 1) [snoozeIntForm setIntValue: temp at:0]; else [snoozeIntForm setIntValue: 1 at:0]; [self snoozeFinished: self]; return self; } - snoozeNoUp: sender { [snoozeNoForm setIntValue: ([snoozeNoForm intValueAt: 0] + 1) at:0]; [self snoozeFinished: self]; return self; } - snoozeNoDown: sender { int temp; temp = [snoozeNoForm intValueAt: 0] - 1; if( temp > 1) [snoozeNoForm setIntValue: temp at:0]; else [snoozeNoForm setIntValue: 1 at:0]; [self snoozeFinished: self]; return self; } - snoozeFinished: sender { static char buf[50]; int sInt, sNo; // The window has changed [self setDocEdited: TRUE]; if( [snoozeButton state]) { sInt = [snoozeIntForm intValueAt: 0]; sNo = [snoozeNoForm intValueAt: 0]; sprintf(buf, "time%s",(sNo == 1)?"":"s"); [snoozeTimesTextField setStringValue: buf]; sprintf(buf, "minute%s",(sInt == 1)?"":"s"); [snoozeMinutesTextField setStringValue: buf]; sprintf(buf,"Snooze alarm set every %d minute%s " "for the next %d minute%s.", sInt, (sInt == 1)?"":"s", (sInt * sNo), ((sInt * sNo) == 1)?"":"s" ); [testSnoozeTextField setStringValue: buf]; } else [testSnoozeTextField setStringValue: "The snooze function is not enabled."]; [self selectNextText: sender]; return self; } - message: sender { [messageForm setEnabled: [messageButton state]]; return self; } - messageFinished: sender { // The window has changed [self setDocEdited: TRUE]; return self; } - sound: sender { int mode; // state of alarmSound matrix mode = [alarmSoundRadioMatrix selectedRow]; [alarmSoundForm setEnabled: mode != 2]; [playButton setEnabled: mode == 0]; [setButton setEnabled: mode == 0]; [stopButton setEnabled: FALSE]; if( mode !=2) [alarmSoundForm selectTextAt: 0]; return self; } - soundFinished: sender { // The window has changed [self setDocEdited: TRUE]; if( [alarmSoundRadioMatrix selectedRow] == 0) [self checkSound: self]; return self; } - playSound:sender { int error; // If we are given a path name for an alarm sound, use the pathname // in newFromSoundFile. Otherwise, we will have to go look for it // using findSoundFor. if( index((char *) [alarmSoundForm stringValueAt:0], '/') == (char *) 0) soundfile = [Sound findSoundFor: (char *) [alarmSoundForm stringValueAt:0]]; else soundfile = [[Sound alloc] initFromSoundfile: (char *) [alarmSoundForm stringValueAt:0]]; if( soundfile != nil) { [soundfile setDelegate: self]; // From 1.0 Docs, Sound Kit, pp22-498 [Sound getVolume: &oldVolumeLeft:&oldVolumeRight]; if( [global volume] >= 0) [Sound setVolume: [global volume] : [global volume]]; error = [soundfile play]; if( error == 0) { [stopButton setEnabled : TRUE]; [playButton setEnabled : TRUE]; } else { char errorString[200]; // Restore old volume [Sound setVolume: oldVolumeLeft: oldVolumeRight]; sprintf(errorString, "Error #%d (%s) occured while " "trying to play the sound <%s>.\n", error, SNDSoundError(error), [alarmSoundForm stringValueAt:0]); NXRunAlertPanel("Alarm Error",errorString, "Oh well...",NULL,NULL); } } else { NXRunAlertPanel("Sound not found", "I couldn't find that sound.", "Oh well...",NULL,NULL); [alarmSoundForm selectText:self]; } return self; } - checkSound:sender { if( [alarmSoundRadioMatrix selectedRow] != 0 ) { [self selectNextText:sender]; return self; } if( ([Sound findSoundFor: (char *) [alarmSoundForm stringValueAt:0]] == nil) && ( access( [alarmSoundForm stringValueAt:0], R_OK) == -1)) { NXRunAlertPanel("Sound not found", "I couldn't find that sound. " "Please double check.", "OK",NULL,NULL); [alarmSoundForm selectText:self]; } else [self selectNextText:sender]; return self; } - stopSound:sender { [soundfile stop]; return self; } - willPlay : sender { #ifdef DEBUG fprintf(stderr,"Alarm sound starting.\n"); #endif [playButton setEnabled: FALSE]; return self; } - hadError: sender { char errorString[200]; int error = [[sender soundBeingProcessed] processingError]; sprintf(errorString, "Error #%d (%s) occured while playing the sound <%s>.\n", error, SNDSoundError(error), [alarmSoundForm stringValueAt:0]); NXRunAlertPanel("Alarm Error",errorString, "Oh well...",NULL,NULL); [stopButton setEnabled: FALSE]; if( [alarmSoundRadioMatrix selectedRow] == 0) [playButton setEnabled: TRUE]; else [playButton setEnabled: FALSE]; // Restore old volume [Sound setVolume: oldVolumeLeft: oldVolumeRight]; return self; } - didPlay:sender { [soundfile free]; [stopButton setEnabled: FALSE]; if( [alarmSoundRadioMatrix selectedRow] == 0) [playButton setEnabled: TRUE]; else [playButton setEnabled: FALSE]; // Restore old volume [Sound setVolume: oldVolumeLeft: oldVolumeRight]; return self; } - insertEventAndClose: sender { #ifdef DEBUG fprintf(stderr,"InsertEventAndClose: %x is the flag.\n", [NXApp currentEvent]->flags); #endif if( [self insertEvent:self] == nil) // user aborted return self; if( !( ([NXApp currentEvent]->flags) & NX_ALTERNATEMASK)) [self close]; [cassandra queueDidChange:self]; return self; } - insertEvent:sender { struct tm time, *timePointer; int vAnniv; time = *timeNow(); [ev setMessage: (char *) [messageForm stringValueAt:0]]; [ev setShowMessage: [messageButton state]]; switch( [alarmSoundRadioMatrix selectedRow] ) { case 0: // sound [ev setAlarmAction: 1]; break; case 1: // runCommand [ev setAlarmAction: 3]; break; case 2: // nada [ev setAlarmAction: 0]; break; } [ev setAlarmSound: (char *) [alarmSoundForm stringValueAt:0]]; if( (timePointer = [self getDate: self]) == NULL) return nil; [ev setTime: timePointer]; if( [anniversaryForm intValueAt:0] > 99) { NXRunAlertPanel("Anniversary Overload", "Due to a design error that cannot be fixed " "until a future version, you cannot have a reoccuring " "event of more than 99 intervals.","OK",NULL,NULL); [anniversaryForm selectTextAt: 0]; return nil; } vAnniv = ([anniversaryRadioMatrix selectedCol] +1 ) * 100; [ev setAnniversary: ([anniversaryButton state] ? ([anniversaryForm intValueAt:0] + vAnniv) : 0) ]; [ev setDestroy: 1]; // Destroy not supported after v0.9.2 [ev setSnoozeNo: ([snoozeButton state] ?[snoozeNoForm intValueAt:0] :0)]; [ev setSnoozeInt: ([snoozeButton state] ?[snoozeIntForm intValueAt:0] :0)]; [ev setPriority: [priorityRadioMatrix selectedCol]*50]; // If the user tries to put in an event with a date that has // already past, inform them of the problem */ if( timeCompare( [ev time], &time ) == -1) if( NXRunAlertPanel("Insert Warning", "The date you have typed in has already passed. " "Are you sure you want to insert it?", "Insert","Cancel",NULL) == 0) return nil; [ev insertEvent]; // The window has been saved [self setDocEdited: FALSE]; return self; } - setSound:sender { OpenPanel *myOpenPanel; char tempDir[128], *tempFile; myOpenPanel = [OpenPanel new]; if( index([ev alarmSound], '/') == (char *) 0) // If the present isn't [ev setAlarmSound: ALARMSOUND]; // a path to a sound strcpy(tempDir, [ev alarmSound]); tempFile = rindex(tempDir,'/') + 1; *(rindex (tempDir,'/')) = '\0'; #ifdef DEBUG fprintf(stderr,"Open directory <%s> with file <%s>\n", tempDir, tempFile); #endif if( [myOpenPanel runModalForDirectory: tempDir file: tempFile types: alarmExtensions ] == 0) return self; #ifdef DEBUG fprintf(stderr,"Opening file <%s>\n", [myOpenPanel filename]); #endif [ev setAlarmSound: (char *) [myOpenPanel filename]]; [alarmSoundForm setStringValue: [ev alarmSound] at: 0]; return self; } - setCassandra: anObject { cassandra = anObject; return self; } - anniversaryFinished: sender { int radioCol, temp; static char buf1[10], buf2[80]; // The window has changed [self setDocEdited: TRUE]; radioCol = [anniversaryRadioMatrix selectedCol]; temp = [anniversaryForm intValueAt:0]; sprintf(buf1, "%s%c", frequencyChar[radioCol], (temp != 1)?'s':'\0'); [everyTextField setStringValue: buf1]; if( [anniversaryButton state]) { if( temp == 1) sprintf(buf2,"I will remind you every %s.", frequencyChar[radioCol]); else sprintf(buf2,"I will remind you every %d %s.", [anniversaryForm intValueAt:0], buf1); [testAnniversaryTextField setStringValue: buf2]; } else [testAnniversaryTextField setStringValue: "This is not a reoccuring event."]; return self; } - updateTestDate : (struct tm *) tnow { static char buf[5]; extern const char *shortWeekDays[7]; [testDateTextField setStringValue: ascMyTime( tnow, NOSEC, [global militaryTime])]; sprintf(buf,"%s", shortWeekDays[tnow->tm_wday]); [wdayTextField setStringValue: buf ]; return self; } // Slight workaround for IB, since IB only likes values // that return (id), but I need the (struct tm *) in another // part of the program, so all we do is message getDate // and ignore the return value. - dateFinished: sender { // The window has changed [self setDocEdited: TRUE]; [self getDate:sender]; return self; } - (struct tm*) getDate : (id) sender { static struct tm eventTime; int month, year; static char buf[100]; extern const char *shortMonths[12]; eventTime.tm_sec = 0; // Get the hour form and make sure it is in good shape strcpy(buf, [hourForm stringValueAt:0]); eventTime.tm_hour = atoi(buf); if( ![global militaryTime]) // if we are not using 24hr time { // then let's check for am/pm suffix if( rindex( buf, 'a') || rindex(buf, 'A') || rindex(buf, 'n') || rindex(buf, 'N')) [amPmButton setState: AM]; else if (rindex(buf, 'p') || rindex(buf,'P') || rindex(buf, 'm') || rindex(buf, 'M')) [amPmButton setState: PM]; } if( [global militaryTime]) { if( eventTime.tm_hour < 0 || eventTime.tm_hour > 23) { NXRunAlertPanel( "Time error", "I had trouble reading the hour " "of the event. " "We are using military time. " "Please type in a number from " "0-23 in the hour form.", "OK",NULL,NULL); [hourForm selectTextAt:0]; return NULL; } } else { if( eventTime.tm_hour < 1 || eventTime.tm_hour > 12) { NXRunAlertPanel( "Time error", "I had trouble reading the hour " "of the event. " "We are using am/pm time. " "Please type in a number from 1-12 " "in the hour form.", "OK",NULL,NULL); [hourForm selectTextAt:0]; return NULL; } if(eventTime.tm_hour == 12) eventTime.tm_hour = 0; eventTime.tm_hour += ( ([amPmButton state] == AM) ? 0 : 12); } // Get the minutes, check their format eventTime.tm_min = [minuteForm intValueAt:0]; if( eventTime.tm_min < 0 || eventTime.tm_min > 59) { NXRunAlertPanel( "Time error", "I had trouble reading the minute " "of the event. " "Please type in a number from 0-59 " "in the minute form.", "OK",NULL,NULL); [minuteForm selectTextAt:0]; return NULL; } if( (month = monthFromAscii((char*) [monthForm stringValueAt:0])) == 0) { [monthForm selectTextAt:0]; return NULL; // If the month is in an incorrect format return } eventTime.tm_mon = ( month - 1); // Get the year and check its format year = [yearForm intValueAt:0]; if( year < 0 || year > 3000) { NXRunAlertPanel( "Time error", "I had trouble reading the year of the event. " "Please type in a number from 0-3000 in the " "year form. See the manual or online help " "for abbreviations.", "OK",NULL,NULL); [yearForm selectTextAt:0]; return NULL; } if( year < 70) eventTime.tm_year = 100+ year; if( year >= 70 && year < 100) eventTime.tm_year = year; if( year >= 100) eventTime.tm_year = year - 1900; // Get the day, check its form eventTime.tm_mday = [dayForm intValueAt:0]; if( eventTime.tm_mday < 1 || eventTime.tm_mday > 31) { sprintf( buf, "I had trouble reading the day of the event. " "Please type in a number from 1-31 in the " "day form. (Hint: %s. %4d has %d days)", shortMonths[eventTime.tm_mon], eventTime.tm_year + 1900, daysInMonth( eventTime.tm_mon + 1, eventTime.tm_year + 1900)); NXRunAlertPanel( "Time error",buf,"OK",NULL,NULL); [dayForm selectTextAt:0]; return NULL; } fixTmStructure( &eventTime); [self updateTestDate: &eventTime]; [self selectNextText:sender]; return ( &eventTime); } - selectNextText:sender { // If the sender is a form class or a subclass of it, then // we want the nextText private variable of the sender, // to use to select the next Form after the user hits return // but NeXT programmers haven't given us a method to access it // so we take it by brute force (I know, I know.... breaking data // abstractions...) // This is out of Cox, "Object Orientated Programming, pp.147 if( [sender isKindOf: [Form class] ] ) { struct idform {@defs(Form);} *p = (struct idform *)sender; [p->nextText selectText:self]; } return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.