-- file: EditorFiles.Mesa -- edited by Schroeder, January 13, 1981 11:37 AM -- edited by Brotz, May 3, 1982 5:33 PM -- edited by Levin, February 22, 1980 12:42 PM DIRECTORY dsD: FROM "DisplayDefs" USING [ChangeCursor, CursorShape, FaceType, GetCursor, GetStringWidth, ScreenXCoord], Editor USING [CancelSourceSelection, RefreshSoThatFirstCharStartsLine, ResetBuffers, ResetDeletionBuffer, SelectNextBlank, SwapMessageWithDeletionBuffer, TurnOnDeliver, UnrecognizedCommand, UpdateScreen], exD: FROM "ExceptionDefs" USING [AppendDecimalToExceptionLine, AppendStringToExceptionLine, ClearExceptionsRegion, confirmFileName, DisplayExceptionLine, DisplayExceptionOrStringOnLine, DisplayExceptionStringOnLine, Exception, ExceptionLineOverflow, FlashExceptionsRegion, getFailed, messageTooBig, nil, putWillOverwrite, SysBug, willReplaceMessage], inD: FROM "InteractorDefs" USING [AskUserToConfirm, BracketsHouseRefresher, CaretIsBlinking, ChangeCommandMenu, CharIndex, CommandProcedure, ConfirmBrackets, House, HousePtr, IndicateCommandBusy, IndicateCommandFinished, leftMargin, maxBracketStringLength, MessageTextNbrPtr, NullCommand, RefreshHouse, rightMargin, ScreenXCoord, SetCaretBlinking, TextHouseRefresher, TextSelection], intCommon USING [actionPoint, cmCommandNbr, CMCommandRegion, cmTextNbr, commandType, composedMessageEdited, copyMenuSegment, copySourceBracketsHouse, copyTargetBracketsHouse, currentCommand, disableWriting, editorMenuState, findBracketsHouse, findHouse, findMenuSegment, getPutBracketsHouse, getPutMenuSegment, newTargetSelection, runBracketsHouse, runCommandMode, runMenuSegment, substituteHouse, substituteMenuSegment, substituteNewBracketsHouse, substituteOldBracketsHouse, target], lmD: FROM "LaurelMenuDefs" USING [copySourceBracketsNumber, copyTargetBracketsNumber, deliverCommandNumber, EditorMenuState, findBracketsNumber, findCommandNumber, getPutBracketsNumber, HouseDescriptor, MapHouseNumberToHousePtr, MapHouseTextToHousePtr, runBracketsNumber, substituteCommandNumber, substituteNewBracketsNumber, substituteOldBracketsNumber, SwapInMenu], opD: FROM "OperationsDefs" USING [Copy, FileError], Storage USING [FreeString, String], String USING [AppendLongNumber, AppendString, EquivalentSubString, SubStringDescriptor], vmD: FROM "VirtualMgrDefs" USING [CharIndex, ComposedMessage, ComposedMessagePtr, DeleteRangeInMessage, GetMessageSize, InsertFileInMessage, InsertRangeInMessage, MessageOverflow, MessageRange, PutRangeInFile]; EditorFiles: PROGRAM IMPORTS dsD, Editor, exD, inD, intC: intCommon, lmD, opD, Storage, String, vmD EXPORTS Editor, inD, lmD = BEGIN OPEN Editor, inD; GCommand: PUBLIC PROCEDURE [mnp: MessageTextNbrPtr] = -- Replaces the current primary selection with the contents of the file named in -- the get/put brackets. BEGIN getHouse: HousePtr _ lmD.MapHouseTextToHousePtr[intC.cmCommandNbr.houses, "Get"L]; ChangeEditorMenu[getPut]; IF getHouse # NIL THEN IndicateCommandBusy[intC.currentCommand _ getHouse]; exD.DisplayExceptionLine[exD.confirmFileName, 1]; IF ConfirmBrackets[hp: intC.getPutBracketsHouse, fileExtension: ".form."L] THEN Getter[intC.target.start, intC.target.end, mnp, intC.getPutBracketsHouse.text]; IF getHouse # NIL THEN IndicateCommandFinished[getHouse]; intC.currentCommand _ NIL; END; -- of GCommand -- GetCommand: PUBLIC CommandProcedure = -- Replaces the current composed message with the contents of the file named in -- the brackets. BEGIN oldText: STRING _ [maxBracketStringLength]; gpbHp: HousePtr; ChangeEditorMenu[getPut]; gpbHp _ intC.getPutBracketsHouse; String.AppendString[oldText, gpbHp.text]; IF ~confirmed AND ~ConfirmBrackets[hp: gpbHp, fileExtension: ".form."L] THEN RETURN; IF intC.composedMessageEdited AND vmD.GetMessageSize[intC.cmTextNbr.message] # 0 AND ~AskUserToConfirm[exD.willReplaceMessage] THEN {RefreshHouse[gpbHp, oldText]; RETURN}; Getter[0, vmD.GetMessageSize[intC.cmTextNbr.message], intC.cmTextNbr, gpbHp.text]; intC.runCommandMode _ FALSE; END; -- of GetCommand -- Getter: PUBLIC PROCEDURE [start, end: CharIndex, mnp: MessageTextNbrPtr, fileName: STRING] = -- Replaces [start .. end) from mnp.message with contents of fileName. BEGIN selectionLength: CARDINAL = end - start; insertionLength: CARDINAL; preInsertionMessageLength: CARDINAL; preGetMessageLength: CharIndex _ vmD.GetMessageSize[mnp.message]; whereToInsert: vmD.ComposedMessagePtr; completeGet: BOOLEAN = (start = 0 AND end = preGetMessageLength); isForm: BOOLEAN _ FALSE; dotForm: STRING _ ".form"L; trailerSSD: String.SubStringDescriptor _ String.SubStringDescriptor[base: fileName, offset: fileName.length - 5, length: 5]; dotFormSSD: String.SubStringDescriptor _ String.SubStringDescriptor[base: dotForm, offset: 0, length: 5]; fName: STRING; ReportErrorAndCleanup: PROCEDURE [exception: exD.Exception, s: STRING] = BEGIN -- sorry, subsequent undo not permitted IF ~completeGet THEN vmD.InsertRangeInMessage [targetIndex: start, targetMessage: vmD.ComposedMessage[mnp.message], from: vmD.MessageRange[0, end - start, mnp.deletionBuffer]]; ResetDeletionBuffer[mnp]; exD.DisplayExceptionLine[exD.getFailed, 1]; exD.DisplayExceptionOrStringOnLine[exception, s, 2]; exD.FlashExceptionsRegion[]; END; -- of ReportErrorAndCleanup -- CancelSourceSelection[mnp]; ResetBuffers[mnp]; IF completeGet THEN whereToInsert _ mnp.deletionBuffer ELSE BEGIN vmD.InsertRangeInMessage[targetIndex: 0, targetMessage: mnp.deletionBuffer, from: vmD.MessageRange[start, end, mnp.message]]; vmD.DeleteRangeInMessage[from: vmD.MessageRange[start, end, mnp.message]]; whereToInsert _ vmD.ComposedMessage[mnp.message]; END; preInsertionMessageLength _ vmD.GetMessageSize[whereToInsert]; IF fileName.length > 5 AND String.EquivalentSubString[@trailerSSD, @dotFormSSD] THEN isForm _ TRUE; fName _ fileName; BEGIN -- for EXITS -- vmD.InsertFileInMessage[targetIndex: start, targetMessage: whereToInsert, file: fName ! opD.FileError => SELECT reason FROM notFound => BEGIN -- try adding .form to the filename. IF fName.length > 0 THEN FOR i: CARDINAL IN [0 .. fName.length) DO IF fName[i] = '. THEN EXIT; REPEAT FINISHED => BEGIN -- This can only happen once. fName _ Storage.String[fileName.length + 5]; String.AppendString[fName, fileName]; String.AppendString[fName, dotForm]; isForm _ TRUE; RETRY; END; ENDLOOP; ReportErrorAndCleanup[exD.nil, errorString]; GO TO Return; END; ENDCASE => {ReportErrorAndCleanup[exD.nil, errorString]; GO TO Return}; vmD.MessageOverflow => {ReportErrorAndCleanup[exD.messageTooBig, NIL]; GO TO Return};]; insertionLength _ vmD.GetMessageSize[whereToInsert] - preInsertionMessageLength; exD.ClearExceptionsRegion[]; exD.AppendDecimalToExceptionLine[insertionLength, 1]; exD.AppendStringToExceptionLine[" characters read."L, 1]; IF completeGet THEN BEGIN intC.target _ TextSelection[mnp, 0, 0, 0, 0, char, FALSE]; SwapMessageWithDeletionBuffer[mnp]; intC.commandType _ get; mnp.message.formatStart _ mnp.message.formatEnd _ 0; RefreshSoThatFirstCharStartsLine[0, mnp.lines, mnp]; IF isForm THEN Editor.SelectNextBlank[mnp, TRUE]; TurnOnDeliver[]; intC.composedMessageEdited _ FALSE; END ELSE BEGIN intC.target _ TextSelection[mnp, start, start + insertionLength, start, 0, char, FALSE]; vmD.InsertRangeInMessage [targetIndex: 0, targetMessage: mnp.insertionBuffer, from: vmD.MessageRange[start, start + insertionLength, mnp.message]]; intC.commandType _ replace; UpdateScreen[start: start, nCharsDeleted: end - start, nCharsInserted: insertionLength, mnp: mnp]; END; intC.newTargetSelection _ TRUE; intC.actionPoint _ start; mnp.haveMessage _ TRUE; GO TO Return; EXITS Return => IF fName # fileName THEN Storage.FreeString[fName]; END; END; -- of Getter -- PCommand: PUBLIC PROCEDURE [mnp: MessageTextNbrPtr] = -- Writes the current primary selection onto the file named in the get/put -- brackets. BEGIN oldText: STRING _ [maxBracketStringLength]; gpbHp: HousePtr; putHouse: HousePtr _ lmD.MapHouseTextToHousePtr[intC.cmCommandNbr.houses, "Put"L]; IF intC.disableWriting THEN {UnrecognizedCommand[]; RETURN}; ChangeEditorMenu[getPut]; gpbHp _ intC.getPutBracketsHouse; IF putHouse # NIL THEN IndicateCommandBusy[intC.currentCommand _ putHouse]; exD.DisplayExceptionLine[exD.confirmFileName, 1]; String.AppendString[oldText, gpbHp.text]; IF ConfirmBrackets[gpbHp] THEN [] _ Putter[intC.target.start, intC.target.end, mnp, gpbHp, oldText]; IF putHouse # NIL THEN IndicateCommandFinished[putHouse]; intC.currentCommand _ NIL; END; -- of PCommand -- PutCommand: PUBLIC CommandProcedure = -- Writes the current composed message onto the file named in the get/put -- brackets. BEGIN oldText: STRING _ [maxBracketStringLength]; gpbHp: HousePtr; ChangeEditorMenu[getPut]; gpbHp _ intC.getPutBracketsHouse; String.AppendString[oldText, gpbHp.text]; IF (confirmed OR ConfirmBrackets[gpbHp]) AND Putter[0, vmD.GetMessageSize[intC.cmTextNbr.message], intC.cmTextNbr, gpbHp, oldText] THEN intC.composedMessageEdited _ FALSE; IndicateCommandFinished[hp]; IF CaretIsBlinking[] THEN SetCaretBlinking[intC.target.point, intC.target.mnp]; END; -- of PutCommand -- Putter: PUBLIC PROCEDURE [start, end: CharIndex, mnp: MessageTextNbrPtr, hp: HousePtr, oldText: STRING] RETURNS [successful: BOOLEAN] = -- Writes [start .. end) from mnp.message onto file named in hp.text. BEGIN savedCursor: dsD.CursorShape; [savedCursor, , ] _ dsD.GetCursor[]; dsD.ChangeCursor[hourGlass]; successful _ TRUE; vmD.PutRangeInFile[from: vmD.MessageRange[start, end, mnp.message], file: hp.text, concurrenceNeeded: TRUE, UserConcurs: AskUserToConfirm ! opD.FileError => BEGIN IF reason = cancel THEN RefreshHouse[hp, oldText]; successful _ FALSE; CONTINUE; END]; IF successful THEN BEGIN exD.AppendDecimalToExceptionLine[end - start, 1]; exD.AppendStringToExceptionLine[" characters written."L, 1]; END; dsD.ChangeCursor[savedCursor]; END; -- of Putter -- CopyCommand: PUBLIC CommandProcedure = -- Copies a remote or local file to a remote or local file using opD.Copy. The composed -- message is not affected by this command. BEGIN bytesCopied: LONG CARDINAL; count: STRING = [12]; OverwriteOK: PROCEDURE RETURNS [BOOLEAN] = {RETURN[AskUserToConfirm[exD.putWillOverwrite]]}; ChangeEditorMenu[copy]; IF ~(confirmed OR ConfirmBrackets[intC.copySourceBracketsHouse]) OR ~ConfirmBrackets[intC.copyTargetBracketsHouse] THEN RETURN; exD.ClearExceptionsRegion[]; bytesCopied _ opD.Copy [intC.copySourceBracketsHouse.text, intC.copyTargetBracketsHouse.text, OverwriteOK ! opD.FileError => BEGIN exD.DisplayExceptionStringOnLine["Copy failed: "L, 1]; exD.AppendStringToExceptionLine [IF reason = get THEN "can't get "L ELSE "can't put "L, 1]; exD.AppendStringToExceptionLine [IF reason = get THEN intC.copySourceBracketsHouse.text ELSE intC.copyTargetBracketsHouse.text, 1 ! exD.ExceptionLineOverflow => CONTINUE]; exD.DisplayExceptionStringOnLine[errorString, 2]; exD.FlashExceptionsRegion[]; GO TO Return; END]; String.AppendLongNumber[count, bytesCopied, 10]; exD.AppendStringToExceptionLine[count, 1]; exD.AppendStringToExceptionLine[" bytes copied."L, 1]; EXITS Return => NULL; END; -- of CopyCommand -- MenuChange: PUBLIC SIGNAL = CODE; -- Raised by ChangeCommandMenu to notify any HousePtr holders that they may be -- invalid. ChangeEditorMenu: PUBLIC PROCEDURE [newState: lmD.EditorMenuState] = -- Change the Editor menu to reflect the newState. Raises the resumable SIGNAL -- MenuChange if the menu is actually changing. BEGIN lastHouse: HousePtr; linesToKeep: CARDINAL; IF newState = intC.editorMenuState THEN RETURN; SIGNAL MenuChange; linesToKeep _ intC.cmCommandNbr.nLines - (IF intC.editorMenuState = singleLine THEN 0 ELSE 1); IF intC.cmCommandNbr.houses = NIL THEN exD.SysBug[]; FOR lastHouse _ intC.cmCommandNbr.houses, lastHouse.nextHouse UNTIL lastHouse.nextHouse = NIL OR lastHouse.nextHouse.lineNumber = linesToKeep DO ENDLOOP; SELECT newState FROM singleLine => lastHouse.nextHouse _ NIL; getPut => BEGIN lastHouse.nextHouse _ lmD.SwapInMenu[intC.getPutMenuSegment]; intC.getPutBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.getPutBracketsNumber]; END; run => BEGIN lastHouse.nextHouse _ lmD.SwapInMenu[intC.runMenuSegment]; intC.runBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.runBracketsNumber]; END; find => BEGIN lastHouse.nextHouse _ lmD.SwapInMenu[intC.findMenuSegment]; intC.findHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.findCommandNumber]; intC.findBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.findBracketsNumber]; END; substitute => BEGIN lastHouse.nextHouse _ lmD.SwapInMenu[intC.substituteMenuSegment]; intC.substituteHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.substituteCommandNumber]; intC.substituteNewBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.substituteNewBracketsNumber]; intC.substituteOldBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.substituteOldBracketsNumber]; END; copy => BEGIN lastHouse.nextHouse _ lmD.SwapInMenu[intC.copyMenuSegment]; intC.copySourceBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.copySourceBracketsNumber]; intC.copyTargetBracketsHouse _ lmD.MapHouseNumberToHousePtr [lastHouse, lmD.deliverCommandNumber, lmD.copyTargetBracketsNumber]; END; ENDCASE => exD.SysBug[]; FOR lastHouse _ lastHouse.nextHouse, lastHouse.nextHouse UNTIL lastHouse = NIL DO lastHouse.lineNumber _ linesToKeep; ENDLOOP; ChangeCommandMenu [cnp: intC.cmCommandNbr, region: intC.CMCommandRegion, linesToKeep: linesToKeep]; intC.editorMenuState _ newState; END; -- of ChangeEditorMenu -- ShortenEditorMenuCommand: PUBLIC CommandProcedure = BEGIN ChangeEditorMenu[singleLine]; IF CaretIsBlinking[] THEN SetCaretBlinking[intC.target.point, intC.target.mnp]; END; -- of ShortenEditorMenuCommand -- CreateCommandHouses: PUBLIC PROCEDURE [items: DESCRIPTOR FOR ARRAY OF lmD.HouseDescriptor, allocateNode: PROCEDURE [CARDINAL] RETURNS [POINTER], allocateString: PROCEDURE [CARDINAL] RETURNS [STRING], firstLine: CARDINAL _ 0, firstLeftX: ScreenXCoord _ leftMargin] RETURNS [hp: HousePtr] = BEGIN interCommandSpacing: CARDINAL = 15; preBracketSpacing: CARDINAL = 7; bracketWidth: CARDINAL = 80; h: HousePtr; x: ScreenXCoord _ firstLeftX; faceType: dsD.FaceType; width, totalWidth: CARDINAL; lineNumber: CARDINAL _ firstLine; hp _ NIL; FOR i: CARDINAL IN [0 .. LENGTH[items]) DO faceType _ IF items[i].type = text THEN plainFace ELSE boldFace; totalWidth _ width _ dsD.GetStringWidth[items[i].text, faceType]; IF items[i].type = brackets THEN totalWidth _ width + preBracketSpacing + bracketWidth; IF totalWidth + x > rightMargin THEN {lineNumber _ lineNumber + 1; x _ leftMargin}; IF items[i].rightFlush THEN x _ rightMargin - totalWidth; IF hp = NIL THEN hp _ h _ allocateNode[SIZE[House]] ELSE h _ h.nextHouse _ allocateNode[SIZE[House]]; h^ _ House [nextHouse: NIL, lineNumber: lineNumber, topY: 0, bottomY: 0, leftX: x, rightX: x + width, text: allocateString[items[i].text.length], fixedEdge: left, typeface: faceType, needsConfirmation: items[i].needsConfirmation, trackerIndicateDone: items[i].indicDone, callable: items[i].type # text, command: IF items[i].command = NIL THEN NullCommand ELSE items[i].command, houseRefresher: TextHouseRefresher]; String.AppendString[h.text, items[i].text]; IF items[i].type = brackets THEN BEGIN h _ h.nextHouse _ allocateNode[SIZE[House]]; h^ _ House [nextHouse: NIL, lineNumber: lineNumber, topY: 0, bottomY: 0, leftX: x + width + preBracketSpacing, rightX: IF items[i].endOfLine THEN rightMargin ELSE x + totalWidth, text: allocateString[maxBracketStringLength], fixedEdge: left, typeface: plainFace, needsConfirmation: FALSE, trackerIndicateDone: TRUE, callable: FALSE, command: NullCommand, houseRefresher: BracketsHouseRefresher]; String.AppendString[h.text, items[i].bracketsText]; END; IF items[i].endOfLine THEN x _ rightMargin + 1 ELSE x _ x + totalWidth + interCommandSpacing; ENDLOOP; END; -- of CreateCommandHouses -- END. -- of EditorFiles --z19932(635)\f1