From cae250057c8ad1a0ce35ff5d119063e187789038 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Fri, 26 May 2006 20:51:51 +0000 Subject: Fix for Novell bug #178631 2006-05-26 Jeffrey Stedfast Fix for Novell bug #178631 * e-attachment-bar.c: Changed the EAttachmentBarPrivate struct, we no longer use a linked list, instead we use a GPtrArray - faster, simpler (plus all the code used indexes anyway, so it was really bizarre). (free_attachment_list): Removed. (attachment_destroy): New GWeakNotify callback for when an EAttachment object gets destroyed. Remove the attachment from the attachments array. (add_common): Updated to add to an array rather than a linked list. Also weak_ref the attachment object. (remove_attachment): Removed. (update): Updated to use the array instead of linked list of attachments. (e_attachment_bar_remove_selected): Same. (e_attachment_bar_set_width): Same. (e_attachment_bar_edit_selected): Same. (e_attachment_bar_get_selected): Same. (e_attachment_bar_get_attachment): Same. (e_attachment_bar_get_all_attachments): Same and also optimised since we can cheat now without having to g_slist_reverse. (e_attachment_bar_get_parts): Same. (destroy): Same. (eab_drag_data_get): Same. (init): Init attachments to a g_ptr_array_new (e_attachment_bar_to_multipart): Updated to use the attachments array. (e_attachment_bar_get_num_attachments): Updated to return the attachments->len. (e_attachment_bar_get_download_count): Updated to use the array. * e-attachment.c (finalise): Close the editor dialog if it is open. (async_progress_update_cb): If the phase is COMPLETE but the file_size is 0, then treat it as an error. In the error case, unref the attachment object (this will magically remove it from the EAttachmentBar). (close_cb): Don't unref the attachment object here anymore. (e_attachment_edit): Don't ref the EAttachment anymore. svn path=/trunk/; revision=32042 --- widgets/misc/e-attachment-bar.c | 658 +++++++++++++++++++--------------------- 1 file changed, 308 insertions(+), 350 deletions(-) (limited to 'widgets/misc/e-attachment-bar.c') diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index b8dda048d5..02b78f1c76 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -70,10 +70,10 @@ static GnomeIconListClass *parent_class = NULL; struct _EAttachmentBarPrivate { GtkWidget *attach; /* attachment file dialogue, if active */ - - GList *attachments; - guint num_attachments; - gchar *path; + + gboolean batch_unref; + GPtrArray *attachments; + char *path; }; @@ -89,7 +89,7 @@ static void update (EAttachmentBar *bar); static char * -size_to_string (gulong size) +size_to_string (size_t size) { char *size_string; @@ -120,17 +120,13 @@ size_to_string (gulong size) /* Attachment handling functions. */ static void -free_attachment_list (EAttachmentBar *bar) +attachment_destroy (EAttachmentBar *bar, EAttachment *attachment) { - EAttachmentBarPrivate *priv; - GList *p; - - priv = bar->priv; - - for (p = priv->attachments; p != NULL; p = p->next) - g_object_unref (p->data); + if (bar->priv->batch_unref) + return; - priv->attachments = NULL; + if (g_ptr_array_remove (bar->priv->attachments, attachment)) + g_signal_emit (bar, signals[CHANGED], 0); } static void @@ -141,18 +137,13 @@ attachment_changed_cb (EAttachment *attachment, } static void -add_common (EAttachmentBar *bar, - EAttachment *attachment) +add_common (EAttachmentBar *bar, EAttachment *attachment) { g_return_if_fail (attachment != NULL); - g_signal_connect (attachment, "changed", - G_CALLBACK (attachment_changed_cb), - bar); - - bar->priv->attachments = g_list_append (bar->priv->attachments, - attachment); - bar->priv->num_attachments++; + g_ptr_array_add (bar->priv->attachments, attachment); + g_object_weak_ref ((GObject *) attachment, (GWeakNotify) attachment_destroy, bar); + g_signal_connect (attachment, "changed", G_CALLBACK (attachment_changed_cb), bar); update (bar); @@ -160,53 +151,30 @@ add_common (EAttachmentBar *bar, } static void -add_from_mime_part (EAttachmentBar *bar, - CamelMimePart *part) +add_from_mime_part (EAttachmentBar *bar, CamelMimePart *part) { add_common (bar, e_attachment_new_from_mime_part (part)); } static void -add_from_file (EAttachmentBar *bar, - const char *file_name, - const char *disposition) +add_from_file (EAttachmentBar *bar, const char *file_name, const char *disposition) { EAttachment *attachment; CamelException ex; camel_exception_init (&ex); - attachment = e_attachment_new (file_name, disposition, &ex); - if (attachment) { + + if ((attachment = e_attachment_new (file_name, disposition, &ex))) { add_common (bar, attachment); } else { /* FIXME: Avoid using error from mailer */ - e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)bar), "mail-composer:no-attach", - file_name, camel_exception_get_description(&ex), NULL); + e_error_run ((GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) bar), "mail-composer:no-attach", + file_name, camel_exception_get_description (&ex), NULL); camel_exception_clear (&ex); } } -static void -remove_attachment (EAttachmentBar *bar, - EAttachment *attachment) -{ - g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail (g_list_find (bar->priv->attachments, attachment) != NULL); - - bar->priv->attachments = g_list_remove (bar->priv->attachments, - attachment); - bar->priv->num_attachments--; - if (attachment->editor_gui != NULL) { - GtkWidget *dialog = glade_xml_get_widget (attachment->editor_gui, "dialog"); - g_signal_emit_by_name (dialog, "response", GTK_RESPONSE_CLOSE); - } - - g_object_unref(attachment); - - g_signal_emit (bar, signals[CHANGED], 0); -} - /* Icon list contents handling. */ static void @@ -215,7 +183,7 @@ calculate_height_width(EAttachmentBar *bar, int *new_width, int *new_height) int width, height, icon_width; PangoFontMetrics *metrics; PangoContext *context; - + context = gtk_widget_get_pango_context ((GtkWidget *) bar); metrics = pango_context_get_metrics (context, ((GtkWidget *) bar)->style->font_desc, pango_context_get_language (context)); width = PANGO_PIXELS (pango_font_metrics_get_approximate_char_width (metrics)) * 15; @@ -296,10 +264,10 @@ e_attachment_bar_create_attachment_cache (EAttachment *attachment) static void update (EAttachmentBar *bar) { - EAttachmentBarPrivate *priv; + struct _EAttachmentBarPrivate *priv; GnomeIconList *icon_list; - GList *p; int bar_width, bar_height; + int i; priv = bar->priv; icon_list = GNOME_ICON_LIST (bar); @@ -309,29 +277,28 @@ update (EAttachmentBar *bar) gnome_icon_list_clear (icon_list); /* FIXME could be faster, but we don't care. */ - for (p = priv->attachments; p != NULL; p = p->next) { + for (i = 0; i < priv->attachments->len; i++) { EAttachment *attachment; CamelContentType *content_type; char *size_string, *label; - GdkPixbuf *pixbuf=NULL; + GdkPixbuf *pixbuf = NULL; const char *desc; - attachment = p->data; - + attachment = priv->attachments->pdata[i]; + if (!attachment->is_available_local) { /* stock_attach would be better, but its fugly scaled up */ - pixbuf = e_icon_factory_get_icon("stock_unknown", E_ICON_SIZE_DIALOG); - if (pixbuf) { + if ((pixbuf = e_icon_factory_get_icon("stock_unknown", E_ICON_SIZE_DIALOG))) { attachment->index = gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, ""); - g_object_unref(pixbuf); + g_object_unref (pixbuf); } continue; } + content_type = camel_mime_part_get_content_type (attachment->body); /* Get the image out of the attachment and create a thumbnail for it */ - pixbuf = attachment->pixbuf_cache; - if (pixbuf) { + if ((pixbuf = attachment->pixbuf_cache)) { g_object_ref(pixbuf); } else if (camel_content_type_is(content_type, "image", "*")) { CamelDataWrapper *wrapper; @@ -370,13 +337,10 @@ update (EAttachmentBar *bar) } } - attachment->pixbuf_cache = gdk_pixbuf_scale_simple - (pixbuf, - width, - height, - GDK_INTERP_BILINEAR); + attachment->pixbuf_cache = gdk_pixbuf_scale_simple (pixbuf, width, height, + GDK_INTERP_BILINEAR); pixbuf = attachment->pixbuf_cache; - g_object_ref(pixbuf); + g_object_ref (pixbuf); } else { pixbuf = NULL; g_warning ("GdkPixbufLoader Error"); @@ -398,8 +362,7 @@ update (EAttachmentBar *bar) if (!desc) desc = _("attachment"); - if (attachment->size - && (size_string = size_to_string (attachment->size))) { + if (attachment->size && (size_string = size_to_string (attachment->size))) { label = g_strdup_printf ("%s (%s)", desc, size_string); g_free (size_string); } else @@ -417,65 +380,65 @@ update (EAttachmentBar *bar) } g_free (mime_type); } - + if (pixbuf) { - GdkPixbuf* pixbuf_orig = pixbuf; + GdkPixbuf *pixbuf_orig = pixbuf; pixbuf = gdk_pixbuf_add_alpha (pixbuf_orig, TRUE, 255, 255, 255); - + /* gdk_pixbuf_add_alpha returns a newly allocated pixbuf, free the original one. */ g_object_unref (pixbuf_orig); - + /* In case of a attachment bar, in a signed/encrypted part, display the status as a emblem*/ if (attachment->sign) { /* Show the signature status at the right-bottom.*/ GdkPixbuf *sign = NULL; - int x,y; - + int x, y; + if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_BAD) - sign = e_icon_factory_get_icon("stock_signature-bad", E_ICON_SIZE_MENU); + sign = e_icon_factory_get_icon ("stock_signature-bad", E_ICON_SIZE_MENU); else if (attachment->sign == CAMEL_CIPHER_VALIDITY_SIGN_GOOD) - sign = e_icon_factory_get_icon("stock_signature-ok", E_ICON_SIZE_MENU); + sign = e_icon_factory_get_icon ("stock_signature-ok", E_ICON_SIZE_MENU); else - sign = e_icon_factory_get_icon("stock_signature", E_ICON_SIZE_MENU); - - x = gdk_pixbuf_get_width(pixbuf) - 17; - y = gdk_pixbuf_get_height(pixbuf) - 17; + sign = e_icon_factory_get_icon "stock_signature", E_ICON_SIZE_MENU); - gdk_pixbuf_copy_area(sign, 0, 0, 16, 16, pixbuf, x, y); + x = gdk_pixbuf_get_width (pixbuf) - 17; + y = gdk_pixbuf_get_height (pixbuf) - 17; + + gdk_pixbuf_copy_area (sign, 0, 0, 16, 16, pixbuf, x, y); g_object_unref (sign); } - + if (attachment->encrypt) { /* Show the encryption status at the top left.*/ - GdkPixbuf *encrypt = e_icon_factory_get_icon("stock_lock-ok", E_ICON_SIZE_MENU); + GdkPixbuf *encrypt = e_icon_factory_get_icon ("stock_lock-ok", E_ICON_SIZE_MENU); - gdk_pixbuf_copy_area(encrypt, 0, 0, 16, 16, pixbuf, 1, 1); + gdk_pixbuf_copy_area (encrypt, 0, 0, 16, 16, pixbuf, 1, 1); g_object_unref (encrypt); } - + gnome_icon_list_append_pixbuf (icon_list, pixbuf, NULL, label); - g_object_unref(pixbuf); + g_object_unref (pixbuf); } g_free (label); } gnome_icon_list_thaw (icon_list); - + /* Resize */ if (bar->expand) { - gtk_widget_get_size_request ((GtkWidget *)bar, &bar_width, &bar_height); - - if (bar->priv->num_attachments) { + gtk_widget_get_size_request ((GtkWidget *) bar, &bar_width, &bar_height); + + if (bar->priv->attachments->len) { int per_col, rows, height, width; - + calculate_height_width(bar, &width, &height); per_col = bar_width / width; per_col = (per_col ? per_col : 1); - rows = (bar->priv->num_attachments + per_col -1 )/ per_col; - gtk_widget_set_size_request ((GtkWidget *)bar, bar_width, rows * height); + rows = (bar->priv->attachments->len + per_col -1) / per_col; + gtk_widget_set_size_request ((GtkWidget *) bar, bar_width, rows * height); } } } @@ -512,47 +475,35 @@ update_remote_file (EAttachment *attachment, EAttachmentBar *bar) void e_attachment_bar_remove_selected (EAttachmentBar *bar) { - GnomeIconList *icon_list; + struct _EAttachmentBarPrivate *priv; EAttachment *attachment; - GList *attachment_list, *p; - int num = 0, left, dlen; - - g_return_if_fail (bar != NULL); + int id, left, nrem = 0; + GList *items; + g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - icon_list = GNOME_ICON_LIST (bar); + priv = bar->priv; - /* Weee! I am especially proud of this piece of cheesy code: it is - truly awful. But unless one attaches a huge number of files, it - will not be as greedy as intended. FIXME of course. */ + if (!(items = gnome_icon_list_get_selection ((GnomeIconList *) bar))) + return; - attachment_list = NULL; - p = gnome_icon_list_get_selection (icon_list); - dlen = g_list_length (p); - for ( ; p != NULL; p = p->next) { - num = GPOINTER_TO_INT (p->data); - attachment = E_ATTACHMENT (g_list_nth_data (bar->priv->attachments, num)); - - /* We need to check if there are duplicated index in the return list of - gnome_icon_list_get_selection() because of gnome bugzilla bug #122356. - FIXME in the future. */ - - if (g_list_find (attachment_list, attachment) == NULL) { - attachment_list = g_list_prepend (attachment_list, attachment); + while (items != NULL) { + if ((id = GPOINTER_TO_INT (items->data) - nrem) < priv->attachments->len) { + /* Note: this removes the item from the array due to the weak_ref callback */ + attachment = priv->attachments->pdata[id]; + g_object_unref (attachment); + nrem++; } + + items = items->next; } - for (p = attachment_list; p != NULL; p = p->next) - remove_attachment (bar, E_ATTACHMENT (p->data)); - - g_list_free (attachment_list); - update (bar); - left = gnome_icon_list_get_num_icons (icon_list); - num = num - dlen + 1; - if (left > 0) - gnome_icon_list_focus_icon (icon_list, left > num ? num : left - 1); + id++; + + if ((left = gnome_icon_list_get_num_icons ((GnomeIconList *) bar)) > 0) + gnome_icon_list_focus_icon ((GnomeIconList *) bar, left > id ? id : left - 1); } void @@ -563,120 +514,136 @@ e_attachment_bar_set_width(EAttachmentBar *bar, int bar_width) calculate_height_width(bar, &width, &height); per_col = bar_width / width; per_col = (per_col ? per_col : 1); - rows = (bar->priv->num_attachments + per_col - 1) / per_col; + rows = (bar->priv->attachments->len + per_col - 1) / per_col; gtk_widget_set_size_request ((GtkWidget *)bar, bar_width, rows * height); } void e_attachment_bar_edit_selected (EAttachmentBar *bar) { - GnomeIconList *icon_list; - GList *selection, *attach; - int num; - - g_return_if_fail (bar != NULL); + struct _EAttachmentBarPrivate *priv; + EAttachment *attachment; + GList *items; + int id; + g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - icon_list = GNOME_ICON_LIST (bar); + priv = bar->priv; - selection = gnome_icon_list_get_selection (icon_list); - if (selection) { - num = GPOINTER_TO_INT (selection->data); - attach = g_list_nth (bar->priv->attachments, num); - if (attach) - e_attachment_edit ((EAttachment *)attach->data, GTK_WIDGET (bar)); + items = gnome_icon_list_get_selection ((GnomeIconList *) bar); + while (items != NULL) { + if ((id = GPOINTER_TO_INT (items->data)) < priv->attachments->len) { + attachment = priv->attachments->pdata[id]; + e_attachment_edit (attachment, GTK_WIDGET (bar)); + } + + items = items->next; } } GtkWidget ** e_attachment_bar_get_selector(EAttachmentBar *bar) { - g_return_val_if_fail (bar != NULL, 0); - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); return &bar->priv->attach; } + +/** + * e_attachment_bar_get_selected: + * @bar: an #EAttachmentBar object + * + * Returns a newly allocated #GSList of ref'd #EAttachment objects + * representing the selected items in the #EAttachmentBar Icon List. + **/ GSList * e_attachment_bar_get_selected (EAttachmentBar *bar) { + struct _EAttachmentBarPrivate *priv; GSList *attachments = NULL; - GList *p; - - g_return_val_if_fail (bar != NULL, 0); - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - p = gnome_icon_list_get_selection((GnomeIconList *)bar); - for ( ; p != NULL; p = p->next) { - int num = GPOINTER_TO_INT(p->data); - EAttachment *attachment = g_list_nth_data(bar->priv->attachments, num); - - if (attachment && g_slist_find(attachments, attachment) == NULL) { - g_object_ref(attachment); - attachments = g_slist_prepend(attachments, attachment); + EAttachment *attachment; + GList *items; + int id; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); + + priv = bar->priv; + + items = gnome_icon_list_get_selection ((GnomeIconList *) bar); + + while (items != NULL) { + if ((id = GPOINTER_TO_INT (items->data)) < priv->attachments->len) { + attachment = priv->attachments->pdata[id]; + attachments = g_slist_prepend (attachments, attachment); + g_object_ref (attachment); } + + items = items->next; } - attachments = g_slist_reverse(attachments); + + attachments = g_slist_reverse (attachments); return attachments; } /* FIXME: Cleanup this, since there is a api to get selected attachments */ -/* if id != -1, then use it as an index for target of the popup */ +/** + * e_attachment_bar_get_attachment: + * @bar: an #EAttachmentBar object + * @id: Index of the desired attachment or -1 to request all selected attachments + * + * Returns a newly allocated #GSList of ref'd #EAttachment objects + * representing the requested item(s) in the #EAttachmentBar Icon + * List. + **/ GSList * e_attachment_bar_get_attachment (EAttachmentBar *bar, int id) { - GSList *attachments = NULL; - GList *p; + struct _EAttachmentBarPrivate *priv; EAttachment *attachment; - - g_return_val_if_fail (bar != NULL, 0); - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - /* We need to check if there are duplicated index in the return list of - gnome_icon_list_get_selection() because of gnome bugzilla bug #122356. - FIXME in the future. */ - - if (id == -1 - || (attachment = g_list_nth_data(bar->priv->attachments, id)) == NULL) { - p = gnome_icon_list_get_selection((GnomeIconList *)bar); - for ( ; p != NULL; p = p->next) { - int num = GPOINTER_TO_INT(p->data); - EAttachment *attachment = g_list_nth_data(bar->priv->attachments, num); - - if (attachment && g_slist_find(attachments, attachment) == NULL) { - g_object_ref(attachment); - attachments = g_slist_prepend(attachments, attachment); - } - } - attachments = g_slist_reverse(attachments); - } else { - g_object_ref(attachment); - attachments = g_slist_prepend(attachments, attachment); - } + GSList *attachments; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); + + priv = bar->priv; + + if (id == -1 || id > priv->attachments->len) + return e_attachment_bar_get_selected (bar); + + attachment = priv->attachments->pdata[id]; + attachments = g_slist_prepend (NULL, attachment); + g_object_ref (attachment); return attachments; } + +/** + * e_attachment_bar_get_all_attachments: + * @bar: an #EAttachmentBar object + * + * Returns a newly allocated #GSList of ref'd #EAttachment objects. + **/ GSList * e_attachment_bar_get_all_attachments (EAttachmentBar *bar) { + struct _EAttachmentBarPrivate *priv; GSList *attachments = NULL; - GList *p; EAttachment *attachment; - - g_return_val_if_fail (bar != NULL, 0); - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - for ( p = bar->priv->attachments; p!= NULL; p = p->next) { - attachment = p->data; - if (attachment && attachment->is_available_local) { + int i; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); + + priv = bar->priv; + + for (i = priv->attachments->len - 1; i >= 0; i--) { + attachment = priv->attachments->pdata[i]; + if (attachment->is_available_local) { + attachments = g_slist_prepend (attachments, attachment); g_object_ref (attachment); - attachments= g_slist_prepend(attachments, attachment); } - } - - attachments = g_slist_reverse(attachments); + } return attachments; } @@ -685,20 +652,22 @@ e_attachment_bar_get_all_attachments (EAttachmentBar *bar) GSList * e_attachment_bar_get_parts (EAttachmentBar *bar) { - EAttachment *attachment; - GList *p = NULL; - GSList *part_list = NULL; - - g_return_val_if_fail (bar != NULL, 0); - g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - - for ( p = bar->priv->attachments; p!= NULL; p = p->next) { - attachment = p->data; - if (attachment && attachment->is_available_local) - part_list = g_slist_prepend(part_list, attachment->body); - } + struct _EAttachmentBarPrivate *priv; + EAttachment *attachment; + GSList *parts = NULL; + int i; + + g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), NULL); + + priv = bar->priv; + + for (i = 0; i < priv->attachments->len; i++) { + attachment = priv->attachments->pdata[i]; + if (attachment->is_available_local) + parts = g_slist_prepend (parts, attachment->body); + } - return part_list; + return parts; } /* GtkObject methods. */ @@ -706,20 +675,26 @@ e_attachment_bar_get_parts (EAttachmentBar *bar) static void destroy (GtkObject *object) { - EAttachmentBar *bar; - - bar = E_ATTACHMENT_BAR (object); + EAttachmentBar *bar = (EAttachmentBar *) object; + struct _EAttachmentBarPrivate *priv = bar->priv; + EAttachment *attachment; + int i; - if (bar->priv) { - free_attachment_list (bar); - - if (bar->priv->attach) - gtk_widget_destroy(bar->priv->attach); - - if (bar->priv->path) - g_free (bar->priv->path); - - g_free (bar->priv); + if ((priv = bar->priv)) { + priv->batch_unref = TRUE; + for (i = 0; i < priv->attachments->len; i++) { + attachment = priv->attachments->pdata[i]; + g_object_unref (attachment); + } + g_ptr_array_free (priv->attachments, TRUE); + + if (priv->attach) + gtk_widget_destroy (priv->attach); + + if (priv->path) + g_free (priv->path); + + g_free (priv); bar->priv = NULL; } @@ -728,20 +703,17 @@ destroy (GtkObject *object) } static char * -temp_save_part(CamelMimePart *part) +temp_save_part (CamelMimePart *part) { const char *filename; char *tmpdir, *path, *mfilename = NULL, *utf8_mfilename = NULL; CamelStream *stream; CamelDataWrapper *wrapper; - - tmpdir = e_mkdtemp("evolution-tmp-XXXXXX"); - if (tmpdir == NULL) { + + if (!(tmpdir = e_mkdtemp ("evolution-tmp-XXXXXX"))) return NULL; - } - - filename = camel_mime_part_get_filename (part); - if (filename == NULL) { + + if (!(filename = camel_mime_part_get_filename (part))) { /* This is the default filename used for temporary file creation */ filename = _("Unknown"); } else { @@ -751,14 +723,14 @@ temp_save_part(CamelMimePart *part) g_free (utf8_mfilename); filename = (const char *) mfilename; } - - path = g_build_filename(tmpdir, filename, NULL); - g_free(tmpdir); - g_free(mfilename); - + + path = g_build_filename (tmpdir, filename, NULL); + g_free (tmpdir); + g_free (mfilename); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); stream = camel_stream_fs_new_with_name (path, O_RDWR|O_CREAT|O_TRUNC, 0600); - + if (!stream) { /* TODO handle error conditions */ g_message ("DEBUG: could not open the file to write\n"); @@ -783,51 +755,54 @@ temp_save_part(CamelMimePart *part) static void eab_drag_data_get(EAttachmentBar *bar, GdkDragContext *drag, GtkSelectionData *data, guint info, guint time) { - char *path; - GList *tmp; - gchar **uris; - int length, i=0; - + struct _EAttachmentBarPrivate *priv = bar->priv; + EAttachment *attachment; + char *path, **uris; + int len, n, i = 0; + CamelURL *url; + GList *items; + if (info) return; - tmp = gnome_icon_list_get_selection (GNOME_ICON_LIST(bar)); - length = g_list_length (tmp); - - uris = g_malloc0(sizeof(bar) * (length+1)); - - for (; tmp; tmp = tmp->next) { - int num = GPOINTER_TO_INT(tmp->data); - EAttachment *attachment = g_list_nth_data(bar->priv->attachments, num); - CamelURL *curl; - + items = gnome_icon_list_get_selection (GNOME_ICON_LIST (bar)); + len = g_list_length (items); + + uris = g_malloc0 (sizeof (char *) * (len + 1)); + + for ( ; items != NULL; items = items->next) { + if (!((n = GPOINTER_TO_INT (items->data)) < priv->attachments->len)) + continue; + + attachment = priv->attachments->pdata[n]; + if (!attachment->is_available_local) continue; - + if (attachment->store_uri) { - uris[i] = attachment->store_uri; - i++; + uris[i++] = attachment->store_uri; continue; } - path = temp_save_part(attachment->body); - /* If we are not able to save, ignore it*/ - if (path == NULL) + + /* If we are not able to save, ignore it */ + if (!(path = temp_save_part (attachment->body))) continue; - curl = camel_url_new("file:", NULL); - camel_url_set_path (curl, path); - attachment->store_uri = camel_url_to_string (curl, 0); - camel_url_free(curl); - g_free(path); + url = camel_url_new ("file:", NULL); + camel_url_set_path (url, path); + attachment->store_uri = camel_url_to_string (url, 0); + camel_url_free (url); + g_free (path); - uris[i] = attachment->store_uri; - i++; + uris[i++] = attachment->store_uri; } - uris[i]=0; - gtk_selection_data_set_uris(data, uris); + + uris[i] = NULL; + + gtk_selection_data_set_uris (data, uris); g_free (uris); - + return; } @@ -865,17 +840,17 @@ eab_button_press_event(EAttachmentBar *bar, GdkEventButton *event, gpointer dumm }; selected = gnome_icon_list_get_selection(icon_list); - length = g_list_length(selected); + length = g_list_length (selected); if (event) { icon_number = gnome_icon_list_get_icon_at(icon_list, event->x, event->y); if (icon_number < 0) { - /* When nothing is selected deselect all*/ - gnome_icon_list_unselect_all(icon_list); + /* When nothing is selected, deselect all */ + gnome_icon_list_unselect_all (icon_list); length = 0; selected = NULL; } - + if (event->button == 1) { /* If something is selected, then allow drag or else help to select */ if (length) @@ -884,11 +859,11 @@ eab_button_press_event(EAttachmentBar *bar, GdkEventButton *event, gpointer dumm gtk_drag_source_unset((GtkWidget *)bar); return FALSE; } - + /* If not r-click dont progress any more.*/ if (event->button != 3) - return FALSE; - + return FALSE; + /* When a r-click on something, if it is in the already selected list, consider a r-click of multiple things * or deselect all and select only this for r-click */ @@ -897,42 +872,42 @@ eab_button_press_event(EAttachmentBar *bar, GdkEventButton *event, gpointer dumm if (GPOINTER_TO_INT(tmp->data) == icon_number) take_selected = TRUE; } - + if (!take_selected) { gnome_icon_list_unselect_all(icon_list); gnome_icon_list_select_icon(icon_list, icon_number); } } - } + } + return FALSE; } static gboolean eab_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, gpointer *dummy) { - GSList *p = NULL; + EAttachment *attachment; GError *error = NULL; gboolean ret = FALSE; - + CamelURL *url; + char *path; + GSList *p; + if (E_IS_ATTACHMENT_BAR (bar) && event->type == GDK_2BUTTON_PRESS) { p = e_attachment_bar_get_selected (bar); - if (p && g_slist_length(p) == 1) { - EAttachment *attachment; - char *path = NULL; - - attachment = (EAttachment *)p->data; - + if (p && p->next == NULL) { + attachment = p->data; + /* Check if the file is stored already */ if (!attachment->store_uri) { - CamelURL *curl; - - path = temp_save_part (attachment->body); - curl = camel_url_new ("file://", NULL); - camel_url_set_path ( curl, path); - attachment->store_uri = camel_url_to_string (curl, 0); - camel_url_free (curl); + path = temp_save_part (attachment->body); + url = camel_url_new ("file:", NULL); + camel_url_set_path (url, path); + attachment->store_uri = camel_url_to_string (url, 0); + camel_url_free (url); + g_free (path); } - + /* launch the url now */ gnome_url_show (attachment->store_uri, &error); if (error) { @@ -940,13 +915,12 @@ eab_icon_clicked_cb (EAttachmentBar *bar, GdkEvent *event, gpointer *dummy) g_error_free (error); error = NULL; } - - g_free (path); + ret = TRUE; } - + if (p) { - g_slist_foreach (p, (GFunc)g_object_unref, NULL); + g_slist_foreach (p, (GFunc) g_object_unref, NULL); g_slist_free (p); } } @@ -982,13 +956,13 @@ class_init (EAttachmentBarClass *klass) static void init (EAttachmentBar *bar) { - EAttachmentBarPrivate *priv; + struct _EAttachmentBarPrivate *priv; - priv = g_new (EAttachmentBarPrivate, 1); + priv = g_new (struct _EAttachmentBarPrivate, 1); priv->attach = NULL; - priv->attachments = NULL; - priv->num_attachments = 0; + priv->batch_unref = FALSE; + priv->attachments = g_ptr_array_new (); priv->path = NULL; bar->priv = priv; @@ -1045,8 +1019,8 @@ e_attachment_bar_new (GtkAdjustment *adj) gnome_icon_list_set_selection_mode (icon_list, GTK_SELECTION_MULTIPLE); atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (new)), - _("Attachment Bar")); - + _("Attachment Bar")); + g_signal_connect (new, "button_release_event", G_CALLBACK(eab_button_release_event), NULL); g_signal_connect (new, "button_press_event", G_CALLBACK(eab_button_press_event), NULL); g_signal_connect (new, "drag-data-get", G_CALLBACK(eab_drag_data_get), NULL); @@ -1149,54 +1123,46 @@ attach_to_multipart (CamelMultipart *multipart, } void -e_attachment_bar_to_multipart (EAttachmentBar *bar, - CamelMultipart *multipart, - const char *default_charset) +e_attachment_bar_to_multipart (EAttachmentBar *bar, CamelMultipart *multipart, const char *default_charset) { - EAttachmentBarPrivate *priv; - GList *p; + struct _EAttachmentBarPrivate *priv; + EAttachment *attachment; + int i; g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); g_return_if_fail (CAMEL_IS_MULTIPART (multipart)); priv = bar->priv; - for (p = priv->attachments; p != NULL; p = p->next) { - EAttachment *attachment; - - attachment = E_ATTACHMENT (p->data); + for (i = 0; i < priv->attachments->len; i++) { + attachment = priv->attachments->pdata[i]; if (attachment->is_available_local) attach_to_multipart (multipart, attachment, default_charset); } } - + guint e_attachment_bar_get_num_attachments (EAttachmentBar *bar) { - g_return_val_if_fail (bar != NULL, 0); g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); - return bar->priv->num_attachments; + return bar->priv->attachments->len; } - + void -e_attachment_bar_attach (EAttachmentBar *bar, - const gchar *file_name, - char *disposition) +e_attachment_bar_attach (EAttachmentBar *bar, const char *file_name, const char *disposition) { g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - g_return_if_fail ( file_name != NULL && disposition != NULL); + g_return_if_fail (file_name != NULL && disposition != NULL); add_from_file (bar, file_name, disposition); } void -e_attachment_bar_add_attachment (EAttachmentBar *bar, - EAttachment *attachment) +e_attachment_bar_add_attachment (EAttachmentBar *bar, EAttachment *attachment) { - g_return_if_fail (bar != NULL); g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); add_common (bar, attachment); @@ -1205,56 +1171,48 @@ e_attachment_bar_add_attachment (EAttachmentBar *bar, int e_attachment_bar_get_download_count (EAttachmentBar *bar) { - EAttachmentBarPrivate *priv; - GList *p; - int count=0; + struct _EAttachmentBarPrivate *priv; + EAttachment *attachment; + int i, n = 0; - g_return_val_if_fail (bar != NULL, 0); g_return_val_if_fail (E_IS_ATTACHMENT_BAR (bar), 0); priv = bar->priv; - for (p = priv->attachments; p != NULL; p = p->next) { - EAttachment *attachment; - - attachment = p->data; + for (i = 0; i < priv->attachments->len; i++) { + attachment = priv->attachments->pdata[i]; if (!attachment->is_available_local) - count++; + n++; } - - return count; + + return n; } -void -e_attachment_bar_attach_remote_file (EAttachmentBar *bar, - const gchar *url, const char *disposition) +void +e_attachment_bar_attach_remote_file (EAttachmentBar *bar, const char *url, const char *disposition) { EAttachment *attachment; CamelException ex; - - g_return_if_fail ( bar!=NULL ); + g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); - + if (!bar->priv->path) - bar->priv->path = e_mkdtemp("attach-XXXXXX"); - + bar->priv->path = e_mkdtemp ("attach-XXXXXX"); + camel_exception_init (&ex); - attachment = e_attachment_new_remote_file (url, disposition, bar->priv->path, &ex); - g_signal_connect (attachment, "update", G_CALLBACK(update_remote_file), bar); - if (attachment) { + if ((attachment = e_attachment_new_remote_file (url, disposition, bar->priv->path, &ex))) { add_common (bar, attachment); + g_signal_connect (attachment, "update", G_CALLBACK (update_remote_file), bar); } else { - e_error_run((GtkWindow *)gtk_widget_get_toplevel((GtkWidget *)bar), "mail-composer:no-attach", - attachment->file_name, camel_exception_get_description(&ex), NULL); + e_error_run ((GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) bar), "mail-composer:no-attach", + attachment->file_name, camel_exception_get_description (&ex), NULL); camel_exception_clear (&ex); } } void -e_attachment_bar_attach_mime_part (EAttachmentBar *bar, - CamelMimePart *part) +e_attachment_bar_attach_mime_part (EAttachmentBar *bar, CamelMimePart *part) { - g_return_if_fail ( bar!=NULL ); g_return_if_fail (E_IS_ATTACHMENT_BAR (bar)); add_from_mime_part (bar, part); -- cgit v1.2.3