]> Pileus Git - ~andy/gtk/blob - modules/printbackends/file/gtkprintbackendfile.c
3322db1a465b8a6e6b9e4ccef897fec46dcadb7e
[~andy/gtk] / modules / printbackends / file / gtkprintbackendfile.c
1 /* GTK - The GIMP Toolkit
2  * gtkprintbackendfile.c: Default implementation of GtkPrintBackend 
3  * for printing to a file
4  * Copyright (C) 2003, Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include "config.h"
23
24 #include <unistd.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <errno.h>
32 #include <cairo.h>
33 #include <cairo-pdf.h>
34 #include <cairo-ps.h>
35 #include <cairo-svg.h>
36
37 #include <glib/gi18n-lib.h>
38
39 #include "gtk/gtk.h"
40 #include "gtk/gtkprinter-private.h"
41
42 #include "gtkprintbackendfile.h"
43
44 typedef struct _GtkPrintBackendFileClass GtkPrintBackendFileClass;
45
46 #define GTK_PRINT_BACKEND_FILE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_FILE, GtkPrintBackendFileClass))
47 #define GTK_IS_PRINT_BACKEND_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_FILE))
48 #define GTK_PRINT_BACKEND_FILE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_FILE, GtkPrintBackendFileClass))
49
50 #define _STREAM_MAX_CHUNK_SIZE 8192
51
52 static GType print_backend_file_type = 0;
53
54 struct _GtkPrintBackendFileClass
55 {
56   GtkPrintBackendClass parent_class;
57 };
58
59 struct _GtkPrintBackendFile
60 {
61   GtkPrintBackend parent_instance;
62 };
63
64 typedef enum
65 {
66   FORMAT_PDF,
67   FORMAT_PS,
68   FORMAT_SVG,
69   N_FORMATS
70 } OutputFormat;
71
72 static const gchar* formats[N_FORMATS] =
73 {
74   "pdf",
75   "ps",
76   "svg"
77 };
78
79 static GObjectClass *backend_parent_class;
80
81 static void                 gtk_print_backend_file_class_init      (GtkPrintBackendFileClass *class);
82 static void                 gtk_print_backend_file_init            (GtkPrintBackendFile      *impl);
83 static void                 file_printer_get_settings_from_options (GtkPrinter              *printer,
84                                                                     GtkPrinterOptionSet     *options,
85                                                                     GtkPrintSettings        *settings);
86 static GtkPrinterOptionSet *file_printer_get_options               (GtkPrinter              *printer,
87                                                                     GtkPrintSettings        *settings,
88                                                                     GtkPageSetup            *page_setup,
89                                                                     GtkPrintCapabilities     capabilities);
90 static void                 file_printer_prepare_for_print         (GtkPrinter              *printer,
91                                                                     GtkPrintJob             *print_job,
92                                                                     GtkPrintSettings        *settings,
93                                                                     GtkPageSetup            *page_setup);
94 static void                 gtk_print_backend_file_print_stream    (GtkPrintBackend         *print_backend,
95                                                                     GtkPrintJob             *job,
96                                                                     GIOChannel              *data_io,
97                                                                     GtkPrintJobCompleteFunc  callback,
98                                                                     gpointer                 user_data,
99                                                                     GDestroyNotify           dnotify);
100 static cairo_surface_t *    file_printer_create_cairo_surface      (GtkPrinter              *printer,
101                                                                     GtkPrintSettings        *settings,
102                                                                     gdouble                  width,
103                                                                     gdouble                  height,
104                                                                     GIOChannel              *cache_io);
105
106 static GList *              file_printer_list_papers               (GtkPrinter              *printer);
107 static GtkPageSetup *       file_printer_get_default_page_size     (GtkPrinter              *printer);
108
109 static void
110 gtk_print_backend_file_register_type (GTypeModule *module)
111 {
112   const GTypeInfo print_backend_file_info =
113   {
114     sizeof (GtkPrintBackendFileClass),
115     NULL,               /* base_init */
116     NULL,               /* base_finalize */
117     (GClassInitFunc) gtk_print_backend_file_class_init,
118     NULL,               /* class_finalize */
119     NULL,               /* class_data */
120     sizeof (GtkPrintBackendFile),
121     0,          /* n_preallocs */
122     (GInstanceInitFunc) gtk_print_backend_file_init,
123   };
124
125   print_backend_file_type = g_type_module_register_type (module,
126                                                          GTK_TYPE_PRINT_BACKEND,
127                                                          "GtkPrintBackendFile",
128                                                          &print_backend_file_info, 0);
129 }
130
131 G_MODULE_EXPORT void 
132 pb_module_init (GTypeModule *module)
133 {
134   gtk_print_backend_file_register_type (module);
135 }
136
137 G_MODULE_EXPORT void 
138 pb_module_exit (void)
139 {
140
141 }
142   
143 G_MODULE_EXPORT GtkPrintBackend * 
144 pb_module_create (void)
145 {
146   return gtk_print_backend_file_new ();
147 }
148
149 /*
150  * GtkPrintBackendFile
151  */
152 GType
153 gtk_print_backend_file_get_type (void)
154 {
155   return print_backend_file_type;
156 }
157
158 /**
159  * gtk_print_backend_file_new:
160  *
161  * Creates a new #GtkPrintBackendFile object. #GtkPrintBackendFile
162  * implements the #GtkPrintBackend interface with direct access to
163  * the filesystem using Unix/Linux API calls
164  *
165  * Return value: the new #GtkPrintBackendFile object
166  **/
167 GtkPrintBackend *
168 gtk_print_backend_file_new (void)
169 {
170   return g_object_new (GTK_TYPE_PRINT_BACKEND_FILE, NULL);
171 }
172
173 static void
174 gtk_print_backend_file_class_init (GtkPrintBackendFileClass *class)
175 {
176   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
177
178   backend_parent_class = g_type_class_peek_parent (class);
179
180   backend_class->print_stream = gtk_print_backend_file_print_stream;
181   backend_class->printer_create_cairo_surface = file_printer_create_cairo_surface;
182   backend_class->printer_get_options = file_printer_get_options;
183   backend_class->printer_get_settings_from_options = file_printer_get_settings_from_options;
184   backend_class->printer_prepare_for_print = file_printer_prepare_for_print;
185   backend_class->printer_list_papers = file_printer_list_papers;
186   backend_class->printer_get_default_page_size = file_printer_get_default_page_size;
187 }
188
189 /* return N_FORMATS if no explicit format in the settings */
190 static OutputFormat
191 format_from_settings (GtkPrintSettings *settings)
192 {
193   const gchar *value;
194   gint i;
195
196   if (settings == NULL)
197     return N_FORMATS;
198
199   value = gtk_print_settings_get (settings,
200                                   GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
201   if (value == NULL)
202     return N_FORMATS;
203
204   for (i = 0; i < N_FORMATS; ++i)
205     if (strcmp (value, formats[i]) == 0)
206       break;
207
208   g_assert (i < N_FORMATS);
209
210   return (OutputFormat) i;
211 }
212
213 static gchar *
214 output_file_from_settings (GtkPrintSettings *settings,
215                            const gchar      *default_format)
216 {
217   gchar *uri = NULL;
218   
219   if (settings)
220     uri = g_strdup (gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_URI));
221
222   if (uri == NULL)
223     { 
224       const gchar *extension;
225       gchar *name, *locale_name, *path;
226
227       if (default_format)
228         extension = default_format;
229       else
230         {
231           OutputFormat format;
232
233           format = format_from_settings (settings);
234           switch (format)
235             {
236               default:
237               case FORMAT_PDF:
238                 extension = "pdf";
239                 break;
240               case FORMAT_PS:
241                 extension = "ps";
242                 break;
243               case FORMAT_SVG:
244                 extension = "svg";
245                 break;
246             }
247         }
248  
249       /* default filename used for print-to-file */ 
250       name = g_strdup_printf (_("output.%s"), extension);
251       locale_name = g_filename_from_utf8 (name, -1, NULL, NULL, NULL);
252       g_free (name);
253
254       if (locale_name != NULL)
255         {
256           const gchar *document_dir = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS);
257           
258           if (document_dir == NULL)
259             {
260               gchar *current_dir = g_get_current_dir ();
261               path = g_build_filename (current_dir, locale_name, NULL);
262               g_free (current_dir);
263             }
264           else
265             path = g_build_filename (document_dir, locale_name, NULL);
266
267           uri = g_filename_to_uri (path, NULL, NULL);
268
269           g_free (locale_name);
270           g_free (path);
271         }
272     }
273
274   return uri;
275 }
276
277 static cairo_status_t
278 _cairo_write (void                *closure,
279               const unsigned char *data,
280               unsigned int         length)
281 {
282   GIOChannel *io = (GIOChannel *)closure;
283   gsize written;
284   GError *error;
285
286   error = NULL;
287
288   GTK_NOTE (PRINTING,
289             g_print ("FILE Backend: Writting %i byte chunk to temp file\n", length));
290
291   while (length > 0) 
292     {
293       g_io_channel_write_chars (io, (const gchar *) data, length, &written, &error);
294
295       if (error != NULL)
296         {
297           GTK_NOTE (PRINTING,
298                      g_print ("FILE Backend: Error writting to temp file, %s\n", error->message));
299
300           g_error_free (error);
301           return CAIRO_STATUS_WRITE_ERROR;
302         }    
303
304       GTK_NOTE (PRINTING,
305                 g_print ("FILE Backend: Wrote %i bytes to temp file\n", written));
306       
307       data += written;
308       length -= written;
309     }
310
311   return CAIRO_STATUS_SUCCESS;
312 }
313
314
315 static cairo_surface_t *
316 file_printer_create_cairo_surface (GtkPrinter       *printer,
317                                    GtkPrintSettings *settings,
318                                    gdouble           width, 
319                                    gdouble           height,
320                                    GIOChannel       *cache_io)
321 {
322   cairo_surface_t *surface;
323   OutputFormat format;
324   const cairo_svg_version_t *versions;
325   int num_versions = 0;
326
327   format = format_from_settings (settings);
328
329   switch (format)
330     {
331       default:
332       case FORMAT_PDF:
333         surface = cairo_pdf_surface_create_for_stream (_cairo_write, cache_io, width, height);
334         break;
335       case FORMAT_PS:
336         surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height);
337         break;
338       case FORMAT_SVG:
339         surface = cairo_svg_surface_create_for_stream (_cairo_write, cache_io, width, height);
340         cairo_svg_get_versions (&versions, &num_versions);
341         if (num_versions > 0)
342           cairo_svg_surface_restrict_to_version (surface, versions[num_versions - 1]);
343         break;
344     }
345
346   cairo_surface_set_fallback_resolution (surface,
347                                          2.0 * gtk_print_settings_get_printer_lpi (settings),
348                                          2.0 * gtk_print_settings_get_printer_lpi (settings));
349
350   return surface;
351 }
352
353 typedef struct {
354   GtkPrintBackend *backend;
355   GtkPrintJobCompleteFunc callback;
356   GtkPrintJob *job;
357   GFileOutputStream *target_io_stream;
358   gpointer user_data;
359   GDestroyNotify dnotify;
360 } _PrintStreamData;
361
362 static void
363 file_print_cb (GtkPrintBackendFile *print_backend,
364                GError              *error,
365                gpointer            user_data)
366 {
367   _PrintStreamData *ps = (_PrintStreamData *) user_data;
368
369   GDK_THREADS_ENTER ();
370
371   if (ps->target_io_stream != NULL)
372     g_output_stream_close (G_OUTPUT_STREAM (ps->target_io_stream), NULL, NULL);
373
374   if (ps->callback)
375     ps->callback (ps->job, ps->user_data, error);
376
377   if (ps->dnotify)
378     ps->dnotify (ps->user_data);
379
380   gtk_print_job_set_status (ps->job,
381                             (error != NULL)?GTK_PRINT_STATUS_FINISHED_ABORTED:GTK_PRINT_STATUS_FINISHED);
382
383   if (ps->job)
384     g_object_unref (ps->job);
385  
386   g_free (ps);
387
388   GDK_THREADS_LEAVE ();
389 }
390
391 static gboolean
392 file_write (GIOChannel   *source,
393             GIOCondition  con,
394             gpointer      user_data)
395 {
396   gchar buf[_STREAM_MAX_CHUNK_SIZE];
397   gsize bytes_read;
398   GError *error;
399   GIOStatus read_status;
400   _PrintStreamData *ps = (_PrintStreamData *) user_data;
401
402   error = NULL;
403
404   read_status = 
405     g_io_channel_read_chars (source,
406                              buf,
407                              _STREAM_MAX_CHUNK_SIZE,
408                              &bytes_read,
409                              &error);
410
411   if (read_status != G_IO_STATUS_ERROR)
412     {
413       gsize bytes_written;
414
415       g_output_stream_write_all (G_OUTPUT_STREAM (ps->target_io_stream),
416                                  buf,
417                                  bytes_read,
418                                  &bytes_written,
419                                  NULL,
420                                  &error);
421     }
422
423   if (error != NULL || read_status == G_IO_STATUS_EOF)
424     {
425       file_print_cb (GTK_PRINT_BACKEND_FILE (ps->backend), error, user_data);
426
427       if (error != NULL)
428         {
429           GTK_NOTE (PRINTING,
430                     g_print ("FILE Backend: %s\n", error->message));
431
432           g_error_free (error);
433         }
434
435       return FALSE;
436     }
437
438   GTK_NOTE (PRINTING,
439             g_print ("FILE Backend: Writting %i byte chunk to target file\n", bytes_read));
440
441   return TRUE;
442 }
443
444 static void
445 gtk_print_backend_file_print_stream (GtkPrintBackend        *print_backend,
446                                      GtkPrintJob            *job,
447                                      GIOChannel             *data_io,
448                                      GtkPrintJobCompleteFunc callback,
449                                      gpointer                user_data,
450                                      GDestroyNotify          dnotify)
451 {
452   GError *internal_error = NULL;
453   _PrintStreamData *ps;
454   GtkPrintSettings *settings;
455   gchar *uri;
456   GFile *file = NULL;
457
458   settings = gtk_print_job_get_settings (job);
459
460   ps = g_new0 (_PrintStreamData, 1);
461   ps->callback = callback;
462   ps->user_data = user_data;
463   ps->dnotify = dnotify;
464   ps->job = g_object_ref (job);
465   ps->backend = print_backend;
466
467   internal_error = NULL;
468   uri = output_file_from_settings (settings, NULL);
469
470   if (uri == NULL)
471     goto error;
472
473   file = g_file_new_for_uri (uri);
474   ps->target_io_stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &internal_error);
475
476   g_object_unref (file);
477   g_free (uri);
478
479 error:
480   if (internal_error != NULL)
481     {
482       file_print_cb (GTK_PRINT_BACKEND_FILE (print_backend),
483                     internal_error, ps);
484
485       g_error_free (internal_error);
486       return;
487     }
488
489   g_io_add_watch (data_io, 
490                   G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
491                   (GIOFunc) file_write,
492                   ps);
493 }
494
495 static void
496 gtk_print_backend_file_init (GtkPrintBackendFile *backend)
497 {
498   GtkPrinter *printer;
499   
500   printer = g_object_new (GTK_TYPE_PRINTER,
501                           "name", _("Print to File"),
502                           "backend", backend,
503                           "is-virtual", TRUE,
504                           "accepts-pdf", TRUE,
505                           NULL); 
506
507   gtk_printer_set_has_details (printer, TRUE);
508   gtk_printer_set_icon_name (printer, "document-save");
509   gtk_printer_set_is_active (printer, TRUE);
510
511   gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
512   g_object_unref (printer);
513
514   gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (backend));
515 }
516
517 typedef struct {
518   GtkPrinter          *printer;
519   GtkPrinterOptionSet *set;
520 } _OutputFormatChangedData;
521
522 static void
523 set_printer_format_from_option_set (GtkPrinter          *printer,
524                                     GtkPrinterOptionSet *set)
525 {
526   GtkPrinterOption *format_option;
527   const gchar *value;
528   gint i;
529
530   format_option = gtk_printer_option_set_lookup (set, "output-file-format");
531   if (format_option && format_option->value)
532     {
533       value = format_option->value;
534       if (value)
535         {
536           for (i = 0; i < N_FORMATS; ++i)
537             if (strcmp (value, formats[i]) == 0)
538               break;
539
540           g_assert (i < N_FORMATS);
541
542           switch (i)
543             {
544               case FORMAT_PDF:
545                 gtk_printer_set_accepts_pdf (printer, TRUE);
546                 gtk_printer_set_accepts_ps (printer, FALSE);
547                 break;
548               case FORMAT_PS:
549                 gtk_printer_set_accepts_pdf (printer, FALSE);
550                 gtk_printer_set_accepts_ps (printer, TRUE);
551                 break;
552               case FORMAT_SVG:
553               default:
554                 gtk_printer_set_accepts_pdf (printer, FALSE);
555                 gtk_printer_set_accepts_ps (printer, FALSE);
556                 break;
557             }
558         }
559     }
560 }
561
562 static void
563 file_printer_output_file_format_changed (GtkPrinterOption    *format_option,
564                                          gpointer             user_data)
565 {
566   GtkPrinterOption *uri_option;
567   gchar            *base = NULL;
568   _OutputFormatChangedData *data = (_OutputFormatChangedData *) user_data;
569
570   if (! format_option->value)
571     return;
572
573   uri_option = gtk_printer_option_set_lookup (data->set,
574                                               "gtk-main-page-custom-input");
575
576   if (uri_option && uri_option->value)
577     {
578       const gchar *uri = uri_option->value;
579       const gchar *dot = strrchr (uri, '.');
580
581       if (dot)
582         {
583           gint i;
584
585           /*  check if the file extension matches one of the known ones  */
586           for (i = 0; i < N_FORMATS; i++)
587             if (strcmp (dot + 1, formats[i]) == 0)
588               break;
589
590           if (i < N_FORMATS && strcmp (formats[i], format_option->value))
591             {
592               /*  the file extension is known but doesn't match the
593                *  selected one, strip it away
594                */
595               base = g_strndup (uri, dot - uri);
596             }
597         }
598       else
599         {
600           /*  there's no file extension  */
601           base = g_strdup (uri);
602         }
603     }
604
605   if (base)
606     {
607       gchar *tmp = g_strdup_printf ("%s.%s", base, format_option->value);
608
609       gtk_printer_option_set (uri_option, tmp);
610       g_free (tmp);
611       g_free (base);
612     }
613
614   set_printer_format_from_option_set (data->printer, data->set);
615 }
616
617 static GtkPrinterOptionSet *
618 file_printer_get_options (GtkPrinter           *printer,
619                           GtkPrintSettings     *settings,
620                           GtkPageSetup         *page_setup,
621                           GtkPrintCapabilities  capabilities)
622 {
623   GtkPrinterOptionSet *set;
624   GtkPrinterOption *option;
625   const gchar *n_up[] = {"1", "2", "4", "6", "9", "16" };
626   const gchar *pages_per_sheet = NULL;
627   const gchar *format_names[N_FORMATS] = { N_("PDF"), N_("Postscript"), N_("SVG") };
628   const gchar *supported_formats[N_FORMATS];
629   gchar *display_format_names[N_FORMATS];
630   gint n_formats = 0;
631   OutputFormat format;
632   gchar *uri;
633   gint current_format = 0;
634   _OutputFormatChangedData *format_changed_data;
635
636   format = format_from_settings (settings);
637
638   set = gtk_printer_option_set_new ();
639
640   option = gtk_printer_option_new ("gtk-n-up", _("Pages per _sheet:"), GTK_PRINTER_OPTION_TYPE_PICKONE);
641   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
642                                          (char **) n_up, (char **) n_up /* FIXME i18n (localised digits)! */);
643   if (settings)
644     pages_per_sheet = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_NUMBER_UP);
645   if (pages_per_sheet)
646     gtk_printer_option_set (option, pages_per_sheet);
647   else
648     gtk_printer_option_set (option, "1");
649   gtk_printer_option_set_add (set, option);
650   g_object_unref (option);
651
652   if (capabilities & (GTK_PRINT_CAPABILITY_GENERATE_PDF | GTK_PRINT_CAPABILITY_GENERATE_PS))
653     {
654       if (capabilities & GTK_PRINT_CAPABILITY_GENERATE_PDF)
655         {
656           if (format == FORMAT_PDF || format == N_FORMATS)
657             {
658               format = FORMAT_PDF;
659               current_format = n_formats;
660             }
661           supported_formats[n_formats] = formats[FORMAT_PDF];
662           display_format_names[n_formats] = _(format_names[FORMAT_PDF]);
663           n_formats++;
664         }
665       if (capabilities & GTK_PRINT_CAPABILITY_GENERATE_PS)
666         {
667           if (format == FORMAT_PS || format == N_FORMATS)
668             current_format = n_formats;
669           supported_formats[n_formats] = formats[FORMAT_PS];
670           display_format_names[n_formats] = _(format_names[FORMAT_PS]);
671           n_formats++;
672         }
673     }
674   else
675     {
676       switch (format)
677         {
678           default:
679           case FORMAT_PDF:
680             current_format = FORMAT_PDF;
681             break;
682           case FORMAT_PS:
683             current_format = FORMAT_PS;
684             break;
685           case FORMAT_SVG:
686             current_format = FORMAT_SVG;            
687             break;
688         }
689
690       for (n_formats = 0; n_formats < N_FORMATS; ++n_formats)
691         {
692           supported_formats[n_formats] = formats[n_formats];
693           display_format_names[n_formats] = _(format_names[n_formats]);
694         }
695     }
696
697   uri = output_file_from_settings (settings, supported_formats[current_format]);
698
699   option = gtk_printer_option_new ("gtk-main-page-custom-input", _("File"), 
700                                    GTK_PRINTER_OPTION_TYPE_FILESAVE);
701   gtk_printer_option_set_activates_default (option, TRUE);
702   gtk_printer_option_set (option, uri);
703   g_free (uri);
704   option->group = g_strdup ("GtkPrintDialogExtension");
705   gtk_printer_option_set_add (set, option);
706
707   if (n_formats > 1)
708     {
709       option = gtk_printer_option_new ("output-file-format", _("_Output format"), 
710                                        GTK_PRINTER_OPTION_TYPE_ALTERNATIVE);
711       option->group = g_strdup ("GtkPrintDialogExtension");
712
713       gtk_printer_option_choices_from_array (option, n_formats,
714                                              (char **) supported_formats,
715                                              display_format_names);
716       gtk_printer_option_set (option, supported_formats[current_format]);
717       gtk_printer_option_set_add (set, option);
718
719       set_printer_format_from_option_set (printer, set);
720       format_changed_data = g_new (_OutputFormatChangedData, 1);
721       format_changed_data->printer = printer;
722       format_changed_data->set = set;
723       g_signal_connect_data (option, "changed",
724                              G_CALLBACK (file_printer_output_file_format_changed),
725                              format_changed_data, (GClosureNotify)g_free, 0);
726
727       g_object_unref (option);
728     }
729
730   return set;
731 }
732
733 static void
734 file_printer_get_settings_from_options (GtkPrinter          *printer,
735                                         GtkPrinterOptionSet *options,
736                                         GtkPrintSettings    *settings)
737 {
738   GtkPrinterOption *option;
739
740   option = gtk_printer_option_set_lookup (options, "gtk-main-page-custom-input");
741   gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, option->value);
742
743   option = gtk_printer_option_set_lookup (options, "output-file-format");
744   if (option)
745     gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT, option->value);
746
747   option = gtk_printer_option_set_lookup (options, "gtk-n-up");
748   if (option)
749     gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP, option->value);
750
751   option = gtk_printer_option_set_lookup (options, "gtk-n-up-layout");
752   if (option)
753     gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, option->value);
754 }
755
756 static void
757 file_printer_prepare_for_print (GtkPrinter       *printer,
758                                 GtkPrintJob      *print_job,
759                                 GtkPrintSettings *settings,
760                                 GtkPageSetup     *page_setup)
761 {
762   gdouble scale;
763   GtkPrintPages pages;
764   GtkPageRange *ranges;
765   gint n_ranges;
766
767   pages = gtk_print_settings_get_print_pages (settings);
768   gtk_print_job_set_pages (print_job, pages);
769
770   if (pages == GTK_PRINT_PAGES_RANGES)
771     ranges = gtk_print_settings_get_page_ranges (settings, &n_ranges);
772   else
773     {
774       ranges = NULL;
775       n_ranges = 0;
776     }
777
778   gtk_print_job_set_page_ranges (print_job, ranges, n_ranges);
779   gtk_print_job_set_collate (print_job, gtk_print_settings_get_collate (settings));
780   gtk_print_job_set_reverse (print_job, gtk_print_settings_get_reverse (settings));
781   gtk_print_job_set_num_copies (print_job, gtk_print_settings_get_n_copies (settings));
782   gtk_print_job_set_n_up (print_job, gtk_print_settings_get_number_up (settings));
783   gtk_print_job_set_n_up_layout (print_job, gtk_print_settings_get_number_up_layout (settings));
784
785   scale = gtk_print_settings_get_scale (settings);
786   if (scale != 100.0)
787     gtk_print_job_set_scale (print_job, scale / 100.0);
788
789   gtk_print_job_set_page_set (print_job, gtk_print_settings_get_page_set (settings));
790   gtk_print_job_set_rotate (print_job, TRUE);
791 }
792
793 static GList *
794 file_printer_list_papers (GtkPrinter *printer)
795 {
796   GList *result = NULL;
797   GList *papers, *p;
798   GtkPageSetup *page_setup;
799
800   papers = gtk_paper_size_get_paper_sizes (TRUE);
801
802   for (p = papers; p; p = p->next)
803     {
804       GtkPaperSize *paper_size = p->data;
805
806       page_setup = gtk_page_setup_new ();
807       gtk_page_setup_set_paper_size (page_setup, paper_size);
808       gtk_paper_size_free (paper_size);
809       result = g_list_prepend (result, page_setup);
810     }
811
812   g_list_free (papers);
813
814   return g_list_reverse (result);
815 }
816
817 static GtkPageSetup *
818 file_printer_get_default_page_size (GtkPrinter *printer)
819 {
820   GtkPageSetup *result = NULL;
821
822   return result;
823 }