]> Pileus Git - ~andy/gtk/blobdiff - modules/printbackends/cups/gtkprintbackendcups.c
Bug 535158 – can't rearrange the order of multi pages per side
[~andy/gtk] / modules / printbackends / cups / gtkprintbackendcups.c
index 5dcec1dd683d864c87ece44b7f390589a1fcc917..96dd2daf3fbb0ee607aa4dadd53049918c706450 100644 (file)
@@ -106,6 +106,8 @@ struct _GtkPrintBackendCups
   guint list_printers_poll;
   guint list_printers_pending : 1;
   guint got_default_printer   : 1;
+  guint default_printer_poll;
+  GtkCupsConnectionTest *default_printer_connection_test;
 
   char **covers;
   char  *default_cover_before;
@@ -120,6 +122,7 @@ static void                 gtk_print_backend_cups_init            (GtkPrintBack
 static void                 gtk_print_backend_cups_finalize        (GObject                           *object);
 static void                 gtk_print_backend_cups_dispose         (GObject                           *object);
 static void                 cups_get_printer_list                  (GtkPrintBackend                   *print_backend);
+static void                 cups_get_default_printer               (GtkPrintBackendCups               *print_backend);
 static void                 cups_request_execute                   (GtkPrintBackendCups               *print_backend,
                                                                    GtkCupsRequest                    *request,
                                                                    GtkPrintCupsResponseCallbackFunc   callback,
@@ -141,7 +144,7 @@ static void                 cups_printer_prepare_for_print         (GtkPrinter
 static GList *              cups_printer_list_papers               (GtkPrinter                        *printer);
 static GtkPageSetup *       cups_printer_get_default_page_size     (GtkPrinter                        *printer);
 static void                 cups_printer_request_details           (GtkPrinter                        *printer);
-static void                 cups_request_default_printer           (GtkPrintBackendCups               *print_backend);
+static gboolean             cups_request_default_printer           (GtkPrintBackendCups               *print_backend);
 static void                 cups_request_ppd                       (GtkPrinter                        *printer);
 static void                 cups_printer_get_hard_margins          (GtkPrinter                        *printer,
                                                                    double                            *top,
@@ -509,7 +512,10 @@ gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
   backend_cups->default_cover_after = NULL;
   backend_cups->number_of_covers = 0;
 
-  cups_request_default_printer (backend_cups);
+  backend_cups->default_printer_poll = 0;
+  backend_cups->default_printer_connection_test = NULL;
+
+  cups_get_default_printer (backend_cups);
 }
 
 static void
@@ -530,6 +536,8 @@ gtk_print_backend_cups_finalize (GObject *object)
 
   g_free (backend_cups->default_cover_before);
   g_free (backend_cups->default_cover_after);
+
+  gtk_cups_connection_test_free (backend_cups->default_printer_connection_test);
   
   backend_parent_class->finalize (object);
 }
@@ -548,6 +556,10 @@ gtk_print_backend_cups_dispose (GObject *object)
     g_source_remove (backend_cups->list_printers_poll);
   backend_cups->list_printers_poll = 0;
   
+  if (backend_cups->default_printer_poll > 0)
+    g_source_remove (backend_cups->default_printer_poll);
+  backend_cups->default_printer_poll = 0;
+
   backend_parent_class->dispose (object);
 }
 
@@ -1100,9 +1112,13 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
         {
           N_("Printer '%s' is low on toner."),
           N_("Printer '%s' has no toner left."),
+          /* Translators: "Developer" like on photo development context */
           N_("Printer '%s' is low on developer."),
+          /* Translators: "Developer" like on photo development context */
           N_("Printer '%s' is out of developer."),
+          /* Translators: "marker" is one color bin of the printer */
           N_("Printer '%s' is low on at least one marker supply."),
+          /* Translators: "marker" is one color bin of the printer */
           N_("Printer '%s' is out of at least one marker supply."),
           N_("The cover is open on printer '%s'."),
           N_("The door is open on printer '%s'."),
@@ -1352,10 +1368,13 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
       if (state_msg != NULL && strlen (state_msg) == 0)
         {
           if (is_paused && !is_accepting_jobs)
+                 /* Translators: this is a printer status. */
             tmp_msg2 = g_strdup ( N_("Paused ; Rejecting Jobs"));
           if (is_paused && is_accepting_jobs)
+                 /* Translators: this is a printer status. */
             tmp_msg2 = g_strdup ( N_("Paused"));
           if (!is_paused && !is_accepting_jobs)
+                 /* Translators: this is a printer status. */
             tmp_msg2 = g_strdup ( N_("Rejecting Jobs"));
 
           if (tmp_msg2 != NULL)
@@ -1808,6 +1827,27 @@ cups_get_user_options (const char     *printer_name,
   return num_options;
 }
 
+/* This function requests default printer from a CUPS server in regular intervals.
+ * In the case of unreachable CUPS server the request is repeated later.
+ * The default printer is not requested in the case of previous success.
+ */
+static void
+cups_get_default_printer (GtkPrintBackendCups *backend)
+{
+  GtkPrintBackendCups *cups_backend;
+
+  cups_backend = backend;
+
+  cups_backend->default_printer_connection_test = gtk_cups_connection_test_new (NULL);
+  if (cups_backend->default_printer_poll == 0)
+    {
+      if (cups_request_default_printer (cups_backend))
+        cups_backend->default_printer_poll = gdk_threads_add_timeout_seconds (1,
+                                                                              (GSourceFunc) cups_request_default_printer,
+                                                                              backend);
+    }
+}
+
 static void
 cups_request_default_printer_cb (GtkPrintBackendCups *print_backend,
                                 GtkCupsResult       *result,
@@ -1816,6 +1856,8 @@ cups_request_default_printer_cb (GtkPrintBackendCups *print_backend,
   ipp_t *response;
   ipp_attribute_t *attr;
 
+  GDK_THREADS_ENTER ();
+
   response = gtk_cups_result_get_response (result);
   
   if ((attr = ippFindAttribute (response, "printer-name", IPP_TAG_NAME)) != NULL)
@@ -1828,27 +1870,35 @@ cups_request_default_printer_cb (GtkPrintBackendCups *print_backend,
    */
   if (print_backend->list_printers_poll != 0)
     cups_request_printer_list (print_backend);
+
+  GDK_THREADS_LEAVE ();
 }
 
-static void
+static gboolean
 cups_request_default_printer (GtkPrintBackendCups *print_backend)
 {
   GtkCupsRequest *request;
   const char *str;
   char *name = NULL;
 
+  if (!gtk_cups_connection_test_is_server_available (print_backend->default_printer_connection_test))
+    return TRUE;
+
+  gtk_cups_connection_test_free (print_backend->default_printer_connection_test);
+  print_backend->default_printer_connection_test = NULL;
+
   if ((str = g_getenv ("LPDEST")) != NULL)
     {
       print_backend->default_printer = g_strdup (str);
       print_backend->got_default_printer = TRUE;
-      return;
+      return FALSE;
     }
   else if ((str = g_getenv ("PRINTER")) != NULL &&
           strcmp (str, "lp") != 0)
     {
       print_backend->default_printer = g_strdup (str);
       print_backend->got_default_printer = TRUE;
-      return;
+      return FALSE;
     }
   
   /* Figure out user setting for default printer */  
@@ -1857,7 +1907,7 @@ cups_request_default_printer (GtkPrintBackendCups *print_backend)
     {
        print_backend->default_printer = name;
        print_backend->got_default_printer = TRUE;
-       return;
+       return FALSE;
     }
 
   request = gtk_cups_request_new (NULL,
@@ -1872,6 +1922,8 @@ cups_request_default_printer (GtkPrintBackendCups *print_backend)
                         (GtkPrintCupsResponseCallbackFunc) cups_request_default_printer_cb,
                        g_object_ref (print_backend),
                        g_object_unref);
+
+  return FALSE;
 }
 
 static void
@@ -1957,11 +2009,17 @@ static const struct {
   const char *translation;
 } cups_choice_translations[] = {
   { "Duplex", "None", N_("One Sided") },
+  /* Translators: this is an option of "Paper Source" */
   { "InputSlot", "Auto", N_("Auto Select") },
+  /* Translators: this is an option of "Paper Source" */
   { "InputSlot", "AutoSelect", N_("Auto Select") },
+  /* Translators: this is an option of "Paper Source" */
   { "InputSlot", "Default", N_("Printer Default") },
+  /* Translators: this is an option of "Paper Source" */
   { "InputSlot", "None", N_("Printer Default") },
+  /* Translators: this is an option of "Paper Source" */
   { "InputSlot", "PrinterDefault", N_("Printer Default") },
+  /* Translators: this is an option of "Paper Source" */
   { "InputSlot", "Unspecified", N_("Auto Select") },
 };
 
@@ -2626,17 +2684,23 @@ cups_printer_get_options (GtkPrinter           *printer,
   char *n_up[] = {"1", "2", "4", "6", "9", "16" };
   char *prio[] = {"100", "80", "50", "30" };
   char *prio_display[] = {N_("Urgent"), N_("High"), N_("Medium"), N_("Low") };
+  char *n_up_layout[] = { "lrtb", "lrbt", "rltb", "rlbt", "tblr", "tbrl", "btlr", "btrl" };
+  char *n_up_layout_display[] = { N_("Left to right, top to bottom"), N_("Left to right, bottom to top"), 
+                                  N_("Right to left, top to bottom"), N_("Right to left, bottom to top"), 
+                                  N_("Top to bottom, left to right"), N_("Top to bottom, right to left"), 
+                                  N_("Bottom to top, left to right"), N_("Bottom to top, right to left") };
   char *name;
   int num_opts;
   cups_option_t *opts = NULL;
   GtkPrintBackendCups *backend;
+  GtkTextDirection text_direction;
 
 
   set = gtk_printer_option_set_new ();
 
   /* Cups specific, non-ppd related settings */
 
-  option = gtk_printer_option_new ("gtk-n-up", "Pages Per Sheet", GTK_PRINTER_OPTION_TYPE_PICKONE);
+  option = gtk_printer_option_new ("gtk-n-up", _("Pages Per Sheet"), GTK_PRINTER_OPTION_TYPE_PICKONE);
   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
                                         n_up, n_up);
   gtk_printer_option_set (option, "1");
@@ -2644,10 +2708,30 @@ cups_printer_get_options (GtkPrinter           *printer,
   gtk_printer_option_set_add (set, option);
   g_object_unref (option);
 
+  if (cups_printer_get_capabilities (printer) & GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT)
+    {
+      for (i = 0; i < G_N_ELEMENTS (n_up_layout_display); i++)
+        n_up_layout_display[i] = _(n_up_layout_display[i]);
+  
+      option = gtk_printer_option_new ("gtk-n-up-layout", _("Page Ordering"), GTK_PRINTER_OPTION_TYPE_PICKONE);
+      gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up_layout),
+                                             n_up_layout, n_up_layout_display);
+
+      text_direction = gtk_widget_get_default_direction ();
+      if (text_direction == GTK_TEXT_DIR_LTR)
+        gtk_printer_option_set (option, "lrtb");
+      else
+        gtk_printer_option_set (option, "rltb");
+
+      set_option_from_settings (option, settings);
+      gtk_printer_option_set_add (set, option);
+      g_object_unref (option);
+    }
+
   for (i = 0; i < G_N_ELEMENTS(prio_display); i++)
     prio_display[i] = _(prio_display[i]);
   
-  option = gtk_printer_option_new ("gtk-job-prio", "Job Priority", GTK_PRINTER_OPTION_TYPE_PICKONE);
+  option = gtk_printer_option_new ("gtk-job-prio", _("Job Priority"), GTK_PRINTER_OPTION_TYPE_PICKONE);
   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (prio),
                                         prio, prio_display);
   gtk_printer_option_set (option, "50");
@@ -2655,7 +2739,7 @@ cups_printer_get_options (GtkPrinter           *printer,
   gtk_printer_option_set_add (set, option);
   g_object_unref (option);
 
-  option = gtk_printer_option_new ("gtk-billing-info", "Billing Info", GTK_PRINTER_OPTION_TYPE_STRING);
+  option = gtk_printer_option_new ("gtk-billing-info", _("Billing Info"), GTK_PRINTER_OPTION_TYPE_STRING);
   gtk_printer_option_set (option, "");
   set_option_from_settings (option, settings);
   gtk_printer_option_set_add (set, option);
@@ -2669,6 +2753,7 @@ cups_printer_get_options (GtkPrinter           *printer,
       char *cover_display_default[] = {N_("None"), N_("Classified"), N_("Confidential"), N_("Secret"), N_("Standard"), N_("Top Secret"), N_("Unclassified"),};
       char **cover = NULL;
       char **cover_display = NULL;
+      char **cover_display_translated = NULL;
       gint num_of_covers = 0;
       gpointer value;
       gint j;
@@ -2678,6 +2763,8 @@ cups_printer_get_options (GtkPrinter           *printer,
       cover[num_of_covers] = NULL;
       cover_display = g_new (char *, num_of_covers + 1);
       cover_display[num_of_covers] = NULL;
+      cover_display_translated = g_new (char *, num_of_covers + 1);
+      cover_display_translated[num_of_covers] = NULL;
 
       for (i = 0; i < num_of_covers; i++)
         {
@@ -2693,11 +2780,11 @@ cups_printer_get_options (GtkPrinter           *printer,
         }
 
       for (i = 0; i < num_of_covers; i++)
-        cover_display[i] = _(cover_display[i]);
+        cover_display_translated[i] = _(cover_display[i]);
   
-      option = gtk_printer_option_new ("gtk-cover-before", "Before", GTK_PRINTER_OPTION_TYPE_PICKONE);
+      option = gtk_printer_option_new ("gtk-cover-before", _("Before"), GTK_PRINTER_OPTION_TYPE_PICKONE);
       gtk_printer_option_choices_from_array (option, num_of_covers,
-                                        cover, cover_display);
+                                        cover, cover_display_translated);
 
       if (backend->default_cover_before != NULL)
         gtk_printer_option_set (option, backend->default_cover_before);
@@ -2707,9 +2794,9 @@ cups_printer_get_options (GtkPrinter           *printer,
       gtk_printer_option_set_add (set, option);
       g_object_unref (option);
 
-      option = gtk_printer_option_new ("gtk-cover-after", "After", GTK_PRINTER_OPTION_TYPE_PICKONE);
+      option = gtk_printer_option_new ("gtk-cover-after", _("After"), GTK_PRINTER_OPTION_TYPE_PICKONE);
       gtk_printer_option_choices_from_array (option, num_of_covers,
-                                        cover, cover_display);
+                                        cover, cover_display_translated);
       if (backend->default_cover_after != NULL)
         gtk_printer_option_set (option, backend->default_cover_after);
       else
@@ -2720,9 +2807,10 @@ cups_printer_get_options (GtkPrinter           *printer,
 
       g_strfreev (cover);
       g_strfreev (cover_display);
+      g_free (cover_display_translated);
     }
 
-  option = gtk_printer_option_new ("gtk-print-time", "Print at", GTK_PRINTER_OPTION_TYPE_PICKONE);
+  option = gtk_printer_option_new ("gtk-print-time", _("Print at"), GTK_PRINTER_OPTION_TYPE_PICKONE);
   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (print_at),
                                         print_at, print_at);
   gtk_printer_option_set (option, "now");
@@ -2730,7 +2818,7 @@ cups_printer_get_options (GtkPrinter           *printer,
   gtk_printer_option_set_add (set, option);
   g_object_unref (option);
   
-  option = gtk_printer_option_new ("gtk-print-time-text", "Print at time", GTK_PRINTER_OPTION_TYPE_STRING);
+  option = gtk_printer_option_new ("gtk-print-time-text", _("Print at time"), GTK_PRINTER_OPTION_TYPE_STRING);
   gtk_printer_option_set (option, "");
   set_option_from_settings (option, settings);
   gtk_printer_option_set_add (set, option);
@@ -3087,6 +3175,11 @@ set_option_from_settings (GtkPrinterOption *option,
       map_settings_to_option (option, all_map, G_N_ELEMENTS (all_map),
                              settings, GTK_PRINT_SETTINGS_NUMBER_UP, "number-up");
     }
+  else if (strcmp (option->name, "gtk-n-up-layout") == 0)
+    {
+      map_settings_to_option (option, all_map, G_N_ELEMENTS (all_map),
+                             settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, "number-up-layout");
+    }
   else if (strcmp (option->name, "gtk-billing-info") == 0)
     {
       cups_value = gtk_print_settings_get (settings, "cups-job-billing");
@@ -3167,6 +3260,9 @@ foreach_option_get_settings (GtkPrinterOption *option,
   else if (strcmp (option->name, "gtk-n-up") == 0)
     map_option_to_settings (value, all_map, G_N_ELEMENTS (all_map),
                            settings, GTK_PRINT_SETTINGS_NUMBER_UP, "number-up");
+  else if (strcmp (option->name, "gtk-n-up-layout") == 0)
+    map_option_to_settings (value, all_map, G_N_ELEMENTS (all_map),
+                           settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, "number-up-layout");
   else if (strcmp (option->name, "gtk-billing-info") == 0 && strlen (value) > 0)
     gtk_print_settings_set (settings, "cups-job-billing", value);
   else if (strcmp (option->name, "gtk-job-prio") == 0)
@@ -3396,5 +3492,8 @@ cups_printer_get_capabilities (GtkPrinter *printer)
     GTK_PRINT_CAPABILITY_COPIES |
     GTK_PRINT_CAPABILITY_COLLATE |
     GTK_PRINT_CAPABILITY_REVERSE |
+#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 1 && CUPS_VERSION_PATCH >= 15) || (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR > 1) || CUPS_VERSION_MAJOR > 1
+    GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT |
+#endif
     GTK_PRINT_CAPABILITY_NUMBER_UP;
 }