3 (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 Dev/Mod/Markers.odc *)
7 Kernel, Files, Stores, Fonts, Ports, Models, Views, Controllers, Properties, Dialog,
8 TextModels, TextSetters, TextViews, TextControllers, TextMappers;
12 undefined* = 0; mark* = 1; message* = 2;
13 firstMode = 1; lastMode = 2;
18 errFile = "Errors"; point = Ports.point;
21 View* = POINTER TO ABSTRACT RECORD (Views.View)
24 msg-: POINTER TO ARRAY OF CHAR;
28 Directory* = POINTER TO ABSTRACT RECORD END;
31 StdView = POINTER TO RECORD (View) END;
33 StdDirectory = POINTER TO RECORD (Directory) END;
35 SetModeOp = POINTER TO RECORD (Stores.Operation)
42 dir-, stdDir-: Directory;
44 globR: TextModels.Reader; globW: TextModels.Writer; (* recycling done in Load, Insert *)
51 PROCEDURE (v: View) CopyFromSimpleView- (source: Views.View), EXTENSIBLE;
53 (* v.CopyFrom^(source); *)
55 v.err := source.err; v.mode := source.mode;
56 IF source.msg # NIL THEN
57 NEW(v.msg, LEN(source.msg^)); v.msg^ := source.msg^$
60 END CopyFromSimpleView;
63 PROCEDURE (v: View) InitContext* (context: Models.Context), EXTENSIBLE;
65 ASSERT(v.mode # undefined, 20);
66 v.InitContext^(context)
70 PROCEDURE (v: View) InitErr* (err: INTEGER), NEW, EXTENSIBLE;
72 ASSERT(v.msg = NIL, 20);
73 IF v.err # err THEN v.err := err; v.mode := mark END;
74 IF v.mode = undefined THEN v.mode := mark END
77 PROCEDURE (v: View) InitMsg* (msg: ARRAY OF CHAR), NEW, EXTENSIBLE;
78 VAR i: INTEGER; str: ARRAY 1024 OF CHAR;
80 ASSERT(v.msg = NIL, 20);
81 Dialog.MapString(msg, str);
82 i := 0; WHILE str[i] # 0X DO INC(i) END;
83 NEW(v.msg, i + 1); v.msg^ := str$;
87 PROCEDURE (v: View) SetMode* (mode: INTEGER), NEW, EXTENSIBLE;
90 ASSERT((firstMode <= mode) & (mode <= lastMode), 20);
92 NEW(op); op.view := v; op.mode := mode;
93 Views.Do(v, "#System:ViewSetting", op)
100 PROCEDURE (d: Directory) New* (type: INTEGER): View, NEW, ABSTRACT;
101 PROCEDURE (d: Directory) NewMsg* (msg: ARRAY OF CHAR): View, NEW, ABSTRACT;
106 PROCEDURE (op: SetModeOp) Do;
107 VAR v: View; mode: INTEGER;
110 mode := v.mode; v.mode := op.mode; op.mode := mode;
111 Views.Update(v, Views.keepFrames);
112 IF v.context # NIL THEN v.context.SetSize(Views.undefined, Views.undefined) END
115 PROCEDURE ToggleMode (v: View);
118 IF ABS(v.err) # noCode THEN
119 IF v.mode < lastMode THEN mode := v.mode + 1 ELSE mode := firstMode END
121 IF v.mode < message THEN mode := v.mode + 1 ELSE mode := firstMode END
127 (* primitives for StdView *)
129 PROCEDURE NumToStr (x: INTEGER; VAR s: ARRAY OF CHAR; VAR i: INTEGER);
130 VAR j: INTEGER; m: ARRAY 32 OF CHAR;
133 j := 0; REPEAT m[j] := CHR(x MOD 10 + ORD("0")); x := x DIV 10; INC(j) UNTIL x = 0;
134 i := 0; REPEAT DEC(j); s[i] := m[j]; INC(i) UNTIL j = 0;
138 PROCEDURE Load (v: StdView);
139 VAR view: Views.View; t: TextModels.Model; s: TextMappers.Scanner;
140 err: INTEGER; i: INTEGER; ch: CHAR; loc: Files.Locator;
141 msg: ARRAY 1024 OF CHAR;
143 err := ABS(v.err); NumToStr(err, msg, i);
144 loc := Files.dir.This("Dev"); IF loc = NIL THEN RETURN END;
145 loc := loc.This("Rsrc"); IF loc = NIL THEN RETURN END;
146 view := Views.OldView(loc, errFile);
147 IF (view # NIL) & (view IS TextViews.View) THEN
148 t := view(TextViews.View).ThisModel();
153 UNTIL ((s.type = TextMappers.int) & (s.int = err)) OR (s.type = TextMappers.eot);
154 IF s.type = TextMappers.int THEN
156 WHILE (ch >= " ") & (i < LEN(msg) - 1) DO
157 msg[i] := ch; INC(i); s.rider.ReadChar(ch)
163 NEW(v.msg, i + 1); v.msg^ := msg$
166 PROCEDURE DrawMsg (v: StdView; f: Views.Frame; font: Fonts.Font; color: Ports.Color);
167 VAR w, h, asc, dsc: INTEGER;
171 v.context.GetSize(w, h);
172 f.DrawLine(point, 0, w - 2 * point, h, 0, color);
173 f.DrawLine(w - 2 * point, 0, point, h, 0, color)
175 font.GetBounds(asc, dsc, w);
176 f.DrawString(2 * point, asc, color, v.msg^, font)
180 PROCEDURE ShowMsg (v: StdView);
182 IF v.msg = NIL THEN Load(v) END;
183 Dialog.ShowStatus(v.msg^)
186 PROCEDURE Track (v: StdView; f: Views.Frame; x, y: INTEGER; buttons: SET);
187 VAR c: Models.Context; t: TextModels.Model; u, w, h: INTEGER; isDown, in, in0: BOOLEAN; m: SET;
189 v.context.GetSize(w, h); u := f.dot; in0 := FALSE;
190 in := (0 <= x) & (x < w) & (0 <= y) & (y < h);
193 f.MarkRect(u, 0, w - u, h, Ports.fill, Ports.invert, Ports.show); in0 := in
195 f.Input(x, y, m, isDown);
196 in := (0 <= x) & (x < w) & (0 <= y) & (y < h)
199 f.MarkRect(u, 0, w - u, h, Ports.fill, Ports.invert, Ports.hide);
200 IF Dialog.showsStatus & ~(Controllers.modify IN buttons) & ~(Controllers.doubleClick IN buttons) THEN
206 WITH c: TextModels.Context DO
208 TextControllers.SetCaret(t, c.Pos() + 1)
214 PROCEDURE SizePref (v: StdView; VAR p: Properties.SizePref);
215 VAR c: Models.Context; a: TextModels.Attributes; font: Fonts.Font; asc, dsc, w: INTEGER;
218 IF (c # NIL) & (c IS TextModels.Context) THEN a := c(TextModels.Context).Attr(); font := a.font
219 ELSE font := Fonts.dir.Default()
221 font.GetBounds(asc, dsc, w);
225 p.w := p.h + 2 * point
227 IF v.msg = NIL THEN Load(v) END;
228 p.w := font.StringWidth(v.msg^) + 4 * point
235 PROCEDURE (v: StdView) ExternalizeAs (VAR s1: Stores.Store);
240 PROCEDURE (v: StdView) SetMode(mode: INTEGER);
241 BEGIN v.SetMode^(mode); ShowMsg(v)
244 PROCEDURE (v: StdView) Restore (f: Views.Frame; l, t, r, b: INTEGER);
245 VAR c: Models.Context; a: TextModels.Attributes; font: Fonts.Font; color: Ports.Color;
248 c := v.context; c.GetSize(w, h);
249 WITH c: TextModels.Context DO a := c.Attr(); font := a.font ELSE font := Fonts.dir.Default() END;
250 IF TRUE (*f.colors >= 4*) THEN color := Ports.grey50 ELSE color := Ports.defaultColor END;
252 f.DrawRect(point, 0, w - point, h, Ports.fill, color);
253 DrawMsg(v, f, font, Ports.background)
255 f.DrawRect(point, 0, w - point, h, 0, color);
256 DrawMsg(v, f, font, Ports.defaultColor)
260 PROCEDURE (v: StdView) GetBackground (VAR color: Ports.Color);
262 color := Ports.background
265 PROCEDURE (v: StdView) HandleCtrlMsg (f: Views.Frame; VAR msg: Controllers.Message;
266 VAR focus: Views.View);
268 WITH msg: Controllers.TrackMsg DO
269 Track(v, f, msg.x, msg.y, msg.modifiers)
274 PROCEDURE (v: StdView) HandlePropMsg (VAR msg: Properties.Message);
275 VAR c: Models.Context; a: TextModels.Attributes; font: Fonts.Font; asc, w: INTEGER;
277 WITH msg: Properties.Preference DO
278 WITH msg: Properties.SizePref DO
280 | msg: Properties.ResizePref DO
282 | msg: Properties.FocusPref DO
285 | msg: Properties.StorePref DO
288 | msg: TextSetters.Pref DO
290 IF (c # NIL) & (c IS TextModels.Context) THEN
291 a := c(TextModels.Context).Attr(); font := a.font
293 font := Fonts.dir.Default()
295 font.GetBounds(asc, msg.dsc, w)
305 PROCEDURE (d: StdDirectory) New (err: INTEGER): View;
308 NEW(v); v.InitErr(err); RETURN v
311 PROCEDURE (d: StdDirectory) NewMsg (msg: ARRAY OF CHAR): View;
314 NEW(v); v.InitErr(noCode); v.InitMsg(msg); RETURN v
322 globR := NIL; globW := NIL
326 (** miscellaneous **)
328 PROCEDURE Insert* (text: TextModels.Model; pos: INTEGER; v: View);
329 VAR w: TextModels.Writer; r: TextModels.Reader;
331 ASSERT(v.era = 0, 20);
332 Models.BeginModification(Models.clean, text);
334 IF pos > text.Length() THEN pos := text.Length() END;
335 globW := text.NewWriter(globW); w := globW; w.SetPos(pos);
336 IF pos > 0 THEN DEC(pos) END;
337 globR := text.NewReader(globR); r := globR; r.SetPos(pos); r.Read;
338 IF r.attr # NIL THEN w.SetAttr(r.attr) END;
339 w.WriteView(v, Views.undefined, Views.undefined);
340 Models.EndModification(Models.clean, text);
343 PROCEDURE Unmark* (text: TextModels.Model);
344 VAR r: TextModels.Reader; v: Views.View; pos: INTEGER;
345 script: Stores.Operation;
347 Models.BeginModification(Models.clean, text);
348 Models.BeginScript(text, "#Dev:DeleteMarkers", script);
349 r := text.NewReader(NIL); r.ReadView(v);
351 IF r.view IS View THEN
352 pos := r.Pos() - 1; text.Delete(pos, pos + 1); r.SetPos(pos)
357 Models.EndScript(text, script);
358 Models.EndModification(Models.clean, text);
361 PROCEDURE ShowFirstError* (text: TextModels.Model; focusOnly: BOOLEAN);
362 VAR v1: Views.View; pos: INTEGER;
364 globR := text.NewReader(globR); globR.SetPos(0);
365 REPEAT globR.ReadView(v1) UNTIL globR.eot OR (v1 IS View);
368 TextViews.ShowRange(text, pos, pos, focusOnly);
369 TextControllers.SetCaret(text, pos);
370 v1(View).SetMode(v1(View).mode)
377 PROCEDURE UnmarkErrors*;
378 VAR t: TextModels.Model;
380 t := TextViews.FocusText();
381 IF t # NIL THEN Unmark(t) END
384 PROCEDURE NextError*;
385 VAR c: TextControllers.Controller; t: TextModels.Model; v1: Views.View;
388 c := TextControllers.Focus();
391 IF c.HasCaret() THEN pos := c.CaretPos()
392 ELSIF c.HasSelection() THEN c.GetSelection(beg, pos)
395 TextControllers.SetSelection(t, TextControllers.none, TextControllers.none);
396 globR := t.NewReader(globR); globR.SetPos(pos);
397 REPEAT globR.ReadView(v1) UNTIL globR.eot OR (v1 IS View);
399 pos := globR.Pos(); v1(View).SetMode(v1(View).mode);
400 TextViews.ShowRange(t, pos, pos, TextViews.focusOnly)
402 pos := 0; Dialog.Beep
404 TextControllers.SetCaret(t, pos);
409 PROCEDURE ToggleCurrent*;
410 VAR c: TextControllers.Controller; t: TextModels.Model; v: Views.View; pos: INTEGER;
412 c := TextControllers.Focus();
413 IF (c # NIL) & c.HasCaret() THEN
414 t := c.text; pos := c.CaretPos();
415 globR := t.NewReader(globR); globR.SetPos(pos); globR.ReadPrev;
417 IF (v # NIL) & (v IS View) THEN ToggleMode(v(View)) END;
418 TextViews.ShowRange(t, pos, pos, TextViews.focusOnly);
419 TextControllers.SetCaret(t, pos);
425 PROCEDURE SetDir* (d: Directory);
435 NEW(d); dir := d; stdDir := d
439 Init; Kernel.InstallCleaner(Cleanup)
441 Kernel.RemoveCleaner(Cleanup)