[gtk+] printing: Get output bin via IPP



commit 4e4a2fe17ef70e44dcd368cc927c9552d4f80b3b
Author: Marek Kasik <mkasik redhat com>
Date:   Tue Jun 23 13:28:21 2015 +0200

    printing: Get output bin via IPP
    
    Request "output-bin-supported" and "output-bin-default" attributes through
    IPP if there is no PPD for selected printer.
    Pass "output-bin" option with other options in printer_get_options().
    Translate standard IPP values of "output-bin" option.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725441

 modules/printbackends/cups/gtkprintbackendcups.c |  139 ++++++++++++++++++++--
 modules/printbackends/cups/gtkprintercups.c      |    5 +
 modules/printbackends/cups/gtkprintercups.h      |    2 +
 3 files changed, 135 insertions(+), 11 deletions(-)
---
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c 
b/modules/printbackends/cups/gtkprintbackendcups.c
index 05b03bc..242ba3a 100644
--- a/modules/printbackends/cups/gtkprintbackendcups.c
+++ b/modules/printbackends/cups/gtkprintbackendcups.c
@@ -1939,6 +1939,8 @@ static const char * const printer_attrs_detailed[] =
     "media-top-margin-supported",
     "sides-default",
     "sides-supported",
+    "output-bin-default",
+    "output-bin-supported",
   };
 
 typedef enum
@@ -1996,6 +1998,8 @@ typedef struct
   GList    *sides_supported;
   char    **covers;
   int       number_of_covers;
+  gchar    *output_bin_default;
+  GList    *output_bin_supported;
 } PrinterSetupInfo;
 
 static void
@@ -2365,6 +2369,17 @@ cups_printer_handle_attribute (GtkPrintBackendCups *cups_backend,
 
       info->media_size_supported = g_list_reverse (info->media_size_supported);
     }
+  else if (g_strcmp0 (ippGetName (attr), "output-bin-default") == 0)
+    {
+      info->output_bin_default = g_strdup (ippGetString (attr, 0, NULL));
+    }
+  else if (g_strcmp0 (ippGetName (attr), "output-bin-supported") == 0)
+    {
+      for (i = 0; i < ippGetCount (attr); i++)
+        info->output_bin_supported = g_list_prepend (info->output_bin_supported, g_strdup (ippGetString 
(attr, i, NULL)));
+
+      info->output_bin_supported = g_list_reverse (info->output_bin_supported);
+    }
   else
     {
       GTK_NOTE (PRINTING,
@@ -2673,6 +2688,8 @@ cups_request_printer_info_cb (GtkPrintBackendCups *cups_backend,
             }
           GTK_PRINTER_CUPS (printer)->sides_default = info->sides_default;
           GTK_PRINTER_CUPS (printer)->sides_supported = info->sides_supported;
+          GTK_PRINTER_CUPS (printer)->output_bin_default = info->output_bin_default;
+          GTK_PRINTER_CUPS (printer)->output_bin_supported = info->output_bin_supported;
 
           gtk_printer_set_has_details (printer, TRUE);
           g_signal_emit_by_name (printer, "details-acquired", TRUE);
@@ -4306,6 +4323,7 @@ static const struct {
   const char *translation;
 } ipp_option_translations[] = {
   { "sides", "gtk-duplex", N_("Two Sided") },
+  { "output-bin", "gtk-output-tray", N_("Output Tray") },
 };
 
 static const struct {
@@ -4318,6 +4336,37 @@ static const struct {
   { "sides", "two-sided-long-edge", NC_("sides", "Long Edge (Standard)") },
   /* Translators: this is an option of "Two Sided" */
   { "sides", "two-sided-short-edge", NC_("sides", "Short Edge (Flip)") },
+
+  /* Translators: Top output bin */
+  { "output-bin", "top", NC_("output-bin", "Top Bin") },
+  /* Translators: Middle output bin */
+  { "output-bin", "middle", NC_("output-bin", "Middle Bin") },
+  /* Translators: Bottom output bin */
+  { "output-bin", "bottom", NC_("output-bin", "Bottom Bin") },
+  /* Translators: Side output bin */
+  { "output-bin", "side", NC_("output-bin", "Side Bin") },
+  /* Translators: Left output bin */
+  { "output-bin", "left", NC_("output-bin", "Left Bin") },
+  /* Translators: Right output bin */
+  { "output-bin", "right", NC_("output-bin", "Right Bin") },
+  /* Translators: Center output bin */
+  { "output-bin", "center", NC_("output-bin", "Center Bin") },
+  /* Translators: Rear output bin */
+  { "output-bin", "rear", NC_("output-bin", "Rear Bin") },
+  /* Translators: Output bin where one sided output is oriented in the face-up position */
+  { "output-bin", "face-up", NC_("output-bin", "Face Up Bin") },
+  /* Translators: Output bin where one sided output is oriented in the face-down position */
+  { "output-bin", "face-down", NC_("output-bin", "Face Down Bin") },
+  /* Translators: Large capacity output bin */
+  { "output-bin", "large-capacity", NC_("output-bin", "Large Capacity Bin") },
+  /* Translators: Output stacker number %d */
+  { "output-bin", "stacker-N", NC_("output-bin", "Stacker %d") },
+  /* Translators: Output mailbox number %d */
+  { "output-bin", "mailbox-N", NC_("output-bin", "Mailbox %d") },
+  /* Translators: Private mailbox */
+  { "output-bin", "my-mailbox", NC_("output-bin", "My Mailbox") },
+  /* Translators: Output tray number %d */
+  { "output-bin", "tray-N", NC_("output-bin", "Tray %d") },
 };
 
 static const struct {
@@ -5036,18 +5085,47 @@ static gchar *
 get_ipp_choice_translation (const gchar  *ipp_option_name,
                             const gchar  *ipp_choice)
 {
-  gchar *translation = NULL;
-  gint   i;
+  const gchar *nptr;
+  guint64      index;
+  gchar       *translation = NULL;
+  gsize        ipp_choice_length;
+  gchar       *endptr;
+  gint         i;
 
   for (i = 0; i < G_N_ELEMENTS (ipp_choice_translations); i++)
     {
-      if (g_strcmp0 (ipp_choice_translations[i].ipp_option_name, ipp_option_name) == 0 &&
-          g_strcmp0 (ipp_choice_translations[i].ipp_choice, ipp_choice) == 0)
+      if (g_strcmp0 (ipp_choice_translations[i].ipp_option_name, ipp_option_name) == 0)
         {
-          translation = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE,
-                                                ipp_option_name,
-                                                ipp_choice_translations[i].translation));
-          break;
+          ipp_choice_length = strlen (ipp_choice_translations[i].ipp_choice);
+
+          if (g_strcmp0 (ipp_choice_translations[i].ipp_choice, ipp_choice) == 0)
+            {
+              translation = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE,
+                                                    ipp_option_name,
+                                                    ipp_choice_translations[i].translation));
+              break;
+            }
+          else if (g_str_has_suffix (ipp_choice_translations[i].ipp_choice, "-N") &&
+                   g_ascii_strncasecmp (ipp_choice_translations[i].ipp_choice,
+                                        ipp_choice,
+                                        ipp_choice_length - 2) == 0)
+            {
+              /* Find out index of the ipp_choice if it is supported for the choice. */
+              endptr = NULL;
+              nptr = ipp_choice + ipp_choice_length - 1;
+              index = g_ascii_strtoull (nptr,
+                                        &endptr,
+                                        10);
+
+              if (index != 0 || endptr != nptr)
+                {
+                  translation = g_strdup_printf (g_dpgettext2 (GETTEXT_PACKAGE,
+                                                               ipp_option_name,
+                                                               ipp_choice_translations[i].translation),
+                                                 index);
+                  break;
+                }
+            }
         }
     }
 
@@ -5055,6 +5133,37 @@ get_ipp_choice_translation (const gchar  *ipp_option_name,
 }
 
 /*
+ * Format an IPP choice to a displayable string.
+ */
+static gchar *
+format_ipp_choice (const gchar *ipp_choice)
+{
+  gboolean  after_space = TRUE;
+  gchar    *result = NULL;
+  gsize     i;
+
+  if (ipp_choice != NULL)
+    {
+      result = g_strdup (ipp_choice);
+      /* Replace all '-' by spaces. */
+      result = g_strdelimit (result, "-", ' ');
+      if (g_str_is_ascii (result))
+        {
+          /* Convert all leading characters to upper case. */
+          for (i = 0; i < strlen (result); i++)
+            {
+              if (after_space && g_ascii_isalpha (result[i]))
+                result[i] = g_ascii_toupper (result[i]);
+
+              after_space = g_ascii_isspace (result[i]);
+            }
+        }
+    }
+
+  return result;
+}
+
+/*
  * Look the IPP option up in given set of options.
  * Create it if it doesn't exist and set its default value
  * if available.
@@ -5109,7 +5218,7 @@ setup_ipp_option (gchar               *ipp_option_name,
           if (translation != NULL)
             choices_display[i] = translation;
           else
-            choices_display[i] = g_strdup (ipp_choice);
+            choices_display[i] = format_ipp_choice (ipp_choice);
 
           i++;
         }
@@ -5392,6 +5501,14 @@ cups_printer_get_options (GtkPrinter           *printer,
 
       if (option != NULL)
         set_option_from_settings (option, settings);
+
+      option = setup_ipp_option ("output-bin",
+                                 cups_printer->output_bin_default,
+                                 cups_printer->output_bin_supported,
+                                 set);
+
+      if (option != NULL)
+        set_option_from_settings (option, settings);
     }
 
   /* Now honor the user set defaults for this printer */
@@ -5793,7 +5910,7 @@ set_option_from_settings (GtkPrinterOption *option,
   else if (strcmp (option->name, "gtk-output-tray") == 0)
     map_settings_to_option (option, output_tray_map, G_N_ELEMENTS (output_tray_map),
                            settings, GTK_PRINT_SETTINGS_OUTPUT_BIN,
-                           "OutputBin", NULL);
+                           "OutputBin", "output-bin");
   else if (strcmp (option->name, "gtk-duplex") == 0)
     map_settings_to_option (option, duplex_map, G_N_ELEMENTS (duplex_map),
                            settings, GTK_PRINT_SETTINGS_DUPLEX,
@@ -5910,7 +6027,7 @@ foreach_option_get_settings (GtkPrinterOption *option,
   else if (strcmp (option->name, "gtk-output-tray") == 0)
     map_option_to_settings (value, output_tray_map, G_N_ELEMENTS (output_tray_map),
                            settings, GTK_PRINT_SETTINGS_OUTPUT_BIN,
-                           "OutputBin", NULL, FALSE);
+                           "OutputBin", "output-bin", option_is_ipp_option (option));
   else if (strcmp (option->name, "gtk-duplex") == 0)
     map_option_to_settings (value, duplex_map, G_N_ELEMENTS (duplex_map),
                            settings, GTK_PRINT_SETTINGS_DUPLEX,
diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c
index 4a0f373..4a94cbd 100644
--- a/modules/printbackends/cups/gtkprintercups.c
+++ b/modules/printbackends/cups/gtkprintercups.c
@@ -137,6 +137,8 @@ gtk_printer_cups_init (GtkPrinterCups *printer)
   printer->sides_supported = NULL;
   printer->number_of_covers = 0;
   printer->covers = NULL;
+  printer->output_bin_default = NULL;
+  printer->output_bin_supported = NULL;
 }
 
 static void
@@ -190,6 +192,9 @@ gtk_printer_cups_finalize (GObject *object)
   g_free (printer->sides_default);
   g_list_free_full (printer->sides_supported, g_free);
 
+  g_free (printer->output_bin_default);
+  g_list_free_full (printer->output_bin_supported, g_free);
+
   if (printer->get_remote_ppd_poll > 0)
     g_source_remove (printer->get_remote_ppd_poll);
   printer->get_remote_ppd_attempts = 0;
diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h
index 3cf4ceb..837035a 100644
--- a/modules/printbackends/cups/gtkprintercups.h
+++ b/modules/printbackends/cups/gtkprintercups.h
@@ -68,6 +68,8 @@ struct _GtkPrinterCups
   gboolean  media_margin_default_set;
   gchar    *sides_default;
   GList    *sides_supported;
+  gchar    *output_bin_default;
+  GList    *output_bin_supported;
 
   gchar  *default_cover_before;
   gchar  *default_cover_after;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]