Mercurial > geeqie.yaz
comparison src/print.c @ 9:d907d608745f
Sync to GQview 1.5.9 release.
########
DO NOT BASE ENHANCEMENTS OR TRANSLATION UPDATES ON CODE IN THIS CVS!
This CVS is never up to date with current development and is provided
solely for reference purposes, please use the latest official release
package when making any changes or translation updates.
########
author | gqview |
---|---|
date | Sat, 26 Feb 2005 00:13:35 +0000 |
parents | |
children | 17acca639a86 |
comparison
equal
deleted
inserted
replaced
8:e0d0593d519e | 9:d907d608745f |
---|---|
1 /* | |
2 * GQview | |
3 * (C) 2004 John Ellis | |
4 * | |
5 * Author: John Ellis | |
6 * | |
7 * This software is released under the GNU General Public License (GNU GPL). | |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
10 */ | |
11 | |
12 | |
13 #include "gqview.h" | |
14 #include "print.h" | |
15 | |
16 #include "filelist.h" | |
17 #include "image.h" | |
18 #include "image-load.h" | |
19 #include "pixbuf_util.h" | |
20 #include "thumb.h" | |
21 #include "utilops.h" | |
22 #include "ui_bookmark.h" | |
23 #include "ui_menu.h" | |
24 #include "ui_misc.h" | |
25 #include "ui_utildlg.h" | |
26 #include "ui_fileops.h" | |
27 #include "ui_spinner.h" | |
28 #include "ui_tabcomp.h" | |
29 | |
30 | |
31 #include <locale.h> | |
32 #include <signal.h> | |
33 | |
34 | |
35 #define PRINT_LPR_COMMAND "lpr" | |
36 #define PRINT_LPR_CUSTOM "lpr -P %s" | |
37 #define PRINT_LPR_QUERY "lpstat -p" | |
38 | |
39 #define PRINT_DLG_WIDTH 600 | |
40 #define PRINT_DLG_HEIGHT 400 | |
41 | |
42 #define PRINT_DLG_PREVIEW_WIDTH 270 | |
43 #define PRINT_DLG_PREVIEW_HEIGHT -1 | |
44 | |
45 /* these are in point units */ | |
46 #define PRINT_MIN_WIDTH 100 | |
47 #define PRINT_MIN_HEIGHT 100 | |
48 #define PRINT_MAX_WIDTH 4000 | |
49 #define PRINT_MAX_HEIGHT 4000 | |
50 | |
51 #define PRINT_MARGIN_DEFAULT 36 | |
52 | |
53 #define PRINT_PROOF_MIN_SIZE 8 | |
54 #define PRINT_PROOF_MAX_SIZE 720 | |
55 #define PRINT_PROOF_DEFAULT_SIZE 144 | |
56 #define PRINT_PROOF_MARGIN 5 | |
57 | |
58 /* default page size */ | |
59 #define PAGE_LAYOUT_WIDTH 850 | |
60 #define PAGE_LAYOUT_HEIGHT 1100 | |
61 | |
62 /* preview uses 1 pixel = PRINT_PREVIEW_SCALE points */ | |
63 #define PRINT_PREVIEW_SCALE 4 | |
64 | |
65 /* default dpi to use for printing ps image data */ | |
66 #define PRINT_PS_DPI_DEFAULT 300.0 | |
67 #define PRINT_PS_DPI_MIN 150.0 | |
68 /* method to use when scaling down image data */ | |
69 #define PRINT_PS_MAX_INTERP GDK_INTERP_BILINEAR | |
70 | |
71 /* padding between objects */ | |
72 #define PRINT_TEXT_PADDING 3.0 | |
73 | |
74 /* locale for postscript portability */ | |
75 #define POSTSCRIPT_LOCALE "C" | |
76 | |
77 | |
78 /* group and keys for saving prefs */ | |
79 #define PRINT_PREF_GROUP "print_settings" | |
80 | |
81 #define PRINT_PREF_SAVE "save_settings" | |
82 | |
83 #define PRINT_PREF_OUTPUT "output" | |
84 #define PRINT_PREF_FORMAT "format" | |
85 #define PRINT_PREF_DPI "dpi" | |
86 #define PRINT_PREF_UNITS "units" | |
87 #define PRINT_PREF_SIZE "size" | |
88 #define PRINT_PREF_ORIENTATION "orientation" | |
89 | |
90 #define PRINT_PREF_CUSTOM_WIDTH "custom_width" | |
91 #define PRINT_PREF_CUSTOM_HEIGHT "custom_height" | |
92 #define PRINT_PREF_MARGIN_LEFT "margin_left" | |
93 #define PRINT_PREF_MARGIN_RIGHT "margin_right" | |
94 #define PRINT_PREF_MARGIN_TOP "margin_top" | |
95 #define PRINT_PREF_MARGIN_BOTTOM "margin_bottom" | |
96 #define PRINT_PREF_PROOF_WIDTH "proof_width" | |
97 #define PRINT_PREF_PROOF_HEIGHT "proof_height" | |
98 | |
99 #define PRINT_PREF_PRINTERC "custom_printer" | |
100 | |
101 | |
102 typedef enum { | |
103 PRINT_SOURCE_IMAGE = 0, | |
104 PRINT_SOURCE_SELECTION, | |
105 PRINT_SOURCE_ALL, | |
106 PRINT_SOURCE_COUNT | |
107 } PrintSource; | |
108 | |
109 const gchar *print_source_text[] = { | |
110 N_("Image"), | |
111 N_("Selection"), | |
112 N_("All"), | |
113 NULL | |
114 }; | |
115 | |
116 typedef enum { | |
117 PRINT_LAYOUT_IMAGE = 0, | |
118 PRINT_LAYOUT_PROOF, | |
119 PRINT_LAYOUT_COUNT | |
120 } PrintLayout; | |
121 | |
122 const gchar *print_layout_text[] = { | |
123 N_("One image per page"), | |
124 N_("Proof sheet"), | |
125 NULL | |
126 }; | |
127 | |
128 typedef enum { | |
129 PRINT_OUTPUT_PS_LPR = 0, | |
130 PRINT_OUTPUT_PS_CUSTOM, | |
131 PRINT_OUTPUT_PS_FILE, | |
132 PRINT_OUTPUT_RGB_FILE, | |
133 PRINT_OUTPUT_COUNT | |
134 } PrintOutput; | |
135 | |
136 const gchar *print_output_text[] = { | |
137 N_("Default printer"), | |
138 N_("Custom printer"), | |
139 N_("PostScript file"), | |
140 N_("Image file"), | |
141 NULL, | |
142 NULL | |
143 }; | |
144 | |
145 typedef enum { | |
146 PRINT_FILE_JPG_LOW = 0, | |
147 PRINT_FILE_JPG_NORMAL, | |
148 PRINT_FILE_JPG_HIGH, | |
149 PRINT_FILE_PNG, | |
150 PRINT_FILE_COUNT | |
151 } PrintFileFormat; | |
152 | |
153 const gchar *print_file_format_text[] = { | |
154 N_("jpeg, low quality"), | |
155 N_("jpeg, normal quality"), | |
156 N_("jpeg, high quality"), | |
157 "png", | |
158 NULL | |
159 }; | |
160 | |
161 typedef enum { | |
162 RENDER_FORMAT_PREVIEW, | |
163 RENDER_FORMAT_RGB, | |
164 RENDER_FORMAT_PS | |
165 } RenderFormat; | |
166 | |
167 typedef enum { | |
168 TEXT_INFO_FILENAME = 1 << 0, | |
169 TEXT_INFO_FILEDATE = 1 << 1, | |
170 TEXT_INFO_FILESIZE = 1 << 2, | |
171 TEXT_INFO_DIMENSIONS = 1 << 3 | |
172 } TextInfo; | |
173 | |
174 typedef struct _PrintWindow PrintWindow; | |
175 struct _PrintWindow | |
176 { | |
177 GenericDialog *dialog; | |
178 | |
179 gchar *source_path; | |
180 GList *source_selection; | |
181 GList *source_list; | |
182 | |
183 PrintSource source; | |
184 PrintLayout layout; | |
185 PrintOutput output; | |
186 | |
187 gchar *output_path; | |
188 gchar *output_custom; | |
189 | |
190 PrintFileFormat output_format; | |
191 | |
192 gdouble max_dpi; | |
193 | |
194 GtkWidget *notebook; | |
195 | |
196 GtkWidget *path_entry; | |
197 GtkWidget *custom_entry; | |
198 GtkWidget *path_format_menu; | |
199 GtkWidget *max_dpi_menu; | |
200 | |
201 ImageWindow *layout_image; | |
202 gdouble layout_width; | |
203 gdouble layout_height; | |
204 | |
205 gint layout_idle_id; | |
206 | |
207 gint image_scale; | |
208 | |
209 GtkWidget *image_scale_spin; | |
210 | |
211 gdouble proof_width; | |
212 gdouble proof_height; | |
213 gint proof_columns; | |
214 gint proof_rows; | |
215 GList *proof_point; | |
216 gint proof_position; | |
217 gint proof_page; | |
218 | |
219 GtkWidget *proof_group; | |
220 GtkWidget *proof_width_spin; | |
221 GtkWidget *proof_height_spin; | |
222 | |
223 GtkWidget *paper_menu; | |
224 GtkWidget *paper_width_spin; | |
225 GtkWidget *paper_height_spin; | |
226 GtkWidget *paper_units_menu; | |
227 GtkWidget *paper_orientation_menu; | |
228 | |
229 GtkWidget *margin_left_spin; | |
230 GtkWidget *margin_right_spin; | |
231 GtkWidget *margin_top_spin; | |
232 GtkWidget *margin_bottom_spin; | |
233 | |
234 gint paper_units; | |
235 gint paper_size; | |
236 gdouble paper_width; | |
237 gdouble paper_height; | |
238 gint paper_orientation; | |
239 | |
240 gdouble margin_left; | |
241 gdouble margin_right; | |
242 gdouble margin_top; | |
243 gdouble margin_bottom; | |
244 | |
245 GtkWidget *button_back; | |
246 GtkWidget *button_next; | |
247 GtkWidget *page_label; | |
248 GtkWidget *print_button; | |
249 | |
250 gdouble single_scale; | |
251 gdouble single_x; | |
252 gdouble single_y; | |
253 | |
254 GtkWidget *single_scale_spin; | |
255 | |
256 TextInfo text_fields; | |
257 gint text_points; | |
258 guint8 text_r; | |
259 guint8 text_g; | |
260 guint8 text_b; | |
261 | |
262 gint save_settings; | |
263 | |
264 /* job printing */ | |
265 | |
266 GenericDialog *job_dialog; | |
267 GtkWidget *job_progress; | |
268 GtkWidget *job_progress_label; | |
269 | |
270 RenderFormat job_format; | |
271 PrintOutput job_output; | |
272 | |
273 FILE *job_file; | |
274 FILE *job_pipe; | |
275 gchar *job_path; | |
276 | |
277 GdkPixbuf *job_pixbuf; | |
278 | |
279 gint job_page; | |
280 ImageLoader *job_loader; | |
281 }; | |
282 | |
283 | |
284 static void print_job_throw_error(PrintWindow *pw, const gchar *message); | |
285 static gint print_job_start(PrintWindow *pw, RenderFormat format, PrintOutput output); | |
286 static void print_job_close(PrintWindow *pw, gint error); | |
287 static void print_window_close(PrintWindow *pw); | |
288 | |
289 | |
290 /* misc utils */ | |
291 | |
292 static gint clip_region(gdouble x1, gdouble y1, gdouble w1, gdouble h1, | |
293 gdouble x2, gdouble y2, gdouble w2, gdouble h2, | |
294 gdouble *rx, gdouble *ry, gdouble *rw, gdouble *rh) | |
295 { | |
296 if (x2 + w2 <= x1 || x2 >= x1 + w1 || | |
297 y2 + h2 <= y1 || y2 >= y1 + h1) | |
298 { | |
299 return FALSE; | |
300 } | |
301 | |
302 *rx = MAX(x1, x2); | |
303 *rw = MIN((x1 + w1), (x2 + w2)) - *rx; | |
304 | |
305 *ry = MAX(y1, y2); | |
306 *rh = MIN((y1 + h1), (y2 + h2)) - *ry; | |
307 | |
308 return TRUE; | |
309 } | |
310 | |
311 static const gchar *print_output_name(PrintOutput output) | |
312 { | |
313 if (output < 0 || output >= PRINT_OUTPUT_COUNT) return ""; | |
314 | |
315 return _(print_output_text[output]); | |
316 } | |
317 | |
318 | |
319 /* | |
320 *----------------------------------------------------------------------------- | |
321 * data | |
322 *----------------------------------------------------------------------------- | |
323 */ | |
324 | |
325 | |
326 typedef enum { | |
327 PAPER_UNIT_POINTS = 0, | |
328 PAPER_UNIT_MM, | |
329 PAPER_UNIT_CM, | |
330 PAPER_UNIT_INCH, | |
331 PAPER_UNIT_PICAS, | |
332 PAPER_UNIT_COUNT | |
333 } PaperUnits; | |
334 | |
335 typedef enum { | |
336 PAPER_ORIENTATION_PORTRAIT = 0, | |
337 PAPER_ORIENTATION_LANDSCAPE, | |
338 PAPER_ORIENTATION_COUNT | |
339 } PaperOrientation; | |
340 | |
341 typedef struct _PaperSize PaperSize; | |
342 struct _PaperSize { | |
343 gchar *description; | |
344 gint width; | |
345 gint height; | |
346 PaperOrientation orientation; | |
347 }; | |
348 | |
349 const gchar *print_paper_units[] = { | |
350 N_("points"), | |
351 N_("millimeters"), | |
352 N_("centimeters"), | |
353 N_("inches"), | |
354 N_("picas"), | |
355 NULL | |
356 }; | |
357 | |
358 const gchar *print_paper_orientation[] = { | |
359 N_("Portrait"), | |
360 N_("Landscape"), | |
361 NULL | |
362 }; | |
363 | |
364 PaperSize print_paper_sizes[] = { | |
365 { N_("Custom"), 360, 720, PAPER_ORIENTATION_PORTRAIT }, | |
366 { N_("Letter"), 612, 792, PAPER_ORIENTATION_PORTRAIT }, /* in 8.5 x 11 */ | |
367 { N_("Legal"), 612, 1008, PAPER_ORIENTATION_PORTRAIT }, /* in 8.5 x 14 */ | |
368 { N_("Executive"), 522, 756, PAPER_ORIENTATION_PORTRAIT }, /* in 7.25x 10.5 */ | |
369 { "A0", 2384, 3370, PAPER_ORIENTATION_PORTRAIT }, /* mm 841 x 1189 */ | |
370 { "A1", 1684, 2384, PAPER_ORIENTATION_PORTRAIT }, /* mm 594 x 841 */ | |
371 { "A2", 1191, 1684, PAPER_ORIENTATION_PORTRAIT }, /* mm 420 x 594 */ | |
372 { "A3", 842, 1191, PAPER_ORIENTATION_PORTRAIT }, /* mm 297 x 420 */ | |
373 { "A4", 595, 842, PAPER_ORIENTATION_PORTRAIT }, /* mm 210 x 297 */ | |
374 { "A5", 420, 595, PAPER_ORIENTATION_PORTRAIT }, /* mm 148 x 210 */ | |
375 { "A6", 298, 420, PAPER_ORIENTATION_PORTRAIT }, /* mm 105 x 148 */ | |
376 { "B3", 1001, 1417, PAPER_ORIENTATION_PORTRAIT }, /* mm 353 x 500 */ | |
377 { "B4", 709, 1001, PAPER_ORIENTATION_PORTRAIT }, /* mm 250 x 353 */ | |
378 { "B5", 499, 709, PAPER_ORIENTATION_PORTRAIT }, /* mm 176 x 250 */ | |
379 { "B6", 354, 499, PAPER_ORIENTATION_PORTRAIT }, /* mm 125 x 176 */ | |
380 { N_("Envelope #10"), 297, 684, PAPER_ORIENTATION_LANDSCAPE }, /* in 4.125 x 9.5 */ | |
381 { N_("Envelope #9"), 279, 639, PAPER_ORIENTATION_LANDSCAPE }, /* in 3.875 x 8.875 */ | |
382 { N_("Envelope C4"), 649, 918, PAPER_ORIENTATION_LANDSCAPE }, /* mm 229 x 324 */ | |
383 { N_("Envelope C5"), 459, 649, PAPER_ORIENTATION_LANDSCAPE }, /* mm 162 x 229 */ | |
384 { N_("Envelope C6"), 323, 459, PAPER_ORIENTATION_LANDSCAPE }, /* mm 114 x 162 */ | |
385 { N_("Photo 6x4"), 432, 288, PAPER_ORIENTATION_PORTRAIT }, /* in 6 x 4 */ | |
386 { N_("Photo 8x10"), 576, 720, PAPER_ORIENTATION_PORTRAIT }, /* in 8 x 10 */ | |
387 { N_("Postcard"), 284, 419, PAPER_ORIENTATION_LANDSCAPE }, /* mm 100 x 148 */ | |
388 { N_("Tabloid"), 792, 1224, PAPER_ORIENTATION_PORTRAIT }, /* in 11 x 17 */ | |
389 { NULL, 0, 0, 0 } | |
390 }; | |
391 | |
392 | |
393 static PaperSize *print_paper_size_nth(gint n) | |
394 { | |
395 PaperSize *ps = NULL; | |
396 gint i = 0; | |
397 | |
398 while (i <= n && print_paper_sizes[i].description) | |
399 { | |
400 ps = &print_paper_sizes[i]; | |
401 i++; | |
402 } | |
403 | |
404 return ps; | |
405 } | |
406 | |
407 static gint print_paper_size_lookup(gint n, gdouble *width, gdouble *height) | |
408 { | |
409 PaperSize *ps; | |
410 gdouble w, h; | |
411 | |
412 ps = print_paper_size_nth(n); | |
413 if (!ps) return FALSE; | |
414 | |
415 if (ps->orientation == PAPER_ORIENTATION_PORTRAIT) | |
416 { | |
417 w = ps->width; | |
418 h = ps->height; | |
419 } | |
420 else | |
421 { | |
422 h = ps->width; | |
423 w = ps->height; | |
424 } | |
425 | |
426 if (width) *width = w; | |
427 if (height) *height = h; | |
428 | |
429 return TRUE; | |
430 } | |
431 | |
432 static gdouble print_paper_size_convert_units(gdouble value, PaperUnits src, PaperUnits dst) | |
433 { | |
434 gdouble ret; | |
435 | |
436 if (src == dst) return value; | |
437 | |
438 switch (src) | |
439 { | |
440 case PAPER_UNIT_MM: | |
441 ret = value / 25.4 * 72.0; | |
442 break; | |
443 case PAPER_UNIT_CM: | |
444 ret = value / 2.54 * 72.0; | |
445 break; | |
446 case PAPER_UNIT_INCH: | |
447 ret = value * 72.0; | |
448 break; | |
449 case PAPER_UNIT_PICAS: | |
450 ret = value * 12.0; | |
451 break; | |
452 case PAPER_UNIT_POINTS: | |
453 default: | |
454 ret = value; | |
455 break; | |
456 } | |
457 | |
458 switch (dst) | |
459 { | |
460 case PAPER_UNIT_MM: | |
461 ret = ret / 72.0 * 25.4; | |
462 break; | |
463 case PAPER_UNIT_CM: | |
464 ret = ret / 72.0 * 2.54; | |
465 break; | |
466 case PAPER_UNIT_INCH: | |
467 ret = ret / 72.0; | |
468 break; | |
469 case PAPER_UNIT_PICAS: | |
470 ret = ret / 12.0; | |
471 break; | |
472 case PAPER_UNIT_POINTS: | |
473 default: | |
474 break; | |
475 } | |
476 | |
477 return ret; | |
478 } | |
479 | |
480 static PaperUnits paper_unit_default(void) | |
481 { | |
482 const char *result; | |
483 #if 0 | |
484 /* this is not used because it is not even slightly portable */ | |
485 #include <langinfo.h> | |
486 | |
487 result = nl_langinfo(_NL_MEASUREMENT_MEASUREMENT); | |
488 if (result[0] == '2') return PAPER_UNIT_INCH; | |
489 #endif | |
490 | |
491 #ifdef LC_MEASUREMENT | |
492 result = setlocale(LC_MEASUREMENT, NULL); | |
493 #else | |
494 result = setlocale(LC_ALL, NULL); | |
495 #endif | |
496 if (result && | |
497 (strstr(result, "_US") || strstr(result, "_PR")) ) | |
498 { | |
499 return PAPER_UNIT_INCH; | |
500 } | |
501 | |
502 return PAPER_UNIT_CM; | |
503 } | |
504 | |
505 /* | |
506 *----------------------------------------------------------------------------- | |
507 * the layout window | |
508 *----------------------------------------------------------------------------- | |
509 */ | |
510 | |
511 static gint print_layout_page_count(PrintWindow *pw); | |
512 | |
513 | |
514 static gint print_preview_unit(gdouble points) | |
515 { | |
516 return (int)(points / PRINT_PREVIEW_SCALE); | |
517 } | |
518 | |
519 static void print_proof_size(PrintWindow *pw, gdouble *width, gdouble *height) | |
520 { | |
521 if (width) *width = pw->proof_width + PRINT_PROOF_MARGIN * 2; | |
522 if (height) | |
523 { | |
524 gdouble h; | |
525 | |
526 h = pw->proof_height + PRINT_PROOF_MARGIN * 2; | |
527 if (pw->text_fields != 0) h += PRINT_TEXT_PADDING; | |
528 if (pw->text_fields & TEXT_INFO_FILENAME) h+= (gdouble)pw->text_points * 1.25; | |
529 if (pw->text_fields & TEXT_INFO_DIMENSIONS) h+= (gdouble)pw->text_points * 1.25; | |
530 if (pw->text_fields & TEXT_INFO_FILEDATE) h+= (gdouble)pw->text_points * 1.25; | |
531 if (pw->text_fields & TEXT_INFO_FILESIZE) h+= (gdouble)pw->text_points * 1.25; | |
532 *height = h; | |
533 } | |
534 } | |
535 | |
536 static void print_window_layout_status(PrintWindow *pw) | |
537 { | |
538 gint total; | |
539 gchar *buf; | |
540 | |
541 total = print_layout_page_count(pw); | |
542 pw->proof_page = CLAMP(pw->proof_page, 0, total - 1); | |
543 | |
544 buf = g_strdup_printf(_("page %d of %d"), pw->proof_page + 1, (total > 0) ? total : 1); | |
545 gtk_label_set_text(GTK_LABEL(pw->page_label), buf); | |
546 g_free(buf); | |
547 | |
548 gtk_widget_set_sensitive(pw->page_label, (total > 0)); | |
549 | |
550 gtk_widget_set_sensitive(pw->button_back, (pw->proof_page > 0)); | |
551 gtk_widget_set_sensitive(pw->button_next, (pw->proof_page < total - 1)); | |
552 | |
553 gtk_widget_set_sensitive(pw->print_button, total > 0); | |
554 } | |
555 | |
556 static void print_window_layout_render_stop(PrintWindow *pw) | |
557 { | |
558 if (pw->layout_idle_id != -1) | |
559 { | |
560 g_source_remove(pw->layout_idle_id); | |
561 pw->layout_idle_id = -1; | |
562 } | |
563 } | |
564 | |
565 static gboolean print_window_layout_render_idle(gpointer data) | |
566 { | |
567 PrintWindow *pw = data; | |
568 | |
569 print_job_close(pw, FALSE); | |
570 print_job_start(pw, RENDER_FORMAT_PREVIEW, 0); | |
571 | |
572 pw->layout_idle_id = -1; | |
573 return FALSE; | |
574 } | |
575 | |
576 static void print_window_layout_render(PrintWindow *pw) | |
577 { | |
578 gdouble proof_w, proof_h; | |
579 | |
580 print_proof_size(pw, &proof_w, &proof_h); | |
581 pw->proof_columns = (pw->layout_width - pw->margin_left - pw->margin_right) / proof_w; | |
582 pw->proof_rows = (pw->layout_height - pw->margin_top - pw->margin_bottom) / proof_h; | |
583 | |
584 print_window_layout_status(pw); | |
585 | |
586 if (pw->layout_idle_id == -1) | |
587 { | |
588 pw->layout_idle_id = g_idle_add(print_window_layout_render_idle, pw); | |
589 } | |
590 } | |
591 | |
592 static void print_window_layout_size(PrintWindow *pw) | |
593 { | |
594 GdkPixbuf *pixbuf; | |
595 gdouble width; | |
596 gdouble height; | |
597 gint sw, sh; | |
598 | |
599 if (!pw->layout_image) return; | |
600 | |
601 if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) | |
602 { | |
603 width = pw->paper_height; | |
604 height = pw->paper_width; | |
605 } | |
606 else | |
607 { | |
608 width = pw->paper_width; | |
609 height = pw->paper_height; | |
610 } | |
611 | |
612 pw->layout_width = width; | |
613 pw->layout_height = height; | |
614 | |
615 sw = print_preview_unit(width); | |
616 sh = print_preview_unit(height); | |
617 pixbuf = pw->layout_image->pixbuf; | |
618 if (!pixbuf || | |
619 gdk_pixbuf_get_width(pixbuf) != sw || | |
620 gdk_pixbuf_get_height(pixbuf) != sh) | |
621 { | |
622 pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, sw, sh); | |
623 image_change_pixbuf(pw->layout_image, pixbuf, 0.0); | |
624 g_object_unref(pixbuf); | |
625 } | |
626 | |
627 print_window_layout_render(pw); | |
628 print_window_layout_status(pw); | |
629 } | |
630 | |
631 static gint print_layout_page_count(PrintWindow *pw) | |
632 { | |
633 gint images; | |
634 gint images_per_page; | |
635 gint pages; | |
636 | |
637 if (pw->layout_width - pw->margin_left - pw->margin_right <= 0.0 || | |
638 pw->layout_height - pw->margin_top - pw->margin_bottom <= 0.0) | |
639 { | |
640 return 0; | |
641 } | |
642 | |
643 switch (pw->source) | |
644 { | |
645 case PRINT_SOURCE_ALL: | |
646 images = g_list_length(pw->source_list); | |
647 break; | |
648 case PRINT_SOURCE_SELECTION: | |
649 images = g_list_length(pw->source_selection); | |
650 break; | |
651 case PRINT_SOURCE_IMAGE: | |
652 default: | |
653 images = (pw->source_path) ? 1 : 0; | |
654 break; | |
655 } | |
656 | |
657 switch (pw->layout) | |
658 { | |
659 case PRINT_LAYOUT_PROOF: | |
660 images_per_page = pw->proof_columns * pw->proof_rows; | |
661 break; | |
662 case PRINT_LAYOUT_IMAGE: | |
663 default: | |
664 images_per_page = 1; | |
665 break; | |
666 } | |
667 | |
668 if (images < 1 || images_per_page < 1) return 0; | |
669 | |
670 pages = images / images_per_page; | |
671 if (pages * images_per_page < images) pages++; | |
672 | |
673 return pages; | |
674 } | |
675 | |
676 static void print_layout_page_step(PrintWindow *pw, gint step) | |
677 { | |
678 gint max; | |
679 gint page; | |
680 | |
681 max = print_layout_page_count(pw); | |
682 page = pw->proof_page + step; | |
683 | |
684 if (page >= max) page = max - 1; | |
685 if (page < 0) page = 0; | |
686 | |
687 if (page == pw->proof_page) return; | |
688 | |
689 pw->proof_page = page; | |
690 print_window_layout_size(pw); | |
691 } | |
692 | |
693 static void print_layout_page_back_cb(GtkWidget *widget, gpointer data) | |
694 { | |
695 PrintWindow *pw = data; | |
696 | |
697 print_layout_page_step(pw, -1); | |
698 } | |
699 | |
700 static void print_layout_page_next_cb(GtkWidget *widget, gpointer data) | |
701 { | |
702 PrintWindow *pw = data; | |
703 | |
704 print_layout_page_step(pw, 1); | |
705 } | |
706 | |
707 static void print_layout_zoom_in_cb(GtkWidget *widget, gpointer data) | |
708 { | |
709 PrintWindow *pw = data; | |
710 image_zoom_adjust(pw->layout_image, 0.25); | |
711 } | |
712 | |
713 static void print_layout_zoom_out_cb(GtkWidget *widget, gpointer data) | |
714 { | |
715 PrintWindow *pw = data; | |
716 image_zoom_adjust(pw->layout_image, -0.25); | |
717 } | |
718 | |
719 static void print_layout_zoom_original_cb(GtkWidget *widget, gpointer data) | |
720 { | |
721 PrintWindow *pw = data; | |
722 gdouble zoom; | |
723 | |
724 zoom = image_zoom_get(pw->layout_image); | |
725 image_zoom_set(pw->layout_image, (zoom == 1.0) ? 0.0 : 1.0); | |
726 } | |
727 | |
728 static GtkWidget *print_window_layout_setup(PrintWindow *pw, GtkWidget *box) | |
729 { | |
730 GtkWidget *vbox; | |
731 GtkWidget *hbox; | |
732 GtkWidget *group; | |
733 GtkWidget *button; | |
734 | |
735 vbox = pref_box_new(box, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); | |
736 group = pref_frame_new(vbox, TRUE, _("Preview"), GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); | |
737 | |
738 pw->layout_idle_id = -1; | |
739 | |
740 pw->layout_image = image_new(FALSE); | |
741 gtk_widget_set_size_request(pw->layout_image->widget, PRINT_DLG_PREVIEW_WIDTH, PRINT_DLG_PREVIEW_HEIGHT); | |
742 | |
743 gtk_box_pack_start(GTK_BOX(group), pw->layout_image->widget, TRUE, TRUE, 0); | |
744 gtk_widget_show(pw->layout_image->widget); | |
745 | |
746 hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
747 pw->button_back = pref_button_new(hbox, GTK_STOCK_GO_BACK, NULL, TRUE, | |
748 G_CALLBACK(print_layout_page_back_cb), pw); | |
749 pw->button_next = pref_button_new(hbox, GTK_STOCK_GO_FORWARD, NULL, TRUE, | |
750 G_CALLBACK(print_layout_page_next_cb), pw); | |
751 pw->page_label = pref_label_new(hbox, ""); | |
752 | |
753 button = pref_button_new(NULL, GTK_STOCK_ZOOM_OUT, NULL, TRUE, | |
754 G_CALLBACK(print_layout_zoom_out_cb), pw); | |
755 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
756 gtk_widget_show(button); | |
757 button = pref_button_new(NULL, GTK_STOCK_ZOOM_IN, NULL, TRUE, | |
758 G_CALLBACK(print_layout_zoom_in_cb), pw); | |
759 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
760 gtk_widget_show(button); | |
761 button = pref_button_new(NULL, GTK_STOCK_ZOOM_100, NULL, TRUE, | |
762 G_CALLBACK(print_layout_zoom_original_cb), pw); | |
763 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
764 gtk_widget_show(button); | |
765 | |
766 print_window_layout_size(pw); | |
767 | |
768 return vbox; | |
769 } | |
770 | |
771 static void print_window_spin_set(GtkSpinButton *spin, gpointer block_data, | |
772 gdouble value, gdouble min, gdouble max, | |
773 gdouble step, gdouble page, gint digits) | |
774 { | |
775 if (block_data) g_signal_handlers_block_matched(G_OBJECT(spin), G_SIGNAL_MATCH_DATA, | |
776 0, 0, NULL, NULL, block_data); | |
777 gtk_spin_button_set_digits(spin, digits); | |
778 gtk_spin_button_set_increments(spin, step, page); | |
779 gtk_spin_button_set_range(spin, min, max); | |
780 gtk_spin_button_set_value(spin, value); | |
781 | |
782 if (block_data) g_signal_handlers_unblock_matched(G_OBJECT(spin), G_SIGNAL_MATCH_DATA, | |
783 0, 0, NULL, NULL, block_data); | |
784 } | |
785 | |
786 static void print_window_layout_sync_layout(PrintWindow *pw) | |
787 { | |
788 gtk_widget_set_sensitive(pw->image_scale_spin, (pw->layout == PRINT_LAYOUT_IMAGE)); | |
789 gtk_widget_set_sensitive(pw->proof_group, (pw->layout == PRINT_LAYOUT_PROOF)); | |
790 } | |
791 | |
792 static void print_window_layout_sync_paper(PrintWindow *pw) | |
793 { | |
794 gdouble width, height; | |
795 gint digits; | |
796 gdouble step; | |
797 gdouble page; | |
798 | |
799 gtk_widget_set_sensitive(pw->paper_width_spin, (pw->paper_size == 0)); | |
800 gtk_widget_set_sensitive(pw->paper_height_spin, (pw->paper_size == 0)); | |
801 | |
802 width = print_paper_size_convert_units((gdouble)pw->paper_width, PAPER_UNIT_POINTS, pw->paper_units); | |
803 height = print_paper_size_convert_units((gdouble)pw->paper_height, PAPER_UNIT_POINTS, pw->paper_units); | |
804 | |
805 switch (pw->paper_units) | |
806 { | |
807 case PAPER_UNIT_MM: | |
808 digits = 1; | |
809 step = 1.0; | |
810 page = 10.0; | |
811 break; | |
812 case PAPER_UNIT_CM: | |
813 digits = 2; | |
814 step = 0.5; | |
815 page = 1.0; | |
816 break; | |
817 case PAPER_UNIT_INCH: | |
818 digits = 3; | |
819 step = 0.25; | |
820 page = 1.0; | |
821 break; | |
822 case PAPER_UNIT_PICAS: | |
823 digits = 2; | |
824 step = 1.0; | |
825 page = 6.0; | |
826 break; | |
827 case PAPER_UNIT_POINTS: | |
828 default: | |
829 digits = 1; | |
830 step = 1.0; | |
831 page = 10.0; | |
832 break; | |
833 } | |
834 | |
835 print_window_spin_set(GTK_SPIN_BUTTON(pw->paper_width_spin), pw, width, | |
836 print_paper_size_convert_units(PRINT_MIN_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), | |
837 print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), | |
838 step, page, digits); | |
839 | |
840 print_window_spin_set(GTK_SPIN_BUTTON(pw->paper_height_spin), pw, height, | |
841 print_paper_size_convert_units(PRINT_MIN_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), | |
842 print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), | |
843 step, page, digits); | |
844 | |
845 print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_left_spin), pw, | |
846 print_paper_size_convert_units(pw->margin_left, PAPER_UNIT_POINTS, pw->paper_units), | |
847 0.0, | |
848 print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), | |
849 step, page, digits); | |
850 | |
851 print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_right_spin), pw, | |
852 print_paper_size_convert_units(pw->margin_right, PAPER_UNIT_POINTS, pw->paper_units), | |
853 0.0, | |
854 print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), | |
855 step, page, digits); | |
856 | |
857 print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_top_spin), pw, | |
858 print_paper_size_convert_units(pw->margin_top, PAPER_UNIT_POINTS, pw->paper_units), | |
859 0.0, | |
860 print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), | |
861 step, page, digits); | |
862 | |
863 print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_bottom_spin), pw, | |
864 print_paper_size_convert_units(pw->margin_bottom, PAPER_UNIT_POINTS, pw->paper_units), | |
865 0.0, | |
866 print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), | |
867 step, page, digits); | |
868 | |
869 print_window_spin_set(GTK_SPIN_BUTTON(pw->proof_width_spin), pw, | |
870 print_paper_size_convert_units(pw->proof_width, PAPER_UNIT_POINTS, pw->paper_units), | |
871 print_paper_size_convert_units(PRINT_PROOF_MIN_SIZE, PAPER_UNIT_POINTS, pw->paper_units), | |
872 print_paper_size_convert_units(PRINT_PROOF_MAX_SIZE, PAPER_UNIT_POINTS, pw->paper_units), | |
873 step, page, digits); | |
874 | |
875 print_window_spin_set(GTK_SPIN_BUTTON(pw->proof_height_spin), pw, | |
876 print_paper_size_convert_units(pw->proof_height, PAPER_UNIT_POINTS, pw->paper_units), | |
877 print_paper_size_convert_units(PRINT_PROOF_MIN_SIZE, PAPER_UNIT_POINTS, pw->paper_units), | |
878 print_paper_size_convert_units(PRINT_PROOF_MAX_SIZE, PAPER_UNIT_POINTS, pw->paper_units), | |
879 step, page, digits); | |
880 } | |
881 | |
882 static void print_window_layout_set_size(PrintWindow *pw, gdouble width, gdouble height) | |
883 { | |
884 pw->paper_width = width; | |
885 pw->paper_height = height; | |
886 | |
887 print_window_layout_sync_paper(pw); | |
888 | |
889 print_window_layout_size(pw); | |
890 } | |
891 | |
892 static void print_window_layout_set_orientation(PrintWindow *pw, PaperOrientation o) | |
893 { | |
894 if (pw->paper_orientation == o) return; | |
895 | |
896 pw->paper_orientation = o; | |
897 | |
898 print_window_layout_size(pw); | |
899 } | |
900 | |
901 /* | |
902 *----------------------------------------------------------------------------- | |
903 * list printers | |
904 *----------------------------------------------------------------------------- | |
905 */ | |
906 | |
907 static GList *print_window_list_printers(void) | |
908 { | |
909 FILE *p; | |
910 GList *list = NULL; | |
911 gchar buffer[2048]; | |
912 | |
913 p = popen(PRINT_LPR_QUERY, "r"); | |
914 if (!p) return NULL; | |
915 | |
916 while (fgets(buffer, sizeof(buffer), p) != NULL) | |
917 { | |
918 gchar *ptr; | |
919 gchar *end; | |
920 | |
921 ptr = buffer; | |
922 if (strncmp(ptr, "printer ", 8) != 0) continue; | |
923 if (strstr(ptr, "enabled") == NULL) continue; | |
924 ptr += 8; | |
925 end = ptr; | |
926 while (*end != '\0' && *end != '\n' && *end != ' ' && *end != '\t') end++; | |
927 *end = '\0'; | |
928 list = g_list_append(list, g_strdup(ptr)); | |
929 if (debug) printf("adding printer: %s\n", ptr); | |
930 } | |
931 | |
932 pclose(p); | |
933 | |
934 return list; | |
935 } | |
936 | |
937 /* | |
938 *----------------------------------------------------------------------------- | |
939 * print ps | |
940 *----------------------------------------------------------------------------- | |
941 */ | |
942 | |
943 typedef struct _PipeError PipeError; | |
944 struct _PipeError { | |
945 struct sigaction old_action; | |
946 sig_atomic_t *error; | |
947 }; | |
948 | |
949 static sig_atomic_t pipe_handler_error = FALSE; | |
950 static PipeError *pipe_handler_data = NULL; | |
951 | |
952 static void pipe_handler_sigpipe_cb(int fd) | |
953 { | |
954 pipe_handler_error = TRUE; | |
955 } | |
956 | |
957 static PipeError *pipe_handler_new(void) | |
958 { | |
959 struct sigaction new_action; | |
960 PipeError *pe; | |
961 | |
962 if (pipe_handler_data) | |
963 { | |
964 printf("warning SIGPIPE handler already in use\n"); | |
965 return NULL; | |
966 } | |
967 | |
968 pe = g_new0(PipeError, 1); | |
969 | |
970 pipe_handler_error = FALSE; | |
971 pe->error = &pipe_handler_error; | |
972 | |
973 new_action.sa_handler = pipe_handler_sigpipe_cb; | |
974 sigemptyset (&new_action.sa_mask); | |
975 new_action.sa_flags = 0; | |
976 | |
977 /* setup our signal handler */ | |
978 sigaction (SIGPIPE, &new_action, &pe->old_action); | |
979 | |
980 pipe_handler_data = pe; | |
981 return pe; | |
982 } | |
983 | |
984 static void pipe_handler_free(PipeError *pe) | |
985 { | |
986 if (!pe) return; | |
987 if (pe != pipe_handler_data) printf("warning SIGPIPE handler not closing same data\n"); | |
988 | |
989 /* restore the original signal handler */ | |
990 sigaction (SIGPIPE, &pe->old_action, NULL); | |
991 | |
992 pipe_handler_data = NULL; | |
993 g_free(pe); | |
994 } | |
995 | |
996 static gint pipe_handler_check(PipeError *pe) | |
997 { | |
998 if (!pe) return FALSE; | |
999 return *pe->error; | |
1000 } | |
1001 | |
1002 static FILE *print_job_ps_fd(PrintWindow *pw) | |
1003 { | |
1004 if (pw->job_file) return pw->job_file; | |
1005 if (pw->job_pipe) return pw->job_pipe; | |
1006 return NULL; | |
1007 } | |
1008 | |
1009 static gint print_job_ps_init(PrintWindow *pw) | |
1010 { | |
1011 FILE *f; | |
1012 PipeError *pe; | |
1013 const gchar *cmd = NULL; | |
1014 const gchar *path = NULL; | |
1015 gchar *lc_pointer; | |
1016 gint ret; | |
1017 | |
1018 if (pw->job_file != NULL || pw->job_pipe != NULL) return FALSE; | |
1019 | |
1020 switch (pw->job_output) | |
1021 { | |
1022 case PRINT_OUTPUT_PS_LPR: | |
1023 cmd = PRINT_LPR_COMMAND; | |
1024 break; | |
1025 case PRINT_OUTPUT_PS_CUSTOM: | |
1026 cmd = pw->output_custom; | |
1027 break; | |
1028 case PRINT_OUTPUT_PS_FILE: | |
1029 path = pw->output_path; | |
1030 break; | |
1031 default: | |
1032 return FALSE; | |
1033 break; | |
1034 } | |
1035 | |
1036 if (cmd) | |
1037 { | |
1038 pw->job_pipe = popen(cmd, "w"); | |
1039 | |
1040 if (!pw->job_pipe) | |
1041 { | |
1042 gchar *buf; | |
1043 | |
1044 buf = g_strdup_printf(_("Unable to open pipe for writing.\n\"%s\""), cmd); | |
1045 print_job_throw_error(pw, buf); | |
1046 g_free(buf); | |
1047 | |
1048 return FALSE; | |
1049 } | |
1050 } | |
1051 else if (path) | |
1052 { | |
1053 gchar *pathl; | |
1054 | |
1055 if (isfile(path)) | |
1056 { | |
1057 gchar *buf; | |
1058 | |
1059 buf = g_strdup_printf(_("A file with name %s already exists."), path); | |
1060 print_job_throw_error(pw, buf); | |
1061 g_free(buf); | |
1062 | |
1063 return FALSE; | |
1064 } | |
1065 | |
1066 pathl = path_from_utf8(path); | |
1067 pw->job_file = fopen(pathl, "w"); | |
1068 g_free(pathl); | |
1069 | |
1070 if (!pw->job_file) | |
1071 { | |
1072 gchar *buf; | |
1073 | |
1074 buf = g_strdup_printf(_("Failure writing to file %s"), path); | |
1075 print_job_throw_error(pw, buf); | |
1076 g_free(buf); | |
1077 | |
1078 return FALSE; | |
1079 } | |
1080 | |
1081 g_free(pw->job_path); | |
1082 pw->job_path = g_strdup(path); | |
1083 } | |
1084 | |
1085 f = print_job_ps_fd(pw); | |
1086 if (!f) return FALSE; | |
1087 | |
1088 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
1089 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | |
1090 | |
1091 pe = pipe_handler_new(); | |
1092 | |
1093 /* comments, etc. */ | |
1094 fprintf(f, "%%!PS-Adobe-3.0\n"); | |
1095 fprintf(f, "%%%%Creator: GQview Version %s\n", VERSION); | |
1096 fprintf(f, "%%%%CreationDate: \n"); | |
1097 fprintf(f, "%%%%LanguageLevel 2\n"); | |
1098 fprintf(f, "%%%%DocumentMedia: \n"); | |
1099 fprintf(f, "%%%%Orientation: %s\n", | |
1100 (pw->paper_orientation == PAPER_ORIENTATION_PORTRAIT) ? "Portrait" : "Landscape"); | |
1101 fprintf(f, "%%%%BoundingBox: %f %f %f %f\n", | |
1102 0.0, 0.0, pw->paper_width, pw->paper_height); | |
1103 fprintf(f, "%%%%Pages: %d\n", print_layout_page_count(pw)); | |
1104 fprintf(f, "%%%%PageOrder: Ascend\n"); | |
1105 fprintf(f, "%%%%Title:\n"); | |
1106 | |
1107 /* setup page size, coordinates (do we really need this?) */ | |
1108 #if 0 | |
1109 fprintf(f, "<<\n"); | |
1110 fprintf(f, "/PageSize [%f %f]\n", pw->layout_width, pw->layout_height); | |
1111 fprintf(f, "/ImagingBBox [%f %f %f %f]\n", /* l b r t */ | |
1112 pw->margin_left, pw->margin_bottom, | |
1113 pw->layout_width - pw->margin_right, pw->layout_height - pw->margin_top); | |
1114 fprintf(f, "/Orientation %d\n", | |
1115 (pw->paper_orientation == PAPER_ORIENTATION_PORTRAIT) ? 0 : 1); | |
1116 fprintf(f, ">> setpagedevice\n"); | |
1117 #endif | |
1118 | |
1119 ret = !pipe_handler_check(pe); | |
1120 pipe_handler_free(pe); | |
1121 | |
1122 if (lc_pointer) | |
1123 { | |
1124 setlocale(LC_NUMERIC, lc_pointer); | |
1125 g_free(lc_pointer); | |
1126 } | |
1127 | |
1128 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1129 | |
1130 return ret; | |
1131 } | |
1132 | |
1133 static gint print_job_ps_page_new(PrintWindow *pw, gint page) | |
1134 { | |
1135 FILE *f; | |
1136 PipeError *pe; | |
1137 gchar *lc_pointer; | |
1138 gint ret; | |
1139 | |
1140 f= print_job_ps_fd(pw); | |
1141 if (!f) return FALSE; | |
1142 | |
1143 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
1144 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | |
1145 | |
1146 pe = pipe_handler_new(); | |
1147 | |
1148 fprintf(f, "%%%% page %d\n", page + 1); | |
1149 | |
1150 if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) | |
1151 { | |
1152 fprintf(f, "/pagelevel save def\n"); | |
1153 fprintf(f, "%d 0 translate 90 rotate\n", (gint)pw->layout_height); | |
1154 } | |
1155 | |
1156 ret = !pipe_handler_check(pe); | |
1157 pipe_handler_free(pe); | |
1158 | |
1159 if (lc_pointer) | |
1160 { | |
1161 setlocale(LC_NUMERIC, lc_pointer); | |
1162 g_free(lc_pointer); | |
1163 } | |
1164 | |
1165 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1166 | |
1167 return ret; | |
1168 } | |
1169 | |
1170 static gint print_job_ps_page_done(PrintWindow *pw) | |
1171 { | |
1172 FILE *f; | |
1173 PipeError *pe; | |
1174 gchar *lc_pointer; | |
1175 gint ret; | |
1176 | |
1177 f = print_job_ps_fd(pw); | |
1178 if (!f) return FALSE; | |
1179 | |
1180 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
1181 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | |
1182 | |
1183 pe = pipe_handler_new(); | |
1184 | |
1185 if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) | |
1186 { | |
1187 fprintf(f, "pagelevel restore\n"); | |
1188 } | |
1189 | |
1190 fprintf(f, "showpage\n"); | |
1191 | |
1192 ret = !pipe_handler_check(pe); | |
1193 pipe_handler_free(pe); | |
1194 | |
1195 if (lc_pointer) | |
1196 { | |
1197 setlocale(LC_NUMERIC, lc_pointer); | |
1198 g_free(lc_pointer); | |
1199 } | |
1200 | |
1201 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1202 | |
1203 return ret; | |
1204 } | |
1205 | |
1206 static void print_job_ps_page_image_pixel(FILE *f, guchar *pix) | |
1207 { | |
1208 static gchar hex_digits[] = "0123456789abcdef"; | |
1209 gchar text[8]; | |
1210 gint i; | |
1211 | |
1212 for (i = 0; i < 3; i++) | |
1213 { | |
1214 text[i*2] = hex_digits[pix[i] >> 4]; | |
1215 text[i*2+1] = hex_digits[pix[i] & 0xf]; | |
1216 } | |
1217 text[6] = '\0'; | |
1218 | |
1219 fprintf(f, text); | |
1220 } | |
1221 static gint print_job_ps_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, | |
1222 gdouble x, gdouble y, gdouble w, gdouble h, | |
1223 gdouble offx, gdouble offy) | |
1224 { | |
1225 FILE *f; | |
1226 PipeError *pe; | |
1227 gchar *lc_pointer; | |
1228 gint sw, sh; | |
1229 gint bps; | |
1230 gint rowstride; | |
1231 guchar *pix; | |
1232 gint i, j; | |
1233 gint c; | |
1234 guchar *p; | |
1235 gint ret; | |
1236 | |
1237 if (!pixbuf) return TRUE; | |
1238 | |
1239 f = print_job_ps_fd(pw); | |
1240 if (!f) return FALSE; | |
1241 | |
1242 sw = gdk_pixbuf_get_width(pixbuf); | |
1243 sh = gdk_pixbuf_get_height(pixbuf); | |
1244 | |
1245 if (pw->max_dpi >= PRINT_PS_DPI_MIN && | |
1246 sw / pw->max_dpi > w / 72.0) | |
1247 { | |
1248 pixbuf = gdk_pixbuf_scale_simple(pixbuf, | |
1249 (gint)(w / 72.0 * pw->max_dpi), | |
1250 (gint)(h / 72.0 * pw->max_dpi), | |
1251 PRINT_PS_MAX_INTERP); | |
1252 sw = gdk_pixbuf_get_width(pixbuf); | |
1253 sh = gdk_pixbuf_get_height(pixbuf); | |
1254 } | |
1255 else | |
1256 { | |
1257 g_object_ref(G_OBJECT(pixbuf)); | |
1258 } | |
1259 | |
1260 bps = (gdk_pixbuf_get_has_alpha(pixbuf)) ? 4 : 3; | |
1261 rowstride = gdk_pixbuf_get_rowstride(pixbuf); | |
1262 pix = gdk_pixbuf_get_pixels(pixbuf); | |
1263 | |
1264 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
1265 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | |
1266 | |
1267 pe = pipe_handler_new(); | |
1268 | |
1269 fprintf(f, "gsave\n"); | |
1270 fprintf(f, "[%f 0 0 %f %f %f] concat\n", w, h, x, pw->layout_height - h - y); | |
1271 fprintf(f, "/buf %d string def\n", sw * 3); | |
1272 fprintf(f, "%d %d %d\n", sw, sh, 8); | |
1273 fprintf(f, "[%d 0 0 -%d 0 %d]\n", sw, sh, sh); | |
1274 fprintf(f, "{ currentfile buf readhexstring pop }\n"); | |
1275 fprintf(f, "false %d colorimage\n", 3); | |
1276 | |
1277 c = 0; | |
1278 for (j = 0; j < sh; j++) | |
1279 { | |
1280 p = pix + j * rowstride; | |
1281 for (i = 0; i < sw; i++) | |
1282 { | |
1283 print_job_ps_page_image_pixel(f, p); | |
1284 p+=bps; | |
1285 c++; | |
1286 if (c > 11) | |
1287 { | |
1288 fprintf(f, "\n"); | |
1289 c = 0; | |
1290 } | |
1291 } | |
1292 } | |
1293 if (c > 0) fprintf(f, "\n"); | |
1294 fprintf(f, "grestore\n"); | |
1295 | |
1296 ret = !pipe_handler_check(pe); | |
1297 pipe_handler_free(pe); | |
1298 | |
1299 if (lc_pointer) | |
1300 { | |
1301 setlocale(LC_NUMERIC, lc_pointer); | |
1302 g_free(lc_pointer); | |
1303 } | |
1304 | |
1305 g_object_unref(G_OBJECT(pixbuf)); | |
1306 | |
1307 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1308 | |
1309 return ret; | |
1310 } | |
1311 | |
1312 static const gchar *ps_text_to_hex_array(FILE *f, const gchar *text, gdouble x, gdouble y) | |
1313 { | |
1314 static gchar hex_digits[] = "0123456789abcdef"; | |
1315 const gchar *p; | |
1316 | |
1317 if (!text) return NULL; | |
1318 | |
1319 fprintf(f, "%f %f moveto\n", x, y); | |
1320 fprintf(f, "<"); | |
1321 | |
1322 /* fixme: convert utf8 to ascii or proper locale string.. */ | |
1323 | |
1324 p = text; | |
1325 while (*p != '\0' && *p != '\n') | |
1326 { | |
1327 gchar text[3]; | |
1328 | |
1329 text[0] = hex_digits[*p >> 4]; | |
1330 text[1] = hex_digits[*p & 0xf]; | |
1331 text[2] = '\0'; | |
1332 | |
1333 fprintf(f, text); | |
1334 | |
1335 p++; | |
1336 } | |
1337 | |
1338 fprintf(f, ">\n"); | |
1339 fprintf(f, "dup stringwidth pop 2 div neg 0 rmoveto show\n"); | |
1340 | |
1341 return p; | |
1342 } | |
1343 | |
1344 static void ps_text_parse(FILE *f, const gchar *text, gdouble x, gdouble y, gdouble point_size) | |
1345 { | |
1346 const gchar *p; | |
1347 | |
1348 if (!text) return; | |
1349 | |
1350 fprintf(f, "newpath\n"); | |
1351 | |
1352 p = text; | |
1353 while (p && *p != '\0') | |
1354 { | |
1355 p = ps_text_to_hex_array(f, p, x, y); | |
1356 if (p && *p == '\n') p++; | |
1357 y -= point_size; | |
1358 } | |
1359 | |
1360 fprintf(f, "closepath\n"); | |
1361 } | |
1362 | |
1363 static gint print_job_ps_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, | |
1364 gdouble x, gdouble y, gdouble width, | |
1365 guint8 r, guint8 g, guint8 b) | |
1366 { | |
1367 FILE *f; | |
1368 PipeError *pe; | |
1369 gchar *lc_pointer; | |
1370 gint ret; | |
1371 | |
1372 if (!text) return TRUE; | |
1373 | |
1374 f = print_job_ps_fd(pw); | |
1375 if (!f) return FALSE; | |
1376 | |
1377 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
1378 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | |
1379 | |
1380 pe = pipe_handler_new(); | |
1381 | |
1382 fprintf(f, "/Sans findfont\n"); | |
1383 fprintf(f, "%f scalefont\n", point_size); | |
1384 fprintf(f, "setfont\n"); | |
1385 | |
1386 fprintf(f, "%f %f %f setrgbcolor\n", (gdouble)r / 255.0, (gdouble)g / 255.0, (gdouble)b / 255.0); | |
1387 ps_text_parse(f, text, x, pw->layout_height - y - point_size, point_size); | |
1388 | |
1389 ret = !pipe_handler_check(pe); | |
1390 pipe_handler_free(pe); | |
1391 | |
1392 if (lc_pointer) | |
1393 { | |
1394 setlocale(LC_NUMERIC, lc_pointer); | |
1395 g_free(lc_pointer); | |
1396 } | |
1397 | |
1398 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1399 | |
1400 return ret; | |
1401 } | |
1402 | |
1403 static gint print_job_ps_end(PrintWindow *pw) | |
1404 { | |
1405 FILE *f; | |
1406 PipeError *pe; | |
1407 gchar *lc_pointer; | |
1408 gint ret; | |
1409 | |
1410 f = print_job_ps_fd(pw); | |
1411 if (!f) return FALSE; | |
1412 | |
1413 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | |
1414 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | |
1415 | |
1416 pe = pipe_handler_new(); | |
1417 | |
1418 fprintf(f, "%%%%EOF\n"); | |
1419 | |
1420 ret = !pipe_handler_check(pe); | |
1421 pipe_handler_free(pe); | |
1422 | |
1423 if (lc_pointer) | |
1424 { | |
1425 setlocale(LC_NUMERIC, lc_pointer); | |
1426 g_free(lc_pointer); | |
1427 } | |
1428 | |
1429 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1430 | |
1431 return ret; | |
1432 } | |
1433 | |
1434 /* | |
1435 *----------------------------------------------------------------------------- | |
1436 * print rgb | |
1437 *----------------------------------------------------------------------------- | |
1438 */ | |
1439 | |
1440 static gint print_job_rgb_page_new(PrintWindow *pw, gint page) | |
1441 { | |
1442 gint total; | |
1443 | |
1444 if (pw->job_pixbuf) | |
1445 { | |
1446 pixbuf_set_rect_fill(pw->job_pixbuf, 0, 0, | |
1447 gdk_pixbuf_get_width(pw->job_pixbuf), | |
1448 gdk_pixbuf_get_height(pw->job_pixbuf), | |
1449 255, 255, 255, 255); | |
1450 } | |
1451 | |
1452 g_free(pw->job_path); | |
1453 pw->job_path = NULL; | |
1454 | |
1455 total = print_layout_page_count(pw); | |
1456 | |
1457 if (!pw->output_path || | |
1458 page < 0 || page >= total) return FALSE; | |
1459 | |
1460 if (total > 1) | |
1461 { | |
1462 const gchar *ext; | |
1463 gchar *base; | |
1464 | |
1465 ext = extension_from_path(pw->output_path); | |
1466 | |
1467 if (ext) | |
1468 { | |
1469 base = g_strndup(pw->output_path, ext - pw->output_path); | |
1470 } | |
1471 else | |
1472 { | |
1473 base = g_strdup(pw->output_path); | |
1474 ext = ""; | |
1475 } | |
1476 pw->job_path = g_strdup_printf("%s_%03d%s", base, page + 1, ext); | |
1477 g_free(base); | |
1478 } | |
1479 else | |
1480 { | |
1481 pw->job_path = g_strdup(pw->output_path); | |
1482 } | |
1483 | |
1484 if (isfile(pw->job_path)) | |
1485 { | |
1486 gchar *buf; | |
1487 | |
1488 buf = g_strdup_printf(_("A file with name %s already exists."), pw->job_path); | |
1489 print_job_throw_error(pw, buf); | |
1490 g_free(buf); | |
1491 | |
1492 g_free(pw->job_path); | |
1493 pw->job_path = NULL; | |
1494 } | |
1495 | |
1496 return (pw->job_path != NULL); | |
1497 } | |
1498 | |
1499 static gint print_job_rgb_page_done(PrintWindow *pw) | |
1500 { | |
1501 gchar *pathl; | |
1502 gint ret = FALSE; | |
1503 | |
1504 if (!pw->job_pixbuf) return FALSE; | |
1505 | |
1506 pathl = path_from_utf8(pw->job_path); | |
1507 | |
1508 if (pw->output_format == PRINT_FILE_PNG) | |
1509 { | |
1510 ret = pixbuf_to_file_as_png(pw->job_pixbuf, pathl); | |
1511 } | |
1512 else | |
1513 { | |
1514 gint quality = 0; | |
1515 | |
1516 switch (pw->output_format) | |
1517 { | |
1518 case PRINT_FILE_JPG_LOW: | |
1519 quality = 65; | |
1520 break; | |
1521 case PRINT_FILE_JPG_NORMAL: | |
1522 quality = 80; | |
1523 break; | |
1524 case PRINT_FILE_JPG_HIGH: | |
1525 quality = 95; | |
1526 break; | |
1527 default: | |
1528 break; | |
1529 } | |
1530 | |
1531 if (quality > 0) | |
1532 { | |
1533 ret = pixbuf_to_file_as_jpg(pw->job_pixbuf, pathl, quality); | |
1534 } | |
1535 } | |
1536 | |
1537 g_free(pathl); | |
1538 | |
1539 if (!ret) | |
1540 { | |
1541 gchar *buf; | |
1542 | |
1543 buf = g_strdup_printf(_("Failure writing to file %s"), pw->job_path); | |
1544 print_job_throw_error(pw, buf); | |
1545 g_free(buf); | |
1546 } | |
1547 | |
1548 return ret; | |
1549 } | |
1550 | |
1551 static gint print_job_rgb_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, | |
1552 gdouble x, gdouble y, gdouble w, gdouble h, | |
1553 gdouble offx, gdouble offy) | |
1554 { | |
1555 gdouble sw, sh; | |
1556 gdouble dw, dh; | |
1557 gdouble rx, ry, rw, rh; | |
1558 | |
1559 if (!pw->job_pixbuf) return FALSE; | |
1560 if (!pixbuf) return TRUE; | |
1561 | |
1562 sw = (gdouble)gdk_pixbuf_get_width(pixbuf); | |
1563 sh = (gdouble)gdk_pixbuf_get_height(pixbuf); | |
1564 | |
1565 dw = (gdouble)gdk_pixbuf_get_width(pw->job_pixbuf); | |
1566 dh = (gdouble)gdk_pixbuf_get_height(pw->job_pixbuf); | |
1567 | |
1568 if (clip_region(x, y, w, h, | |
1569 0.0, 0.0, dw, dh, | |
1570 &rx, &ry, &rw, &rh)) | |
1571 { | |
1572 gdk_pixbuf_composite(pixbuf, pw->job_pixbuf, rx, ry, rw, rh, | |
1573 x + offx, y + offy, | |
1574 w / sw, h / sh, | |
1575 (w / sw < 0.01 || h / sh < 0.01) ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR, 255); | |
1576 } | |
1577 | |
1578 return TRUE; | |
1579 } | |
1580 | |
1581 static gdouble convert_pango_dpi(gdouble points) | |
1582 { | |
1583 static gdouble dpi = 0.0; | |
1584 | |
1585 if (dpi == 0.0) | |
1586 { | |
1587 GtkSettings *settings; | |
1588 GObjectClass *klass; | |
1589 | |
1590 settings = gtk_settings_get_default(); | |
1591 klass = G_OBJECT_CLASS(GTK_SETTINGS_GET_CLASS(settings)); | |
1592 if (g_object_class_find_property(klass, "gtk-xft-dpi")) | |
1593 { | |
1594 int int_dpi; | |
1595 g_object_get(settings, "gtk-xft-dpi", &int_dpi, NULL); | |
1596 dpi = (gdouble)int_dpi / PANGO_SCALE; | |
1597 } | |
1598 | |
1599 if (dpi < 25.0) | |
1600 { | |
1601 static gint warned = FALSE; | |
1602 gdouble fallback_dpi = 96.0; | |
1603 | |
1604 if (!warned) | |
1605 { | |
1606 if (dpi == 0.0) | |
1607 { | |
1608 printf("pango dpi unknown, assuming %.0f\n", fallback_dpi); | |
1609 } | |
1610 else | |
1611 { | |
1612 printf("pango dpi reported as %.0f ignored, assuming %.0f\n", dpi, fallback_dpi); | |
1613 } | |
1614 warned = TRUE; | |
1615 } | |
1616 | |
1617 dpi = fallback_dpi; | |
1618 } | |
1619 } | |
1620 | |
1621 if (dpi == 0) return points; | |
1622 return points * 72.0 / dpi; | |
1623 } | |
1624 | |
1625 static gint print_job_rgb_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, | |
1626 gdouble x, gdouble y, gdouble width, | |
1627 guint8 r, guint8 g, guint8 b) | |
1628 { | |
1629 PangoLayout *layout; | |
1630 PangoFontDescription *desc; | |
1631 gint lw, lh; | |
1632 | |
1633 if (!pw->job_pixbuf) return FALSE; | |
1634 | |
1635 layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); | |
1636 | |
1637 desc = pango_font_description_new(); | |
1638 pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE); | |
1639 pango_layout_set_font_description(layout, desc); | |
1640 pango_font_description_free(desc); | |
1641 | |
1642 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); | |
1643 pango_layout_set_text(layout, text, -1); | |
1644 | |
1645 pango_layout_get_pixel_size(layout, &lw, &lh); | |
1646 x = x - (gdouble)lw / 2.0; | |
1647 | |
1648 pixbuf_draw_layout(pw->job_pixbuf, layout, pw->dialog->dialog, x, y, r, g, b, 255); | |
1649 g_object_unref(G_OBJECT(layout)); | |
1650 | |
1651 return TRUE; | |
1652 } | |
1653 | |
1654 static gint print_job_rgb_init(PrintWindow *pw) | |
1655 { | |
1656 if (pw->job_pixbuf) g_object_unref(pw->job_pixbuf); | |
1657 pw->job_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, | |
1658 (gint)pw->layout_width, (gint)pw->layout_height); | |
1659 | |
1660 return print_job_rgb_page_new(pw, pw->job_page); | |
1661 } | |
1662 | |
1663 /* | |
1664 *----------------------------------------------------------------------------- | |
1665 * print preview | |
1666 *----------------------------------------------------------------------------- | |
1667 */ | |
1668 | |
1669 static gint print_job_preview_page_new(PrintWindow *pw, gint page) | |
1670 { | |
1671 GdkPixbuf *pixbuf; | |
1672 gint w, h; | |
1673 gint l, r, t, b; | |
1674 | |
1675 pixbuf = pw->job_pixbuf; | |
1676 if (!pixbuf) return FALSE; | |
1677 | |
1678 w = print_preview_unit(pw->layout_width); | |
1679 h = print_preview_unit(pw->layout_height); | |
1680 l = print_preview_unit(pw->margin_left); | |
1681 r = print_preview_unit(pw->margin_right); | |
1682 t = print_preview_unit(pw->margin_top); | |
1683 b = print_preview_unit(pw->margin_bottom); | |
1684 | |
1685 /* fill background */ | |
1686 pixbuf_set_rect_fill(pixbuf, 0, 0, w, h, | |
1687 255, 255, 255, 255); | |
1688 | |
1689 /* draw cm or inch grid */ | |
1690 if (TRUE) | |
1691 { | |
1692 gdouble i; | |
1693 gdouble grid; | |
1694 PaperUnits units; | |
1695 | |
1696 units = (pw->paper_units == PAPER_UNIT_MM || | |
1697 pw->paper_units == PAPER_UNIT_CM) ? PAPER_UNIT_CM : PAPER_UNIT_INCH; | |
1698 | |
1699 grid = print_paper_size_convert_units(1.0, units, PAPER_UNIT_POINTS); | |
1700 for (i = grid ; i < pw->layout_width; i += grid) | |
1701 { | |
1702 pixbuf_draw_rect_fill(pixbuf, print_preview_unit(i), 0, 1, h, 0, 0, 0, 16); | |
1703 } | |
1704 for (i = grid; i < pw->layout_height; i += grid) | |
1705 { | |
1706 pixbuf_draw_rect_fill(pixbuf, 0, print_preview_unit(i), w, 1, 0, 0, 0, 16); | |
1707 } | |
1708 } | |
1709 | |
1710 /* proof sheet grid */ | |
1711 if (pw->layout == PRINT_LAYOUT_PROOF) | |
1712 { | |
1713 gdouble i, j; | |
1714 gdouble proof_w, proof_h; | |
1715 gint uw, uh; | |
1716 | |
1717 print_proof_size(pw, &proof_w, &proof_h); | |
1718 uw = print_preview_unit(proof_w + PRINT_PREVIEW_SCALE - 0.1); | |
1719 uh = print_preview_unit(proof_h + PRINT_PREVIEW_SCALE - 0.1); | |
1720 | |
1721 for (i = 0; i < pw->proof_columns; i++) | |
1722 for (j = 0; j < pw->proof_rows; j++) | |
1723 { | |
1724 gint x, y; | |
1725 | |
1726 x = pw->margin_left + (pw->layout_width - pw->margin_left - pw->margin_right - (pw->proof_columns * proof_w)) / 2 + i * proof_w; | |
1727 y = pw->margin_top + j * proof_h; | |
1728 | |
1729 pixbuf_draw_rect(pixbuf, print_preview_unit(x), print_preview_unit(y), uw, uh, | |
1730 255, 0, 0, 64, 1, 1, 1, 1); | |
1731 } | |
1732 } | |
1733 | |
1734 /* non-printable region (margins) */ | |
1735 pixbuf_draw_rect(pixbuf, 0, 0, w, h, | |
1736 0, 0, 0, 16, | |
1737 l, r, t, b); | |
1738 | |
1739 /* margin lines */ | |
1740 pixbuf_draw_rect(pixbuf, l, 0, w - l - r, h, | |
1741 0, 0, 255, 128, | |
1742 1, 1, 0, 0); | |
1743 pixbuf_draw_rect(pixbuf, 0, t, w, h - t - b, | |
1744 0, 0, 255, 128, | |
1745 0, 0, 1, 1); | |
1746 | |
1747 /* border */ | |
1748 pixbuf_draw_rect(pixbuf, 0, 0, w, h, | |
1749 0, 0, 0, 255, | |
1750 1, 1, 1, 1); | |
1751 | |
1752 image_area_changed(pw->layout_image, 0, 0, w, h); | |
1753 | |
1754 return TRUE; | |
1755 } | |
1756 | |
1757 static gint print_job_preview_page_done(PrintWindow *pw) | |
1758 { | |
1759 return TRUE; | |
1760 } | |
1761 | |
1762 static gint print_job_preview_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, | |
1763 gdouble x, gdouble y, gdouble w, gdouble h, | |
1764 gdouble offx, gdouble offy) | |
1765 { | |
1766 gdouble sw, sh; | |
1767 gdouble dw, dh; | |
1768 gdouble rx, ry, rw, rh; | |
1769 | |
1770 if (!pw->job_pixbuf) return FALSE; | |
1771 if (!pixbuf) return TRUE; | |
1772 | |
1773 sw = (gdouble)gdk_pixbuf_get_width(pixbuf); | |
1774 sh = (gdouble)gdk_pixbuf_get_height(pixbuf); | |
1775 | |
1776 dw = (gdouble)gdk_pixbuf_get_width(pw->job_pixbuf); | |
1777 dh = (gdouble)gdk_pixbuf_get_height(pw->job_pixbuf); | |
1778 | |
1779 x = print_preview_unit(x); | |
1780 y = print_preview_unit(y); | |
1781 w = print_preview_unit(w); | |
1782 h = print_preview_unit(h); | |
1783 offx = print_preview_unit(offx); | |
1784 offy = print_preview_unit(offy); | |
1785 | |
1786 if (clip_region(x, y, w, h, | |
1787 0.0, 0.0, dw, dh, | |
1788 &rx, &ry, &rw, &rh)) | |
1789 { | |
1790 gdk_pixbuf_composite(pixbuf, pw->job_pixbuf, rx, ry, rw, rh, | |
1791 x + offx, y + offy, | |
1792 w / sw, h / sh, | |
1793 (w / sw < 0.01 || h / sh < 0.01) ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR, 255); | |
1794 | |
1795 image_area_changed(pw->layout_image, rx, ry, rw, rh); | |
1796 } | |
1797 | |
1798 return TRUE; | |
1799 } | |
1800 | |
1801 static gint print_job_preview_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, | |
1802 gdouble x, gdouble y, gdouble width, | |
1803 guint8 r, guint8 g, guint8 b) | |
1804 { | |
1805 PangoLayout *layout; | |
1806 PangoFontDescription *desc; | |
1807 gint lw, lh; | |
1808 GdkPixbuf *pixbuf; | |
1809 | |
1810 if (!pw->job_pixbuf) return FALSE; | |
1811 | |
1812 layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); | |
1813 | |
1814 desc = pango_font_description_new(); | |
1815 pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE); | |
1816 pango_layout_set_font_description(layout, desc); | |
1817 pango_font_description_free(desc); | |
1818 | |
1819 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); | |
1820 pango_layout_set_text(layout, text, -1); | |
1821 | |
1822 pango_layout_get_pixel_size(layout, &lw, &lh); | |
1823 x = x - (gdouble)lw / 2.0; | |
1824 | |
1825 pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, lw, lh); | |
1826 pixbuf_set_rect_fill(pixbuf, 0, 0, lw, lh, 0, 0, 0, 0); | |
1827 pixbuf_draw_layout(pixbuf, layout, pw->dialog->dialog, 0, 0, r, g, b, 255); | |
1828 g_object_unref(G_OBJECT(layout)); | |
1829 | |
1830 print_job_preview_page_image(pw, pixbuf, x, y, (gdouble)lw, (gdouble)lh, 0, 0); | |
1831 g_object_unref(pixbuf); | |
1832 | |
1833 return TRUE; | |
1834 } | |
1835 | |
1836 static gint print_job_preview_init(PrintWindow *pw) | |
1837 { | |
1838 if (pw->job_pixbuf) g_object_unref(pw->job_pixbuf); | |
1839 pw->job_pixbuf = pw->layout_image->pixbuf; | |
1840 g_object_ref(pw->job_pixbuf); | |
1841 | |
1842 return print_job_preview_page_new(pw, pw->job_page); | |
1843 } | |
1844 | |
1845 | |
1846 /* | |
1847 *----------------------------------------------------------------------------- | |
1848 * wrappers | |
1849 *----------------------------------------------------------------------------- | |
1850 */ | |
1851 | |
1852 static gint print_job_page_new(PrintWindow *pw) | |
1853 { | |
1854 switch (pw->job_format) | |
1855 { | |
1856 case RENDER_FORMAT_RGB: | |
1857 return print_job_rgb_page_new(pw, pw->job_page); | |
1858 case RENDER_FORMAT_PS: | |
1859 return print_job_ps_page_new(pw, pw->job_page); | |
1860 case RENDER_FORMAT_PREVIEW: | |
1861 return print_job_preview_page_new(pw, pw->job_page); | |
1862 } | |
1863 | |
1864 return FALSE; | |
1865 } | |
1866 | |
1867 static gint print_job_page_done(PrintWindow *pw) | |
1868 { | |
1869 switch (pw->job_format) | |
1870 { | |
1871 case RENDER_FORMAT_RGB: | |
1872 return print_job_rgb_page_done(pw); | |
1873 case RENDER_FORMAT_PS: | |
1874 return print_job_ps_page_done(pw); | |
1875 case RENDER_FORMAT_PREVIEW: | |
1876 return print_job_preview_page_done(pw); | |
1877 } | |
1878 | |
1879 return FALSE; | |
1880 } | |
1881 | |
1882 static gint print_job_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, | |
1883 gdouble x, gdouble y, gdouble w, gdouble h, | |
1884 gdouble offx, gdouble offy) | |
1885 { | |
1886 gint success = FALSE; | |
1887 | |
1888 if (w <= 0.0 || h <= 0.0) return TRUE; | |
1889 | |
1890 switch (pw->job_format) | |
1891 { | |
1892 case RENDER_FORMAT_RGB: | |
1893 success = print_job_rgb_page_image(pw, pixbuf, x, y, w, h, offx, offy); | |
1894 break; | |
1895 case RENDER_FORMAT_PS: | |
1896 success = print_job_ps_page_image(pw, pixbuf, x, y, w, h, offx, offy); | |
1897 break; | |
1898 case RENDER_FORMAT_PREVIEW: | |
1899 success = print_job_preview_page_image(pw, pixbuf, x, y, w, h, offx, offy); | |
1900 break; | |
1901 } | |
1902 | |
1903 return success; | |
1904 } | |
1905 | |
1906 static gint print_job_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, | |
1907 gdouble x, gdouble y, gdouble width, | |
1908 guint8 r, guint8 g, guint8 b) | |
1909 { | |
1910 gint success = TRUE; | |
1911 | |
1912 if (!text) return TRUE; | |
1913 | |
1914 switch (pw->job_format) | |
1915 { | |
1916 case RENDER_FORMAT_RGB: | |
1917 success = print_job_rgb_page_text(pw, text, point_size, x, y, width, r, g, b); | |
1918 break; | |
1919 case RENDER_FORMAT_PS: | |
1920 success = print_job_ps_page_text(pw, text, point_size, x, y, width, r, g, b); | |
1921 break; | |
1922 case RENDER_FORMAT_PREVIEW: | |
1923 success = print_job_preview_page_text(pw, text, point_size, x, y, width, r, g, b); | |
1924 break; | |
1925 } | |
1926 | |
1927 return success; | |
1928 } | |
1929 | |
1930 /* | |
1931 *----------------------------------------------------------------------------- | |
1932 * print ? | |
1933 *----------------------------------------------------------------------------- | |
1934 */ | |
1935 | |
1936 static gint print_job_render_image(PrintWindow *pw); | |
1937 static gint print_job_render_proof(PrintWindow *pw); | |
1938 | |
1939 | |
1940 static void print_job_status(PrintWindow *pw) | |
1941 { | |
1942 gdouble value; | |
1943 gint page; | |
1944 gint total; | |
1945 gchar *buf; | |
1946 | |
1947 if (!pw->job_progress) return; | |
1948 | |
1949 page = pw->job_page; | |
1950 total = print_layout_page_count(pw); | |
1951 | |
1952 if (pw->layout == PRINT_LAYOUT_PROOF && pw->proof_point) | |
1953 { | |
1954 GList *start; | |
1955 | |
1956 start = g_list_first(pw->proof_point); | |
1957 value = (gdouble)g_list_position(start, pw->proof_point) / g_list_length(start); | |
1958 } | |
1959 else | |
1960 { | |
1961 value = (total > 0) ? (gdouble)page / total : 0.0; | |
1962 } | |
1963 | |
1964 buf = g_strdup_printf(_("Page %d"), page + 1); | |
1965 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pw->job_progress), buf); | |
1966 g_free(buf); | |
1967 | |
1968 if (pw->job_path && pw->job_progress_label) | |
1969 { | |
1970 gtk_label_set_text(GTK_LABEL(pw->job_progress_label), pw->job_path); | |
1971 } | |
1972 | |
1973 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pw->job_progress), value); | |
1974 } | |
1975 | |
1976 static void print_job_throw_error(PrintWindow *pw, const gchar *message) | |
1977 { | |
1978 GenericDialog *gd; | |
1979 GtkWidget *parent = NULL; | |
1980 GtkWidget *group; | |
1981 GtkWidget *label; | |
1982 gchar *buf; | |
1983 | |
1984 if (GTK_WIDGET_VISIBLE(pw->dialog->dialog)) parent = pw->dialog->dialog; | |
1985 | |
1986 gd = generic_dialog_new(_("Printing error"), "GQview", "print_warning", | |
1987 parent, TRUE, NULL, NULL); | |
1988 generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, NULL, TRUE); | |
1989 | |
1990 buf = g_strdup_printf(_("An error occured printing to %s."), print_output_name(pw->output)); | |
1991 generic_dialog_add_message(gd, GTK_STOCK_DIALOG_ERROR, _("Printing error"), buf); | |
1992 g_free(buf); | |
1993 | |
1994 group = pref_group_new(gd->vbox, FALSE, _("Details"), GTK_ORIENTATION_VERTICAL); | |
1995 label = pref_label_new(group, message); | |
1996 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); | |
1997 | |
1998 gtk_widget_show(gd->dialog); | |
1999 } | |
2000 | |
2001 static void print_job_done(PrintWindow *pw) | |
2002 { | |
2003 print_job_close(pw, FALSE); | |
2004 } | |
2005 | |
2006 static gint print_job_text_image(PrintWindow *pw, const gchar *path, | |
2007 gdouble x, gdouble y, gdouble width, | |
2008 gint sw, gint sh, gint proof) | |
2009 { | |
2010 GString *string; | |
2011 gint space = FALSE; | |
2012 gint newline = FALSE; | |
2013 gint ret; | |
2014 | |
2015 if (pw->text_fields == 0) return TRUE; | |
2016 | |
2017 string = g_string_new(""); | |
2018 path = pw->job_loader->path; | |
2019 | |
2020 if (pw->text_fields & TEXT_INFO_FILENAME) | |
2021 { | |
2022 g_string_append(string, filename_from_path(path)); | |
2023 newline = TRUE; | |
2024 } | |
2025 if (pw->text_fields & TEXT_INFO_DIMENSIONS) | |
2026 { | |
2027 if (newline) g_string_append(string, "\n"); | |
2028 g_string_append_printf(string, "%d x %d", (gint)sw, (gint)sh); | |
2029 newline = proof; | |
2030 space = !proof; | |
2031 } | |
2032 if (pw->text_fields & TEXT_INFO_FILEDATE) | |
2033 { | |
2034 if (newline) g_string_append(string, "\n"); | |
2035 if (space) g_string_append(string, " - "); | |
2036 g_string_append(string, text_from_time(filetime(pw->job_loader->path))); | |
2037 newline = proof; | |
2038 space = !proof; | |
2039 } | |
2040 if (pw->text_fields & TEXT_INFO_FILESIZE) | |
2041 { | |
2042 gchar *size; | |
2043 | |
2044 if (newline) g_string_append(string, "\n"); | |
2045 if (space) g_string_append(string, " - "); | |
2046 size = text_from_size_abrev(filesize(pw->job_loader->path)); | |
2047 g_string_append(string, size); | |
2048 g_free(size); | |
2049 } | |
2050 | |
2051 ret = print_job_page_text(pw, string->str, pw->text_points, x, y, width, | |
2052 pw->text_r, pw->text_g, pw->text_b); | |
2053 | |
2054 g_string_free(string, TRUE); | |
2055 | |
2056 return ret; | |
2057 } | |
2058 | |
2059 static void print_job_render_image_loader_done(ImageLoader *il, gpointer data) | |
2060 { | |
2061 PrintWindow *pw = data; | |
2062 GdkPixbuf *pixbuf; | |
2063 gint success = TRUE; | |
2064 | |
2065 pixbuf = image_loader_get_pixbuf(il); | |
2066 if (pixbuf) | |
2067 { | |
2068 gdouble sw, sh; | |
2069 gdouble dw, dh; | |
2070 gdouble x, y, w, h; | |
2071 gdouble scale; | |
2072 gdouble offx, offy; | |
2073 | |
2074 sw = (gdouble)gdk_pixbuf_get_width(pixbuf); | |
2075 sh = (gdouble)gdk_pixbuf_get_height(pixbuf); | |
2076 | |
2077 dw = pw->layout_width - pw->margin_left - pw->margin_right; | |
2078 dh = pw->layout_height - pw->margin_top - pw->margin_bottom; | |
2079 | |
2080 if (dw / sw < dh / sh) | |
2081 { | |
2082 w = dw; | |
2083 h = dw / sw * sh; | |
2084 scale = w / sw; | |
2085 } | |
2086 else | |
2087 { | |
2088 h = dh; | |
2089 w = dh / sh *sw; | |
2090 scale = h / sh; | |
2091 } | |
2092 | |
2093 if (pw->image_scale >= 5) | |
2094 { | |
2095 w = w * (gdouble)pw->image_scale / 100.0; | |
2096 h = h * (gdouble)pw->image_scale / 100.0; | |
2097 } | |
2098 | |
2099 x = pw->margin_left + (dw / 2) - (w / 2); | |
2100 y = pw->margin_top + (dh / 2) - (h / 2); | |
2101 | |
2102 offx = offy = 0; | |
2103 | |
2104 if (x < 0) | |
2105 { | |
2106 w += x; | |
2107 offx = x; | |
2108 x = 0; | |
2109 } | |
2110 if (x + w >= pw->layout_width) w = pw->layout_width - x; | |
2111 | |
2112 if (y < 0) | |
2113 { | |
2114 h += y; | |
2115 offy = y; | |
2116 y = 0; | |
2117 } | |
2118 if (y + h >= pw->layout_height) h = pw->layout_height - y; | |
2119 | |
2120 success = (success && | |
2121 print_job_page_image(pw, pixbuf, x, y, w, h, offx, offy)); | |
2122 | |
2123 x = x + w / 2; | |
2124 y = y + h + PRINT_TEXT_PADDING; | |
2125 | |
2126 success = (success && | |
2127 print_job_text_image(pw, pw->job_loader->path, x, y, dw, sw, sh, FALSE)); | |
2128 } | |
2129 | |
2130 image_loader_free(pw->job_loader); | |
2131 pw->job_loader = NULL; | |
2132 | |
2133 if (pw->job_format == RENDER_FORMAT_PREVIEW) | |
2134 { | |
2135 print_job_done(pw); | |
2136 return; | |
2137 } | |
2138 | |
2139 success = (success && print_job_page_done(pw)); | |
2140 if (!success) | |
2141 { | |
2142 print_job_close(pw, TRUE); | |
2143 return; | |
2144 } | |
2145 | |
2146 pw->job_page++; | |
2147 print_job_status(pw); | |
2148 | |
2149 if (print_job_render_image(pw)) | |
2150 { | |
2151 if (!print_job_page_new(pw)) print_job_close(pw, TRUE); | |
2152 } | |
2153 else | |
2154 { | |
2155 print_job_done(pw); | |
2156 } | |
2157 } | |
2158 | |
2159 static gint print_job_render_image(PrintWindow *pw) | |
2160 { | |
2161 gchar *path = NULL; | |
2162 | |
2163 switch (pw->source) | |
2164 { | |
2165 case PRINT_SOURCE_SELECTION: | |
2166 path = g_list_nth_data(pw->source_selection, pw->job_page); | |
2167 break; | |
2168 case PRINT_SOURCE_ALL: | |
2169 path = g_list_nth_data(pw->source_list, pw->job_page); | |
2170 break; | |
2171 case PRINT_SOURCE_IMAGE: | |
2172 default: | |
2173 if (pw->job_page == 0) path = pw->source_path; | |
2174 break; | |
2175 } | |
2176 | |
2177 image_loader_free(pw->job_loader); | |
2178 pw->job_loader = NULL; | |
2179 | |
2180 if (!path) return FALSE; | |
2181 | |
2182 pw->job_loader = image_loader_new(path); | |
2183 if (!image_loader_start(pw->job_loader, print_job_render_image_loader_done, pw)) | |
2184 { | |
2185 image_loader_free(pw->job_loader); | |
2186 pw->job_loader= NULL; | |
2187 } | |
2188 | |
2189 return TRUE; | |
2190 } | |
2191 | |
2192 static void print_job_render_proof_loader_done(ImageLoader *il, gpointer data) | |
2193 { | |
2194 PrintWindow *pw = data; | |
2195 GdkPixbuf *pixbuf; | |
2196 gdouble x, y; | |
2197 gdouble w, h; | |
2198 gdouble proof_w, proof_h; | |
2199 gdouble icon_w, icon_h; | |
2200 gdouble scale; | |
2201 gint success = TRUE; | |
2202 | |
2203 if (pw->proof_columns < 1 || pw->proof_rows < 1) | |
2204 { | |
2205 image_loader_free(pw->job_loader); | |
2206 pw->job_loader = NULL; | |
2207 | |
2208 print_job_done(pw); | |
2209 | |
2210 return; | |
2211 } | |
2212 | |
2213 pixbuf = image_loader_get_pixbuf(il); | |
2214 | |
2215 w = gdk_pixbuf_get_width(pixbuf); | |
2216 h = gdk_pixbuf_get_height(pixbuf); | |
2217 | |
2218 if (pw->proof_width / w < pw->proof_height / h) | |
2219 { | |
2220 icon_w = pw->proof_width; | |
2221 icon_h = pw->proof_width / w * h; | |
2222 scale = icon_w / w; | |
2223 } | |
2224 else | |
2225 { | |
2226 icon_h = pw->proof_height; | |
2227 icon_w = pw->proof_height / h * w; | |
2228 scale = icon_h / h; | |
2229 } | |
2230 | |
2231 y = pw->proof_position / pw->proof_columns; | |
2232 x = pw->proof_position - (y * pw->proof_columns); | |
2233 | |
2234 print_proof_size(pw, &proof_w, &proof_h); | |
2235 | |
2236 x *= proof_w; | |
2237 y *= proof_h; | |
2238 x += pw->margin_left + (pw->layout_width - pw->margin_left - pw->margin_right - (pw->proof_columns * proof_w)) / 2 + (proof_w - icon_w) / 2; | |
2239 y += pw->margin_top + PRINT_PROOF_MARGIN + (pw->proof_height - icon_h) / 2; | |
2240 | |
2241 success = (success && | |
2242 print_job_page_image(pw, pixbuf, x, y, icon_w, icon_h, 0, 0)); | |
2243 | |
2244 x = x + icon_w / 2; | |
2245 y = y + icon_h + (pw->proof_height - icon_h) / 2 + PRINT_TEXT_PADDING; | |
2246 | |
2247 success = (success && | |
2248 print_job_text_image(pw, pw->job_loader->path, x, y, icon_w + PRINT_PROOF_MARGIN * 2, w, h, TRUE)); | |
2249 | |
2250 if (!success) | |
2251 { | |
2252 print_job_close(pw, TRUE); | |
2253 return; | |
2254 } | |
2255 | |
2256 if (pw->proof_point) pw->proof_point = pw->proof_point->next; | |
2257 | |
2258 pw->proof_position++; | |
2259 if (pw->proof_position >= pw->proof_columns * pw->proof_rows) | |
2260 { | |
2261 if (pw->job_format == RENDER_FORMAT_PREVIEW) | |
2262 { | |
2263 print_job_done(pw); | |
2264 return; | |
2265 } | |
2266 | |
2267 if (!print_job_page_done(pw)) | |
2268 { | |
2269 print_job_close(pw, TRUE); | |
2270 return; | |
2271 } | |
2272 | |
2273 pw->proof_position = 0; | |
2274 pw->job_page++; | |
2275 if (print_job_render_proof(pw)) | |
2276 { | |
2277 if (!print_job_page_new(pw)) | |
2278 { | |
2279 print_job_close(pw, TRUE); | |
2280 return; | |
2281 } | |
2282 print_job_status(pw); | |
2283 } | |
2284 else | |
2285 { | |
2286 print_job_done(pw); | |
2287 } | |
2288 } | |
2289 else | |
2290 { | |
2291 if (print_job_render_proof(pw)) | |
2292 { | |
2293 print_job_status(pw); | |
2294 } | |
2295 else | |
2296 { | |
2297 if (print_job_page_done(pw)) | |
2298 { | |
2299 print_job_done(pw); | |
2300 } | |
2301 else | |
2302 { | |
2303 print_job_close(pw, TRUE); | |
2304 } | |
2305 } | |
2306 } | |
2307 } | |
2308 | |
2309 static gint print_job_render_proof(PrintWindow *pw) | |
2310 { | |
2311 gchar *path = NULL; | |
2312 | |
2313 if (pw->proof_columns < 1 || pw->proof_rows < 1) return FALSE; | |
2314 | |
2315 if (!pw->proof_point && pw->proof_position == 0 && pw->source == PRINT_SOURCE_IMAGE) | |
2316 { | |
2317 path = pw->source_path; | |
2318 } | |
2319 else if (pw->proof_point && | |
2320 pw->proof_position < pw->proof_columns * pw->proof_rows) | |
2321 { | |
2322 path = pw->proof_point->data; | |
2323 } | |
2324 | |
2325 if (!path) return FALSE; | |
2326 | |
2327 image_loader_free(pw->job_loader); | |
2328 pw->job_loader = image_loader_new(path); | |
2329 if (!image_loader_start(pw->job_loader, print_job_render_proof_loader_done, pw)) | |
2330 { | |
2331 image_loader_free(pw->job_loader); | |
2332 pw->job_loader = NULL; | |
2333 } | |
2334 | |
2335 return TRUE; | |
2336 } | |
2337 | |
2338 static void print_job_render(PrintWindow *pw) | |
2339 { | |
2340 gdouble proof_w, proof_h; | |
2341 gint finished; | |
2342 | |
2343 pw->proof_position = 0; | |
2344 | |
2345 switch (pw->source) | |
2346 { | |
2347 case PRINT_SOURCE_SELECTION: | |
2348 pw->proof_point = pw->source_selection; | |
2349 break; | |
2350 case PRINT_SOURCE_ALL: | |
2351 pw->proof_point = pw->source_list; | |
2352 break; | |
2353 case PRINT_SOURCE_IMAGE: | |
2354 default: | |
2355 pw->proof_point = NULL; | |
2356 break; | |
2357 } | |
2358 | |
2359 print_proof_size(pw, &proof_w, &proof_h); | |
2360 pw->proof_columns = (pw->layout_width - pw->margin_left - pw->margin_right) / proof_w; | |
2361 pw->proof_rows = (pw->layout_height - pw->margin_top - pw->margin_bottom) / proof_h; | |
2362 | |
2363 if (pw->job_format == RENDER_FORMAT_PREVIEW) | |
2364 { | |
2365 gint total; | |
2366 | |
2367 total = print_layout_page_count(pw); | |
2368 if (pw->job_page < 0 || pw->job_page >= total) | |
2369 { | |
2370 print_job_done(pw); | |
2371 return; | |
2372 } | |
2373 | |
2374 if (pw->proof_point && pw->job_page > 0) | |
2375 { | |
2376 pw->proof_point = g_list_nth(pw->proof_point, pw->job_page * pw->proof_columns * pw->proof_rows); | |
2377 } | |
2378 } | |
2379 | |
2380 if (!print_job_page_new(pw)) | |
2381 { | |
2382 print_job_close(pw, TRUE); | |
2383 return; | |
2384 } | |
2385 | |
2386 if (pw->layout == PRINT_LAYOUT_IMAGE) | |
2387 { | |
2388 finished = !print_job_render_image(pw); | |
2389 } | |
2390 else | |
2391 { | |
2392 finished = !print_job_render_proof(pw); | |
2393 } | |
2394 | |
2395 if (finished) print_job_done(pw); | |
2396 } | |
2397 | |
2398 static gint print_job_init(PrintWindow *pw) | |
2399 { | |
2400 gint success = FALSE; | |
2401 | |
2402 pw->job_page = 0; | |
2403 | |
2404 switch (pw->job_format) | |
2405 { | |
2406 case RENDER_FORMAT_RGB: | |
2407 success = print_job_rgb_init(pw); | |
2408 break; | |
2409 case RENDER_FORMAT_PS: | |
2410 success = print_job_ps_init(pw); | |
2411 break; | |
2412 case RENDER_FORMAT_PREVIEW: | |
2413 pw->job_page = pw->proof_page; | |
2414 success = print_job_preview_init(pw); | |
2415 break; | |
2416 } | |
2417 | |
2418 return success; | |
2419 } | |
2420 | |
2421 static gint print_job_finish(PrintWindow *pw) | |
2422 { | |
2423 gint success = FALSE; | |
2424 | |
2425 switch (pw->job_format) | |
2426 { | |
2427 case RENDER_FORMAT_RGB: | |
2428 success = TRUE; | |
2429 break; | |
2430 case RENDER_FORMAT_PS: | |
2431 print_job_ps_end(pw); | |
2432 break; | |
2433 case RENDER_FORMAT_PREVIEW: | |
2434 success = TRUE; | |
2435 break; | |
2436 } | |
2437 | |
2438 return success; | |
2439 } | |
2440 | |
2441 static void print_job_close_file(PrintWindow *pw) | |
2442 { | |
2443 if (pw->job_file) | |
2444 { | |
2445 fclose(pw->job_file); | |
2446 pw->job_file = NULL; | |
2447 } | |
2448 | |
2449 if (pw->job_pipe) | |
2450 { | |
2451 PipeError *pe; | |
2452 | |
2453 pe = pipe_handler_new(); | |
2454 pclose(pw->job_pipe); | |
2455 pipe_handler_free(pe); | |
2456 | |
2457 pw->job_pipe = NULL; | |
2458 } | |
2459 } | |
2460 | |
2461 static gboolean print_job_close_finish_cb(gpointer data) | |
2462 { | |
2463 PrintWindow *pw = data; | |
2464 | |
2465 print_window_close(pw); | |
2466 return FALSE; | |
2467 } | |
2468 | |
2469 static void print_job_close(PrintWindow *pw, gint error) | |
2470 { | |
2471 if (!error) print_job_finish(pw); | |
2472 | |
2473 print_job_close_file(pw); | |
2474 g_free(pw->job_path); | |
2475 pw->job_path = NULL; | |
2476 | |
2477 if (pw->job_dialog) | |
2478 { | |
2479 generic_dialog_close(pw->job_dialog); | |
2480 pw->job_dialog = NULL; | |
2481 pw->job_progress = NULL; | |
2482 } | |
2483 | |
2484 image_loader_free(pw->job_loader); | |
2485 pw->job_loader = NULL; | |
2486 | |
2487 if (pw->job_pixbuf) | |
2488 { | |
2489 g_object_unref(pw->job_pixbuf); | |
2490 pw->job_pixbuf = NULL; | |
2491 } | |
2492 | |
2493 if (pw->dialog && !GTK_WIDGET_VISIBLE(pw->dialog->dialog)) | |
2494 { | |
2495 g_idle_add_full(G_PRIORITY_HIGH_IDLE, print_job_close_finish_cb, pw, NULL); | |
2496 } | |
2497 } | |
2498 | |
2499 static void print_job_cancel_cb(GenericDialog *gd, gpointer data) | |
2500 { | |
2501 PrintWindow *pw = data; | |
2502 | |
2503 print_job_close(pw, FALSE); | |
2504 } | |
2505 | |
2506 static void print_pref_store(PrintWindow *pw) | |
2507 { | |
2508 | |
2509 pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_SAVE, pw->save_settings); | |
2510 | |
2511 if (!pw->save_settings) return; | |
2512 | |
2513 /* only store values that are actually used in this print job, hence the if()s */ | |
2514 | |
2515 pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_OUTPUT, pw->output); | |
2516 | |
2517 if (pw->output == PRINT_OUTPUT_RGB_FILE) | |
2518 { | |
2519 pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_FORMAT, pw->output_format); | |
2520 } | |
2521 | |
2522 if (pw->job_format == RENDER_FORMAT_PS) | |
2523 { | |
2524 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_DPI, pw->max_dpi); | |
2525 } | |
2526 | |
2527 pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_UNITS, pw->paper_units); | |
2528 pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_SIZE, pw->paper_size); | |
2529 pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_ORIENTATION, pw->paper_orientation); | |
2530 | |
2531 if (pw->paper_size == 0) | |
2532 { | |
2533 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_CUSTOM_WIDTH, pw->paper_width); | |
2534 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_CUSTOM_HEIGHT, pw->paper_height); | |
2535 } | |
2536 | |
2537 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_LEFT, pw->margin_left); | |
2538 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_RIGHT, pw->margin_right); | |
2539 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_TOP, pw->margin_top); | |
2540 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_BOTTOM, pw->margin_bottom); | |
2541 | |
2542 if (pw->layout == PRINT_LAYOUT_PROOF) | |
2543 { | |
2544 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_PROOF_WIDTH, pw->proof_width); | |
2545 pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_PROOF_HEIGHT, pw->proof_height); | |
2546 } | |
2547 | |
2548 if (pw->output == PRINT_OUTPUT_PS_CUSTOM) | |
2549 { | |
2550 pref_list_string_set(PRINT_PREF_GROUP, PRINT_PREF_PRINTERC, pw->output_custom); | |
2551 } | |
2552 | |
2553 if (pw->output == PRINT_OUTPUT_RGB_FILE || | |
2554 pw->output == PRINT_OUTPUT_PS_FILE) | |
2555 { | |
2556 tab_completion_append_to_history(pw->path_entry, pw->output_path); | |
2557 } | |
2558 } | |
2559 | |
2560 static gint print_job_start(PrintWindow *pw, RenderFormat format, PrintOutput output) | |
2561 { | |
2562 GtkWidget *hbox; | |
2563 GtkWidget *spinner; | |
2564 gchar *msg; | |
2565 | |
2566 if (pw->job_dialog) return FALSE; | |
2567 | |
2568 pw->job_format = format; | |
2569 pw->job_output = output; | |
2570 | |
2571 if (!print_job_init(pw)) | |
2572 { | |
2573 print_job_close(pw, TRUE); | |
2574 return FALSE; | |
2575 } | |
2576 | |
2577 if (format == RENDER_FORMAT_PREVIEW) | |
2578 { | |
2579 print_job_render(pw); | |
2580 return TRUE; | |
2581 } | |
2582 | |
2583 print_pref_store(pw); | |
2584 | |
2585 gtk_widget_hide(pw->dialog->dialog); | |
2586 | |
2587 pw->job_dialog = file_util_gen_dlg(_("Print - GQview"), "gqview", "print_job_dialog", | |
2588 (GtkWidget *)gtk_window_get_transient_for(GTK_WINDOW(pw->dialog->dialog)), FALSE, | |
2589 print_job_cancel_cb, pw); | |
2590 | |
2591 msg = g_strdup_printf(_("Printing %d pages to %s."), print_layout_page_count(pw), print_output_name(pw->output)); | |
2592 generic_dialog_add_message(pw->job_dialog, NULL, msg, NULL); | |
2593 g_free(msg); | |
2594 | |
2595 if (pw->job_output == PRINT_OUTPUT_PS_FILE || | |
2596 pw->job_output == PRINT_OUTPUT_RGB_FILE) | |
2597 { | |
2598 hbox = pref_box_new(pw->job_dialog->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); | |
2599 pref_label_new(hbox, _("Filename:")); | |
2600 | |
2601 pw->job_progress_label = pref_label_new(hbox, ""); | |
2602 } | |
2603 else | |
2604 { | |
2605 pw->job_progress_label = NULL; | |
2606 } | |
2607 | |
2608 pref_spacer(pw->job_dialog->vbox, PREF_PAD_SPACE); | |
2609 | |
2610 hbox = pref_box_new(pw->job_dialog->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); | |
2611 | |
2612 pw->job_progress = gtk_progress_bar_new(); | |
2613 gtk_box_pack_start(GTK_BOX(hbox), pw->job_progress, TRUE, TRUE, 0); | |
2614 gtk_widget_show(pw->job_progress); | |
2615 | |
2616 spinner = spinner_new(NULL, SPINNER_SPEED); | |
2617 gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); | |
2618 gtk_widget_show(spinner); | |
2619 | |
2620 gtk_widget_show(pw->job_dialog->dialog); | |
2621 | |
2622 print_job_render(pw); | |
2623 print_job_status(pw); | |
2624 | |
2625 return TRUE; | |
2626 } | |
2627 | |
2628 static void print_window_print_start(PrintWindow *pw) | |
2629 { | |
2630 RenderFormat format; | |
2631 | |
2632 switch(pw->output) | |
2633 { | |
2634 case PRINT_OUTPUT_RGB_FILE: | |
2635 format = RENDER_FORMAT_RGB; | |
2636 break; | |
2637 case PRINT_OUTPUT_PS_FILE: | |
2638 case PRINT_OUTPUT_PS_CUSTOM: | |
2639 case PRINT_OUTPUT_PS_LPR: | |
2640 default: | |
2641 format = RENDER_FORMAT_PS; | |
2642 break; | |
2643 } | |
2644 | |
2645 print_job_start(pw, format, pw->output); | |
2646 } | |
2647 | |
2648 | |
2649 /* | |
2650 *----------------------------------------------------------------------------- | |
2651 * combo box util | |
2652 *----------------------------------------------------------------------------- | |
2653 */ | |
2654 | |
2655 static GtkWidget *print_combo_menu(const gchar *text[], gint count, gint preferred, | |
2656 GCallback func, gpointer data) | |
2657 { | |
2658 GtkWidget *combo; | |
2659 gint i; | |
2660 | |
2661 combo = gtk_combo_box_new_text(); | |
2662 | |
2663 for (i = 0 ; i < count; i++) | |
2664 { | |
2665 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _(text[i])); | |
2666 } | |
2667 | |
2668 if (preferred >= 0 && preferred < count) | |
2669 { | |
2670 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), preferred); | |
2671 } | |
2672 | |
2673 if (func) g_signal_connect(G_OBJECT(combo), "changed", func, data); | |
2674 | |
2675 return combo; | |
2676 } | |
2677 | |
2678 | |
2679 /* | |
2680 *----------------------------------------------------------------------------- | |
2681 * paper selection | |
2682 *----------------------------------------------------------------------------- | |
2683 */ | |
2684 | |
2685 static GtkWidget *print_paper_menu(GtkWidget *table, gint column, gint row, | |
2686 gint preferred, GCallback func, gpointer data) | |
2687 { | |
2688 GtkWidget *combo; | |
2689 gint i; | |
2690 | |
2691 pref_table_label(table, column, row, (_("Format:")), 1.0); | |
2692 | |
2693 combo = gtk_combo_box_new_text(); | |
2694 | |
2695 i = 0; | |
2696 while (print_paper_sizes[i].description) | |
2697 { | |
2698 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), _(print_paper_sizes[i].description)); | |
2699 i++; | |
2700 } | |
2701 | |
2702 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), preferred); | |
2703 if (func) g_signal_connect(G_OBJECT(combo), "changed", func, data); | |
2704 | |
2705 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, | |
2706 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
2707 gtk_widget_show(combo); | |
2708 | |
2709 return combo; | |
2710 } | |
2711 | |
2712 static void print_paper_select_cb(GtkWidget *combo, gpointer data) | |
2713 { | |
2714 PrintWindow *pw = data; | |
2715 PaperSize *ps; | |
2716 gint n; | |
2717 | |
2718 n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); | |
2719 ps = print_paper_size_nth(n); | |
2720 | |
2721 if (!ps) return; | |
2722 | |
2723 pw->paper_size = n; | |
2724 | |
2725 if (pw->paper_size == 0) | |
2726 { | |
2727 print_window_layout_sync_paper(pw); | |
2728 return; | |
2729 } | |
2730 | |
2731 if (ps->orientation == PAPER_ORIENTATION_PORTRAIT) | |
2732 { | |
2733 print_window_layout_set_size(pw, ps->width, ps->height); | |
2734 } | |
2735 else | |
2736 { | |
2737 print_window_layout_set_size(pw, ps->height, ps->width); | |
2738 } | |
2739 } | |
2740 | |
2741 static void print_paper_size_cb(GtkWidget *spin, gpointer data) | |
2742 { | |
2743 PrintWindow *pw = data; | |
2744 gdouble value; | |
2745 | |
2746 value = print_paper_size_convert_units(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)), | |
2747 pw->paper_units, PAPER_UNIT_POINTS); | |
2748 | |
2749 if (spin == pw->paper_width_spin) | |
2750 { | |
2751 pw->paper_width = value; | |
2752 } | |
2753 else | |
2754 { | |
2755 pw->paper_height = value; | |
2756 } | |
2757 | |
2758 print_window_layout_set_size(pw, pw->paper_width, pw->paper_height); | |
2759 } | |
2760 | |
2761 static GtkWidget *print_paper_units_menu(GtkWidget *table, gint column, gint row, | |
2762 PaperUnits units, GCallback func, gpointer data) | |
2763 { | |
2764 GtkWidget *combo; | |
2765 | |
2766 pref_table_label(table, column, row, (_("Units:")), 1.0); | |
2767 | |
2768 combo = print_combo_menu(print_paper_units, PAPER_UNIT_COUNT, units, func, data); | |
2769 | |
2770 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, | |
2771 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
2772 gtk_widget_show(combo); | |
2773 | |
2774 return combo; | |
2775 } | |
2776 | |
2777 static void print_paper_units_set(PrintWindow *pw, PaperUnits units) | |
2778 { | |
2779 PaperUnits old_units; | |
2780 | |
2781 if (units < 0 || units >= PAPER_UNIT_COUNT) return; | |
2782 | |
2783 old_units = pw->paper_units; | |
2784 pw->paper_units = units; | |
2785 print_window_layout_sync_paper(pw); | |
2786 | |
2787 if ((units == PAPER_UNIT_MM || units == PAPER_UNIT_CM) != | |
2788 (old_units == PAPER_UNIT_MM || old_units == PAPER_UNIT_CM)) | |
2789 { | |
2790 print_window_layout_render(pw); | |
2791 } | |
2792 } | |
2793 | |
2794 static void print_paper_units_cb(GtkWidget *combo, gpointer data) | |
2795 { | |
2796 PrintWindow *pw = data; | |
2797 PaperUnits units; | |
2798 | |
2799 units = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); | |
2800 | |
2801 print_paper_units_set(pw, units); | |
2802 } | |
2803 | |
2804 static GtkWidget *print_paper_orientation_menu(GtkWidget *table, gint column, gint row, | |
2805 PaperOrientation preferred, | |
2806 GCallback func, gpointer data) | |
2807 { | |
2808 GtkWidget *combo; | |
2809 | |
2810 pref_table_label(table, column, row, (_("Orientation:")), 1.0); | |
2811 | |
2812 combo = print_combo_menu(print_paper_orientation, PAPER_ORIENTATION_COUNT, preferred, func, data); | |
2813 | |
2814 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, | |
2815 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
2816 gtk_widget_show(combo); | |
2817 | |
2818 return combo; | |
2819 } | |
2820 | |
2821 static void print_paper_orientation_cb(GtkWidget *combo, gpointer data) | |
2822 { | |
2823 PrintWindow *pw = data; | |
2824 PaperOrientation o; | |
2825 | |
2826 o = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); | |
2827 | |
2828 print_window_layout_set_orientation(pw, o); | |
2829 } | |
2830 | |
2831 static void print_paper_margin_cb(GtkWidget *spin, gpointer data) | |
2832 { | |
2833 PrintWindow *pw = data; | |
2834 gdouble value; | |
2835 | |
2836 value = print_paper_size_convert_units(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)), | |
2837 pw->paper_units, PAPER_UNIT_POINTS); | |
2838 | |
2839 if (spin == pw->margin_left_spin) | |
2840 { | |
2841 pw->margin_left = CLAMP(value, 0.0, pw->paper_width); | |
2842 } | |
2843 else if (spin == pw->margin_right_spin) | |
2844 { | |
2845 pw->margin_right = CLAMP(value, 0.0, pw->paper_width); | |
2846 } | |
2847 else if (spin == pw->margin_top_spin) | |
2848 { | |
2849 pw->margin_top = CLAMP(value, 0.0, pw->paper_height); | |
2850 } | |
2851 else if (spin == pw->margin_bottom_spin) | |
2852 { | |
2853 pw->margin_bottom = CLAMP(value, 0.0, pw->paper_height); | |
2854 } | |
2855 | |
2856 print_window_layout_set_size(pw, pw->paper_width, pw->paper_height); | |
2857 } | |
2858 | |
2859 static GtkWidget *print_misc_menu(GtkWidget *parent_box, gint preferred, | |
2860 const gchar *title, const gchar *key, | |
2861 gint count, const gchar **text, | |
2862 GCallback func, gpointer data) | |
2863 { | |
2864 GtkWidget *box; | |
2865 GtkWidget *button = NULL; | |
2866 gint i; | |
2867 | |
2868 box = pref_group_new(parent_box, FALSE, title, GTK_ORIENTATION_VERTICAL); | |
2869 | |
2870 for (i = 0; i < count; i++) | |
2871 { | |
2872 button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _(text[i])); | |
2873 if (i == preferred) | |
2874 { | |
2875 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | |
2876 } | |
2877 g_object_set_data(G_OBJECT(button), key, GINT_TO_POINTER(i)); | |
2878 if (func) g_signal_connect(G_OBJECT(button), "clicked", func, data); | |
2879 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); | |
2880 gtk_widget_show(button); | |
2881 } | |
2882 | |
2883 return box; | |
2884 } | |
2885 | |
2886 static void print_source_select_cb(GtkWidget *widget, gpointer data) | |
2887 { | |
2888 PrintWindow *pw = data; | |
2889 | |
2890 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return; | |
2891 | |
2892 pw->source = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "print_source")); | |
2893 print_window_layout_size(pw); | |
2894 } | |
2895 | |
2896 static void print_layout_select_cb(GtkWidget *widget, gpointer data) | |
2897 { | |
2898 PrintWindow *pw = data; | |
2899 | |
2900 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return; | |
2901 | |
2902 pw->layout = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "print_layout")); | |
2903 | |
2904 print_window_layout_sync_layout(pw); | |
2905 print_window_layout_size(pw); | |
2906 } | |
2907 | |
2908 static void print_image_scale_cb(GtkWidget *spin, gpointer data) | |
2909 { | |
2910 PrintWindow *pw = data; | |
2911 | |
2912 pw->image_scale = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)); | |
2913 | |
2914 print_window_layout_set_size(pw, pw->paper_width, pw->paper_height); | |
2915 } | |
2916 | |
2917 static void print_proof_size_cb(GtkWidget *spin, gpointer data) | |
2918 { | |
2919 PrintWindow *pw = data; | |
2920 gdouble value; | |
2921 | |
2922 value = print_paper_size_convert_units(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)), | |
2923 pw->paper_units, PAPER_UNIT_POINTS); | |
2924 | |
2925 if (spin == pw->proof_width_spin) | |
2926 { | |
2927 pw->proof_width = value; | |
2928 } | |
2929 else | |
2930 { | |
2931 pw->proof_height = value; | |
2932 } | |
2933 | |
2934 print_window_layout_render(pw); | |
2935 } | |
2936 | |
2937 static GtkWidget *print_output_menu(GtkWidget *table, gint column, gint row, | |
2938 PrintOutput preferred, GCallback func, gpointer data) | |
2939 { | |
2940 GtkWidget *combo; | |
2941 | |
2942 pref_table_label(table, column, row, (_("Destination:")), 1.0); | |
2943 | |
2944 combo = print_combo_menu(print_output_text, PRINT_OUTPUT_COUNT, preferred, func, data); | |
2945 | |
2946 gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, | |
2947 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
2948 gtk_widget_show(combo); | |
2949 | |
2950 return combo; | |
2951 } | |
2952 | |
2953 static void print_custom_entry_set(PrintWindow *pw, GtkWidget *combo) | |
2954 { | |
2955 GtkListStore *store; | |
2956 const gchar *text; | |
2957 GList *list; | |
2958 GList *work; | |
2959 | |
2960 store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))); | |
2961 gtk_list_store_clear(store); | |
2962 | |
2963 list = print_window_list_printers(); | |
2964 work = list; | |
2965 while (work) | |
2966 { | |
2967 gchar *name; | |
2968 gchar *buf; | |
2969 | |
2970 name = work->data; | |
2971 work = work->next; | |
2972 | |
2973 buf = g_strdup_printf(PRINT_LPR_CUSTOM, name); | |
2974 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), buf); | |
2975 g_free(buf); | |
2976 } | |
2977 path_list_free(list); | |
2978 | |
2979 if (pref_list_string_get(PRINT_PREF_GROUP, PRINT_PREF_PRINTERC, &text)) | |
2980 { | |
2981 gtk_entry_set_text(GTK_ENTRY(pw->custom_entry), text); | |
2982 } | |
2983 else | |
2984 { | |
2985 text = gtk_entry_get_text(GTK_ENTRY(pw->custom_entry)); | |
2986 if (!text || strlen(text) == 0) | |
2987 { | |
2988 gchar *buf; | |
2989 | |
2990 buf = g_strdup_printf(PRINT_LPR_CUSTOM, _("<printer name>")); | |
2991 gtk_entry_set_text(GTK_ENTRY(pw->custom_entry), buf); | |
2992 g_free(buf); | |
2993 } | |
2994 } | |
2995 } | |
2996 | |
2997 static void print_output_set(PrintWindow *pw, PrintOutput output) | |
2998 { | |
2999 gint use_file = FALSE; | |
3000 gint use_custom = FALSE; | |
3001 gint use_format = FALSE; | |
3002 | |
3003 pw->output = output; | |
3004 | |
3005 switch (pw->output) | |
3006 { | |
3007 case PRINT_OUTPUT_RGB_FILE: | |
3008 use_file = TRUE; | |
3009 use_format = TRUE; | |
3010 break; | |
3011 case PRINT_OUTPUT_PS_FILE: | |
3012 use_file = TRUE; | |
3013 break; | |
3014 case PRINT_OUTPUT_PS_CUSTOM: | |
3015 use_custom = TRUE; | |
3016 break; | |
3017 case PRINT_OUTPUT_PS_LPR: | |
3018 default: | |
3019 break; | |
3020 } | |
3021 | |
3022 gtk_widget_set_sensitive(gtk_widget_get_parent(pw->path_entry), use_file); | |
3023 gtk_widget_set_sensitive(gtk_widget_get_parent(pw->custom_entry), use_custom); | |
3024 gtk_widget_set_sensitive(pw->path_format_menu, use_format); | |
3025 gtk_widget_set_sensitive(pw->max_dpi_menu, !use_format); | |
3026 } | |
3027 | |
3028 static void print_output_cb(GtkWidget *combo, gpointer data) | |
3029 { | |
3030 PrintWindow *pw = data; | |
3031 PrintOutput output; | |
3032 | |
3033 output = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); | |
3034 | |
3035 print_output_set(pw, output); | |
3036 } | |
3037 | |
3038 static GtkWidget *print_output_format_menu(GtkWidget * table, gint column, gint row, | |
3039 PrintFileFormat preferred, GCallback func, gpointer data) | |
3040 { | |
3041 GtkWidget *combo; | |
3042 | |
3043 combo = print_combo_menu(print_file_format_text, PRINT_FILE_COUNT, preferred, func, data); | |
3044 | |
3045 gtk_table_attach(GTK_TABLE(table), combo, column, column + 1, row, row + 1, | |
3046 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
3047 gtk_widget_show(combo); | |
3048 | |
3049 return combo; | |
3050 } | |
3051 | |
3052 static void print_output_format_cb(GtkWidget *combo, gpointer data) | |
3053 { | |
3054 PrintWindow *pw = data; | |
3055 | |
3056 pw->output_format = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); | |
3057 } | |
3058 | |
3059 static GtkWidget *print_output_dpi_menu(GtkWidget * table, gint column, gint row, | |
3060 gdouble dpi, GCallback func, gpointer data) | |
3061 { | |
3062 static gint dpilist[] = { 150, 300, 600, 1200, 0, -1}; | |
3063 GtkWidget *combo; | |
3064 GtkListStore *store; | |
3065 GtkCellRenderer *renderer; | |
3066 gint current = 1; | |
3067 gint i; | |
3068 | |
3069 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); | |
3070 | |
3071 i = 0; | |
3072 while (dpilist[i] != -1) | |
3073 { | |
3074 GtkTreeIter iter; | |
3075 gchar *text; | |
3076 | |
3077 if (dpilist[i] == 0) | |
3078 { | |
3079 text = g_strdup(_("Unlimited")); | |
3080 } | |
3081 else | |
3082 { | |
3083 text = g_strdup_printf("%d", dpilist[i]); | |
3084 } | |
3085 | |
3086 gtk_list_store_append(store, &iter); | |
3087 gtk_list_store_set(store, &iter, 0, text, 1, dpilist[i], -1); | |
3088 g_free(text); | |
3089 | |
3090 if (dpi == (gdouble)dpilist[i]) current = i; | |
3091 | |
3092 i++; | |
3093 } | |
3094 | |
3095 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); | |
3096 g_object_unref(store); | |
3097 | |
3098 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current); | |
3099 if (func) g_signal_connect(G_OBJECT(combo), "changed", func, data); | |
3100 | |
3101 renderer = gtk_cell_renderer_text_new(); | |
3102 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE); | |
3103 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", 0, NULL); | |
3104 | |
3105 gtk_table_attach(GTK_TABLE(table), combo, column, column + 1, row, row + 1, | |
3106 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
3107 gtk_widget_show(combo); | |
3108 | |
3109 return combo; | |
3110 } | |
3111 | |
3112 static void print_output_dpi_cb(GtkWidget *combo, gpointer data) | |
3113 { | |
3114 PrintWindow *pw = data; | |
3115 GtkTreeModel *store; | |
3116 GtkTreeIter iter; | |
3117 gint n = -1; | |
3118 | |
3119 store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); | |
3120 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) return; | |
3121 gtk_tree_model_get(store, &iter, 1, &n, -1); | |
3122 | |
3123 pw->max_dpi = (gdouble)n; | |
3124 } | |
3125 | |
3126 static void print_text_field_set(PrintWindow *pw, TextInfo field, gint active) | |
3127 { | |
3128 if (active) | |
3129 { | |
3130 pw->text_fields |= field; | |
3131 } | |
3132 else | |
3133 { | |
3134 pw->text_fields &= ~field; | |
3135 } | |
3136 | |
3137 print_window_layout_render(pw); | |
3138 } | |
3139 | |
3140 static void print_text_cb_name(GtkWidget *widget, gpointer data) | |
3141 { | |
3142 PrintWindow *pw = data; | |
3143 gint active; | |
3144 | |
3145 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
3146 print_text_field_set(pw, TEXT_INFO_FILENAME, active); | |
3147 } | |
3148 | |
3149 static void print_text_cb_date(GtkWidget *widget, gpointer data) | |
3150 { | |
3151 PrintWindow *pw = data; | |
3152 gint active; | |
3153 | |
3154 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
3155 print_text_field_set(pw, TEXT_INFO_FILEDATE, active); | |
3156 } | |
3157 | |
3158 static void print_text_cb_size(GtkWidget *widget, gpointer data) | |
3159 { | |
3160 PrintWindow *pw = data; | |
3161 gint active; | |
3162 | |
3163 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
3164 print_text_field_set(pw, TEXT_INFO_FILESIZE, active); | |
3165 } | |
3166 | |
3167 static void print_text_cb_dims(GtkWidget *widget, gpointer data) | |
3168 { | |
3169 PrintWindow *pw = data; | |
3170 gint active; | |
3171 | |
3172 active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
3173 print_text_field_set(pw, TEXT_INFO_DIMENSIONS, active); | |
3174 } | |
3175 | |
3176 static void print_text_cb_points(GtkWidget *widget, gpointer data) | |
3177 { | |
3178 PrintWindow *pw = data; | |
3179 | |
3180 pw->text_points = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); | |
3181 print_window_layout_render(pw); | |
3182 } | |
3183 | |
3184 static void print_text_menu(GtkWidget *box, PrintWindow *pw) | |
3185 { | |
3186 GtkWidget *group; | |
3187 | |
3188 group = pref_group_new(box, FALSE, _("Show"), GTK_ORIENTATION_VERTICAL); | |
3189 | |
3190 pref_checkbox_new(group, _("Name"), (pw->text_fields & TEXT_INFO_FILENAME), | |
3191 G_CALLBACK(print_text_cb_name), pw); | |
3192 pref_checkbox_new(group, _("Date"), (pw->text_fields & TEXT_INFO_FILEDATE), | |
3193 G_CALLBACK(print_text_cb_date), pw); | |
3194 pref_checkbox_new(group, _("Size"), (pw->text_fields & TEXT_INFO_FILESIZE), | |
3195 G_CALLBACK(print_text_cb_size), pw); | |
3196 pref_checkbox_new(group, _("Dimensions"), (pw->text_fields & TEXT_INFO_DIMENSIONS), | |
3197 G_CALLBACK(print_text_cb_dims), pw); | |
3198 | |
3199 group = pref_group_new(box, FALSE, _("Font"), GTK_ORIENTATION_VERTICAL); | |
3200 | |
3201 pref_spin_new(group, _("Size:"), _("points"), | |
3202 8.0, 100.0, 1.0, 0, pw->text_points, | |
3203 G_CALLBACK(print_text_cb_points), pw); | |
3204 | |
3205 #if 0 | |
3206 button = color_selection_new(); | |
3207 gtk_box_pack_start(GTK_BOX(group), button, FALSE, FALSE, 0); | |
3208 gtk_widget_show(button); | |
3209 #endif | |
3210 } | |
3211 | |
3212 /* | |
3213 *----------------------------------------------------------------------------- | |
3214 * print window | |
3215 *----------------------------------------------------------------------------- | |
3216 */ | |
3217 | |
3218 static void print_window_close(PrintWindow *pw) | |
3219 { | |
3220 print_window_layout_render_stop(pw); | |
3221 | |
3222 generic_dialog_close(pw->dialog); | |
3223 pw->dialog = NULL; | |
3224 | |
3225 print_job_close(pw, FALSE); | |
3226 | |
3227 g_free(pw->source_path); | |
3228 path_list_free(pw->source_selection); | |
3229 path_list_free(pw->source_list); | |
3230 | |
3231 g_free(pw->output_path); | |
3232 g_free(pw->output_custom); | |
3233 | |
3234 g_free(pw); | |
3235 } | |
3236 | |
3237 static void print_window_print_cb(GenericDialog *gd, gpointer data) | |
3238 { | |
3239 PrintWindow *pw = data; | |
3240 | |
3241 switch (pw->output) | |
3242 { | |
3243 case PRINT_OUTPUT_RGB_FILE: | |
3244 case PRINT_OUTPUT_PS_FILE: | |
3245 g_free(pw->output_path); | |
3246 pw->output_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->path_entry))); | |
3247 break; | |
3248 case PRINT_OUTPUT_PS_CUSTOM: | |
3249 g_free(pw->output_custom); | |
3250 pw->output_custom = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->custom_entry))); | |
3251 break; | |
3252 case PRINT_OUTPUT_PS_LPR: | |
3253 default: | |
3254 break; | |
3255 } | |
3256 | |
3257 print_window_print_start(pw); | |
3258 } | |
3259 | |
3260 static void print_window_cancel_cb(GenericDialog *gd, gpointer data) | |
3261 { | |
3262 PrintWindow *pw = data; | |
3263 | |
3264 print_window_close(pw); | |
3265 } | |
3266 | |
3267 static gint print_pref_int(const gchar *key, gint fallback) | |
3268 { | |
3269 gint value; | |
3270 | |
3271 if (pref_list_int_get(PRINT_PREF_GROUP, key, &value)) return value; | |
3272 return fallback; | |
3273 } | |
3274 | |
3275 static gdouble print_pref_double(const gchar *key, gdouble fallback) | |
3276 { | |
3277 gdouble value; | |
3278 | |
3279 if (pref_list_double_get(PRINT_PREF_GROUP, key, &value)) return value; | |
3280 return fallback; | |
3281 } | |
3282 | |
3283 void print_window_new(const gchar *path, GList *selection, GList *list, GtkWidget *parent) | |
3284 { | |
3285 PrintWindow *pw; | |
3286 GdkGeometry geometry; | |
3287 GtkWidget *main_box; | |
3288 GtkWidget *vbox; | |
3289 GtkWidget *label; | |
3290 GtkWidget *combo; | |
3291 GtkWidget *box; | |
3292 GtkWidget *table; | |
3293 | |
3294 pw = g_new0(PrintWindow, 1); | |
3295 | |
3296 pw->source_path = g_strdup(path); | |
3297 pw->source_selection = selection; | |
3298 pw->source_list = list; | |
3299 | |
3300 pw->source = PRINT_SOURCE_SELECTION; | |
3301 pw->layout = PRINT_LAYOUT_IMAGE; | |
3302 | |
3303 pw->output = print_pref_int(PRINT_PREF_OUTPUT, PRINT_OUTPUT_PS_LPR); | |
3304 pw->output_format = print_pref_int(PRINT_PREF_FORMAT, PRINT_FILE_JPG_NORMAL); | |
3305 | |
3306 pw->max_dpi = print_pref_double(PRINT_PREF_DPI, PRINT_PS_DPI_DEFAULT); | |
3307 | |
3308 pw->paper_units = print_pref_int(PRINT_PREF_UNITS, paper_unit_default()); | |
3309 pw->paper_size = print_pref_int(PRINT_PREF_SIZE, 1); | |
3310 if (pw->paper_size == 0 || | |
3311 !print_paper_size_lookup(pw->paper_size, &pw->paper_width, &pw->paper_height)) | |
3312 { | |
3313 pw->paper_width = print_pref_double(PRINT_PREF_CUSTOM_WIDTH, 360.0); | |
3314 pw->paper_height = print_pref_double(PRINT_PREF_CUSTOM_HEIGHT, 720.0); | |
3315 } | |
3316 pw->paper_orientation = print_pref_int(PRINT_PREF_ORIENTATION, PAPER_ORIENTATION_PORTRAIT); | |
3317 | |
3318 pw->margin_left = print_pref_double(PRINT_PREF_MARGIN_LEFT, PRINT_MARGIN_DEFAULT); | |
3319 pw->margin_right = print_pref_double(PRINT_PREF_MARGIN_RIGHT, PRINT_MARGIN_DEFAULT); | |
3320 pw->margin_top = print_pref_double(PRINT_PREF_MARGIN_TOP, PRINT_MARGIN_DEFAULT); | |
3321 pw->margin_bottom = print_pref_double(PRINT_PREF_MARGIN_BOTTOM, PRINT_MARGIN_DEFAULT); | |
3322 | |
3323 pw->proof_width = print_pref_double(PRINT_PREF_PROOF_WIDTH, PRINT_PROOF_DEFAULT_SIZE); | |
3324 pw->proof_height = print_pref_double(PRINT_PREF_PROOF_HEIGHT, PRINT_PROOF_DEFAULT_SIZE); | |
3325 | |
3326 pw->text_fields = TEXT_INFO_FILENAME; | |
3327 pw->text_points = 10; | |
3328 pw->text_r = pw->text_g = pw->text_b = 0; | |
3329 | |
3330 pw->save_settings = print_pref_int(PRINT_PREF_SAVE, TRUE); | |
3331 | |
3332 pw->dialog = file_util_gen_dlg(_("Print - GQview"), "gqview", "print_dialog", | |
3333 parent, FALSE, | |
3334 print_window_cancel_cb, pw); | |
3335 | |
3336 geometry.min_width = 32; | |
3337 geometry.min_height = 32; | |
3338 geometry.base_width = PRINT_DLG_WIDTH; | |
3339 geometry.base_height = PRINT_DLG_HEIGHT; | |
3340 gtk_window_set_geometry_hints(GTK_WINDOW(pw->dialog->dialog), NULL, &geometry, | |
3341 GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); | |
3342 | |
3343 pw->print_button = generic_dialog_add_button(pw->dialog, GTK_STOCK_PRINT, NULL, print_window_print_cb, TRUE); | |
3344 | |
3345 main_box = pref_box_new(pw->dialog->vbox, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); | |
3346 | |
3347 pw->notebook = gtk_notebook_new(); | |
3348 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(pw->notebook), GTK_POS_TOP); | |
3349 gtk_box_pack_start(GTK_BOX(main_box), pw->notebook, FALSE, FALSE, 0); | |
3350 | |
3351 /* layout tab */ | |
3352 | |
3353 vbox = gtk_vbox_new(FALSE, 0); | |
3354 gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); | |
3355 gtk_widget_show(vbox); | |
3356 label = gtk_label_new(_("Layout")); | |
3357 gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); | |
3358 | |
3359 print_misc_menu(vbox, pw->source, _("Source"), "print_source", | |
3360 PRINT_SOURCE_COUNT, print_source_text, | |
3361 G_CALLBACK(print_source_select_cb), pw); | |
3362 | |
3363 box = print_misc_menu(vbox, pw->layout, _("Layout"), "print_layout", | |
3364 PRINT_LAYOUT_COUNT, print_layout_text, | |
3365 G_CALLBACK(print_layout_select_cb), pw); | |
3366 | |
3367 pref_spacer(box, PREF_PAD_GROUP); | |
3368 | |
3369 table = pref_table_new(box, 2, 2, FALSE, FALSE); | |
3370 | |
3371 pw->image_scale_spin = pref_table_spin(table, 0, 0, _("Image size:"), "%", | |
3372 5.0, 100.0, 1.0, 0, 100.0, | |
3373 G_CALLBACK(print_image_scale_cb), pw); | |
3374 | |
3375 label = pref_table_label(table, 0, 1, _("Proof size:"), 1.0); | |
3376 pw->proof_group = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL); | |
3377 pref_link_sensitivity(label, pw->proof_group); | |
3378 | |
3379 pw->proof_width_spin = pref_spin_new(pw->proof_group, NULL, NULL, | |
3380 0.0, 50.0, 0.1, 3, 0.0, | |
3381 G_CALLBACK(print_proof_size_cb), pw); | |
3382 pw->proof_height_spin = pref_spin_new(pw->proof_group, "x", NULL, | |
3383 0.0, 50.0, 0.1, 3, 0.0, | |
3384 G_CALLBACK(print_proof_size_cb), pw); | |
3385 | |
3386 /* text tab */ | |
3387 | |
3388 vbox = gtk_vbox_new(FALSE, 0); | |
3389 gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); | |
3390 gtk_widget_show(vbox); | |
3391 label = gtk_label_new(_("Text")); | |
3392 gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); | |
3393 | |
3394 print_text_menu(vbox, pw); | |
3395 | |
3396 /* paper tab */ | |
3397 | |
3398 vbox = gtk_vbox_new(FALSE, 0); | |
3399 gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); | |
3400 gtk_widget_show(vbox); | |
3401 label = gtk_label_new(_("Paper")); | |
3402 gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); | |
3403 | |
3404 table = pref_table_new(vbox, 2, 4, FALSE, FALSE); | |
3405 | |
3406 print_paper_menu(table, 0, 0, pw->paper_size, G_CALLBACK(print_paper_select_cb), pw); | |
3407 | |
3408 label = pref_table_label(table, 0, 1, (_("Size:")), 1.0); | |
3409 box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL); | |
3410 pw->paper_width_spin = pref_spin_new(box, NULL, NULL, | |
3411 1.0, 10000.0, 1.0, 2, 66, | |
3412 G_CALLBACK(print_paper_size_cb), pw); | |
3413 pw->paper_height_spin = pref_spin_new(box, "x", NULL, | |
3414 1.0, 10000.0, 1.0, 2, 66, | |
3415 G_CALLBACK(print_paper_size_cb), pw); | |
3416 pref_link_sensitivity(label, pw->paper_width_spin); | |
3417 | |
3418 pw->paper_units_menu = print_paper_units_menu(table, 0, 2, pw->paper_units, | |
3419 G_CALLBACK(print_paper_units_cb), pw); | |
3420 | |
3421 print_paper_orientation_menu(table, 0, 3, pw->paper_orientation, | |
3422 G_CALLBACK(print_paper_orientation_cb), pw); | |
3423 | |
3424 box = pref_group_new(vbox, FALSE, _("Margins"), GTK_ORIENTATION_VERTICAL); | |
3425 table = pref_table_new(box, 4, 2, FALSE, FALSE); | |
3426 pw->margin_left_spin = pref_table_spin(table, 0, 0, _("Left:"), NULL, | |
3427 0.0, 50.0, 0.1, 3, 0.0, | |
3428 G_CALLBACK(print_paper_margin_cb), pw); | |
3429 pw->margin_right_spin = pref_table_spin(table, 2, 0, _("Right:"), NULL, | |
3430 0.0, 50.0, 0.1, 3, 0.0, | |
3431 G_CALLBACK(print_paper_margin_cb), pw); | |
3432 pw->margin_top_spin = pref_table_spin(table, 0, 1, _("Top:"), NULL, | |
3433 0.0, 50.0, 0.1, 3, 0.0, | |
3434 G_CALLBACK(print_paper_margin_cb), pw); | |
3435 pw->margin_bottom_spin = pref_table_spin(table, 2, 1, _("Bottom:"), NULL, | |
3436 0.0, 50.0, 0.1, 3, 0.0, | |
3437 G_CALLBACK(print_paper_margin_cb), pw); | |
3438 | |
3439 /* printer tab */ | |
3440 | |
3441 vbox = gtk_vbox_new(FALSE, 0); | |
3442 gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); | |
3443 gtk_widget_show(vbox); | |
3444 label = gtk_label_new(_("Printer")); | |
3445 gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); | |
3446 | |
3447 table = pref_table_new(vbox, 2, 5, FALSE, FALSE); | |
3448 print_output_menu(table, 0, 0, pw->output, G_CALLBACK(print_output_cb), pw); | |
3449 | |
3450 label = pref_table_label(table, 0, 1, _("Custom printer:"), 1.0); | |
3451 combo = history_combo_new(&pw->custom_entry, NULL, "print_custom", -1); | |
3452 print_custom_entry_set(pw, combo); | |
3453 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, | |
3454 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
3455 gtk_widget_show(combo); | |
3456 | |
3457 pref_link_sensitivity(label, combo); | |
3458 | |
3459 label = pref_table_label(table, 0, 2, _("File:"), 1.0); | |
3460 combo = tab_completion_new_with_history(&pw->path_entry, NULL, "print_path", -1, NULL, pw); | |
3461 tab_completion_add_select_button(pw->path_entry, NULL, FALSE); | |
3462 gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, | |
3463 GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); | |
3464 gtk_widget_show(combo); | |
3465 | |
3466 pref_link_sensitivity(label, combo); | |
3467 | |
3468 label = pref_table_label(table, 0, 3, _("File format:"), 1.0); | |
3469 pw->path_format_menu = print_output_format_menu(table, 1, 3, pw->output_format, | |
3470 G_CALLBACK(print_output_format_cb), pw); | |
3471 pref_link_sensitivity(label, pw->path_format_menu); | |
3472 | |
3473 label = pref_table_label(table, 0, 4, _("DPI:"), 1.0); | |
3474 pw->max_dpi_menu = print_output_dpi_menu(table, 1, 4, pw->max_dpi, | |
3475 G_CALLBACK(print_output_dpi_cb), pw); | |
3476 pref_link_sensitivity(label, pw->max_dpi_menu); | |
3477 | |
3478 print_output_set(pw, pw->output); | |
3479 | |
3480 vbox = print_window_layout_setup(pw, main_box); | |
3481 pref_checkbox_new_int(vbox, _("Remember print settings"), pw->save_settings, &pw->save_settings); | |
3482 | |
3483 print_window_layout_sync_layout(pw); | |
3484 print_window_layout_sync_paper(pw); | |
3485 | |
3486 gtk_widget_show(pw->notebook); | |
3487 gtk_widget_show(pw->dialog->dialog); | |
3488 } | |
3489 |