-- file: IntDisplayCom.Mesa -- last edited by Horning, March 2, 1978 10:58 PM -- last edited by Kierr, March 8, 1978 4:51 PM -- last edited by Brotz, November 13, 1981 12:24 PM -- last edited by Schroeder, Wednesday Nov. 5, 1980 3:14 pm PST. -- last edited by Levin, January 8, 1981 10:19 AM. -- last edited by Taft, May 21, 1983 1:50 PM DIRECTORY Core USING [Close, Delete, Open], dsD: FROM "DisplayDefs" USING [ClearRectangle, lineHeight, PutCharInBitMap, ScreenYCoord], Editor USING [RefreshSoThatFirstCharStartsLine], exD: FROM "ExceptionDefs" USING [cantMoveToFileInUse, diskErrorTargetDamage, DisplayException, Exception, moveWouldOverfill, newFile, nil, noCurrentFile, noMessagesMoved, noMoveIllegalName, noSelectedEntries, noUndeletedMessages], inD: FROM "InteractorDefs" USING [CommandProcedure, Confirm, ConfirmBrackets, Consider, DisplayTOCEntry, leftMargin, LinePtr, MakeTOCIndexVisible, MapTOCIndexToTOCLine, MapTOCIndexToTopY, markLeftX, MessageTextNbrPtr, NextTOCEntry, numberLeftX, rightMargin, ScreenYCoord, ScrollDownTOC, ScrollUpTOC, TOCLineNumber, TOCTextNbrPtr, UpdateTOCThumbLine], intCommon USING [displayAfterDelete, dmTextNbr, moveToBracketsHouse, tocTextNbr], opD: FROM "OperationsDefs" USING [AppendMailToFileOperation, NoMessagesMoved], String USING [AppendString], tsD: FROM "TOCSelectionDefs" USING [DeconsiderAll, FirstSelectedEntry, IsSelected, LastSelectedEntry, NextSelectedEntry, SetTOCSelection, TOCSelectionEmpty], vmD: FROM "VirtualMgrDefs" USING [DisplayMessage, DisplayMessagePtr, FirstFreeTOCIndex, FlushDisplayMessage, GetTOCFixedPart, LoadDisplayMessage, PutTOCFixedPart, TOCFixedPart, TOCHandle, TOCIndex, UnlockTOC, WaitForLock], VMDefs USING [CantOpen, FileHandle]; IntDisplayCom: PROGRAM IMPORTS Core, dsD, Editor, exD, inD, intC: intCommon, opD, String, tsD, vmD, VMDefs EXPORTS inD = BEGIN OPEN inD; -- Purpose: handles user interactions including the display, keyboard and mouse. This -- division gathers together commands and their arguments and is responsible for the -- display of all error messages. DeleteCommand: PUBLIC CommandProcedure = -- Sets deleted field for each selected TOCEntry. Updates the display to reflect the changes. BEGIN tnp: TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle _ tnp.toc; key: CARDINAL _ vmD.WaitForLock[toc]; ModifyTOCOperation[tnp, key, delete]; DoDisplayAfterDelete[tnp, key]; vmD.UnlockTOC[toc, key]; END; -- of DeleteCommand -- DoDisplayAfterDelete: PRIVATE PROC [tnp: TOCTextNbrPtr, key: CARDINAL] = BEGIN toc: vmD.TOCHandle = tnp.toc; index: vmD.TOCIndex _ vmD.DisplayMessage[intC.dmTextNbr.message].index; IF intC.displayAfterDelete AND tnp.haveToc AND ~tsD.TOCSelectionEmpty[toc, key] AND index = tsD.FirstSelectedEntry[toc, key] AND index = tsD.LastSelectedEntry[toc, key] AND index + 1 < vmD.FirstFreeTOCIndex[toc, key] THEN BEGIN fp: vmD.TOCFixedPart; vmD.GetTOCFixedPart[toc, key, index + 1, @fp]; IF ~fp.seen THEN BEGIN exception: exD.Exception _ DisplayMessageOperation[tnp, key]; SELECT exception FROM exD.nil, exD.noUndeletedMessages => NULL; ENDCASE => exD.DisplayException[exception]; END; END; END; -- of DoDisplayAfterDelete -- ModifyTOCOperation: PRIVATE PROCEDURE [tnp: TOCTextNbrPtr, key: CARDINAL, action: {delete, undelete, move}] = -- Sets fields for each selected TOCEntry. Updates the display to reflect the changes. BEGIN toc: vmD.TOCHandle = tnp.toc; line: LinePtr _ tnp.lines; topLineNumber: TOCLineNumber _ line.linePair.lineNumber; index: vmD.TOCIndex; fp: vmD.TOCFixedPart; IF ~tnp.haveToc THEN {exD.DisplayException[exD.noCurrentFile]; RETURN}; IF tsD.TOCSelectionEmpty[toc, key] THEN {exD.DisplayException[exD.noSelectedEntries]; RETURN}; FOR index _ tsD.FirstSelectedEntry[toc, key], tsD.NextSelectedEntry[toc, key, index] UNTIL index = 0 DO vmD.GetTOCFixedPart[toc, key, index, @fp]; IF action = move AND ~ fp.deleted THEN fp.mark _ 'm; fp.deleted _ (action = delete OR action = move); vmD.PutTOCFixedPart[toc, key, index, @fp]; ENDLOOP; index _ line.linePair.index; IF tsD.IsSelected[toc, key, index] THEN -- TOC entry at top of screen may be only partially visible [line, ] _ DisplayTOCEntry [tnp: tnp, key: key, index: index, suppressed: topLineNumber - 1, firstLine: line]; UNTIL (index _ tsD.NextSelectedEntry[toc, key, index]) = 0 OR (line _ MapTOCIndexToTOCLine[index, tnp]) = NIL DO [ , ] _ DisplayTOCEntry[tnp, key, index, 0, line]; ENDLOOP; END; -- of ModifyTOCOperation -- UndeleteCommand: PUBLIC CommandProcedure = -- Clears deleted field for each selected TOCEntry. Updates the display to reflect the -- changes. BEGIN tnp: TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle _ tnp.toc; key: CARDINAL _ vmD.WaitForLock[toc]; ModifyTOCOperation[tnp, key, undelete]; vmD.UnlockTOC[toc, key]; END; -- of UndeleteCommand -- DisplayMessageCommand: PUBLIC CommandProcedure = -- Clears DM text neighborhood. Sets TOC selection to the current displayed message if it -- was already selected, otherwise the first selected TOCEntry. If the current display -- message index equals is this selected message, then displays and selects the next -- undeleted message, otherwise displays the selected message. Virtualizes the selected -- message and refreshes the DM text Nbr. BEGIN tnp: TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle _ tnp.toc; key: CARDINAL _ vmD.WaitForLock[toc]; exception: exD.Exception _ DisplayMessageOperation[tnp, key]; vmD.UnlockTOC[toc, key]; IF exception # exD.nil THEN exD.DisplayException[exception]; END; -- of DisplayMessageCommand -- DisplayMessageOperation: PROCEDURE [tnp: TOCTextNbrPtr, key: CARDINAL] RETURNS [exception: exD.Exception] = -- Clears DM text neighborhood. Sets TOC selection to the current displayed message if it -- was already selected, otherwise the first selected TOCEntry. If the current display -- message index equals is this selected message, then displays and selects the next -- undeleted message, otherwise displays the selected message. Virtualizes the selected -- message and refreshes the DM text Nbr. BEGIN fp: vmD.TOCFixedPart; selectedIndex: vmD.TOCIndex; dm: MessageTextNbrPtr = intC.dmTextNbr; toc: vmD.TOCHandle = tnp.toc; message: vmD.DisplayMessagePtr = vmD.DisplayMessage[dm.message]; exception _ exD.nil; IF ~tnp.haveToc THEN RETURN[exD.noCurrentFile]; IF tsD.TOCSelectionEmpty[toc, key] THEN RETURN[exD.noSelectedEntries]; selectedIndex _ message.index; BEGIN -- for EXITS -- SELECT TRUE FROM (~dm.haveMessage OR message.toc # toc OR ~tsD.IsSelected[toc, key, selectedIndex]) => BEGIN selectedIndex _ tsD.FirstSelectedEntry[toc, key]; MakeTOCIndexVisible[selectedIndex, key]; END; (tsD.FirstSelectedEntry[toc, key] # tsD.LastSelectedEntry[toc, key]) => BEGIN -- currently viewing one of a series of selected entries. originalSelectedIndex: vmD.TOCIndex _ selectedIndex; DO selectedIndex _ IF selectedIndex = tsD.LastSelectedEntry[toc, key] THEN tsD.FirstSelectedEntry[toc, key] ELSE tsD.NextSelectedEntry[toc, key, selectedIndex]; IF selectedIndex = originalSelectedIndex THEN BEGIN selectedIndex _ tsD.FirstSelectedEntry[toc, key]; GO TO SelectNextUndeletedEntry; END; vmD.GetTOCFixedPart[toc, key, selectedIndex, @fp]; IF ~fp.deleted THEN EXIT; ENDLOOP; MakeTOCIndexVisible[selectedIndex, key]; END ENDCASE => GO TO SelectNextUndeletedEntry; EXITS SelectNextUndeletedEntry => BEGIN DO nextMessageExists, visible, postVisible: BOOLEAN; initialY, postSelectionY: ScreenYCoord; [initialY, visible] _ MapTOCIndexToTopY[selectedIndex, tnp]; [nextMessageExists, selectedIndex] _ NextTOCEntry[tnp, key, selectedIndex]; IF ~nextMessageExists THEN RETURN[exD.noUndeletedMessages]; MakeTOCIndexVisible[selectedIndex, key]; [postSelectionY, postVisible] _ MapTOCIndexToTopY[selectedIndex, tnp]; IF visible AND postVisible AND tnp.firstLineOffScreen.state # empty THEN IF initialY < postSelectionY THEN ScrollUpTOC[tnp.topY + postSelectionY - initialY, tnp, key] ELSE IF initialY > postSelectionY THEN ScrollDownTOC[tnp.topY + initialY - postSelectionY, tnp, key]; vmD.GetTOCFixedPart[toc, key, selectedIndex, @fp]; IF ~fp.deleted THEN EXIT; ENDLOOP; tsD.DeconsiderAll[tnp, key]; tsD.SetTOCSelection[toc, key, selectedIndex]; Consider[selectedIndex, selectedIndex, tnp, key]; END; END; -- of EXITS -- IF dm.haveMessage THEN BEGIN messageToc: vmD.TOCHandle = message.toc; IF messageToc = toc THEN vmD.FlushDisplayMessage[message, key] ELSE BEGIN messageKey: CARDINAL _ vmD.WaitForLock[messageToc]; vmD.FlushDisplayMessage[message, messageKey]; vmD.UnlockTOC[messageToc, messageKey]; END; END; UpdateTOCThumbLine[tnp, key]; vmD.LoadDisplayMessage[toc, key, selectedIndex, message]; message.formatStart _ message.formatEnd _ 0; dm.haveMessage _ TRUE; dsD.ClearRectangle[leftMargin, rightMargin, dm.topY, dm.bottomY]; Editor.RefreshSoThatFirstCharStartsLine[firstChar: 0, firstLine: dm.lines, mnp: dm]; vmD.GetTOCFixedPart[toc, key, selectedIndex, @fp]; IF ~fp.seen THEN BEGIN line: LinePtr; fp.seen _ TRUE; vmD.PutTOCFixedPart[toc, key, selectedIndex, @fp]; line _ MapTOCIndexToTOCLine[selectedIndex, tnp]; IF line # NIL THEN BEGIN dsD.ClearRectangle[markLeftX, numberLeftX, line.y, line.y + dsD.lineHeight]; [] _ dsD.PutCharInBitMap[fp.mark, markLeftX, line.y, plainFace]; END; END; END; -- of DisplayMessageOperation -- MoveMessageToFileCommand: PUBLIC CommandProcedure = -- Calls AppendMailToFileOperation for all selected messages in the current mail file to be -- appended to the file whose name appears in the Move to brackets. If the operation is -- successful, then the messages are Deleted. BEGIN appendFileHandle: VMDefs.FileHandle; appendFileName: STRING; fName: STRING = [75]; i: CARDINAL; fileCreated: BOOLEAN _ FALSE; bracketsText: STRING = intC.moveToBracketsHouse.text; tnp: TOCTextNbrPtr = intC.tocTextNbr; toc: vmD.TOCHandle _ tnp.toc; key: CARDINAL _ 0; IF ~confirmed AND ~ConfirmBrackets[hp: intC.moveToBracketsHouse, fileExtension: ".mail."L] THEN RETURN; IF ~tnp.haveToc THEN {exD.DisplayException[exD.noCurrentFile]; RETURN}; key _ vmD.WaitForLock[toc]; IF tsD.TOCSelectionEmpty[toc, key] THEN {exD.DisplayException[exD.noSelectedEntries]; vmD.UnlockTOC[toc, key]; RETURN}; vmD.UnlockTOC[toc, key]; -- first check for extension String.AppendString[fName, bracketsText]; appendFileName _ fName; IF fName.length > 0 THEN FOR i IN [0 .. fName.length) DO IF fName[i] = '. THEN EXIT; REPEAT FINISHED => String.AppendString[fName, ".mail"L]; ENDLOOP; -- Now check for new file: BEGIN -- for EXITS -- appendFileHandle _ Core.Open[appendFileName, read ! VMDefs.CantOpen => SELECT reason FROM notFound => BEGIN exD.DisplayException[exD.newFile]; IF ~inD.Confirm[2] THEN GO TO Return; fileCreated _ TRUE; GO TO Continue; END; alreadyExists => {exD.DisplayException[exD.cantMoveToFileInUse]; GO TO Return}; illegalFileName => {exD.DisplayException[exD.noMoveIllegalName]; GO TO Return}; ENDCASE => GO TO Return]; Core.Close[appendFileHandle]; EXITS Continue => NULL; Return => RETURN; END; -- of EXITS block -- key _ vmD.WaitForLock[toc]; BEGIN -- for EXITS -- opD.AppendMailToFileOperation[toc, key, appendFileName ! opD.NoMessagesMoved => BEGIN exD.DisplayException[SELECT reason FROM diskFull => exD.moveWouldOverfill, noUndeleted => exD.noMessagesMoved, ENDCASE => exD.diskErrorTargetDamage]; IF fileCreated THEN BEGIN appendFileHandle _ Core.Open[appendFileName, update ! VMDefs.CantOpen => GO TO unlock]; Core.Delete[appendFileHandle]; END; GO TO unlock; END]; ModifyTOCOperation[tnp, key, move]; DoDisplayAfterDelete[tnp, key]; GO TO unlock; EXITS unlock => vmD.UnlockTOC[toc, key]; END; -- of EXITS block -- END; -- of MoveMessageToFileCommand -- END. -- of IntDisplayCom --z20461(529)\f1