implement Rowm; include "common.m"; sys : Sys; bufio : Bufio; utils : Utils; drawm : Draw; acme : Acme; graph : Graph; gui : Gui; dat : Dat; bufferm : Bufferm; textm : Textm; filem : Filem; windowm : Windowm; columnm : Columnm; exec : Exec; look : Look; edit : Edit; ecmd : Editcmd; ALLLOOPER, ALLTOFILE, ALLMATCHFILE, ALLFILECHECK, ALLELOGTERM, ALLEDITINIT, ALLUPDATE: import Edit; sprint : import sys; FALSE, TRUE, XXX : import Dat; Border, BUFSIZE, Astring : import Dat; Reffont, reffont, Lock, Ref : import dat; row, home, mouse : import dat; fontnames : import acme; font, draw : import graph; Point, Rect, Image : import drawm; min, max, abs, error, warning, clearmouse, stralloc, strfree : import utils; black, white, mainwin : import gui; Buffer : import bufferm; Tag, Rowtag, Text : import textm; Window : import windowm; File : import filem; Column : import columnm; Iobuf : import bufio; init(mods : ref Dat->Mods) { sys = mods.sys; bufio = mods.bufio; dat = mods.dat; utils = mods.utils; drawm = mods.draw; acme = mods.acme; graph = mods.graph; gui = mods.gui; bufferm = mods.bufferm; textm = mods.textm; filem = mods.filem; windowm = mods.windowm; columnm = mods.columnm; exec = mods.exec; look = mods.look; edit = mods.edit; ecmd = mods.editcmd; } newrow() : ref Row { r := ref Row; r.qlock = Lock.init(); r.r = ((0, 0), (0, 0)); r.tag = nil; r.col = nil; r.ncol = 0; return r; } Row.init(row : self ref Row, r : Rect) { r1 : Rect; t : ref Text; dummy : ref File = nil; draw(mainwin, r, white, nil, (0, 0)); row.r = r; row.col = nil; row.ncol = 0; r1 = r; r1.max.y = r1.min.y + font.height; row.tag = textm->newtext(); t = row.tag; t.init(dummy.addtext(t), r1, Reffont.get(FALSE, FALSE, FALSE, nil), acme->tagcols); t.what = Rowtag; t.row = row; t.w = nil; t.col = nil; r1.min.y = r1.max.y; r1.max.y += Border; draw(mainwin, r1, black, nil, (0, 0)); t.insert(0, "Newcol Kill Putall Dump Exit ", 29, TRUE, 0); t.setselect(t.file.buf.nc, t.file.buf.nc); } Row.add(row : self ref Row, c : ref Column, x : int) : ref Column { r, r1 : Rect; d : ref Column; i : int; d = nil; r = row.r; r.min.y = row.tag.frame.r.max.y+Border; if(x0){ #steal 40% of last column by default d = row.col[row.ncol-1]; x = d.r.min.x + 3*d.r.dx()/5; } # look for column we'll land on for(i=0; i 0){ if(i < row.ncol) i++; # new column will go after d r = d.r; if(r.dx() < 100) return nil; draw(mainwin, r, white, nil, (0, 0)); r1 = r; r1.max.x = min(x, r.max.x-50); if(r1.dx() < 50) r1.max.x = r1.min.x+50; d.reshape(r1); r1.min.x = r1.max.x; r1.max.x = r1.min.x+Border; draw(mainwin, r1, black, nil, (0, 0)); r.min.x = r1.max.x; } if(c == nil){ c = ref Column; c.init(r); reffont.r.inc(); }else c.reshape(r); c.row = row; c.tag.row = row; orc := row.col; row.col = array[row.ncol+1] of ref Column; row.col[0:] = orc[0:i]; row.col[i+1:] = orc[i:row.ncol]; orc = nil; row.col[i] = c; row.ncol++; clearmouse(); return c; } Row.reshape(row : self ref Row, r : Rect) { i, dx, odx : int; r1, r2 : Rect; c : ref Column; dx = r.dx(); odx = row.r.dx(); row.r = r; r1 = r; r1.max.y = r1.min.y + font.height; row.tag.reshape(r1); r1.min.y = r1.max.y; r1.max.y += Border; draw(mainwin, r1, black, nil, (0, 0)); r.min.y = r1.max.y; r1 = r; r1.max.x = r1.min.x; for(i=0; icursorswitch(dat->boxcursor); b = mouse.buttons; op = mouse.xy; while(mouse.buttons == b) acme->frgetmouse(); graph->cursorswitch(dat->arrowcursor); if(mouse.buttons){ while(mouse.buttons) acme->frgetmouse(); return; } for(i=0; i0 && p.xc.r.max.x)){ # shuffle x = c.r.min.x; row.close(c, FALSE); if(row.add(c, p.x) == nil) # whoops! if(row.add(c, x) == nil) # WHOOPS! if(row.add(c, -1)==nil){ # shit! row.close(c, TRUE); return; } c.mousebut(); return; } d = row.col[i-1]; if(p.x < d.r.min.x+80+Dat->Scrollwid) p.x = d.r.min.x+80+Dat->Scrollwid; if(p.x > c.r.max.x-80-Dat->Scrollwid) p.x = c.r.max.x-80-Dat->Scrollwid; r = d.r; r.max.x = c.r.max.x; draw(mainwin, r, white, nil, (0, 0)); r.max.x = p.x; d.reshape(r); r = c.r; r.min.x = p.x; r.max.x = r.min.x; r.max.x += Border; draw(mainwin, r, black, nil, (0, 0)); r.min.x = r.max.x; r.max.x = c.r.max.x; c.reshape(r); c.mousebut(); } Row.close(row : self ref Row, c : ref Column, dofree : int) { r : Rect; i : int; for(i=0; ibartflag) t = dat->barttext; else t = row.which(p); if(t!=nil && !(t.what==Tag && p.in(t.scrollr))){ w = t.w; if(w == nil) t.typex(r, 0); else{ w.lock('K'); w.typex(t, r); w.unlock(); } } row.qlock.unlock(); return t; } Row.clean(row : self ref Row, exiting : int) : int { clean : int; i : int; clean = TRUE; for(i=0; iException; if (sys->rescue("*", e) == sys->EXCEPTION){ sys->rescued(Sys->ONCE, ""); return; } if(file == nil){ if(home == nil){ warning(nil, "can't find file for dump: $home not defined\n"); sys->raise(""); } buf = sprint("%s/acme.dump", home); file = buf; } b = bufio->create(file, Bufio->OWRITE, 8r600); if(b == nil){ warning(nil, sprint("can't open %s: %r\n", file)); sys->raise(""); } r = stralloc(BUFSIZE); b.puts(acme->wdir); b.putc('\n'); b.puts(fontnames[0]); b.putc('\n'); b.puts(fontnames[1]); b.putc('\n'); for(i=0; iQWevent] > byte 0) if(w.dumpstr == nil) continue; # zeroxes of external windows are tossed if(t.file.ntext > 1) for(n=0; nQWevent] != byte 0) { j = c.nw; continue; } } fontname = ""; if(t.reffont.f != font) fontname = t.reffont.f.name; a = t.file.name; if(t.file.dumpid){ dumped = FALSE; b.puts(sprint("x%11d %11d %11d %11d %11d %s\n", i, t.file.dumpid, w.body.q0, w.body.q1, 100*(w.r.min.y-c.r.min.y)/c.r.dy(), fontname)); }else if(w.dumpstr != nil){ dumped = FALSE; b.puts(sprint("e%11d %11d %11d %11d %11d %s\n", i, t.file.dumpid, 0, 0, 100*(w.r.min.y-c.r.min.y)/c.r.dy(), fontname)); }else if(len a == 0){ # don't save unnamed windows continue; }else if((!w.dirty && utils->access(a)==0) || w.isdir){ dumped = FALSE; t.file.dumpid = w.id; b.puts(sprint("f%11d %11d %11d %11d %11d %s\n", i, w.id, w.body.q0, w.body.q1, 100*(w.r.min.y-c.r.min.y)/c.r.dy(), fontname)); }else{ dumped = TRUE; t.file.dumpid = w.id; b.puts(sprint("F%11d %11d %11d %11d %11d %11d %s\n", i, j, w.body.q0, w.body.q1, 100*(w.r.min.y-c.r.min.y)/c.r.dy(), w.body.file.buf.nc, fontname)); } a = nil; buf = w.ctlprint(); b.puts(buf); m = min(BUFSIZE, w.tag.file.buf.nc); w.tag.file.buf.read(0, r, 0, m); n = 0; while(n Dat->BUFSIZE) n = Dat->BUFSIZE; t.file.buf.read(q0, r, 0, n); b.puts(r.s[0:n]); q0 += n; } } if(w.dumpstr != nil){ if(w.dumpdir != nil) b.puts(sprint("%s\n%s\n", w.dumpdir, w.dumpstr)); else b.puts(sprint("\n%s\n", w.dumpstr)); } } } b.close(); b = nil; strfree(r); r = nil; } rdline(b : ref Iobuf, line : int) : (int, string) { l : string; l = b.gets('\n'); if(l != nil) line++; return (line, l); } Row.loadx(row : self ref Row, file : string, initing : int) { i, j, line, percent, y, nr, nfontr, n, ns, ndumped, dumpid, x : int; b, bout : ref Iobuf; fontname : string; l, buf, t : string; rune : int; r, fontr : string; c, c1, c2 : ref Column; q0, q1 : int; r1, r2 : Rect; w : ref Window; e := ref sys->Exception; if (sys->rescue("*", e) == Sys->EXCEPTION){ sys->rescued(Sys->ONCE, ""); return; } if(file == nil){ if(home == nil){ warning(nil, "can't find file for load: $home not defined\n"); sys->raise(""); } buf = sprint("%s/acme.dump", home); file = buf; } b = bufio->open(file, Bufio->OREAD); if(b == nil){ warning(nil, sprint("can't open load file %s: %r\n", file)); sys->raise(""); } f := ref sys->Exception; if (sys->rescue("*", f) == Sys->EXCEPTION){ sys->rescued(Sys->ONCE, ""); warning(nil, sprint("bad load file %s:%d\n", file, line)); b.close(); # sys->rescued(Sys->ONCE, ""); sys->raise(""); } # current directory (line, l) = rdline(b, 0); if(l == nil) sys->raise(""); l = l[0:len l - 1]; if(sys->chdir(l) < 0){ warning(nil, sprint("can't chdir %s\n", l)); b.close(); return; } # global fonts for(i=0; i<2; i++){ (line, l) = rdline(b, line); if(l == nil) sys->raise(""); l = l[0:len l -1]; if(l != nil && l != fontnames[i]) Reffont.get(i, TRUE, i==0 && initing, l); } if(initing && row.ncol==0) row.init(mainwin.clipr); (line, l) = rdline(b, line); if(l == nil) sys->raise(""); j = len l/12; if(j<=0 || j>10) sys->raise(""); for(i=0; i=100) sys->raise(""); x = row.r.min.x+percent*row.r.dx()/100; if(i < row.ncol){ if(i == 0) continue; c1 = row.col[i-1]; c2 = row.col[i]; r1 = c1.r; r2 = c2.r; r1.max.x = x; r2.min.x = x+Border; if(r1.dx() < 50 || r2.dx() < 50) continue; draw(mainwin, (r1.min, r2.max), white, nil, (0, 0)); c1.reshape(r1); c2.reshape(r2); r2.min.x = x; r2.max.x = x+Border; draw(mainwin, r2, black, nil, (0, 0)); } if(i >= row.ncol) row.add(nil, x); } for(;;){ (line, l) = rdline(b, line); if(l == nil) break; dumpid = 0; case(l[0]){ 'e' => if(len l < 1+5*12+1) sys->raise(""); (line, l) = rdline(b, line); # ctl line; ignored if(l == nil) sys->raise(""); (line, l) = rdline(b, line); # directory if(l == nil) sys->raise(""); l = l[0:len l -1]; if(len l != 0) r = l; else{ if(home == nil) r = "./"; else r = home+"/"; } nr = len r; (line, l) = rdline(b, line); # command if(l == nil) sys->raise(""); t = l[0:len l -1]; spawn exec->run(nil, t, r, nr, TRUE, nil, nil, FALSE); # r is freed in run() continue; 'f' => if(len l < 1+5*12+1) sys->raise(""); fontname = l[1+5*12:len l - 1]; ndumped = -1; 'F' => if(len l < 1+6*12+1) sys->raise(""); fontname = l[1+6*12:len l - 1]; ndumped = int l[1+5*12:1+5*12+11]; 'x' => if(len l < 1+5*12+1) sys->raise(""); fontname = l[1+5*12: len l - 1]; ndumped = -1; dumpid = int l[1+1*12:1+1*12+11]; * => sys->raise(""); } l = l[0:len l -1]; if(len fontname != 0) { fontr = fontname; nfontr = len fontname; } else (fontr, nfontr) = (nil, 0); i = int l[1+0*12:1+0*12+11]; j = int l[1+1*12:1+1*12+11]; q0 = int l[1+2*12:1+2*12+11]; q1 = int l[1+3*12:1+3*12+11]; percent = int l[1+4*12:1+4*12+11]; if(i<0 || i>10) sys->raise(""); if(i > row.ncol) i = row.ncol; c = row.col[i]; y = c.r.min.y+(percent*c.r.dy())/100; if(y=c.r.max.y) y = -1; if(dumpid == 0) w = c.add(nil, nil, y); else w = c.add(nil, look->lookid(dumpid, TRUE), y); if(w == nil) continue; w.dumpid = j; (line, l) = rdline(b, line); if(l == nil) sys->raise(""); l = l[0:len l - 1]; r = l[5*12:len l]; nr = len r; ns = -1; for(n=0; n= 0){ # simplest thing is to put it in a file and load that buf = sprint("/tmp/d%d.%.4sacme", sys->pctl(0, nil), utils->getuser()); bout = bufio->create(buf, Bufio->OWRITE, 8r600); if(bout == nil){ warning(nil, "can't create temp file: %r\n"); b.close(); return; } for(n=0; nEOF){ bout.close(); bout = nil; sys->raise(""); } bout.putc(rune); } bout.close(); bout = nil; w.body.loadx(0, buf, 1); w.body.file.mod = TRUE; for(n=0; nremove(buf); buf = nil; }else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-') exec->get(w.body, nil, nil, FALSE, nil, 0); l = r = nil; if(fontr != nil){ exec->fontx(w.body, nil, nil, fontr, nfontr); fontr = nil; } if(q0>w.body.file.buf.nc || q1>w.body.file.buf.nc || q0>q1) q0 = q1 = 0; w.body.show(q0, q1); w.maxlines = min(w.body.frame.nlines, max(w.maxlines, w.body.frame.maxlines)); } b.close(); } allwindows(o: int, aw: ref Dat->Allwin) { for(i:=0; i pick k := aw{ LP => ecmd->alllooper(w, k.lp); } ALLTOFILE => pick k := aw{ FF => ecmd->alltofile(w, k.ff); } ALLMATCHFILE => pick k := aw{ FF => ecmd->allmatchfile(w, k.ff); } ALLFILECHECK => pick k := aw{ FC => ecmd->allfilecheck(w, k.fc); } ALLELOGTERM => edit->allelogterm(w); ALLEDITINIT => edit->alleditinit(w); ALLUPDATE => edit->allupdate(w); } } } }