aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/printing/e-contact-print.c
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/printing/e-contact-print.c')
-rw-r--r--addressbook/printing/e-contact-print.c1015
1 files changed, 390 insertions, 625 deletions
diff --git a/addressbook/printing/e-contact-print.c b/addressbook/printing/e-contact-print.c
index 32098689d9..002e284366 100644
--- a/addressbook/printing/e-contact-print.c
+++ b/addressbook/printing/e-contact-print.c
@@ -33,19 +33,11 @@
#include <libxml/xmlmemory.h>
#include <libgnome/gnome-util.h>
#include <glib/gi18n.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeprint/gnome-print.h>
-#include <libgnomeprint/gnome-print-unit.h>
-#include <libgnomeprint/gnome-print-config.h>
-#include <libgnomeprint/gnome-font.h>
-#include <libgnomeprint/gnome-print-job.h>
-#include <libgnomeprintui/gnome-print-dialog.h>
-#include <libgnomeprintui/gnome-print-job-preview.h>
#include <libebook/e-book.h>
#include <libebook/e-contact.h>
#include <gtk/gtk.h>
-#include <gtk/gtkprintunixdialog.h>
+#include <libedataserver/e-flag.h>
#include <libedataserver/e-xml-utils.h>
#include "e-util/e-print.h"
@@ -53,556 +45,340 @@
#include "e-util/e-util-private.h"
#include "e-contact-print.h"
-
-#define SCALE 5
-#define HYPHEN_PIXELS 20
-#define HYPHEN_PENALTY ( (SCALE) * (SCALE) * (HYPHEN_PIXELS) * (HYPHEN_PIXELS) )
typedef struct _EContactPrintContext EContactPrintContext;
typedef struct _ContactPrintItem ContactPrintItem;
struct _EContactPrintContext
{
- GtkPrintContext *pc;
- GtkPrintOperation *print;
- GnomePrintJob *master;
- PangoLayout *pl;
+ GtkPrintContext *context;
gdouble x;
gdouble y;
gint column;
+ gdouble column_width;
+ gdouble column_spacing;
EContactPrintStyle *style;
gboolean first_section;
PangoFontDescription *letter_heading_font;
- char *character;
+ gchar *section;
gboolean first_contact;
- gboolean uses_book;
- int type;
- gint response_id;
EBook *book;
EBookQuery *query;
- GList *contacts;
-};
-
-struct _ContactPrintItem
-{
- EContactPrintContext *ctxt;
- EContactPrintStyle *style;
- EContact *contact;
GList *contact_list;
- EBook *book;
- GtkPrintSettings *settings;
- gboolean uses_book, uses_list;
};
-static void
-contact_draw_page (GtkPrintOperation *print, GtkPrintContext *context, gint page_nr, ContactPrintItem *cpi);
-
-static void
-print_func (EBookView *book_view, const GList *contacts, EContactPrintContext *ctxt);
-
-static double
-get_font_height (PangoFontDescription *font)
+static gdouble
+get_font_height (PangoFontDescription *desc)
{
- return (double)pango_font_description_get_size (font)/(double)PANGO_SCALE;
+ return pango_units_to_double (
+ pango_font_description_get_size (desc));
}
-static double
-get_font_width (EContactPrintContext *context, PangoFontDescription *font, const char *text)
+static gdouble
+get_font_width (GtkPrintContext *context,
+ PangoFontDescription *desc,
+ const gchar *text)
{
- int width;
- int height;
+ PangoLayout *layout;
+ gint width, height;
- g_return_val_if_fail (font, 0.0);
- g_return_val_if_fail (text, 0.0);
+ g_return_val_if_fail (desc, .0);
+ g_return_val_if_fail (text, .0);
- g_assert (context->pl);
- pango_layout_set_font_description (context->pl, font);
- pango_layout_set_text (context->pl, text, -1);
- pango_layout_set_width (context->pl, -1);
- pango_layout_set_indent (context->pl, 0);
+ layout = gtk_print_context_create_pango_layout (context);
- pango_layout_get_size (context->pl,
- &width,
- &height);
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, text, -1);
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_indent (layout, 0);
- return (double)width/(double)PANGO_SCALE;
-}
+ pango_layout_get_size (layout, &width, &height);
-static PangoFontDescription*
-find_font (const char *name, double height)
-{
- PangoFontDescription *desc = pango_font_description_new ();
- pango_font_description_set_family (desc, name);
- pango_font_description_set_size (desc, height * PANGO_SCALE);
+ g_object_unref (layout);
- return desc;
+ return pango_units_to_double (width);
}
-static PangoFontDescription*
-find_closest_font_from_weight_slant (const guchar *family, GnomeFontWeight weight, gboolean italic, gdouble size)
+static void
+e_contact_output (GtkPrintContext *context,
+ PangoFontDescription *font,
+ gdouble x, gdouble y, gdouble width,
+ const gchar *text)
{
- PangoFontDescription *desc = pango_font_description_new ();
- pango_font_description_set_family (desc, family);
-
- /* GnomePrintWeight and PangoWeight values should be interchangeable: */
- pango_font_description_set_weight (desc, (PangoWeight)weight);
+ PangoLayout *layout;
+ gdouble indent;
+ cairo_t *cr;
- if (italic) {
- pango_font_description_set_style (desc, PANGO_STYLE_ITALIC);
- }
- pango_font_description_set_size (desc, size * PANGO_SCALE);
+ layout = gtk_print_context_create_pango_layout (context);
- return desc;
-}
+ if (width == -1 || get_font_width (context, font, text) <= width)
+ indent = .0;
+ else
+ indent = get_font_width (context, font, " ");
-static void
-e_contact_output(EContactPrintContext *ctxt, PangoFontDescription *font, double x, double y, double width, const gchar *text)
-{
- double indent;
- cairo_t *cr = gtk_print_context_get_cairo_context (ctxt->pc);
- cairo_save(cr);
+ pango_layout_set_font_description (layout, font);
+ pango_layout_set_text (layout, text, -1);
+ pango_layout_set_width (layout, pango_units_from_double (width));
+ pango_layout_set_indent (layout, pango_units_from_double (indent));
- if ( width == -1 || get_font_width(ctxt, font, text) <= width ) {
- indent = 0.0;
- } else {
- indent = get_font_width (ctxt, font, " ");
- }
+ cr = gtk_print_context_get_cairo_context (context);
- g_assert (ctxt->pl);
- pango_layout_set_font_description (ctxt->pl, font);
- pango_layout_set_text (ctxt->pl, text, -1);
- pango_layout_set_width (ctxt->pl, width*PANGO_SCALE);
- pango_layout_set_indent (ctxt->pl, indent*PANGO_SCALE);
-
- cairo_move_to(cr, x, y);
- pango_cairo_show_layout (cr, ctxt->pl);
+ cairo_save (cr);
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr, layout);
cairo_restore (cr);
+ g_object_unref (layout);
}
static gdouble
-e_contact_text_height(EContactPrintContext *ctxt, PangoFontDescription *font, double width, const gchar *text)
+e_contact_text_height (GtkPrintContext *context,
+ PangoFontDescription *desc,
+ const gchar *text)
{
- gint w, h;
+ PangoLayout *layout;
+ gint width, height;
- g_assert (ctxt->pl);
- pango_layout_set_font_description (ctxt->pl, font);
- pango_layout_set_text (ctxt->pl, text, -1);
- pango_layout_set_width (ctxt->pl, 1); /* fix me width hard coded */
- pango_layout_set_indent (ctxt->pl, 0);
- pango_layout_get_size (ctxt->pl, &w, &h);
+ layout = gtk_print_context_create_pango_layout (context);
- return (double)h/(double)PANGO_SCALE;
-}
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, text, -1);
-#if 0
-static void
-e_contact_output_and_advance(EContactPrintContext *ctxt, PangoFontDescription *font, double x, double width, gchar *text)
-{
- ctxt->y -= .1 * get_font_height (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 * get_font_height (font);
-}
-#endif
+ pango_layout_get_size (layout, &width, &height);
-static void
-e_contact_rectangle(GtkPrintContext *pc,
- gdouble x0,
- gdouble y0,
- gdouble x1,
- gdouble y1,
- gdouble r,
- gdouble g,
- gdouble b)
-{
- cairo_t *cr;
- cr = gtk_print_context_get_cairo_context (pc);
- cairo_save(cr);
- cairo_set_source_rgb(cr, r, g, b);
- cairo_rectangle (cr,x0, y0, x1, y1);
- cairo_fill (cr);
- cairo_restore (cr);
-}
+ g_object_unref (layout);
-static double
-e_contact_get_letter_heading_height (EContactPrintContext *ctxt)
-{
- return get_font_height (ctxt->letter_heading_font);
+ return pango_units_to_double (height);
}
static void
-e_contact_print_letter_heading (EContactPrintContext *ctxt, gchar *character)
+e_contact_print_letter_heading (EContactPrintContext *ctxt, gchar *letter)
{
- gdouble height;
- gdouble width;
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ PangoFontMetrics *metrics;
+ gint width, height;
cairo_t *cr;
- width = get_font_width(ctxt, ctxt->letter_heading_font, "m") * 1.7;
- height = get_font_height (ctxt->letter_heading_font);
-
- cr = gtk_print_context_get_cairo_context (ctxt->pc);
- cairo_save(cr);
+ desc = ctxt->letter_heading_font;
- e_contact_rectangle( ctxt->pc, ctxt->x, ctxt->y, width, height + 6, 0, 0, 0);
- cairo_set_source_rgb(cr, 1, 1, 1);
- ctxt->y += 4;
- e_contact_output(ctxt, ctxt->letter_heading_font,
- ctxt->x + (width - get_font_width(ctxt, ctxt->letter_heading_font, character))/ 2 - 5,
- ctxt->y - 5,
- -1,
- character);
- ctxt->y += height;
- ctxt->y += 2;
- ctxt->y += 3;
-
- cairo_restore(cr);
-}
+ layout = gtk_print_context_create_pango_layout (ctxt->context);
-static void
-e_contact_start_new_page(EContactPrintContext *ctxt)
-{
- cairo_t *cr;
- cr = gtk_print_context_get_cairo_context (ctxt->pc);
- ctxt->x = ctxt->style->left_margin;
- ctxt->y = ctxt->style->top_margin;
- cairo_show_page (cr);
- ctxt->column = 0;
-}
+ /* Make the rectangle thrice the average character width.
+ * XXX Works well for English, what about other locales? */
+ metrics = pango_context_get_metrics (
+ pango_layout_get_context (layout),
+ desc, pango_language_get_default ());
+ width = pango_font_metrics_get_approximate_char_width (metrics) * 3;
+ pango_font_metrics_unref (metrics);
-static double
-e_contact_get_contact_size(EContact *contact, EContactPrintContext *ctxt)
-{
- const char *file_as;
- gdouble height = 0;
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
- gdouble column_width;
- gint field;
- column_width = (page_width + 18) / ctxt->style->num_columns - 18;
+ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, letter, -1);
+ pango_layout_set_width (layout, width);
+ pango_layout_get_size (layout, NULL, &height);
- height += get_font_height (ctxt->style->headings_font) * .2;
+ /* Draw white text centered in a black rectangle. */
- height += get_font_height (ctxt->style->headings_font) * .2;
+ cr = gtk_print_context_get_cairo_context (ctxt->context);
- file_as = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, .0, .0, .0);
+ cairo_rectangle (
+ cr, ctxt->x, ctxt->y,
+ pango_units_to_double (width),
+ pango_units_to_double (height));
+ cairo_fill (cr);
+ cairo_restore (cr);
- height += e_contact_text_height(ctxt, ctxt->style->headings_font, column_width - 4, file_as);
+ cairo_save (cr);
+ cairo_move_to (cr, ctxt->x, ctxt->y);
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ pango_cairo_show_layout (cr, layout);
+ cairo_restore (cr);
- height += get_font_height (ctxt->style->headings_font) * .2;
+ ctxt->y += pango_units_to_double (height);
+}
- height += get_font_height (ctxt->style->headings_font) * .2;
-
- for(field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
- char *string;
- string = e_contact_get(contact, field);
- if (string && *string) {
- double xoff = 0;
- xoff += get_font_width(ctxt, ctxt->style->body_font, e_contact_pretty_name (field));
- xoff += get_font_width(ctxt, ctxt->style->body_font, ": ");
- height += e_contact_text_height(ctxt, ctxt->style->body_font, column_width - xoff, string);
- height += .2 * get_font_height (ctxt->style->body_font);
- }
- g_free(string);
- }
- height += get_font_height (ctxt->style->headings_font) * .4;
+static void
+e_contact_start_new_page (EContactPrintContext *ctxt)
+{
+ cairo_t *cr;
- /* g_message ("%s %g", e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FILE_AS), height); */
- return height;
-}
+ cr = gtk_print_context_get_cairo_context (ctxt->context);
+ cairo_show_page (cr);
+
+ ctxt->x = ctxt->y = .0;
+ ctxt->column = 0;
+}
static void
e_contact_print_contact (EContact *contact, EContactPrintContext *ctxt)
{
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
- gdouble column_width;
char *file_as;
cairo_t *cr;
int field;
- column_width = (page_width + 18) / ctxt->style->num_columns - 18;
- cr = gtk_print_context_get_cairo_context (ctxt->pc);
+ cr = gtk_print_context_get_cairo_context (ctxt->context);
cairo_save(cr);
ctxt->y += get_font_height (ctxt->style->headings_font) * .2;
- ctxt->y += get_font_height (ctxt->style->headings_font) * .2;
file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
- if (ctxt->style->print_using_grey)
- e_contact_rectangle(ctxt->pc,
- ctxt->x,ctxt->y + get_font_height (ctxt->style->headings_font) * .3,
- column_width,
- e_contact_text_height(ctxt,
- ctxt->style->headings_font,
- column_width - 4, file_as)
- + get_font_height (ctxt->style->headings_font) * .3,
- .85, .85, .85);
-
-
- e_contact_output(ctxt, ctxt->style->headings_font, ctxt->x + 2, ctxt->y + 5, column_width + 4, file_as);
- ctxt->y += e_contact_text_height(ctxt, ctxt->style->headings_font, column_width + 4, file_as);
+ if (ctxt->style->print_using_grey) {
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, .85, .85, .85);
+ cairo_rectangle (cr, ctxt->x, ctxt->y, ctxt->column_width,
+ e_contact_text_height (ctxt->context,
+ ctxt->style->headings_font, file_as));
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
+
+ e_contact_output (
+ ctxt->context, ctxt->style->headings_font,
+ ctxt->x, ctxt->y, ctxt->column_width + 4, file_as);
+ ctxt->y += e_contact_text_height (
+ ctxt->context, ctxt->style->headings_font, file_as);
+
g_free (file_as);
ctxt->y += get_font_height (ctxt->style->headings_font) * .2;
- ctxt->y += get_font_height (ctxt->style->headings_font) * .2;
-
- for(field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING;field++)
+
+ for (field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++)
{
- char *string;
- string = e_contact_get(contact, field);
-
- if (string && *string) {
- double xoff = 0;
-
- e_contact_output(ctxt,
- ctxt->style->body_font,
- ctxt->x + xoff,
- ctxt->y + 5,
- -1,
- e_contact_pretty_name (field));
-
- xoff += get_font_width(ctxt, ctxt->style->body_font, e_contact_pretty_name (field));
- e_contact_output(ctxt, ctxt->style->body_font, ctxt->x + xoff, ctxt->y + 5, -1, ": ");
- xoff += get_font_width(ctxt, ctxt->style->body_font, ": ");
-
- e_contact_output(ctxt,
- ctxt->style->body_font,
- ctxt->x + xoff,
- ctxt->y + 5,
- column_width - xoff,
- string);
-
- ctxt->y += e_contact_text_height(ctxt, ctxt->style->body_font, column_width - xoff, string);
- ctxt->y += .2 * get_font_height (ctxt->style->body_font);
+ const gchar *value;
+ gchar *text;
- }
- g_free(string);
- }
- ctxt->y += get_font_height (ctxt->style->headings_font) * .4 + 8;
- cairo_restore(cr);
-}
+ value = e_contact_get_const (contact, field);
+ if (value == NULL || *value == '\0')
+ continue;
-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;
+ text = g_strdup_printf ("%s: %s",
+ e_contact_pretty_name (field), value);
- column_offset = (page_width + 18) / ctxt->style->num_columns;
- ctxt->column ++;
+ e_contact_output (
+ ctxt->context, ctxt->style->body_font,
+ ctxt->x, ctxt->y, -1, text);
- if (ctxt->column >= ctxt->style->num_columns) {
- e_contact_start_new_page(ctxt);
- ctxt->column = 0;
+ ctxt->y += e_contact_text_height (
+ ctxt->context, ctxt->style->body_font, text);
+
+ ctxt->y += .2 * get_font_height (ctxt->style->body_font);
+
+ g_free (text);
}
- ctxt->x = ctxt->style->left_margin + column_offset * ctxt->column;
- ctxt->y = ctxt->style->top_margin + 12;
+
+ ctxt->y += get_font_height (ctxt->style->headings_font) * .4 + 8;
+
+ cairo_restore (cr);
}
static void
-complete_sequence (EBookView *book_view, EBookViewStatus status, EContactPrintContext *ctxt)
+e_contact_start_new_column (EContactPrintContext *ctxt)
{
- GList *contacts = ctxt->contacts;
-
- ctxt->first_contact = TRUE;
- ctxt->character = NULL;
- ctxt->y = ctxt->style->page_height + ctxt->style->top_margin;
- ctxt->x = (ctxt->style->left_margin);
-
- for(; contacts; contacts = contacts->next) {
- EContact *contact = contacts->data;
- guchar *file_as;
- gchar *letter_str = NULL;
-
- file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
-
- if (file_as != NULL) {
- letter_str = g_strndup (file_as, g_utf8_next_char (file_as) - (gchar *) file_as);
- }
- if ( file_as && (!ctxt->character || g_utf8_collate (ctxt->character, letter_str) != 0) ) {
- g_free (ctxt->character);
- ctxt->character = g_strdup (letter_str);
- if (ctxt->style->sections_start_new_page && ! ctxt->first_contact) {
- e_contact_start_new_page(ctxt);
- }
- else if ((!ctxt->first_contact) && (ctxt->y > ctxt->style->page_height * 60 ))
- e_contact_start_new_column(ctxt);
- if ( ctxt->style->letter_headings )
- e_contact_print_letter_heading(ctxt, ctxt->character);
- ctxt->first_section = FALSE;
- }
-
- else if ( (!ctxt->first_contact) && (ctxt->y > ctxt->style->page_height * 60)) {
- e_contact_start_new_column(ctxt);
- if ( ctxt->style->letter_headings )
- e_contact_print_letter_heading(ctxt, ctxt->character);
- }
-
- g_free (letter_str);
- e_contact_print_contact(contact, ctxt);
- ctxt->first_contact = FALSE;
+ if (++ctxt->column >= ctxt->style->num_columns)
+ e_contact_start_new_page (ctxt);
+ else {
+ ctxt->x = ctxt->column *
+ (ctxt->column_width + ctxt->column_spacing);
+ ctxt->y = .0;
}
-
- if (book_view)
- g_object_unref(book_view);
-
- g_object_unref(ctxt->pc);
- g_object_unref(ctxt->pl);
- if (ctxt->book)
- g_object_unref(ctxt->book);
-
- g_free(ctxt->character);
- if (ctxt->query)
- e_book_query_unref (ctxt->query);
- g_list_foreach(ctxt->contacts, (GFunc) g_object_unref, NULL);
- g_list_free(ctxt->contacts);
- pango_font_description_free(ctxt->style->headings_font);
- pango_font_description_free(ctxt->style->body_font);
- pango_font_description_free(ctxt->style->header_font);
- pango_font_description_free(ctxt->style->footer_font);
- pango_font_description_free(ctxt->letter_heading_font);
- g_free(ctxt->style);
}
static int
contact_compare (EContact *contact1, EContact *contact2)
{
- if (contact1 && contact2) {
- const char *file_as1, *file_as2;
- file_as1 = e_contact_get_const (contact1, E_CONTACT_FILE_AS);
- file_as2 = e_contact_get_const (contact2, E_CONTACT_FILE_AS);
-
- if (file_as1 && file_as2)
- return g_utf8_collate(file_as1, file_as2);
- if (file_as1)
- return -1;
- if (file_as2)
- return 1;
- return strcmp(e_contact_get_const(contact1, E_CONTACT_UID), e_contact_get_const(contact2, E_CONTACT_UID));
- } else {
+ const gchar *field1, *field2;
+
+ if (contact1 == NULL || contact2 == NULL)
return 0;
- }
-}
-static void
-create_contact(EBookView *book_view, const GList *contacts, EContactPrintContext *ctxt)
-{
- for(; contacts; contacts = contacts->next) {
- EContact *contact = contacts->data;
- g_object_ref(contact);
- ctxt->contacts = g_list_insert_sorted(ctxt->contacts, contact, (GCompareFunc) contact_compare);
- }
-}
+ field1 = e_contact_get_const (contact1, E_CONTACT_FILE_AS);
+ field2 = e_contact_get_const (contact2, E_CONTACT_FILE_AS);
-static void
-book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, EContactPrintContext *ctxt)
-{
- g_object_ref(book_view);
-
- g_signal_connect(book_view,
- "contacts_added",
- G_CALLBACK(create_contact),
- ctxt);
- g_signal_connect(book_view,
- "sequence_complete",
- G_CALLBACK(print_func),
- ctxt);
- e_book_view_start (book_view);
-}
+ if (field1 != NULL && field2 != NULL)
+ return g_utf8_collate (field1, field2);
-static void
-print_func (EBookView *book_view, const GList *contacts, EContactPrintContext *ctxt)
-{
- GtkPrintSettings *settings;
- settings = gtk_print_settings_new ();
- /* runs a print dialog, emittings signals */
- if(ctxt->response_id == GTK_RESPONSE_APPLY)
- gtk_print_operation_run (ctxt->print, GTK_PRINT_OPERATION_ACTION_PREVIEW, NULL, NULL);
- else
- gtk_print_operation_run (ctxt->print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, NULL);
- settings = gtk_print_operation_get_print_settings (ctxt->print);
- e_print_save_settings (settings);
-}
+ if (field1 != NULL || field2 != NULL)
+ return (field1 != NULL) ? -1 : 1;
-static void
-e_contact_do_print_contacts (EBook *book, EBookQuery *query, EContactPrintContext *ctxt)
-{
- EBookView *bookview;
- gboolean status;
+ field1 = e_contact_get_const (contact1, E_CONTACT_UID);
+ field2 = e_contact_get_const (contact2, E_CONTACT_UID);
+
+ g_assert (field1 != NULL && field2 != NULL);
- status = e_book_get_book_view (book, query, NULL, -1, &bookview, NULL);
- book_view_loaded (book, 1, bookview, ctxt);
+ return strcmp (field1, field2);
}
-
-static void
-e_contact_do_print (EBook *book, EBookQuery *query, EContactPrintContext *ctxt)
-{
- switch ( ctxt->style->type ) {
- case E_CONTACT_PRINT_TYPE_CARDS:
- e_contact_do_print_contacts( book, query, ctxt);
- break;
- default:
- break;
+
+static void
+contacts_added (EBookView *book_view, const GList *contact_list,
+ EContactPrintContext *ctxt)
+{
+ while (contact_list != NULL) {
+ ctxt->contact_list = g_list_insert_sorted(
+ ctxt->contact_list,
+ g_object_ref (contact_list->data),
+ (GCompareFunc) contact_compare);
+ contact_list = contact_list->next;
}
}
-static void lowify( char *data )
+static void
+sequence_complete (EBookView *book_view, const GList *contact_list,
+ EFlag *book_view_started)
{
- for ( ; *data; data++ )
- *data = tolower((unsigned char) *data);
+ e_flag_set (book_view_started);
}
-static gboolean get_bool( char *data )
+static gboolean
+get_bool (gchar *data)
{
- if ( data ) {
- lowify ( data );
- return ! strcmp(data, "true");
- } else
+ if (data)
+ return (g_ascii_strcasecmp (data, "true") == 0);
+ else
return FALSE;
}
-static void get_string( char *data, char **variable )
+static void
+get_string (gchar *data, gchar **variable)
{
- g_free ( *variable );
- if ( data )
- *variable = g_strdup( data );
- else
- *variable = g_strdup( "" );
+ g_free (*variable);
+ *variable = g_strdup ((data != NULL) ? data : "");
}
-static int get_integer( char *data )
+static gint
+get_integer (gchar *data)
{
- if ( data )
- return atoi(data);
- else
- return 0;
+ return (data != NULL) ? atoi (data) : 0;
}
-static double get_float( char *data )
+static gdouble
+get_float (gchar *data)
{
- if ( data )
- return atof(data);
- else
- return 0;
+ return (data != NULL) ? atof (data) : .0;
}
-static void get_font( char *data, PangoFontDescription **variable )
+static void
+get_font (gchar *data, PangoFontDescription **variable)
{
- if ( data ) {
- PangoFontDescription *font = pango_font_description_from_string ( data );
- if ( font ) {
- pango_font_description_free(*variable);
- *variable = font;
- }
+ PangoFontDescription *desc = NULL;
+
+ if (data != NULL)
+ desc = pango_font_description_from_string (data);
+
+ if (desc != NULL) {
+ pango_font_description_free (*variable);
+ *variable = desc;
}
}
-
static void
-e_contact_build_style(EContactPrintStyle *style, GtkPrintSettings *config)
+e_contact_build_style (EContactPrintStyle *style)
{
xmlDocPtr styledoc;
gchar *filename;
@@ -614,8 +390,8 @@ e_contact_build_style(EContactPrintStyle *style, GtkPrintSettings *config)
style->blank_forms = 2;
style->letter_headings = FALSE;
- style->headings_font = find_closest_font_from_weight_slant ("Sans", GNOME_FONT_BOLD, FALSE, 8);
- style->body_font = find_closest_font_from_weight_slant ("Sans", GNOME_FONT_BOOK, FALSE, 6);
+ style->headings_font = pango_font_description_from_string ("Sans Bold 8");
+ style->body_font = pango_font_description_from_string ("Sans 6");
style->print_using_grey = TRUE;
style->paper_type = 0;
@@ -639,21 +415,23 @@ e_contact_build_style(EContactPrintStyle *style, GtkPrintSettings *config)
#endif
style->orientation_portrait = FALSE;
- style->header_font = find_closest_font_from_weight_slant ("Sans", GNOME_FONT_BOOK, FALSE, 6);
+ style->header_font = pango_font_description_copy (style->body_font);
style->left_header = g_strdup("");
style->center_header = g_strdup("");
style->right_header = g_strdup("");
- style->footer_font = find_closest_font_from_weight_slant ("Sans", GNOME_FONT_BOOK, FALSE, 6);
+ style->footer_font = pango_font_description_copy (style->body_font);
- style->left_footer = g_strdup("");
- style->center_footer = g_strdup("");
- style->right_footer = g_strdup("");
+ style->left_footer = g_strdup ("");
+ style->center_footer = g_strdup ("");
+ style->right_footer = g_strdup ("");
style->reverse_on_even_pages = FALSE;
- filename = g_build_filename(EVOLUTION_ECPSDIR, "medbook.ecps", NULL);
+
+ filename = g_build_filename (EVOLUTION_ECPSDIR, "medbook.ecps", NULL);
styledoc = e_xml_parse_file (filename);
- g_free(filename);
+ g_free (filename);
+
if (styledoc) {
xmlNodePtr stylenode = xmlDocGetRootElement(styledoc);
xmlNodePtr node;
@@ -662,12 +440,11 @@ e_contact_build_style(EContactPrintStyle *style, GtkPrintSettings *config)
if ( !strcmp( node->name, "title" ) ) {
get_string(data, &(style->title));
} else if ( !strcmp( node->name, "type" ) ) {
- lowify( data );
- if ( !strcmp( data, "cards" ) )
+ if (g_ascii_strcasecmp (data, "cards") == 0)
style->type = E_CONTACT_PRINT_TYPE_CARDS;
- else if ( !strcmp( data, "memo_style" ) )
+ else if (g_ascii_strcasecmp (data, "memo_style") == 0)
style->type = E_CONTACT_PRINT_TYPE_MEMO_STYLE;
- else if ( !strcmp( data, "phone_list" ) )
+ else if (g_ascii_strcasecmp (data, "phone_list") == 0)
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);
@@ -701,8 +478,8 @@ e_contact_build_style(EContactPrintStyle *style, GtkPrintSettings *config)
style->page_height = get_float(data);
} else if ( !strcmp( node->name, "orientation" ) ) {
if ( data ) {
- lowify(data);
- style->orientation_portrait = strcmp(data, "landscape");
+ style->orientation_portrait =
+ (g_ascii_strcasecmp (data, "landscape") != 0);
} else {
style->orientation_portrait = TRUE;
}
@@ -733,204 +510,192 @@ e_contact_build_style(EContactPrintStyle *style, GtkPrintSettings *config)
}
-static gint
-e_contact_print_close(GnomeDialog *dialog, gpointer data)
+static void
+load_contacts (EContactPrintContext *ctxt)
{
- return FALSE;
+ /* Load contacts from the EBook. This is an asynchronous operation
+ * but we force it to be synchronous here. */
+
+ EBookView *book_view;
+ EFlag *book_view_started;
+
+ book_view_started = e_flag_new ();
+
+ e_book_get_book_view (
+ ctxt->book, ctxt->query, NULL, -1, &book_view, NULL);
+
+ g_signal_connect (
+ book_view, "contacts_added",
+ G_CALLBACK (contacts_added), ctxt);
+ g_signal_connect (
+ book_view, "sequence_complete",
+ G_CALLBACK (sequence_complete), book_view_started);
+
+ e_book_view_start (book_view);
+
+ while (!e_flag_is_set (book_view_started))
+ g_main_context_iteration (NULL, TRUE);
+
+ e_flag_free (book_view_started);
}
-void
-e_contact_print_response(GtkWidget *dialog, gint response_id, gpointer data)
+static void
+free_contacts (EContactPrintContext *ctxt)
{
-#ifdef G_OS_UNIX /* Just to get it to build on Win32 */
- GtkPrintSettings *settings;
- GtkPaperSize *paper_size;
- GtkPageSetup *page_setup;
- GList *contact_list = NULL;
- EBook *book = NULL;
- EBookQuery *query = NULL;
- EContact *contact = NULL;
- gdouble font_size;
- gboolean uses_book = FALSE, uses_list = FALSE, uses_range = FALSE;
-
- EContactPrintContext *ctxt = g_new0 (EContactPrintContext, 1);
- EContactPrintStyle *style = g_new0 (EContactPrintStyle, 1);
- ContactPrintItem *cpi = g_new0 (ContactPrintItem, 1);
-
- settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog));
- uses_range = GPOINTER_TO_INT (g_object_get_data(G_OBJECT (dialog),"uses_range"));
-
- if (uses_range) {
- if (gtk_print_settings_get_print_pages (settings) == GTK_PRINT_PAGES_ALL) {
- uses_book = TRUE;
- }
- if (gtk_print_settings_get_print_pages (settings) == GTK_PRINT_PAGES_CURRENT)
- uses_list = TRUE;
- }
- else {
- uses_book = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "uses_book"));
- uses_list = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dialog), "uses_list"));
- }
- if (uses_book) {
- book = g_object_get_data(G_OBJECT(dialog), "book");
- query = g_object_get_data(G_OBJECT(dialog), "query");
- e_book_query_ref (query);
- }
- else if (uses_list) {
- contact_list = g_object_get_data(G_OBJECT(dialog), "contact_list");
- }
- else {
- contact = g_object_get_data(G_OBJECT(dialog), "contact");
- }
-
- page_setup = gtk_page_setup_new ();
- paper_size = gtk_paper_size_new ("iso_a4"); /* FIXME paper size hardcoded */
- gtk_page_setup_set_paper_size (page_setup, paper_size);
- ctxt->print = gtk_print_operation_new ();
- gtk_print_operation_set_default_page_setup (ctxt->print, page_setup);
- gtk_print_operation_set_n_pages (ctxt->print, 1);
- gtk_print_settings_set_print_pages (settings, GTK_PRINT_PAGES_ALL);
-
- /* style information */
- e_contact_build_style(style, settings);
- style->page_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_INCH);
- style->page_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_INCH);
- ctxt->x = 0;
- ctxt->y = 0;
+ g_list_foreach (ctxt->contact_list, (GFunc) g_object_unref, NULL);
+ g_list_free (ctxt->contact_list);
+}
+
+static void
+contact_begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ EContactPrintContext *ctxt)
+{
+ GtkPageSetup *setup;
+ gdouble page_width;
+
+ e_contact_build_style (ctxt->style);
+
+ setup = gtk_print_context_get_page_setup (context);
+ page_width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS);
+
+ ctxt->context = context;
+ ctxt->x = ctxt->y = .0;
ctxt->column = 0;
- ctxt->style = style;
+ ctxt->first_contact = TRUE;
ctxt->first_section = TRUE;
- ctxt->type = GTK_RESPONSE_OK;
- font_size = 72 * ctxt->style->page_height / 27.0 / 2.0;
- ctxt->letter_heading_font = find_font (pango_font_description_get_family (ctxt->style->headings_font),
- get_font_height (ctxt->style->headings_font)*1.5);
- ctxt->book = book;
- ctxt->query = query;
- ctxt->response_id = response_id;
- cpi->uses_book = uses_book;
- cpi->uses_list = uses_list;
- cpi->settings = settings;
- cpi->ctxt = ctxt;
- cpi->contact= contact;
- cpi->ctxt->contacts = NULL;
- cpi->contact_list= contact_list;
- cpi->book = book;
- gtk_print_operation_set_print_settings (ctxt->print, settings);
- g_signal_connect (ctxt->print, "draw_page",G_CALLBACK (contact_draw_page), cpi);
-
- if (!uses_book) {
- if(ctxt->response_id == GTK_RESPONSE_APPLY)
- gtk_print_operation_run (ctxt->print, GTK_PRINT_OPERATION_ACTION_PREVIEW, NULL, NULL);
- else
- gtk_print_operation_run (ctxt->print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL, NULL);
- settings = gtk_print_operation_get_print_settings (ctxt->print);
- e_print_save_settings (settings);
- }
- else
- e_contact_do_print_contacts (book, query, ctxt);
-
- g_object_unref (cpi);
- if (!uses_book) {
- g_object_unref (ctxt->print);
- g_free (ctxt);
- }
- gtk_widget_destroy (dialog);
-#else
- g_warning ("Not implemented currently on Windows");
-#endif
-}
+ ctxt->section = NULL;
+ ctxt->column_spacing = gtk_print_context_get_dpi_x (context) / 4;
+ ctxt->column_width = (page_width + ctxt->column_spacing) /
+ ctxt->style->num_columns - ctxt->column_spacing;
+
+ ctxt->letter_heading_font = pango_font_description_new ();
+ pango_font_description_set_family (
+ ctxt->letter_heading_font,
+ pango_font_description_get_family (
+ ctxt->style->headings_font));
+ pango_font_description_set_size (
+ ctxt->letter_heading_font,
+ pango_font_description_get_size (
+ ctxt->style->headings_font) * 1.5);
+
+ if (ctxt->book != NULL)
+ load_contacts (ctxt);
+}
-GtkWidget *
-e_contact_print_dialog_new(EBook *book, char *query, GList *list)
+static void
+contact_draw (EContact *contact, EContactPrintContext *ctxt)
{
- GtkWidget *dialog;
- GList *copied_list = NULL;
- GList *l;
-
- dialog = e_print_get_dialog(_("Print contacts"), 0);
-
- if (list != NULL) {
- copied_list = g_list_copy (list);
- for (l = copied_list; l; l = l->next)
- l->data = e_contact_duplicate (E_CONTACT (l->data));
+ GtkPageSetup *setup;
+ gdouble page_height;
+ gchar *file_as;
+ gboolean new_section = FALSE;
+
+ setup = gtk_print_context_get_page_setup (ctxt->context);
+ page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);
+
+ file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+
+ if (file_as != NULL) {
+ gchar *section;
+ gsize width;
+
+ width = g_utf8_next_char (file_as) - file_as;
+ section = g_utf8_strup (file_as, width);
+
+ new_section = (ctxt->section == NULL ||
+ g_utf8_collate (ctxt->section, section) != 0);
+
+ if (new_section) {
+ g_free (ctxt->section);
+ ctxt->section = section;
+ } else
+ g_free (section);
+ }
+
+ if (new_section) {
+ if (!ctxt->first_contact) {
+ if (ctxt->style->sections_start_new_page)
+ e_contact_start_new_page (ctxt);
+ else if (ctxt->y > page_height)
+ e_contact_start_new_column (ctxt);
+ }
+ if (ctxt->style->letter_headings)
+ e_contact_print_letter_heading (ctxt, ctxt->section);
+ ctxt->first_section = FALSE;
+ }
+
+ else if (!ctxt->first_contact && (ctxt->y > page_height)) {
+ e_contact_start_new_column (ctxt);
+ if (ctxt->style->letter_headings)
+ e_contact_print_letter_heading (ctxt, ctxt->section);
}
- g_object_ref(book);
- g_object_set_data(G_OBJECT(dialog), "contact_list", copied_list);
- g_object_set_data(G_OBJECT(dialog), "book", book);
- g_object_set_data(G_OBJECT(dialog), "query", e_book_query_from_string (query));
- g_object_set_data(G_OBJECT(dialog), "uses_range", GINT_TO_POINTER (TRUE));
-
- g_signal_connect(dialog,
- "response", G_CALLBACK(e_contact_print_response), NULL);
- g_signal_connect(dialog,
- "close", G_CALLBACK(e_contact_print_close), NULL);
- return dialog;
+ e_contact_print_contact (contact, ctxt);
+
+ ctxt->first_contact = FALSE;
}
-GtkWidget *
-e_contact_print_contact_dialog_new(EContact *contact)
+static void
+contact_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ EContactPrintContext *ctxt)
{
- GtkWidget *dialog;
-
- dialog = e_print_get_dialog(_("Print contact"), 0);
- contact = e_contact_duplicate(contact);
- g_object_set_data(G_OBJECT(dialog), "contact", contact);
- g_object_set_data(G_OBJECT(dialog), "uses_list", GINT_TO_POINTER (FALSE));
- g_object_set_data(G_OBJECT(dialog), "uses_book", GINT_TO_POINTER (FALSE));
- g_object_set_data(G_OBJECT(dialog), "uses_range", GINT_TO_POINTER (FALSE));
- g_signal_connect(dialog,
- "response", G_CALLBACK(e_contact_print_response), NULL);
- g_signal_connect(dialog,
- "close", G_CALLBACK(e_contact_print_close), NULL);
- return dialog;
+ g_list_foreach (ctxt->contact_list, (GFunc) contact_draw, ctxt);
}
-
-GtkWidget *
-e_contact_print_contact_list_dialog_new(GList *list)
+
+static void
+contact_end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ EContactPrintContext *ctxt)
{
- GtkWidget *dialog;
- GList *copied_list;
- GList *l;
-
- if (list == NULL)
- return NULL;
-
- copied_list = g_list_copy (list);
- for (l = copied_list; l; l = l->next)
- l->data = e_contact_duplicate (E_CONTACT (l->data));
-
- dialog = e_print_get_dialog(_("Print contact"), 0);
-
- g_object_set_data(G_OBJECT(dialog), "contact_list", copied_list);
- g_object_set_data(G_OBJECT(dialog), "uses_list", GINT_TO_POINTER (TRUE));
- g_object_set_data(G_OBJECT(dialog), "uses_book", GINT_TO_POINTER (FALSE));
- g_object_set_data(G_OBJECT(dialog), "uses_range", GINT_TO_POINTER (FALSE));
- g_signal_connect(dialog,
- "response", G_CALLBACK(e_contact_print_response), NULL);
- g_signal_connect(dialog,
- "close", G_CALLBACK(e_contact_print_close), NULL);
- return dialog;
+ pango_font_description_free (ctxt->style->headings_font);
+ pango_font_description_free (ctxt->style->body_font);
+ pango_font_description_free (ctxt->style->header_font);
+ pango_font_description_free (ctxt->style->footer_font);
+ pango_font_description_free (ctxt->letter_heading_font);
+
+ g_free (ctxt->section);
+
+ if (ctxt->book != NULL)
+ free_contacts (ctxt);
}
-static void
-contact_draw_page (GtkPrintOperation *print, GtkPrintContext *context, gint page_nr, ContactPrintItem *cpi)
+void
+e_contact_print (EBook *book, EBookQuery *query,
+ GList *contact_list, GtkPrintOperationAction action)
{
- cpi->ctxt->pc = context;
- g_object_ref (cpi->ctxt->pc);
- cpi->ctxt->pl =gtk_print_context_create_pango_layout (context);
-
- if (cpi->uses_book) {
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, cpi->ctxt);
- }
-
- else if (cpi->uses_list) {
- cpi->ctxt->contacts = cpi->contact_list;
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, cpi->ctxt);
- }
- else {
- cpi->ctxt->contacts = g_list_append(NULL,cpi->contact);
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_OK, cpi->ctxt);
- }
+ GtkPrintOperation *operation;
+ EContactPrintContext ctxt;
+ EContactPrintStyle style;
+
+ if (book != NULL) {
+ ctxt.book = book;
+ ctxt.query = query;
+ ctxt.contact_list = NULL;
+ } else {
+ ctxt.book = NULL;
+ ctxt.query = NULL;
+ ctxt.contact_list = contact_list;
+ }
+ ctxt.style = &style;
+
+ operation = e_print_operation_new ();
+ gtk_print_operation_set_n_pages (operation, 1);
+
+ g_signal_connect (
+ operation, "begin-print",
+ G_CALLBACK (contact_begin_print), &ctxt);
+ g_signal_connect (
+ operation, "draw_page",
+ G_CALLBACK (contact_draw_page), &ctxt);
+ g_signal_connect (
+ operation, "end-print",
+ G_CALLBACK (contact_end_print), &ctxt);
+
+ gtk_print_operation_run (operation, action, NULL, NULL);
+
+ g_object_unref (operation);
}