<> <> <> <> <<(Changed the implementation so that this interface never catches any errors -- they will all be caught at the WhiteboardDB level and turned into WBErrors)>> <<(Added Grid size property to whiteboards)>> <> DIRECTORY Atom, DB, FileNames USING[GetShortName], Rope, ViewerTools, WhiteboardDBPrivate; WhiteboardDBPrivateImpl: CEDAR PROGRAM IMPORTS DB, FileNames, Atom, Rope EXPORTS WhiteboardDBPrivate = BEGIN OPEN WhiteboardDBPrivate; ROPE: TYPE = Rope.ROPE; WBSegment: PUBLIC ROPE _ NIL; wbType: PUBLIC ATOM _ $Whiteboard; <> WBEntity: DB.Domain; -- the domain of whiteboards <> versionProp: DB.Attribute; gridProp: DB.Attribute; WBItem: DB.Domain; -- the domain of entities that are displayed on whiteboards Note: DB.Entity; -- notes (text boxes) are a subclass of WBItems Icon: DB.Entity; -- Icons are the other class of WBItems <> contents: DB.Attribute; format: DB.Attribute; <> iconName: DB.Attribute; iconLabel: DB.Attribute; iconType: DB.Attribute; iconIcon: DB.Attribute; iconArgument: DB.Attribute; <> container: DB.Relation; containerIs: DB.Attribute; containerOf: DB.Attribute; containerX: DB.Attribute; containerY: DB.Attribute; containerW: DB.Attribute; containerH: DB.Attribute; CloseTransaction: PROC [] = { trans: DB.Transaction = DB.GetSegmentInfo[$Whiteboard].trans; caughtAborted: BOOL _ FALSE; IF trans # NIL THEN DB.CloseTransaction[trans ! DB.Aborted => { caughtAborted _ TRUE; CONTINUE }]; IF caughtAborted THEN DB.AbortTransaction[trans] }; Initialize: PUBLIC PROC[DBFile: ROPE] = BEGIN IF NOT Rope.Equal[WBSegment, DBFile] THEN { IF WBSegment = NIL THEN WBSegment _ DBFile ELSE {WBSegment _ DBFile; CloseTransaction[] } }; ResetSchema[] END; ResetSchema: PUBLIC PROC[] = { IF DB.GetSegmentInfo[$Whiteboard].trans # NIL THEN RETURN; SetUpSegment[WBSegment]; IF NOT DB.Null[Note] THEN RETURN; Note _ DB.DeclareDomain["Note", $Whiteboard]; Icon _ DB.DeclareDomain["WBIcon", $Whiteboard]; WBItem _ DB.DeclareDomain["WBItems", $Whiteboard]; DB.DeclareSubType[of: WBItem, is: Note]; DB.DeclareSubType[of: WBItem, is: Icon]; WBEntity _ DB.DeclareDomain["Whiteboard", $Whiteboard]; contents _ DB.DeclareProperty["contents", Note, DB.RopeType, $Whiteboard]; format _ DB.DeclareProperty["format", Note, DB.RopeType, $Whiteboard]; iconName _ DB.DeclareProperty["entity", Icon, DB.RopeType, $Whiteboard]; iconLabel _ DB.DeclareProperty["label", Icon, DB.RopeType, $Whiteboard]; iconType _ DB.DeclareProperty["type", Icon, DB.RopeType, $Whiteboard]; iconIcon _ DB.DeclareProperty["icon", Icon, DB.RopeType, $Whiteboard]; iconArgument _ DB.DeclareProperty["argument", Icon, DB.RopeType, $Whiteboard]; <> versionProp _ DB.DeclareProperty["version", WBEntity, DB.IntType, $Whiteboard]; gridProp _ DB.DeclareProperty["gridSize", WBEntity, DB.IntType, $Whiteboard]; container _ DB.DeclareRelation["container", $Whiteboard]; containerIs _ DB.DeclareAttribute[container, "is", WBEntity]; containerOf _ DB.DeclareAttribute[container, "of", WBItem]; containerX _ DB.DeclareAttribute[container, "x", DB.IntType]; containerY _ DB.DeclareAttribute[container, "y", DB.IntType]; containerW _ DB.DeclareAttribute[container, "w", DB.IntType]; containerH _ DB.DeclareAttribute[container, "h", DB.IntType]; [] _ DB.DeclareIndex[container, LIST[containerIs]] }; SetUpSegment: PROC [segmentFile: ROPE] ~ { segment: ATOM = $Whiteboard; segmentNumber: NAT = 310B; readOnly: BOOL _ FALSE; DB.Initialize[nCachePages: 256]; <> DB.DeclareSegment[segmentFile, segment, segmentNumber, FALSE]; DB.OpenTransaction[$Whiteboard ! DB.Error => TRUSTED { IF code = ProtectionViolation THEN { readOnly _ TRUE; CONTINUE } ELSE REJECT } ]; IF readOnly THEN { <> DB.CloseTransaction[DB.GetSegmentInfo[segment].trans]; DB.DeclareSegment[segmentFile, segment, segmentNumber, TRUE, FALSE]; DB.OpenTransaction[segment] }; }; <> DeclareWhiteboard: PUBLIC PROC[name: ROPE] RETURNS[wb: Whiteboard] = { wb _ DB.DeclareEntity[WBEntity, name] }; GetVersion: PUBLIC PROC[wb: Whiteboard] RETURNS[version: INT] = { version _ DB.V2I[DB.GetP[wb, versionProp]] }; SetVersion: PUBLIC PROC[wb: Whiteboard, version: INT] = { [] _ DB.SetP[wb, versionProp, DB.I2V[version]] }; GetGridSize: PUBLIC PROC[wb: Whiteboard] RETURNS[gridSize: INT] = { gridSize _ DB.V2I[DB.GetP[wb, gridProp]]; IF gridSize <= 0 THEN gridSize _ 1 }; SetGridSize: PUBLIC PROC[wb: Whiteboard, gridSize: INT] = { [] _ DB.SetP[wb, gridProp, DB.I2V[gridSize]] }; NameOf: PUBLIC PROC[wb: Whiteboard] RETURNS[name: ROPE] = { name _ DB.NameOf[wb] }; DestroyWhiteboard: PUBLIC PROC[wb: Whiteboard] = { IF DB.Null[wb] THEN RETURN; DB.DestroyEntity[wb]; <> FOR wbList: LIST OF Whiteboard _ Enumerate[], wbList.rest UNTIL wbList = NIL DO nextWB: Whiteboard = wbList.first; name: ROPE = NameOf[nextWB]; children: ChildSet = Children[nextWB, TRUE]; FOR child: WhiteboardDBPrivate.WBItem _ NextChild[children], NextChild[children] UNTIL child = NIL DO IF Rope.Equal[name, GetIconProps[child].name] THEN DB.DestroyEntity[child] ENDLOOP ENDLOOP }; Exists: PUBLIC PROC[name: ROPE] RETURNS[BOOL] = { RETURN[NOT DB.Null[DB.DeclareEntity[WBEntity, name, OldOnly]]] }; Enumerate: PUBLIC PROC[] RETURNS[wbList: LIST OF Whiteboard] = { wbSet: DB.EntitySet = DB.DomainSubset[WBEntity]; FOR wb: DB.Entity _ DB.NextEntity[wbSet], DB.NextEntity[wbSet] UNTIL wb = NIL DO wbList _ CONS[wb, wbList] ENDLOOP; DB.ReleaseEntitySet[wbSet] }; <> FetchWBItem: PUBLIC PROC[name: ROPE, type: ItemType] RETURNS[item: WhiteboardDBPrivate.WBItem] = { item _ IF type = note THEN DB.DeclareEntity[Note, name, OldOnly] ELSE DB.DeclareEntity[Icon, name, OldOnly] }; Parent: PUBLIC PROC[item: WhiteboardDBPrivate.WBItem] RETURNS[wb: Whiteboard] = { wb _ DB.V2E[DB.GetF[DB.DeclareRelship[container, LIST[[containerOf, item]]], containerIs]] }; Children: PUBLIC PROC[wb: Whiteboard, onlyWhiteboards: BOOL _ FALSE] RETURNS[children: ChildSet] = { rs: DB.RelshipSet = DB.RelationSubset[container, LIST[[containerIs, wb]]]; children _ NEW[ChildSetObject _ [rs, onlyWhiteboards]] }; NextChild: PUBLIC PROC[children: ChildSet] RETURNS[child: WhiteboardDBPrivate.WBItem] = { rs: DB.RelshipSet = children.rs; IF rs # NIL THEN { IF NOT children.screen THEN { next: DB.Relship = DB.NextRelship[rs]; IF next = NIL THEN RETURN[NIL]; child _ DB.V2E[DB.GetF[next, containerOf]] } ELSE FOR next: DB.Relship _ DB.NextRelship[rs], DB.NextRelship[rs] UNTIL next = NIL DO child _ DB.V2E[DB.GetF[next, containerOf]]; IF TypeOf[child] = icon AND GetIconProps[child].type = wbType THEN EXIT ELSE child _ NIL ENDLOOP; IF child = NIL THEN {DB.ReleaseRelshipSet[rs]; children.rs _ NIL} } ELSE child _ NIL }; TypeOf: PUBLIC PROC[item: WhiteboardDBPrivate.WBItem] RETURNS[type: ItemType] = { type _ IF DB.Eq[DB.DomainOf[item], Note] THEN note ELSE icon }; Position: PUBLIC PROC[item: WhiteboardDBPrivate.WBItem] RETURNS[x, y: INT] = { cRS: DB.Relship = DB.DeclareRelship[container, LIST[[containerOf, item]]]; x _ DB.V2I[DB.GetF[cRS, containerX]]; y _ DB.V2I[DB.GetF[cRS, containerY]] }; Size: PUBLIC PROC[item: WhiteboardDBPrivate.WBItem] RETURNS[w, h: INT] = { cRS: DB.Relship = DB.DeclareRelship[container, LIST[[containerOf, item]]]; w _ DB.V2I[DB.GetF[cRS, containerW]]; h _ DB.V2I[DB.GetF[cRS, containerH]] }; Move: PUBLIC PROC[item: WhiteboardDBPrivate.WBItem, newX, newY: INT] = { cRS: DB.Relship = DB.DeclareRelship[container, LIST[[containerOf, item]]]; DB.SetF[cRS, containerX, DB.I2V[newX]]; DB.SetF[cRS, containerY, DB.I2V[newY]] }; Destroy: PUBLIC PROC[item: WhiteboardDBPrivate.WBItem] = { IF NOT DB.Null[item] THEN DB.DestroyEntity[item] }; <> NewNote: PUBLIC PROC[parent: Whiteboard, x, y, w, h: INT, content: ViewerTools.TiogaContents] RETURNS[newNote: WBNote] = { note: WBNote = DB.DeclareEntity[Note]; props: DB.Relship = DB.DeclareRelship[container, LIST[[containerOf, note]]]; DB.SetF[props, containerIs, parent]; DB.SetF[props, containerX, DB.I2V[x]]; DB.SetF[props, containerY, DB.I2V[y]]; DB.SetF[props, containerW, DB.I2V[w]]; DB.SetF[props, containerH, DB.I2V[h]]; [] _ DB.SetP[note, contents, DB.S2V[content.contents]]; [] _ DB.SetP[note, format, DB.S2V[content.formatting]]; RETURN[note] }; <<>> GetContents: PUBLIC PROC[note: WBNote] RETURNS[content: ViewerTools.TiogaContents] = { content _ NEW[ViewerTools.TiogaContentsRec _ []]; content.contents _ DB.V2S[DB.GetP[note, contents]]; content.formatting _ DB.V2S[DB.GetP[note, format]] }; <<>> SetContents: PUBLIC PROC[note: WBNote, content: ViewerTools.TiogaContents] = { [] _ DB.SetP[note, contents, DB.S2V[content.contents]]; [] _ DB.SetP[note, format, DB.S2V[content.formatting]] }; <<>> Grow: PUBLIC PROC[note: WBNote, newW, newH: INT] = { props: DB.Relship = DB.DeclareRelship[container, LIST[[containerOf, note]]]; DB.SetF[props, containerW, DB.I2V[newW]]; DB.SetF[props, containerH, DB.I2V[newH]] }; <> NewIcon: PUBLIC PROC[parent: Whiteboard, x, y: INT, name, label, icon, argument: ROPE, type: ATOM] RETURNS[newIcon: WBIcon] = { wbIcon: WhiteboardDBPrivate.WBIcon = DB.DeclareEntity[Icon]; props: DB.Relship = DB.DeclareRelship[container, LIST[[containerOf, wbIcon]]]; DB.SetF[props, containerIs, parent]; DB.SetF[props, containerX, DB.I2V[x]]; DB.SetF[props, containerY, DB.I2V[y]]; DB.SetF[props, containerW, DB.I2V[64]]; DB.SetF[props, containerH, DB.I2V[64]]; [] _ DB.SetP[wbIcon, iconIcon, DB.S2V[icon]]; [] _ DB.SetP[wbIcon, iconName, DB.S2V[name]]; [] _ DB.SetP[wbIcon, iconLabel, DB.S2V[label]]; [] _ DB.SetP[wbIcon, iconArgument, DB.S2V[argument]]; [] _ DB.SetP[wbIcon, iconType, DB.S2V[Atom.GetPName[type]]]; RETURN[wbIcon] }; GetDisplayProps: PUBLIC PROC[wbIcon: WBIcon] RETURNS[label, icon: ROPE] = { label _ DB.V2S[DB.GetP[wbIcon, iconLabel]]; icon _ DB.V2S[DB.GetP[wbIcon, iconIcon]]; IF Rope.Equal[icon, ""] THEN { icon _ DefaultIcon[wbIcon]; [] _ DB.SetP[wbIcon, iconLabel, DB.S2V[icon]] }; IF Rope.Equal[label, ""] THEN { type: ATOM; name: ROPE; [name, type] _ GetIconProps[wbIcon]; label _ IF type = $Text THEN FileNames.GetShortName[name] ELSE name; [] _ DB.SetP[wbIcon, iconLabel, DB.S2V[label]] } }; GetToolArgument: PUBLIC PROC[wbIcon: WBIcon] RETURNS[argument: ROPE] = { argument _ DB.V2S[DB.GetP[wbIcon, iconArgument]] }; DefaultIcon: PROC[wbIcon: WBIcon] RETURNS[iconName: ROPE] = { name: ROPE; type: ATOM; [name, type] _ GetIconProps[wbIcon]; SELECT type FROM wbType => iconName _ "Whiteboard"; $ToolRope => iconName _ "Typescript"; $Text => iconName _ "Document"; $Tool => iconName _ name; ENDCASE => iconName _ "Acorn" }; GetIconProps: PUBLIC PROC[wbIcon: WBIcon] RETURNS[name: ROPE, type: ATOM] = { name _ DB.V2S[DB.GetP[wbIcon, iconName]]; type _ Atom.MakeAtom[DB.V2S[DB.GetP[wbIcon, iconType]]] }; SetProps: PUBLIC PROC[wbIcon: WBIcon, name, label, icon: ROPE, type: ATOM] = { [] _ DB.SetP[wbIcon, iconIcon, DB.S2V[icon]]; [] _ DB.SetP[wbIcon, iconName, DB.S2V[name]]; [] _ DB.SetP[wbIcon, iconLabel, DB.S2V[IF label = NIL THEN name ELSE label]]; [] _ DB.SetP[wbIcon, iconType, DB.S2V[Atom.GetPName[type]]]}; END...