TEditDocumentsCacheImpl.mesa
Copyright Ó 1985, 1991 by Xerox Corporation. All rights reserved.
Edited by Paxton on October 20, 1982 8:39 am
Last Edited by: Maxwell, January 6, 1983 11:10 am
Last Edited by: Plass, April 10, 1985 10:17:55 am PST
Michael Plass, October 19, 1987 10:37:13 am PDT
Doug Wyatt, October 29, 1991 5:56 pm PST
DIRECTORY
Menus USING [ChangeNumberOfLines],
Process USING [Detach],
Rope USING [Concat, Equal, Map, ROPE, Size],
TEditDocumentsCache USING [],
TEditDocumentPrivate USING [],
TEditInput USING [FreeTree],
TEditProfile USING [showUnsavedDocumentsList, unsavedDocumentCacheSize],
TextNode USING [Ref],
TiogaAccess USING [Create, Looks, Put, Writer],
TiogaAccessViewers USING [WriteViewer],
ViewerClasses USING [Viewer],
ViewerOps USING [CreateViewer, DestroyViewer, EstablishViewerPosition, PaintViewer];
TEditDocumentsCacheImpl: CEDAR MONITOR
IMPORTS Menus, Process, Rope, TEditInput, TEditProfile, TiogaAccess, TiogaAccessViewers, ViewerOps
EXPORTS TEditDocumentsCache, TEditDocumentPrivate
=
BEGIN
ROPE: TYPE ~ Rope.ROPE;
UnsavedDocumentInfo: TYPE = REF UnsavedDocumentInfoRec;
UnsavedDocumentInfoRec:
TYPE =
RECORD [fileName:
ROPE, root: TextNode.Ref];
list: LIST OF UnsavedDocumentInfo;
viewer: ViewerClasses.Viewer;
GetList:
PUBLIC
ENTRY
PROC
RETURNS [
ROPE] = {
RETURN [GetListInternal[]]
};
GetListInternal:
INTERNAL
PROC
RETURNS [rope:
ROPE] = {
FOR l:
LIST
OF UnsavedDocumentInfo ¬ list, l.rest
UNTIL l=
NIL
DO
rope ¬ Rope.Concat[rope, Rope.Concat["\n", l.first.fileName]];
ENDLOOP;
};
RecordUnsavedDocument:
PUBLIC
ENTRY
PROC [fileName:
ROPE, root: TextNode.Ref] = {
ENABLE UNWIND => NULL;
Size:
PROC
RETURNS [size:
INTEGER] = {
size ¬ 0;
IF list=NIL THEN RETURN;
FOR l:
LIST
OF UnsavedDocumentInfo ¬ list, l.rest
UNTIL l=
NIL
DO
size ¬ size+1;
ENDLOOP;
};
info: UnsavedDocumentInfo;
oldRoot: TextNode.Ref;
IF (oldRoot ¬ SearchList[fileName]) #
NIL
THEN
-- discard previous entry, if any
TEditInput.FreeTree[oldRoot];
info ¬ NEW[UnsavedDocumentInfoRec ¬ [fileName, root]];
list ¬ CONS[info, list];
WHILE Size[] >
MAX[TEditProfile.unsavedDocumentCacheSize, 0]
DO
DiscardOldest[];
ENDLOOP;
TRUSTED { Process.Detach[FORK Update[]] };
};
FindUnsavedDocument:
PUBLIC
ENTRY
PROC [fileName:
ROPE]
RETURNS [root: TextNode.Ref] = {
ENABLE UNWIND => NULL;
IF (root ¬ SearchList[fileName]) # NIL THEN TRUSTED {Process.Detach[FORK Update[]] }
};
DiscardOldest:
PROC = {
IF list=NIL THEN RETURN;
FOR l:
LIST
OF UnsavedDocumentInfo ¬ list, l.rest
DO
IF l.rest # NIL THEN LOOP; -- spin until get to the oldest entry
TEditInput.FreeTree[SearchList[l.first.fileName]];
RETURN;
ENDLOOP;
};
SearchList:
PROC [fileName:
ROPE]
RETURNS [root: TextNode.Ref] = {
-- if find, then remove
prev: LIST OF UnsavedDocumentInfo;
IF list=NIL THEN RETURN [NIL];
IF Rope.Equal[list.first.fileName, fileName,
FALSE]
THEN {
root ¬ list.first.root;
list ¬ list.rest;
RETURN;
};
prev ¬ list;
FOR l:
LIST
OF UnsavedDocumentInfo ¬ list.rest, l.rest
UNTIL l=
NIL
DO
IF Rope.Equal[l.first.fileName, fileName,
FALSE]
THEN {
root ¬ l.first.root;
prev.rest ¬ l.rest;
RETURN;
};
prev ¬ l;
ENDLOOP;
RETURN [NIL];
};
Update:
PUBLIC
ENTRY
PROC = {
ENABLE UNWIND => NULL;
rope: ROPE ¬ GetListInternal[]; -- this is monitored, so get consistent list
viewerName: ROPE = "Unsaved Documents List";
ViewerOk:
PROC
RETURNS [
BOOL] = {
RETURN [viewer #
NIL
AND
NOT viewer.destroyed
AND viewer.file=
NIL
AND
Rope.Equal[viewer.name, viewerName]]
};
writer: TiogaAccess.Writer ~ TiogaAccess.Create[];
looks: TiogaAccess.Looks ¬ ALL[FALSE];
format: ATOM ¬ NIL;
comment: BOOL ¬ FALSE;
deltaLevel: INT ¬ 1;
Put:
PROC [rope:
ROPE] ~ {
action:
PROC [c:
CHAR]
RETURNS [quit:
BOOL ¬
FALSE] ~ {
TiogaAccess.Put[writer, [
charSet: 0,
char: c,
looks: looks,
format: format,
comment: comment,
endOfNode: (c = '\n),
deltaLevel: deltaLevel,
propList: NIL
]];
};
[] ¬ Rope.Map[base: rope, action: action];
};
IF NOT TEditProfile.showUnsavedDocumentsList THEN RETURN;
IF Rope.Size[rope] = 0
THEN {
IF ViewerOk[] THEN ViewerOps.DestroyViewer[viewer];
RETURN
};
IF
NOT ViewerOk[]
THEN {
viewer ¬ ViewerOps.CreateViewer[flavor: $Text, info: [name: viewerName,
iconic: TRUE], paint: FALSE];
viewer.class.set[self: viewer, data: NIL, op: $ReadOnly];
Menus.ChangeNumberOfLines[viewer.menu, 0]; -- don't let user mess with it
ViewerOps.EstablishViewerPosition[viewer, viewer.wx, viewer.wy, viewer.ww, viewer.wh];
ViewerOps.PaintViewer[viewer, all]
};
format ¬ $note;
Put["The following files were edited but not saved. They may still be restored with edits intact simply by loading them. If you really want to get rid of the edits, load the file and hit Reset.\n"];
format ¬ $lead;
deltaLevel ¬ 0;
Put[rope];
Put["\n"];
TiogaAccessViewers.WriteViewer[writer, viewer];
viewer.newVersion ¬ TRUE; -- set edited bit
ViewerOps.PaintViewer[viewer, caption]
}; -- repaint the caption
END.