diff options
| author | Simeon Simeonov | 2018-02-26 11:23:00 +0100 |
|---|---|---|
| committer | Simeon Simeonov | 2018-02-26 11:23:00 +0100 |
| commit | 0b3cbf57875fd692e4ba0b336fefa4bee1ed00dc (patch) | |
| tree | af916a30553c78ce9d4f2d8658656a175c5b6921 /src/printing.c | |
Initial commit for sylpheed 3.7.0
Diffstat (limited to 'src/printing.c')
| -rw-r--r-- | src/printing.c | 747 |
1 files changed, 747 insertions, 0 deletions
diff --git a/src/printing.c b/src/printing.c new file mode 100644 index 0000000..ca0f55f --- /dev/null +++ b/src/printing.c | |||
| @@ -0,0 +1,747 @@ | |||
| 1 | /* | ||
| 2 | * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client | ||
| 3 | * Copyright (C) 1999-2017 Hiroyuki Yamamoto | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifdef HAVE_CONFIG_H | ||
| 21 | # include "config.h" | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #include "defs.h" | ||
| 25 | #include "printing.h" | ||
| 26 | |||
| 27 | #include <glib.h> | ||
| 28 | #include <glib/gi18n.h> | ||
| 29 | #if GTK_CHECK_VERSION(2, 10, 0) | ||
| 30 | #include <gtk/gtkprintoperation.h> | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #include <stdio.h> | ||
| 34 | |||
| 35 | #include "mainwindow.h" | ||
| 36 | #include "procmsg.h" | ||
| 37 | #include "procheader.h" | ||
| 38 | #include "prefs_common.h" | ||
| 39 | #include "alertpanel.h" | ||
| 40 | #include "utils.h" | ||
| 41 | |||
| 42 | #if GTK_CHECK_VERSION(2, 10, 0) | ||
| 43 | |||
| 44 | #define SPACING 2.0 | ||
| 45 | |||
| 46 | typedef struct | ||
| 47 | { | ||
| 48 | MsgInfo *msginfo; | ||
| 49 | gint n_pages; | ||
| 50 | gchar *hdr_data; | ||
| 51 | gchar *msg_text_file; | ||
| 52 | FILE *fp; | ||
| 53 | } MsgPrintInfo; | ||
| 54 | |||
| 55 | typedef struct | ||
| 56 | { | ||
| 57 | gint page_nr_per_msg; | ||
| 58 | MsgPrintInfo *mpinfo; | ||
| 59 | glong pos; | ||
| 60 | gint lines; | ||
| 61 | } PageInfo; | ||
| 62 | |||
| 63 | typedef struct | ||
| 64 | { | ||
| 65 | GSList *mlist; | ||
| 66 | gint n_msgs; | ||
| 67 | MsgPrintInfo *msgs; | ||
| 68 | GPtrArray *pages; | ||
| 69 | gint n_pages; | ||
| 70 | |||
| 71 | MimeInfo *partinfo; | ||
| 72 | |||
| 73 | gdouble line_h; | ||
| 74 | gint lines_per_page; | ||
| 75 | |||
| 76 | gboolean all_headers; | ||
| 77 | } PrintData; | ||
| 78 | |||
| 79 | static GtkPrintSettings *settings = NULL; | ||
| 80 | static GtkPageSetup *page_setup = NULL; | ||
| 81 | |||
| 82 | static gint get_header_data(MsgPrintInfo *mpinfo, PrintData *print_data) | ||
| 83 | { | ||
| 84 | MsgInfo *msginfo; | ||
| 85 | FILE *fp; | ||
| 86 | GPtrArray *headers; | ||
| 87 | GString *str; | ||
| 88 | gint i; | ||
| 89 | |||
| 90 | msginfo = mpinfo->msginfo; | ||
| 91 | |||
| 92 | if ((fp = procmsg_open_message(msginfo)) == NULL) | ||
| 93 | return -1; | ||
| 94 | |||
| 95 | if (print_data->all_headers) | ||
| 96 | headers = procheader_get_header_array_asis(fp, NULL); | ||
| 97 | else | ||
| 98 | headers = procheader_get_header_array_for_display(fp, NULL); | ||
| 99 | |||
| 100 | fclose(fp); | ||
| 101 | |||
| 102 | str = g_string_new(NULL); | ||
| 103 | |||
| 104 | for (i = 0; i < headers->len; i++) { | ||
| 105 | Header *hdr; | ||
| 106 | gchar *text; | ||
| 107 | const gchar *body; | ||
| 108 | |||
| 109 | hdr = g_ptr_array_index(headers, i); | ||
| 110 | |||
| 111 | if (!g_ascii_strcasecmp(hdr->name, "Subject")) | ||
| 112 | body = msginfo->subject; | ||
| 113 | else if (!g_ascii_strcasecmp(hdr->name, "From")) | ||
| 114 | body = msginfo->from; | ||
| 115 | else if (!g_ascii_strcasecmp(hdr->name, "To")) | ||
| 116 | body = msginfo->to; | ||
| 117 | else if (!g_ascii_strcasecmp(hdr->name, "Cc")) { | ||
| 118 | unfold_line(hdr->body); | ||
| 119 | body = hdr->body; | ||
| 120 | while (g_ascii_isspace(*body)) | ||
| 121 | body++; | ||
| 122 | } else { | ||
| 123 | body = hdr->body; | ||
| 124 | while (g_ascii_isspace(*body)) | ||
| 125 | body++; | ||
| 126 | } | ||
| 127 | |||
| 128 | if (body && *body != '\0') | ||
| 129 | text = g_markup_printf_escaped("<b>%s:</b> %s\n", | ||
| 130 | hdr->name, body); | ||
| 131 | else | ||
| 132 | text = g_markup_printf_escaped("<b>%s:</b> (none)\n", | ||
| 133 | hdr->name); | ||
| 134 | g_string_append(str, text); | ||
| 135 | g_free(text); | ||
| 136 | } | ||
| 137 | |||
| 138 | /* dummy character for correct separation */ | ||
| 139 | g_string_append_c(str, ' '); | ||
| 140 | |||
| 141 | mpinfo->hdr_data = g_string_free(str, FALSE); | ||
| 142 | procheader_header_array_destroy(headers); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static gint layout_set_headers(PangoLayout *layout, MsgPrintInfo *mpinfo, | ||
| 148 | PrintData *print_data) | ||
| 149 | { | ||
| 150 | PangoFontDescription *desc; | ||
| 151 | gint size; | ||
| 152 | |||
| 153 | g_return_val_if_fail(mpinfo->hdr_data != NULL, -1); | ||
| 154 | |||
| 155 | desc = pango_font_description_from_string(prefs_common_get()->textfont); | ||
| 156 | size = pango_font_description_get_size(desc); | ||
| 157 | pango_font_description_free(desc); | ||
| 158 | desc = gtkut_get_default_font_desc(); | ||
| 159 | debug_print("layout_set_headers: using font %s (style %d, %g pt)\n", pango_font_description_get_family(desc), pango_font_description_get_style(desc), (gdouble)size / PANGO_SCALE); | ||
| 160 | pango_font_description_set_size(desc, size); | ||
| 161 | pango_layout_set_font_description(layout, desc); | ||
| 162 | pango_font_description_free(desc); | ||
| 163 | |||
| 164 | pango_layout_set_markup(layout, mpinfo->hdr_data, -1); | ||
| 165 | |||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static gint message_count_page(MsgPrintInfo *mpinfo, GtkPrintContext *context, | ||
| 170 | PrintData *print_data) | ||
| 171 | { | ||
| 172 | cairo_t *cr; | ||
| 173 | gdouble width, height, line_h, hdr_h = 0.0, body_h; | ||
| 174 | gdouble dpi_x, dpi_y; | ||
| 175 | PangoLayout *layout; | ||
| 176 | PangoFontDescription *desc; | ||
| 177 | gint layout_h; | ||
| 178 | gint lines_per_page, lines_left; | ||
| 179 | gint n_pages = 1; | ||
| 180 | PageInfo *pinfo; | ||
| 181 | gint i; | ||
| 182 | FILE *fp = NULL; | ||
| 183 | gchar buf[BUFFSIZE]; | ||
| 184 | glong pos = 0; | ||
| 185 | |||
| 186 | cr = gtk_print_context_get_cairo_context(context); | ||
| 187 | width = gtk_print_context_get_width(context); | ||
| 188 | height = gtk_print_context_get_height(context); | ||
| 189 | dpi_x = gtk_print_context_get_dpi_x(context); | ||
| 190 | dpi_y = gtk_print_context_get_dpi_y(context); | ||
| 191 | |||
| 192 | layout = gtk_print_context_create_pango_layout(context); | ||
| 193 | pango_layout_set_width(layout, width * PANGO_SCALE); | ||
| 194 | pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); | ||
| 195 | pango_layout_set_spacing(layout, (SPACING / 72 * dpi_y) * PANGO_SCALE); | ||
| 196 | |||
| 197 | if (!print_data->partinfo) { | ||
| 198 | if (get_header_data(mpinfo, print_data) < 0) { | ||
| 199 | g_object_unref(layout); | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | layout_set_headers(layout, mpinfo, print_data); | ||
| 203 | |||
| 204 | pango_layout_get_size(layout, NULL, &layout_h); | ||
| 205 | hdr_h = (gdouble)layout_h / PANGO_SCALE; | ||
| 206 | } | ||
| 207 | |||
| 208 | pango_layout_set_attributes(layout, NULL); | ||
| 209 | desc = pango_font_description_from_string(prefs_common_get()->textfont); | ||
| 210 | pango_layout_set_font_description(layout, desc); | ||
| 211 | pango_font_description_free(desc); | ||
| 212 | |||
| 213 | pango_layout_set_text(layout, "Test", -1); | ||
| 214 | pango_layout_get_size(layout, NULL, &layout_h); | ||
| 215 | if (layout_h <= 0) { | ||
| 216 | g_warning("invalid layout_h (%d) ! falling back to default height (%d)\n", layout_h, 12 * PANGO_SCALE); | ||
| 217 | layout_h = 12 * PANGO_SCALE; | ||
| 218 | } | ||
| 219 | line_h = (gdouble)layout_h / PANGO_SCALE + (SPACING / 72 * dpi_y); | ||
| 220 | print_data->line_h = line_h; | ||
| 221 | lines_per_page = (height - line_h) / line_h; | ||
| 222 | print_data->lines_per_page = lines_per_page; | ||
| 223 | body_h = height - hdr_h - line_h; | ||
| 224 | if (body_h < 0) | ||
| 225 | body_h = 0.0; | ||
| 226 | lines_left = body_h / line_h; | ||
| 227 | |||
| 228 | debug_print("width = %g, height = %g\n", width, height); | ||
| 229 | debug_print("dpi_x = %g, dpi_y = %g\n", dpi_x, dpi_y); | ||
| 230 | debug_print("layout_h = %d, line_h = %g, lines_per_page = %d\n", layout_h, line_h, lines_per_page); | ||
| 231 | debug_print("hdr_h = %g, body_h = %g, lines_left = %d\n", hdr_h, body_h, lines_left); | ||
| 232 | |||
| 233 | if (print_data->partinfo) { | ||
| 234 | FILE *msgfp; | ||
| 235 | |||
| 236 | if ((msgfp = procmsg_open_message(mpinfo->msginfo)) == NULL) | ||
| 237 | return -1; | ||
| 238 | fp = procmime_get_text_content(print_data->partinfo, msgfp, | ||
| 239 | NULL); | ||
| 240 | fclose(msgfp); | ||
| 241 | } else { | ||
| 242 | mpinfo->msg_text_file = get_tmp_file(); | ||
| 243 | if (procmsg_save_message_as_text(mpinfo->msginfo, mpinfo->msg_text_file, NULL, print_data->all_headers) == 0) { | ||
| 244 | if ((fp = g_fopen(mpinfo->msg_text_file, "rb")) != NULL) { | ||
| 245 | while (fgets(buf, sizeof(buf), fp) != NULL) | ||
| 246 | if (buf[0] == '\r' || buf[0] == '\n') | ||
| 247 | break; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | } | ||
| 251 | if (!fp) { | ||
| 252 | g_warning("Can't get text part\n"); | ||
| 253 | return -1; | ||
| 254 | } | ||
| 255 | |||
| 256 | i = 0; | ||
| 257 | pos = ftell(fp); | ||
| 258 | pinfo = g_new(PageInfo, 1); | ||
| 259 | pinfo->page_nr_per_msg = 0; | ||
| 260 | pinfo->mpinfo = mpinfo; | ||
| 261 | pinfo->pos = pos; | ||
| 262 | pinfo->lines = lines_left; | ||
| 263 | g_ptr_array_add(print_data->pages, pinfo); | ||
| 264 | |||
| 265 | while (fgets(buf, sizeof(buf), fp) != NULL) { | ||
| 266 | gint lines; | ||
| 267 | gint line_offset = 0; | ||
| 268 | |||
| 269 | strretchomp(buf); | ||
| 270 | pango_layout_set_text(layout, buf, -1); | ||
| 271 | lines = pango_layout_get_line_count(layout); | ||
| 272 | |||
| 273 | while (lines_left < lines) { | ||
| 274 | PangoLayoutLine *line; | ||
| 275 | |||
| 276 | debug_print("page increment: %d: lines_left = %d, lines = %d\n", i, lines_left, lines); | ||
| 277 | line_offset += lines_left; | ||
| 278 | line = pango_layout_get_line(layout, line_offset); | ||
| 279 | lines -= lines_left; | ||
| 280 | lines_left = lines_per_page; | ||
| 281 | |||
| 282 | pinfo = g_new(PageInfo, 1); | ||
| 283 | pinfo->page_nr_per_msg = ++i; | ||
| 284 | pinfo->mpinfo = mpinfo; | ||
| 285 | pinfo->pos = pos + line->start_index; | ||
| 286 | pinfo->lines = lines_left; | ||
| 287 | g_ptr_array_add(print_data->pages, pinfo); | ||
| 288 | } | ||
| 289 | |||
| 290 | lines_left -= lines; | ||
| 291 | pos = ftell(fp); | ||
| 292 | } | ||
| 293 | |||
| 294 | rewind(fp); | ||
| 295 | mpinfo->fp = fp; | ||
| 296 | |||
| 297 | g_object_unref(layout); | ||
| 298 | |||
| 299 | n_pages = i + 1; | ||
| 300 | debug_print("n_pages = %d\n", n_pages); | ||
| 301 | |||
| 302 | return n_pages; | ||
| 303 | } | ||
| 304 | |||
| 305 | static void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, | ||
| 306 | gpointer data) | ||
| 307 | { | ||
| 308 | PrintData *print_data = data; | ||
| 309 | gint n_pages = 0; | ||
| 310 | gint i; | ||
| 311 | |||
| 312 | debug_print("begin_print\n"); | ||
| 313 | |||
| 314 | for (i = 0; i < print_data->n_msgs; i++) { | ||
| 315 | n_pages += message_count_page(&print_data->msgs[i], context, | ||
| 316 | print_data); | ||
| 317 | } | ||
| 318 | |||
| 319 | print_data->n_pages = n_pages; | ||
| 320 | gtk_print_operation_set_n_pages(operation, n_pages); | ||
| 321 | } | ||
| 322 | |||
| 323 | static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, | ||
| 324 | gint page_nr, gpointer data) | ||
| 325 | { | ||
| 326 | PrintData *print_data = data; | ||
| 327 | PageInfo *pinfo; | ||
| 328 | MsgPrintInfo *mpinfo; | ||
| 329 | MsgInfo *msginfo; | ||
| 330 | cairo_t *cr; | ||
| 331 | PangoLayout *layout; | ||
| 332 | gdouble width, height; | ||
| 333 | gdouble dpi; | ||
| 334 | gint layout_h; | ||
| 335 | PangoFontDescription *desc; | ||
| 336 | gint font_size; | ||
| 337 | gchar buf[BUFFSIZE]; | ||
| 338 | gint count = 0; | ||
| 339 | |||
| 340 | if (page_nr >= print_data->n_pages) | ||
| 341 | return; | ||
| 342 | |||
| 343 | pinfo = g_ptr_array_index(print_data->pages, page_nr); | ||
| 344 | mpinfo = pinfo->mpinfo; | ||
| 345 | msginfo = mpinfo->msginfo; | ||
| 346 | |||
| 347 | debug_print("draw_page: %d (%d), pos = %ld\n", page_nr, pinfo->page_nr_per_msg, pinfo->pos); | ||
| 348 | debug_print("msg pages = %d\n", mpinfo->n_pages); | ||
| 349 | |||
| 350 | cr = gtk_print_context_get_cairo_context(context); | ||
| 351 | width = gtk_print_context_get_width(context); | ||
| 352 | height = gtk_print_context_get_height(context); | ||
| 353 | dpi = gtk_print_context_get_dpi_y(context); | ||
| 354 | |||
| 355 | #if 0 | ||
| 356 | cairo_set_source_rgb(cr, 0.8, 0.8, 0.8); | ||
| 357 | cairo_rectangle(cr, 0, 0, width, font_size * 5); | ||
| 358 | cairo_fill(cr); | ||
| 359 | #endif | ||
| 360 | |||
| 361 | cairo_set_source_rgb(cr, 0, 0, 0); | ||
| 362 | cairo_move_to(cr, 0, 0); | ||
| 363 | |||
| 364 | layout = gtk_print_context_create_pango_layout(context); | ||
| 365 | pango_layout_set_width(layout, width * PANGO_SCALE); | ||
| 366 | pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR); | ||
| 367 | pango_layout_set_spacing(layout, (SPACING / 72 * dpi) * PANGO_SCALE); | ||
| 368 | |||
| 369 | if (pinfo->page_nr_per_msg == 0 && mpinfo->hdr_data) { | ||
| 370 | if (layout_set_headers(layout, mpinfo, print_data) < 0) { | ||
| 371 | g_object_unref(layout); | ||
| 372 | return; | ||
| 373 | } | ||
| 374 | |||
| 375 | pango_cairo_show_layout(cr, layout); | ||
| 376 | pango_layout_get_size(layout, NULL, &layout_h); | ||
| 377 | cairo_rel_move_to(cr, 0, (double)layout_h / PANGO_SCALE); | ||
| 378 | } | ||
| 379 | |||
| 380 | pango_layout_set_attributes(layout, NULL); | ||
| 381 | desc = pango_font_description_from_string(prefs_common_get()->textfont); | ||
| 382 | font_size = pango_font_description_get_size(desc); | ||
| 383 | debug_print("draw_page: using font %s (style %d, %g pt)\n", pango_font_description_get_family(desc), pango_font_description_get_style(desc), (gdouble)font_size / PANGO_SCALE); | ||
| 384 | pango_font_description_set_size(desc, font_size); | ||
| 385 | pango_layout_set_font_description(layout, desc); | ||
| 386 | pango_font_description_free(desc); | ||
| 387 | |||
| 388 | if (fseek(mpinfo->fp, pinfo->pos, SEEK_SET) < 0) { | ||
| 389 | FILE_OP_ERROR("draw_page", "fseek"); | ||
| 390 | g_object_unref(layout); | ||
| 391 | return; | ||
| 392 | } | ||
| 393 | |||
| 394 | while (count < pinfo->lines) { | ||
| 395 | gint lines; | ||
| 396 | gint i; | ||
| 397 | PangoLayoutIter *iter; | ||
| 398 | PangoLayoutLine *layout_line; | ||
| 399 | gint baseline; | ||
| 400 | gdouble x, y; | ||
| 401 | |||
| 402 | if (fgets(buf, sizeof(buf), mpinfo->fp) == NULL) | ||
| 403 | break; | ||
| 404 | strretchomp(buf); | ||
| 405 | if (buf[0] == '\0') { | ||
| 406 | /* dummy character for correct empty line height */ | ||
| 407 | buf[0] = ' '; | ||
| 408 | buf[1] = '\0'; | ||
| 409 | } | ||
| 410 | |||
| 411 | pango_layout_set_text(layout, buf, -1); | ||
| 412 | lines = pango_layout_get_line_count(layout); | ||
| 413 | iter = pango_layout_get_iter(layout); | ||
| 414 | cairo_get_current_point(cr, &x, &y); | ||
| 415 | |||
| 416 | for (i = 0; i < lines; i++) { | ||
| 417 | layout_line = pango_layout_iter_get_line(iter); | ||
| 418 | baseline = pango_layout_iter_get_baseline(iter); | ||
| 419 | cairo_move_to(cr, 0, | ||
| 420 | y + (gdouble)baseline / PANGO_SCALE); | ||
| 421 | pango_cairo_show_layout_line(cr, layout_line); | ||
| 422 | count++; | ||
| 423 | if (count >= pinfo->lines && i + 1 < lines) | ||
| 424 | break; | ||
| 425 | pango_layout_iter_next_line(iter); | ||
| 426 | } | ||
| 427 | |||
| 428 | pango_layout_iter_free(iter); | ||
| 429 | |||
| 430 | pango_layout_get_size(layout, NULL, &layout_h); | ||
| 431 | cairo_move_to(cr, 0, | ||
| 432 | y + (gdouble)layout_h / PANGO_SCALE + (SPACING / 72 * dpi)); | ||
| 433 | } | ||
| 434 | debug_print("count = %d\n", count); | ||
| 435 | |||
| 436 | desc = gtkut_get_default_font_desc(); | ||
| 437 | pango_font_description_set_size(desc, font_size); | ||
| 438 | pango_layout_set_font_description(layout, desc); | ||
| 439 | pango_font_description_free(desc); | ||
| 440 | g_snprintf(buf, sizeof(buf), "- %d -", pinfo->page_nr_per_msg + 1); | ||
| 441 | pango_layout_set_text(layout, buf, -1); | ||
| 442 | pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); | ||
| 443 | cairo_move_to(cr, 0, height - (gdouble)font_size / PANGO_SCALE / 72 * dpi); | ||
| 444 | pango_cairo_show_layout(cr, layout); | ||
| 445 | |||
| 446 | g_object_unref(layout); | ||
| 447 | } | ||
| 448 | |||
| 449 | static gboolean printing_load_settings(void) | ||
| 450 | { | ||
| 451 | #if GTK_CHECK_VERSION(2, 12, 0) | ||
| 452 | gchar *file; | ||
| 453 | GtkPrintSettings *new_settings; | ||
| 454 | |||
| 455 | debug_print("printing_load_settings: load settings\n"); | ||
| 456 | |||
| 457 | file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "printingrc", NULL); | ||
| 458 | if (!is_file_exist(file)) { | ||
| 459 | debug_print("printing_load_settings: %s not exist\n", file); | ||
| 460 | g_free(file); | ||
| 461 | return FALSE; | ||
| 462 | } | ||
| 463 | |||
| 464 | if ((new_settings = gtk_print_settings_new_from_file(file, NULL)) == NULL) { | ||
| 465 | g_warning("printing_load_settings: gtk_print_settings_new_from_file: %s: error", file); | ||
| 466 | g_free(file); | ||
| 467 | return FALSE; | ||
| 468 | } | ||
| 469 | g_free(file); | ||
| 470 | |||
| 471 | if (settings) | ||
| 472 | g_object_unref(settings); | ||
| 473 | settings = new_settings; | ||
| 474 | |||
| 475 | return TRUE; | ||
| 476 | #else | ||
| 477 | return FALSE; | ||
| 478 | #endif /* GTK_CHECK_VERSION(2, 12, 0) */ | ||
| 479 | } | ||
| 480 | |||
| 481 | static gboolean printing_save_settings(void) | ||
| 482 | { | ||
| 483 | #if GTK_CHECK_VERSION(2, 12, 0) | ||
| 484 | gchar *file; | ||
| 485 | gboolean ret = TRUE; | ||
| 486 | |||
| 487 | g_return_val_if_fail(settings != NULL, FALSE); | ||
| 488 | |||
| 489 | debug_print("printing_save_settings: save settings\n"); | ||
| 490 | |||
| 491 | file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "printingrc", NULL); | ||
| 492 | if (gtk_print_settings_to_file(settings, file, NULL) != TRUE) { | ||
| 493 | g_warning("printing_save_settings: gtk_print_settings_to_file: %s: error", file); | ||
| 494 | ret = FALSE; | ||
| 495 | } | ||
| 496 | g_free(file); | ||
| 497 | |||
| 498 | return ret; | ||
| 499 | #else | ||
| 500 | return FALSE; | ||
| 501 | #endif /* GTK_CHECK_VERSION(2, 12, 0) */ | ||
| 502 | } | ||
| 503 | |||
| 504 | static gboolean printing_load_page_setup(void) | ||
| 505 | { | ||
| 506 | #if GTK_CHECK_VERSION(2, 12, 0) | ||
| 507 | gchar *file; | ||
| 508 | GtkPageSetup *new_setup; | ||
| 509 | |||
| 510 | debug_print("printing_load_page_setup: load page setup\n"); | ||
| 511 | |||
| 512 | file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "pagesetuprc", NULL); | ||
| 513 | if (!is_file_exist(file)) { | ||
| 514 | debug_print("printing_load_page_setup: %s not exist\n", file); | ||
| 515 | g_free(file); | ||
| 516 | return FALSE; | ||
| 517 | } | ||
| 518 | |||
| 519 | if ((new_setup = gtk_page_setup_new_from_file(file, NULL)) == NULL) { | ||
| 520 | g_warning("printing_load_page_setup: gtk_page_setup_new_from_file: %s: error", file); | ||
| 521 | g_free(file); | ||
| 522 | return FALSE; | ||
| 523 | } | ||
| 524 | g_free(file); | ||
| 525 | |||
| 526 | if (page_setup) | ||
| 527 | g_object_unref(page_setup); | ||
| 528 | page_setup = new_setup; | ||
| 529 | |||
| 530 | return TRUE; | ||
| 531 | #else | ||
| 532 | return FALSE; | ||
| 533 | #endif /* GTK_CHECK_VERSION(2, 12, 0) */ | ||
| 534 | } | ||
| 535 | |||
| 536 | static gboolean printing_save_page_setup(void) | ||
| 537 | { | ||
| 538 | #if GTK_CHECK_VERSION(2, 12, 0) | ||
| 539 | gchar *file; | ||
| 540 | gboolean ret = TRUE; | ||
| 541 | |||
| 542 | g_return_val_if_fail(page_setup != NULL, FALSE); | ||
| 543 | |||
| 544 | debug_print("printing_save_page_setup: save page setup\n"); | ||
| 545 | |||
| 546 | file = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, "pagesetuprc", NULL); | ||
| 547 | if (gtk_page_setup_to_file(page_setup, file, NULL) != TRUE) { | ||
| 548 | g_warning("printing_save_page_setup: gtk_page_setup_to_file: %s: error", file); | ||
| 549 | ret = FALSE; | ||
| 550 | } | ||
| 551 | g_free(file); | ||
| 552 | |||
| 553 | return ret; | ||
| 554 | #else | ||
| 555 | return FALSE; | ||
| 556 | #endif /* GTK_CHECK_VERSION(2, 12, 0) */ | ||
| 557 | } | ||
| 558 | |||
| 559 | gint printing_print_messages_gtk(GSList *mlist, MimeInfo *partinfo, | ||
| 560 | gboolean all_headers) | ||
| 561 | { | ||
| 562 | GtkPrintOperation *op; | ||
| 563 | GtkPrintOperationResult res; | ||
| 564 | PrintData *print_data; | ||
| 565 | GSList *cur; | ||
| 566 | gchar *prev_dir; | ||
| 567 | gint i; | ||
| 568 | |||
| 569 | g_return_val_if_fail(mlist != NULL, -1); | ||
| 570 | |||
| 571 | debug_print("printing start\n"); | ||
| 572 | |||
| 573 | prev_dir = g_get_current_dir(); | ||
| 574 | change_dir(get_document_dir()); | ||
| 575 | |||
| 576 | print_data = g_new0(PrintData, 1); | ||
| 577 | print_data->mlist = mlist; | ||
| 578 | print_data->n_msgs = g_slist_length(mlist); | ||
| 579 | print_data->msgs = g_new0(MsgPrintInfo, print_data->n_msgs); | ||
| 580 | for (i = 0, cur = mlist; cur != NULL; i++, cur = cur->next) { | ||
| 581 | print_data->msgs[i].msginfo = (MsgInfo *)cur->data; | ||
| 582 | } | ||
| 583 | print_data->pages = g_ptr_array_new(); | ||
| 584 | print_data->n_pages = 0; | ||
| 585 | print_data->partinfo = partinfo; | ||
| 586 | print_data->line_h = 0.0; | ||
| 587 | print_data->all_headers = all_headers; | ||
| 588 | |||
| 589 | op = gtk_print_operation_new(); | ||
| 590 | |||
| 591 | /* GTK_UNIT_POINTS introduces text corruption bug, so use pixel unit */ | ||
| 592 | gtk_print_operation_set_unit(op, GTK_UNIT_PIXEL); | ||
| 593 | |||
| 594 | g_signal_connect(op, "begin-print", G_CALLBACK(begin_print), | ||
| 595 | print_data); | ||
| 596 | g_signal_connect(op, "draw-page", G_CALLBACK(draw_page), print_data); | ||
| 597 | |||
| 598 | if (!settings) | ||
| 599 | printing_load_settings(); | ||
| 600 | if (settings) | ||
| 601 | gtk_print_operation_set_print_settings(op, settings); | ||
| 602 | if (!page_setup) | ||
| 603 | printing_load_page_setup(); | ||
| 604 | if (page_setup) | ||
| 605 | gtk_print_operation_set_default_page_setup(op, page_setup); | ||
| 606 | |||
| 607 | res = gtk_print_operation_run | ||
| 608 | (op, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, | ||
| 609 | GTK_WINDOW(main_window_get()->window), NULL); | ||
| 610 | |||
| 611 | if (res == GTK_PRINT_OPERATION_RESULT_APPLY) { | ||
| 612 | if (settings) | ||
| 613 | g_object_unref(settings); | ||
| 614 | settings = g_object_ref(gtk_print_operation_get_print_settings(op)); | ||
| 615 | printing_save_settings(); | ||
| 616 | } | ||
| 617 | |||
| 618 | g_object_unref(op); | ||
| 619 | for (i = 0; i < print_data->pages->len; i++) { | ||
| 620 | PageInfo *pinfo; | ||
| 621 | pinfo = g_ptr_array_index(print_data->pages, i); | ||
| 622 | g_free(pinfo); | ||
| 623 | } | ||
| 624 | g_ptr_array_free(print_data->pages, TRUE); | ||
| 625 | for (i = 0; i < print_data->n_msgs; i++) { | ||
| 626 | g_free(print_data->msgs[i].hdr_data); | ||
| 627 | if (print_data->msgs[i].fp) | ||
| 628 | fclose(print_data->msgs[i].fp); | ||
| 629 | if (print_data->msgs[i].msg_text_file) { | ||
| 630 | g_unlink(print_data->msgs[i].msg_text_file); | ||
| 631 | g_free(print_data->msgs[i].msg_text_file); | ||
| 632 | } | ||
| 633 | } | ||
| 634 | g_free(print_data); | ||
| 635 | |||
| 636 | change_dir(prev_dir); | ||
| 637 | g_free(prev_dir); | ||
| 638 | |||
| 639 | debug_print("printing finished\n"); | ||
| 640 | |||
| 641 | return 0; | ||
| 642 | } | ||
| 643 | |||
| 644 | void printing_page_setup_gtk(void) | ||
| 645 | { | ||
| 646 | GtkPageSetup *new_page_setup; | ||
| 647 | |||
| 648 | if (!settings) | ||
| 649 | printing_load_settings(); | ||
| 650 | if (!settings) | ||
| 651 | settings = gtk_print_settings_new(); | ||
| 652 | if (!page_setup) | ||
| 653 | printing_load_page_setup(); | ||
| 654 | |||
| 655 | new_page_setup = gtk_print_run_page_setup_dialog | ||
| 656 | (GTK_WINDOW(main_window_get()->window), page_setup, settings); | ||
| 657 | |||
| 658 | if (page_setup) | ||
| 659 | g_object_unref(page_setup); | ||
| 660 | page_setup = new_page_setup; | ||
| 661 | |||
| 662 | printing_save_page_setup(); | ||
| 663 | } | ||
| 664 | |||
| 665 | #endif /* GTK_CHECK_VERSION(2, 10, 0) */ | ||
| 666 | |||
| 667 | static gint check_command_line(const gchar *cmdline) | ||
| 668 | { | ||
| 669 | gchar *msg; | ||
| 670 | |||
| 671 | msg = g_strconcat | ||
| 672 | (_("The message will be printed with the following command:"), | ||
| 673 | "\n\n", cmdline ? cmdline : _("(Default print command)"), | ||
| 674 | NULL); | ||
| 675 | if (alertpanel(_("Print"), msg, GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL) | ||
| 676 | != G_ALERTDEFAULT) { | ||
| 677 | g_free(msg); | ||
| 678 | return -2; | ||
| 679 | } | ||
| 680 | g_free(msg); | ||
| 681 | |||
| 682 | if (cmdline && str_find_format_times(cmdline, 's') != 1) { | ||
| 683 | alertpanel_error(_("Print command line is invalid:\n`%s'"), | ||
| 684 | cmdline); | ||
| 685 | return -1; | ||
| 686 | } | ||
| 687 | |||
| 688 | return 0; | ||
| 689 | } | ||
| 690 | |||
| 691 | gint printing_print_messages_with_command(GSList *mlist, gboolean all_headers, | ||
| 692 | const gchar *cmdline) | ||
| 693 | { | ||
| 694 | MsgInfo *msginfo; | ||
| 695 | GSList *cur; | ||
| 696 | |||
| 697 | g_return_val_if_fail(mlist != NULL, -1); | ||
| 698 | |||
| 699 | if (check_command_line(cmdline) < 0) | ||
| 700 | return -1; | ||
| 701 | |||
| 702 | for (cur = mlist; cur != NULL; cur = cur->next) { | ||
| 703 | msginfo = (MsgInfo *)cur->data; | ||
| 704 | if (msginfo) | ||
| 705 | procmsg_print_message(msginfo, cmdline, all_headers); | ||
| 706 | } | ||
| 707 | |||
| 708 | return 0; | ||
| 709 | } | ||
| 710 | |||
| 711 | gint printing_print_messages(GSList *mlist, gboolean all_headers) | ||
| 712 | { | ||
| 713 | #if GTK_CHECK_VERSION(2, 10, 0) | ||
| 714 | if (!prefs_common.use_print_cmd) | ||
| 715 | return printing_print_messages_gtk(mlist, NULL, all_headers); | ||
| 716 | else | ||
| 717 | #endif /* GTK_CHECK_VERSION(2, 10, 0) */ | ||
| 718 | return printing_print_messages_with_command | ||
| 719 | (mlist, all_headers, prefs_common.print_cmd); | ||
| 720 | } | ||
| 721 | |||
| 722 | gint printing_print_message(MsgInfo *msginfo, gboolean all_headers) | ||
| 723 | { | ||
| 724 | GSList mlist; | ||
| 725 | |||
| 726 | mlist.data = msginfo; | ||
| 727 | mlist.next = NULL; | ||
| 728 | return printing_print_messages(&mlist, all_headers); | ||
| 729 | } | ||
| 730 | |||
| 731 | gint printing_print_message_part(MsgInfo *msginfo, MimeInfo *partinfo) | ||
| 732 | { | ||
| 733 | #if GTK_CHECK_VERSION(2, 10, 0) | ||
| 734 | if (!prefs_common.use_print_cmd) { | ||
| 735 | GSList mlist; | ||
| 736 | |||
| 737 | mlist.data = msginfo; | ||
| 738 | mlist.next = NULL; | ||
| 739 | return printing_print_messages_gtk(&mlist, partinfo, FALSE); | ||
| 740 | } | ||
| 741 | #endif /* GTK_CHECK_VERSION(2, 10, 0) */ | ||
| 742 | if (check_command_line(prefs_common.print_cmd) < 0) | ||
| 743 | return -1; | ||
| 744 | procmsg_print_message_part(msginfo, partinfo, prefs_common.print_cmd, | ||
| 745 | FALSE); | ||
| 746 | return 0; | ||
| 747 | } | ||
