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