-- File NoteEditorImpl.mesa -- Created by Donahue, October 27, 1982 11:37 am -- Last edited by: -- Donahue March 14, 1983 3:35 pm -- Cattell December 22, 1983 12:57 pm DIRECTORY Buttons: TYPE USING[ ButtonProc ], DB, DBEnvironment, NoteEditor, Menus, Rope, VFonts, ViewerClasses: TYPE USING[ Viewer ], ViewerOps: TYPE USING[ AddProp, FetchProp, PaintHint, PaintViewer ], ViewerTools, VTables: TYPE USING[ VTable, Create, GetTableEntry, GetEntryOffset, NullBorder, SetTableEntry, Install, SetEntryOffset ]; NoteEditorImpl: PROGRAM IMPORTS DB, ViewerOps, VTables, Rope, VFonts, ViewerTools EXPORTS NoteEditor = BEGIN OPEN DB, Rope, ViewerClasses, VTables; DisplayNote: PUBLIC PROC[ entity: Entity, parent: Viewer, segment: DB.Segment _ NIL, openHeight: NAT _ 0, openWidth: NAT _ 0, noEdits: BOOLEAN _ FALSE ] RETURNS[ NoteRow: VTable] = { -- Display note subwindow. Note that if noEdits=TRUE and the required schema is underfined -- or no note exists, then we return immediately. NoteRel: Relation = DeclareRelation["note", IF entity = NIL THEN segment ELSE SegmentOf[entity], OldOnly]; NoteOfAttr: Attribute = DB.DeclareAttribute[ r: NoteRel, name: "of", type: AnyDomainType, version: OldOnly ]; NoteIsAttr: Attribute = DB.DeclareAttribute[ r: NoteRel, name: "is", type: RopeType, version: OldOnly]; noteRelship: Relship_ IF NoteRel=NIL OR entity = NIL THEN NIL ELSE NextRelship[RelationSubset[NoteRel, LIST[AttributeValue[NoteOfAttr, entity]]]]; text: ROPE_ IF noteRelship = NIL THEN NIL ELSE GetFS[ noteRelship, NoteIsAttr ]; tiogaText: ViewerTools.TiogaContents_ RopeToTioga[text]; IF noEdits AND Rope.Equal[text, ""] THEN RETURN[NIL]; NoteRow _ Create[ columns: 2, parent: parent ]; SetTableEntry[table: NoteRow, column: 0, name: "Notes", flavor: $Button, proc: SetHeight, border: NullBorder ]; GetTableEntry[ NoteRow, 0, 0 ].border _ TRUE; IF openHeight = 0 THEN openHeight _ VFonts.FontHeight[]*(Rope.Length[text]/70+2); IF openWidth = 0 THEN openWidth _ 40*VFonts.CharWidth['A]; SetTableEntry[ table: NoteRow, column: 1, flavor: $Text, border: NullBorder, h: openHeight, w: openWidth, useMaxSize: TRUE ]; GetTableEntry[ NoteRow, 0, 1 ].scrollable _ TRUE; ViewerTools.SetTiogaContents[ viewer: GetTableEntry[ NoteRow, 0, 1], contents: tiogaText, paint: FALSE ]; IF noEdits THEN { ViewerTools.InhibitUserEdits[ GetTableEntry[ NoteRow, 0, 1] ]; ViewerOps.AddProp[ NoteRow, $edits, NEW[ BOOLEAN _ FALSE ] ] }; Install[ NoteRow, FALSE ]; ViewerOps.AddProp[ NoteRow, $note, noteRelship ] }; SetHeight: Buttons.ButtonProc = TRUSTED { viewer: Viewer = NARROW[ parent, Viewer ]; NoteRow: VTable = viewer.parent; textViewer: Viewer = GetTableEntry[ table: NoteRow, column: 1 ]; text: ROPE = ViewerTools.GetContents[ textViewer ]; edits: REF ANY = ViewerOps.FetchProp[ NoteRow, $edits ]; textHeight: INT = textViewer.wh; textWidth: INT = textViewer.ww; SELECT mouseButton FROM Menus.MouseButton[red] => { ViewerTools.SetSelection[ viewer: GetTableEntry[ table: NoteRow, column: 1 ], selection: NIL ]; RETURN }; Menus.MouseButton[blue] => SetTableEntry[ table: NoteRow, column: 1, flavor: $Text, border: NullBorder, useMaxSize: TRUE, w: textWidth, h: textHeight+2*VFonts.FontHeight[]+5 ]; ENDCASE; GetTableEntry[ table: NoteRow, column: 1 ].scrollable _ TRUE; IF edits # NIL THEN ViewerTools.InhibitUserEdits[ GetTableEntry[ table: NoteRow, column: 1 ] ]; ViewerTools.SetContents[ viewer: GetTableEntry[ table: NoteRow, column: 1 ], contents: text, paint: FALSE ]; Install[ NoteRow, FALSE ]; SetEntryOffset[ table: NoteRow, column: 0, yoff: GetEntryOffset[ table: NoteRow, column: 1 ].yoff ]; Install[ NoteRow.parent, FALSE ]; ViewerOps.PaintViewer[ NoteRow.parent.parent, ViewerOps.PaintHint[client] ] }; SaveNote: PUBLIC PROC[newEntity: Entity, viewer: Viewer, update: BOOLEAN _ FALSE] = { text: ROPE = TiogaToRope[ViewerTools.GetTiogaContents[ GetTableEntry[viewer, 0, 1] ]]; NoteRel: Relation = DeclareRelation["note", SegmentOf[newEntity], NewOrOld]; NoteOfAttr: Attribute = DeclareAttribute[NoteRel, "of", AnyDomainType]; NoteIsAttr: Attribute = DeclareAttribute[NoteRel, "is", RopeType]; IF update THEN { noteRelship: Relship = V2E[ ViewerOps.FetchProp[ viewer, $note ] ]; IF noteRelship # NIL THEN { SetF[ noteRelship, NoteIsAttr, S2V[text] ]; RETURN }; }; ViewerOps.AddProp[ viewer, $note, CreateRelship[ r: NoteRel, init: LIST[ AttributeValue[attribute: NoteOfAttr, lo: newEntity ], AttributeValue[attribute: NoteIsAttr, lo: S2V[text]]]]]; }; TiogaToRope: PROC[tioga: ViewerTools.TiogaContents] RETURNS [rope: ROPE] = { -- Converts a tioga node into a single rope that can be stored in a database or file. IF tioga.formatting.Length[]=0 THEN -- No formatting RETURN[tioga.contents] ELSE -- Concatenate text and formatting with a null as separator RETURN[Rope.Cat[tioga.contents, "\000", tioga.formatting]]; }; RopeToTioga: PROC[rope: ROPE] RETURNS [tioga: ViewerTools.TiogaContents] = { -- Converts a rope into the two parts previously concatenated by TiogaToRope. pos: INT_ rope.Find["\000"]; IF pos=-1 THEN -- No formatting: fake a Tioga node tioga_ NEW[ViewerTools.TiogaContentsRec_ [rope, NIL]] ELSE -- Break into parts before and after null separator tioga_ NEW[ViewerTools.TiogaContentsRec_ [rope.Substr[0, pos], rope.Substr[pos+1]]]; }; END. Ę˜JščĪcĒœĪk œ žœžœažœžœžœžœJžœžœ‚žœžœ5žœžœžœ*Īn œžœžœjžœžœžœžœ žœāžœ žœžœ žœ§žœ žœžœ žœžœžœžœ0žœ3žœžœžœžœžœžœfžœ žœžœžœžœéžœžœžœAžœžœ¯žœ5žœožœ žœ žœužœžœžœžœ†žœŽžœ7žœžœ;žœ!žœžœ žœŸžœžœ žœWžœ@žœžœ žœžœĶžœžœ”žœaŸœžœžœ,žœžœžœļžœžœOžœžœžœ9žœPžœ‚Ÿ œžœ#žœžœ`žœžœžœžœCžœ@Ÿ œžœžœžœzžœžœž œžœ1žœ žœžœžœAžœ žœ8žœ˜’.—…—