]> Pileus Git - ~andy/gtk/blobdiff - modules/printbackends/file/gtkprintbackendfile.c
file printbackend: Protect a callback by GDK_THREADS_ENTER
[~andy/gtk] / modules / printbackends / file / gtkprintbackendfile.c
index 79023c96824d7efb6647b3900aaa92ac58a37d37..fdb36b6dbc75237c6ebf8d0d940493cd612ce0ef 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
@@ -215,13 +213,13 @@ output_file_from_settings (GtkPrintSettings *settings,
                           const gchar      *default_format)
 {
   gchar *uri = NULL;
-  
+
   if (settings)
     uri = g_strdup (gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_URI));
 
   if (uri == NULL)
     { 
-      const gchar *extension;
+      const gchar *extension, *basename, *output_dir;
       gchar *name, *locale_name, *path;
 
       if (default_format)
@@ -245,30 +243,43 @@ output_file_from_settings (GtkPrintSettings *settings,
                 break;
             }
         }
-      /* default filename used for print-to-file */ 
-      name = g_strdup_printf (_("output.%s"), extension);
+
+      basename = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_BASENAME);
+      if (basename == NULL)
+        basename = _("output");
+
+      name = g_strconcat (basename, ".", extension, NULL);
+
       locale_name = g_filename_from_utf8 (name, -1, NULL, NULL, NULL);
       g_free (name);
 
       if (locale_name != NULL)
-        {
-          const gchar *document_dir = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
-          
-          if (document_dir == NULL)
+        {      
+          output_dir = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_DIR);
+          if (output_dir == NULL)
             {
-              gchar *current_dir = g_get_current_dir ();
-              path = g_build_filename (current_dir, locale_name, NULL);
-              g_free (current_dir);
-            }
+              const gchar *document_dir = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
+
+              if (document_dir == NULL)
+                {
+                  gchar *current_dir = g_get_current_dir ();
+                  path = g_build_filename (current_dir, locale_name, NULL);
+                  g_free (current_dir);
+                }
+              else
+                path = g_build_filename (document_dir, locale_name, NULL);
+
+              uri = g_filename_to_uri (path, NULL, NULL); 
+           }
           else
-            path = g_build_filename (document_dir, locale_name, NULL);
-
-          uri = g_filename_to_uri (path, NULL, NULL);
+            {
+              path = g_build_filename (output_dir, locale_name, NULL);
+              uri = g_filename_to_uri (path, NULL, NULL);
+            }
 
+          g_free (path); 
           g_free (locale_name);
-          g_free (path);
-       }
+        }
     }
 
   return uri;
@@ -359,15 +370,14 @@ typedef struct {
   GDestroyNotify dnotify;
 } _PrintStreamData;
 
+/* expects GDK lock to be held */
 static void
-file_print_cb (GtkPrintBackendFile *print_backend,
-               GError              *error,
-               gpointer            user_data)
+file_print_cb_locked (GtkPrintBackendFile *print_backend,
+                      GError              *error,
+                      gpointer            user_data)
 {
   _PrintStreamData *ps = (_PrintStreamData *) user_data;
 
-  GDK_THREADS_ENTER ();
-
   if (ps->target_io_stream != NULL)
     g_output_stream_close (G_OUTPUT_STREAM (ps->target_io_stream), NULL, NULL);
 
@@ -382,8 +392,18 @@ file_print_cb (GtkPrintBackendFile *print_backend,
 
   if (ps->job)
     g_object_unref (ps->job);
+
   g_free (ps);
+}
+
+static void
+file_print_cb (GtkPrintBackendFile *print_backend,
+               GError              *error,
+               gpointer            user_data)
+{
+  GDK_THREADS_ENTER ();
+
+  file_print_cb_locked (print_backend, error, user_data);
 
   GDK_THREADS_LEAVE ();
 }
@@ -401,7 +421,7 @@ file_write (GIOChannel   *source,
 
   error = NULL;
 
-  read_status = 
+  read_status =
     g_io_channel_read_chars (source,
                              buf,
                              _STREAM_MAX_CHUNK_SIZE,
@@ -479,8 +499,8 @@ gtk_print_backend_file_print_stream (GtkPrintBackend        *print_backend,
 error:
   if (internal_error != NULL)
     {
-      file_print_cb (GTK_PRINT_BACKEND_FILE (print_backend),
-                    internal_error, ps);
+      file_print_cb_locked (GTK_PRINT_BACKEND_FILE (print_backend),
+                            internal_error, ps);
 
       g_error_free (internal_error);
       return;
@@ -501,6 +521,7 @@ gtk_print_backend_file_init (GtkPrintBackendFile *backend)
                          "name", _("Print to File"),
                          "backend", backend,
                          "is-virtual", TRUE,
+                         "accepts-pdf", TRUE,
                          NULL); 
 
   gtk_printer_set_has_details (printer, TRUE);
@@ -513,17 +534,63 @@ gtk_print_backend_file_init (GtkPrintBackendFile *backend)
   gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (backend));
 }
 
+typedef struct {
+  GtkPrinter          *printer;
+  GtkPrinterOptionSet *set;
+} _OutputFormatChangedData;
+
+static void
+set_printer_format_from_option_set (GtkPrinter          *printer,
+                                   GtkPrinterOptionSet *set)
+{
+  GtkPrinterOption *format_option;
+  const gchar *value;
+  gint i;
+
+  format_option = gtk_printer_option_set_lookup (set, "output-file-format");
+  if (format_option && format_option->value)
+    {
+      value = format_option->value;
+      if (value)
+        {
+         for (i = 0; i < N_FORMATS; ++i)
+           if (strcmp (value, formats[i]) == 0)
+             break;
+
+         g_assert (i < N_FORMATS);
+
+         switch (i)
+           {
+             case FORMAT_PDF:
+               gtk_printer_set_accepts_pdf (printer, TRUE);
+               gtk_printer_set_accepts_ps (printer, FALSE);
+               break;
+             case FORMAT_PS:
+               gtk_printer_set_accepts_pdf (printer, FALSE);
+               gtk_printer_set_accepts_ps (printer, TRUE);
+               break;
+             case FORMAT_SVG:
+             default:
+               gtk_printer_set_accepts_pdf (printer, FALSE);
+               gtk_printer_set_accepts_ps (printer, FALSE);
+               break;
+           }
+       }
+    }
+}
+
 static void
 file_printer_output_file_format_changed (GtkPrinterOption    *format_option,
-                                         GtkPrinterOptionSet *set)
+                                        gpointer             user_data)
 {
   GtkPrinterOption *uri_option;
   gchar            *base = NULL;
+  _OutputFormatChangedData *data = (_OutputFormatChangedData *) user_data;
 
   if (! format_option->value)
     return;
 
-  uri_option = gtk_printer_option_set_lookup (set,
+  uri_option = gtk_printer_option_set_lookup (data->set,
                                               "gtk-main-page-custom-input");
 
   if (uri_option && uri_option->value)
@@ -563,6 +630,8 @@ file_printer_output_file_format_changed (GtkPrinterOption    *format_option,
       g_free (tmp);
       g_free (base);
     }
+
+  set_printer_format_from_option_set (data->printer, data->set);
 }
 
 static GtkPrinterOptionSet *
@@ -582,6 +651,7 @@ file_printer_get_options (GtkPrinter           *printer,
   OutputFormat format;
   gchar *uri;
   gint current_format = 0;
+  _OutputFormatChangedData *format_changed_data;
 
   format = format_from_settings (settings);
 
@@ -666,9 +736,13 @@ file_printer_get_options (GtkPrinter           *printer,
       gtk_printer_option_set (option, supported_formats[current_format]);
       gtk_printer_option_set_add (set, option);
 
-      g_signal_connect (option, "changed",
-                        G_CALLBACK (file_printer_output_file_format_changed),
-                        set);
+      set_printer_format_from_option_set (printer, set);
+      format_changed_data = g_new (_OutputFormatChangedData, 1);
+      format_changed_data->printer = printer;
+      format_changed_data->set = set;
+      g_signal_connect_data (option, "changed",
+                            G_CALLBACK (file_printer_output_file_format_changed),
+                            format_changed_data, (GClosureNotify)g_free, 0);
 
       g_object_unref (option);
     }
@@ -706,28 +780,34 @@ file_printer_prepare_for_print (GtkPrinter       *printer,
                                GtkPageSetup     *page_setup)
 {
   gdouble scale;
+  GtkPrintPages pages;
+  GtkPageRange *ranges;
+  gint n_ranges;
 
-  print_job->print_pages = gtk_print_settings_get_print_pages (settings);
-  print_job->page_ranges = NULL;
-  print_job->num_page_ranges = 0;
-  
-  if (print_job->print_pages == GTK_PRINT_PAGES_RANGES)
-    print_job->page_ranges =
-      gtk_print_settings_get_page_ranges (settings,
-                                         &print_job->num_page_ranges);
-  
-  print_job->collate = gtk_print_settings_get_collate (settings);
-  print_job->reverse = gtk_print_settings_get_reverse (settings);
-  print_job->num_copies = gtk_print_settings_get_n_copies (settings);
-  print_job->number_up = gtk_print_settings_get_number_up (settings);
-  print_job->number_up_layout = gtk_print_settings_get_number_up_layout (settings);
+  pages = gtk_print_settings_get_print_pages (settings);
+  gtk_print_job_set_pages (print_job, pages);
+
+  if (pages == GTK_PRINT_PAGES_RANGES)
+    ranges = gtk_print_settings_get_page_ranges (settings, &n_ranges);
+  else
+    {
+      ranges = NULL;
+      n_ranges = 0;
+    }
+
+  gtk_print_job_set_page_ranges (print_job, ranges, n_ranges);
+  gtk_print_job_set_collate (print_job, gtk_print_settings_get_collate (settings));
+  gtk_print_job_set_reverse (print_job, gtk_print_settings_get_reverse (settings));
+  gtk_print_job_set_num_copies (print_job, gtk_print_settings_get_n_copies (settings));
+  gtk_print_job_set_n_up (print_job, gtk_print_settings_get_number_up (settings));
+  gtk_print_job_set_n_up_layout (print_job, gtk_print_settings_get_number_up_layout (settings));
 
   scale = gtk_print_settings_get_scale (settings);
   if (scale != 100.0)
-    print_job->scale = scale/100.0;
+    gtk_print_job_set_scale (print_job, scale / 100.0);
 
-  print_job->page_set = gtk_print_settings_get_page_set (settings);
-  print_job->rotate_to_orientation = TRUE;
+  gtk_print_job_set_page_set (print_job, gtk_print_settings_get_page_set (settings));
+  gtk_print_job_set_rotate (print_job, TRUE);
 }
 
 static GList *