diff options
Diffstat (limited to 'addressbook/printing/e-contact-print.c')
-rw-r--r-- | addressbook/printing/e-contact-print.c | 783 |
1 files changed, 683 insertions, 100 deletions
diff --git a/addressbook/printing/e-contact-print.c b/addressbook/printing/e-contact-print.c index 482ccb6104..bcc4b5b725 100644 --- a/addressbook/printing/e-contact-print.c +++ b/addressbook/printing/e-contact-print.c @@ -29,37 +29,248 @@ #include <libgnomeprint/gnome-print-multipage.h> #include <gnome-xml/tree.h> #include <gnome-xml/parser.h> +#include <gnome-xml/xmlmemory.h> #include <ctype.h> +#include <libhnj/hsjust.h> +#include <libhnj/just.h> + +#define SCALE 5 +#define HYPHEN_PIXELS 20 +#define HYPHEN_PENALTY ( (SCALE) * (SCALE) * (HYPHEN_PIXELS) * (HYPHEN_PIXELS) ) typedef struct _EContactPrintContext EContactPrintContext; +static int cardcount; + struct _EContactPrintContext { GnomePrintContext *pc; GnomePrintMaster *master; gdouble x; gdouble y; + gint column; EContactPrintStyle *style; gboolean first_section; + gchar first_char_on_page; + gchar last_char_on_page; + GnomeFont *letter_heading_font; + GnomeFont *letter_tab_font; }; +static gint +e_contact_divide_text(GnomePrintContext *pc, GnomeFont *font, double width, gchar *text, GList **return_val /* Of type char[] */) +{ + if ( width == -1 || gnome_font_get_width_string(font, text) <= width ) { + if ( return_val ) { + *return_val = g_list_append(*return_val, g_strdup(text)); + } + return 1; + } else { +#if 1 + int i, l; + double x = 0; + int lastend = 0; + int linestart = 0; + int firstword = 1; + int linecount = 0; + l = strlen(text); + for ( i = 0; i < l; i++ ) { + if ( text[i] == ' ' ) { + if ( (!firstword) && x + gnome_font_get_width_string_n(font, text + lastend, i - lastend) > width ) { + if (return_val) { + *return_val = g_list_append(*return_val, g_strndup(text + linestart, lastend - linestart)); + } + x = gnome_font_get_width_string(font, " "); + linestart = lastend + 1; + x += gnome_font_get_width_string_n(font, text + linestart, i - linestart); + lastend = i; + linecount ++; + } else { + x += gnome_font_get_width_string_n(font, text + lastend, i - lastend); + lastend = i; + } + firstword = 0; + } else if ( text[i] == '\n' ) { + if ( (!firstword) && x + gnome_font_get_width_string_n(font, text + lastend, i - lastend) > width ) { + if (return_val) { + *return_val = g_list_append(*return_val, g_strndup(text + linestart, lastend - linestart)); + } + linestart = lastend + 1; + lastend = i; + linecount ++; + } + if (return_val) { + *return_val = g_list_append(*return_val, g_strndup(text + linestart, i - linestart)); + } + linestart = i + 1; + lastend = i + 1; + linecount ++; + x = gnome_font_get_width_string(font, " "); + + firstword = 1; + } + } + if ( (!firstword) && x + gnome_font_get_width_string_n(font, text + lastend, i - lastend) > width ) { + if (return_val) { + *return_val = g_list_append(*return_val, g_strndup(text + linestart, lastend - linestart)); + } + linestart = lastend + 1; + lastend = i; + linecount ++; + } + if (return_val) { + *return_val = g_list_append(*return_val, g_strndup(text + linestart, i - linestart)); + } + linecount ++; + return(linecount); +#else + HnjBreak *breaks; + gint *result; + gint *is; + gint n_breaks = 0, n_actual_breaks = 0; + gint i; + gint l; + gchar *hyphenation; + double x = - gnome_font_get_width_string(font, " ") * SCALE; + HnjParams hnjparams; + + hnjparams.set_width = width * SCALE + x; + hnjparams.max_neg_space = 0; + hnjparams.tab_width = 0; + + l = strlen(text); + + /* find possible line breaks. */ + for (i = 0; i < l; i++) { + if (text[i] == '-') + n_breaks++; + else if (text[i] == ' ') + n_breaks++; +#if 0 + else if (hyphenation[i] & 1) + n_breaks++; +#endif + } + + breaks = g_new( HnjBreak, n_breaks + 1 ); + result = g_new( gint, n_breaks + 1 ); + is = g_new( gint, n_breaks + 1 ); + n_breaks = 0; + /* find possible line breaks. */ + + for (i = 0; i < l; i++) { + if ( text[i] == '-' ) { + x += gnome_font_get_width(font, text[i]) * SCALE; + breaks[n_breaks].x0 = x; + breaks[n_breaks].x1 = x; + breaks[n_breaks].penalty = HYPHEN_PENALTY; + breaks[n_breaks].flags = HNJ_JUST_FLAG_ISHYPHEN; + is[n_breaks] = i + 1; + n_breaks++; + } else if ( text[i] == ' ' ) { + breaks[ n_breaks ].x0 = x; + x += gnome_font_get_width(font, text[i]) * SCALE; + breaks[ n_breaks ].x1 = x; + breaks[ n_breaks ].penalty = 0; + breaks[ n_breaks ].flags = HNJ_JUST_FLAG_ISSPACE; + is[ n_breaks ] = i + 1; + n_breaks++; +#if 0 + } else if (word->hyphenation[i] & 1) { + breaks[n_breaks].x0 = x + gnome_font_get_width(font, '-') * SCALE; + breaks[n_breaks].x1 = x; + breaks[n_breaks].penalty = HYPHEN_PENALTY; + breaks[n_breaks].flags = HNJ_JUST_FLAG_ISHYPHEN; + is[n_breaks] = i + 1; + n_breaks++; +#endif + } else + x += gnome_font_get_width(font, text[i]) * SCALE; + + } + is[n_breaks] = i; + breaks[n_breaks].flags = 0; + n_breaks++; + + /* Calculate optimal line breaks. */ + n_actual_breaks = hnj_hs_just (breaks, n_breaks, + &hnjparams, result); + + if ( return_val ) { + gchar *next_val; + if ( breaks[result[0]].flags == HNJ_JUST_FLAG_ISHYPHEN && text[is[result[0]]] != '-' ) { + next_val = g_new(gchar, is[result[0]] + 2); + strncpy(next_val, text, is[result[0]]); + next_val[is[result[0]]] = 0; + strcat(next_val, "-"); + } else { + next_val = g_new(gchar, is[result[0]] + 1); + strncpy(next_val, text, is[result[0]]); + next_val[is[result[0]]] = 0; + } + *return_val = g_list_append(*return_val, next_val); + + for ( i = 1; i < n_actual_breaks; i++ ) { + if ( (breaks[result[i]].flags & HNJ_JUST_FLAG_ISHYPHEN) && (text[is[result[i]]] != '-') ) { + next_val = g_new(gchar, is[result[i]] - is[result[i - 1]] + 2); + strncpy(next_val, text + is[result[i - 1]], is[result[i]] - is[result[i - 1]]); + next_val[is[result[i]] - is[result[i - 1]]] = 0; + strcat(next_val, "-"); + } else { + next_val = g_new(gchar, is[result[i]] - is[result[i - 1]] + 1); + strncpy(next_val, text + is[result[i - 1]], is[result[i]] - is[result[i - 1]]); + next_val[is[result[i]] - is[result[i - 1]]] = 0; + } + *return_val = g_list_append(*return_val, next_val); + } + } + + g_free (breaks); + g_free (result); + g_free (is); + return n_actual_breaks; +#endif + } +} + static void -e_contact_output(GnomePrintContext *pc, GnomeFont *font, double x, double y, gchar *text) +e_contact_output(GnomePrintContext *pc, GnomeFont *font, double x, double y, double width, gchar *text) { + GList *list = NULL, *list_start; + int first_line = 1; 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); + e_contact_divide_text(pc, font, width, text, &list); + for ( list_start = list; list; list = g_list_next(list)) { + y -= gnome_font_get_ascender(font); + gnome_print_moveto(pc, x, y); + gnome_print_show(pc, (char *)list->data); + y -= gnome_font_get_descender(font); + y -= .2 * font->size; + if ( first_line ) { + x += gnome_font_get_width_string(font, " "); + first_line = 0; + } + } + g_list_foreach( list_start, (GFunc) g_free, NULL ); + g_list_free( list_start ); gnome_print_grestore(pc); } +static gdouble +e_contact_text_height(GnomePrintContext *pc, GnomeFont *font, double width, gchar *text) +{ + int line_count = e_contact_divide_text(pc, font, width, text, NULL); + return line_count * (gnome_font_get_ascender(font) + gnome_font_get_descender(font)) + + line_count * .2 * font->size; +} + static void -e_contact_output_and_advance(EContactPrintContext *ctxt, GnomeFont *font, double x, gchar *text) +e_contact_output_and_advance(EContactPrintContext *ctxt, GnomeFont *font, double x, double width, 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); + e_contact_output(ctxt->pc, font, x, ctxt->y, width, text); + ctxt->y -= e_contact_text_height(ctxt->pc, font, width, text); ctxt->y -= .1 * font->size; } @@ -91,7 +302,67 @@ static gchar *e_card_get_string(void *card, gchar *key) static gchar *e_card_get_string_fileas(void *card) { - return "Lahey, Chris"; + if (cardcount < 4) + return "Lahey, Chris"; + else if (cardcount < 20) + return "Rasputin"; + else if (cardcount < 24) + return "Wow, this guy has a really long name. Can you believe it?"; + else + return "Zamboni"; +} + +static double +e_contact_get_letter_tab_width (EContactPrintContext *ctxt) +{ + return gnome_font_get_width_string(ctxt->letter_tab_font, "123") + 4 + 18; +} + +static double +e_contact_print_letter_tab (EContactPrintContext *ctxt) +{ + char character; + gdouble x, y; + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble tab_height, tab_width; + gdouble font_size; + tab_height = 72 * (ctxt->style->page_height - ctxt->style->top_margin - ctxt->style->bottom_margin) / 27.0; + font_size = tab_height / 2; + tab_width = e_contact_get_letter_tab_width(ctxt) - 18; + x = page_width + 72 * (ctxt->style->left_margin) - tab_width; + y = 72 * (ctxt->style->page_height - ctxt->style->top_margin); + + + gnome_print_gsave( ctxt->pc ); + if ( ctxt->style->print_using_grey ) + e_contact_rectangle( ctxt->pc, x, 72 * (ctxt->style->page_height - ctxt->style->top_margin), x + tab_width, ctxt->style->bottom_margin * 72, .85, .85, .85 ); + for ( character = 'A' - 1; character <= 'Z'; character ++ ) { + char string[] = "123"; + if ( character >= 'A' ) { + string[0] = tolower(character); + string[1] = 0; + } + if ( character >= ctxt->first_char_on_page && character <= ctxt->last_char_on_page ) { + e_contact_rectangle( ctxt->pc, x + 1, y - 1, x + tab_width - 1, y - (tab_height - 1), 0, 0, 0 ); + gnome_print_setrgbcolor( ctxt->pc, 1, 1, 1 ); + e_contact_output( ctxt->pc, ctxt->letter_tab_font, x + tab_width / 2 - gnome_font_get_width_string(ctxt->letter_tab_font, string) / 2, y - (tab_height - font_size) / 2, -1, string ); + } else { + gnome_print_setrgbcolor( ctxt->pc, 0, 0, 0 ); + e_contact_output( ctxt->pc, ctxt->letter_tab_font, x + tab_width / 2 - gnome_font_get_width_string(ctxt->letter_tab_font, string) / 2, y - (tab_height - font_size) / 2, -1, string ); + } + y -= tab_height; + } + gnome_print_grestore( ctxt->pc ); + 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) +{ + gdouble ascender, descender; + ascender = gnome_font_get_ascender(ctxt->letter_heading_font); + descender = gnome_font_get_descender(ctxt->letter_heading_font); + return ascender + descender + 9; } static void @@ -100,55 +371,61 @@ 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); + width = gnome_font_get_width_string(ctxt->letter_heading_font, "m") * 1.7; + ascender = gnome_font_get_ascender(ctxt->letter_heading_font); + descender = gnome_font_get_descender(ctxt->letter_heading_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); + e_contact_rectangle( ctxt->pc, ctxt->x, ctxt->y, ctxt->x + width, ctxt->y - (ascender + descender + 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; + e_contact_output(ctxt->pc, ctxt->letter_heading_font, ctxt->x + (width - gnome_font_get_width_string(ctxt->letter_heading_font, character))/ 2, ctxt->y, -1, 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; + ctxt->column = 0; + if ( ctxt->style->letter_tabs ) + e_contact_print_letter_tab(ctxt); gnome_print_showpage(ctxt->pc); + + ctxt->first_char_on_page = ctxt->last_char_on_page + 1; } static double e_contact_get_card_size(void *card, EContactPrintContext *ctxt, GList *shown_fields) { - double height = 0; - height += ctxt->style->headings_font->size; + gdouble height = 0; + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble column_width; + if ( ctxt->style->letter_tabs ) + page_width -= e_contact_get_letter_tab_width(ctxt); + column_width = (page_width + 18) / ctxt->style->num_columns - 18; + + height += ctxt->style->headings_font->size * .2; + + height += ctxt->style->headings_font->size * .2; + + height += e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, e_card_get_string_fileas(card)); + height += ctxt->style->headings_font->size * .2; + + height += ctxt->style->headings_font->size * .2; + for(; shown_fields; shown_fields = g_list_next(shown_fields)) { + double xoff = 0; 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; + xoff += gnome_font_get_width_string(ctxt->style->body_font, shown_fields->data); + xoff += gnome_font_get_width_string(ctxt->style->body_font, ": "); + height += e_contact_text_height(ctxt->pc, ctxt->style->body_font, column_width - xoff, field); + height += .2 * ctxt->style->body_font->size; } + height += ctxt->style->headings_font->size * .4; return height; } @@ -156,95 +433,313 @@ e_contact_get_card_size(void *card, EContactPrintContext *ctxt, GList *shown_fie static void e_contact_print_card (void *card, EContactPrintContext *ctxt, GList *shown_fields) { + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble column_width; + if ( ctxt->style->letter_tabs ) + page_width -= e_contact_get_letter_tab_width(ctxt); + column_width = (page_width + 18) / ctxt->style->num_columns - 18; + 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; + + ctxt->y -= ctxt->style->headings_font->size * .2; + + ctxt->y -= ctxt->style->headings_font->size * .2; + + if (ctxt->style->print_using_grey) + e_contact_rectangle(ctxt->pc, ctxt->x, ctxt->y + ctxt->style->headings_font->size * .2, ctxt->x + column_width, ctxt->y - e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, e_card_get_string_fileas(card)) - ctxt->style->headings_font->size * .2, .85, .85, .85); + e_contact_output(ctxt->pc, ctxt->style->headings_font, ctxt->x + 2, ctxt->y, column_width - 4, e_card_get_string_fileas(card)); + ctxt->y -= e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, e_card_get_string_fileas(card)); + ctxt->y -= ctxt->style->headings_font->size * .2; + + ctxt->y -= ctxt->style->headings_font->size * .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); + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, 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, ": "); + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, ": "); 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, column_width - xoff, field); + ctxt->y -= e_contact_text_height(ctxt->pc, ctxt->style->body_font, column_width - xoff, field); + ctxt->y -= .2 * ctxt->style->body_font->size; + } + ctxt->y -= ctxt->style->headings_font->size * .4; + gnome_print_grestore(ctxt->pc); +} + +static void +e_contact_start_new_column (EContactPrintContext *ctxt) +{ + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble column_offset; + if ( ctxt->style->letter_tabs ) + page_width -= e_contact_get_letter_tab_width(ctxt); + column_offset = (page_width + 18) / ctxt->style->num_columns; + ctxt->column ++; + if (ctxt->column >= ctxt->style->num_columns) { + e_contact_start_new_page(ctxt); + ctxt->column = 0; + } + ctxt->x = (72 * ctxt->style->left_margin) + column_offset * ctxt->column; + ctxt->y = 72 * (ctxt->style->page_height - ctxt->style->top_margin); +} + +static void +e_contact_do_print_cards (void *book, EContactPrintContext *ctxt, GList *shown_fields) +{ + gchar *character = NULL; + void *card = NULL; + gboolean first_contact = TRUE; + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble column_width; + 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); + + ctxt->first_char_on_page = 'A' - 1; + + column_width = (page_width + 18) / ctxt->style->num_columns - 18; + /* + for(card = e_book_get_first(book); card; card = e_book_get_next(book)) { + */ + for (cardcount=0; cardcount < 30; cardcount++) { + gchar *file_as = e_card_get_string_fileas(card); + if ( file_as && (!character || *character != tolower(*file_as)) ) { + if (ctxt->style->sections_start_new_page && ! first_contact) { + e_contact_start_new_page(ctxt); } - 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; + else if ((!first_contact) && (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_column(ctxt); + if (!character) + character = g_strdup(" "); + *character = tolower(*file_as); + if ( ctxt->style->letter_headings ) + e_contact_print_letter_heading(ctxt, character); + ctxt->first_section = FALSE; + } + else if ( (!first_contact) && (ctxt->y - e_contact_get_card_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72)) { + e_contact_start_new_column(ctxt); + if ( ctxt->style->letter_headings ) + e_contact_print_letter_heading(ctxt, character); + } + ctxt->last_char_on_page = toupper(*file_as); + if ( ctxt->last_char_on_page < ctxt->first_char_on_page ) + ctxt->first_char_on_page = ctxt->last_char_on_page; + e_contact_print_card(card, ctxt, shown_fields); + first_contact = FALSE; + } + ctxt->last_char_on_page = 'Z'; + if ( ctxt->style->letter_tabs ) + e_contact_print_letter_tab(ctxt); + gnome_print_showpage(ctxt->pc); + gnome_print_context_close(ctxt->pc); + g_free(character); +} + +static double +e_contact_get_phone_list_size(void *card, EContactPrintContext *ctxt, GList *shown_fields) +{ + double height = 0; + + height += ctxt->style->headings_font->size * .2; + + height += ctxt->style->headings_font->size * .2; + + for(; shown_fields; shown_fields = g_list_next(shown_fields)) { + if ( 1 ) /* field is a phone field. */ { + gchar *field = e_card_get_string(card, shown_fields->data); + height += e_contact_text_height(ctxt->pc, ctxt->style->body_font, 100, field); + height += .2 * ctxt->style->body_font->size; + } + } + height += ctxt->style->headings_font->size * .4; + return height; +} + + +static void +e_contact_print_phone_list (void *card, EContactPrintContext *ctxt, GList *shown_fields) +{ + gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble column_width; + double xoff, dotwidth; + int dotcount; + char *dots; + int i; + if ( ctxt->style->letter_tabs ) + page_width -= e_contact_get_letter_tab_width(ctxt); + column_width = (page_width + 18) / ctxt->style->num_columns - 18; + + gnome_print_gsave(ctxt->pc); + + ctxt->y -= ctxt->style->headings_font->size * .2; + + ctxt->y -= ctxt->style->headings_font->size * .2; + + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x, ctxt->y, -1, e_card_get_string_fileas(card)); + + xoff = column_width - 9 * ctxt->style->body_font->size; + dotwidth = xoff - + gnome_font_get_width_string(ctxt->style->body_font, e_card_get_string_fileas(card)) - + gnome_font_get_width_string(ctxt->style->body_font, " "); + dotcount = dotwidth / gnome_font_get_width(ctxt->style->body_font, '.'); + dots = g_new(gchar, dotcount + 1); + for (i = 0; i < dotcount; i++) + dots[i] = '.'; + dots[dotcount] = 0; + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff - dotcount * gnome_font_get_width(ctxt->style->body_font, '.'), ctxt->y, -1, dots); + g_free(dots); + + for(; shown_fields; shown_fields = g_list_next(shown_fields)) { + if ( 1 ) /* field is a phone field. */ { + gchar *field = e_card_get_string(card, shown_fields->data); + e_contact_output(ctxt->pc, ctxt->style->body_font, ctxt->x + xoff, ctxt->y, -1, shown_fields->data); + e_contact_output(ctxt->pc, ctxt->style->body_font, + ctxt->x + column_width - gnome_font_get_width_string(ctxt->style->body_font, + field), + ctxt->y, + -1, + field); + ctxt->y -= e_contact_text_height(ctxt->pc, ctxt->style->body_font, 100, field); + ctxt->y -= .2 * ctxt->style->body_font->size; } } + ctxt->y -= ctxt->style->headings_font->size * .4; gnome_print_grestore(ctxt->pc); } static void -e_contact_do_print (void *book, EContactPrintContext *ctxt, GList *shown_fields) +e_contact_do_print_phone_list (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); + gboolean first_contact = TRUE; gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin); + gdouble column_width; 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); + + ctxt->first_char_on_page = 'A' - 1; + + column_width = (page_width + 18) / ctxt->style->num_columns - 18; /* for(card = e_book_get_first(book); card; card = e_book_get_next(book)) { */ - for (i=0; i < 40; i++) { + for (i=0; i < 30; 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) + if ( file_as && (!character || *character != tolower(*file_as)) ) { + if (ctxt->style->sections_start_new_page && ! first_contact) { e_contact_start_new_page(ctxt); + } + else if ((!first_contact) && (ctxt->y - e_contact_get_letter_heading_height(ctxt) - e_contact_get_phone_list_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72)) + e_contact_start_new_column(ctxt); if (!character) character = g_strdup(" "); *character = tolower(*file_as); - e_contact_print_letter_heading(ctxt, character); + if ( ctxt->style->letter_headings ) + 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); + else if ( (!first_contact) && (ctxt->y - e_contact_get_card_size(card, ctxt, shown_fields) < ctxt->style->bottom_margin * 72)) { + e_contact_start_new_column(ctxt); + if ( ctxt->style->letter_headings ) + e_contact_print_letter_heading(ctxt, character); } - e_contact_print_card(card, ctxt, shown_fields); + ctxt->last_char_on_page = toupper(*file_as); + if ( ctxt->last_char_on_page < ctxt->first_char_on_page ) + ctxt->first_char_on_page = ctxt->last_char_on_page; + e_contact_print_phone_list(card, ctxt, shown_fields); + first_contact = FALSE; } + ctxt->last_char_on_page = 'Z'; + if ( ctxt->style->letter_tabs ) + e_contact_print_letter_tab(ctxt); gnome_print_showpage(ctxt->pc); gnome_print_context_close(ctxt->pc); g_free(character); } static void +e_contact_do_print (void *book, EContactPrintContext *ctxt, GList *shown_fields) +{ + switch ( ctxt->style->type ) { + case E_CONTACT_PRINT_TYPE_CARDS: + e_contact_do_print_cards( book, ctxt, shown_fields ); + break; + case E_CONTACT_PRINT_TYPE_PHONE_LIST: + e_contact_do_print_phone_list( book, ctxt, shown_fields ); + break; + } +} + +static void lowify( char *data ) +{ + for ( ; *data; data++ ) + *data = tolower(*data); +} + +static gboolean get_bool( char *data ) +{ + if ( data ) { + lowify ( data ); + return ! strcmp(data, "true"); + } else + return FALSE; +} + +static void get_string( char *data, char **variable ) +{ + g_free ( *variable ); + if ( data ) + *variable = g_strdup( data ); + else + *variable = g_strdup( "" ); +} + +static int get_integer( char *data ) +{ + if ( data ) + return atoi(data); + else + return 0; +} + +static double get_float( char *data ) +{ + if ( data ) + return atof(data); + else + return 0; +} + +static void get_font( char *data, GnomeFont **variable ) +{ + if ( data ) { + GnomeFont *font = gnome_font_new_from_full_name( data ); + if ( font ) { + gtk_object_unref( GTK_OBJECT(*variable) ); + *variable = font; + } + } +} + + +static void e_contact_build_style(EContactPrintStyle *style) { xmlDocPtr styledoc; - style->title = ""; - style->sections_start_new_page = FALSE; - style->num_columns = 1; + style->title = g_strdup(""); + style->type = E_CONTACT_PRINT_TYPE_CARDS; + style->sections_start_new_page = TRUE; + style->num_columns = 2; style->blank_forms = 2; style->letter_tabs = TRUE; - style->letter_headings = TRUE; + style->letter_headings = FALSE; style->headings_font = gnome_font_new("Helvetica-Bold", 8); style->body_font = gnome_font_new("Helvetica", 6); style->print_using_grey = TRUE; @@ -263,22 +758,97 @@ e_contact_build_style(EContactPrintStyle *style) style->page_width = 4.25; style->page_height = 5.5; #endif +#if 0 + style->page_width = 5.5; + style->page_height = 8.5; +#endif style->orientation_portrait = FALSE; style->header_font = gnome_font_new("Helvetica", 6); - style->left_header = ""; - style->center_header = ""; - style->right_header = ""; + style->left_header = g_strdup(""); + style->center_header = g_strdup(""); + style->right_header = g_strdup(""); style->footer_font = gnome_font_new("Helvetica", 6); - style->left_footer = ""; - style->center_footer = ""; - style->right_footer = ""; + style->left_footer = g_strdup(""); + style->center_footer = g_strdup(""); + style->right_footer = g_strdup(""); style->reverse_on_even_pages = FALSE; - styledoc = xmlParseFile("smallbook.ecps"); if (styledoc) { -#if 0 xmlNodePtr stylenode = xmlDocGetRootElement(styledoc); -#endif + xmlNodePtr node; + for (node = stylenode->childs; node; node = node->next) { + char *data = xmlNodeGetContent ( node ); + if ( !strcmp( node->name, "title" ) ) { + get_string(data, &(style->title)); + } else if ( !strcmp( node->name, "type" ) ) { + lowify( data ); + if ( !strcmp( data, "cards" ) ) + style->type = E_CONTACT_PRINT_TYPE_CARDS; + else if ( !strcmp( data, "memo_style" ) ) + style->type = E_CONTACT_PRINT_TYPE_MEMO_STYLE; + else if ( !strcmp( data, "phone_list" ) ) + style->type = E_CONTACT_PRINT_TYPE_PHONE_LIST; + } else if ( !strcmp( node->name, "sections_start_new_page" ) ) { + style->sections_start_new_page = get_bool(data); + } else if ( !strcmp( node->name, "num_columns" ) ) { + style->num_columns = get_integer(data); + } else if ( !strcmp( node->name, "blank_forms" ) ) { + style->blank_forms = get_integer(data); + } else if ( !strcmp( node->name, "letter_tabs" ) ) { + style->letter_tabs = get_bool(data); + } else if ( !strcmp( node->name, "letter_headings" ) ) { + style->letter_headings = get_bool(data); + } else if ( !strcmp( node->name, "headings_font" ) ) { + get_font( data, &(style->headings_font) ); + } else if ( !strcmp( node->name, "body_font" ) ) { + get_font( data, &(style->body_font) ); + } else if ( !strcmp( node->name, "print_using_grey" ) ) { + style->print_using_grey = get_bool(data); + } else if ( !strcmp( node->name, "paper_width" ) ) { + style->paper_width = get_float(data); + } else if ( !strcmp( node->name, "paper_height" ) ) { + style->paper_height = get_float(data); + } else if ( !strcmp( node->name, "top_margin" ) ) { + style->top_margin = get_float(data); + } else if ( !strcmp( node->name, "left_margin" ) ) { + style->left_margin = get_float(data); + } else if ( !strcmp( node->name, "bottom_margin" ) ) { + style->bottom_margin = get_float(data); + } else if ( !strcmp( node->name, "right_margin" ) ) { + style->right_margin = get_float(data); + } else if ( !strcmp( node->name, "page_width" ) ) { + style->page_width = get_float(data); + } else if ( !strcmp( node->name, "page_height" ) ) { + style->page_height = get_float(data); + } else if ( !strcmp( node->name, "orientation" ) ) { + if ( data ) { + lowify(data); + style->orientation_portrait = strcmp(data, "landscape"); + } else { + style->orientation_portrait = TRUE; + } + } else if ( !strcmp( node->name, "header_font" ) ) { + get_font( data, &(style->header_font) ); + } else if ( !strcmp( node->name, "left_header" ) ) { + get_string(data, &(style->left_header)); + } else if ( !strcmp( node->name, "center_header" ) ) { + get_string(data, &(style->center_header)); + } else if ( !strcmp( node->name, "right_header" ) ) { + get_string(data, &(style->right_header)); + } else if ( !strcmp( node->name, "footer_font" ) ) { + get_font( data, &(style->footer_font) ); + } else if ( !strcmp( node->name, "left_footer" ) ) { + get_string(data, &(style->left_footer)); + } else if ( !strcmp( node->name, "center_footer" ) ) { + get_string(data, &(style->center_footer)); + } else if ( !strcmp( node->name, "right_footer" ) ) { + get_string(data, &(style->right_footer)); + } else if ( !strcmp( node->name, "reverse_on_even_pages" ) ) { + style->reverse_on_even_pages = get_bool(data); + } + if ( data ) + xmlFree (data); + } xmlFreeDoc(styledoc); } } @@ -299,6 +869,7 @@ e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data) GnomePrintContext *pc; void *book = gtk_object_get_data(GTK_OBJECT(dialog), "book"); GList *shown_fields = gtk_object_get_data(GTK_OBJECT(dialog), "shown_fields"); + gdouble font_size; switch( button ) { case GNOME_PRINT_PRINT: master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) ); @@ -307,15 +878,21 @@ e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data) ctxt.x = 0; ctxt.y = 0; + ctxt.column = 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); + ctxt.first_char_on_page = 'A' - 1; + + font_size = 72 * ctxt.style->page_height / 27.0 / 2.0; + ctxt.letter_heading_font = gnome_font_new(gnome_font_get_name(ctxt.style->headings_font), ctxt.style->headings_font->size * 1.5); + ctxt.letter_tab_font = gnome_font_new(gnome_font_get_name(ctxt.style->headings_font), font_size); + + ctxt.pc = GNOME_PRINT_CONTEXT(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); @@ -330,15 +907,21 @@ e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data) ctxt.x = 0; ctxt.y = 0; + ctxt.column = 0; ctxt.style = &style; ctxt.master = master; ctxt.first_section = TRUE; + ctxt.first_char_on_page = 'A' - 1; + + font_size = 72 * ctxt.style->page_height / 27.0 / 2.0; + ctxt.letter_heading_font = gnome_font_new(gnome_font_get_name(ctxt.style->headings_font), ctxt.style->headings_font->size * 1.5); + ctxt.letter_tab_font = gnome_font_new(gnome_font_get_name(ctxt.style->headings_font), font_size); - 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); + ctxt.pc = GNOME_PRINT_CONTEXT(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")); @@ -365,8 +948,8 @@ e_contact_print_dialog_new(void *book, GList *shown_fields) 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); + "clicked", GTK_SIGNAL_FUNC(e_contact_print_button), NULL); gtk_signal_connect(GTK_OBJECT(dialog), - "close", e_contact_print_close, NULL); + "close", GTK_SIGNAL_FUNC(e_contact_print_close), NULL); return dialog; } |