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