[evolution-patches] Re: [Evolution-hackers] Possibility to save all attachments



Jeff, NotZed and Anna,
    I attatched the patch for HEAD here. Please review it.
    Thanks!
       Harry

Ettore Perazzoli wrote:
On Thu, 2003-07-24 at 02:33, Kósa Ferenc wrote:
  
I use evolution since ver 1.0.2, and I am very satisfied with it. But
would somebody be so kind to implement the function of saving all
attachments in one place?
    

This list is not for feature requests, please use evolution ximian com
for that.

But aside from this, we had a patch from Harry Lu which implemented this
functionality a while ago.  Can we get this reviewed and committed to
HEAD now?

http://lists.ximian.com/archives/public/evolution-patches/2003-June/001760.html
 
(Anna should review the UI change of course.)

-- Ettore
_______________________________________________
evolution-hackers maillist  -  evolution-hackers lists ximian com
http://lists.ximian.com/mailman/listinfo/evolution-hackers


  
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	25 Jul 2003 07:35:07 -0000
@@ -1,3 +1,18 @@
+2003-07-25  Harry Lu  <harry lu sun com>
+
+	*Fix for bug #6951
+
+	* mail-display.c (launch_cb): Bypass the new added menu item.
+	(save_all_data_cb): New function. Do the real save-all work.
+	(save_all_part): 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	25 Jul 2003 07:35:10 -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,112 @@
 	mail_display_queue_redisplay (md);
 }
 
-static gboolean
+static void
+save_all_data_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) {
+		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 if (S_ISDIR (st.st_mode)) {
+		dir = g_strdup (filename);
+	} else {
+		dir = g_path_get_dirname (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_part (GPtrArray *attachment_array)
+{
+	GtkFileSelection *dir_select;
+	char *dir, *home, *p, *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 */
+	p = dir + strlen(dir);
+	if (*p == '/')
+		dir2 = g_strdup (dir);
+	else
+		dir2 = g_strdup_printf ("%s/", 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 (dir);
+	g_free (dir2);
+
+	g_signal_connect (dir_select->ok_button, "clicked", 
+		G_CALLBACK (save_all_data_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_part (attachment_array);
+}
+
+
+static gboolean 
 button_press (GtkWidget *widget, GdkEvent *event, CamelMimePart *part)
 {
 	MailDisplay *md;
@@ -475,12 +582,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 +617,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 +651,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 +669,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 +1100,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 +1113,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 +1183,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, (gpointer)part);
+	g_ptr_array_add (attachment_array, (gpointer)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]