-- file: ChollaStepList.mesa -- edited by Barth, August 20, 1981 11:05 PM -- edited by Brotz, March 3, 1983 5:11 PM -- edited by Crowther, December 23, 1981 10:13 AM DIRECTORY Ascii, ccD: FROM "ChollaCmdDefs", csD: FROM "CoreStreamDefs", dsD: FROM "DisplayDefs", Editor, exD: FROM "ExceptionDefs", inD: FROM "InteractorDefs", intCommon, lmD: FROM "LaurelMenuDefs", MessageParse, opD: FROM "OperationsDefs", Storage, String, tsD: FROM "TOCSelectionDefs", vmD: FROM "VirtualMgrDefs"; ChollaStepList: PROGRAM IMPORTS ccD, dsD, Editor, exD, inD, intC: intCommon, lmD, MessageParse, Storage, String, tsD, vmD EXPORTS ccD = BEGIN stepListTopHp, stepListMiddleHp, stepLowerHp, stepListBracketsHp, prototypesMiddleHp, prototypesLowerHp: inD.HousePtr; SLStepList: inD.CommandProcedure = BEGIN IF ~ccD.IsAuthorized[onlooker, hp] THEN RETURN; SELECT TRUE FROM ~confirmed AND ~inD.ConfirmBrackets[hp: hp.nextHouse, fileExtension: "StepList.chml."L] => NULL; hp.nextHouse.text.length = 0 => BEGIN String.AppendString[hp.nextHouse.text, ccD.stepListRunName]; hp.nextHouse.houseRefresher[hp.nextHouse]; exD.DisplayExceptionString["Must name a run."L]; END; hp.nextHouse.text.length > 20 => exD.DisplayExceptionString["Run name is too long!"L]; ENDCASE => BEGIN ccD.PreserveChangeInDoneFile[]; IF InstallStepList[stepListBracketsHp.text] THEN DoLowerMenu[ccD.stepListLowerHp]; END; END; -- of SLStepList -- InstallStepList: PUBLIC PROCEDURE [runName: STRING] RETURNS [worked: BOOLEAN] = BEGIN -- it should compute the current step as the first unstarted step -- and set the selection for it IF ~MakeStepListCurrent[runName] THEN RETURN[FALSE]; intC.bboardCommandHouse.command _ SLBBoardCommand; intC.userBracketsHouse.nextHouse _ stepListTopHp; inD.ChangeCommandMenu [cnp: intC.mailCommandNbr, region: intC.mailCommandRegion, linesToKeep: 2]; intC.tocCommandNbr.houses _ stepListMiddleHp; inD.ChangeCommandMenu [cnp: intC.tocCommandNbr, region: intC.TOCCommandRegion, linesToKeep: 0]; DoLowerMenu[ccD.stepListLowerHp]; RETURN[TRUE]; END; -- of InstallStepList -- MakeStepListCurrent: PROCEDURE [runName: STRING] RETURNS [BOOLEAN] = BEGIN fileName: STRING _ [ccD.tocCacheFileStringLength]; tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle; key: CARDINAL; IF runName[0] # '[ AND runName.length >= 18 THEN {exD.DisplayExceptionString["Run name is too long."L]; RETURN[FALSE]}; ccD.CleanupDisplayMessage[]; ccD.displayedStep _ 0; IF tnp.toc # NIL THEN {key _ vmD.WaitForLock[tnp.toc]; toc _ tnp.toc; tnp.toc _ NIL; vmD.UnlockTOC[toc, key]}; dsD.ClearRectangle[inD.leftMargin, inD.rightMargin, tnp.topY, tnp.bottomY]; String.AppendString[fileName, runName]; String.AppendString[fileName, "StepList.chml"L]; [toc, key] _ ccD.GetTOCForFile[fileName, stepList]; IF toc = NIL THEN {exD.DisplayExceptionString["Cannot get Step list file."L]; RETURN[FALSE]}; SetSelectionToStepToDo[toc, key]; -- Order in the String appends is critical: runName may be = to stepListBracketsHp.text. ccD.stepListRunName.length _ 0; String.AppendString[ccD.stepListRunName, runName]; stepListBracketsHp.text.length _ 0; String.AppendString[stepListBracketsHp.text, ccD.stepListRunName]; tnp.toc _ toc; dsD.ClearRectangle[inD.leftMargin, inD.rightMargin, tnp.topY, tnp.bottomY]; inD.TOCTextPainter[tnp, key]; vmD.UnlockTOC[toc, key]; RETURN[TRUE]; END; -- of MakeStepListCurrent -- SLLaurelCommand: inD.CommandProcedure = BEGIN ccD.PreserveChangeInDoneFile[]; ccD.RestoreLaurel[]; END; -- of SLLaurelCommand -- SLBBoardCommand: inD.CommandProcedure = BEGIN IF ~ccD.IsAuthorized[onlooker, hp] THEN RETURN; ccD.PreserveChangeInDoneFile[]; ccD.CleanupDisplayMessage[]; ccD.InstallBB[]; END; -- of SLBBoardCommand -- PrototypesCommand: inD.CommandProcedure = BEGIN tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle; key: CARDINAL; IF intC.cmCommandNbr.houses = prototypesLowerHp THEN RETURN; IF ~ccD.IsAuthorized[maven, hp] THEN RETURN; ccD.PreserveChangeInDoneFile[]; ccD.CleanupDisplayMessage[]; ccD.displayedStep _ 0; IF tnp.toc # NIL THEN {key _ vmD.WaitForLock[tnp.toc]; toc _ tnp.toc; tnp.toc _ NIL; vmD.UnlockTOC[toc, key]}; [toc, key] _ ccD.GetTOCForFile["StepListPrototypes"L, prototypes]; tnp.toc _ toc; intC.tocCommandNbr.houses _ prototypesMiddleHp; inD.ChangeCommandMenu [cnp: intC.tocCommandNbr, region: intC.TOCCommandRegion, linesToKeep: 0]; DoLowerMenu[prototypesLowerHp]; tsD.ResetTOCSelection[toc, key]; dsD.ClearRectangle[inD.leftMargin, inD.rightMargin, tnp.topY, tnp.bottomY]; inD.TOCTextPainter[tnp, key]; vmD.UnlockTOC[toc, key]; END; -- of PrototypesCommand -- CurrentStep: PUBLIC PROCEDURE RETURNS [entry: vmD.TOCIndex] = BEGIN toc: vmD.TOCHandle = ccD.cacheTable[stepList].a.toc; key: CARDINAL = vmD.WaitForLock[toc]; last: vmD.TOCIndex = tsD.LastSelectedEntry[toc, key]; entry _ tsD.FirstSelectedEntry[toc, key]; IF entry # last OR entry # ccD.displayedStep THEN entry _ 0; IF entry = 0 THEN exD.DisplayExceptionString["Selection missmatch"L]; vmD.UnlockTOC[toc, key]; END; -- of CurrentStep -- StepCommand: inD.CommandProcedure = BEGIN tocString: STRING _ [opD.maxTOCStringLength]; tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; key: CARDINAL = vmD.WaitForLock[toc]; entry: vmD.TOCIndex _ tsD.FirstSelectedEntry[toc, key]; last: vmD.TOCIndex = tsD.LastSelectedEntry[toc, key]; IF ~ccD.IsAuthorized[onlooker, hp] THEN {vmD.UnlockTOC[toc, key]; RETURN}; IF entry # last OR entry = 0 THEN {exD.DisplayExceptionString["Need one selection"L]; vmD.UnlockTOC[toc, key]; RETURN}; IF entry = ccD.displayedStep AND entry = ccD.currentStepNumber THEN BEGIN entry _ MIN[entry + 1, toc.indexFF - 1]; inD.MakeTOCIndexVisible[entry, key]; tsD.DeconsiderAll[tnp, key]; tsD.SetTOCSelection[toc, key, entry]; inD.Consider[entry, entry, tnp, key]; END; vmD.GetTOCString[toc, key, entry, tocString]; vmD.UnlockTOC[toc, key]; ccD.displayedStep _ entry; ccD.CleanupDisplayMessage[]; DoLowerMenu[stepLowerHp]; ccD.StepOperation[tocString]; END; -- of StepCommand -- StepListAndPrototypesDisplayCommand: inD.CommandProcedure = BEGIN IF ~ccD.IsAuthorized[onlooker, hp] THEN RETURN; inD.DisplayMessageCommand[hp, TRUE]; END; -- of StepListAndPrototypesDisplayCommand -- MarkCommand: inD.CommandProcedure = BEGIN tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; key: CARDINAL; cm: vmD.ComposedMessagePtr; index: vmD.TOCIndex; i: vmD.CharIndex; IF ~ccD.IsAuthorized[technician, hp] THEN RETURN; key _ vmD.WaitForLock[toc]; cm _ vmD.AllocateComposedMessageObject[]; FOR index _ tsD.FirstSelectedEntry[toc, key], tsD.NextSelectedEntry[toc, key, index] UNTIL index = 0 DO fieldList, subjectFL: MessageParse.FieldList; count: CARDINAL; ccD.LoadComposedMessage[toc, key, index, cm]; fieldList _ MessageParse.MakeFieldList[cm]; [subjectFL, count] _ MessageParse.LocateField[fieldList, "Subject"L]; IF count = 0 THEN exD.SysBug[]; FOR i IN [subjectFL.valueStart .. subjectFL.valueEnd) DO IF vmD.GetMessageChar[cm, i] = '/ THEN BEGIN i _ i + 1; IF i >= subjectFL.valueEnd THEN EXIT; IF vmD.GetMessageChar[cm, i] = ccD.stepListMarkChar THEN BEGIN vmD.DeleteRangeInMessage[[i, i + 1, cm]]; subjectFL.valueEnd _ subjectFL.valueEnd - 1; MessageParse.UpdateFieldList[subjectFL.next, -1]; END ELSE BEGIN vmD.StartMessageInsertion[cm, i]; vmD.InsertMessageChar[cm, ccD.stepListMarkChar]; vmD.StopMessageInsertion[cm]; subjectFL.valueEnd _ subjectFL.valueEnd + 1; MessageParse.UpdateFieldList[subjectFL.next, 1]; END; [] _ ccD.SendChollaMail[replace, step, toc, key, index, cm, @fieldList]; EXIT; END; ENDLOOP; MessageParse.FreeFieldList[fieldList]; ENDLOOP; inD.UpdateTOCThumbLine[tnp, key]; vmD.UnlockTOC[toc, key]; vmD.FreeVirtualMessageObject[cm]; END; -- of MarkCommand -- EditListCommand: inD.CommandProcedure = BEGIN mnp: inD.MessageTextNbrPtr = intC.cmTextNbr; cm: vmD.ComposedMessagePtr; toc: vmD.TOCHandle = intC.tocTextNbr.toc; key: CARDINAL; tocString: STRING _ [opD.maxTOCStringLength]; start: CARDINAL; IF ~ccD.IsAuthorized[maven, hp] THEN RETURN; IF ~confirmed AND ~inD.Confirm[1] THEN RETURN; ccD.PreserveChangeInDoneFile[]; DoLowerMenu[ccD.stepListLowerHp]; Editor.SwapMessageWithDeletionBuffer[mnp]; cm _ vmD.ComposedMessage[mnp.message]; vmD.InitComposedMessage[cm, ""L]; vmD.StartMessageInsertion[cm, 0]; key _ vmD.WaitForLock[toc]; FOR i: vmD.TOCIndex _ tsD.FirstSelectedEntry[toc, key], tsD.NextSelectedEntry[toc, key, i] UNTIL i = 0 DO vmD.GetTOCString[toc, key, i, tocString]; start _ 0; THROUGH [1 .. 2] DO UNTIL tocString[start] = opD.substringSeparator DO start _ start + 1; ENDLOOP; start _ start + 1; ENDLOOP; [] _ vmD.InsertSubstringInMessage[cm, tocString, start, tocString.length - start]; [] _ vmD.InsertMessageChar[cm, Ascii.CR]; ENDLOOP; vmD.StopMessageInsertion[cm]; vmD.UnlockTOC[toc, key]; ccD.ResetTheEditor[TRUE]; END; -- of EditListCommand -- EditEntryCommand: inD.CommandProcedure = BEGIN mnp: inD.MessageTextNbrPtr = intC.cmTextNbr; cm: vmD.ComposedMessagePtr; toc: vmD.TOCHandle = intC.tocTextNbr.toc; key: CARDINAL; tocIndex: vmD.TOCIndex; fieldList: MessageParse.FieldList; IF ~ccD.IsAuthorized[maven, hp] THEN RETURN; key _ vmD.WaitForLock[toc]; tocIndex _ tsD.FirstSelectedEntry[toc, key]; vmD.UnlockTOC[toc, key]; IF tocIndex = 0 THEN {exD.DisplayExceptionString["An entry must be selected."L]; RETURN}; IF ~confirmed AND ~inD.Confirm[1] THEN RETURN; ccD.PreserveChangeInDoneFile[]; DoLowerMenu[ccD.stepListLowerHp]; Editor.SwapMessageWithDeletionBuffer[mnp]; cm _ vmD.ComposedMessage[mnp.message]; key _ vmD.WaitForLock[toc]; ccD.LoadComposedMessage[toc, key, tocIndex, cm]; vmD.UnlockTOC[toc, key]; fieldList _ MessageParse.MakeFieldList[cm]; MessageParse.DeleteField[cm, @fieldList, "UniqueID"L]; MessageParse.DeleteField[cm, @fieldList, "ThisID"L]; MessageParse.FreeFieldList[fieldList]; ccD.ResetTheEditor[TRUE]; END; -- of EditEntryCommand -- InsertInStepListCommand: inD.CommandProcedure = BEGIN cm: vmD.ComposedMessagePtr = vmD.ComposedMessage[intC.cmTextNbr.message]; tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; fieldList, subjectFL: MessageParse.FieldList _ NIL; nIDs: CARDINAL; valid: BOOLEAN; count, key: CARDINAL; first, preInsertFF: vmD.TOCIndex; IF ~ccD.IsAuthorized[maven, hp] THEN RETURN; ccD.StartMultiTOCOperation[]; BEGIN -- for EXITS -- key _ vmD.WaitForLock[toc]; first _ tsD.FirstSelectedEntry[toc, key] + 1; preInsertFF _ toc.indexFF; IF first < FirstEditableStep[toc, key] THEN BEGIN exD.DisplayExceptionString["Editing the step list before a started step is not allowed."L]; GO TO Return; END; fieldList _ MessageParse.MakeFieldList[cm]; [subjectFL, count] _ MessageParse.LocateField[fieldList, "Subject"L]; SELECT count FROM 0 => {[valid, nIDs] _ ValidateInsertList[cm, fieldList]; IF ~valid THEN GO TO Return}; 1 => BEGIN string: STRING _ [opD.maxTOCStringLength]; IF subjectFL.valueEnd - subjectFL.valueStart > opD.maxTOCStringLength THEN {exD.DisplayExceptionString["Entry too long!"L]; GO TO Return}; MessageParse.GetWholeField[cm, subjectFL, "Subject"L, string]; IF ~ValidateOneStepListLine[string] THEN GO TO Return; nIDs _ 1; END; ENDCASE => {exD.DisplayExceptionString["Too many Subject: fields!"L]; GO TO Return}; tsD.DeconsiderAll[tnp, key]; tsD.ResetTOCSelection[toc, key]; MessageParse.ReplaceOrAppendField[cm, @fieldList, "Run"L, ccD.stepListRunName]; IF ~ccD.SendChollaMail[action: insert, type: step, toc: toc, key: key, index: first, cm: cm, fieldListPtr: @fieldList, nIDs: nIDs] THEN exD.DisplayExceptionString["Could not insert in step list!"L]; IF toc.indexFF = preInsertFF THEN first _ first - 1; IF first > 0 THEN tsD.SetTOCSelection[toc, key, first]; tsD.ConsiderAll[tnp, key]; inD.UpdateTOCThumbLine[tnp, key]; EXITS Return => NULL; END; -- of EXITS block -- MessageParse.FreeFieldList[fieldList]; vmD.UnlockTOC[toc, key]; ccD.FinishMultiTOCOperation[]; END; -- of InsertInStepListCommand -- ValidateInsertList: PROCEDURE [cm: vmD.ComposedMessagePtr, fieldList: MessageParse.FieldList] RETURNS [valid: BOOLEAN, nIDs: CARDINAL] = BEGIN char: CHARACTER; string: STRING _ [opD.maxTOCStringLength]; nIDs _ 0; valid _ FALSE; FOR i: vmD.CharIndex IN [0 .. vmD.GetMessageSize[cm]) DO IF (char _ vmD.GetMessageChar[cm, i]) = Ascii.CR THEN BEGIN IF string.length > 0 THEN BEGIN IF ValidateOneStepListLine[string] THEN {nIDs _ nIDs + 1; string.length _ 0} ELSE GO TO Malformed; END; END ELSE BEGIN IF string.length >= string.maxlength THEN {exD.DisplayExceptionString["Entry too long!"L]; GO TO Malformed}; string[string.length] _ char; string.length _ string.length + 1; END; REPEAT Malformed => BEGIN target: inD.TextSelectionPtr = @intC.target; exD.DisplayExceptionStringOnLine ["Malformed step list entry near underlined selection."L, 2]; Editor.DeUnderlineSelection[selection: target, underline: target]; target^ _ inD.TextSelection[intC.cmTextNbr, i, i + 1, i, 0, char, FALSE]; intC.newTargetSelection _ TRUE; Editor.UnderlineSelection[selection: target, underline: target]; inD.IdleLoop[]; RETURN; END; ENDLOOP; IF nIDs = 0 THEN {exD.DisplayExceptionString["Cannot insert: no steps are specified."L]; RETURN}; IF vmD.GetMessageChar[cm, 0] # Ascii.CR THEN BEGIN vmD.StartMessageInsertion[cm, 0]; vmD.InsertMessageChar[cm, Ascii.CR]; vmD.StopMessageInsertion[cm]; MessageParse.UpdateFieldList[fieldList, 1]; END; valid _ TRUE; END; -- of ValidateInsertList -- ValidateOneStepListLine: PROCEDURE [string: STRING] RETURNS [valid: BOOLEAN] = BEGIN slashCount: CARDINAL _ 0; stepName: STRING _ [2]; specName: STRING _ [2]; dataName: STRING _ [0]; p: ccD.ParsedStep _ [specName, 0, dataName, 0, stepName, none, 0, 0]; FOR i: CARDINAL IN [0 .. string.length) DO IF string[i] = '/ THEN slashCount _ slashCount + 1; ENDLOOP; ccD.ParseStep[string, @p]; valid _ FALSE; SELECT TRUE FROM p.stepName.length = 0 => exD.DisplayExceptionString["No /StepName/"L]; slashCount MOD 2 = 1 => exD.DisplayExceptionString["Unmatched slash ( / )."L]; p.status = none => exD.DisplayExceptionString["Invalid status word."L]; p.specName.length = 0 => exD.DisplayExceptionString["No specification listed."L]; ENDCASE => valid _ TRUE; END; -- of ValidateOneStepListLine -- ReplaceEntryCommand: inD.CommandProcedure = BEGIN tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; fieldList, subjectFL, deleteFL: MessageParse.FieldList _ NIL; cm: vmD.ComposedMessagePtr = vmD.ComposedMessage[intC.cmTextNbr.message]; deleteCM: vmD.ComposedMessagePtr; index, firstIndex, lastIndex: vmD.TOCIndex; count, key, nIDs: CARDINAL; valid: BOOLEAN; IF ~ccD.IsAuthorized[maven, hp] THEN RETURN; ccD.StartMultiTOCOperation[]; BEGIN -- for EXITS -- key _ vmD.WaitForLock[toc]; firstIndex _ lastIndex _ tsD.FirstSelectedEntry[toc, key]; IF firstIndex < FirstEditableStep[toc, key] THEN BEGIN exD.DisplayExceptionString["Editing the step list before a started step is not allowed."L]; GO TO Return; END; IF firstIndex = 0 THEN {exD.DisplayExceptionString["An entry must be selected"L]; GO TO Return}; UNTIL (index _ tsD.NextSelectedEntry[toc, key, lastIndex]) = 0 DO IF index # lastIndex + 1 THEN {exD.DisplayExceptionString["Cannot replace discontiguous steps!"L]; GO TO Return}; lastIndex _ index; ENDLOOP; fieldList _ MessageParse.MakeFieldList[cm]; [subjectFL, count] _ MessageParse.LocateField[fieldList, "Subject"L]; SELECT count FROM 0 => {[valid, nIDs] _ ValidateInsertList[cm, fieldList]; IF ~valid THEN GO TO Return}; 1 => BEGIN string: STRING _ [opD.maxTOCStringLength]; IF subjectFL.valueEnd - subjectFL.valueStart > opD.maxTOCStringLength THEN {exD.DisplayExceptionString["Entry too long!"L]; GO TO Return}; MessageParse.GetWholeField[cm, subjectFL, "Subject"L, string]; IF ~ValidateOneStepListLine[string] THEN GO TO Return; nIDs _ 1; END; ENDCASE => {exD.DisplayExceptionString["Too many Subject: fields!"L]; GO TO Return}; MessageParse.ReplaceOrAppendField[cm, @fieldList, "Run"L, ccD.stepListRunName]; deleteCM _ vmD.AllocateComposedMessageObject[]; tsD.DeconsiderAll[tnp, key]; tsD.ResetTOCSelection[toc, key]; FOR index DECREASING IN [firstIndex .. lastIndex] DO ccD.LoadComposedMessage[toc, key, index, deleteCM]; deleteFL _ MessageParse.MakeFieldList[deleteCM]; IF ~ccD.SendChollaMail[delete, step, toc, key, index, deleteCM, @deleteFL] THEN exD.DisplayExceptionString["Could not delete entry!"L]; MessageParse.FreeFieldList[deleteFL]; ENDLOOP; vmD.FreeVirtualMessageObject[deleteCM]; IF ~ccD.SendChollaMail[action: insert, type: step, toc: toc, key: key, index: firstIndex, cm: cm, fieldListPtr: @fieldList, nIDs: nIDs] THEN exD.DisplayExceptionString["Could not insert entry!"L]; inD.UpdateTOCThumbLine[tnp, key]; EXITS Return => NULL; END; -- of EXITS block -- vmD.UnlockTOC[toc, key]; ccD.FinishMultiTOCOperation[]; MessageParse.FreeFieldList[fieldList]; END; -- of ReplaceEntryCommand -- DeleteEntryCommand: inD.CommandProcedure = BEGIN tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; key: CARDINAL; cm: vmD.ComposedMessagePtr _ vmD.AllocateComposedMessageObject[]; prev: vmD.TOCIndex; ccD.StartMultiTOCOperation[]; key _ vmD.WaitForLock[toc]; SELECT TRUE FROM ~ccD.IsAuthorized[maven, hp] => NULL; tsD.TOCSelectionEmpty[toc, key] => exD.DisplayExceptionString["An entry must be selected"L]; tsD.FirstSelectedEntry[toc, key] < FirstEditableStep[toc, key] => exD.DisplayExceptionString["Editing the step list before a started step is not allowed."L]; (confirmed OR inD.Confirm[1]) => FOR tocIndex: vmD.TOCIndex _ tsD.LastSelectedEntry[toc, key], prev UNTIL tocIndex = 0 DO fieldList: MessageParse.FieldList; prev _ tsD.PrevSelectedEntry[toc, key, tocIndex]; tsD.RemoveRange[toc, key, tocIndex, tocIndex]; ccD.LoadComposedMessage[toc, key, tocIndex, cm]; fieldList _ MessageParse.MakeFieldList[cm]; IF ~ccD.SendChollaMail[delete, step, toc, key, tocIndex, cm, @fieldList] THEN exD.DisplayExceptionString["Could not delete entry!"L]; MessageParse.FreeFieldList[fieldList]; ENDLOOP; ENDCASE; inD.UpdateTOCThumbLine[tnp, key]; vmD.UnlockTOC[toc, key]; ccD.FinishMultiTOCOperation[]; vmD.FreeVirtualMessageObject[cm]; END; -- of DeleteEntryCommand -- PrototypesInsertCommand: inD.CommandProcedure = BEGIN cm: vmD.ComposedMessagePtr = vmD.ComposedMessage[intC.cmTextNbr.message]; tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; key: CARDINAL _ vmD.WaitForLock[toc]; tocIndex: vmD.TOCIndex _ tsD.FirstSelectedEntry[toc, key] + 1; IF ccD.IsAuthorized[maven, hp] THEN BEGIN fieldList: MessageParse.FieldList; tsD.DeconsiderAll[tnp, key]; tsD.ResetTOCSelection[toc, key]; fieldList _ MessageParse.MakeFieldList[cm]; BEGIN -- for EXITS -- IF MessageParse.LocateField[fieldList, "Subject"L].count = 0 THEN BEGIN exD.DisplayExceptionString ["No Subject: field! Are you sure you want to modify the Prototypes file?"L]; IF ~inD.Confirm[2] THEN GO TO DontWantTo; END; IF ccD.SendChollaMail[insert, prototypes, toc, key, tocIndex, cm, @fieldList] THEN tsD.SetTOCSelection[toc, key, tocIndex] ELSE exD.DisplayExceptionString["Malformed prototypes message!"L]; EXITS DontWantTo => NULL; END; -- of block for EXITS -- MessageParse.FreeFieldList[fieldList]; tsD.ConsiderAll[tnp, key]; inD.UpdateTOCThumbLine[tnp, key]; END; vmD.UnlockTOC[toc, key]; END; -- of PrototypesInsertCommand -- PrototypesReplaceCommand: inD.CommandProcedure = BEGIN cm: vmD.ComposedMessagePtr = vmD.ComposedMessage[intC.cmTextNbr.message]; tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; key: CARDINAL _ vmD.WaitForLock[toc]; tocIndex: vmD.TOCIndex _ tsD.FirstSelectedEntry[toc, key]; SELECT TRUE FROM ~ccD.IsAuthorized[maven, hp] => NULL; tocIndex = 0 => exD.DisplayExceptionString["An entry must be selected"L]; ENDCASE => BEGIN fieldList: MessageParse.FieldList _ MessageParse.MakeFieldList[cm]; CopyUniqueIDsIntoMessage[toc, key, tocIndex, cm, @fieldList]; IF ~ccD.SendChollaMail[replace, prototypes, toc, key, tocIndex, cm, @fieldList] THEN exD.DisplayExceptionString["Could not replace prototype message!"L]; MessageParse.FreeFieldList[fieldList]; END; inD.UpdateTOCThumbLine[tnp, key]; vmD.UnlockTOC[toc, key]; END; -- of PrototypesReplaceCommand -- PrototypesDeleteCommand: inD.CommandProcedure = BEGIN tnp: inD.TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle = tnp.toc; key: CARDINAL _ vmD.WaitForLock[toc]; cm: vmD.ComposedMessagePtr _ vmD.AllocateComposedMessageObject[]; prev: vmD.TOCIndex; SELECT TRUE FROM ~ccD.IsAuthorized[maven, hp] => NULL; tsD.TOCSelectionEmpty[toc, key] => exD.DisplayExceptionString["An entry must be selected"L]; (confirmed OR inD.Confirm[1]) => FOR tocIndex: vmD.TOCIndex _ tsD.LastSelectedEntry[toc, key], prev UNTIL tocIndex = 0 DO fieldList: MessageParse.FieldList; prev _ tsD.PrevSelectedEntry[toc, key, tocIndex]; tsD.RemoveRange[toc, key, tocIndex, tocIndex]; ccD.LoadComposedMessage[toc, key, tocIndex, cm]; fieldList _ MessageParse.MakeFieldList[cm]; IF ~ccD.SendChollaMail[delete, prototypes, toc, key, tocIndex, cm, @fieldList] THEN exD.DisplayExceptionString["Could not delete prototype message!"L]; MessageParse.FreeFieldList[fieldList]; ENDLOOP; ENDCASE; inD.UpdateTOCThumbLine[tnp, key]; vmD.UnlockTOC[toc, key]; vmD.FreeVirtualMessageObject[cm]; END; -- of PrototypesDeleteCommand -- GetStepStatus: PUBLIC PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL, index: vmD.TOCIndex] RETURNS [s: ccD.StepStatus] = BEGIN dummy: STRING _ [0]; p: ccD.ParsedStep _ [dummy, 0, dummy, 0, dummy, none, 0, 0]; tocString: STRING _ [opD.maxTOCStringLength]; vmD.GetTOCString[toc, key, index, tocString]; ccD.ParseStep[tocString, @p]; RETURN[p.status]; END; -- of GetStepStatus -- SetStepStatus: PUBLIC PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL, index: vmD.TOCIndex, s: ccD.StepStatus] = BEGIN dummy: STRING _ [0]; p: ccD.ParsedStep _ [dummy, 0, dummy, 0, dummy, none, 0, 0]; tocString: STRING _ [opD.maxTOCStringLength]; statusString: STRING _ [20]; lookup: ARRAY [0 .. 1) OF MessageParse.FieldRec _ [[name: "Subject"L, bodyStart: 0, bodyEnd: 0, found: 0]]; dm: vmD.DisplayMessagePtr _ vmD.AllocateDisplayMessageObject[]; vmD.LoadDisplayMessage[toc, key, index, dm]; MessageParse.ParseMessage[vm: dm, fields: DESCRIPTOR[lookup]]; IF lookup[0].found # 1 THEN exD.SysBug[]; --someday do better StatusToString[s, statusString]; FOR i: CARDINAL IN [0 .. 11) DO vmD.PutMessageChar[dm, lookup[0].bodyStart + 1 + i, statusString[i]]; ENDLOOP; vmD.FlushDisplayMessage[dm, key]; vmD.FreeVirtualMessageObject[dm]; vmD.GetTOCString[toc, key, index, tocString]; ccD.ParseStep[tocString, @p]; IF p.status = none THEN exD.SysBug[]; FOR i: CARDINAL IN [0 .. 11) DO tocString[p.statusIndex + i] _ statusString[i]; ENDLOOP; vmD.PutTOCString[toc, key, index, tocString]; IF intC.tocTextNbr.toc = toc THEN inD.RefreshTOCChange[toc, key, index, replace]; END; -- of SetStepStatus -- StatusToString: PUBLIC PROCEDURE [s: ccD.StepStatus, t: STRING] = BEGIN a: STRING _ SELECT s FROM finished => "Finished "L, notStarted => "Not Started"L, started => "Started "L, inProcess => "InProcess "L, processDone => "Processed "L, rejected => "Rejected "L, ENDCASE => "None "L; t.length _ 0; String.AppendString[t , a]; END; -- of StatusToString -- SetSelectionToStepToDo: PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL] = BEGIN index: vmD.TOCIndex = StepToDo[toc, key]; IF index = 0 THEN tsD.ResetTOCSelection[toc, key] ELSE tsD.SetTOCSelection[toc, key, index]; END; -- of SetSelectionToStepToDo -- StepToDo: PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL] RETURNS [index: vmD.TOCIndex] = BEGIN statusWord: STRING _ [15]; indexFF: vmD.TOCIndex = vmD.FirstFreeTOCIndex[toc, key]; index _ 0; FOR i: vmD.TOCIndex DECREASING IN [1 .. indexFF) DO ccD.StatusOfTOCEntry[toc, key, i, statusWord]; SELECT TRUE FROM String.EquivalentString[statusWord, "NotStarted"L] => LOOP; String.EquivalentString[statusWord, "Finished"L] => index _ i + 1; String.EquivalentString[statusWord, "Rejected"L] => index _ i + 1; ENDCASE => index _ i; IF index = indexFF THEN index _ index - 1; EXIT; ENDLOOP; END; -- of StepToDo -- FirstEditableStep: PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL] RETURNS [vmD.TOCIndex] = BEGIN statusWord: STRING _ [15]; indexFF: vmD.TOCIndex = vmD.FirstFreeTOCIndex[toc, key]; FOR index: vmD.TOCIndex DECREASING IN [1 .. indexFF) DO ccD.StatusOfTOCEntry[toc, key, index, statusWord]; IF ~String.EquivalentString[statusWord, "NotStarted"L] THEN RETURN[index + 1]; ENDLOOP; RETURN[1]; END; -- of FirstEditableStep -- DoLowerMenu: PUBLIC PROCEDURE [hp: inD.HousePtr] = -- Sets the editor window menu to the list headed by hp. BEGIN IF intC.cmCommandNbr.houses = hp THEN RETURN; lmD.ChangeEditorMenu[singleLine]; intC.cmCommandNbr.houses _ hp; inD.ChangeCommandMenu [cnp: intC.cmCommandNbr, region: intC.CMCommandRegion, linesToKeep: 0]; END; -- of DoLowerMenu -- CopyUniqueIDsIntoMessage: PUBLIC PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL, index: vmD.TOCIndex, cm: vmD.ComposedMessagePtr, fieldListPtr: MessageParse.FieldListPtr] = BEGIN thisID, uniqueID: ccD.UniqueID; ccD.GetBothIDsUsingIndex[toc, key, index, @thisID, @uniqueID]; ccD.FillIDField[cm, fieldListPtr, "UniqueID"L, @uniqueID]; ccD.FillIDField[cm, fieldListPtr, "ThisID"L, @thisID]; END; -- of CopyUniqueIDsIntoMessage -- -- Startup code for StepList -- Init: PROCEDURE = BEGIN stepListTopMenu: ARRAY [0 .. 3) OF lmD.HouseDescriptor _ [[text: "Step list"L, type: brackets, bracketsText: ""L, command: SLStepList], [text: "Prototypes"L, command: PrototypesCommand], [text: "Laurel"L, command: SLLaurelCommand, indicDone: FALSE, endOfLine: TRUE, rightFlush: TRUE]]; stepListMiddleMenu: ARRAY [0 .. 6) OF lmD.HouseDescriptor _ [[text: "Step"L, command: StepCommand], [text: "Display"L, command: StepListAndPrototypesDisplayCommand], [text: "Mark"L, command: MarkCommand], [text: "Edit list"L, command: EditListCommand], [text: "Edit entry"L, command: EditEntryCommand], [text: "Spec"L, type: brackets, bracketsText: ""L, command: ccD.SpecCommand]]; stepListLowerMenu: ARRAY [0 .. 4) OF lmD.HouseDescriptor _ [[text: "Step list: "L, type: text], [text: "Insert"L, command: InsertInStepListCommand], [text: "Replace"L, command: ReplaceEntryCommand], [text: "Delete"L, command: DeleteEntryCommand]]; stepLowerMenu: ARRAY [0 .. 6) OF lmD.HouseDescriptor _ [[text: "Start"L, command: ccD.StartStepCommand], [text: "Process"L, command: ccD.ProcessStepCommand], [text: "Cancel"L, command: ccD.CancelStepCommand], [text: "Process done"L, command: ccD.ProcessDoneStepCommand], [text: "Reject"L, command: ccD.RejectStepCommand], [text: "Finish"L, endOfLine: TRUE, command: ccD.FinishStepCommand]]; prototypesMiddleMenu: ARRAY [0 .. 1) OF lmD.HouseDescriptor _ [[text: "Display"L, command: StepListAndPrototypesDisplayCommand]]; prototypesLowerMenu: ARRAY [0 .. 4) OF lmD.HouseDescriptor _ [[text: "Prototypes: "L, type: text], [text: "Insert"L, command: PrototypesInsertCommand], [text: "Replace"L, command: PrototypesReplaceCommand], [text: "Delete"L, command: PrototypesDeleteCommand]]; prototypesHp, laurelHp: inD.HousePtr; stepListTopHp _ lmD.CreateCommandHouses [DESCRIPTOR[stepListTopMenu], Storage.Node, Storage.String, 2, intC.newMailCommandHouse.leftX]; stepListBracketsHp _ stepListTopHp.nextHouse; prototypesHp _ lmD.MapHouseTextToHousePtr[stepListTopHp, "Prototypes"L]; laurelHp _ lmD.MapHouseTextToHousePtr[prototypesHp, "Laurel"L]; prototypesHp.leftX _ prototypesHp.leftX + (laurelHp.leftX - prototypesHp.rightX - 25); prototypesHp.rightX _ prototypesHp.rightX + (laurelHp.leftX - prototypesHp.rightX - 25); stepListMiddleHp _ lmD.CreateCommandHouses [DESCRIPTOR[stepListMiddleMenu], Storage.Node, Storage.String, 0]; ccD.stepListLowerHp _ lmD.CreateCommandHouses [DESCRIPTOR[stepListLowerMenu], Storage.Node, Storage.String, 0]; ccD.stepListLowerHp.typeface _ italicFace; stepLowerHp _ lmD.CreateCommandHouses [DESCRIPTOR[stepLowerMenu], Storage.Node, Storage.String, 0]; prototypesMiddleHp _ lmD.CreateCommandHouses [DESCRIPTOR[prototypesMiddleMenu], Storage.Node, Storage.String, 0]; prototypesLowerHp _ lmD.CreateCommandHouses [DESCRIPTOR[prototypesLowerMenu], Storage.Node, Storage.String, 0]; prototypesLowerHp.typeface _ italicFace; END; -- of Init -- Init[]; END. -- of ChollaStepList --(635)\f1 8513v1V3146v3V4762v3V7328v3V57v4V29v2V31v2V27v3V22v7V