-- 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.