d382391997-10-29Per Hedbor /* $Id: wizard.pike,v 1.42 1997/10/29 14:27:19 per Exp $
2da8471997-08-20Per Hedbor  * name="Wizard generator";
fc94331997-10-25Per Hedbor  * doc="This file generats all the nice wizards";
2da8471997-08-20Per Hedbor  */ inherit "roxenlib";
fc94331997-10-25Per Hedbor string wizard_tag_var(string n, mapping m, mixed a, mixed b)
2da8471997-08-20Per Hedbor {
fc94331997-10-25Per Hedbor  object id; if(n=="cvar") // Container. Default value in 'a', id in 'b'. { id = b; m["default"] = a; } else // tag. No contents, id in 'b'. id = a;
2da8471997-08-20Per Hedbor  string current = id->variables[m->name] || m["default"];
2ebb571997-08-21Per Hedbor 
2da8471997-08-20Per Hedbor  switch(m->type) { default: // String.... m->type = "string"; m_delete(m,"default"); m->value = current||"";
78d67d1997-08-20Per Hedbor  if(!m->size)m->size="60,1";
2da8471997-08-20Per Hedbor  return make_tag("input", m);
6796b01997-08-20Per Hedbor  case "list": // String.... string n = m->name, res="<table cellpadding=0 cellspacing=0 border=0>"; if(!id->variables[n]) id->variables[n]=current; m->type = "string"; if(!m->size)m->size="60,1"; m_delete(m,"default"); foreach((current||"")/"\0"-({""}), string v) { res+="<tr><td>"+v+"</td><td><font size=-2>"; m->name="_delete_"+n+":"+v; m->value = " Remove "; m->type = "submit"; res+=make_tag("input",m)+"</td></tr>"; } m->name = "_new_"+n; m->type = "string"; m->value = ""; res+= "<tr><td>"+make_tag("input", m)+"</td><td><font size=-2>"; m->name="_Add"; m->value = " Add "; m->type = "submit"; res+=make_tag("input",m)+"</font></td></tr>"; res+="</table>"; return res;
78d67d1997-08-20Per Hedbor  case "text": m_delete(m,"type"); m_delete(m,"default");
d382391997-10-29Per Hedbor  m_delete(m, "value");
75ebae1997-08-20Per Hedbor  if(!m->rows)m->rows="6"; if(!m->cols)m->cols="40";
57bd8f1997-08-20Per Hedbor  return make_container("textarea", m, html_encode_string(current||""));
78d67d1997-08-20Per Hedbor 
9cc6771997-08-20Fredrik Noring  case "radio": m_delete(m,"default"); return make_tag("input "+((!id->variables[m->name] && current) || (current==m->value)?" checked":""), m); case "checkbox":
2ebb571997-08-21Per Hedbor  string res;
9cc6771997-08-20Fredrik Noring  m_delete(m,"default"); m_delete(m, m->name); m_delete(id->variables, m->name);
e3e8441997-08-22Per Hedbor  if(current && current!="0") m->checked="checked";
2ebb571997-08-21Per Hedbor  res=make_tag("input", m); m->type="hidden"; m->value="0"; return res+make_tag("input", m);
78d67d1997-08-20Per Hedbor 
2da8471997-08-20Per Hedbor  case "int": m->type = "number"; m_delete(m,"default");
78d67d1997-08-20Per Hedbor  m->value = (string)((int)current); if(!m->size)m->size="8,1"; return make_tag("input", m); case "float": m->type = "number"; m_delete(m,"default"); m->value = (string)((float)current); if(!m->size)m->size="14,1";
2da8471997-08-20Per Hedbor  return make_tag("input", m);
fc94331997-10-25Per Hedbor  case "color": int h, s, v; if(id->variables[m->name+".hsv"]) sscanf(id->variables[m->name+".hsv"], "%d,%d,%d", h, s, v); else { array tmp = rgb_to_hsv(@parse_color(current||"black")); h = tmp[0]; s = tmp[1]; v = tmp[2]; } if(id->variables[m->name+".entered"] && strlen(current=id->variables[m->name+".entered"])) { array tmp = rgb_to_hsv(@parse_color(current||"black")); h = tmp[0]; s = tmp[1]; v = tmp[2]; } if(id->variables["foo.x"]) h=(int)id->variables["foo.x"]; if(id->variables["bar.y"]) s=255-(int)id->variables["bar.y"]; if(id->variables["foo.y"]) v=255-(int)id->variables["foo.y"]; m_delete(id->variables, "foo.x"); m_delete(id->variables, "foo.y"); m_delete(id->variables, "bar.x"); m_delete(id->variables, "bar.y"); id->variables[m->name+".hsv"] = h+","+s+","+v; array a=hsv_to_rgb(h,s,v); string bgcol=sprintf("#%02x%02x%02x",a[0],a[1],a[2]); id->variables[m->name] = bgcol; return ("<table><tr>\n" "<td width=258 rowspan=2>\n" " <table bgcolor=black cellpadding=1 border=0 cellspacing=0 width=258><tr><td>\n" " <input type=image name=foo src=/internal-roxen-colsel width=256 height=256 border=0></a>\n" " </td></table>\n" "</td>\n" "<td width=30 rowspan=2></td>\n" "<td width=32 rowspan=2>\n" " <table bgcolor=black cellpadding=1 border=0 cellspacing=0 width=32><tr><td>\n" "<input type=image src=\"/internal-roxen-colorbar:"+ (string)h+","+(string)v+","+(string)s+"\" " "name=bar width=30 height=256 border=0></a>" "</td></table>\n" "</td>\n" "<td width=32 rowspan=2></td>\n" "<td width=120>\n" " <table bgcolor=black cellpadding=1 border=3 cellspacing=0 width=90>\n" " <tr><td height=90 width=90 bgcolor="+bgcol+">&nbsp;"+ (m->tt?"<font color='"+m->tc+"'>"+m->tt+"</font>":"") +"</td></table>\n" "</td><tr>\n" "<td width=120>\n" "<b>R:</b> "+(string)a[0]+"<br>\n" "<b>G:</b> "+(string)a[1]+"<br>\n" "<b>B:</b> "+(string)a[2]+"<br>\n" "<hr size=2 align=left noshade width=70>\n" "<b>H:</b> "+(string)h+"<br>\n" "<b>S:</b> "+(string)s+"<br>\n" "<b>V:</b> "+(string)v+"<br>\n" "<hr size=2 align=left noshade width=70>\n"+ "<font size=-1><input type=string name="+ m->name+".entered size=8 value='"+ color_name(a)+"'></font></td></table>\n"); case "font": string res=""; m->type = "select"; m->choices = roxen->available_fonts(1)*","; if(id->conf && id->conf->modules["graphic_text"]) res = ("<input type=submit value='Example'><br>"+ ((current&&strlen(current))? "<gtext nfont='"+current+"'>Example Text</gtext><br>" :"")); return make_tag("var", m)+res;
2da8471997-08-20Per Hedbor  case "toggle": m_delete(m,"default"); return make_container("select", m, "<option"+((int)current?" selected":"")+" value=1>Yes" "<option"+(!(int)current?" selected":"")+" value=0>No"); case "select":
fc94331997-10-25Per Hedbor  if(!m->choices && m->options) m->choices = m->options; m_delete(m,"default"); m_delete(m,"type"); mapping m2 = copy_value(m); m_delete(m2, "choices"); m_delete(m2, "options"); return make_container("select", m2, Array.map(m->choices/",", lambda(string s, string c) {
d382391997-10-29Per Hedbor  string t; if(sscanf(s, "%s:%s", s, t) != 2) t = s; return "<option value='"+s+"' "+(s==c?" selected":"")+">"+html_encode_string(t)+"\n";
fc94331997-10-25Per Hedbor  },current)*"");
2da8471997-08-20Per Hedbor  case "select_multiple":
fc94331997-10-25Per Hedbor  if(!m->choices && m->options) m->choices = m->options;
2da8471997-08-20Per Hedbor  m_delete(m,"default"); m_delete(m,"type");
fc94331997-10-25Per Hedbor  m2 = copy_value(m); m_delete(m2, "choices"); m_delete(m2, "options"); m2->multiple="1"; return make_container("select", m2, Array.map(m->choices/",",
d382391997-10-29Per Hedbor  lambda(string s, array c) { string t; if(sscanf(s, "%s:%s", s, t) != 2) t = s; return "<option value='"+s+"' "+(search(c,s)!=-1?"selected":"")+">"+html_encode_string(t)+"\n";
fc94331997-10-25Per Hedbor  },(current||"")/"\0")*"");
2da8471997-08-20Per Hedbor  } } mapping decompress_state(string from) { if(!from) return ([]); from = MIME.decode_base64(from); catch { object gz = Gz; if(sizeof(indices(gz))) from = gz->inflate()->inflate(from); }; return decode_value(from); } string compress_state(mapping state) { state = copy_value(state); m_delete(state,"_state"); m_delete(state,"next_page"); m_delete(state,"prev_page"); m_delete(state,"help"); m_delete(state,"action"); m_delete(state,"unique"); m_delete(state,"help");
2ebb571997-08-21Per Hedbor // werror(sprintf("State=%O\n", state));
2da8471997-08-20Per Hedbor  string from = encode_value(state); object gz = Gz; if(sizeof(indices(gz))) { string from2 = gz->deflate()->deflate(from); if(strlen(from2)<strlen(from)) from=from2; } return MIME.encode_base64( from ); }
0582051997-08-20Per Hedbor string parse_wizard_help(string t, mapping m, string contents, object id, mapping v)
2da8471997-08-20Per Hedbor {
0582051997-08-20Per Hedbor  v->help=1;
2da8471997-08-20Per Hedbor  if(!id->variables->help) return ""; return contents; }
2ebb571997-08-21Per Hedbor string make_title()
1e5ee81997-08-21Per Hedbor {
2ebb571997-08-21Per Hedbor  string s = (this_object()->wizard_name||this_object()->name) - "<p>"; sscanf(s, "%*s//%s", s); sscanf(s, "%*d:%s", s); return s;
1e5ee81997-08-21Per Hedbor }
cb2fef1997-08-23Marcus Comstedt  int num_pages(string wiz_name)
62d8c41997-10-16Per Hedbor {
2da8471997-08-20Per Hedbor  int max_page; for(int i=0; i<100; i++) if(!this_object()[wiz_name+i]) { max_page=i-1; break; }
cb2fef1997-08-23Marcus Comstedt  return max_page+1; }
2da8471997-08-20Per Hedbor 
cb2fef1997-08-23Marcus Comstedt string parse_wizard_page(string form, object id, string wiz_name) { int max_page = num_pages(wiz_name)-1;
2da8471997-08-20Per Hedbor  string res; int page = ((int)id->variables->_page);
0582051997-08-20Per Hedbor  mapping foo = ([]);
2da8471997-08-20Per Hedbor  // Cannot easily be inlined below, believe me... Side-effects. form = parse_html(form,([ "var":wizard_tag_var, ]),
fc94331997-10-25Per Hedbor  ([ "cvar":wizard_tag_var, "help":parse_wizard_help]), id, foo );
2da8471997-08-20Per Hedbor  res = ("<!--Wizard-->\n"
0582051997-08-20Per Hedbor  "<form method=get>\n"
2da8471997-08-20Per Hedbor  " <input type=hidden name=action value=\""+id->variables->action+"\">\n" " <input type=hidden name=_page value=\""+page+"\">\n"
0582051997-08-20Per Hedbor  " <input type=hidden name=_state value=\""+compress_state(id->variables)+"\">\n" "<table bgcolor=black cellpadding=1 border=0 cellspacing=0 width=80%>\n"
6796b01997-08-20Per Hedbor  " <tr><td><table bgcolor=#eeeeee cellpadding=0 "
2da8471997-08-20Per Hedbor  " cellspacing=0 border=0 width=100%>\n"
2ebb571997-08-21Per Hedbor  " <tr><td valign=top><table width=100% height=100% cellspacing=0 cellpadding=5>\n<tr><td valign=top>\n" "<font size=+2>"+make_title()+"</font>"
6ad3161997-08-20Per Hedbor  " </td>\n<td align=right>"+
2ebb571997-08-21Per Hedbor  (max_page?"Page "+(page+1)+"/"+(max_page+1):"")+"</td>\n"
2da8471997-08-20Per Hedbor  " \n<td align=right>"+
822f431997-08-20Per Hedbor  (foo->help && !id->variables->help?
06cc931997-08-20Per Hedbor  "<font size=-1><input type=image name=help src="+ (id->conf?"/internal-roxen-help":"/image/help.gif")+ " border=0 value=\"Help\"></font>":"")
2da8471997-08-20Per Hedbor  +"</td>\n"
9cc6771997-08-20Fredrik Noring  " </tr><tr><td colspan=3><table cellpadding=0 cellspacing=0 border=0 width=100%><tr bgcolor=#000000><td><img src="+
06cc931997-08-20Per Hedbor  (id->conf?"/internal-roxen-unit":"/image/unit.gif")+
822f431997-08-20Per Hedbor  " width=1 height=1></td></tr></table></td></tr>\n"
2da8471997-08-20Per Hedbor  " </table><table cellpadding=6><tr><td>\n" "<!-- The output from the page function -->\n" +form+ "\n<!-- End of the output from the page function -->\n" "\n</td></tr></table>\n" " <table width=100%><tr><td width=33%>"+ (page>0? " <input type=submit name=prev_page value=\"<- Previous\">":"")+ "</td><td width=33% align=center >"+ (page==max_page? " <input type=submit name=ok value=\" Ok \">":"")+ " <input type=submit name=cancel value=\" Cancel \">"+ "</td>" "</td><td width=33% align=right >"+ (page!=max_page? " <input type=submit name=next_page value=\"Next ->\">":"")+ "</td></tr></table>" " </td><tr>\n" " </table>\n" " </td></tr>\n"
0582051997-08-20Per Hedbor  "</table>\n"
2da8471997-08-20Per Hedbor  " </form>\n"
0582051997-08-20Per Hedbor  );
2da8471997-08-20Per Hedbor  return res; } #define PAGE(X) ((string)(((int)v->_page)+(X)))
6796b01997-08-20Per Hedbor mapping|string wizard_for(object id,string cancel,mixed ... args)
2da8471997-08-20Per Hedbor { string data; int offset = 1; mapping v=id->variables;
6796b01997-08-20Per Hedbor  string wiz_name = "page_";
7c1ccb1997-08-22Per Hedbor 
2da8471997-08-20Per Hedbor  if(v->next_page)
7c1ccb1997-08-22Per Hedbor  { function c;
2d72561997-08-22Per Hedbor  if(!functionp(c=this_object()["verify_"+v->_page]) || (!c( id, @args )))
7c1ccb1997-08-22Per Hedbor  v->_page = PAGE(1); }
2da8471997-08-20Per Hedbor  else if(v->prev_page) {
0a1b801997-08-24Per Hedbor  v->_page = PAGE(-1);
2da8471997-08-20Per Hedbor  offset=-1; } else if(v->ok)
7c1ccb1997-08-22Per Hedbor  { function c;
0a1b801997-08-24Per Hedbor  mapping s = decompress_state(v->_state); foreach(indices(s), string q) v[q] = v[q]||s[q];
2d72561997-08-22Per Hedbor  if(!functionp(c=this_object()["verify_"+v->_page]) || (!c( id, @args ))) return (((c=this_object()->wizard_done)?c(id,@args):0) || http_redirect(cancel||id->not_query, @(id->conf?({id}):({}))));
7c1ccb1997-08-22Per Hedbor  }
2da8471997-08-20Per Hedbor  else if(v["help.x"]) { m_delete(v, "help.x"); m_delete(v, "help.y"); v->help="1";
7c1ccb1997-08-22Per Hedbor  } else if(v->cancel) {
2da8471997-08-20Per Hedbor  return http_redirect(cancel||id->not_query, @(id->conf?({id}):({})));
7c1ccb1997-08-22Per Hedbor  }
a376e31997-08-20Per Hedbor  mapping s = decompress_state(v->_state); foreach(indices(s), string q) v[q] = v[q]||s[q];
2da8471997-08-20Per Hedbor 
6796b01997-08-20Per Hedbor  foreach(indices(id->variables), string n) { string q,on=n; if(sscanf(n, "_new_%s", n)) { if((v->_Add) && strlen(v[on]-"\r")) { if(v[n]) v[n]+="\0"+v[on]; else v[n]=v[on]; m_delete(v, on); m_delete(v, "_Add"); } } else if(sscanf(n, "_delete_%s:%s", n,q)==2) { if(v[n]) v[n]=replace(replace(v[n]/"\0",q,"")*"\0","\0\0","\0"); m_delete(v, on);
2ebb571997-08-21Per Hedbor  }
6796b01997-08-20Per Hedbor  } for(; !data; v->_page=PAGE(offset))
2da8471997-08-20Per Hedbor  { function pg=this_object()[wiz_name+((int)v->_page)]; if(!pg) return "Error: Invalid page ("+v->_page+")!";
2319be1997-08-20Per Hedbor  if(data = pg(id,@args)) break;
2da8471997-08-20Per Hedbor  } return parse_wizard_page(data,id,wiz_name); }
4bb6411997-08-20Per Hedbor  mapping wizards = ([]);
62d8c41997-10-16Per Hedbor string err;
2319be1997-08-20Per Hedbor object get_wizard(string act, string dir, mixed ... args)
4bb6411997-08-20Per Hedbor {
7c1ccb1997-08-22Per Hedbor  act-="/";
62d8c41997-10-16Per Hedbor  // _master->set_inhibit_compile_errors(""); // catch { if(!wizards[dir+act]) wizards[dir+act]=compile_file(dir+act)(@args); // }; if(_master->errrors && strlen(_master->errors)) err+=_master->errors; // _master->set_inhibit_compile_errors(0); // if(!wizards[dir+act]) throw("Failed to compile "+act+"\n");
4bb6411997-08-20Per Hedbor  return wizards[dir+act]; }
7c1ccb1997-08-22Per Hedbor 
6cc9811997-08-20Per Hedbor int zonk=time(); mapping get_actions(string base,string dir, array args) { mapping acts = ([ ]); foreach(get_dir(dir), string act) { mixed err; err = catch { if(act[0]!='#' && act[-1]=='e') { string sm,rn = (get_wizard(act,dir,@args)->name||act), name; if(sscanf(rn, "%*s:%s", name) != 2) name = rn; sscanf(name, "%s//%s", sm, name); if(!acts[sm]) acts[sm] = ({ }); acts[sm]+= ({"<!-- "+rn+" --><dt><font size=\"+2\">" "<a href=\""+base+"?action="+act+"&unique="+(zonk++)+"\">"+ name+"</a></font><dd>"+(get_wizard(act,dir,@args)->doc||"")}); } };
62d8c41997-10-16Per Hedbor  if(err) report_error(describe_backtrace(err));
6cc9811997-08-20Per Hedbor  } return acts; }
6796b01997-08-20Per Hedbor string act_describe_submenues(array menues, string base,string sel)
4bb6411997-08-20Per Hedbor {
6cc9811997-08-20Per Hedbor  if(sizeof(menues)==1) return "";
6796b01997-08-20Per Hedbor  string res = "<font size=+3>";
6cc9811997-08-20Per Hedbor  foreach(sort(menues), string s)
6796b01997-08-20Per Hedbor  res+= (s==sel?"<li>":"<font color=#eeeeee><li></font><a href=\""+base+"?sm="+replace(s||"Misc"," ","%20")+ "&uniq="+(++zonk)+"\">")+(s||"Misc")+ (s==sel?"<br>":"</a><br>")+""; return res + "</font>";
6cc9811997-08-20Per Hedbor } string focused_wizard_menu; mixed wizard_menu(object id, string dir, string base, mixed ... args) { mapping acts;
2ebb571997-08-21Per Hedbor  if(id->pragma["no-cache"]) wizards=([]);
6cc9811997-08-20Per Hedbor  if(!id->variables->sm) id->variables->sm = focused_wizard_menu; else focused_wizard_menu = id->variables->sm=="0"?0:id->variables->sm;
4bb6411997-08-20Per Hedbor  if(!id->variables->action) {
4b7b611997-10-24Fredrik Noring  mixed wizbug; wizbug = catch {
62d8c41997-10-16Per Hedbor  mapping acts = get_actions(base, dir, args); string res; res= ("<table cellpadding=3><tr><td valign=top bgcolor=#eeeeee>"+
6796b01997-08-20Per Hedbor  act_describe_submenues(indices(acts),base,id->variables->sm)+ "</td>\n\n<td valign=top>"+
2ebb571997-08-21Per Hedbor  (sizeof(acts)>1 && acts[id->variables->sm]?"<font size=+3>"+
6796b01997-08-20Per Hedbor  (id->variables->sm||"Misc")+"</font><dl>":"<dl>")+ (sort(acts[id->variables->sm]||({}))*"\n")+
62d8c41997-10-16Per Hedbor  "</dl></td></tr></table>"+
4b7b611997-10-24Fredrik Noring  (err && strlen(err)?"<pre>"+err+"</pre>":""));
62d8c41997-10-16Per Hedbor  err=""; return res; };
4b7b611997-10-24Fredrik Noring  if(wizbug) err = describe_backtrace(wizbug);
94d5321997-10-24Fredrik Noring  if(err && strlen(err)) {
62d8c41997-10-16Per Hedbor  string res="<pre>"+err+"</pre>"; err=""; return res; }
4b7b611997-10-24Fredrik Noring  } else { object o = get_wizard(id->variables->action,dir); if(!o) { mixed res = "<pre>"+err+"</pre>"; err=""; return res; } mixed res= o->wizard_for(id,base,@args);
62d8c41997-10-16Per Hedbor  err=""; return res; }
4b7b611997-10-24Fredrik Noring  return "<pre>The Wizard is confused.</pre>";
4bb6411997-08-20Per Hedbor }
1c5e031997-08-20Fredrik Noring  /*** Additional Action Functions ***/ string html_table(array(string) subtitles, array(array(string)) table) { string r = "";
2ebb571997-08-21Per Hedbor  r += ("<table bgcolor=black border=0 cellspacing=0 cellpadding=1>\n" "<tr><td>\n");
9cc6771997-08-20Fredrik Noring  r += "<table border=0 cellspacing=0 cellpadding=4>\n"; r += "<tr bgcolor=#113377>\n";
6420831997-08-21Per Hedbor  int cols; foreach(subtitles, mixed s) { if(stringp(s)) {
88c98b1997-08-21Per Hedbor  r+="<th nowrap align=left><font color=#ffffff>"+s+" &nbsp; </font></th>";
6420831997-08-21Per Hedbor  cols++; } else {
88c98b1997-08-21Per Hedbor  r+="</tr><tr bgcolor=#113377><th nowrap align=left colspan="+cols+">" "<font color=#ffffff>"+s[0]+" &nbsp; </font></th>";
6420831997-08-21Per Hedbor  }
88c98b1997-08-21Per Hedbor  }
1c5e031997-08-20Fredrik Noring  r += "</tr>";
88c98b1997-08-21Per Hedbor 
1c5e031997-08-20Fredrik Noring  for(int i = 0; i < sizeof(table); i++) { r += "<tr bgcolor="+(i%2?"#ddeeff":"#ffffff")+">";
6420831997-08-21Per Hedbor  foreach(table[i], mixed s)
8609241997-08-23Henrik Grubbström (Grubba)  if(arrayp(s))
6420831997-08-21Per Hedbor  r += "</tr><tr bgcolor="+(i%2?"#ddeeff":"#ffffff")+
88c98b1997-08-21Per Hedbor  "><td colspan="+cols+">"+s[0]+" &nbsp;</td>";
8609241997-08-23Henrik Grubbström (Grubba)  else r += "<td nowrap>"+s+"&nbsp;&nbsp;</td>";
1c5e031997-08-20Fredrik Noring  r += "</tr>\n"; }
1e5ee81997-08-21Per Hedbor  r += "</table></td></tr>\n";
1c5e031997-08-20Fredrik Noring  r += "</table><br>\n"; return r; }
6796b01997-08-20Per Hedbor 
2ebb571997-08-21Per Hedbor  string html_notice(string notice, object id) {
56d2e11997-08-26Peter Bortas  return ("<table><tr><td valign=top><img \nalt=Notice: src=\""+
2ebb571997-08-21Per Hedbor  (id->conf?"/internal-roxen-":"/image/") +"err_1.gif\"></td><td valign=top>"+notice+"</td></tr></table>"); } string html_warning(string notice, object id) {
56d2e11997-08-26Peter Bortas  return ("<table><tr><td valign=top><img \nalt=Warning: src=\""+
2ebb571997-08-21Per Hedbor  (id->conf?"/internal-roxen-":"/image/") +"err_2.gif\"></td><td valign=top>"+notice+"</td></tr></table>"); } string html_error(string notice, object id) {
56d2e11997-08-26Peter Bortas  return ("<table><tr><td valign=top><img \nalt=Error: src=\""+
2ebb571997-08-21Per Hedbor  (id->conf?"/internal-roxen-":"/image/") +"err_3.gif\"></td><td valign=top>"+notice+"</td></tr></table>"); }
a683e81997-08-24Per Hedbor 
9974541997-08-24Per Hedbor string html_border(string what, int|void width, int|void ww)
a683e81997-08-24Per Hedbor { return ("<table border=0 cellpadding="+(width+1)+" cellspacing=0 "
9974541997-08-24Per Hedbor  "bgcolor=black><tr><td><table border=0 cellpadding="+(ww)+ " cellspacing=0 bgcolor=white><tr><td>"+what+"</tr></td></table>"
4013561997-08-24Per Hedbor  "</td></tr></table>"); } void filter_checkbox_variables(mapping v) { foreach(indices(v), string s) if(v[s]=="0") m_delete(v,s);
a683e81997-08-24Per Hedbor }