diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2007-04-20 14:57:55 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2007-04-20 14:57:55 +0800 |
commit | 4a044a636e418f4c95a85819aa92316e21f58b35 (patch) | |
tree | fed737c87045e269aa840b770172fb798682fd10 /addressbook | |
parent | ba064da784cd29692e0db6d4560c7e7a8c68aeeb (diff) | |
download | gsoc2013-evolution-4a044a636e418f4c95a85819aa92316e21f58b35.tar.gz gsoc2013-evolution-4a044a636e418f4c95a85819aa92316e21f58b35.tar.zst gsoc2013-evolution-4a044a636e418f4c95a85819aa92316e21f58b35.zip |
Clean up printing in Evolution (bug #426816)
svn path=/trunk/; revision=33440
Diffstat (limited to 'addressbook')
-rw-r--r-- | addressbook/ChangeLog | 24 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook-view.c | 4 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-addressbook-view.c | 236 | ||||
-rw-r--r-- | addressbook/gui/widgets/e-addressbook-view.h | 4 | ||||
-rw-r--r-- | addressbook/printing/Makefile.am | 2 | ||||
-rw-r--r-- | addressbook/printing/e-contact-print-envelope.c | 91 | ||||
-rw-r--r-- | addressbook/printing/e-contact-print-envelope.h | 7 | ||||
-rw-r--r-- | addressbook/printing/e-contact-print-types.h | 2 | ||||
-rw-r--r-- | addressbook/printing/e-contact-print.c | 1015 | ||||
-rw-r--r-- | addressbook/printing/e-contact-print.h | 11 | ||||
-rw-r--r-- | addressbook/printing/test-print.c | 11 |
11 files changed, 496 insertions, 911 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 1dae147ff8..f357e37235 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,27 @@ +2007-04-20 Matthew Barnes <mbarnes@redhat.com> + + ** Fixes part of bug #426816 + + * gui/component/addressbook-view.c: + * gui/widgets/e-addressbook-view.c: + * gui/widgets/e-addressbook-view.h: + * printing/e-contact-print.c: + * printing/e-contact-print.h: + * printing/e-contact-print-types.h: + Refactor the printing infrastructure. + Migrate off of libgnomeprint[ui] once and for all. + + * printing/test-print.c: + Migrate off of libgnomeprint[ui] once and for all. + + * printing/e-contact-print-envelope.c: + * printing/e-contact-print-envelope.h: + This module is unused. Disable it, but keep the logic around for + future reference. + + * printing/Makefile.am: + Remove e-contact-print-envelope.[ch]. + 2007-04-19 Matthew Barnes <mbarnes@redhat.com> ** Fixes part of bug #429422 diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c index 7defe5e42b..53a5453e1c 100644 --- a/addressbook/gui/component/addressbook-view.c +++ b/addressbook/gui/component/addressbook-view.c @@ -193,7 +193,7 @@ print_cb (BonoboUIComponent *uih, void *user_data, const char *path) AddressbookView *view = (AddressbookView *) user_data; EABView *v = get_current_view (view); if (v) - eab_view_print (v, 0); + eab_view_print (v, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); } static void @@ -202,7 +202,7 @@ print_preview_cb (BonoboUIComponent *uih, void *user_data, const char *path) AddressbookView *view = (AddressbookView *) user_data; EABView *v = get_current_view (view); if (v) - eab_view_print_preview (v); + eab_view_print (v, GTK_PRINT_OPERATION_ACTION_PREVIEW); } static void diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c index 282f142a77..14019d582b 100644 --- a/addressbook/gui/widgets/e-addressbook-view.c +++ b/addressbook/gui/widgets/e-addressbook-view.c @@ -37,11 +37,6 @@ #include <e-util/e-icon-factory.h> #include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeprint/gnome-print.h> -#include <libgnomeprint/gnome-print-job.h> -#include <libgnomeprintui/gnome-print-dialog.h> -#include <libgnomeprintui/gnome-print-job-preview.h> - #include "addressbook/printing/e-contact-print.h" #include "addressbook/printing/e-contact-print-envelope.h" #include "addressbook/gui/widgets/eab-popup.h" @@ -81,7 +76,6 @@ #include <libxml/tree.h> #include <libxml/parser.h> -#include <gtk/gtkprintunixdialog.h> #define SHOW_ALL_SEARCH "(contains \"x-evolution-any-field\" \"\")" @@ -121,7 +115,6 @@ static void query_changed (ESearchBar *esb, EABView *view); static void search_activated (ESearchBar *esb, EABView *view); static void search_menu_activated (ESearchBar *esb, int id, EABView *view); static GList *get_master_list (void); -static void contact_print_button_draw_page (GtkPrintOperation *print, GtkPrintContext *context, gint page_nr,EPrintable *printable); #define PARENT_TYPE GTK_TYPE_VBOX static GtkVBoxClass *parent_class = NULL; @@ -874,17 +867,13 @@ print (EPopup *ep, EPopupItem *pitem, void *data) { /*ContactAndBook *contact_and_book = data;*/ EABPopupTargetSelect *t = (EABPopupTargetSelect *)ep->target; - GtkWidget *dialog; + GList *contact_list; - if (t->cards->len == 1) { - dialog = e_contact_print_contact_dialog_new(t->cards->pdata[0]); - e_contact_print_response (dialog, GTK_RESPONSE_OK, NULL); - } else { - GList *contacts = get_contact_list(t); - dialog = e_contact_print_contact_list_dialog_new (contacts); - e_contact_print_response (dialog, GTK_RESPONSE_OK, NULL); - g_list_free(contacts); - } + contact_list = get_contact_list (t); + e_contact_print ( + NULL, NULL, contact_list, + GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); + g_list_free (contact_list); } static void @@ -1703,77 +1692,46 @@ get_master_list (void) return category_list; } -typedef struct { - GtkWidget *table; - GObject *printable; -} EContactPrintDialogWeakData; - static void -e_contact_print_destroy(gpointer data, GObject *where_object_was) +contact_print_button_draw_page (GtkPrintOperation *operation, + GtkPrintContext *context, + gint page_nr, + EPrintable *printable) { - EContactPrintDialogWeakData *weak_data = data; - g_object_unref (weak_data->printable); - g_object_unref (weak_data->table); - g_free (weak_data); + GtkPageSetup *setup; + gdouble top_margin; + cairo_t *cr; + + setup = gtk_print_context_get_page_setup (context); + top_margin = gtk_page_setup_get_top_margin (setup, GTK_UNIT_POINTS); + + cr = gtk_print_context_get_cairo_context (context); + + e_printable_reset (printable); + + while (e_printable_data_left (printable)) { + cairo_save (cr); + e_printable_print_page ( + printable, context, 6.5 * 72, top_margin + 10, TRUE); + cairo_restore (cr); + } } static void -e_contact_print_button(GtkDialog *dialog, gint response, gpointer data) -{ -#ifdef G_OS_UNIX /* Just to get it to build on Win32 */ - GtkPrintOperation *print; - GtkPrintSettings *settings; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - EPrintable *printable = g_object_get_data(G_OBJECT(dialog), "printable"); - print = gtk_print_operation_new (); - page_setup = gtk_page_setup_new (); - - /*get & set,the settings of the dialog */ - settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (dialog)); - paper_size = gtk_paper_size_new ("iso_a4"); /* FIXME paper size hardcoded */ - gtk_page_setup_set_paper_size (page_setup, paper_size); - gtk_print_operation_set_print_settings (print, settings); - - gtk_print_operation_set_n_pages (print, 1); - gtk_print_operation_set_default_page_setup (print, page_setup); - /* run the dialog */ - g_signal_connect (print,"draw_page",G_CALLBACK(contact_print_button_draw_page), printable); - - if (response == GTK_RESPONSE_APPLY) - gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PREVIEW, NULL, NULL); - else - gtk_print_operation_run (print,GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, NULL,NULL); - - gtk_widget_destroy(dialog); - g_object_unref (print); -#else - g_warning ("Not implemented currently on Windows"); -#endif -} +e_contact_print_button (EPrintable *printable, GtkPrintOperationAction action) +{ + GtkPrintOperation *operation; -static void -contact_print_button_draw_page (GtkPrintOperation *print, GtkPrintContext *context, gint page_nr,EPrintable *printable) + operation = e_print_operation_new (); + gtk_print_operation_set_n_pages (operation, 1); -{ - cairo_t *cr; - GtkPageSetup *page_setup; - gdouble top_margin; - - cr = gtk_print_context_get_cairo_context (context); - page_setup = gtk_print_operation_get_default_page_setup (print); - top_margin = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_POINTS); - e_printable_reset(printable); - while (e_printable_data_left(printable)) { - cairo_save (cr); - e_printable_print_page (printable, - context, - 6.5 * 72, - top_margin + 10, - TRUE); - cairo_restore (cr); - } + g_signal_connect ( + operation, "draw_page", + G_CALLBACK (contact_print_button_draw_page), printable); + + gtk_print_operation_run (operation, action, NULL, NULL); + + g_object_unref (operation); } void @@ -1838,110 +1796,44 @@ eab_view_discard_menus (EABView *view) } void -eab_view_print(EABView *view, int preview) +eab_view_print (EABView *view, GtkPrintOperationAction action) { if (view->view_type == EAB_VIEW_MINICARD) { - char *query; EBook *book; - GtkWidget *print; - GList *list; - - g_object_get (view->model, - "query", &query, - "book", &book, - NULL); - list = get_selected_contacts (view); - print = e_contact_print_dialog_new (book, query, list); - - if (!preview) - e_contact_print_response (print, GTK_RESPONSE_OK, NULL); - else - e_contact_print_response (print, GTK_RESPONSE_APPLY, NULL); - - g_free (query); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - } - else if (view->view_type == EAB_VIEW_TABLE) { - GtkWidget *dialog; - EPrintable *printable; - ETable *etable; - EContactPrintDialogWeakData *weak_data; - - /* FIXME: Allow range selection in table views, as in minicard view */ - dialog = e_print_get_dialog (_("Print cards"), 0); + EBookQuery *query; + gchar *query_string; + GList *contact_list; - g_object_get(view->widget, "table", &etable, NULL); - printable = e_table_get_printable(etable); - g_object_ref_sink (printable); - g_object_unref(etable); - g_object_ref (view->widget); + g_object_get ( + view->model, "query", &query_string, + "book", &book, NULL); - g_object_set_data (G_OBJECT (dialog), "table", view->widget); - g_object_set_data (G_OBJECT (dialog), "printable", printable); - - weak_data = g_new (EContactPrintDialogWeakData, 1); - weak_data->table = view->widget; - weak_data->printable = G_OBJECT (printable); - g_object_weak_ref (G_OBJECT (dialog), e_contact_print_destroy, weak_data); - if (preview) - e_contact_print_button (dialog, GTK_RESPONSE_APPLY, NULL); + if (query_string != NULL) + query = e_book_query_from_string (query_string); else - e_contact_print_button (dialog, GTK_RESPONSE_OK, NULL); - } -#ifdef WITH_ADDRESSBOOK_VIEW_TREEVIEW - else if (view->view_type == EAB_VIEW_TREEVIEW) { - /* XXX */ - } -#endif -} + query = NULL; + g_free (query_string); -void -eab_view_print_preview(EABView *view) -{ - if (view->view_type == EAB_VIEW_MINICARD) { - char *query; - EBook *book; - GtkWidget *dialog; - GList *list; + contact_list = get_selected_contacts (view); + e_contact_print (book, query, contact_list, action); + g_list_foreach (contact_list, (GFunc) g_object_unref, NULL); + g_list_free (contact_list); - g_object_get (view->model, - "query", &query, - "book", &book, - NULL); + if (query != NULL) + e_book_query_unref (query); - list = get_selected_contacts (view); - if (list != NULL) - dialog = e_contact_print_contact_list_dialog_new (list); - else - dialog = e_contact_print_dialog_new (book, query, list); - e_contact_print_response (dialog, GTK_RESPONSE_APPLY, NULL); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); - g_free (query); - }else if (view->view_type == EAB_VIEW_TABLE) { - GtkWidget *dialog; + } else if (view->view_type == EAB_VIEW_TABLE) { EPrintable *printable; - ETable *etable; - EContactPrintDialogWeakData *weak_data; + ETable *table; - /* FIXME: Allow range selection in table views, as in minicard view */ - dialog = e_print_get_dialog (_("Print cards"), 0); - - g_object_get(view->widget, "table", &etable, NULL); - printable = e_table_get_printable(etable); + g_object_get (view->widget, "table", &table, NULL); + printable = e_table_get_printable (table); g_object_ref_sink (printable); - g_object_unref(etable); - g_object_ref (view->widget); + g_object_unref (table); - g_object_set_data (G_OBJECT (dialog), "table", view->widget); - g_object_set_data (G_OBJECT (dialog), "printable", printable); - - weak_data = g_new (EContactPrintDialogWeakData, 1); - weak_data->table = view->widget; - weak_data->printable = G_OBJECT (printable); - g_object_weak_ref (G_OBJECT (dialog), e_contact_print_destroy, weak_data); - e_contact_print_button (dialog, GTK_RESPONSE_APPLY, NULL); + e_contact_print_button (printable, action); + + g_object_unref (printable); } } diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h index 0f674c9edd..b525e97ed0 100644 --- a/addressbook/gui/widgets/e-addressbook-view.h +++ b/addressbook/gui/widgets/e-addressbook-view.h @@ -130,8 +130,8 @@ void eab_view_save_as (EABView *view, gboolean all); void eab_view_view (EABView *view); void eab_view_send (EABView *view); void eab_view_send_to (EABView *view); -void eab_view_print (EABView *view, int preview); -void eab_view_print_preview (EABView *view); +void eab_view_print (EABView *view, + GtkPrintOperationAction action); void eab_view_delete_selection (EABView *view, gboolean is_delete); void eab_view_cut (EABView *view); void eab_view_copy (EABView *view); diff --git a/addressbook/printing/Makefile.am b/addressbook/printing/Makefile.am index 0f3a3e85f3..6113519b2f 100644 --- a/addressbook/printing/Makefile.am +++ b/addressbook/printing/Makefile.am @@ -22,8 +22,6 @@ noinst_LTLIBRARIES = \ libecontactprint.la libecontactprint_la_SOURCES = \ - e-contact-print-envelope.c \ - e-contact-print-envelope.h \ e-contact-print-style-editor.c \ e-contact-print-style-editor.h \ e-contact-print-types.h \ diff --git a/addressbook/printing/e-contact-print-envelope.c b/addressbook/printing/e-contact-print-envelope.c index 1c9b210a97..eabe41aa48 100644 --- a/addressbook/printing/e-contact-print-envelope.c +++ b/addressbook/printing/e-contact-print-envelope.c @@ -19,16 +19,17 @@ * Boston, MA 02111-1307, USA. */ +/* XXX Keeping the rendering code around for future reference, + * but it needs a lot of work to make it usable again. */ + +#if 0 + #include <config.h> #include "addressbook/printing/e-contact-print-envelope.h" #include <glib.h> #include <glib/gi18n.h> #include <libgnomeui/gnome-dialog.h> #include <time.h> -#include <libgnomeprintui/gnome-print-dialog.h> -#include <libgnomeprint/gnome-print.h> -#include <libgnomeprint/gnome-print-job.h> -#include <libgnomeprintui/gnome-print-job-preview.h> #include <e-util/e-print.h> #define ENVELOPE_HEIGHT (72.0 * 4.0) @@ -123,12 +124,6 @@ ecpe_linelist_print(GnomePrintContext *pc, GnomeFont *font, char *address, EcpeL } } -static gint -e_contact_print_envelope_close(GnomeDialog *dialog, gpointer data) -{ - return FALSE; -} - static void ecpe_print(GnomePrintContext *pc, EContact *contact, gboolean as_return) { @@ -166,78 +161,4 @@ ecpe_print(GnomePrintContext *pc, EContact *contact, gboolean as_return) gnome_print_context_close(pc); } -static void -e_contact_print_envelope_button(GnomeDialog *dialog, gint button, gpointer data) -{ - GnomePrintJob *master; - GnomePrintContext *pc; - GnomePrintConfig *config; - EContact *contact = NULL; - GtkWidget *preview; - - contact = g_object_get_data(G_OBJECT(dialog), "contact"); - - switch( button ) { - case GNOME_PRINT_DIALOG_RESPONSE_PRINT: - config = gnome_print_dialog_get_config (GNOME_PRINT_DIALOG (dialog)); - master = gnome_print_job_new (config); - pc = gnome_print_job_get_context( master ); - - ecpe_print(pc, contact, FALSE); - - gnome_print_job_print(master); - gnome_dialog_close(dialog); - break; - case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW: - config = gnome_print_dialog_get_config (GNOME_PRINT_DIALOG (dialog)); - master = gnome_print_job_new (config); - pc = gnome_print_job_get_context( master ); - - ecpe_print(pc, contact, FALSE); - - preview = GTK_WIDGET(gnome_print_job_preview_new(master, "Print Preview")); - gtk_widget_show_all(preview); - break; - case GNOME_PRINT_DIALOG_RESPONSE_CANCEL: - g_object_unref(contact); - gnome_dialog_close(dialog); - break; - } -} - -GtkWidget * -e_contact_print_envelope_dialog_new(EContact *contact) -{ - GtkWidget *dialog; - - dialog = e_print_get_dialog (_("Print envelope"), GNOME_PRINT_DIALOG_COPIES); - - contact = e_contact_duplicate(contact); - g_object_set_data(G_OBJECT(dialog), "contact", contact); - g_signal_connect(dialog, - "clicked", G_CALLBACK(e_contact_print_envelope_button), NULL); - g_signal_connect(dialog, - "close", G_CALLBACK(e_contact_print_envelope_close), NULL); - return dialog; -} - -/* FIXME: Print all the contacts selected. */ -GtkWidget * -e_contact_print_envelope_list_dialog_new(GList *list) -{ - GtkWidget *dialog; - EContact *contact; - - if (list == NULL) - return NULL; - - dialog = e_print_get_dialog(_("Print envelope"), GNOME_PRINT_DIALOG_COPIES); - - contact = e_contact_duplicate(list->data); - g_object_set_data(G_OBJECT(dialog), "contact", contact); - g_signal_connect(dialog, - "clicked", G_CALLBACK(e_contact_print_envelope_button), NULL); - g_signal_connect(dialog, - "close", G_CALLBACK(e_contact_print_envelope_close), NULL); - return dialog; -} +#endif diff --git a/addressbook/printing/e-contact-print-envelope.h b/addressbook/printing/e-contact-print-envelope.h index a7a8492638..05009b9035 100644 --- a/addressbook/printing/e-contact-print-envelope.h +++ b/addressbook/printing/e-contact-print-envelope.h @@ -22,11 +22,6 @@ #ifndef E_CONTACT_PRINT_ENVELOPE_H #define E_CONTACT_PRINT_ENVELOPE_H -#include <gtk/gtkwidget.h> -#include <libebook/e-contact.h> -#include "e-contact-print-types.h" - -GtkWidget *e_contact_print_envelope_dialog_new(EContact *contact); -GtkWidget *e_contact_print_envelope_list_dialog_new(GList *list); +/* XXX Currently unused */ #endif /* E_CONTACT_PRINT_ENVELOPE_H */ diff --git a/addressbook/printing/e-contact-print-types.h b/addressbook/printing/e-contact-print-types.h index 5aafa96d40..d1fe68e745 100644 --- a/addressbook/printing/e-contact-print-types.h +++ b/addressbook/printing/e-contact-print-types.h @@ -23,8 +23,6 @@ #define E_CONTACT_PRINT_TYPES_H #include <glib.h> -#include <libgnomeprint/gnome-font.h> -#include <libgnomeprint/gnome-print-pango.h> typedef struct _EContactPrintStyle EContactPrintStyle; typedef enum _EContactPrintType EContactPrintType; 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); } diff --git a/addressbook/printing/e-contact-print.h b/addressbook/printing/e-contact-print.h index bc7b36c0da..a43f8b70eb 100644 --- a/addressbook/printing/e-contact-print.h +++ b/addressbook/printing/e-contact-print.h @@ -23,14 +23,13 @@ #define E_CONTACT_PRINT_H #include <glib.h> -#include <gtk/gtkwidget.h> +#include <gtk/gtkprintoperation.h> #include <libebook/e-book.h> -#include <libebook/e-contact.h> #include "e-contact-print-types.h" -GtkWidget *e_contact_print_dialog_new (EBook *book, char *query, GList *list); -GtkWidget *e_contact_print_contact_dialog_new (EContact *card); -GtkWidget *e_contact_print_contact_list_dialog_new(GList *list); -void e_contact_print_response (GtkWidget *dialog, gint response_id, gpointer data); +void e_contact_print (EBook *book, + EBookQuery *query, + GList *contact_list, + GtkPrintOperationAction action); #endif /* E_CONTACT_PRINT_H */ diff --git a/addressbook/printing/test-print.c b/addressbook/printing/test-print.c index 708885a861..1ac88dfa0a 100644 --- a/addressbook/printing/test-print.c +++ b/addressbook/printing/test-print.c @@ -32,12 +32,6 @@ /* This is a horrible thing to do, but it is just a test. */ GtkWidget *print; -static gint test_close(GnomeDialog *dialog, gpointer data) -{ - exit(0); - return 1; -} - #if 0 static void about_callback( GtkWidget *widget, gpointer data ) { @@ -77,9 +71,8 @@ int main( int argc, char *argv[] ) shown_fields = g_list_append(shown_fields, "Third field"); shown_fields = g_list_append(shown_fields, "Fourth field"); - print = e_contact_print_dialog_new(NULL, NULL, NULL); - gtk_widget_show_all(print); - g_signal_connect(print, "close", G_CALLBACK(test_close), NULL); + /* does nothing */ + e_contact_print (NULL, NULL, NULL, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); bonobo_main(); |