Re: [evolution-patches] Re: [Evolution-hackers] Possibility to save all attachments
- From: Harry Lu <harry lu sun com>
- To: Jeffrey Stedfast <fejj ximian com>
- Cc: evolution-patches <evolution-patches ximian com>
- Subject: Re: [evolution-patches] Re: [Evolution-hackers] Possibility to save all attachments
- Date: Mon, 28 Jul 2003 12:07:51 +0800
Jeff,
Thanks for the reviewing.
I modified my patch according to most of your suggestions. For the
FIXME part, since I copied that part code from launch_cb(), I don't
know how to fix it:( Do you have some suggestions?
For the gtk_file_selection_set_filename () part, there is no
examples in existing evolution code using g_filename_from_utf8() and I
don't know whether this is really needed. So I just leave it there.
Maybe we can take care of this kind of problems later together.
Please review it again.
Thanks!
Harry
Index: evolution/mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.2778
diff -u -r1.2778 ChangeLog
--- evolution/mail/ChangeLog 23 Jul 2003 17:37:29 -0000 1.2778
+++ evolution/mail/ChangeLog 28 Jul 2003 03:30:28 -0000
@@ -1,3 +1,18 @@
+2003-07-28 Harry Lu <harry lu sun com>
+
+ *Fix for bug #6951
+
+ * mail-display.c (launch_cb): Bypass the new added menu item.
+ (save_all_parts_cb): New function. Do the real save-all work.
+ (save_all_parts): New function. Get the directory to save to.
+ (save_all_cb): New function. The call-back function for the new
+ added menu item.
+ (pixmap_press): Add the new menu item "Save All Attachment...".
+ (ptr_array_free_notify): A simple wrapper function to free the
+ pointer array.
+ (do_attachment_header): Save attachment pointer in an array for
+ "Save All Attachment" use.
+
2003-07-23 Jeffrey Stedfast <fejj ximian com>
* mail-format.c (mail_format_data_wrapper_write_to_stream): Revert
Index: evolution/mail/mail-display.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-display.c,v
retrieving revision 1.287
diff -u -r1.287 mail-display.c
--- evolution/mail/mail-display.c 23 Jul 2003 15:01:26 -0000 1.287
+++ evolution/mail/mail-display.c 28 Jul 2003 03:30:35 -0000
@@ -375,9 +375,11 @@
/* Yum. Too bad EPopupMenu doesn't allow per-item closures. */
children = gtk_container_get_children (GTK_CONTAINER (widget->parent));
- g_return_if_fail (children != NULL && children->next != NULL && children->next->next != NULL);
-
- for (c = children->next->next, apps = handler->applications; c && apps; c = c->next, apps = apps->next) {
+ /* We need to bypass the first 2 menu items */
+ g_return_if_fail (children != NULL && children->next != NULL
+ && children->next->next != NULL && children->next->next->next != NULL);
+
+ for (c = children->next->next->next, apps = handler->applications; c && apps; c = c->next, apps = apps->next) {
if (c->data == widget)
break;
}
@@ -435,7 +437,106 @@
mail_display_queue_redisplay (md);
}
-static gboolean
+static void
+save_all_parts_cb (GtkWidget *widget, gpointer user_data)
+{
+ GtkFileSelection *dir_select = (GtkFileSelection *)
+ gtk_widget_get_ancestor (widget, GTK_TYPE_FILE_SELECTION);
+ const char *filename;
+ char *save_filename, *dir;
+ struct stat st;
+ int i;
+ GPtrArray *attachment_array;
+ CamelMimePart *part;
+ GConfClient *gconf;
+
+ gtk_widget_hide (GTK_WIDGET (dir_select));
+
+ /* Get the selected directory name */
+ filename = gtk_file_selection_get_filename (dir_select);
+ if (stat (filename, &st) == -1 || !S_ISDIR (st.st_mode)) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ _("%s is not a valid directory name."), filename);
+
+ /* FIXME: this should be async */
+ gtk_dialog_run ((GtkDialog *) dialog);
+ gtk_widget_destroy (dialog);
+ gtk_widget_destroy (GTK_WIDGET (dir_select));
+ return;
+ } else {
+ dir = g_strdup (filename);
+ }
+
+ /* Now save the attachment one by one */
+ attachment_array = (GPtrArray *)user_data;
+ for (i = 0; i < attachment_array->len; i++) {
+ part = g_ptr_array_index (attachment_array, i);
+ save_filename = make_safe_filename (dir, part);
+ write_data_to_file (part, save_filename, FALSE);
+ g_free (save_filename);
+ }
+
+ /* preserve the pathname */
+ gconf = mail_config_get_gconf_client ();
+ gconf_client_set_string (gconf, "/apps/evolution/mail/save_dir", dir, NULL);
+ g_free (dir);
+
+ gtk_widget_destroy (GTK_WIDGET (dir_select));
+}
+
+static void
+save_all_parts (GPtrArray *attachment_array)
+{
+ GtkFileSelection *dir_select;
+ char *dir, *home, *dir2;
+ GConfClient *gconf;
+
+ g_return_if_fail (attachment_array != NULL);
+
+ home = getenv ("HOME");
+ gconf = mail_config_get_gconf_client ();
+ dir = gconf_client_get_string (gconf, "/apps/evolution/mail/save_dir", NULL);
+ dir = dir ? dir : (home ? g_strdup (home) : g_strdup (""));
+
+ /* Make sure dir2 has a '/' as its tail */
+ dir2 = g_strdup_printf ("%s/", dir);
+ g_free (dir);
+
+ dir_select = GTK_FILE_SELECTION (
+ gtk_file_selection_new (_("Select a Directory to Save All Attachment")));
+ gtk_file_selection_set_filename (dir_select, dir2);
+ gtk_widget_set_sensitive (GTK_WIDGET (dir_select->file_list), FALSE);
+ g_free (dir2);
+
+ g_signal_connect (dir_select->ok_button, "clicked",
+ G_CALLBACK (save_all_parts_cb), attachment_array);
+ g_signal_connect_swapped (dir_select->cancel_button,
+ "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ dir_select);
+
+ gtk_widget_show (GTK_WIDGET (dir_select));
+}
+
+static void
+save_all_cb (GtkWidget *widget, gpointer user_data)
+{
+ MailDisplay *md = g_object_get_data (user_data, "MailDisplay");
+ GPtrArray *attachment_array;
+
+ if (md == NULL) {
+ g_warning ("No MailDisplay!");
+ return;
+ }
+
+ attachment_array = g_datalist_get_data (md->data, "attachment_array");
+ save_all_parts (attachment_array);
+}
+
+
+static gboolean
button_press (GtkWidget *widget, GdkEvent *event, CamelMimePart *part)
{
MailDisplay *md;
@@ -475,12 +576,14 @@
EPopupMenu *menu;
GtkMenu *gtk_menu;
EPopupMenu save_item = E_POPUP_ITEM (N_("Save Attachment..."), G_CALLBACK (save_cb), 0);
+ EPopupMenu save_all_item = E_POPUP_ITEM (N_("Save All Attachment..."), G_CALLBACK (save_all_cb), 0);
EPopupMenu view_item = E_POPUP_ITEM (N_("View Inline"), G_CALLBACK (inline_cb), 2);
EPopupMenu open_item = E_POPUP_ITEM (N_("Open in %s..."), G_CALLBACK (launch_cb), 1);
MailDisplay *md;
CamelMimePart *part;
MailMimeHandler *handler;
int mask = 0, i, nitems;
+ int current_item = 0;
if (event->type == GDK_BUTTON_PRESS) {
#ifdef USE_OLD_DISPLAY_STYLE
@@ -508,17 +611,23 @@
handler = mail_lookup_handler (g_object_get_data ((GObject *) widget, "mime_type"));
if (handler && handler->applications)
- nitems = g_list_length (handler->applications) + 2;
+ nitems = g_list_length (handler->applications) + 3;
else
- nitems = 3;
+ nitems = 4;
menu = g_new0 (EPopupMenu, nitems + 1);
/* Save item */
- memcpy (&menu[0], &save_item, sizeof (menu[0]));
- menu[0].name = _(menu[0].name);
-
+ memcpy (&menu[current_item], &save_item, sizeof (menu[current_item]));
+ menu[current_item].name = g_strdup (_(menu[current_item].name));
+ current_item++;
+
+ /* Save All item */
+ memcpy (&menu[current_item], &save_all_item, sizeof (menu[current_item]));
+ menu[current_item].name = g_strdup (_(menu[current_item].name));
+ current_item++;
+
/* Inline view item */
- memcpy (&menu[1], &view_item, sizeof (menu[1]));
+ memcpy (&menu[current_item], &view_item, sizeof (menu[current_item]));
if (handler && handler->builtin) {
md = g_object_get_data ((GObject *) widget, "MailDisplay");
@@ -536,15 +645,16 @@
name = prop->v._u.value_string;
else
name = "bonobo";
- menu[1].name = g_strdup_printf (_("View Inline (via %s)"), name);
+ menu[current_item].name = g_strdup_printf (_("View Inline (via %s)"), name);
} else
- menu[1].name = g_strdup (_(menu[1].name));
+ menu[current_item].name = g_strdup (_(menu[current_item].name));
} else
- menu[1].name = g_strdup (_("Hide"));
+ menu[current_item].name = g_strdup (_("Hide"));
} else {
- menu[1].name = g_strdup (_(menu[1].name));
+ menu[current_item].name = g_strdup (_(menu[current_item].name));
mask |= 2;
}
+ current_item++;
/* External views */
if (handler && handler->applications) {
@@ -553,14 +663,15 @@
int i;
apps = handler->applications;
- for (i = 2; i < nitems; i++, apps = apps->next) {
+ for (i = current_item; i < nitems; i++, apps = apps->next) {
app = apps->data;
memcpy (&menu[i], &open_item, sizeof (menu[i]));
menu[i].name = g_strdup_printf (_(menu[i].name), app->name);
+ current_item++;
}
} else {
- memcpy (&menu[2], &open_item, sizeof (menu[2]));
- menu[2].name = g_strdup_printf (_(menu[2].name), _("External Viewer"));
+ memcpy (&menu[current_item], &open_item, sizeof (menu[current_item]));
+ menu[current_item].name = g_strdup_printf (_(menu[current_item].name), _("External Viewer"));
mask |= 1;
}
@@ -983,6 +1094,12 @@
}
}
+/* This is a wrapper function */
+void ptr_array_free_notify (gpointer array)
+{
+ g_ptr_array_free ((GPtrArray *) array, TRUE);
+}
+
static gboolean
do_attachment_header (GtkHTML *html, GtkHTMLEmbedded *eb,
CamelMimePart *part, MailDisplay *md)
@@ -990,6 +1107,7 @@
GtkWidget *button, *mainbox, *hbox, *arrow, *popup;
MailMimeHandler *handler;
struct _PixbufLoader *pbl;
+ GPtrArray *attachment_array;
pbl = g_new0 (struct _PixbufLoader, 1);
if (strncasecmp (eb->type, "image/", 6) == 0) {
@@ -1059,6 +1177,19 @@
g_object_set_data ((GObject *) popup, "MailDisplay", md);
g_object_set_data ((GObject *) popup, "CamelMimePart", part);
g_object_set_data_full ((GObject *) popup, "mime_type", g_strdup (eb->type), (GDestroyNotify) g_free);
+
+ /* Save attachment pointer in an array for "save all attachment" use */
+ attachment_array = g_datalist_get_data (md->data, "attachment_array");
+ if (!attachment_array) {
+ attachment_array = g_ptr_array_new ();
+ g_datalist_set_data_full (md->data, "attachment_array",
+ attachment_array, (GDestroyNotify) ptr_array_free_notify);
+ }
+ /* Since the attachment pointer might have been added to the array before,
+ remove it first anyway to avoide duplication */
+ g_ptr_array_remove (attachment_array, part);
+ g_ptr_array_add (attachment_array, part);
+
g_signal_connect (popup, "button_press_event", G_CALLBACK (pixmap_press), md->scroll);
g_signal_connect (popup, "key_press_event", G_CALLBACK (pixmap_press), md->scroll);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]