diff options
-rw-r--r-- | addressbook/gui/component/e-book-shell-module.c | 6 | ||||
-rw-r--r-- | doc/reference/shell/eshell-sections.txt | 1 | ||||
-rw-r--r-- | e-util/e-binding.c | 52 | ||||
-rw-r--r-- | e-util/e-binding.h | 13 | ||||
-rw-r--r-- | e-util/e-util.c | 24 | ||||
-rw-r--r-- | e-util/e-util.h | 1 | ||||
-rw-r--r-- | mail/e-mail-reader.c | 83 | ||||
-rw-r--r-- | mail/e-mail-shell-module-settings.c | 42 | ||||
-rw-r--r-- | mail/e-mail-shell-view-actions.c | 18 | ||||
-rw-r--r-- | mail/e-mail-shell-view-private.h | 2 | ||||
-rw-r--r-- | mail/em-folder-view.c | 259 | ||||
-rw-r--r-- | mail/em-format-html-display.c | 275 | ||||
-rw-r--r-- | mail/em-format-html-display.h | 115 | ||||
-rw-r--r-- | mail/em-format-html-print.c | 4 | ||||
-rw-r--r-- | mail/em-format-html.c | 795 | ||||
-rw-r--r-- | mail/em-format-html.h | 183 | ||||
-rw-r--r-- | mail/em-format.c | 259 | ||||
-rw-r--r-- | mail/em-format.h | 219 | ||||
-rw-r--r-- | mail/em-mailer-prefs.c | 36 | ||||
-rw-r--r-- | mail/mail-config.h | 29 | ||||
-rw-r--r-- | shell/e-shell-migrate.c | 14 | ||||
-rw-r--r-- | shell/e-shell-window-private.c | 14 | ||||
-rw-r--r-- | shell/e-shell.c | 27 | ||||
-rw-r--r-- | shell/e-shell.h | 2 |
24 files changed, 1628 insertions, 845 deletions
diff --git a/addressbook/gui/component/e-book-shell-module.c b/addressbook/gui/component/e-book-shell-module.c index bc224a93ad..0197661326 100644 --- a/addressbook/gui/component/e-book-shell-module.c +++ b/addressbook/gui/component/e-book-shell-module.c @@ -260,6 +260,7 @@ static void action_contact_new_cb (GtkAction *action, EShellWindow *shell_window) { + EShell *shell; EBook *book = NULL; GConfClient *client; ESourceList *source_list; @@ -273,10 +274,11 @@ action_contact_new_cb (GtkAction *action, return; } - client = gconf_client_get_default (); + shell = e_shell_window_get_shell (shell_window); + client = e_shell_get_gconf_client (shell); + key = "/apps/evolution/addressbook/display/primary_addressbook"; uid = gconf_client_get_string (client, key, NULL); - g_object_unref (client); if (uid != NULL) { ESource *source; diff --git a/doc/reference/shell/eshell-sections.txt b/doc/reference/shell/eshell-sections.txt index 14213d2806..9f881ac65d 100644 --- a/doc/reference/shell/eshell-sections.txt +++ b/doc/reference/shell/eshell-sections.txt @@ -8,6 +8,7 @@ e_shell_get_canonical_name e_shell_get_module_by_name e_shell_get_module_by_scheme e_shell_get_shell_settings +e_shell_get_gconf_client e_shell_create_shell_window e_shell_handle_uris e_shell_watch_window diff --git a/e-util/e-binding.c b/e-util/e-binding.c index 26e62c6a23..26e23ee792 100644 --- a/e-util/e-binding.c +++ b/e-util/e-binding.c @@ -480,3 +480,55 @@ e_mutual_binding_unbind (EMutualBinding *binding) g_signal_handler_disconnect ( binding->reverse.dst_object, binding->direct.handler); } + +/** + * e_binding_transform_color_to_string: + * @src_value: a #GValue of type #GDK_TYPE_COLOR + * @dst_value: a #GValue of type #G_TYPE_STRING + * @user_data: not used + * + * Transforms a #GdkColor value to a color string specification. + * + * Returns: %TRUE always + **/ +gboolean +e_binding_transform_color_to_string (const GValue *src_value, + GValue *dst_value, + gpointer user_data) +{ + const GdkColor *color; + gchar *string; + + color = g_value_get_boxed (src_value); + string = gdk_color_to_string (color); + g_value_set_string (dst_value, string); + g_free (string); + + return TRUE; +} + +/** + * e_binding_transform_string_to_color: + * @src_value: a #GValue of type #G_TYPE_STRING + * @dst_value: a #GValue of type #GDK_TYPE_COLOR + * @user_data: not used + * + * Transforms a color string specification to a #GdkColor. + * + * Returns: %TRUE if color string specification was valid + **/ +gboolean +e_binding_transform_string_to_color (const GValue *src_value, + GValue *dst_value, + gpointer user_data) +{ + GdkColor color; + const gchar *string; + gboolean success; + + string = g_value_get_string (src_value); + if (gdk_color_parse (string, &color)) + g_value_set_boxed (dst_value, &color); + + return success; +} diff --git a/e-util/e-binding.h b/e-util/e-binding.h index 2cced75920..676093bfad 100644 --- a/e-util/e-binding.h +++ b/e-util/e-binding.h @@ -26,7 +26,7 @@ #ifndef E_BINDING_H #define E_BINDING_H -#include <glib-object.h> +#include <gdk/gdk.h> G_BEGIN_DECLS @@ -102,6 +102,17 @@ EMutualBinding *e_mutual_binding_new_with_negation const gchar *property2); void e_mutual_binding_unbind (EMutualBinding *binding); + +/* Useful transformation functions */ +gboolean e_binding_transform_color_to_string + (const GValue *src_value, + GValue *dst_value, + gpointer user_data); +gboolean e_binding_transform_string_to_color + (const GValue *src_value, + GValue *dst_value, + gpointer user_data); + G_END_DECLS #endif /* E_BINDING_H */ diff --git a/e-util/e-util.c b/e-util/e-util.c index a5e6c6b548..c65fcbceaf 100644 --- a/e-util/e-util.c +++ b/e-util/e-util.c @@ -432,6 +432,30 @@ e_write_file_uri (const gchar *filename, const gchar *data) return res; } +/** + * e_color_to_value: + * color: a #GdkColor + * + * Converts a #GdkColor to a 24-bit RGB color value. + * + * Returns: a 24-bit color value + **/ +guint32 +e_color_to_value (GdkColor *color) +{ + guint16 red; + guint16 green; + guint16 blue; + + g_return_val_if_fail (color != NULL, 0); + + red = color->red >> 8; + green = color->green >> 8; + blue = color->blue >> 8; + + return (guint32) (((red << 16) | (green << 8) | blue) & 0xffffff); +} + static gint epow10 (gint number) { diff --git a/e-util/e-util.h b/e-util/e-util.h index 28d7a50a39..65e492850f 100644 --- a/e-util/e-util.h +++ b/e-util/e-util.h @@ -64,6 +64,7 @@ gint e_int_compare (gconstpointer x, gconstpointer y); gboolean e_write_file_uri (const gchar *filename, const gchar *data); +guint32 e_color_to_value (GdkColor *color); /* This only makes a filename safe for usage as a filename. * It still may have shell meta-characters in it. */ diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index 456e046152..ab7c86c160 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -95,19 +95,6 @@ exit: } static void -action_mail_caret_mode_cb (GtkToggleAction *action, - EMailReader *reader) -{ - EMFormatHTMLDisplay *html_display; - gboolean active; - - active = gtk_toggle_action_get_active (action); - html_display = e_mail_reader_get_html_display (reader); - - em_format_html_display_set_caret_mode (html_display, active); -} - -static void action_mail_charset_cb (GtkRadioAction *action, GtkRadioAction *current, EMailReader *reader) @@ -122,7 +109,7 @@ action_mail_charset_cb (GtkRadioAction *action, charset = g_object_get_data (G_OBJECT (action), "charset"); /* Charset for "Default" action will be NULL. */ - em_format_set_charset ((EMFormat *) html_display, charset); + em_format_set_charset (EM_FORMAT (html_display), charset); } static void @@ -149,7 +136,7 @@ action_mail_clipboard_copy_cb (GtkAction *action, GtkHTML *html; html_display = e_mail_reader_get_html_display (reader); - html = ((EMFormatHTML *) html_display)->html; + html = EM_FORMAT_HTML (html_display)->html; gtk_html_copy (html); } @@ -300,7 +287,7 @@ action_mail_flag_clear_cb (GtkAction *action, em_utils_flag_for_followup_clear (window, folder, uids); - em_format_redraw ((EMFormat *) html_display); + em_format_redraw (EM_FORMAT (html_display)); } static void @@ -322,7 +309,7 @@ action_mail_flag_completed_cb (GtkAction *action, em_utils_flag_for_followup_completed (window, folder, uids); - em_format_redraw ((EMFormat *) html_display); + em_format_redraw (EM_FORMAT (html_display)); } static void @@ -443,7 +430,7 @@ action_mail_load_images_cb (GtkAction *action, html_display = e_mail_reader_get_html_display (reader); - em_format_html_load_http ((EMFormatHTML *) html_display); + em_format_html_load_images (EM_FORMAT_HTML (html_display)); } static void @@ -880,7 +867,7 @@ action_mail_select_all_cb (GtkAction *action, gboolean selection_active; html_display = e_mail_reader_get_html_display (reader); - html = ((EMFormatHTML *) html_display)->html; + html = EM_FORMAT_HTML (html_display)->html; gtk_html_select_all (html); @@ -904,7 +891,7 @@ action_mail_show_all_headers_cb (GtkToggleAction *action, else mode = EM_FORMAT_NORMAL; - em_format_set_mode ((EMFormat *) html_display, mode); + em_format_set_mode (EM_FORMAT (html_display), mode); } static void @@ -930,7 +917,7 @@ action_mail_show_source_cb (GtkAction *action, browser = e_mail_browser_new (shell_module); reader = E_MAIL_READER (browser); html_display = e_mail_reader_get_html_display (reader); - em_format_set_mode ((EMFormat *) html_display, EM_FORMAT_SOURCE); + em_format_set_mode (EM_FORMAT (html_display), EM_FORMAT_SOURCE); e_mail_reader_set_folder (reader, folder, folder_uri); e_mail_reader_set_message (reader, uids->pdata[0], FALSE); gtk_widget_show (browser); @@ -1621,7 +1608,7 @@ static GtkToggleActionEntry mail_reader_toggle_entries[] = { N_("_Caret Mode"), "F7", N_("Show a blinking cursor in the body of displayed messages"), - G_CALLBACK (action_mail_caret_mode_cb), + NULL, /* No callback required */ FALSE }, { "mail-show-all-headers", @@ -1643,7 +1630,7 @@ mail_reader_link_clicked_cb (EMailReader *reader, MessageList *message_list; const gchar *folder_uri; - html = ((EMFormatHTML *) html_display)->html; + html = EM_FORMAT_HTML (html_display)->html; message_list = e_mail_reader_get_message_list (reader); window = e_mail_reader_get_window (reader); folder_uri = message_list->folder_uri; @@ -1834,7 +1821,7 @@ mail_reader_message_loaded_cb (CamelFolder *folder, (EEventTarget *) target); em_format_format ( - (EMFormat *) html_display, folder, message_uid, message); + EM_FORMAT (html_display), folder, message_uid, message); /* Reset the shell view icon. */ e_shell_event (shell, "mail-icon", "evolution-mail"); @@ -1862,7 +1849,7 @@ mail_reader_message_loaded_cb (CamelFolder *folder, /* Display the error inline and clear the exception. */ stream = gtk_html_begin ( - ((EMFormatHTML *) html_display)->html); + EM_FORMAT_HTML (html_display)->html); gtk_html_stream_printf ( stream, "<h2>%s</h2><p>%s</p>", _("Unable to retrieve message"), @@ -1890,7 +1877,7 @@ mail_reader_message_selected_timeout_cb (EMailReader *reader) message_list = e_mail_reader_get_message_list (reader); cursor_uid = message_list->cursor_uid; - format_uid = ((EMFormat *) html_display)->uid; + format_uid = EM_FORMAT (html_display)->uid; if (cursor_uid != NULL) { if (g_strcmp0 (cursor_uid, format_uid) != 0) @@ -1900,7 +1887,7 @@ mail_reader_message_selected_timeout_cb (EMailReader *reader) g_object_ref (reader), mail_msg_fast_ordered_push); } else - em_format_format ((EMFormat *) html_display, NULL, NULL, NULL); + em_format_format (EM_FORMAT (html_display), NULL, NULL, NULL); key = "message-selected-timeout"; g_object_set_data (G_OBJECT (reader), key, NULL); @@ -1962,7 +1949,7 @@ mail_reader_set_folder (EMailReader *reader, if (message_list->folder != NULL) mail_sync_folder (message_list->folder, NULL, NULL); - em_format_format ((EMFormat *) html_display, NULL, NULL, NULL); + em_format_format (EM_FORMAT (html_display), NULL, NULL, NULL); message_list_set_folder (message_list, folder, folder_uri, outgoing); mail_reader_emit_folder_loaded (reader); @@ -2062,6 +2049,9 @@ e_mail_reader_get_type (void) void e_mail_reader_init (EMailReader *reader) { + EShell *shell; + EShellModule *shell_module; + EShellSettings *shell_settings; EMFormatHTMLDisplay *html_display; GtkActionGroup *action_group; MessageList *message_list; @@ -2075,6 +2065,10 @@ e_mail_reader_init (EMailReader *reader) action_group = e_mail_reader_get_action_group (reader); html_display = e_mail_reader_get_html_display (reader); message_list = e_mail_reader_get_message_list (reader); + shell_module = e_mail_reader_get_shell_module (reader); + + shell = e_shell_module_get_shell (shell_module); + shell_settings = e_shell_get_shell_settings (shell); gtk_action_group_add_actions ( action_group, mail_reader_entries, @@ -2124,6 +2118,37 @@ e_mail_reader_init (EMailReader *reader) action = e_mail_reader_get_action (reader, action_name); g_object_set (action, "short-label", _("Reply"), NULL); + /* Bind properties. */ + + e_binding_new_full ( + G_OBJECT (shell_settings), "mail-citation-color", + G_OBJECT (html_display), "citation-color", + e_binding_transform_string_to_color, + NULL, NULL); + + e_binding_new ( + G_OBJECT (shell_settings), "mail-image-loading-policy", + G_OBJECT (html_display), "image-loading-policy"); + + e_binding_new ( + G_OBJECT (shell_settings), "mail-only-local-photos", + G_OBJECT (html_display), "only-local-photos"); + + e_binding_new ( + G_OBJECT (shell_settings), "mail-show-animated-images", + G_OBJECT (html_display), "animate"); + + e_binding_new ( + G_OBJECT (shell_settings), "mail-show-sender-photo", + G_OBJECT (html_display), "show-sender-photo"); + + action_name = "mail-caret-mode"; + action = e_mail_reader_get_action (reader, action_name); + + e_mutual_binding_new ( + G_OBJECT (action), "active", + G_OBJECT (html_display), "caret-mode"); + /* Connect signals. */ g_signal_connect_swapped ( @@ -2131,7 +2156,7 @@ e_mail_reader_init (EMailReader *reader) G_CALLBACK (mail_reader_link_clicked_cb), reader); g_signal_connect_swapped ( - ((EMFormatHTML *) html_display)->html, "button-release-event", + EM_FORMAT_HTML (html_display)->html, "button-release-event", G_CALLBACK (mail_reader_html_button_release_event_cb), reader); g_signal_connect_swapped ( diff --git a/mail/e-mail-shell-module-settings.c b/mail/e-mail-shell-module-settings.c index e657296de3..94bfd1ac11 100644 --- a/mail/e-mail-shell-module-settings.c +++ b/mail/e-mail-shell-module-settings.c @@ -95,15 +95,15 @@ e_mail_shell_module_init_settings (EShell *shell) e_shell_settings_install_property ( g_param_spec_string ( - "mail-citation-color", + "mail-charset-default", + NULL, NULL, NULL, - "#737373", G_PARAM_READWRITE)); e_shell_settings_bind_to_gconf ( - shell_settings, "mail-citation-color", - "/apps/evolution/mail/display/citation_colour"); + shell_settings, "mail-charset-default", + "/apps/evolution/mail/display/charset"); e_shell_settings_install_property ( g_param_spec_boolean ( @@ -118,6 +118,18 @@ e_mail_shell_module_init_settings (EShell *shell) "/apps/evolution/mail/junk/check_incoming"); e_shell_settings_install_property ( + g_param_spec_string ( + "mail-citation-color", + NULL, + NULL, + "#737373", + G_PARAM_READWRITE)); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-citation-color", + "/apps/evolution/mail/display/citation_colour"); + + e_shell_settings_install_property ( g_param_spec_boolean ( "mail-confirm-expunge", NULL, @@ -201,6 +213,7 @@ e_mail_shell_module_init_settings (EShell *shell) shell_settings, "mail-force-message-limit", "/apps/evolution/mail/display/force_message_limit"); + /* This value corresponds to MailConfigForwardStyle enum. */ e_shell_settings_install_property ( g_param_spec_int ( "mail-forward-style", @@ -215,6 +228,21 @@ e_mail_shell_module_init_settings (EShell *shell) shell_settings, "mail-forward-style", "/apps/evolution/mail/format/forward_style"); + /* This value corresponds to MailConfigHTTPMode enum. */ + e_shell_settings_install_property ( + g_param_spec_int ( + "mail-image-loading-policy", + NULL, + NULL, + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + e_shell_settings_bind_to_gconf ( + shell_settings, "mail-image-loading-policy", + "/apps/evolution/mail/display/load_http_images"); + e_shell_settings_install_property ( g_param_spec_boolean ( "mail-magic-spacebar", @@ -303,9 +331,9 @@ e_mail_shell_module_init_settings (EShell *shell) shell_settings, "mail-prompt-delete-in-vfolder", "/apps/evolution/mail/prompts/delete_in_vfolder"); - /* Note: This value corresponds to MailConfigReplyStyle enum, - * but the ordering of the combo box items in preferences - * has changed. We use transformation functions there. */ + /* This value corresponds to MailConfigReplyStyle enum, + * but the ordering of the combo box items in preferences + * has changed. We use transformation functions there. */ e_shell_settings_install_property ( g_param_spec_int ( "mail-reply-style", diff --git a/mail/e-mail-shell-view-actions.c b/mail/e-mail-shell-view-actions.c index 99d3078bde..08c5882a5b 100644 --- a/mail/e-mail-shell-view-actions.c +++ b/mail/e-mail-shell-view-actions.c @@ -89,11 +89,25 @@ action_mail_create_search_folder_cb (GtkAction *action, } static void +action_mail_download_foreach_cb (CamelService *service) +{ + if (CAMEL_IS_DISCO_STORE (service) || + CAMEL_IS_OFFLINE_STORE (service)) + mail_store_prepare_offline (CAMEL_STORE (service)); +} + +static void action_mail_download_cb (GtkAction *action, EMailShellView *mail_shell_view) { - /* FIXME */ - g_print ("Action: %s\n", gtk_action_get_name (GTK_ACTION (action))); + EShellView *shell_view; + EShellModule *shell_module; + + shell_view = E_SHELL_VIEW (mail_shell_view); + shell_module = e_shell_view_get_shell_module (shell_view); + + e_mail_shell_module_stores_foreach ( + shell_module, (GHFunc) action_mail_download_foreach_cb, NULL); } static void diff --git a/mail/e-mail-shell-view-private.h b/mail/e-mail-shell-view-private.h index 8d295cd2a4..8568438c39 100644 --- a/mail/e-mail-shell-view-private.h +++ b/mail/e-mail-shell-view-private.h @@ -26,6 +26,8 @@ #include <glib/gi18n.h> #include <gtkhtml/gtkhtml.h> +#include <camel/camel-disco-store.h> +#include <camel/camel-offline-store.h> #include <camel/camel-vtrash-folder.h> #include <camel/camel-search-private.h> /* for camel_search_word */ diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c index 7412f0abe3..a857405bf9 100644 --- a/mail/em-folder-view.c +++ b/mail/em-folder-view.c @@ -261,8 +261,6 @@ emfv_init(GObject *o) gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1); emfv->async = mail_async_event_new(); - - emfv_setting_setup(emfv); } static void @@ -351,24 +349,6 @@ from(BonoboUIComponent *uid, void *data, const char *path) \ } static void -prepare_offline(void *key, void *value, void *data) -{ - CamelService *service = key; - - if (CAMEL_IS_DISCO_STORE(service) - || CAMEL_IS_OFFLINE_STORE(service)) { - mail_store_prepare_offline((CamelStore *)service); - } -} - -static void -emfv_prepare_offline(BonoboUIComponent *uid, void *data, const char *path) -{ - e_mail_shell_module_stores_foreach ( - mail_shell_module, prepare_offline, NULL); -} - -static void emfv_edit_cut(BonoboUIComponent *uid, void *data, const char *path) { EMFolderView *emfv = data; @@ -483,7 +463,6 @@ emp_uri_popup_vfolder_recipient(EPopup *ep, EPopupItem *pitem, void *data) /* ********************************************************************** */ static BonoboUIVerb emfv_message_verbs[] = { - BONOBO_UI_UNSAFE_VERB ("PrepareForOffline", emfv_prepare_offline), BONOBO_UI_UNSAFE_VERB ("EditCut", emfv_edit_cut), BONOBO_UI_UNSAFE_VERB ("EditCopy", emfv_edit_copy), BONOBO_UI_UNSAFE_VERB ("EditPaste", emfv_edit_paste), @@ -501,54 +480,6 @@ static BonoboUIVerb emfv_message_verbs[] = { }; static void -emfv_enable_menus(EMFolderView *emfv) -{ - guint32 disable_mask; - GString *name; - GSList *l; - - if (emfv->uic == NULL) - return; - - { - if (emfv->menu) { - EMMenuTargetSelect *t; - - t = em_menu_target_new_select(emfv->menu, emfv->folder, emfv->folder_uri, message_list_get_selected(emfv->list)); - t->target.widget = GTK_WIDGET (emfv); - e_menu_update_target((EMenu *)emfv->menu, t); - } - } - - if (emfv->folder) { - EMPopup *emp = em_popup_new("dummy"); - EMPopupTargetSelect *t; - - t = em_folder_view_get_popup_target(emfv, emp, FALSE); - disable_mask = t->target.mask; - e_popup_target_free((EPopup *)emp, t); - g_object_unref(emp); - } else { - disable_mask = ~0; - } - - name = g_string_new(""); - for (l = emfv->enable_map; l; l = l->next) { - EMFolderViewEnable *map = l->data; - int i; - - for (i=0;map[i].name;i++) { - int state = (map[i].mask & disable_mask) == 0; - - g_string_printf(name, "/commands/%s", map[i].name); - bonobo_ui_component_set_prop(emfv->uic, name->str, "sensitive", state?"1":"0", NULL); - } - } - - g_string_free(name, TRUE); -} - -static void emfv_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) { @@ -649,18 +580,6 @@ em_folder_view_get_popup_target(EMFolderView *emfv, EMPopup *emp, int on_display } void -em_folder_view_set_statusbar (EMFolderView *emfv, gboolean statusbar) -{ - g_return_if_fail (emfv); - - emfv->statusbar_active = statusbar; - - if (statusbar && emfv->uic) - bonobo_ui_component_set_translate (emfv->uic, "/", - "<status><item name=\"main\"/></status>", NULL); -} - -void em_folder_view_set_hide_deleted(EMFolderView *emfv, gboolean status) { if (emfv->folder && (emfv->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)) @@ -1100,43 +1019,17 @@ emfv_set_seen(EMFolderView *emfv, const char *uid) /* keep these two tables in sync */ enum { - EMFV_ANIMATE_IMAGES = 1, - EMFV_CHARSET, - EMFV_CITATION_COLOUR, - EMFV_CITATION_MARK, - EMFV_CARET_MODE, - EMFV_MESSAGE_STYLE, - EMFV_MARK_SEEN, - EMFV_MARK_SEEN_TIMEOUT, - EMFV_LOAD_HTTP, + EMFV_CHARSET = 1, EMFV_HEADERS, - EMFV_SHOW_PREVIEW, EMFV_SHOW_DELETED, - EMFV_THREAD_LIST, - EMFV_PANED_SIZE, - EMFV_SENDER_PHOTO, - EMFV_PHOTO_LOCAL, EMFV_SETTINGS /* last, for loop count */ }; /* IF these get too long, update key field */ static const char * const emfv_display_keys[] = { - "animate_images", "charset", - "citation_colour", - "mark_citations", - "caret_mode", - "message_style", - "mark_seen", - "mark_seen_timeout", - "load_http_images", "headers", - "show_preview", "show_deleted", - "thread_list", - "paned_size", - "sender_photo", - "photo_local", }; static GHashTable *emfv_setting_key; @@ -1156,49 +1049,9 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold g_return_if_fail (tkey != NULL); switch(GPOINTER_TO_INT(g_hash_table_lookup(emfv_setting_key, tkey+1))) { - case EMFV_ANIMATE_IMAGES: - em_format_html_display_set_animate(emfv->preview, gconf_value_get_bool (value)); - break; case EMFV_CHARSET: em_format_set_default_charset((EMFormat *)emfv->preview, gconf_value_get_string (value)); break; - case EMFV_CITATION_COLOUR: { - const char *s; - GdkColor colour; - guint32 rgb; - - s = gconf_value_get_string (value); - gdk_color_parse(s?s:"#737373", &colour); - rgb = ((colour.red & 0xff00) << 8) | (colour.green & 0xff00) | ((colour.blue & 0xff00) >> 8); - em_format_html_set_mark_citations((EMFormatHTML *)emfv->preview, - ((EMFormatHTML *)emfv->preview)->mark_citations, rgb); - break; } - case EMFV_CITATION_MARK: - em_format_html_set_mark_citations((EMFormatHTML *)emfv->preview, - gconf_value_get_bool (value), - ((EMFormatHTML *)emfv->preview)->citation_colour); - break; - case EMFV_CARET_MODE: - em_format_html_display_set_caret_mode(emfv->preview, gconf_value_get_bool (value)); - break; - case EMFV_MESSAGE_STYLE: - if (EM_FOLDER_VIEW_GET_CLASS (emfv)->update_message_style) { - int style = gconf_value_get_int (value); - - if (style < EM_FORMAT_NORMAL || style > EM_FORMAT_SOURCE) - style = EM_FORMAT_NORMAL; - em_format_set_mode((EMFormat *)emfv->preview, style); - } - break; - case EMFV_MARK_SEEN: - emfv->mark_seen = gconf_value_get_bool (value); - break; - case EMFV_MARK_SEEN_TIMEOUT: - emfv->mark_seen_timeout = gconf_value_get_int (value); - break; - case EMFV_LOAD_HTTP: - em_format_html_set_load_http((EMFormatHTML *)emfv->preview, gconf_value_get_int(value)); - break; case EMFV_HEADERS: { GSList *header_config_list, *p; EMFormat *emf = (EMFormat *)emfv->preview; @@ -1223,45 +1076,6 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold if (emf->message) em_format_redraw(emf); break; } - case EMFV_SENDER_PHOTO: { - EMFormat *emf = (EMFormat *)emfv->preview; - - emf->show_photo = gconf_value_get_bool (value); - if (emf->message) - em_format_redraw(emf); - - break; } - case EMFV_PHOTO_LOCAL: { - EMFormat *emf = (EMFormat *)emfv->preview; - - emf->photo_local = gconf_value_get_bool (value); - - break; } - case EMFV_SHOW_PREVIEW: { - gboolean state_gconf, state_camel; - char *ret; - - /* If emfv->folder hasn't been initialized, do nothing */ - if (!emfv->folder) - return; - - state_gconf = gconf_value_get_bool (value); - if (state_gconf == FALSE) - emfv_enable_menus (emfv); - - if ((ret = camel_object_meta_get (emfv->folder, "evolution:show_preview"))) { - state_camel = (ret[0] != '0'); - g_free (ret); - if (state_gconf == state_camel) - return; - } - - if (camel_object_meta_set (emfv->folder, "evolution:show_preview", state_gconf ? "1" : "0")) - camel_object_state_write (emfv->folder); - if (emfv->list_active) - em_folder_browser_show_preview ((EMFolderBrowser *)emfv, state_gconf); - bonobo_ui_component_set_prop (emfv->uic, "/commands/ViewPreview", "state", state_gconf ? "1" : "0", NULL); - break; } case EMFV_SHOW_DELETED: { gboolean state; @@ -1272,78 +1086,7 @@ emfv_setting_notify(GConfClient *gconf, guint cnxn_id, GConfEntry *entry, EMFold if (emfv->uic) bonobo_ui_component_set_prop (emfv->uic, "/commands/HideDeleted", "state", state ? "0" : "1", NULL); break; } - case EMFV_THREAD_LIST: { - gboolean state_gconf, state_camel; - char *ret; - - /* If emfv->folder or emfv->list hasn't been initialized, do nothing */ - if (!emfv->folder || !emfv->list) - return; - - state_gconf = gconf_value_get_bool (value); - if ((ret = camel_object_meta_get (emfv->folder, "evolution:thread_list"))) { - state_camel = (ret[0] != '0'); - g_free (ret); - if (state_gconf == state_camel) - return; - } - - if (camel_object_meta_set (emfv->folder, "evolution:thread_list", state_gconf ? "1" : "0")) - camel_object_state_write (emfv->folder); - message_list_set_threaded (emfv->list, state_gconf); - bonobo_ui_component_set_prop (emfv->uic, "/commands/ViewThreaded", "state", state_gconf ? "1" : "0", NULL); - break; } - case EMFV_PANED_SIZE: { - EMFolderBrowser *emfb = (EMFolderBrowser *)emfv; - int paned_size; - - if (!emfv->list_active || !emfb->vpane || !emfv->preview_active) - return; - - paned_size = gconf_value_get_int (value); - if (paned_size == gtk_paned_get_position (GTK_PANED (emfb->vpane))) - return; - - gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size); - break; } - } -} - -static void -emfv_setting_setup(EMFolderView *emfv) -{ - GConfClient *gconf = gconf_client_get_default(); - GConfEntry *entry; - GError *err = NULL; - int i; - char key[64]; - - if (emfv_setting_key == NULL) { - emfv_setting_key = g_hash_table_new(g_str_hash, g_str_equal); - for (i=1;i<EMFV_SETTINGS;i++) - g_hash_table_insert(emfv_setting_key, (void *)emfv_display_keys[i-1], GINT_TO_POINTER(i)); - } - - gconf_client_add_dir(gconf, "/apps/evolution/mail/display", GCONF_CLIENT_PRELOAD_NONE, NULL); - - for (i=1;err == NULL && i<EMFV_SETTINGS;i++) { - sprintf(key, "/apps/evolution/mail/display/%s", emfv_display_keys[i-1]); - entry = gconf_client_get_entry(gconf, key, NULL, TRUE, &err); - if (entry) { - emfv_setting_notify(gconf, 0, entry, emfv); - gconf_entry_free(entry); - } } - - if (err) { - g_warning("Could not load display settings: %s", err->message); - g_error_free(err); - } - - emfv->priv->setting_notify_id = gconf_client_notify_add(gconf, "/apps/evolution/mail/display", - (GConfClientNotifyFunc)emfv_setting_notify, - emfv, NULL, NULL); - g_object_unref(gconf); } static void diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c index ff7e77c8f6..03ded0ef5c 100644 --- a/mail/em-format-html-display.c +++ b/mail/em-format-html-display.c @@ -101,6 +101,10 @@ #define d(x) +#define EM_FORMAT_HTML_DISPLAY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayPrivate)) + struct _EMFormatHTMLDisplayPrivate { /* For the interactive search dialogue */ /* TODO: Should this be more subtle, like the mozilla one? */ @@ -127,6 +131,12 @@ struct _EMFormatHTMLDisplayPrivate { gboolean updated; }; +enum { + PROP_0, + PROP_ANIMATE, + PROP_CARET_MODE +}; + static int efhd_html_button_press_event (GtkWidget *widget, GdkEventButton *event, EMFormatHTMLDisplay *efh); static void efhd_html_link_clicked (GtkHTML *html, const char *url, EMFormatHTMLDisplay *efhd); static void efhd_html_on_url (GtkHTML *html, const char *url, EMFormatHTMLDisplay *efhd); @@ -207,57 +217,50 @@ static EMFormatHTMLClass *efhd_parent; static EMFormatClass *efhd_format_class; static void -efhd_gtkhtml_realise(GtkHTML *html, EMFormatHTMLDisplay *efhd) +efhd_gtkhtml_realize(GtkHTML *html, EMFormatHTMLDisplay *efhd) { + EMFormatHTMLColorType type; + EMFormatHTML *efh; + GdkColor *color; GtkStyle *style; + gint state; - /* FIXME: does this have to be re-done every time we draw? */ - - /* My favorite thing to do... muck around with colors so we respect people's stupid themes. - However, we only do this if we are rendering to the screen -- we ignore the theme - when we are printing. */ - style = gtk_widget_get_style((GtkWidget *)html); - if (style) { - int state = GTK_WIDGET_STATE(html); - gushort r, g, b; - - r = style->fg[state].red >> 8; - g = style->fg[state].green >> 8; - b = style->fg[state].blue >> 8; + efh = EM_FORMAT_HTML (efhd); + state = GTK_WIDGET_STATE (html); - efhd->formathtml.header_colour = ((r<<16) | (g<< 8) | b) & 0xffffff; - - r = style->bg[state].red >> 8; - g = style->bg[state].green >> 8; - b = style->bg[state].blue >> 8; + style = gtk_widget_get_style (GTK_WIDGET (html)); + if (style == NULL) + return; - efhd->formathtml.body_colour = ((r<<16) | (g<< 8) | b) & 0xffffff; + g_object_freeze_notify (G_OBJECT (efh)); - r = style->dark[state].red >> 8; - g = style->dark[state].green >> 8; - b = style->dark[state].blue >> 8; + color = &style->bg[state]; + type = EM_FORMAT_HTML_COLOR_BODY; + em_format_html_set_color (efh, type, color); - efhd->formathtml.frame_colour = ((r<<16) | (g<< 8) | b) & 0xffffff; + color = &style->base[GTK_STATE_NORMAL]; + type = EM_FORMAT_HTML_COLOR_CONTENT; + em_format_html_set_color (efh, type, color); - r = style->base[GTK_STATE_NORMAL].red >> 8; - g = style->base[GTK_STATE_NORMAL].green >> 8; - b = style->base[GTK_STATE_NORMAL].blue >> 8; + color = &style->dark[state]; + type = EM_FORMAT_HTML_COLOR_FRAME; + em_format_html_set_color (efh, type, color); - efhd->formathtml.content_colour = ((r<<16) | (g<< 8) | b) & 0xffffff; + color = &style->fg[state]; + type = EM_FORMAT_HTML_COLOR_HEADER; + em_format_html_set_color (efh, type, color); - r = style->text[state].red >> 8; - g = style->text[state].green >> 8; - b = style->text[state].blue >> 8; + color = &style->text[state]; + type = EM_FORMAT_HTML_COLOR_TEXT; + em_format_html_set_color (efh, type, color); - efhd->formathtml.text_colour = ((r<<16) | (g<< 8) | b) & 0xffffff; -#undef DARKER - } + g_object_thaw_notify (G_OBJECT (efh)); } static void efhd_gtkhtml_style_set(GtkHTML *html, GtkStyle *old, EMFormatHTMLDisplay *efhd) { - efhd_gtkhtml_realise(html, efhd); + efhd_gtkhtml_realize(html, efhd); em_format_redraw((EMFormat *)efhd); } @@ -267,12 +270,12 @@ efhd_init(GObject *o) EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)o; #define efh ((EMFormatHTML *)efhd) - efhd->priv = g_malloc0(sizeof(*efhd->priv)); + efhd->priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE(efhd); efhd->search_tok = (ESearchingTokenizer *)e_searching_tokenizer_new(); gtk_html_set_tokenizer (efh->html, (HTMLTokenizer *)efhd->search_tok); - g_signal_connect(efh->html, "realize", G_CALLBACK(efhd_gtkhtml_realise), o); + g_signal_connect(efh->html, "realize", G_CALLBACK(efhd_gtkhtml_realize), o); g_signal_connect(efh->html, "style-set", G_CALLBACK(efhd_gtkhtml_style_set), o); /* we want to convert url's etc */ efh->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES; @@ -285,19 +288,65 @@ efhd_init(GObject *o) } static void -efhd_finalise(GObject *o) +efhd_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ANIMATE: + em_format_html_display_set_animate ( + EM_FORMAT_HTML_DISPLAY (object), + g_value_get_boolean (value)); + return; + + case PROP_CARET_MODE: + em_format_html_display_set_caret_mode ( + EM_FORMAT_HTML_DISPLAY (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +efhd_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ANIMATE: + g_value_set_boolean ( + value, em_format_html_display_get_animate ( + EM_FORMAT_HTML_DISPLAY (object))); + return; + + case PROP_CARET_MODE: + g_value_set_boolean ( + value, em_format_html_display_get_caret_mode ( + EM_FORMAT_HTML_DISPLAY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +efhd_finalize (GObject *object) { - EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)o; + EMFormatHTMLDisplayPrivate *priv; - /* check pending stuff */ + priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (object); - if (efhd->priv->files) - g_hash_table_destroy(efhd->priv->files); + if (priv->files != NULL) + g_hash_table_destroy (priv->files); - g_free(efhd->priv->search_text); - g_free(efhd->priv); + g_free (priv->search_text); - ((GObjectClass *)efhd_parent)->finalize(o); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (efhd_parent)->finalize (object); } static gboolean @@ -311,22 +360,51 @@ efhd_bool_accumulator(GSignalInvocationHint *ihint, GValue *out, const GValue *i } static void -efhd_class_init(GObjectClass *klass) -{ - ((EMFormatClass *)klass)->find_handler = efhd_find_handler; - ((EMFormatClass *)klass)->format_clone = efhd_format_clone; - ((EMFormatClass *)klass)->format_error = efhd_format_error; - ((EMFormatClass *)klass)->format_source = efhd_format_source; - ((EMFormatClass *)klass)->format_attachment = efhd_format_attachment; - ((EMFormatClass *)klass)->format_optional = efhd_format_optional; - ((EMFormatClass *)klass)->format_secure = efhd_format_secure; - ((EMFormatClass *)klass)->complete = efhd_complete; - - klass->finalize = efhd_finalise; +efhd_class_init (GObjectClass *class) +{ + GObjectClass *object_class; + EMFormatClass *format_class; + + g_type_class_add_private (class, sizeof (EMFormatHTMLDisplayPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = efhd_set_property; + object_class->get_property = efhd_get_property; + object_class->finalize = efhd_finalize; + + format_class = EM_FORMAT_CLASS (class); + format_class->find_handler = efhd_find_handler; + format_class->format_clone = efhd_format_clone; + format_class->format_error = efhd_format_error; + format_class->format_source = efhd_format_source; + format_class->format_attachment = efhd_format_attachment; + format_class->format_optional = efhd_format_optional; + format_class->format_secure = efhd_format_secure; + format_class->complete = efhd_complete; + + g_object_class_install_property ( + object_class, + PROP_ANIMATE, + g_param_spec_boolean ( + "animate", + "Animate Images", + NULL, + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_CARET_MODE, + g_param_spec_boolean ( + "caret-mode", + "Caret Mode", + NULL, + FALSE, + G_PARAM_READWRITE)); efhd_signals[EFHD_LINK_CLICKED] = g_signal_new("link_clicked", - G_TYPE_FROM_CLASS(klass), + G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, link_clicked), NULL, NULL, @@ -335,7 +413,7 @@ efhd_class_init(GObjectClass *klass) efhd_signals[EFHD_POPUP_EVENT] = g_signal_new("popup_event", - G_TYPE_FROM_CLASS(klass), + G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, popup_event), efhd_bool_accumulator, NULL, @@ -346,7 +424,7 @@ efhd_class_init(GObjectClass *klass) efhd_signals[EFHD_ON_URL] = g_signal_new("on_url", - G_TYPE_FROM_CLASS(klass), + G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(EMFormatHTMLDisplayClass, on_url), NULL, NULL, @@ -354,7 +432,7 @@ efhd_class_init(GObjectClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); - efhd_builtin_init((EMFormatHTMLDisplayClass *)klass); + efhd_builtin_init((EMFormatHTMLDisplayClass *)class); } GType @@ -388,11 +466,11 @@ efhd_scroll_event(GtkWidget *w, GdkEventScroll *event, EMFormatHTMLDisplay *efhd { if(event->direction == GDK_SCROLL_UP) { - gtk_html_zoom_in (efhd->formathtml.html); + gtk_html_zoom_in (efhd->parent.html); } else if(event->direction == GDK_SCROLL_DOWN) { - gtk_html_zoom_out (efhd->formathtml.html); + gtk_html_zoom_out (efhd->parent.html); } return TRUE; } @@ -405,30 +483,71 @@ EMFormatHTMLDisplay *em_format_html_display_new(void) efhd = g_object_new(em_format_html_display_get_type(), 0); - g_signal_connect(efhd->formathtml.html, "iframe_created", G_CALLBACK(efhd_iframe_created), efhd); - g_signal_connect(efhd->formathtml.html, "link_clicked", G_CALLBACK(efhd_html_link_clicked), efhd); - g_signal_connect(efhd->formathtml.html, "on_url", G_CALLBACK(efhd_html_on_url), efhd); - g_signal_connect(efhd->formathtml.html, "button_press_event", G_CALLBACK(efhd_html_button_press_event), efhd); - g_signal_connect(efhd->formathtml.html,"scroll_event", G_CALLBACK(efhd_scroll_event), efhd); + g_signal_connect(efhd->parent.html, "iframe_created", G_CALLBACK(efhd_iframe_created), efhd); + g_signal_connect(efhd->parent.html, "link_clicked", G_CALLBACK(efhd_html_link_clicked), efhd); + g_signal_connect(efhd->parent.html, "on_url", G_CALLBACK(efhd_html_on_url), efhd); + g_signal_connect(efhd->parent.html, "button_press_event", G_CALLBACK(efhd_html_button_press_event), efhd); + g_signal_connect(efhd->parent.html,"scroll_event", G_CALLBACK(efhd_scroll_event), efhd); return efhd; } -void em_format_html_display_goto_anchor(EMFormatHTMLDisplay *efhd, const char *name) +gboolean +em_format_html_display_get_animate (EMFormatHTMLDisplay *efhd) { - printf("FIXME: go to anchor '%s'\n", name); + GtkHTML *html; + + g_return_val_if_fail (EM_IS_FORMAT_HTML_DISPLAY (efhd), FALSE); + + html = ((EMFormatHTML *) efhd)->html; + + return gtk_html_get_animate (html); } -void em_format_html_display_set_animate(EMFormatHTMLDisplay *efhd, gboolean state) +void +em_format_html_display_set_animate (EMFormatHTMLDisplay *efhd, + gboolean animate) { - efhd->animate = state; - gtk_html_set_animate(((EMFormatHTML *)efhd)->html, state); + GtkHTML *html; + + /* XXX Note this is imperfect. If animate is set by + * some other means we won't emit a notification. */ + + g_return_if_fail (EM_IS_FORMAT_HTML_DISPLAY (efhd)); + + html = ((EMFormatHTML *) efhd)->html; + gtk_html_set_animate (html, animate); + + g_object_notify (G_OBJECT (efhd), "animate"); } -void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean state) +gboolean +em_format_html_display_get_caret_mode (EMFormatHTMLDisplay *efhd) { - efhd->caret_mode = state; - gtk_html_set_caret_mode(((EMFormatHTML *)efhd)->html, state); + GtkHTML *html; + + g_return_val_if_fail (EM_IS_FORMAT_HTML_DISPLAY (efhd), FALSE); + + html = ((EMFormatHTML *) efhd)->html; + + return gtk_html_get_caret_mode (html); +} + +void +em_format_html_display_set_caret_mode (EMFormatHTMLDisplay *efhd, + gboolean caret_mode) +{ + GtkHTML *html; + + /* XXX Note this is imperfect. If caret mode is set by + * some other means we won't emit a notification. */ + + g_return_if_fail (EM_IS_FORMAT_HTML_DISPLAY (efhd)); + + html = ((EMFormatHTML *) efhd)->html; + gtk_html_set_caret_mode (html, caret_mode); + + g_object_notify (G_OBJECT (efhd), "caret-mode"); } EAttachmentBar * @@ -883,7 +1002,7 @@ em_format_html_display_popup_menu (EMFormatHTMLDisplay *efhd) EMFormatPURI *puri = NULL; gboolean res = FALSE; - html = efhd->formathtml.html; + html = efhd->parent.html; efhd_get_uri_puri (GTK_WIDGET (html), NULL, efhd, &uri, &puri); @@ -2347,7 +2466,7 @@ efhd_bar_scroll_event(GtkWidget *w, GdkEventScroll *event, EMFormatHTMLDisplay * /* Emulate the scroll over the attachment bar, as if it is scrolled in the window. * It doesnt go automatically since the GnomeIconList is a layout by itself */ - g_signal_emit_by_name (gtk_widget_get_parent((GtkWidget *)efhd->formathtml.html), "scroll_event", event, &ret); + g_signal_emit_by_name (gtk_widget_get_parent((GtkWidget *)efhd->parent.html), "scroll_event", event, &ret); return TRUE; } diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h index 651b981364..b659994114 100644 --- a/mail/em-format-html-display.h +++ b/mail/em-format-html-display.h @@ -22,35 +22,55 @@ Concrete class for formatting mails to displayed html */ -#ifndef _EM_FORMAT_HTML_DISPLAY_H -#define _EM_FORMAT_HTML_DISPLAY_H +#ifndef EM_FORMAT_HTML_DISPLAY_H +#define EM_FORMAT_HTML_DISPLAY_H #include "mail/em-format-html.h" #include "widgets/misc/e-attachment-bar.h" +/* Standard GObject macros */ +#define EM_TYPE_FORMAT_HTML_DISPLAY \ + (em_format_html_display_get_type ()) +#define EM_FORMAT_HTML_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplay)) +#define EM_FORMAT_HTML_DISPLAY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayClass)) +#define EM_IS_FORMAT_HTML_DISPLAY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY)) +#define EM_IS_FORMAT_HTML_DISPLAY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT_HTML_DISPLAY)) +#define EM_FORMAT_HTML_DISPLAY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayClass)) + +/* Search options */ +#define EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY (0) +#define EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY (1) +#define EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE (1 << 8) + +G_BEGIN_DECLS + typedef struct _EMFormatHTMLDisplay EMFormatHTMLDisplay; typedef struct _EMFormatHTMLDisplayClass EMFormatHTMLDisplayClass; +typedef struct _EMFormatHTMLDisplayPrivate EMFormatHTMLDisplayPrivate; struct _CamelMimePart; struct _EMFormatHTMLDisplay { - EMFormatHTML formathtml; - - struct _EMFormatHTMLDisplayPrivate *priv; + EMFormatHTML parent; + EMFormatHTMLDisplayPrivate *priv; struct _ESearchingTokenizer *search_tok; - unsigned int animate:1; - unsigned int caret_mode:1; unsigned int nobar:1; }; -#define EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY (0) -#define EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY (1) -#define EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE (1<<8) - struct _EMFormatHTMLDisplayClass { - EMFormatHTMLClass formathtml_class; + EMFormatHTMLClass parent_class; /* a link clicked normally */ void (*link_clicked)(EMFormatHTMLDisplay *efhd, const char *uri); @@ -60,34 +80,43 @@ struct _EMFormatHTMLDisplayClass { void (*on_url)(EMFormatHTMLDisplay *efhd, const char *uri); }; -GType em_format_html_display_get_type(void); -EMFormatHTMLDisplay *em_format_html_display_new(void); - -void em_format_html_display_goto_anchor(EMFormatHTMLDisplay *efhd, const char *name); - -void em_format_html_display_set_animate(EMFormatHTMLDisplay *efhd, gboolean state); -void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean state); - -void em_format_html_display_set_search(EMFormatHTMLDisplay *efhd, int type, GSList *strings); -void em_format_html_display_search(EMFormatHTMLDisplay *efhd); -void em_format_html_display_search_with (EMFormatHTMLDisplay *efhd, char *word); -void em_format_html_display_search_close (EMFormatHTMLDisplay *efhd); - -GtkWidget *em_format_html_get_search_dialog (EMFormatHTMLDisplay *efhd); - -void em_format_html_display_cut (EMFormatHTMLDisplay *efhd); -void em_format_html_display_copy (EMFormatHTMLDisplay *efhd); -void em_format_html_display_paste (EMFormatHTMLDisplay *efhd); - -void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd); -void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd); -void em_format_html_display_zoom_reset (EMFormatHTMLDisplay *efhd); -EAttachmentBar *em_format_html_display_get_bar (EMFormatHTMLDisplay *efhd); - -gboolean em_format_html_display_popup_menu (EMFormatHTMLDisplay *efhd); - -/* experimental */ -struct _EPopupExtension; -void em_format_html_display_set_popup(EMFormatHTMLDisplay *, struct _EPopupExtension *); - -#endif /* !_EM_FORMAT_HTML_DISPLAY_H */ +GType em_format_html_display_get_type (void); +EMFormatHTMLDisplay * + em_format_html_display_new (void); +gboolean em_format_html_display_get_animate + (EMFormatHTMLDisplay *efhd); +void em_format_html_display_set_animate + (EMFormatHTMLDisplay *efhd, + gboolean animate); +gboolean em_format_html_display_get_caret_mode + (EMFormatHTMLDisplay *efhd); +void em_format_html_display_set_caret_mode + (EMFormatHTMLDisplay *efhd, + gboolean caret_mode); +void em_format_html_display_set_search + (EMFormatHTMLDisplay *efhd, + int type, + GSList *strings); +void em_format_html_display_search (EMFormatHTMLDisplay *efhd); +void em_format_html_display_search_with + (EMFormatHTMLDisplay *efhd, + char *word); +void em_format_html_display_search_close + (EMFormatHTMLDisplay *efhd); +GtkWidget * em_format_html_get_search_dialog(EMFormatHTMLDisplay *efhd); +void em_format_html_display_cut (EMFormatHTMLDisplay *efhd); +void em_format_html_display_copy (EMFormatHTMLDisplay *efhd); +void em_format_html_display_paste (EMFormatHTMLDisplay *efhd); + +void em_format_html_display_zoom_in (EMFormatHTMLDisplay *efhd); +void em_format_html_display_zoom_out (EMFormatHTMLDisplay *efhd); +void em_format_html_display_zoom_reset + (EMFormatHTMLDisplay *efhd); +EAttachmentBar *em_format_html_display_get_bar (EMFormatHTMLDisplay *efhd); + +gboolean em_format_html_display_popup_menu + (EMFormatHTMLDisplay *efhd); + +G_END_DECLS + +#endif /* EM_FORMAT_HTML_DISPLAY_H */ diff --git a/mail/em-format-html-print.c b/mail/em-format-html-print.c index 985828d2af..28767d216d 100644 --- a/mail/em-format-html-print.c +++ b/mail/em-format-html-print.c @@ -210,9 +210,7 @@ emfhp_got_message (CamelFolder *folder, const char *uid, return; } - if (efhp->source != NULL) - ((EMFormatHTML *)efhp)->load_http = - efhp->source->load_http_now; + em_format_html_load_images (EM_FORMAT_HTML (efhp)); g_signal_connect ( efhp, "complete", G_CALLBACK (emfhp_complete), efhp); diff --git a/mail/em-format-html.c b/mail/em-format-html.c index 02e07939fc..bafb82ae36 100644 --- a/mail/em-format-html.c +++ b/mail/em-format-html.c @@ -48,7 +48,6 @@ #include "e-util/e-util.h" #include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-embedded.h> #include <gtkhtml/gtkhtml-stream.h> #include <glib/gi18n.h> @@ -83,6 +82,10 @@ #define d(x) +#define EM_FORMAT_HTML_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTMLPrivate)) + #define EFM_MESSAGE_START_ANAME "evolution#message#start" #define EFH_MESSAGE_START "<A name=\"" EFM_MESSAGE_START_ANAME "\"></A>" @@ -103,6 +106,27 @@ struct _EMFormatHTMLPrivate { EDList pending_jobs; GMutex *lock; + + GdkColor colors[EM_FORMAT_HTML_NUM_COLOR_TYPES]; + MailConfigHTTPMode image_loading_policy; + + guint load_images_now : 1; + guint only_local_photos : 1; + guint show_sender_photo : 1; +}; + +enum { + PROP_0, + PROP_BODY_COLOR, + PROP_CITATION_COLOR, + PROP_CONTENT_COLOR, + PROP_FRAME_COLOR, + PROP_HEADER_COLOR, + PROP_IMAGE_LOADING_POLICY, + PROP_MARK_CITATIONS, + PROP_ONLY_LOCAL_PHOTOS, + PROP_SHOW_SENDER_PHOTO, + PROP_TEXT_COLOR }; static void efh_url_requested(GtkHTML *html, const char *url, GtkHTMLStream *handle, EMFormatHTML *efh); @@ -122,7 +146,7 @@ static void efh_builtin_init(EMFormatHTMLClass *efhc); static void efh_write_image(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri); -static EMFormatClass *efh_parent; +static gpointer parent_class; static CamelDataCache *emfh_http_cache; #define EMFH_HTTP_CACHE_PATH "http" @@ -136,44 +160,6 @@ efh_free_cache(struct _EMFormatHTMLCache *efhc) } static void -efh_init(GObject *o) -{ - EMFormatHTML *efh = (EMFormatHTML *)o; - - efh->priv = g_malloc0(sizeof(*efh->priv)); - - e_dlist_init(&efh->pending_object_list); - e_dlist_init(&efh->priv->pending_jobs); - efh->priv->lock = g_mutex_new(); - efh->priv->format_id = -1; - efh->priv->text_inline_parts = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) efh_free_cache); - - efh->html = (GtkHTML *)gtk_html_new(); - gtk_html_set_blocking(efh->html, FALSE); - gtk_html_set_caret_first_focus_anchor (efh->html, EFM_MESSAGE_START_ANAME); - g_object_ref_sink(efh->html); - - gtk_html_set_default_content_type(efh->html, "text/html; charset=utf-8"); - gtk_html_set_editable(efh->html, FALSE); - - g_signal_connect(efh->html, "url_requested", G_CALLBACK(efh_url_requested), efh); - g_signal_connect(efh->html, "object_requested", G_CALLBACK(efh_object_requested), efh); - - efh->body_colour = 0xeeeeee; - efh->header_colour = 0xeeeeee; - efh->text_colour = 0; - efh->frame_colour = 0x3f3f3f; - efh->content_colour = 0xffffff; - efh->text_html_flags = CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES - | CAMEL_MIME_FILTER_TOHTML_MARK_CITATION; - efh->show_icon = TRUE; - efh->state = EM_FORMAT_HTML_STATE_NONE; -} - -static void efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh) { if (efh->priv->format_timeout_id != 0) { @@ -187,8 +173,8 @@ efh_gtkhtml_destroy(GtkHTML *html, EMFormatHTML *efh) if (efh->priv->format_id != -1) mail_msg_cancel(efh->priv->format_id); - if (efh->html) { - g_object_unref(efh->html); + if (efh->html != NULL) { + g_object_unref (efh->html); efh->html = NULL; } } @@ -205,121 +191,583 @@ efh_insert_cache(EMFormatHTML *efh, const char *partid) return efhc; } +static void +efh_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_BODY_COLOR: + em_format_html_set_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_BODY, + g_value_get_boxed (value)); + return; + + case PROP_CITATION_COLOR: + em_format_html_set_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_CITATION, + g_value_get_boxed (value)); + return; + + case PROP_CONTENT_COLOR: + em_format_html_set_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_CONTENT, + g_value_get_boxed (value)); + return; + + case PROP_FRAME_COLOR: + em_format_html_set_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_FRAME, + g_value_get_boxed (value)); + return; + + case PROP_HEADER_COLOR: + em_format_html_set_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_HEADER, + g_value_get_boxed (value)); + return; + + case PROP_IMAGE_LOADING_POLICY: + em_format_html_set_image_loading_policy ( + EM_FORMAT_HTML (object), + g_value_get_int (value)); + return; + + case PROP_MARK_CITATIONS: + em_format_html_set_mark_citations ( + EM_FORMAT_HTML (object), + g_value_get_boolean (value)); + return; + + case PROP_ONLY_LOCAL_PHOTOS: + em_format_html_set_only_local_photos ( + EM_FORMAT_HTML (object), + g_value_get_boolean (value)); + return; + + case PROP_SHOW_SENDER_PHOTO: + em_format_html_set_show_sender_photo ( + EM_FORMAT_HTML (object), + g_value_get_boolean (value)); + return; + + case PROP_TEXT_COLOR: + em_format_html_set_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_TEXT, + g_value_get_boxed (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} static void -efh_finalise(GObject *o) +efh_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - EMFormatHTML *efh = (EMFormatHTML *)o; + GdkColor color; + + switch (property_id) { + case PROP_BODY_COLOR: + em_format_html_get_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_BODY, + &color); + g_value_set_boxed (value, &color); + return; - /* FIXME: check for leaked stuff */ + case PROP_CITATION_COLOR: + em_format_html_get_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_CITATION, + &color); + g_value_set_boxed (value, &color); + return; + + case PROP_CONTENT_COLOR: + em_format_html_get_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_CONTENT, + &color); + g_value_set_boxed (value, &color); + return; + + case PROP_FRAME_COLOR: + em_format_html_get_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_FRAME, + &color); + g_value_set_boxed (value, &color); + return; + + case PROP_HEADER_COLOR: + em_format_html_get_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_HEADER, + &color); + g_value_set_boxed (value, &color); + return; + + case PROP_IMAGE_LOADING_POLICY: + g_value_set_int ( + value, + em_format_html_get_image_loading_policy ( + EM_FORMAT_HTML (object))); + return; + + case PROP_MARK_CITATIONS: + g_value_set_boolean ( + value, em_format_html_get_mark_citations ( + EM_FORMAT_HTML (object))); + return; + + case PROP_ONLY_LOCAL_PHOTOS: + g_value_set_boolean ( + value, em_format_html_get_only_local_photos ( + EM_FORMAT_HTML (object))); + return; - em_format_html_clear_pobject(efh); + case PROP_SHOW_SENDER_PHOTO: + g_value_set_boolean ( + value, em_format_html_get_show_sender_photo ( + EM_FORMAT_HTML (object))); + return; + + case PROP_TEXT_COLOR: + em_format_html_get_color ( + EM_FORMAT_HTML (object), + EM_FORMAT_HTML_COLOR_TEXT, + &color); + g_value_set_boxed (value, &color); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} - efh_gtkhtml_destroy(efh->html, efh); +static void +efh_finalize (GObject *object) +{ + EMFormatHTML *efh = EM_FORMAT_HTML (object); + + /* FIXME: check for leaked stuff */ - g_hash_table_destroy(efh->priv->text_inline_parts); + em_format_html_clear_pobject (efh); + efh_gtkhtml_destroy (efh->html, efh); - g_free(efh->priv); + g_hash_table_destroy (efh->priv->text_inline_parts); - ((GObjectClass *)efh_parent)->finalize(o); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -efh_base_init(EMFormatHTMLClass *efhklass) +efh_base_init (EMFormatHTMLClass *class) { - efh_builtin_init(efhklass); + efh_builtin_init (class); } static void -efh_class_init(GObjectClass *klass) +efh_class_init (EMFormatHTMLClass *class) { - ((EMFormatClass *)klass)->format_clone = efh_format_clone; - ((EMFormatClass *)klass)->format_error = efh_format_error; - ((EMFormatClass *)klass)->format_source = efh_format_source; - ((EMFormatClass *)klass)->format_attachment = efh_format_attachment; - ((EMFormatClass *)klass)->format_secure = efh_format_secure; - ((EMFormatClass *)klass)->busy = efh_busy; - - klass->finalize = efh_finalise; + GObjectClass *object_class; + EMFormatClass *format_class; + gchar *pathname; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMFormatHTMLPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = efh_set_property; + object_class->get_property = efh_get_property; + object_class->finalize = efh_finalize; + + format_class = EM_FORMAT_CLASS (class); + format_class->format_clone = efh_format_clone; + format_class->format_error = efh_format_error; + format_class->format_source = efh_format_source; + format_class->format_attachment = efh_format_attachment; + format_class->format_secure = efh_format_secure; + format_class->busy = efh_busy; + + g_object_class_install_property ( + object_class, + PROP_BODY_COLOR, + g_param_spec_boxed ( + "body-color", + "Body Color", + NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_CITATION_COLOR, + g_param_spec_boxed ( + "citation-color", + "Citation Color", + NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_CONTENT_COLOR, + g_param_spec_boxed ( + "content-color", + "Content Color", + NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FRAME_COLOR, + g_param_spec_boxed ( + "frame-color", + "Frame Color", + NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_HEADER_COLOR, + g_param_spec_boxed ( + "header-color", + "Header Color", + NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + + /* FIXME Make this a proper enum property. */ + g_object_class_install_property ( + object_class, + PROP_IMAGE_LOADING_POLICY, + g_param_spec_int ( + "image-loading-policy", + "Image Loading Policy", + NULL, + 0, + G_MAXINT, + MAIL_CONFIG_HTTP_ALWAYS, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_MARK_CITATIONS, + g_param_spec_boolean ( + "mark-citations", + "Mark Citations", + NULL, + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_ONLY_LOCAL_PHOTOS, + g_param_spec_boolean ( + "only-local-photos", + "Only Local Photos", + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SHOW_SENDER_PHOTO, + g_param_spec_boolean ( + "show-sender-photo", + "Show Sender Photo", + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_TEXT_COLOR, + g_param_spec_boxed ( + "text-color", + "Text Color", + NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + + /* cache expiry - 2 hour access, 1 day max */ + pathname = g_build_filename ( + e_get_user_data_dir (), "cache", NULL); + emfh_http_cache = camel_data_cache_new (pathname, 0, NULL); + if (emfh_http_cache) { + camel_data_cache_set_expire_age(emfh_http_cache, 24*60*60); + camel_data_cache_set_expire_access(emfh_http_cache, 2*60*60); + } + g_free (pathname); +} + +static void +efh_init (EMFormatHTML *efh) +{ + GdkColor *color; + + efh->priv = EM_FORMAT_HTML_GET_PRIVATE (efh); + + e_dlist_init(&efh->pending_object_list); + e_dlist_init(&efh->priv->pending_jobs); + efh->priv->lock = g_mutex_new(); + efh->priv->format_id = -1; + efh->priv->text_inline_parts = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) NULL, + (GDestroyNotify) efh_free_cache); + + efh->html = (GtkHTML *) gtk_html_new (); + g_object_ref_sink(efh->html); + + gtk_html_set_blocking (efh->html, FALSE); + gtk_html_set_caret_first_focus_anchor (efh->html, EFM_MESSAGE_START_ANAME); + + gtk_html_set_default_content_type(efh->html, "text/html; charset=utf-8"); + gtk_html_set_editable(efh->html, FALSE); + + g_signal_connect(efh->html, "url_requested", G_CALLBACK(efh_url_requested), efh); + g_signal_connect(efh->html, "object_requested", G_CALLBACK(efh_object_requested), efh); + + color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_BODY]; + gdk_color_parse ("0xeeeeee", color); + + color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_CONTENT]; + gdk_color_parse ("0xffffff", color); + + color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_FRAME]; + gdk_color_parse ("0x3f3f3f", color); + + color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_HEADER]; + gdk_color_parse ("0xeeeeee", color); + + color = &efh->priv->colors[EM_FORMAT_HTML_COLOR_TEXT]; + gdk_color_parse ("0x000000", color); + + efh->text_html_flags = + CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | + CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES | + CAMEL_MIME_FILTER_TOHTML_MARK_CITATION; + efh->show_icon = TRUE; + efh->state = EM_FORMAT_HTML_STATE_NONE; + + g_signal_connect_swapped ( + efh, "notify::mark-citations", + G_CALLBACK (em_format_redraw), NULL); } GType -em_format_html_get_type(void) +em_format_html_get_type (void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof(EMFormatHTMLClass), - (GBaseInitFunc)efh_base_init, NULL, - (GClassInitFunc)efh_class_init, - NULL, NULL, - sizeof(EMFormatHTML), 0, - (GInstanceInitFunc)efh_init + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMFormatHTMLClass), + (GBaseInitFunc) efh_base_init, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) efh_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMFormatHTML), + 0, /* n_preallocs */ + (GInstanceInitFunc) efh_init, + NULL /* value_table */ }; - const char *base_directory = e_get_user_data_dir (); - char *path; - - efh_parent = g_type_class_ref(em_format_get_type()); - type = g_type_register_static(em_format_get_type(), "EMFormatHTML", &info, 0); - /* cache expiry - 2 hour access, 1 day max */ - path = alloca(strlen(base_directory)+16); - sprintf(path, "%s/cache", base_directory); - emfh_http_cache = camel_data_cache_new(path, 0, NULL); - if (emfh_http_cache) { - camel_data_cache_set_expire_age(emfh_http_cache, 24*60*60); - camel_data_cache_set_expire_access(emfh_http_cache, 2*60*60); - } + type = g_type_register_static ( + em_format_get_type(), "EMFormatHTML", &type_info, 0); } return type; } -EMFormatHTML *em_format_html_new(void) +EMFormatHTML * +em_format_html_new(void) +{ + return g_object_new (EM_TYPE_FORMAT_HTML, NULL); +} + +void +em_format_html_load_images (EMFormatHTML *efh) { - EMFormatHTML *efh; + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); - efh = g_object_new(em_format_html_get_type(), NULL); + if (efh->priv->image_loading_policy == MAIL_CONFIG_HTTP_ALWAYS) + return; - return efh; + /* This will remain set while we're still + * rendering the same message, then it wont be. */ + efh->priv->load_images_now = TRUE; + em_format_redraw (EM_FORMAT (efh)); } -/* force loading of http images */ -void em_format_html_load_http(EMFormatHTML *emfh) +void +em_format_html_get_color (EMFormatHTML *efh, + EMFormatHTMLColorType type, + GdkColor *color) { - if (emfh->load_http == MAIL_CONFIG_HTTP_ALWAYS) - return; + GdkColor *format_color; + + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); + g_return_if_fail (type >= 0); + g_return_if_fail (type < EM_FORMAT_HTML_NUM_COLOR_TYPES); + g_return_if_fail (color != NULL); - /* This will remain set while we're still rendering the same message, then it wont be */ - emfh->load_http_now = TRUE; - d(printf("redrawing with images forced on\n")); - em_format_redraw((EMFormat *)emfh); + format_color = &efh->priv->colors[type]; + + color->red = format_color->red; + color->green = format_color->green; + color->blue = format_color->blue; } void -em_format_html_set_load_http(EMFormatHTML *emfh, int style) +em_format_html_set_color (EMFormatHTML *efh, + EMFormatHTMLColorType type, + const GdkColor *color) { - if (emfh->load_http != style) { - emfh->load_http = style; - em_format_redraw((EMFormat *)emfh); + GdkColor *format_color; + const gchar *property_name; + + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); + g_return_if_fail (type >= 0); + g_return_if_fail (type < EM_FORMAT_HTML_NUM_COLOR_TYPES); + g_return_if_fail (color != NULL); + + format_color = &efh->priv->colors[type]; + + if (gdk_color_equal (color, format_color)) + return; + + format_color->red = color->red; + format_color->green = color->green; + format_color->blue = color->blue; + + switch (type) { + case EM_FORMAT_HTML_COLOR_BODY: + property_name = "body-color"; + break; + case EM_FORMAT_HTML_COLOR_CITATION: + property_name = "citation-color"; + break; + case EM_FORMAT_HTML_COLOR_CONTENT: + property_name = "content-color"; + break; + case EM_FORMAT_HTML_COLOR_FRAME: + property_name = "frame-color"; + break; + case EM_FORMAT_HTML_COLOR_HEADER: + property_name = "header-color"; + break; + case EM_FORMAT_HTML_COLOR_TEXT: + property_name = "text-color"; + break; + default: + g_return_if_reached (); } + + g_object_notify (G_OBJECT (efh), property_name); +} + +MailConfigHTTPMode +em_format_html_get_image_loading_policy (EMFormatHTML *efh) +{ + g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), 0); + + return efh->priv->image_loading_policy;; } void -em_format_html_set_mark_citations(EMFormatHTML *emfh, int state, guint32 citation_colour) +em_format_html_set_image_loading_policy (EMFormatHTML *efh, + MailConfigHTTPMode policy) { - if (emfh->mark_citations ^ state || emfh->citation_colour != citation_colour) { - emfh->mark_citations = state; - emfh->citation_colour = citation_colour; + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); - if (state) - emfh->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_MARK_CITATION; - else - emfh->text_html_flags &= ~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION; + if (policy == efh->priv->image_loading_policy) + return; - em_format_redraw((EMFormat *)emfh); - } + efh->priv->image_loading_policy = policy; + + g_object_notify (G_OBJECT (efh), "image-loading-policy"); +} + +gboolean +em_format_html_get_mark_citations (EMFormatHTML *efh) +{ + guint32 flags; + + g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE); + + flags = efh->text_html_flags; + + return ((flags & CAMEL_MIME_FILTER_TOHTML_MARK_CITATION) != 0); +} + +void +em_format_html_set_mark_citations (EMFormatHTML *efh, + gboolean mark_citations) +{ + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); + + if (mark_citations) + efh->text_html_flags |= + CAMEL_MIME_FILTER_TOHTML_MARK_CITATION; + efh->text_html_flags &= + ~CAMEL_MIME_FILTER_TOHTML_MARK_CITATION; + + g_object_notify (G_OBJECT (efh), "mark-citations"); +} + +gboolean +em_format_html_get_only_local_photos (EMFormatHTML *efh) +{ + g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE); + + return efh->priv->only_local_photos; +} + +void +em_format_html_set_only_local_photos (EMFormatHTML *efh, + gboolean only_local_photos) +{ + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); + + efh->priv->only_local_photos = only_local_photos; + + g_object_notify (G_OBJECT (efh), "only-local-photos"); +} + +gboolean +em_format_html_get_show_sender_photo (EMFormatHTML *efh) +{ + g_return_val_if_fail (EM_IS_FORMAT_HTML (efh), FALSE); + + return efh->priv->show_sender_photo; +} + +void +em_format_html_set_show_sender_photo (EMFormatHTML *efh, + gboolean show_sender_photo) +{ + g_return_if_fail (EM_IS_FORMAT_HTML (efh)); + + efh->priv->show_sender_photo = show_sender_photo; + + g_object_notify (G_OBJECT (efh), "show-sender-photo"); } CamelMimePart * @@ -477,13 +925,15 @@ static void emfh_gethttp(struct _EMFormatHTMLJob *job, int cancelled) instream = cistream = camel_data_cache_get(emfh_http_cache, EMFH_HTTP_CACHE_PATH, job->u.uri, NULL); if (instream == NULL) { + MailConfigHTTPMode policy; char *proxy; + policy = em_format_html_get_image_loading_policy (job->format); - if (!(job->format->load_http_now - || job->format->load_http == MAIL_CONFIG_HTTP_ALWAYS - || (job->format->load_http == MAIL_CONFIG_HTTP_SOMETIMES - && em_utils_in_addressbook((CamelInternetAddress *)camel_mime_message_get_from(job->format->format.message), FALSE)))) { + if (!(job->format->priv->load_images_now + || policy == MAIL_CONFIG_HTTP_ALWAYS + || (policy == MAIL_CONFIG_HTTP_SOMETIMES + && em_utils_in_addressbook((CamelInternetAddress *)camel_mime_message_get_from(job->format->parent.message), FALSE)))) { /* TODO: Ideally we would put the http requests into another queue and only send them out if the user selects 'load images', when they do. The problem is how to maintain this state with multiple renderings, and how to adjust the thread dispatch/setup routine to handle it */ @@ -672,7 +1122,11 @@ static const char *smime_sign_colour[4] = { static void efh_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid) { - efh_parent->format_secure(emf, stream, part, valid); + EMFormatClass *format_class; + + format_class = EM_FORMAT_GET_CLASS (emf); + g_return_if_fail (format_class->format_secure != NULL); + format_class->format_secure (emf, stream, part, valid); /* To explain, if the validity is the same, then we are the base validity and now have a combined sign/encrypt validity @@ -726,6 +1180,7 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo CamelContentType *type; const char *format; guint32 flags; + guint32 rgb; int i, count, len; struct _EMFormatHTMLCache *efhc; @@ -782,8 +1237,10 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo camel_content_type_unref(ct); } + rgb = e_color_to_value ( + &efh->priv->colors[EM_FORMAT_HTML_COLOR_CITATION]); filtered_stream = camel_stream_filter_new_with_stream(stream); - html_filter = camel_mime_filter_tohtml_new(flags, efh->citation_colour); + html_filter = camel_mime_filter_tohtml_new(flags, rgb); camel_stream_filter_add(filtered_stream, html_filter); camel_object_unref(html_filter); @@ -799,9 +1256,17 @@ efh_text_plain(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFo type = camel_mime_part_get_content_type(newpart); if (camel_content_type_is (type, "text", "*") && !camel_content_type_is(type, "text", "calendar")) { - camel_stream_printf (stream, - "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n", - efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff); + camel_stream_printf ( + stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n", + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_FRAME]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_CONTENT]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_TEXT])); camel_stream_write_string(stream, "<tt>\n" EFH_MESSAGE_START); em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, (CamelDataWrapper *)newpart); camel_stream_flush((CamelStream *)filtered_stream); @@ -839,9 +1304,17 @@ efh_text_enriched(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, E camel_stream_filter_add(filtered_stream, enriched); camel_object_unref(enriched); - camel_stream_printf (stream, - "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n" EFH_MESSAGE_START, - efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff); + camel_stream_printf ( + stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n" EFH_MESSAGE_START, + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_FRAME]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_CONTENT]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_TEXT])); em_format_format_text((EMFormat *)efh, (CamelStream *)filtered_stream, (CamelDataWrapper *)part); @@ -876,10 +1349,18 @@ efh_text_html(EMFormatHTML *efh, CamelStream *stream, CamelMimePart *part, EMFor EMFormatPURI *puri; char *cid = NULL; - camel_stream_printf (stream, - "<div style=\"border: solid #%06x 1px; background-color: #%06x; color: #%06x;\">\n" - "<!-- text/html -->\n" EFH_MESSAGE_START, - efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff); + camel_stream_printf ( + stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; color: #%06x;\">\n" + "<!-- text/html -->\n" EFH_MESSAGE_START, + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_FRAME]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_CONTENT]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_TEXT])); /* TODO: perhaps we don't need to calculate this anymore now base is handled better */ /* calculate our own location string so add_puri doesn't do it @@ -1016,9 +1497,17 @@ efh_message_deliverystatus(EMFormatHTML *efh, CamelStream *stream, CamelMimePart guint32 rgb = 0x737373; /* Yuck, this is copied from efh_text_plain */ - camel_stream_printf (stream, - "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n", - efh->frame_colour & 0xffffff, efh->content_colour & 0xffffff, efh->text_colour & 0xffffff); + camel_stream_printf ( + stream, "<div style=\"border: solid #%06x 1px; background-color: #%06x; padding: 10px; color: #%06x;\">\n", + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_FRAME]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_CONTENT]), + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_TEXT])); filtered_stream = camel_stream_filter_new_with_stream(stream); html_filter = camel_mime_filter_tohtml_new(efh->text_html_flags, rgb); @@ -1210,10 +1699,14 @@ static EMFormatHandler type_builtin_table[] = { static void efh_builtin_init(EMFormatHTMLClass *efhc) { - int i; + EMFormatClass *efc; + gint ii; + + efc = (EMFormatClass *) efhc; - for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++) - em_format_class_add_handler((EMFormatClass *)efhc, &type_builtin_table[i]); + for (ii = 0; ii < G_N_ELEMENTS (type_builtin_table); ii++) + em_format_class_add_handler ( + efc, &type_builtin_table[ii]); } /* ********************************************************************** */ @@ -1247,12 +1740,17 @@ efh_format_exec (struct _format_msg *m) if (m->format->html == NULL) return; - camel_stream_printf((CamelStream *)m->estream, - "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" - "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n" - "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n", - m->format->body_colour & 0xffffff, - m->format->header_colour & 0xffffff); + camel_stream_printf ( + (CamelStream *)m->estream, + "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" + "<head>\n<meta name=\"generator\" content=\"Evolution Mail Component\">\n</head>\n" + "<body bgcolor =\"#%06x\" text=\"#%06x\" marginwidth=6 marginheight=6>\n", + e_color_to_value ( + &m->format->priv->colors[ + EM_FORMAT_HTML_COLOR_BODY]), + e_color_to_value ( + &m->format->priv->colors[ + EM_FORMAT_HTML_COLOR_HEADER])); /* <insert top-header stuff here> */ @@ -1332,8 +1830,8 @@ efh_format_done (struct _format_msg *m) { d(printf("formatting finished\n")); - m->format->load_http_now = FALSE; m->format->priv->format_id = -1; + m->format->priv->load_images_now = FALSE; m->format->state = EM_FORMAT_HTML_STATE_NONE; g_signal_emit_by_name(m->format, "complete"); } @@ -1387,7 +1885,9 @@ efh_format_timeout(struct _format_msg *m) d(printf(" ready to go, firing off format thread\n")); /* call super-class to kick it off */ - efh_parent->format_clone((EMFormat *)efh, m->folder, m->uid, m->message, m->format_source); + EM_FORMAT_CLASS (parent_class)->format_clone ( + EM_FORMAT (efh), m->folder, m->uid, + m->message, m->format_source); em_format_html_clear_pobject(m->format); /* FIXME: method off EMFormat? */ @@ -1854,10 +2354,12 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part) charset = camel_iconv_charset_name(charset); if (!efh->simple_headers) - camel_stream_printf(stream, - "<font color=\"#%06x\">\n" - "<table cellpadding=\"0\" width=\"100%%\">", - efh->header_colour & 0xffffff); + camel_stream_printf ( + stream, "<font color=\"#%06x\">\n" + "<table cellpadding=\"0\" width=\"100%%\">", + e_color_to_value ( + &efh->priv->colors[ + EM_FORMAT_HTML_COLOR_HEADER])); hdr_charset = emf->charset ? emf->charset : emf->default_charset; @@ -1939,7 +2441,8 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part) face = !g_ascii_strcasecmp (h->name, "Face"); while (header) { - if (emf->show_photo && !photo_name && !g_ascii_strcasecmp (header->name, "From")) + if (em_format_html_get_show_sender_photo (efh) && + !photo_name && !g_ascii_strcasecmp (header->name, "From")) photo_name = header->value; if (!mailer_shown && mailer && (!g_ascii_strcasecmp (header->name, "X-Mailer") || @@ -1997,10 +2500,12 @@ efh_format_headers(EMFormatHTML *efh, CamelStream *stream, CamelMedium *part) if (photo_name) { char *classid; CamelMimePart *photopart; + gboolean only_local_photo; cia = camel_internet_address_new(); camel_address_decode((CamelAddress *) cia, (const char *) photo_name); - photopart = em_utils_contact_photo (cia, emf->photo_local); + only_local_photo = em_format_html_get_only_local_photos (efh); + photopart = em_utils_contact_photo (cia, only_local_photo); if (photopart) { contact_has_photo = TRUE; diff --git a/mail/em-format-html.h b/mail/em-format-html.h index a74432fdd9..33d60ae19a 100644 --- a/mail/em-format-html.h +++ b/mail/em-format-html.h @@ -25,24 +25,42 @@ Concrete class for formatting mails to html */ -#ifndef _EM_FORMAT_HTML_H -#define _EM_FORMAT_HTML_H - -#include "mail/em-format.h" +#ifndef EM_FORMAT_HTML_H +#define EM_FORMAT_HTML_H + +#include <mail/em-format.h> +#include <mail/mail-config.h> +#include <camel/camel-medium.h> +#include <camel/camel-mime-part.h> +#include <camel/camel-stream.h> +#include <camel/camel-url.h> +#include <gtkhtml/gtkhtml.h> +#include <gtkhtml/gtkhtml-embedded.h> + +/* Standard GObject macros */ +#define EM_TYPE_FORMAT_HTML \ + (em_format_html_get_type ()) +#define EM_FORMAT_HTML(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTML)) +#define EM_FORMAT_HTML_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT_HTML, EMFormatHTMLClass)) +#define EM_IS_FORMAT_HTML(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT_HTML)) +#define EM_IS_FORMAT_HTML_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT_HTML)) +#define EM_FORMAT_HTML_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT_HTML, EMFormatHTMLClass)) + +G_BEGIN_DECLS typedef struct _EMFormatHTML EMFormatHTML; typedef struct _EMFormatHTMLClass EMFormatHTMLClass; - -#if 0 -struct _EMFormatHTMLHandler { - EFrormatHandler base; -}; -#endif - -struct _GtkHTMLEmbedded; -struct _CamelMimePart; -struct _CamelMedium; -struct _CamelStream; +typedef struct _EMFormatHTMLPrivate EMFormatHTMLPrivate; enum _em_format_html_header_flags { EM_FORMAT_HTML_HEADER_TO = 1<<0, @@ -55,9 +73,19 @@ typedef enum { EM_FORMAT_HTML_STATE_RENDERING } EMFormatHTMLState; -/* A HTMLJob will be executed in another thread, in sequence, +typedef enum { + EM_FORMAT_HTML_COLOR_BODY, /* header area background */ + EM_FORMAT_HTML_COLOR_CITATION, /* citation font color */ + EM_FORMAT_HTML_COLOR_CONTENT, /* message area background */ + EM_FORMAT_HTML_COLOR_FRAME, /* frame around message area */ + EM_FORMAT_HTML_COLOR_HEADER, /* header font color */ + EM_FORMAT_HTML_COLOR_TEXT, /* message font color */ + EM_FORMAT_HTML_NUM_COLOR_TYPES +} EMFormatHTMLColorType; + +/* A HTMLJob will be executed in another thread, in sequence. It's job is to write to its stream, close it if successful, - then exit */ + then exit. */ typedef struct _EMFormatHTMLJob EMFormatHTMLJob; @@ -85,21 +113,21 @@ typedef struct _EMFormatHTMLJob EMFormatHTMLJob; * may be used to allocate these. **/ struct _EMFormatHTMLJob { - struct _EMFormatHTMLJob *next; - struct _EMFormatHTMLJob *prev; + EMFormatHTMLJob *next; + EMFormatHTMLJob *prev; EMFormatHTML *format; - struct _CamelStream *stream; + CamelStream *stream; /* We need to track the state of the visibility tree at the point this uri was generated */ struct _EMFormatPURITree *puri_level; - struct _CamelURL *base; + CamelURL *base; - void (*callback)(struct _EMFormatHTMLJob *job, int cancelled); + void (*callback)(EMFormatHTMLJob *job, int cancelled); union { char *uri; - struct _CamelMedium *msg; + CamelMedium *msg; EMFormatPURI *puri; struct _EMFormatPURITree *puri_level; void *data; @@ -109,7 +137,7 @@ struct _EMFormatHTMLJob { /* Pending object (classid: url) */ typedef struct _EMFormatHTMLPObject EMFormatHTMLPObject; -typedef gboolean (*EMFormatHTMLPObjectFunc)(EMFormatHTML *md, struct _GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); +typedef gboolean (*EMFormatHTMLPObjectFunc)(EMFormatHTML *md, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); /** * struct _EMFormatHTMLPObject - Pending object. @@ -130,16 +158,16 @@ typedef gboolean (*EMFormatHTMLPObjectFunc)(EMFormatHTML *md, struct _GtkHTMLEmb * em_format_html_add_pobject() may be used to allocate these. **/ struct _EMFormatHTMLPObject { - struct _EMFormatHTMLPObject *next; - struct _EMFormatHTMLPObject *prev; + EMFormatHTMLPObject *next; + EMFormatHTMLPObject *prev; - void (*free)(struct _EMFormatHTMLPObject *); - struct _EMFormatHTML *format; + void (*free)(EMFormatHTMLPObject *); + EMFormatHTML *format; char *classid; EMFormatHTMLPObjectFunc func; - struct _CamelMimePart *part; + CamelMimePart *part; }; #define EM_FORMAT_HTML_HEADER_NOCOLUMNS (EM_FORMAT_HEADER_LAST) @@ -178,26 +206,16 @@ struct _EMFormatHTMLPObject { * multipart/related objects and inline images. **/ struct _EMFormatHTML { - EMFormat format; + EMFormat parent; + EMFormatHTMLPrivate *priv; - struct _EMFormatHTMLPrivate *priv; - - struct _GtkHTML *html; + GtkHTML *html; EDList pending_object_list; GSList *headers; guint32 text_html_flags; /* default flags for text to html conversion */ - guint32 body_colour; /* header box colour */ - guint32 header_colour; - guint32 text_colour; - guint32 frame_colour; - guint32 content_colour; - guint32 citation_colour; - unsigned int load_http:2; - unsigned int load_http_now:1; - unsigned int mark_citations:1; unsigned int simple_headers:1; /* simple header format, no box/table */ unsigned int hide_headers:1; /* no headers at all */ unsigned int show_icon:1; /* show an icon when the sender used Evo */ @@ -207,30 +225,69 @@ struct _EMFormatHTML { }; struct _EMFormatHTMLClass { - EMFormatClass format_class; - + EMFormatClass parent_class; }; -GType em_format_html_get_type(void); -EMFormatHTML *em_format_html_new(void); - -void em_format_html_load_http(EMFormatHTML *emf); - -void em_format_html_set_load_http(EMFormatHTML *emf, int style); -void em_format_html_set_mark_citations(EMFormatHTML *emf, int state, guint32 citation_colour); +GType em_format_html_get_type (void); +EMFormatHTML * em_format_html_new (void); +void em_format_html_load_images (EMFormatHTML *efh); +void em_format_html_get_color (EMFormatHTML *efh, + EMFormatHTMLColorType type, + GdkColor *color); +void em_format_html_set_color (EMFormatHTML *efh, + EMFormatHTMLColorType type, + const GdkColor *color); +MailConfigHTTPMode + em_format_html_get_image_loading_policy + (EMFormatHTML *efh); +void em_format_html_set_image_loading_policy + (EMFormatHTML *efh, + MailConfigHTTPMode policy); +gboolean em_format_html_get_mark_citations + (EMFormatHTML *efh); +void em_format_html_set_mark_citations + (EMFormatHTML *efh, + gboolean mark_citations); +gboolean em_format_html_get_only_local_photos + (EMFormatHTML *efh); +void em_format_html_set_only_local_photos + (EMFormatHTML *efh, + gboolean only_local_photos); +gboolean em_format_html_get_show_sender_photo + (EMFormatHTML *efh); +void em_format_html_set_show_sender_photo + (EMFormatHTML *efh, + gboolean show_sender_photo); /* retrieves a pseudo-part icon wrapper for a file */ -struct _CamelMimePart *em_format_html_file_part(EMFormatHTML *efh, const char *mime_type, const char *filename); +CamelMimePart * em_format_html_file_part (EMFormatHTML *efh, + const gchar *mime_type, + const gchar *filename); /* for implementers */ -EMFormatHTMLPObject *em_format_html_add_pobject(EMFormatHTML *efh, size_t size, const char *classid, struct _CamelMimePart *part, EMFormatHTMLPObjectFunc func); -EMFormatHTMLPObject *em_format_html_find_pobject(EMFormatHTML *emf, const char *classid); -EMFormatHTMLPObject *em_format_html_find_pobject_func(EMFormatHTML *emf, struct _CamelMimePart *part, EMFormatHTMLPObjectFunc func); -void em_format_html_remove_pobject(EMFormatHTML *emf, EMFormatHTMLPObject *pobject); -void em_format_html_clear_pobject(EMFormatHTML *emf); - -EMFormatHTMLJob *em_format_html_job_new(EMFormatHTML *emfh, void (*callback)(struct _EMFormatHTMLJob *job, int cancelled), void *data) -; -void em_format_html_job_queue(EMFormatHTML *emfh, struct _EMFormatHTMLJob *job); - -#endif /* ! EM_FORMAT_HTML_H */ +EMFormatHTMLPObject * + em_format_html_add_pobject (EMFormatHTML *efh, + size_t size, + const char *classid, + CamelMimePart *part, + EMFormatHTMLPObjectFunc func); +EMFormatHTMLPObject * + em_format_html_find_pobject (EMFormatHTML *efh, + const char *classid); +EMFormatHTMLPObject * + em_format_html_find_pobject_func(EMFormatHTML *efh, + CamelMimePart *part, + EMFormatHTMLPObjectFunc func); +void em_format_html_remove_pobject (EMFormatHTML *efh, + EMFormatHTMLPObject *pobject); +void em_format_html_clear_pobject (EMFormatHTML *efh); +EMFormatHTMLJob * + em_format_html_job_new (EMFormatHTML *efh, + void (*callback)(EMFormatHTMLJob *job, int cancelled), + void *data); +void em_format_html_job_queue (EMFormatHTML *efh, + EMFormatHTMLJob *job); + +G_END_DECLS + +#endif /* EM_FORMAT_HTML_H */ diff --git a/mail/em-format.c b/mail/em-format.c index a807481827..95db7daeec 100644 --- a/mail/em-format.c +++ b/mail/em-format.c @@ -32,7 +32,6 @@ #include <gio/gio.h> #include <libedataserver/e-msgport.h> -#include <camel/camel-url.h> #include <camel/camel-stream.h> #include <camel/camel-stream-mem.h> #include <camel/camel-multipart.h> @@ -63,8 +62,8 @@ This is still kind of yucky, we should maintian a full tree of all this data, along with/as part of the puri tree */ struct _EMFormatCache { - struct _CamelCipherValidity *valid; /* validity copy */ - struct _CamelMimePart *secured; /* encrypted subpart */ + CamelCipherValidity *valid; /* validity copy */ + CamelMimePart *secured; /* encrypted subpart */ unsigned int state:2; /* inline state */ @@ -86,8 +85,8 @@ enum { EMF_LAST_SIGNAL, }; -static guint emf_signals[EMF_LAST_SIGNAL]; -static GObjectClass *emf_parent; +static gpointer parent_class; +static guint signals[EMF_LAST_SIGNAL]; static void emf_free_cache(struct _EMFormatCache *efc) @@ -112,18 +111,14 @@ emf_insert_cache(EMFormat *emf, const char *partid) } static void -emf_init(GObject *o) +emf_init (EMFormat *emf) { - EMFormat *emf = (EMFormat *)o; - emf->inline_table = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) emf_free_cache); emf->composer = FALSE; emf->print = FALSE; - emf->show_photo = TRUE; - emf->photo_local = TRUE; e_dlist_init(&emf->header_list); em_format_default_headers(emf); emf->part_id = g_string_new(""); @@ -133,14 +128,14 @@ emf_init(GObject *o) } static void -emf_finalise(GObject *o) +emf_finalize (GObject *object) { - EMFormat *emf = (EMFormat *)o; + EMFormat *emf = EM_FORMAT (object); if (emf->session) - camel_object_unref(emf->session); + camel_object_unref (emf->session); - g_hash_table_destroy(emf->inline_table); + g_hash_table_destroy (emf->inline_table); em_format_clear_headers(emf); camel_cipher_validity_free(emf->valid); @@ -150,54 +145,66 @@ emf_finalise(GObject *o) /* FIXME: check pending jobs */ - ((GObjectClass *)emf_parent)->finalize(o); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -emf_base_init(EMFormatClass *emfklass) +emf_base_init (EMFormatClass *class) { - emfklass->type_handlers = g_hash_table_new(g_str_hash, g_str_equal); - emf_builtin_init(emfklass); + class->type_handlers = g_hash_table_new (g_str_hash, g_str_equal); + emf_builtin_init (class); } static void -emf_class_init(GObjectClass *klass) +emf_class_init (EMFormatClass *class) { - ((EMFormatClass *)klass)->type_handlers = g_hash_table_new(g_str_hash, g_str_equal); - emf_builtin_init((EMFormatClass *)klass); - - klass->finalize = emf_finalise; - ((EMFormatClass *)klass)->find_handler = emf_find_handler; - ((EMFormatClass *)klass)->format_clone = emf_format_clone; - ((EMFormatClass *)klass)->format_secure = emf_format_secure; - ((EMFormatClass *)klass)->busy = emf_busy; - - emf_signals[EMF_COMPLETE] = - g_signal_new("complete", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EMFormatClass, complete), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + + object_class = G_OBJECT_CLASS (class); + object_class->finalize = emf_finalize; + + class->find_handler = emf_find_handler; + class->format_clone = emf_format_clone; + class->format_secure = emf_format_secure; + class->busy = emf_busy; + + signals[EMF_COMPLETE] = g_signal_new ( + "complete", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMFormatClass, complete), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + class->type_handlers = g_hash_table_new (g_str_hash, g_str_equal); + emf_builtin_init (class); } GType -em_format_get_type(void) +em_format_get_type (void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof(EMFormatClass), - (GBaseInitFunc)emf_base_init, NULL, - (GClassInitFunc)emf_class_init, - NULL, NULL, - sizeof(EMFormat), 0, - (GInstanceInitFunc)emf_init + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMFormatClass), + (GBaseInitFunc) emf_base_init, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) emf_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMFormat), + 0, /* n_preallocs */ + (GInstanceInitFunc) emf_init, + NULL /* value_table */ }; - emf_parent = g_type_class_ref(G_TYPE_OBJECT); - type = g_type_register_static(G_TYPE_OBJECT, "EMFormat", &info, 0); + + type = g_type_register_static ( + G_TYPE_OBJECT, "EMFormat", &type_info, 0); } return type; @@ -259,6 +266,7 @@ em_format_merge_handler(EMFormat *new, EMFormat *old) g_hash_table_foreach (oldc->type_handlers, merge_missing, &fclasses); } + /** * em_format_class_remove_handler: * @emfc: @@ -289,6 +297,20 @@ em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info) } } +const EMFormatHandler * +em_format_find_handler (EMFormat *emf, + const gchar *mime_type) +{ + EMFormatClass *class; + + g_return_val_if_fail (EM_IS_FORMAT (emf), NULL); + g_return_val_if_fail (mime_type != NULL, NULL); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_val_if_fail (class->find_handler != NULL, NULL); + return class->find_handler (emf, mime_type); +} + /** * em_format_find_handler: * @emf: @@ -762,10 +784,10 @@ emf_busy(EMFormat *emf) /** * em_format_format_clone: - * @emf: Mail formatter. - * @folder: Camel Folder. - * @uid: Uid of message. - * @msg: Camel Message. + * @emf: an #EMFormat + * @folder: a #CamelFolder or %NULL + * @uid: Message UID or %NULL + * @msg: a #CamelMimeMessage or %NULL * @emfsource: Used as a basis for user-altered layout, e.g. inline viewed * attachments. * @@ -776,7 +798,43 @@ emf_busy(EMFormat *emf) * a display refresh, or it can be used to generate an identical layout, * e.g. to print what the user has shown inline. **/ -/* e_format_format_clone is a macro */ +void +em_format_format_clone (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *message, + EMFormat *source) +{ + EMFormatClass *class; + + g_return_if_fail (EM_IS_FORMAT (emf)); + g_return_if_fail (folder == NULL || CAMEL_IS_FOLDER (folder)); + g_return_if_fail (message == NULL || CAMEL_IS_MIME_MESSAGE (message)); + g_return_if_fail (source == NULL || EM_IS_FORMAT (source)); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_if_fail (class->format_clone != NULL); + class->format_clone (emf, folder, uid, message, source); +} + +void +em_format_format (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *message) +{ + /* em_format_format_clone() will check the arguments. */ + em_format_format_clone (emf, folder, uid, message, NULL); +} + +void +em_format_redraw (EMFormat *emf) +{ + g_return_if_fail (EM_IS_FORMAT (emf)); + + em_format_format_clone ( + emf, emf->folder, emf->uid, emf->message, emf); +} /** * em_format_set_mode: @@ -1015,28 +1073,101 @@ void em_format_set_inline(EMFormat *emf, const char *partid, int state) em_format_redraw(emf); } -void em_format_format_error(EMFormat *emf, CamelStream *stream, const char *fmt, ...) +void +em_format_format_attachment (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part, + const gchar *mime_type, + const struct _EMFormatHandler *info) { + EMFormatClass *class; + + g_return_if_fail (EM_IS_FORMAT (emf)); + g_return_if_fail (CAMEL_IS_STREAM (stream)); + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + g_return_if_fail (mime_type != NULL); + g_return_if_fail (info != NULL); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_if_fail (class->format_attachment != NULL); + class->format_attachment (emf, stream, mime_part, mime_type, info); +} + +void +em_format_format_error (EMFormat *emf, + CamelStream *stream, + const gchar *format, + ...) +{ + EMFormatClass *class; + gchar *errmsg; va_list ap; - char *txt; - va_start(ap, fmt); - txt = g_strdup_vprintf(fmt, ap); - ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_error((emf), (stream), (txt)); - g_free(txt); + g_return_if_fail (EM_IS_FORMAT (emf)); + g_return_if_fail (CAMEL_IS_STREAM (stream)); + g_return_if_fail (format != NULL); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_if_fail (class->format_error != NULL); + + va_start (ap, format); + errmsg = g_strdup_vprintf (format, ap); + class->format_error (emf, stream, errmsg); + g_free (errmsg); + va_end (ap); } void -em_format_format_secure(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part, struct _CamelCipherValidity *valid) +em_format_format_secure (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part, + CamelCipherValidity *valid) { - ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_secure(emf, stream, part, valid); + EMFormatClass *class; + + g_return_if_fail (EM_IS_FORMAT (emf)); + g_return_if_fail (CAMEL_IS_STREAM (stream)); + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + g_return_if_fail (valid != NULL); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_if_fail (class->format_secure != NULL); + class->format_secure (emf, stream, mime_part, valid); if (emf->valid_parent == NULL && emf->valid != NULL) { - camel_cipher_validity_free(emf->valid); + camel_cipher_validity_free (emf->valid); emf->valid = NULL; } } +void +em_format_format_source (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part) +{ + EMFormatClass *class; + + g_return_if_fail (EM_IS_FORMAT (emf)); + g_return_if_fail (CAMEL_IS_STREAM (stream)); + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_if_fail (class->format_source != NULL); + class->format_source (emf, stream, mime_part); +} + +gboolean +em_format_busy (EMFormat *emf) +{ + EMFormatClass *class; + + g_return_val_if_fail (EM_IS_FORMAT (emf), FALSE); + + class = EM_FORMAT_GET_CLASS (emf); + g_return_val_if_fail (class->busy != NULL, FALSE); + return class->busy (emf); +} + /* should this be virtual? */ void em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part) @@ -1350,7 +1481,7 @@ emf_multipart_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *part, em_format_format_secure(emf, stream, opart, valid); } - /* TODO: Make sure when we finalise this part, it is zero'd out */ + /* TODO: Make sure when we finalize this part, it is zero'd out */ camel_object_unref(opart); camel_object_unref(context); camel_exception_free(ex); @@ -1706,10 +1837,10 @@ static EMFormatHandler type_builtin_table[] = { }; static void -emf_builtin_init(EMFormatClass *klass) +emf_builtin_init(EMFormatClass *class) { int i; for (i=0;i<sizeof(type_builtin_table)/sizeof(type_builtin_table[0]);i++) - g_hash_table_insert(klass->type_handlers, type_builtin_table[i].mime_type, &type_builtin_table[i]); + g_hash_table_insert(class->type_handlers, type_builtin_table[i].mime_type, &type_builtin_table[i]); } diff --git a/mail/em-format.h b/mail/em-format.h index 7b2dd4bd56..fc29eeaeb4 100644 --- a/mail/em-format.h +++ b/mail/em-format.h @@ -25,28 +25,48 @@ Abstract class for formatting mime messages */ -#ifndef _EM_FORMAT_H -#define _EM_FORMAT_H +#ifndef EM_FORMAT_H +#define EM_FORMAT_H #include <glib-object.h> -#include "libedataserver/e-msgport.h" - -struct _CamelStream; -struct _CamelMimePart; -struct _CamelMedium; -struct _CamelSession; -struct _CamelURL; -struct _CamelDataWrapper; -struct _CamelMimeMessage; -struct _CamelCipherValidity; +#include <camel/camel-url.h> +#include <camel/camel-folder.h> +#include <camel/camel-stream.h> +#include <camel/camel-session.h> +#include <camel/camel-mime-part.h> +#include <camel/camel-mime-message.h> +#include <camel/camel-cipher-context.h> +#include <libedataserver/e-msgport.h> + +/* Standard GObject macros */ +#define EM_TYPE_FORMAT \ + (em_format_get_type ()) +#define EM_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EM_TYPE_FORMAT, EMFormat)) +#define EM_FORMAT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EM_TYPE_FORMAT, EMFormatClass)) +#define EM_IS_FORMAT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EM_TYPE_FORMAT)) +#define EM_IS_FORMAT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EM_TYPE_FORMAT)) +#define EM_FORMAT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EM_TYPE_FORMAT, EMFormatClass)) + +G_BEGIN_DECLS typedef struct _EMFormat EMFormat; typedef struct _EMFormatClass EMFormatClass; +typedef struct _EMFormatPrivate EMFormatPrivate; typedef struct _EMFormatHandler EMFormatHandler; typedef struct _EMFormatHeader EMFormatHeader; -typedef void (*EMFormatFunc) (EMFormat *md, struct _CamelStream *stream, struct _CamelMimePart *part, const EMFormatHandler *info); +typedef void (*EMFormatFunc) (EMFormat *md, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info); typedef enum _em_format_mode_t { EM_FORMAT_NORMAL, @@ -88,7 +108,7 @@ enum _em_format_handler_t { typedef struct _EMFormatPURI EMFormatPURI; -typedef void (*EMFormatPURIFunc)(EMFormat *md, struct _CamelStream *stream, EMFormatPURI *puri); +typedef void (*EMFormatPURIFunc)(EMFormat *md, CamelStream *stream, EMFormatPURI *puri); /** * struct _EMFormatPURI - Pending URI object. @@ -125,7 +145,7 @@ struct _EMFormatPURI { char *part_id; /* will always be set, emf->part_id->str for this part */ EMFormatPURIFunc func; - struct _CamelMimePart *part; + CamelMimePart *part; unsigned int use_count; /* used by multipart/related to see if it was accessed */ }; @@ -193,25 +213,25 @@ struct _EMFormatHeader { struct _EMFormat { GObject parent; - struct _EMFormatPrivate *priv; + EMFormatPrivate *priv; - struct _CamelMimeMessage *message; /* the current message */ + CamelMimeMessage *message; /* the current message */ - struct _CamelFolder *folder; + CamelFolder *folder; char *uid; GString *part_id; /* current part id prefix, for identifying parts directly */ EDList header_list; /* if empty, then all */ - struct _CamelSession *session; /* session, used for authentication when required */ - struct _CamelURL *base; /* content-base header or absolute content-location, for any part */ + CamelSession *session; /* session, used for authentication when required */ + CamelURL *base; /* content-base header or absolute content-location, for any part */ const char *snoop_mime_type; /* if we snooped an application/octet-stream type, what we snooped */ /* for validity enveloping */ - struct _CamelCipherValidity *valid; - struct _CamelCipherValidity *valid_parent; + CamelCipherValidity *valid; + CamelCipherValidity *valid_parent; /* for forcing inlining */ GHashTable *inline_table; @@ -229,8 +249,6 @@ struct _EMFormat { char *default_charset; /* charset fallback */ gboolean composer; /* Formatting from composer ?*/ gboolean print; - gboolean show_photo; /* Want to show the photo of the sender ?*/ - gboolean photo_local; /* Photos only from local addressbooks */ }; struct _EMFormatClass { @@ -242,91 +260,142 @@ struct _EMFormatClass { const EMFormatHandler *(*find_handler)(EMFormat *, const char *mime_type); /* start formatting a message */ - void (*format_clone)(EMFormat *, struct _CamelFolder *, const char *uid, struct _CamelMimeMessage *, EMFormat *); - - void *dummy0; + void (*format_clone)(EMFormat *, CamelFolder *, const char *uid, CamelMimeMessage *, EMFormat *); /* some internel error/inconsistency */ - void (*format_error)(EMFormat *, struct _CamelStream *, const char *msg); + void (*format_error)(EMFormat *, CamelStream *, const char *msg); /* use for external structured parts */ - void (*format_attachment)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, const char *mime_type, const struct _EMFormatHandler *info); - - void *dummy1; + void (*format_attachment)(EMFormat *, CamelStream *, CamelMimePart *, const char *mime_type, const struct _EMFormatHandler *info); /* use for unparsable content */ - void (*format_source)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *); + void (*format_source)(EMFormat *, CamelStream *, CamelMimePart *); /* for outputing secure(d) content */ - void (*format_secure)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, struct _CamelCipherValidity *); + void (*format_secure)(EMFormat *, CamelStream *, CamelMimePart *, CamelCipherValidity *); /* returns true if the formatter is still busy with pending stuff */ gboolean (*busy)(EMFormat *); /* Shows optional way to open messages */ - void (*format_optional)(EMFormat *, struct _CamelStream *, struct _CamelMimePart *, struct _CamelStream* ); + void (*format_optional)(EMFormat *, CamelStream *, CamelMimePart *, CamelStream* ); /* signals */ /* complete, alternative to polling busy, for asynchronous work */ void (*complete)(EMFormat *); }; -void em_format_set_mode(EMFormat *emf, em_format_mode_t type); -void em_format_set_charset(EMFormat *emf, const char *charset); -void em_format_set_default_charset(EMFormat *emf, const char *charset); +void em_format_set_mode (EMFormat *emf, + em_format_mode_t type); +void em_format_set_charset (EMFormat *emf, + const char *charset); +void em_format_set_default_charset (EMFormat *emf, + const char *charset); + +/* also indicates to show all headers */ +void em_format_clear_headers (EMFormat *emf); -void em_format_clear_headers(EMFormat *emf); /* also indicates to show all headers */ -void em_format_default_headers(EMFormat *emf); -void em_format_add_header(EMFormat *emf, const char *name, guint32 flags); +void em_format_default_headers (EMFormat *emf); +void em_format_add_header (EMFormat *emf, + const gchar *name, + guint32 flags); /* FIXME: Need a 'clone' api to copy details about the current view (inlines etc) Or maybe it should live with sub-classes? */ -int em_format_is_attachment(EMFormat *emf, struct _CamelMimePart *part); +int em_format_is_attachment (EMFormat *emf, + CamelMimePart *part); -int em_format_is_inline(EMFormat *emf, const char *partid, struct _CamelMimePart *part, const EMFormatHandler *handle); -void em_format_set_inline(EMFormat *emf, const char *partid, int state); +int em_format_is_inline (EMFormat *emf, + const char *partid, + CamelMimePart *part, + const EMFormatHandler *handle); +void em_format_set_inline (EMFormat *emf, + const char *partid, + int state); -char *em_format_describe_part(struct _CamelMimePart *part, const char *mimetype); +char * em_format_describe_part (CamelMimePart *part, + const char *mime_type); /* for implementers */ -GType em_format_get_type(void); - -void em_format_class_add_handler(EMFormatClass *emfc, EMFormatHandler *info); -void em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info); -#define em_format_find_handler(emf, type) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->find_handler((emf), (type)) -const EMFormatHandler *em_format_fallback_handler(EMFormat *emf, const char *mime_type); +GType em_format_get_type (void); + +void em_format_class_add_handler (EMFormatClass *emfc, + EMFormatHandler *info); +void em_format_class_remove_handler (EMFormatClass *emfc, + EMFormatHandler *info); +const EMFormatHandler * + em_format_find_handler (EMFormat *emf, + const gchar *mime_type); +const EMFormatHandler * + em_format_fallback_handler (EMFormat *emf, + const gchar *mime_type); /* puri is short for pending uri ... really */ -EMFormatPURI *em_format_add_puri(EMFormat *emf, size_t size, const char *uri, struct _CamelMimePart *part, EMFormatPURIFunc func); -EMFormatPURI *em_format_find_visible_puri(EMFormat *emf, const char *uri); -EMFormatPURI *em_format_find_puri(EMFormat *emf, const char *uri); -void em_format_clear_puri_tree(EMFormat *emf); -void em_format_push_level(EMFormat *emf); -void em_format_pull_level(EMFormat *emf); +EMFormatPURI * em_format_add_puri (EMFormat *emf, + size_t size, + const char *uri, + CamelMimePart *part, + EMFormatPURIFunc func); +EMFormatPURI * em_format_find_visible_puri (EMFormat *emf, + const char *uri); +EMFormatPURI * em_format_find_puri (EMFormat *emf, + const char *uri); +void em_format_clear_puri_tree (EMFormat *emf); +void em_format_push_level (EMFormat *emf); +void em_format_pull_level (EMFormat *emf); /* clones inline state/view and format, or use to redraw */ -#define em_format_format_clone(emf, folder, uid, msg, src) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), (folder), (uid), (msg), (src)) +void em_format_format_clone (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *message, + EMFormat *source); + /* formats a new message */ -#define em_format_format(emf, folder, uid, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((emf), (folder), (uid), (msg), NULL) -#define em_format_redraw(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_clone((EMFormat *)(emf), \ - ((EMFormat *)(emf))->folder, \ - ((EMFormat *)(emf))->uid, \ - ((EMFormat *)(emf))->message, \ - (EMFormat *)(emf)) -void em_format_format_error(EMFormat *emf, struct _CamelStream *stream, const char *fmt, ...); -#define em_format_format_attachment(emf, stream, msg, type, info) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_attachment((emf), (stream), (msg), (type), (info)) -#define em_format_format_source(emf, stream, msg) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->format_source((emf), (stream), (msg)) -void em_format_format_secure(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part, struct _CamelCipherValidity *valid); - -#define em_format_busy(emf) ((EMFormatClass *)G_OBJECT_GET_CLASS(emf))->busy((emf)) +void em_format_format (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *message); +void em_format_redraw (EMFormat *emf); +void em_format_format_attachment (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part, + const gchar *mime_type, + const struct _EMFormatHandler *info); +void em_format_format_error (EMFormat *emf, + CamelStream *stream, + const gchar *format, + ...) G_GNUC_PRINTF (3, 4); +void em_format_format_secure (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part, + CamelCipherValidity *valid); +void em_format_format_source (EMFormat *emf, + CamelStream *stream, + CamelMimePart *mime_part); + +gboolean em_format_busy (EMFormat *emf); /* raw content only */ -void em_format_format_content(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part); -/* raw content text parts - should this just be checked/done by above? */ -void em_format_format_text(EMFormat *emf, struct _CamelStream *stream, struct _CamelDataWrapper *part); +void em_format_format_content (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part); -void em_format_part_as(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part, const char *mime_type); -void em_format_part(EMFormat *emf, struct _CamelStream *stream, struct _CamelMimePart *part); -void em_format_merge_handler(EMFormat *new, EMFormat *old); +/* raw content text parts - should this just be checked/done by above? */ +void em_format_format_text (EMFormat *emf, + CamelStream *stream, + CamelDataWrapper *part); + +void em_format_part_as (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part, + const gchar *mime_type); +void em_format_part (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part); +void em_format_merge_handler (EMFormat *new, + EMFormat *old); + +G_END_DECLS #endif /* ! _EM_FORMAT_H */ diff --git a/mail/em-mailer-prefs.c b/mail/em-mailer-prefs.c index 1131ff5ebe..bc93778738 100644 --- a/mail/em-mailer-prefs.c +++ b/mail/em-mailer-prefs.c @@ -181,38 +181,6 @@ mark_seen_timeout_reverse_transform (const GValue *src_value, return TRUE; } -static gboolean -transform_color_to_string (const GValue *src_value, - GValue *dst_value, - gpointer user_data) -{ - const GdkColor *color; - gchar *string; - - color = g_value_get_boxed (src_value); - string = gdk_color_to_string (color); - g_value_set_string (dst_value, string); - g_free (string); - - return TRUE; -} - -static gboolean -transform_string_to_color (const GValue *src_value, - GValue *dst_value, - gpointer user_data) -{ - GdkColor color; - const gchar *string; - gboolean success; - - string = g_value_get_string (src_value); - if (gdk_color_parse (string, &color)) - g_value_set_boxed (dst_value, &color); - - return success; -} - enum { JH_LIST_COLUMN_NAME, JH_LIST_COLUMN_VALUE, @@ -978,8 +946,8 @@ em_mailer_prefs_construct (EMMailerPrefs *prefs, e_mutual_binding_new_full ( G_OBJECT (shell_settings), "mail-citation-color", G_OBJECT (widget), "color", - transform_string_to_color, - transform_color_to_string, + e_binding_transform_string_to_color, + e_binding_transform_color_to_string, NULL, NULL); widget = glade_xml_get_widget (gui, "chkEnableSearchFolders"); diff --git a/mail/mail-config.h b/mail/mail-config.h index 6c4683113f..9a3386dd1d 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -23,9 +23,8 @@ #ifndef MAIL_CONFIG_H #define MAIL_CONFIG_H -#include <glib.h> #include <glib-object.h> - +#include <camel/camel-folder.h> #include <camel/camel-provider.h> struct _EAccount; @@ -38,21 +37,7 @@ struct _ESignatureList; struct _GConfClient; struct _GtkWindow; -struct _CamelFolder; - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -typedef struct _MailConfigSignature { - int id; - char *name; - char *filename; - char *script; - gboolean html; -} MailConfigSignature; - +G_BEGIN_DECLS typedef enum { MAIL_CONFIG_HTTP_NEVER, @@ -115,8 +100,8 @@ void mail_config_uri_renamed (GCompareFunc uri_cmp, const char *old, const char void mail_config_uri_deleted (GCompareFunc uri_cmp, const char *uri); /* static utility functions */ -char *mail_config_folder_to_cachename (struct _CamelFolder *folder, const char *prefix); -char *mail_config_folder_to_safe_url (struct _CamelFolder *folder); +char *mail_config_folder_to_cachename (CamelFolder *folder, const char *prefix); +char *mail_config_folder_to_safe_url (CamelFolder *folder); guint mail_config_get_error_timeout (void); guint mail_config_get_error_level (void); @@ -128,10 +113,6 @@ gboolean mail_config_get_lookup_book_local_only (void); GType evolution_mail_config_get_type (void); -gboolean evolution_mail_config_factory_init (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* MAIL_CONFIG_H */ diff --git a/shell/e-shell-migrate.c b/shell/e-shell-migrate.c index b4467028f4..aa3e1e0f97 100644 --- a/shell/e-shell-migrate.c +++ b/shell/e-shell-migrate.c @@ -85,7 +85,8 @@ shell_migrate_attempt (EShell *shell, } static void -shell_migrate_get_version (gint *major, +shell_migrate_get_version (EShell *shell, + gint *major, gint *minor, gint *micro) { @@ -97,9 +98,8 @@ shell_migrate_get_version (gint *major, old_data_dir = shell_migrate_get_old_data_dir (); key = GCONF_VERSION_KEY; - client = gconf_client_get_default (); + client = e_shell_get_gconf_client (shell); string = gconf_client_get_string (client, key, NULL); - g_object_unref (client); if (string != NULL) { /* Since 1.4.0 we've kept the version key in GConf. */ @@ -206,6 +206,7 @@ e_shell_migrate_attempt (EShell *shell) g_return_val_if_fail (E_IS_SHELL (shell), FALSE); + client = e_shell_get_gconf_client (shell); old_data_dir = shell_migrate_get_old_data_dir (); if (sscanf (BASE_VERSION, "%d.%d", &curr_major, &curr_minor) != 2) { @@ -215,7 +216,7 @@ e_shell_migrate_attempt (EShell *shell) curr_micro = atoi (UPGRADE_REVISION); - shell_migrate_get_version (&major, &minor, µ); + shell_migrate_get_version (shell, &major, &minor, µ); if (!(curr_major > major || (curr_major == major && curr_minor > minor) || @@ -253,10 +254,8 @@ e_shell_migrate_attempt (EShell *shell) _exit (EXIT_SUCCESS); /* Record a successful migration. */ - client = gconf_client_get_default (); string = g_strdup_printf ("%d.%d.%d", major, minor, micro); gconf_client_set_string (client, GCONF_VERSION_KEY, string, NULL); - g_object_unref (client); g_free (string); migrated = TRUE; @@ -264,7 +263,6 @@ e_shell_migrate_attempt (EShell *shell) check_old: key = GCONF_LAST_VERSION_KEY; - client = gconf_client_get_default (); /* Try to retrieve the last migrated version from GConf. */ string = gconf_client_get_string (client, key, NULL); @@ -321,8 +319,6 @@ check_old: gconf_client_set_string (client, key, string, NULL); g_free (string); - g_object_unref (client); - return TRUE; } diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c index 02aac6cf10..bfaa87396b 100644 --- a/shell/e-shell-window-private.c +++ b/shell/e-shell-window-private.c @@ -26,13 +26,16 @@ shell_window_save_switcher_style_cb (GtkRadioAction *action, GtkRadioAction *current, EShellWindow *shell_window) { + EShell *shell; GConfClient *client; GtkToolbarStyle style; const gchar *key; const gchar *string; GError *error = NULL; - client = gconf_client_get_default (); + shell = e_shell_window_get_shell (shell_window); + client = e_shell_get_gconf_client (shell); + style = gtk_radio_action_get_current_value (action); key = "/apps/evolution/shell/view_defaults/buttons_style"; @@ -59,13 +62,12 @@ shell_window_save_switcher_style_cb (GtkRadioAction *action, g_warning ("%s", error->message); g_error_free (error); } - - g_object_unref (client); } static void shell_window_init_switcher_style (EShellWindow *shell_window) { + EShell *shell; GtkAction *action; GConfClient *client; GtkToolbarStyle style; @@ -76,7 +78,9 @@ shell_window_init_switcher_style (EShellWindow *shell_window) /* XXX GConfBridge doesn't let you convert between numeric properties * and string keys, so we have to create the binding manually. */ - client = gconf_client_get_default (); + shell = e_shell_window_get_shell (shell_window); + client = e_shell_get_gconf_client (shell); + action = ACTION (SWITCHER_STYLE_ICONS); key = "/apps/evolution/shell/view_defaults/buttons_style"; string = gconf_client_get_string (client, key, &error); @@ -99,8 +103,6 @@ shell_window_init_switcher_style (EShellWindow *shell_window) action, "changed", G_CALLBACK (shell_window_save_switcher_style_cb), shell_window); - - g_object_unref (client); } static void diff --git a/shell/e-shell.c b/shell/e-shell.c index e2d7761965..203e216344 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -40,6 +40,7 @@ struct _EShellPrivate { GList *watched_windows; EShellSettings *settings; + GConfClient *gconf_client; /* Shell Modules */ GList *loaded_modules; @@ -459,6 +460,11 @@ shell_dispose (GObject *object) priv->settings = NULL; } + if (priv->gconf_client != NULL) { + g_object_unref (priv->gconf_client); + priv->gconf_client = NULL; + } + g_list_foreach ( priv->loaded_modules, (GFunc) g_type_module_unuse, NULL); @@ -830,6 +836,7 @@ shell_init (EShell *shell) modules_by_scheme = g_hash_table_new (g_str_hash, g_str_equal); shell->priv->settings = g_object_new (E_TYPE_SHELL_SETTINGS, NULL); + shell->priv->gconf_client = gconf_client_get_default (); shell->priv->modules_by_name = modules_by_name; shell->priv->modules_by_scheme = modules_by_scheme; shell->priv->safe_mode = e_file_lock_exists (); @@ -1021,6 +1028,23 @@ e_shell_get_shell_settings (EShell *shell) } /** + * e_shell_get_gconf_client: + * @shell: an #EShell + * + * Returns the default #GConfClient. This function is purely for + * convenience. The @shell owns the reference so you don't have to. + * + * Returns: the default #GConfClient + **/ +GConfClient * +e_shell_get_gconf_client (EShell *shell) +{ + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + return shell->priv->gconf_client; +} + +/** * e_shell_create_shell_window: * @shell: an #EShell * @view_name: name of the initial shell view, or %NULL @@ -1055,10 +1079,9 @@ e_shell_create_shell_window (EShell *shell, const gchar *key; GError *error = NULL; - client = gconf_client_get_default (); + client = e_shell_get_gconf_client (shell); key = "/apps/evolution/shell/view_defaults/component_id"; gconf_client_set_string (client, key, view_name, &error); - g_object_unref (client); if (error != NULL) { g_warning ("%s", error->message); diff --git a/shell/e-shell.h b/shell/e-shell.h index 3f23779ee7..137900214d 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -29,6 +29,7 @@ #define E_SHELL_H #include <unique/unique.h> +#include <gconf/gconf-client.h> #include <shell/e-shell-common.h> #include <shell/e-shell-module.h> #include <shell/e-shell-settings.h> @@ -85,6 +86,7 @@ EShellModule * e_shell_get_module_by_name (EShell *shell, EShellModule * e_shell_get_module_by_scheme (EShell *shell, const gchar *scheme); EShellSettings *e_shell_get_shell_settings (EShell *shell); +GConfClient * e_shell_get_gconf_client (EShell *shell); GtkWidget * e_shell_create_shell_window (EShell *shell, const gchar *view_name); guint e_shell_handle_uris (EShell *shell, |