TEdit.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Doug Wyatt, April 1, 1992 6:17 pm PST
DIRECTORY
Atom USING [PropList],
Imager USING [Context],
NodeStyle USING [StyleKind],
Rope USING [ROPE],
TEditFormat USING [LineInfo],
Tioga USING [Node, Location, Span, nullSpan, Looks, noLooks];
TEdit: CEDAR DEFINITIONS ~ BEGIN
Doc
Doc: TYPE ~ REF DocRep;
DocRep: TYPE ~ RECORD [
root: Tioga.Node, -- root of the tree
views: LIST OF View ¬ NIL, -- views of this document
tsInfo: TSInfo ¬ NIL, -- special typescript information
selection: ARRAY SelectionId OF Selection ¬ ALL[NIL],
edited: BOOL ¬ FALSE -- has the document been edited?
<<lock: LockRef, -- $DocumentLock property>>
selectionHistory: Selection, -- $SelectionHistory property
fileExtension: ATOM, -- $FileExtension property
fileCreateDate: BasicTime.GMT, -- $FileCreateDate property
readOnly: BOOLFALSE, -- user edits inhibited
];
CreateDoc: PROC [root: Tioga.Node] RETURNS [Doc];
Create a new Doc and associate it with the given root node.
DocFromRoot: PROC [root: Tioga.Node] RETURNS [Doc];
Return the Doc associated with the given root node, or NIL if none.
ttyChars: CARDINAL = 128;
size of input buffer for TS; overflow goes to rope
TSInfo: TYPE = REF TSInfoRec;
TSInfoRec: TYPE = RECORD [
iIncr: CONDITION, -- raised whenever add to input
looks: Tioga.Looks ¬ Tioga.noLooks, -- for PutChar
inputRope: Rope.ROPE, -- for overflow from input array
inputLoc: INT ¬ 0, -- index of next char to read from rope
input: PACKED ARRAY [0..ttyChars) OF CHAR,
iQp, oQp: [0..ttyChars) ¬ 0, -- read and write indexes for input buffer
intParam: INT, -- parameter from TIP
waitingInGetChar: BOOL ¬ FALSE,
abort: BOOL ¬ FALSE
];
Selection
SelectionId: TYPE ~ {primary, secondary, feedback};
Selection: TYPE ~ REF SelectionRep;
SelectionRep: TYPE ~ RECORD [
span: Tioga.Span ¬ Tioga.nullSpan,
granularity: SelectionGrain ¬ point,
punctuation: PunctuationPosition ¬ none, -- not currently implemented
insertion: BeforeAfter ¬ before, -- insert at span.start or span.end?
looks: Tioga.Looks ¬ Tioga.noLooks, -- caret looks
pendingDelete: BOOL ¬ FALSE -- Laurel-style pending deletion of selection
];
SelectionGrain: TYPE ~ {point, char, word, node, branch};
PunctuationPosition: TYPE ~ {none, leading, trailing};
BeforeAfter: TYPE ~ {before, after};
View
View: TYPE ~ REF ViewRep; -- formerly TEditDocumentData
ViewRep: TYPE ~ RECORD [
doc: Doc ¬ NIL, -- the underlying document
window: Window ¬ NIL, -- window displaying this view
-- parameters --
cw, ch: INTEGER ¬ 0, -- width and height of view
styleKind: StyleKind ¬ screen, -- screen or print style
commentFilter: CommentFilter ¬ includeComments, -- controls showing of comment nodes
firstLinesOnly: BOOL ¬ FALSE, -- if true, display only first line of each node
clipLevel: NestingLevel ¬ NestingLevel.LAST, -- display no nodes deeper than this
scrollLoc: Tioga.Location ¬ [NIL, 0], -- starting location set by scrollbar
-- computed view --
lines: LineArray ¬ NIL, -- formatted lines
nLines: NAT ¬ 0, -- number of lines
maxLevel: NestingLevel ¬ 0, -- max nesting level currently displayed
stopLoc: Tioga.Location ¬ [NIL, 0], -- location of line that would follow view, if any
range: VisibleRange ¬ [0, 1], -- what portion of document is visible
propList: Atom.PropList ¬ NIL
];
StyleKind: TYPE ~ NodeStyle.StyleKind;
CommentFilter: TYPE ~ { includeComments, excludeComments, onlyComments };
NestingLevel: TYPE ~ INTEGER; -- this type should be in TextNode
VisibleRange: TYPE ~ RECORD [top, bot: REAL];
Scroll: TYPE ~ { no, endofdoc, endofsel };
LineArray: TYPE ~ REF LineArrayRep;
LineArrayRep: TYPE ~ RECORD [SEQUENCE size: NAT OF Line];
Line: TYPE ~ REF LineRep;
LineRep: TYPE ~ RECORD [
info: TEditFormat.LineInfo,
baseline: INTEGER ¬ 0, -- from top of viewer
resolve: INTEGER ¬ 0, -- from top of viewer
valid: BOOL ¬ FALSE -- metrics valid for this line
];
Window
Window: TYPE ~ REF WindowRep;
WindowRep: TYPE ~ RECORD [class: WindowClass, data: REF];
WindowClass: TYPE ~ REF WindowClassRep;
WindowClassRep: TYPE ~ RECORD [
Paint: PROC [self: Window, action: PROC [Imager.Context]],
SetScroll: PROC [self: Window, range: VisibleRange]
];
Ops
ForEachView: PROC [doc: Doc, action: PROC [View]];
SpinAndLock: PROC [view: View, who: Rope.ROPE,
interrupt, defer: BOOL ¬ FALSE] RETURNS [ok: BOOL];
if caller is not the original locking process, waits for other process to unlock first
if interrupt is true, increments view.interrupt to ask repaint of viewer to terminate
if defer is true and interrupt is true and view.interrupt > 0, returns false without locking.
Unlock: PROC [view: View];
give up the lock
Locking
WithDocLock: PROC [doc: Doc, action: PROC [doc: Doc]];
WithDocLocks: PROC [doc1, doc2: Doc, action: PROC [doc1, doc2: Doc]];
WithDocLockViaView: PROC [view: View, action: PROC [doc: Doc]];
WithDocLocksViaViews: PROC [view1, view2: View, action: PROC [doc1, doc2: Doc]];
END.