From c6dc44268599a322f91c4f0d8b86861526f57797 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Thu, 20 Sep 2018 19:29:39 +0100 Subject: [PATCH] Fix #160: Replace print dialog by standard GTK dialog https://github.com/BestImageViewer/geeqie/issues/160 Does not include proof print. --- src/options.c | 4 + src/options.h | 6 + src/print.c | 3663 +++++-------------------------------------------- src/rcfile.c | 8 + 4 files changed, 386 insertions(+), 3295 deletions(-) diff --git a/src/options.c b/src/options.c index eec3b489..200b552d 100644 --- a/src/options.c +++ b/src/options.c @@ -194,6 +194,10 @@ ConfOptions *init_options(ConfOptions *options) options->read_metadata_in_idle = FALSE; options->star_rating.star = STAR_RATING_STAR; options->star_rating.rejected = STAR_RATING_REJECTED; + + options->printer.font = g_strdup("Serif 10"); + options->printer.text_fields = 1; + return options; } diff --git a/src/options.h b/src/options.h index 3b2d62b7..f9e92dcc 100644 --- a/src/options.h +++ b/src/options.h @@ -301,6 +301,12 @@ struct _ConfOptions gunichar rejected; } star_rating; + /* Printer */ + struct { + gchar *font; + gint text_fields; + } printer; + gboolean read_metadata_in_idle; }; diff --git a/src/print.c b/src/print.c index fbc4759c..4dc09199 100644 --- a/src/print.c +++ b/src/print.c @@ -1,8 +1,7 @@ /* - * Copyright (C) 2004 John Ellis - * Copyright (C) 2008 - 2016 The Geeqie Team + * Copyright (C) 2018 The Geeqie Team * - * Author: John Ellis + * Author: Colin Clark * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,3114 +22,93 @@ #include "print.h" #include "filedata.h" -#include "filefilter.h" -#include "image.h" #include "image-load.h" -#include "pixbuf_util.h" -#include "thumb.h" -#include "utilops.h" -#include "ui_bookmark.h" -#include "ui_menu.h" #include "ui_misc.h" -#include "ui_utildlg.h" #include "ui_fileops.h" -#include "ui_spinner.h" -#include "ui_tabcomp.h" -#include -#include -#include +#define PRINT_SETTINGS "print_settings" // filename save printer settings +#define PAGE_SETUP "page_setup" // filename save page setup -#define PRINT_LPR_COMMAND "lpr" -#define PRINT_LPR_CUSTOM "lpr -P %s" -#define PRINT_LPR_QUERY "lpstat -p" - -#define PRINT_DLG_WIDTH 600 -#define PRINT_DLG_HEIGHT 400 - -#define PRINT_DLG_PREVIEW_WIDTH 270 -#define PRINT_DLG_PREVIEW_HEIGHT -1 - -/* these are in point units */ -#define PRINT_MIN_WIDTH 100 -#define PRINT_MIN_HEIGHT 100 -#define PRINT_MAX_WIDTH 4000 -#define PRINT_MAX_HEIGHT 4000 - -#define PRINT_MARGIN_DEFAULT 36 - -#define PRINT_PROOF_MIN_SIZE 8 -#define PRINT_PROOF_MAX_SIZE 720 -#define PRINT_PROOF_DEFAULT_SIZE 144 -#define PRINT_PROOF_MARGIN 5 - -/* default page size */ -#define PAGE_LAYOUT_WIDTH 850 -#define PAGE_LAYOUT_HEIGHT 1100 - -/* preview uses 1 pixel = PRINT_PREVIEW_SCALE points */ -#define PRINT_PREVIEW_SCALE 4 - -/* default dpi to use for printing ps image data */ -#define PRINT_PS_DPI_DEFAULT 300.0 -#define PRINT_PS_DPI_MIN 150.0 -/* method to use when scaling down image data */ -#define PRINT_PS_MAX_INTERP GDK_INTERP_BILINEAR -/* color to use as mask when printing transparent images */ -#define PRINT_PS_MASK_R 255 -#define PRINT_PS_MASK_G 255 -#define PRINT_PS_MASK_B 255 - -/* padding between objects */ -#define PRINT_TEXT_PADDING 3.0 - -/* locale for postscript portability */ -#define POSTSCRIPT_LOCALE "C" - - -/* group and keys for saving prefs */ -#define PRINT_PREF_GROUP "print_settings" - -#define PRINT_PREF_SAVE "save_settings" - -#define PRINT_PREF_OUTPUT "output" -#define PRINT_PREF_FORMAT "format" -#define PRINT_PREF_DPI "dpi" -#define PRINT_PREF_UNITS "units" -#define PRINT_PREF_SIZE "size" -#define PRINT_PREF_ORIENTATION "orientation" - -#define PRINT_PREF_CUSTOM_WIDTH "custom_width" -#define PRINT_PREF_CUSTOM_HEIGHT "custom_height" -#define PRINT_PREF_MARGIN_LEFT "margin_left" -#define PRINT_PREF_MARGIN_RIGHT "margin_right" -#define PRINT_PREF_MARGIN_TOP "margin_top" -#define PRINT_PREF_MARGIN_BOTTOM "margin_bottom" -#define PRINT_PREF_PROOF_WIDTH "proof_width" -#define PRINT_PREF_PROOF_HEIGHT "proof_height" - -#define PRINT_PREF_PRINTERC "custom_printer" - -#define PRINT_PREF_TEXT "text" -#define PRINT_PREF_TEXTSIZE "textsize" -#define PRINT_PREF_TEXTCOLOR_R "textcolor_r" -#define PRINT_PREF_TEXTCOLOR_G "textcolor_g" -#define PRINT_PREF_TEXTCOLOR_B "textcolor_b" - -#define PRINT_PREF_SOURCE "source" -#define PRINT_PREF_LAYOUT "layout" - -#define PRINT_PREF_IMAGE_SCALE "image_scale" - -typedef enum { - PRINT_SOURCE_IMAGE = 0, - PRINT_SOURCE_SELECTION, - PRINT_SOURCE_ALL, - PRINT_SOURCE_COUNT -} PrintSource; - -const gchar *print_source_text[] = { - N_("Image"), - N_("Selection"), - N_("All"), - NULL -}; - -typedef enum { - PRINT_LAYOUT_IMAGE = 0, - PRINT_LAYOUT_PROOF, - PRINT_LAYOUT_COUNT -} PrintLayout; - -const gchar *print_layout_text[] = { - N_("One image per page"), - N_("Proof sheet"), - NULL -}; - -typedef enum { - PRINT_OUTPUT_PS_LPR = 0, - PRINT_OUTPUT_PS_CUSTOM, - PRINT_OUTPUT_PS_FILE, - PRINT_OUTPUT_RGB_FILE, - PRINT_OUTPUT_COUNT -} PrintOutput; - -const gchar *print_output_text[] = { - N_("Default printer"), - N_("Custom printer"), - N_("PostScript file"), - N_("Image file"), - NULL, - NULL -}; - -typedef enum { - PRINT_FILE_JPG_LOW = 0, - PRINT_FILE_JPG_NORMAL, - PRINT_FILE_JPG_HIGH, - PRINT_FILE_PNG, - PRINT_FILE_COUNT -} PrintFileFormat; - -const gchar *print_file_format_text[] = { - N_("jpeg, low quality"), - N_("jpeg, normal quality"), - N_("jpeg, high quality"), - "png", - NULL -}; - -typedef enum { - RENDER_FORMAT_PREVIEW, - RENDER_FORMAT_RGB, - RENDER_FORMAT_PS -} RenderFormat; - -typedef enum { - TEXT_INFO_FILENAME = 1 << 0, - TEXT_INFO_FILEDATE = 1 << 1, - TEXT_INFO_FILESIZE = 1 << 2, - TEXT_INFO_DIMENSIONS = 1 << 3, - TEXT_INFO_FILEPATH = 1 << 4 -} TextInfo; - -typedef enum { - PAPER_UNIT_POINTS = 0, - PAPER_UNIT_MM, - PAPER_UNIT_CM, - PAPER_UNIT_INCH, - PAPER_UNIT_PICAS, - PAPER_UNIT_COUNT -} PaperUnits; - -typedef enum { - PAPER_ORIENTATION_PORTRAIT = 0, - PAPER_ORIENTATION_LANDSCAPE, - PAPER_ORIENTATION_COUNT -} PaperOrientation; - - -typedef struct _PrintWindow PrintWindow; -struct _PrintWindow -{ - GenericDialog *dialog; - - FileData *source_fd; - GList *source_selection; - GList *source_list; - - PrintSource source; - PrintLayout layout; - PrintOutput output; - - gchar *output_path; - gchar *output_custom; - - PrintFileFormat output_format; - - gdouble max_dpi; - - GtkWidget *notebook; - - GtkWidget *path_entry; - GtkWidget *custom_entry; - GtkWidget *path_format_menu; - GtkWidget *max_dpi_menu; - - ImageWindow *layout_image; - gdouble layout_width; - gdouble layout_height; - - guint layout_idle_id; /* event source id */ - - gdouble image_scale; - - GtkWidget *image_scale_spin; - - gdouble proof_width; - gdouble proof_height; - gint proof_columns; - gint proof_rows; - GList *proof_point; - gint proof_position; - gint proof_page; - - GtkWidget *proof_group; - GtkWidget *proof_width_spin; - GtkWidget *proof_height_spin; - - GtkWidget *paper_menu; - GtkWidget *paper_width_spin; - GtkWidget *paper_height_spin; - GtkWidget *paper_units_menu; - GtkWidget *paper_orientation_menu; - - GtkWidget *margin_left_spin; - GtkWidget *margin_right_spin; - GtkWidget *margin_top_spin; - GtkWidget *margin_bottom_spin; - - PaperUnits paper_units; - gint paper_size; - gdouble paper_width; - gdouble paper_height; - PaperOrientation paper_orientation; - - gdouble margin_left; - gdouble margin_right; - gdouble margin_top; - gdouble margin_bottom; - - GtkWidget *button_back; - GtkWidget *button_next; - GtkWidget *page_label; - GtkWidget *print_button; - - gdouble single_scale; - gdouble single_x; - gdouble single_y; - - GtkWidget *single_scale_spin; - - TextInfo text_fields; - gint text_points; - guint8 text_r; - guint8 text_g; - guint8 text_b; - - gint save_settings; - - /* job printing */ - - GenericDialog *job_dialog; - GtkWidget *job_progress; - GtkWidget *job_progress_label; - - RenderFormat job_format; - PrintOutput job_output; - - FILE *job_file; - FILE *job_pipe; - gchar *job_path; - - GdkPixbuf *job_pixbuf; - - gint job_page; - ImageLoader *job_loader; -}; - - -static void print_job_throw_error(PrintWindow *pw, const gchar *message); -static gint print_job_start(PrintWindow *pw, RenderFormat format, PrintOutput output); -static void print_job_close(PrintWindow *pw, gint error); -static void print_window_close(PrintWindow *pw); - - -/* misc utils */ - -static gboolean clip_region(gdouble x1, gdouble y1, gdouble w1, gdouble h1, - gdouble x2, gdouble y2, gdouble w2, gdouble h2, - gdouble *rx, gdouble *ry, gdouble *rw, gdouble *rh) -{ - if (x2 + w2 <= x1 || x2 >= x1 + w1 || - y2 + h2 <= y1 || y2 >= y1 + h1) - { - return FALSE; - } - - *rx = MAX(x1, x2); - *rw = MIN((x1 + w1), (x2 + w2)) - *rx; - - *ry = MAX(y1, y2); - *rh = MIN((y1 + h1), (y2 + h2)) - *ry; - - return TRUE; -} - -static const gchar *print_output_name(PrintOutput output) -{ - if (output >= PRINT_OUTPUT_COUNT) return ""; - - return _(print_output_text[output]); -} - - -/* - *----------------------------------------------------------------------------- - * data - *----------------------------------------------------------------------------- - */ - - -typedef struct _PaperSize PaperSize; -struct _PaperSize { - gchar *description; - gint width; - gint height; - PaperOrientation orientation; -}; - -const gchar *print_paper_units[] = { - N_("points"), - N_("millimeters"), - N_("centimeters"), - N_("inches"), - N_("picas"), - NULL -}; - -const gchar *print_paper_orientation[] = { - N_("Portrait"), - N_("Landscape"), - NULL -}; - -PaperSize print_paper_sizes[] = { - { N_("Custom"), 360, 720, PAPER_ORIENTATION_PORTRAIT }, - { N_("Letter"), 612, 792, PAPER_ORIENTATION_PORTRAIT }, /* in 8.5 x 11 */ - { N_("Legal"), 612, 1008, PAPER_ORIENTATION_PORTRAIT }, /* in 8.5 x 14 */ - { N_("Executive"), 522, 756, PAPER_ORIENTATION_PORTRAIT }, /* in 7.25x 10.5 */ - { "A0", 2384, 3370, PAPER_ORIENTATION_PORTRAIT }, /* mm 841 x 1189 */ - { "A1", 1684, 2384, PAPER_ORIENTATION_PORTRAIT }, /* mm 594 x 841 */ - { "A2", 1191, 1684, PAPER_ORIENTATION_PORTRAIT }, /* mm 420 x 594 */ - { "A3", 842, 1191, PAPER_ORIENTATION_PORTRAIT }, /* mm 297 x 420 */ - { "A4", 595, 842, PAPER_ORIENTATION_PORTRAIT }, /* mm 210 x 297 */ - { "A5", 420, 595, PAPER_ORIENTATION_PORTRAIT }, /* mm 148 x 210 */ - { "A6", 298, 420, PAPER_ORIENTATION_PORTRAIT }, /* mm 105 x 148 */ - { "B3", 1001, 1417, PAPER_ORIENTATION_PORTRAIT }, /* mm 353 x 500 */ - { "B4", 709, 1001, PAPER_ORIENTATION_PORTRAIT }, /* mm 250 x 353 */ - { "B5", 499, 709, PAPER_ORIENTATION_PORTRAIT }, /* mm 176 x 250 */ - { "B6", 354, 499, PAPER_ORIENTATION_PORTRAIT }, /* mm 125 x 176 */ - { N_("Envelope #10"), 297, 684, PAPER_ORIENTATION_LANDSCAPE }, /* in 4.125 x 9.5 */ - { N_("Envelope #9"), 279, 639, PAPER_ORIENTATION_LANDSCAPE }, /* in 3.875 x 8.875 */ - { N_("Envelope C4"), 649, 918, PAPER_ORIENTATION_LANDSCAPE }, /* mm 229 x 324 */ - { N_("Envelope C5"), 459, 649, PAPER_ORIENTATION_LANDSCAPE }, /* mm 162 x 229 */ - { N_("Envelope C6"), 323, 459, PAPER_ORIENTATION_LANDSCAPE }, /* mm 114 x 162 */ - { N_("Photo 6x4"), 432, 288, PAPER_ORIENTATION_PORTRAIT }, /* in 6 x 4 */ - { N_("Photo 8x10"), 576, 720, PAPER_ORIENTATION_PORTRAIT }, /* in 8 x 10 */ - { N_("Postcard"), 284, 419, PAPER_ORIENTATION_LANDSCAPE }, /* mm 100 x 148 */ - { N_("Tabloid"), 792, 1224, PAPER_ORIENTATION_PORTRAIT }, /* in 11 x 17 */ - { NULL, 0, 0, 0 } -}; - - -static PaperSize *print_paper_size_nth(gint n) -{ - PaperSize *ps = NULL; - gint i = 0; - - while (i <= n && print_paper_sizes[i].description) - { - ps = &print_paper_sizes[i]; - i++; - } - - return ps; -} - -static gint print_paper_size_lookup(gint n, gdouble *width, gdouble *height) -{ - PaperSize *ps; - gdouble w, h; - - ps = print_paper_size_nth(n); - if (!ps) return FALSE; - - if (ps->orientation == PAPER_ORIENTATION_PORTRAIT) - { - w = ps->width; - h = ps->height; - } - else - { - h = ps->width; - w = ps->height; - } - - if (width) *width = w; - if (height) *height = h; - - return TRUE; -} - -static gdouble print_paper_size_convert_units(gdouble value, PaperUnits src, PaperUnits dst) -{ - gdouble ret; - - if (src == dst) return value; - - switch (src) - { - case PAPER_UNIT_MM: - ret = value / 25.4 * 72.0; - break; - case PAPER_UNIT_CM: - ret = value / 2.54 * 72.0; - break; - case PAPER_UNIT_INCH: - ret = value * 72.0; - break; - case PAPER_UNIT_PICAS: - ret = value * 12.0; - break; - case PAPER_UNIT_POINTS: - default: - ret = value; - break; - } - - switch (dst) - { - case PAPER_UNIT_MM: - ret = ret / 72.0 * 25.4; - break; - case PAPER_UNIT_CM: - ret = ret / 72.0 * 2.54; - break; - case PAPER_UNIT_INCH: - ret = ret / 72.0; - break; - case PAPER_UNIT_PICAS: - ret = ret / 12.0; - break; - case PAPER_UNIT_POINTS: - default: - break; - } - - return ret; -} - -static PaperUnits paper_unit_default(void) -{ - const gchar *result; -#if 0 - /* this is not used because it is not even slightly portable */ - #include - - result = nl_langinfo(_NL_MEASUREMENT_MEASUREMENT); - if (result[0] == '2') return PAPER_UNIT_INCH; -#endif - -#ifdef LC_MEASUREMENT - result = setlocale(LC_MEASUREMENT, NULL); -#else - result = setlocale(LC_ALL, NULL); -#endif - if (result && - (strstr(result, "_US") || strstr(result, "_PR")) ) - { - return PAPER_UNIT_INCH; - } - - return PAPER_UNIT_CM; -} - -/* - *----------------------------------------------------------------------------- - * the layout window - *----------------------------------------------------------------------------- - */ - -static gint print_layout_page_count(PrintWindow *pw); - - -static gint print_preview_unit(gdouble points) -{ - return (gint)(points / PRINT_PREVIEW_SCALE); -} - -static void print_proof_size(PrintWindow *pw, gdouble *width, gdouble *height) -{ - if (width) *width = pw->proof_width + PRINT_PROOF_MARGIN * 2; - if (height) - { - gdouble h; - - h = pw->proof_height + PRINT_PROOF_MARGIN * 2; - if (pw->text_fields != 0) h += PRINT_TEXT_PADDING; - if (pw->text_fields & TEXT_INFO_FILENAME) h+= (gdouble)pw->text_points * 1.25; - if (pw->text_fields & TEXT_INFO_DIMENSIONS) h+= (gdouble)pw->text_points * 1.25; - if (pw->text_fields & TEXT_INFO_FILEDATE) h+= (gdouble)pw->text_points * 1.25; - if (pw->text_fields & TEXT_INFO_FILESIZE) h+= (gdouble)pw->text_points * 1.25; - *height = h; - } -} - -static void print_window_layout_status(PrintWindow *pw) -{ - gint total; - gchar *buf; - - total = print_layout_page_count(pw); - pw->proof_page = CLAMP(pw->proof_page, 0, total - 1); - - buf = g_strdup_printf(_("page %d of %d"), pw->proof_page + 1, (total > 0) ? total : 1); - gtk_label_set_text(GTK_LABEL(pw->page_label), buf); - g_free(buf); - - gtk_widget_set_sensitive(pw->page_label, (total > 0)); - - gtk_widget_set_sensitive(pw->button_back, (pw->proof_page > 0)); - gtk_widget_set_sensitive(pw->button_next, (pw->proof_page < total - 1)); - - gtk_widget_set_sensitive(pw->print_button, total > 0); -} - -static void print_window_layout_render_stop(PrintWindow *pw) -{ - if (pw->layout_idle_id) - { - g_source_remove(pw->layout_idle_id); - pw->layout_idle_id = 0; - } -} - -static gboolean print_window_layout_render_idle(gpointer data) -{ - PrintWindow *pw = data; - - print_job_close(pw, FALSE); - print_job_start(pw, RENDER_FORMAT_PREVIEW, 0); - - pw->layout_idle_id = 0; - return FALSE; -} - -static void print_window_layout_render(PrintWindow *pw) -{ - gdouble proof_w, proof_h; - - print_proof_size(pw, &proof_w, &proof_h); - pw->proof_columns = (pw->layout_width - pw->margin_left - pw->margin_right) / proof_w; - pw->proof_rows = (pw->layout_height - pw->margin_top - pw->margin_bottom) / proof_h; - - print_window_layout_status(pw); - - if (!pw->layout_idle_id) - { - pw->layout_idle_id = g_idle_add(print_window_layout_render_idle, pw); - } -} - -static void print_window_layout_size(PrintWindow *pw) -{ - GdkPixbuf *pixbuf; - gdouble width; - gdouble height; - gint sw, sh; - - if (!pw->layout_image) return; - - if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) - { - width = pw->paper_height; - height = pw->paper_width; - } - else - { - width = pw->paper_width; - height = pw->paper_height; - } - - pw->layout_width = width; - pw->layout_height = height; - - sw = print_preview_unit(width); - sh = print_preview_unit(height); - pixbuf = image_get_pixbuf(pw->layout_image); - if (!pixbuf || - gdk_pixbuf_get_width(pixbuf) != sw || - gdk_pixbuf_get_height(pixbuf) != sh) - { - pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, sw, sh); - image_change_pixbuf(pw->layout_image, pixbuf, 0.0, FALSE); - g_object_unref(pixbuf); - } - - print_window_layout_render(pw); - print_window_layout_status(pw); -} - -static gint print_layout_page_count(PrintWindow *pw) -{ - gint images; - gint images_per_page; - gint pages; - - if (pw->layout_width - pw->margin_left - pw->margin_right <= 0.0 || - pw->layout_height - pw->margin_top - pw->margin_bottom <= 0.0) - { - return 0; - } - - switch (pw->source) - { - case PRINT_SOURCE_ALL: - images = g_list_length(pw->source_list); - break; - case PRINT_SOURCE_SELECTION: - images = g_list_length(pw->source_selection); - break; - case PRINT_SOURCE_IMAGE: - default: - images = (pw->source_fd) ? 1 : 0; - break; - } - - switch (pw->layout) - { - case PRINT_LAYOUT_PROOF: - images_per_page = pw->proof_columns * pw->proof_rows; - break; - case PRINT_LAYOUT_IMAGE: - default: - images_per_page = 1; - break; - } - - if (images < 1 || images_per_page < 1) return 0; - - pages = images / images_per_page; - if (pages * images_per_page < images) pages++; - - return pages; -} - -static void print_layout_page_step(PrintWindow *pw, gint step) -{ - gint max; - gint page; - - max = print_layout_page_count(pw); - page = pw->proof_page + step; - - if (page >= max) page = max - 1; - if (page < 0) page = 0; - - if (page == pw->proof_page) return; - - pw->proof_page = page; - print_window_layout_size(pw); -} - -static void print_layout_page_back_cb(GtkWidget *widget, gpointer data) -{ - PrintWindow *pw = data; - - print_layout_page_step(pw, -1); -} - -static void print_layout_page_next_cb(GtkWidget *widget, gpointer data) -{ - PrintWindow *pw = data; - - print_layout_page_step(pw, 1); -} - -static void print_layout_zoom_in_cb(GtkWidget *widget, gpointer data) -{ - PrintWindow *pw = data; - image_zoom_adjust(pw->layout_image, 0.25); -} - -static void print_layout_zoom_out_cb(GtkWidget *widget, gpointer data) -{ - PrintWindow *pw = data; - image_zoom_adjust(pw->layout_image, -0.25); -} - -static void print_layout_zoom_original_cb(GtkWidget *widget, gpointer data) -{ - PrintWindow *pw = data; - gdouble zoom; - - zoom = image_zoom_get(pw->layout_image); - image_zoom_set(pw->layout_image, (zoom == 1.0) ? 0.0 : 1.0); -} - -static GtkWidget *print_window_layout_setup(PrintWindow *pw, GtkWidget *box) -{ - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *group; - GtkWidget *button; - - vbox = pref_box_new(box, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); - group = pref_frame_new(vbox, TRUE, _("Preview"), GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); - - pw->layout_idle_id = 0; - - pw->layout_image = image_new(FALSE); - gtk_widget_set_size_request(pw->layout_image->widget, PRINT_DLG_PREVIEW_WIDTH, PRINT_DLG_PREVIEW_HEIGHT); - - gtk_box_pack_start(GTK_BOX(group), pw->layout_image->widget, TRUE, TRUE, 0); - gtk_widget_show(pw->layout_image->widget); - - hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); - pw->button_back = pref_button_new(hbox, GTK_STOCK_GO_BACK, NULL, TRUE, - G_CALLBACK(print_layout_page_back_cb), pw); - pw->button_next = pref_button_new(hbox, GTK_STOCK_GO_FORWARD, NULL, TRUE, - G_CALLBACK(print_layout_page_next_cb), pw); - pw->page_label = pref_label_new(hbox, ""); - - button = pref_button_new(NULL, GTK_STOCK_ZOOM_OUT, NULL, TRUE, - G_CALLBACK(print_layout_zoom_out_cb), pw); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - button = pref_button_new(NULL, GTK_STOCK_ZOOM_IN, NULL, TRUE, - G_CALLBACK(print_layout_zoom_in_cb), pw); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - button = pref_button_new(NULL, GTK_STOCK_ZOOM_100, NULL, TRUE, - G_CALLBACK(print_layout_zoom_original_cb), pw); - gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - print_window_layout_size(pw); - - return vbox; -} - -static void print_window_spin_set(GtkSpinButton *spin, gpointer block_data, - gdouble value, gdouble min, gdouble max, - gdouble step, gdouble page, gint digits) -{ - if (block_data) g_signal_handlers_block_matched(G_OBJECT(spin), G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, block_data); - gtk_spin_button_set_digits(spin, digits); - gtk_spin_button_set_increments(spin, step, page); - gtk_spin_button_set_range(spin, min, max); - gtk_spin_button_set_value(spin, value); - - if (block_data) g_signal_handlers_unblock_matched(G_OBJECT(spin), G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, block_data); -} - -static void print_window_layout_sync_layout(PrintWindow *pw) -{ - gtk_widget_set_sensitive(pw->image_scale_spin, (pw->layout == PRINT_LAYOUT_IMAGE)); - gtk_widget_set_sensitive(pw->proof_group, (pw->layout == PRINT_LAYOUT_PROOF)); -} - -static void print_window_layout_sync_paper(PrintWindow *pw) -{ - gdouble width, height; - gint digits; - gdouble step; - gdouble page; - - gtk_widget_set_sensitive(pw->paper_width_spin, (pw->paper_size == 0)); - gtk_widget_set_sensitive(pw->paper_height_spin, (pw->paper_size == 0)); - - width = print_paper_size_convert_units((gdouble)pw->paper_width, PAPER_UNIT_POINTS, pw->paper_units); - height = print_paper_size_convert_units((gdouble)pw->paper_height, PAPER_UNIT_POINTS, pw->paper_units); - - switch (pw->paper_units) - { - case PAPER_UNIT_MM: - digits = 1; - step = 1.0; - page = 10.0; - break; - case PAPER_UNIT_CM: - digits = 2; - step = 0.5; - page = 1.0; - break; - case PAPER_UNIT_INCH: - digits = 3; - step = 0.25; - page = 1.0; - break; - case PAPER_UNIT_PICAS: - digits = 2; - step = 1.0; - page = 6.0; - break; - case PAPER_UNIT_POINTS: - default: - digits = 1; - step = 1.0; - page = 10.0; - break; - } - - print_window_spin_set(GTK_SPIN_BUTTON(pw->paper_width_spin), pw, width, - print_paper_size_convert_units(PRINT_MIN_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), - print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->paper_height_spin), pw, height, - print_paper_size_convert_units(PRINT_MIN_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), - print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_left_spin), pw, - print_paper_size_convert_units(pw->margin_left, PAPER_UNIT_POINTS, pw->paper_units), - 0.0, - print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_right_spin), pw, - print_paper_size_convert_units(pw->margin_right, PAPER_UNIT_POINTS, pw->paper_units), - 0.0, - print_paper_size_convert_units(PRINT_MAX_WIDTH, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_top_spin), pw, - print_paper_size_convert_units(pw->margin_top, PAPER_UNIT_POINTS, pw->paper_units), - 0.0, - print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->margin_bottom_spin), pw, - print_paper_size_convert_units(pw->margin_bottom, PAPER_UNIT_POINTS, pw->paper_units), - 0.0, - print_paper_size_convert_units(PRINT_MAX_HEIGHT, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->proof_width_spin), pw, - print_paper_size_convert_units(pw->proof_width, PAPER_UNIT_POINTS, pw->paper_units), - print_paper_size_convert_units(PRINT_PROOF_MIN_SIZE, PAPER_UNIT_POINTS, pw->paper_units), - print_paper_size_convert_units(PRINT_PROOF_MAX_SIZE, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); - - print_window_spin_set(GTK_SPIN_BUTTON(pw->proof_height_spin), pw, - print_paper_size_convert_units(pw->proof_height, PAPER_UNIT_POINTS, pw->paper_units), - print_paper_size_convert_units(PRINT_PROOF_MIN_SIZE, PAPER_UNIT_POINTS, pw->paper_units), - print_paper_size_convert_units(PRINT_PROOF_MAX_SIZE, PAPER_UNIT_POINTS, pw->paper_units), - step, page, digits); -} - -static void print_window_layout_set_size(PrintWindow *pw, gdouble width, gdouble height) -{ - pw->paper_width = width; - pw->paper_height = height; - - print_window_layout_sync_paper(pw); - - print_window_layout_size(pw); -} - -static void print_window_layout_set_orientation(PrintWindow *pw, PaperOrientation o) -{ - if (pw->paper_orientation == o) return; - - pw->paper_orientation = o; - - print_window_layout_size(pw); -} - -/* - *----------------------------------------------------------------------------- - * list printers - *----------------------------------------------------------------------------- - */ - -static GList *print_window_list_printers(void) -{ - FILE *p; - GList *list = NULL; - gchar buffer[2048]; - - p = popen(PRINT_LPR_QUERY, "r"); - if (!p) return NULL; - - while (fgets(buffer, sizeof(buffer), p) != NULL) - { - gchar *ptr; - gchar *end; - - ptr = buffer; - if (strncmp(ptr, "printer ", 8) != 0) continue; - if (strstr(ptr, "enabled") == NULL) continue; - ptr += 8; - end = ptr; - while (*end != '\0' && *end != '\n' && *end != ' ' && *end != '\t') end++; - *end = '\0'; - list = g_list_append(list, g_strdup(ptr)); - DEBUG_1("adding printer: %s", ptr); - } - - pclose(p); - - return list; -} - -/* - *----------------------------------------------------------------------------- - * print ps - *----------------------------------------------------------------------------- - */ - -typedef struct _PipeError PipeError; -struct _PipeError { - struct sigaction old_action; - sig_atomic_t *error; -}; - -static sig_atomic_t pipe_handler_error = FALSE; -static PipeError *pipe_handler_data = NULL; - -static void pipe_handler_sigpipe_cb(gint fd) -{ - pipe_handler_error = TRUE; -} - -static PipeError *pipe_handler_new(void) -{ - struct sigaction new_action; - PipeError *pe; - - if (pipe_handler_data) - { - log_printf("warning SIGPIPE handler already in use\n"); - return NULL; - } - - pe = g_new0(PipeError, 1); - - pipe_handler_error = FALSE; - pe->error = &pipe_handler_error; - - new_action.sa_handler = pipe_handler_sigpipe_cb; - sigemptyset(&new_action.sa_mask); - new_action.sa_flags = 0; - - /* setup our signal handler */ - sigaction(SIGPIPE, &new_action, &pe->old_action); - - pipe_handler_data = pe; - return pe; -} - -static void pipe_handler_free(PipeError *pe) -{ - if (!pe) return; - if (pe != pipe_handler_data) log_printf("warning SIGPIPE handler not closing same data\n"); - - /* restore the original signal handler */ - sigaction(SIGPIPE, &pe->old_action, NULL); - - pipe_handler_data = NULL; - g_free(pe); -} - -static gboolean pipe_handler_check(PipeError *pe) -{ - if (!pe) return FALSE; - return !!(*pe->error); -} - -static FILE *print_job_ps_fd(PrintWindow *pw) -{ - if (pw->job_file) return pw->job_file; - if (pw->job_pipe) return pw->job_pipe; - return NULL; -} - -static gboolean print_job_ps_init(PrintWindow *pw) -{ - FILE *f; - PipeError *pe; - const gchar *cmd = NULL; - const gchar *path = NULL; - gchar *lc_pointer; - gboolean ret; - - if (pw->job_file != NULL || pw->job_pipe != NULL) return FALSE; - - switch (pw->job_output) - { - case PRINT_OUTPUT_PS_LPR: - cmd = PRINT_LPR_COMMAND; - break; - case PRINT_OUTPUT_PS_CUSTOM: - cmd = pw->output_custom; - break; - case PRINT_OUTPUT_PS_FILE: - path = pw->output_path; - break; - default: - return FALSE; - break; - } - - if (cmd) - { - pw->job_pipe = popen(cmd, "w"); - - if (!pw->job_pipe) - { - gchar *buf; - - buf = g_strdup_printf(_("Unable to open pipe for writing.\n\"%s\""), cmd); - print_job_throw_error(pw, buf); - g_free(buf); - - return FALSE; - } - } - else if (path) - { - gchar *pathl; - - if (isfile(path)) - { - gchar *buf; - - buf = g_strdup_printf(_("A file with name %s already exists."), path); - print_job_throw_error(pw, buf); - g_free(buf); - - return FALSE; - } - - pathl = path_from_utf8(path); - pw->job_file = fopen(pathl, "w"); - g_free(pathl); - - if (!pw->job_file) - { - gchar *buf; - - buf = g_strdup_printf(_("Failure writing to file %s"), path); - print_job_throw_error(pw, buf); - g_free(buf); - - return FALSE; - } - - g_free(pw->job_path); - pw->job_path = g_strdup(path); - } - - f = print_job_ps_fd(pw); - if (!f) return FALSE; - - lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); - - pe = pipe_handler_new(); - - /* comments, etc. */ - g_fprintf(f, "%%!PS-Adobe-3.0\n"); - g_fprintf(f, "%%%%Creator: %s Version %s\n", GQ_APPNAME, VERSION); - g_fprintf(f, "%%%%CreationDate: \n"); - g_fprintf(f, "%%%%LanguageLevel 2\n"); - g_fprintf(f, "%%%%DocumentMedia: \n"); - g_fprintf(f, "%%%%Orientation: %s\n", - (pw->paper_orientation == PAPER_ORIENTATION_PORTRAIT) ? "Portrait" : "Landscape"); - g_fprintf(f, "%%%%BoundingBox: %f %f %f %f\n", - 0.0, 0.0, pw->paper_width, pw->paper_height); - g_fprintf(f, "%%%%Pages: %d\n", print_layout_page_count(pw)); - g_fprintf(f, "%%%%PageOrder: Ascend\n"); - g_fprintf(f, "%%%%Title:\n"); - - /* setup page size, coordinates (do we really need this?) */ - /* enabled for 1.0beta2 https://bugzilla.redhat.com/222639 */ -#if 1 - g_fprintf(f, "<<\n"); - g_fprintf(f, "/PageSize [%f %f]\n", pw->layout_width, pw->layout_height); - g_fprintf(f, "/ImagingBBox [%f %f %f %f]\n", /* l b r t */ - pw->margin_left, pw->margin_bottom, - pw->layout_width - pw->margin_right, pw->layout_height - pw->margin_top); - g_fprintf(f, "/Orientation %d\n", - (pw->paper_orientation == PAPER_ORIENTATION_PORTRAIT) ? 0 : 1); - g_fprintf(f, ">> setpagedevice\n"); -#endif - - ret = !pipe_handler_check(pe); - pipe_handler_free(pe); - - if (lc_pointer) - { - setlocale(LC_NUMERIC, lc_pointer); - g_free(lc_pointer); - } - - if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); - - return ret; -} - -static gboolean print_job_ps_page_new(PrintWindow *pw, gint page) -{ - FILE *f; - PipeError *pe; - gchar *lc_pointer; - gboolean ret; - - f= print_job_ps_fd(pw); - if (!f) return FALSE; - - lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); - - pe = pipe_handler_new(); - - g_fprintf(f, "%%%% page %d\n", page + 1); - - if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) - { - g_fprintf(f, "/pagelevel save def\n"); - g_fprintf(f, "%d 0 translate 90 rotate\n", (gint)pw->layout_height); - } - - ret = !pipe_handler_check(pe); - pipe_handler_free(pe); - - if (lc_pointer) - { - setlocale(LC_NUMERIC, lc_pointer); - g_free(lc_pointer); - } - - if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); - - return ret; -} - -static gboolean print_job_ps_page_done(PrintWindow *pw) -{ - FILE *f; - PipeError *pe; - gchar *lc_pointer; - gboolean ret; - - f = print_job_ps_fd(pw); - if (!f) return FALSE; - - lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); - - pe = pipe_handler_new(); - - if (pw->paper_orientation == PAPER_ORIENTATION_LANDSCAPE) - { - g_fprintf(f, "pagelevel restore\n"); - } - - g_fprintf(f, "showpage\n"); - - ret = !pipe_handler_check(pe); - pipe_handler_free(pe); - - if (lc_pointer) - { - setlocale(LC_NUMERIC, lc_pointer); - g_free(lc_pointer); - } - - if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); - - return ret; -} - -static void print_job_ps_page_image_pixel(FILE *f, guchar *pix) -{ - static gchar hex_digits[] = "0123456789abcdef"; - gchar text[8]; - gint i; - - for (i = 0; i < 3; i++) - { - text[i*2] = hex_digits[pix[i] >> 4]; - text[i*2+1] = hex_digits[pix[i] & 0xf]; - } - text[6] = '\0'; - - g_fprintf(f, "%s", text); -} -static gboolean print_job_ps_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, - gdouble x, gdouble y, gdouble w, gdouble h, - gdouble offx, gdouble offy) -{ - FILE *f; - PipeError *pe; - gchar *lc_pointer; - gint sw, sh; - gint bps; - gint rowstride; - guchar *pix; - gint i, j; - gint c; - guchar *p; - guchar bps_buf[3]; - gboolean ret; - - if (!pixbuf) return TRUE; - - f = print_job_ps_fd(pw); - if (!f) return FALSE; - - sw = gdk_pixbuf_get_width(pixbuf); - sh = gdk_pixbuf_get_height(pixbuf); - - if (pw->max_dpi >= PRINT_PS_DPI_MIN && - sw / pw->max_dpi > w / 72.0) - { - pixbuf = gdk_pixbuf_scale_simple(pixbuf, - (gint)(w / 72.0 * pw->max_dpi), - (gint)(h / 72.0 * pw->max_dpi), - PRINT_PS_MAX_INTERP); - sw = gdk_pixbuf_get_width(pixbuf); - sh = gdk_pixbuf_get_height(pixbuf); - } - else - { - g_object_ref(G_OBJECT(pixbuf)); - } - - bps = (gdk_pixbuf_get_has_alpha(pixbuf)) ? 4 : 3; - rowstride = gdk_pixbuf_get_rowstride(pixbuf); - pix = gdk_pixbuf_get_pixels(pixbuf); - - lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); - - pe = pipe_handler_new(); - - g_fprintf(f, "gsave\n"); - g_fprintf(f, "[%f 0 0 %f %f %f] concat\n", w, h, x, pw->layout_height - h - y); - g_fprintf(f, "/buf %d string def\n", sw * 3); - g_fprintf(f, "%d %d %d\n", sw, sh, 8); - g_fprintf(f, "[%d 0 0 -%d 0 %d]\n", sw, sh, sh); - g_fprintf(f, "{ currentfile buf readhexstring pop }\n"); - g_fprintf(f, "false %d colorimage\n", 3); - - c = 0; - for (j = 0; j < sh; j++) - { - p = pix + j * rowstride; - for (i = 0; i < sw; i++) - { - if (bps == 3) - { - print_job_ps_page_image_pixel(f, p); - } - else - { - bps_buf[0] = (p[0] * p[3] + PRINT_PS_MASK_R * (256 - p[3])) >> 8; - bps_buf[1] = (p[1] * p[3] + PRINT_PS_MASK_G * (256 - p[3])) >> 8; - bps_buf[2] = (p[2] * p[3] + PRINT_PS_MASK_B * (256 - p[3])) >> 8; - print_job_ps_page_image_pixel(f, bps_buf); - } - p+=bps; - c++; - if (c > 11) - { - g_fprintf(f, "\n"); - c = 0; - } - } - } - if (c > 0) g_fprintf(f, "\n"); - g_fprintf(f, "grestore\n"); - - ret = !pipe_handler_check(pe); - pipe_handler_free(pe); - - if (lc_pointer) - { - setlocale(LC_NUMERIC, lc_pointer); - g_free(lc_pointer); - } - - g_object_unref(G_OBJECT(pixbuf)); - - if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); - - return ret; -} - -static gdouble convert_pango_dpi(gdouble points); - -static gboolean print_job_ps_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, - gdouble x, gdouble y, gdouble width, - guint8 r, guint8 g, guint8 b) -{ - PangoLayout *layout; - PangoFontDescription *desc; - GdkPixbuf *pixbuf; - gint lw, lh; - gboolean ret; - gdouble scale_to_max_dpi = (pw->max_dpi >= PRINT_PS_DPI_MIN) ? pw->max_dpi / 72.0 : 1200.0 / 72.0; - - layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); - - desc = pango_font_description_new(); - pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE * scale_to_max_dpi); - pango_layout_set_font_description(layout, desc); - pango_font_description_free(desc); - - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - pango_layout_set_text(layout, text, -1); - - pango_layout_get_pixel_size(layout, &lw, &lh); - x = x - (gdouble)lw / 2.0 / scale_to_max_dpi; - - pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, lw, lh); - gdk_pixbuf_fill(pixbuf, 0xffffffff); - pixbuf_draw_layout(pixbuf, layout, pw->dialog->dialog, 0, 0, r, g, b, 255); - g_object_unref(G_OBJECT(layout)); - - ret = print_job_ps_page_image(pw, pixbuf, x, y, - /* do not allow rescaling of the pixbuf due to rounding errors */ - ((gdouble)lw + 0.01) / scale_to_max_dpi, - ((gdouble)lh + 0.01) / scale_to_max_dpi, - 0, 0); - - g_object_unref(G_OBJECT(pixbuf)); - - return ret; -} - -static gboolean print_job_ps_end(PrintWindow *pw) -{ - FILE *f; - PipeError *pe; - gchar *lc_pointer; - gboolean ret; - - f = print_job_ps_fd(pw); - if (!f) return FALSE; - - lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); - setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); - - pe = pipe_handler_new(); - - g_fprintf(f, "%%%%EOF\n"); - - ret = !pipe_handler_check(pe); - pipe_handler_free(pe); - - if (lc_pointer) - { - setlocale(LC_NUMERIC, lc_pointer); - g_free(lc_pointer); - } - - if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); - - return ret; -} - -/* - *----------------------------------------------------------------------------- - * print rgb - *----------------------------------------------------------------------------- - */ - -static gboolean print_job_rgb_page_new(PrintWindow *pw, gint page) -{ - gint total; - - if (pw->job_pixbuf) - { - pixbuf_set_rect_fill(pw->job_pixbuf, 0, 0, - gdk_pixbuf_get_width(pw->job_pixbuf), - gdk_pixbuf_get_height(pw->job_pixbuf), - 255, 255, 255, 255); - } - - g_free(pw->job_path); - pw->job_path = NULL; - - total = print_layout_page_count(pw); - - if (!pw->output_path || - page < 0 || page >= total) return FALSE; - - if (total > 1) - { - const gchar *ext; - gchar *base; - - ext = registered_extension_from_path(pw->output_path); - - if (ext) - { - base = g_strndup(pw->output_path, ext - pw->output_path); - } - else - { - base = g_strdup(pw->output_path); - ext = ""; - } - pw->job_path = g_strdup_printf("%s_%03d%s", base, page + 1, ext); - g_free(base); - } - else - { - pw->job_path = g_strdup(pw->output_path); - } - - if (isfile(pw->job_path)) - { - gchar *buf; - - buf = g_strdup_printf(_("A file with name %s already exists."), pw->job_path); - print_job_throw_error(pw, buf); - g_free(buf); - - g_free(pw->job_path); - pw->job_path = NULL; - } - - return (pw->job_path != NULL); -} - -static gboolean print_job_rgb_page_done(PrintWindow *pw) -{ - gchar *pathl; - gboolean ret = FALSE; - - if (!pw->job_pixbuf) return FALSE; - - pathl = path_from_utf8(pw->job_path); - - if (pw->output_format == PRINT_FILE_PNG) - { - ret = pixbuf_to_file_as_png(pw->job_pixbuf, pathl); - } - else - { - gint quality = 0; - - switch (pw->output_format) - { - case PRINT_FILE_JPG_LOW: - quality = 65; - break; - case PRINT_FILE_JPG_NORMAL: - quality = 80; - break; - case PRINT_FILE_JPG_HIGH: - quality = 95; - break; - default: - break; - } - - if (quality > 0) - { - ret = pixbuf_to_file_as_jpg(pw->job_pixbuf, pathl, quality); - } - } - - g_free(pathl); - - if (!ret) - { - gchar *buf; - - buf = g_strdup_printf(_("Failure writing to file %s"), pw->job_path); - print_job_throw_error(pw, buf); - g_free(buf); - } - - return ret; -} - -static gboolean print_job_rgb_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, - gdouble x, gdouble y, gdouble w, gdouble h, - gdouble offx, gdouble offy) -{ - gdouble sw, sh; - gdouble dw, dh; - gdouble rx, ry, rw, rh; - - if (!pw->job_pixbuf) return FALSE; - if (!pixbuf) return TRUE; - - sw = (gdouble)gdk_pixbuf_get_width(pixbuf); - sh = (gdouble)gdk_pixbuf_get_height(pixbuf); - - dw = (gdouble)gdk_pixbuf_get_width(pw->job_pixbuf); - dh = (gdouble)gdk_pixbuf_get_height(pw->job_pixbuf); - - if (clip_region(x, y, w, h, - 0.0, 0.0, dw, dh, - &rx, &ry, &rw, &rh)) - { - gdk_pixbuf_composite(pixbuf, pw->job_pixbuf, rx, ry, rw, rh, - x + offx, y + offy, - w / sw, h / sh, - (w / sw < 0.01 || h / sh < 0.01) ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR, 255); - } - - return TRUE; -} - -static gdouble convert_pango_dpi(gdouble points) -{ - static gdouble dpi = 0.0; - - if (dpi == 0.0) - { - GtkSettings *settings; - GObjectClass *klass; - - settings = gtk_settings_get_default(); - klass = G_OBJECT_CLASS(GTK_SETTINGS_GET_CLASS(settings)); - if (g_object_class_find_property(klass, "gtk-xft-dpi")) - { - gint int_dpi; - g_object_get(settings, "gtk-xft-dpi", &int_dpi, NULL); - dpi = (gdouble)int_dpi / PANGO_SCALE; - } - - if (dpi < 25.0) - { - static gboolean warned = FALSE; - gdouble fallback_dpi = 96.0; - - if (!warned) - { - if (dpi == 0.0) - { - log_printf("pango dpi unknown, assuming %.0f\n", fallback_dpi); - } - else - { - log_printf("pango dpi reported as %.0f ignored, assuming %.0f\n", dpi, fallback_dpi); - } - warned = TRUE; - } - - dpi = fallback_dpi; - } - } - - if (dpi == 0) return points; - return points * 72.0 / dpi; -} - -static gboolean print_job_rgb_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, - gdouble x, gdouble y, gdouble width, - guint8 r, guint8 g, guint8 b) -{ - PangoLayout *layout; - PangoFontDescription *desc; - gint lw, lh; - - if (!pw->job_pixbuf) return FALSE; - - layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); - - desc = pango_font_description_new(); - pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE); - pango_layout_set_font_description(layout, desc); - pango_font_description_free(desc); - - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - pango_layout_set_text(layout, text, -1); - - pango_layout_get_pixel_size(layout, &lw, &lh); - x = x - (gdouble)lw / 2.0; - - pixbuf_draw_layout(pw->job_pixbuf, layout, pw->dialog->dialog, x, y, r, g, b, 255); - g_object_unref(G_OBJECT(layout)); - - return TRUE; -} - -static gboolean print_job_rgb_init(PrintWindow *pw) -{ - if (pw->job_pixbuf) g_object_unref(pw->job_pixbuf); - pw->job_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, - (gint)pw->layout_width, (gint)pw->layout_height); - - return print_job_rgb_page_new(pw, pw->job_page); -} - -/* - *----------------------------------------------------------------------------- - * print preview - *----------------------------------------------------------------------------- - */ - -static gboolean print_job_preview_page_new(PrintWindow *pw, gint page) -{ - GdkPixbuf *pixbuf; - gint w, h; - gint l, r, t, b; - - pixbuf = pw->job_pixbuf; - if (!pixbuf) return FALSE; - - w = print_preview_unit(pw->layout_width); - h = print_preview_unit(pw->layout_height); - l = print_preview_unit(pw->margin_left); - r = print_preview_unit(pw->margin_right); - t = print_preview_unit(pw->margin_top); - b = print_preview_unit(pw->margin_bottom); - - /* fill background */ - pixbuf_set_rect_fill(pixbuf, 0, 0, w, h, - 255, 255, 255, 255); - - /* draw cm or inch grid */ - if (TRUE) - { - gdouble i; - gdouble grid; - PaperUnits units; - - units = (pw->paper_units == PAPER_UNIT_MM || - pw->paper_units == PAPER_UNIT_CM) ? PAPER_UNIT_CM : PAPER_UNIT_INCH; - - grid = print_paper_size_convert_units(1.0, units, PAPER_UNIT_POINTS); - for (i = grid ; i < pw->layout_width; i += grid) - { - pixbuf_draw_rect_fill(pixbuf, print_preview_unit(i), 0, 1, h, 0, 0, 0, 16); - } - for (i = grid; i < pw->layout_height; i += grid) - { - pixbuf_draw_rect_fill(pixbuf, 0, print_preview_unit(i), w, 1, 0, 0, 0, 16); - } - } - - /* proof sheet grid */ - if (pw->layout == PRINT_LAYOUT_PROOF) - { - gdouble i, j; - gdouble proof_w, proof_h; - gint uw, uh; - - print_proof_size(pw, &proof_w, &proof_h); - uw = print_preview_unit(proof_w + PRINT_PREVIEW_SCALE - 0.1); - uh = print_preview_unit(proof_h + PRINT_PREVIEW_SCALE - 0.1); - - for (i = 0; i < pw->proof_columns; i++) - for (j = 0; j < pw->proof_rows; j++) - { - gint x, y; - - x = pw->margin_left + (pw->layout_width - pw->margin_left - pw->margin_right - (pw->proof_columns * proof_w)) / 2 + i * proof_w; - y = pw->margin_top + j * proof_h; - - pixbuf_draw_rect(pixbuf, print_preview_unit(x), print_preview_unit(y), uw, uh, - 255, 0, 0, 64, 1, 1, 1, 1); - } - } - - /* non-printable region (margins) */ - pixbuf_draw_rect(pixbuf, 0, 0, w, h, - 0, 0, 0, 16, - l, r, t, b); - - /* margin lines */ - pixbuf_draw_rect(pixbuf, l, 0, w - l - r, h, - 0, 0, 255, 128, - 1, 1, 0, 0); - pixbuf_draw_rect(pixbuf, 0, t, w, h - t - b, - 0, 0, 255, 128, - 0, 0, 1, 1); - - /* border */ - pixbuf_draw_rect(pixbuf, 0, 0, w, h, - 0, 0, 0, 255, - 1, 1, 1, 1); - - image_area_changed(pw->layout_image, 0, 0, w, h); - - return TRUE; -} - -static gboolean print_job_preview_page_done(PrintWindow *pw) -{ - return TRUE; -} - -static gboolean print_job_preview_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, - gdouble x, gdouble y, gdouble w, gdouble h, - gdouble offx, gdouble offy) -{ - gdouble sw, sh; - gdouble dw, dh; - gdouble rx, ry, rw, rh; - - if (!pw->job_pixbuf) return FALSE; - if (!pixbuf) return TRUE; - - sw = (gdouble)gdk_pixbuf_get_width(pixbuf); - sh = (gdouble)gdk_pixbuf_get_height(pixbuf); - - dw = (gdouble)gdk_pixbuf_get_width(pw->job_pixbuf); - dh = (gdouble)gdk_pixbuf_get_height(pw->job_pixbuf); - - x = print_preview_unit(x); - y = print_preview_unit(y); - w = print_preview_unit(w); - h = print_preview_unit(h); - offx = print_preview_unit(offx); - offy = print_preview_unit(offy); - - if (clip_region(x, y, w, h, - 0.0, 0.0, dw, dh, - &rx, &ry, &rw, &rh)) - { - gdk_pixbuf_composite(pixbuf, pw->job_pixbuf, rx, ry, rw, rh, - x + offx, y + offy, - w / sw, h / sh, - (w / sw < 0.01 || h / sh < 0.01) ? GDK_INTERP_NEAREST : GDK_INTERP_BILINEAR, 255); - - image_area_changed(pw->layout_image, rx, ry, rw, rh); - } - - return TRUE; -} - -static gboolean print_job_preview_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, - gdouble x, gdouble y, gdouble width, - guint8 r, guint8 g, guint8 b) -{ - PangoLayout *layout; - PangoFontDescription *desc; - gint lw, lh; - GdkPixbuf *pixbuf; - - if (!pw->job_pixbuf) return FALSE; - - layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); - - desc = pango_font_description_new(); - pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE); - pango_layout_set_font_description(layout, desc); - pango_font_description_free(desc); - - pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); - pango_layout_set_text(layout, text, -1); - - pango_layout_get_pixel_size(layout, &lw, &lh); - x = x - (gdouble)lw / 2.0; - - pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, lw, lh); - pixbuf_set_rect_fill(pixbuf, 0, 0, lw, lh, 0, 0, 0, 0); - pixbuf_draw_layout(pixbuf, layout, pw->dialog->dialog, 0, 0, r, g, b, 255); - g_object_unref(G_OBJECT(layout)); - - print_job_preview_page_image(pw, pixbuf, x, y, (gdouble)lw, (gdouble)lh, 0, 0); - g_object_unref(pixbuf); - - return TRUE; -} - -static gboolean print_job_preview_init(PrintWindow *pw) -{ - if (pw->job_pixbuf) g_object_unref(pw->job_pixbuf); - pw->job_pixbuf = image_get_pixbuf(pw->layout_image); - g_object_ref(pw->job_pixbuf); - - return print_job_preview_page_new(pw, pw->job_page); -} - - -/* - *----------------------------------------------------------------------------- - * wrappers - *----------------------------------------------------------------------------- - */ - -static gboolean print_job_page_new(PrintWindow *pw) -{ - switch (pw->job_format) - { - case RENDER_FORMAT_RGB: - return print_job_rgb_page_new(pw, pw->job_page); - case RENDER_FORMAT_PS: - return print_job_ps_page_new(pw, pw->job_page); - case RENDER_FORMAT_PREVIEW: - return print_job_preview_page_new(pw, pw->job_page); - } - - return FALSE; -} - -static gboolean print_job_page_done(PrintWindow *pw) -{ - switch (pw->job_format) - { - case RENDER_FORMAT_RGB: - return print_job_rgb_page_done(pw); - case RENDER_FORMAT_PS: - return print_job_ps_page_done(pw); - case RENDER_FORMAT_PREVIEW: - return print_job_preview_page_done(pw); - } - - return FALSE; -} - -static gboolean print_job_page_image(PrintWindow *pw, GdkPixbuf *pixbuf, - gdouble x, gdouble y, gdouble w, gdouble h, - gdouble offx, gdouble offy) -{ - gboolean success = FALSE; - - if (w <= 0.0 || h <= 0.0) return TRUE; - - switch (pw->job_format) - { - case RENDER_FORMAT_RGB: - success = print_job_rgb_page_image(pw, pixbuf, x, y, w, h, offx, offy); - break; - case RENDER_FORMAT_PS: - success = print_job_ps_page_image(pw, pixbuf, x, y, w, h, offx, offy); - break; - case RENDER_FORMAT_PREVIEW: - success = print_job_preview_page_image(pw, pixbuf, x, y, w, h, offx, offy); - break; - } - - return success; -} - -static gboolean print_job_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, - gdouble x, gdouble y, gdouble width, - guint8 r, guint8 g, guint8 b) -{ - gboolean success = TRUE; - - if (!text) return TRUE; - - switch (pw->job_format) - { - case RENDER_FORMAT_RGB: - success = print_job_rgb_page_text(pw, text, point_size, x, y, width, r, g, b); - break; - case RENDER_FORMAT_PS: - success = print_job_ps_page_text(pw, text, point_size, x, y, width, r, g, b); - break; - case RENDER_FORMAT_PREVIEW: - success = print_job_preview_page_text(pw, text, point_size, x, y, width, r, g, b); - break; - } - - return success; -} - -/* - *----------------------------------------------------------------------------- - * print ? - *----------------------------------------------------------------------------- - */ - -static gboolean print_job_render_image(PrintWindow *pw); -static gboolean print_job_render_proof(PrintWindow *pw); - - -static void print_job_status(PrintWindow *pw) -{ - gdouble value; - gint page; - gint total; - gchar *buf; - - if (!pw->job_progress) return; - - page = pw->job_page; - total = print_layout_page_count(pw); - - if (pw->layout == PRINT_LAYOUT_PROOF && pw->proof_point) - { - GList *start; - - start = g_list_first(pw->proof_point); - value = (gdouble)g_list_position(start, pw->proof_point) / g_list_length(start); - } - else - { - value = (total > 0) ? (gdouble)page / total : 0.0; - } - - buf = g_strdup_printf(_("Page %d"), page + 1); - gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pw->job_progress), buf); - g_free(buf); - - if (pw->job_path && pw->job_progress_label) - { - gtk_label_set_text(GTK_LABEL(pw->job_progress_label), pw->job_path); - } - - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pw->job_progress), value); -} - -static void print_job_throw_error(PrintWindow *pw, const gchar *message) -{ - GenericDialog *gd; - GtkWidget *parent = NULL; - GtkWidget *group; - GtkWidget *label; - gchar *buf; - - if (gtk_widget_get_visible(pw->dialog->dialog)) parent = pw->dialog->dialog; - - gd = generic_dialog_new(_("Printing error"), "print_warning", - parent, TRUE, NULL, NULL); - generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, NULL, TRUE); - - buf = g_strdup_printf(_("An error occurred printing to %s."), print_output_name(pw->output)); - generic_dialog_add_message(gd, GTK_STOCK_DIALOG_ERROR, _("Printing error"), buf, TRUE); - g_free(buf); - - group = pref_group_new(gd->vbox, FALSE, _("Details"), GTK_ORIENTATION_VERTICAL); - label = pref_label_new(group, message); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); - - gtk_widget_show(gd->dialog); -} - -static void print_job_done(PrintWindow *pw) -{ - print_job_close(pw, FALSE); -} - -static gboolean print_job_text_image(PrintWindow *pw, const gchar *path, - gdouble x, gdouble y, gdouble width, - gint sw, gint sh, gint proof) -{ - GString *string; - gboolean space = FALSE; - gboolean newline = FALSE; - gboolean ret; - - if (pw->text_fields == 0) return TRUE; - - string = g_string_new(""); - path = image_loader_get_fd(pw->job_loader)->path; - - if (pw->text_fields & TEXT_INFO_FILENAME) - { - if (pw->text_fields & TEXT_INFO_FILEPATH) - g_string_append(string, path); - else - g_string_append(string, filename_from_path(path)); - newline = TRUE; - } - else if (pw->text_fields & TEXT_INFO_FILEPATH) - { - gchar *dirname = g_path_get_dirname(path); - - g_string_append_printf(string, "%s%s", dirname, G_DIR_SEPARATOR_S); - g_free(dirname); - newline = TRUE; - } - if (pw->text_fields & TEXT_INFO_DIMENSIONS) - { - if (newline) g_string_append(string, "\n"); - g_string_append_printf(string, "%d x %d", (gint)sw, (gint)sh); - newline = proof; - space = !proof; - } - if (pw->text_fields & TEXT_INFO_FILEDATE) - { - if (newline) g_string_append(string, "\n"); - if (space) g_string_append(string, " - "); - g_string_append(string, text_from_time(filetime(image_loader_get_fd(pw->job_loader)->path))); - newline = proof; - space = !proof; - } - if (pw->text_fields & TEXT_INFO_FILESIZE) - { - gchar *size; - - if (newline) g_string_append(string, "\n"); - if (space) g_string_append(string, " - "); - size = text_from_size_abrev(filesize(image_loader_get_fd(pw->job_loader)->path)); - g_string_append(string, size); - g_free(size); - } - - ret = print_job_page_text(pw, string->str, pw->text_points, x, y, width, - pw->text_r, pw->text_g, pw->text_b); - - g_string_free(string, TRUE); - - return ret; -} - -static void print_job_render_image_loader_done(ImageLoader *il, gpointer data) -{ - PrintWindow *pw = data; - GdkPixbuf *pixbuf; - gboolean success = TRUE; - - pixbuf = image_loader_get_pixbuf(il); - if (pixbuf) - { - gdouble sw, sh; - gdouble dw, dh; - gdouble x, y, w, h; - gdouble offx, offy; - - sw = (gdouble)gdk_pixbuf_get_width(pixbuf); - sh = (gdouble)gdk_pixbuf_get_height(pixbuf); - - dw = pw->layout_width - pw->margin_left - pw->margin_right; - dh = pw->layout_height - pw->margin_top - pw->margin_bottom; - - if (dw / sw < dh / sh) - { - w = dw; - h = dw / sw * sh; - } - else - { - h = dh; - w = dh / sh *sw; - } - - if (pw->image_scale >= 5.0) - { - w = w * pw->image_scale / 100.0; - h = h * pw->image_scale / 100.0; - } - - x = pw->margin_left + (dw / 2) - (w / 2); - y = pw->margin_top + (dh / 2) - (h / 2); - - offx = offy = 0; - - if (x < 0) - { - w += x; - offx = x; - x = 0; - } - if (x + w >= pw->layout_width) w = pw->layout_width - x; - - if (y < 0) - { - h += y; - offy = y; - y = 0; - } - if (y + h >= pw->layout_height) h = pw->layout_height - y; - - success = (success && - print_job_page_image(pw, pixbuf, x, y, w, h, offx, offy)); - - x = x + w / 2; - y = y + h + PRINT_TEXT_PADDING; - - success = (success && - print_job_text_image(pw, image_loader_get_fd(pw->job_loader)->path, x, y, dw, sw, sh, FALSE)); - } - - image_loader_free(pw->job_loader); - pw->job_loader = NULL; - - if (pw->job_format == RENDER_FORMAT_PREVIEW) - { - print_job_done(pw); - return; - } - - success = (success && print_job_page_done(pw)); - if (!success) - { - print_job_close(pw, TRUE); - return; - } - - pw->job_page++; - print_job_status(pw); - - if (print_job_render_image(pw)) - { - if (!print_job_page_new(pw)) print_job_close(pw, TRUE); - } - else - { - print_job_done(pw); - } -} - -static gboolean print_job_render_image(PrintWindow *pw) -{ - FileData *fd = NULL; - - switch (pw->source) - { - case PRINT_SOURCE_SELECTION: - fd = g_list_nth_data(pw->source_selection, pw->job_page); - break; - case PRINT_SOURCE_ALL: - fd = g_list_nth_data(pw->source_list, pw->job_page); - break; - case PRINT_SOURCE_IMAGE: - default: - if (pw->job_page == 0) fd = pw->source_fd; - break; - } - - image_loader_free(pw->job_loader); - pw->job_loader = NULL; - - if (!fd) return FALSE; - - pw->job_loader = image_loader_new(fd); - g_signal_connect(G_OBJECT(pw->job_loader), "done", (GCallback)print_job_render_image_loader_done, pw); - if (!image_loader_start(pw->job_loader)) - { - image_loader_free(pw->job_loader); - pw->job_loader= NULL; - } - - return TRUE; -} - -static void print_job_render_proof_loader_done(ImageLoader *il, gpointer data) -{ - PrintWindow *pw = data; - GdkPixbuf *pixbuf; - gdouble x, y; - gdouble w, h; - gdouble proof_w, proof_h; - gdouble icon_w, icon_h; - gboolean success = TRUE; - - if (pw->proof_columns < 1 || pw->proof_rows < 1) - { - image_loader_free(pw->job_loader); - pw->job_loader = NULL; - - print_job_done(pw); - - return; - } - - pixbuf = image_loader_get_pixbuf(il); - - if (options->image.exif_proof_rotate_enable == TRUE) { - pixbuf = pixbuf_apply_orientation(pixbuf, il->fd->exif_orientation); - } - - w = gdk_pixbuf_get_width(pixbuf); - h = gdk_pixbuf_get_height(pixbuf); - - if (pw->proof_width / w < pw->proof_height / h) - { - icon_w = pw->proof_width; - icon_h = pw->proof_width / w * h; - } - else - { - icon_h = pw->proof_height; - icon_w = pw->proof_height / h * w; - } - - y = pw->proof_position / pw->proof_columns; - x = pw->proof_position - (y * pw->proof_columns); - - print_proof_size(pw, &proof_w, &proof_h); - - x *= proof_w; - y *= proof_h; - x += pw->margin_left + (pw->layout_width - pw->margin_left - pw->margin_right - (pw->proof_columns * proof_w)) / 2 + (proof_w - icon_w) / 2; - y += pw->margin_top + PRINT_PROOF_MARGIN + (pw->proof_height - icon_h) / 2; - - success = (success && - print_job_page_image(pw, pixbuf, x, y, icon_w, icon_h, 0, 0)); - - x = x + icon_w / 2; - y = y + icon_h + (pw->proof_height - icon_h) / 2 + PRINT_TEXT_PADDING; - - success = (success && - print_job_text_image(pw, image_loader_get_fd(pw->job_loader)->path, x, y, icon_w + PRINT_PROOF_MARGIN * 2, w, h, TRUE)); - - if (!success) - { - print_job_close(pw, TRUE); - return; - } - - if (pw->proof_point) pw->proof_point = pw->proof_point->next; - - pw->proof_position++; - if (pw->proof_position >= pw->proof_columns * pw->proof_rows) - { - if (pw->job_format == RENDER_FORMAT_PREVIEW) - { - print_job_done(pw); - return; - } - - if (!print_job_page_done(pw)) - { - print_job_close(pw, TRUE); - return; - } - - pw->proof_position = 0; - pw->job_page++; - if (print_job_render_proof(pw)) - { - if (!print_job_page_new(pw)) - { - print_job_close(pw, TRUE); - return; - } - print_job_status(pw); - } - else - { - print_job_done(pw); - } - } - else - { - if (print_job_render_proof(pw)) - { - print_job_status(pw); - } - else - { - if (print_job_page_done(pw)) - { - print_job_done(pw); - } - else - { - print_job_close(pw, TRUE); - } - } - } -} - -static gboolean print_job_render_proof(PrintWindow *pw) -{ - FileData *fd = NULL; - - if (pw->proof_columns < 1 || pw->proof_rows < 1) return FALSE; - - if (!pw->proof_point && pw->proof_position == 0 && pw->source == PRINT_SOURCE_IMAGE) - { - fd = pw->source_fd; - } - else if (pw->proof_point && - pw->proof_position < pw->proof_columns * pw->proof_rows) - { - fd = pw->proof_point->data; - } - - if (!fd) return FALSE; - - image_loader_free(pw->job_loader); - pw->job_loader = image_loader_new(fd); - g_signal_connect(G_OBJECT(pw->job_loader), "done", (GCallback)print_job_render_proof_loader_done, pw); - if (!image_loader_start(pw->job_loader)) - { - image_loader_free(pw->job_loader); - pw->job_loader = NULL; - } - - return TRUE; -} - -static void print_job_render(PrintWindow *pw) -{ - gdouble proof_w, proof_h; - gboolean finished; - - pw->proof_position = 0; - - switch (pw->source) - { - case PRINT_SOURCE_SELECTION: - pw->proof_point = pw->source_selection; - break; - case PRINT_SOURCE_ALL: - pw->proof_point = pw->source_list; - break; - case PRINT_SOURCE_IMAGE: - default: - pw->proof_point = NULL; - break; - } - - print_proof_size(pw, &proof_w, &proof_h); - pw->proof_columns = (pw->layout_width - pw->margin_left - pw->margin_right) / proof_w; - pw->proof_rows = (pw->layout_height - pw->margin_top - pw->margin_bottom) / proof_h; - - if (pw->job_format == RENDER_FORMAT_PREVIEW) - { - gint total; - - total = print_layout_page_count(pw); - if (pw->job_page < 0 || pw->job_page >= total) - { - print_job_done(pw); - return; - } - - if (pw->proof_point && pw->job_page > 0) - { - pw->proof_point = g_list_nth(pw->proof_point, pw->job_page * pw->proof_columns * pw->proof_rows); - } - } - - if (!print_job_page_new(pw)) - { - print_job_close(pw, TRUE); - return; - } - - if (pw->layout == PRINT_LAYOUT_IMAGE) - { - finished = !print_job_render_image(pw); - } - else - { - finished = !print_job_render_proof(pw); - } - - if (finished) print_job_done(pw); -} - -static gboolean print_job_init(PrintWindow *pw) -{ - gboolean success = FALSE; - - pw->job_page = 0; - - switch (pw->job_format) - { - case RENDER_FORMAT_RGB: - success = print_job_rgb_init(pw); - break; - case RENDER_FORMAT_PS: - success = print_job_ps_init(pw); - break; - case RENDER_FORMAT_PREVIEW: - pw->job_page = pw->proof_page; - success = print_job_preview_init(pw); - break; - } - - return success; -} - -static gboolean print_job_finish(PrintWindow *pw) -{ - gboolean success = FALSE; - - switch (pw->job_format) - { - case RENDER_FORMAT_RGB: - success = TRUE; - break; - case RENDER_FORMAT_PS: - print_job_ps_end(pw); - break; - case RENDER_FORMAT_PREVIEW: - success = TRUE; - break; - } - - return success; -} - -static void print_job_close_file(PrintWindow *pw) -{ - if (pw->job_file) - { - fclose(pw->job_file); - pw->job_file = NULL; - } - - if (pw->job_pipe) - { - PipeError *pe; - - pe = pipe_handler_new(); - pclose(pw->job_pipe); - pipe_handler_free(pe); - - pw->job_pipe = NULL; - } -} - -static gboolean print_job_close_finish_cb(gpointer data) -{ - PrintWindow *pw = data; - - print_window_close(pw); - return FALSE; -} - -static void print_job_close(PrintWindow *pw, gint error) -{ - if (!error) print_job_finish(pw); - - print_job_close_file(pw); - g_free(pw->job_path); - pw->job_path = NULL; - - if (pw->job_dialog) - { - generic_dialog_close(pw->job_dialog); - pw->job_dialog = NULL; - pw->job_progress = NULL; - } - - image_loader_free(pw->job_loader); - pw->job_loader = NULL; - - if (pw->job_pixbuf) - { - g_object_unref(pw->job_pixbuf); - pw->job_pixbuf = NULL; - } - - if (pw->dialog && !gtk_widget_get_visible(pw->dialog->dialog)) - { - g_idle_add_full(G_PRIORITY_HIGH_IDLE, print_job_close_finish_cb, pw, NULL); - } -} - -static void print_job_cancel_cb(GenericDialog *gd, gpointer data) -{ - PrintWindow *pw = data; - - print_job_close(pw, FALSE); -} - -static void print_pref_store(PrintWindow *pw) -{ - - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_SAVE, pw->save_settings); - - if (!pw->save_settings) return; - - /* only store values that are actually used in this print job, hence the if()s */ - - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_OUTPUT, pw->output); - - if (pw->output == PRINT_OUTPUT_RGB_FILE) - { - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_FORMAT, pw->output_format); - } - - if (pw->job_format == RENDER_FORMAT_PS) - { - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_DPI, pw->max_dpi); - } - - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_UNITS, pw->paper_units); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_SIZE, pw->paper_size); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_ORIENTATION, pw->paper_orientation); - - if (pw->paper_size == 0) - { - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_CUSTOM_WIDTH, pw->paper_width); - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_CUSTOM_HEIGHT, pw->paper_height); - } - - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_LEFT, pw->margin_left); - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_RIGHT, pw->margin_right); - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_TOP, pw->margin_top); - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_MARGIN_BOTTOM, pw->margin_bottom); - - if (pw->layout == PRINT_LAYOUT_PROOF) - { - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_PROOF_WIDTH, pw->proof_width); - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_PROOF_HEIGHT, pw->proof_height); - } - - if (pw->output == PRINT_OUTPUT_PS_CUSTOM) - { - pref_list_string_set(PRINT_PREF_GROUP, PRINT_PREF_PRINTERC, pw->output_custom); - } - - if (pw->output == PRINT_OUTPUT_RGB_FILE || - pw->output == PRINT_OUTPUT_PS_FILE) - { - tab_completion_append_to_history(pw->path_entry, pw->output_path); - } - - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_TEXT, pw->text_fields); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_TEXTSIZE, pw->text_points); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_TEXTCOLOR_R, pw->text_r); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_TEXTCOLOR_G, pw->text_g); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_TEXTCOLOR_B, pw->text_b); - - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_SOURCE, pw->source); - pref_list_int_set(PRINT_PREF_GROUP, PRINT_PREF_LAYOUT, pw->layout); - - pref_list_double_set(PRINT_PREF_GROUP, PRINT_PREF_IMAGE_SCALE, pw->image_scale); -} - -static gboolean print_job_start(PrintWindow *pw, RenderFormat format, PrintOutput output) -{ - GtkWidget *hbox; - GtkWidget *spinner; - gchar *msg; - - if (pw->job_dialog) return FALSE; - - pw->job_format = format; - pw->job_output = output; - - if (!print_job_init(pw)) - { - print_job_close(pw, TRUE); - return FALSE; - } - - if (format == RENDER_FORMAT_PREVIEW) - { - print_job_render(pw); - return TRUE; - } - - print_pref_store(pw); - - gtk_widget_hide(pw->dialog->dialog); - - pw->job_dialog = file_util_gen_dlg(_("Print"), "print_job_dialog", - (GtkWidget *)gtk_window_get_transient_for(GTK_WINDOW(pw->dialog->dialog)), FALSE, - print_job_cancel_cb, pw); - - msg = g_strdup_printf(_("Printing %d pages to %s."), print_layout_page_count(pw), print_output_name(pw->output)); - generic_dialog_add_message(pw->job_dialog, NULL, msg, NULL, TRUE); - g_free(msg); - - if (pw->job_output == PRINT_OUTPUT_PS_FILE || - pw->job_output == PRINT_OUTPUT_RGB_FILE) - { - hbox = pref_box_new(pw->job_dialog->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); - pref_label_new(hbox, _("Filename:")); - - pw->job_progress_label = pref_label_new(hbox, ""); - } - else - { - pw->job_progress_label = NULL; - } - - pref_spacer(pw->job_dialog->vbox, PREF_PAD_SPACE); - - hbox = pref_box_new(pw->job_dialog->vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); - - pw->job_progress = gtk_progress_bar_new(); - gtk_box_pack_start(GTK_BOX(hbox), pw->job_progress, TRUE, TRUE, 0); - gtk_widget_show(pw->job_progress); - - spinner = spinner_new(NULL, SPINNER_SPEED); - gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); - gtk_widget_show(spinner); - - gtk_widget_show(pw->job_dialog->dialog); - - print_job_render(pw); - print_job_status(pw); - - return TRUE; -} - -static void print_window_print_start(PrintWindow *pw) -{ - RenderFormat format; - - switch (pw->output) - { - case PRINT_OUTPUT_RGB_FILE: - format = RENDER_FORMAT_RGB; - break; - case PRINT_OUTPUT_PS_FILE: - case PRINT_OUTPUT_PS_CUSTOM: - case PRINT_OUTPUT_PS_LPR: - default: - format = RENDER_FORMAT_PS; - break; - } - - print_job_start(pw, format, pw->output); -} - - -/* - *----------------------------------------------------------------------------- - * combo box util - *----------------------------------------------------------------------------- - */ - -static GtkWidget *print_combo_menu(const gchar *text[], gint count, gint preferred, - GCallback func, gpointer data) -{ - GtkWidget *combo; - gint i; - - combo = gtk_combo_box_text_new(); - - for (i = 0 ; i < count; i++) - { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(text[i])); - } - - if (preferred >= 0 && preferred < count) - { - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), preferred); - } - - if (func) g_signal_connect(G_OBJECT(combo), "changed", func, data); - - return combo; -} - - -/* - *----------------------------------------------------------------------------- - * paper selection - *----------------------------------------------------------------------------- - */ - -static GtkWidget *print_paper_menu(GtkWidget *table, gint column, gint row, - PaperOrientation preferred, GCallback func, gpointer data) -{ - GtkWidget *combo; - gint i; - - pref_table_label(table, column, row, (_("Format:")), 1.0); - - combo = gtk_combo_box_text_new(); - - i = 0; - while (print_paper_sizes[i].description) - { - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(print_paper_sizes[i].description)); - i++; - } - - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), preferred); - if (func) g_signal_connect(G_OBJECT(combo), "changed", func, data); - - gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); - - return combo; -} - -static void print_paper_select_cb(GtkWidget *combo, gpointer data) -{ - PrintWindow *pw = data; - PaperSize *ps; - gint n; - - n = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); - ps = print_paper_size_nth(n); - - if (!ps) return; - - pw->paper_size = n; - - if (pw->paper_size == 0) - { - print_window_layout_sync_paper(pw); - return; - } - - if (ps->orientation == PAPER_ORIENTATION_PORTRAIT) - { - print_window_layout_set_size(pw, ps->width, ps->height); - } - else - { - print_window_layout_set_size(pw, ps->height, ps->width); - } -} - -static void print_paper_size_cb(GtkWidget *spin, gpointer data) -{ - PrintWindow *pw = data; - gdouble value; - - value = print_paper_size_convert_units(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)), - pw->paper_units, PAPER_UNIT_POINTS); - - if (spin == pw->paper_width_spin) - { - pw->paper_width = value; - } - else - { - pw->paper_height = value; - } - - print_window_layout_set_size(pw, pw->paper_width, pw->paper_height); -} - -static GtkWidget *print_paper_units_menu(GtkWidget *table, gint column, gint row, - PaperUnits units, GCallback func, gpointer data) -{ - GtkWidget *combo; - - pref_table_label(table, column, row, (_("Units:")), 1.0); - - combo = print_combo_menu(print_paper_units, PAPER_UNIT_COUNT, units, func, data); - - gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); - - return combo; -} - -static void print_paper_units_set(PrintWindow *pw, PaperUnits units) -{ - PaperUnits old_units; - - if (units >= PAPER_UNIT_COUNT) return; - - old_units = pw->paper_units; - pw->paper_units = units; - print_window_layout_sync_paper(pw); - - if ((units == PAPER_UNIT_MM || units == PAPER_UNIT_CM) != - (old_units == PAPER_UNIT_MM || old_units == PAPER_UNIT_CM)) - { - print_window_layout_render(pw); - } -} - -static void print_paper_units_cb(GtkWidget *combo, gpointer data) -{ - PrintWindow *pw = data; - PaperUnits units; - - units = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); - - print_paper_units_set(pw, units); -} - -static GtkWidget *print_paper_orientation_menu(GtkWidget *table, gint column, gint row, - PaperOrientation preferred, - GCallback func, gpointer data) -{ - GtkWidget *combo; - - pref_table_label(table, column, row, (_("Orientation:")), 1.0); - - combo = print_combo_menu(print_paper_orientation, PAPER_ORIENTATION_COUNT, preferred, func, data); - - gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); - - return combo; -} - -static void print_paper_orientation_cb(GtkWidget *combo, gpointer data) -{ - PrintWindow *pw = data; - PaperOrientation o; - - o = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); - - print_window_layout_set_orientation(pw, o); -} - -static void print_paper_margin_cb(GtkWidget *spin, gpointer data) -{ - PrintWindow *pw = data; - gdouble value; - - value = print_paper_size_convert_units(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)), - pw->paper_units, PAPER_UNIT_POINTS); - - if (spin == pw->margin_left_spin) - { - pw->margin_left = CLAMP(value, 0.0, pw->paper_width); - } - else if (spin == pw->margin_right_spin) - { - pw->margin_right = CLAMP(value, 0.0, pw->paper_width); - } - else if (spin == pw->margin_top_spin) - { - pw->margin_top = CLAMP(value, 0.0, pw->paper_height); - } - else if (spin == pw->margin_bottom_spin) - { - pw->margin_bottom = CLAMP(value, 0.0, pw->paper_height); - } - - print_window_layout_set_size(pw, pw->paper_width, pw->paper_height); -} - -static GtkWidget *print_misc_menu(GtkWidget *parent_box, gint preferred, - const gchar *title, const gchar *key, - gint count, const gchar **text, - GCallback func, gpointer data) -{ - GtkWidget *box; - GtkWidget *button = NULL; - gint i; - - box = pref_group_new(parent_box, FALSE, title, GTK_ORIENTATION_VERTICAL); - - for (i = 0; i < count; i++) - { - button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), _(text[i])); - if (i == preferred) - { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); - } - g_object_set_data(G_OBJECT(button), key, GINT_TO_POINTER(i)); - if (func) g_signal_connect(G_OBJECT(button), "clicked", func, data); - gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0); - gtk_widget_show(button); - } +/* method to use when scaling down image data */ +#define PRINT_MAX_INTERP GDK_INTERP_HYPER - return box; -} +typedef enum { + TEXT_INFO_FILENAME = 1 << 0, + TEXT_INFO_FILEDATE = 1 << 1, + TEXT_INFO_FILESIZE = 1 << 2, + TEXT_INFO_DIMENSIONS = 1 << 3, + TEXT_INFO_FILEPATH = 1 << 4 +} TextInfo; -static void print_source_select_cb(GtkWidget *widget, gpointer data) +typedef struct _PrintWindow PrintWindow; +struct _PrintWindow { - PrintWindow *pw = data; + GtkWidget *vbox; + GList *source_selection; - if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return; + TextInfo text_fields; + gint job_page; + ImageLoader *job_loader; - pw->source = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "print_source")); - print_window_layout_size(pw); -} + GList *print_pixbuf_queue; + gboolean job_render_finished; +}; -static void print_layout_select_cb(GtkWidget *widget, gpointer data) +static gint print_layout_page_count(PrintWindow *pw) { - PrintWindow *pw = data; + gint images; - if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return; + images = g_list_length(pw->source_selection); - pw->layout = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "print_layout")); + if (images < 1 ) return 0; - print_window_layout_sync_layout(pw); - print_window_layout_size(pw); + return images; } -static void print_image_scale_cb(GtkWidget *spin, gpointer data) -{ - PrintWindow *pw = data; - - pw->image_scale = gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)); - - print_window_layout_set_size(pw, pw->paper_width, pw->paper_height); -} +static gboolean print_job_render_image(PrintWindow *pw); -static void print_proof_size_cb(GtkWidget *spin, gpointer data) +static void print_job_render_image_loader_done(ImageLoader *il, gpointer data) { PrintWindow *pw = data; - gdouble value; - - value = print_paper_size_convert_units(gtk_spin_button_get_value(GTK_SPIN_BUTTON(spin)), - pw->paper_units, PAPER_UNIT_POINTS); - - if (spin == pw->proof_width_spin) - { - pw->proof_width = value; - } - else - { - pw->proof_height = value; - } - - print_window_layout_render(pw); -} - -static GtkWidget *print_output_menu(GtkWidget *table, gint column, gint row, - PrintOutput preferred, GCallback func, gpointer data) -{ - GtkWidget *combo; - - pref_table_label(table, column, row, (_("Destination:")), 1.0); - - combo = print_combo_menu(print_output_text, PRINT_OUTPUT_COUNT, preferred, func, data); - - gtk_table_attach(GTK_TABLE(table), combo, column + 1, column + 2, row, row + 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); - - return combo; -} - -static void print_custom_entry_set(PrintWindow *pw, GtkWidget *combo) -{ - GtkListStore *store; - const gchar *text; - GList *list; - GList *work; - - store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))); - gtk_list_store_clear(store); - - list = print_window_list_printers(); - work = list; - while (work) - { - gchar *name; - gchar *buf; - - name = work->data; - work = work->next; - - buf = g_strdup_printf(PRINT_LPR_CUSTOM, name); - gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), buf); - g_free(buf); - } - string_list_free(list); + GdkPixbuf *pixbuf; - if (pref_list_string_get(PRINT_PREF_GROUP, PRINT_PREF_PRINTERC, &text)) - { - gtk_entry_set_text(GTK_ENTRY(pw->custom_entry), text); - } - else - { - text = gtk_entry_get_text(GTK_ENTRY(pw->custom_entry)); - if (!text || strlen(text) == 0) - { - gchar *buf; + pixbuf = image_loader_get_pixbuf(il); - buf = g_strdup_printf(PRINT_LPR_CUSTOM, _("")); - gtk_entry_set_text(GTK_ENTRY(pw->custom_entry), buf); - g_free(buf); - } - } -} + g_object_ref(pixbuf); + pw->print_pixbuf_queue = g_list_append(pw->print_pixbuf_queue, pixbuf); -static void print_output_set(PrintWindow *pw, PrintOutput output) -{ - gboolean use_file = FALSE; - gboolean use_custom = FALSE; - gboolean use_format = FALSE; + image_loader_free(pw->job_loader); + pw->job_loader = NULL; - pw->output = output; + pw->job_page++; - switch (pw->output) + if (!print_job_render_image(pw)) { - case PRINT_OUTPUT_RGB_FILE: - use_file = TRUE; - use_format = TRUE; - break; - case PRINT_OUTPUT_PS_FILE: - use_file = TRUE; - break; - case PRINT_OUTPUT_PS_CUSTOM: - use_custom = TRUE; - break; - case PRINT_OUTPUT_PS_LPR: - default: - break; + pw->job_render_finished = TRUE; } - - gtk_widget_set_sensitive(gtk_widget_get_parent(pw->path_entry), use_file); - gtk_widget_set_sensitive(gtk_widget_get_parent(pw->custom_entry), use_custom); - gtk_widget_set_sensitive(pw->path_format_menu, use_format); - gtk_widget_set_sensitive(pw->max_dpi_menu, !use_format); -} - -static void print_output_cb(GtkWidget *combo, gpointer data) -{ - PrintWindow *pw = data; - PrintOutput output; - - output = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); - - print_output_set(pw, output); } -static GtkWidget *print_output_format_menu(GtkWidget * table, gint column, gint row, - PrintFileFormat preferred, GCallback func, gpointer data) -{ - GtkWidget *combo; - - combo = print_combo_menu(print_file_format_text, PRINT_FILE_COUNT, preferred, func, data); - - gtk_table_attach(GTK_TABLE(table), combo, column, column + 1, row, row + 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); - - return combo; -} - -static void print_output_format_cb(GtkWidget *combo, gpointer data) +static gboolean print_job_render_image(PrintWindow *pw) { - PrintWindow *pw = data; + FileData *fd = NULL; - pw->output_format = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); -} + fd = g_list_nth_data(pw->source_selection, pw->job_page); + if (!fd) return FALSE; -static GtkWidget *print_output_dpi_menu(GtkWidget * table, gint column, gint row, - gdouble dpi, GCallback func, gpointer data) -{ - static gint dpilist[] = { 150, 300, 600, 1200, 0, -1}; - GtkWidget *combo; - GtkListStore *store; - GtkCellRenderer *renderer; - gint current = 1; - gint i; + image_loader_free(pw->job_loader); + pw->job_loader = NULL; - store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); + pw->job_loader = image_loader_new(fd); + g_signal_connect(G_OBJECT(pw->job_loader), "done", + (GCallback)print_job_render_image_loader_done, pw); - i = 0; - while (dpilist[i] != -1) + if (!image_loader_start(pw->job_loader)) { - GtkTreeIter iter; - gchar *text; - - if (dpilist[i] == 0) - { - text = g_strdup(_("Unlimited")); - } - else - { - text = g_strdup_printf("%d", dpilist[i]); - } - - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, text, 1, dpilist[i], -1); - g_free(text); - - if (dpi == (gdouble)dpilist[i]) current = i; - - i++; + image_loader_free(pw->job_loader); + pw->job_loader= NULL; } - combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); - g_object_unref(store); - - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), current); - if (func) g_signal_connect(G_OBJECT(combo), "changed", func, data); - - renderer = gtk_cell_renderer_text_new(); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE); - gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", 0, NULL); - - gtk_table_attach(GTK_TABLE(table), combo, column, column + 1, row, row + 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); - - return combo; -} - -static void print_output_dpi_cb(GtkWidget *combo, gpointer data) -{ - PrintWindow *pw = data; - GtkTreeModel *store; - GtkTreeIter iter; - gint n = -1; - - store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo)); - if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) return; - gtk_tree_model_get(store, &iter, 1, &n, -1); - - pw->max_dpi = (gdouble)n; + return TRUE; } static void print_text_field_set(PrintWindow *pw, TextInfo field, gboolean active) @@ -3143,8 +121,6 @@ static void print_text_field_set(PrintWindow *pw, TextInfo field, gboolean activ { pw->text_fields &= ~field; } - - print_window_layout_render(pw); } static void print_text_cb_name(GtkWidget *widget, gpointer data) @@ -3192,17 +168,39 @@ static void print_text_cb_dims(GtkWidget *widget, gpointer data) print_text_field_set(pw, TEXT_INFO_DIMENSIONS, active); } -static void print_text_cb_points(GtkWidget *widget, gpointer data) +static void print_set_font_cb(GtkWidget *widget, gpointer data) { - PrintWindow *pw = data; +#if GTK_CHECK_VERSION(3,4,0) + GtkWidget *dialog; + char *font; + PangoFontDescription *font_desc; + + dialog = gtk_font_chooser_dialog_new("Printer Font", GTK_WINDOW(gtk_widget_get_toplevel(widget))); + gtk_font_chooser_set_font(GTK_FONT_CHOOSER(dialog), options->printer.font); - pw->text_points = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget)); - print_window_layout_render(pw); + if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_CANCEL) + { + font_desc = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(dialog)); + font = pango_font_description_to_string(font_desc); + g_free(options->printer.font); + options->printer.font = g_strdup(font); + g_free(font); + } + + gtk_widget_destroy(dialog); +#else + const char *font; + + font = gtk_font_button_get_font_name(GTK_FONT_BUTTON(widget)); + options->printer.font = g_strdup(font); +#endif } static void print_text_menu(GtkWidget *box, PrintWindow *pw) { GtkWidget *group; + GtkWidget *hbox; + GtkWidget *button; group = pref_group_new(box, FALSE, _("Show"), GTK_ORIENTATION_VERTICAL); @@ -3219,290 +217,365 @@ static void print_text_menu(GtkWidget *box, PrintWindow *pw) group = pref_group_new(box, FALSE, _("Font"), GTK_ORIENTATION_VERTICAL); - pref_spin_new(group, _("Size:"), _("points"), - 8.0, 100.0, 1.0, 0, pw->text_points, - G_CALLBACK(print_text_cb_points), pw); -} + hbox = pref_box_new(group, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_BUTTON_GAP); -/* - *----------------------------------------------------------------------------- - * print window - *----------------------------------------------------------------------------- - */ +#if GTK_CHECK_VERSION(3,4,0) + button = pref_button_new(NULL, GTK_STOCK_SELECT_FONT, _("Font"), FALSE, + G_CALLBACK(print_set_font_cb), pw); +#else + button = gtk_font_button_new(); + gtk_font_button_set_title(GTK_FONT_BUTTON(button), "Printer Font"); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(button), options->printer.font); + g_signal_connect(G_OBJECT(button), "font-set", + G_CALLBACK(print_set_font_cb),NULL); +#endif + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); + gtk_widget_show(button); +} -static void print_window_close(PrintWindow *pw) +static gboolean paginate_cb(GtkPrintOperation *operation, + GtkPrintContext *context, + gpointer data) { - print_window_layout_render_stop(pw); - - generic_dialog_close(pw->dialog); - pw->dialog = NULL; + PrintWindow *pw = data; - print_job_close(pw, FALSE); + if (pw->job_render_finished) + { + return TRUE; + } + else + { + return FALSE; + } +} - file_data_unref(pw->source_fd); - filelist_free(pw->source_selection); - filelist_free(pw->source_list); +/* Returns the "depth" of a layout, that is the distance from the + * top of the layout to the baseline of the first line in the + * layout. */ +int get_layout_depth(PangoLayout *layout) +{ + PangoLayoutLine *layout_line = pango_layout_get_line(layout,0); + PangoRectangle rect; - g_free(pw->output_path); - g_free(pw->output_custom); + pango_layout_line_get_extents(layout_line, NULL, &rect); - g_free(pw); + return PANGO_ASCENT(rect); } -static void print_window_print_cb(GenericDialog *gd, gpointer data) +static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, + gint page_nr, gpointer data) { + FileData *fd; PrintWindow *pw = data; + cairo_t *cr; + gdouble width, height; + gdouble width_pixbuf_image, height_pixbuf_image; + gdouble width_offset; + gdouble height_offset; + GdkPixbuf *pixbuf; + GdkPixbuf *pixbuf_scaled; + PangoLayout *layout; + PangoFontDescription *desc; + GString *text = g_string_new(NULL); + PangoRectangle ink_rect, logical_rect; + gdouble depth; + gdouble text_padding; + gdouble x, y, w, h, scale; + gdouble pango_height; + + pixbuf = g_list_nth_data(pw->print_pixbuf_queue, page_nr); + width_pixbuf_image = gdk_pixbuf_get_width(pixbuf); + height_pixbuf_image = gdk_pixbuf_get_height(pixbuf); - switch (pw->output) + fd = g_list_nth_data(pw->source_selection, page_nr); + + if (pw->text_fields & TEXT_INFO_FILENAME) + { + text = g_string_append(text, g_strdup(fd->name)); + text = g_string_append(text, "\n"); + } + if (pw->text_fields & TEXT_INFO_FILEDATE) + { + text = g_string_append(text, g_strdup(text_from_time(fd->date))); + text = g_string_append(text, "\n"); + } + if (pw->text_fields & TEXT_INFO_FILESIZE) { - case PRINT_OUTPUT_RGB_FILE: - case PRINT_OUTPUT_PS_FILE: - g_free(pw->output_path); - pw->output_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->path_entry))); - break; - case PRINT_OUTPUT_PS_CUSTOM: - g_free(pw->output_custom); - pw->output_custom = g_strdup(gtk_entry_get_text(GTK_ENTRY(pw->custom_entry))); - break; - case PRINT_OUTPUT_PS_LPR: - default: - break; + text = g_string_append(text, g_strdup(text_from_size(fd->size))); + text = g_string_append(text, "\n"); + } + if (pw->text_fields & TEXT_INFO_DIMENSIONS) + { + g_string_append_printf(text, "%d x %d", (gint)width_pixbuf_image, + (gint)height_pixbuf_image); + text = g_string_append(text, "\n"); + } + if (pw->text_fields & TEXT_INFO_FILEPATH) + { + text = g_string_append(text, g_strdup(fd->path)); + text = g_string_append(text, "\n"); } - print_window_print_start(pw); -} + cr = gtk_print_context_get_cairo_context(context); + width = gtk_print_context_get_width(context); + height = gtk_print_context_get_height(context); -static void print_window_cancel_cb(GenericDialog *gd, gpointer data) -{ - PrintWindow *pw = data; + if (text->len > 0) + { + text = g_string_truncate(text, text->len - 1); - print_window_close(pw); -} + layout = pango_cairo_create_layout(cr); -static gint print_pref_int(const gchar *key, gint fallback) -{ - gint value; + pango_layout_set_text(layout, text->str, -1); + desc = pango_font_description_from_string(options->printer.font); + pango_layout_set_font_description(layout, desc); - if (pref_list_int_get(PRINT_PREF_GROUP, key, &value)) return value; - return fallback; -} + pango_layout_get_extents(layout, &ink_rect, &logical_rect); + x = ((gdouble)logical_rect.width / PANGO_SCALE) ; + y = ((gdouble)logical_rect.height / PANGO_SCALE); -static gdouble print_pref_double(const gchar *key, gdouble fallback) -{ - gdouble value; + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); + pango_layout_set_text(layout, text->str, -1); - if (pref_list_double_get(PRINT_PREF_GROUP, key, &value)) return value; - return fallback; -} + depth = (gdouble)get_layout_depth(layout); + text_padding = depth / 2 / PANGO_SCALE ; -void print_window_new(FileData *fd, GList *selection, GList *list, GtkWidget *parent) -{ - PrintWindow *pw; - GdkGeometry geometry; - GtkWidget *main_box; - GtkWidget *vbox; - GtkWidget *label; - GtkWidget *combo; - GtkWidget *box; - GtkWidget *table; + pango_height = y + text_padding * 2; - pw = g_new0(PrintWindow, 1); + } + else + { + pango_height = 0; + depth = 0; + text_padding = 0; + x = 0; + y = 0; + } - pw->source_fd = file_data_ref(fd); - pw->source_selection = file_data_process_groups_in_selection(selection, FALSE, NULL); - pw->source_list = list; + if ((width / width_pixbuf_image) < ((height - pango_height) / height_pixbuf_image)) + { + w = width; + scale = width / width_pixbuf_image; + h = height_pixbuf_image * scale; + height_offset = (height - (h + pango_height)) / 2; + width_offset = 0; + } + else + { + h = height - pango_height ; + scale = (height - pango_height) / height_pixbuf_image; + w = width_pixbuf_image * scale; + height_offset = 0; + width_offset = (width - (width_pixbuf_image * scale)) / 2; + } - pw->source = print_pref_int(PRINT_PREF_SOURCE, PRINT_SOURCE_SELECTION); - pw->layout = print_pref_int(PRINT_PREF_LAYOUT, PRINT_LAYOUT_IMAGE); + if (text->len > 0) + { + cairo_move_to(cr, (w / 2) - (x / 2) + width_offset, h + height_offset + text_padding); + pango_cairo_show_layout(cr, layout); + } - pw->image_scale = print_pref_double(PRINT_PREF_IMAGE_SCALE, 100.0); + pixbuf_scaled = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h); + gdk_pixbuf_scale(pixbuf, pixbuf_scaled, 0, 0, w, h, 0, 0, scale, scale, PRINT_MAX_INTERP); - pw->output = print_pref_int(PRINT_PREF_OUTPUT, PRINT_OUTPUT_PS_LPR); - pw->output_format = print_pref_int(PRINT_PREF_FORMAT, PRINT_FILE_JPG_NORMAL); + cairo_rectangle(cr, width_offset, height_offset, w, h); - pw->max_dpi = print_pref_double(PRINT_PREF_DPI, PRINT_PS_DPI_DEFAULT); + gdk_cairo_set_source_pixbuf(cr, pixbuf_scaled, width_offset, height_offset); + cairo_fill(cr); - pw->paper_units = print_pref_int(PRINT_PREF_UNITS, paper_unit_default()); - pw->paper_size = print_pref_int(PRINT_PREF_SIZE, 1); - if (pw->paper_size == 0 || - !print_paper_size_lookup(pw->paper_size, &pw->paper_width, &pw->paper_height)) + if (text->len > 0) { - pw->paper_width = print_pref_double(PRINT_PREF_CUSTOM_WIDTH, 360.0); - pw->paper_height = print_pref_double(PRINT_PREF_CUSTOM_HEIGHT, 720.0); + g_object_unref(layout); + g_string_free(text, TRUE); + pango_font_description_free(desc); } - pw->paper_orientation = print_pref_int(PRINT_PREF_ORIENTATION, PAPER_ORIENTATION_PORTRAIT); - pw->margin_left = print_pref_double(PRINT_PREF_MARGIN_LEFT, PRINT_MARGIN_DEFAULT); - pw->margin_right = print_pref_double(PRINT_PREF_MARGIN_RIGHT, PRINT_MARGIN_DEFAULT); - pw->margin_top = print_pref_double(PRINT_PREF_MARGIN_TOP, PRINT_MARGIN_DEFAULT); - pw->margin_bottom = print_pref_double(PRINT_PREF_MARGIN_BOTTOM, PRINT_MARGIN_DEFAULT); + g_object_unref(pixbuf_scaled); - pw->proof_width = print_pref_double(PRINT_PREF_PROOF_WIDTH, PRINT_PROOF_DEFAULT_SIZE); - pw->proof_height = print_pref_double(PRINT_PREF_PROOF_HEIGHT, PRINT_PROOF_DEFAULT_SIZE); + return; +} - pw->text_fields = print_pref_int(PRINT_PREF_TEXT, TEXT_INFO_FILENAME); - pw->text_points = print_pref_int(PRINT_PREF_TEXTSIZE, 10); - pw->text_r = print_pref_int(PRINT_PREF_TEXTCOLOR_R, 0); - pw->text_g = print_pref_int(PRINT_PREF_TEXTCOLOR_G, 0); - pw->text_b = print_pref_int(PRINT_PREF_TEXTCOLOR_B, 0); +static void begin_print(GtkPrintOperation *operation, + GtkPrintContext *context, + gpointer user_data) +{ + PrintWindow *pw = user_data; + gint page_count; - pw->save_settings = print_pref_int(PRINT_PREF_SAVE, TRUE); + page_count = print_layout_page_count(pw); + gtk_print_operation_set_n_pages (operation, page_count); - pw->dialog = file_util_gen_dlg(_("Print"), "print_dialog", - parent, FALSE, - print_window_cancel_cb, pw); + print_job_render_image(pw); +} - geometry.min_width = DEFAULT_MINIMAL_WINDOW_SIZE; - geometry.min_height = DEFAULT_MINIMAL_WINDOW_SIZE; - geometry.base_width = PRINT_DLG_WIDTH; - geometry.base_height = PRINT_DLG_HEIGHT; - gtk_window_set_geometry_hints(GTK_WINDOW(pw->dialog->dialog), NULL, &geometry, - GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); - pw->print_button = generic_dialog_add_button(pw->dialog, GTK_STOCK_PRINT, NULL, print_window_print_cb, TRUE); +GObject *option_tab_cb(GtkPrintOperation *operation, gpointer user_data) +{ + PrintWindow *pw = user_data; - main_box = pref_box_new(pw->dialog->vbox, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); + return G_OBJECT(pw->vbox); +} - pw->notebook = gtk_notebook_new(); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(pw->notebook), GTK_POS_TOP); - gtk_box_pack_start(GTK_BOX(main_box), pw->notebook, FALSE, FALSE, 0); +static void print_pref_store(PrintWindow *pw) +{ + options->printer.text_fields = pw->text_fields; +} - /* layout tab */ +static void end_print_cb(GtkPrintOperation *operation, + GtkPrintContext *context, gpointer data) +{ + PrintWindow *pw = data; + GList *work; + GdkPixbuf *pixbuf; + gchar *path; + GtkPrintSettings *print_settings; + GtkPageSetup *page_setup; + GError *error = NULL; - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); - gtk_widget_show(vbox); - label = gtk_label_new(_("Layout")); - gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); + print_settings = gtk_print_operation_get_print_settings(operation); + path = g_build_filename(get_rc_dir(), PRINT_SETTINGS, NULL); - print_misc_menu(vbox, pw->source, _("Source"), "print_source", - PRINT_SOURCE_COUNT, print_source_text, - G_CALLBACK(print_source_select_cb), pw); + gtk_print_settings_to_file(print_settings, path, &error); + if (error) + { + log_printf("Error: Print settings save failed:\n%s", error->message); + g_error_free(error); + error = NULL; + } + g_free(path); + g_object_unref(print_settings); - box = print_misc_menu(vbox, pw->layout, _("Layout"), "print_layout", - PRINT_LAYOUT_COUNT, print_layout_text, - G_CALLBACK(print_layout_select_cb), pw); + page_setup = gtk_print_operation_get_default_page_setup(operation); + path = g_build_filename(get_rc_dir(), PAGE_SETUP, NULL); - pref_spacer(box, PREF_PAD_GROUP); + gtk_page_setup_to_file(page_setup, path, &error); + if (error) + { + log_printf("Error: Print page setup save failed:\n%s", error->message); + g_error_free(error); + error = NULL; + } + g_free(path); + g_object_unref(page_setup); - table = pref_table_new(box, 2, 2, FALSE, FALSE); + print_pref_store(pw); - pw->image_scale_spin = pref_table_spin(table, 0, 0, _("Image size:"), "%", - 5.0, 100.0, 1.0, 0, pw->image_scale, - G_CALLBACK(print_image_scale_cb), pw); + work = pw->print_pixbuf_queue; + while (work) + { + pixbuf = work->data; + if (pixbuf) + { + g_object_unref(pixbuf); + } + work = work->next; + } + g_list_free(pw->print_pixbuf_queue); + g_free(pw); +} - label = pref_table_label(table, 0, 1, _("Proof size:"), 1.0); - pw->proof_group = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL); - pref_link_sensitivity(label, pw->proof_group); +void print_window_new(FileData *fd, GList *selection, GList *list, GtkWidget *parent) +{ + PrintWindow *pw; + GtkWidget *vbox; + GtkPrintOperation *operation; + GtkPageSetup *page_setup; + gchar *uri; + const gchar *dir; + GError *error = NULL; + gchar *path; + GtkPrintSettings *settings; - pw->proof_width_spin = pref_spin_new(pw->proof_group, NULL, NULL, - 0.0, 50.0, 0.1, 3, 0.0, - G_CALLBACK(print_proof_size_cb), pw); - pw->proof_height_spin = pref_spin_new(pw->proof_group, "x", NULL, - 0.0, 50.0, 0.1, 3, 0.0, - G_CALLBACK(print_proof_size_cb), pw); + pw = g_new0(PrintWindow, 1); - /* text tab */ + pw->source_selection = file_data_process_groups_in_selection(selection, FALSE, NULL); + pw->text_fields = options->printer.text_fields; vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); gtk_widget_show(vbox); - label = gtk_label_new(_("Text")); - gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); print_text_menu(vbox, pw); + pw->vbox = vbox; - /* paper tab */ + pw->print_pixbuf_queue = NULL; + pw->job_render_finished = FALSE; + pw->job_page = 0; - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); - gtk_widget_show(vbox); - label = gtk_label_new(_("Paper")); - gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); - - table = pref_table_new(vbox, 2, 4, FALSE, FALSE); - - print_paper_menu(table, 0, 0, pw->paper_size, G_CALLBACK(print_paper_select_cb), pw); - - label = pref_table_label(table, 0, 1, (_("Size:")), 1.0); - box = pref_table_box(table, 1, 1, GTK_ORIENTATION_HORIZONTAL, NULL); - pw->paper_width_spin = pref_spin_new(box, NULL, NULL, - 1.0, 10000.0, 1.0, 2, 66, - G_CALLBACK(print_paper_size_cb), pw); - pw->paper_height_spin = pref_spin_new(box, "x", NULL, - 1.0, 10000.0, 1.0, 2, 66, - G_CALLBACK(print_paper_size_cb), pw); - pref_link_sensitivity(label, pw->paper_width_spin); - - pw->paper_units_menu = print_paper_units_menu(table, 0, 2, pw->paper_units, - G_CALLBACK(print_paper_units_cb), pw); - - print_paper_orientation_menu(table, 0, 3, pw->paper_orientation, - G_CALLBACK(print_paper_orientation_cb), pw); - - box = pref_group_new(vbox, FALSE, _("Margins"), GTK_ORIENTATION_VERTICAL); - table = pref_table_new(box, 4, 2, FALSE, FALSE); - pw->margin_left_spin = pref_table_spin(table, 0, 0, _("Left:"), NULL, - 0.0, 50.0, 0.1, 3, 0.0, - G_CALLBACK(print_paper_margin_cb), pw); - pw->margin_right_spin = pref_table_spin(table, 2, 0, _("Right:"), NULL, - 0.0, 50.0, 0.1, 3, 0.0, - G_CALLBACK(print_paper_margin_cb), pw); - pw->margin_top_spin = pref_table_spin(table, 0, 1, _("Top:"), NULL, - 0.0, 50.0, 0.1, 3, 0.0, - G_CALLBACK(print_paper_margin_cb), pw); - pw->margin_bottom_spin = pref_table_spin(table, 2, 1, _("Bottom:"), NULL, - 0.0, 50.0, 0.1, 3, 0.0, - G_CALLBACK(print_paper_margin_cb), pw); - - /* printer tab */ + operation = gtk_print_operation_new(); + settings = gtk_print_settings_new(); - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), PREF_PAD_BORDER); - gtk_widget_show(vbox); - label = gtk_label_new(_("Printer")); - gtk_notebook_append_page(GTK_NOTEBOOK(pw->notebook), vbox, label); + gtk_print_operation_set_custom_tab_label(operation, "Options"); + gtk_print_operation_set_use_full_page(operation, TRUE); + gtk_print_operation_set_unit(operation, GTK_UNIT_POINTS); + gtk_print_operation_set_embed_page_setup(operation, TRUE); + gtk_print_operation_set_allow_async (operation, TRUE); + dir = g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS); + if (dir == NULL) + { + dir = g_get_home_dir(); + } - table = pref_table_new(vbox, 2, 5, FALSE, FALSE); - print_output_menu(table, 0, 0, pw->output, G_CALLBACK(print_output_cb), pw); + uri = g_build_filename("file:/", dir, "geeqie-file.pdf", NULL); + gtk_print_settings_set(settings, GTK_PRINT_SETTINGS_OUTPUT_URI, uri); + g_free(uri); - label = pref_table_label(table, 0, 1, _("Custom printer:"), 1.0); - combo = history_combo_new(&pw->custom_entry, NULL, "print_custom", -1); - print_custom_entry_set(pw, combo); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); + path = g_build_filename(get_rc_dir(), PRINT_SETTINGS, NULL); + gtk_print_settings_load_file(settings, path, &error); + if (error) + { + log_printf("Error: Printer settings load failed:\n%s", error->message); + g_error_free(error); + error = NULL; + } + gtk_print_operation_set_print_settings(operation, settings); + g_free(path); - pref_link_sensitivity(label, combo); + page_setup = gtk_page_setup_new(); + path = g_build_filename(get_rc_dir(), PAGE_SETUP, NULL); + gtk_page_setup_load_file(page_setup, path, &error); + if (error) + { + log_printf("Error: Print page setup load failed:\n%s", error->message); + g_error_free(error); + error = NULL; + } + gtk_print_operation_set_default_page_setup(operation, page_setup); + g_free(path); - label = pref_table_label(table, 0, 2, _("File:"), 1.0); - combo = tab_completion_new_with_history(&pw->path_entry, NULL, "print_path", -1, NULL, pw); - tab_completion_add_select_button(pw->path_entry, NULL, FALSE); - gtk_table_attach(GTK_TABLE(table), combo, 1, 2, 2, 3, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show(combo); + g_signal_connect (G_OBJECT (operation), "begin-print", + G_CALLBACK (begin_print), pw); + g_signal_connect (G_OBJECT (operation), "draw-page", + G_CALLBACK (draw_page), pw); + g_signal_connect (G_OBJECT (operation), "end-print", + G_CALLBACK (end_print_cb), pw); + g_signal_connect (G_OBJECT (operation), "create-custom-widget", + G_CALLBACK (option_tab_cb), pw); + g_signal_connect (G_OBJECT (operation), "paginate", + G_CALLBACK (paginate_cb), pw); - pref_link_sensitivity(label, combo); + gtk_print_operation_set_n_pages(operation, print_layout_page_count(pw)); - label = pref_table_label(table, 0, 3, _("File format:"), 1.0); - pw->path_format_menu = print_output_format_menu(table, 1, 3, pw->output_format, - G_CALLBACK(print_output_format_cb), pw); - pref_link_sensitivity(label, pw->path_format_menu); + gtk_print_operation_run(operation, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, + GTK_WINDOW (parent), &error); - label = pref_table_label(table, 0, 4, _("DPI:"), 1.0); - pw->max_dpi_menu = print_output_dpi_menu(table, 1, 4, pw->max_dpi, - G_CALLBACK(print_output_dpi_cb), pw); - pref_link_sensitivity(label, pw->max_dpi_menu); + if (error) + { + GtkWidget *dialog; - print_output_set(pw, pw->output); + dialog = gtk_message_dialog_new(GTK_WINDOW (parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s", error->message); + g_error_free (error); - vbox = print_window_layout_setup(pw, main_box); - pref_checkbox_new_int(vbox, _("Remember print settings"), pw->save_settings, &pw->save_settings); + g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), NULL); - print_window_layout_sync_layout(pw); - print_window_layout_sync_paper(pw); + gtk_widget_show (dialog); + } - gtk_widget_show(pw->notebook); - gtk_widget_show(pw->dialog->dialog); + g_object_unref(page_setup); + g_object_unref(settings); } /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/rcfile.c b/src/rcfile.c index c6314e8f..3d2a5006 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -494,6 +494,10 @@ static void write_global_attributes(GString *outstr, gint indent) WRITE_NL(); WRITE_INT(*options, cp_mv_rn.auto_padding); WRITE_NL(); WRITE_CHAR(*options, cp_mv_rn.auto_end); WRITE_NL(); WRITE_INT(*options, cp_mv_rn.formatted_start); + + /* printer */ + WRITE_NL(); WRITE_CHAR(*options, printer.font); + WRITE_NL(); WRITE_INT(*options, printer.text_fields); } static void write_color_profile(GString *outstr, gint indent) @@ -829,6 +833,10 @@ static gboolean load_global_params(const gchar **attribute_names, const gchar ** if (READ_CHAR(*options, cp_mv_rn.auto_end)) continue; if (READ_INT(*options, cp_mv_rn.formatted_start)) continue; + /* printer */ + if (READ_CHAR(*options, printer.font)) continue; + if (READ_INT(*options, printer.text_fields)) continue; + /* Dummy options */ if (READ_DUMMY(*options, image.dither_quality, "deprecated since 2012-08-13")) continue; -- 2.20.1