diff options
Diffstat (limited to 'addressbook/printing/e-contact-print.c')
-rw-r--r-- | addressbook/printing/e-contact-print.c | 372 |
1 files changed, 372 insertions, 0 deletions
diff --git a/addressbook/printing/e-contact-print.c b/addressbook/printing/e-contact-print.c new file mode 100644 index 0000000000..482ccb6104 --- /dev/null +++ b/addressbook/printing/e-contact-print.c @@ -0,0 +1,372 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * e-contact-print.c + * Copyright (C) 2000 Helix Code, Inc. + * Author: Chris Lahey <clahey@helixcode.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include "e-contact-print.h" +#include <libgnomeprint/gnome-print.h> +#include <libgnomeprint/gnome-print-dialog.h> +#include <libgnomeprint/gnome-print-master.h> +#include <libgnomeprint/gnome-print-master-preview.h> +#include <libgnomeprint/gnome-print-multipage.h> +#include <gnome-xml/tree.h> +#include <gnome-xml/parser.h> +#include <ctype.h> + +typedef struct _EContactPrintContext EContactPrintContext; + +struct _EContactPrintContext +{ + GnomePrintContext *pc; + GnomePrintMaster *master; + gdouble x; + gdouble y; + EContactPrintStyle *style; + gboolean first_section; +}; + +static void +e_contact_output(GnomePrintContext *pc, GnomeFont *font, double x, double y, gchar *text) +{ + gnome_print_gsave(pc); + gnome_print_setfont(pc, font); + y -= gnome_font_get_ascender(font); + gnome_print_moveto(pc, x, y); + gnome_print_show(pc, text); + gnome_print_grestore(pc); +} + +static void +e_contact_output_and_advance(EContactPrintContext *ctxt, GnomeFont *font, double x, gchar *text) +{ + ctxt->y -= .1 * font->size; + e_contact_output(ctxt->pc, font, x, ctxt->y, text); + ctxt->y -= gnome_font_get_ascender(font) - gnome_font_get_descender(font); + ctxt->y -= .1 * font->size; +} + +static void +e_contact_rectangle(GnomePrintContext *pc, + gdouble x0, + gdouble y0, + gdouble x1, + gdouble y1, + gdouble r, + gdouble g, + gdouble b) +{ + gnome_print_gsave(pc); + gnome_print_setrgbcolor(pc, r, g, b); + gnome_print_moveto(pc, x0, y0); + gnome_print_lineto(pc, x1, y0); + gnome_print_lineto(pc, x1, y1); + gnome_print_lineto(pc, x0, y1); + gnome_print_lineto(pc, x0, y0); + gnome_print_fill(pc); + gnome_print_grestore(pc); +} + +static gchar *e_card_get_string(void *card, gchar *key) +{ + return key; +} + +static gchar *e_card_get_string_fileas(void *card) +{ + return "Lahey, Chris"; +} + +static void +e_contact_print_letter_heading (EContactPrintContext *ctxt, gchar *character) +{ + gdouble ascender, descender; + gdouble width; + + width = gnome_font_get_width_string(ctxt->style->headings_font, "m "); + ascender = gnome_font_get_ascender(ctxt->style->headings_font); + descender = gnome_font_get_descender(ctxt->style->headings_font); + gnome_print_gsave( ctxt->pc ); + e_contact_rectangle( ctxt->pc, ctxt->x, ctxt->y, ctxt->x + width, ctxt->y - (ctxt->style->headings_font->size + 6), 0, 0, 0); + gnome_print_setrgbcolor(ctxt->pc, 1, 1, 1); + ctxt->y -= 4; + e_contact_output(ctxt->pc, ctxt->style->headings_font, ctxt->x + (width - gnome_font_get_width_string(ctxt->style->headings_font, character))/ 2, ctxt->y, character); + ctxt->y -= ascender - descender; + ctxt->y -= 2; + ctxt->y -= 3; + gnome_print_grestore( ctxt->pc ); +} + +static double +e_contact_get_letter_tab_width (EContactPrintContext *ctxt) +{ + return gnome_font_get_width_string(ctxt->style->body_font, "123") + ctxt->style->body_font->size / 5; +} + +static double +e_contact_get_letter_heading_height (EContactPrintContext *ctxt) +{ + return ctxt->style->headings_font->size * 2; +} + +static void +e_contact_start_new_page(EContactPrintContext *ctxt) +{ + ctxt->x = ctxt->style->left_margin * 72; + ctxt->y = (ctxt->style->page_height - ctxt->style->top_margin) * 72; + gnome_print_showpage(ctxt->pc); +} + +static double +e_contact_get_card_size(void *card, EContactPrintContext *ctxt, GList *shown_fields) +{ + double height = 0; + height += ctxt->style->headings_font->size; + for(; shown_fields; shown_fields = g_list_next(shown_fields)) { + gchar *field = e_card_get_string(card, shown_fields->data); + gchar *start = field; + gchar *text; + gchar *temp; + for( text = start, temp = strchr(text, '\n'); temp; text = temp + 1, temp = strchr(text, '\n')) { + height += ctxt->style->body_font->size; + } + height += ctxt->style->body_font->size; + } + return height; +} + + +static void +e_contact_print_card (void *card, EContactPrintContext *ctxt, GList *shown_fields) +{ + gnome_print_gsave(ctxt->pc); + ctxt->y -= 2; + e_contact_rectangle(ctxt->pc, ctxt->x, ctxt->y + 2, ctxt->x + (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin) * 72, ctxt->y - (gnome_font_get_ascender(ctxt->style->headings_font) - gnome_font_get_descender(ctxt->style->headings_font)) - 2, .85, .85, .85); + e_contact_output(ctxt->pc, ctxt->style->headings_font, ctxt->x + 2, ctxt->y, e_card_get_string_fileas(card)); + ctxt->y -= gnome_font_get_ascender(ctxt->style->headings_font) - gnome_font_get_descender(ctxt->style->headings_font); + ctxt->y -= 2; + + for(; shown_fields; shown_fields = g_list_next(shown_fields)) { + double xoff = 0; + gchar *field = e_card_get_string(card, shown_fields->data); + ctxt->y -= .1 * ctxt->style->body_font->size; + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, shown_fields->data); + xoff += gnome_font_get_width_string(ctxt->style->body_font, shown_fields->data); + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, ": "); + xoff += gnome_font_get_width_string(ctxt->style->body_font, ": "); + if (strchr(field, '\n')) { + gchar *start = g_strdup(field); + gchar *text; + gchar *temp; + for( text = start, temp = strchr(text, '\n'); temp; text = temp + 1, temp = strchr(text, '\n')) { + *temp = 0; + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, text); + ctxt->y -= gnome_font_get_ascender(ctxt->style->body_font) - gnome_font_get_descender(ctxt->style->body_font); + ctxt->y -= .2 * ctxt->style->body_font->size; + xoff = 0; + } + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, text); + ctxt->y -= gnome_font_get_ascender(ctxt->style->body_font) - gnome_font_get_descender(ctxt->style->body_font); + ctxt->y -= .1 * ctxt->style->body_font->size; + g_free(text); + } else { + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, field); + ctxt->y -= gnome_font_get_ascender(ctxt->style->body_font) - gnome_font_get_descender(ctxt->style->body_font); + ctxt->y -= .1 * ctxt->style->body_font->size; + } + } + gnome_print_grestore(ctxt->pc); +} + +static void +e_contact_do_print (void *book, EContactPrintContext *ctxt, GList *shown_fields) +{ + gchar *character = NULL; + gchar first_page_character = 'a' - 1; + void *card = NULL; + int i; + gdouble page_height = 72 * (ctxt->style->page_height - ctxt->style->top_margin - ctxt->style->bottom_margin); + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + ctxt->y = (ctxt->style->page_height - ctxt->style->top_margin) * 72; + ctxt->x = (ctxt->style->left_margin) * 72; + if ( ctxt->style->letter_tabs ) + page_width -= e_contact_get_letter_tab_width(ctxt); + /* + for(card = e_book_get_first(book); card; card = e_book_get_next(book)) { + */ + for (i=0; i < 40; i++) { + gchar *file_as = e_card_get_string_fileas(card); + if ( ctxt->style->letter_headings && file_as && (!character || *character != tolower(*file_as)) ) { + if (ctxt->style->sections_start_new_page) + e_contact_start_new_page(ctxt); + else if (ctxt->y - e_contact_get_letter_heading_height(ctxt) - e_contact_get_card_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72) + e_contact_start_new_page(ctxt); + if (!character) + character = g_strdup(" "); + *character = tolower(*file_as); + e_contact_print_letter_heading(ctxt, character); + ctxt->first_section = FALSE; + } + if (ctxt->y - e_contact_get_card_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72) { + e_contact_start_new_page(ctxt); + e_contact_print_letter_heading(ctxt, character); + } + e_contact_print_card(card, ctxt, shown_fields); + } + gnome_print_showpage(ctxt->pc); + gnome_print_context_close(ctxt->pc); + g_free(character); +} + +static void +e_contact_build_style(EContactPrintStyle *style) +{ + xmlDocPtr styledoc; + style->title = ""; + style->sections_start_new_page = FALSE; + style->num_columns = 1; + style->blank_forms = 2; + style->letter_tabs = TRUE; + style->letter_headings = TRUE; + style->headings_font = gnome_font_new("Helvetica-Bold", 8); + style->body_font = gnome_font_new("Helvetica", 6); + style->print_using_grey = TRUE; + style->paper_type = 0; + style->paper_width = 8.5; + style->paper_height = 11; + style->paper_source = 0; + style->top_margin = .5; + style->left_margin = .5; + style->bottom_margin = .5; + style->right_margin = .5; + style->page_size = 0; + style->page_width = 2.75; + style->page_height = 4.25; +#if 0 + style->page_width = 4.25; + style->page_height = 5.5; +#endif + style->orientation_portrait = FALSE; + style->header_font = gnome_font_new("Helvetica", 6); + style->left_header = ""; + style->center_header = ""; + style->right_header = ""; + style->footer_font = gnome_font_new("Helvetica", 6); + style->left_footer = ""; + style->center_footer = ""; + style->right_footer = ""; + style->reverse_on_even_pages = FALSE; + + styledoc = xmlParseFile("smallbook.ecps"); + if (styledoc) { +#if 0 + xmlNodePtr stylenode = xmlDocGetRootElement(styledoc); +#endif + xmlFreeDoc(styledoc); + } +} + +static gint +e_contact_print_close(GnomeDialog *dialog, gpointer data) +{ + return FALSE; +} + +static void +e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data) +{ + EContactPrintContext ctxt; + EContactPrintStyle style; + GnomePrintMaster *master; + GtkWidget *preview; + GnomePrintContext *pc; + void *book = gtk_object_get_data(GTK_OBJECT(dialog), "book"); + GList *shown_fields = gtk_object_get_data(GTK_OBJECT(dialog), "shown_fields"); + switch( button ) { + case GNOME_PRINT_PRINT: + master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) ); + pc = gnome_print_master_get_context( master ); + e_contact_build_style(&style); + + ctxt.x = 0; + ctxt.y = 0; + ctxt.style = &style; + ctxt.master = master; + ctxt.first_section = TRUE; + + ctxt.pc = gnome_print_multipage_new_from_sizes(pc, + 72 * style.paper_width, + 72 * style.paper_height, + 72 * style.page_width, + 72 * style.page_height); + + e_contact_do_print(book, &ctxt, shown_fields); + gnome_print_master_print(master); + gtk_object_unref(GTK_OBJECT(ctxt.pc)); + gtk_object_unref(GTK_OBJECT(master)); + gnome_dialog_close(dialog); + break; + case GNOME_PRINT_PREVIEW: + master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) ); + pc = gnome_print_master_get_context( master ); + e_contact_build_style(&style); + + ctxt.x = 0; + ctxt.y = 0; + ctxt.style = &style; + ctxt.master = master; + ctxt.first_section = TRUE; + + ctxt.pc = gnome_print_multipage_new_from_sizes(pc, + 72 * style.paper_width, + 72 * style.paper_height, + 72 * style.page_width, + 72 * style.page_height); + + e_contact_do_print(book, &ctxt, shown_fields); + preview = GTK_WIDGET(gnome_print_master_preview_new(master, "Print Preview")); + gtk_widget_show_all(preview); + gtk_object_unref(GTK_OBJECT(ctxt.pc)); + gtk_object_unref(GTK_OBJECT(master)); + break; + case GNOME_PRINT_CANCEL: + gnome_dialog_close(dialog); + break; + } +} + +GtkWidget * +e_contact_print_dialog_new(void *book, GList *shown_fields) +{ + GtkWidget *dialog; + + + dialog = gnome_print_dialog_new("Print cards", GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES); + gnome_print_dialog_construct_range_any(GNOME_PRINT_DIALOG(dialog), GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_SELECTION, + NULL, NULL, NULL); + + gtk_object_set_data(GTK_OBJECT(dialog), "book", book); + gtk_object_set_data(GTK_OBJECT(dialog), "shown_fields", shown_fields); + gtk_signal_connect(GTK_OBJECT(dialog), + "clicked", e_contact_print_button, NULL); + gtk_signal_connect(GTK_OBJECT(dialog), + "close", e_contact_print_close, NULL); + return dialog; +} |