]> www.fi.muni.cz Git - evince.git/blob - shell/ev-print-job.c
Translation updated.
[evince.git] / shell / ev-print-job.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2004 Martin Kretzschmar
4  *
5  *  Author:
6  *    Martin Kretzschmar <martink@gnome.org>
7  *
8  * Evince is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Evince is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21  */
22
23 #include <config.h>
24
25 #include <unistd.h>
26
27 #include <glib.h>
28 #include <glib/gi18n.h>
29 #include <glib-object.h>
30
31 /* for gnome_print_job_set_file */
32 #define GNOME_PRINT_UNSTABLE_API
33 #include <libgnomeprint/gnome-print-job.h>
34
35 #include "ev-file-exporter.h"
36 #include "ev-print-job.h"
37 #include "ev-page-cache.h"
38
39 #define EV_PRINT_JOB_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), EV_PRINT_JOB, EvPrintJobClass))
40 #define EV_IS_PRINT_JOB_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), EV_PRINT_JOB))
41 #define EV_PRINT_JOB_GET_CLASS(object)  (G_TYPE_INSTANCE_GET_CLASS((object), EV_PRINT_JOB, EvPrintJobClass))
42
43 struct _EvPrintJob {
44         GObject parent_instance;
45
46         EvDocument *document;
47         GnomePrintJob *gnome_print_job;
48         double width; /* FIXME unused */
49         double height; /* FIXME unused */
50         gboolean duplex; /* FIXME unused */
51         int copies;
52         int collate;
53
54         /* range printing */
55         int first_page;
56         int last_page;
57
58         int fd;
59         char *temp_file;
60         guint idle_id;
61         gboolean printing;
62         int next_page;
63         int copies_done;
64         int shift;
65 };
66
67 struct _EvPrintJobClass {
68         GObjectClass parent_class;
69 };
70
71 enum {
72         PROP_0,
73         PROP_GNOME_PRINT_JOB,
74         PROP_DOCUMENT,
75         PROP_PRINT_DIALOG
76 };
77
78 G_DEFINE_TYPE (EvPrintJob, ev_print_job, G_TYPE_OBJECT);
79
80 static void
81 ev_print_job_finalize (GObject *object)
82 {
83         EvPrintJob *job = EV_PRINT_JOB (object);
84
85         if (job && job->document) {
86                 g_object_unref (job->document);
87                 job->document = NULL;
88         }
89
90         if (job && job->gnome_print_job) {
91                 g_object_unref (job->gnome_print_job);
92                 job->gnome_print_job = NULL;
93         }
94
95         G_OBJECT_CLASS (ev_print_job_parent_class)->finalize (object);
96 }
97
98 static void
99 ev_print_job_set_property (GObject *object, guint prop_id,
100                            const GValue *value, GParamSpec *pspec)
101 {
102         EvPrintJob *job;
103
104         job = EV_PRINT_JOB (object);
105
106         switch (prop_id) {
107         case PROP_GNOME_PRINT_JOB:
108                 ev_print_job_set_gnome_print_job (
109                         job, GNOME_PRINT_JOB (g_value_get_object (value)));
110                 break;
111         case PROP_DOCUMENT:
112                 ev_print_job_set_document (job, EV_DOCUMENT (g_value_get_object (value)));
113                 break;
114         case PROP_PRINT_DIALOG:
115                 ev_print_job_use_print_dialog_settings (
116                         job, GNOME_PRINT_DIALOG (g_value_get_object (value)));
117                 break;
118         default:
119                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
120                 break;
121         }
122
123 }
124
125 static void
126 ev_print_job_get_property (GObject *object, guint prop_id,
127                            GValue *value, GParamSpec *pspec)
128 {
129         EvPrintJob *job;
130
131         job = EV_PRINT_JOB (object);
132
133         switch (prop_id) {
134         case PROP_GNOME_PRINT_JOB:
135                 g_value_set_object (value, job->gnome_print_job);
136                 break;
137         case PROP_DOCUMENT:
138                 g_value_set_object (value, job->document);
139                 break;
140         default:
141                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
142                 break;
143         }
144 }
145
146
147 static void
148 ev_print_job_class_init (EvPrintJobClass *ev_print_job_class)
149 {
150         GObjectClass *g_object_class;
151
152         g_object_class = G_OBJECT_CLASS (ev_print_job_class);
153
154         g_object_class->finalize = ev_print_job_finalize;
155         g_object_class->set_property = ev_print_job_set_property;
156         g_object_class->get_property = ev_print_job_get_property;
157
158         g_object_class_install_property (g_object_class,
159                                          PROP_GNOME_PRINT_JOB,
160                                          g_param_spec_object ("gnome_print_job",
161                                                               "GnomePrintJob",
162                                                               "GnomePrintJob",
163                                                               GNOME_TYPE_PRINT_JOB,
164                                                               G_PARAM_READWRITE));
165         g_object_class_install_property (g_object_class,
166                                          PROP_DOCUMENT,
167                                          g_param_spec_object ("document",
168                                                               "Document object",
169                                                               "Document from which to print",
170                                                               G_TYPE_OBJECT, /* EV_TYPE_DOCUMENT, */
171                                                               G_PARAM_READWRITE));
172         g_object_class_install_property (g_object_class,
173                                          PROP_PRINT_DIALOG,
174                                          g_param_spec_object ("print_dialog",
175                                                               "GnomePrintDialog",
176                                                               "GnomePrintDialog with user settings",
177                                                               GNOME_TYPE_PRINT_DIALOG,
178                                                               G_PARAM_WRITABLE));
179
180 }
181
182 static void
183 ev_print_job_init (EvPrintJob *ev_print_job)
184 {
185 }
186
187 void
188 ev_print_job_set_gnome_print_job (EvPrintJob *job, GnomePrintJob *gpj)
189 {
190         g_return_if_fail (EV_IS_PRINT_JOB (job));
191
192         if (job->gnome_print_job == gpj)
193                 return;
194
195         if (job->gnome_print_job)
196                 g_object_unref (job->gnome_print_job);
197         
198         if (gpj)
199                 g_object_ref (gpj);
200
201         job->gnome_print_job = gpj;
202 }
203
204 void
205 ev_print_job_set_document (EvPrintJob *job, EvDocument *document)
206 {
207         g_return_if_fail (EV_IS_PRINT_JOB (job));
208
209         if (job->document == document)
210                 return;
211
212         if (job->document)
213                 g_object_ref (job->document);
214
215         if (document)
216                 g_object_ref (document);
217         
218         job->document = document;
219 }
220
221 void
222 ev_print_job_use_print_dialog_settings (EvPrintJob *job, GnomePrintDialog *dialog)
223 {
224         GnomePrintConfig *print_config;
225         EvPageCache *page_cache = ev_page_cache_get (job->document);
226
227         g_return_if_fail (EV_IS_PRINT_JOB (job));
228         g_return_if_fail (GNOME_IS_PRINT_DIALOG (dialog));
229
230         print_config = gnome_print_dialog_get_config (dialog);
231         gnome_print_dialog_get_copies (dialog, &job->copies, &job->collate);
232         gnome_print_config_get_page_size (print_config,
233                                           &job->width, &job->height);
234         gnome_print_config_get_boolean (print_config,
235                                         (guchar *)GNOME_PRINT_KEY_DUPLEX, &job->duplex);
236
237         page_cache = ev_page_cache_get (job->document);
238
239         /* get the printing ranges */
240         switch (gnome_print_dialog_get_range (dialog)) {
241         case GNOME_PRINT_RANGE_ALL:
242                 job->first_page = 0;
243                 job->last_page = ev_page_cache_get_n_pages (page_cache) - 1;
244                 break;
245         case GNOME_PRINT_RANGE_RANGE:
246                 gnome_print_dialog_get_range_page (dialog, &job->first_page, &job->last_page);
247                 /* convert 1-based user interface to 0-based internal numbers */
248                 job->first_page--;
249                 job->last_page--;
250                 break;
251         default:
252                 g_assert_not_reached ();
253         }
254
255         gnome_print_config_unref (print_config);
256 }
257
258 static gboolean
259 idle_print_handler (EvPrintJob *job)
260 {
261         if (!job->printing) {
262                 ev_document_doc_mutex_lock ();
263                 ev_file_exporter_begin (
264                         EV_FILE_EXPORTER (job->document),
265                         EV_FILE_FORMAT_PS,
266                         job->temp_file, 
267                         MIN (job->first_page, job->last_page),
268                         MAX (job->first_page, job->last_page),
269                         job->width, job->height, job->duplex);
270                 ev_document_doc_mutex_unlock ();
271                 job->next_page = job->first_page;
272                 job->shift = (job->first_page > job->last_page) ? -1 : 1;
273                 job->printing = TRUE;
274                 return TRUE;
275         }
276         
277         if ((job->next_page - job->last_page) * job->shift <= 0) {
278                 EvRenderContext *rc;
279 #if 0
280                 g_printerr ("Printing page %d\n", job->next_page);
281 #endif
282                 rc = ev_render_context_new (0, job->next_page, 1.0);
283
284                 ev_document_doc_mutex_lock ();
285                 ev_file_exporter_do_page (EV_FILE_EXPORTER (job->document), rc);
286                 ev_document_doc_mutex_unlock ();
287
288                 g_object_unref (rc);
289
290                 if (job->collate) {
291                         /* collate must repeat the same page */
292                         job->copies_done++;
293                         if(job->copies == job->copies_done) {
294                                 job->next_page += job->shift;
295                                 job->copies_done = 0;
296                         }
297                 } else {
298                         job->next_page += job->shift;
299                         if ((job->next_page - job->last_page) * job->shift > 0){
300                                 job->copies_done++;
301                                 if(job->copies_done < job->copies) {
302                                         /* more copies to go, restart to the first page */
303                                         job->next_page = job->first_page;
304                                 }
305                         }
306                 }
307                 return TRUE;
308         } else { /* no more pages or copies */
309                 ev_document_doc_mutex_lock ();
310                 ev_file_exporter_end (EV_FILE_EXPORTER (job->document));
311                 ev_document_doc_mutex_unlock ();
312
313                 close (job->fd);
314                 job->fd = 0;
315
316                 gnome_print_job_print (job->gnome_print_job);
317
318                 unlink (job->temp_file);
319                 g_free (job->temp_file);
320
321                 g_object_unref (job->gnome_print_job);
322                 job->gnome_print_job = NULL;
323
324                 job->printing = FALSE;
325                 job->idle_id = 0;
326                 return FALSE;
327         }
328 }
329
330 static void
331 print_closure_finalize (EvPrintJob *job, GClosure *closure)
332 {
333         g_object_unref (job);
334 }
335
336 void
337 ev_print_job_print (EvPrintJob *job, GtkWindow *parent)
338 {
339         GClosure *closure;
340         GSource *idle_source;
341
342         g_return_if_fail (EV_IS_PRINT_JOB (job));
343         g_return_if_fail (job->document != NULL);
344         g_return_if_fail (EV_IS_FILE_EXPORTER (job->document));
345 #if 0
346         g_printerr ("Printing...\n");
347 #endif
348
349         job->fd = g_file_open_tmp ("evince_print.ps.XXXXXX", &job->temp_file, NULL);
350         if (job->fd <= -1)
351                 return; /* FIXME use GError */
352
353         gnome_print_job_set_file (job->gnome_print_job, job->temp_file);
354
355         g_object_ref (job);
356         closure = g_cclosure_new (G_CALLBACK (idle_print_handler), job, NULL);
357         g_closure_add_finalize_notifier (
358                 closure, job, (GClosureNotify)print_closure_finalize);
359
360         idle_source = g_idle_source_new ();
361         g_source_set_closure (idle_source, closure);
362         job->idle_id = g_source_attach (idle_source, NULL);
363         g_source_unref (idle_source);
364 }