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



when we start working on 1.6

Jeff

On Wed, 2003-06-18 at 23:24, Harry Lu wrote:
> 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);
>  	
-- 
Jeffrey Stedfast
Evolution Hacker - Ximian, Inc.
fejj ximian com  - www.ximian.com




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