From bc4f60ba176b64cc8fd8ffa47a01542f8eb25bdf Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 26 Mar 2009 19:33:16 +0000 Subject: Saving progress again on the attachment rewrite. svn path=/branches/kill-bonobo/; revision=37478 --- widgets/misc/e-attachment-dialog.c | 6 +- widgets/misc/e-attachment-store.c | 134 -------------- widgets/misc/e-attachment.c | 345 ++++++++++++++++++++++++++++++++++--- 3 files changed, 327 insertions(+), 158 deletions(-) (limited to 'widgets/misc') diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c index a844c228eb..dd39a253c9 100644 --- a/widgets/misc/e-attachment-dialog.c +++ b/widgets/misc/e-attachment-dialog.c @@ -97,11 +97,13 @@ attachment_dialog_update (EAttachmentDialog *dialog) widget = dialog->priv->display_name_entry; gtk_widget_set_sensitive (widget, sensitive); - gtk_entry_set_text (GTK_ENTRY (widget), display_name); + if (display_name != NULL) + gtk_entry_set_text (GTK_ENTRY (widget), display_name); widget = dialog->priv->description_entry; gtk_widget_set_sensitive (widget, sensitive); - gtk_entry_set_text (GTK_ENTRY (widget), description); + if (description != NULL) + gtk_entry_set_text (GTK_ENTRY (widget), description); widget = dialog->priv->content_type_label; gtk_label_set_text (GTK_LABEL (widget), type_description); diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c index 6086ed4d2f..3b273f929c 100644 --- a/widgets/misc/e-attachment-store.c +++ b/widgets/misc/e-attachment-store.c @@ -30,8 +30,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT_STORE, EAttachmentStorePrivate)) -#define DEFAULT_ICON_NAME "mail-attachment" - struct _EAttachmentStorePrivate { GHashTable *attachment_index; gchar *background_filename; @@ -223,123 +221,6 @@ attachment_store_constructed (GObject *object) gconf_bridge_bind_property (bridge, key, object, prop); } -static void -attachment_store_row_changed (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter) -{ - EAttachmentStorePrivate *priv; - EAttachment *attachment; - GFileInfo *file_info; - GFile *file; - GIcon *icon; - GList *list; - const gchar *content_type; - const gchar *display_name; - const gchar *thumbnail_path; - gchar *content_description; - gchar *display_size; - gchar *caption; - gboolean loading; - gboolean saving; - goffset size; - gint column_id; - gint percent; - - priv = E_ATTACHMENT_STORE_GET_PRIVATE (model); - - if (priv->ignore_row_changed) - return; - - column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT; - gtk_tree_model_get (model, iter, column_id, &attachment, -1); - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - - file_info = e_attachment_get_file_info (attachment); - if (file_info == NULL) { - g_object_unref (attachment); - return; - } - - content_type = g_file_info_get_content_type (file_info); - display_name = g_file_info_get_display_name (file_info); - thumbnail_path = e_attachment_get_thumbnail_path (attachment); - loading = e_attachment_get_loading (attachment); - percent = e_attachment_get_percent (attachment); - saving = e_attachment_get_saving (attachment); - icon = g_file_info_get_icon (file_info); - size = g_file_info_get_size (file_info); - - content_type = (content_type != NULL) ? content_type : ""; - content_description = g_content_type_get_description (content_type); - display_size = g_format_size_for_display (size); - - if (size > 0) - caption = g_strdup_printf ( - "%s\n(%s)", display_name, display_size); - else - caption = g_strdup (display_name); - - /* Prefer the thumbnail if we have one. */ - if (thumbnail_path != NULL && *thumbnail_path != '\0') { - file = g_file_new_for_path (thumbnail_path); - icon = g_file_icon_new (file); - g_object_unref (file); - - /* Else use the standard icon for the content type. */ - } else if (icon != NULL) - g_object_ref (icon); - - /* Last ditch fallback. (GFileInfo not yet loaded?) */ - else - icon = g_themed_icon_new (DEFAULT_ICON_NAME); - - /* Apply emblems. */ - list = e_attachment_list_emblems (attachment); - if (list != NULL) { - GIcon *emblemed_icon; - GEmblem *emblem; - - emblem = G_EMBLEM (list->data); - emblemed_icon = g_emblemed_icon_new (icon, emblem); - list = g_list_delete_link (list, list); - g_object_unref (emblem); - - while (list != NULL) { - emblem = G_EMBLEM (list->data); - g_emblemed_icon_add_emblem ( - G_EMBLEMED_ICON (emblemed_icon), emblem); - list = g_list_delete_link (list, list); - g_object_unref (emblem); - } - - g_object_unref (icon); - icon = emblemed_icon; - } - - /* We're about to trigger another "row-changed" - * signal, so this prevents infinite recursion. */ - priv->ignore_row_changed = TRUE; - - gtk_list_store_set ( - GTK_LIST_STORE (model), iter, - E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_description, - E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, - E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, - E_ATTACHMENT_STORE_COLUMN_ICON, icon, - E_ATTACHMENT_STORE_COLUMN_LOADING, loading, - E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, - E_ATTACHMENT_STORE_COLUMN_SAVING, saving, - E_ATTACHMENT_STORE_COLUMN_SIZE, size, - -1); - - priv->ignore_row_changed = FALSE; - - g_object_unref (icon); - g_free (content_description); - g_free (display_size); -} - static void attachment_store_class_init (EAttachmentStoreClass *class) { @@ -425,12 +306,6 @@ attachment_store_class_init (EAttachmentStoreClass *class) G_PARAM_READABLE)); } -static void -attachment_store_iface_init (GtkTreeModelIface *iface) -{ - iface->row_changed = attachment_store_row_changed; -} - static void attachment_store_init (EAttachmentStore *store) { @@ -481,18 +356,9 @@ e_attachment_store_get_type (void) NULL /* value_table */ }; - static const GInterfaceInfo iface_info = { - (GInterfaceInitFunc) attachment_store_iface_init, - (GInterfaceFinalizeFunc) NULL, - NULL /* interface_data */ - }; - type = g_type_register_static ( GTK_TYPE_LIST_STORE, "EAttachmentStore", &type_info, 0); - - g_type_add_interface_static ( - type, GTK_TYPE_TREE_MODEL, &iface_info); } return type; diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 55b3280e87..7044aa8cde 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -32,11 +32,15 @@ #include #include "e-util/e-util.h" +#include "e-attachment-store.h" #define E_ATTACHMENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) +/* Fallback Icon */ +#define DEFAULT_ICON_NAME "mail-attachment" + /* Emblems */ #define EMBLEM_CANCELLED "gtk-cancel" #define EMBLEM_LOADING "emblem-downloads" @@ -122,25 +126,258 @@ attachment_get_default_charset (void) } static void -attachment_notify_model (EAttachment *attachment) +attachment_update_file_info_columns (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + GFileInfo *file_info; + const gchar *content_type; + const gchar *display_name; + gchar *display_size; + gchar *caption; + goffset size; + + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + content_type = g_file_info_get_content_type (file_info); + display_name = g_file_info_get_display_name (file_info); + size = g_file_info_get_size (file_info); + + display_size = g_format_size_for_display (size); + + if (size > 0) + caption = g_strdup_printf ( + "%s\n(%s)", display_name, display_size); + else + caption = g_strdup (display_name); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_CAPTION, caption, + E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_type, + E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name, + E_ATTACHMENT_STORE_COLUMN_SIZE, size, + -1); + + g_free (display_size); + g_free (caption); +} + +static void +attachment_update_icon_column (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + GFileInfo *file_info; + GCancellable *cancellable; + GIcon *icon = NULL; + const gchar *emblem_name = NULL; + const gchar *thumbnail_path = NULL; + + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + cancellable = attachment->priv->cancellable; + file_info = e_attachment_get_file_info (attachment); + + if (file_info != NULL) { + icon = g_file_info_get_icon (file_info); + thumbnail_path = g_file_info_get_attribute_byte_string ( + file_info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH); + } + + /* Prefer the thumbnail if we have one. */ + if (thumbnail_path != NULL && *thumbnail_path != '\0') { + GFile *file; + + file = g_file_new_for_path (thumbnail_path); + icon = g_file_icon_new (file); + g_object_unref (file); + + /* Else use the standard icon for the content type. */ + } else if (icon != NULL) + g_object_ref (icon); + + /* Last ditch fallback. (GFileInfo not yet loaded?) */ + else + icon = g_themed_icon_new (DEFAULT_ICON_NAME); + + /* Pick an emblem, limit one. Choices listed by priority. */ + + if (g_cancellable_is_cancelled (cancellable)) + emblem_name = EMBLEM_CANCELLED; + + else if (e_attachment_get_loading (attachment)) + emblem_name = EMBLEM_LOADING; + + else if (e_attachment_get_saving (attachment)) + emblem_name = EMBLEM_SAVING; + + else if (e_attachment_get_encrypted (attachment)) + switch (e_attachment_get_encrypted (attachment)) { + case CAMEL_CIPHER_VALIDITY_ENCRYPT_WEAK: + emblem_name = EMBLEM_ENCRYPT_WEAK; + break; + + case CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED: + emblem_name = EMBLEM_ENCRYPT_UNKNOWN; + break; + + case CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG: + emblem_name = EMBLEM_ENCRYPT_STRONG; + break; + + default: + g_warn_if_reached (); + break; + } + + else if (e_attachment_get_signed (attachment)) + switch (e_attachment_get_signed (attachment)) { + case CAMEL_CIPHER_VALIDITY_SIGN_GOOD: + emblem_name = EMBLEM_SIGN_GOOD; + break; + + case CAMEL_CIPHER_VALIDITY_SIGN_BAD: + emblem_name = EMBLEM_SIGN_BAD; + break; + + case CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN: + case CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY: + emblem_name = EMBLEM_SIGN_UNKNOWN; + break; + + default: + g_warn_if_reached (); + break; + } + + if (emblem_name != NULL) { + GIcon *emblemed_icon; + GEmblem *emblem; + + emblemed_icon = g_themed_icon_new (emblem_name); + emblem = g_emblem_new (emblemed_icon); + g_object_unref (emblemed_icon); + + emblemed_icon = g_emblemed_icon_new (icon, emblem); + g_object_unref (emblem); + g_object_unref (icon); + + icon = emblemed_icon; + } + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_ICON, icon, + -1); + + g_object_unref (icon); +} + +static void +attachment_update_loading_column (EAttachment *attachment) { GtkTreeRowReference *reference; GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter; + GFileInfo *file_info; + gboolean loading; reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; - if (reference == NULL) + /* Don't show progress until we have a GFileInfo. */ + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) return; model = gtk_tree_row_reference_get_model (reference); path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + loading = e_attachment_get_loading (attachment); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_LOADING, loading, + -1); +} + +static void +attachment_update_percent_column (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gint percent; + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_model_row_changed (model, path, &iter); + gtk_tree_path_free (path); + + percent = e_attachment_get_percent (attachment); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_PERCENT, percent, + -1); +} +static void +attachment_update_saving_column (EAttachment *attachment) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gboolean saving; + + reference = e_attachment_get_reference (attachment); + if (!gtk_tree_row_reference_valid (reference)) + return; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + gtk_tree_model_get_iter (model, &iter, path); gtk_tree_path_free (path); + + saving = e_attachment_get_saving (attachment); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + E_ATTACHMENT_STORE_COLUMN_SAVING, saving, + -1); } static void @@ -167,8 +404,6 @@ attachment_set_file_info (EAttachment *attachment, model = gtk_tree_row_reference_get_model (reference); g_object_notify (G_OBJECT (model), "total-size"); } - - attachment_notify_model (attachment); } static void @@ -192,8 +427,6 @@ attachment_set_loading (EAttachment *attachment, model = gtk_tree_row_reference_get_model (reference); g_object_notify (G_OBJECT (model), "num-loading"); } - - attachment_notify_model (attachment); } static void @@ -207,8 +440,6 @@ attachment_set_saving (EAttachment *attachment, g_object_notify (G_OBJECT (attachment), "percent"); g_object_notify (G_OBJECT (attachment), "saving"); g_object_thaw_notify (G_OBJECT (attachment)); - - attachment_notify_model (attachment); } static void @@ -220,8 +451,6 @@ attachment_progress_cb (goffset current_num_bytes, (current_num_bytes * 100) / total_num_bytes; g_object_notify (G_OBJECT (attachment), "percent"); - - attachment_notify_model (attachment); } static gboolean @@ -230,7 +459,7 @@ attachment_cancelled_timeout_cb (EAttachment *attachment) attachment->priv->emblem_timeout_id = 0; g_cancellable_reset (attachment->priv->cancellable); - attachment_notify_model (attachment); + attachment_update_icon_column (attachment); return FALSE; } @@ -247,6 +476,8 @@ attachment_cancelled_cb (EAttachment *attachment) attachment->priv->emblem_timeout_id = g_timeout_add_seconds ( 1, (GSourceFunc) attachment_cancelled_timeout_cb, attachment); + + attachment_update_icon_column (attachment); } static void @@ -555,6 +786,66 @@ attachment_init (EAttachment *attachment) attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE; + g_signal_connect ( + attachment, "notify::encrypted", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::file-info", + G_CALLBACK (attachment_update_file_info_columns), NULL); + + g_signal_connect ( + attachment, "notify::file-info", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::file-info", + G_CALLBACK (attachment_update_loading_column), NULL); + + g_signal_connect ( + attachment, "notify::loading", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::loading", + G_CALLBACK (attachment_update_loading_column), NULL); + + g_signal_connect ( + attachment, "notify::percent", + G_CALLBACK (attachment_update_percent_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_file_info_columns), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_loading_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_saving_column), NULL); + + g_signal_connect ( + attachment, "notify::reference", + G_CALLBACK (attachment_update_percent_column), NULL); + + g_signal_connect ( + attachment, "notify::saving", + G_CALLBACK (attachment_update_icon_column), NULL); + + g_signal_connect ( + attachment, "notify::saving", + G_CALLBACK (attachment_update_saving_column), NULL); + + g_signal_connect ( + attachment, "notify::signed", + G_CALLBACK (attachment_update_icon_column), NULL); + g_signal_connect_swapped ( attachment->priv->cancellable, "cancelled", G_CALLBACK (attachment_cancelled_cb), attachment); @@ -851,10 +1142,6 @@ e_attachment_get_reference (EAttachment *attachment) { g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - /* Don't return an invalid tree row reference. */ - if (!gtk_tree_row_reference_valid (attachment->priv->reference)) - e_attachment_set_reference (attachment, NULL); - return attachment->priv->reference; } @@ -900,7 +1187,6 @@ e_attachment_set_encrypted (EAttachment *attachment, attachment->priv->encrypted = encrypted; g_object_notify (G_OBJECT (attachment), "encrypted"); - attachment_notify_model (attachment); } camel_cipher_validity_sign_t @@ -922,7 +1208,6 @@ e_attachment_set_signed (EAttachment *attachment, attachment->priv->signed_ = signed_; g_object_notify (G_OBJECT (attachment), "signed"); - attachment_notify_model (attachment); } const gchar * @@ -1695,9 +1980,24 @@ attachment_open_file (AttachmentOpenContext *open_context) simple = open_context->simple; open_context->simple = NULL; - if (open_context->app_info == NULL) - open_context->app_info = g_file_query_default_handler ( - open_context->file, NULL, &error); + /* Find a default app based on content type. */ + if (open_context->app_info == NULL) { + EAttachment *attachment; + GFileInfo *file_info; + const gchar *content_type; + + attachment = open_context->attachment; + file_info = e_attachment_get_file_info (attachment); + if (file_info == NULL) + goto exit; + + content_type = g_file_info_get_content_type (file_info); + if (content_type == NULL) + goto exit; + + open_context->app_info = g_app_info_get_default_for_type ( + content_type, FALSE); + } if (open_context->app_info == NULL) goto exit; @@ -2132,7 +2432,8 @@ attachment_save_replace_cb (GFile *destination, * this because CamelStream is synchronous-only, and using threads * is dangerous because CamelDataWrapper is not reentrant. */ buffer = g_byte_array_new (); - stream = camel_stream_mem_new_with_byte_array (buffer); + stream = camel_stream_mem_new (); + camel_stream_mem_set_byte_array (CAMEL_STREAM_MEM (stream), buffer); wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)); camel_data_wrapper_decode_to_stream (wrapper, stream); camel_object_unref (stream); -- cgit v1.2.3