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