835c6c2001-06-17Martin Nilsson // This file is part of Roxen WebServer.
f41b982009-05-07Martin Stjernholm // Copyright © 1997 - 2009, Roxen IS.
835c6c2001-06-17Martin Nilsson //
24c6c12000-02-20Martin Nilsson // Wizard generator
0917d32013-03-04Anders Johansson // $Id$
10c7e11999-12-28Martin Nilsson 
29dfef1999-01-05Martin Stjernholm /* wizard_automaton operation (old behavior if it isn't defined): mapping(string:array) wizard_automaton = ([ "foo": ({dispatch, prev_page, next_page, page_name}), ... ]); dispatch: A string redirects the wizard to that page. 0 or the name of this page continues with it. prev_page: A string is the page for the previous button. 0 if none. next_page: A string is the page for the next button. 0 makes an ok button instead. -1 gives neither button. page_name: Optional page name. Defaults to "". Any of these may be a function that returns the value:
f98e321999-11-29Per Hedbor  lambda (RequestID id, string page, mixed ... args);
29dfef1999-01-05Martin Stjernholm  id: Request id. page: The entry in wizard_automaton. args: The extra args to wizard_menu() or wizard_for(). Other callbacks:
f98e321999-11-29Per Hedbor  o string|mapping page_foo (RequestID id, mixed ... args);
29dfef1999-01-05Martin Stjernholm  The function that produces page "foo". May return 0 to cause a redirect to the next page (or the previous one if the user pressed previous to enter it). Goes to the done page if there isn't any such page.
f98e321999-11-29Per Hedbor  o int verify_foo (RequestID id, mixed ... args);
29dfef1999-01-05Martin Stjernholm  A verify function that's run when the user presses next or ok in page "foo". Returns 0 if it's ok to leave the page, anything else re-runs the page function to redisplay the page.
f98e321999-11-29Per Hedbor  o string|mapping wizard_done (RequestID id, mixed ... args);
29dfef1999-01-05Martin Stjernholm  The function for the done page, from which it's not possible to return to the other wizard pages. May return 0 to skip the page. (Differences from old behavior: -1 is not a meaningful return value and a string is run through parse_wizard_page().) The dispatch function is always run before any other function for a page. That makes it suitable to contain all page init stuff and also state sanity checks, since it can bail to other pages on errors etc. The intention is also that it should be shared between several pages that has init code in common. Special pages: "start": Start page. "done": Finish page. The page function is wizard_done(). Only dispatch is used in the wizard_automaton entry. "cancel": Cancels the wizard. Has no wizard_automaton entry. Bugs: There's no good way to share variables between the functions. Can we say id->misc? :P */
2da8471997-08-20Per Hedbor  inherit "roxenlib";
c96d642001-03-05Martin Nilsson #include <roxen.h> //<locale-token project="roxen_message">LOCALE</locale-token> #define LOCALE(X,Y) _STR_LOCALE("roxen_message",X,Y)
29dfef1999-01-05Martin Stjernholm  #ifdef DEBUG_WIZARD
c96d642001-03-05Martin Nilsson # define DEBUGMSG(msg) report_debug(msg)
29dfef1999-01-05Martin Stjernholm #else
10c7e11999-12-28Martin Nilsson # define DEBUGMSG(msg)
29dfef1999-01-05Martin Stjernholm #endif
735c401999-07-02Mattias Andersson  string loc_encode(string val, void|mapping args, void|string def) { string quote = args->quote || def || "html"; switch (quote) { case "html": return html_encode_string(val); break; case "none": return val; break; } return val; }
d0a19d1999-11-26Henrik Grubbström (Grubba) string wizard_tag_var(string n, mapping m, mixed a, mixed|void b)
2da8471997-08-20Per Hedbor {
f98e321999-11-29Per Hedbor  RequestID id;
fc94331997-10-25Per Hedbor  if(n=="cvar") // Container. Default value in 'a', id in 'b'. { id = b;
e8f6df1998-05-22Per Hedbor  if(m->type == "select" || m->type == "select_multiple")
2f40281998-06-01Mattias Wingstedt  if (m->parse)
4e17dc1998-07-17Fredrik Noring  m->options = (replace(parse_rxml( a, id ), ",", "__CoMma__") / "\n" - ({ "" })) * ",";
2f40281998-06-01Mattias Wingstedt  else m->options = (a / "\n") * ","; else if (m->parse)
2dc9141998-05-29Mattias Wingstedt  m["default"] = parse_rxml( a, id );
2f40281998-06-01Mattias Wingstedt  else m["default"] = a;
5c5ace1998-07-23Per Hedbor  } else // tag. No contents, id in 'a'.
fc94331997-10-25Per Hedbor  id = a;
2da8471997-08-20Per Hedbor  string current = id->variables[m->name] || m["default"];
3df2f51997-11-13David Hedbor  if(current) current = current +"";
2da8471997-08-20Per Hedbor  switch(m->type) {
8442681998-08-31Honza Petrous  default: // String or password field or hidden value.... if((m->type != "password") && (m->type != "hidden"))
14e93d2000-02-13Elias Levy  m->type = "text";
2da8471997-08-20Per Hedbor  m_delete(m,"default");
735c401999-07-02Mattias Andersson  m->value = loc_encode(current||m->value||"", m, "none");
f8f1122003-03-18Jonas Wallden  if(!m->size)m->size="60";
6302041999-10-04Martin Nilsson  m_delete(m,"quote");
2da8471997-08-20Per Hedbor  return make_tag("input", m);
6796b01997-08-20Per Hedbor  case "list": // String....
9c15e11999-07-22Martin Nilsson  string n = m->name, res="<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">";
6796b01997-08-20Per Hedbor  if(!id->variables[n]) id->variables[n]=current;
10c7e11999-12-28Martin Nilsson 
14e93d2000-02-13Elias Levy  m->type = "text";
f8f1122003-03-18Jonas Wallden  if(!m->size)m->size="60";
6796b01997-08-20Per Hedbor  m_delete(m,"default"); foreach((current||"")/"\0"-({""}), string v) {
9c15e11999-07-22Martin Nilsson  res+="<tr><td>"+loc_encode(v, m, "html")+"</td><td><font size=\"-2\">";
6796b01997-08-20Per Hedbor  m->name="_delete_"+n+":"+v;
c96d642001-03-05Martin Nilsson  m->value = " " + LOCALE(16, "Remove") + " ";
6796b01997-08-20Per Hedbor  m->type = "submit";
6302041999-10-04Martin Nilsson  res+=make_tag("input",m-(["quote":""]))+"</td></tr>";
6796b01997-08-20Per Hedbor  } m->name = "_new_"+n;
87d8102000-02-13Elias Levy  m->type = "text";
6796b01997-08-20Per Hedbor  m->value = "";
9c15e11999-07-22Martin Nilsson  res+= "<tr><td>"+make_tag("input", m)+"</td><td><font size=\"-2\">";
6796b01997-08-20Per Hedbor  m->name="_Add";
c96d642001-03-05Martin Nilsson  m->value = " " + LOCALE(18, "Add") + " ";
6796b01997-08-20Per Hedbor  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";
6302041999-10-04Martin Nilsson  return make_container("textarea", m-(["quote":""]), loc_encode(current||"", m, "html"));
78d67d1997-08-20Per Hedbor 
9cc6771997-08-20Fredrik Noring  case "radio": m_delete(m,"default");
489ff51998-07-19Per Hedbor  if((!id->variables[m->name] && current) || (current==m->value)) m->checked="checked"; return make_tag("input",m);
9cc6771997-08-20Fredrik Noring  case "checkbox": m_delete(m,"default");
9040021998-11-22Francesco Chemolli  if (!m->value) m->value="on";
571e761998-11-28Fredrik Noring  if (current && current != "0" && (current == "1"||mkmultiset(current/"\0")[m->value]))
9040021998-11-22Francesco Chemolli  m->checked="checked";
ffa5362000-02-02Jonas Wallden  res=make_tag("input",m); m->type="hidden"; // Yes, this hidden var is needed! Cleared boxes may m->value="0"; // otherwise revert to their initial set state.
636e782004-06-25Jonas Wallden  m_delete(m, "id"); // Can't have the same ID twice
ffa5362000-02-02Jonas Wallden  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);
f8f1122003-03-18Jonas Wallden  if(!m->size)m->size="8";
78d67d1997-08-20Per Hedbor  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;
82b3fe2001-01-17Anders Johansson  array a;
10c7e11999-12-28Martin Nilsson  if(id->variables[m->name+".hsv"])
fc94331997-10-25Per Hedbor  sscanf(id->variables[m->name+".hsv"], "%d,%d,%d", h, s, v); else {
82b3fe2001-01-17Anders Johansson  a = parse_color(current||"black"); [h,s,v] = rgb_to_hsv(@a);
10c7e11999-12-28Martin Nilsson  }
a62ee71998-07-22Johan Schön  if(id->variables[m->name+".foo.x"]) { h = (int)id->variables[m->name+".foo.x"]; v = 255-(int)id->variables[m->name+".foo.y"]; } else if(id->variables[m->name+".bar.y"]) s=255-(int)id->variables[m->name+".bar.y"];
3d03581997-11-05David Hedbor  else if(id->variables[m->name+".entered"] && strlen(current=id->variables[m->name+".entered"]))
fc94331997-10-25Per Hedbor  {
82b3fe2001-01-17Anders Johansson  a = parse_color(current||"black"); [h,s,v] = rgb_to_hsv(@a);
fc94331997-10-25Per Hedbor  }
3d03581997-11-05David Hedbor 
a62ee71998-07-22Johan Schön  m_delete(id->variables, m->name+".foo.x"); m_delete(id->variables, m->name+".foo.y"); m_delete(id->variables, m->name+".bar.x"); m_delete(id->variables, m->name+".bar.y");
fc94331997-10-25Per Hedbor  id->variables[m->name+".hsv"] = h+","+s+","+v;
82b3fe2001-01-17Anders Johansson  if(!a) a = hsv_to_rgb(h,s,v); string bgcol = sprintf("#%02x%02x%02x",a[0],a[1],a[2]);
fc94331997-10-25Per Hedbor  id->variables[m->name] = bgcol;
10c7e11999-12-28Martin Nilsson  return
fc94331997-10-25Per Hedbor  ("<table><tr>\n"
9c15e11999-07-22Martin Nilsson  "<td width=\"258\" rowspan=\"2\">\n" " <table bgcolor=\"#000000\" cellpadding=\"1\" border=\"0\" cellspacing=\"0\" width=\"258\"><tr><td>\n" " <input type=\"image\" name=\""+m->name+".foo\" src=\"/internal-roxen-colsel\"" " width=\"256\" height=\"256\" border=\"0\"></td>\n"
4f24fe1998-09-16Marcus Wellhardh  "</table>\n"
fc94331997-10-25Per Hedbor  "</td>\n"
9c15e11999-07-22Martin Nilsson  "<td width=\"30\" rowspan=\"2\"></td>\n" "<td width=\"32\" rowspan=\"2\">\n" " <table bgcolor=\"#000000\" cellpadding=\"1\" border=\"0\" cellspacing=\"0\" width=\"32\"><tr><td>\n" "<input type=\"image\" src=\"/internal-roxen-colorbar:"+
fc94331997-10-25Per Hedbor  (string)h+","+(string)v+","+(string)s+"\" "
9c15e11999-07-22Martin Nilsson  "name=\""+m->name+".bar\" width=\"30\" height=\"256\" border=\"0\"></td>"
4f24fe1998-09-16Marcus Wellhardh  "</table>\n"
fc94331997-10-25Per Hedbor  "</td>\n"
9c15e11999-07-22Martin Nilsson  "<td width=\"32\" rowspan=\"2\"></td>\n" "<td width=\"120\">\n" " <table bgcolor=\"#000000\" 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>":"")
fc94331997-10-25Per Hedbor  +"</td></table>\n" "</td><tr>\n"
9c15e11999-07-22Martin Nilsson  "<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=\"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=\"noshade\" width=\"70\" />\n"+ "<font size=\"-1\"><input type=\"string\" name=\""+ m->name+".entered\" size=\"8\" value=\""+
51cc6f2006-02-15Jonas Wallden  color_name(a)+"\"> <input type=\"submit\" value=\"OK\"></font></td></table>\n");
fc94331997-10-25Per Hedbor 
4f24fe1998-09-16Marcus Wellhardh  case "color-small":
10c7e11999-12-28Martin Nilsson  if(id->variables[m->name+".hsv"])
4f24fe1998-09-16Marcus Wellhardh  sscanf(id->variables[m->name+".hsv"], "%d,%d,%d", h, s, v); else {
82b3fe2001-01-17Anders Johansson  a = parse_color(current||"black"); [h,s,v] = rgb_to_hsv(@a);
10c7e11999-12-28Martin Nilsson  }
4f24fe1998-09-16Marcus Wellhardh  if(id->variables[m->name+".foo.x"]) { h = ((int)id->variables[m->name+".foo.x"])*2; v = 255-((int)id->variables[m->name+".foo.y"])*2; } else if(id->variables[m->name+".bar.y"]) s = 255-((int)id->variables[m->name+".bar.y"])*2; else if(id->variables[m->name+".entered"] && strlen(current=id->variables[m->name+".entered"])) {
82b3fe2001-01-17Anders Johansson  a = parse_color(current||"black"); [h,s,v] = rgb_to_hsv(@a);
4f24fe1998-09-16Marcus Wellhardh  } m_delete(id->variables, m->name+".foo.x"); m_delete(id->variables, m->name+".foo.y"); m_delete(id->variables, m->name+".bar.x"); m_delete(id->variables, m->name+".bar.y"); id->variables[m->name+".hsv"] = h+","+s+","+v;
82b3fe2001-01-17Anders Johansson  if(!a) a = hsv_to_rgb(h,s,v); bgcol = sprintf("#%02x%02x%02x",a[0],a[1],a[2]);
4f24fe1998-09-16Marcus Wellhardh  id->variables[m->name] = bgcol;
10c7e11999-12-28Martin Nilsson  return
9c15e11999-07-22Martin Nilsson  ("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>\n" "<td rowspan=\"2\">\n" " <table bgcolor=\"#000000\" cellpadding=\"1\" border=\"0\" cellspacing=\"0\"><tr><td>\n" " <input type=\"image\" name=\""+m->name+".foo\" " "src=\"/internal-roxen-colsel-small\" " "width=\"128\" height=\"128\" border=\"0\"></td>\n"
4f24fe1998-09-16Marcus Wellhardh  " </table>\n" "</td>\n"
9c15e11999-07-22Martin Nilsson  "<td width=\"8\" rowspan=\"2\"><img src=\"/internal-roxen-unit\" width=\"8\" /></td>\n" "<td width=\"18\" rowspan=\"2\">\n" " <table bgcolor=\"#000000\" cellpadding=\"1\" border=\"0\" cellspacing=\"0\"><tr><td>\n" " <input type=\"image\" src=\"/internal-roxen-colorbar:"+
4f24fe1998-09-16Marcus Wellhardh  (string)h+","+(string)v+","+(string)s+"\" "
9c15e11999-07-22Martin Nilsson  "name=\""+m->name+".bar\" width=\"16\" height=\"128\" border=\"0\"></td>\n"
4f24fe1998-09-16Marcus Wellhardh  " </table>\n" "</td>\n"
9c15e11999-07-22Martin Nilsson  "<td width=\"8\" rowspan=\"2\"><img src=\"/internal-roxen-unit\" width=\"8\" /></td>\n"
4f24fe1998-09-16Marcus Wellhardh  "<td>\n"
9c15e11999-07-22Martin Nilsson  " <table bgcolor=\"#000000\" width=\"64\" border=\"3\" " "cellpadding=\"1\" cellspacing=\"0\"><tr>\n" " <td height=\"64\" width=\"64\" bgcolor=\""+bgcol+"\">&nbsp;"+ (m->tt?"<font color=\""+m->tc+"\">"+m->tt+"</font>":"")+"\n"
4f24fe1998-09-16Marcus Wellhardh  " </td></tr>\n" " </table>\n" "</td>\n"
9c15e11999-07-22Martin Nilsson  "<tr><td width=\"110\">\n" "<font size=\"-1\"><input type=\"string\" name=\""+ m->name+".entered\" size=\"8\" value=\""+
72cade2006-03-06Jonas Wallden  color_name(a)+"\"> <input type=\"submit\" value=\"" + LOCALE(38, "OK") + "\"></font>"
4f24fe1998-09-16Marcus Wellhardh  "</td></tr>\n" "</table>\n");
c35fba2004-03-06Jonas Wallden  case "color-js": // Note: This code requires ColorSelector.js if (string color_input = id->variables[m->name]) current = color_input; a = parse_color(current || "black"); [h, s, v] = rgb_to_hsv(@a);
0729a12006-03-14Fredrik Noring  if(!h && !s && !v) s = 255;
c35fba2004-03-06Jonas Wallden  current = upper_case(sprintf("#%02x%02x%02x", a[0], a[1], a[2])); id->variables[m->name] = current;
6af13e2004-06-01Jonas Wallden  int mark_x_left = 5 + (int) (h / 2); int mark_y_top = 5 + (int) ((255 - v) / 2); int mark_y_small_top = 5 + (int) ((255 - s) / 2);
c35fba2004-03-06Jonas Wallden  string output = "<script language='javascript'>\n" " var PREFIX_h = " + h + ";\n" " var PREFIX_s = " + s + ";\n" " var PREFIX_v = " + v + ";\n"
ee37dc2004-03-13Jonas Wallden  " function PREFIX_colsel_click(event, in_bar, in_cross)\n"
c35fba2004-03-06Jonas Wallden  " {\n"
b18b5f2004-03-07Jonas Wallden  " var hsv = colsel_click(event, \"PREFIX_\", PREFIX_h,\n"
ee37dc2004-03-13Jonas Wallden  " PREFIX_s, PREFIX_v, in_bar, in_cross);\n"
b18b5f2004-03-07Jonas Wallden  " PREFIX_h = hsv[0];\n" " PREFIX_s = hsv[1];\n"
c25aac2006-03-10Stefan Wallström  " PREFIX_v = hsv[2];\n"+ (m->onChange||"")+
c35fba2004-03-06Jonas Wallden  " }\n" " function PREFIX_colsel_type(value, update_field)\n" " {\n"
b18b5f2004-03-07Jonas Wallden  " var hsv = colsel_type(\"PREFIX_\", value, update_field);\n" " PREFIX_h = hsv[0];\n" " PREFIX_s = hsv[1];\n"
c25aac2006-03-10Stefan Wallström  " PREFIX_v = hsv[2];\n"+ (m->onChange||"")+
c35fba2004-03-06Jonas Wallden  " }\n" "</script>" "<js-popup args-variable='__popup' event='onClick' props='color_props'>"
ee37dc2004-03-13Jonas Wallden  " <img src='/internal-roxen-colsel-mark-x' id='PREFIX_mark_x'" " onClick='PREFIX_colsel_click(event, 0, \"x\"); return false;'" " style='position: absolute;" " cursor: crosshair;" " z-index: 2'>" " <img src='/internal-roxen-colsel-mark-y' id='PREFIX_mark_y'" " onClick='PREFIX_colsel_click(event, 0, \"y\"); return false;'" " style='position: absolute;" " cursor: crosshair;" " z-index: 2'>" " <img src='/internal-roxen-colsel-mark-y-small'" " id='PREFIX_mark_y_small'" " style='position: absolute;" " cursor: pointer;" " z-index: 2'>"
b18b5f2004-03-07Jonas Wallden  " <table border='0' cellspacing='0' cellpadding='4' bgcolor='#ffffff'"
d7f9a62013-04-18Anders Johansson  " class='roxen-color-selector'"
b18b5f2004-03-07Jonas Wallden  " style='border-top: 1px solid #888888;" " border-left: 1px solid #888888;" " border-bottom: 2px solid #888888;" " border-right: 2px solid #888888'>"
c35fba2004-03-06Jonas Wallden  " <tr>"
b18b5f2004-03-07Jonas Wallden  " <td style='border-right: 1px solid #888888'" " ><img src='/internal-roxen-colsel-small'"
1b664a2004-03-08Jonas Wallden  " width='128' height='128' style='cursor: crosshair'"
b18b5f2004-03-07Jonas Wallden  " onClick='PREFIX_colsel_click(event, 0); return false;'" " /></td>" " <td><img id='PREFIX_colorbar' width='16' height='128'"
ee37dc2004-03-13Jonas Wallden  " src='/internal-roxen-colorbar-small:" + h + "," + v + ",-1'"
8f12092004-03-07Jonas Wallden  " style='cursor: pointer'"
b18b5f2004-03-07Jonas Wallden  " onClick='PREFIX_colsel_click(event, 1); return false;'" " /></td>" " </tr><tr>" " <td colspan='2' style='border-top: 1px solid #888888'" " ><img src='/internal-roxen-pixel-000000'"
d7f9a62013-04-18Anders Johansson  " class='black'"
8f12092004-03-07Jonas Wallden  " width='76' height='10' style='cursor: pointer'"
b18b5f2004-03-07Jonas Wallden  " onClick='PREFIX_colsel_type(\"#000000\", 1);' " " /><img src='/internal-roxen-pixel-ffffff'"
d7f9a62013-04-18Anders Johansson  " class='white'"
8f12092004-03-07Jonas Wallden  " width='76' height='10' style='cursor: pointer'"
b18b5f2004-03-07Jonas Wallden  " onClick='PREFIX_colsel_type(\"#FFFFFF\", 1);' " " /></td>"
c35fba2004-03-06Jonas Wallden  " </tr>" " </table>" "</js-popup>"
6af13e2004-06-01Jonas Wallden  // These initializations used to be in the style attributes above // but MSIE 6.0 failed to recognize them so we execute them explicitly // instead. "<script language='javascript'>"
21de5d2006-02-17Jonas Wallden  "getObject('PREFIX_mark_x').style.top = '5px';" "getObject('PREFIX_mark_x').style.left = '" + mark_x_left + "px';" "getObject('PREFIX_mark_y').style.top = '" + mark_y_top + "px';" "getObject('PREFIX_mark_y').style.left = '5px';" "getObject('PREFIX_mark_y_small').style.top = '" + mark_y_small_top + "px';" "getObject('PREFIX_mark_y_small').style.left = '143px';"
6af13e2004-06-01Jonas Wallden  "</script>"
c35fba2004-03-06Jonas Wallden  "<table border='0' cellspacing='0' cellpadding='2'>" "<tr>" " <td>" " <input type='text' size='10' value='" + current + "' id='PREFIX_color_input' "
c25aac2006-03-10Stefan Wallström  " name='" + m->name + "' onChange='PREFIX_colsel_type(this.value, 1);"+(m->onChange||"")+"' />"
c35fba2004-03-06Jonas Wallden  " </td>" " <td>"
7e831c2004-08-01Anders Johansson  " <table border='0' cellspacing='0' cellpadding='0' bgcolor='#ffffff'>"
c35fba2004-03-06Jonas Wallden  " <tr>" " <td style='background: " + current + "; border: 1px solid #888888' " " id='PREFIX_preview'"
b18b5f2004-03-07Jonas Wallden  " ><img src='/internal-roxen-colsel-arrow'" " width='49' height='16' border='0'" " style='border: 4px solid #ffffff; cursor: pointer'" " ::='&form.__popup;'"
c35fba2004-03-06Jonas Wallden  " ></td>" " </tr>" " </table>" " </td>" "</tr>" "</table>"; string clean_name = replace(m->name, "-", "_"); return replace(output, "PREFIX", clean_name);
fc94331997-10-25Per Hedbor  case "font": m->type = "select";
b796b51998-11-18Per Hedbor  m->lines = "20";
7108e72000-01-17Jonas Wallden  m->choices = roxen.fonts->available_fonts() * ",";
4f24fe1998-09-16Marcus Wellhardh  if(id->conf && id->conf->modules["graphic_text"] && !m->noexample)
c96d642001-03-05Martin Nilsson  res = ("<input type=\"submit\" value=\"" + LOCALE(47, "Example") + "\"><br />"+
fc94331997-10-25Per Hedbor  ((current&&strlen(current))?
b1bbf42001-08-24Jonas Wallden  "<gtext font=\""+current+"\">" + LOCALE(48, "Example Text") + "</gtext><br />"
fc94331997-10-25Per Hedbor  :""));
4f24fe1998-09-16Marcus Wellhardh  m_delete(m, "noexample");
027dd02001-05-07Jonas Wallden  return wizard_tag_var("var", m, id) + res;
fc94331997-10-25Per Hedbor 
2da8471997-08-20Per Hedbor  case "toggle": m_delete(m,"default"); return make_container("select", m,
c96d642001-03-05Martin Nilsson  "<option"+((int)current?" selected=\"selected\"":"")+" value=\"1\">" + LOCALE(49, "Yes") + "</option>\n" "<option"+(!(int)current?" selected=\"selected\"":"")+" value=\"0\">" + LOCALE(50, "No") + "</option>\n");
2da8471997-08-20Per Hedbor  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);
de12852006-05-18Henrik Grubbström (Grubba)  if (m->select_override) { if (!m->id) { m->id = "wizard-select-" + random(65536) + "-" + random(65536); } m_delete(m2, "select_override"); m2->id = m->id + "-selector"; m2->onchange = "var field = document.getElementById('" + m->id + "-field');" "if (field) { "; if (m->select_none) { m2->onchange += " if (this.value == '" + m2->select_none +"') {" " field.setAttribute('disabled', 'yes');"
db3af92006-05-18Henrik Grubbström (Grubba)  " field.disabled = 'disabled';"
de12852006-05-18Henrik Grubbström (Grubba)  " field.value = '';" " } else {"
db3af92006-05-18Henrik Grubbström (Grubba)  " field.disabled = '';"
de12852006-05-18Henrik Grubbström (Grubba)  " field.removeAttribute('disabled');"; } m2->onchange += " if (this.value != '" + m->select_override +"') {" " field.value = this.value;" " }"; if (m->select_none) { m2->onchange += " }"; } m2->onchange += "}"; if (m->autosubmit) { m2->onchange += "submit();"; m_delete(m2, "autosubmit"); } } else if (m->autosubmit) { m2->onchange = "javascript:submit();"; m_delete(m2, "autosubmit"); }
fc94331997-10-25Per Hedbor  m_delete(m2, "choices"); m_delete(m2, "options");
b950c11998-03-13Francesco Chemolli  //escape the characters we need for internal purposes.. m->choices=replace(m->choices,
10c7e11999-12-28Martin Nilsson  ({"\\,", "\\:"}),
b950c11998-03-13Francesco Chemolli  ({"__CoMma__", "__CoLon__"}));
80f90f2006-05-22Jonas Wallden  string tc = current && replace(current, ({"\\,", "\\:"}), ({"__CoMma__", "__CoLon__"}));
de12852006-05-18Henrik Grubbström (Grubba)  array(string) choices = m->choices/",";
b950c11998-03-13Francesco Chemolli 
de12852006-05-18Henrik Grubbström (Grubba)  foreach(choices, string c) { sscanf(c, "%[^:]", c); if (c == tc) { tc = 0; break; } } if (!tc) { tc = current; } else if (m->select_override) { tc = m->select_override; } else { // Unlisted choice selected!
ce11b82006-05-30Jonas Wallden  if (tc != "") choices += ({ tc + ":" + tc });
de12852006-05-18Henrik Grubbström (Grubba)  tc = current; } string selector = make_container("select", m2, map(choices, lambda(string s, string c, mapping m) {
d382391997-10-29Per Hedbor  string t; if(sscanf(s, "%s:%s", s, t) != 2) t = s;
10c7e11999-12-28Martin Nilsson  s=replace(s,({"__CoMma__",
b950c11998-03-13Francesco Chemolli  "__CoLon__"}),({",",":"})); //can't be done before.
10c7e11999-12-28Martin Nilsson  t=replace(t,({"__CoMma__",
b950c11998-03-13Francesco Chemolli  "__CoLon__"}),({",",":"}));
de12852006-05-18Henrik Grubbström (Grubba)  return "<option value=\"" + s + "\" " + (s==c ? " selected=\"selected\"":"") + ">" + loc_encode(t, m, "html") + "</option>\n"; }, tc, m)*""); if (m->select_override) { m2->id = m->id + "-field"; m2->onchange = "var selector = document.getElementById('" + m->id + "-selector');" "if (selector) { " " selector.value = this.value;" " if (selector.value != this.value) {" " selector.value = '" + m->select_override + "';" " }" "}"; m2->value = ""; if (current == m->select_none) { m2->disabled = "yes"; } else if (current != m->select_override) { m2->value = current; }
8af8352006-05-31Jonas Wallden  selector += "&nbsp;" + make_tag("input", m2) + "<input type='hidden' name='__select_override_vars' " " value='" + m2->name + ":" + m->select_override + "' />";
de12852006-05-18Henrik Grubbström (Grubba)  }
2da8471997-08-20Per Hedbor 
de12852006-05-18Henrik Grubbström (Grubba)  return selector;
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";
b950c11998-03-13Francesco Chemolli  //escape the characters we need for internal purposes.. m->choices=replace(m->choices,
10c7e11999-12-28Martin Nilsson  ({"\\,", "\\:"}),
b950c11998-03-13Francesco Chemolli  ({"__CoMma__", "__CoLon__"}));
85c1342009-04-15Jonas Wallden  return make_container("select", m2, map(m->choices/"," - ({ "" }),
735c401999-07-02Mattias Andersson  lambda(string s, array c, mapping m) {
d382391997-10-29Per Hedbor  string t; if(sscanf(s, "%s:%s", s, t) != 2) t = s;
10c7e11999-12-28Martin Nilsson  s=replace(s,({"__CoMma__",
b950c11998-03-13Francesco Chemolli  "__CoLon__"}),({",",":"})); //can't be done before.
10c7e11999-12-28Martin Nilsson  t=replace(t,({"__CoMma__",
b950c11998-03-13Francesco Chemolli  "__CoLon__"}),({",",":"}));
c96d642001-03-05Martin Nilsson  return "<option value=\""+s+"\" "+(search(c,s)!=-1?"selected=\"selected\"":"")+">"+ loc_encode(t, m, "html")+"</option>\n";
735c401999-07-02Mattias Andersson  },(current||"")/"\0",m)*"");
2da8471997-08-20Per Hedbor  } } mapping decompress_state(string from) { if(!from) return ([]); from = MIME.decode_base64(from);
10c7e11999-12-28Martin Nilsson  catch
8fed9a1999-11-28Per Hedbor  {
2da8471997-08-20Per Hedbor  object gz = Gz; if(sizeof(indices(gz))) from = gz->inflate()->inflate(from);
9e7c072000-01-19Martin Stjernholm  return decode_value(from);
2da8471997-08-20Per Hedbor  };
9e7c072000-01-19Martin Stjernholm  return ([]);
2da8471997-08-20Per Hedbor }
10c7e11999-12-28Martin Nilsson 
2da8471997-08-20Per Hedbor  string compress_state(mapping state) {
bc18ea2000-08-04Fredrik Noring  // NOTE: Variables which begin with "!_" will // not be compressed in the state.
2da8471997-08-20Per Hedbor  state = copy_value(state); m_delete(state,"_state"); m_delete(state,"next_page");
a8e00e2004-01-22Jonas Wallden  m_delete(state,"next_page.x"); m_delete(state,"next_page.y");
2da8471997-08-20Per Hedbor  m_delete(state,"prev_page");
a8e00e2004-01-22Jonas Wallden  m_delete(state,"prev_page.x"); m_delete(state,"prev_page.y");
2da8471997-08-20Per Hedbor  m_delete(state,"help"); m_delete(state,"action"); m_delete(state,"unique");
20d9c32000-08-04Fredrik Noring  foreach(glob("!_*", indices(state)), string s) m_delete(state, s);
91d3c32001-03-12Martin Nilsson // report_debug(sprintf("State=%O\n", state));
2ebb571997-08-21Per Hedbor 
2da8471997-08-20Per Hedbor  string from = encode_value(state); object gz = Gz; if(sizeof(indices(gz)))
8fed9a1999-11-28Per Hedbor  from = gz->deflate()->deflate(from);
2da8471997-08-20Per Hedbor  return MIME.encode_base64( from ); }
96ee982003-01-22Henrik Grubbström (Grubba) string parse_wizard_help(string|Parser.HTML t, mapping m, string contents,
d70a062001-04-12Martin Nilsson  RequestID id, void|mapping v)
2da8471997-08-20Per Hedbor {
d70a062001-04-12Martin Nilsson  if(v) v->help=1; else id->misc->wizard_help=1;
2da8471997-08-20Per Hedbor  if(!id->variables->help) return ""; return contents; }
2ebb571997-08-21Per Hedbor string make_title()
1e5ee81997-08-21Per Hedbor {
34ca372001-02-22Stefan Wallström  string s = (string)(this_object()->wizard_name ||
c96d642001-03-05Martin Nilsson  this_object()->name || LOCALE(51, "No name")) -
b950c11998-03-13Francesco Chemolli  "<p>";
2ebb571997-08-21Per Hedbor  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; }
41d0f91998-02-20Per Hedbor #define Q(X) replace(X,({"<",">","&","\""}),({"&lt;","&gt;","&amp;","&quote;"}))
c96d642001-03-05Martin Nilsson #define LABEL(X,Y) (this_object()->X?Q(this_object()->X):Y)
2da8471997-08-20Per Hedbor 
f98e321999-11-29Per Hedbor string parse_wizard_page(string form, RequestID id, string wiz_name, void|string page_name)
cb2fef1997-08-23Marcus Comstedt {
29dfef1999-01-05Martin Stjernholm  mapping(string:array) automaton = this_object()->wizard_automaton; int max_page = !automaton && num_pages(wiz_name)-1;
2da8471997-08-20Per Hedbor  string res;
29dfef1999-01-05Martin Stjernholm  string page = id->variables->_page; int pageno = (int)page;
0582051997-08-20Per Hedbor  mapping foo = ([]);
eeeaad1999-02-26Henrik Grubbström (Grubba)  // FIXME: Add support for preparse on the page-level. // form = parse_rxml(form, id);
2da8471997-08-20Per Hedbor  // Cannot easily be inlined below, believe me... Side-effects.
817fd21998-11-09Marcus Comstedt  form = parse_html(form,(id->misc->extra_wizard_tags||([]))+ ([ "var":wizard_tag_var, ]), (id->misc->extra_wizard_container||([]))+
10c7e11999-12-28Martin Nilsson  ([ "cvar":wizard_tag_var,
fc94331997-10-25Per Hedbor  "help":parse_wizard_help]), id, foo );
b126661999-11-28Martin Stjernholm  // We commonly feed the action variable both from the URL with // "...?action=foo.pike" and with an <input> tag from the previous // page. Netscape ignores one of them, but IE sends both. Thus we // have to discard the extra value in the IE case. (We simply assume // both values are the same here; maybe it could be done better.)
a6437b1999-12-16Martin Stjernholm  if (stringp (id->variables->action)) id->variables->action = (id->variables->action/"\0")[0];
10c7e11999-12-28Martin Nilsson 
456cbf2000-01-28Jonas Wallden  // Use custom method if caller doesn't like GET or perhaps wants other // attributes included. string method = this_object()->wizard_method || "method=\"get\"";
81a8142002-05-15Marcus Wellhardh #ifdef USE_WIZARD_COOKIE
d32b432011-06-17Martin Stjernholm  // FIXME: If this is enabled there may be trouble with the state // getting mixed up between wizards when one wizard initiates // another. The state should be extended with a wizard identifier // then.
81a8142002-05-15Marcus Wellhardh  string state_form = ""; id->add_response_header("Set-Cookie", sprintf("WizardState=%s; path=/", compress_state(id->real_variables) - "\r\n")); #else string state_form = "<input type=\"hidden\" name=\"_state\" value=\""+ compress_state(id->real_variables)+"\" />\n"; #endif
85c1492016-01-12Henrik Grubbström (Grubba) 
c453f82018-01-17Karl Gustav Sterneberg  string wizard_id = Roxen.get_wizard_id_cookie(id);
9c15e11999-07-22Martin Nilsson  res = ("\n<!--Wizard-->\n"
28ac782016-01-11Henrik Grubbström (Grubba)  "<form " + method + ">\n" "<input type=\"hidden\" name=\"_roxen_wizard_id\" value=\"" + html_encode_string(wizard_id) + "\" />\n" +
a6437b1999-12-16Martin Stjernholm  (stringp (id->variables->action) ?
28ac782016-01-11Henrik Grubbström (Grubba)  "<input type=\"hidden\" name=\"action\" value=\"" + html_encode_string(id->variables->action) + "\" />\n" :
a6437b1999-12-16Martin Stjernholm  "") +
28ac782016-01-11Henrik Grubbström (Grubba)  "<input type=\"hidden\" name=\"_page\" value=\"" + html_encode_string(page) + "\" />\n"
81a8142002-05-15Marcus Wellhardh  +state_form+
9c15e11999-07-22Martin Nilsson  "<table bgcolor=\"#000000\" cellpadding=\"1\" border=\"0\" cellspacing=\"0\" width=\"80%\">\n" " <tr><td><table bgcolor=\"#eeeeee\" cellpadding=\"0\" " "cellspacing=\"0\" border=\"0\" width=\"100%\">\n"
fd9f872000-04-03Jonas Wallden  " <tr><td valign=\"top\"><table width=\"100%\" cellspacing=\"0\" cellpadding=\"5\">\n"
9c15e11999-07-22Martin Nilsson  " <tr><td valign=top><font size=\"+2\">"+make_title()+"</font></td>\n" "<td align=\"right\">"+
8492171998-02-19Mirar (Pontus Hagland)  (wiz_name=="done"
c96d642001-03-05Martin Nilsson  ?LABEL(completed_label, LOCALE(52, "Completed")) :page_name || (max_page?LABEL(page_label, LOCALE(53, "Page "))+(pageno+1)+"/"+(max_page+1):""))+
8492171998-02-19Mirar (Pontus Hagland)  "</td>\n"
9c15e11999-07-22Martin Nilsson  " \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")+
9c15e11999-07-22Martin Nilsson  " border=\"0\" value=\"Help\"></font>":"")
2da8471997-08-20Per Hedbor  +"</td>\n"
9c15e11999-07-22Martin Nilsson  " </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")+
9c15e11999-07-22Martin Nilsson  "\" width=\"1\" height=\"1\" alt=\"\" /></td></tr></table></td></tr>\n" " </table><table cellpadding=\"6\"><tr><td>\n"
2da8471997-08-20Per Hedbor  "<!-- The output from the page function -->\n" +form+ "\n<!-- End of the output from the page function -->\n" "\n</td></tr></table>\n"
9c15e11999-07-22Martin Nilsson  " <table width=\"100%\"><tr><td width=\"33%\">"+
29dfef1999-01-05Martin Stjernholm  (((automaton ? stringp (id->variables->_prev) : pageno>0) && wiz_name!="done")?
c96d642001-03-05Martin Nilsson  "\n <input type=submit name=prev_page value=\""+ LABEL(previous_label, LOCALE(54, "&lt;- Previous"))+"\" />":"")+
9c15e11999-07-22Martin Nilsson  "</td><td width=\"33%\" align=\"center\">"+
8492171998-02-19Mirar (Pontus Hagland)  (wiz_name!="done"
29dfef1999-01-05Martin Stjernholm  ?(((automaton ? !id->variables->_next : pageno==max_page)
5488931999-11-17Jonas Wallden  ?"\n&nbsp;&nbsp;<input type=\"submit\" name=\"ok\" value=\" "+
c96d642001-03-05Martin Nilsson  LABEL(ok_label, LOCALE(55, "OK"))+" \" />&nbsp;&nbsp;"
8492171998-02-19Mirar (Pontus Hagland)  :"")+
5488931999-11-17Jonas Wallden  "\n&nbsp;&nbsp;<input type=\"submit\" name=\"cancel\" value=\" "+
05cf862001-08-23Jonas Wallden  LABEL(cancel_label, LOCALE(56, "Cancel"))+" \" />&nbsp;&nbsp;")
c96d642001-03-05Martin Nilsson  :"\n <input type=\"submit\" name=\"cancel\" value=\" "+ LABEL(ok_label, LOCALE(55, "OK"))+" \" />")+
9c15e11999-07-22Martin Nilsson  "</td><td width=\"33%\" align=\"right\">"+
29dfef1999-01-05Martin Stjernholm  (((automaton ? stringp (id->variables->_next) : pageno!=max_page) && wiz_name!="done")?
c96d642001-03-05Martin Nilsson  "\n <input type=\"submit\" name=\"next_page\" value=\""+ LABEL(next_label, LOCALE(57, "Next -&gt;"))+"\" />":"")+
9c15e11999-07-22Martin Nilsson  "</td></tr></table>\n"
1cd7922000-03-01Marcus Wellhardh  " </td></tr>\n"
2da8471997-08-20Per Hedbor  " </table>\n" " </td></tr>\n"
0582051997-08-20Per Hedbor  "</table>\n"
9c15e11999-07-22Martin Nilsson  "</form>\n"
0582051997-08-20Per Hedbor  );
2da8471997-08-20Per Hedbor  return res; }
d22eee2011-04-06Martin Stjernholm mapping|string wizard_cancel_exit (mapping state, string default_return_url, RequestID id) { return http_redirect ((state->cancel_url && state->cancel_url[0]) || default_return_url || id->not_query, // id->conf check is probably just old crud. id->conf && id); } mapping|string wizard_done_exit (mapping state, string default_return_url, RequestID id) {
1f71c52011-04-06Martin Stjernholm  return http_redirect ((state->done_url && state->done_url[0]) || default_return_url || id->not_query,
d22eee2011-04-06Martin Stjernholm  // id->conf check is probably just old crud. id->conf && id); }
2da8471997-08-20Per Hedbor #define PAGE(X) ((string)(((int)v->_page)+(X)))
8bb3972011-05-28Martin Stjernholm mapping(string:array) wizard_get_state (RequestID id) //! Decodes the wizard state and incorporates it into //! id->real_variables, letting existing variables override those from //! the wizard state. Returns the wizard state without overrides.
2da8471997-08-20Per Hedbor {
8bb3972011-05-28Martin Stjernholm  mapping(string:array) s = id->misc->wizard_state; if (s) return s;
7c1ccb1997-08-22Per Hedbor 
8bb3972011-05-28Martin Stjernholm  string state_str;
81a8142002-05-15Marcus Wellhardh #ifdef USE_WIZARD_COOKIE
8bb3972011-05-28Martin Stjernholm  state_str = id->real_variables->_page && id->cookies->WizardState;
81a8142002-05-15Marcus Wellhardh #else
8bb3972011-05-28Martin Stjernholm  state_str = id->real_variables->_state && id->real_variables->_state[0];
81a8142002-05-15Marcus Wellhardh #endif
8bb3972011-05-28Martin Stjernholm  if (state_str) s = decompress_state(state_str); else { s = ([]); if (this->return_to_referrer && !id->real_variables->_wiz_ret && id->referer && sizeof (id->referer)) { // Define return_to_referrer to use the Referer to go back to // the previous place after the wizard is done. This currently // doesn't use a stack, so if we're coming here from another // wizard return then we ignore the referrer so that the // ordinary "cancel" url is used instead.
40895b2011-06-17Martin Stjernholm  // // Note that this only works with the assumption that the // referring wizard (or other page) doesn't retain the _wiz_ret // variable in later links.
8bb3972011-05-28Martin Stjernholm  string referrer = id->referer[0]; if (!has_value (referrer, "&_wiz_ret=") && !has_value (referrer, "?_wiz_ret=")) { if (has_value (referrer, "?")) referrer += "&_wiz_ret="; else referrer += "?_wiz_ret=";
1f71c52011-04-06Martin Stjernholm  }
8bb3972011-05-28Martin Stjernholm  s->cancel_url = s->done_url = ({referrer});
1f71c52011-04-06Martin Stjernholm  } }
acf6eb1998-07-30Johan Schön 
8bb3972011-05-28Martin Stjernholm  mapping(string:array) vars = id->real_variables;
1663eb2011-05-28Martin Stjernholm  foreach(s; string q; array var)
8bb3972011-05-28Martin Stjernholm  if (!vars[q]) vars[q] = var; return id->misc->wizard_state = s; }
4e0d212016-01-22Jonas Walldén protected void reset_buttons(FakedVariables v)
28ac782016-01-11Henrik Grubbström (Grubba) { m_delete (v, "next_page"); m_delete (v, "next_page.x"); m_delete (v, "next_page.y"); m_delete (v, "prev_page"); m_delete (v, "prev_page.x"); m_delete (v, "prev_page.y"); m_delete (v, "ok"); m_delete (v, "ok.x"); m_delete (v, "ok.y"); }
8bb3972011-05-28Martin Stjernholm mapping|string wizard_for(RequestID id,string cancel,mixed ... args) { string data; int offset = 1; string wiz_name = "page_"; mapping(string:array) s = wizard_get_state (id);
a8e00e2004-01-22Jonas Wallden  if(id->real_variables->cancel || id->real_variables["cancel.x"])
d22eee2011-04-06Martin Stjernholm  return wizard_cancel_exit (s, cancel, id);
42ae312001-02-05Per Hedbor 
8af8352006-05-31Jonas Wallden  // Handle double posting of variables in select override widgets foreach(Array.uniq(id->real_variables->__select_override_vars || ({ }) ), string override_combo) { [string override_var, string override_marker] = override_combo / ":"; array(string) override_info = id->real_variables[override_var]; if (sizeof(override_info) > 1) { string override_value = override_info[0]; if (override_value != override_info[1]) { if (override_value == override_marker) { override_value = override_info[1]; #if 0 } else if (override_info[1] == override_marker) { /* Already ok. */ } else { /* Ambiguous case. Warn? */ #endif /* 0 */ } } id->real_variables[override_var] = ({ override_value }); } }
42ae312001-02-05Per Hedbor  FakedVariables v=id->variables;
2fec621997-11-23Mirar (Pontus Hagland) 
04f1582002-06-10Jonas Wallden  int current_page = (int) v->_page;
c453f82018-01-17Karl Gustav Sterneberg  string wizard_id = Roxen.get_wizard_id_cookie(id);
85c1492016-01-12Henrik Grubbström (Grubba)  if (!sizeof(wizard_id || "")) {
dfb2082018-01-03Henrik Grubbström (Grubba)  // Create a new cookie. // Set the secure flag on the cookie if accessed over https [WS-135]. // NB: The cookie is used from Javascript, so it can't have // httponly set.
19a0452018-01-19Karl Gustav Sterneberg  wizard_id = Roxen.set_wizard_id_cookie(id);
85c1492016-01-12Henrik Grubbström (Grubba)  DEBUGMSG(sprintf("Wizard: Generated new wizard_id: %s\n", wizard_id)); } if (wizard_id != id->variables["_roxen_wizard_id"]) { // Invalid or unset roxen_wizard_id. if (current_page) { report_warning("Wizard: Invalid wizard_id: %O != %O.\n" "Resetting page from %O to 0.\n", v["_roxen_wizard_id"], wizard_id, current_page); } // Correct it, and return to page #0. id->real_variables["_roxen_wizard_id"] = ({ wizard_id }); current_page = 0; m_delete(id->real_variables, "_page"); m_delete(v, "_page"); // Also reset some typical action buttons as a preventive measure. reset_buttons(v); // FIXME: Do we need to reset any other variables? }
29dfef1999-01-05Martin Stjernholm  mapping(string:array) automaton = this_object()->wizard_automaton;
e45f381999-01-10Martin Stjernholm  function dispatcher;
29dfef1999-01-05Martin Stjernholm  string oldpage, page_name;
a8e00e2004-01-22Jonas Wallden  if (automaton && (!v->_page || v->next_page || v["next_page.x"] || v->prev_page || v["prev_page.x"] || v->ok || v["ok.x"])) {
29dfef1999-01-05Martin Stjernholm  if (!v->_page && automaton->start) v->_page = "start"; oldpage = v->_page; if (v->_page) { array page_state = automaton[v->_page]; if (!page_state) return "Internal error in wizard code: " "No entry " + v->_page + " in automaton."; function|string redirect = page_state[0]; if (functionp (redirect)) {
e45f381999-01-10Martin Stjernholm  dispatcher = redirect;
29dfef1999-01-05Martin Stjernholm  DEBUGMSG (sprintf ("Wizard: Running dispatch function %O for page %s\n", redirect, v->_page)); redirect = redirect (id, v->_page, @args); } if (stringp (redirect) && redirect != v->_page) { DEBUGMSG ("Wizard: Internal redirect to page " + redirect + "\n"); // Redirect takes precedence over the user choice.
28ac782016-01-11Henrik Grubbström (Grubba)  reset_buttons(v);
29dfef1999-01-05Martin Stjernholm  v->_page = redirect; } } }
a8e00e2004-01-22Jonas Wallden  if(v->next_page || v["next_page.x"])
7c1ccb1997-08-22Per Hedbor  {
29dfef1999-01-05Martin Stjernholm  function c=this_object()["verify_"+v->_page]; int fail = 0; if (functionp (c)) { fail = c (id, @args); DEBUGMSG (sprintf ("Wizard: Verify function %O %s\n", c, fail ? "failed" : "succeeded")); } if (!fail) { v->_page = automaton ? v->_next : PAGE(1); DEBUGMSG ("Wizard: Going to next page\n"); }
7c1ccb1997-08-22Per Hedbor  }
a8e00e2004-01-22Jonas Wallden  else if(v->prev_page || v["prev_page.x"])
2da8471997-08-20Per Hedbor  {
29dfef1999-01-05Martin Stjernholm  v->_page = automaton ? v->_prev : PAGE(-1); DEBUGMSG ("Wizard: Going to previous page\n");
2da8471997-08-20Per Hedbor  offset=-1; }
a8e00e2004-01-22Jonas Wallden  else if(v->ok || v["ok.x"])
7c1ccb1997-08-22Per Hedbor  {
29dfef1999-01-05Martin Stjernholm  function c=this_object()["verify_"+v->_page]; int fail = 0; if (functionp (c)) { fail = c (id, @args); DEBUGMSG (sprintf ("Wizard: Verify function %O %s\n", c, fail ? "failed" : "succeeded"));
beaca01998-02-20Per Hedbor  }
29dfef1999-01-05Martin Stjernholm  if(!fail) if (automaton) v->_page = 0; // Handle done state in the automaton code below. else { mixed res; if(c=this_object()->wizard_done) { DEBUGMSG ("Wizard: \"Ok\" pressed; running wizard_done\n"); res = c(id,@args); } if(res != -1)
d22eee2011-04-06Martin Stjernholm  return res || wizard_done_exit (s, cancel, id);
29dfef1999-01-05Martin Stjernholm  DEBUGMSG ("Wizard: -1 from wizard_done; continuing\n"); }
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";
10c7e11999-12-28Martin Nilsson  }
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);
10c7e11999-12-28Martin Nilsson  }
6796b01997-08-20Per Hedbor  }
29dfef1999-01-05Martin Stjernholm  if (automaton) { int i = 0; while (1) { if (++i == 4711) return "Internal error in wizard code: " "Probably infinite redirect loop in automaton."; if (v->_page == "cancel") {
d22eee2011-04-06Martin Stjernholm  DEBUGMSG ("Wizard: Canceling\n"); return wizard_cancel_exit (s, cancel, id);
29dfef1999-01-05Martin Stjernholm  } if (!v->_page) v->_page = "done", oldpage = 0; function|string redirect = 0; array page_state = automaton[v->_page]; if (!page_state && v->_page != "done") return "Internal error in wizard code: No entry " + v->_page + " in automaton."; if (page_state && v->_page != oldpage) { redirect = page_state[0]; if (functionp (redirect)) {
7052192009-11-27Stefan Wallström  dispatcher = redirect; DEBUGMSG (sprintf ("Wizard: Running dispatch function %O for page %s\n", dispatcher, v->_page)); redirect = dispatcher (id, v->_page, @args);
29dfef1999-01-05Martin Stjernholm  } else dispatcher = 0; } oldpage = 0; if (redirect && redirect != v->_page) { DEBUGMSG ("Wizard: Internal redirect to page " + redirect + "\n"); v->_page = redirect; } else if (v->_page == "done") { function donefn = this_object()->wizard_done; if (!functionp (donefn)) return "Internal error in wizard code: No wizard_done function."; DEBUGMSG ("Wizard: Running wizard_done\n"); data = donefn (id, @args);
d22eee2011-04-06Martin Stjernholm  if (!data) return wizard_done_exit (s, cancel, id);
29dfef1999-01-05Martin Stjernholm  wiz_name = "done"; break; } else { function pagefn = this_object()[wiz_name + v->_page]; if (!functionp (pagefn)) return "Internal error in wizard code: " "No page function for " + v->_page + "."; DEBUGMSG (sprintf ("Wizard: Running page function %O\n", pagefn)); data = pagefn (id, @args); if (data) { id->variables->_prev = functionp (page_state[1]) ? page_state[1] (id, v->_page, @args) : page_state[1]; id->variables->_next = functionp (page_state[2]) ? page_state[2] (id, v->_page, @args) : page_state[2]; // So that dispatch functions may be used for prev/next too. if ((<"cancel", "done">)[id->variables->_prev]) id->variables->_prev = 0; if ((<"cancel", "done">)[id->variables->_next]) id->variables->_next = 0; page_name = sizeof (page_state) < 4 ? "" : functionp (page_state[3]) ? page_state[3] (id, v->_page, @args) : page_state[3]; DEBUGMSG ("Wizard: prev_page " + id->variables->_prev + ", next_page " + id->variables->_next + ", page_name \"" + page_name + "\"\n"); break; } else { int dir = offset > 0 ? 2 : 1; v->_page = functionp (page_state[dir]) ? page_state[dir] (id, v->_page, @args) : page_state[dir]; DEBUGMSG ("Wizard: No data from page function; going to " + (stringp (v->_page) ? (offset > 0 ? "next" : "previous") +
e6c9341999-01-09Martin Stjernholm  " page " + v->_page : "done page") + "\n");
29dfef1999-01-05Martin Stjernholm  if (!stringp (v->_page)) v->_page = 0; } }
b26e8a1998-06-29Marcus Comstedt  }
2da8471997-08-20Per Hedbor  }
04f1582002-06-10Jonas Wallden  else {
29dfef1999-01-05Martin Stjernholm  for(; !data; v->_page=PAGE(offset)) { function pg=this_object()[wiz_name+((int)v->_page)]; function c = !pg && this_object()["wizard_done"]; if(functionp(c)) { DEBUGMSG ("Wizard: Running wizard_done\n"); mixed res = c(id,@args);
10c7e11999-12-28Martin Nilsson  if(res != -1)
d22eee2011-04-06Martin Stjernholm  return res || wizard_done_exit (s, cancel, id);
29dfef1999-01-05Martin Stjernholm  } if(!pg) return "Internal error in wizard code: Invalid page ("+v->_page+")!"; DEBUGMSG (sprintf ("Wizard: Running page function %O\n", pg)); if(data = pg(id,@args)) break; DEBUGMSG ("Wizard: No data from page function; going to " + (offset > 0 ? "next" : "previous") + " page\n");
04f1582002-06-10Jonas Wallden  // If going backwards and we end up on a negative page (e.g. due to // intermediate pages returning 0) we remain on current page. This is // done so that wizards which skip pages in the beginning won't result // in wizard_done() when trying to step into hidden pages. if ((offset < 0) && ((int) v->_page <= 0)) { v->_page = current_page; pg = this_object()[wiz_name + ((int) v->_page)]; if (pg && (data = pg(id, @args))) break; }
29dfef1999-01-05Martin Stjernholm  }
04f1582002-06-10Jonas Wallden  }
29dfef1999-01-05Martin Stjernholm 
b950c11998-03-13Francesco Chemolli  // If it's a mapping we can presume it is an http response, and return // it directly. if (mappingp(data)) return data;
29dfef1999-01-05Martin Stjernholm  return parse_wizard_page(data,id,wiz_name,page_name);
2da8471997-08-20Per Hedbor }
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-="/";
57e7992000-04-19Martin Nilsson  object w = wizards[dir+act]; if(!w) w = wizards[dir+act] = compile_file(dir+act)(@args); return w;
4bb6411997-08-20Per Hedbor }
7c1ccb1997-08-22Per Hedbor 
add34e2000-08-17Per Hedbor int zonk=time(1);
f98e321999-11-29Per Hedbor mapping get_actions(RequestID id, string base,string dir, array args)
6cc9811997-08-20Per Hedbor { mapping acts = ([ ]);
f7758f2001-03-07Jonas Wallden  // Cannot clear wizard cache since it will trigger massive recompiles of // wizards from inside SiteBuilder. It also breaks wizards which use // persistent storage. // // if(id->pragma["no-cache"]) wizards=([]);
aa78422001-09-10Fredrik Noring  foreach(get_dir(dir) - ({ ".distignore" }), string act)
6cc9811997-08-20Per Hedbor  { mixed err;
b796b51998-11-18Per Hedbor  object e;
31463c1999-12-06Marcus Wellhardh  master()->set_inhibit_compile_errors(e = ErrorContainer());
6cc9811997-08-20Per Hedbor  err = catch {
bd74201999-05-07Martin Stjernholm  if(!(<'#', '_'>)[act[0]] && act[-1]=='e')
6cc9811997-08-20Per Hedbor  { 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);
7c99042009-03-13Anders Johansson  if(!acts[sm]) acts[sm] = ({ });
fc83ef1998-02-21Johan Schön  if(id->misc->raw_wizard_actions)
7c99042009-03-13Anders Johansson  { // This is probably dead code. if(!sizeof(acts[sm])) acts[sm] += ({ ([]) });
fc83ef1998-02-21Johan Schön  acts[sm][0][name]= ({ name, base, (["action":act,"unique":(string)(zonk++) ]), (get_wizard(act,dir,@args)->doc||"") });
7c99042009-03-13Anders Johansson  }
fc83ef1998-02-21Johan Schön  else acts[sm]+= ({"<!-- "+rn+" --><dt><font size=\"+2\">"
6cc9811997-08-20Per Hedbor  "<a href=\""+base+"?action="+act+"&unique="+(zonk++)+"\">"+ name+"</a></font><dd>"+(get_wizard(act,dir,@args)->doc||"")}); } };
17d6d12000-03-30Per Hedbor  if( strlen( e->get_warnings() ) ) report_warning( e->get_warnings() );
31463c1999-12-06Marcus Wellhardh  if(strlen(e->get()))
b796b51998-11-18Per Hedbor  error("While compiling wizards:\n"+e->get());
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+=
9c15e11999-07-22Martin Nilsson  (s==sel?"<li>":"<font color=\"#eeeeee\"><li></font><a href=\""+base+"?sm="+replace(s||"Misc"," ","%20")+
6796b01997-08-20Per Hedbor  "&uniq="+(++zonk)+"\">")+(s||"Misc")+
9c15e11999-07-22Martin Nilsson  (s==sel?"<br />":"</a><br />")+"";
6796b01997-08-20Per Hedbor  return res + "</font>";
6cc9811997-08-20Per Hedbor } string focused_wizard_menu;
f98e321999-11-29Per Hedbor mixed wizard_menu(RequestID id, string dir, string base, mixed ... args)
6cc9811997-08-20Per Hedbor { mapping acts;
8bb3972011-05-28Martin Stjernholm 
f7758f2001-03-07Jonas Wallden  // Cannot clear wizard cache since it will trigger massive recompiles of // wizards from inside SiteBuilder. It also breaks wizards which use // persistent storage. // // 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;
10c7e11999-12-28Martin Nilsson 
4bb6411997-08-20Per Hedbor  if(!id->variables->action) {
4b7b611997-10-24Fredrik Noring  mixed wizbug; wizbug = catch {
fc83ef1998-02-21Johan Schön  mapping acts = get_actions(id, base, dir, args); if(id->misc->raw_wizard_actions) return acts[id->variables->sm];
62d8c41997-10-16Per Hedbor  string res;
b6f5ae2009-04-08Jonas Wallden  string submenus = act_describe_submenues(indices(acts),base,id->variables->sm); if (sizeof(submenus)) { submenus = "<td valign='top' bgcolor='#eeeeee'>" + submenus + "</td>\n"; } res= ("<table cellpadding=\"3\"><tr>" + submenus + "<td valign=\"top\">"+
9c15e11999-07-22Martin Nilsson  (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 {
88612d2000-08-08Martin Stjernholm  // We commonly feed the action variable both from the URL with // "...?action=foo.pike" and with an <input> tag from the previous // page. Netscape ignores one of them, but IE sends both. Thus we // have to discard the extra value in the IE case. (We simply assume // both values are the same here; maybe it could be done better.) id->variables->action = (id->variables->action/"\0")[0];
4b7b611997-10-24Fredrik Noring  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 ***/
8b10b91998-02-15Fredrik Noring string format_numeric(string s, string|void sep)
1c5e031997-08-20Fredrik Noring {
8b10b91998-02-15Fredrik Noring  sep = reverse(sep||"&nbsp;"); array(string) as = s/" "; string t = "";
cab22a2000-11-14Martin Nilsson  s = reverse(as[0]);
8b10b91998-02-15Fredrik Noring  while(sizeof(s)) { if(sizeof(s) > 3) t += s[0..2]+sep; else t += s; s = s[3..]; }
10c7e11999-12-28Martin Nilsson  return (({reverse(t)})+as[1..])*" ";
8b10b91998-02-15Fredrik Noring } string html_table(array(string) subtitles, array(array(string)) table, mapping|void opt) { /* Options:
7de86c1999-07-23Martin Nilsson  * bordercolor, titlebgcolor, titlecolor, oddbgcolor, evenbgcolor, modulo
8b10b91998-02-15Fredrik Noring  * Containers: * <fields>[num|text, ...]</fields> */
f74b131999-07-24Martin Nilsson  if(!opt) opt = ([]);
24c6c12000-02-20Martin Nilsson  // RXML <2.0 compatibility stuff
7de86c1999-07-23Martin Nilsson  if(opt->fgcolor0) { opt->oddbgcolor=opt->fgcolor0; m_delete(opt, "fgcolor0"); } if(opt->fgcolor1) { opt->evenbgcolor=opt->fgcolor1; m_delete(opt, "fgcolor1"); } if(opt->bgcolor) { opt->bordercolor=opt->bgcolor; m_delete(opt, "bgcolor"); }
1c5e031997-08-20Fredrik Noring  string r = "";
8b10b91998-02-15Fredrik Noring  int m = (int)(opt->modulo?opt->modulo:1);
7de86c1999-07-23Martin Nilsson  r += ("<table bgcolor=\""+(opt->bordercolor||"#000000")+"\" border=\"0\" "
9c15e11999-07-22Martin Nilsson  "cellspacing=\"0\" cellpadding=\"1\">\n"
2ebb571997-08-21Per Hedbor  "<tr><td>\n");
9c15e11999-07-22Martin Nilsson  r += "<table border=\"0\" cellspacing=\"0\" cellpadding=\"4\">\n"; r += "<tr bgcolor=\""+(opt->titlebgcolor||"#113377")+"\">\n";
6420831997-08-21Per Hedbor  int cols; foreach(subtitles, mixed s) { if(stringp(s)) {
9c15e11999-07-22Martin Nilsson  r+=("<th nowrap=\"nowrap\" align=\"left\"><font color=\""+ (opt->titlecolor||"#ffffff")+"\">"+s+" &nbsp; </font></th>");
6420831997-08-21Per Hedbor  cols++; } else {
9c15e11999-07-22Martin Nilsson  r+=("</tr><tr bgcolor=\""+(opt->titlebgcolor||"#113377")+"\">" "<th nowrap=\"nowrap\" align=\"left\" colspan=\""+cols+"\">" "<font color=\""+(opt->titlecolor||"#ffffff")+"\">"+s[0]+
8b10b91998-02-15Fredrik Noring  " &nbsp; </font></th>");
6420831997-08-21Per Hedbor  }
10c7e11999-12-28Martin Nilsson  }
1c5e031997-08-20Fredrik Noring  r += "</tr>";
10c7e11999-12-28Martin Nilsson 
1c5e031997-08-20Fredrik Noring  for(int i = 0; i < sizeof(table); i++) {
8b10b91998-02-15Fredrik Noring  string tr;
7de86c1999-07-23Martin Nilsson  r += tr = "<tr bgcolor="+((i/m)%2?opt->evenbgcolor||"#ddeeff": opt->oddbgcolor||"#ffffff")+">";
8b10b91998-02-15Fredrik Noring  for(int j = 0; j < sizeof(table[i]); j++) { mixed s = table[i][j];
8609241997-08-23Henrik Grubbström (Grubba)  if(arrayp(s))
9c15e11999-07-22Martin Nilsson  r += "</tr>"+tr+"<td colspan=\""+cols+"\">"+s[0]+" &nbsp;</td>";
8b10b91998-02-15Fredrik Noring  else { string type = "text"; if(arrayp(opt->fields) && j < sizeof(opt->fields)) type = opt->fields[j]; switch(type) { case "num": array a = s/".";
9c15e11999-07-22Martin Nilsson  r += "<td nowrap=\"nowrap\" align=\"right\">";
8b10b91998-02-15Fredrik Noring  if(sizeof(a) > 1) { r += (format_numeric(a[0])+"."+ reverse(format_numeric(reverse(a[1]), ";psbn&"))); } else r += format_numeric(s, "&nbsp;"); break;
2af8301999-03-22Zsolt Varga  case "right":
9c15e11999-07-22Martin Nilsson  r += "<td align=\"right\">"+s;
2af8301999-03-22Zsolt Varga  break; case "center":
9c15e11999-07-22Martin Nilsson  r += "<td align=\"center\">"+s;
2af8301999-03-22Zsolt Varga  break; case "left":
9c15e11999-07-22Martin Nilsson  r += "<td align=\"left\">"+s;
2af8301999-03-22Zsolt Varga  break;
8b10b91998-02-15Fredrik Noring  case "text": default:
9c15e11999-07-22Martin Nilsson  r += "<td nowrap=\"nowrap\">"+s;
8b10b91998-02-15Fredrik Noring  }
b0ae391999-10-04Jonas Wallden  // Simple heuristics to detect cells containing a table, image etc // where trailing spaces will give really ugly results if (!(stringp(s) && (strlen(s) > 2)
3258411999-12-08Jonas Wallden  && (< "<img ", "<tabl", "<gtex", "<var ", "<pre>", "<sb-i" >)[s[0..4]]
b0ae391999-10-04Jonas Wallden  && (s[-1] == '>' || s[-2] == '>'))) { r += "&nbsp;&nbsp;"; } r += "</td>";
8b10b91998-02-15Fredrik Noring  } }
1c5e031997-08-20Fredrik Noring  r += "</tr>\n"; }
1e5ee81997-08-21Per Hedbor  r += "</table></td></tr>\n";
caa2891999-10-07Jonas Wallden  r += "</table>" /* +(opt->noxml?"<br>":"<br />")+ */ "\n";
1c5e031997-08-20Fredrik Noring  return r; }
6796b01997-08-20Per Hedbor 
2ebb571997-08-21Per Hedbor 
f98e321999-11-29Per Hedbor string html_notice(string notice, RequestID id)
2ebb571997-08-21Per Hedbor {
7de86c1999-07-23Martin Nilsson  return ("<table><tr><td valign=\"top\"><img \nalt=\"Notice:\" src=\""+
2ebb571997-08-21Per Hedbor  (id->conf?"/internal-roxen-":"/image/")
93f1262001-04-24Jonas Wallden  +"err_1.gif\" />&nbsp;&nbsp;</td><td valign=\"top\">"+notice+"</td></tr></table>");
2ebb571997-08-21Per Hedbor }
f98e321999-11-29Per Hedbor string html_warning(string notice, RequestID id)
2ebb571997-08-21Per Hedbor {
7de86c1999-07-23Martin Nilsson  return ("<table><tr><td valign=\"top\"><img \nalt=\"Warning:\" src=\""+
2ebb571997-08-21Per Hedbor  (id->conf?"/internal-roxen-":"/image/")
93f1262001-04-24Jonas Wallden  +"err_2.gif\" />&nbsp;&nbsp;</td><td valign=\"top\">"+notice+"</td></tr></table>");
2ebb571997-08-21Per Hedbor }
f98e321999-11-29Per Hedbor string html_error(string notice, RequestID id)
2ebb571997-08-21Per Hedbor {
9c15e11999-07-22Martin Nilsson  return ("<table><tr><td valign=\"top\"><img \nalt=\"Error:\" src=\""+
2ebb571997-08-21Per Hedbor  (id->conf?"/internal-roxen-":"/image/")
37a8352001-04-24Jonas Wallden  +"err_3.gif\" />&nbsp;&nbsp;</td><td valign=\"top\">"+notice+"</td></tr></table>");
2ebb571997-08-21Per Hedbor }
a683e81997-08-24Per Hedbor 
3d03581997-11-05David Hedbor string html_border(string what, int|void width, int|void ww, string|void bgcolor, string|void bdcolor)
a683e81997-08-24Per Hedbor {
9c15e11999-07-22Martin Nilsson  return ("<table border=\"0\" cellpadding=\""+(width+1)+"\" cellspacing=\"0\" " "bgcolor=\""+(bdcolor||"#000000")+ "\"><tr><td><table border=\"0\" cellpadding=\""+(ww)+ "\" cellspacing=\"0\" bgcolor=\""+(bgcolor||"#ffffff")+ "\"><tr><td>"+what+"</tr></td></table>"
4013561997-08-24Per Hedbor  "</td></tr></table>"); } void filter_checkbox_variables(mapping v) {
f0e2861998-05-14H. William Welliver III  foreach(indices(v), string s) { if(!v[s] || (v[s]=="0")) m_delete(v,s);
10c7e11999-12-28Martin Nilsson  else
f0e2861998-05-14H. William Welliver III  v[s]-="\00"; }
a683e81997-08-24Per Hedbor }