home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / oberon / system1 / dialog.mod (.txt) < prev    next >
Oberon Text  |  1977-12-31  |  22KB  |  493 lines

  1. Syntax10.Scn.Fnt
  2. Syntax10i.Scn.Fnt
  3. StampElems
  4. Alloc
  5. 8 May 95
  6. Syntax10b.Scn.Fnt
  7. MODULE Dialog;    
  8.     (**  extended version by Markus Knasm
  9. ller 25.May.94 -  
  10.     IMPORT DialogFrames, Dialogs, DialogButtons, Display, Display1, Files, In, Input, MenuViewers, 
  11.         TextFrames, Texts, Oberon, Printer, Viewers;
  12.     (* DialogText must be loaded before, because setting of o.Edit and o.Update must be before Editing is possible *)
  13.     CONST 
  14.         ML =2; MM = 1; MR = 0; CRSU = 0C1X; CRSD = 0C2X; CRSR = 0C3X; CRSL = 0C4X; CR = 0DX;
  15.         editMenu = "System.Close  System.Copy  System.Grow  Dialog.Store "; 
  16.         markW = 5;
  17.     VAR 
  18.         reticule*:Oberon.Marker;  (** used as caret *)
  19.         w0: Texts.Writer;  
  20.         DW, DH, CL: INTEGER;
  21.         nx, ny, X1, X0, Y1, Y0: INTEGER;
  22.         editObjectX, editObjectY: INTEGER;
  23.     PROCEDURE Min (x: INTEGER; y:INTEGER): INTEGER;
  24.     BEGIN IF x < y THEN RETURN x ELSE RETURN y END
  25.     END Min;
  26.     PROCEDURE Open*;     (** name | ^ *)
  27.     (** opens a dialog viewer and displays the dialog from file name *)
  28.         VAR x, y, res: INTEGER; p: Dialogs.Panel; name: ARRAY 64 OF CHAR; 
  29.     BEGIN
  30.         In.Open; In.Name (name);
  31.         IF In.Done THEN         
  32.             Oberon.AllocateSystemViewer (Oberon.Mouse.X, x, y);
  33.             DialogFrames.OpenPanel (name, x, y, p)        
  34.         END 
  35.     END Open;
  36.     PROCEDURE SetInitCmd*;    (** cmd | ^ *)
  37.     (** sets the command of the marked dialog to cmd *)
  38.         VAR x, y: INTEGER; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR; 
  39.     BEGIN 
  40.         In.Open; In.Name (cmd); 
  41.         IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END;
  42.         IF Dialogs.res = Dialogs.ok THEN
  43.             DialogFrames.GetCaretPosition (p, x, y);
  44.             IF p # NIL THEN p.SetCmd (cmd) ELSE Dialogs.res := Dialogs.noPanelSelected END
  45.         END;
  46.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  47.     END SetInitCmd;
  48.     PROCEDURE SetName*;    (** name | ^ *)
  49.     (** sets the name of the object under the caret to name *)
  50.         VAR o: Dialogs.Object; p: Dialogs.Panel; name: ARRAY 16 OF CHAR;  
  51.     BEGIN 
  52.         In.Open; In.Name (name); 
  53.         IF In.Done THEN Dialogs.res := Dialogs.ok  
  54.         ELSE In.Open; In.String (name); IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END
  55.         END;
  56.         IF Dialogs.res = Dialogs.ok THEN 
  57.             DialogFrames.FindObject (o, p); 
  58.             IF Dialogs.res = Dialogs.ok THEN o.SetName (name) END
  59.         END;
  60.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  61.     END SetName;
  62.     PROCEDURE SetCmd*;    (** cmd | ^ *)
  63.     (** sets the command of the object under the caret to cmd *)
  64.         VAR o: Dialogs.Object; p: Dialogs.Panel; cmd: ARRAY 32 OF CHAR; 
  65.     BEGIN 
  66.         In.Open; In.Name (cmd); 
  67.         IF In.Done THEN Dialogs.res := Dialogs.ok ELSE Dialogs.res := Dialogs.wrongInput END;
  68.         IF Dialogs.res = Dialogs.ok THEN
  69.             DialogFrames.FindObject (o, p);
  70.             IF Dialogs.res = Dialogs.ok THEN o.SetCmd (cmd) END
  71.         END;
  72.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  73.     END SetCmd;
  74.     PROCEDURE SetPar*;    (** par | ^ *)
  75.     (** sets the parameter of the item at the caret to par.  par is from type {ch} *)
  76.         VAR o: Dialogs.Object; p: Dialogs.Panel; par: ARRAY 32 OF CHAR; ch: CHAR; i: INTEGER;
  77.     BEGIN 
  78.         In.Open; In.Char (ch); i := 0;
  79.         WHILE In.Done & (ch = " ") DO In.Char (ch) END; (* skip leading blanks *)
  80.         IF ~ In.Done THEN 
  81.             Dialogs.res := Dialogs.wrongInput
  82.         ELSE 
  83.             Dialogs.res := Dialogs.ok;
  84.             WHILE In.Done & (ch # CR) & (ch # "~") & (i < 31) DO par[i] := ch; INC (i); In.Char (ch) END;
  85.             par[i] := 0X;
  86.         END;
  87.         IF Dialogs.res = Dialogs.ok THEN
  88.             DialogFrames.FindObject (o, p);
  89.             IF Dialogs.res = Dialogs.ok THEN o.SetPar (par) END
  90.         END;
  91.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  92.     END SetPar;
  93.     PROCEDURE SetDim*;    (** x y w h | ^ *)
  94.     (** sets the lower left coordinates of the object under the caret to x and y, the width to w and the height to h *)
  95.         VAR x, y, w, h, x1, y1: INTEGER; o: Dialogs.Object; p: Dialogs.Panel; v: Viewers.Viewer; 
  96.     BEGIN
  97.         In.Open; In.Int (x); Dialogs.res := Dialogs.ok; 
  98.         IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  99.         In.Int (y); IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  100.         In.Int (w); IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  101.         In.Int (h); IF ~ In.Done THEN Dialogs.res := Dialogs.wrongInput END;
  102.         DialogFrames.GetCaretPosition (p, x1, y1);
  103.         v := Viewers.This (x1, y1);
  104.         IF (v = NIL) OR (x > v.W) OR (ABS (y) > v.H) THEN Dialogs.res := Dialogs.wrongInput END;
  105.         IF Dialogs.res = Dialogs.ok THEN
  106.             DialogFrames.FindObject (o, p);
  107.             IF  Dialogs.res = Dialogs.ok THEN o.SetDim (x, y, w, h, FALSE) END
  108.         END;
  109.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  110.     END SetDim;
  111.     PROCEDURE AlignSelected*;    (** dir | ^ *)
  112.     (** aligns the selected objects so that they have the same left, right, top or bottom coordinates *)
  113.         VAR dir: CHAR; x, y: INTEGER; p: Dialogs.Panel; name: ARRAY 64 OF CHAR;
  114.     BEGIN
  115.         In.Open; In.Name (name); Dialogs.res := Dialogs.ok;
  116.         IF In.Done THEN dir := name[0] END; 
  117.         IF (dir # "R") & (dir # "L") & (dir # "U") & (dir # "D") THEN
  118.             Dialogs.res := Dialogs.wrongInput
  119.         ELSE 
  120.             DialogFrames.GetCaretPosition (p, x, y);
  121.             IF p # NIL THEN
  122.                 p.AlignSelected (dir)
  123.             ELSE
  124.                 Dialogs.res := Dialogs.noPanelSelected
  125.             END
  126.         END;
  127.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  128.     END AlignSelected;
  129.     PROCEDURE RegulateDistance*;    (** dir | ^ *)
  130.     (** regulates the distance between the selected objects *)
  131.         VAR dir:  CHAR; i, j: INTEGER; p: Dialogs.Panel; name: ARRAY 64 OF CHAR;
  132.     BEGIN
  133.         In.Open; In.Name (name); Dialogs.res := Dialogs.ok;
  134.         IF In.Done THEN dir := name [0] END;    
  135.         IF  (dir # "R") & (dir #"L") & (dir # "U") & (dir # "D")
  136.             THEN Dialogs.res := Dialogs.wrongInput
  137.         ELSE
  138.             DialogFrames.GetCaretPosition (p, i, j);
  139.             IF p # NIL THEN
  140.                 p.RegulateDistance (dir)
  141.             ELSE 
  142.                 Dialogs.res := Dialogs.noPanelSelected
  143.             END
  144.         END;
  145.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  146.     END RegulateDistance;
  147.     PROCEDURE GetDim*;
  148.     (** writes the coordinates of the lower left corner, the width and the height 
  149.         of the object under the caret to the log viewer *)
  150.         VAR x, y, w, h: INTEGER; o: Dialogs.Object; p: Dialogs.Panel;
  151.     BEGIN
  152.         DialogFrames.FindObject (o, p);
  153.         IF Dialogs.res = Dialogs.ok THEN 
  154.             o.GetDim (x, y, w, h);
  155.             Texts.WriteString (w0, "Coor: "); Texts.WriteInt (w0, x, 5); Texts.WriteInt (w0, y, 5); 
  156.             Texts.WriteLn (w0); Texts.WriteString (w0, "Wide and Height: "); Texts.WriteInt (w0, w, 5); 
  157.             Texts.WriteInt (w0, h, 5); Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  158.         ELSE
  159.             Dialogs.Error ("Dialog") 
  160.         END
  161.     END GetDim;    
  162.     PROCEDURE GetName*;
  163.     (** writes the name of the object under the caret to the log viewer *)
  164.         VAR o: Dialogs.Object; p: Dialogs.Panel; name: ARRAY 32 OF CHAR;
  165.     BEGIN
  166.         DialogFrames.FindObject (o, p);
  167.         IF Dialogs.res = Dialogs.ok THEN
  168.             COPY (o.name, name); Texts.WriteString (w0, "Name: "); Texts.WriteString (w0, name); 
  169.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  170.         ELSE
  171.             Dialogs.Error ("Dialog")
  172.         END
  173.     END GetName;
  174.     PROCEDURE GetCmd*;
  175.     (** writes the command of the object under the caret to the log viewer *)
  176.         VAR o: Dialogs.Object; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR;
  177.     BEGIN
  178.         DialogFrames.FindObject (o, p);
  179.         IF Dialogs.res = Dialogs.ok THEN
  180.             COPY (o.cmd, cmd); Texts.WriteString (w0, "Command: "); Texts.WriteString (w0, cmd); 
  181.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  182.         ELSE
  183.             Dialogs.Error ("Dialog")
  184.         END
  185.     END GetCmd;
  186.     PROCEDURE GetInitCmd*;
  187.     (** writes the command of the marked dialog to the log viewer *)
  188.         VAR x, y: INTEGER; p: Dialogs.Panel; cmd: ARRAY 64 OF CHAR;
  189.     BEGIN
  190.         DialogFrames.GetCaretPosition (p, x, y); Dialogs.res := Dialogs.ok;
  191.         IF p # NIL THEN
  192.             COPY (p.cmd, cmd); Texts.WriteString (w0, "Command: "); Texts.WriteString (w0, cmd); 
  193.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  194.         ELSE
  195.             Dialogs.res := Dialogs.noPanelSelected
  196.         END;
  197.         IF Dialogs.res # Dialogs.ok THEN Dialogs.Error ("Dialog") END
  198.     END GetInitCmd;
  199.     PROCEDURE GetPar*;
  200.     (** writes the component par of the item under the caret to the log viewer *)
  201.         VAR o: Dialogs.Object; p: Dialogs.Panel; par: ARRAY 64 OF CHAR;
  202.     BEGIN
  203.         DialogFrames.FindObject (o, p);
  204.         IF Dialogs.res = Dialogs.ok THEN
  205.             COPY (o.par, par); Texts.WriteString (w0, "Parameter: "); Texts.WriteString (w0, par); 
  206.             Texts.WriteLn (w0); Texts.Append (Oberon.Log, w0.buf)
  207.         ELSE
  208.             Dialogs.Error ("Dialog")
  209.         END
  210.     END GetPar;
  211.     PROCEDURE SetGrid*;    (** int | ^ *)
  212.     (** sets the grid to which mouse movements are restricted *)
  213.         VAR i: INTEGER; f: DialogFrames.Frame; v: Viewers.Viewer;
  214.     BEGIN
  215.         v := Oberon.MarkedViewer();
  216.         IF v.dsc.next IS DialogFrames.Frame THEN
  217.             f := v.dsc.next(DialogFrames.Frame);
  218.             In.Open; In.Int(i);
  219.             IF (In.Done) & (i <= DialogFrames.gridMax) & (i >= DialogFrames.gridMin) THEN
  220.                 f.grid := i; Dialogs.res := Dialogs.ok
  221.             ELSE
  222.                 Dialogs.res := Dialogs.wrongInput; Dialogs.Error ("Dialog")
  223.             END
  224.         END
  225.     END SetGrid;
  226.     PROCEDURE box (o: Dialogs.Object; VAR done: BOOLEAN);
  227.         VAR x, y, w, h: INTEGER;
  228.     BEGIN
  229.         IF ~o.selected THEN RETURN END;
  230.         o.GetDim (x, y, w, h);  y := ABS (y); 
  231.         IF x < X0 THEN X0 := x END;
  232.         IF X1 < x + w THEN X1 := x + w END;
  233.         IF y - h < Y0 THEN Y0 := y - h END;
  234.         IF Y1 < y THEN Y1 := y END
  235.     END box;
  236.     PROCEDURE EnumCopy (o: Dialogs.Object; VAR done: BOOLEAN);
  237.         VAR x, y, w, h: INTEGER; new: Dialogs.Object;
  238.     BEGIN
  239.         IF ~o.selected THEN RETURN END;  
  240.         new := NIL; o.Copy (new); new.SetName (""); 
  241.         o.GetDim (x, y, w, h); new.SetDim (x + nx, y + ny, w, h, new.overlapping);
  242.         o.panel.Insert (new, new.overlapping);
  243.     END EnumCopy;
  244.     PROCEDURE Do*;
  245.         VAR o: Dialogs.Object; v: Viewers.Viewer; t: Texts.Text; r: Texts.Reader; ch: CHAR;
  246.     BEGIN
  247.         o := Dialogs.editObject; v := Oberon.Par.vwr;
  248.         IF o # NIL THEN o.Update (Dialogs.cmdPanel) END;
  249.         t := v.dsc (TextFrames.Frame).text; 
  250.         Texts.OpenReader (r, t, t.len - 1); Texts.Read (r, ch);
  251.         IF (ch = "!") & (Dialogs.res = Dialogs.ok) & (o # NIL) THEN Texts.Delete (t, t.len - 1, t.len) END
  252.     END Do; 
  253.     PROCEDURE Track (f: DialogFrames.Frame; keys: SET; x0, y0: INTEGER; o: Dialogs.Object);
  254.         VAR 
  255.             keys0, keysum: SET; new: Dialogs.Object; ch1, ch2, ch3: BOOLEAN; 
  256.             x, y, xh, yh, wh, hh, xdif, ydif, col, ox, oy, ow, oh: INTEGER; ch: CHAR;
  257.             gfmsg: DialogFrames.GetFrameMsg; v: Viewers.Viewer; t: Texts.Text; r: Texts.Reader;
  258.     BEGIN 
  259.         col := Display.white; keys0 := keys; keysum := keys;
  260.         ch1 := FALSE; ch2 := FALSE; ch3 := FALSE;
  261.         xdif := x0; ydif := y0; 
  262.         IF o # NIL THEN o.GetDim (xh, yh, wh, hh) ELSE xh := x0; yh := y0 END;
  263.         IF (keys0 = {MR}) & (o # NIL) THEN 
  264.             IF o.selected THEN o.UnSelect ELSE o.Select END
  265.         END;
  266.         REPEAT 
  267.             Input.Mouse (keys, x, y); keysum := keysum + keys; 
  268.             xdif := xdif DIV f.grid * f.grid; ydif := ydif DIV f.grid * f.grid;
  269.             x := x DIV f.grid * f.grid; y := y DIV f.grid * f.grid;
  270.             Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y);
  271.             IF (xdif # x) OR (ydif # y) THEN
  272.                 IF  (keys0 = {MM}) THEN
  273.                     IF (keysum = {MM}) THEN
  274.                         IF (o # NIL) & (~ o.selected OR (o.panel.NofSelObjects () <= 1)) THEN
  275.                             o.GetDim (ox, oy, ow, oh);
  276.                             o.SetDim (ox - xdif + x, oy - ydif + y, ow, oh, FALSE);
  277.                             IF Dialogs.res = Dialogs.ok THEN ch1 := TRUE; xdif := x; ydif := y END
  278.                         ELSE
  279.                             f.panel.MoveSelected (x - xdif, y - ydif);
  280.                             IF Dialogs.res = Dialogs.ok THEN ch3 := TRUE; xdif := x; ydif := y; xh := x0; yh := y0 END
  281.                         END
  282.                     ELSIF (keysum = {MM, ML}) & (o # NIL) & ~ch3 THEN
  283.                         o.GetDim (ox, oy, ow, oh);
  284.                         o.SetDim (ox, oy, ow - xdif + x, oh - ydif + y, FALSE);
  285.                         IF Dialogs.res = Dialogs.ok THEN xdif := x; ydif := y; ch2 := TRUE END
  286.                     END; 
  287.                 ELSIF (keys0 = {MR}) & (o = NIL) THEN
  288.                     Display1.Line (f, col, x0, y0, x0, ydif, Display.invert); Display1.Line (f, col, x0, y0, xdif, y0, Display.invert);
  289.                     Display1.Line (f, col, x0, ydif, xdif, ydif, Display.invert); Display1.Line (f, col, xdif, y0, xdif, ydif, Display.invert);
  290.                     xdif := x; ydif := y;
  291.                     f.panel.Select (Min (x0 - f.X, xdif - f.X), Min (y0 - f.Y - f.H, ydif - f.Y - f.H), ABS (x0 - xdif), ABS (y0 - ydif));
  292.                     Display1.Line (f, col, x0, y0, x0, ydif, Display.invert); Display1.Line (f, col, x0, y0, xdif, y0, Display.invert);
  293.                     Display1.Line (f, col, x0, ydif, xdif, ydif, Display.invert); Display1.Line (f, col, xdif, y0, xdif, ydif, Display.invert);
  294.                 END;
  295.             END;
  296.         UNTIL keys = {};
  297.         IF (keys0 = {ML}) & (keysum = {ML}) THEN
  298.             Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y); 
  299.             Oberon.DrawCursor (Oberon.Pointer, reticule, x, y);
  300.             Oberon.PassFocus (Viewers.This (x, y));
  301.         ELSIF (keys0 = {ML}) & (keysum = {ML, MM}) THEN
  302.             X0 := MAX (INTEGER); X1 := MIN (INTEGER); Y0:= MAX (INTEGER); Y1 := MIN (INTEGER);
  303.             f.panel.Enumerate (box);
  304.             nx := (x - f.X) - X0; ny := (y - f.Y - f.H) + Y0; f.panel.Enumerate (EnumCopy)
  305.         ELSIF (keys0 = {MR}) & (keysum = {ML, MR}) & (o # NIL) THEN 
  306.             f.panel.Remove (o); f.panel.RemoveSelections  
  307.         ELSIF (keys0 = {MR}) & (keysum = {MM, MR}) & (o # NIL) THEN 
  308.                 o.UnSelect (); new := NIL; o.Copy (new);
  309.                 o.GetDim (ox, oy, ow, oh); new.SetName (""); new.SetDim (ox - x0 + x, oy - y0 + y, ow, oh, FALSE);
  310.                 f.panel.Insert (new, new.overlapping)
  311.         ELSIF (keys0 = {MR}) & (o=NIL) THEN
  312.             Display1.Line (f, col, x0, y0, x0, ydif, Display.invert); Display1.Line (f, col, x0, y0, xdif, y0, Display.invert);
  313.             Display1.Line (f, col, x0, ydif, xdif, ydif, Display.invert); Display1.Line (f, col, xdif, y0, xdif, ydif, Display.invert);
  314.             IF keysum = {MR, ML} THEN 
  315.                 f.panel.RemoveObjects (Min (x0 - f.X, xdif - f.X), Min (y0 - f.Y - f.H, ydif - f.Y - f.H), ABS (x0 - xdif), ABS (y0 - ydif));
  316.             END
  317.         ELSIF (keys0 = {MM}) & (keysum = {MM, MR}) & (o # NIL) THEN 
  318.             IF ch1 THEN
  319.                 o.GetDim (ox, oy, ow, oh); o.SetDim (xh, yh, ow, oh, FALSE); (* set back to original position *) 
  320.             ELSIF ch3 THEN
  321.                 f.panel.MoveSelected (xh - xdif, yh - ydif)
  322.             END;
  323.             ch1 := FALSE; ch3 := FALSE; editObjectX := x; editObjectY := y; o.Edit ();
  324.             (* removing of ! caused by changing the contents of text items *)
  325.             gfmsg.p := Dialogs.editPanel; Viewers.Broadcast (gfmsg); 
  326.             IF gfmsg.f # NIL THEN
  327.                 v := Viewers.This (gfmsg.f.X, gfmsg.f.Y);
  328.                 IF (v # NIL) & (v IS MenuViewers.Viewer) & (v.dsc IS TextFrames.Frame) THEN  
  329.                     t := v.dsc (TextFrames.Frame).text;
  330.                     Texts.OpenReader (r, t, t.len - 1); Texts.Read (r, ch);
  331.                     IF ch = "!" THEN Texts.Delete (t, t.len - 1, t.len) END
  332.                 END
  333.             END
  334.         END;
  335.         IF (ch1) & (keysum # {MM}) & (keysum # {MM, ML}) & (o # NIL) THEN
  336.             o.GetDim (ox, oy, ow, oh); o.SetDim (xh, yh, ow, oh, FALSE)
  337.         END;
  338.         IF (ch3) & (keysum # {MM}) & (keysum # {MM, ML}) THEN
  339.             f.panel.MoveSelected (xh - xdif, yh - ydif)
  340.         END;
  341.         IF (ch2) & (keysum # {MM, ML}) & (o # NIL) THEN
  342.             o.GetDim (xh, yh, ow, oh); o.SetDim (xh, yh, wh, hh, FALSE)
  343.         END;
  344.     END Track;
  345.     PROCEDURE Handle* (f: Display.Frame; VAR msg: Display.FrameMsg);
  346.     (** handles messages which were sent to the edit-frame f *)
  347.         VAR self: DialogFrames.Frame; o: Dialogs.Object;
  348.     BEGIN 
  349.         self := f (DialogFrames.Frame);
  350.         WITH msg: Oberon.InputMsg DO
  351.             IF msg.id = Oberon.consume THEN 
  352.                 IF msg.ch = CRSL THEN self.panel.MoveSelected (- self.grid, 0)
  353.                 ELSIF msg.ch = CRSR THEN self.panel.MoveSelected (self.grid, 0)
  354.                 ELSIF msg.ch = CRSD THEN self.panel.MoveSelected (0, - self.grid)
  355.                 ELSIF msg.ch = CRSU THEN self.panel.MoveSelected (0, self.grid)
  356.                 END
  357.             ELSIF (msg.id = Oberon.track) & (msg.keys # {}) THEN 
  358.                 o := self.panel.ThisObject (msg.X - self.X, msg.Y - self.Y - f.H);
  359.                 Track (self, msg.keys, msg.X, msg.Y, o)
  360.             ELSE 
  361.                 DialogFrames.Handle (f, msg)
  362.             END
  363.         | msg: Oberon.ControlMsg DO
  364.             IF (msg.id = Oberon.neutralize) THEN self.panel.RemoveSelections () END;
  365.             DialogFrames.Handle (f, msg)
  366.         ELSE 
  367.             DialogFrames.Handle (f, msg)
  368.         END
  369.     END Handle;
  370.     PROCEDURE Edit*;    (** name | ^ *)
  371.     (** opens a dialog viewer and displays the dialog from file name for editing *)
  372.         VAR name: ARRAY 32 OF CHAR; df: DialogFrames.Frame; v: Viewers.Viewer; x, y: INTEGER;
  373.             panel: Dialogs.Panel; file: Files.File; r: Files.Rider; m: TextFrames.Frame; t: Texts.Text; buf: Texts.Buffer;
  374.     BEGIN
  375.         In.Open; In.Name(name); panel := NIL;
  376.         IF In.Done THEN 
  377.             NEW(panel); file := Files.Old (name);
  378.             IF file # NIL THEN Files.Set (r, file, 0); panel.Load (r) END
  379.         END;
  380.         IF panel # NIL THEN
  381.             NEW(df); df.Open (Handle, panel); df.col := 11;
  382.             Oberon.AllocateUserViewer (Oberon.Mouse.X, x, y);
  383.             IF Files.Old ("Dialog.Menu.Text") = NIL THEN
  384.                 m := TextFrames.NewMenu (name, editMenu)
  385.             ELSE
  386.                 m := TextFrames.NewMenu (name, "");
  387.                 NEW (t); Texts.Open (t, "Dialog.Menu.Text");
  388.                 NEW (buf); Texts.OpenBuf (buf); Texts.Save (t, 0, t.len, buf); Texts.Append (m.text, buf)
  389.             END;
  390.             v := MenuViewers.New (m, df, TextFrames.menuH, x, y)
  391.         END
  392.     END Edit;
  393.     PROCEDURE Store*;
  394.     (** stores the dialog under the name appearing in its menu frame *)
  395.         VAR v: Viewers.Viewer; f: Files.File; r: Files.Rider; s: Texts.Scanner; name: ARRAY 64 OF CHAR;
  396.             t: Texts.Text; r2: Texts.Reader; ch: CHAR;
  397.     BEGIN 
  398.         v := Oberon.Par.vwr; name := "";
  399.         IF (v.dsc # Oberon.Par.frame) OR (v.dsc = NIL) OR (v.dsc.next = NIL) OR ~(v.dsc.next IS DialogFrames.Frame) THEN
  400.             v := Oberon.MarkedViewer ();
  401.             Texts.OpenScanner (s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan (s);
  402.             IF (s.line = 0) & ((s.class = Texts.Name) OR (s.class = Texts.String)) THEN COPY (s.s, name) END
  403.         END;
  404.         IF (v.dsc # NIL) & (v.dsc.next # NIL) & (v.dsc.next IS DialogFrames.Frame) THEN
  405.             IF (name = "") & (v.dsc IS TextFrames.Frame) THEN
  406.                 Texts.OpenScanner (s, v.dsc(TextFrames.Frame).text, 0); Texts.Scan (s);
  407.                 IF (s.line = 0) & ((s.class = Texts.Name) OR (s.class = Texts.String)) THEN COPY (s.s, name) END
  408.             END;
  409.             IF name # "" THEN f := Files.New(name); Files.Set(r, f, 0);
  410.                 v.dsc.next(DialogFrames.Frame).panel.Store (r); 
  411.                 Files.Register (f);
  412.                 Texts.WriteString (w0, "Dialog.Store "); 
  413.                 Texts.WriteString (w0, name); Texts.WriteLn (w0);
  414.                 Texts.Append (Oberon.Log, w0.buf)
  415.             END;
  416.             t := v.dsc (TextFrames.Frame).text;
  417.             Texts.OpenReader (r2, t, t.len - 1); Texts.Read (r2, ch);
  418.             IF ch = "!" THEN Texts.Delete (t, t.len - 1, t.len) END
  419.         END
  420.     END Store;
  421.     PROCEDURE Print*;     (**  ^ | * | {name} ~ *) 
  422.     (** prints dialogs to print server named server *)
  423.         VAR s: Texts.Scanner; p: Dialogs.Panel; x, y, res: INTEGER; 
  424.             r: Files.Rider; file: Files.File; name: ARRAY 32 OF CHAR;
  425.         PROCEDURE PrintGetMainArg (VAR s: Texts.Scanner);
  426.         (* see implementation of module Edit *)
  427.             VAR text: Texts.Text; beg, end, time: LONGINT;
  428.         BEGIN
  429.             Texts.Scan (s);
  430.             IF (s.class = Texts.Char) & (s.c = "^") THEN 
  431.                 Oberon.GetSelection (text, beg, end, time);
  432.                 IF time >= 0 THEN Texts.OpenScanner (s, text, beg); Texts.Scan (s) END
  433.             END;
  434.             IF s.line # 0 THEN s.class := Texts.Inval END
  435.         END PrintGetMainArg;
  436.         PROCEDURE PrintError (res: INTEGER);
  437.         (* writes an error message to the log viewer *)
  438.         BEGIN
  439.             IF res = 1 THEN Texts.WriteString (w0, "Dialog Print Error 1: No connection")
  440.             ELSIF res = 2 THEN Texts.WriteString (w0, "Dialog Print Error 2: No link")
  441.             ELSIF res = 3 THEN Texts.WriteString (w0, "Dialog Print Error 3: Bad response")
  442.             ELSIF res = 4 THEN Texts.WriteString (w0, "Dialog Print Error 4: Wrong input")
  443.             ELSIF res = 5 THEN Texts.WriteString (w0, "Dialog Print Error 5: No panel selected")
  444.             END;
  445.             Texts.WriteLn (w0);
  446.             Texts.Append (Oberon.Log, w0.buf)
  447.         END PrintError;
  448.     BEGIN
  449.         Texts.OpenScanner (s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan (s);
  450.         IF ((s.class = Texts.Name) OR (s.class = Texts.String)) & (s.line = 0) THEN
  451.             COPY (s.s, name); PrintGetMainArg (s); res := 0;
  452.             IF (s.class = Texts.Char) & (s.c = "*") THEN 
  453.                 DialogFrames.GetCaretPosition (p, x, y);
  454.             ELSIF s.class = Texts.Name THEN 
  455.                 file := Files.Old (s.s);
  456.                 IF file # NIL THEN 
  457.                     NEW (p); Files.Set (r, file, 0); p.Load (r); 
  458.                 ELSE
  459.                     res := 4
  460.                 END
  461.             ELSIF (Oberon.Par.vwr # NIL) & (Oberon.Par.vwr IS MenuViewers.Viewer) & (Oberon.Par.vwr.dsc.next IS DialogFrames.Frame) THEN
  462.                 p := Oberon.Par.vwr.dsc.next(DialogFrames.Frame).panel;
  463.             ELSE
  464.                 res := 4
  465.             END;
  466.             IF (p # NIL) & (res = 0) THEN
  467.                 Printer.Open (name, Oberon.User, Oberon.Password); res := Printer.res;
  468.                 IF res = 0 THEN
  469.                     p.Print (0, Printer.PageHeight); Printer.Page (1); Printer.Close     
  470.                 END
  471.             ELSE
  472.                 IF res # 4 THEN res := 5 END
  473.             END
  474.         ELSE 
  475.             res :=4
  476.         END;
  477.         IF res # 0 THEN PrintError (res) END;
  478.     END Print;
  479.     PROCEDURE DrawReticule (x, y: INTEGER);
  480.     BEGIN
  481.         IF x < CL THEN
  482.             IF x < markW THEN x := markW ELSIF x > DW THEN x := DW - markW END
  483.         ELSE
  484.             IF x < CL + markW THEN x := CL + markW ELSIF x > CL + DW THEN x := CL + DW - markW END
  485.         END;
  486.         IF y < markW THEN y := markW ELSIF y > DH THEN y := DH - markW END;
  487.         Display.CopyPattern (Display.white, Display.cross, x - markW, y - markW, 2)
  488.     END DrawReticule;
  489. BEGIN
  490.     DW := Display.Width - 8; DH := Display.Height - 8; CL := Display.ColLeft;
  491.     Texts.OpenWriter (w0); reticule.Draw := DrawReticule; reticule.Fade := DrawReticule;
  492. END Dialog.
  493.