<> <> <> <> <> <> DIRECTORY CDRopeViewer, Menus, ViewerOps, ViewerClasses, ViewerTools, Rope; CDRopeViewerImpl: CEDAR MONITOR IMPORTS ViewerOps, ViewerTools, Menus EXPORTS CDRopeViewer = BEGIN SaveProc: TYPE = CDRopeViewer.SaveProc; <<--PROC[contents, formatting: Rope.ROPE, clientData: REF, discard: BOOL]>> MyData: TYPE = RECORD [ tiogaContents: ViewerTools.TiogaContents _ NIL, init: BOOL _ FALSE, finished: BOOL _ FALSE, --monitored save: SaveProc _ NIL, clientData: REF _ NIL, skipSaveOnDiscard: BOOL _ TRUE, saved: CONDITION ]; ResetButton: Menus.ClickProc = { data: REF MyData ~ NARROW[clientData]; viewer: ViewerClasses.Viewer ~ NARROW[parent]; IF ShouldSkip[data, FALSE] THEN RETURN; -- ignore additional clicks ViewerTools.SetTiogaContents[viewer, data.tiogaContents]; ViewerOps.PaintViewer[viewer, $menu]; }; ClearButton: Menus.ClickProc = { data: REF MyData ~ NARROW[clientData]; viewer: ViewerClasses.Viewer ~ NARROW[parent]; IF ShouldSkip[data, FALSE] THEN RETURN; -- ignore additional clicks ViewerTools.SetTiogaContents[viewer, NEW[ViewerTools.TiogaContentsRec]]; ViewerOps.PaintViewer[viewer, $menu]; }; Destroy: PROC [viewer: ViewerClasses.Viewer] = { <<--Destroys all the linked viewers>> first: ViewerClasses.Viewer _ viewer; WHILE viewer#NIL DO next: ViewerClasses.Viewer _ viewer.link; ViewerOps.DestroyViewer[viewer]; IF next=first OR next=NIL THEN EXIT; viewer _ next; ENDLOOP }; SaveButton: Menus.ClickProc = { data: REF MyData ~ NARROW[clientData]; viewer: ViewerClasses.Viewer ~ NARROW[parent]; IF ShouldSkip[data, TRUE] THEN RETURN; -- ignore additional clicks data.tiogaContents _ ViewerTools.GetTiogaContents[viewer]; data.save[data.tiogaContents.contents, data.tiogaContents.formatting, data.clientData, FALSE]; NotifyFinished[data]; Destroy[viewer]; }; DetachButton: Menus.ClickProc = { data: REF MyData ~ NARROW[clientData]; viewer: ViewerClasses.Viewer ~ NARROW[parent]; newViewer: ViewerClasses.Viewer; tiogaContents: ViewerTools.TiogaContents; IF ShouldSkip[data, FALSE] THEN RETURN; -- ignore additional clicks tiogaContents _ ViewerTools.GetTiogaContents[viewer]; newViewer _ ViewerTools.MakeNewTextViewer[[name: "[Detached comment]"]]; ViewerTools.SetTiogaContents[newViewer, tiogaContents]; }; DiscardButton: Menus.ClickProc = { data: REF MyData ~ NARROW[clientData]; IF ShouldSkip[data, TRUE] THEN RETURN; IF ~data.skipSaveOnDiscard THEN { data.save[data.tiogaContents.contents, data.tiogaContents.formatting, data.clientData, TRUE] }; NotifyFinished[data]; Destroy[NARROW[parent]]; }; ShouldSkip: ENTRY PROC [data: REF MyData, finish: BOOL_FALSE] RETURNS [skip: BOOL] = { ENABLE UNWIND => NULL; skip _ data.finished OR ~data.init; IF finish THEN data.finished _ data.init; }; NotifyFinished: ENTRY PROC [data: REF MyData] = { ENABLE UNWIND => NULL; NOTIFY data.saved; }; WaitUntilDone: ENTRY PROC[myData: REF MyData] = { ENABLE UNWIND => NULL; WHILE ~myData.finished DO WAIT myData.saved; ENDLOOP; }; Edit: PUBLIC PROC [contents, caption, formatting: Rope.ROPE_NIL, save: SaveProc_NIL, clientData: REF_NIL, fork: BOOL_TRUE, saveOnDiscard: BOOL_FALSE] = { <> MakeMenu: PROC [data: REF MyData, needDiscard: BOOL, previous: Menus.Menu] RETURNS [menu: Menus.Menu] = { RemoveEntry: PROC [key: Rope.ROPE] = { entry: Menus.MenuEntry = Menus.FindEntry[menu, key]; IF entry#NIL THEN Menus.ReplaceMenuEntry[menu, entry, NIL]; }; AddEntry: PROC [key: Rope.ROPE, proc: Menus.ClickProc, guarded: BOOL _ FALSE] ~ { Menus.InsertMenuEntry[menu, Menus.CreateEntry[name: key, proc: proc, clientData: data, documentation: NIL, fork: TRUE, guarded: guarded]]; }; menu _ IF previous#NIL THEN Menus.CopyMenu[previous] ELSE Menus.CreateMenu[]; RemoveEntry["Get"]; RemoveEntry["GetImpl"]; RemoveEntry["Store"]; RemoveEntry["Clear"]; RemoveEntry["Reset"]; RemoveEntry["Save"]; RemoveEntry["PrevFile"]; IF needDiscard AND save#NIL THEN AddEntry["Discard", DiscardButton, TRUE]; IF save#NIL THEN AddEntry["Save", SaveButton]; AddEntry["Detach", DetachButton]; AddEntry["Reset", ResetButton, TRUE]; AddEntry["Clear", ClearButton, TRUE]; }; viewer: ViewerClasses.Viewer; myData: REF MyData _ NEW[MyData _ [ tiogaContents: NEW[ViewerTools.TiogaContentsRec _ [contents: contents, formatting: formatting]], init: FALSE, finished: FALSE, save: save, clientData: clientData ]]; viewer _ ViewerTools.MakeNewTextViewer[[ iconic: FALSE, name: caption, inhibitDestroy: saveOnDiscard ]]; ViewerOps.SetMenu[viewer, MakeMenu[myData, saveOnDiscard, viewer.menu]]; ViewerTools.SetTiogaContents[viewer, myData.tiogaContents]; ViewerTools.SetSelection[viewer, NEW[ViewerTools.SelPosRec]]; IF save=NIL THEN ViewerTools.InhibitUserEdits[viewer]; ViewerOps.PaintViewer[viewer, $menu]; myData.init _ TRUE; IF ~fork THEN WaitUntilDone[myData]; }; <<>> END.