]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintjob.c
Add docs.
[~andy/gtk] / gtk / gtkprintjob.c
1 /* GtkPrintJob
2  * Copyright (C) 2006 John (J5) Palmieri  <johnp@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #include <sys/types.h>
30 #include <sys/stat.h>
31
32 #include <glib/gstdio.h>
33 #include "gtkintl.h"
34 #include "gtkprivate.h"
35
36 #include "gtkprintjob.h"
37 #include "gtkprinter.h"
38 #include "gtkprintbackend.h"
39 #include "gtkalias.h"
40
41 #ifndef O_BINARY
42 #define O_BINARY 0
43 #endif
44
45 struct _GtkPrintJobPrivate
46 {
47   gchar *title;
48
49   int spool_file_fd;
50   cairo_surface_t *surface;
51
52   GtkPrintStatus status;
53   GtkPrintBackend *backend;  
54   GtkPrinter *printer;
55   GtkPrintSettings *settings;
56   GtkPageSetup *page_setup;
57
58   gint printer_set : 1;
59   gint page_setup_set : 1;
60   gint settings_set  : 1;
61 };
62
63
64 #define GTK_PRINT_JOB_GET_PRIVATE(o)  \
65    (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_JOB, GtkPrintJobPrivate))
66
67 static void     gtk_print_job_finalize     (GObject               *object);
68 static void     gtk_print_job_set_property (GObject               *object,
69                                             guint                  prop_id,
70                                             const GValue          *value,
71                                             GParamSpec            *pspec);
72 static void     gtk_print_job_get_property (GObject               *object,
73                                             guint                  prop_id,
74                                             GValue                *value,
75                                             GParamSpec            *pspec);
76 static GObject* gtk_print_job_constructor  (GType                  type,
77                                             guint                  n_construct_properties,
78                                             GObjectConstructParam *construct_params);
79
80 enum {
81   STATUS_CHANGED,
82   LAST_SIGNAL
83 };
84
85 enum {
86   PROP_0,
87   GTK_PRINT_JOB_PROP_TITLE,
88   GTK_PRINT_JOB_PROP_PRINTER,
89   GTK_PRINT_JOB_PROP_PAGE_SETUP,
90   GTK_PRINT_JOB_PROP_SETTINGS
91 };
92
93 static guint signals[LAST_SIGNAL] = { 0 };
94
95 G_DEFINE_TYPE (GtkPrintJob, gtk_print_job, G_TYPE_OBJECT);
96
97 static void
98 gtk_print_job_class_init (GtkPrintJobClass *class)
99 {
100   GObjectClass *object_class;
101   object_class = (GObjectClass *) class;
102
103   object_class->finalize = gtk_print_job_finalize;
104   object_class->constructor = gtk_print_job_constructor;
105   object_class->set_property = gtk_print_job_set_property;
106   object_class->get_property = gtk_print_job_get_property;
107
108   g_type_class_add_private (class, sizeof (GtkPrintJobPrivate));
109
110   g_object_class_install_property (G_OBJECT_CLASS (class),
111                                    GTK_PRINT_JOB_PROP_TITLE,
112                                    g_param_spec_string ("title",
113                                                         P_("Title"),
114                                                         P_("Title of the print job"),
115                                                         NULL,
116                                                         GTK_PARAM_READWRITE |
117                                                         G_PARAM_CONSTRUCT_ONLY));
118
119   g_object_class_install_property (G_OBJECT_CLASS (class),
120                                    GTK_PRINT_JOB_PROP_PRINTER,
121                                    g_param_spec_object ("printer",
122                                                         P_("Printer"),
123                                                         P_("Printer to print the job to"),
124                                                         GTK_TYPE_PRINTER,
125                                                         GTK_PARAM_READWRITE |
126                                                         G_PARAM_CONSTRUCT_ONLY));
127
128   g_object_class_install_property (G_OBJECT_CLASS (class),
129                                    GTK_PRINT_JOB_PROP_SETTINGS,
130                                    g_param_spec_object ("settings",
131                                                         P_("Settings"),
132                                                         P_("Printer settings"),
133                                                         GTK_TYPE_PRINT_SETTINGS,
134                                                         GTK_PARAM_READWRITE |
135                                                         G_PARAM_CONSTRUCT_ONLY));
136
137   g_object_class_install_property (G_OBJECT_CLASS (class),
138                                    GTK_PRINT_JOB_PROP_PAGE_SETUP,
139                                    g_param_spec_object ("page-setup",
140                                                         P_("Page Setup"),
141                                                         P_("Page Setup"),
142                                                         GTK_TYPE_PAGE_SETUP,
143                                                         GTK_PARAM_READWRITE |
144                                                         G_PARAM_CONSTRUCT_ONLY));
145
146   /**
147    * GtkPrintJob::status-changed:
148    * @job: the #GtkPrintJob object on which the signal was emitted
149    *
150    * Gets emitted when the status of a job changes. The signal handler
151    * can use gtk_print_job_get_status() to obtain the new status.
152    *
153    * Since: 2.10
154    */
155   signals[STATUS_CHANGED] =
156    g_signal_new ("status-changed",
157                  G_TYPE_FROM_CLASS (class),
158                  G_SIGNAL_RUN_LAST,
159                  G_STRUCT_OFFSET (GtkPrintJobClass, status_changed),
160                  NULL, NULL,
161                  g_cclosure_marshal_VOID__VOID,
162                  G_TYPE_NONE, 0);
163 }
164
165 static void
166 gtk_print_job_init (GtkPrintJob *job)
167 {
168   job->priv = GTK_PRINT_JOB_GET_PRIVATE (job); 
169   job->priv->spool_file_fd = -1;
170
171   job->priv->title = g_strdup ("");
172   job->priv->surface = NULL;
173   job->priv->backend = NULL;
174   job->priv->printer = NULL;
175
176   job->priv->printer_set = FALSE;
177   job->priv->settings_set = FALSE;
178   job->priv->page_setup_set = FALSE;
179   job->priv->status = GTK_PRINT_STATUS_INITIAL;
180
181   job->print_pages = GTK_PRINT_PAGES_ALL;
182   job->page_ranges = NULL;
183   job->num_page_ranges = 0;
184   job->collate = FALSE;
185   job->reverse = FALSE;
186   job->num_copies = 1;
187   job->scale = 1.0;
188   job->page_set = GTK_PAGE_SET_ALL;
189   job->rotate_to_orientation = FALSE;
190 }
191
192
193 static GObject*
194 gtk_print_job_constructor (GType                  type,
195                            guint                  n_construct_properties,
196                            GObjectConstructParam *construct_params)
197 {
198   GtkPrintJob *job;
199   GObject *object;
200
201   object =
202     G_OBJECT_CLASS (gtk_print_job_parent_class)->constructor (type,
203                                                               n_construct_properties,
204                                                               construct_params);
205
206   job = GTK_PRINT_JOB (object);
207   
208   g_assert (job->priv->printer_set &&
209             job->priv->settings_set &&
210             job->priv->page_setup_set);
211   
212   _gtk_printer_prepare_for_print (job->priv->printer,
213                                   job,
214                                   job->priv->settings,
215                                   job->priv->page_setup);
216
217   return object;
218 }
219
220
221 static void
222 gtk_print_job_finalize (GObject *object)
223 {
224   GtkPrintJob *job;
225   
226   g_return_if_fail (object != NULL);
227
228   job = GTK_PRINT_JOB (object);
229
230   if (job->priv->spool_file_fd > 0)
231     {
232       close (job->priv->spool_file_fd);
233       job->priv->spool_file_fd = -1;
234     }
235   
236   if (job->priv->backend)
237     g_object_unref (G_OBJECT (job->priv->backend));
238
239   if (job->priv->printer)
240     g_object_unref (G_OBJECT (job->priv->printer));
241
242   if (job->priv->surface)
243     cairo_surface_destroy (job->priv->surface);
244
245   if (job->priv->settings)
246     g_object_unref (job->priv->settings);
247   
248   if (job->priv->page_setup)
249     g_object_unref (job->priv->page_setup);
250
251   g_free (job->page_ranges);
252   job->page_ranges = NULL;
253   
254   g_free (job->priv->title);
255   job->priv->title = NULL;
256   
257   if (G_OBJECT_CLASS (gtk_print_job_parent_class)->finalize)
258     G_OBJECT_CLASS (gtk_print_job_parent_class)->finalize (object);
259 }
260
261 /**
262  * gtk_print_job_new:
263  * @title: the job title
264  * @printer: a #GtkPrinter
265  * @settings: a #GtkPrintSettings
266  * @page_setup: a #GtkPageSetup
267  *
268  * Creates a new #GtkPrintJob.
269  *
270  * Return value: a new #GtkPrintJob
271  *
272  * Since: 2.10
273  **/
274 GtkPrintJob *
275 gtk_print_job_new (const gchar      *title,
276                    GtkPrinter       *printer,
277                    GtkPrintSettings *settings,
278                    GtkPageSetup     *page_setup)
279 {
280   GObject *result;
281   result = g_object_new (GTK_TYPE_PRINT_JOB,
282                          "title", title,
283                          "printer", printer,
284                          "settings", settings,
285                          "page-setup", page_setup,
286                          NULL);
287   return (GtkPrintJob *) result;
288 }
289
290 /**
291  * gtk_print_job_get_settings:
292  * @job: a #GtkPrintJob
293  * 
294  * Gets the #GtkPrintSettings of the print job.
295  * 
296  * Return value: the settings of @job
297  *
298  * Since: 2.10
299  */
300 GtkPrintSettings *
301 gtk_print_job_get_settings (GtkPrintJob *job)
302 {
303   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), NULL);
304   
305   return job->priv->settings;
306 }
307
308 /**
309  * gtk_print_job_get_printer:
310  * @job: a #GtkPrintJob
311  * 
312  * Gets the #GtkPrinter of the print job.
313  * 
314  * Return value: the printer of @job
315  *
316  * Since: 2.10
317  */
318 GtkPrinter *
319 gtk_print_job_get_printer (GtkPrintJob *job)
320 {
321   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), NULL);
322   
323   return job->priv->printer;
324 }
325
326 /**
327  * gtk_print_job_get_title:
328  * @job: a #GtkPrintJob
329  * 
330  * Gets the job title.
331  * 
332  * Return value: the title of @job
333  *
334  * Since: 2.10
335  */
336 G_CONST_RETURN gchar *
337 gtk_print_job_get_title (GtkPrintJob *job)
338 {
339   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), NULL);
340   
341   return job->priv->title;
342 }
343
344 /**
345  * gtk_print_job_get_status:
346  * @job: a #GtkPrintJob
347  * 
348  * Gets the status of the print job.
349  * 
350  * Return value: the status of @job
351  *
352  * Since: 2.10
353  */
354 GtkPrintStatus
355 gtk_print_job_get_status (GtkPrintJob *job)
356 {
357   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), GTK_PRINT_STATUS_FINISHED);
358   
359   return job->priv->status;
360 }
361
362 void
363 gtk_print_job_set_status (GtkPrintJob   *job,
364                           GtkPrintStatus status)
365 {
366   g_return_if_fail (GTK_IS_PRINT_JOB (job));
367
368   if (job->priv->status == status)
369     return;
370
371   job->priv->status = status;
372   g_signal_emit (job, signals[STATUS_CHANGED], 0);
373 }
374
375 /**
376  * gtk_print_job_set_source_file:
377  * @job: a #GtkPrintJob
378  * @filename: the file to be printed
379  * @error: return location for errors
380  * 
381  * Make the #GtkPrintJob send an existing document to the 
382  * printing system. The file can be in any format understood
383  * by the platforms printing system (typically PostScript,
384  * but on many platforms PDF may work too).
385  * 
386  * Returns: %FALSE if an error occurred
387  *
388  * Since: 2.10
389  **/
390 gboolean
391 gtk_print_job_set_source_file (GtkPrintJob *job,
392                                const gchar *filename,
393                                GError     **error)
394 {
395   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), FALSE);
396   
397   job->priv->spool_file_fd = g_open (filename, O_RDONLY|O_BINARY);
398   if (job->priv->spool_file_fd < 0)
399     {
400       gchar *display_filename = g_filename_display_name (filename);
401       int save_errno = errno;
402       
403       g_set_error (error,
404                    G_FILE_ERROR,
405                    g_file_error_from_errno (save_errno),
406                    _("Failed to open file '%s': %s"),
407                    display_filename, 
408                    g_strerror (save_errno));
409       
410       g_free (display_filename);
411
412       return FALSE;
413     }
414     return TRUE;
415 }
416
417 /**
418  * gtk_print_job_get_surface:
419  * @job: a #GtkPrintJob
420  * @error: return location for errors, or %NULL
421  * 
422  * Gets a cairo surface onto which the pages of
423  * the print job should be rendered.
424  * 
425  * Return value: the cairo surface of @job
426  *
427  * Since: 2.10
428  **/
429 cairo_surface_t *
430 gtk_print_job_get_surface (GtkPrintJob  *job,
431                            GError      **error)
432 {
433   gchar *filename;
434   gdouble width, height;
435   GtkPaperSize *paper_size;
436   
437   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), NULL);
438
439   if (job->priv->surface)
440     return job->priv->surface;
441   
442   job->priv->spool_file_fd = g_file_open_tmp ("gtkprint_XXXXXX", 
443                                                     &filename, 
444                                                     error);
445   if (job->priv->spool_file_fd == -1)
446     return NULL;
447
448   fchmod (job->priv->spool_file_fd, S_IRUSR | S_IWUSR);
449   unlink (filename);
450
451   paper_size = gtk_page_setup_get_paper_size (job->priv->page_setup);
452   width = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
453   height = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
454   
455   job->priv->surface = _gtk_printer_create_cairo_surface (job->priv->printer,
456                                                           width, height,
457                                                           job->priv->spool_file_fd);
458  
459   return job->priv->surface;
460 }
461
462 static void
463 gtk_print_job_set_property (GObject      *object,
464                             guint         prop_id,
465                             const GValue *value,
466                             GParamSpec   *pspec)
467
468 {
469   GtkPrintJob *job = GTK_PRINT_JOB (object);
470   GtkPrintSettings *settings;
471
472   switch (prop_id)
473     {
474     case GTK_PRINT_JOB_PROP_TITLE:
475       job->priv->title = g_value_dup_string (value);
476       break;
477     
478     case GTK_PRINT_JOB_PROP_PRINTER:
479       job->priv->printer = GTK_PRINTER (g_value_dup_object (value));
480       job->priv->printer_set = TRUE;
481       job->priv->backend = g_object_ref (gtk_printer_get_backend (job->priv->printer));
482       break;
483
484     case GTK_PRINT_JOB_PROP_PAGE_SETUP:
485       job->priv->page_setup = GTK_PAGE_SETUP (g_value_dup_object (value));
486       job->priv->page_setup_set = TRUE;
487       break;
488       
489     case GTK_PRINT_JOB_PROP_SETTINGS:
490       /* We save a copy of the settings since we modify
491        * if when preparing the printer job. */
492       settings = GTK_PRINT_SETTINGS (g_value_get_object (value));
493       job->priv->settings = gtk_print_settings_copy (settings);
494       job->priv->settings_set = TRUE;
495       break;
496
497     default:
498       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
499       break;
500     }
501 }
502
503 static void
504 gtk_print_job_get_property (GObject    *object,
505                             guint       prop_id,
506                             GValue     *value,
507                             GParamSpec *pspec)
508 {
509   GtkPrintJob *job = GTK_PRINT_JOB (object);
510
511   switch (prop_id)
512     {
513     case GTK_PRINT_JOB_PROP_TITLE:
514       g_value_set_string (value, job->priv->title);
515       break;
516     case GTK_PRINT_JOB_PROP_PRINTER:
517       g_value_set_object (value, job->priv->printer);
518       break;
519     case GTK_PRINT_JOB_PROP_SETTINGS:
520       g_value_set_object (value, job->priv->settings);
521       break;
522     case GTK_PRINT_JOB_PROP_PAGE_SETUP:
523       g_value_set_object (value, job->priv->page_setup);
524       break;
525     default:
526       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
527       break;
528     }
529 }
530
531 /**
532  * gtk_print_job_send:
533  * @job: a GtkPrintJob
534  * @callback: function to call when the job completes
535  * @user_data: user data that gets passed to @callback
536  * @dnotify: destroy notify for @user_data
537  * @error: return location for errors, or %NULL
538  * 
539  * Sends the print job off to the printer.  
540  * 
541  * Return value: %FALSE if an error occurred
542  *
543  * Since: 2.10
544  **/
545 gboolean
546 gtk_print_job_send (GtkPrintJob             *job,
547                     GtkPrintJobCompleteFunc  callback,
548                     gpointer                 user_data,
549                     GDestroyNotify           dnotify,
550                     GError                 **error)
551 {
552   g_return_val_if_fail (GTK_IS_PRINT_JOB (job), FALSE);
553   g_return_val_if_fail (job->priv->spool_file_fd > 0, FALSE);
554   
555   gtk_print_job_set_status (job, GTK_PRINT_STATUS_SENDING_DATA);
556   lseek (job->priv->spool_file_fd, 0, SEEK_SET);
557   gtk_print_backend_print_stream (job->priv->backend,
558                                   job,
559                                   job->priv->spool_file_fd,
560                                   callback,
561                                   user_data,
562                                   dnotify);
563
564   return TRUE;
565 }
566
567 #define __GTK_PRINT_JOB_C__
568 #include "gtkaliasdef.c"