Re: [evolution-patches] Patch for bug 6951 (save all attachments)



Ettore, Jeff and NotZed,
    I modified my patch to use mail_config_get_gconf_client () instead of gconf_client_get_default ().
    Since 1.4 has been out, when will my patch be reviewed and checked in?
    Thanks!
       Harry

Harry Lu wrote:
No problem. I will post my patch to bugzilla to keep a record. Later when you have time (hopefully in your 1.6 time frame),  please review it and commit it if possible.
Thanks!
    Harry

Ettore Perazzoli wrote:
On Mon, 2003-05-12 at 23:55, Harry Lu wrote:
  
Jeff, NotZed and others,
    Attached is my patch based on CVS HEAD. Finally I have some time to 
finish it:)
    Please review it when you have time.  Any chances to put it into 
Evolution 1.4?
    Thanks!
       Harry
    

It's too late for any kind of changes like this to go into 1.4, since we
are 100% feature frozen (and we are getting very close to a final 1.4
release).

I haven't looked very closely at the patch, but it looks like possible
1.6 material...

-- Ettore

  
Index: evolution/mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.2752
diff -u -r1.2752 ChangeLog
--- evolution/mail/ChangeLog	18 Jun 2003 18:01:54 -0000	1.2752
+++ evolution/mail/ChangeLog	19 Jun 2003 03:14:11 -0000
@@ -1,3 +1,19 @@
+2003-06-19  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-06-18  Jeffrey Stedfast  <fejj ximian com>
 
 	* message-list.c (hide_save_state): Only save state if we have a
Index: evolution/mail/mail-display.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-display.c,v
retrieving revision 1.282
diff -u -r1.282 mail-display.c
--- evolution/mail/mail-display.c	11 Jun 2003 16:19:34 -0000	1.282
+++ evolution/mail/mail-display.c	19 Jun 2003 03:14:19 -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;
 	}
@@ -436,6 +438,111 @@
 }
 
 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 void
 button_press (GtkWidget *widget, CamelMimePart *part)
 {
 	MailDisplay *md;
@@ -455,12 +562,14 @@
 {
 	EPopupMenu *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;
 	
 #ifdef USE_OLD_DISPLAY_STYLE
 	if (event->button != 3) {
@@ -484,17 +593,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");
 		
@@ -512,15 +627,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) {
@@ -529,14 +645,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;
 	}
 	
@@ -1007,6 +1124,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)
@@ -1014,6 +1137,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) {
@@ -1080,6 +1204,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);
 	


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]