TiogaPrivate.mesa
Copyright Ó 1986 by Xerox Corporation. All rights reserved.
Doug Wyatt, September 22, 1986 5:10:28 pm PDT
DIRECTORY
Rosary USING [ROSARY],
Tioga;
TiogaPrivate: CEDAR DEFINITIONS
~ BEGIN OPEN Tioga;
ROSARY: TYPE ~ Rosary.ROSARY;
CheckNode, TreeCheck
CheckFailed: ERROR;
Check: PROC [node: Node];
does CheckRope & CheckRuns
CheckRope: PROC [rope: ROPE];
CheckRuns: PROC [runs: Runs];
Verify: PROC [node: Node];
... called to verify that a Tioga tree structure is valid. If a problem is discovered, an exit to the debugger with an error message and locale is taken.
NodeProps
Put, Remove properties
RefBool: PROC [BOOL] RETURNS [REF BOOL];
Returns a shared REF to the given BOOL; convenient for boolean property values.
PutProp: PROC [n: Node, name: ATOM, value: REF];
NIL is a valid value. Use RemProp to remove property. (Although GetProp will not distinguish between property value NIL and no property present, it is useful to be able to have NIL values to avoid creating garbage. Setting to NIL doesn't release the property record, so don't need to reallocate when next set to a non-NIL value.
RemProp: PROC [n: Node, name: ATOM];
Property Attributes
This section deals with attributes of property names. Attributes are just tags associated with the property names that modify the way the properties are treated by Tioga. The most important attribute is $Visible, which says whether or not the value of the property can affect the appearance of the formatted document; if such a property's value is changed (at the TextEdit level or above), the node and all of its children will be repainted. The attributes are associated with the code that is currently loaded and registered, not with documents. Refer to NodePropsImpl for a list of meaningful attributes.
DeclarePropertyAttribute: PROC [name: ATOM, attribute: ATOM];
Associates an attribute with a property name.
Is: PROC [name: ATOM, attribute: ATOM] RETURNS [BOOL];
Tests whether the named property and a given attribute.
GetPropertyAttributes: PROC [name: ATOM] RETURNS [LIST OF ATOM];
For completeness only; list is read-only.
SetPropertyAttributes: PROC [name: ATOM, attributes: LIST OF ATOM];
For completeness only; list is read-only.
NodeAddrs
AddrsProp: PROC RETURNS [ATOM];
PutTextAddr: PROC [n: Node, addr: REF, location: INT, pin: BOOLFALSE];
assigns addr to location in text
ok if addr was previously assigned elsewhere in the text
location automatically updated when text is edited
RemTextAddr: PROC [n: Node, addr: REF];
removes the given addr
if addr has been moved, does RemTextAddr on new location also
PinTextAddr: PROC [n: Node, addr: REF];
don't modify location when edits take place
UnpinTextAddr: PROC [n: Node, addr: REF];
UnpinAllAddrs: PROC [n: Node];
MoveTextAddr: PROC [from, to: Node, addr: REF, location: INT];
does RemTextAddr[from, addr]; PutTextAddr[to, addr, location];
add leaves forwarding address for use by GetTextAddr
GetTextAddr: PROC [n: Node, addr: REF] RETURNS [node: Node, location: INT];
generates ERROR TextAddrNotFound if the addr is not in the mapping
node may be different than n if addr has been moved
TryGetTextAddr: PROC [n: Node, addr: REF]
RETURNS [found: BOOL, node: Node, location: INT];
TextAddrNotFound: ERROR;
MapTextAddrs: PROC [n: Node, action: TextAddrsAction] RETURNS [BOOL];
apply the action to each addr&location pair for the text
returns true if&when an action returns true
skips pinned or moved addresses
TextAddrsAction: TYPE = PROC [addr: REF, location: INT] RETURNS [BOOL];
Notify proc registration
AddAddrNotifyProc: PROC [proc: AddrNotifyProc];
RemoveAddrNotifyProc: PROC [proc: AddrNotifyProc];
AddrNotifyProc: TYPE = PROC [node: Node, new: PROC [old: INT] RETURNS [INT]];
Editing Operations for persistent addrs
AddrReplace: PROC [node: Node, start, len, newlen: INT];
replace chars in [start..start+len) by newlen chars
addrs that are in the replaced section move to start
add (newlen-len) to addrs that are after the replaced section
Update Functions for persistent addrs
AfterReplace: PROC [initLoc, start, len, newlen: INT] RETURNS [newLoc: INT];
EditNotify
Change Record
ChangeType: TYPE = {
ChangingView, ChangingText, ChangingTextForPaste, ChangingSpanForPaste,
ChangingFormat, ChangingProp, MovingNodes, NodeNesting, InsertingNode
};
Change: TYPE = RECORD [SELECT kind: ChangeType FROM
ChangingView => [
viewer: REF,
old: Location
],
ChangingText => [
root: Node, text: Node,
start, newlen, oldlen: INT,
oldRope: ROPE,
oldRuns: Runs,
oldCharSets: ROSARY,
oldCharProps: ROSARY
],
ChangingTextForPaste => [
rope: ROPE,
runs: Runs,
charSets: ROSARY,
charProps: ROSARY,
start, len: INT
],
ChangingSpanForPaste => [
span: Span
],
ChangingFormat => [ -- change format for node
root: Node, node: Node,
newFormatName, oldFormatName: ATOM
],
ChangingProp => [ -- change property for node
root, node: Node, propName: ROPE, propAtom: ATOM, newval, oldval: REF
],
MovingNodes => [
destRoot, sourceRoot: Node,
dest, first, last, pred: Node, nesting: INTEGER,
afterDest: BOOL
],
dest cannot be within nodes [first..last]
pred is the node before first. pred and nesting used for undo
NodeNesting => [ -- change nesting of nodes [first..last]
root, first, last: Node, change: INTEGER
],
InsertingNode => [ -- insert new node after dest
root, new, dest: Node
],
ENDCASE
];
Notification Operations
ChangeSet: TYPE = PACKED ARRAY ChangeType OF Flag;
Flag: TYPE = BOOLFALSE;
defaultChangeSet: ChangeSet = ALL[TRUE];
EditNotifyProc: TYPE = PROC [change: REF READONLY Change];
When: TYPE = { before, after };
indicates whether notify before or after the change has taken place
Priority: TYPE = { high, normal, low };
high priority procs called before normal, and normal called before low
e.g., might use high priority for clearing style cache,
normal for redisplay, and
low for saving replay info
AddEditNotifyProc: PROC [world: World, proc: EditNotifyProc, time: When ← after,
priority: Priority ← normal, changeSet: ChangeSet ← defaultChangeSet];
add new proc to list of notification procedures
call proc before/after any edit in its changeSet
use time=before for applications such as saving text for undo
use time=after for applications such as reformat & redisplay
RemoveEditNotifyProc: PROC [world: World, proc: EditNotifyProc, time: When ← after];
remove proc from list of notification procedures
EditNotify: PROC [world: World, change: REF READONLY Change, time: When];
call the appropriate edit notify procs
UndoEvent
Event: TYPE = REF EventBody;
EventBody: TYPE = RECORD [subevents: SubEvent];
SubEvent: TYPE = REF SubEventBody;
SubEventBody: TYPE = RECORD [
next: SubEvent,
undoProc: UndoProc,
undoRef: REF Change
];
UndoProc: TYPE ~ PROC [world: World, undoRef: REF Change];
procedure supplied by client to undo the effects of a particular subevent
CreateEvent: PROC RETURNS [Event];
NoteEvent: PROC [world: World, undoProc: UndoProc, undoRef: REF Change];
adds <undoProc, undoRef> to list of subevents
UndoEvent: PROC [world: World, undoEvent: Event];
calls undoProc[world, undoRef] for each subevent
in reverse order that subevents originally happened
world arg is to record the effects of Undo so it too will be undoable
ResetEvent: PROC [event: Event];
resets the list of subevents to NIL
Undo automatically does a Reset when it is finished
EmptyEvent: PROC [event: Event] RETURNS [BOOL];
returns true if subevents list is empty
Miscellaneous
Flatten: PROC [node: Node] RETURNS [BOOL];
returns true if it decides to flatten rope & runs
this is done automatically after a certain number of edits to the node
World info
EditNotifyData: TYPE ~ REF EditNotifyDataRep;
EditNotifyDataRep: TYPE; -- see EditNotifyImpl
World: TYPE ~ REF WorldRep;
WorldRep: TYPE ~ RECORD [
editNotify: EditNotifyData,
currentEvent: Event,
paste: REF Change.ChangingSpanForPaste,
afterMoved1, afterMoved2: Location
];
END.