-- File NoteEditorImpl.mesa
-- Created by Donahue, October 27, 1982 11:37 am
-- Last edited by:
-- Donahue March 14, 1983 3:35 pm
-- Cattell August 10, 1983 11:24 am

DIRECTORY
Buttons: TYPE USING[ ButtonProc ],
DB,
DBEnvironment,
NoteEditor,
Menus,
Rope: TYPE USING[ ROPE, Equal, Length ],
VFonts,
ViewerClasses: TYPE USING[ Viewer ],
ViewerOps: TYPE USING[ AddProp, FetchProp, PaintHint, PaintViewer ],
ViewerTools: TYPE USING[ GetContents, SelPosRec,
        SetContents, SetSelection, InhibitUserEdits ],
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: BOOLEANFALSE ]
     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: ROPEIF noteRelship = NIL THEN NIL ELSE GetFS[ noteRelship, NoteIsAttr ];
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.SetContents[
viewer: GetTableEntry[ NoteRow, 0, 1], contents: text, paint: FALSE ];
IF noEdits THEN
 { ViewerTools.InhibitUserEdits[ GetTableEntry[ NoteRow, 0, 1] ];
  ViewerOps.AddProp[ NoteRow, $edits, NEW[ BOOLEANFALSE ] ] };
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: BOOLEANFALSE] = {
text: ROPE = ViewerTools.GetContents[ 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]]]]];
  };

END.