home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
jËzyki_programowania
/
oberon
/
system
/
dir.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1977-12-31
|
22KB
|
617 lines
Syntax10.Scn.Fnt
StampElems
Alloc
29 May 96
VersionElems
AllocBeg
Syntax10.Scn.Fnt
PowerMac
Windows
AmigaAmiga
PowerMac
Syntax10.Scn.Fnt
DELR = 008X; PageUp = 0ACX; PageDown = 0ADX; Home = 091X; BRK = 0B9X;Windows
Syntax10.Scn.Fnt
DELR = 0A1X; PageUp = 0C5X; PageDown = 0C6X; Home = 0C8X; BRK = 0ACX;Amiga
VersionElems
AllocEnd
Syntax10i.Scn.Fnt
Syntax10b.Scn.Fnt
FoldElems
Syntax10i.Scn.Fnt
forward declarations
MarkElems
Alloc
Syntax10i.Scn.Fnt
track mouse
Syntax10i.Scn.Fnt
open subdirectory
Syntax10i.Scn.Fnt
open file
MODULE Dir; (** HM
IMPORT Files, Display, Input, Viewers, Texts, TextFrames, MenuViewers, Oberon, Directories, Strings, In, Out;
CONST
DELR = 0A1X; PageUp = 0C5X; PageDown = 0C6X; Home = 0C8X; BRK = 0ACX;
delimiter = Directories.delimiter;
left =2; middle = 1; right = 0;
delete = 0; copy = 1; move = 2; select = 3; unselect = 4; (*opcodes for ForAllElemsDo*)
pixel = LONG(10000);
CR = 0DX; DEL = 7FX; CRSU = 0C1X; CRSD = 0C2X;
Elem* = POINTER TO ElemDesc;
ElemDesc* = RECORD (Texts.ElemDesc)
name*: ARRAY 32 OF CHAR;
sel*: BOOLEAN;
icon, iconSel, iconCopy: Display.Pattern
END ;
Text* = POINTER TO TextDesc;
TextDesc* = RECORD (Texts.TextDesc)
path*: ARRAY 128 OF CHAR
END ;
UpdateMsg = RECORD (Display.FrameMsg)
op: INTEGER;
path, name: ARRAY 128 OF CHAR
END ;
Opener = POINTER TO OpenerDesc; (*list of commands to open files*)
OpenerDesc = RECORD
pattern, cmd: ARRAY 32 OF CHAR;
next: Opener
END ;
scratch: Texts.Text;
invalidOp: BOOLEAN; (*TRUE if text operation suppressed in Notify*)
ignoreNeutralize: BOOLEAN;
w: Texts.Writer;
fileIcon, fileIconSel, fileIconCopy: Display.Pattern; (*x=0, y=0, w=15, h=13*)
dirIcon, dirIconSel, dirIconCopy: Display.Pattern; (*x=0, y=0, w=15, h=13*)
copyHull, moveHull: Display.Pattern;
copyMarker, moveMarker: Oberon.Marker;
mask: ARRAY 32 OF CHAR;
openers: Opener;
CBtext: Texts.Text; (* global variable for callback procedure MakeEntry *)
oldNotifier: Directories.Notifier;
PROCEDURE ^ NoNotify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);
PROCEDURE ^ Notify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);
PROCEDURE ^ NotifyDir* (op: INTEGER; path, name: ARRAY OF CHAR);
PROCEDURE ^ HandleElem* (e: Texts.Elem; VAR m: Texts.ElemMsg);
PROCEDURE ^ HandleFrame*(f: Display.Frame; VAR m: Display.FrameMsg);
PROCEDURE (e: Elem)
Update;
VAR m: TextFrames.UpdateMsg;
BEGIN
m.id := TextFrames.replace; m.text := Texts.ElemBase(e);
m.beg := Texts.ElemPos(e); m.end := m.beg + 1;
Viewers.Broadcast(m)
END Update;
PROCEDURE (e: Elem)
Restore;
VAR r: Texts.Reader; t: Texts.Text; pos1, pos2: LONGINT;
BEGIN
t := Texts.ElemBase(e); pos1 := Texts.ElemPos(e) + 1;
Texts.OpenReader(r, t, pos1); Texts.ReadElem(r);
IF r.eot THEN pos2 := t.len -1
ELSE pos2 := Texts.Pos(r) - 2
END ;
Texts.Delete(t, pos1, pos2); Texts.WriteString(w, e.name); Texts.Insert(t, pos1, w.buf)
END Restore;
PROCEDURE (e: Elem)
Check;
VAR s: Texts.Scanner; t: Texts.Text; old, new: ARRAY 256 OF CHAR;
res: INTEGER;
BEGIN
t := Texts.ElemBase(e);
Texts.OpenScanner(s, t, Texts.ElemPos(e) + 1);
Texts.Scan(s);
IF (s.class = Texts.Name) & (s.line = 0) THEN
IF e.name # s.s THEN
COPY(t(Text).path, old); Strings.Append(delimiter, old);
COPY(old, new);
Strings.Append(e.name, old);
Strings.Append(s.s, new);
Files.Rename(old, new, res);
IF res > 1 THEN Out.String("-- failed$"); e.Restore END
END
ELSE Out.String("-- failed$"); e.Restore
END Check;
PROCEDURE
Diff (VAR a, b: ARRAY OF CHAR): INTEGER;
VAR i, d: INTEGER;
BEGIN i := 0;
LOOP
IF CAP(a[i]) = CAP(b[i]) THEN
IF a[i] = 0X THEN d := 0; EXIT END
ELSIF CAP(a[i]) < CAP(b[i]) THEN d := -1; EXIT
ELSE d := 1; EXIT
END ;
INC(i)
END ;
RETURN d
END Diff;
PROCEDURE
NewElem (name: ARRAY OF CHAR; isDir: BOOLEAN): Elem;
VAR e: Elem;
BEGIN
NEW(e); e.W := 15 * pixel; e.H := 13 * pixel; e.handle := HandleElem;
COPY(name, e.name); e.sel := FALSE;
IF isDir THEN e.icon := dirIcon; e.iconSel := dirIconSel; e.iconCopy := dirIconCopy
ELSE e.icon := fileIcon; e.iconSel := fileIconSel; e.iconCopy := fileIconCopy
END ;
RETURN e
END NewElem;
PROCEDURE
ThisElem (t: Texts.Text; pos: LONGINT): Elem;
VAR r: Texts.Reader; ch: CHAR;
BEGIN
Texts.OpenReader(r, t, pos); Texts.Read(r, ch);
IF ch # Texts.ElemChar THEN Texts.ReadPrevElem(r) END ;
IF r.eot THEN RETURN NIL ELSE RETURN r.elem(Elem) END
END ThisElem;
PROCEDURE
FindElem (t: Texts.Text; name: ARRAY OF CHAR; VAR e: Elem; VAR pos: LONGINT; VAR d: INTEGER);
VAR r: Texts.Reader;
BEGIN
Texts.OpenReader(r, t, 0); Texts.ReadElem(r);
LOOP
IF r.eot THEN e := NIL; d := 1; pos := t.len; RETURN END ;
IF r.elem IS Elem THEN
e := r.elem(Elem);
d := Diff(e.name, name);
IF d >= 0 THEN pos := Texts.ElemPos(e); EXIT END
END ;
Texts.ReadElem(r)
END FindElem;
PROCEDURE
CopyFile (e:Elem; src, dst: Text);
CONST bufSize = 4096;
VAR sn, dn: ARRAY 128 OF CHAR; sf, df: Files.File; sr, dr: Files.Rider;
len: LONGINT; buf: ARRAY bufSize OF CHAR;
BEGIN
COPY(src.path, sn); Strings.Append(delimiter, sn); Strings.Append(e.name, sn);
COPY(dst.path, dn); Strings.Append(delimiter, dn); Strings.Append(e.name, dn);
sf := Files.Old(sn); Files.Set(sr, sf, 0);
df := Files.New(dn); Files.Set(dr, df, 0);
REPEAT
Files.ReadBytes(sr, buf, bufSize); Files.WriteBytes(dr, buf, bufSize - sr.res)
UNTIL sr.res # 0;
Files.Register(df);
END CopyFile;
PROCEDURE
MoveFile (e:Elem; src, dst: Text);
VAR sn, dn: ARRAY 256 OF CHAR; res: INTEGER;
BEGIN
COPY(src.path, sn); Strings.Append(delimiter, sn); Strings.Append(e.name, sn);
COPY(dst.path, dn); Strings.Append(delimiter, dn); Strings.Append(e.name, dn);
Files.Rename(sn, dn, res);
END MoveFile;
PROCEDURE
MakeEntry(d: Directories.Directory; name: ARRAY OF CHAR; isDir: BOOLEAN; VAR continue: BOOLEAN);
VAR e: Elem; pos: LONGINT; found: INTEGER;
BEGIN
Texts.WriteElem(w, NewElem(name, isDir)); Texts.WriteString(w, name); Texts.WriteLn(w);
FindElem(CBtext, name, e, pos, found); Texts.Insert(CBtext, pos, w.buf)
END MakeEntry;
PROCEDURE
OpenDir (d: Directories.Directory);
VAR t: Text; f: TextFrames.Frame; x, y: INTEGER; v: Viewers.Viewer;
BEGIN
NEW(t); Texts.Open(t, ""); COPY(d.path, t.path);
t.notify := NoNotify; CBtext := t;
Directories.Enumerate(d, MakeEntry);
CBtext := NIL; t.notify := Notify;
NEW(f); TextFrames.Open(f, t, 0); f.handle := HandleFrame;
Oberon.AllocateSystemViewer(0, x, y);
v := MenuViewers.New(
TextFrames.NewMenu(d.path, "^Dir.Menu.Text"),
f, TextFrames.menuH, x, y)
END OpenDir;
PROCEDURE
ForAllElemsDo (op: INTEGER; src, dst: Text);
VAR r: Texts.Reader; beg, end: LONGINT; f: TextFrames.Frame; e: Elem; path: ARRAY 256 OF CHAR; res: INTEGER;
m: UpdateMsg;
BEGIN
IF src = NIL THEN RETURN END ;
end := src.len; Texts.OpenReader(r, src, end);
LOOP
Texts.ReadPrevElem(r); IF r.eot THEN EXIT END ;
IF r.elem IS Elem THEN
e := r.elem(Elem); beg := Texts.Pos(r);
IF e.sel THEN
IF op = delete THEN
COPY(src.path, path); Strings.Append(delimiter, path); Strings.Append(e.name, path);
Files.Delete(path, res);
IF res # 0 THEN
Out.String("-- failed$")
ELSE
m.op := Directories.delete; COPY(src.path, m.path); COPY(e.name, m.name); (*<<FF*)
Viewers.Broadcast(m);
END;
ELSIF op = copy THEN
CopyFile(e, src, dst);
e.sel := FALSE; e.Update;
m.op := Directories.insert; COPY(dst.path, m.path); COPY(e.name, m.name); (*<<FF*)
Viewers.Broadcast(m);
ELSIF op = move THEN
MoveFile(e, src, dst);
m.op := Directories.delete; COPY(src.path, m.path); COPY(e.name, m.name); (*<<FF*)
Viewers.Broadcast(m);
m.op := Directories.insert; COPY(dst.path, m.path); COPY(e.name, m.name);
Viewers.Broadcast(m);
ELSIF op = unselect THEN
e.sel := FALSE; e.Update
END ;
Texts.OpenReader(r, src, beg)
ELSIF (op = select) & Strings.Match(e.name, mask) THEN
e.sel := TRUE; e.Update
END ;
end := beg
END
END ForAllElemsDo;
PROCEDURE
DrawCopy (x, y: INTEGER);
BEGIN
Display.CopyPattern(Display.white, copyHull, x, y, Display.invert)
END DrawCopy;
PROCEDURE
DrawMove (x, y: INTEGER);
BEGIN
Display.CopyPattern(Display.white, moveHull, x, y, Display.invert)
END DrawMove;
PROCEDURE
ThisFrame (x, y: INTEGER): TextFrames.Frame;
VAR v: Viewers.Viewer; f: Display.Frame;
BEGIN
v := Viewers.This(x, y); f := v.dsc;
WHILE (f # NIL)
& ((x < f.X) OR (x > f.X+f.W) OR (y < f.Y) OR (y > f.Y+f.H)) DO
f := f.next
END ;
IF f IS TextFrames.Frame THEN RETURN f(TextFrames.Frame)
ELSE RETURN NIL
END ThisFrame;
PROCEDURE
TargetText(): Text;
VAR f: TextFrames.Frame;
BEGIN
IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN
f := Oberon.Par.frame.next(TextFrames.Frame)
ELSE
f := ThisFrame(Oberon.Pointer.X, Oberon.Pointer.Y);
END ;
IF f.text IS Text THEN RETURN f.text(Text) ELSE RETURN NIL END
END TargetText;
PROCEDURE
Init;
VAR line: ARRAY 14 OF SET; s: Texts.Scanner; x: Opener;
BEGIN
line[1] := {};
line[2] := {1..8};
line[3] := {1, 8};
line[4] := {1, 8};
line[5] := {1, 8};
line[6] := {1, 8};
line[7] := {1, 8};
line[8] := {1, 8};
line[9] := {1, 5..8};
line[10] := {1, 5, 7};
line[11] := {1, 5, 6};
line[12] := {1..5};
line[13] := {};
fileIcon := Display.NewPattern(line, 15, 13);
line[1] := {};
line[2] := {1..8};
line[3] := {1, 4, 8};
line[4] := {1, 4, 8};
line[5] := {1, 2..6, 8};
line[6] := {1, 4, 8};
line[7] := {1, 4, 8};
line[8] := {1, 8};
line[9] := {1, 5..8};
line[10] := {1, 5, 7};
line[11] := {1, 5, 6};
line[12] := {1..5};
line[13] := {};
fileIconCopy := Display.NewPattern(line, 15, 13);
line[1] := {};
line[2] := {1..8};
line[3] := {1..8};
line[4] := {1..8};
line[5] := {1..8};
line[6] := {1..8};
line[7] := {1..8};
line[8] := {1..8};
line[9] := {1..8};
line[10] := {1..5, 7};
line[11] := {1..6};
line[12] := {1..5};
line[13] := {};
fileIconSel := Display.NewPattern(line, 15, 13);
line[1] := {};
line[2] := {};
line[3] := {1..10};
line[4] := {1, 10};
line[5] := {1, 10};
line[6] := {1, 10};
line[7] := {1, 10};
line[8] := {1, 10};
line[9] := {1, 10};
line[10] := {1..10};
line[11] := {1, 5};
line[12] := {1..4};
line[13] := {};
dirIcon := Display.NewPattern(line, 15, 13);
line[1] := {};
line[2] := {};
line[3] := {1..10};
line[4] := {1, 6, 10};
line[5] := {1, 6, 10};
line[6] := {1, 4..8, 10};
line[7] := {1, 6, 10};
line[8] := {1, 6, 10};
line[9] := {1, 10};
line[10] := {1..10};
line[11] := {1, 5};
line[12] := {1..4};
line[13] := {};
dirIconCopy := Display.NewPattern(line, 15, 13);
line[1] := {};
line[2] := {};
line[3] := {1..10};
line[4] := {1..10};
line[5] := {1..10};
line[6] := {1..10};
line[7] := {1..10};
line[8] := {1..10};
line[9] := {1..10};
line[10] := {1..10};
line[11] := {1, 5};
line[12] := {1..4};
line[13] := {};
dirIconSel := Display.NewPattern(line, 15, 13);
copyMarker.Draw := DrawCopy; copyMarker.Fade := DrawCopy;
moveMarker.Draw := DrawMove; moveMarker.Fade := DrawMove;
Texts.OpenWriter(w);
ignoreNeutralize := FALSE;
oldNotifier := Directories.notify;
Directories.notify := NotifyDir;
NEW(scratch); Texts.Open(scratch, "Dir.Menu.Text"); scratch.notify := NoNotify;
Texts.OpenScanner(s, scratch, 0); openers := NIL;
REPEAT Texts.Scan(s) UNTIL s.eot OR (s.line # 0);
WHILE s.class = Texts.String DO
NEW(x); COPY(s.s, x.pattern); Texts.Scan(s);
IF s.class IN {Texts.Name, Texts.String} THEN COPY(s.s, x.cmd); Texts.Scan(s); x.next := openers; openers := x END
END Init;
PROCEDURE
NoNotify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);
END NoNotify;
PROCEDURE
Notify (t: Texts.Text; op: INTEGER; beg, end: LONGINT);
VAR b: Texts.Buffer; r: Texts.Reader; ch: CHAR; pos: LONGINT;
BEGIN
IF op = TextFrames.delete THEN
pos := scratch.len; Texts.Recall(b); Texts.Append(scratch, b);
Texts.OpenReader(r, scratch, pos);
REPEAT
Texts.Read(r, ch)
UNTIL r.eot OR (ch = CR) OR (ch = Texts.ElemChar) & (r.elem IS Elem);
IF ~r.eot THEN
invalidOp := TRUE;
t.notify := NoNotify;
Texts.Save(scratch, pos, t.len, b);
Texts.Insert(t, beg, b);
t.notify := Notify;
op := TextFrames.replace; end := beg
END
ELSIF op = TextFrames.insert THEN
Texts.OpenReader(r, t, beg); pos := beg;
REPEAT
Texts.Read(r, ch); INC(pos)
UNTIL (pos > end) OR (ch = CR)
OR (ch = Texts.ElemChar) & (r.elem IS Elem);
IF pos <= end THEN
invalidOp := TRUE;
t.notify := NoNotify;
Texts.Delete(t, beg, end);
t.notify := Notify;
op := TextFrames.replace; end := beg
END
END ;
ignoreNeutralize := TRUE;
TextFrames.NotifyDisplay(t, op, beg, end);
ignoreNeutralize := FALSE
END Notify;
PROCEDURE
NotifyDir* (op: INTEGER; path, name: ARRAY OF CHAR);
VAR m: UpdateMsg;
BEGIN
m.op := op; COPY(path, m.path); COPY(name, m.name);
Viewers.Broadcast(m);
oldNotifier(op, path, name)
END NotifyDir;
PROCEDURE
HandleElem* (e: Texts.Elem; VAR m: Texts.ElemMsg);
CONST moved = -1000;
VAR e1: Elem; x, y, x0, y0, dsr, res: INTEGER; keys: SET; t: Texts.Text;
path: ARRAY 128 OF CHAR; marker: Oberon.Marker;
f: TextFrames.Frame; src, dst: Text; d: Directories.Directory; name: ARRAY 256 OF CHAR; o: Opener;
BEGIN
WITH e: Elem DO
WITH m: Texts.CopyMsg DO
IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(Elem) END ;
Texts.CopyElem(e, e1);
COPY(e.name, e1.name);
e1.sel := e.sel; e1.icon := e.icon; e1.iconSel := e.iconSel; e1.iconCopy := e.iconCopy
| m: TextFrames.DisplayMsg DO
IF ~m.prepare THEN
IF e.sel THEN
Display.CopyPattern(Display.white, e.iconSel, m.X0, m.Y0+1, Display.replace)
ELSE
Display.CopyPattern(Display.white, e.icon, m.X0, m.Y0+1, Display.replace)
END
END
| m: TextFrames.TrackMsg DO
IF middle IN m.keys THEN
e.sel := ~e.sel; e.Update;
src := m.frame(TextFrames.Frame).text(Text);
Input.Mouse(keys, x0, y0);
marker := Oberon.Arrow; copyHull := e.iconCopy; moveHull := e.icon;
REPEAT Input.Mouse(keys, x, y); m.keys := m.keys + keys;
IF (e.icon # dirIcon) & ((ABS(x-x0) > 10) OR (ABS(y-y0) > 10)) THEN
x0 := moved;
IF m.keys = {middle, left} THEN marker := copyMarker ELSE marker := moveMarker END
END ;
Oberon.DrawCursor(Oberon.Mouse, marker, x, y)
UNTIL keys = {};
IF m.keys = {middle, right} THEN
IF e.icon = dirIcon THEN
t := Texts.ElemBase(e);
COPY(t(Text).path, path); Strings.Append(delimiter, path); Strings.Append(e.name, path);
OpenDir(Directories.This(path))
ELSE
d := Directories.Current(); name := "";
IF src.path # d.path THEN
Strings.Append(src.path, name); Strings.Append(delimiter, name)
END ;
Strings.Append(e.name, name);
o := openers;
WHILE (o # NIL) & ~Strings.Match(e.name, o.pattern) DO o := o.next END ;
IF o = NIL THEN NEW(o); o.cmd := "Edit.Open" END ;
Oberon.Par.vwr := Viewers.This(m.X, m.Y); Oberon.Par.frame := m.frame;
Oberon.Par.pos := scratch.len; Oberon.Par.text := scratch;
Texts.WriteString(w, name); Texts.Append(scratch, w.buf);
Oberon.Call(o.cmd, Oberon.Par, FALSE, res)
END ;
e.sel := FALSE; e.Update
ELSIF (x0 = moved) & e.sel THEN
f := ThisFrame(x, y);
IF (f # NIL) & (f # m.frame) & (f.text IS Text) THEN
dst := f.text(Text);
IF m.keys = {middle} THEN
ForAllElemsDo(move, src, dst)
ELSIF m.keys = {middle, left} THEN
ForAllElemsDo(copy, src, dst)
END
END
END
END
ELSE
END
END HandleElem;
PROCEDURE
HandleFrame* (f: Display.Frame; VAR m: Display.FrameMsg);
VAR ready: BOOLEAN; e: Elem; keys: SET; x, y, d: INTEGER; t: Texts.Text;
pos, pos2: LONGINT; r: Texts.Reader; ch: CHAR; path: ARRAY 256 OF CHAR; dir: Directories.Directory;
PROCEDURE CheckChar(ch: CHAR): BOOLEAN;
BEGIN
RETURN (ch=".") OR
((ch>="0") & (ch<="9")) OR
((ch>="A") & (ch<="Z")) OR
((ch>="a") & (ch<="z"));
END CheckChar;
BEGIN
ready := FALSE;
WITH f: TextFrames.Frame DO
WITH m: Oberon.InputMsg DO
IF m.id = Oberon.consume THEN
pos := f.carloc.pos; e := ThisElem(f.text, pos);
IF (m.ch = CR) OR (m.ch = PageUp) OR (m.ch = PageDown) OR (m.ch = Home) OR (m.ch = BRK) THEN
e.Check; TextFrames.RemoveCaret(f); ready := TRUE
ELSIF (m.ch = CRSU) OR (m.ch = CRSD) THEN
e.Check
ELSIF m.ch = DEL THEN
invalidOp := FALSE;
TextFrames.Handle(f, m); ready := TRUE;
IF invalidOp THEN
e := ThisElem(f.text, pos);
e.Check; TextFrames.RemoveCaret(f)
END
ELSE
Texts.OpenReader(r, f.text, f.carloc.pos); Texts.Read(r, ch);
ready := (ch = Texts.ElemChar) & (r.elem IS Elem);
(* We have to check here wether the char is allowed or not.
Allowed chars; letters, digits, "." *)
IF ~CheckChar(m.ch) THEN ready := TRUE END;
END
ELSIF (m.id = Oberon.track) & f.hasCar & (m.keys * {middle, right} # {}) THEN
e := ThisElem(f.text, f.carloc.pos);
IF (e # NIL) & (ThisElem(f.text, TextFrames.Pos(f, x, y)) # e) THEN e.Check END
END
| m: Oberon.ControlMsg DO
IF m.id = Oberon.defocus THEN
e := ThisElem(f.text, f.carloc.pos);
Input.Mouse(keys, x, y);
IF (e # NIL) & ((f # ThisFrame(x, y)) OR (ThisElem(f.text, TextFrames.Pos(f, x, y)) # e)) THEN
e.Check
END
ELSIF (m.id = Oberon.neutralize) & ~ignoreNeutralize & f.hasCar THEN
e := ThisElem(f.text, f.carloc.pos);
IF e # NIL THEN e.Check END
END
| m: UpdateMsg DO
IF (Diff(f.text(Text).path, m.path) = 0) THEN
t := f.text; FindElem(t, m.name, e, pos, d);
t.notify := TextFrames.NotifyDisplay;
CASE m.op OF
| Directories.insert:
IF d # 0 THEN
COPY(m.path, path); Strings.Append(delimiter, path); Strings.Append(m.name, path);
dir := Directories.This(path);
Texts.WriteElem(w, NewElem(m.name, dir # NIL)); Texts.WriteString(w, m.name); Texts.WriteLn(w);
Texts.Insert(t, pos, w.buf)
END
| Directories.delete:
IF d = 0 THEN
Texts.OpenReader(r, t, pos+1); Texts.ReadElem(r);
IF r.eot THEN pos2 := t.len ELSE pos2 := Texts.Pos(r) - 1 END ;
Texts.Delete(t, pos, pos2)
END
| Directories.change:
END ;
t.notify := Notify
END
ELSE
END
END ;
IF ~ready THEN TextFrames.Handle(f, m) END
END HandleFrame;
PROCEDURE
Open*;
dir: Directories.Directory; (*<<FF*)
BEGIN
NEW(dir);
COPY(Files.CurrentDir, dir.path);
OpenDir(dir);
dir := NIL;
END Open;
PROCEDURE
New*;
VAR name: ARRAY 256 OF CHAR; i: INTEGER;
BEGIN
In.Open;
IF In.Next() = In.string THEN In.String(name) ELSE In.Name(name) END ;
IF In.Done THEN Directories.Create(name) END
END New;
PROCEDURE
Delete*;
BEGIN
ForAllElemsDo(delete, TargetText(), NIL)
END Delete;
PROCEDURE
Select*;
VAR ch: CHAR; i: INTEGER;
BEGIN
In.Open; i := 0;
REPEAT In.Char(ch) UNTIL ch >= " ";
REPEAT mask[i] := ch; INC(i); In.Char(ch) UNTIL (ch <= " ") OR (ch > 7FX);
mask[i] := 0X;
ForAllElemsDo(select, TargetText(), NIL)
END Select;
PROCEDURE
Deselect*;
BEGIN
ForAllElemsDo(unselect, TargetText(), NIL)
END Deselect;
BEGIN
Init
END Dir.