forsyth20121205-174063a80cc13 years agoHistory
1178 lines · 32.4 KB · Brainfuck
RawDownload
implement Browser; ## Copyright © 2003 Vita Nuova Holdings Limited.  All rights reserved.# include "sys.m";	sys : Sys;include "draw.m";	draw: Draw;	Rect: import draw;include "tk.m";	tk: Tk;include "tkclient.m";	tkclient: Tkclient;include "./pathreader.m";include "./browser.m"; entryheight := ""; init(){	sys = load Sys Sys->PATH;	if (sys == nil)		badmod(Sys->PATH);	draw = load Draw Draw->PATH;	if (draw == nil)		badmod(Draw->PATH);	tk = load Tk Tk->PATH;	if (tk == nil)		badmod(Tk->PATH);	tkclient = load Tkclient Tkclient->PATH;	if (tkclient == nil)		badmod(Tkclient->PATH);	tkclient->init();} Browse.new(top: ref Tk->Toplevel, tkchanname, root, rlabel: string, nopanes: int, reader: PathReader): ref Browse{	b : Browse;	b.top = top;	b.tkchan = tkchanname;	if (nopanes < 1 || nopanes > 2)		return nil;	b.nopanes = 2;	b.bgnorm = bgnorm;	b.bgselect = bgselect;	b.selected = array[2] of { * => Selected (File(nil, nil), nil) };	b.opened = (root, nil) :: nil;	if (root == nil)		return nil;	if (root[len root - 1] != '/')		root[len root] = '/';	b.pane0width = "2 3";	b.root = root;	b.rlabel = rlabel;	b.reader = reader;	b.pane1 = File (nil, "-123");	b.released = 1;	tkcmds(top, pane0scr); 	tkcmds(top, pane1scr);	tkcmd(top, "bind .fbrowse.lmov <Button-1> {send "+b.tkchan+" movdiv %X}"); 	size := tkcmd(top, "grid size .fbrowse");	p := isat(size, " ");	tkcmd(top, "label .fbrowse.l -text { }  -anchor w -width 0" +		" -font /fonts/charon/plain.normal.font");	tkcmd(top, ".fbrowse.l configure -height "+tkcmd(top, ".fbrowse.l cget -height"));	tkcmd(top, "grid .fbrowse.l -row 0 -column 0 -sticky ew -pady 2 -columnspan 4");	rb := ref b;	rb.newroot(b.root, b.rlabel);	rb.changeview(nopanes);	setbrowsescrollr(rb);	return rb;} Browse.refresh(b: self ref Browse){	scrval := tkcmd(b.top, ".fbrowse.sy1 get");	p := isat(scrval, " ");	p1 := b.pane1;	b.newroot(b.root, b.rlabel);	setbrowsescrollr(b);	if (b.nopanes == 2)		popdirpane1(b, p1);	b.selectfile(1,DESELECT, File (nil, nil), nil);	b.selectfile(0,DESELECT, File (nil, nil), nil);	tkcmd(b.top, ".fbrowse.c1 yview moveto "+scrval[:p]+"; update");} bgnorm := "white";bgselect := "#5555FF"; ft := " -font /fonts/charon/plain.normal.font";fts := " -font /fonts/charon/plain.tiny.font";ftb := " -font /fonts/charon/bold.normal.font"; Browse.gotoselectfile(b: self ref Browse, file: File): string{	(dir, tkpath) := b.gotopath(file, 0);	if (tkpath == nil)		return nil;	# Select dir	tkpath += ".l";	if (dir.qid != nil)		tkpath += "Q" + dir.qid;	b.selectfile(0, SELECT, dir, tkpath); 	# If it is a file, select the file too	if (!File.eq(file, dir)) {		slaves := tkcmd(b.top, "grid slaves .fbrowse.fl2");		(nil, lst) := sys->tokenize(slaves, " ");		for (; lst != nil; lst = tl lst) {			if (File.eq(file, *b.getpath(hd lst))) {				b.selectfile(1, SELECT, file, hd lst);				tkpath = hd lst;				break;			}		}		pane1see(b);	}	return tkpath;} pane1see(b: ref Browse){	f := b.selected[1].tkpath;	if (f == "")		return;	x1 := int tkcmd(b.top, f+" cget -actx") - int tkcmd(b.top, ".fbrowse.fl2 cget -actx");	y1 := int tkcmd(b.top, f+" cget -acty") - int tkcmd(b.top, ".fbrowse.fl2 cget -acty");	x2 := x1 + int tkcmd(b.top, f+" cget -actwidth");	y2 := y1 + int tkcmd(b.top, f+" cget -actheight");	tkcmd(b.top, sys->sprint(".fbrowse.c2 see %d %d %d %d", x1,y1,x2,y2));} Browse.opendir(b: self ref Browse, file: File, tkpath: string, action: int): int{	curr := tkcmd(b.top, tkpath+".lp cget -text");	if ((action == OPEN || action == TOGGLE) && curr == "+") {		tkcmd(b.top, tkpath+".lp configure -text {-} -relief sunken");		popdirpane0(b, file, tkpath);		seeframe(b.top, tkpath);		b.addopened(file, 1);		setbrowsescrollr(b);		return 1;	}	else if ((action == CLOSE || action == TOGGLE) && curr == "-") {		tkcmd(b.top, tkpath+".lp configure -text {+} -relief raised");		slaves := tkcmd(b.top, "grid slaves "+tkpath+" -column 1");		p := isat(slaves, " ");		if (p != -1)			tkcmd(b.top, "destroy "+slaves[p:]);		slaves = tkcmd(b.top, "grid slaves "+tkpath+" -column 2");		if (slaves != "")			tkcmd(b.top, "destroy "+slaves);		b.addopened(file, 0);		setbrowsescrollr(b);		return 1;	}	return 0;} Browse.addopened(b: self ref Browse, file: File, add: int){	tmp : list of File = nil;	for (; b.opened != nil; b.opened = tl b.opened) {		dir := hd b.opened;		if (!File.eq(file, dir))			tmp = dir :: tmp;	}	if (add)		tmp = file :: tmp;	b.opened = tmp;} Browse.changeview(b: self ref Browse, nopanes: int){	if (b.nopanes == nopanes)		return;	w := int tkcmd(b.top, ".fbrowse cget -actwidth");	ws := int tkcmd(b.top, ".fbrowse.sy1 cget -width");	if (nopanes == 1) {		b.pane0width = tkcmd(b.top, ".fbrowse.c1 cget -actwidth") + " " +						tkcmd(b.top, ".fbrowse.c2 cget -actwidth");		tkcmd(b.top, "grid forget .fbrowse.sx2 .fbrowse.c2 .fbrowse.lmov");		tkcmd(b.top, "grid columnconfigure .fbrowse 3 -weight 0");	}	else {		(nil, wlist) := sys->tokenize(b.pane0width, " ");		tkcmd(b.top, "grid columnconfigure .fbrowse 1 -weight "+hd wlist);		tkcmd(b.top, "grid columnconfigure .fbrowse 3 -weight "+hd tl wlist); 		tkcmd(b.top, "grid .fbrowse.sx2 -row 3 -column 3 -sticky ew");		tkcmd(b.top, "grid .fbrowse.c2 -row 2 -column 3 -sticky nsew");		tkcmd(b.top, "grid .fbrowse.lmov -row 2 -column 2 -rowspan 2 -sticky ns");	}	b.nopanes = nopanes;} Browse.selectfile(b: self ref Browse, pane, action: int, file: File, tkpath: string){	if (action == SELECT && b.selected[pane].tkpath == tkpath)		return;	if (b.selected[pane].tkpath != nil)		tk->cmd(b.top, b.selected[pane].tkpath+" configure -bg "+bgnorm);	if ((action == TOGGLE && b.selected[pane].tkpath == tkpath) || action == DESELECT) {		if (pane == 0)			popdirpane1(b, File (nil,nil));		b.selected[pane] = (File(nil, nil), nil);		return;	}	b.selected[pane] = (file, tkpath);	tkcmd(b.top, tkpath+" configure -bg "+bgselect);	if (pane == 0)		popdirpane1(b, file);} Browse.resize(b: self ref Browse){ 	p1 := b.pane1; 	b.pane1 = File (nil, nil);  	if (p1.path != "") 		popdirpane1(b, p1); 	if (b.selected[1].tkpath != nil) {		s := b.selected[1];		b.selectfile(1, DESELECT, s.file, s.tkpath);		b.selectfile(1, SELECT, s.file, s.tkpath);	}} setbrowsescrollr(b: ref Browse){	h := tkcmd(b.top, ".fbrowse.fl cget -height");	w := tkcmd(b.top, ".fbrowse.fl cget -width");	tkcmd(b.top, ".fbrowse.c1 configure -scrollregion {0 0 "+w+" "+h+"}");	if (b.nopanes == 2) {		h = tkcmd(b.top, ".fbrowse.fl2 cget -height");		w = tkcmd(b.top, ".fbrowse.fl2 cget -width");		tkcmd(b.top, ".fbrowse.c2 configure -scrollregion {0 0 "+w+" "+h+"}");	}} seeframe(top: ref Tk->Toplevel, frame: string){	x := int tkcmd(top, frame+" cget -actx") - int tkcmd(top, ".fbrowse.fl cget -actx");	y := int tkcmd(top, frame+" cget -acty")  - int tkcmd(top, ".fbrowse.fl cget -acty");	w := int tkcmd(top, frame+" cget -width");	h := int tkcmd(top, frame+" cget -height");	wc := int tkcmd(top, ".fbrowse.c1 cget -width");	hc := int tkcmd(top, ".fbrowse.c1 cget -height");	if (w > wc)		w = wc;	if (h > hc)		h = hc;	tkcmd(top, sys->sprint(".fbrowse.c1 see %d %d %d %d",x,y,x+w,y+h));} # Goes to selected dir OR dir containing selected fileBrowse.gotopath(b: self ref Browse, file: File, openfinal: int): (File, string){	tkpath := ".fbrowse.fl.f0";	path := b.root;	testqid := "";	testpath := "";	close : list of string;	trackbacklist : list of (string, list of string, list of string) = nil;	trackback := 0;	enddir := "";	endfile := "";	filetkpath := "";	if (file.path[len file.path - 1] != '/') {		# i.e. is not a directory		p := isatback(file.path, "/");		enddir = file.path[:p + 1];	}	if (enddir == path) {		if (!dircontainsfile(b, File (path, nil), file))			return (File (nil, nil), nil);	}	else {		for(;;) {			lst : list of string;			if (trackback) {				(path, lst, close) = hd trackbacklist;				trackbacklist = tl trackbacklist;				if (close != nil)					b.opendir(File (hd close, hd tl close), hd tl tl close, CLOSE);				trackback = 0;			}			else {				frames := tkcmd(b.top, "grid slaves "+tkpath+" -column 1");				(nil, lst) = sys->tokenize(frames, " ");				if (lst != nil)					lst = tl lst; # ignore first frame (name of parent dir);			}			found := 0;			hasdups := 1;			for (; lst != nil; lst = tl lst) {				testpath = path;				if (hasdups) {					labels := tkcmd(b.top, "grid slaves "+hd lst+" -row 0");					(nil, lst2) := sys->tokenize(labels, " ");					testpath += tkcmd(b.top, hd tl lst2+" cget -text") + "/";					testqid = getqidfromlabel(hd tl lst2);					if (testqid == nil)						hasdups = 0;				}				else					testpath += tkcmd(b.top, hd lst+".l cget -text") + "/";				if (len testpath <= len file.path && file.path[:len testpath] == testpath) {					opened := 0;					close = nil;					if (openfinal || testpath != file.path)						opened = b.opendir(File(testpath, testqid), hd lst, OPEN);					if (opened)						close = testpath :: testqid :: hd lst :: nil;					if (tl lst != nil && hasdups)						trackbacklist = (path, tl lst, close) :: trackbacklist;					tkpath = hd lst;					path = testpath;					found = 1;					break;				}			}			if (enddir != nil && path == enddir)				if (dircontainsfile(b, File(testpath, testqid), file))					break;			if (!found) {				if (trackbacklist == nil)					return (File (nil, nil), nil);				trackback = 1;			}			else if (testpath == file.path && testqid == file.qid)				break;		}	}	seeframe(b.top, tkpath);	dir := File (path, testqid);	popdirpane1(b, dir);	return (dir, tkpath);} dircontainsfile(b: ref Browse, dir, file: File): int{	(files, hasdups) := b.reader->readpath(dir);	for (j := 0; j < len files; j++) {							if (files[j].name == file.path[len dir.path:] && 				(!hasdups || files[j].qid.path == big file.qid))			return 1;	}	return 0;} Browse.getpath(b: self ref Browse, f: string): ref File{	if (len f < 11 || f[:11] != ".fbrowse.fl")		return nil;	(nil, lst) := sys->tokenize(f, ".");	lst = tl lst;	if (hd lst == "fl2") {		# i.e. is in pane 1		qid := getqidfromlabel(f);		return ref File (b.pane1.path + tk->cmd(b.top, f+" cget -text"), qid);	}	tkpath := ".fbrowse.fl.f0";	path := b.root;	lst = tl tl lst;	started := 0;#	sys->print("getpath: %s %s\n",tkpath, path);	qid := "";	for (; lst != nil; lst = tl lst) {		tkpath += "."+hd lst;		if ((hd lst)[0] == 'l') {			qid = getqidfromlabel(tkpath);			if (qid != nil)				qid = "Q" + qid;			if (len hd lst - len qid > 1)				path += tk->cmd(b.top, tkpath+" cget -text");		}		else if ((hd lst)[0] == 'f') {			qid = getqidfromframe(b,tkpath);			if (qid != nil)				qid = "Q"+qid;			path += tk->cmd(b.top, tkpath+".l"+qid+" cget -text") + "/";		}#		sys->print("getpath: %s %s\n",tkpath, path);	}	# Temporary hack!	if (qid != nil)		qid = qid[1:];	return ref File (path, qid);} setroot(b: ref Browse, rlabel, root: string){	b.root = root;	b.rlabel = rlabel;	makedir(b, File (root, nil), ".fbrowse.fl.f0", rlabel, "0");	tkcmd(b.top, "grid forget .fbrowse.fl.f0.lp");} getqidfromframe(b: ref Browse, frame: string): string{	tmp := tkcmd(b.top, "grid slaves "+frame+" -row 0");	(nil, lst) := sys->tokenize(tmp, " \t\n");	if (lst == nil)		return nil;	return getqidfromlabel(hd tl lst);} getqidfromlabel(label: string): string{	p := isatback(label, "Q");	if (p != -1)		return label[p+1:];	return nil;} popdirpane0(b: ref Browse, dir : File, frame: string){	(dirs, hasdups) := b.reader->readpath(dir);	for (i := 0; i < len dirs; i++) {		si := string i;		f : string;		dirqid := string dirs[i].qid.path;		if (!hasdups)			dirqid = nil;		if (dirs[i].mode & sys->DMDIR) {			f = frame + ".f"+si;			makedir(b, File (dir.path+dirs[i].name, dirqid), f, dirs[i].name, string (i+1));		}		else {			if (b.nopanes == 1) {				f = frame + ".l"+si;				makefile(b, f, dirs[i].name, string (i+1), dirqid);			}		}	}	dirs = nil;} isopened(b: ref Browse, dir: File): int{	for (tmp := b.opened; tmp != nil; tmp = tl tmp) {		if (File.eq(hd tmp, dir))			return 1;	}	return 0;} makefile(b: ref Browse, f, name, row, qid: string){	if (qid != nil)		f += "Q" + qid;	bgcol := bgnorm;#	if (f == selected[0].t1)#		bgcol = bgselect;	p := isat(name, "\0");	if (p != -1) {		tkcmd(b.top, "label "+f+" -text {"+name[:p]+"} -bg "+bgcol+ft);		tkcmd(b.top, "label "+f+"b -text {"+name[p+1:]+"} -bg "+bgcol+ft);		tkcmd(b.top, "grid "+f+" -row "+row+" -column 1 -sticky w -padx 5 -pady 2");		tkcmd(b.top, "grid "+f+"b -row "+row+" -column 2 -sticky w -pady 2");		tkcmd(b.top, "bind "+f+" <Button-2> {send "+b.tkchan+" but2pane1 "+f+"}");		tkcmd(b.top, "bind "+f+" <ButtonRelease-2> {send "+b.tkchan+" release}");	}	else {		tkcmd(b.top, "label "+f+" -text {"+name+"} -bg "+bgcol+ft);		tkcmd(b.top, "grid "+f+" -row "+row+" -column 1 -sticky w -padx 5 -pady 2");	}	tkcmd(b.top, "bind "+f+" <Button-1> {send "+b.tkchan+" but1pane0 "+f+"}");	tkcmd(b.top, "bind "+f+" <ButtonRelease-1> {send "+b.tkchan+" release}");	tkcmd(b.top, "bind "+f+" <Button-2> {send "+b.tkchan+" but2pane0 "+f+"}");	tkcmd(b.top, "bind "+f+" <ButtonRelease-2> {send "+b.tkchan+" release}");	tkcmd(b.top, "bind "+f+" <Button-3> {send "+b.tkchan+" but3pane0 "+f+"}");	tkcmd(b.top, "bind "+f+" <ButtonRelease-3> {send "+b.tkchan+" release}");} Browse.defaultaction(b: self ref Browse, lst: list of string, rfile: ref File){	tkpath: string;	file: File;	if (len lst > 1) {		tkpath = hd tl lst;		if (len tkpath > 11 && tkpath[:11] == ".fbrowse.fl") {			if (rfile == nil)				file = *b.getpath(tkpath);			else				file = *rfile;		}	}	case hd lst {		"release" =>			b.released = 1;		"open" or "double1pane0" =>			if (file.path == b.root)

Lines 1–500 of 1178.