<> <> <> <> <> 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 = BEGIN ENABLE UNWIND => NULL; 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]; END; ClearButton: Menus.ClickProc = BEGIN ENABLE UNWIND => NULL; 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]; END; SaveButton: Menus.ClickProc = BEGIN 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]; ViewerOps.DestroyViewer[viewer]; END; DetachButton: Menus.ClickProc = BEGIN 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]; END; DiscardButton: Menus.ClickProc = BEGIN 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]; ViewerOps.DestroyViewer[NARROW[parent]]; END; ShouldSkip: ENTRY PROC [data: REF MyData, finish: BOOL_FALSE] RETURNS [skip: BOOL] = BEGIN ENABLE UNWIND => NULL; skip _ data.finished OR ~data.init; IF finish THEN data.finished _ data.init; END; NotifyFinished: ENTRY PROC [data: REF MyData] = BEGIN ENABLE UNWIND => NULL; NOTIFY data.saved; END; WaitUntilDone: ENTRY PROC[myData: REF MyData] = BEGIN ENABLE UNWIND => NULL; WHILE ~myData.finished DO WAIT myData.saved; ENDLOOP; END; Edit: PUBLIC PROC [contents, caption, formatting: Rope.ROPE_NIL, save: SaveProc_NIL, clientData: REF_NIL, fork: BOOL_TRUE, saveOnDiscard: BOOL_FALSE ] = BEGIN MakeMenu: PROC [data: REF MyData, needDiscard: BOOL] RETURNS [menu: Menus.Menu] = BEGIN menu _ Menus.CreateMenu[]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[name: "Clear", proc: ClearButton, clientData: data, guarded: TRUE]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[name: "Reset", proc: ResetButton, clientData: data, guarded: TRUE]]; IF needDiscard THEN Menus.AppendMenuEntry[menu, Menus.CreateEntry[name: "Discard", proc: DiscardButton, clientData: data, guarded: TRUE]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[name: "Save", proc: SaveButton, clientData: data]]; Menus.AppendMenuEntry[menu, Menus.CreateEntry[name: "Detach", proc: DetachButton, clientData: data]]; END; viewer: ViewerClasses.Viewer; myData: REF MyData _ NEW[MyData]; myData.save _ save; myData.clientData _ clientData; myData.tiogaContents _ NEW[ViewerTools.TiogaContentsRec _ [contents: contents, formatting: formatting] ]; viewer _ ViewerTools.MakeNewTextViewer[[ iconic: FALSE, name: caption, inhibitDestroy: saveOnDiscard ]]; ViewerOps.SetMenu[viewer, MakeMenu[myData, saveOnDiscard]]; ViewerTools.SetTiogaContents[viewer, myData.tiogaContents]; ViewerTools.SetSelection[viewer, NEW[ViewerTools.SelPosRec]]; ViewerOps.PaintViewer[viewer, $menu]; myData.init _ TRUE; IF ~fork THEN WaitUntilDone[myData]; END; <<>> END.