diff options
-rw-r--r-- | plugins/audio-inline/Makefile.am | 7 | ||||
-rw-r--r-- | plugins/audio-inline/audio-inline.c | 97 | ||||
-rw-r--r-- | plugins/dbx-import/Makefile.am | 6 | ||||
-rw-r--r-- | plugins/external-editor/external-editor.c | 2 | ||||
-rw-r--r-- | plugins/itip-formatter/Makefile.am | 7 | ||||
-rw-r--r-- | plugins/itip-formatter/itip-formatter.c | 975 | ||||
-rw-r--r-- | plugins/itip-formatter/itip-view.c | 2349 | ||||
-rw-r--r-- | plugins/itip-formatter/itip-view.h | 280 | ||||
-rw-r--r-- | plugins/mail-to-task/Makefile.am | 6 | ||||
-rw-r--r-- | plugins/mail-to-task/mail-to-task.c | 11 | ||||
-rw-r--r-- | plugins/mark-all-read/Makefile.am | 6 | ||||
-rw-r--r-- | plugins/prefer-plain/prefer-plain.c | 94 | ||||
-rw-r--r-- | plugins/pst-import/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/tnef-attachments/Makefile.am | 2 | ||||
-rw-r--r-- | plugins/tnef-attachments/tnef-plugin.c | 61 | ||||
-rw-r--r-- | plugins/vcard-inline/Makefile.am | 7 | ||||
-rw-r--r-- | plugins/vcard-inline/vcard-inline.c | 373 |
17 files changed, 2566 insertions, 1719 deletions
diff --git a/plugins/audio-inline/Makefile.am b/plugins/audio-inline/Makefile.am index d5dc1a5a60..7afdceec97 100644 --- a/plugins/audio-inline/Makefile.am +++ b/plugins/audio-inline/Makefile.am @@ -17,8 +17,7 @@ liborg_gnome_audio_inline_la_CPPFLAGS = \ -I$(top_srcdir)/widgets \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(GSTREAMER_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GSTREAMER_CFLAGS) liborg_gnome_audio_inline_la_SOURCES = audio-inline.c @@ -27,10 +26,10 @@ liborg_gnome_audio_inline_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) liborg_gnome_audio_inline_la_LIBADD = \ $(top_builddir)/mail/libevolution-mail.la \ $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/em-format/libemformat.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(GSTREAMER_LIBS) \ - $(GTKHTML_LIBS) + $(GSTREAMER_LIBS) EXTRA_DIST = org-gnome-audio-inline.eplug.xml diff --git a/plugins/audio-inline/audio-inline.c b/plugins/audio-inline/audio-inline.c index a5e7ccd68c..45238db2eb 100644 --- a/plugins/audio-inline/audio-inline.c +++ b/plugins/audio-inline/audio-inline.c @@ -29,7 +29,6 @@ #include "e-util/e-mktemp.h" #include "mail/em-format-hook.h" #include "mail/em-format-html.h" -#include "gtkhtml/gtkhtml-embedded.h" #include "gst/gst.h" #define d(x) @@ -45,12 +44,11 @@ e_plugin_lib_enable (EPlugin *ep, void org_gnome_audio_inline_format (gpointer ep, EMFormatHookTarget *t); -static volatile gint org_gnome_audio_class_id_counter = 0; +typedef struct _EMFormatInlineAudioPURI EMFormatInlineAudioPURI; -struct _org_gnome_audio_inline_pobject { - EMFormatHTMLPObject object; +struct _EMFormatInlineAudioPURI { + EMFormatPURI puri; - CamelMimePart *part; gchar *filename; GstElement *playbin; gulong bus_id; @@ -61,9 +59,9 @@ struct _org_gnome_audio_inline_pobject { }; static void -org_gnome_audio_inline_pobject_free (EMFormatHTMLPObject *o) +org_gnome_audio_inline_pobject_free (EMFormatPURI *o) { - struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) o; + EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) o; d(printf ("audio inline formatter: pobject free\n")); @@ -82,10 +80,6 @@ org_gnome_audio_inline_pobject_free (EMFormatHTMLPObject *o) po->stop_button = NULL; } - if (po->part) { - g_object_unref (po->part); - po->part = NULL; - } if (po->filename) { g_unlink (po->filename); g_free (po->filename); @@ -106,9 +100,9 @@ org_gnome_audio_inline_pobject_free (EMFormatHTMLPObject *o) static void org_gnome_audio_inline_pause_clicked (GtkWidget *button, - EMFormatHTMLPObject *pobject) + EMFormatPURI *puri) { - struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; if (po->playbin) { /* pause playing */ @@ -118,9 +112,9 @@ org_gnome_audio_inline_pause_clicked (GtkWidget *button, static void org_gnome_audio_inline_stop_clicked (GtkWidget *button, - EMFormatHTMLPObject *pobject) + EMFormatPURI *puri) { - struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; if (po->playbin) { /* ready to play */ @@ -150,7 +144,7 @@ org_gnome_audio_inline_gst_callback (GstBus *bus, GstMessage *message, gpointer data) { - struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) data; + EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) data; GstMessageType msg_type; g_return_val_if_fail (po != NULL, TRUE); @@ -195,9 +189,9 @@ org_gnome_audio_inline_gst_callback (GstBus *bus, static void org_gnome_audio_inline_play_clicked (GtkWidget *button, - EMFormatHTMLPObject *pobject) + EMFormatPURI *puri) { - struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; GstState cur_state; d(printf ("audio inline formatter: play\n")); @@ -215,7 +209,7 @@ org_gnome_audio_inline_play_clicked (GtkWidget *button, d(printf ("audio inline formatter: write to temp file %s\n", po->filename)); stream = camel_stream_fs_new_with_name (po->filename, O_RDWR | O_CREAT | O_TRUNC, 0600, NULL); - data = camel_medium_get_content (CAMEL_MEDIUM (po->part)); + data = camel_medium_get_content (CAMEL_MEDIUM (po->puri.part)); camel_data_wrapper_decode_to_stream_sync ( data, stream, NULL, NULL); camel_stream_flush (stream, NULL, NULL); @@ -281,13 +275,31 @@ org_gnome_audio_inline_add_button (GtkWidget *box, return button; } -static gboolean -org_gnome_audio_inline_button_panel (EMFormatHTML *efh, - GtkHTMLEmbedded *eb, - EMFormatHTMLPObject *pobject) +static void +write_button_panel (EMFormat *emf, + EMFormatPURI *puri, + CamelStream *stream, + EMFormatWriterInfo *info, + GCancellable *cancellable) +{ + gchar *str; + + str = g_strdup_printf ( + "<object type=\"application/x-org-gnome-audio-inline-button-panel\" " + "width=\"100%%\" height=\"auto\" data=\"%s\" id=\"%s\"></object>", + puri->uri, puri->uri); + camel_stream_write_string (stream, str, cancellable, NULL); + + g_free (str); +} + +static GtkWidget * +org_gnome_audio_inline_button_panel (EMFormat *emf, + EMFormatPURI *puri, + GCancellable *cancellable) { GtkWidget *box; - struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + EMFormatInlineAudioPURI *po = (EMFormatInlineAudioPURI *) puri; /* it is OK to call UI functions here, since we are called from UI thread */ @@ -297,42 +309,39 @@ org_gnome_audio_inline_button_panel (EMFormatHTML *efh, po->stop_button = g_object_ref (org_gnome_audio_inline_add_button (box, GTK_STOCK_MEDIA_STOP, G_CALLBACK (org_gnome_audio_inline_stop_clicked), po, FALSE)); gtk_widget_show (box); - gtk_container_add ((GtkContainer *) eb, box); - return TRUE; + return box; } void org_gnome_audio_inline_format (gpointer ep, EMFormatHookTarget *t) { - struct _org_gnome_audio_inline_pobject *pobj; - gchar *classid; - gchar *content; - - classid = g_strdup_printf ( - "org-gnome-audio-inline-button-panel-%d", - org_gnome_audio_class_id_counter); + EMFormatInlineAudioPURI *pobj; + gint len; - org_gnome_audio_class_id_counter++; + len = t->part_id->len; + g_string_append (t->part_id, ".org-gnome-audio-inline-button-panel"); - d(printf ("audio inline formatter: format classid %s\n", classid)); + d(printf ("audio inline formatter: format classid %s\n", t->part_id->str)); - pobj = (struct _org_gnome_audio_inline_pobject *) - em_format_html_add_pobject ( - (EMFormatHTML *) t->format, sizeof (*pobj), classid, - t->part, org_gnome_audio_inline_button_panel); - pobj->part = g_object_ref (t->part); + pobj = (EMFormatInlineAudioPURI *) em_format_puri_new ( + t->format, sizeof (EMFormatInlineAudioPURI), + t->part, t->part_id->str); + pobj->puri.widget_func = org_gnome_audio_inline_button_panel; + pobj->puri.write_func = write_button_panel; + pobj->puri.part = g_object_ref (t->part); + pobj->puri.is_attachment = TRUE; pobj->filename = NULL; pobj->playbin = NULL; pobj->play_button = NULL; pobj->stop_button = NULL; pobj->pause_button = NULL; pobj->bus_id = 0; - pobj->object.free = org_gnome_audio_inline_pobject_free; + pobj->puri.free = org_gnome_audio_inline_pobject_free; pobj->target_state = GST_STATE_NULL; - content = g_strdup_printf ("<object classid=%s></object>\n", classid); - camel_stream_write_string (t->stream, content, NULL, NULL); - g_free (content); + em_format_add_puri (t->format, (EMFormatPURI *) pobj); + + g_string_truncate (t->part_id, len); } diff --git a/plugins/dbx-import/Makefile.am b/plugins/dbx-import/Makefile.am index eeaf69ff3f..5bead7d3fd 100644 --- a/plugins/dbx-import/Makefile.am +++ b/plugins/dbx-import/Makefile.am @@ -16,8 +16,7 @@ liborg_gnome_dbx_import_la_CPPFLAGS = \ -I$(top_srcdir)/widgets \ -I$(top_builddir) \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GNOME_PLATFORM_CFLAGS) liborg_gnome_dbx_import_la_SOURCES = dbx-importer.c @@ -30,8 +29,7 @@ liborg_gnome_dbx_import_la_LIBADD = \ $(top_builddir)/libemail-engine/libemail-engine.la \ $(top_builddir)/libemail-utils/libemail-utils.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) + $(GNOME_PLATFORM_LIBS) EXTRA_DIST = org-gnome-dbx-import.eplug.xml diff --git a/plugins/external-editor/external-editor.c b/plugins/external-editor/external-editor.c index 6b787b9201..6b0d375f26 100644 --- a/plugins/external-editor/external-editor.c +++ b/plugins/external-editor/external-editor.c @@ -469,7 +469,7 @@ e_plugin_ui_init (GtkUIManager *manager, EMsgComposer *composer) { GtkhtmlEditor *editor; - EWebView *web_view; + EWebViewGtkHTML *web_view; editor = GTKHTML_EDITOR (composer); diff --git a/plugins/itip-formatter/Makefile.am b/plugins/itip-formatter/Makefile.am index 381f99ecf1..e0672eb734 100644 --- a/plugins/itip-formatter/Makefile.am +++ b/plugins/itip-formatter/Makefile.am @@ -7,9 +7,9 @@ liborg_gnome_itip_formatter_la_CPPFLAGS = \ $(AM_CPPFLAGS) \ -I$(top_srcdir) \ -I$(top_srcdir)/widgets \ + -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GNOME_PLATFORM_CFLAGS) liborg_gnome_itip_formatter_la_SOURCES = itip-formatter.c itip-view.c itip-view.h @@ -26,8 +26,7 @@ liborg_gnome_itip_formatter_la_LIBADD = \ $(top_builddir)/libemail-engine/libemail-engine.la \ $(top_builddir)/libevolution-utils/libevolution-utils.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) + $(GNOME_PLATFORM_LIBS) error_DATA = org-gnome-itip-formatter.error errordir = $(privdatadir)/errors diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c index 0b0acd4af3..b40a5082ce 100644 --- a/plugins/itip-formatter/itip-formatter.c +++ b/plugins/itip-formatter/itip-formatter.c @@ -33,7 +33,6 @@ #include <libedataserver/e-account-list.h> #include <libedataserverui/e-source-selector.h> #include <libedataserverui/e-client-utils.h> -#include <gtkhtml/gtkhtml-embedded.h> #include <libevolution-utils/e-alert-dialog.h> #include <e-util/e-mktemp.h> @@ -58,12 +57,11 @@ #include "itip-view.h" -#define CLASSID "itip://" #define CONF_KEY_DELETE "delete-processed" #define d(x) -struct _itip_puri { +struct _ItipPURI { EMFormatPURI puri; const EMFormatHandler *handle; @@ -72,7 +70,6 @@ struct _itip_puri { CamelMimePart *part; gchar *uid; - GtkWidget *view; ESourceList *source_lists[E_CAL_CLIENT_SOURCE_TYPE_LAST]; GHashTable *clients[E_CAL_CLIENT_SOURCE_TYPE_LAST]; @@ -146,13 +143,15 @@ struct _itip_puri { GHashTable *real_comps; /* ESource's UID -> ECalComponent stored on the server */ }; +typedef struct _ItipPURI ItipPURI; + void format_itip (EPlugin *ep, EMFormatHookTarget *target); GtkWidget *itip_formatter_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data); -static void itip_attachment_frame (EMFormat *emf, CamelStream *stream, EMFormatPURI *puri, GCancellable *cancellable); gint e_plugin_lib_enable (EPlugin *ep, gint enable); typedef struct { - struct _itip_puri *puri; + ItipPURI *puri; + ItipView *view; GCancellable *cancellable; gboolean keep_alarm_check; GHashTable *conflicts; @@ -246,7 +245,7 @@ find_attendee_if_sentby (icalcomponent *ical_comp, } static void -find_to_address (struct _itip_puri *pitip, +find_to_address (ItipPURI *pitip, icalcomponent *ical_comp, icalparameter_partstat *status) { @@ -370,7 +369,7 @@ find_to_address (struct _itip_puri *pitip, } static void -find_from_address (struct _itip_puri *pitip, +find_from_address (ItipPURI *pitip, icalcomponent *ical_comp) { EIterator *it; @@ -434,7 +433,7 @@ find_from_address (struct _itip_puri *pitip, } static ECalComponent * -get_real_item (struct _itip_puri *pitip) +get_real_item (ItipPURI *pitip) { ECalComponent *comp = NULL; ESource *source; @@ -451,7 +450,7 @@ get_real_item (struct _itip_puri *pitip) } static void -adjust_item (struct _itip_puri *pitip, +adjust_item (ItipPURI *pitip, ECalComponent *comp) { ECalComponent *real_comp; @@ -479,14 +478,15 @@ adjust_item (struct _itip_puri *pitip, } static void -set_buttons_sensitive (struct _itip_puri *pitip) +set_buttons_sensitive (ItipPURI *pitip, + ItipView *view) { gboolean read_only = TRUE; if (pitip->current_client) read_only = e_client_is_readonly (E_CLIENT (pitip->current_client)); - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), pitip->current_client != NULL && !read_only); + itip_view_set_buttons_sensitive (view, pitip->current_client != NULL && !read_only); } static void @@ -515,7 +515,8 @@ cal_opened_cb (GObject *source_object, gpointer user_data) { ESource *source = E_SOURCE (source_object); - struct _itip_puri *pitip = user_data; + ItipView *view = user_data; + ItipPURI *pitip = itip_view_get_puri (view); ECalClientSourceType source_type; EClient *client = NULL; ECalClient *cal_client; @@ -533,8 +534,7 @@ cal_opened_cb (GObject *source_object, } else if (error != NULL) { g_warn_if_fail (client == NULL); - add_failed_to_load_msg ( - ITIP_VIEW (pitip->view), source, error); + add_failed_to_load_msg (view, source, error); g_error_free (error); return; } @@ -556,8 +556,7 @@ cal_opened_cb (GObject *source_object, icalcomp = e_cal_component_get_icalcomponent (pitip->comp); show_recur_check = check_is_instance (icalcomp); - itip_view_set_show_recur_check ( - ITIP_VIEW (pitip->view), show_recur_check); + itip_view_set_show_recur_check (view, show_recur_check); } if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { @@ -566,19 +565,18 @@ cal_opened_cb (GObject *source_object, needs_decline = e_client_check_capability ( E_CLIENT (client), CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING); - itip_view_set_needs_decline ( - ITIP_VIEW (pitip->view), needs_decline); - itip_view_set_mode ( - ITIP_VIEW (pitip->view), ITIP_VIEW_MODE_PUBLISH); + itip_view_set_needs_decline (view, needs_decline); + itip_view_set_mode (view, ITIP_VIEW_MODE_PUBLISH); } pitip->current_client = cal_client; - set_buttons_sensitive (pitip); + set_buttons_sensitive (pitip, view); } static void -start_calendar_server (struct _itip_puri *pitip, +start_calendar_server (ItipPURI *pitip, + ItipView *view, ESource *source, ECalClientSourceType type, GAsyncReadyCallback func, @@ -592,10 +590,10 @@ start_calendar_server (struct _itip_puri *pitip, if (client) { pitip->current_client = client; - itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->progress_info_id); + itip_view_remove_lower_info_item (view, pitip->progress_info_id); pitip->progress_info_id = 0; - set_buttons_sensitive (pitip); + set_buttons_sensitive (pitip, view); return; } @@ -610,20 +608,21 @@ start_calendar_server (struct _itip_puri *pitip, } static void -start_calendar_server_by_uid (struct _itip_puri *pitip, +start_calendar_server_by_uid (ItipPURI *pitip, + ItipView *view, const gchar *uid, ECalClientSourceType type) { gint i; - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE); + itip_view_set_buttons_sensitive (view, FALSE); for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { ESource *source; source = e_source_list_peek_source_by_uid (pitip->source_lists[i], uid); if (source) { - start_calendar_server (pitip, source, type, cal_opened_cb, pitip); + start_calendar_server (pitip, view, source, type, cal_opened_cb, view); break; } } @@ -634,25 +633,27 @@ source_selected_cb (ItipView *view, ESource *source, gpointer data) { - struct _itip_puri *pitip = data; + ItipPURI *pitip = data; - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE); + itip_view_set_buttons_sensitive (view, FALSE); g_return_if_fail (source != NULL); - start_calendar_server (pitip, source, pitip->type, cal_opened_cb, pitip); + start_calendar_server (pitip, view, source, pitip->type, cal_opened_cb, view); } static void find_cal_update_ui (FormatItipFindData *fd, ECalClient *cal_client) { - struct _itip_puri *pitip; + ItipPURI *pitip; + ItipView *view; ESource *source; g_return_if_fail (fd != NULL); pitip = fd->puri; + view = fd->view; /* UI part gone */ if (g_cancellable_is_cancelled (fd->cancellable)) @@ -661,13 +662,13 @@ find_cal_update_ui (FormatItipFindData *fd, source = cal_client ? e_client_get_source (E_CLIENT (cal_client)) : NULL; if (cal_client && g_hash_table_lookup (fd->conflicts, cal_client)) { - itip_view_add_upper_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING, + itip_view_add_upper_info_item_printf (view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, _("An appointment in the calendar '%s' conflicts with this meeting"), e_source_peek_name (source)); } /* search for a master object if the detached object doesn't exist in the calendar */ if (pitip->current_client && pitip->current_client == cal_client) { - itip_view_set_show_keep_alarm_check (ITIP_VIEW (pitip->view), fd->keep_alarm_check); + itip_view_set_show_keep_alarm_check (view, fd->keep_alarm_check); pitip->current_client = cal_client; @@ -681,35 +682,35 @@ find_cal_update_ui (FormatItipFindData *fd, /* We clear everything because we don't really care * about any other info/warnings now we found an * existing versions */ - itip_view_clear_lower_info_items (ITIP_VIEW (pitip->view)); + itip_view_clear_lower_info_items (view); pitip->progress_info_id = 0; /* FIXME Check read only state of calendar? */ - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Found the appointment in the calendar '%s'"), e_source_peek_name (source)); + itip_view_add_lower_info_item_printf (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Found the appointment in the calendar '%s'"), e_source_peek_name (source)); - set_buttons_sensitive (pitip); + set_buttons_sensitive (pitip, view); } else if (!pitip->current_client) - itip_view_set_show_keep_alarm_check (ITIP_VIEW (pitip->view), FALSE); + itip_view_set_show_keep_alarm_check (view, FALSE); if (pitip->current_client && pitip->current_client == cal_client) { if (e_cal_client_check_recurrences_no_master (pitip->current_client)) { icalcomponent *icalcomp = e_cal_component_get_icalcomponent (pitip->comp); if (check_is_instance (icalcomp)) - itip_view_set_show_recur_check (ITIP_VIEW (pitip->view), TRUE); + itip_view_set_show_recur_check (view, TRUE); else - itip_view_set_show_recur_check (ITIP_VIEW (pitip->view), FALSE); + itip_view_set_show_recur_check (view, FALSE); } if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { /* TODO The static capability should be made generic to convey that the calendar contains unaccepted items */ if (e_client_check_capability (E_CLIENT (pitip->current_client), CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING)) - itip_view_set_needs_decline (ITIP_VIEW (pitip->view), TRUE); + itip_view_set_needs_decline (view, TRUE); else - itip_view_set_needs_decline (ITIP_VIEW (pitip->view), FALSE); + itip_view_set_needs_decline (view, FALSE); - itip_view_set_mode (ITIP_VIEW (pitip->view), ITIP_VIEW_MODE_PUBLISH); + itip_view_set_mode (view, ITIP_VIEW_MODE_PUBLISH); } } } @@ -724,9 +725,10 @@ decrease_find_data (FormatItipFindData *fd) if (fd->count == 0 && !g_cancellable_is_cancelled (fd->cancellable)) { gboolean rsvp_enabled = FALSE; - struct _itip_puri *pitip = fd->puri; + ItipPURI *pitip = fd->puri; + ItipView *view = fd->view; - itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->progress_info_id); + itip_view_remove_lower_info_item (view, pitip->progress_info_id); pitip->progress_info_id = 0; /* @@ -740,10 +742,10 @@ decrease_find_data (FormatItipFindData *fd) pitip->has_organizer) { rsvp_enabled = TRUE; } - itip_view_set_show_rsvp (ITIP_VIEW (pitip->view), rsvp_enabled); + itip_view_set_show_rsvp_check (view, rsvp_enabled); /* default is chosen in extract_itip_data() based on content of the VEVENT */ - itip_view_set_rsvp (ITIP_VIEW (pitip->view), !pitip->no_reply_wanted); + itip_view_set_rsvp (view, !pitip->no_reply_wanted); if ((pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST) && !pitip->current_client) { @@ -789,32 +791,35 @@ decrease_find_data (FormatItipFindData *fd) if (!source) source = e_source_list_peek_source_any (pitip->source_lists[pitip->type]); - itip_view_set_source_list (ITIP_VIEW (pitip->view), pitip->source_lists[pitip->type]); + itip_view_set_source_list (view, pitip->source_lists[pitip->type]); g_signal_connect ( - pitip->view, "source_selected", + view, "source_selected", G_CALLBACK (source_selected_cb), pitip); if (source) { - itip_view_set_source (ITIP_VIEW (pitip->view), source); + itip_view_set_source (view, source); /* FIXME Shouldn't the buttons be sensitized here? */ } else { - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to find any calendars")); - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE); + itip_view_add_lower_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to find any calendars")); + itip_view_set_buttons_sensitive (view, FALSE); } } else if (!pitip->current_client) { switch (pitip->type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Unable to find this meeting in any calendar")); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, + _("Unable to find this meeting in any calendar")); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Unable to find this task in any task list")); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, + _("Unable to find this task in any task list")); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_WARNING, - _("Unable to find this memo in any memo list")); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, + _("Unable to find this memo in any memo list")); break; default: g_assert_not_reached (); @@ -828,6 +833,8 @@ decrease_find_data (FormatItipFindData *fd) g_object_unref (fd->cancellable); g_free (fd->uid); g_free (fd->rid); + if (fd->sexp) + g_free (fd->sexp); g_free (fd); } } @@ -982,7 +989,8 @@ find_cal_opened_cb (GObject *source_object, { ESource *source = E_SOURCE (source_object); FormatItipFindData *fd = user_data; - struct _itip_puri *pitip = fd->puri; + ItipPURI *pitip = fd->puri; + ItipView *view = fd->view; ECalClientSourceType source_type; EClient *client = NULL; ECalClient *cal_client; @@ -1011,8 +1019,7 @@ find_cal_opened_cb (GObject *source_object, * to find the item, this won't be cleared but the * selector might be shown */ g_warn_if_fail (client == NULL); - add_failed_to_load_msg ( - ITIP_VIEW (pitip->view), source, error); + add_failed_to_load_msg (view, source, error); decrease_find_data (fd); g_error_free (error); return; @@ -1053,7 +1060,8 @@ find_cal_opened_cb (GObject *source_object, } static void -find_server (struct _itip_puri *pitip, +find_server (ItipPURI *pitip, + ItipView *view, ECalComponent *comp) { FormatItipFindData *fd = NULL; @@ -1076,7 +1084,7 @@ find_server (struct _itip_puri *pitip, uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); camel_url_free (url); - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE); + itip_view_set_buttons_sensitive (view, FALSE); groups = e_source_list_peek_groups (pitip->source_lists[pitip->type]); for (l = groups; l; l = l->next) { @@ -1115,11 +1123,13 @@ find_server (struct _itip_puri *pitip, if (current_source) { l = sources_conflict; - pitip->progress_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, - _("Opening the calendar. Please wait...")); + pitip->progress_info_id = itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, + _("Opening the calendar. Please wait...")); } else { - pitip->progress_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, - _("Searching for an existing version of this appointment")); + pitip->progress_info_id = itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, + _("Searching for an existing version of this appointment")); l = all_sources; } @@ -1132,6 +1142,7 @@ find_server (struct _itip_puri *pitip, fd = g_new0 (FormatItipFindData, 1); fd->puri = pitip; + fd->view = view; fd->cancellable = g_object_ref (pitip->cancellable); fd->conflicts = g_hash_table_new (g_direct_hash, g_direct_equal); fd->uid = g_strdup (uid); @@ -1154,9 +1165,9 @@ find_server (struct _itip_puri *pitip, d(printf ("Increasing itip formatter search count to %d\n", fd->count)); if (current_source == source) - start_calendar_server (pitip, source, pitip->type, find_cal_opened_cb, fd); + start_calendar_server (pitip, view, source, pitip->type, find_cal_opened_cb, fd); else - start_calendar_server (pitip, source, pitip->type, find_cal_opened_cb, fd); + start_calendar_server (pitip, view, source, pitip->type, find_cal_opened_cb, fd); } @@ -1349,32 +1360,36 @@ get_uri_for_part (CamelMimePart *mime_part) } static void -update_item_progress_info (struct _itip_puri *pitip, +update_item_progress_info (ItipPURI *pitip, + ItipView *view, const gchar *message) { if (pitip->update_item_progress_info_id) { - itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->update_item_progress_info_id); + itip_view_remove_lower_info_item (view, pitip->update_item_progress_info_id); pitip->update_item_progress_info_id = 0; if (!message) - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), TRUE); + itip_view_set_buttons_sensitive (view, TRUE); } if (pitip->update_item_error_info_id) { - itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->update_item_error_info_id); + itip_view_remove_lower_info_item (view, pitip->update_item_error_info_id); pitip->update_item_error_info_id = 0; } if (message) { - itip_view_set_buttons_sensitive (ITIP_VIEW (pitip->view), FALSE); - pitip->update_item_progress_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), - ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, - message); + itip_view_set_buttons_sensitive (view, FALSE); + pitip->update_item_progress_info_id = + itip_view_add_lower_info_item ( + view, + ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, + message); } } static void -finish_message_delete_with_rsvp (struct _itip_puri *pitip, +finish_message_delete_with_rsvp (ItipPURI *pitip, + ItipView *view, ECalClient *client) { gboolean save_schedules = e_cal_client_check_save_schedules (client); @@ -1382,7 +1397,7 @@ finish_message_delete_with_rsvp (struct _itip_puri *pitip, if (!save_schedules && pitip->delete_message && pitip->folder) camel_folder_delete_message (pitip->folder, pitip->uid); - if (itip_view_get_rsvp (ITIP_VIEW (pitip->view))) { + if (itip_view_get_rsvp (view)) { ECalComponent *comp = NULL; icalcomponent *ical_comp; icalproperty *prop; @@ -1435,7 +1450,7 @@ finish_message_delete_with_rsvp (struct _itip_puri *pitip, g_slist_free (list); /* Add a comment if there user set one */ - comment = itip_view_get_rsvp_comment (ITIP_VIEW (pitip->view)); + comment = itip_view_get_rsvp_comment (view); if (comment) { GSList comments; ECalComponentText text; @@ -1462,7 +1477,7 @@ finish_message_delete_with_rsvp (struct _itip_puri *pitip, g_object_unref (comp); } - update_item_progress_info (pitip, NULL); + update_item_progress_info (pitip, view, NULL); } static void @@ -1472,44 +1487,51 @@ receive_objects_ready_cb (GObject *ecalclient, { ECalClient *client = E_CAL_CLIENT (ecalclient); ESource *source = e_client_get_source (E_CLIENT (client)); - struct _itip_puri *pitip = user_data; + ItipView *view = user_data; + ItipPURI *pitip = itip_view_get_puri (view); gboolean save_schedules; GError *error = NULL; if (!e_cal_client_receive_objects_finish (client, result, &error)) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED) && !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED)) { - update_item_progress_info (pitip, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Unable to send item to calendar '%s'. %s"), - e_source_peek_name (source), error ? error->message : _("Unknown error")); + update_item_progress_info (pitip, view, NULL); + pitip->update_item_error_info_id = + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Unable to send item to calendar '%s'. %s"), + e_source_peek_name (source), error ? error->message : _("Unknown error")); } g_clear_error (&error); return; } - itip_view_set_source_list (ITIP_VIEW (pitip->view), NULL); + itip_view_set_source_list (view, NULL); - itip_view_clear_lower_info_items (ITIP_VIEW (pitip->view)); + itip_view_clear_lower_info_items (view); switch (pitip->update_item_response) { case ITIP_VIEW_RESPONSE_ACCEPT: - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as accepted"), e_source_peek_name (source)); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Sent to calendar '%s' as accepted"), e_source_peek_name (source)); break; case ITIP_VIEW_RESPONSE_TENTATIVE: - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as tentative"), e_source_peek_name (source)); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Sent to calendar '%s' as tentative"), e_source_peek_name (source)); break; case ITIP_VIEW_RESPONSE_DECLINE: /* FIXME some calendars just might not save it at all, is this accurate? */ - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as declined"), e_source_peek_name (source)); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Sent to calendar '%s' as declined"), e_source_peek_name (source)); break; case ITIP_VIEW_RESPONSE_CANCEL: /* FIXME some calendars just might not save it at all, is this accurate? */ - itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, - _("Sent to calendar '%s' as canceled"), e_source_peek_name (source)); + itip_view_add_lower_info_item_printf ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Sent to calendar '%s' as canceled"), e_source_peek_name (source)); break; default: g_assert_not_reached (); @@ -1528,7 +1550,7 @@ receive_objects_ready_cb (GObject *ecalclient, if (mi) { changes = camel_folder_change_info_new (); - if (itip_view_get_recur_check_state (ITIP_VIEW (pitip->view))) { + if (itip_view_get_recur_check_state (view)) { /* Recurring appointment and "apply-to-all" is selected */ tag = camel_message_info_user_tag (mi, "recurrence-key"); if (tag) { @@ -1565,11 +1587,12 @@ receive_objects_ready_cb (GObject *ecalclient, } } - finish_message_delete_with_rsvp (pitip, client); + finish_message_delete_with_rsvp (pitip, view, client); } static void -update_item (struct _itip_puri *pitip, +update_item (ItipPURI *pitip, + ItipView *view, ItipViewResponse response) { struct icaltimetype stamp; @@ -1578,7 +1601,7 @@ update_item (struct _itip_puri *pitip, ECalComponent *clone_comp; gchar *str; - update_item_progress_info (pitip, _("Saving changes to the calendar. Please wait...")); + update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); /* Set X-MICROSOFT-CDO-REPLYTIME to record the time at which * the user accepted/declined the request. (Outlook ignores @@ -1600,7 +1623,7 @@ update_item (struct _itip_puri *pitip, icalcomponent_add_component (pitip->top_level, clone); icalcomponent_set_method (pitip->top_level, pitip->method); - if (!itip_view_get_inherit_alarm_check_state (ITIP_VIEW (pitip->view))) { + if (!itip_view_get_inherit_alarm_check_state (view)) { icalcomponent *alarm_comp; icalcompiter alarm_iter; @@ -1615,13 +1638,13 @@ update_item (struct _itip_puri *pitip, clone_comp = e_cal_component_new (); if (!e_cal_component_set_icalcomponent (clone_comp, clone)) { - update_item_progress_info (pitip, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), + update_item_progress_info (pitip, view, NULL); + pitip->update_item_error_info_id = itip_view_add_lower_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to parse item")); goto cleanup; } - if (itip_view_get_keep_alarm_check_state (ITIP_VIEW (pitip->view))) { + if (itip_view_get_keep_alarm_check_state (view)) { ECalComponent *real_comp; GList *alarms, *l; ECalComponentAlarm *alarm; @@ -1704,7 +1727,12 @@ update_item (struct _itip_puri *pitip, pitip->update_item_response = response; - e_cal_client_receive_objects (pitip->current_client, pitip->top_level, pitip->cancellable, receive_objects_ready_cb, pitip); + e_cal_client_receive_objects ( + pitip->current_client, + pitip->top_level, + pitip->cancellable, + receive_objects_ready_cb, + view); cleanup: icalcomponent_remove_component (pitip->top_level, clone); @@ -1791,7 +1819,8 @@ send_comp_to_attendee (ECalComponentItipMethod method, } static void -remove_delegate (struct _itip_puri *pitip, +remove_delegate (ItipPURI *pitip, + ItipView *view, const gchar *delegate, const gchar *delegator, ECalComponent *comp) @@ -1800,13 +1829,21 @@ remove_delegate (struct _itip_puri *pitip, gchar *comment = g_strdup_printf (_("Organizer has removed the delegate %s "), itip_strip_mailto (delegate)); /* send cancellation notice to delegate */ - status = send_comp_to_attendee (E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp, delegate, pitip->current_client, comment); + status = send_comp_to_attendee ( + E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp, + delegate, pitip->current_client, comment); if (status) - send_comp_to_attendee (E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp, delegator, pitip->current_client, comment); + send_comp_to_attendee ( + E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp, + delegator, pitip->current_client, comment); if (status) { - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Sent a cancelation notice to the delegate")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Sent a cancelation notice to the delegate")); } else - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Could not send the cancelation notice to the delegate")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Could not send the cancelation notice to the delegate")); g_free (comment); @@ -1839,7 +1876,8 @@ modify_object_cb (GObject *ecalclient, gpointer user_data) { ECalClient *client = E_CAL_CLIENT (ecalclient); - struct _itip_puri *pitip = user_data; + ItipView *view = user_data; + ItipPURI *pitip = itip_view_get_puri (view); GError *error = NULL; if (!e_cal_client_modify_object_finish (client, result, &error)) { @@ -1849,21 +1887,25 @@ modify_object_cb (GObject *ecalclient, return; } - update_item_progress_info (pitip, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), - ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Unable to update attendee. %s"), error ? error->message : _("Unknown error")); + update_item_progress_info (pitip, view, NULL); + pitip->update_item_error_info_id = + itip_view_add_lower_info_item_printf ( + view, + ITIP_VIEW_INFO_ITEM_TYPE_ERROR, + _("Unable to update attendee. %s"), + error ? error->message : _("Unknown error")); g_clear_error (&error); } else { - update_item_progress_info (pitip, NULL); - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), + update_item_progress_info (pitip, view, NULL); + itip_view_add_lower_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Attendee status updated")); } } static void -update_attendee_status_icalcomp (struct _itip_puri *pitip, +update_attendee_status_icalcomp (ItipPURI *pitip, + ItipView *view, icalcomponent *icalcomp) { ECalComponent *comp; @@ -1878,7 +1920,9 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { icalcomponent_free (icalcomp); - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("The meeting is invalid and cannot be updated")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, + _("The meeting is invalid and cannot be updated")); } else { icalcomponent *org_icalcomp; const gchar *delegate; @@ -1889,12 +1933,13 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, if (attendees != NULL) { ECalComponentAttendee *a = attendees->data; icalproperty *prop, *del_prop; + EShell *shell = e_shell_get_default (); prop = find_attendee (icalcomp, itip_strip_mailto (a->value)); if ((a->status == ICAL_PARTSTAT_DELEGATED) && (del_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->delto))) && !(find_attendee (icalcomp, itip_strip_mailto (a->delto)))) { gint response; delegate = icalproperty_get_attendee (del_prop); - response = e_alert_run_dialog_for_args (GTK_WINDOW (gtk_widget_get_toplevel (pitip->view)), + response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), "org.gnome.itip-formatter:add-delegate", itip_strip_mailto (a->value), itip_strip_mailto (delegate), NULL); @@ -1902,7 +1947,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, icalcomponent_add_property (icalcomp, icalproperty_new_clone (del_prop)); e_cal_component_rescan (comp); } else if (response == GTK_RESPONSE_NO) { - remove_delegate (pitip, delegate, itip_strip_mailto (a->value), comp); + remove_delegate (pitip, view, delegate, itip_strip_mailto (a->value), comp); goto cleanup; } else { goto cleanup; @@ -1913,7 +1958,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, gint response; if (a->delfrom && *a->delfrom) { - response = e_alert_run_dialog_for_args (GTK_WINDOW (gtk_widget_get_toplevel (pitip->view)), + response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), "org.gnome.itip-formatter:add-delegate", itip_strip_mailto (a->delfrom), itip_strip_mailto (a->value), NULL); @@ -1924,6 +1969,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, e_cal_component_rescan (comp); } else if (response == GTK_RESPONSE_NO) { remove_delegate (pitip, + view, itip_strip_mailto (a->value), itip_strip_mailto (a->delfrom), comp); @@ -1933,7 +1979,7 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, } } - response = e_alert_run_dialog_for_args (GTK_WINDOW (gtk_widget_get_toplevel (pitip->view)), + response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), "org.gnome.itip-formatter:add-unknown-attendee", NULL); if (response == GTK_RESPONSE_YES) { @@ -1943,8 +1989,9 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, goto cleanup; } } else if (a->status == ICAL_PARTSTAT_NONE || a->status == ICAL_PARTSTAT_X) { - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, - _("Attendee status could not be updated because the status is invalid")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, + _("Attendee status could not be updated because the status is invalid")); goto cleanup; } else { if (a->status == ICAL_PARTSTAT_DELEGATED) { @@ -1966,14 +2013,19 @@ update_attendee_status_icalcomp (struct _itip_puri *pitip, update_x (pitip->comp, comp); - if (itip_view_get_update (ITIP_VIEW (pitip->view))) { + if (itip_view_get_update (view)) { e_cal_component_commit_sequence (comp); itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_client, NULL, NULL, NULL, TRUE, FALSE); } - update_item_progress_info (pitip, _("Saving changes to the calendar. Please wait...")); + update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); - e_cal_client_modify_object (pitip->current_client, icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL, pitip->cancellable, modify_object_cb, pitip); + e_cal_client_modify_object ( + pitip->current_client, + icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL, + pitip->cancellable, + modify_object_cb, + view); cleanup: g_object_unref (comp); @@ -1985,7 +2037,8 @@ update_attendee_status_get_object_without_rid_cb (GObject *ecalclient, gpointer user_data) { ECalClient *client = E_CAL_CLIENT (ecalclient); - struct _itip_puri *pitip = user_data; + ItipView *view = user_data; + ItipPURI *pitip = itip_view_get_puri (view); icalcomponent *icalcomp = NULL; GError *error = NULL; @@ -1998,14 +2051,15 @@ update_attendee_status_get_object_without_rid_cb (GObject *ecalclient, g_clear_error (&error); - update_item_progress_info (pitip, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), + update_item_progress_info (pitip, view, NULL); + pitip->update_item_error_info_id = itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, _("Attendee status can not be updated because the item no longer exists")); return; } - update_attendee_status_icalcomp (pitip, icalcomp); + update_attendee_status_icalcomp (pitip, view, icalcomp); } static void @@ -2014,7 +2068,8 @@ update_attendee_status_get_object_with_rid_cb (GObject *ecalclient, gpointer user_data) { ECalClient *client = E_CAL_CLIENT (ecalclient); - struct _itip_puri *pitip = user_data; + ItipView *view = user_data; + ItipPURI *pitip = itip_view_get_puri (view); icalcomponent *icalcomp = NULL; GError *error = NULL; @@ -2036,24 +2091,32 @@ update_attendee_status_get_object_with_rid_cb (GObject *ecalclient, if (!rid || !*rid) { g_free (rid); - update_item_progress_info (pitip, NULL); - pitip->update_item_error_info_id = itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), + update_item_progress_info (pitip, view, NULL); + pitip->update_item_error_info_id = itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_WARNING, _("Attendee status can not be updated because the item no longer exists")); return; } - e_cal_client_get_object (pitip->current_client, uid, NULL, pitip->cancellable, update_attendee_status_get_object_without_rid_cb, pitip); + e_cal_client_get_object ( + pitip->current_client, + uid, + NULL, + pitip->cancellable, + update_attendee_status_get_object_without_rid_cb, + view); g_free (rid); return; } - update_attendee_status_icalcomp (pitip, icalcomp); + update_attendee_status_icalcomp (pitip, view, icalcomp); } static void -update_attendee_status (struct _itip_puri *pitip) +update_attendee_status (ItipPURI *pitip, + ItipView *view) { const gchar *uid = NULL; gchar *rid; @@ -2062,16 +2125,22 @@ update_attendee_status (struct _itip_puri *pitip) e_cal_component_get_uid (pitip->comp, &uid); rid = e_cal_component_get_recurid_as_string (pitip->comp); - update_item_progress_info (pitip, _("Saving changes to the calendar. Please wait...")); + update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); /* search for a master object if the detached object doesn't exist in the calendar */ - e_cal_client_get_object (pitip->current_client, uid, rid, pitip->cancellable, update_attendee_status_get_object_with_rid_cb, pitip); + e_cal_client_get_object ( + pitip->current_client, + uid, rid, + pitip->cancellable, + update_attendee_status_get_object_with_rid_cb, + view); g_free (rid); } static void -send_item (struct _itip_puri *pitip) +send_item (ItipPURI *pitip, + ItipView *view) { ECalComponent *comp; @@ -2083,13 +2152,19 @@ send_item (struct _itip_puri *pitip) switch (pitip->type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Meeting information sent")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Meeting information sent")); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Task information sent")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Task information sent")); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Memo information sent")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, + _("Memo information sent")); break; default: g_assert_not_reached (); @@ -2098,13 +2173,19 @@ send_item (struct _itip_puri *pitip) } else { switch (pitip->type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to send meeting information, the meeting does not exist")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, + _("Unable to send meeting information, the meeting does not exist")); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to send task information, the task does not exist")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, + _("Unable to send task information, the task does not exist")); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR, _("Unable to send memo information, the memo does not exist")); + itip_view_add_lower_info_item ( + view, ITIP_VIEW_INFO_ITEM_TYPE_ERROR, + _("Unable to send memo information, the memo does not exist")); break; default: g_assert_not_reached (); @@ -2155,8 +2236,7 @@ attachment_load_finish (EAttachment *attachment, } static void -save_vcalendar_cb (GtkWidget *button, - struct _itip_puri *pitip) +save_vcalendar_cb (ItipPURI *pitip) { EAttachment *attachment; EShell *shell; @@ -2187,39 +2267,28 @@ save_vcalendar_cb (GtkWidget *button, attachment_load_finish, file); } -static GtkWidget * -set_itip_error (struct _itip_puri *pitip, - GtkContainer *container, +static void +set_itip_error (ItipView *view, const gchar *primary, - const gchar *secondary) + const gchar *secondary, + gboolean save_btn) { - GtkWidget *vbox, *label; - gchar *message; + gchar *error; - vbox = gtk_vbox_new (FALSE, 12); - gtk_widget_show (vbox); + error = g_strdup_printf ( + "<div class=\"error\">" + "<p><b>%s</b></p>" + "<p>%s</p>", + primary, secondary); - message = g_strdup_printf ("<b>%s</b>", primary); - label = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_label_set_markup (GTK_LABEL (label), message); - g_free (message); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - - label = gtk_label_new (secondary); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + itip_view_set_error (view, error, save_btn); - gtk_container_add (container, vbox); - - return vbox; + g_free (error); } static gboolean -extract_itip_data (struct _itip_puri *pitip, - GtkContainer *container, +extract_itip_data (ItipPURI *pitip, + ItipView *view, gboolean *have_alarms) { EShell *shell; @@ -2237,9 +2306,10 @@ extract_itip_data (struct _itip_puri *pitip, shell_settings = e_shell_get_shell_settings (shell); if (!pitip->vcalendar) { - set_itip_error (pitip, container, - _("The calendar attached is not valid"), - _("The message claims to contain a calendar, but the calendar is not a valid iCalendar.")); + set_itip_error (view, + _("The calendar attached is not valid"), + _("The message claims to contain a calendar, but the calendar is not a valid iCalendar."), + FALSE); return FALSE; } @@ -2248,9 +2318,10 @@ extract_itip_data (struct _itip_puri *pitip, pitip->main_comp = icalparser_parse_string (pitip->vcalendar); if (pitip->main_comp == NULL || !is_icalcomp_valid (pitip->main_comp)) { - set_itip_error (pitip, container, - _("The calendar attached is not valid"), - _("The message claims to contain a calendar, but the calendar is not a valid iCalendar.")); + set_itip_error (view, + _("The calendar attached is not valid"), + _("The message claims to contain a calendar, but the calendar is not a valid iCalendar."), + FALSE); if (pitip->main_comp) { icalcomponent_free (pitip->main_comp); @@ -2289,9 +2360,10 @@ extract_itip_data (struct _itip_puri *pitip, } if (pitip->ical_comp == NULL) { - set_itip_error (pitip, container, - _("The item in the calendar is not valid"), - _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information")); + set_itip_error (view, + _("The item in the calendar is not valid"), + _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"), + FALSE); return FALSE; } @@ -2317,9 +2389,11 @@ extract_itip_data (struct _itip_puri *pitip, pitip->type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS; break; default: - set_itip_error (pitip, container, - _("The item in the calendar is not valid"), - _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information")); + set_itip_error (view, + _("The item in the calendar is not valid"), + _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"), + FALSE); + return FALSE; } @@ -2329,27 +2403,12 @@ extract_itip_data (struct _itip_puri *pitip, pitip->total += icalcomponent_count_components (pitip->main_comp, ICAL_VJOURNAL_COMPONENT); if (pitip->total > 1) { - GtkWidget *save, *vbox, *hbox; - - vbox = set_itip_error (pitip, container, - _("The calendar attached contains multiple items"), - _("To process all of these items, the file should be saved and the calendar imported")); - - g_return_val_if_fail (vbox != NULL, FALSE); - hbox = gtk_hbox_new (FALSE, 0); + set_itip_error (view, + _("The calendar attached contains multiple items"), + _("To process all of these items, the file should be saved and the calendar imported"), + TRUE); - save = gtk_button_new_from_stock (GTK_STOCK_SAVE); - gtk_container_set_border_width (GTK_CONTAINER (save), 10); - gtk_box_pack_start (GTK_BOX (hbox), save, FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - g_signal_connect ( - save, "clicked", - G_CALLBACK (save_vcalendar_cb), pitip); - return FALSE; } if (pitip->total > 0) { pitip->current = 1; } else { @@ -2428,9 +2487,10 @@ extract_itip_data (struct _itip_puri *pitip, g_object_unref (pitip->comp); pitip->comp = NULL; - set_itip_error (pitip, container, - _("The item in the calendar is not valid"), - _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information")); + set_itip_error (view, + _("The item in the calendar is not valid"), + _("The message does contain a calendar, but the calendar contains no events, tasks or free/busy information"), + FALSE); return FALSE; }; @@ -2527,7 +2587,7 @@ static MailMsgInfo open_calendar_info = { static gboolean idle_open_cb (gpointer data) { - struct _itip_puri *pitip = data; + ItipPURI *pitip = data; struct _opencal_msg *m; gchar *start, *end; @@ -2544,18 +2604,23 @@ idle_open_cb (gpointer data) } static void -view_response_cb (GtkWidget *widget, +view_response_cb (ItipView *view, ItipViewResponse response, gpointer data) { - struct _itip_puri *pitip = data; + ItipPURI *pitip = data; gboolean status = FALSE; icalproperty *prop; ECalComponentTransparency trans; + if (response == ITIP_VIEW_RESPONSE_SAVE) { + save_vcalendar_cb (pitip); + return; + } + pitip->can_delete_invitation_from_cache = FALSE; if (pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST) { - if (itip_view_get_free_time_check_state (ITIP_VIEW (pitip->view))) + if (itip_view_get_free_time_check_state (view)) e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT); else e_cal_component_set_transparency (pitip->comp, E_CAL_COMPONENT_TRANSP_OPAQUE); @@ -2571,7 +2636,7 @@ view_response_cb (GtkWidget *widget, /* check if it is a recur instance (no master object) and * add a property */ - if (itip_view_get_recur_check_state (ITIP_VIEW (pitip->view))) { + if (itip_view_get_recur_check_state (view)) { prop = icalproperty_new_x ("All"); icalproperty_set_x_name (prop, "X-GW-RECUR-INSTANCES-MOD-TYPE"); icalcomponent_add_property (pitip->ical_comp, prop); @@ -2587,7 +2652,7 @@ view_response_cb (GtkWidget *widget, if (status) { e_cal_component_rescan (pitip->comp); pitip->can_delete_invitation_from_cache = TRUE; - update_item (pitip, response); + update_item (pitip, view, response); } break; case ITIP_VIEW_RESPONSE_TENTATIVE: @@ -2596,7 +2661,7 @@ view_response_cb (GtkWidget *widget, if (status) { e_cal_component_rescan (pitip->comp); pitip->can_delete_invitation_from_cache = TRUE; - update_item (pitip, response); + update_item (pitip, view, response); } break; case ITIP_VIEW_RESPONSE_DECLINE: @@ -2613,17 +2678,17 @@ view_response_cb (GtkWidget *widget, if (status) { e_cal_component_rescan (pitip->comp); pitip->can_delete_invitation_from_cache = TRUE; - update_item (pitip, response); + update_item (pitip, view, response); } break; case ITIP_VIEW_RESPONSE_UPDATE: - update_attendee_status (pitip); + update_attendee_status (pitip, view); break; case ITIP_VIEW_RESPONSE_CANCEL: - update_item (pitip, response); + update_item (pitip, view, response); break; case ITIP_VIEW_RESPONSE_REFRESH: - send_item (pitip); + send_item (pitip, view); break; case ITIP_VIEW_RESPONSE_OPEN: g_idle_add (idle_open_cb, pitip); @@ -2697,14 +2762,12 @@ in_proper_folder (CamelFolder *folder) return res; } -static gboolean -format_itip_object (EMFormatHTML *efh, - GtkHTMLEmbedded *eb, - EMFormatHTMLPObject *pobject) +static void +init_itip_view (ItipPURI *info, + ItipView *view) { EShell *shell; EShellSettings *shell_settings; - struct _itip_puri *info; ECalComponentText text; ECalComponentOrganizer organizer; ECalComponentDateTime datetime; @@ -2716,189 +2779,190 @@ format_itip_object (EMFormatHTML *efh, gint i; gboolean response_enabled; gboolean have_alarms = FALSE; + EMFormat *emf = info->puri.emf; shell = e_shell_get_default (); shell_settings = e_shell_get_shell_settings (shell); - info = (struct _itip_puri *) em_format_find_puri ((EMFormat *) efh, pobject->classid); + /* Reset current client before initializing view */ + info->current_client = NULL; - /* Accounts */ + /* Accounts */ info->accounts = e_get_account_list (); - /* Source Lists and open ecal clients */ + /* Source Lists and open ecal clients */ for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { if (!e_cal_client_get_sources (&info->source_lists[i], i, NULL)) - /* FIXME More error handling? */ + /* FIXME More error handling? */ info->source_lists[i] = NULL; - /* Initialize the ecal hashes */ + /* Initialize the ecal hashes */ info->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } - /* FIXME Handle multiple VEVENTS with the same UID, ie detached instances */ - if (!extract_itip_data (info, GTK_CONTAINER (eb), &have_alarms)) - return TRUE; - - info->view = itip_view_new (); - gtk_container_add (GTK_CONTAINER (eb), info->view); - gtk_widget_show (info->view); + /* FIXME Handle multiple VEVENTS with the same UID, ie detached instances */ + if (!extract_itip_data (info, view, &have_alarms)) + return; - response_enabled = in_proper_folder (((EMFormat *) efh)->folder); + response_enabled = in_proper_folder (emf->folder); if (!response_enabled) { - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_HIDE_ALL); + itip_view_set_mode (view, ITIP_VIEW_MODE_HIDE_ALL); } else { - itip_view_set_show_inherit_alarm_check (ITIP_VIEW (info->view), have_alarms && (info->method == ICAL_METHOD_PUBLISH || info->method == ICAL_METHOD_REQUEST)); + itip_view_set_show_inherit_alarm_check ( + view, + have_alarms && (info->method == ICAL_METHOD_PUBLISH || info->method == ICAL_METHOD_REQUEST)); switch (info->method) { - case ICAL_METHOD_PUBLISH: - case ICAL_METHOD_REQUEST: - /* - * Treat meeting request (sent by organizer directly) and - * published evend (forwarded by organizer or attendee) alike: - * if the event has an organizer, then it can be replied to and - * we show the "accept/tentative/decline" choice. - * Otherwise only show "accept". - */ - itip_view_set_mode (ITIP_VIEW (info->view), - info->has_organizer ? - ITIP_VIEW_MODE_REQUEST : - ITIP_VIEW_MODE_PUBLISH); - break; - case ICAL_METHOD_REPLY: - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REPLY); - break; - case ICAL_METHOD_ADD: - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_ADD); - break; - case ICAL_METHOD_CANCEL: - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_CANCEL); - break; - case ICAL_METHOD_REFRESH: - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REFRESH); - break; - case ICAL_METHOD_COUNTER: - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_COUNTER); - break; - case ICAL_METHOD_DECLINECOUNTER: - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_DECLINECOUNTER); - break; - case ICAL_METHOD_X : - /* Handle appointment requests from Microsoft Live. This is - * a best-at-hand-now handling. Must be revisited when we have - * better access to the source of such meetings */ - info->method = ICAL_METHOD_REQUEST; - itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REQUEST); - break; - default: - return FALSE; + case ICAL_METHOD_PUBLISH: + case ICAL_METHOD_REQUEST: + /* + * Treat meeting request (sent by organizer directly) and + * published evend (forwarded by organizer or attendee) alike: + * if the event has an organizer, then it can be replied to and + * we show the "accept/tentative/decline" choice. + * Otherwise only show "accept". + */ + itip_view_set_mode (view, + info->has_organizer ? + ITIP_VIEW_MODE_REQUEST : + ITIP_VIEW_MODE_PUBLISH); + break; + case ICAL_METHOD_REPLY: + itip_view_set_mode (view, ITIP_VIEW_MODE_REPLY); + break; + case ICAL_METHOD_ADD: + itip_view_set_mode (view, ITIP_VIEW_MODE_ADD); + break; + case ICAL_METHOD_CANCEL: + itip_view_set_mode (view, ITIP_VIEW_MODE_CANCEL); + break; + case ICAL_METHOD_REFRESH: + itip_view_set_mode (view, ITIP_VIEW_MODE_REFRESH); + break; + case ICAL_METHOD_COUNTER: + itip_view_set_mode (view, ITIP_VIEW_MODE_COUNTER); + break; + case ICAL_METHOD_DECLINECOUNTER: + itip_view_set_mode (view, ITIP_VIEW_MODE_DECLINECOUNTER); + break; + case ICAL_METHOD_X : + /* Handle appointment requests from Microsoft Live. This is + * a best-at-hand-now handling. Must be revisited when we have + * better access to the source of such meetings */ + info->method = ICAL_METHOD_REQUEST; + itip_view_set_mode (view, ITIP_VIEW_MODE_REQUEST); + break; + default: + return; } } - itip_view_set_item_type (ITIP_VIEW (info->view), info->type); + itip_view_set_item_type (view, info->type); if (response_enabled) { switch (info->method) { - case ICAL_METHOD_REQUEST: - /* FIXME What about the name? */ - itip_view_set_delegator (ITIP_VIEW (info->view), info->delegator_name ? info->delegator_name : info->delegator_address); - case ICAL_METHOD_PUBLISH: - case ICAL_METHOD_ADD: - case ICAL_METHOD_CANCEL: - case ICAL_METHOD_DECLINECOUNTER: - itip_view_set_show_update (ITIP_VIEW (info->view), FALSE); - - /* An organizer sent this */ - e_cal_component_get_organizer (info->comp, &organizer); - org = organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value); - - itip_view_set_organizer (ITIP_VIEW (info->view), org); - if (organizer.sentby) - itip_view_set_organizer_sentby (ITIP_VIEW (info->view), itip_strip_mailto (organizer.sentby)); - - if (info->my_address) { - if (!(organizer.value && !g_ascii_strcasecmp (itip_strip_mailto (organizer.value), info->my_address)) - && !(organizer.sentby && !g_ascii_strcasecmp (itip_strip_mailto (organizer.sentby), info->my_address)) - && (info->to_address && g_ascii_strcasecmp (info->to_address, info->my_address))) - itip_view_set_proxy (ITIP_VIEW (info->view), info->to_name ? info->to_name : info->to_address); - } - break; - case ICAL_METHOD_REPLY: - case ICAL_METHOD_REFRESH: - case ICAL_METHOD_COUNTER: - itip_view_set_show_update (ITIP_VIEW (info->view), TRUE); + case ICAL_METHOD_REQUEST: + /* FIXME What about the name? */ + itip_view_set_delegator (view, info->delegator_name ? info->delegator_name : info->delegator_address); + case ICAL_METHOD_PUBLISH: + case ICAL_METHOD_ADD: + case ICAL_METHOD_CANCEL: + case ICAL_METHOD_DECLINECOUNTER: + itip_view_set_show_update_check (view, FALSE); + + /* An organizer sent this */ + e_cal_component_get_organizer (info->comp, &organizer); + org = organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value); + + itip_view_set_organizer (view, org); + if (organizer.sentby) + itip_view_set_organizer_sentby ( + view, itip_strip_mailto (organizer.sentby)); + + if (info->my_address) { + if (!(organizer.value && !g_ascii_strcasecmp (itip_strip_mailto (organizer.value), info->my_address)) + && !(organizer.sentby && !g_ascii_strcasecmp (itip_strip_mailto (organizer.sentby), info->my_address)) + && (info->to_address && g_ascii_strcasecmp (info->to_address, info->my_address))) + itip_view_set_proxy (view, info->to_name ? info->to_name : info->to_address); + } + break; + case ICAL_METHOD_REPLY: + case ICAL_METHOD_REFRESH: + case ICAL_METHOD_COUNTER: + itip_view_set_show_update_check (view, TRUE); - /* An attendee sent this */ - e_cal_component_get_attendee_list (info->comp, &list); - if (list != NULL) { - ECalComponentAttendee *attendee; + /* An attendee sent this */ + e_cal_component_get_attendee_list (info->comp, &list); + if (list != NULL) { + ECalComponentAttendee *attendee; - attendee = list->data; + attendee = list->data; - itip_view_set_attendee (ITIP_VIEW (info->view), attendee->cn ? attendee->cn : itip_strip_mailto (attendee->value)); + itip_view_set_attendee (view, attendee->cn ? attendee->cn : itip_strip_mailto (attendee->value)); - if (attendee->sentby) - itip_view_set_attendee_sentby (ITIP_VIEW (info->view), itip_strip_mailto (attendee->sentby)); + if (attendee->sentby) + itip_view_set_attendee_sentby (view, itip_strip_mailto (attendee->sentby)); - if (info->my_address) { - if (!(attendee->value && !g_ascii_strcasecmp (itip_strip_mailto (attendee->value), info->my_address)) - && !(attendee->sentby && !g_ascii_strcasecmp (itip_strip_mailto (attendee->sentby), info->my_address)) - && (info->from_address && g_ascii_strcasecmp (info->from_address, info->my_address))) - itip_view_set_proxy (ITIP_VIEW (info->view), info->from_name ? info->from_name : info->from_address); - } + if (info->my_address) { + if (!(attendee->value && !g_ascii_strcasecmp (itip_strip_mailto (attendee->value), info->my_address)) + && !(attendee->sentby && !g_ascii_strcasecmp (itip_strip_mailto (attendee->sentby), info->my_address)) + && (info->from_address && g_ascii_strcasecmp (info->from_address, info->my_address))) + itip_view_set_proxy (view, info->from_name ? info->from_name : info->from_address); + } - e_cal_component_free_attendee_list (list); - } - break; - default: - g_assert_not_reached (); - break; + e_cal_component_free_attendee_list (list); + } + break; + default: + g_assert_not_reached (); + break; } } e_cal_component_get_summary (info->comp, &text); - itip_view_set_summary (ITIP_VIEW (info->view), text.value ? text.value : C_("cal-itip", "None")); + itip_view_set_summary (view, text.value ? text.value : C_("cal-itip", "None")); e_cal_component_get_location (info->comp, &string); - itip_view_set_location (ITIP_VIEW (info->view), string); + itip_view_set_location (view, string); - /* Status really only applies for REPLY */ + /* Status really only applies for REPLY */ if (response_enabled && info->method == ICAL_METHOD_REPLY) { e_cal_component_get_attendee_list (info->comp, &list); if (list != NULL) { ECalComponentAttendee *a = list->data; switch (a->status) { - case ICAL_PARTSTAT_ACCEPTED: - itip_view_set_status (ITIP_VIEW (info->view), _("Accepted")); - break; - case ICAL_PARTSTAT_TENTATIVE: - itip_view_set_status (ITIP_VIEW (info->view), _("Tentatively Accepted")); - break; - case ICAL_PARTSTAT_DECLINED: - itip_view_set_status (ITIP_VIEW (info->view), _("Declined")); - break; - case ICAL_PARTSTAT_DELEGATED: - itip_view_set_status (ITIP_VIEW (info->view), _("Delegated")); - break; - default: - itip_view_set_status (ITIP_VIEW (info->view), _("Unknown")); + case ICAL_PARTSTAT_ACCEPTED: + itip_view_set_status (view, _("Accepted")); + break; + case ICAL_PARTSTAT_TENTATIVE: + itip_view_set_status (view, _("Tentatively Accepted")); + break; + case ICAL_PARTSTAT_DECLINED: + itip_view_set_status (view, _("Declined")); + break; + case ICAL_PARTSTAT_DELEGATED: + itip_view_set_status (view, _("Delegated")); + break; + default: + itip_view_set_status (view, _("Unknown")); } } e_cal_component_free_attendee_list (list); } if (info->method == ICAL_METHOD_REPLY - || info->method == ICAL_METHOD_COUNTER - || info->method == ICAL_METHOD_DECLINECOUNTER) { - /* FIXME Check spec to see if multiple comments are actually valid */ - /* Comments for iTIP are limited to one per object */ + || info->method == ICAL_METHOD_COUNTER + || info->method == ICAL_METHOD_DECLINECOUNTER) { + /* FIXME Check spec to see if multiple comments are actually valid */ + /* Comments for iTIP are limited to one per object */ e_cal_component_get_comment_list (info->comp, &list); if (list) { ECalComponentText *text = list->data; if (text->value) - itip_view_set_comment (ITIP_VIEW (info->view), text->value); + itip_view_set_comment (view, text->value); } e_cal_component_free_text_list (list); } @@ -2910,24 +2974,25 @@ format_itip_object (EMFormatHTML *efh, if (!gstring && text->value) gstring = g_string_new (text->value); else if (text->value) - g_string_append_printf (gstring, "\n\n%s", text->value); + g_string_append_printf (gstring, "\n\n%s", text->value); } + e_cal_component_free_text_list (list); if (gstring) { - itip_view_set_description (ITIP_VIEW (info->view), gstring->str); + itip_view_set_description (view, gstring->str); g_string_free (gstring, TRUE); } - to_zone = e_shell_settings_get_pointer (shell_settings, "cal-timezone"); + to_zone = e_shell_settings_get_pointer (shell_settings, "cal-timezone"); e_cal_component_get_dtstart (info->comp, &datetime); info->start_time = 0; if (datetime.value) { struct tm start_tm; - /* If the timezone is not in the component, guess the local time */ - /* Should we guess if the timezone is an olsen name somehow? */ + /* If the timezone is not in the component, guess the local time */ + /* Should we guess if the timezone is an olsen name somehow? */ if (datetime.value->is_utc) from_zone = icaltimezone_get_utc_timezone (); else if (!datetime.value->is_utc && datetime.tzid) @@ -2937,13 +3002,13 @@ format_itip_object (EMFormatHTML *efh, start_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone); - itip_view_set_start (ITIP_VIEW (info->view), &start_tm, datetime.value->is_date); + itip_view_set_start (view, &start_tm, datetime.value->is_date); info->start_time = icaltime_as_timet_with_zone (*datetime.value, from_zone); } icalcomp = e_cal_component_get_icalcomponent (info->comp); - /* Set the recurrence id */ + /* Set the recurrence id */ if (check_is_instance (icalcomp) && datetime.value) { ECalComponentRange *recur_id; struct icaltimetype icaltime = icaltime_convert_to_zone (*datetime.value, to_zone); @@ -2962,8 +3027,8 @@ format_itip_object (EMFormatHTML *efh, if (datetime.value) { struct tm end_tm; - /* If the timezone is not in the component, guess the local time */ - /* Should we guess if the timezone is an olsen name somehow? */ + /* If the timezone is not in the component, guess the local time */ + /* Should we guess if the timezone is an olsen name somehow? */ if (datetime.value->is_utc) from_zone = icaltimezone_get_utc_timezone (); else if (!datetime.value->is_utc && datetime.tzid) @@ -2972,61 +3037,59 @@ format_itip_object (EMFormatHTML *efh, from_zone = NULL; if (datetime.value->is_date) { - /* RFC says the DTEND is not inclusive, thus subtract one day - * if we have a date */ + /* RFC says the DTEND is not inclusive, thus subtract one day + * if we have a date */ icaltime_adjust (datetime.value, -1, 0, 0, 0); } end_tm = icaltimetype_to_tm_with_zone (datetime.value, from_zone, to_zone); - itip_view_set_end (ITIP_VIEW (info->view), &end_tm, datetime.value->is_date); + itip_view_set_end (view, &end_tm, datetime.value->is_date); info->end_time = icaltime_as_timet_with_zone (*datetime.value, from_zone); } e_cal_component_free_datetime (&datetime); - /* Recurrence info */ - /* FIXME Better recurring description */ + /* Recurrence info */ + /* FIXME Better recurring description */ if (e_cal_component_has_recurrences (info->comp)) { - /* FIXME Tell the user we don't support recurring tasks */ + /* FIXME Tell the user we don't support recurring tasks */ switch (info->type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - itip_view_add_upper_info_item (ITIP_VIEW (info->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This meeting recurs")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - itip_view_add_upper_info_item (ITIP_VIEW (info->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This task recurs")); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - itip_view_add_upper_info_item (ITIP_VIEW (info->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This memo recurs")); - break; - default: - g_assert_not_reached (); - break; + case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: + itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This meeting recurs")); + break; + case E_CAL_CLIENT_SOURCE_TYPE_TASKS: + itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This task recurs")); + break; + case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: + itip_view_add_upper_info_item (view, ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("This memo recurs")); + break; + default: + g_assert_not_reached (); + break; } } if (response_enabled) { g_signal_connect ( - info->view, "response", + view, "response", G_CALLBACK (view_response_cb), info); - itip_view_set_show_free_time_check (ITIP_VIEW (info->view), info->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS && (info->method == ICAL_METHOD_PUBLISH || info->method == ICAL_METHOD_REQUEST)); + itip_view_set_show_free_time_check (view, info->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS && (info->method == ICAL_METHOD_PUBLISH || info->method == ICAL_METHOD_REQUEST)); if (info->calendar_uid) { - start_calendar_server_by_uid (info, info->calendar_uid, info->type); + start_calendar_server_by_uid (info, view, info->calendar_uid, info->type); } else { - find_server (info, info->comp); - set_buttons_sensitive (info); + find_server (info, view, info->comp); + set_buttons_sensitive (info, view); } } - - return TRUE; } static void puri_free (EMFormatPURI *puri) { - struct _itip_puri *pitip = (struct _itip_puri *) puri; + ItipPURI *pitip = (ItipPURI *) puri; gint i; g_cancellable_cancel (pitip->cancellable); @@ -3081,40 +3144,125 @@ puri_free (EMFormatPURI *puri) g_hash_table_destroy (pitip->real_comps); } +static void +write_itip_view (EMFormat *emf, + EMFormatPURI *puri, + CamelStream *stream, + EMFormatWriterInfo *info, + GCancellable *cancellable) +{ + GString *buffer; + + if (info->mode == EM_FORMAT_WRITE_MODE_PRINTING) { + ItipView *view; + ItipPURI *ipuri; + + buffer = g_string_sized_new (1024); + + ipuri = (ItipPURI *) puri; + view = itip_view_new (ipuri); + + init_itip_view (ipuri, view); + itip_view_write_for_printing (view, buffer); + + /* Destroy the view when the formatter is destroyed */ + g_object_weak_ref (G_OBJECT (emf), (GWeakNotify) g_object_unref, view); + + } else if (info->mode == EM_FORMAT_WRITE_MODE_RAW) { + buffer = g_string_sized_new (2048); + + itip_view_write (buffer); + + } else { + gchar *uri; + + uri = em_format_build_mail_uri ( + emf->folder, emf->message_uid, + "part_id", G_TYPE_STRING, puri->uri, + "mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, + NULL); + + buffer = g_string_sized_new (256); + g_string_append_printf (buffer, + "<div class=\"part-container\" " + "style=\"border: none; background: none;\">" + "<iframe width=\"100%%\" height=\"auto\"" + " frameborder=\"0\" src=\"%s\" name=\"%s\" id=\"%s\"></iframe>" + "</div>", + uri, puri->uri, puri->uri); + + g_free (uri); + } + + camel_stream_write_string (stream, buffer->str, cancellable, NULL); + + g_string_free (buffer, TRUE); +} + +static void +bind_itip_view (WebKitDOMElement *element, + EMFormatPURI *puri) +{ + if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) { + GString *buffer = g_string_new (""); + WebKitDOMDocument *document; + ItipView *view; + + document = webkit_dom_html_iframe_element_get_content_document ( + WEBKIT_DOM_HTML_IFRAME_ELEMENT (element)); + + view = itip_view_new ((ItipPURI *) puri); + g_object_set_data_full (G_OBJECT (element), "view", view, + (GDestroyNotify) g_object_unref); + + itip_view_create_dom_bindings (view, + webkit_dom_document_get_document_element (document)); + + init_itip_view ((ItipPURI *) puri, view); + g_string_free (buffer, TRUE); + } +} + void format_itip (EPlugin *ep, EMFormatHookTarget *target) { GSettings *settings; - gchar *classid; - struct _itip_puri *puri; + ItipPURI *puri; CamelDataWrapper *content; CamelStream *stream; GByteArray *byte_array; - gchar *string; + gint len; - classid = g_strdup_printf("itip:///%s", ((EMFormat *) target->format)->part_id->str); + len = target->part_id->len; + g_string_append_printf (target->part_id, ".itip"); /* mark message as containing calendar, thus it will show the icon in message list now on */ - if (target->format->uid && target->format->folder && - !camel_folder_get_message_user_flag (target->format->folder, target->format->uid, "$has_cal")) - camel_folder_set_message_user_flag (target->format->folder, target->format->uid, "$has_cal", TRUE); - - puri = (struct _itip_puri *) em_format_add_puri (target->format, sizeof (struct _itip_puri), classid, target->part, itip_attachment_frame); - - em_format_html_add_pobject ((EMFormatHTML *) target->format, sizeof (EMFormatHTMLPObject), classid, target->part, format_itip_object); + if (target->format->message_uid && target->format->folder && + !camel_folder_get_message_user_flag (target->format->folder, target->format->message_uid, "$has_cal")) + camel_folder_set_message_user_flag (target->format->folder, target->format->message_uid, "$has_cal", TRUE); settings = g_settings_new ("org.gnome.evolution.plugin.itip"); + + puri = (ItipPURI *) em_format_puri_new ( + target->format, sizeof (ItipPURI), + target->part, target->part_id->str); + puri->puri.write_func = write_itip_view; + puri->puri.bind_func = bind_itip_view; + puri->puri.free = puri_free; + puri->puri.is_attachment = target->info->is_attachment; + puri->puri.mime_type = g_strdup ("text/html"); puri->delete_message = g_settings_get_boolean (settings, CONF_KEY_DELETE); puri->has_organizer = FALSE; puri->no_reply_wanted = FALSE; puri->folder = ((EMFormat *) target->format)->folder; - puri->uid = g_strdup (((EMFormat *) target->format)->uid); + puri->uid = g_strdup (((EMFormat *) target->format)->message_uid); puri->msg = ((EMFormat *) target->format)->message; puri->part = target->part; puri->cancellable = g_cancellable_new (); puri->real_comps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - puri->puri.free = puri_free; + + em_format_add_puri (target->format, (EMFormatPURI *) puri); g_object_unref (settings); @@ -3132,16 +3280,7 @@ format_itip (EPlugin *ep, (gchar *) byte_array->data, byte_array->len); g_object_unref (stream); - - string = g_strdup_printf ( - "<table border=0 width=\"100%%\" cellpadding=3><tr>" - "<td valign=top><object classid=\"%s\"></object></td>" - "<td width=100%% valign=top></td></tr></table>", - classid); - camel_stream_write_string (target->stream, string, NULL, NULL); - g_free (string); - - g_free (classid); + g_string_truncate (target->part_id, len); } static void @@ -3315,19 +3454,3 @@ itip_formatter_page_factory (EPlugin *ep, return page; } - -static void -itip_attachment_frame (EMFormat *emf, - CamelStream *stream, - EMFormatPURI *puri, - GCancellable *cancellable) -{ - struct _itip_puri *info = (struct _itip_puri *) puri; - - info->handle->handler ( - emf, stream, info->puri.part, - info->handle, cancellable, FALSE); - - camel_stream_close (stream, cancellable, NULL); -} - diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c index 273238490b..53bba25100 100644 --- a/plugins/itip-formatter/itip-view.c +++ b/plugins/itip-formatter/itip-view.c @@ -31,22 +31,25 @@ #include <libedataserverui/e-source-combo-box.h> #include <libecal/e-cal-client.h> #include <libecal/e-cal-time-util.h> -#include <gtkhtml/gtkhtml-embedded.h> #include <mail/em-format-hook.h> #include <mail/em-format-html.h> #include <libedataserver/e-account-list.h> #include <e-util/e-util.h> #include <e-util/e-unicode.h> #include <calendar/gui/itip-utils.h> +#include <webkit/webkitdom.h> + #include "itip-view.h" +#define d(x) + #define MEETING_ICON "stock_new-meeting" #define ITIP_VIEW_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), ITIP_TYPE_VIEW, ItipViewPrivate)) -G_DEFINE_TYPE (ItipView, itip_view, GTK_TYPE_HBOX) +G_DEFINE_TYPE (ItipView, itip_view, G_TYPE_OBJECT) typedef struct { ItipViewInfoItemType type; @@ -59,7 +62,7 @@ struct _ItipViewPrivate { ItipViewMode mode; ECalClientSourceType type; - GtkWidget *sender_label; + gchar *sender; gchar *organizer; gchar *organizer_sentby; gchar *delegator; @@ -67,71 +70,85 @@ struct _ItipViewPrivate { gchar *attendee_sentby; gchar *proxy; - GtkWidget *summary_label; gchar *summary; - GtkWidget *location_header; - GtkWidget *location_label; gchar *location; - - GtkWidget *status_header; - GtkWidget *status_label; - gchar *status; - - GtkWidget *comment_header; - GtkWidget *comment_label; + gchar *status; gchar *comment; - GtkWidget *start_header; - GtkWidget *start_label; struct tm *start_tm; - gboolean start_tm_is_date; + gint start_tm_is_date : 1; + gchar *start_label; + const gchar *start_header; - GtkWidget *end_header; - GtkWidget *end_label; struct tm *end_tm; - gboolean end_tm_is_date; + gint end_tm_is_date : 1; + gchar *end_label; + const gchar *end_header; - GtkWidget *upper_info_box; GSList *upper_info_items; - - GtkWidget *lower_info_box; GSList *lower_info_items; guint next_info_item_id; - GtkWidget *description_label; gchar *description; - GtkWidget *selector_box; - GtkWidget *escb; - GtkWidget *escb_header; ESourceList *source_list; - GtkWidget *rsvp_box; - GtkWidget *rsvp_check; - GtkWidget *rsvp_comment_header; - GtkWidget *rsvp_comment_text; - gboolean rsvp_show; + gint buttons_sensitive : 1; - GtkWidget *recur_box; - GtkWidget *recur_check; + gboolean is_recur_set; - GtkWidget *update_box; - GtkWidget *update_check; - gboolean update_show; + gint needs_decline : 1; - GtkWidget *options_box; - GtkWidget *free_time_check; - GtkWidget *keep_alarm_check; - GtkWidget *inherit_alarm_check; + WebKitDOMDocument *dom_document; + ItipPURI *puri; - GtkWidget *button_box; - gboolean buttons_sensitive; - - gboolean needs_decline; + gchar *error; }; +#define TEXT_ROW_SENDER "text_row_sender" +#define TABLE_ROW_SUMMARY "table_row_summary" +#define TABLE_ROW_LOCATION "table_row_location" +#define TABLE_ROW_START_DATE "table_row_start_time" +#define TABLE_ROW_END_DATE "table_row_end_time" +#define TABLE_ROW_STATUS "table_row_status" +#define TABLE_ROW_COMMENT "table_row_comment" +#define TABLE_ROW_DESCRIPTION "table_row_description" +#define TABLE_ROW_RSVP_COMMENT "table_row_rsvp_comment" +#define TABLE_ROW_ESCB "table_row_escb" +#define TABLE_ROW_BUTTONS "table_row_buttons" + +#define TABLE_BUTTONS "table_buttons" + +#define SELECT_ESOURCE "select_esource" +#define TEXTAREA_RSVP_COMMENT "textarea_rsvp_comment" + +#define CHECKBOX_RSVP "checkbox_rsvp" +#define CHECKBOX_RECUR "checkbox_recur" +#define CHECKBOX_UPDATE "checkbox_update" +#define CHECKBOX_FREE_TIME "checkbox_free_time" +#define CHECKBOX_KEEP_ALARM "checkbox_keep_alarm" +#define CHECKBOX_INHERIT_ALARM "checkbox_inherit_alarm" + +#define BUTTON_OPEN_CALENDAR "button_open_calendar" +#define BUTTON_DECLINE "button_decline" +#define BUTTON_DECLINE_ALL "button_decline_all" +#define BUTTON_ACCEPT "button_accept" +#define BUTTON_ACCEPT_ALL "button_accept_all" +#define BUTTON_TENTATIVE "button_tentative" +#define BUTTON_TENTATIVE_ALL "button_tentative_all" +#define BUTTON_SEND_INFORMATION "button_send_information" +#define BUTTON_UPDATE "button_update" +#define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status" +#define BUTTON_SAVE "button_save" + +#define TABLE_UPPER_ITIP_INFO "table_upper_itip_info" +#define TABLE_LOWER_ITIP_INFO "table_lower_itip_info" + +#define DIV_ITIP_CONTENT "div_itip_content" +#define DIV_ITIP_ERROR "div_itip_error" + /* Signal IDs */ enum { SOURCE_SELECTED, @@ -354,7 +371,7 @@ dupe_first_bold (const gchar *format, return res; } -static void +static gchar * set_calendar_sender_text (ItipView *view) { ItipViewPrivate *priv; @@ -435,14 +452,12 @@ set_calendar_sender_text (ItipView *view) if (sender && on_behalf_of) sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL); - gtk_label_set_text (GTK_LABEL (priv->sender_label), sender); - gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE); - g_free (on_behalf_of); - g_free (sender); + + return sender; } -static void +static gchar * set_tasklist_sender_text (ItipView *view) { ItipViewPrivate *priv; @@ -523,14 +538,12 @@ set_tasklist_sender_text (ItipView *view) if (sender && on_behalf_of) sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL); - gtk_label_set_text (GTK_LABEL (priv->sender_label), sender); - gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE); - g_free (on_behalf_of); - g_free (sender); + + return sender; } -static void +static gchar * set_journal_sender_text (ItipView *view) { ItipViewPrivate *priv; @@ -575,106 +588,47 @@ set_journal_sender_text (ItipView *view) if (sender && on_behalf_of) sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL); - gtk_label_set_text (GTK_LABEL (priv->sender_label), sender); - gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE); - g_free (on_behalf_of); - g_free (sender); + + return sender; } static void set_sender_text (ItipView *view) { ItipViewPrivate *priv; - priv = view->priv; switch (priv->type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - set_calendar_sender_text (view); + priv->sender = set_calendar_sender_text (view); break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - set_tasklist_sender_text (view); + priv->sender = set_tasklist_sender_text (view); break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - set_journal_sender_text (view); + priv->sender = set_journal_sender_text (view); break; default: + priv->sender = NULL; break; } -} - -static void -set_summary_text (ItipView *view) -{ - ItipViewPrivate *priv; - gchar *summary = NULL; - - priv = view->priv; - - summary = g_markup_printf_escaped ("<b>%s</b>", priv->summary); - - gtk_label_set_text (GTK_LABEL (priv->summary_label), summary); - gtk_label_set_use_markup (GTK_LABEL (priv->summary_label), TRUE); - - g_free (summary); -} - -static void -set_location_text (ItipView *view) -{ - ItipViewPrivate *priv; - - priv = view->priv; - - gtk_label_set_text (GTK_LABEL (priv->location_label), priv->location); - - priv->location ? gtk_widget_show (priv->location_header) : gtk_widget_hide (priv->location_header); - priv->location ? gtk_widget_show (priv->location_label) : gtk_widget_hide (priv->location_label); -} -static void -set_status_text (ItipView *view) -{ - ItipViewPrivate *priv; - - priv = view->priv; - - gtk_label_set_text (GTK_LABEL (priv->status_label), priv->status); - - priv->status ? gtk_widget_show (priv->status_header) : gtk_widget_hide (priv->status_header); - priv->status ? gtk_widget_show (priv->status_label) : gtk_widget_hide (priv->status_label); -} - -static void -set_comment_text (ItipView *view) -{ - ItipViewPrivate *priv; - - priv = view->priv; - - gtk_label_set_text (GTK_LABEL (priv->comment_label), priv->comment); - - priv->comment ? gtk_widget_show (priv->comment_header) : gtk_widget_hide (priv->comment_header); - priv->comment ? gtk_widget_show (priv->comment_label) : gtk_widget_hide (priv->comment_label); -} - -static void -set_description_text (ItipView *view) -{ - ItipViewPrivate *priv; - - priv = view->priv; + if (priv->sender && priv->dom_document) { + WebKitDOMElement *div; - gtk_label_set_text (GTK_LABEL (priv->description_label), priv->description); - - priv->description ? gtk_widget_show (priv->description_label) : gtk_widget_hide (priv->description_label); + div = webkit_dom_document_get_element_by_id ( + priv->dom_document, TEXT_ROW_SENDER); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (div), priv->sender, NULL); + } } static void update_start_end_times (ItipView *view) { ItipViewPrivate *priv; + WebKitDOMElement *row, *col; gchar buffer[256]; time_t now; struct tm *now_tm; @@ -684,240 +638,211 @@ update_start_end_times (ItipView *view) now = time (NULL); now_tm = localtime (&now); + if (priv->start_label) + g_free (priv->start_label); + if (priv->end_label) + g_free (priv->end_label); + #define is_same(_member) (priv->start_tm->_member == priv->end_tm->_member) if (priv->start_tm && priv->end_tm && priv->start_tm_is_date && priv->end_tm_is_date && is_same (tm_mday) && is_same (tm_mon) && is_same (tm_year)) { /* it's an all day event in one particular day */ format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256); - gtk_label_set_text (GTK_LABEL (priv->start_label), buffer); - gtk_label_set_text (GTK_LABEL (priv->start_header), _("All day:")); - - gtk_widget_show (priv->start_header); - gtk_widget_show (priv->start_label); - gtk_widget_hide (priv->end_header); - gtk_widget_hide (priv->end_label); + priv->start_label = g_strdup (buffer); + priv->start_header = _("All day:"); + priv->end_header = NULL; + priv->end_label = NULL; } else { if (priv->start_tm) { format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256); - gtk_label_set_text (GTK_LABEL (priv->start_label), buffer); - gtk_label_set_text (GTK_LABEL (priv->start_header), priv->start_tm_is_date ? _("Start day:") : _("Start time:")); - gtk_widget_show (priv->start_header); - gtk_widget_show (priv->start_label); + priv->start_header = priv->start_tm_is_date ? _("Start day:") : _("Start time:"); + priv->start_label = g_strdup (buffer); } else { - gtk_label_set_text (GTK_LABEL (priv->start_label), NULL); - gtk_widget_hide (priv->start_header); - gtk_widget_hide (priv->start_label); + priv->start_header = NULL; + priv->start_label = NULL; } if (priv->end_tm) { format_date_and_time_x (priv->end_tm, now_tm, FALSE, TRUE, FALSE, priv->end_tm_is_date, buffer, 256); - gtk_label_set_text (GTK_LABEL (priv->end_label), buffer); - gtk_label_set_text (GTK_LABEL (priv->end_header), priv->end_tm_is_date ? _("End day:") : _("End time:")); - gtk_widget_show (priv->end_header); - gtk_widget_show (priv->end_label); + priv->end_header = priv->end_tm_is_date ? _("End day:") : _("End time:"); + priv->end_label = g_strdup (buffer); } else { - gtk_label_set_text (GTK_LABEL (priv->end_label), NULL); - gtk_widget_hide (priv->end_header); - gtk_widget_hide (priv->end_label); + priv->end_header = NULL; + priv->end_label = NULL; } } - #undef is_same -} - -static void -set_info_items (GtkWidget *info_box, - GSList *info_items) -{ - GSList *l; - gtk_container_foreach (GTK_CONTAINER (info_box), (GtkCallback) gtk_widget_destroy, NULL); - - for (l = info_items; l; l = l->next) { - ItipViewInfoItem *item = l->data; - GtkWidget *hbox, *image, *label; + if (priv->dom_document) { + row = webkit_dom_document_get_element_by_id ( + priv->dom_document, TABLE_ROW_START_DATE); + if (priv->start_header && priv->start_label) { + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), FALSE); - hbox = gtk_hbox_new (FALSE, 0); + col = webkit_dom_element_get_first_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), priv->start_header, NULL); - switch (item->type) { - case ITIP_VIEW_INFO_ITEM_TYPE_INFO: - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_SMALL_TOOLBAR); - break; - case ITIP_VIEW_INFO_ITEM_TYPE_WARNING: - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR); - break; - case ITIP_VIEW_INFO_ITEM_TYPE_ERROR: - image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_SMALL_TOOLBAR); - break; - case ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS: - image = gtk_spinner_new (); - gtk_spinner_start (GTK_SPINNER (image)); - break; - case ITIP_VIEW_INFO_ITEM_TYPE_NONE: - default: - image = NULL; + col = webkit_dom_element_get_last_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), priv->start_label, NULL); + } else { + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), TRUE); } - if (image) { - gtk_widget_show (image); - gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 6); - } + row = webkit_dom_document_get_element_by_id ( + priv->dom_document, TABLE_ROW_END_DATE); + if (priv->end_header && priv->end_label) { + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), FALSE); - label = gtk_label_new (item->message); - gtk_label_set_selectable (GTK_LABEL (label), TRUE); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6); + col = webkit_dom_element_get_first_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), priv->end_header, NULL); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (info_box), hbox, FALSE, FALSE, 6); + col = webkit_dom_element_get_last_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), priv->end_label, NULL); + } else { + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), TRUE); + } } } static void -set_upper_info_items (ItipView *view) +button_clicked_cb (WebKitDOMElement *element, + WebKitDOMEvent *event, + gpointer data) { - ItipViewPrivate *priv; + ItipViewResponse response; + gchar *responseStr; - priv = view->priv; + responseStr = webkit_dom_html_button_element_get_value ( + WEBKIT_DOM_HTML_BUTTON_ELEMENT (element)); - set_info_items (priv->upper_info_box, priv->upper_info_items); + response = atoi (responseStr); + + //d(printf("Clicked btton %d\n", response)); + g_signal_emit (G_OBJECT (data), signals[RESPONSE], 0, response); } static void -set_lower_info_items (ItipView *view) +itip_view_finalize (GObject *object) { ItipViewPrivate *priv; + GSList *iter; - priv = view->priv; + priv = ITIP_VIEW_GET_PRIVATE (object); - set_info_items (priv->lower_info_box, priv->lower_info_items); -} + d(printf("Itip view finalized!\n")); -#define DATA_RESPONSE_KEY "ItipView::button_response" + if (priv->sender) { + g_free (priv->sender); + priv->sender = NULL; + } -static void -button_clicked_cb (GtkWidget *widget, - gpointer data) -{ - ItipViewResponse response; + if (priv->organizer) { + g_free (priv->organizer); + priv->organizer = NULL; + } - response = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), DATA_RESPONSE_KEY)); + if (priv->organizer_sentby) { + g_free (priv->organizer_sentby); + priv->organizer_sentby = NULL; + } - g_signal_emit (G_OBJECT (data), signals[RESPONSE], 0, response); -} + if (priv->delegator) { + g_free (priv->delegator); + priv->delegator = NULL; + } -static void -set_one_button (ItipView *view, - const gchar *label, - const gchar *stock_id, - ItipViewResponse response) -{ - ItipViewPrivate *priv; - GtkWidget *button; - GtkWidget *image; - gpointer data; + if (priv->attendee) { + g_free (priv->attendee); + priv->attendee = NULL; + } - priv = view->priv; + if (priv->attendee_sentby) { + g_free (priv->attendee_sentby); + priv->attendee_sentby = NULL; + } - button = gtk_button_new_with_mnemonic (label); - image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON); - gtk_button_set_image (GTK_BUTTON (button), image); + if (priv->proxy) { + g_free (priv->proxy); + priv->proxy = NULL; + } - data = GINT_TO_POINTER (response); - g_object_set_data (G_OBJECT (button), DATA_RESPONSE_KEY, data); + if (priv->summary) { + g_free (priv->summary); + priv->summary = NULL; + } - gtk_widget_show (button); - gtk_container_add (GTK_CONTAINER (priv->button_box), button); + if (priv->location) { + g_free (priv->location); + priv->location = NULL; + } - g_signal_connect ( - button, "clicked", G_CALLBACK (button_clicked_cb), view); -} + if (priv->status) { + g_free (priv->status); + priv->status = NULL; + } -static void -set_buttons (ItipView *view) -{ - ItipViewPrivate *priv; - gboolean is_recur_set = FALSE; + if (priv->comment) { + g_free (priv->comment); + priv->comment = NULL; + } - priv = view->priv; + if (priv->start_tm) { + g_free (priv->start_tm); + priv->start_tm = NULL; + } - is_recur_set = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->recur_check)); - gtk_container_foreach (GTK_CONTAINER (priv->button_box), (GtkCallback) gtk_widget_destroy, NULL); + if (priv->start_label) { + g_free (priv->start_label); + priv->start_label = NULL; + } - if (priv->mode == ITIP_VIEW_MODE_HIDE_ALL) - return; + if (priv->end_tm) { + g_free (priv->end_tm); + priv->end_tm = NULL; + } - /* Everything gets the open button */ - set_one_button (view, _("_Open Calendar"), GTK_STOCK_JUMP_TO, ITIP_VIEW_RESPONSE_OPEN); + if (priv->end_label) { + g_free (priv->end_label); + priv->end_label = NULL; + } - switch (priv->mode) { - case ITIP_VIEW_MODE_PUBLISH: - /* FIXME Is this really the right button? */ - if (priv->needs_decline) - set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - break; - case ITIP_VIEW_MODE_REQUEST: - set_one_button (view, is_recur_set ? _("_Decline all") : _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - set_one_button (view, is_recur_set ? _("_Tentative all") : _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); - set_one_button (view, is_recur_set ? _("A_ccept all") : _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - break; - case ITIP_VIEW_MODE_ADD: - if (priv->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { - set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - set_one_button (view, _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); - } - set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - break; - case ITIP_VIEW_MODE_REFRESH: - /* FIXME Is this really the right button? */ - set_one_button (view, _("_Send Information"), GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_REFRESH); - break; - case ITIP_VIEW_MODE_REPLY: - /* FIXME Is this really the right button? */ - set_one_button (view, _("_Update Attendee Status"), GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_UPDATE); - break; - case ITIP_VIEW_MODE_CANCEL: - set_one_button (view, _("_Update"), GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_CANCEL); - break; - case ITIP_VIEW_MODE_COUNTER: - set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - set_one_button (view, _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); - set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - break; - case ITIP_VIEW_MODE_DECLINECOUNTER: - set_one_button (view, _("_Decline"), GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); - set_one_button (view, _("_Tentative"), GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); - set_one_button (view, _("A_ccept"), GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); - break; - default: - break; + if (priv->description) { + g_free (priv->description); + priv->description = NULL; } -} -static void -itip_view_finalize (GObject *object) -{ - ItipViewPrivate *priv; + for (iter = priv->lower_info_items; iter; iter = iter->next) { + ItipViewInfoItem *item = iter->data; + g_free (item->message); + g_free (item); + } + if (priv->lower_info_items) { + g_slist_free (priv->lower_info_items); + priv->lower_info_items = NULL; + } - priv = ITIP_VIEW_GET_PRIVATE (object); + for (iter = priv->upper_info_items; iter; iter = iter->next) { + ItipViewInfoItem *item = iter->data; + g_free (item->message); + g_free (item); + } + if (priv->upper_info_items) { + g_slist_free (priv->upper_info_items); + priv->upper_info_items = NULL; + } - g_free (priv->organizer); - g_free (priv->organizer_sentby); - g_free (priv->delegator); - g_free (priv->attendee); - g_free (priv->attendee_sentby); - g_free (priv->proxy); - g_free (priv->summary); - g_free (priv->location); - g_free (priv->status); - g_free (priv->comment); - g_free (priv->start_tm); - g_free (priv->end_tm); - g_free (priv->description); - - itip_view_clear_upper_info_items (ITIP_VIEW (object)); - itip_view_clear_lower_info_items (ITIP_VIEW (object)); + if (priv->error) { + g_free (priv->error); + priv->error = NULL; + } /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (itip_view_parent_class)->finalize (object); @@ -953,31 +878,31 @@ itip_view_class_init (ItipViewClass *class) } static void -rsvp_toggled_cb (GtkWidget *widget, +rsvp_toggled_cb (WebKitDOMHTMLInputElement *input, + WebKitDOMEvent *event, gpointer data) { + WebKitDOMElement *el; + ItipView *view = data; - ItipViewPrivate *priv; gboolean rsvp; - priv = view->priv; + rsvp = webkit_dom_html_input_element_get_checked (input); - rsvp = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->rsvp_check)); - - gtk_widget_set_sensitive (priv->rsvp_comment_header, rsvp); - gtk_widget_set_sensitive (priv->rsvp_comment_text, rsvp); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TEXTAREA_RSVP_COMMENT); + webkit_dom_html_text_area_element_set_disabled ( + WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp); } static void -recur_toggled_cb (GtkWidget *widget, +recur_toggled_cb (WebKitDOMHTMLInputElement *input, + WebKitDOMEvent *event, gpointer data) { ItipView *view = data; - ItipViewPrivate *priv; - priv = view->priv; - - itip_view_set_mode (view, priv->mode); + itip_view_set_mode (view, view->priv->mode); } /* @@ -985,290 +910,647 @@ recur_toggled_cb (GtkWidget *widget, check1 was changed, so make the second available based on state of the first check. */ static void -alarm_check_toggled_cb (GtkWidget *check1, - GtkWidget *check2) +alarm_check_toggled_cb (WebKitDOMHTMLInputElement *check1, + WebKitDOMEvent *event, + ItipView *view) { - g_return_if_fail (check1 != NULL); - g_return_if_fail (check2 != NULL); + WebKitDOMElement *check2; + gchar *id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (check1)); + + if (g_strcmp0 (id, CHECKBOX_INHERIT_ALARM)) { + check2 = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_KEEP_ALARM); + } else { + check2 = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_INHERIT_ALARM); + } - gtk_widget_set_sensitive (check2, !(gtk_widget_get_visible (check1) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check1)))); + g_free (id); + + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (check2), + (webkit_dom_html_element_get_hidden ( + WEBKIT_DOM_HTML_ELEMENT (check1)) && + webkit_dom_html_input_element_get_checked (check1))); } static void -itip_view_init (ItipView *view) +source_changed_cb (WebKitDOMElement *select, + WebKitDOMEvent *event, + ItipView *view) { - GtkWidget *icon, *vbox, *hbox, *separator, *table, *label; - GtkWidget *scrolled_window; + ESource *source; - view->priv = ITIP_VIEW_GET_PRIVATE (view); + source = itip_view_get_source (view); + + d(printf("Source changed to '%s'\n", e_source_peek_name (source))); + g_signal_emit (view, signals[SOURCE_SELECTED], 0, source); +} + +static void +append_checkbox_table_row (GString *buffer, + const gchar *name, + const gchar *label) +{ + g_string_append_printf ( + buffer, + "<tr id=\"table_row_%s\" hidden=\"\"><td colspan=\"2\">" + "<input type=\"checkbox\" name=\"%s\" id=\"%s\" value=\"%s\" >" + "<label for=\"%s\">%s</label>" + "</td></tr>\n", + name, name, name, name, name, label); +} + +static void +append_text_table_row (GString *buffer, + const gchar *id, + const gchar *label, + const gchar *value) +{ + if (label && *label) { + + g_string_append_printf (buffer, + "<tr id=\"%s\" %s><th>%s</th><td>%s</td></tr>\n", + id, (value && *value) ? "" : "hidden=\"\"", label, value); + + } else { + + g_string_append_printf ( + buffer, + "<tr id=\"%s\" hidden=\"\"><td colspan=\"2\"></td></tr>\n", + id); + + } +} + +static void +append_info_item_row (ItipView *view, + const gchar *table_id, + ItipViewInfoItem *item) +{ + WebKitDOMElement *table; + WebKitDOMHTMLElement *row, *cell; + const gchar *icon_name; + gchar *id; + + table = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, table_id); + row = webkit_dom_html_table_element_insert_row ( + WEBKIT_DOM_HTML_TABLE_ELEMENT (table), -1, NULL); + + id = g_strdup_printf ("%s_row_%d", table_id, item->id); + webkit_dom_html_element_set_id (row, id); + g_free (id); + + switch (item->type) { + case ITIP_VIEW_INFO_ITEM_TYPE_INFO: + icon_name = GTK_STOCK_DIALOG_INFO; + break; + case ITIP_VIEW_INFO_ITEM_TYPE_WARNING: + icon_name = GTK_STOCK_DIALOG_WARNING; + break; + case ITIP_VIEW_INFO_ITEM_TYPE_ERROR: + icon_name = GTK_STOCK_DIALOG_ERROR; + break; + case ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS: + icon_name = GTK_STOCK_FIND; + break; + case ITIP_VIEW_INFO_ITEM_TYPE_NONE: + default: + icon_name = NULL; + } + + cell = webkit_dom_html_table_row_element_insert_cell ( + (WebKitDOMHTMLTableRowElement *) row, -1, NULL); + + if (icon_name) { + WebKitDOMElement *image; + gchar *icon_uri; - view->priv->mode = ITIP_VIEW_MODE_NONE; - - gtk_box_set_spacing (GTK_BOX (view), 12); - - /* The meeting icon */ - icon = gtk_image_new_from_icon_name ( - MEETING_ICON, GTK_ICON_SIZE_LARGE_TOOLBAR); - gtk_misc_set_alignment (GTK_MISC (icon), 0.5, 0); - gtk_widget_show (icon); - - gtk_box_pack_start (GTK_BOX (view), icon, FALSE, FALSE, 0); - - /* The RHS */ - vbox = gtk_vbox_new (FALSE, 12); - gtk_widget_show (vbox); - gtk_box_pack_start (GTK_BOX (view), vbox, FALSE, FALSE, 0); - - /* The first section listing the sender */ - /* FIXME What to do if the send and organizer do not match */ - view->priv->sender_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->sender_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->sender_label), 0, 0.5); - gtk_widget_show (view->priv->sender_label); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->sender_label, FALSE, FALSE, 0); - - separator = gtk_hseparator_new (); - gtk_widget_show (separator); - gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); - - /* A table with information on the meeting and any extra info/warnings */ - table = gtk_table_new (4, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); - - /* Summary */ - view->priv->summary_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->summary_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->summary_label), 0, 0.5); - gtk_label_set_line_wrap_mode (GTK_LABEL (view->priv->summary_label), PANGO_WRAP_WORD); - gtk_label_set_line_wrap (GTK_LABEL (view->priv->summary_label), TRUE); - gtk_widget_show (view->priv->summary_label); - gtk_table_attach (GTK_TABLE (table), view->priv->summary_label, 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); - - /* Location */ - view->priv->location_header = gtk_label_new (_("Location:")); - view->priv->location_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->location_header), TRUE); - gtk_label_set_selectable (GTK_LABEL (view->priv->location_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->location_header), 0, 0.5); - gtk_misc_set_alignment (GTK_MISC (view->priv->location_label), 0, 0.5); - gtk_table_attach (GTK_TABLE (table), view->priv->location_header, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), view->priv->location_label, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0); - - /* Start time */ - view->priv->start_header = gtk_label_new (_("Start time:")); - view->priv->start_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->start_header), TRUE); - gtk_label_set_selectable (GTK_LABEL (view->priv->start_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->start_header), 0, 0.5); - gtk_misc_set_alignment (GTK_MISC (view->priv->start_label), 0, 0.5); - gtk_widget_show (view->priv->start_header); - gtk_table_attach (GTK_TABLE (table), view->priv->start_header, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), view->priv->start_label, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0); - - /* End time */ - view->priv->end_header = gtk_label_new (_("End time:")); - view->priv->end_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->end_header), TRUE); - gtk_label_set_selectable (GTK_LABEL (view->priv->end_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->end_header), 0, 0.5); - gtk_misc_set_alignment (GTK_MISC (view->priv->end_label), 0, 0.5); - gtk_table_attach (GTK_TABLE (table), view->priv->end_header, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), view->priv->end_label, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 0, 0); - - /* Status */ - view->priv->status_header = gtk_label_new (_("Status:")); - view->priv->status_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->status_header), TRUE); - gtk_label_set_selectable (GTK_LABEL (view->priv->status_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->status_header), 0, 0.5); - gtk_misc_set_alignment (GTK_MISC (view->priv->status_label), 0, 0.5); - gtk_table_attach (GTK_TABLE (table), view->priv->status_header, 0, 1, 4, 5, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), view->priv->status_label, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0); - - /* Comment */ - view->priv->comment_header = gtk_label_new (_("Comment:")); - view->priv->comment_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->comment_header), TRUE); - gtk_label_set_selectable (GTK_LABEL (view->priv->comment_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->comment_header), 0, 0.5); - gtk_misc_set_alignment (GTK_MISC (view->priv->comment_label), 0, 0.5); - gtk_table_attach (GTK_TABLE (table), view->priv->comment_header, 0, 1, 5, 6, GTK_FILL, 0, 0, 0); - gtk_table_attach (GTK_TABLE (table), view->priv->comment_label, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, 0, 0, 0); + image = webkit_dom_document_create_element ( + view->priv->dom_document, "IMG", NULL); + + icon_uri = g_strdup_printf ("gtk-stock://%s", icon_name); + webkit_dom_html_image_element_set_src ( + WEBKIT_DOM_HTML_IMAGE_ELEMENT (image), icon_uri); + g_free (icon_uri); + + webkit_dom_node_append_child ( + WEBKIT_DOM_NODE (cell), + WEBKIT_DOM_NODE (image), + NULL); + } + + cell = webkit_dom_html_table_row_element_insert_cell ( + (WebKitDOMHTMLTableRowElement *) row, -1, NULL); + + webkit_dom_html_element_set_inner_html (cell, item->message, NULL); + + d(printf("Added row %s_row_%d ('%s')\n", table_id, item->id, item->message)); +} + +static void +remove_info_item_row (ItipView *view, + const gchar *table_id, + guint id) +{ + WebKitDOMElement *row; + gchar *row_id; + + row_id = g_strdup_printf ("%s_row_%d", table_id, id); + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, row_id); + g_free (row_id); + + webkit_dom_node_remove_child ( + webkit_dom_node_get_parent_node (WEBKIT_DOM_NODE (row)), + WEBKIT_DOM_NODE (row), + NULL); + + d(printf("Removed row %s_row_%d\n", table_id, id)); +} + +static void +buttons_table_write_button (GString *buffer, + const gchar *name, + const gchar *label, + const gchar *icon, + ItipViewResponse response) +{ + g_string_append_printf ( + buffer, + "<td><button type=\"button\" name=\"%s\" value=\"%d\" id=\"%s\" hidden>" + "<div><img src=\"gtk-stock://%s?size=%d\"> <span>%s</span></div>" + "</button></td>\n", + name, response, name, icon, GTK_ICON_SIZE_BUTTON, label); +} + +static void +append_buttons_table (GString *buffer) +{ + g_string_append (buffer, + "<table class=\"itip buttons\" border=\"0\" " + "id=\"" TABLE_BUTTONS "\" cellspacing=\"6\" " + "cellpadding=\"0\" >" + "<tr id=\"" TABLE_ROW_BUTTONS "\">"); + + /* Everything gets the open button */ + buttons_table_write_button ( + buffer, BUTTON_OPEN_CALENDAR, _("Open Calendar"), + GTK_STOCK_JUMP_TO, ITIP_VIEW_RESPONSE_OPEN); + buttons_table_write_button ( + buffer, BUTTON_DECLINE_ALL, _("Decline all"), + GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); + buttons_table_write_button ( + buffer, BUTTON_DECLINE, _("Decline"), + GTK_STOCK_CANCEL, ITIP_VIEW_RESPONSE_DECLINE); + buttons_table_write_button ( + buffer, BUTTON_TENTATIVE_ALL, _("Tentative all"), + GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); + buttons_table_write_button ( + buffer, BUTTON_TENTATIVE, _("Tentative"), + GTK_STOCK_DIALOG_QUESTION, ITIP_VIEW_RESPONSE_TENTATIVE); + buttons_table_write_button ( + buffer, BUTTON_ACCEPT_ALL, _("Accept all"), + GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); + buttons_table_write_button ( + buffer, BUTTON_ACCEPT, _("Accept"), + GTK_STOCK_APPLY, ITIP_VIEW_RESPONSE_ACCEPT); + buttons_table_write_button ( + buffer, BUTTON_SEND_INFORMATION, _("Send Information"), + GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_REFRESH); + buttons_table_write_button ( + buffer, BUTTON_UPDATE_ATTENDEE_STATUS, _("Update Attendee Status"), + GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_UPDATE); + buttons_table_write_button ( + buffer, BUTTON_UPDATE, _("Update"), + GTK_STOCK_REFRESH, ITIP_VIEW_RESPONSE_CANCEL); + + g_string_append (buffer, "</tr></table>"); +} + +void +itip_view_write (GString *buffer) +{ + g_string_append (buffer, + "<html>\n" + "<head>\n" + "<title>ITIP</title>\n" + "<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\" />\n" + "</head>\n" + "<body>\n"); + + g_string_append_printf (buffer, + "<img src=\"gtk-stock://%s?size=%d\" class=\"itip icon\" />\n", + MEETING_ICON, GTK_ICON_SIZE_BUTTON); + + g_string_append (buffer, + "<div class=\"itip content\" id=\"" DIV_ITIP_CONTENT "\">\n"); + + /* The first section listing the sender */ + /* FIXME What to do if the send and organizer do not match */ + g_string_append (buffer, + "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\"></div>\n"); + + g_string_append (buffer, "<hr>\n"); + + /* Elementary event information */ + g_string_append (buffer, + "<table class=\"itip table\" border=\"0\" " + "cellspacing=\"5\" cellpadding=\"0\">\n"); + + append_text_table_row (buffer, TABLE_ROW_SUMMARY, NULL, NULL); + append_text_table_row (buffer, TABLE_ROW_LOCATION, _("Location:"), NULL); + append_text_table_row (buffer, TABLE_ROW_START_DATE, _("Start time:"), NULL); + append_text_table_row (buffer, TABLE_ROW_END_DATE, _("End time:"), NULL); + append_text_table_row (buffer, TABLE_ROW_STATUS, _("Status:"), NULL); + append_text_table_row (buffer, TABLE_ROW_COMMENT, _("Comment:"), NULL); + + g_string_append (buffer, "</table>\n"); /* Upper Info items */ - view->priv->upper_info_box = gtk_vbox_new (FALSE, 12); - gtk_widget_show (view->priv->upper_info_box); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->upper_info_box, FALSE, FALSE, 0); + g_string_append (buffer, + "<table class=\"itip info\" id=\"" TABLE_UPPER_ITIP_INFO "\" border=\"0\" " + "cellspacing=\"5\" cellpadding=\"0\">"); - /* Description */ - view->priv->description_label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (view->priv->description_label), TRUE); - gtk_label_set_line_wrap (GTK_LABEL (view->priv->description_label), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->description_label), 0, 0.5); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->description_label, FALSE, FALSE, 0); + /* Description */ + g_string_append (buffer, + "<div id=\"" TABLE_ROW_DESCRIPTION "\" class=\"itip description\" hidden=\"\"></div>\n"); - separator = gtk_hseparator_new (); - gtk_widget_show (separator); - gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); + g_string_append (buffer, "<hr>\n"); /* Lower Info items */ - view->priv->lower_info_box = gtk_vbox_new (FALSE, 12); - gtk_widget_show (view->priv->lower_info_box); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->lower_info_box, FALSE, FALSE, 0); + g_string_append (buffer, + "<table class=\"itip info\" id=\"" TABLE_LOWER_ITIP_INFO "\" border=\"0\" " + "cellspacing=\"5\" cellpadding=\"0\">"); - /* Selector area */ - view->priv->selector_box = gtk_hbox_new (FALSE, 12); - gtk_widget_show (view->priv->selector_box); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->selector_box, FALSE, FALSE, 0); + g_string_append (buffer, + "<table class=\"itip table\" border=\"0\" " + "cellspacing=\"5\" cellpadding=\"0\">\n"); - /* RSVP area */ - view->priv->rsvp_box = gtk_vbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->rsvp_box, FALSE, FALSE, 0); - - view->priv->rsvp_check = gtk_check_button_new_with_mnemonic (_("Send _reply to sender")); - gtk_widget_show (view->priv->rsvp_check); - gtk_box_pack_start (GTK_BOX (view->priv->rsvp_box), view->priv->rsvp_check, FALSE, FALSE, 0); - - g_signal_connect ( - view->priv->rsvp_check, "toggled", - G_CALLBACK (rsvp_toggled_cb), view); - - hbox = gtk_hbox_new (FALSE, 12); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (view->priv->rsvp_box), hbox, FALSE, FALSE, 0); - - label = gtk_label_new (NULL); - gtk_label_set_selectable (GTK_LABEL (label), TRUE); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - view->priv->rsvp_comment_header = gtk_label_new (_("Comment:")); - gtk_label_set_selectable (GTK_LABEL (view->priv->rsvp_comment_header), TRUE); - gtk_misc_set_alignment (GTK_MISC (view->priv->rsvp_comment_header), 0.0, 0.0); - gtk_widget_set_sensitive (view->priv->rsvp_comment_header, FALSE); - gtk_widget_show (view->priv->rsvp_comment_header); - gtk_box_pack_start (GTK_BOX (hbox), view->priv->rsvp_comment_header, FALSE, FALSE, 0); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), 120); - gtk_widget_show (scrolled_window); - gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0); - - view->priv->rsvp_comment_text = gtk_text_view_new (); - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view->priv->rsvp_comment_text), GTK_WRAP_WORD_CHAR); - gtk_widget_set_sensitive (view->priv->rsvp_comment_text, FALSE); - gtk_widget_show (view->priv->rsvp_comment_text); - gtk_container_add (GTK_CONTAINER (scrolled_window), view->priv->rsvp_comment_text); + g_string_append (buffer, + "<tr id=\"" TABLE_ROW_ESCB "\" hidden=\"\""">" + "<th></th>" + "<td><select name=\"" SELECT_ESOURCE "\" id=\"" SELECT_ESOURCE "\"></select></td>" + "</tr>\n"); /* RSVP area */ - view->priv->update_box = gtk_vbox_new (FALSE, 12); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->update_box, FALSE, FALSE, 0); + append_checkbox_table_row (buffer, CHECKBOX_RSVP, _("Send reply to sender")); + + /* Comments */ + g_string_append_printf (buffer, + "<tr id=\"" TABLE_ROW_RSVP_COMMENT "\" hidden=\"\">" + "<th>%s</th>" + "<td><textarea name=\"" TEXTAREA_RSVP_COMMENT "\" " + "id=\"" TEXTAREA_RSVP_COMMENT "\" " + "rows=\"3\" cols=\"40\" disabled=\"\">" + "</textarea></td>\n" + "</tr>\n", + _("Comment:")); + + /* Updates */ + append_checkbox_table_row (buffer, CHECKBOX_UPDATE, _("Send updates to attendees")); + + /* The recurrence check button */ + append_checkbox_table_row (buffer, CHECKBOX_RECUR, _("Apply to all instances")); + append_checkbox_table_row (buffer, CHECKBOX_FREE_TIME, _("Show time as free")); + append_checkbox_table_row (buffer, CHECKBOX_KEEP_ALARM, _("Preserve my reminder")); + append_checkbox_table_row (buffer, CHECKBOX_INHERIT_ALARM, _("Inherit reminder")); - view->priv->update_check = gtk_check_button_new_with_mnemonic (_("Send _updates to attendees")); - gtk_widget_show (view->priv->update_check); - gtk_box_pack_start (GTK_BOX (view->priv->update_box), view->priv->update_check, FALSE, FALSE, 0); + g_string_append (buffer, "</table>\n"); - /* The recurrence check button */ - view->priv->recur_box = gtk_vbox_new (FALSE, 12); - gtk_widget_show (view->priv->recur_box); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->recur_box, FALSE, FALSE, 0); + /* Buttons table */ + append_buttons_table (buffer); - view->priv->recur_check = gtk_check_button_new_with_mnemonic (_("_Apply to all instances")); - gtk_box_pack_start (GTK_BOX (view->priv->recur_box), view->priv->recur_check, FALSE, FALSE, 0); + /* <div class="itip content" > */ + g_string_append (buffer, "</div>\n"); + + g_string_append (buffer, "<div class=\"itip error\" id=\"" DIV_ITIP_ERROR "\"></div>"); + + g_string_append (buffer, "</body></html>"); +} + +void +itip_view_write_for_printing (ItipView *view, + GString *buffer) +{ + if (view->priv->error && *view->priv->error) { + g_string_append (buffer, view->priv->error); + return; + } - g_signal_connect ( - view->priv->recur_check, "toggled", - G_CALLBACK (recur_toggled_cb), view); + g_string_append (buffer, + "<div class=\"itip print_content\" id=\"" DIV_ITIP_CONTENT "\">\n"); + + /* The first section listing the sender */ + /* FIXME What to do if the send and organizer do not match */ + g_string_append_printf (buffer, + "<div id=\"" TEXT_ROW_SENDER "\" class=\"itip sender\">%s</div>\n", + view->priv->sender ? view->priv->sender : ""); + + g_string_append (buffer, "<hr>\n"); + + /* Elementary event information */ + g_string_append (buffer, + "<table class=\"itip table\" border=\"0\" " + "cellspacing=\"5\" cellpadding=\"0\">\n"); + + append_text_table_row ( + buffer, TABLE_ROW_SUMMARY, + NULL, view->priv->summary); + append_text_table_row ( + buffer, TABLE_ROW_LOCATION, + _("Location:"), view->priv->location); + append_text_table_row ( + buffer, TABLE_ROW_START_DATE, + view->priv->start_header, view->priv->start_label); + append_text_table_row ( + buffer, TABLE_ROW_END_DATE, + view->priv->end_header, view->priv->end_label); + append_text_table_row ( + buffer, TABLE_ROW_STATUS, + _("Status:"), view->priv->status); + append_text_table_row ( + buffer, TABLE_ROW_COMMENT, + _("Comment:"), view->priv->comment); + + g_string_append (buffer, "</table>\n"); + + /* Description */ + g_string_append_printf ( + buffer, + "<div id=\"" TABLE_ROW_DESCRIPTION "\" " + "class=\"itip description\" %s>%s</div>\n", + view->priv->description ? "" : "hidden=\"\"", view->priv->description); + + g_string_append (buffer, "</div>"); +} - view->priv->options_box = gtk_vbox_new (FALSE, 2); - gtk_widget_show (view->priv->options_box); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->options_box, FALSE, FALSE, 0); +void +itip_view_create_dom_bindings (ItipView *view, + WebKitDOMElement *element) +{ + WebKitDOMElement *el; + WebKitDOMDocument *doc; - view->priv->free_time_check = gtk_check_button_new_with_mnemonic (_("Show time as _free")); - gtk_box_pack_start (GTK_BOX (view->priv->options_box), view->priv->free_time_check, FALSE, FALSE, 0); + doc = webkit_dom_node_get_owner_document (WEBKIT_DOM_NODE (element)); + view->priv->dom_document = doc; - view->priv->keep_alarm_check = gtk_check_button_new_with_mnemonic (_("_Preserve my reminder")); - /* default value is to keep user's alarms */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->keep_alarm_check), TRUE); - gtk_box_pack_start (GTK_BOX (view->priv->options_box), view->priv->keep_alarm_check, FALSE, FALSE, 0); + el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RECUR); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (recur_toggled_cb), FALSE, view); + } - /* To Translators: This is a check box to inherit a reminder. */ - view->priv->inherit_alarm_check = gtk_check_button_new_with_mnemonic (_("_Inherit reminder")); - gtk_box_pack_start (GTK_BOX (view->priv->options_box), view->priv->inherit_alarm_check, FALSE, FALSE, 0); + el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_RSVP); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (rsvp_toggled_cb), FALSE, view); + } - g_signal_connect ( - view->priv->keep_alarm_check, "toggled", - G_CALLBACK (alarm_check_toggled_cb), - view->priv->inherit_alarm_check); - g_signal_connect ( - view->priv->inherit_alarm_check, "toggled", - G_CALLBACK (alarm_check_toggled_cb), - view->priv->keep_alarm_check); + el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_INHERIT_ALARM); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (alarm_check_toggled_cb), FALSE, view); + } - /* The buttons for actions */ - view->priv->button_box = gtk_hbutton_box_new (); - gtk_button_box_set_layout (GTK_BUTTON_BOX (view->priv->button_box), GTK_BUTTONBOX_START); - gtk_box_set_spacing (GTK_BOX (view->priv->button_box), 12); - gtk_widget_show (view->priv->button_box); - gtk_box_pack_start (GTK_BOX (vbox), view->priv->button_box, FALSE, FALSE, 0); + el = webkit_dom_document_get_element_by_id (doc, CHECKBOX_KEEP_ALARM); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (alarm_check_toggled_cb), FALSE, view); + } - view->priv->buttons_sensitive = TRUE; + el = webkit_dom_document_get_element_by_id (doc, BUTTON_OPEN_CALENDAR); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_ACCEPT_ALL); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_TENTATIVE_ALL); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_DECLINE_ALL); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_UPDATE_ATTENDEE_STATUS); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, BUTTON_SEND_INFORMATION); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } + + el = webkit_dom_document_get_element_by_id (doc, SELECT_ESOURCE); + if (el) { + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "change", + G_CALLBACK (source_changed_cb), FALSE, view); + } +} + +static void +itip_view_init (ItipView *view) +{ + view->priv = ITIP_VIEW_GET_PRIVATE (view); } -GtkWidget * -itip_view_new (void) +ItipView * +itip_view_new (ItipPURI *puri) { - ItipView *itip_view = g_object_new (ITIP_TYPE_VIEW, "homogeneous", FALSE, "spacing", 6, NULL); + ItipView *view; + + view = ITIP_VIEW (g_object_new (ITIP_TYPE_VIEW, NULL)); + view->priv->puri = puri; - return GTK_WIDGET (itip_view); + return view; +} + +ItipPURI * +itip_view_get_puri (ItipView *view) +{ + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + return view->priv->puri; +} + +static void +show_button (ItipView *view, + const gchar *id) +{ + WebKitDOMElement *button; + + button = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, id); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (button), FALSE); } void itip_view_set_mode (ItipView *view, ItipViewMode mode) { - ItipViewPrivate *priv; + WebKitDOMElement *row, *cell; + WebKitDOMElement *button; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - priv->mode = mode; + view->priv->mode = mode; set_sender_text (view); - set_buttons (view); + + if (!view->priv->dom_document) + return; + + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_BUTTONS); + cell = webkit_dom_element_get_first_element_child (row); + do { + button = webkit_dom_element_get_first_element_child (cell); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (button), TRUE); + } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL); + + view->priv->is_recur_set = itip_view_get_recur_check_state (view); + + /* Always visible */ + show_button (view, BUTTON_OPEN_CALENDAR); + + switch (mode) { + case ITIP_VIEW_MODE_PUBLISH: + if (view->priv->needs_decline) { + show_button (view, BUTTON_DECLINE); + } + show_button (view, BUTTON_ACCEPT); + break; + case ITIP_VIEW_MODE_REQUEST: + show_button (view, view->priv->is_recur_set ? BUTTON_DECLINE_ALL : BUTTON_DECLINE); + show_button (view, view->priv->is_recur_set ? BUTTON_TENTATIVE_ALL : BUTTON_TENTATIVE); + show_button (view, view->priv->is_recur_set ? BUTTON_ACCEPT_ALL : BUTTON_ACCEPT); + break; + case ITIP_VIEW_MODE_ADD: + if (view->priv->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) { + show_button (view, BUTTON_DECLINE); + show_button (view, BUTTON_TENTATIVE); + } + show_button (view, BUTTON_ACCEPT); + break; + case ITIP_VIEW_MODE_REFRESH: + show_button (view, BUTTON_SEND_INFORMATION); + break; + case ITIP_VIEW_MODE_REPLY: + show_button (view, BUTTON_UPDATE_ATTENDEE_STATUS); + break; + case ITIP_VIEW_MODE_CANCEL: + show_button (view, BUTTON_UPDATE); + break; + case ITIP_VIEW_MODE_COUNTER: + case ITIP_VIEW_MODE_DECLINECOUNTER: + show_button (view, BUTTON_DECLINE); + show_button (view, BUTTON_TENTATIVE); + show_button (view, BUTTON_ACCEPT); + break; + default: + break; + } } ItipViewMode itip_view_get_mode (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, ITIP_VIEW_MODE_NONE); g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE); - priv = view->priv; - - return priv->mode; + return view->priv->mode; } void itip_view_set_item_type (ItipView *view, ECalClientSourceType type) { - ItipViewPrivate *priv; + WebKitDOMElement *row, *cell; + const gchar *header; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + view->priv->type = type; + + if (!view->priv->dom_document) + return; + + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_ESCB); + cell = webkit_dom_element_get_first_element_child (row); + + switch (view->priv->type) { + case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: + header = _("Calendar:"); + break; + case E_CAL_CLIENT_SOURCE_TYPE_TASKS: + header = _("Tasks:"); + break; + case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: + header = _("Memos:"); + break; + default: + header = NULL; + break; + } - priv->type = type; + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (cell), header ? header : "", NULL); set_sender_text (view); } @@ -1276,31 +1558,21 @@ itip_view_set_item_type (ItipView *view, ECalClientSourceType itip_view_get_item_type (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, ITIP_VIEW_MODE_NONE); g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE); - priv = view->priv; - - return priv->type; + return view->priv->type; } void itip_view_set_organizer (ItipView *view, const gchar *organizer) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - if (priv->organizer) - g_free (priv->organizer); + if (view->priv->organizer) + g_free (view->priv->organizer); - priv->organizer = e_utf8_ensure_valid (organizer); + view->priv->organizer = e_utf8_ensure_valid (organizer); set_sender_text (view); } @@ -1308,31 +1580,21 @@ itip_view_set_organizer (ItipView *view, const gchar * itip_view_get_organizer (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->organizer; + return view->priv->organizer; } void itip_view_set_organizer_sentby (ItipView *view, const gchar *sentby) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - if (priv->organizer_sentby) - g_free (priv->organizer_sentby); + if (view->priv->organizer_sentby) + g_free (view->priv->organizer_sentby); - priv->organizer_sentby = e_utf8_ensure_valid (sentby); + view->priv->organizer_sentby = e_utf8_ensure_valid (sentby); set_sender_text (view); } @@ -1340,31 +1602,21 @@ itip_view_set_organizer_sentby (ItipView *view, const gchar * itip_view_get_organizer_sentby (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->organizer_sentby; + return view->priv->organizer_sentby; } void itip_view_set_attendee (ItipView *view, const gchar *attendee) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - if (priv->attendee) - g_free (priv->attendee); + if (view->priv->attendee) + g_free (view->priv->attendee); - priv->attendee = e_utf8_ensure_valid (attendee); + view->priv->attendee = e_utf8_ensure_valid (attendee); set_sender_text (view); } @@ -1372,31 +1624,21 @@ itip_view_set_attendee (ItipView *view, const gchar * itip_view_get_attendee (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->attendee; + return view->priv->attendee; } void itip_view_set_attendee_sentby (ItipView *view, const gchar *sentby) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - if (priv->attendee_sentby) - g_free (priv->attendee_sentby); + if (view->priv->attendee_sentby) + g_free (view->priv->attendee_sentby); - priv->attendee_sentby = e_utf8_ensure_valid (sentby); + view->priv->attendee_sentby = e_utf8_ensure_valid (sentby); set_sender_text (view); } @@ -1404,31 +1646,21 @@ itip_view_set_attendee_sentby (ItipView *view, const gchar * itip_view_get_attendee_sentby (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->attendee_sentby; + return view->priv->attendee_sentby; } void itip_view_set_proxy (ItipView *view, const gchar *proxy) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (view->priv->proxy) + g_free (view->priv->proxy); - if (priv->proxy) - g_free (priv->proxy); - - priv->proxy = e_utf8_ensure_valid (proxy); + view->priv->proxy = e_utf8_ensure_valid (proxy); set_sender_text (view); } @@ -1436,31 +1668,21 @@ itip_view_set_proxy (ItipView *view, const gchar * itip_view_get_proxy (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->proxy; + return view->priv->proxy; } void itip_view_set_delegator (ItipView *view, const gchar *delegator) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - if (priv->delegator) - g_free (priv->delegator); + if (view->priv->delegator) + g_free (view->priv->delegator); - priv->delegator = e_utf8_ensure_valid (delegator); + view->priv->delegator = e_utf8_ensure_valid (delegator); set_sender_text (view); } @@ -1468,174 +1690,188 @@ itip_view_set_delegator (ItipView *view, const gchar * itip_view_get_delegator (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->delegator; + return view->priv->delegator; } void itip_view_set_summary (ItipView *view, const gchar *summary) { - ItipViewPrivate *priv; + WebKitDOMElement *row, *col; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (view->priv->summary) + g_free (view->priv->summary); - if (priv->summary) - g_free (priv->summary); + view->priv->summary = summary ? g_strstrip (e_utf8_ensure_valid (summary)) : NULL; - priv->summary = summary ? g_strstrip (e_utf8_ensure_valid (summary)) : NULL; + if (!view->priv->dom_document) + return; + + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_SUMMARY); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->summary == NULL)); - set_summary_text (view); + col = webkit_dom_element_get_last_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), + view->priv->summary ? view->priv->summary : "", + NULL); } const gchar * itip_view_get_summary (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->summary; + return view->priv->summary; } void itip_view_set_location (ItipView *view, const gchar *location) { - ItipViewPrivate *priv; + WebKitDOMElement *row, *col; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (view->priv->location) + g_free (view->priv->location); - if (priv->location) - g_free (priv->location); + view->priv->location = location ? g_strstrip (e_utf8_ensure_valid (location)) : NULL; + + if (!view->priv->dom_document) + return; - priv->location = location ? g_strstrip (e_utf8_ensure_valid (location)) : NULL; + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_LOCATION); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->location == NULL)); - set_location_text (view); + col = webkit_dom_element_get_last_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), + view->priv->location ? view->priv->location : "", + NULL); } const gchar * itip_view_get_location (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->location; + return view->priv->location; } void itip_view_set_status (ItipView *view, const gchar *status) { - ItipViewPrivate *priv; + WebKitDOMElement *row, *col; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (view->priv->status) + g_free (view->priv->status); - if (priv->status) - g_free (priv->status); + view->priv->status = status ? g_strstrip (e_utf8_ensure_valid (status)) : NULL; + + if (!view->priv->dom_document) + return; - priv->status = status ? g_strstrip (e_utf8_ensure_valid (status)) : NULL; + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_STATUS); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->status == NULL)); - set_status_text (view); + col = webkit_dom_element_get_last_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), + view->priv->status ? view->priv->status : "", + NULL); } const gchar * itip_view_get_status (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->status; + return view->priv->status; } void itip_view_set_comment (ItipView *view, const gchar *comment) { - ItipViewPrivate *priv; + WebKitDOMElement *row, *col; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (view->priv->comment) + g_free (view->priv->comment); - if (priv->comment) - g_free (priv->comment); + view->priv->comment = comment ? g_strstrip (e_utf8_ensure_valid (comment)) : NULL; - priv->comment = comment ? g_strstrip (e_utf8_ensure_valid (comment)) : NULL; + if (!view->priv->dom_document) + return; - set_comment_text (view); + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_COMMENT); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), (view->priv->comment == NULL)); + + col = webkit_dom_element_get_last_element_child (row); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (col), + view->priv->comment ? view->priv->comment : "", + NULL); } const gchar * itip_view_get_comment (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->comment; + return view->priv->comment; } void itip_view_set_description (ItipView *view, const gchar *description) { - ItipViewPrivate *priv; + WebKitDOMElement *div; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (view->priv->description) + g_free (view->priv->description); - if (priv->description) - g_free (priv->description); + view->priv->description = description ? g_strstrip (e_utf8_ensure_valid (description)) : NULL; + + if (!view->priv->dom_document) + return; - priv->description = description ? g_strstrip (e_utf8_ensure_valid (description)) : NULL; + div = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_DESCRIPTION); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (div), (view->priv->description == NULL)); - set_description_text (view); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (div), + view->priv->description ? view->priv->description : "", + NULL); } const gchar * itip_view_get_description (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->description; + return view->priv->description; } void @@ -1645,7 +1881,6 @@ itip_view_set_start (ItipView *view, { ItipViewPrivate *priv; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; @@ -1669,17 +1904,12 @@ const struct tm * itip_view_get_start (ItipView *view, gboolean *is_date) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - if (is_date) - *is_date = priv->start_tm_is_date; + *is_date = view->priv->start_tm_is_date; - return priv->start_tm; + return view->priv->start_tm; } void @@ -1689,7 +1919,6 @@ itip_view_set_end (ItipView *view, { ItipViewPrivate *priv; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; @@ -1713,17 +1942,12 @@ const struct tm * itip_view_get_end (ItipView *view, gboolean *is_date) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - if (is_date) - *is_date = priv->end_tm_is_date; + *is_date = view->priv->end_tm_is_date; - return priv->end_tm; + return view->priv->end_tm; } guint @@ -1734,7 +1958,6 @@ itip_view_add_upper_info_item (ItipView *view, ItipViewPrivate *priv; ItipViewInfoItem *item; - g_return_val_if_fail (view != NULL, 0); g_return_val_if_fail (ITIP_IS_VIEW (view), 0); priv = view->priv; @@ -1747,7 +1970,10 @@ itip_view_add_upper_info_item (ItipView *view, priv->upper_info_items = g_slist_append (priv->upper_info_items, item); - set_upper_info_items (view); + if (!view->priv->dom_document) + return item->id; + + append_info_item_row (view, TABLE_UPPER_ITIP_INFO, item); return item->id; } @@ -1762,7 +1988,6 @@ itip_view_add_upper_info_item_printf (ItipView *view, gchar *message; guint id; - g_return_val_if_fail (view != NULL, 0); g_return_val_if_fail (ITIP_IS_VIEW (view), 0); va_start (args, format); @@ -1782,7 +2007,6 @@ itip_view_remove_upper_info_item (ItipView *view, ItipViewPrivate *priv; GSList *l; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; @@ -1796,7 +2020,8 @@ itip_view_remove_upper_info_item (ItipView *view, g_free (item->message); g_free (item); - set_upper_info_items (view); + if (!view->priv->dom_document) + remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, id); return; } @@ -1809,16 +2034,16 @@ itip_view_clear_upper_info_items (ItipView *view) ItipViewPrivate *priv; GSList *l; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; - gtk_container_foreach (GTK_CONTAINER (priv->upper_info_box), (GtkCallback) gtk_widget_destroy, NULL); - for (l = priv->upper_info_items; l; l = l->next) { ItipViewInfoItem *item = l->data; + if (view->priv->dom_document) + remove_info_item_row (view, TABLE_UPPER_ITIP_INFO, item->id); + g_free (item->message); g_free (item); } @@ -1835,7 +2060,6 @@ itip_view_add_lower_info_item (ItipView *view, ItipViewPrivate *priv; ItipViewInfoItem *item; - g_return_val_if_fail (view != NULL, 0); g_return_val_if_fail (ITIP_IS_VIEW (view), 0); priv = view->priv; @@ -1848,7 +2072,10 @@ itip_view_add_lower_info_item (ItipView *view, priv->lower_info_items = g_slist_append (priv->lower_info_items, item); - set_lower_info_items (view); + if (!view->priv->dom_document) + return item->id; + + append_info_item_row (view, TABLE_LOWER_ITIP_INFO, item); return item->id; } @@ -1863,7 +2090,6 @@ itip_view_add_lower_info_item_printf (ItipView *view, gchar *message; guint id; - g_return_val_if_fail (view != NULL, 0); g_return_val_if_fail (ITIP_IS_VIEW (view), 0); va_start (args, format); @@ -1883,7 +2109,6 @@ itip_view_remove_lower_info_item (ItipView *view, ItipViewPrivate *priv; GSList *l; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; @@ -1897,7 +2122,8 @@ itip_view_remove_lower_info_item (ItipView *view, g_free (item->message); g_free (item); - set_lower_info_items (view); + if (view->priv->dom_document) + remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, id); return; } @@ -1910,16 +2136,16 @@ itip_view_clear_lower_info_items (ItipView *view) ItipViewPrivate *priv; GSList *l; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; - gtk_container_foreach (GTK_CONTAINER (priv->lower_info_box), (GtkCallback) gtk_widget_destroy, NULL); - for (l = priv->lower_info_items; l; l = l->next) { ItipViewInfoItem *item = l->data; + if (view->priv->dom_document) + remove_info_item_row (view, TABLE_LOWER_ITIP_INFO, item->id); + g_free (item->message); g_free (item); } @@ -1929,14 +2155,76 @@ itip_view_clear_lower_info_items (ItipView *view) } static void -source_changed_cb (ESourceComboBox *escb, - ItipView *view) +source_list_changed_cb (ESourceList *source_list, + ItipView *view) { - ESource *source; + GSList *groups, *iter; + WebKitDOMElement *select; - source = e_source_combo_box_get_active (escb); + d(printf("Assigning a new source list!\n")); - g_signal_emit (view, signals[SOURCE_SELECTED], 0, source); + if (!view->priv->dom_document) + return; + + select = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, SELECT_ESOURCE); + + while (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (select))) { + webkit_dom_node_remove_child ( + WEBKIT_DOM_NODE (select), + webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (select)), + NULL); + } + + groups = e_source_list_peek_groups (source_list); + for (iter = groups; iter; iter = iter->next) { + + ESourceGroup *group = iter->data; + GSList *sources, *iter2; + WebKitDOMElement *optgroup; + + sources = e_source_group_peek_sources (group); + if (sources == NULL) + continue; + + optgroup = webkit_dom_document_create_element ( + view->priv->dom_document, "OPTGROUP", NULL); + webkit_dom_html_opt_group_element_set_label ( + WEBKIT_DOM_HTML_OPT_GROUP_ELEMENT (optgroup), + e_source_group_peek_name (group)); + + webkit_dom_node_append_child ( + WEBKIT_DOM_NODE (select), + WEBKIT_DOM_NODE (optgroup), + NULL); + + for (iter2 = sources; iter2; iter2 = iter2->next) { + + WebKitDOMElement *option; + ESource *source = iter2->data; + + option = webkit_dom_document_create_element ( + view->priv->dom_document, "OPTION", NULL); + webkit_dom_html_option_element_set_value ( + WEBKIT_DOM_HTML_OPTION_ELEMENT (option), + e_source_peek_uid (source)); + webkit_dom_html_option_element_set_label ( + WEBKIT_DOM_HTML_OPTION_ELEMENT (option), + e_source_peek_name (source)); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (option), + e_source_peek_name (source), NULL); + webkit_dom_html_element_set_class_name ( + WEBKIT_DOM_HTML_ELEMENT (option), "calendar"); + + webkit_dom_node_append_child ( + WEBKIT_DOM_NODE (optgroup), + WEBKIT_DOM_NODE (option), + NULL); + } + } + + source_changed_cb (select, NULL, view); } void @@ -1945,7 +2233,6 @@ itip_view_set_source_list (ItipView *view, { ItipViewPrivate *priv; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); priv = view->priv; @@ -1953,380 +2240,660 @@ itip_view_set_source_list (ItipView *view, if (priv->source_list) g_object_unref (priv->source_list); - if (priv->escb) - gtk_widget_destroy (priv->escb); - if (!source_list) { - if (priv->escb_header) - gtk_widget_destroy (priv->escb_header); - priv->source_list = NULL; - priv->escb = NULL; - priv->escb_header = NULL; - return; } priv->source_list = g_object_ref (source_list); - priv->escb = e_source_combo_box_new (source_list); - gtk_widget_show (priv->escb); - g_signal_connect ( - priv->escb, "changed", - G_CALLBACK (source_changed_cb), view); - - if (!priv->escb_header) { - if (priv->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) - priv->escb_header = gtk_label_new_with_mnemonic (_("_Calendar:")); - else if (priv->type == E_CAL_CLIENT_SOURCE_TYPE_TASKS) - priv->escb_header = gtk_label_new_with_mnemonic (_("_Tasks:")); - else if (priv->type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - priv->escb_header = gtk_label_new_with_mnemonic (_("_Memos:")); + source_list_changed_cb (source_list, view); - gtk_label_set_selectable (GTK_LABEL (priv->escb_header), TRUE); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->escb_header), priv->escb); - gtk_widget_show (priv->escb_header); - } - - gtk_box_pack_start (GTK_BOX (priv->selector_box), priv->escb_header, FALSE, TRUE, 6); - gtk_box_pack_start (GTK_BOX (priv->selector_box), priv->escb, FALSE, TRUE, 0); + g_signal_connect (source_list, "changed", + G_CALLBACK (source_list_changed_cb), view); } ESourceList * itip_view_get_source_list (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - return priv->source_list; + return view->priv->source_list; } void itip_view_set_source (ItipView *view, ESource *source) { - ItipViewPrivate *priv; + WebKitDOMElement *select; + WebKitDOMElement *row; + gulong i, len; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + d(printf("Settings default source '%s'\n", e_source_peek_name (source))); - if (!priv->escb) + if (!view->priv->dom_document) return; - e_source_combo_box_set_active ( - E_SOURCE_COMBO_BOX (priv->escb), source); + row = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_ESCB); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (row), (source == NULL)); + if (source == NULL) + return; + + select = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, SELECT_ESOURCE); + + /* <select> does not emit 'change' event when already selected <option> + * is re-selected, but we need to notify itip formatter, so that it would + * make all the buttons sensitive */ + if (source == itip_view_get_source (view)) { + source_changed_cb (select, NULL, view); + } + + if (webkit_dom_html_select_element_get_disabled ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) { + webkit_dom_html_select_element_set_disabled ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE); + } + + len = webkit_dom_html_select_element_get_length ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select)); + for (i = 0; i < len; i++) { + + WebKitDOMNode *node; + WebKitDOMHTMLOptionElement *option; + gchar *value; + + node = webkit_dom_html_select_element_item ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select), i); + option = WEBKIT_DOM_HTML_OPTION_ELEMENT (node); + + value = webkit_dom_html_option_element_get_value (option); + if (g_strcmp0 (value, e_source_peek_uid (source)) == 0) { + webkit_dom_html_option_element_set_selected ( + option, TRUE); + + g_free (value); + break; + } + + g_free (value); + } } ESource * itip_view_get_source (ItipView *view) { - ItipViewPrivate *priv; + WebKitDOMElement *select; + gchar *uid; + ESource *source; + gboolean disable = FALSE; - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; - - if (!priv->escb) + if (!view->priv->dom_document) return NULL; - return e_source_combo_box_get_active ( - E_SOURCE_COMBO_BOX (priv->escb)); + select = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, SELECT_ESOURCE); + if (webkit_dom_html_select_element_get_disabled ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select))) { + webkit_dom_html_select_element_set_disabled ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select), FALSE); + disable = TRUE; + } + + uid = webkit_dom_html_select_element_get_value ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select)); + + source = e_source_list_peek_source_by_uid ( + view->priv->source_list, uid); + g_free (uid); + + if (disable) { + webkit_dom_html_select_element_set_disabled ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (select), TRUE); + } + + return source; } void itip_view_set_rsvp (ItipView *view, gboolean rsvp) { - ItipViewPrivate *priv; + WebKitDOMElement *el; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (!view->priv->dom_document) + return; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->rsvp_check), rsvp); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RSVP); + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), rsvp); - gtk_widget_set_sensitive (priv->rsvp_comment_header, rsvp); - gtk_widget_set_sensitive (priv->rsvp_comment_text, rsvp); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TEXTAREA_RSVP_COMMENT); + webkit_dom_html_text_area_element_set_disabled ( + WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp); } gboolean itip_view_get_rsvp (ItipView *view) { - ItipViewPrivate *priv; + WebKitDOMElement *el; - g_return_val_if_fail (view != NULL, FALSE); g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - priv = view->priv; + if (!view->priv->dom_document) + return FALSE; - return priv->rsvp_show && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->rsvp_check)); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_UPDATE); + return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); } void -itip_view_set_show_rsvp (ItipView *view, - gboolean rsvp) +itip_view_set_show_rsvp_check (ItipView *view, + gboolean show) { - ItipViewPrivate *priv; + WebKitDOMElement *label; + WebKitDOMElement *el; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, "table_row_" CHECKBOX_RSVP); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RSVP); + label = webkit_dom_element_get_next_element_sibling (el); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - priv->rsvp_show = rsvp; + if (!show) { + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); + } - priv->rsvp_show ? gtk_widget_show (priv->rsvp_box) : gtk_widget_hide (priv->rsvp_box); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_RSVP_COMMENT); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); } gboolean -itip_view_get_show_rsvp (ItipView *view) +itip_view_get_show_rsvp_check (ItipView *view) { - ItipViewPrivate *priv; + WebKitDOMElement *el; - g_return_val_if_fail (view != NULL, FALSE); g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - priv = view->priv; + if (!view->priv->dom_document) + return FALSE; - return priv->rsvp_show; + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RSVP); + return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el)); } void itip_view_set_update (ItipView *view, gboolean update) { - ItipViewPrivate *priv; + WebKitDOMElement *el; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_UPDATE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->update_check), update); + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), update); } gboolean itip_view_get_update (ItipView *view) { - ItipViewPrivate *priv; + WebKitDOMElement *el; - g_return_val_if_fail (view != NULL, FALSE); g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - priv = view->priv; + if (!view->priv->dom_document) + return FALSE; - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->update_check)); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_UPDATE); + return webkit_dom_html_input_element_get_checked (WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); } void -itip_view_set_show_update (ItipView *view, - gboolean update) +itip_view_set_show_update_check (ItipView *view, + gboolean show) { - ItipViewPrivate *priv; + WebKitDOMElement *label; + WebKitDOMElement *el; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, "table_row_" CHECKBOX_UPDATE); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); - priv->update_show = update; + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_UPDATE); + label = webkit_dom_element_get_next_element_sibling (el); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); - priv->update_show ? gtk_widget_show (priv->update_box) : gtk_widget_hide (priv->update_box); + if (!show) { + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); + } } gboolean -itip_view_get_show_update (ItipView *view) +itip_view_get_show_update_check (ItipView *view) { - ItipViewPrivate *priv; + WebKitDOMElement *el; - g_return_val_if_fail (view != NULL, FALSE); g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - priv = view->priv; + if (!view->priv->dom_document) + return FALSE; - return priv->update_show; + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_UPDATE); + return !webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el)); } void itip_view_set_rsvp_comment (ItipView *view, const gchar *comment) { - ItipViewPrivate *priv; - GtkTextBuffer *text_buffer; + WebKitDOMElement *el; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TEXTAREA_RSVP_COMMENT); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (el), (comment == NULL)); - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->rsvp_comment_text)); - gtk_text_buffer_set_text (text_buffer, comment, -1); + if (comment) { + webkit_dom_html_text_area_element_set_value ( + WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), comment); + } } gchar * itip_view_get_rsvp_comment (ItipView *view) { - ItipViewPrivate *priv; - GtkTextBuffer *text_buffer; - GtkTextIter start, end; + WebKitDOMElement *el; - g_return_val_if_fail (view != NULL, NULL); g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - priv = view->priv; + if (!view->priv->dom_document) + return NULL; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TEXTAREA_RSVP_COMMENT); - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->rsvp_comment_text)); - gtk_text_buffer_get_bounds (text_buffer, &start, &end); + if (webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (el))) { + return NULL; + } - return gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE); + return webkit_dom_html_text_area_element_get_value ( + WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el)); } void itip_view_set_needs_decline (ItipView *view, gboolean needs_decline) { - ItipViewPrivate *priv; - - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; - - priv->needs_decline = needs_decline; + view->priv->needs_decline = needs_decline; } void itip_view_set_buttons_sensitive (ItipView *view, gboolean sensitive) { - ItipViewPrivate *priv; + WebKitDOMElement *el, *cell; - g_return_if_fail (view != NULL); g_return_if_fail (ITIP_IS_VIEW (view)); - priv = view->priv; + d(printf("Settings buttons %s\n", sensitive ? "sensitive" : "insensitive")); - priv->buttons_sensitive = sensitive; + view->priv->buttons_sensitive = sensitive; + + if (!view->priv->dom_document) + return; - gtk_widget_set_sensitive (priv->button_box, priv->buttons_sensitive); - gtk_widget_set_sensitive (priv->update_box, priv->buttons_sensitive); - gtk_widget_set_sensitive (priv->recur_box, priv->buttons_sensitive); - gtk_widget_set_sensitive (priv->options_box, priv->buttons_sensitive); - gtk_widget_set_sensitive (priv->selector_box, priv->buttons_sensitive); - gtk_widget_set_sensitive (priv->rsvp_box, priv->buttons_sensitive); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_UPDATE); + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RECUR); + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_FREE_TIME); + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_KEEP_ALARM); + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_INHERIT_ALARM); + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RSVP); + webkit_dom_html_input_element_set_disabled ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TEXTAREA_RSVP_COMMENT); + webkit_dom_html_text_area_element_set_disabled ( + WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, SELECT_ESOURCE); + webkit_dom_html_select_element_set_disabled ( + WEBKIT_DOM_HTML_SELECT_ELEMENT (el), !sensitive); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, TABLE_ROW_BUTTONS); + cell = webkit_dom_element_get_first_element_child (el); + do { + WebKitDOMElement *btn; + btn = webkit_dom_element_get_first_element_child (cell); + if (!webkit_dom_html_element_get_hidden ( + WEBKIT_DOM_HTML_ELEMENT (btn))) { + webkit_dom_html_button_element_set_disabled ( + WEBKIT_DOM_HTML_BUTTON_ELEMENT (btn), !sensitive); + } + } while ((cell = webkit_dom_element_get_next_element_sibling (cell)) != NULL); } gboolean itip_view_get_buttons_sensitive (ItipView *view) { - ItipViewPrivate *priv; - - g_return_val_if_fail (view != NULL, FALSE); g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - priv = view->priv; - - return priv->buttons_sensitive; + return view->priv->buttons_sensitive; } gboolean itip_view_get_recur_check_state (ItipView *view) { - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->recur_check)); + WebKitDOMElement *el; + + g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); + + if (!view->priv->dom_document) + return FALSE; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RECUR); + return webkit_dom_html_input_element_get_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); } void itip_view_set_show_recur_check (ItipView *view, gboolean show) { - g_return_if_fail (view != NULL); + WebKitDOMElement *label; + WebKitDOMElement *el; + g_return_if_fail (ITIP_IS_VIEW (view)); - if (show) - gtk_widget_show (view->priv->recur_check); - else { - gtk_widget_hide (view->priv->recur_check); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->recur_check), FALSE); + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, "table_row_" CHECKBOX_RECUR); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_RECUR); + label = webkit_dom_element_get_next_element_sibling (el); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); + + if (!show) { + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); } + + /* and update state of the second check */ + alarm_check_toggled_cb ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), + NULL, view); } void itip_view_set_show_free_time_check (ItipView *view, gboolean show) { - g_return_if_fail (view != NULL); + WebKitDOMElement *label; + WebKitDOMElement *el; + g_return_if_fail (ITIP_IS_VIEW (view)); - if (show) - gtk_widget_show (view->priv->free_time_check); - else { - gtk_widget_hide (view->priv->free_time_check); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->free_time_check), FALSE); + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, "table_row_" CHECKBOX_FREE_TIME); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_FREE_TIME); + label = webkit_dom_element_get_next_element_sibling (el); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); + + if (!show) { + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); } + + /* and update state of the second check */ + alarm_check_toggled_cb ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), + NULL, view); } gboolean itip_view_get_free_time_check_state (ItipView *view) { - g_return_val_if_fail (view != NULL, FALSE); + WebKitDOMElement *el; + + g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->free_time_check)); + if (!view->priv->dom_document) + return FALSE; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_FREE_TIME); + return webkit_dom_html_input_element_get_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); } void itip_view_set_show_keep_alarm_check (ItipView *view, gboolean show) { - g_return_if_fail (view != NULL); + WebKitDOMElement *label; + WebKitDOMElement *el; + g_return_if_fail (ITIP_IS_VIEW (view)); - if (show) - gtk_widget_show (view->priv->keep_alarm_check); - else - gtk_widget_hide (view->priv->keep_alarm_check); + if (!view->priv->dom_document) + return; - /* and update state of the second check */ - alarm_check_toggled_cb (view->priv->keep_alarm_check, view->priv->inherit_alarm_check); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, "table_row_" CHECKBOX_KEEP_ALARM); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_KEEP_ALARM); + label = webkit_dom_element_get_next_element_sibling (el); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); + + if (!show) { + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); + } + + /* and update state of the second check */ + alarm_check_toggled_cb ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), + NULL, view); } gboolean itip_view_get_keep_alarm_check_state (ItipView *view) { - g_return_val_if_fail (view != NULL, FALSE); + WebKitDOMElement *el; + + g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->keep_alarm_check)); + if (!view->priv->dom_document) + return FALSE; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_KEEP_ALARM); + return webkit_dom_html_input_element_get_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); } void itip_view_set_show_inherit_alarm_check (ItipView *view, gboolean show) { - g_return_if_fail (view != NULL); + WebKitDOMElement *label; + WebKitDOMElement *el; + g_return_if_fail (ITIP_IS_VIEW (view)); - if (show) - gtk_widget_show (view->priv->inherit_alarm_check); - else { - gtk_widget_hide (view->priv->inherit_alarm_check); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->priv->inherit_alarm_check), FALSE); + if (!view->priv->dom_document) + return; + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, "table_row_" CHECKBOX_INHERIT_ALARM); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (el), !show); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_INHERIT_ALARM); + label = webkit_dom_element_get_next_element_sibling (el); + webkit_dom_html_element_set_hidden (WEBKIT_DOM_HTML_ELEMENT (label), !show); + + if (!show) { + webkit_dom_html_input_element_set_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), FALSE); } /* and update state of the second check */ - alarm_check_toggled_cb (view->priv->inherit_alarm_check, view->priv->keep_alarm_check); + alarm_check_toggled_cb ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el), + NULL, view); } gboolean itip_view_get_inherit_alarm_check_state (ItipView *view) { - g_return_val_if_fail (view != NULL, FALSE); + WebKitDOMElement *el; + + g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE); + + if (!view->priv->dom_document) + return FALSE; - return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->priv->inherit_alarm_check)); + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, CHECKBOX_INHERIT_ALARM); + return webkit_dom_html_input_element_get_checked ( + WEBKIT_DOM_HTML_INPUT_ELEMENT (el)); } + +void +itip_view_set_error (ItipView *view, + const gchar *error_html, + gboolean show_save_btn) +{ + WebKitDOMElement *content, *error; + GString *str; + + g_return_if_fail (ITIP_IS_VIEW (view)); + g_return_if_fail (error_html); + + str = g_string_new (error_html); + + if (show_save_btn) { + g_string_append (str, + "<table border=\"0\" width=\"100%\">" + "<tr width=\"100%\" id=\"" TABLE_ROW_BUTTONS "\">"); + + buttons_table_write_button ( + str, BUTTON_SAVE, _("Save"), + GTK_STOCK_SAVE, ITIP_VIEW_RESPONSE_SAVE); + + g_string_append (str, "</tr></table>"); + } + + view->priv->error = str->str; + g_string_free (str, FALSE); + + if (!view->priv->dom_document) + return; + + content = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, DIV_ITIP_CONTENT); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (content), TRUE); + + error = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, DIV_ITIP_ERROR); + webkit_dom_html_element_set_hidden ( + WEBKIT_DOM_HTML_ELEMENT (error), FALSE); + + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (error), view->priv->error, NULL); + + if (show_save_btn) { + WebKitDOMElement *el; + + show_button (view, BUTTON_SAVE); + + el = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, BUTTON_SAVE); + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (el), "click", + G_CALLBACK (button_clicked_cb), FALSE, view); + } +} + diff --git a/plugins/itip-formatter/itip-view.h b/plugins/itip-formatter/itip-view.h index 538306c822..5ae8d9cd17 100644 --- a/plugins/itip-formatter/itip-view.h +++ b/plugins/itip-formatter/itip-view.h @@ -29,6 +29,7 @@ #include <gtk/gtk.h> #include <libedataserver/e-source-list.h> #include <libecal/e-cal-client.h> +#include <webkit/webkitdom.h> G_BEGIN_DECLS @@ -42,6 +43,7 @@ G_BEGIN_DECLS typedef struct _ItipView ItipView; typedef struct _ItipViewPrivate ItipViewPrivate; typedef struct _ItipViewClass ItipViewClass; +typedef struct _ItipPURI ItipPURI; typedef enum { ITIP_VIEW_MODE_NONE, @@ -64,7 +66,8 @@ typedef enum { ITIP_VIEW_RESPONSE_UPDATE, ITIP_VIEW_RESPONSE_CANCEL, ITIP_VIEW_RESPONSE_REFRESH, - ITIP_VIEW_RESPONSE_OPEN + ITIP_VIEW_RESPONSE_OPEN, + ITIP_VIEW_RESPONSE_SAVE } ItipViewResponse; typedef enum { @@ -76,115 +79,188 @@ typedef enum { } ItipViewInfoItemType; struct _ItipView { - GtkHBox parent_instance; + GObject parent_instance; ItipViewPrivate *priv; - - GtkWidget *action_vbox; }; struct _ItipViewClass { - GtkHBoxClass parent_class; - - void (* source_selected) (ItipView *view, ESource *selected_source); - void (* response) (ItipView *view, gint response); -}; - -GType itip_view_get_type (void); -GtkWidget *itip_view_new (void); - -void itip_view_set_mode (ItipView *view, ItipViewMode mode); -ItipViewMode itip_view_get_mode (ItipView *view); - -void itip_view_set_item_type (ItipView *view, ECalClientSourceType type); -ECalClientSourceType itip_view_get_item_type (ItipView *view); - -void itip_view_set_organizer (ItipView *view, const gchar *organizer); -const gchar *itip_view_get_organizer (ItipView *view); - -void itip_view_set_organizer_sentby (ItipView *view, const gchar *sentby); -const gchar *itip_view_get_organizer_sentby (ItipView *view); - -void itip_view_set_attendee (ItipView *view, const gchar *attendee); -const gchar *itip_view_get_attendee (ItipView *view); - -void itip_view_set_attendee_sentby (ItipView *view, const gchar *sentby); -const gchar *itip_view_get_attendee_sentby (ItipView *view); - -void itip_view_set_delegator (ItipView *view, const gchar *delegator); -const gchar *itip_view_get_delegator (ItipView *view); - -void itip_view_set_proxy (ItipView *view, const gchar *proxy); -const gchar *itip_view_get_proxy (ItipView *view); - -void itip_view_set_summary (ItipView *view, const gchar *summary); -const gchar *itip_view_get_summary (ItipView *view); - -void itip_view_set_location (ItipView *view, const gchar *location); -const gchar *itip_view_get_location (ItipView *view); - -void itip_view_set_status (ItipView *view, const gchar *status); -const gchar *itip_view_get_status (ItipView *view); - -void itip_view_set_comment (ItipView *view, const gchar *comment); -const gchar *itip_view_get_comment (ItipView *view); + GObjectClass parent_class; -void itip_view_set_description (ItipView *view, const gchar *description); -const gchar *itip_view_get_description (ItipView *view); + void (* source_selected) (ItipView *view, + ESource *selected_source); -void itip_view_set_start (ItipView *view, struct tm *start, gboolean is_date); -const struct tm *itip_view_get_start (ItipView *view, gboolean *is_date); - -void itip_view_set_end (ItipView *view, struct tm *end, gboolean is_date); -const struct tm *itip_view_get_end (ItipView *view, gboolean *is_date); - -guint itip_view_add_upper_info_item (ItipView *view, ItipViewInfoItemType type, const gchar *message); -guint itip_view_add_upper_info_item_printf (ItipView *view, ItipViewInfoItemType, const gchar *format, ...) G_GNUC_PRINTF (3, 4); -void itip_view_remove_upper_info_item (ItipView *view, guint id); -void itip_view_clear_upper_info_items (ItipView *view); - -guint itip_view_add_lower_info_item (ItipView *view, ItipViewInfoItemType type, const gchar *message); -guint itip_view_add_lower_info_item_printf (ItipView *view, ItipViewInfoItemType type, const gchar *format, ...) G_GNUC_PRINTF (3, 4); -void itip_view_remove_lower_info_item (ItipView *view, guint id); -void itip_view_clear_lower_info_items (ItipView *view); - -void itip_view_set_source_list (ItipView *view, ESourceList *source_list); -ESourceList *itip_view_get_source_list (ItipView *view); - -void itip_view_set_source (ItipView *view, ESource *source); -ESource *itip_view_get_source (ItipView *view); - -void itip_view_set_rsvp (ItipView *view, gboolean rsvp); -gboolean itip_view_get_rsvp (ItipView *view); - -void itip_view_set_show_rsvp (ItipView *view, gboolean rsvp); -gboolean itip_view_get_show_rsvp (ItipView *view); - -void itip_view_set_update (ItipView *view, gboolean update); -gboolean itip_view_get_update (ItipView *view); - -void itip_view_set_show_update (ItipView *view, gboolean update); -gboolean itip_view_get_show_update (ItipView *view); - -void itip_view_set_rsvp_comment (ItipView *view, const gchar *comment); -gchar *itip_view_get_rsvp_comment (ItipView *view); - -void itip_view_set_buttons_sensitive (ItipView *view, gboolean sensitive); -gboolean itip_view_get_buttons_sensitive (ItipView *view); - -void itip_view_set_show_recur_check (ItipView *view, gboolean show); -gboolean itip_view_get_recur_check_state (ItipView *view); - -void itip_view_set_needs_decline (ItipView *view, gboolean needs_decline); - -void itip_view_set_show_free_time_check (ItipView *view, gboolean show); -gboolean itip_view_get_free_time_check_state (ItipView *view); - -void itip_view_set_show_keep_alarm_check (ItipView *view, gboolean show); -gboolean itip_view_get_keep_alarm_check_state (ItipView *view); + void (* response) (ItipView *view, + gint response); +}; -void itip_view_set_show_inherit_alarm_check (ItipView *view, gboolean show); -gboolean itip_view_get_inherit_alarm_check_state (ItipView *view); +GType itip_view_get_type (void); + +ItipView * itip_view_new (ItipPURI *puri); + +void itip_view_write (GString *buffer); + +void itip_view_write_for_printing (ItipView *view, + GString *buffer); + +void itip_view_create_dom_bindings (ItipView *view, + WebKitDOMElement *element); + +ItipPURI * itip_view_get_puri (ItipView *view); + +void itip_view_set_mode (ItipView *view, + ItipViewMode mode); +ItipViewMode itip_view_get_mode (ItipView *view); + +void itip_view_set_item_type (ItipView *view, + ECalClientSourceType type); +ECalClientSourceType + itip_view_get_item_type (ItipView *view); + +void itip_view_set_organizer (ItipView *view, + const gchar *organizer); +const gchar * itip_view_get_organizer (ItipView *view); + +void itip_view_set_organizer_sentby (ItipView *view, + const gchar *sentby); +const gchar * itip_view_get_organizer_sentby (ItipView *view); + +void itip_view_set_attendee (ItipView *view, + const gchar *attendee); +const gchar * itip_view_get_attendee (ItipView *view); + +void itip_view_set_attendee_sentby (ItipView *view, + const gchar *sentby); +const gchar * itip_view_get_attendee_sentby (ItipView *view); + +void itip_view_set_delegator (ItipView *view, + const gchar *delegator); +const gchar * itip_view_get_delegator (ItipView *view); + +void itip_view_set_proxy (ItipView *view, + const gchar *proxy); +const gchar * itip_view_get_proxy (ItipView *view); + +void itip_view_set_summary (ItipView *view, + const gchar *summary); +const gchar * itip_view_get_summary (ItipView *view); + +void itip_view_set_location (ItipView *view, + const gchar *location); +const gchar * itip_view_get_location (ItipView *view); + +void itip_view_set_status (ItipView *view, + const gchar *status); +const gchar * itip_view_get_status (ItipView *view); + +void itip_view_set_comment (ItipView *view, + const gchar *comment); +const gchar * itip_view_get_comment (ItipView *view); + +void itip_view_set_description (ItipView *view, + const gchar *description); +const gchar * itip_view_get_description (ItipView *view); + +void itip_view_set_start (ItipView *view, + struct tm *start, + gboolean is_date); +const struct tm * + itip_view_get_start (ItipView *view, + gboolean *is_date); + +void itip_view_set_end (ItipView *view, + struct tm *end, + gboolean is_date); +const struct tm * + itip_view_get_end (ItipView *view, + gboolean *is_date); + +guint itip_view_add_upper_info_item (ItipView *view, + ItipViewInfoItemType type, + const gchar *message); +guint itip_view_add_upper_info_item_printf + (ItipView *view, + ItipViewInfoItemType, + const gchar *format, ...) G_GNUC_PRINTF (3, 4); +void itip_view_remove_upper_info_item + (ItipView *view, + guint id); +void itip_view_clear_upper_info_items + (ItipView *view); + +guint itip_view_add_lower_info_item (ItipView *view, + ItipViewInfoItemType type, + const gchar *message); +guint itip_view_add_lower_info_item_printf + (ItipView *view, + ItipViewInfoItemType type, + const gchar *format, ...) G_GNUC_PRINTF (3, 4); +void itip_view_remove_lower_info_item + (ItipView *view, + guint id); +void itip_view_clear_lower_info_items + (ItipView *view); + +void itip_view_set_source_list (ItipView *view, + ESourceList *source_list); +ESourceList * itip_view_get_source_list (ItipView *view); + +void itip_view_set_source (ItipView *view, + ESource *source); +ESource * itip_view_get_source (ItipView *view); + +void itip_view_set_rsvp (ItipView *view, + gboolean rsvp); +gboolean itip_view_get_rsvp (ItipView *view); + +void itip_view_set_show_rsvp_check (ItipView *view, + gboolean show); +gboolean itip_view_get_show_rsvp_check (ItipView *view); + +void itip_view_set_update (ItipView *view, + gboolean update); +gboolean itip_view_get_update (ItipView *view); + +void itip_view_set_show_update_check (ItipView *view, + gboolean show); +gboolean itip_view_get_show_update_check (ItipView *view); + +void itip_view_set_rsvp_comment (ItipView *view, + const gchar *comment); +gchar * itip_view_get_rsvp_comment (ItipView *view); + +void itip_view_set_buttons_sensitive (ItipView *view, + gboolean sensitive); +gboolean itip_view_get_buttons_sensitive (ItipView *view); + +void itip_view_set_show_recur_check (ItipView *view, + gboolean show); +gboolean itip_view_get_recur_check_state (ItipView *view); + +void itip_view_set_needs_decline (ItipView *view, + gboolean needs_decline); + +void itip_view_set_show_free_time_check + (ItipView *view, + gboolean show); +gboolean itip_view_get_free_time_check_state + (ItipView *view); + +void itip_view_set_show_keep_alarm_check + (ItipView *view, + gboolean show); +gboolean itip_view_get_keep_alarm_check_state + (ItipView *view); + +void itip_view_set_show_inherit_alarm_check + (ItipView *view, + gboolean show); +gboolean itip_view_get_inherit_alarm_check_state + (ItipView *view); + +void itip_view_set_error (ItipView *view, + const gchar *error_html, + gboolean show_save_btn); G_END_DECLS diff --git a/plugins/mail-to-task/Makefile.am b/plugins/mail-to-task/Makefile.am index 66f6ff5057..da78753556 100644 --- a/plugins/mail-to-task/Makefile.am +++ b/plugins/mail-to-task/Makefile.am @@ -9,8 +9,7 @@ liborg_gnome_mail_to_task_la_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/widgets \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GNOME_PLATFORM_CFLAGS) liborg_gnome_mail_to_task_la_SOURCES = mail-to-task.c @@ -26,8 +25,7 @@ liborg_gnome_mail_to_task_la_LIBADD = \ $(top_builddir)/libemail-utils/libemail-utils.la \ $(top_builddir)/libemail-engine/libemail-engine.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) + $(GNOME_PLATFORM_LIBS) EXTRA_DIST = org-gnome-mail-to-task.eplug.xml diff --git a/plugins/mail-to-task/mail-to-task.c b/plugins/mail-to-task/mail-to-task.c index 6cf942acb4..09ec15d6ef 100644 --- a/plugins/mail-to-task/mail-to-task.c +++ b/plugins/mail-to-task/mail-to-task.c @@ -32,7 +32,6 @@ #include <string.h> #include <glib/gi18n-lib.h> -#include <gtkhtml/gtkhtml.h> #include <libecal/e-cal-client.h> #include <libecal/e-cal-component.h> #include <libedataserver/e-account.h> @@ -1062,18 +1061,16 @@ text_contains_nonwhitespace (const gchar *text, static gchar * get_selected_text (EMailReader *reader) { - EMFormatHTML *formatter; - EWebView *web_view; + EMailDisplay *display; gchar *text = NULL; gint len; - formatter = e_mail_reader_get_formatter (reader); - web_view = em_format_html_get_web_view (formatter); + display = e_mail_reader_get_mail_display (reader); - if (!e_web_view_is_selection_active (web_view)) + if (!e_web_view_is_selection_active (E_WEB_VIEW (display))) return NULL; - text = gtk_html_get_selection_plain_text (GTK_HTML (web_view), &len); + text = e_mail_display_get_selection_plain_text (display, &len); if (text == NULL || !text_contains_nonwhitespace (text, len)) { g_free (text); diff --git a/plugins/mark-all-read/Makefile.am b/plugins/mark-all-read/Makefile.am index 739601ce57..4740bff5fb 100644 --- a/plugins/mark-all-read/Makefile.am +++ b/plugins/mark-all-read/Makefile.am @@ -9,8 +9,7 @@ liborg_gnome_mark_all_read_la_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/widgets \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GNOME_PLATFORM_CFLAGS) liborg_gnome_mark_all_read_la_SOURCES = mark-all-read.c @@ -22,8 +21,7 @@ liborg_gnome_mark_all_read_la_LIBADD = \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/libevolution-utils/libevolution-utils.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) + $(GNOME_PLATFORM_LIBS) EXTRA_DIST = org-gnome-mark-all-read.eplug.xml diff --git a/plugins/prefer-plain/prefer-plain.c b/plugins/prefer-plain/prefer-plain.c index 4b1ac49010..5793370374 100644 --- a/plugins/prefer-plain/prefer-plain.c +++ b/plugins/prefer-plain/prefer-plain.c @@ -49,14 +49,12 @@ static gboolean epp_show_suppressed = TRUE; static void make_part_attachment (EMFormat *format, - CamelStream *stream, - CamelMimePart *part, - gint i) + CamelMimePart *part, + GString *part_id, + gboolean force_html, + GCancellable *cancellable) { - gint partidlen = format->part_id->len; - - if (i != -1) - g_string_append_printf (format->part_id, ".alternative-prefer-plain.%d", i); + EMFormatParserInfo info = {0}; if (camel_content_type_is (camel_mime_part_get_content_type (part), "text", "html")) { /* always show HTML as attachments and not inline */ @@ -68,11 +66,9 @@ make_part_attachment (EMFormat *format, g_free (str); } - /* FIXME Not passing a GCancellable here. */ - em_format_part_as ( - format, stream, part, - "application/octet-stream", NULL); - } else if (i == -1 && CAMEL_IS_MIME_MESSAGE (part)) { + em_format_parse_part_as ( + format, part, part_id, &info, "application/octet-stream", cancellable); + } else if (force_html && CAMEL_IS_MIME_MESSAGE (part)) { /* message was asked to be formatted as text/html; * might be for cases where message itself is a text/html part */ CamelMimePart *new_part; @@ -84,15 +80,12 @@ make_part_attachment (EMFormat *format, new_part = camel_mime_part_new (); camel_medium_set_content (CAMEL_MEDIUM (new_part), content); - em_format_part (format, stream, new_part, NULL); + em_format_parse_part (format, new_part, part_id, &info, cancellable); g_object_unref (new_part); } else { - /* FIXME Not passing a GCancellable here. */ - em_format_part (format, stream, part, NULL); + em_format_parse_part (format, part, part_id, &info, cancellable); } - - g_string_truncate (format->part_id, partidlen); } void @@ -101,28 +94,30 @@ org_gnome_prefer_plain_text_html (gpointer ep, { /* In text-only mode, all html output is suppressed for the first processing */ if (epp_mode != EPP_TEXT - || strstr (t->format->part_id->str, ".alternative-prefer-plain.") != NULL - || em_format_is_inline (t->format, t->format->part_id->str, t->part, &(t->item->handler))) + || strstr (t->part_id->str, ".alternative-prefer-plain.") != NULL + || em_format_is_inline (t->format, t->part_id->str, t->part, t->info->handler)) { /* FIXME Not passing a GCancellable here. */ - t->item->handler.old->handler ( - t->format, t->stream, t->part, - t->item->handler.old, NULL, FALSE); - else if (epp_show_suppressed) - make_part_attachment (t->format, t->stream, t->part, -1); + t->info->handler->old->parse_func ( + t->format, t->part, t->part_id, + t->info, NULL); + } else if (epp_show_suppressed) + make_part_attachment (t->format, t->part, t->part_id, TRUE, NULL); } static void export_as_attachments (CamelMultipart *mp, - EMFormat *format, - CamelStream *stream, - CamelMimePart *except) + EMFormat *format, + CamelMimePart *except, + GString *part_id) { gint i, nparts; CamelMimePart *part; + gint len; if (!mp || !CAMEL_IS_MULTIPART (mp)) return; + len = part_id->len; nparts = camel_multipart_get_number (mp); for (i = 0; i < nparts; i++) { part = camel_multipart_get_part (mp, i); @@ -130,11 +125,13 @@ export_as_attachments (CamelMultipart *mp, if (part != except) { CamelMultipart *multipart = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part); + g_string_append_printf (part_id, ".aleternative-prefer-plain.%d", i); if (CAMEL_IS_MULTIPART (multipart)) { - export_as_attachments (multipart, format, stream, except); + export_as_attachments (multipart, format, except, part_id); } else { - make_part_attachment (format, stream, part, i); + make_part_attachment (format, part, part_id, FALSE, NULL); } + g_string_truncate (part_id, len); } } } @@ -147,8 +144,7 @@ org_gnome_prefer_plain_multipart_alternative (gpointer ep, CamelMimePart *part, *display_part = NULL, *calendar_part = NULL; gint i, nparts, partidlen, displayid = 0, calendarid = 0; - /* FIXME: this part-id stuff is poking private data, needs api */ - partidlen = t->format->part_id->len; + partidlen = t->part_id->len; if (epp_mode == EPP_NORMAL) { gboolean have_plain = FALSE; @@ -185,21 +181,20 @@ org_gnome_prefer_plain_multipart_alternative (gpointer ep, } if (display_part && have_plain && nparts == 2) { - g_string_append_printf (t->format->part_id, ".alternative-prefer-plain.%d", displayid); + g_string_append_printf (t->part_id, ".alternative-prefer-plain.%d", displayid); /* FIXME Not passing a GCancellable here. */ - em_format_part_as ( - t->format, t->stream, - display_part, "text/html", NULL); - g_string_truncate (t->format->part_id, partidlen); + em_format_parse_part_as ( + t->format, display_part, t->part_id, t->info, "text/html", NULL); + g_string_truncate (t->part_id, partidlen); } else { /* FIXME Not passing a GCancellable here. */ - t->item->handler.old->handler ( - t->format, t->stream, t->part, - t->item->handler.old, NULL, FALSE); + t->info->handler->old->parse_func ( + t->format, t->part, t->part_id, t->info, NULL); } return; } else if (!CAMEL_IS_MULTIPART (mp)) { - em_format_format_source (t->format, t->stream, t->part, NULL); + /* FIXME Not passing GCancellable here. */ + em_format_parse_part_as (t->format, t->part, t->part_id, t->info, "x-evolution/message/source", NULL); return; } @@ -224,21 +219,22 @@ org_gnome_prefer_plain_multipart_alternative (gpointer ep, /* if we found a text part, show it */ if (display_part) { - g_string_append_printf(t->format->part_id, ".alternative-prefer-plain.%d", displayid); + g_string_append_printf(t->part_id, ".alternative-prefer-plain.%d", displayid); /* FIXME Not passing a GCancellable here. */ - em_format_part_as ( - t->format, t->stream, - display_part, "text/plain", NULL); - g_string_truncate (t->format->part_id, partidlen); + em_format_parse_part_as ( + t->format, display_part, t->part_id, t->info, "text/plain", NULL); + g_string_truncate (t->part_id, partidlen); } /* all other parts are attachments */ if (epp_show_suppressed) - export_as_attachments (mp, t->format, t->stream, display_part); - else if (calendar_part) - make_part_attachment (t->format, t->stream, calendar_part, calendarid); + export_as_attachments (mp, t->format, display_part, t->part_id); + else if (calendar_part) { + g_string_append_printf(t->part_id, ".alternative-prefer-plain.%d", calendarid); + make_part_attachment (t->format, calendar_part, t->part_id, FALSE, NULL); + } - g_string_truncate (t->format->part_id, partidlen); + g_string_truncate (t->part_id, partidlen); } static struct { diff --git a/plugins/pst-import/Makefile.am b/plugins/pst-import/Makefile.am index 5aeb114e90..b81e0d29c2 100644 --- a/plugins/pst-import/Makefile.am +++ b/plugins/pst-import/Makefile.am @@ -18,7 +18,6 @@ liborg_gnome_pst_import_la_CPPFLAGS = \ -I$(top_builddir) \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) \ $(LIBPST_CFLAGS) liborg_gnome_pst_import_la_SOURCES = pst-importer.c @@ -34,7 +33,6 @@ liborg_gnome_pst_import_la_LIBADD = \ $(top_builddir)/libevolution-utils/libevolution-utils.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) \ $(LIBPST_LIBS) EXTRA_DIST = org-gnome-pst-import.eplug.xml diff --git a/plugins/tnef-attachments/Makefile.am b/plugins/tnef-attachments/Makefile.am index 250453d740..6a393044d1 100644 --- a/plugins/tnef-attachments/Makefile.am +++ b/plugins/tnef-attachments/Makefile.am @@ -16,7 +16,6 @@ liborg_gnome_tnef_attachments_la_CPPFLAGS = \ -I$(top_srcdir)/widgets \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) \ $(TNEF_CFLAGS) liborg_gnome_tnef_attachments_la_SOURCES = tnef-plugin.c @@ -28,7 +27,6 @@ liborg_gnome_tnef_attachments_la_LIBADD = \ $(top_builddir)/em-format/libemformat.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) \ -lytnef EXTRA_DIST = org-gnome-tnef-attachments.eplug.xml diff --git a/plugins/tnef-attachments/tnef-plugin.c b/plugins/tnef-attachments/tnef-plugin.c index 5ef2f270b4..0621c12dd3 100644 --- a/plugins/tnef-attachments/tnef-plugin.c +++ b/plugins/tnef-attachments/tnef-plugin.c @@ -92,6 +92,7 @@ org_gnome_format_tnef (gpointer ep, CamelMultipart *mp; CamelMimePart *mainpart; CamelDataWrapper *content; + const EMFormatHandler *handler; gint len; TNEFStruct tnef; @@ -102,15 +103,21 @@ org_gnome_format_tnef (gpointer ep, name = g_build_filename(tmpdir, ".evo-attachment.tnef", NULL); out = camel_stream_fs_new_with_name (name, O_RDWR | O_CREAT, 0666, NULL); - if (out == NULL) - goto fail; + if (out == NULL) { + g_free (name); + return; + } content = camel_medium_get_content ((CamelMedium *) t->part); - if (content == NULL) - goto fail; + if (content == NULL) { + g_free (name); + g_object_unref (out); + return; + } if (camel_data_wrapper_decode_to_stream_sync (content, out, NULL, NULL) == -1 || camel_stream_close (out, NULL, NULL) == -1) { g_object_unref (out); - goto fail; + g_free (name); + return; } g_object_unref (out); @@ -126,8 +133,11 @@ org_gnome_format_tnef (gpointer ep, /* Extraction done */ dir = opendir (tmpdir); - if (dir == NULL) - goto fail; + if (dir == NULL) { + g_object_unref (out); + g_free (name); + return; + } mainpart = camel_mime_part_new (); @@ -177,33 +187,26 @@ org_gnome_format_tnef (gpointer ep, closedir (dir); - len = t->format->part_id->len; - g_string_append_printf(t->format->part_id, ".tnef"); - - if (camel_multipart_get_number (mp) > 0) - /* FIXME Not passing a GCancellable here. */ - em_format_part_as ( - t->format, t->stream, mainpart, - "multipart/mixed", NULL); - else if (t->item->handler.old) - /* FIXME Not passing a GCancellable here. */ - t->item->handler.old->handler ( - t->format, t->stream, t->part, - t->item->handler.old, NULL, FALSE); + len = t->part_id->len; + g_string_append_printf(t->part_id, ".tnef"); + + if (camel_multipart_get_number (mp) > 0) { + handler = em_format_find_handler (t->format, "multiplart/mixed"); + /* FIXME Not passing a GCancellable here. */ + if (handler && handler->parse_func) { + CamelMimePart *part = camel_mime_part_new (); + camel_medium_set_content ((CamelMedium *) part, + CAMEL_DATA_WRAPPER (mp)); + handler->parse_func (t->format, part, t->part_id, t->info, NULL); + g_object_unref (part); + } + } - g_string_truncate (t->format->part_id, len); + g_string_truncate (t->part_id, len); g_object_unref (mp); g_object_unref (mainpart); - goto ok; - fail: - if (t->item->handler.old) - /* FIXME Not passing a GCancellable here. */ - t->item->handler.old->handler ( - t->format, t->stream, t->part, - t->item->handler.old, NULL, FALSE); - ok: g_free (name); g_free (tmpdir); } diff --git a/plugins/vcard-inline/Makefile.am b/plugins/vcard-inline/Makefile.am index 07b747af79..afde012ddf 100644 --- a/plugins/vcard-inline/Makefile.am +++ b/plugins/vcard-inline/Makefile.am @@ -16,8 +16,7 @@ liborg_gnome_vcard_inline_la_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/widgets \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(GTKHTML_CFLAGS) + $(GNOME_PLATFORM_CFLAGS) liborg_gnome_vcard_inline_la_SOURCES = vcard-inline.c @@ -29,9 +28,9 @@ liborg_gnome_vcard_inline_la_LIBADD = \ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ $(top_builddir)/addressbook/printing/libecontactprint.la \ + $(top_builddir)/em-format/libemformat.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(GTKHTML_LIBS) + $(GNOME_PLATFORM_LIBS) EXTRA_DIST = org-gnome-vcard-inline.eplug.xml diff --git a/plugins/vcard-inline/vcard-inline.c b/plugins/vcard-inline/vcard-inline.c index cfe461b163..7d83ab2b34 100644 --- a/plugins/vcard-inline/vcard-inline.c +++ b/plugins/vcard-inline/vcard-inline.c @@ -24,30 +24,33 @@ #include <glib/gi18n-lib.h> #include <libebook/e-book-client.h> #include <libebook/e-contact.h> -#include <gtkhtml/gtkhtml-embedded.h> #include <libedataserverui/e-client-utils.h> #include <libedataserverui/e-source-selector-dialog.h> #include "addressbook/gui/merging/eab-contact-merging.h" -#include "addressbook/gui/widgets/eab-contact-display.h" +#include "addressbook/gui/widgets/eab-contact-formatter.h" #include "addressbook/util/eab-book-util.h" #include "mail/em-format-hook.h" #include "mail/em-format-html.h" +#include "mail/e-mail-display.h" #define d(x) -typedef struct _VCardInlinePObject VCardInlinePObject; +typedef struct _VCardInlinePURI VCardInlinePURI; -struct _VCardInlinePObject { - EMFormatHTMLPObject object; +struct _VCardInlinePURI { + EMFormatPURI puri; GSList *contact_list; ESourceList *source_list; GtkWidget *contact_display; GtkWidget *message_label; -}; -static gint org_gnome_vcard_inline_classid; + EABContactFormatter *formatter; + WebKitDOMElement *iframe; + WebKitDOMElement *toggle_button; + WebKitDOMElement *save_button; +}; /* Forward Declarations */ void org_gnome_vcard_inline_format (gpointer ep, EMFormatHookTarget *target); @@ -61,11 +64,11 @@ e_plugin_lib_enable (EPlugin *ep, } static void -org_gnome_vcard_inline_pobject_free (EMFormatHTMLPObject *object) +org_gnome_vcard_inline_pobject_free (EMFormatPURI *object) { - VCardInlinePObject *vcard_object; + VCardInlinePURI *vcard_object; - vcard_object = (VCardInlinePObject *) object; + vcard_object = (VCardInlinePURI *) object; e_client_util_free_object_slist (vcard_object->contact_list); vcard_object->contact_list = NULL; @@ -84,10 +87,30 @@ org_gnome_vcard_inline_pobject_free (EMFormatHTMLPObject *object) g_object_unref (vcard_object->message_label); vcard_object->message_label = NULL; } + + if (vcard_object->formatter != NULL) { + g_object_unref (vcard_object->formatter); + vcard_object->formatter = NULL; + } + + if (vcard_object->iframe != NULL) { + g_object_unref (vcard_object->iframe); + vcard_object->iframe = NULL; + } + + if (vcard_object->toggle_button != NULL) { + g_object_unref (vcard_object->toggle_button); + vcard_object->toggle_button = NULL; + } + + if (vcard_object->save_button != NULL) { + g_object_unref (vcard_object->save_button); + vcard_object->save_button = NULL; + } } static void -org_gnome_vcard_inline_decode (VCardInlinePObject *vcard_object, +org_gnome_vcard_inline_decode (VCardInlinePURI *vcard_object, CamelMimePart *mime_part) { CamelDataWrapper *data_wrapper; @@ -157,7 +180,9 @@ org_gnome_vcard_inline_client_loaded_cb (ESource *source, } static void -org_gnome_vcard_inline_save_cb (VCardInlinePObject *vcard_object) +org_gnome_vcard_inline_save_cb (WebKitDOMEventTarget *button, + WebKitDOMEvent *event, + VCardInlinePURI *vcard_object) { ESource *source; GSList *contact_list; @@ -192,159 +217,223 @@ org_gnome_vcard_inline_save_cb (VCardInlinePObject *vcard_object) } static void -org_gnome_vcard_inline_toggle_cb (VCardInlinePObject *vcard_object, - GtkButton *button) +org_gnome_vcard_inline_toggle_cb (WebKitDOMEventTarget *button, + WebKitDOMEvent *event, + EMFormatPURI *puri) { - EABContactDisplay *contact_display; + VCardInlinePURI *vcard_object; EABContactDisplayMode mode; - const gchar *label; + gchar *uri; - contact_display = EAB_CONTACT_DISPLAY (vcard_object->contact_display); - mode = eab_contact_display_get_mode (contact_display); + vcard_object = (VCardInlinePURI *) puri; - /* Toggle between "full" and "compact" modes. */ + mode = eab_contact_formatter_get_display_mode (vcard_object->formatter); if (mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL) { mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT; - label = _("Show Full vCard"); + + webkit_dom_html_element_set_inner_text ( + WEBKIT_DOM_HTML_ELEMENT (button), + _("Show Full vCard"), NULL); + } else { mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; - label = _("Show Compact vCard"); + + webkit_dom_html_element_set_inner_text ( + WEBKIT_DOM_HTML_ELEMENT (button), + _("Show Compact vCard"), NULL); } - eab_contact_display_set_mode (contact_display, mode); - gtk_button_set_label (button, label); + eab_contact_formatter_set_display_mode (vcard_object->formatter, mode); + + uri = em_format_build_mail_uri ( + puri->emf->folder, puri->emf->message_uid, + "part_id", G_TYPE_STRING, puri->uri, + "mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, NULL); + + webkit_dom_html_iframe_element_set_src ( + WEBKIT_DOM_HTML_IFRAME_ELEMENT (vcard_object->iframe), uri); + + g_free (uri); } -static gboolean -org_gnome_vcard_inline_embed (EMFormatHTML *format, - GtkHTMLEmbedded *embedded, - EMFormatHTMLPObject *object) +static void +org_gnome_vcard_inline_bind_dom (WebKitDOMElement *attachment, + EMFormatPURI *puri) { - VCardInlinePObject *vcard_object; - GtkWidget *button_box; - GtkWidget *container; - GtkWidget *widget; - EContact *contact; - guint length; - - vcard_object = (VCardInlinePObject *) object; - length = g_slist_length (vcard_object->contact_list); - - if (vcard_object->contact_list != NULL) - contact = E_CONTACT (vcard_object->contact_list->data); - else - contact = NULL; - - container = GTK_WIDGET (embedded); - - widget = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = widget; - - widget = gtk_hbutton_box_new (); - gtk_button_box_set_layout ( - GTK_BUTTON_BOX (widget), GTK_BUTTONBOX_START); - gtk_box_set_spacing (GTK_BOX (widget), 12); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); - gtk_widget_show (widget); - - button_box = widget; - - widget = eab_contact_display_new (); - eab_contact_display_set_contact ( - EAB_CONTACT_DISPLAY (widget), contact); - eab_contact_display_set_mode ( - EAB_CONTACT_DISPLAY (widget), - EAB_CONTACT_DISPLAY_RENDER_COMPACT); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - vcard_object->contact_display = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_label_new (NULL); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - vcard_object->message_label = g_object_ref (widget); - - if (length == 2) { - const gchar *text; - - text = _("There is one other contact."); - gtk_label_set_text (GTK_LABEL (widget), text); - gtk_widget_show (widget); - - } else if (length > 2) { - gchar *text; - - /* Translators: This will always be two or more. */ - text = g_strdup_printf (ngettext ( - "There is %d other contact.", - "There are %d other contacts.", - length - 1), length - 1); - gtk_label_set_text (GTK_LABEL (widget), text); - gtk_widget_show (widget); - g_free (text); - - } else - gtk_widget_hide (widget); - - container = button_box; - - widget = gtk_button_new_with_label (_("Show Full vCard")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (org_gnome_vcard_inline_toggle_cb), - vcard_object); - - widget = gtk_button_new_with_label (_("Save in Address Book")); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - - /* This depends on having a source list. */ - if (vcard_object->source_list != NULL) - gtk_widget_show (widget); - else - gtk_widget_hide (widget); - - g_signal_connect_swapped ( - widget, "clicked", - G_CALLBACK (org_gnome_vcard_inline_save_cb), - vcard_object); - - return TRUE; + WebKitDOMNodeList *list; + WebKitDOMElement *iframe, *toggle_button, *save_button; + VCardInlinePURI *vcard_object; + + vcard_object = (VCardInlinePURI *) puri; + + /* IFRAME */ + list = webkit_dom_element_get_elements_by_tag_name (attachment, "iframe"); + if (webkit_dom_node_list_get_length (list) != 1) + return; + iframe = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0)); + if (vcard_object->iframe) + g_object_unref (vcard_object->iframe); + vcard_object->iframe = g_object_ref (iframe); + + /* TOGGLE DISPLAY MODE BUTTON */ + list = webkit_dom_element_get_elements_by_class_name ( + attachment, "org-gnome-vcard-inline-display-mode-button"); + if (webkit_dom_node_list_get_length (list) != 1) + return; + toggle_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0)); + if (vcard_object->toggle_button) + g_object_unref (vcard_object->toggle_button); + vcard_object->toggle_button = g_object_ref (toggle_button); + + /* SAVE TO ADDRESSBOOK BUTTON */ + list = webkit_dom_element_get_elements_by_class_name ( + attachment, "org-gnome-vcard-inline-save-button"); + if (webkit_dom_node_list_get_length (list) != 1) + return; + save_button = WEBKIT_DOM_ELEMENT (webkit_dom_node_list_item (list, 0)); + if (vcard_object->save_button) + g_object_unref (vcard_object->save_button); + vcard_object->save_button = g_object_ref (save_button); + + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (toggle_button), + "click", G_CALLBACK (org_gnome_vcard_inline_toggle_cb), + FALSE, puri); + + webkit_dom_event_target_add_event_listener ( + WEBKIT_DOM_EVENT_TARGET (save_button), + "click", G_CALLBACK (org_gnome_vcard_inline_save_cb), + FALSE, puri); +} + +static void +org_gnome_vcard_inline_write (EMFormat *emf, + EMFormatPURI *puri, + CamelStream *stream, + EMFormatWriterInfo *info, + GCancellable *cancellable) +{ + VCardInlinePURI *vpuri; + + vpuri = (VCardInlinePURI *) puri; + + if (info->mode == EM_FORMAT_WRITE_MODE_RAW) { + + EContact *contact; + + if (vpuri->contact_list != NULL) + contact = E_CONTACT (vpuri->contact_list->data); + else + contact = NULL; + + eab_contact_formatter_format_contact_sync ( + vpuri->formatter, contact, stream, cancellable); + + } else { + gchar *str, *uri; + gint length; + const gchar *label = NULL; + EABContactDisplayMode mode; + const gchar *info = NULL; + + length = g_slist_length (vpuri->contact_list); + if (length < 1) + return; + + uri = em_format_build_mail_uri ( + emf->folder, emf->message_uid, + "part_id", G_TYPE_STRING, puri->uri, + "mode", G_TYPE_INT, EM_FORMAT_WRITE_MODE_RAW, NULL); + + mode = eab_contact_formatter_get_display_mode (vpuri->formatter); + if (mode == EAB_CONTACT_DISPLAY_RENDER_COMPACT) { + mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; + label =_("Show Full vCard"); + } else { + mode = EAB_CONTACT_DISPLAY_RENDER_COMPACT; + label = _("Show Compact vCard"); + } + + str = g_strdup_printf ( + "<div id=\"%s\">" + "<button type=\"button\" " + "name=\"set-display-mode\" " + "class=\"org-gnome-vcard-inline-display-mode-button\" " + "value=\"%d\">%s</button>" + "<button type=\"button\" " + "name=\"save-to-addressbook\" " + "class=\"org-gnome-vcard-inline-save-button\" " + "value=\"%s\">%s</button><br/>" + "<iframe width=\"100%%\" height=\"auto\" frameborder=\"0\"" + "src=\"%s\" name=\"%s\"></iframe>" + "</div>", + puri->uri, + mode, label, + puri->uri, _("Save To Addressbook"), + uri, puri->uri); + + camel_stream_write_string (stream, str, cancellable, NULL); + + g_free (str); + + if (length == 2) { + + info = _("There is one other contact."); + + } else if (length > 2) { + + /* Translators: This will always be two or more. */ + info = g_strdup_printf (ngettext ( + "There is %d other contact.", + "There are %d other contacts.", + length - 1), length - 1); + } + + if (info) { + + str = g_strdup_printf ( + "<div class=\"attachment-info\">%s</div>", + info); + + camel_stream_write_string (stream, str, cancellable, NULL); + + g_free (str); + } + + g_free (uri); + } } void org_gnome_vcard_inline_format (gpointer ep, EMFormatHookTarget *target) { - VCardInlinePObject *vcard_object; - gchar *classid; - gchar *content; - - classid = g_strdup_printf ( - "org-gnome-vcard-inline-display-%d", - org_gnome_vcard_inline_classid++); - - vcard_object = (VCardInlinePObject *) - em_format_html_add_pobject ( - EM_FORMAT_HTML (target->format), - sizeof (VCardInlinePObject), - classid, target->part, - org_gnome_vcard_inline_embed); + VCardInlinePURI *vcard_object; + gint len; + + len = target->part_id->len; + g_string_append (target->part_id, ".org-gnome-vcard-inline-display"); + + vcard_object = (VCardInlinePURI *) em_format_puri_new ( + target->format, sizeof (VCardInlinePURI), + target->part, target->part_id->str); + vcard_object->puri.mime_type = g_strdup("text/html"); + vcard_object->puri.write_func = org_gnome_vcard_inline_write; + vcard_object->puri.bind_func = org_gnome_vcard_inline_bind_dom; + vcard_object->puri.free = org_gnome_vcard_inline_pobject_free; + vcard_object->puri.is_attachment = true; + vcard_object->formatter + = g_object_new ( + EAB_TYPE_CONTACT_FORMATTER, + "display-mode", EAB_CONTACT_DISPLAY_RENDER_COMPACT, + "render-maps", FALSE, NULL); + + em_format_add_puri (target->format, (EMFormatPURI *) vcard_object); g_object_ref (target->part); - vcard_object->object.free = org_gnome_vcard_inline_pobject_free; org_gnome_vcard_inline_decode (vcard_object, target->part); - e_book_client_get_sources (&vcard_object->source_list, NULL); - content = g_strdup_printf ("<object classid=%s></object>", classid); - camel_stream_write_string (target->stream, content, NULL, NULL); - g_free (content); - - g_free (classid); + g_string_truncate (target->part_id, len); } |