'========================================================================= ' Personal Calendar (PC) Program ' Copyright (c) 1985-1990, Paul Munoz-Colman. All Rights Reserved. ' Version 14.10 ' 31 Oct 1990 ' Shareware $25 '========================================================================= ' DOS File CAL5.BAS ' Independently Compiled Subprograms Which Are Linked With CAL1.BAS '========================================================================= ' Written For IBM PCs & Compatibles Under MS DOS 3.30 on a Northgate 486 ' Compiled By Microsoft Professional BASIC 7.10, Linker Version 5.10 '========================================================================= ' Note -- Tabs in the source file are in positions 6,11,16,21,26,... '========================================================================= ' $INCLUDE: 'cal1.bi' '========================================================================= ' Subprogram List in the Order of Appearance in this File ' (compiled WITHOUT error handling--no /E or /X) '------------------------------------------------------------------------- ' Name Purpose ' --------------------------- --------------------------------------- ' PoppedOverCheck Check to See Whether Popped Over DOS ' PrepareforError Clear and Place for Error Message ' PrepareforFatal Prepare for QuickBASIC Error Message ' PrepareforMessage Clear and Place for Info Message ' PrintCalendar Display Three Months of Calendars ' PrintCopy Print or Copy Appointments to ASCII File ' ProcessAlarm Update Event and History Upon Alarm ' PutApptRecord (Pointer) Put Records in Appt File (Blank if 0) ' QuickSort (SortLow, SortHigh) Sort Alarm Table Routine ' QuitLine Ctl-ESC to Quit Instruction ' QuitLineDelete Ctl-ESC to Quit Instruction ' Fn RandInt (Lower, Upper) Random integer from lower to upper ' ReadCalauto Read Auto Start CALAUTO.DAT File ' ReadCalDOS Read DOS Command CALDOS.DAT File ' ReadCalexcl Read Exclusion CALEXCL.DAT File ' ReadCalfig Read Colors CALFIG.DAT File ' ReadCalmusic Read CALMUSIC.DAT File ' ReadCalres Read CALRES.DAT File ' RefreshEventsNotes Display Clock Screen Footer ' RepackApptRecord Build Event Record From Fields ' RestoreCalKeyState Restore State of Ins,Caps,Num,Scrl ' RestoreDOSKeyState Restore State of DOS Ins,Caps,Num,Scrl ' ReturnLine Enter Instruction ' ReturnLineDelete Enter Instruction Blank Out ' SaveCurrentDirectory (EntryPoint) ' Get Program or User Directory ' SaveDOSKeyState Save State of DOS Ins,Caps,Num,Scrl ' ScreenBottoms Esc, Quit, and Return Instructions ' ScreenBottomsDelete Esc, Quit, and Return Instructions Blank ' SequenceEventsTable Resort Events Listing ' SetArrays Set Array Sizes Based Upon Event File ' SetColors Color Choice Menus ' SetCurrentDirectory (EntryPoint) ' Change to Current or User Directory '========================================================================= SUB PoppedOverCheck STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 52 ' Check to see Whether Program Is Popped Up Over the DOS Prompt or ' Over another Program. Can't remove from memory or SrResidentShell ' Unless Popped Up Over DOS PoppedUpOverProgram = No PoppedUpOverDOS = No IF MemoryResident THEN IF SrOverDOS% THEN '** SRP4 PoppedUpOverDOS = Yes '** SRP4 ELSE '** SRP4 PoppedUpOverProgram = Yes '** SRP4 END IF '** SRP4 END IF Subnum = SubnumSave END SUB '========================================================================= SUB PrepareforError STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 53 CALL ClearScreenNormal(N1) CALL MajorBeeper CALL Kolors(N14) CALL BlankError Subnum = SubnumSave END SUB '========================================================================= SUB PrepareforFatal STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 54 CALL ClearScreenNormal(N1) CALL MajorBeeper CALL Kolors(N14) CALL BlankFatal Subnum = SubnumSave END SUB '========================================================================= SUB PrepareforMessage STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 55 CALL MinorBeeper CALL Kolors(N14) CALL BlankError Subnum = SubnumSave END SUB '========================================================================= SUB PrintCalendar STATIC '========================================================================= ' Display Calendars (PrintCalendar) DEFINT A-Z SubnumSave = Subnum Subnum = 56 '------------------------------------------------------------------------- ' If Printing Report, Make Two Passes, One to Generate Calendars, and ' Another To Return Them To The CalendarDate$ In Memory, If Necessary PrintPass$ = False$ IF PrintingReport THEN PassEntry: IF PrintPass$ = "2" THEN GOTO ExitPoint IF PrintPass$ = "1" THEN IF TodaysDate$ = HoldWhilePrinting$ OR FirstTimeClock = Yes THEN GOTO ExitPoint END IF PrintPass$ = "2" ' Restore Calendar Arrays to CalendarDate$ = HoldWhilePrinting$ ' Whatever They Were END IF IF PrintPass$ = False$ THEN PrintPass$ = "1" HoldWhilePrinting$ = MemoryDate$ CalendarDate$ = TodaysDate$ END IF END IF '------------------------------------------------------------------------- ' If Calendars In Memory, Don't Recompute ' Calendars In Memory--Check If Printing or Timer In Case Resequenced IF MemoryDate$ = CalendarDate$ THEN 'Wrong Date Recomputes ' Right Date/Printing Skips IF PrintPass$ = "1" THEN GOTO ShowCalendars ' Right Date/Time Skips IF MemoryTime! = TimerSave! THEN GOTO ShowCalendars END IF '------------------------------------------------------------------------- ' Not in Memory, So Recompute Calendar Values MemoryTime! = TIMER TimerSave! = MemoryTime! MemoryDate$ = CalendarDate$ CalendarYear = VAL(MID$(CalendarDate$, N1, N4)) CalendarMonth = VAL(MID$(CalendarDate$, N5, N2)) CalendarDay = VAL(MID$(CalendarDate$, N7, N2)) CalendarMonths(N2) = CalendarMonth CalendarYears(N2) = CalendarYear '------------------------------------------------------------------------- ' Months And Years For Prior and Next Calendar SELECT CASE CalendarMonth '-------------------------------------------------------------------- CASE 1 ' Middle Month is January CalendarMonths(N1) = N12 IF CalendarYear > N0 THEN CalendarYears(N1) = CalendarYear - N1 ELSE CalendarYears(N1) = 9999 END IF CalendarMonths(N3) = CalendarMonth + N1 CalendarYears(N3) = CalendarYear '-------------------------------------------------------------------- CASE 2 TO N11 ' Middle Month is February to November CalendarMonths(N1) = CalendarMonth - N1 CalendarYears(N1) = CalendarYear CalendarMonths(N3) = CalendarMonth + N1 CalendarYears(N3) = CalendarYear '-------------------------------------------------------------------- CASE N12 ' Middle Month is December CalendarMonths(N1) = CalendarMonth - N1 CalendarYears(N1) = CalendarYear CalendarMonths(N3) = N1 IF CalendarYear < 9999 THEN CalendarYears(N3) = CalendarYear + N1 ELSE CalendarYears(N3) = N0 END IF '-------------------------------------------------------------------- END SELECT '------------------------------------------------------------------------- ' Determine the First Week Day of Each Month '------------------------------------------------------------------------- FOR MonthIndex = N1 TO N3 CALL YearAdjust(CalendarYears(MonthIndex), AdjustedYear$) DatetoIndex$ = ZeroFill$(AdjustedYear$ + _ RIGHT$(STR$(CalendarMonths(MonthIndex)), N2) + "01") CALL DayDate(DatetoIndex$) FirstDays(MonthIndex) = IndexedDay NEXT '------------------------------------------------------------------------- CalendarImage(N1) = Blank80$ ' Store And Display '------------------------------------------------------------------------- FOR MonthIndex = N1 TO N3 '-------------------------------------------------------------------- IF MonthIndex = N2 THEN ColumnOffset = N17 ELSE ColumnOffset = N22 ' Year Of Middle Month-Centered '-------------------------------------------------------------------- MonthnameStart = CalendarColumns(MonthIndex) + (ColumnOffset - _ LEN(MonthNames$(CalendarMonths(MonthIndex)))) \ N2 MonthnameLength = LEN(MonthNames$(CalendarMonths(MonthIndex))) ' Month Name '-------------------------------------------------------------------- IF MonthIndex <> N2 THEN CALL Myd2(CalendarImage(N1), MonthnameStart, MonthnameLength, _ (MonthNames$(CalendarMonths(MonthIndex)))) END IF MonthnameStart = CalendarColumns(MonthIndex) + (ColumnOffset - _ LEN(MonthNames$(CalendarMonths(MonthIndex)))) \ N2 CALL YearAdjust(CalendarYears(N2), AdjustedYear$) AdjustedYear$ = ZeroFill$(AdjustedYear$) MonthnameLength = LEN(MonthNames$(CalendarMonths(MonthIndex)) + _ Blank1$ + AdjustedYear$) IF MonthIndex = N2 THEN CALL Myd2(CalendarImage(N1), MonthnameStart, MonthnameLength, _ (MonthNames$(CalendarMonths(MonthIndex)) + Blank1$ + AdjustedYear$)) END IF ' Month Name,Year '-------------------------------------------------------------------- NEXT '------------------------------------------------------------------------- CalendarImage(N2) = Blank80$ ' Day Labels '------------------------------------------------------------------------- FOR MonthIndex = N1 TO N3 FOR DayPlacement = N1 TO N7 CALL Myd2(CalendarImage(N2), N1 + _ CalendarColumns(MonthIndex) + N3 * (DayPlacement - N1), _ N2, DayNames$(DayPlacement)) NEXT DayPlacement NEXT MonthIndex '------------------------------------------------------------------------- FOR I = N1 TO N6 CalendarImage(N2 + I) = Blank80$ NEXT '------------------------------------------------------------------------- IF ApptFile THEN AlarmPointer = N1 AlarmsAvailable = Yes LightTable = N1 FOR I = N1 TO N2 * NumberofEvents LightDay(I) = N0 NEXT END IF '------------------------------------------------------------------------- FOR MonthIndex = N1 TO N3 CALL KeyStuff(KeyStatus) ' Days LeapReturn = Leap(CalendarYears(MonthIndex)) IF CalendarMonths(MonthIndex) = N2 AND LeapReturn = N1 THEN EndingDay = 29 ELSE EndingDay = MonthLength(CalendarMonths(MonthIndex)) END IF ' Leap Year Goes To 29 FirstDayOfWeek = FirstDays(MonthIndex) ' Starting Day '-------------------------------------------------------------------- FOR WhichDay = N1 TO EndingDay '--------------------------------------------------------------- WhichRow = (FirstDayOfWeek - N1) \ N7 ' Line To Display The Day On DayOfWeekPosition = FirstDayOfWeek MOD N7 IF DayOfWeekPosition = N0 THEN DayOfWeekPosition = N7 DayOfWeekPosition = DayOfWeekPosition * N3 - N3 DayToShow$ = BlankFill$(RIGHT$(STR$(WhichDay), N2)) '--------------------------------------------------------------- ' Hor Offset CALL Myd2(CalendarImage(N3 + WhichRow), N1 + _ CalendarColumns(MonthIndex) + DayOfWeekPosition, _ N2, DayToShow$) '--------------------------------------------------------------- ' Store The Day In The Display Line IF ApptFile AND AlarmsAvailable THEN SELECT CASE Alarms(AlarmPointer).Alarm CASE IS = 0# AlarmsAvailable = No CASE ELSE AlarmDayStore: DaycalTest& = CalendarYears(MonthIndex) * 10000& _ + CalendarMonths(MonthIndex) * 100& + WhichDay DaytableTest& = _ FIX(Alarms(AlarmPointer).Alarm / 10000&) SELECT CASE DaytableTest& CASE IS < DaycalTest& AlarmPointer = AlarmPointer + N1 IF AlarmPointer <= NumberofEvents THEN GOTO AlarmDayStore END IF AlarmsAvailable = No CASE IS = DaycalTest& LightDay(LightTable) = N1 + WhichRow LightDay(LightTable + N1) = _ CalendarColumns(MonthIndex) + _ DayOfWeekPosition LightTable = LightTable + N2 END SELECT END SELECT END IF '--------------------------------------------------------------- IF MonthIndex = N2 AND WhichDay = CalendarDay THEN HilitRow = WhichRow + N2 ' Hilit Day HilitColumn = CalendarColumns(MonthIndex) + _ DayOfWeekPosition HilitDay$ = DayToShow$ TodayBright = N0 IF ApptFile AND ((NormalCalendars AND OverdueCount) OR _ (DaycalTest& <> 0& AND _ DaycalTest& = DaytableTest&)) THEN TodayBright = N1 END IF END IF FirstDayOfWeek = FirstDayOfWeek + N1 NEXT WhichDay '-------------------------------------------------------------------- IF WhichDay = 29 AND LeapReturn = N1 THEN WhichRow = (FirstDayOfWeek - N1) \ N7 ' Vertical Offset For Leap Year Day DayOfWeekPosition = FirstDayOfWeek MOD N7 IF DayOfWeekPosition = N0 THEN DayOfWeekPosition = N7 DayOfWeekPosition = DayOfWeekPosition * N3 - N3 ' Hor Offset CALL Myd2(CalendarImage(N3 + WhichRow), N1 + _ CalendarColumns(MonthIndex) + DayOfWeekPosition, N3, "29") END IF NEXT MonthIndex '------------------------------------------------------------------------- ' Recompute Finished '------------------------------------------------------------------------- ' Display Calendars ShowCalendars: IF PrintPass$ = "1" THEN ' Calendars From Print or Copy FOR I = N1 TO N8 CALL KeyStuff(KeyStatus) IF PrintorCopy$ = "p" AND CalendarImage(I) <> Blank80$ THEN CALL LprintString(SPACE$(N5) + _ LEFT$(CalendarImage(I), N70), N0) IF LprintTerminate THEN GOTO ExitPoint END IF IF PrintorCopy$ = "w" AND CalendarImage(I) <> Blank80$ THEN PRINT #FilenumCopy, SPACE$(N5); LEFT$(CalendarImage(I), N70) END IF NEXT END IF IF PrintingReport THEN GOTO PassEntry CSRow = CalendarStartRow + N1 CSColumn = CalendarStartColumn + N1 CSColumn2 = CSColumn + CalendarColumns(N2) ShowString$ = LEFT$(CalendarImage(N1), N70) CALL ShowIt(N4, CSRow, CSColumn, ShowString$) ShowString$ = MID$(CalendarImage(N1), N1 + CalendarColumns(N2), N20) CALL ShowIt(N11, N0, CSColumn2, ShowString$) ShowString$ = LEFT$(CalendarImage(N2), N70) CALL ShowIt(N4, Nm1, CSColumn, ShowString$) '------------------------------------------------------------------------- ' Display Calendar Lines On Screen and Highlight If Called For FOR CalendarRow = N1 TO N6 CALL KeyStuff(KeyStatus) CSRow = CalendarStartRow + N2 + CalendarRow CSColumn = CalendarStartColumn + N1 ShowString$ = LEFT$(CalendarImage(N2 + CalendarRow), N70) CALL ShowIt(N4, CSRow, CSColumn, ShowString$) IF ApptFile THEN FOR LightTable = N1 TO Nm1 + N2 * NumberofEvents STEP N2 IF LightDay(LightTable) = N0 OR _ LightDay(LightTable) > CalendarRow THEN EXIT FOR END IF YSave = LightDay(LightTable) 'Array Row CSRow = YSave + CalendarStartRow + N2 'Screen Row XSave = LightDay(LightTable + N1) 'Array Column CSColumn = XSave + CalendarStartColumn + N1 ' Screen Column ShowString$ = MID$(CalendarImage(N2 + YSave), _ N1 + XSave, N2) CALL ShowIt(N11, CSRow, CSColumn, ShowString$) NEXT LightTable END IF NEXT CalendarRow '------------------------------------------------------------------------- CSRow = CalendarStartRow + HilitRow + N1 CSColumn = CalendarStartColumn + HilitColumn + N1 CALL ShowErase(N4, CSRow, CSColumn, N3, Blank0$) IF NOT ApptFile OR TodayBright = N0 THEN CALL Kolors(N7) ELSE CALL Kolors(N14) END IF CALL ShowIt(N0, N0, N0, HilitDay$) CALL DayDate(CalendarDate$) J = IndexedDay CSRow = CalendarStartRow + N2 ShowString$ = LEFT$(DayNames$(J), N2) CALL ShowIt(N0, CSRow, ScreenColumn, ShowString$) ' Hilit Today's Date and Day of the Week RedisplayCalendars = No ExitPoint: Subnum = SubnumSave END SUB '========================================================================= SUB PrintCopy STATIC '========================================================================= ' Print or Copy Appointment File To DOS File DEFINT A-Z SubnumSave = Subnum Subnum = 57 '------------------------------------------------------------------------- PrintingReport = Yes IF ClockScreenPrint THEN GOTO StartPrint '-------------------------------------------------------------------- ' Print/Copy File DirectReturn = Yes ' Clear Line 25 CALL ShowErase(N6, N25, N1, N80, Blank0$) CALL DisplayApptFilename IF PrintorCopy$ <> "p" THEN '--------------------------------------------------------------- CopyFilename$ = SPACE$(N12) CALL Myd2(CopyFilename$, N1, LEN(ApptFilename$), ApptFilename$) CALL Myd2(CopyFilename$, InString(CopyFilename$, Blank1$), _ N4, ".asc") CALL ControlledInput(N25, N28, N25, N8, N12, _ "Name of ASCII File", CopyFilename$, N0, N1, N1, N1) IF Keystroke$ = CHR$(Esc) THEN CALL ClearScreenNormal(N1) GOTO AllOver END IF '--------------------------------------------------------------- CLOSE FilenumCopy OPEN "O", FilenumCopy, CopyFilename$, N80 ELSE StartPrint: CALL InitPrinter If LprintTerminate THEN GOTO TerminatePrint END IF IF NOT ClockScreenPrint THEN CALL Kolors(N14) CALL BlankError IF PrintorCopy$ = "p" THEN CALL ShowIt(N0, N0, N0, "Printing Appointments") ELSE CALL ShowIt(N0, N0, N0, _ ("Generating ASCII File " + CopyFilename$)) END IF END IF '------------------------------------------------------------------------- CALL GetFilenameLength DisplayFilename$ = LEFT$(ApptFilename$, FilenameLength) GOSUB DoubleEqualLine Buffer80$ = DayNames$(TodaysDay) + ", " + DATE$ + SPACE$(N2) + _ TIME$ + " " + DisplayFilename$ + _ "'s Appointment Calendar" GOSUB PrintALine '------------------------------------------------------------------------- GOSUB DoubleEqualLine CALL PrintCalendar ' Calendars Before Events '------------------------------------------------------------------------- GOSUB DoubleEqualLine Buffer80$ = "Events (" + RIGHT$(STR$(EventsScheduled), N3) + ")" GOSUB PrintALine GOSUB DoubleEqualLine '------------------------------------------------------------------------- ' Initialize Counter For Week Break Logic PreviousIndexedDay = N0 FOR I = N1 TO NumberofEvents WhichEvent = I CALL ApptToMenu(N1) CALL KeyStuff(KeyStatus) IF CurrentEventRecord$ <> Blank80$ THEN '---------------------------------------------------------------- ' Write Events ' If No Week Break Wanted, Skip Break Logic IF WeekBreak$ = True$ THEN '---------------------------------------------------------- ' Compute Whether Week Break Needed ' Get New Day of Week and Day Count DatetoIndex$ = MID$(CurrentEventRecord$, N74, N2) + _ LEFT$(CurrentEventRecord$, N6) CALL DayDate(DatetoIndex$) CurrentIndexedDay = IndexedDay CurrentCountedDay& = CountedDay& '---------------------------------------------------------- ' If First Time Through, Initialize Comparison Holders IF PreviousIndexedDay = N0 THEN GOSUB SaveDayCounts ' Save Day Counts '----------------------------------------------------- ' If New Day of Week More Than 7 Beyond Old, ' Or Not Later In Week ELSEIF CurrentIndexedDay < PreviousIndexedDay OR _ (CurrentCountedDay& - _ PreviousCountedDay&) >= 7& THEN GOSUB SingleEqualLine ' Generate Week Breaker GOSUB SaveDayCounts ' Save Day Counts END IF '---------------------------------------------------------- END IF ' Generate Event Line Buffer80$ = CurrentEventLine$ GOSUB PrintALine END IF NEXT '------------------------------------------------------------------------- IF InclNotes THEN ' Write Notes GOSUB DoubleEqualLine Buffer80$ = "Notes" GOSUB PrintALine GOSUB DoubleEqualLine FOR I = N1 TO NumberofNotes CALL KeyStuff(KeyStatus) Pointer = StartingNote + I - N1 CALL GetApptRecord(Pointer) Buffer80$ = ApptBuffer$ IF Buffer80$ <> Blank80$ THEN IF PrintorCopy$ = "p" THEN ' Don't number on a copy CALL MhMidString(Buffer80$, N6%, N75%, _ ApptBuffer$, N1%) MID$(Buffer80$, N1, N5) = SPACE$(N5) MID$(Buffer80$, N1, N5) = STR$(I) END IF GOSUB PrintALine END IF NEXT END IF IF InclHistory THEN ' Write History GOSUB DoubleEqualLine Buffer80$ = "History (" + STR$(LOF(FilenumAppt) \ N80 - _ StartingHistory + N1) + ")" GOSUB PrintALine GOSUB DoubleEqualLine FOR I = StartingHistory TO LOF(FilenumAppt) \ N80 CALL KeyStuff(KeyStatus) CALL GetApptRecord(I) Buffer80$ = ApptBuffer$ IF Buffer80$ <> Blank80$ THEN GOSUB PrintALine NEXT END IF PrintingReport = No IF NOT ClockScreenPrint THEN CALL ClearScreenNormal(N1) CALL Kolors(N14) CALL BlankError Menu1 = MainMenuLastEntry IF PrintorCopy$ = "w" THEN GOSUB DoubleEqualLine CLOSE FilenumCopy CALL ShowIt(N0, N0, N0, _ ("Completed Generation of ASCII File " + CopyFilename$)) GOTO AllOver END IF END IF CALL PageEject LprintJobOver = Yes CALL LprintString(Blank0$, N0) If LprintTerminate THEN GOTO TerminatePrint IF NOT ClockScreenPrint THEN CALL BlankError CALL ShowIt(N0, N0, N0, ("Completed Print Generation for " + _ ApptFilename$)) END IF GOTO AllOver DoubleEqualLine: Buffer80$ = Strng$(N80, 61) 'Main Separator (equals) GOSUB PrintALine RETURN SingleEqualLine: Buffer80$ = Strng$(N80, N45) 'Week Breaker (hyphens) GOSUB PrintALine RETURN PrintALine: CALL KeyStuff(KeyStatus) Buffer80$ = RTRIM$(Buffer80$) IF PrintorCopy$ = "p" THEN CALL LprintString(Buffer80$, N0) ' Generate Print TerminatePrint: IF LprintTerminate THEN LprintTerminate = No PrintPass$ = False$ PrintingReport = No IF NOT ClockScreenPrint THEN CALL Kolors(N14) CALL BlankError CALL ShowIt(N0, N0, N0, _ "Print Generation Terminated by Request") CALL Kolors(N6) CALL ClearLast3 END IF GOTO AllOver END IF ELSE PRINT #FilenumCopy, Buffer80$ ' Generate Record END IF RETURN ' Save Day Counts for Comparison SaveDayCounts: PreviousIndexedDay = CurrentIndexedDay PreviousCountedDay& = CurrentCountedDay& RETURN AllOver: ClockScreenPrint = No LprintTerminate = No Subnum = SubnumSave END SUB '========================================================================= SUB ProcessAlarm STATIC '========================================================================= ' Alarm Ringing, Reschedule Recurring Events, Resequence Table & ' Fill Overdue Table With Late Events '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 58 EventTableStable = No OPEN "R", #FilenumOverdue, ApptFilenameOverdue$, N80 FIELD #FilenumOverdue, N80 AS OverdueBuffer$ FOR AlarmTableIndex = N1 TO NumberofEvents CALL KeyStuff(KeyStatus) '-------------------------------------------------------------------- ' Flag for Rescheduling Bi/Multi/Weeklies or Special Monthlies Rescheduling = No ' Check Each Event For Lateness -- Not Null and Overdue IF Alarms(AlarmTableIndex).Alarm <> 0# AND _ Alarms(AlarmTableIndex).Alarm <= CurrentDateTime# THEN CALL ShowErase(N14, N25, N1, N80, (SPACE$(N19) + _ "Please Wait--Checking Overdue Event" + STR$(AlarmTableIndex) + SPACE$(N4))) '--------------------------------------------------------------- ' Late Event To End of Overdue Table, Alarm Entry Gets Cleared Alarms(AlarmTableIndex).Alarm = 0# OverdueCount = LOF(FilenumOverdue)\N80 + N1 WhichEvent = AlarmTableIndex CALL ApptToMenu(N1) CALL MhLset(OverdueBuffer$, CurrentEventLine$) PUT #FilenumOverdue, OverdueCount '--------------------------------------------------------------- ' If Entry Is Not Null, Then Write It To History IF CurrentEventLine$ <> Blank80$ AND _ CurrentEventLine$ <> NullEvent$ THEN EventtoHistory = Yes HistoryBuffer$ = CurrentEventLine$ CALL WritetoHistory END IF '--------------------------------------------------------------- ' If Entry Is Daily, Bi/Multi/Weekly, Monthly, Quarter/Yearly ' Then Reschedule It LimitedsLeft = VAL(MID$(CurrentEventRecord$, N68, N2)) IF MID$(CurrentEventRecord$, N70, N1) = Blank1$ OR _ LimitedsLeft = N1 THEN '---------------------------------------------------------- ' If Entry Is One-Time or Last Recurring, Blank It Out CurrentEventRecord$ = Blank80$ CurrentEventLine$ = Blank80$ ELSE ' Recurring With Last Time Blanks Out '---------------------------------------------------------- ' Decrement The Recurring Item Count if There IF LimitedsLeft > N0 THEN CALL Myd2(CurrentEventRecord$, N68, N2, _ (RIGHT$(STR$(LimitedsLeft - N1), N2))) END IF '---------------------------------------------------------- ' Rebuild The Menu Entry For That Item ' And Rewrite Event Record WhichEvent = AlarmTableIndex 'On 2 or more or CALL UnpackApptRecord ' unlimited CALL CombineDateTime Rescheduling = Yes CALL ValidateEventDate CALL RepackApptRecord CALL BuildMenuLine END IF CALL MhLset(ApptBuffer$, CurrentEventRecord$) CALL PutApptRecord(N1 + AlarmTableIndex) END IF NEXT CLOSE #FilenumOverdue '------------------------------------------------------------------------- ' Resequence The Event Table CALL SequenceEventsTable '------------------------------------------------------------------------- ' Reprint Calendars, Notes and Events On Display CALL PrintCalendar CALL RefreshEventsNotes Subnum = SubnumSave END SUB '========================================================================= SUB PutApptRecord (Pointer) STATIC '========================================================================= ' Put a Record To the Appointment File ' If a Null String Then Replace it by Blanks DEFINT A-Z SubnumSave = Subnum Subnum = 59 IF NOT ApptFile THEN CALL OpenAppts IF ApptBuffer$ = ZeroLine THEN ' Replace Null Record CALL MhLset(ApptBuffer$, Blank80$) END IF PUT FilenumAppt, Pointer Subnum = SubnumSave END SUB '======================================================================== DEFINT A-Z SUB QuickSort (SortLow, SortHigh) '======================================================================== DEFINT A-Z SubnumSave = Subnum Subnum = 134 '========================================================================= ' QuickSort is adapted here from QB 4.50 Examples File SORTDEMO.BAS. '========================================================================= ' QuickSort works by picking a random "pivot" element in Alarms, then ' moving every element that is bigger to one side of the pivot, and every ' element that is smaller to the other side. QuickSort is then called ' recursively with the two subdivisions created by the pivot. Once the ' number of elements in a subdivision reaches two, the recursive calls end ' and the array is sorted. '======================================================================= IF SortLow < SortHigh THEN ' Only two elements in this subdivision; swap them if they are out of ' order, then end recursive calls IF SortHigh - SortLow = N1 THEN IF Alarms(SortLow).Alarm > Alarms(SortHigh).Alarm THEN SWAP Alarms(SortLow), Alarms(SortHigh) END IF ELSE ' Pick a pivot element at random, then move it to the end RandIndex = RandInt(SortLow, SortHigh) SWAP Alarms(SortHigh), Alarms(RandIndex) Partition = Alarms(SortHigh).Alarm DO ' Move in from both sides towards the pivot element: I = SortLow J = SortHigh DO WHILE (I < J) AND (Alarms(I).Alarm <= Partition) I = I + N1 LOOP DO WHILE (J > I) AND (Alarms(J).Alarm >= Partition) J = J - N1 LOOP ' If we haven't reached the pivot element, it means that two ' elements on either side are out of order, so swap them: IF I < J THEN SWAP Alarms(I), Alarms(J) END IF LOOP WHILE I < J ' Move the pivot element back to its proper place in the array: SWAP Alarms(I), Alarms(SortHigh) ' Recursively call the QuickSort procedure (pass the smaller ' subdivision first to use less stack space): IF (I - SortLow) < (SortHigh - I) THEN QuickSort SortLow, I - N1 QuickSort I + N1, SortHigh ELSE QuickSort I + N1, SortHigh QuickSort SortLow, I - N1 END IF END IF END IF Subnum = SubnumSave END SUB '========================================================================= SUB QuitLine STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 60 CALL QuitLineDelete CALL ShowIt(N7, N25, N62, " Ctl-Esc ") CALL ShowIt(N6, N0, Nm1, "Quit") Subnum = SubnumSave END SUB '========================================================================= SUB QuitLineDelete STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 61 CALL ShowErase(N6, N25, N62, N19, Blank0$) Subnum = SubnumSave END SUB '======================================================================= FUNCTION RandInt%(Lower%, Upper%) STATIC '======================================================================= ' Returns a random integer greater than or equal to the Lower parameter ' and less than or equal to the Upper parameter. '======================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 135 RandInt = INT(RND * (Upper - Lower + N1)) + Lower Subnum = SubnumSave END FUNCTION '========================================================================= SUB ReadCalauto STATIC '========================================================================= ' Read (Or Write) Automatic Startup File DEFINT A-Z SubnumSave = Subnum Subnum = 110 UpdatingCalauto = No IF NOT FileExist("calauto.dat") THEN UpdatingCalauto = Yes ELSE ErrorSwitch = No NewGuy = No ' File Exists, Read It OPEN "I", #FilenumAuto, "calauto.dat" CALL ReadCalautoGet ' with error handling in CAL1 IF ErrorSwitch THEN ' Check for short record ErrorSwitch = No UpdatingCalauto = Yes END IF END IF CLOSE FilenumAuto IF AutoMode$ = True$ AND NOT EarlyPopDownFailed THEN ' If attempt for TSR AutostartMode = Yes ' fails before initialization ELSE ' is complete, don't do AutoStarted = No ' automatic startup AutostartMode = No EarlyPopDownFailed = No END IF IF AutostartMode THEN ' If okay then copy password EnteredPassword$ = ApptPassword$ ELSE ApptPassword$ = Blank8$ ApptFilename$ = Blank8$ END IF ' If a filename, let it alone, else set it to blanks with password IF LEN(ApptFilename$) <> N8 THEN ApptFilename$ = Blank8$ END IF IF ApptFilename$ = Blank8$ THEN ApptPassword$ = Blank8$ EnteredPassword$ = ApptPassword$ END IF IF UpdatingCalauto THEN CALL WriteCalauto 'Create or update auto start file END IF Subnum = SubnumSave END SUB '========================================================================= SUB ReadCalDOS STATIC '========================================================================= ' Read (Or Write) DOS Command for F7 DEFINT A-Z SubnumSave = Subnum Subnum = 111 IF NOT FileExist("caldos.dat") THEN CALL Snooze(0.7!) CALL PrepareforMessage CALL ShowIt(N0, N0, N0, _ " Created Prestored DOS Command File CALDOS.DAT") ELSE NewGuy = No ErrorSwitch = No OPEN "I", FilenumDOS, "caldos.dat" CALL ReadCalDOSGet ' with error handling in main IF NOT ErrorSwitch THEN CLOSE FilenumDOS EXIT SUB END IF END IF DOSCommand$ = Blank80$ CLOSE FilenumDOS CALL WriteCalDOS 'Create DOS Command File Subnum = SubnumSave END SUB '========================================================================= SUB ReadCalexcl STATIC '========================================================================= ' Read (or Write) Text Exclusions From History DEFINT A-Z SubnumSave = Subnum Subnum = 112 IF NOT FileExist("calexcl.dat") THEN 'Read Entry (Write only if problems) ErrorSwitch = Yes CALL Snooze(0.7!) CALL PrepareforMessage CALL ShowIt(N0, N0, N0, _ " Created Event Exclusion From History File CALEXCL.DAT") ELSE NewGuy = No ErrorSwitch = No OPEN "I", FilenumExcl, "calexcl.dat" CALL ReadCalexclGet ' with error handling in CAL1 CLOSE FilenumExcl END IF IF ErrorSwitch THEN CALL WriteCalexcl ErrorSwitch = No Subnum = SubnumSave END SUB '========================================================================= SUB ReadCalfig STATIC '========================================================================= ' Read (Or Write) Color Choice File DEFINT A-Z SubnumSave = Subnum Subnum = 113 Writefig = N0 UpdatingCalfig = No IF NOT FileExist("calfig.dat") THEN 'Read Entry (Write only if problems) UpdatingCalfig = Yes Writefig = N1 ELSE NewGuy = No OPEN "I", FilenumFig, "calfig.dat" ErrorSwitch = No CALL ReadCalfigGet ' with error handling in CAL1 CLOSE FilenumFig IF ErrorSwitch THEN ' Reading Past End Of File UpdatingCalfig = Yes ' Those Variables Which Existed Writefig = N1 ' Are Still In Memory -- The ErrorSwitch = No END IF ' Writing of CALFIG.DAT Will Fill END IF ' in missing parameters '==================================================================== IF Writefig = N1 THEN CALL WriteCalfig Subnum = SubnumSave END SUB '========================================================================= SUB ReadCalmusic STATIC '========================================================================= ' Read (Or Write) Music Choice File For Alarms and Chimes DEFINT A-Z SubnumSave = Subnum Subnum = 114 IF NOT FileExist("calmusic.dat") THEN 'Read Entry (Write only if problems) CALL Snooze(0.7!) ErrorSwitch = Yes CALL PrepareforMessage CALL ShowIt(N0, N0, N0, _ " Created Music Choices File CALMUSIC.DAT") ELSE NewGuy = No ErrorSwitch = No OPEN "I", FilenumMusic, "calmusic.dat" CALL ReadCalmusicGet ' with error handling in CAL1 CLOSE FilenumMusic END IF IF ErrorSwitch THEN ErrorSwitch = No IF LEN(Alarm$) = N0 THEN Alarm$ = Blank80$ CALL Myd2 (Alarm$, N1, N58, "mb t255 ml o4 f9d9f9d9f9d" + _ "9f9d9f9d9 ms a9a9a9a9a9a9a9a9a9a9 t60 p2") END IF IF LEN(Chime$) = N0 THEN Chime$ = Blank80$ CALL Myd2 (Chime$, N1, N32, _ "mb o2 ms l5 t70 bgad p2 dabg p2 t45") END IF IF LEN(Warning$) = N0 THEN Warning$ = Blank80$ CALL Myd2 (Warning$, N1, N58, "mb t255 ml o2 f9d9f9d9f" + _ "9d9f9d9f9d9 ms a9a9a9a9a9a9a9a9a9a9 t60 p2") END IF CALL WriteCalmusic END IF Subnum = SubnumSave END SUB '========================================================================= SUB ReadCalres STATIC '========================================================================= ' Read (Or Write) Stay-Res Options File DEFINT A-Z SubnumSave = Subnum Subnum = 115 WriteRes = N0 UpdatingCalres = No IF NOT FileExist("calres.dat") THEN 'Read Entry (Write only if problems) WriteRes = N1 ELSE NewGuy = No ErrorSwitch = No OPEN "I", FilenumRes, "calres.dat" CALL ReadCalresGet ' with error handling in CAL1 CLOSE FilenumFig IF ErrorSwitch THEN WriteRes = N1 END IF END IF '-------------------------------------------------------------------- ' Set Stay-Res Defaults and Internal Values as Needed '==================================================================== ' Fill In Whichever Options Are Missing IF EverResident$ = True$ THEN SrOptionsChosen = Yes ELSE SrOptionsChosen = No EverResident$ = False$ END IF IF UserPopDateTime$ = False$ THEN AllowPopDateTime = No ELSE UserPopDateTime$ = True$ AllowPopDateTime = Yes END IF IF UseEMS$ = True$ THEN SrDontUseEMS = No ELSE UseEMS$ = False$ SrDontUseEMS = Yes END IF IF NOT SrSnowCheck THEN CALL SrNoSnow END IF IF UseDiskSwap$ = True$ THEN SrDiskSwapping = Yes ELSE UseDiskSwap$ = False$ SrDiskSwapping = No END IF ' Path for "swap" files is calendar's directory IF SrSwapPath$ = Blank0$ OR NOT DirectoryExist(SrSwapPath$) THEN WriteRes = Yes SrSwapPath$ = ReturnPath$ END IF IF SrKscanHot = N0 AND SrKshiftHot = N0 THEN SrKscanHot = 103 ' Ctrl-Lshift-F10 is default hot key SrKshiftHot = N6 END IF ' Get English Name of Defined Hot Key CALL StayResKeyName ' Write File If Not Read Properly IF WriteRes THEN UpdatingCalres = Yes CALL WriteCalres END IF ErrorSwitch = No Subnum = SubnumSave END SUB '========================================================================= SUB RefreshEventsNotes STATIC '========================================================================= ' Refresh Event And Notes On Clock Display Page DEFINT A-Z SubnumSave = Subnum Subnum = 63 FromOverduePage = No SELECT CASE FooterSize CASE 5, N9 FooterStartLine = N15 CASE 3, N4, 8 FooterStartLine = N16 CASE 6, 7 FooterStartLine = N17 END SELECT ' Refresh IF FooterRecall THEN FooterAction$ = Blank1$ 'Footer Recall IF NoteSize <> N0 AND FooterAction$ <> "e" THEN ' Notes FOR I = N1 TO NoteSize CALL KeyStuff(KeyStatus) Pointer = I + CurrentNote + StartingNote - N2 CALL GetApptRecord(Pointer) FooterRow = FooterStartLine + I + N1 IF FooterRow > N21 AND FooterRecall THEN RefreshInstructions = Yes FooterRecall = No END IF WindowLine$ = Blank80$ ' Get Note Number and Right Justify It EditLineLabel$ = STR$(CurrentNote - N1 + I) LenTemp = LEN(EditLineLabel$) - N1 ' Less the leading space IF LenTemp > N3 THEN LenTemp = N3 ' Only the right 3 chars CALL Myd2(WindowLine$, N1, N3, (SPACE$(N3 - LenTemp) + _ RIGHT$(EditLineLabel$, LenTemp))) CALL Myd2(WindowLine$, N6, N75, ApptBuffer$) IF ColorCRT THEN CALL Kolors(N9) ELSE CALL Kolors(N7) END IF CALL ShowIt(N0, FooterRow, N1, WindowLine$) NEXT END IF IF OverdueCount THEN IF OverdueCount > FooterSize - NoteSize THEN CALL ShowOverduePage FromOverduePage = Yes GOTO ExitPoint2 END IF IF SoundLevel > N2 AND NOT AlarmMusicPlayed THEN CALL PlayAlarmWarning(N0) END IF AlarmMusicPlayed = Yes OPEN "R", #FilenumOverdue, ApptFilenameOverdue$, N80 FIELD #FilenumOverdue, N80 AS OverdueBuffer$ FOR I = N1 TO OverdueCount CALL KeyStuff(KeyStatus) GET #FilenumOverdue, I FooterRow = FooterStartLine + NoteSize + I + N1 IF FooterRow > N21 AND FooterRecall THEN RefreshInstructions = Yes FooterRecall = No END IF WindowLine$ = OverdueBuffer$ CALL ShowIt(N16, FooterRow, N1, WindowLine$) NEXT CLOSE #FilenumOverdue END IF IF OverdueCount <> FooterSize - NoteSize AND FooterAction$ <> False$ THEN ' Earliest Events ' Skip Blank WindowSize = FooterSize - NoteSize - OverdueCount FOR I = N1 TO WindowSize WhichEvent = (CurrentEvent - N1 + I) ' Compute Event Table Index, Make Blink if a Warning FooterRow = FooterStartLine + NoteSize + OverdueCount + I + N1 IF I = N1 THEN EventWindowStart = FooterRow END IF IF FooterRow > N21 AND FooterRecall THEN RefreshInstructions = Yes FooterRecall = No END IF CALL ApptToMenu(N1) EventWindow(I) = CurrentEventLine$ NEXT FOR I = N1 to WindowSize IF Pending = N0 THEN CALL Kolors(N8) ELSE WhichEvent = (CurrentEvent - N1 + I) IF PendingEvents(WhichEvent) = N0 THEN CALL Kolors(N8) ELSE ColorForeground = Cl1b + N16 ColorBackground = Cl1f CALL Kolors(N0) END IF END IF CALL ShowIt(N0, (EventWindowStart + I - N1), _ N1, EventWindow(I)) NEXT END IF RedisplayNotesEvents = No ExitPoint2: Subnum = SubnumSave END SUB '========================================================================= SUB RepackApptRecord STATIC '========================================================================= ' Repack Appointment File Record From Individual Variables DEFINT A-Z SubnumSave = Subnum Subnum = 64 CALL Myd2(EventYear1st2$, N1%, N2%, EventDate$) CALL MhMidString(EventYear$, N1%, N2%, EventDate$, N3%) CALL MhMidString(EventMonth$, N1%, N2%, EventDate$, N5%) CALL MhMidString(EventDay$, N1%, N2%, EventDate$, N7%) CALL Myd2(EventHour$, N1%, N2%, EventTime$) CALL MhMidString(EventMinute$, N1%, N2%, EventTime$, N3%) CALL Myd2(CurrentEventRecord$, N1%, N2%, EventYear$) CALL Myd2(CurrentEventRecord$, N3%, N2%, EventMonth$) CALL Myd2(CurrentEventRecord$, N5%, N2%, EventDay$) CALL Myd2(CurrentEventRecord$, N7%, N2%, EventHour$) CALL Myd2(CurrentEventRecord$, N9%, N2%, EventMinute$) CALL Myd2(CurrentEventRecord$, N11%, TextSize%, EventText$) CALL Myd2(CurrentEventRecord$, N68%, N2%, EventLimRepeat$) CALL Myd2(CurrentEventRecord$, N70%, N3%, EventRepeat$) CALL Myd2(CurrentEventRecord$, N74%, N2%, EventYear1st2$) Subnum = SubnumSave END SUB '========================================================================= SUB RestoreCalKeyState STATIC '========================================================================= ' Restore Keys to Last State in This Program DEFINT A-Z SubnumSave = Subnum Subnum = 66 ' It is safe to use BASIC LOCATE here, because we're in the calendar ' and in text mode. IF CursorState THEN ' Turn the Cal cursor on, if appropriate ' If the cursor is within limits, show it. IF CursorRow > N0 AND CursorColumn > N0 AND _ CursorRow <= DisplayRows AND CursorColumn <= DisplayColumns THEN LOCATE CursorRow, CursorColumn, CursorState, _ CursorStart, CursorStop END IF END IF CALL MhSetKbStatus(Insrt%, Caps%, Num%, Scroll%) ' Restore Key States Subnum = SubnumSave END SUB '========================================================================= SUB RestoreDOSKeyState STATIC '========================================================================= ' Restore DOS Keys to Original State DEFINT A-Z SubnumSave = Subnum Subnum = 67 ' Restore the user cursor if there is one ' It isn't safe to use LOCATE here, because we're in the user's underlying ' video mode, so we use a direct DOS BIOS call. InterruptNumber% = &H10 ' ROM-BIOS Video Services Interrupt AH% = &H01 ' Set Cursor Size CL% = DOSCursorStop ' Set the user bottom scan line CH% = DOSCursorStart ' Set the user top scan line IF DOSCursorState THEN ' If cursor was on CH% = CH% OR N32 ' turn on bit 5 ELSE CH% = CH% AND NOT N32 ' else turn it off END IF GOSUB DOSBIOS ' InterruptNumber% = &H10 ' ROM-BIOS Video Services Interrupt AH% = &H02 ' Set Cursor Position function BH% = DOSCursorPage ' Set the user video page DH% = DOSCursorRow ' Set the user cursor row DL% = DOSCursorColumn ' Set the user cursor column GOSUB DOSBIOS ' Restore the state of the Insert, Caps, Num, and Scroll keys CALL MhSetKbStatus(InsertDOS%, CapsDOS%, NumDOS%, ScrollDOS%) Subnum = SubnumSave EXIT SUB DOSBIOS: CALL DOSBIOSServices RETURN END SUB '========================================================================= SUB ReturnLine STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 68 CALL ReturnLineDelete CALL ShowIt(N7, N24, N62, " Return ") CALL ShowIt(N6, N0, Nm1, "Proceed") Subnum = SubnumSave END SUB '========================================================================= SUB ReturnLineDelete STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 69 CALL ShowErase(N6, N24, N62, N19, Blank0$) Subnum = SubnumSave END SUB '========================================================================= SUB SaveCurrentDirectory (EntryPoint) STATIC '========================================================================= ' Store User or Calendar's Current Directory DEFINT A-Z SubnumSave = Subnum Subnum = 70 '----------------------------------------------------------- ' Get User or Calendar Directory DirectoryGet$ = SPACE$(65) DriveGet = N0 CALL MhDir(N1%, DriveGet%, DirectoryGet$, Ecode%) IF Ecode THEN ERROR 255 '------------------------------------------------------------------------- GetPath$ = RTRIM$(CHR$(N64 + DriveGet) + ":\" + ASCIIN$(DirectoryGet$)) DirectoryGet$ = ASCIIZ$(GetPath$) '------------------------------------------------------------------------- IF EntryPoint THEN DriveReturn = DriveGet DirectoryReturn$ = DirectoryGet$ ReturnPath$ = GetPath$ ELSE DriveUser = DriveGet DirectoryUser$ = DirectoryGet$ UserPath$ = GetPath$ END IF Subnum = SubnumSave END SUB '========================================================================= SUB SaveDOSKeyState STATIC '========================================================================= ' Save DOS Keystate DEFINT A-Z SubnumSave = Subnum Subnum = 71 '---------------------------------- ' Determine number of display rows and columns CALL MhDisplay (DispMode%, UserColumns%, UserRows%, Memory%, _ DisplayType%) DisplayColumns = UserColumns DisplayRows = UserRows '---------------------------------- ' Get the state of the insert, caps, num, and scroll keys CALL MhGetKbStatus1(InsertDOS%, CapsDOS%, NumDOS%, ScrollDOS%, _ Alt%, Ctrl%, Left%, Right%) '---------------------------------- ' ROM-BIOS Video Services Interrupt ' Get Cursor, mode, and page Information ' First Determine the user's video page and mode. InterruptNumber% = &H10 ' Video Services AH% = &H0F ' Get User's Video Page and mode GOSUB DOSBIOS2 UserMode = AL% ' Save user video mode CurrentVideoMode = AL% ' and set it as current DOSCursorPage = BH% ' Save user video page CurrentVideoPage = BH% ' and set it as current '---------------------------------- InterruptNumber% = &H10 ' Video Services AH% = &H3 ' Read Cursor Information GOSUB DOSBIOS2 ' On return, this is what the registers contain: ' CH=Cursor start line, CL=Cursor end line ' DH=Cursor Row (base 0), DL=Cursor column (base 0) '---------------------------------- DOSCursorRow = N1 + DH% ' Save user cursor row DOSCursorColumn = N1 + DL% ' Save user cursor column ' Mask Cursor Start Scan Line Bits DOSCursorStart = CH% AND N15 ' Save user cursor top scan line DOSCursorStop = CL% ' Save user cursor bottom scan line DOSCursorBit = CH% AND N32 ' Isolate user Cursor On/Off Bit ' Test for Cursor Off IF DOSCursorBit = N32 THEN ' Save state of user cursor DOSCursorState = N0 ELSE DOSCursorState = N1 END IF '---------------------------------- ' This is the *only* safe place to turn the user cursor off, as we're ' in the underlying program's video mode and page, here. BASIC ' statements don't know anything about this mode and page, so we use ' direct DOS video functions to accomplish this. AH% = &H01 ' Set Cursor Size function CL% = DOSCursorStop ' turn user cursor off CH% = DOSCursorStart CH% = CH% AND NOT N32 ' and turn it off GOSUB DOSBIOS2 '---------------------------------- DOSColor = SCREEN(N1, N1, N1) ' save DOS Colors CALL ColorDecode(DOSColor) ' (not sure this is save in all DOSForeground = ColorForeground ' modes, so looking into a replacement DOSBackground = ColorBackground ' for the BASIC SCREEN function.) ' Subnum = SubnumSave EXIT SUB DOSBIOS2: CALL DOSBIOSServices RETURN END SUB '========================================================================= SUB ScreenBottoms STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 72 IF NOT NewGuy AND NOT SrAutoOptions THEN CALL PopLine END IF CALL EscapeLine CALL ReturnLine CALL QuitLine Subnum = SubnumSave END SUB '========================================================================= SUB ScreenBottomsDelete STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 73 CALL PopLineDelete CALL EscapeLineDelete CALL ReturnLineDelete Subnum = SubnumSave END SUB '========================================================================= SUB SequenceEventsTable STATIC '========================================================================= ' Resequence Event Table When Alarm Rings Or After Event Editing DEFINT A-Z SubnumSave = Subnum Subnum = 65 IF EventTableStable THEN GOTO ExitPoint3 '------------------------------------------------------------------------- NormalAlarmBuild: ' Read the Event List. Decide To Resequence Only If needed. '------------------------------------------------------------------------- IF ClockScreen THEN RefreshInstructions = Yes END IF CALL ShowErase(N14, N25, N1, N80, SPACE$(N21) + _ "Please Wait--Building Alarm List") SchCnt$ = Blank8$ RedisplayNotesEvents = Yes EventsScheduled = N0 HeldDateTime# = 0# Badrec = No ExistingNullrec = No TimerSave! = TIMER '------------------------------------------------------------------------- FOR WhichEvent = N1 TO NumberofEvents CALL KeyStuff(KeyStatus) CALL MhIntToString(SchCnt$, (NumberofEvents% + N1% - WhichEvent%)) CALL ShowIt(N14, N25, N60, SchCnt$) '-------------------------------------------------------------------- ' Blink Event Table Initialize PendingEvents(WhichEvent) = N0 '-------------------------------------------------------------------- RecordPointer = N1 + WhichEvent ' Get Next Record--Sets Contents in CurrentEventRecord$ CALL GetApptRecord(RecordPointer) '-------------------------------------------------------------------- ' Test if Blanks In The Sequence--If So, Sets Resort Flag IF CurrentEventRecord$ = Blank80$ THEN ExistingNullrec = Yes GOTO NextRecord END IF '-------------------------------------------------------------------- ' Non-Blank Record '-------------------------------------------------------------------- ' Set Null Record If There Is One For Test IF ExistingNullrec THEN ' There was a blank record in the middle of non-blank ones Badrec = Yes END IF '-------------------------------------------------------------------- ' Very Old file format didn't have the year 'Fill In "19" In Record For Dates Which Don't Already Have It IF MID$(CurrentEventRecord$, N74, N2) = Blank2$ THEN CALL Myd2(CurrentEventRecord$, N74, N2, "19") END IF '--------------------------------------------------------------- ' Construct the Event Date/Time for Validation CALL MhMidString(EventDateTime$, N1%, N2%, CurrentEventRecord$, N74%) CALL MhMidString(EventDateTime$, N3%, N10%, CurrentEventRecord$, N1%) '--------------------------------------------------------------- ' Check for bad records (missing numerics, out of sequence) IF NumberError(EventDateTime$) THEN ' Non-numeric and non-blank ' blank out, write history, set flag to resort EventtoHistory = No HistoryBuffer$ = CurrentEventRecord$ CALL WritetoHistory CALL MhLset(ApptBuffer$, Blank80$) CALL PutApptRecord(RecordPointer) Badrec = Yes GOTO NextRecord END IF '--------------------------------------------------------------- ' Good Record, Go On CombinedDateTime# = VAL(EventDateTime$) IF CombinedDateTime# > 0# AND _ CombinedDateTime# < HeldDateTime# THEN ' Out-of-sequence but good record Badrec = Yes END IF HeldDateTime# = CombinedDateTime# '--------------------------------------------------------------- ' Bump Next Valid Slot Number EventsScheduled = EventsScheduled + N1 '--------------------------------------------------------------- ' Save Alarm Value In That Slot Alarms(EventsScheduled).Alarm = CombinedDateTime# ' In Case We Need To Sort, Save Appt File Position Alarms(EventsScheduled).Sequence = WhichEvent ' Build Alarms(x).Warning IF Pending THEN ' Skip warning and blink table if not desired CALL ComputePendingValue(Alarms(EventsScheduled).Alarm, _ Alarms(EventsScheduled).Warning) END IF '--------------------------------------------------------------- ' Cancel Automatic Pop Down if Alarm or Warning coming IF ((Pending AND Alarms(WhichEvent).Warning <= CurrentDateTime#) OR _ (Alarms(WhichEvent).Alarm <= CurrentDateTime#)) AND _ SrAutoPopDown AND NOT SrAutoPopDownHappened THEN '---------------------------------------------------------- SrAutoPopDownHappened = Yes IF AutoStarted THEN CALL MinorBeeper CALL ShowIt(N15, N16, Nm2, _ " ... and Automatic Pop Down Has Been Requested, But Cancelled! ") END IF END IF NextRecord: '-------------------------------------------------------------------- NEXT '------------------------------------------------------------------------- ' At this point, an Alarm List is built, with warning times if Pending ' is non-zero. If either blank records were found inbetween the good ' ones, or if the records contained bad data or were out of time ' sequence, the list is resorted and rewritten to the appt file. Else ' we get out here. Note that Alarms(I) may be more compressed than the ' state of the file; this would require sorting. ' In either case, EventsScheduled is solid at this point. ' Of course, there may be nothing to do also. '------------------------------------------------------------------------- IF NOT Badrec AND NOT EventsScheduled THEN GOTO FinishedSequence END IF '------------------------------------------------------------------------- StartSequencing: '-------------------------------------------------------------------- ' Sort Phase 1 -- Sort the Alarms(I) Array '------------------------------------------------------------------------- ExitKeys = No ' Keep Program from Exiting Prematurely '------------------------------------------------------------------------- IF EventsScheduled > N1 THEN ' Don't Sort Only One Event '-------------------------------------------------------------------- ' Sort the Alarms(I) Array. Note that this also sorts the warning ' values (.Warning) AND the appt file position records (.Sequence) CALL ShowErase(N14, N25, N1, N80, (SPACE$(N21) + _ "Please Wait--Sorting Alarm List")) '-------------------------------------------------------------------- ' Use Microsoft's Incredibly Fast Sort Algorithm from QB 4.50 SortLow = N1 SortHigh = EventsScheduled CALL QuickSort(SortLow, SortHigh) ' Sort Alarm Table END IF '-------------------------------------------------------------------- ' Sort Phase 2 -- Build Temporary File of Sorted Events '-------------------------------------------------------------------- ' Open Temporary Event Hold File CALL KillAFile(ApptFilename$ + ".cls") ' Start Fresh! OPEN "R", #FilenumApptSort, ApptFilename$ + ".cls", N80 FIELD #FilenumApptSort, N80 AS TempApptBuffer$ '-------------------------------------------------------------------- CALL ShowErase(N14, N25, N1, N80, (SPACE$(N21) + _ "Please Wait--Building Sorted Events")) SchCnt$ = Blank8$ EventPosition = N0 '-------------------------------------------------------------------- FOR I = N1 TO EventsScheduled CALL MhIntToString(SchCnt$, (EventsScheduled% - I% + N1%)) CALL ShowIt(N14, N25, N60, SchCnt$) ' No point in doing KeyStuff When ExitKeys is Off--Slows Us Down '--------------------------------------------------------------- ' Get the old record EventPosition = EventPosition + N1 GET #FilenumAppt, N1 + Alarms(I).Sequence CALL MhLset(TempApptBuffer$, ApptBuffer$) ' Write it to the new position in the temporary file PUT #FilenumApptSort, EventPosition '--------------------------------------------------------------- NEXT '-------------------------------------------------------------------- ' Sort Phase 3 -- Rewrite Temporary File to Appointment File '-------------------------------------------------------------------- CALL ShowErase(N14, N25, N1, N80, (SPACE$(N21) + _ "Please Wait--Resaving Event List")) SchCnt$ = Blank8$ FOR I = N1 TO NumberofEvents '-------------------------------------------------------------------- ' Note that ENTIRE file is written, not just EventsScheduled '--------------------------------------------------------------- CALL MhIntToString(SchCnt$, (NumberofEvents% - I% + N1%)) CALL ShowIt(N14, N25, N60, SchCnt$) ' Copy Sorted List Back to Appointment File IF I <= EventsScheduled THEN GET #FilenumApptSort, I CALL MhLset(ApptBuffer$, TempApptBuffer$) ELSE CALL MhLset(ApptBuffer$, Blank80$) END IF CALL PutApptRecord(N1 + I) NEXT '-------------------------------------------------------------------- CLOSE #FilenumApptSort CALL KillAFile(ApptFilename$ + ".cls") '-------------------------------------------------------------------- ' Done '-------------------------------------------------------------------- FinishedSequence: IF ClockScreen THEN CALL Kolors(N3) ELSEIF OnEditPage THEN CALL Kolors(N5) ELSE CALL Kolors(N6) END IF CALL ShowIt(N0, N25, N1, Blank80$) ' Flush I/O Buffers for Safety By Closing and Opening File CALL OpenAppts EventTableStable = Yes ExitKeys = Yes ExitPoint3: Subnum = SubnumSave END SUB '========================================================================= SUB SetArrays STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 74 ' Set/Change Definitions Based Upon Event Table Size NumberofEvents = N20 * InString(ValidSizes$, EventSizeCode$) IF NumberofEvents <> EventTableSize THEN EventTableSize = NumberofEvents EventTableStable = No TimerSave! = TIMER END IF NumberofNotes = N20 * InString(ValidSizes$, NoteSizeCode$) OldNumberEvents = NumberofEvents OldNumberNotes = NumberofNotes ' Redefine Appt File Pointers StartingNote = N2 + NumberofEvents StartingHistory = N2 + NumberofEvents + NumberofNotes Subnum = SubnumSave END SUB '========================================================================= SUB SetColors STATIC '========================================================================= DEFINT A-Z SubnumSave = Subnum Subnum = 75 ColorError = N0 FOR ColorPair = N1 TO N7 ' Initialize Screen With Current Colors DetermineWhichPair: SELECT CASE ColorPair CASE 1 CALL Kolors(N1) Csav1 = Cl1f Csav2 = Cl1b CASE 2 CALL Kolors(N2) Csav1 = Cl2f Csav2 = Cl2b CASE 3 CALL Kolors(N3) Csav1 = Cl3f Csav2 = Cl3b CASE N4 CALL Kolors(N4) Csav1 = Cl4f Csav2 = Cl4b CASE N5 CALL Kolors(N5) Csav1 = Cl5f Csav2 = Cl5b CASE 6 CALL Kolors(N6) Csav1 = Cl6f Csav2 = Cl6b CASE 7 CALL Kolors(N7) Csav1 = Chf Csav2 = Chb END SELECT CALL ClearScreenNormal(N1) ScreenTitles$(N1) = " Change " + ColorPairUses$(ColorPair) + _ " Color (Screen" + STR$(ColorPair) + " of 7)" CALL Titles(Nm1) IF ColorError THEN CALL MajorBeeper KolorSet = N18 GOSUB WarningOrBlanking ColorError = N0 END IF CALL ShowIt(N6, N23, N1, "(Note: 8-Color Monitors Show No ") CALL ShowIt(N0, Nm1, N0, " Difference Between The 1st 8 ") CALL ShowIt(N0, Nm1, N0, " And The 2nd 8 Foreground Colors)") FOR ColorPairType = N1 TO N2 ' Calculate Displacements Based On Which Color Is Being Changed XCL = N16 + 35 * (ColorPairType - N1) WhichColor = (ColorPair - N1) * N2 + ColorPairType IF ColorPairType = N1 THEN ListSize = N16 ELSE ListSize = N8 END IF ' Fill 16 Color List for Foreground, 8 for Background FOR Clist = N1 TO ListSize MenuLines(Clist) = Colors$(Clist) NEXT Clist ' Get Current Color Choice ' Store Currently Chosen Colors For Menu SELECT CASE WhichColor CASE 1 ColorChoices(WhichColor) = Cl1f MenuColorBack = Cl1b CASE 2 ColorChoices(WhichColor) = Cl1b MenuColorBack = Cl1f CASE 3 ColorChoices(WhichColor) = Cl2f MenuColorBack = Cl2b CASE N4 ColorChoices(WhichColor) = Cl2b MenuColorBack = Cl2f CASE N5 ColorChoices(WhichColor) = Cl3f MenuColorBack = Cl3b CASE 6 ColorChoices(WhichColor) = Cl3b MenuColorBack = Cl3f CASE 7 ColorChoices(WhichColor) = Cl4f MenuColorBack = Cl4b CASE N8 ColorChoices(WhichColor) = Cl4b MenuColorBack = Cl4f CASE N9 ColorChoices(WhichColor) = Cl5f MenuColorBack = Cl5b CASE N10 ColorChoices(WhichColor) = Cl5b MenuColorBack = Cl5f CASE N11 ColorChoices(WhichColor) = Cl6f MenuColorBack = Cl6b CASE N12 ColorChoices(WhichColor) = Cl6b MenuColorBack = Cl6f CASE N13 ColorChoices(WhichColor) = Chf MenuColorBack = Chb CASE N14 ColorChoices(WhichColor) = Chb MenuColorBack = Chf END SELECT MenuColorFore = ColorChoices(WhichColor) ColorForeground = MenuColorFore ColorBackground = MenuColorBack CALL Kolors(N0) ' Special Colors CALL ShowIt(N0, N4, XCL + N1, (ColorPairTypes$(ColorPairType))) ' Display Menu For Change MenuChoice = N1 + ColorChoices(WhichColor) IF ColorPairType = N1 THEN ColorSave1 = MenuChoice - N1 ELSE ColorSave2 = MenuChoice - N1 END IF CALL MenuDriver(ListSize, MenuChoice, N5, XCL, _ MenuSingleLine, N0, N1, N1) ColorForeground = Csav1 ColorBackground = Csav2 KolorSet = N6 GOSUB WarningOrBlanking ' Delete Error Message ' Normal Out On Beginning of Pair IF MenuExit = MenuCancelled AND ColorPairType = N1 THEN GOTO RewriteColorFile END IF ' Out Before End of Pair Compares With Previous Value ' Set the Changed Color ColorChoices(WhichColor) = MenuChoice - N1 ' Re-Establish Color Setting From Menu Choice GOSUB SaveChangedColor NEXT ColorPairType ' Reject Pairs Which Are Equal ColorError = N0 IF ColorChoices(WhichColor) = ColorChoices(WhichColor - N1) THEN ColorError = N1 ColorChoices(WhichColor) = ColorSave2 GOSUB SaveChangedColor WhichColor = WhichColor - N1 ColorChoices(WhichColor) = ColorSave1 GOSUB SaveChangedColor GOTO DetermineWhichPair ELSEIF MenuExit = MenuCancelled THEN EXIT FOR END IF NEXT ColorPair RewriteColorFile: WhichColor = N0 CALL WriteCalfig CALL ClearScreenNormal(N1) CALL DirectReturnCheck GOTO ExitPoint4 ' Rewrite SaveChangedColor: SELECT CASE WhichColor ' Save Changed Color From Menu CASE 1 Cl1f = ColorChoices(WhichColor) CASE 2 Cl1b = ColorChoices(WhichColor) CASE 3 Cl2f = ColorChoices(WhichColor) CASE N4 Cl2b = ColorChoices(WhichColor) CASE 5 Cl3f = ColorChoices(WhichColor) CASE 6 Cl3b = ColorChoices(WhichColor) CASE 7 Cl4f = ColorChoices(WhichColor) CASE N8 Cl4b = ColorChoices(WhichColor) CASE N9 Cl5f = ColorChoices(WhichColor) CASE N10 Cl5b = ColorChoices(WhichColor) CASE N11 Cl6f = ColorChoices(WhichColor) CASE N12 Cl6b = ColorChoices(WhichColor) CASE N13 Chf = ColorChoices(WhichColor) CASE N14 Chb = ColorChoices(WhichColor) END SELECT RETURN '------------------------------------------------------------------------- WarningOrBlanking: CALL Kolors(KolorSet) ' Warning or blanking color ' Blank Error Area CALL ShowMult(N0, N7, N62, N19, N4) ' Box for message or erase it ' Print Error Message IF KolorSet <> N6 THEN CALL ShowIt(N0, N0, N0, " Background and ") CALL ShowIt(N0, Nm1, N0, " foreground colors ") CALL ShowIt(N0, Nm1, N0, " must be different ") CALL ShowIt(N0, Nm1, N0, " -- try again !! ") END IF RETURN '------------------------------------------------------------------------- ExitPoint4: Subnum = SubnumSave END SUB '========================================================================= SUB SetCurrentDirectory (EntryPoint) STATIC '========================================================================= ' Sets Calendar's, User's, or Swap Path's Directory DEFINT A-Z SubnumSave = Subnum Subnum = 76 '------------------------------------------------------------------------- SELECT CASE EntryPoint CASE 0 ' User's Directory DirectorySet$ = DirectoryUser$ DriveSet = DriveUser CASE 1 ' Calendar's Directory DirectorySet$ = DirectoryReturn$ DriveSet = DriveReturn CASE 2 ' Disk Swap Directory DirectorySet$ = SrSwapPath$ + CHR$(N0) DriveSet = InString(LEFT$(PathLegalChars$, N26), _ LEFT$(SrSwapPath$, N1)) END SELECT CALL MhDir(N2%, DriveSet%, DirectorySet$, Ecode%) ' Set IF Ecode AND EntryPoint <> N2 THEN ERROR 255 END IF Subnum = SubnumSave END SUB ' Drive and Directory '======================================================================== '======================== END OF CAL5.BAS ============================= '========================================================================