From f963cc39a7d21f64f578dae50fd08c44181a3bf6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 9 Mar 2009 03:31:24 +0000 Subject: Cleaning up the attachment bar, centralizing its popup menu, and converting everything to GtkUIManager/GtkActions. Saving progress mid-stream... not sure about the MIME part utilities yet. Also, add some EActivity subclasses. Considering an EFileActivity subclass for asynchronous GIO operations (loading/saving attachments, etc.), but still ironing out details. svn path=/branches/kill-bonobo/; revision=37389 --- widgets/misc/e-attachment.c | 743 ++++++++++++++++++++++++++------------------ 1 file changed, 443 insertions(+), 300 deletions(-) (limited to 'widgets/misc/e-attachment.c') diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 4f5e9ace34..9bb6f09ade 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -27,6 +27,9 @@ #include #endif +#include "e-attachment.h" +#include "e-attachment-dialog.h" + #ifdef G_OS_WIN32 /* Include early (as the gio stuff below will * include it anyway, sigh) to workaround the DATADIR problem. @@ -56,7 +59,27 @@ #include "e-util/e-mktemp.h" #include "e-util/e-util-private.h" -#include "e-attachment.h" +#define E_ATTACHMENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate)) + +struct _EAttachmentPrivate { + gchar *filename; + gchar *description; + gchar *disposition; + gchar *mime_type; + + GdkPixbuf *thumbnail; + CamelMimePart *mime_part; +}; + +enum { + PROP_0, + PROP_DESCRIPTION, + PROP_DISPOSITION, + PROP_FILENAME, + PROP_THUMBNAIL +}; enum { CHANGED, @@ -64,112 +87,207 @@ enum { LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; - -static GObjectClass *parent_class = NULL; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; static void -changed (EAttachment *attachment) +attachment_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - g_signal_emit (attachment, signals[CHANGED], 0); + switch (property_id) { + case PROP_DESCRIPTION: + e_attachment_set_description ( + E_ATTACHMENT (object), + g_value_get_string (value)); + return; + + case PROP_DISPOSITION: + e_attachment_set_disposition ( + E_ATTACHMENT (object), + g_value_get_string (value)); + return; + + case PROP_FILENAME: + e_attachment_set_filename ( + E_ATTACHMENT (object), + g_value_get_string (value)); + return; + + case PROP_THUMBNAIL: + e_attachment_set_thumbnail ( + E_ATTACHMENT (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } +static void +attachment_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_DESCRIPTION: + g_value_set_string ( + value, e_attachment_get_description ( + E_ATTACHMENT (object))); + return; + + case PROP_DISPOSITION: + g_value_set_string ( + value, e_attachment_get_disposition ( + E_ATTACHMENT (object))); + return; + + case PROP_FILENAME: + g_value_set_string ( + value, e_attachment_get_filename ( + E_ATTACHMENT (object))); + return; + + case PROP_THUMBNAIL: + g_value_set_object ( + value, e_attachment_get_thumbnail ( + E_ATTACHMENT (object))); + return; + } -/* GtkObject methods. */ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} static void -finalise (GObject *object) +attachment_dispose (GObject *object) { - EAttachment *attachment = (EAttachment *) object; - GtkWidget *dialog; + EAttachmentPrivate *priv; - if (attachment->editor_gui != NULL) { - dialog = glade_xml_get_widget (attachment->editor_gui, "dialog"); - g_signal_emit_by_name (dialog, "response", GTK_RESPONSE_CLOSE); - } + priv = E_ATTACHMENT_GET_PRIVATE (object); - if (attachment->is_available_local) { - camel_object_unref (attachment->body); - if (attachment->pixbuf_cache != NULL) - g_object_unref (attachment->pixbuf_cache); - } else { - if (attachment->cancellable) { - /* the operation is still running, so cancel it */ - g_cancellable_cancel (attachment->cancellable); - attachment->cancellable = NULL; - } - g_free (attachment->description); + if (priv->thumbnail != NULL) { + g_object_unref (priv->thumbnail); + priv->thumbnail = NULL; } - g_free (attachment->file_name); - g_free (attachment->store_uri); + if (priv->mime_part != NULL) { + camel_object_unref (priv->mime_part); + priv->mime_part = NULL; + } - G_OBJECT_CLASS (parent_class)->finalize (object); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } - -/* Signals. */ - static void -real_changed (EAttachment *attachment) +attachment_finalize (GObject *object) { - g_return_if_fail (E_IS_ATTACHMENT (attachment)); -} + EAttachment *attachment = (EAttachment *) object; -static void -real_update_attachment (EAttachment *attachment, char *msg) -{ - g_return_if_fail (E_IS_ATTACHMENT (attachment)); -} + if (attachment->cancellable) { + /* the operation is still running, so cancel it */ + g_cancellable_cancel (attachment->cancellable); + attachment->cancellable = NULL; + } + + g_free (attachment->store_uri); + + g_free (attachment->priv->filename); + g_free (attachment->priv->description); + g_free (attachment->priv->disposition); + g_free (attachment->priv->mime_type); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} static void -class_init (EAttachmentClass *klass) +attachment_class_init (EAttachmentClass *class) { GObjectClass *object_class; - object_class = (GObjectClass*) klass; - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - object_class->finalize = finalise; - klass->changed = real_changed; - klass->update = real_update_attachment; - - signals[CHANGED] = g_signal_new ("changed", - E_TYPE_ATTACHMENT, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EAttachmentClass, changed), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[UPDATE] = g_signal_new ("update", - E_TYPE_ATTACHMENT, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EAttachmentClass, update), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAttachmentPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = attachment_set_property; + object_class->get_property = attachment_get_property; + object_class->dispose = attachment_dispose; + object_class->finalize = attachment_finalize; + + g_object_class_install_property ( + object_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "description", + "Description", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "disposition", + "Disposition", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_DESCRIPTION, + g_param_spec_string ( + "filename", + "Filename", + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_THUMBNAIL, + g_param_spec_object ( + "thumbnail", + "Thumbnail Image", + NULL, + GDK_TYPE_PIXBUF, + G_PARAM_READWRITE)); + + signals[CHANGED] = g_signal_new ( + "changed", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EAttachmentClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[UPDATE] = g_signal_new ( + "update", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EAttachmentClass, update), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void -init (EAttachment *attachment) +attachment_init (EAttachment *attachment) { - attachment->editor_gui = NULL; - attachment->body = NULL; - attachment->size = 0; - attachment->pixbuf_cache = NULL; + attachment->priv = E_ATTACHMENT_GET_PRIVATE (attachment); + attachment->index = -1; - attachment->file_name = NULL; attachment->percentage = -1; - attachment->description = NULL; - attachment->disposition = FALSE; attachment->sign = CAMEL_CIPHER_VALIDITY_SIGN_NONE; attachment->encrypt = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; - attachment->store_uri = NULL; - attachment->cancellable = NULL; } GType @@ -177,20 +295,22 @@ e_attachment_get_type (void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { sizeof (EAttachmentClass), - NULL, - NULL, - (GClassInitFunc) class_init, - NULL, - NULL, + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) attachment_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ sizeof (EAttachment), - 0, - (GInstanceInitFunc) init, + 0, /* n_preallocs */ + (GInstanceInitFunc) attachment_init, + NULL /* value_table */ }; - type = g_type_register_static (G_TYPE_OBJECT, "EAttachment", &info, 0); + type = g_type_register_static ( + G_TYPE_OBJECT, "EAttachment", &type_info, 0); } return type; @@ -198,42 +318,42 @@ e_attachment_get_type (void) /** * file_ext_is: - * @param file_name: path for file + * @param filename: path for file * @param ext: desired extension, with a dot - * @return if file_name has extension ext or not + * @return if filename has extension ext or not **/ static gboolean -file_ext_is (const char *file_name, const char *ext) +file_ext_is (const char *filename, const char *ext) { int i, dot = -1; - if (!file_name || !ext) + if (!filename || !ext) return FALSE; - for (i = 0; file_name[i]; i++) { - if (file_name [i] == '.') + for (i = 0; filename[i]; i++) { + if (filename [i] == '.') dot = i; } if (dot > 0) { - return 0 == g_ascii_strcasecmp (file_name + dot, ext); + return 0 == g_ascii_strcasecmp (filename + dot, ext); } return FALSE; } static char * -attachment_guess_mime_type (const char *file_name) +attachment_guess_mime_type (const char *filename) { char *type; gchar *content = NULL; - type = e_util_guess_mime_type (file_name, TRUE); + type = e_util_guess_mime_type (filename, TRUE); if (type && strcmp (type, "text/directory") == 0 && - file_ext_is (file_name, ".vcf") && - g_file_get_contents (file_name, &content, NULL, NULL) && + file_ext_is (filename, ".vcf") && + g_file_get_contents (filename, &content, NULL, NULL) && content) { EVCard *vc = e_vcard_new_from_string (content); @@ -265,30 +385,30 @@ attachment_guess_mime_type (const char *file_name) /** * e_attachment_new: - * @file_name: filename to attach + * @filename: filename to attach * @disposition: Content-Disposition of the attachment * @ex: exception * * Return value: the new attachment, or %NULL on error **/ EAttachment * -e_attachment_new (const char *file_name, const char *disposition, CamelException *ex) +e_attachment_new (const char *filename, const char *disposition, CamelException *ex) { EAttachment *new; CamelMimePart *part; CamelDataWrapper *wrapper; CamelStream *stream; struct stat statbuf; - char *mime_type; - char *filename; + gchar *mime_type; + gchar *basename; CamelURL *url; - g_return_val_if_fail (file_name != NULL, NULL); + g_return_val_if_fail (filename != NULL, NULL); - if (g_stat (file_name, &statbuf) < 0) { + if (g_stat (filename, &statbuf) < 0) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); + filename, g_strerror (errno)); return NULL; } @@ -296,18 +416,18 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException if (!S_ISREG (statbuf.st_mode)) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: not a regular file"), - file_name); + filename); return NULL; } - if (!(stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0))) { + if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); + filename, g_strerror (errno)); return NULL; } - if ((mime_type = attachment_guess_mime_type (file_name))) { + if ((mime_type = attachment_guess_mime_type (filename))) { if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { wrapper = (CamelDataWrapper *) camel_mime_message_new (); } else { @@ -330,8 +450,8 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException camel_object_unref (wrapper); camel_mime_part_set_disposition (part, disposition); - filename = g_path_get_basename (file_name); - camel_mime_part_set_filename (part, filename); + basename = g_path_get_basename (filename); + camel_mime_part_set_filename (part, basename); #if 0 /* Note: Outlook 2002 is broken with respect to Content-Ids on @@ -344,17 +464,15 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException g_free (content_id); #endif - new = g_object_new (E_TYPE_ATTACHMENT, NULL); - new->editor_gui = NULL; - new->body = part; + new = g_object_new (E_TYPE_ATTACHMENT, "filename", basename, NULL); + new->priv->mime_part = part; new->size = statbuf.st_size; new->guessed_type = TRUE; new->cancellable = NULL; new->is_available_local = TRUE; - new->file_name = filename; url = camel_url_new ("file://", NULL); - camel_url_set_path (url, file_name); + camel_url_set_path (url, filename); new->store_uri = camel_url_to_string (url, 0); camel_url_free (url); @@ -364,7 +482,7 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException typedef struct { EAttachment *attachment; - char *file_name; + char *filename; char *uri; GtkWindow *parent; /* for error dialog */ @@ -394,7 +512,7 @@ download_info_free (DownloadInfo *download_info) if (download_info->cancellable) g_object_unref (download_info->cancellable); - g_free (download_info->file_name); + g_free (download_info->filename); g_free (download_info->uri); g_free (download_info->buffer); g_free (download_info); @@ -450,7 +568,7 @@ data_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) download_info->attachment->cancellable = NULL; camel_exception_init (&ex); - e_attachment_build_remote_file (download_info->file_name, download_info->attachment, "attachment", &ex); + e_attachment_build_remote_file (download_info->filename, download_info->attachment, &ex); if (camel_exception_is_set (&ex)) { download_info->was_error = TRUE; @@ -482,7 +600,7 @@ download_to_local_path (DownloadInfo *download_info, CamelException *ex) { GError *error = NULL; GFile *src = g_file_new_for_uri (download_info->uri); - GFile *des = g_file_new_for_path (download_info->file_name); + GFile *des = g_file_new_for_path (download_info->filename); gboolean res = FALSE; g_return_val_if_fail (src != NULL && des != NULL, FALSE); @@ -538,6 +656,7 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons DownloadInfo *download_info; CamelURL *url; char *base; + gchar *filename; g_return_val_if_fail (uri != NULL, NULL); @@ -545,25 +664,26 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons base = g_path_get_basename (url->path); camel_url_free (url); - new = g_object_new (E_TYPE_ATTACHMENT, NULL); - new->editor_gui = NULL; - new->body = NULL; + filename = g_build_filename (path, base, NULL); + + new = g_object_new (E_TYPE_ATTACHMENT, "filename", filename, NULL); new->size = 0; new->guessed_type = FALSE; new->cancellable = NULL; new->is_available_local = FALSE; new->percentage = 0; - new->file_name = g_build_filename (path, base, NULL); g_free (base); download_info = g_new0 (DownloadInfo, 1); download_info->attachment = new; - download_info->file_name = g_strdup (new->file_name); + download_info->filename = g_strdup (filename); download_info->uri = g_strdup (uri); download_info->parent = error_dlg_parent; download_info->was_error = FALSE; + g_free (filename); + /* it frees all on the error, so do not free it twice */ if (!download_to_local_path (download_info, ex)) return NULL; @@ -573,23 +693,27 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons void -e_attachment_build_remote_file (const char *file_name, EAttachment *attachment, const char *disposition, CamelException *ex) +e_attachment_build_remote_file (const gchar *filename, + EAttachment *attachment, + CamelException *ex) { CamelMimePart *part; CamelDataWrapper *wrapper; CamelStream *stream; struct stat statbuf; - char *mime_type; - char *filename; + const gchar *description; + const gchar *disposition; + gchar *mime_type; + gchar *basename; CamelURL *url; - g_return_if_fail (file_name != NULL); + g_return_if_fail (filename != NULL); - if (g_stat (file_name, &statbuf) == -1) { + if (g_stat (filename, &statbuf) == -1) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); - g_message ("Cannot attach file %s: %s\n", file_name, g_strerror (errno)); + filename, g_strerror (errno)); + g_message ("Cannot attach file %s: %s\n", filename, g_strerror (errno)); return; } @@ -597,19 +721,19 @@ e_attachment_build_remote_file (const char *file_name, EAttachment *attachment, if (!S_ISREG (statbuf.st_mode)) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: not a regular file"), - file_name); - g_message ("Cannot attach file %s: not a regular file", file_name); + filename); + g_message ("Cannot attach file %s: not a regular file", filename); return; } - if (!(stream = camel_stream_fs_new_with_name (file_name, O_RDONLY, 0))) { + if (!(stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0))) { camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot attach file %s: %s"), - file_name, g_strerror (errno)); + filename, g_strerror (errno)); return; } - if ((mime_type = attachment_guess_mime_type (file_name))) { + if ((mime_type = attachment_guess_mime_type (filename))) { if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { wrapper = (CamelDataWrapper *) camel_mime_message_new (); } else { @@ -631,36 +755,34 @@ e_attachment_build_remote_file (const char *file_name, EAttachment *attachment, camel_medium_set_content_object (CAMEL_MEDIUM (part), wrapper); camel_object_unref (wrapper); - if (attachment->disposition) - camel_mime_part_set_disposition (part, "inline"); - else - camel_mime_part_set_disposition (part, "attachment"); + disposition = e_attachment_get_disposition (attachment); + camel_mime_part_set_disposition (part, disposition); - if (!attachment->file_name) - filename = g_path_get_basename (file_name); + if (e_attachment_get_filename (attachment) == NULL) + basename = g_path_get_basename (filename); else - filename = g_path_get_basename (attachment->file_name); + basename = g_path_get_basename (e_attachment_get_filename (attachment)); camel_mime_part_set_filename (part, filename); - if (attachment->description) { - camel_mime_part_set_description (part, attachment->description); - g_free (attachment->description); - attachment->description = NULL; + description = e_attachment_get_description (attachment); + if (description != NULL) { + camel_mime_part_set_description (part, description); + e_attachment_set_description (attachment, NULL); } - attachment->editor_gui = NULL; - attachment->body = part; + attachment->priv->mime_part = part; attachment->size = statbuf.st_size; attachment->guessed_type = TRUE; - g_free (attachment->file_name); - attachment->file_name = filename; + + e_attachment_set_filename (attachment, basename); url = camel_url_new ("file://", NULL); - camel_url_set_path (url, file_name); + camel_url_set_path (url, filename); attachment->store_uri = camel_url_to_string (url, 0); camel_url_free (url); + g_free (basename); } @@ -674,210 +796,231 @@ EAttachment * e_attachment_new_from_mime_part (CamelMimePart *part) { EAttachment *new; + const gchar *filename; g_return_val_if_fail (CAMEL_IS_MIME_PART (part), NULL); - new = g_object_new (E_TYPE_ATTACHMENT, NULL); - new->editor_gui = NULL; + filename = camel_mime_part_get_filename (part); + + new = g_object_new (E_TYPE_ATTACHMENT, "filename", filename, NULL); camel_object_ref (part); - new->body = part; + new->priv->mime_part = part; new->guessed_type = FALSE; new->is_available_local = TRUE; new->size = camel_mime_part_get_content_size (part); - new->file_name = g_strdup (camel_mime_part_get_filename(part)); return new; } - -/* The attachment property dialog. */ - -typedef struct { +void +e_attachment_edit (EAttachment *attachment, + GtkWindow *parent) +{ GtkWidget *dialog; - GtkEntry *file_name_entry; - GtkEntry *description_entry; - GtkEntry *mime_type_entry; - GtkToggleButton *disposition_checkbox; - EAttachment *attachment; -} DialogData; -static void -destroy_dialog_data (DialogData *data) + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + dialog = e_attachment_dialog_new (parent, attachment); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +const gchar * +e_attachment_get_description (EAttachment *attachment) { - g_free (data); + CamelMimePart *mime_part; + const gchar *description; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + description = camel_mime_part_get_description (mime_part); + else + description = attachment->priv->description; + + return description; } -/* - * fixme: I am converting EVERYTHING to/from UTF-8, although mime types - * are in ASCII. This is not strictly necessary, but we want to be - * consistent and possibly check for errors somewhere. - */ +void +e_attachment_set_description (EAttachment *attachment, + const gchar *description) +{ + CamelMimePart *mime_part; -static void -set_entry (GladeXML *xml, const char *widget_name, const char *value) + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_free (attachment->priv->description); + attachment->priv->description = g_strdup (description); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + camel_mime_part_set_description (mime_part, description); + + g_object_notify (G_OBJECT (attachment), "description"); +} + +const gchar * +e_attachment_get_disposition (EAttachment *attachment) { - GtkEntry *entry; + CamelMimePart *mime_part; + const gchar *disposition; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - entry = GTK_ENTRY (glade_xml_get_widget (xml, widget_name)); - if (entry == NULL) - g_warning ("Entry for `%s' not found.", widget_name); + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + disposition = camel_mime_part_get_disposition (mime_part); else - gtk_entry_set_text (entry, value ? value : ""); + disposition = attachment->priv->disposition; + + return disposition; } -static void -connect_widget (GladeXML *gui, const char *name, const char *signal_name, - GCallback func, gpointer data) +void +e_attachment_set_disposition (EAttachment *attachment, + const gchar *disposition) { - GtkWidget *widget; + CamelMimePart *mime_part; - widget = glade_xml_get_widget (gui, name); - g_signal_connect (widget, signal_name, func, data); + g_return_if_fail (E_IS_ATTACHMENT (attachment)); + + g_free (attachment->priv->disposition); + attachment->priv->disposition = g_strdup (disposition); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + camel_mime_part_set_disposition (mime_part, disposition); + + g_object_notify (G_OBJECT (attachment), "disposition"); } -static void -close_cb (GtkWidget *widget, gpointer data) +const gchar * +e_attachment_get_filename (EAttachment *attachment) { - EAttachment *attachment; - DialogData *dialog_data; + CamelMimePart *mime_part; + const gchar *filename; - dialog_data = (DialogData *) data; - attachment = dialog_data->attachment; + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); - gtk_widget_destroy (dialog_data->dialog); - g_object_unref (attachment->editor_gui); - attachment->editor_gui = NULL; + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + filename = camel_mime_part_get_filename (mime_part); + else + filename = attachment->priv->filename; - destroy_dialog_data (dialog_data); + return filename; } -static void -ok_cb (GtkWidget *widget, gpointer data) +void +e_attachment_set_filename (EAttachment *attachment, + const gchar *filename) { - DialogData *dialog_data; - EAttachment *attachment; - const char *str; + CamelMimePart *mime_part; - dialog_data = (DialogData *) data; - attachment = dialog_data->attachment; + g_return_if_fail (E_IS_ATTACHMENT (attachment)); - str = gtk_entry_get_text (dialog_data->file_name_entry); - if (attachment->is_available_local) - camel_mime_part_set_filename (attachment->body, str); - g_free (attachment->file_name); - attachment->file_name = g_strdup (str); + g_free (attachment->priv->filename); + attachment->priv->filename = g_strdup (filename); - str = gtk_entry_get_text (dialog_data->description_entry); - if (attachment->is_available_local) { - camel_mime_part_set_description (attachment->body, str); - } else { - g_free (attachment->description); - attachment->description = g_strdup (str); - } + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part != NULL) + camel_mime_part_set_filename (mime_part, filename); - str = gtk_entry_get_text (dialog_data->mime_type_entry); - if (attachment->is_available_local) { - camel_mime_part_set_content_type (attachment->body, str); - camel_data_wrapper_set_mime_type(camel_medium_get_content_object(CAMEL_MEDIUM (attachment->body)), str); - } + g_object_notify (G_OBJECT (attachment), "filename"); +} - if (attachment->is_available_local) { - switch (gtk_toggle_button_get_active (dialog_data->disposition_checkbox)) { - case 0: - camel_mime_part_set_disposition (attachment->body, "attachment"); - break; - case 1: - camel_mime_part_set_disposition (attachment->body, "inline"); - break; - default: - /* Hmmmm? */ - break; - } - } else { - attachment->disposition = gtk_toggle_button_get_active (dialog_data->disposition_checkbox); +CamelMimePart * +e_attachment_get_mime_part (EAttachment *attachment) +{ + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + return attachment->priv->mime_part; +} + +const gchar * +e_attachment_get_mime_type (EAttachment *attachment) +{ + CamelContentType *content_type; + CamelMimePart *mime_part; + const gchar *filename; + gchar *mime_type; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + if (attachment->priv->mime_type != NULL) + goto exit; + + mime_part = e_attachment_get_mime_part (attachment); + filename = e_attachment_get_filename (attachment); + content_type = camel_mime_part_get_content_type (mime_part); + + if (mime_part == NULL) + mime_type = attachment_guess_mime_type (filename); + else { + content_type = camel_mime_part_get_content_type (mime_part); + mime_type = camel_content_type_simple (content_type); } - changed (attachment); - close_cb (widget, data); + attachment->priv->mime_type = mime_type; + +exit: + return attachment->priv->mime_type; } -static void -response_cb (GtkWidget *widget, gint response, gpointer data) +GdkPixbuf * +e_attachment_get_thumbnail (EAttachment *attachment) { - if (response == GTK_RESPONSE_OK) - ok_cb (widget, data); - else - close_cb (widget, data); + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL); + + return attachment->priv->thumbnail; } void -e_attachment_edit (EAttachment *attachment, GtkWidget *parent) +e_attachment_set_thumbnail (EAttachment *attachment, + GdkPixbuf *thumbnail) { - CamelContentType *content_type; - const char *disposition; - DialogData *dialog_data; - GladeXML *editor_gui; - GtkWidget *window; - char *type; - char *filename; - g_return_if_fail (E_IS_ATTACHMENT (attachment)); - if (attachment->editor_gui != NULL) { - window = glade_xml_get_widget (attachment->editor_gui, "dialog"); - gdk_window_show (window->window); - return; + if (thumbnail != NULL) { + g_return_if_fail (GDK_IS_PIXBUF (thumbnail)); + g_object_ref (thumbnail); } - filename = g_build_filename (EVOLUTION_GLADEDIR, "e-attachment.glade", NULL); - editor_gui = glade_xml_new (filename, NULL, NULL); - g_free (filename); + if (attachment->priv->thumbnail != NULL) + g_object_unref (attachment->priv->thumbnail); - if (editor_gui == NULL) { - g_warning ("Cannot load `e-attachment.glade'"); - return; - } + attachment->priv->thumbnail = thumbnail; - attachment->editor_gui = editor_gui; - - gtk_window_set_transient_for (GTK_WINDOW (glade_xml_get_widget (editor_gui, "dialog")), - GTK_WINDOW (gtk_widget_get_toplevel (parent))); - - dialog_data = g_new (DialogData, 1); - dialog_data->attachment = attachment; - dialog_data->dialog = glade_xml_get_widget (editor_gui, "dialog"); - dialog_data->file_name_entry = GTK_ENTRY (glade_xml_get_widget (editor_gui, "file_name_entry")); - dialog_data->description_entry = GTK_ENTRY (glade_xml_get_widget (editor_gui, "description_entry")); - dialog_data->mime_type_entry = GTK_ENTRY (glade_xml_get_widget (editor_gui, "mime_type_entry")); - dialog_data->disposition_checkbox = GTK_TOGGLE_BUTTON (glade_xml_get_widget (editor_gui, "disposition_checkbox")); - - if (attachment->is_available_local && attachment->body) { - set_entry (editor_gui, "file_name_entry", camel_mime_part_get_filename (attachment->body)); - set_entry (editor_gui, "description_entry", camel_mime_part_get_description (attachment->body)); - content_type = camel_mime_part_get_content_type (attachment->body); - type = camel_content_type_simple (content_type); - set_entry (editor_gui, "mime_type_entry", type); - g_free (type); - - disposition = camel_mime_part_get_disposition (attachment->body); - gtk_toggle_button_set_active (dialog_data->disposition_checkbox, - disposition && !g_ascii_strcasecmp (disposition, "inline")); - } else { - set_entry (editor_gui, "file_name_entry", attachment->file_name); - set_entry (editor_gui, "description_entry", attachment->description); - if ((type = attachment_guess_mime_type (attachment->file_name))) { - set_entry (editor_gui, "mime_type_entry", type); - g_free (type); - } else { - set_entry (editor_gui, "mime_type_entry", ""); - } + g_object_notify (G_OBJECT (attachment), "thumbnail"); +} - gtk_toggle_button_set_active (dialog_data->disposition_checkbox, attachment->disposition); - } +gboolean +e_attachment_is_image (EAttachment *attachment) +{ + CamelContentType *content_type; + CamelMimePart *mime_part; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); + + mime_part = e_attachment_get_mime_part (attachment); + if (mime_part == NULL) + return FALSE; + + content_type = camel_mime_part_get_content_type (mime_part); + + return camel_content_type_is (content_type, "image", "*"); +} + +gboolean +e_attachment_is_inline (EAttachment *attachment) +{ + const gchar *disposition; + + g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE); - connect_widget (editor_gui, "dialog", "response", (GCallback)response_cb, dialog_data); + disposition = e_attachment_get_disposition (attachment); + g_return_val_if_fail (disposition != NULL, FALSE); - /* make sure that when the parent gets hidden/closed that our windows also close */ - parent = gtk_widget_get_toplevel (parent); - gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog_data->dialog), TRUE); + return (g_ascii_strcasecmp (disposition, "inline") == 0); } -- cgit v1.2.3