<> <> <> DIRECTORY Containers USING [ChildXBound, ChildYBound], Convert USING [RopeFromInt], Graph USING [Entity, EntityGroup, EntityGroupList, EntityList, GraphHandle, GraphProc, NestedEntities, NestedEntitiesList, ROPE, Text, Texts, Viewer], GraphPrivate USING [CallWithLock, RemoveEntity, RemoveText, ShowEntity, ShowText, UserEditAllowed], GraphUtil USING [BlinkMsg, ControllerViewerExits, HandleNotNil], <> Rope USING [Concat, Fetch, IsEmpty, Length], TiogaFileOps USING [AddLooks, CreateRoot, InsertAsLastChild, InsertNode, Ref, SetContents, Store], TiogaButtons USING [CreateButton, CreateButtonFromNode, CreateViewer, LoadViewer, MarkViewerNotEdited, TiogaButton, TiogaButtonList, TiogaButtonProc], TiogaOps USING [Break, FirstChild, GetProp, GetRope, InsertRope, LastChild, Lock, LockSel, Nest, Next, Ref, RestoreSelA, SaveSelA, SelectPoint, SetSelection, StepForward, Unlock, UnlockSel, ViewerDoc], ViewerTools USING [SetContents]; GraphTable: CEDAR PROGRAM IMPORTS Containers, Convert, GraphPrivate, GraphUtil, Rope, TiogaFileOps, TiogaOps, TiogaButtons, ViewerTools EXPORTS GraphPrivate = { OPEN Graph, GraphPrivate; GraphButtonData: TYPE = REF GraphButtonDataRec; GraphButtonDataRec: TYPE = RECORD[ handle: GraphHandle _ NIL, ref: REF ANY _ NIL ]; MakeTable: PUBLIC PROC [handle: GraphHandle, file: ROPE, sx, sy: INTEGER] = { <> IF GraphUtil.HandleNotNil[handle] THEN { OPEN handle; controller.table _ TiogaButtons.CreateViewer[ info: [ wx: sx, wy: sy, ww: 1000, wh: 1000, menu: NIL, parent: controller.viewer, scrollable: TRUE, border: FALSE, caption: FALSE ]]; Containers.ChildXBound[controller.viewer, controller.table]; Containers.ChildYBound[controller.viewer, controller.table]; MakeTableFile[handle, file]; TiogaButtons.LoadViewer[controller.table, file]; CreateButtons[handle]; <> }; }; -- MakeTable MakeTableFile: PROC [handle: GraphHandle, tableFile: ROPE] = { root, prev: TiogaFileOps.Ref; IF GraphUtil.HandleNotNil[handle] THEN { OPEN handle; root _ TiogaFileOps.CreateRoot[]; prev _ TextsTable[handle, root]; FOR egl: EntityGroupList _ entityGroupList, egl.rest UNTIL egl = NIL DO prev _ NETable[handle, egl.first.ys, root, root, prev]; ENDLOOP; TiogaFileOps.Store[root, tableFile]; }; }; -- MakeTableFile NextNode: PROC [root, prev: TiogaFileOps.Ref, rope: ROPE, child: BOOL, look: ROPE _ NIL] RETURNS [new: TiogaFileOps.Ref] = { new _ TiogaFileOps.InsertNode[prev, child]; TiogaFileOps.SetContents[new, rope]; IF NOT look.IsEmpty[] THEN FOR i: INT IN [0..look.Length[]) DO TiogaFileOps.AddLooks[new, 0, rope.Length[], look.Fetch[i], root]; ENDLOOP; }; -- NextNode LastChild: PROC [root, parent, prev: TiogaFileOps.Ref, rope: ROPE, look: ROPE _ NIL] RETURNS [new: TiogaFileOps.Ref] = { new _ TiogaFileOps.InsertAsLastChild[parent, prev]; TiogaFileOps.SetContents[new, rope]; IF NOT look.IsEmpty[] THEN FOR i: INT IN [0..look.Length[]) DO TiogaFileOps.AddLooks[new, 0, rope.Length[], look.Fetch[i], root]; ENDLOOP; }; -- LastChild TextsTable: PROC [handle: GraphHandle, root: TiogaFileOps.Ref] RETURNS [new: TiogaFileOps.Ref] = { new _ NextNode[root, root, "", TRUE]; new _ NextNode[root, new, "Texts", FALSE, "lb"]; -- texts parent new _ NextNode[root, new, "", TRUE]; -- leading blank line FOR ts: Texts _ handle.allTexts, ts.rest UNTIL ts = NIL DO t: Text _ ts.first; -- error if nil. new _ NextNode[ root: root, prev: new, rope: IF t.text = NIL THEN Convert.RopeFromInt[t.id] ELSE t.text, child: FALSE, look: NIL ]; ENDLOOP; }; -- TextsTable <<>> EntityListTable: PROC [handle: GraphHandle, entityList: EntityList, root, parent: TiogaFileOps.Ref] RETURNS [new: TiogaFileOps.Ref] = { new _ parent; -- which is also the previous node. IF entityList # NIL THEN new _ NextNode[root, parent, "", TRUE]; FOR el: EntityList _ entityList, el.rest UNTIL el = NIL DO entity: Entity _ el.first; -- error if nil. new _ LastChild[root: root, parent: parent, prev: new, rope: IF entity.name.IsEmpty[] AND entity.comment.IsEmpty[] THEN Convert.RopeFromInt[entity.id] ELSE entity.name.Concat[entity.comment], look: NIL ]; ENDLOOP; }; -- EntityListTable NETable: PROC [handle: GraphHandle, ne: NestedEntities, root, parent, prev: TiogaFileOps.Ref] RETURNS [new: TiogaFileOps.Ref] = { new _ prev; IF ne # NIL THEN { topLevel: BOOL _ parent = root; neNode: TiogaFileOps.Ref; <> new _ LastChild[root: root, parent: parent, prev: prev, rope: "", look: NIL]; neNode _ new _ NextNode[root: root, prev: new, -- ne.node rope: ne.name.Concat[ne.comment], child: FALSE, look: IF topLevel THEN "lb" ELSE "b" ]; <> new _ EntityListTable[handle, ne.entityList, root, neNode]; FOR nel: NestedEntitiesList _ ne.children, nel.rest UNTIL nel = NIL DO new _ NETable[handle, nel.first, root, neNode, new]; ENDLOOP; }; }; -- NETable CreateButtons: PROC [handle: GraphHandle] = { OPEN handle; root: TiogaOps.Ref _ TiogaOps.ViewerDoc[controller.table]; prev: TiogaOps.Ref; <> <> prev _ TextsButtons[handle, root]; FOR egl: EntityGroupList _ entityGroupList, egl.rest UNTIL egl = NIL DO prev _ NEButtons[handle, egl.first.ys, root, root, prev]; ENDLOOP; <> <> }; -- CreateButtons TextsButtons: PROC [handle: GraphHandle, root: TiogaOps.Ref] RETURNS [last: TiogaOps.Ref] = { OPEN handle; last _ TiogaOps.FirstChild[root]; controller.textsParent _ last _ TiogaOps.StepForward[last]; last _ TiogaOps.StepForward[last]; FOR ts: Texts _ handle.allTexts, ts.rest UNTIL ts = NIL DO t: Text _ ts.first; -- error if nil. last _ TiogaOps.StepForward[last]; [] _ TiogaButtons.CreateButtonFromNode[node: last, proc: TextButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, t]] ]; ENDLOOP; }; -- TextsButtons EntityListButtons: PROC [handle: GraphHandle, entityList: EntityList, root, parent: TiogaOps.Ref] RETURNS [last: TiogaOps.Ref] = { last _ parent; -- which is also the previous node. IF entityList # NIL THEN last _ TiogaOps.StepForward[last]; FOR el: EntityList _ entityList, el.rest UNTIL el = NIL DO entity: Entity _ el.first; -- error if nil. last _ TiogaOps.StepForward[last]; [] _ TiogaButtons.CreateButtonFromNode[node: last, proc: EntityButtonProc, clientData: NEW[GraphButtonDataRec _ [handle, entity]] ]; ENDLOOP; }; -- EntityListButtons NEButtons: PROC [handle: GraphHandle, ne: NestedEntities, root, parent, prev: TiogaOps.Ref] RETURNS [last: TiogaOps.Ref] = { last _ prev; IF ne # NIL THEN { topLevel: BOOL _ parent = root; last _ TiogaOps.StepForward[last]; ne.node _ last _ TiogaOps.StepForward[last]; last _ EntityListButtons[handle, ne.entityList, root, ne.node]; FOR nel: NestedEntitiesList _ ne.children, nel.rest UNTIL nel = NIL DO last _ NEButtons[handle, nel.first, root, ne.node, last]; ENDLOOP; }; }; -- NEButtons EntityGroupButtonProc: TiogaButtons.TiogaButtonProc = { -- noop for now <> <> <> <> <> <