shithub: nc

Download patch

ref: 3b70917596e5536fb49d87097c8d80259cf552e8
parent: a037d9d936d8e2e75a7d951d02784f6ea472e1cc
author: phil9 <telephil9@gmail.com>
date: Mon Dec 26 05:07:16 EST 2022

add alert dialog and use it to report errors

	design could be improved :/

--- a/a.h
+++ b/a.h
@@ -137,6 +137,8 @@
 
 int			match(char*, char*);
 
+void		alert(const char*, const char*, const char*, Mousectl*, Keyboardctl*);
+
 Rectangle	boundsrect(Rectangle);
 Image*		ealloccolor(ulong);
 void*		emalloc(ulong);
@@ -161,6 +163,7 @@
 	Ctitle,
 	Cborder,
 	Csel,
+	Cdialog,
 	Ncols
 };
 extern Image*		cols[Ncols];
--- /dev/null
+++ b/alert.c
@@ -1,0 +1,96 @@
+#include "a.h"
+
+enum { Padding = 8, };
+
+static
+int
+max(int a, int b)
+{
+	return a>b ? a : b;
+}
+
+void
+alert(const char *title, const char *message, const char *err, Mousectl *mctl, Keyboardctl *kctl)
+{
+	Alt alts[3];
+	Rectangle r, sc;
+	Point o, p;
+	Image *b, *save, *bg, *fg;
+	int done, h, w, tw, mw, ew;
+	Mouse m;
+	Rune k;
+
+	alts[0].op = CHANRCV;
+	alts[0].c  = mctl->c;
+	alts[0].v  = &m;
+	alts[1].op = CHANRCV;
+	alts[1].c  = kctl->c;
+	alts[1].v  = &k;
+	alts[2].op = CHANEND;
+	alts[2].c  = nil;
+	alts[2].v  = nil;
+	while(nbrecv(kctl->c, nil)==1)
+		;
+	bg = cols[Cdialog];
+	fg = cols[Cfg];
+	done = 0;
+	save = nil;
+	h = Padding+2*font->height+Padding;
+	if(err != nil)
+		h += font->height;
+	tw = stringwidth(font, title);
+	mw = stringwidth(font, message);
+	ew = err != nil ? stringwidth(font, err) : 0;
+	w = Padding+max(tw, max(mw, ew))+Padding;
+	b = screen;
+	sc = b->clipr;
+	replclipr(b, 0, b->r);
+	while(!done){
+		o = addpt(screen->r.min, Pt((Dx(screen->r)-w)/2, (Dy(screen->r)-h)/2));
+		r = Rect(o.x, o.y, o.x+w, o.y+h);
+		if(save==nil){
+			save = allocimage(display, r, b->chan, 0, DNofill);
+			if(save==nil)
+				break;
+			draw(save, r, b, nil, r.min);
+		}
+		draw(b, r, bg, nil, ZP);
+		border(b, r, 3, fg, ZP);
+		p = addpt(o, Pt(Padding, Padding));
+		string(b, p, fg, ZP, font, title);
+		p.y += font->height;
+		string(b, p, fg, ZP, font, message);
+		if(err != nil){
+			p.x = o.x + Padding;
+			p.y += font->height;
+			string(b, p, fg, ZP, font, err);
+		}
+		flushimage(display, 1);
+		if(b!=screen || !eqrect(screen->clipr, sc)){
+			freeimage(save);
+			save = nil;
+		}
+		b = screen;
+		sc = b->clipr;
+		replclipr(b, 0, b->r);
+		switch(alt(alts)){
+		default:
+			continue;
+			break;
+		case 1:
+			done = (k=='\n' || k==Kesc);
+			break;
+		case 0:
+			done = m.buttons&1 && ptinrect(m.xy, r);
+			break;
+		}
+		if(save){
+			draw(b, save->r, save, nil, save->r.min);
+			freeimage(save);
+			save = nil;
+		}
+			
+	}
+	replclipr(b, 0, sc);
+	flushimage(display, 1);
+}
--- a/dirviewcmd.c
+++ b/dirviewcmd.c
@@ -58,12 +58,16 @@
 {
 	Dirpanel *p;
 	Dir d, null;
-	char opath[1024] = {0}, buf[255] = {0};
+	char errbuf[ERRMAX], opath[1024] = {0}, buf[255] = {0};
 	int n;
 
 	p = dirviewcurrentpanel(dview);
 	if(strcmp(p->model->path, dirviewotherpanel(dview)->model->path) == 0){
 		d = dirmodelgetdir(p->model, dirpanelselectedindex(p));
+		if(d.qid.type&QTDIR){
+			alert("Error", "Cannot rename directories.", nil, mc, kc);
+			return;
+		}
 		snprint(buf, sizeof buf, d.name);
 		if((n = enter("rename:", buf, sizeof buf, mc, kc, nil)) <= 0)
 			return;
@@ -72,9 +76,10 @@
 		snprint(opath, sizeof opath, "%s/%s", p->model->path, d.name);
 		nulldir(&null);
 		null.name = buf;
-		if(dirwstat(opath, &null) < 0)
-			fprint(2, "rename failed: %r\n");
-		else{
+		if(dirwstat(opath, &null) < 0){
+			errstr(errbuf, ERRMAX-1);
+			alert("Error", "Rename failed", errbuf, mc, kc);
+		}else{
 			dirmodelreload(p->model);
 			dirmodelreload(dirviewotherpanel(dview)->model);
 		}			
--- a/main.c
+++ b/main.c
@@ -21,6 +21,7 @@
 	cols[Ctitle] = ealloccolor(DGreygreen);
 	cols[Cborder] = ealloccolor(0xAAAAAAFF);
 	cols[Csel] = ealloccolor(0xCCCCCCFF);
+	cols[Cdialog] = ealloccolor(0xF4F4F4FF);
 }
 
 void
--- a/mkfile
+++ b/mkfile
@@ -12,6 +12,7 @@
 	dirpanel.$O		\
 	viewercmd.$O	\
 	text.$O			\
+	alert.$O		\
 	glob.$O			\
 	utils.$O