Exposing custom options in the web interface #2807

Closed
michaelrsweet opened this Issue Apr 18, 2008 · 4 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Apr 18, 2008

Version: -feature
CUPS.org User: larsuebernickel

Hi,

attached is a patch which adds support for setting custom options to the web interface. The patch is against 1.3.7, because svn wouldn't compile for me last night.

It basically adds a 'Custom' choice to all PickOne options (i.e. it doesn't hide it anymore). Whenever that choice is selected by the user, the parameters for that custom option are displayed and can be set. I used some javascript in the templates for that - I hope that's okay.

Open problems: For now, all parameter types are set via a simple text input and are not validated in any way. Also, Multi-parameter options have their parameters shown in alphabetic order, which is kind of weird for PageSize for example (first Height, then Width).

Please tell me what you think of it and if I'm headed in the right direction (This is my first time with the CUPS codebase ;) )

Lars

P.S: Slightly off topic: CUPS seems to ignore the *CustomFoo and *ParamCustomFoo keywords if they are between *OpenUI and *CloseUI. Is this intentional? I think it'd make more sense inside *OpenUI and *ClosUI ... The GTK+ printing dialog recognizes them in any case, and that's also the way I implemented it in foomatic-rip. The docs are not really clear about this either ...

Collaborator

michaelrsweet commented Apr 24, 2008

CUPS.org User: till.kamppeter

This was already reported as STR #1729 (http://www.cups.org/str.php?L1729).

Collaborator

michaelrsweet commented Apr 24, 2008

CUPS.org User: larsuebernickel

I've just applied the patch against the latest subversion code (revision 7493), and it works without problem.

Collaborator

michaelrsweet commented Apr 24, 2008

CUPS.org User: mike

This is a dupe of STR #1729; moving the patch over there, however your patch will still require a bit of work since we can't depend on Javascript for the user interface (that breaks text-only browsers which we do support).

Thanks for the patch!

Collaborator

michaelrsweet commented Apr 24, 2008

"cups-1.3.7-expose-coptions.patch":

diff -aur cups-1.3.7/cgi-bin/admin.c cups-1.3.7-mine/cgi-bin/admin.c
--- cups-1.3.7/cgi-bin/admin.c 2008-02-13 02:15:29.000000000 +0100
+++ cups-1.3.7-mine/cgi-bin/admin.c 2008-04-18 01:41:51.000000000 +0200
@@ -2735,6 +2735,54 @@
}
}

+/*

  • * 'get_coption_value_string' - Create the value string for the custom
  • * parameters of an option.
  • /
    +static void
    +get_coption_value_string(char *valstr, /
    O - Resulting value string */
  •        size_t size,       /\* I - Maximum size of valstr */
    
  •        ppd_coption_t _opt)    /_ I - Option */
    
    +{
  • ppd_cparam_t *cparam;
  • size_t pos;
  • char keyword[2*PPD_MAX_NAME];
  • const char *var, *var2;
  • if (!strcmp(opt->keyword, "PageSize"))
  • {
  • var = cgiGetVariable("PageSize.Width");
  • var2 = cgiGetVariable("PageSize.Height");
  • snprintf(valstr, size, "Custom.%sx%s", var ? var : "0", var2 ? var2 : "0");
  • }
  • else if (cupsArrayCount(opt->params) == 1)
  • {
  • cparam =ppdFirstCustomParam(opt);
  • snprintf(keyword, 2*PPD_MAX_NAME, "%s.%s", opt->keyword, cparam->name);
  • var = cgiGetVariable(keyword);
  • if (var)
  •  snprintf(valstr, size, "Custom.%s", var);
    
  • }
  • else if (cupsArrayCount(opt->params) >= 1)
  • {
  • valstr[0] = '{';
  • for (cparam = ppdFirstCustomParam(opt), pos = 1;
  • cparam && pos < size;
  • cparam = ppdNextCustomParam(opt))
  • {
  •  snprintf(keyword, 2 \* PPD_MAX_NAME, "%s.%s", opt->keyword, cparam->name);
    
  •  var = cgiGetVariable(keyword);
    
  •  if (!var)
    
  • continue;
  •  pos += snprintf(&valstr[pos], size - pos, "%s=%s, ", cparam->name, var);
    
  • }
  • /* Remove the last ',' */
  • if (pos > 3)
  •  strlcpy(&valstr[pos -3], "}", size);
    
  • }
    +}

/*

  • 'do_set_options()' - Configure the default options for a queue.
    @@ -2762,9 +2810,11 @@
    ppd_file_t ppd; / PPD file /
    ppd_group_t *group; /
    Option group /
    ppd_option_t *option; /
    Option */
  • ppd_coption_t coption; / Custom Option */
  • ppd_cparam_t cparam; / Custom param /
    ppd_attr_t *protocol; /
    cupsProtocol attribute /
    const char *title; /
    Page title */
  • char tmp[1024];

title = cgiText(is_class ? _("Set Class Options") : _("Set Printer Options"));

@@ -2910,7 +2960,7 @@

  cgiSetVariable("KEYWORD", option->keyword);
  cgiSetVariable("KEYTEXT", option->text);
    • if (option->conflicted)
      cgiSetVariable("CONFLICTED", "1");
      else
      @@ -2920,13 +2970,6 @@
      cgiSetSize("TEXT", 0);
      for (k = 0, m = 0; k < option->num_choices; k ++)
      {
  •  /*
    
  •   \* Hide custom option values...
    

- */

  •   if (!strcmp(option->choices[k].choice, "Custom"))
    

- continue;

    cgiSetArray("CHOICES", m, option->choices[k].choice);
    cgiSetArray("TEXT", m, option->choices[k].text);

@@ -2936,6 +2979,70 @@
cgiSetVariable("DEFCHOICE", option->choices[k].choice);
}

  • cgiSetVariable("SHOWPARAMS", "0");
    
  • cgiSetSize("PARAMS", 0);
    
  • cgiSetSize("PARAMTEXT", 0);
    
  • cgiSetSize("PARAMVALUE", 0);
    
  • cgiSetSize("INPUTTYPE", 0);
    
  • if ((coption = ppdFindCustomOption(ppd, option->keyword)))
    
  • {
    
  •   cgiSetVariable("ISCUSTOM", "1");
    
  •   /\* 'coption->marked' is not set? */
    
  •   var = cgiGetVariable("DEFCHOICE");
    
  •   if (var && !strcmp(var, "Custom"))
    
  •     cgiSetVariable("SHOWPARAMS", "1");
    
  •   /*
    
  •    \* TODO Can these be traversed sorted by their order? (The params
    
  •    \* for PageSize gets all messed up this way)
    
  •    */
    
  •   for (cparam = ppdFirstCustomParam(coption), m = 0;
    
  •    cparam;
    
  •    cparam = ppdNextCustomParam(coption))
    
  •   {
    
  •     cgiSetArray("PARAMS", m, cparam->name);
    
  •     cgiSetArray("PARAMTEXT", m, cparam->text);
    
  •     switch (cparam->type) {
    
  •   case PPD_CUSTOM_CURVE:
    
  •   case PPD_CUSTOM_INVCURVE:
    
  •   case PPD_CUSTOM_REAL:
    
  •   case PPD_CUSTOM_POINTS:
    
  •       snprintf(tmp, 50, "%f", cparam->current.custom_real);
    
  •       cgiSetArray("PARAMVALUE", m, tmp);
    
  •       cgiSetArray("INPUTTYPE", m, "text");
    
  •       break;
    
  •   case PPD_CUSTOM_INT:
    
  •       snprintf(tmp, 50, "%d", cparam->current.custom_int);
    
  •       cgiSetArray("PARAMVALUE", m, tmp);
    
  •       cgiSetArray("INPUTTYPE", m, "text");
    
  •       break;
    
  •   case PPD_CUSTOM_PASSCODE:
    
  •   case PPD_CUSTOM_PASSWORD:
    
  •       if (cparam->current.custom_password)
    
  •         cgiSetArray("PARAMVALUE", m, cparam->current.custom_password);
    
  •       else
    
  •         cgiSetArray("PARAMVALUE", m, "");
    
  •       cgiSetArray("INPUTTYPE", m, "password");
    
  •       break;
    
  •   case PPD_CUSTOM_STRING:
    
  •       if (cparam->current.custom_string)
    
  •         cgiSetArray("PARAMVALUE", m, cparam->current.custom_string);
    
  •       else
    
  •         cgiSetArray("PARAMVALUE", m, "");
    
  •       cgiSetArray("INPUTTYPE", m, "text");
    
  •       break;
    
  •     }
    
  •     m++;
    
  •   }
    
  • }
    
  • else
    
  •   cgiSetVariable("ISCUSTOM", "0");
    
    • switch (option->ui)
      {
      case PPD_UI_BOOLEAN :
      @@ -2949,8 +3056,14 @@
      break;
      }
      }
    cgiCopyTemplateLang("option-trailer.tmpl");
    +
  • /* Clear some cgi vars (for future options) */
  • cgiSetVariable("ISCUSTOM", "0");
  • cgiSetSize("PARAMS", 0);
  • cgiSetSize("PARAMTEXT", 0);
  • cgiSetSize("PARAMVALUE", 0);
  • cgiSetSize("INPUTTYPE", 0);
    }
    }

@@ -3185,10 +3298,15 @@
else
var = cgiGetVariable(keyword);

  • if (var != NULL)
    
  •   cupsFilePrintf(out, "*Default%s: %s\n", keyword, var);
    
  • else
    
  • if (var == NULL)
    cupsFilePrintf(out, "%s\n", line);
    
  • else if (!strcmp(var, "Custom") && (coption = ppdFindCustomOption(ppd, keyword)))
    
  • {
    
  •   get_coption_value_string(tmp, 1024, coption);
    
  •   cupsFilePrintf(out, "*Default%s: %s\n", keyword, tmp);
    
  • }
    
  • else
    
  •   cupsFilePrintf(out, "*Default%s: %s\n", keyword, var);
    
    }
    }

Only in cups-1.3.7-mine/cgi-bin: tags
diff -aur cups-1.3.7/cups/options.c cups-1.3.7-mine/cups/options.c
--- cups-1.3.7/cups/options.c 2008-01-29 00:10:10.000000000 +0100
+++ cups-1.3.7-mine/cups/options.c 2008-04-18 01:44:59.000000000 +0200
@@ -474,6 +474,7 @@
quote; /* Quote character */

  • /*
  • Range check input...
    */
    diff -aur cups-1.3.7/doc/cups.css cups-1.3.7-mine/doc/cups.css
    --- cups-1.3.7/doc/cups.css 2007-08-23 20:32:22.000000000 +0200
    +++ cups-1.3.7-mine/doc/cups.css 2008-04-17 15:00:00.000000000 +0200
    @@ -159,6 +159,12 @@
    vertical-align: top;
    }

+TH.sublabel {

  • padding-top: 0pt;
  • text-align: right;
  • font-weight: normal;
    +}

HR {
border: solid thin;
}
Only in cups-1.3.7-mine: rebuild
Only in cups-1.3.7-mine: tags
diff -aur cups-1.3.7/templates/option-pickone.tmpl cups-1.3.7-mine/templates/option-pickone.tmpl
--- cups-1.3.7/templates/option-pickone.tmpl 2005-11-23 04:14:35.000000000 +0100
+++ cups-1.3.7-mine/templates/option-pickone.tmpl 2008-04-17 23:55:15.000000000 +0200
@@ -1,6 +1,15 @@

{keytext}: - + {[choices]{text}} - + +{iscustom=1?{[params] - - - - +}
{paramtext}: - -
+:} diff -aur cups-1.3.7/templates/set-printer-options-header.tmpl cups-1.3.7-mine/templates/set-printer-options-header.tmpl --- cups-1.3.7/templates/set-printer-options-header.tmpl 2005-12-15 23:03:40.000000000 +0100 +++ cups-1.3.7-mine/templates/set-printer-options-header.tmpl 2008-04-17 16:44:41.000000000 +0200 @@ -1,3 +1,17 @@ + +<script type="text/javascript"> + +function choice_changed(sender) { - var cb = document.getElementById("select-" + sender) - var paramstable = document.getElementById(sender + "-params"); - if (cb.value == "Custom") - paramstable.style.display = "table"; - else - paramstable.style.display = "none"; +} + +</script> +

@michaelrsweet michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment