]> www.fi.muni.cz Git - evince.git/blob - shell/ev-print-job.c
intltool-update de
[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         EvFileExporterContext fc;
49         int copies;
50         int collate;
51
52         int fd;
53         char *temp_file;
54         guint idle_id;
55         gboolean printing;
56         int next_page;
57         int copies_done;
58         int shift;
59 };
60
61 struct _EvPrintJobClass {
62         GObjectClass parent_class;
63 };
64
65 enum {
66         PROP_0,
67         PROP_GNOME_PRINT_JOB,
68         PROP_DOCUMENT,
69         PROP_PRINT_DIALOG
70 };
71
72 G_DEFINE_TYPE (EvPrintJob, ev_print_job, G_TYPE_OBJECT);
73
74 static void
75 ev_print_job_finalize (GObject *object)
76 {
77         EvPrintJob *job = EV_PRINT_JOB (object);
78
79         if (job && job->document) {
80                 g_object_unref (job->document);
81                 job->document = NULL;
82         }
83
84         if (job && job->gnome_print_job) {
85                 g_object_unref (job->gnome_print_job);
86                 job->gnome_print_job = NULL;
87         }
88
89         G_OBJECT_CLASS (ev_print_job_parent_class)->finalize (object);
90 }
91
92 static void
93 ev_print_job_set_property (GObject *object, guint prop_id,
94                            const GValue *value, GParamSpec *pspec)
95 {
96         EvPrintJob *job;
97
98         job = EV_PRINT_JOB (object);
99
100         switch (prop_id) {
101         case PROP_GNOME_PRINT_JOB:
102                 ev_print_job_set_gnome_print_job (
103                         job, GNOME_PRINT_JOB (g_value_get_object (value)));
104                 break;
105         case PROP_DOCUMENT:
106                 ev_print_job_set_document (job, EV_DOCUMENT (g_value_get_object (value)));
107                 break;
108         case PROP_PRINT_DIALOG:
109                 ev_print_job_use_print_dialog_settings (
110                         job, GNOME_PRINT_DIALOG (g_value_get_object (value)));
111                 break;
112         default:
113                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
114                 break;
115         }
116
117 }
118
119 static void
120 ev_print_job_get_property (GObject *object, guint prop_id,
121                            GValue *value, GParamSpec *pspec)
122 {
123         EvPrintJob *job;
124
125         job = EV_PRINT_JOB (object);
126
127         switch (prop_id) {
128         case PROP_GNOME_PRINT_JOB:
129                 g_value_set_object (value, job->gnome_print_job);
130                 break;
131         case PROP_DOCUMENT:
132                 g_value_set_object (value, job->document);
133                 break;
134         default:
135                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
136                 break;
137         }
138 }
139
140
141 static void
142 ev_print_job_class_init (EvPrintJobClass *ev_print_job_class)
143 {
144         GObjectClass *g_object_class;
145
146         g_object_class = G_OBJECT_CLASS (ev_print_job_class);
147
148         g_object_class->finalize = ev_print_job_finalize;
149         g_object_class->set_property = ev_print_job_set_property;
150         g_object_class->get_property = ev_print_job_get_property;
151
152         g_object_class_install_property (g_object_class,
153                                          PROP_GNOME_PRINT_JOB,
154                                          g_param_spec_object ("gnome_print_job",
155                                                               "GnomePrintJob",
156                                                               "GnomePrintJob",
157                                                               GNOME_TYPE_PRINT_JOB,
158                                                               G_PARAM_READWRITE));
159         g_object_class_install_property (g_object_class,
160                                          PROP_DOCUMENT,
161                                          g_param_spec_object ("document",
162                                                               "Document object",
163                                                               "Document from which to print",
164                                                               G_TYPE_OBJECT, /* EV_TYPE_DOCUMENT, */
165                                                               G_PARAM_READWRITE));
166         g_object_class_install_property (g_object_class,
167                                          PROP_PRINT_DIALOG,
168                                          g_param_spec_object ("print_dialog",
169                                                               "GnomePrintDialog",
170                                                               "GnomePrintDialog with user settings",
171                                                               GNOME_TYPE_PRINT_DIALOG,
172                                                               G_PARAM_WRITABLE));
173
174 }
175
176 static void
177 ev_print_job_init (EvPrintJob *ev_print_job)
178 {
179 }
180
181 void
182 ev_print_job_set_gnome_print_job (EvPrintJob *job, GnomePrintJob *gpj)
183 {
184         g_return_if_fail (EV_IS_PRINT_JOB (job));
185
186         if (job->gnome_print_job == gpj)
187                 return;
188
189         if (job->gnome_print_job)
190                 g_object_unref (job->gnome_print_job);
191         
192         if (gpj)
193                 g_object_ref (gpj);
194
195         job->gnome_print_job = gpj;
196 }
197
198 void
199 ev_print_job_set_document (EvPrintJob *job, EvDocument *document)
200 {
201         g_return_if_fail (EV_IS_PRINT_JOB (job));
202
203         if (job->document == document)
204                 return;
205
206         if (job->document)
207                 g_object_ref (job->document);
208
209         if (document)
210                 g_object_ref (document);
211         
212         job->document = document;
213 }
214
215 void
216 ev_print_job_use_print_dialog_settings (EvPrintJob *job, GnomePrintDialog *dialog)
217 {
218         GnomePrintConfig *print_config;
219         EvPageCache *page_cache = ev_page_cache_get (job->document);
220         gint first_page, last_page;
221
222         g_return_if_fail (EV_IS_PRINT_JOB (job));
223         g_return_if_fail (GNOME_IS_PRINT_DIALOG (dialog));
224
225         print_config = gnome_print_dialog_get_config (dialog);
226         gnome_print_dialog_get_copies (dialog, &job->copies, &job->collate);
227         gnome_print_config_get_page_size (print_config,
228                                           &job->fc.paper_width, &job->fc.paper_height);
229         gnome_print_config_get_boolean (print_config,
230                                         (guchar *)GNOME_PRINT_KEY_DUPLEX, &job->fc.duplex);
231
232         page_cache = ev_page_cache_get (job->document);
233
234         /* get the printing ranges */
235         switch (gnome_print_dialog_get_range (dialog)) {
236         case GNOME_PRINT_RANGE_ALL:
237                 first_page = 0;
238                 last_page = ev_page_cache_get_n_pages (page_cache) - 1;
239                 break;
240         case GNOME_PRINT_RANGE_RANGE:
241                 gnome_print_dialog_get_range_page (dialog, &first_page, &last_page);
242                 /* convert 1-based user interface to 0-based internal numbers */
243                 first_page--;
244                 last_page--;
245                 break;
246         default:
247                 g_assert_not_reached ();
248         }
249
250         job->fc.first_page = MIN (first_page, last_page);
251         job->fc.last_page = MAX (first_page, last_page);
252
253         gnome_print_config_unref (print_config);
254 }
255
256 static gboolean
257 idle_print_handler (EvPrintJob *job)
258 {
259         if (!job->printing) {
260                 ev_document_doc_mutex_lock ();
261                 ev_file_exporter_begin (EV_FILE_EXPORTER (job->document),
262                                         &(job->fc));
263                 ev_document_doc_mutex_unlock ();
264                 job->next_page = job->fc.first_page;
265                 job->shift = (job->fc.first_page > job->fc.last_page) ? -1 : 1;
266                 job->printing = TRUE;
267                 return TRUE;
268         }
269         
270         if ((job->next_page - job->fc.last_page) * job->shift <= 0) {
271                 EvRenderContext *rc;
272 #if 0
273                 g_printerr ("Printing page %d\n", job->next_page);
274 #endif
275                 rc = ev_render_context_new (0, job->next_page, 1.0);
276
277                 ev_document_doc_mutex_lock ();
278                 ev_file_exporter_do_page (EV_FILE_EXPORTER (job->document), rc);
279                 ev_document_doc_mutex_unlock ();
280
281                 g_object_unref (rc);
282
283                 if (job->collate) {
284                         /* collate must repeat the same page */
285                         job->copies_done++;
286                         if(job->copies == job->copies_done) {
287                                 job->next_page += job->shift;
288                                 job->copies_done = 0;
289                         }
290                 } else {
291                         job->next_page += job->shift;
292                         if ((job->next_page - job->fc.last_page) * job->shift > 0){
293                                 job->copies_done++;
294                                 if(job->copies_done < job->copies) {
295                                         /* more copies to go, restart to the first page */
296                                         job->next_page = job->fc.first_page;
297                                 }
298                         }
299                 }
300                 return TRUE;
301         } else { /* no more pages or copies */
302                 ev_document_doc_mutex_lock ();
303                 ev_file_exporter_end (EV_FILE_EXPORTER (job->document));
304                 ev_document_doc_mutex_unlock ();
305
306                 close (job->fd);
307                 job->fd = 0;
308
309                 gnome_print_job_print (job->gnome_print_job);
310
311                 unlink (job->temp_file);
312                 g_free (job->temp_file);
313
314                 g_object_unref (job->gnome_print_job);
315                 job->gnome_print_job = NULL;
316
317                 job->printing = FALSE;
318                 job->idle_id = 0;
319                 return FALSE;
320         }
321 }
322
323 static void
324 print_closure_finalize (EvPrintJob *job, GClosure *closure)
325 {
326         g_object_unref (job);
327 }
328
329 void
330 ev_print_job_print (EvPrintJob *job, GtkWindow *parent)
331 {
332         GClosure *closure;
333         GSource *idle_source;
334
335         g_return_if_fail (EV_IS_PRINT_JOB (job));
336         g_return_if_fail (job->document != NULL);
337         g_return_if_fail (EV_IS_FILE_EXPORTER (job->document));
338 #if 0
339         g_printerr ("Printing...\n");
340 #endif
341
342         job->fd = g_file_open_tmp ("evince_print.ps.XXXXXX", &job->temp_file, NULL);
343         if (job->fd <= -1)
344                 return; /* FIXME use GError */
345
346         job->fc.format = EV_FILE_FORMAT_PS;
347         job->fc.filename = job->temp_file;
348         gnome_print_job_set_file (job->gnome_print_job, job->temp_file);
349
350         g_object_ref (job);
351         closure = g_cclosure_new (G_CALLBACK (idle_print_handler), job, NULL);
352         g_closure_add_finalize_notifier (
353                 closure, job, (GClosureNotify)print_closure_finalize);
354
355         idle_source = g_idle_source_new ();
356         g_source_set_closure (idle_source, closure);
357         job->idle_id = g_source_attach (idle_source, NULL);
358         g_source_unref (idle_source);
359 }