evolution r37470 - in branches/kill-bonobo: calendar/gui/dialogs composer mail widgets/misc



Author: mbarnes
Date: Tue Mar 24 02:05:26 2009
New Revision: 37470
URL: http://svn.gnome.org/viewvc/evolution?rev=37470&view=rev

Log:
Saving progress again on the attachment rewrite.


Added:
   branches/kill-bonobo/mail/e-mail-attachment-bar.c
   branches/kill-bonobo/mail/e-mail-attachment-bar.h
Modified:
   branches/kill-bonobo/calendar/gui/dialogs/comp-editor.c
   branches/kill-bonobo/composer/e-msg-composer.c
   branches/kill-bonobo/mail/Makefile.am
   branches/kill-bonobo/mail/em-format-html-display.c
   branches/kill-bonobo/mail/em-format-html.c
   branches/kill-bonobo/widgets/misc/e-activity.c
   branches/kill-bonobo/widgets/misc/e-attachment-dialog.c
   branches/kill-bonobo/widgets/misc/e-attachment-icon-view.c
   branches/kill-bonobo/widgets/misc/e-attachment-paned.c
   branches/kill-bonobo/widgets/misc/e-attachment-paned.h
   branches/kill-bonobo/widgets/misc/e-attachment-store.c
   branches/kill-bonobo/widgets/misc/e-attachment-store.h
   branches/kill-bonobo/widgets/misc/e-attachment-tree-view.c
   branches/kill-bonobo/widgets/misc/e-attachment-view.c
   branches/kill-bonobo/widgets/misc/e-attachment-view.h
   branches/kill-bonobo/widgets/misc/e-attachment.c
   branches/kill-bonobo/widgets/misc/e-attachment.h

Modified: branches/kill-bonobo/calendar/gui/dialogs/comp-editor.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/dialogs/comp-editor.c	(original)
+++ branches/kill-bonobo/calendar/gui/dialogs/comp-editor.c	Tue Mar 24 02:05:26 2009
@@ -63,6 +63,7 @@
 #include "../e-cal-popup.h"
 #include "../calendar-config-keys.h"
 #include "cal-attachment-select-file.h"
+#include "widgets/misc/e-attachment-view.h"
 #include "widgets/misc/e-attachment-paned.h"
 
 #include "e-util/e-error.h"
@@ -233,11 +234,9 @@
                     guint info,
                     guint time)
 {
-	EAttachmentPaned *paned;
 	EAttachmentView *view;
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 
 	e_attachment_view_drag_data_received (
 		view, context, x, y, selection, info, time);
@@ -250,11 +249,9 @@
              gint y,
              guint time)
 {
-	EAttachmentPaned *paned;
 	EAttachmentView *view;
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 
 	return e_attachment_view_drag_motion (view, context, x, y, time);
 }
@@ -262,7 +259,6 @@
 static GSList *
 get_attachment_list (CompEditor *editor)
 {
-	EAttachmentPaned *paned;
 	EAttachmentStore *store;
 	EAttachmentView *view;
 	GtkTreeModel *model;
@@ -275,8 +271,7 @@
 
 	e_cal_component_get_uid (editor->priv->comp, &comp_uid);
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 	store = e_attachment_view_get_store (view);
 
 	model = GTK_TREE_MODEL (store);
@@ -681,12 +676,10 @@
 action_attach_cb (GtkAction *action,
                   CompEditor *editor)
 {
-	EAttachmentPaned *paned;
 	EAttachmentStore *store;
 	EAttachmentView *view;
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 	store = e_attachment_view_get_store (view);
 
 	e_attachment_store_run_load_dialog (store, GTK_WINDOW (editor));
@@ -815,7 +808,6 @@
                 CompEditor *editor)
 {
 	CompEditorPrivate *priv = editor->priv;
-	EAttachmentPaned *paned;
 	EAttachmentStore *store;
 	EAttachmentView *view;
 	ECalComponentText text;
@@ -823,11 +815,10 @@
 	gboolean read_only, correct = FALSE;
 	ECalComponent *comp;
 
-	paned = E_ATTACHMENT_PANED (priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (priv->attachment_paned);
 	store = e_attachment_view_get_store (view);
 
-	if (e_attachment_store_get_num_downloading (store) > 0) {
+	if (e_attachment_store_get_num_loading (store) > 0) {
 		gboolean response = 1;
 	/*FIXME: Cannot use mail functions from calendar!!!! */
 #if 0
@@ -1504,7 +1495,6 @@
 comp_editor_init (CompEditor *editor)
 {
 	CompEditorPrivate *priv;
-	EAttachmentPaned *paned;
 	EAttachmentView *view;
 	GtkActionGroup *action_group;
 	GtkAction *action;
@@ -1626,8 +1616,7 @@
 
 	/* Add a GtkRecentAction to the "individual" action group. */
 	action_group = comp_editor_get_action_group (editor, "individual");
-	paned = E_ATTACHMENT_PANED (priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (priv->attachment_paned);
 	action = e_attachment_view_recent_action_new (
 		view, "attach-recent", _("Recent _Documents"));
 	gtk_action_group_add_action (action_group, action);
@@ -2251,13 +2240,11 @@
 static void
 set_attachment_list (CompEditor *editor, GSList *attach_list)
 {
-	EAttachmentPaned *paned;
 	EAttachmentStore *store;
 	EAttachmentView *view;
 	GSList *iter = NULL;
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 	store = e_attachment_view_get_store (view);
 
 	if (e_attachment_store_get_num_attachments (store) > 0) {
@@ -2281,14 +2268,12 @@
 static void
 fill_widgets (CompEditor *editor)
 {
-	EAttachmentPaned *paned;
 	EAttachmentStore *store;
 	EAttachmentView *view;
 	CompEditorPrivate *priv;
 	GList *l;
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 	store = e_attachment_view_get_store (view);
 
 	priv = editor->priv;
@@ -2628,7 +2613,6 @@
 GSList *
 comp_editor_get_mime_attach_list (CompEditor *editor)
 {
-	EAttachmentPaned *paned;
 	EAttachmentStore *store;
 	EAttachmentView *view;
 	GtkTreeModel *model;
@@ -2637,8 +2621,7 @@
 	GSList *attach_list = NULL;
 	gboolean valid;
 
-	paned = E_ATTACHMENT_PANED (editor->priv->attachment_paned);
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (editor->priv->attachment_paned);
 	store = e_attachment_view_get_store (view);
 
 	model = GTK_TREE_MODEL (store);

Modified: branches/kill-bonobo/composer/e-msg-composer.c
==============================================================================
--- branches/kill-bonobo/composer/e-msg-composer.c	(original)
+++ branches/kill-bonobo/composer/e-msg-composer.c	Tue Mar 24 02:05:26 2009
@@ -3803,7 +3803,7 @@
 	view = e_msg_composer_get_attachment_view (composer);
 	store = e_attachment_view_get_store (view);
 
-	if (e_attachment_store_get_num_downloading (store) > 0) {
+	if (e_attachment_store_get_num_loading (store) > 0) {
 		if (!em_utils_prompt_user (GTK_WINDOW (composer), NULL,
 			"mail-composer:ask-send-message-pending-download", NULL)) {
 			return NULL;
@@ -4255,13 +4255,9 @@
 EAttachmentView *
 e_msg_composer_get_attachment_view (EMsgComposer *composer)
 {
-	EAttachmentPaned *paned;
-
 	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);
 
-	paned = E_ATTACHMENT_PANED (composer->priv->attachment_paned);
-
-	return e_attachment_paned_get_view (paned);
+	return E_ATTACHMENT_VIEW (composer->priv->attachment_paned);
 }
 
 void

Modified: branches/kill-bonobo/mail/Makefile.am
==============================================================================
--- branches/kill-bonobo/mail/Makefile.am	(original)
+++ branches/kill-bonobo/mail/Makefile.am	Tue Mar 24 02:05:26 2009
@@ -35,6 +35,8 @@
 	libevolution-module-mail.la
 
 libevolution_module_mail_la_SOURCES =			\
+	e-mail-attachment-bar.c				\
+	e-mail-attachment-bar.h				\
 	e-mail-browser.c				\
 	e-mail-browser.h				\
 	e-mail-display.c				\

Added: branches/kill-bonobo/mail/e-mail-attachment-bar.c
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/mail/e-mail-attachment-bar.c	Tue Mar 24 02:05:26 2009
@@ -0,0 +1,656 @@
+/*
+ * e-mail-attachment-bar.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>  
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "e-mail-attachment-bar.h"
+
+#include <glib/gi18n.h>
+#include "e-util/e-binding.h"
+#include "e-attachment-store.h"
+#include "e-attachment-icon-view.h"
+#include "e-attachment-tree-view.h"
+
+#define E_MAIL_ATTACHMENT_BAR_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBarPrivate))
+
+#define NUM_VIEWS 2
+
+struct _EMailAttachmentBarPrivate {
+	GtkTreeModel *model;
+	GtkWidget *vbox;
+	GtkWidget *expander;
+	GtkWidget *combo_box;
+	GtkWidget *icon_view;
+	GtkWidget *tree_view;
+	GtkWidget *icon_frame;
+	GtkWidget *tree_frame;
+	GtkWidget *status_icon;
+	GtkWidget *status_label;
+
+	gint active_view;
+	guint expanded : 1;
+};
+
+enum {
+	PROP_0,
+	PROP_ACTIVE_VIEW,
+	PROP_EDITABLE,
+	PROP_EXPANDED
+};
+
+static gpointer parent_class;
+
+static void
+mail_attachment_bar_sync_icon_view (EMailAttachmentBar *bar)
+{
+	EAttachmentView *source;
+	EAttachmentView *target;
+
+	source = E_ATTACHMENT_VIEW (bar->priv->tree_view);
+	target = E_ATTACHMENT_VIEW (bar->priv->icon_view);
+
+	/* Only sync if the tree view is active.  This prevents the
+	 * two views from endlessly trying to sync with each other. */
+	if (e_mail_attachment_bar_get_active_view (bar) == 1)
+		e_attachment_view_sync_selection (source, target);
+}
+
+static void
+mail_attachment_bar_sync_tree_view (EMailAttachmentBar *bar)
+{
+	EAttachmentView *source;
+	EAttachmentView *target;
+
+	source = E_ATTACHMENT_VIEW (bar->priv->icon_view);
+	target = E_ATTACHMENT_VIEW (bar->priv->tree_view);
+
+	/* Only sync if the icon view is active.  This prevents the
+	 * two views from endlessly trying to sync with each other. */
+	if (e_mail_attachment_bar_get_active_view (bar) == 0)
+		e_attachment_view_sync_selection (source, target);
+}
+
+static void
+mail_attachment_bar_update_status (EMailAttachmentBar *bar)
+{
+	EAttachmentView *view;
+	EAttachmentStore *store;
+	GtkExpander *expander;
+	GtkLabel *label;
+	gint num_attachments;
+	guint64 total_size;
+	gchar *display_size;
+	gchar *markup;
+
+	view = E_ATTACHMENT_VIEW (bar);
+	store = e_attachment_view_get_store (view);
+	expander = GTK_EXPANDER (bar->priv->expander);
+	label = GTK_LABEL (bar->priv->status_label);
+
+	num_attachments = e_attachment_store_get_num_attachments (store);
+	total_size = e_attachment_store_get_total_size (store);
+	display_size = g_format_size_for_display (total_size);
+
+	markup = g_strdup_printf (
+		"<b>%d</b> %s (%s)", num_attachments, ngettext (
+		"Attachment", "Attachments", num_attachments),
+		display_size);
+	gtk_label_set_markup (label, markup);
+	g_free (markup);
+
+	g_free (display_size);
+}
+
+static void
+mail_attachment_bar_set_property (GObject *object,
+                                  guint property_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ACTIVE_VIEW:
+			e_mail_attachment_bar_set_active_view (
+				E_MAIL_ATTACHMENT_BAR (object),
+				g_value_get_int (value));
+			return;
+
+		case PROP_EDITABLE:
+			e_attachment_view_set_editable (
+				E_ATTACHMENT_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_EXPANDED:
+			e_mail_attachment_bar_set_expanded (
+				E_MAIL_ATTACHMENT_BAR (object),
+				g_value_get_boolean (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_attachment_bar_get_property (GObject *object,
+                                  guint property_id,
+                                  GValue *value,
+                                  GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_ACTIVE_VIEW:
+			g_value_set_int (
+				value,
+				e_mail_attachment_bar_get_active_view (
+				E_MAIL_ATTACHMENT_BAR (object)));
+			return;
+
+		case PROP_EDITABLE:
+			g_value_set_boolean (
+				value,
+				e_attachment_view_get_editable (
+				E_ATTACHMENT_VIEW (object)));
+			return;
+
+		case PROP_EXPANDED:
+			g_value_set_boolean (
+				value,
+				e_mail_attachment_bar_get_expanded (
+				E_MAIL_ATTACHMENT_BAR (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+mail_attachment_bar_dispose (GObject *object)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (object);
+
+	if (priv->model != NULL) {
+		g_object_unref (priv->model);
+		priv->model = NULL;
+	}
+
+	if (priv->vbox != NULL) {
+		g_object_unref (priv->vbox);
+		priv->vbox = NULL;
+	}
+
+	if (priv->expander != NULL) {
+		g_object_unref (priv->expander);
+		priv->expander = NULL;
+	}
+
+	if (priv->combo_box != NULL) {
+		g_object_unref (priv->combo_box);
+		priv->combo_box = NULL;
+	}
+
+	if (priv->icon_view != NULL) {
+		g_object_unref (priv->icon_view);
+		priv->icon_view = NULL;
+	}
+
+	if (priv->tree_view != NULL) {
+		g_object_unref (priv->tree_view);
+		priv->tree_view = NULL;
+	}
+
+	if (priv->icon_frame != NULL) {
+		g_object_unref (priv->icon_frame);
+		priv->icon_frame = NULL;
+	}
+
+	if (priv->tree_frame != NULL) {
+		g_object_unref (priv->tree_frame);
+		priv->tree_frame = NULL;
+	}
+
+	if (priv->status_icon != NULL) {
+		g_object_unref (priv->status_icon);
+		priv->status_icon = NULL;
+	}
+
+	if (priv->status_label != NULL) {
+		g_object_unref (priv->status_label);
+		priv->status_label = NULL;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+mail_attachment_bar_constructed (GObject *object)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (object);
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "active-view",
+		G_OBJECT (priv->combo_box), "active");
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "editable",
+		G_OBJECT (priv->icon_view), "editable");
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "editable",
+		G_OBJECT (priv->tree_view), "editable");
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "expanded",
+		G_OBJECT (priv->expander), "expanded");
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "expanded",
+		G_OBJECT (priv->combo_box), "visible");
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "expanded",
+		G_OBJECT (priv->vbox), "visible");
+}
+
+static EAttachmentViewPrivate *
+mail_attachment_bar_get_private (EAttachmentView *view)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_private (view);
+}
+
+static EAttachmentStore *
+mail_attachment_bar_get_store (EAttachmentView *view)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_store (view);
+}
+
+static GtkTreePath *
+mail_attachment_bar_get_path_at_pos (EAttachmentView *view,
+                                     gint x,
+                                     gint y)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_path_at_pos (view, x, y);
+}
+
+static GList *
+mail_attachment_bar_get_selected_paths (EAttachmentView *view)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_selected_paths (view);
+}
+
+static gboolean
+mail_attachment_bar_path_is_selected (EAttachmentView *view,
+                                      GtkTreePath *path)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_path_is_selected (view, path);
+}
+
+static void
+mail_attachment_bar_select_path (EAttachmentView *view,
+                                 GtkTreePath *path)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_select_path (view, path);
+}
+
+static void
+mail_attachment_bar_unselect_path (EAttachmentView *view,
+                                   GtkTreePath *path)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_unselect_path (view, path);
+}
+
+static void
+mail_attachment_bar_select_all (EAttachmentView *view)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_select_all (view);
+}
+
+static void
+mail_attachment_bar_unselect_all (EAttachmentView *view)
+{
+	EMailAttachmentBarPrivate *priv;
+
+	priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_unselect_all (view);
+}
+
+static void
+mail_attachment_bar_class_init (EMailAttachmentBarClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (EMailAttachmentBarPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = mail_attachment_bar_set_property;
+	object_class->get_property = mail_attachment_bar_get_property;
+	object_class->dispose = mail_attachment_bar_dispose;
+	object_class->constructed = mail_attachment_bar_constructed;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_ACTIVE_VIEW,
+		g_param_spec_int (
+			"active-view",
+			"Active View",
+			NULL,
+			0,
+			NUM_VIEWS,
+			0,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_EXPANDED,
+		g_param_spec_boolean (
+			"expanded",
+			"Expanded",
+			NULL,
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_override_property (
+		object_class, PROP_EDITABLE, "editable");
+}
+
+static void
+mail_attachment_bar_iface_init (EAttachmentViewIface *iface)
+{
+	iface->get_private = mail_attachment_bar_get_private;
+	iface->get_store = mail_attachment_bar_get_store;
+	iface->get_path_at_pos = mail_attachment_bar_get_path_at_pos;
+	iface->get_selected_paths = mail_attachment_bar_get_selected_paths;
+	iface->path_is_selected = mail_attachment_bar_path_is_selected;
+	iface->select_path = mail_attachment_bar_select_path;
+	iface->unselect_path = mail_attachment_bar_unselect_path;
+	iface->select_all = mail_attachment_bar_select_all;
+	iface->unselect_all = mail_attachment_bar_unselect_all;
+}
+
+static void
+mail_attachment_bar_init (EMailAttachmentBar *bar)
+{
+	GtkTreeSelection *selection;
+	GtkSizeGroup *size_group;
+	GtkWidget *container;
+	GtkWidget *widget;
+
+	bar->priv = E_MAIL_ATTACHMENT_BAR_GET_PRIVATE (bar);
+	bar->priv->model = e_attachment_store_new ();
+
+	gtk_box_set_spacing (GTK_BOX (bar), 6);
+
+	/* Keep the expander label and save button the same height. */
+	size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
+
+	/* Construct the Controls */
+
+	container = GTK_WIDGET (bar);
+
+	widget = gtk_hbox_new (FALSE, 6);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = gtk_expander_new (NULL);
+	gtk_expander_set_spacing (GTK_EXPANDER (widget), 0);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	bar->priv->expander = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	widget = gtk_alignment_new (1.0, 0.5, 0.0, 0.0);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = gtk_combo_box_new_text ();
+	gtk_size_group_add_widget (size_group, widget);
+	gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Icon View"));
+	gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("List View"));
+	gtk_container_add (GTK_CONTAINER (container), widget);
+	bar->priv->combo_box = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	container = bar->priv->expander;
+
+	widget = gtk_hbox_new (FALSE, 0);
+	gtk_size_group_add_widget (size_group, widget);
+	gtk_expander_set_label_widget (GTK_EXPANDER (container), widget);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = gtk_image_new_from_icon_name (
+		"mail-attachment", GTK_ICON_SIZE_MENU);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	bar->priv->status_icon = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	widget = gtk_label_new (NULL);
+	gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	bar->priv->status_label = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	/* Construct the Attachment Views */
+
+	container = GTK_WIDGET (bar);
+
+	widget = gtk_vbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+	bar->priv->vbox = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	container = bar->priv->vbox;
+
+	widget = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	bar->priv->icon_frame = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = e_attachment_icon_view_new ();
+	GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+	gtk_icon_view_set_model (GTK_ICON_VIEW (widget), bar->priv->model);
+	gtk_container_add (GTK_CONTAINER (container), widget);
+	bar->priv->icon_view = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	container = bar->priv->vbox;
+
+	widget = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (widget), GTK_SHADOW_IN);
+	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+	bar->priv->tree_frame = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	container = widget;
+
+	widget = e_attachment_tree_view_new ();
+	GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
+	gtk_tree_view_set_model (GTK_TREE_VIEW (widget), bar->priv->model);
+	gtk_container_add (GTK_CONTAINER (container), widget);
+	bar->priv->tree_view = g_object_ref (widget);
+	gtk_widget_show (widget);
+
+	selection = gtk_tree_view_get_selection (
+		GTK_TREE_VIEW (bar->priv->tree_view));
+
+	g_signal_connect_swapped (
+		selection, "changed",
+		G_CALLBACK (mail_attachment_bar_sync_icon_view), bar);
+
+	g_signal_connect_swapped (
+		bar->priv->icon_view, "selection-changed",
+		G_CALLBACK (mail_attachment_bar_sync_tree_view), bar);
+
+	g_signal_connect_swapped (
+		bar->priv->model, "notify::num-attachments",
+		G_CALLBACK (mail_attachment_bar_update_status), bar);
+
+	g_signal_connect_swapped (
+		bar->priv->model, "notify::total-size",
+		G_CALLBACK (mail_attachment_bar_update_status), bar);
+
+	g_object_unref (size_group);
+}
+
+GType
+e_mail_attachment_bar_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo type_info = {
+			sizeof (EMailAttachmentBarClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) mail_attachment_bar_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_data */
+			sizeof (EMailAttachmentBar),
+			0,     /* n_preallocs */
+			(GInstanceInitFunc) mail_attachment_bar_init,
+			NULL   /* value_table */
+		};
+
+		static const GInterfaceInfo iface_info = {
+			(GInterfaceInitFunc) mail_attachment_bar_iface_init,
+			(GInterfaceFinalizeFunc) NULL,
+			NULL   /* interface_data */
+		};
+
+		type = g_type_register_static (
+			GTK_TYPE_VBOX, "EMailAttachmentBar", &type_info, 0);
+
+		g_type_add_interface_static (
+			type, E_TYPE_ATTACHMENT_VIEW, &iface_info);
+	}
+
+	return type;
+}
+
+GtkWidget *
+e_mail_attachment_bar_new (void)
+{
+	return g_object_new (
+		E_TYPE_MAIL_ATTACHMENT_BAR,
+		"editable", FALSE, NULL);
+}
+
+gint
+e_mail_attachment_bar_get_active_view (EMailAttachmentBar *bar)
+{
+	g_return_val_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar), 0);
+
+	return bar->priv->active_view;
+}
+
+void
+e_mail_attachment_bar_set_active_view (EMailAttachmentBar *bar,
+                                       gint active_view)
+{
+	g_return_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar));
+	g_return_if_fail (active_view >= 0 && active_view < NUM_VIEWS);
+
+	bar->priv->active_view = active_view;
+
+	if (active_view == 0) {
+		gtk_widget_show (bar->priv->icon_frame);
+		gtk_widget_hide (bar->priv->tree_frame);
+	} else {
+		gtk_widget_hide (bar->priv->icon_frame);
+		gtk_widget_show (bar->priv->tree_frame);
+	}
+
+	g_object_notify (G_OBJECT (bar), "active-view");
+}
+
+gboolean
+e_mail_attachment_bar_get_expanded (EMailAttachmentBar *bar)
+{
+	g_return_val_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar), FALSE);
+
+	return bar->priv->expanded;
+}
+
+void
+e_mail_attachment_bar_set_expanded (EMailAttachmentBar *bar,
+                                    gboolean expanded)
+{
+	g_return_if_fail (E_IS_MAIL_ATTACHMENT_BAR (bar));
+
+	bar->priv->expanded = expanded;
+
+	g_object_notify (G_OBJECT (bar), "expanded");
+}

Added: branches/kill-bonobo/mail/e-mail-attachment-bar.h
==============================================================================
--- (empty file)
+++ branches/kill-bonobo/mail/e-mail-attachment-bar.h	Tue Mar 24 02:05:26 2009
@@ -0,0 +1,77 @@
+/*
+ * e-mail-attachment-bar.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>  
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_MAIL_ATTACHMENT_BAR_H
+#define E_MAIL_ATTACHMENT_BAR_H
+
+#include <gtk/gtk.h>
+#include <widgets/misc/e-attachment-view.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MAIL_ATTACHMENT_BAR \
+	(e_mail_attachment_bar_get_type ())
+#define E_MAIL_ATTACHMENT_BAR(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBar))
+#define E_MAIL_ATTACHMENT_BAR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBarClass))
+#define E_IS_MAIL_ATTACHMENT_BAR(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_MAIL_ATTACHMENT_BAR))
+#define E_IS_MAIL_ATTACHMENT_BAR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_MAIL_ATTACHMENT_BAR))
+#define E_MAIL_ATTACHMENT_BAR_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_MAIL_ATTACHMENT_BAR, EMailAttachmentBarClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMailAttachmentBar EMailAttachmentBar;
+typedef struct _EMailAttachmentBarClass EMailAttachmentBarClass;
+typedef struct _EMailAttachmentBarPrivate EMailAttachmentBarPrivate;
+
+struct _EMailAttachmentBar {
+	GtkVBox parent;
+	EMailAttachmentBarPrivate *priv;
+};
+
+struct _EMailAttachmentBarClass {
+	GtkVBoxClass parent_class;
+};
+
+GType		e_mail_attachment_bar_get_type	(void);
+GtkWidget *	e_mail_attachment_bar_new	(void);
+gint		e_mail_attachment_bar_get_active_view
+						(EMailAttachmentBar *bar);
+void		e_mail_attachment_bar_set_active_view
+						(EMailAttachmentBar *bar,
+						 gint active_view);
+gboolean	e_mail_attachment_bar_get_expanded
+						(EMailAttachmentBar *bar);
+void		e_mail_attachment_bar_set_expanded
+						(EMailAttachmentBar *bar,
+						 gboolean expanded);
+
+G_END_DECLS
+
+#endif /* E_MAIL_ATTACHMENT_BAR_H */

Modified: branches/kill-bonobo/mail/em-format-html-display.c
==============================================================================
--- branches/kill-bonobo/mail/em-format-html-display.c	(original)
+++ branches/kill-bonobo/mail/em-format-html-display.c	Tue Mar 24 02:05:26 2009
@@ -75,12 +75,12 @@
 #include "mail-config.h"
 
 #include "e-mail-display.h"
+#include "e-mail-attachment-bar.h"
 #include "em-format-html-display.h"
 #include "em-icon-stream.h"
 #include "em-utils.h"
 #include "em-popup.h"
 #include "widgets/misc/e-attachment-view.h"
-#include "widgets/misc/e-attachment-icon-view.h"
 
 #ifdef G_OS_WIN32
 /* Undefine the similar macro from <pthread.h>,it doesn't check if
@@ -100,8 +100,7 @@
 
 struct _EMFormatHTMLDisplayPrivate {
 	/* for Attachment bar */
-	GtkWidget *attachment_view;
-	GtkWidget *attachment_box;
+	GtkWidget *attachment_bar;
 	GtkWidget *label;
 	GtkWidget *save_txt;
 	GtkWidget *arrow;
@@ -150,11 +149,9 @@
 static void efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri);
 static gboolean efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
 static void efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
-static void efhd_message_update_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info);
 static void efhd_attachment_button_show (GtkWidget *w, void *data);
 static gboolean efhd_attachment_button (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject);
 static gboolean efhd_attachment_optional (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *object);
-static void efhd_attachment_bar_refresh (EMFormatHTMLDisplay *efhd);
 
 struct _attach_puri {
 	EMFormatPURI puri;
@@ -194,7 +191,6 @@
 static void efhd_message_prefix(EMFormat *emf, CamelStream *stream, CamelMimePart *part, EMFormatHandler *info);
 
 static void efhd_complete(EMFormat *);
-gboolean efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd);
 
 static void efhd_builtin_init(EMFormatHTMLDisplayClass *efhc);
 
@@ -481,6 +477,9 @@
                         const gchar *mime_type,
                         const EMFormatHandler *handle)
 {
+	EMFormatHTMLDisplay *efhd;
+	EAttachmentView *view;
+	EAttachmentStore *store;
 	char *classid, *text, *html;
 	struct _attach_puri *info;
 
@@ -840,8 +839,6 @@
 
 	{ "x-evolution/message/prefix", (EMFormatFunc)efhd_message_prefix },
 	{ "x-evolution/message/post-header", (EMFormatFunc)efhd_message_add_bar },
-	{ "x-evolution/message/post-header-closure", (EMFormatFunc)efhd_message_update_bar },
-
 };
 
 static void
@@ -1297,7 +1294,6 @@
 static gboolean
 efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
 {
-#if 0  /* KILL-BONOBO  !! FIXME !! */
 	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)efh;
 	EAttachment *new;
 	struct _attach_puri *info;
@@ -1320,10 +1316,15 @@
 		return TRUE;
 	}
 
-	if (efhd->priv->attachment_view) {
+	if (efhd->priv->attachment_bar) {
 		EAttachmentView *view;
 		EAttachmentStore *store;
 
+		view = E_ATTACHMENT_VIEW (efhd->priv->attachment_bar);
+		store = e_attachment_view_get_store (view);
+		e_attachment_store_add_attachment (store, info->attachment);
+
+#if 0  /* KILL-BONOBO */
 		file = camel_mime_part_get_filename(info->puri.part);
 
 		new = info->attachment;
@@ -1353,16 +1354,10 @@
 		} else {
 			g_hash_table_insert (efhd->priv->files, g_strdup(file), GUINT_TO_POINTER(1));
 		}
+#endif
 
-		/* Store the status of encryption / signature on the attachment for emblem display
-		 * FIXME: May not work well always
-		 */
-		new->sign = info->sign;
-		new->encrypt = info->encrypt;
-
-		/* Add the attachment to the bar.*/
-		e_attachment_bar_add_attachment_silent (E_ATTACHMENT_BAR(efhd->priv->attachment_bar), new);
-		efhd_attachment_bar_refresh(efhd);
+		e_attachment_set_encrypted (info->attachment, info->encrypt);
+		e_attachment_set_signed (info->attachment, info->sign);
 	}
 
 	mainbox = gtk_hbox_new(FALSE, 0);
@@ -1456,7 +1451,6 @@
 		gtk_widget_hide(info->down);
 
 	gtk_container_add((GtkContainer *)eb, mainbox);
-#endif
 
 	return TRUE;
 }
@@ -1481,23 +1475,6 @@
 }
 
 static void
-attachment_bar_arrow_clicked(GtkWidget *w, EMFormatHTMLDisplay *efhd)
-{
-
-	efhd->priv->show_bar = !efhd->priv->show_bar;
-
-	if (efhd->priv->show_bar) {
-		gtk_widget_show(efhd->priv->attachment_box);
-		gtk_widget_show(efhd->priv->down);
-		gtk_widget_hide(efhd->priv->forward);
-	} else {
-		gtk_widget_hide(efhd->priv->attachment_box);
-		gtk_widget_show(efhd->priv->forward);
-		gtk_widget_hide(efhd->priv->down);
-	}
-}
-
-static void
 attachments_save_all_clicked (GtkWidget *widget, EMFormatHTMLDisplay *efhd)
 {
 #if 0  /* KILL-BONOBO */
@@ -1565,184 +1542,44 @@
 #endif
 
 static void
-efhd_attachment_bar_refresh (EMFormatHTMLDisplay *efhd)
+efhd_bar_resize (EMFormatHTML *efh,
+                 GtkAllocation *event)
 {
-	EAttachmentStore *store;
-	EAttachmentView *view;
-	guint nattachments;
-
-	if (!efhd->priv->attachment_view)
-		return;
-
-	view = E_ATTACHMENT_VIEW (efhd->priv->attachment_view);
-	store = e_attachment_view_get_store (view);
+	EMFormatHTMLDisplay *efhd;
+	GtkWidget *widget;
+	gint width;
 
-	nattachments = e_attachment_store_get_num_attachments (store);
+	efhd = EM_FORMAT_HTML_DISPLAY (efh);
 
-	if (nattachments > 0) {
-		char *txt;
+	widget = GTK_WIDGET (efh->html);
+	width = widget->allocation.width - 12;
 
-		/* Cant i put in the number of attachments here ?*/
-		txt = g_strdup_printf(ngettext("%d at_tachment", "%d at_tachments", nattachments), nattachments);
-		gtk_label_set_text_with_mnemonic ((GtkLabel *)efhd->priv->label, txt);
-		g_free (txt);
-
-		/* Show the bar even when the first attachment is added */
-		if (nattachments == 1) {
-			gtk_widget_show_all (efhd->priv->attachment_area);
-			gtk_label_set_text_with_mnemonic ((GtkLabel *)efhd->priv->save_txt, _("S_ave"));
-
-			if (efhd->priv->show_bar) {
-				gtk_widget_show(efhd->priv->down);
-				gtk_widget_hide(efhd->priv->forward);
-			} else {
-				gtk_widget_show(efhd->priv->forward);
-				gtk_widget_hide(efhd->priv->down);
-				gtk_widget_hide(efhd->priv->attachment_box);
-			}
-		} else if (nattachments > 1) {
-			gtk_label_set_text_with_mnemonic ((GtkLabel *)efhd->priv->save_txt, _("S_ave All"));
-		}
+	if (width > 0) {
+		widget = efhd->priv->attachment_bar;
+		gtk_widget_set_size_request (widget, width, -1);
 	}
 }
 
-static void
-efhd_bar_resize(GtkWidget *w, GtkAllocation *event, EMFormatHTML *efh)
-{
-#if 0 /* KILL-BONOBO -- Does EAttachmentIconView need a resize method? */
-	int width;
-	GtkRequisition req;
-	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) efh;
-
-	gtk_widget_size_request (efhd->priv->attachment_bar, &req);
-	width = ((GtkWidget *) efh->html)->allocation.width - 16;
-
-	/* Update the width of the bar when the width is greater than 1*/
-	if (width > 0)
-		e_attachment_bar_set_width(E_ATTACHMENT_BAR(efhd->priv->attachment_bar), width);
-#endif
-}
-
-static gboolean
-efhd_bar_scroll_event(GtkWidget *w, GdkEventScroll *event, EMFormatHTMLDisplay *efhd)
-{
-#if 0  /* KILL-BONOBO -- Do we still need this for a GtkIconView? */
-	gboolean ret;
-
-	/* Emulate the scroll over the attachment bar, as if it is scrolled in the window.
-	*  It doesnt go automatically since the GnomeIconList is a layout by itself
-	*/
-	g_signal_emit_by_name (gtk_widget_get_parent((GtkWidget *)efhd->parent.html), "scroll_event", event, &ret);
-#endif
-
-	return TRUE;
-}
-
-gboolean
-efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd)
-{
-	attachment_bar_arrow_clicked (NULL, (EMFormatHTMLDisplay *)efhd);
-
-	return TRUE;
-}
-
-static gboolean
-efhd_update_bar(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
-{
-#if 0  /* KILL-BONOBO -- Does EAttachmentIconView need a refresh method? */
-	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)efh;
-	struct _EMFormatHTMLDisplayPrivate *priv = efhd->priv;
-
-	if (priv->attachment_bar)
-		e_attachment_bar_refresh (E_ATTACHMENT_BAR (priv->attachment_bar));
-#endif
-
-	return TRUE;
-}
-
 static gboolean
-efhd_add_bar(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject)
+efhd_add_bar (EMFormatHTML *efh,
+              GtkHTMLEmbedded *eb,
+              EMFormatHTMLPObject *pobject)
 {
 	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)efh;
 	struct _EMFormatHTMLDisplayPrivate *priv = efhd->priv;
-	GtkWidget *hbox1, *hbox2, *hbox3, *vbox, *txt, *image, *save, *scroll;
-	int width, height, bar_width;
-
-	priv->attachment_view = e_attachment_icon_view_new ();
-	scroll = gtk_scrolled_window_new (NULL, NULL);
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-
-	priv->forward = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
-	priv->down = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
-	hbox3 = gtk_hbox_new (FALSE, 0);
-	gtk_box_pack_start ((GtkBox *)hbox3, priv->forward, FALSE, FALSE, 0);
-	gtk_box_pack_start ((GtkBox *)hbox3, priv->down, FALSE, FALSE, 0);
-	priv->arrow = (GtkWidget *)gtk_tool_button_new(hbox3, NULL);
-	g_signal_connect (priv->arrow, "mnemonic_activate", G_CALLBACK (efhd_mnemonic_show_bar), efh);
-	atk_object_set_name (gtk_widget_get_accessible (priv->arrow), _("Show Attachments"));
-
-	priv->label = gtk_label_new(_("No Attachment"));
-	gtk_label_set_mnemonic_widget (GTK_LABEL (priv->label), priv->arrow);
-	save = gtk_button_new();
-	image = gtk_image_new_from_stock ("gtk-save", GTK_ICON_SIZE_BUTTON);
-	txt = gtk_label_new_with_mnemonic(_("S_ave"));
-	priv->save_txt = txt;
-	hbox1 = gtk_hbox_new(FALSE, 0);
-	gtk_box_pack_start((GtkBox *)hbox1, image, FALSE, FALSE, 2);
-	gtk_box_pack_start((GtkBox *)hbox1, txt, FALSE, FALSE, 0);
-
-	gtk_container_add((GtkContainer *)save, hbox1);
-
-	hbox2 = gtk_hbox_new (FALSE, 0);
-	gtk_box_pack_start ((GtkBox *)hbox2, priv->arrow, FALSE, FALSE, 0);
-	gtk_box_pack_start ((GtkBox *)hbox2, priv->label, FALSE, FALSE, 2);
-	gtk_box_pack_start ((GtkBox *)hbox2, save, FALSE, FALSE, 2);
-
-	priv->attachment_box = scroll;
-	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
-	gtk_container_add ((GtkContainer *)priv->attachment_box, priv->attachment_view);
-
-	gtk_widget_get_size_request(priv->attachment_view, &width, &height);
-
-	/* FIXME: What if the text is more?. Should we reduce the text with appending ...?
-	 * or resize the bar? How to figure out that, it needs more space? */
-	bar_width = ((GtkWidget *)efh->html)->parent->allocation.width - /* FIXME */16;
-	gtk_widget_set_size_request (priv->attachment_view,
-				     bar_width > 0 ? bar_width : 0,
-				     84 /* FIXME: Default show only one row, Dont hardcode size*/);
-
-	vbox = gtk_vbox_new (FALSE, 0);
-	gtk_box_pack_start ((GtkBox *)vbox, hbox2, FALSE, FALSE, 2);
-	gtk_box_pack_start ((GtkBox *)vbox, priv->attachment_box, TRUE, TRUE, 2);
+	GtkWidget *widget;
 
-	gtk_container_add ((GtkContainer *)eb, vbox);
-	gtk_widget_show ((GtkWidget *)eb);
+	widget = e_mail_attachment_bar_new ();
+	gtk_container_add (GTK_CONTAINER (eb), widget);
+	priv->attachment_bar = g_object_ref (widget);
+	gtk_widget_show (widget);
 
-	/* Lets hide it by default and show only when there are attachments */
-	priv->attachment_area = vbox;
-	gtk_widget_hide_all (priv->attachment_area);
-
-	g_signal_connect (priv->arrow, "clicked", G_CALLBACK(attachment_bar_arrow_clicked), efh);
-	g_signal_connect (save, "clicked", G_CALLBACK(attachments_save_all_clicked), efh);
-	g_signal_connect (eb, "size_allocate", G_CALLBACK (efhd_bar_resize), efh);
+	g_signal_connect_swapped (
+		widget, "size-allocate",
+		G_CALLBACK (efhd_bar_resize), efh);
 
 	return TRUE;
 }
-static void
-efhd_message_update_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)
-{
-	EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *) emf;
-	const char *classid = "attachment-bar-refresh";
-
-	if (efhd->priv->updated)
-		return;
-
-	efhd->priv->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-	efhd->priv->updated = TRUE;
-	em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_update_bar);
-	camel_stream_printf(stream, "<td><object classid=\"%s\"></object></td>", classid);
-
-}
 
 static void
 efhd_message_add_bar(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info)

Modified: branches/kill-bonobo/mail/em-format-html.c
==============================================================================
--- branches/kill-bonobo/mail/em-format-html.c	(original)
+++ branches/kill-bonobo/mail/em-format-html.c	Tue Mar 24 02:05:26 2009
@@ -200,10 +200,6 @@
 		handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/rfc822");
 		if (handle)
 			handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
-		handle = em_format_find_handler((EMFormat *)m->format, "x-evolution/message/post-header-closure");
-		if (handle && !((EMFormat *)m->format)->print)
-			handle->handler((EMFormat *)m->format, (CamelStream *)m->estream, (CamelMimePart *)m->message, handle);
-
 	}
 
 	camel_stream_flush((CamelStream *)m->estream);

Modified: branches/kill-bonobo/widgets/misc/e-activity.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-activity.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-activity.c	Tue Mar 24 02:05:26 2009
@@ -69,6 +69,7 @@
 {
 	activity->priv->idle_id = 0;
 	e_activity_cancel (activity);
+	g_object_unref (activity);
 
 	return FALSE;
 }
@@ -78,6 +79,7 @@
 {
 	activity->priv->idle_id = 0;
 	e_activity_complete (activity);
+	g_object_unref (activity);
 
 	return FALSE;
 }
@@ -474,13 +476,24 @@
 void
 e_activity_cancel_in_idle (EActivity *activity)
 {
+	guint old_idle_id;
+
 	g_return_if_fail (E_IS_ACTIVITY (activity));
 
-	if (activity->priv->idle_id > 0)
-		g_source_remove (activity->priv->idle_id);
+	/* Be careful not to finalize the activity.  Decrement the
+	 * reference count only after incrementing it, in case this
+	 * is the last reference. */
+
+	old_idle_id = activity->priv->idle_id;
 
 	activity->priv->idle_id = g_idle_add (
-		(GSourceFunc) activity_idle_cancel_cb, activity);
+		(GSourceFunc) activity_idle_cancel_cb,
+		g_object_ref (activity));
+
+	if (old_idle_id > 0) {
+		g_source_remove (old_idle_id);
+		g_object_unref (activity);
+	}
 }
 
 void
@@ -500,13 +513,24 @@
 void
 e_activity_complete_in_idle (EActivity *activity)
 {
+	guint old_idle_id;
+
 	g_return_if_fail (E_IS_ACTIVITY (activity));
 
-	if (activity->priv->idle_id > 0)
-		g_source_remove (activity->priv->idle_id);
+	/* Be careful not to finalize the activity.  Decrement the
+	 * reference count only after incrementing it, in case this
+	 * is the last reference. */
+
+	old_idle_id = activity->priv->idle_id;
 
 	activity->priv->idle_id = g_idle_add (
-		(GSourceFunc) activity_idle_complete_cb, activity);
+		(GSourceFunc) activity_idle_complete_cb,
+		g_object_ref (activity));
+
+	if (old_idle_id > 0) {
+		g_source_remove (old_idle_id);
+		g_object_unref (activity);
+	}
 }
 
 void

Modified: branches/kill-bonobo/widgets/misc/e-attachment-dialog.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-dialog.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-dialog.c	Tue Mar 24 02:05:26 2009
@@ -52,6 +52,7 @@
 	const gchar *display_name;
 	const gchar *description;
 	const gchar *disposition;
+	gchar *type_description = NULL;
 	gboolean sensitive;
 	gboolean active;
 
@@ -71,32 +72,42 @@
 		disposition = NULL;
 	}
 
+	if (content_type != NULL) {
+		gchar *comment;
+		gchar *mime_type;
+
+		comment = g_content_type_get_description (content_type);
+		mime_type = g_content_type_get_mime_type (content_type);
+
+		type_description =
+			g_strdup_printf ("%s (%s)", comment, mime_type);
+
+		g_free (comment);
+		g_free (mime_type);
+	}
+
 	sensitive = G_IS_FILE_INFO (file_info);
 
 	gtk_dialog_set_response_sensitive (
 		GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
 
-	if (display_name == NULL)
-		display_name = "";
 	widget = dialog->priv->display_name_entry;
 	gtk_widget_set_sensitive (widget, sensitive);
 	gtk_entry_set_text (GTK_ENTRY (widget), display_name);
 
-	if (description == NULL)
-		description = "";
 	widget = dialog->priv->description_entry;
 	gtk_widget_set_sensitive (widget, sensitive);
 	gtk_entry_set_text (GTK_ENTRY (widget), description);
 
-	if (content_type == NULL)
-		content_type = "";
 	widget = dialog->priv->content_type_label;
-	gtk_label_set_text (GTK_LABEL (widget), content_type);
+	gtk_label_set_text (GTK_LABEL (widget), type_description);
 
 	active = (g_strcmp0 (disposition, "inline") == 0);
 	widget = dialog->priv->disposition_checkbox;
 	gtk_widget_set_sensitive (widget, sensitive);
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), active);
+
+	g_free (type_description);
 }
 
 static void

Modified: branches/kill-bonobo/widgets/misc/e-attachment-icon-view.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-icon-view.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-icon-view.c	Tue Mar 24 02:05:26 2009
@@ -35,9 +35,48 @@
 	EAttachmentViewPrivate view_priv;
 };
 
+enum {
+	PROP_0,
+	PROP_EDITABLE
+};
+
 static gpointer parent_class;
 
 static void
+attachment_icon_view_set_property (GObject *object,
+                                   guint property_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_EDITABLE:
+			e_attachment_view_set_editable (
+				E_ATTACHMENT_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+attachment_icon_view_get_property (GObject *object,
+                                   guint property_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_EDITABLE:
+			g_value_set_boolean (
+				value, e_attachment_view_get_editable (
+				E_ATTACHMENT_VIEW (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
 attachment_icon_view_dispose (GObject *object)
 {
 	e_attachment_view_dispose (E_ATTACHMENT_VIEW (object));
@@ -231,6 +270,8 @@
 	g_type_class_add_private (class, sizeof (EAttachmentViewPrivate));
 
 	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = attachment_icon_view_set_property;
+	object_class->get_property = attachment_icon_view_get_property;
 	object_class->dispose = attachment_icon_view_dispose;
 	object_class->finalize = attachment_icon_view_finalize;
 
@@ -240,6 +281,9 @@
 	widget_class->drag_motion = attachment_icon_view_drag_motion;
 	widget_class->drag_data_received = attachment_icon_view_drag_data_received;
 	widget_class->popup_menu = attachment_icon_view_popup_menu;
+
+	g_object_class_override_property (
+		object_class, PROP_EDITABLE, "editable");
 }
 
 static void
@@ -260,6 +304,10 @@
 static void
 attachment_icon_view_init (EAttachmentIconView *icon_view)
 {
+	GtkCellLayout *cell_layout;
+	GtkCellRenderer *renderer;
+
+	cell_layout = GTK_CELL_LAYOUT (icon_view);
 	icon_view->priv = E_ATTACHMENT_ICON_VIEW_GET_PRIVATE (icon_view);
 
 	e_attachment_view_init (E_ATTACHMENT_VIEW (icon_view));
@@ -267,13 +315,23 @@
 	gtk_icon_view_set_selection_mode (
 		GTK_ICON_VIEW (icon_view), GTK_SELECTION_MULTIPLE);
 
-	gtk_icon_view_set_pixbuf_column (
-		GTK_ICON_VIEW (icon_view),
-		E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF);
-
-	gtk_icon_view_set_text_column (
-		GTK_ICON_VIEW (icon_view),
-		E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION);
+	renderer = gtk_cell_renderer_pixbuf_new ();
+	g_object_set (renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
+	gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
+
+	gtk_cell_layout_add_attribute (
+		cell_layout, renderer, "gicon",
+		E_ATTACHMENT_STORE_COLUMN_ICON);
+
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set (
+		renderer, "alignment", PANGO_ALIGN_CENTER,
+		"xalign", 0.5, NULL);
+	gtk_cell_layout_pack_start (cell_layout, renderer, FALSE);
+
+	gtk_cell_layout_add_attribute (
+		cell_layout, renderer, "text",
+		E_ATTACHMENT_STORE_COLUMN_CAPTION);
 }
 
 GType

Modified: branches/kill-bonobo/widgets/misc/e-attachment-paned.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-paned.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-paned.c	Tue Mar 24 02:05:26 2009
@@ -23,6 +23,7 @@
 
 #include <glib/gi18n.h>
 #include "e-util/e-binding.h"
+#include "e-attachment-view.h"
 #include "e-attachment-store.h"
 #include "e-attachment-icon-view.h"
 #include "e-attachment-tree-view.h"
@@ -52,6 +53,7 @@
 enum {
 	PROP_0,
 	PROP_ACTIVE_VIEW,
+	PROP_EDITABLE,
 	PROP_EXPANDED
 };
 
@@ -118,7 +120,7 @@
 	gchar *display_size;
 	gchar *markup;
 
-	view = e_attachment_paned_get_view (paned);
+	view = E_ATTACHMENT_VIEW (paned);
 	store = e_attachment_view_get_store (view);
 	expander = GTK_EXPANDER (paned->priv->expander);
 	label = GTK_LABEL (paned->priv->status_label);
@@ -149,9 +151,9 @@
 
 static void
 attachment_paned_set_property (GObject *object,
-                                  guint property_id,
-                                  const GValue *value,
-                                  GParamSpec *pspec)
+                               guint property_id,
+                               const GValue *value,
+                               GParamSpec *pspec)
 {
 	switch (property_id) {
 		case PROP_ACTIVE_VIEW:
@@ -160,6 +162,12 @@
 				g_value_get_int (value));
 			return;
 
+		case PROP_EDITABLE:
+			e_attachment_view_set_editable (
+				E_ATTACHMENT_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+
 		case PROP_EXPANDED:
 			e_attachment_paned_set_expanded (
 				E_ATTACHMENT_PANED (object),
@@ -172,9 +180,9 @@
 
 static void
 attachment_paned_get_property (GObject *object,
-                                  guint property_id,
-                                  GValue *value,
-                                  GParamSpec *pspec)
+                               guint property_id,
+                               GValue *value,
+                               GParamSpec *pspec)
 {
 	switch (property_id) {
 		case PROP_ACTIVE_VIEW:
@@ -183,6 +191,12 @@
 				E_ATTACHMENT_PANED (object)));
 			return;
 
+		case PROP_EDITABLE:
+			g_value_set_boolean (
+				value, e_attachment_view_get_editable (
+				E_ATTACHMENT_VIEW (object)));
+			return;
+
 		case PROP_EXPANDED:
 			g_value_set_boolean (
 				value, e_attachment_paned_get_expanded (
@@ -270,6 +284,14 @@
 		G_OBJECT (priv->notebook), "page");
 
 	e_mutual_binding_new (
+		G_OBJECT (object), "editable",
+		G_OBJECT (priv->icon_view), "editable");
+
+	e_mutual_binding_new (
+		G_OBJECT (object), "editable",
+		G_OBJECT (priv->tree_view), "editable");
+
+	e_mutual_binding_new (
 		G_OBJECT (object), "expanded",
 		G_OBJECT (priv->expander), "expanded");
 
@@ -282,6 +304,110 @@
 		G_OBJECT (priv->notebook), "visible");
 }
 
+static EAttachmentViewPrivate *
+attachment_paned_get_private (EAttachmentView *view)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_private (view);
+}
+
+static EAttachmentStore *
+attachment_paned_get_store (EAttachmentView *view)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_store (view);
+}
+
+static GtkTreePath *
+attachment_paned_get_path_at_pos (EAttachmentView *view,
+                                  gint x,
+                                  gint y)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_path_at_pos (view, x, y);
+}
+
+static GList *
+attachment_paned_get_selected_paths (EAttachmentView *view)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_get_selected_paths (view);
+}
+
+static gboolean
+attachment_paned_path_is_selected (EAttachmentView *view,
+                                   GtkTreePath *path)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	return e_attachment_view_path_is_selected (view, path);
+}
+
+static void
+attachment_paned_select_path (EAttachmentView *view,
+                              GtkTreePath *path)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_select_path (view, path);
+}
+
+static void
+attachment_paned_unselect_path (EAttachmentView *view,
+                                GtkTreePath *path)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_unselect_path (view, path);
+}
+
+static void
+attachment_paned_select_all (EAttachmentView *view)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_select_all (view);
+}
+
+static void
+attachment_paned_unselect_all (EAttachmentView *view)
+{
+	EAttachmentPanedPrivate *priv;
+
+	priv = E_ATTACHMENT_PANED_GET_PRIVATE (view);
+	view = E_ATTACHMENT_VIEW (priv->icon_view);
+
+	e_attachment_view_unselect_all (view);
+}
+
 static void
 attachment_paned_class_init (EAttachmentPanedClass *class)
 {
@@ -319,6 +445,23 @@
 			FALSE,
 			G_PARAM_READWRITE |
 			G_PARAM_CONSTRUCT));
+
+	g_object_class_override_property (
+		object_class, PROP_EDITABLE, "editable");
+}
+
+static void
+attachment_paned_iface_init (EAttachmentViewIface *iface)
+{
+	iface->get_private = attachment_paned_get_private;
+	iface->get_store = attachment_paned_get_store;
+	iface->get_path_at_pos = attachment_paned_get_path_at_pos;
+	iface->get_selected_paths = attachment_paned_get_selected_paths;
+	iface->path_is_selected = attachment_paned_path_is_selected;
+	iface->select_path = attachment_paned_select_path;
+	iface->unselect_path = attachment_paned_unselect_path;
+	iface->select_all = attachment_paned_select_all;
+	iface->unselect_all = attachment_paned_unselect_all;
 }
 
 static void
@@ -394,7 +537,7 @@
 	gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
 	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 6);
 	paned->priv->status_label = g_object_ref (widget);
-	gtk_widget_show (widget);
+	gtk_widget_hide (widget);
 
 	/* Construct the Attachment Views */
 
@@ -493,9 +636,18 @@
 			NULL   /* value_table */
 		};
 
+		static const GInterfaceInfo iface_info = {
+			(GInterfaceInitFunc) attachment_paned_iface_init,
+			(GInterfaceFinalizeFunc) NULL,
+			NULL   /* interface_data */
+		};
+
 		type = g_type_register_static (
 			GTK_TYPE_VPANED, "EAttachmentPaned",
 			&type_info, 0);
+
+		g_type_add_interface_static (
+			type, E_TYPE_ATTACHMENT_VIEW, &iface_info);
 	}
 
 	return type;
@@ -507,14 +659,6 @@
 	return g_object_new (E_TYPE_ATTACHMENT_PANED, NULL);
 }
 
-EAttachmentView *
-e_attachment_paned_get_view (EAttachmentPaned *paned)
-{
-	g_return_val_if_fail (E_IS_ATTACHMENT_PANED (paned), NULL);
-
-	return E_ATTACHMENT_VIEW (paned->priv->icon_view);
-}
-
 GtkWidget *
 e_attachment_paned_get_content_area (EAttachmentPaned *paned)
 {

Modified: branches/kill-bonobo/widgets/misc/e-attachment-paned.h
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-paned.h	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-paned.h	Tue Mar 24 02:05:26 2009
@@ -23,7 +23,6 @@
 #define E_ATTACHMENT_PANED_H
 
 #include <gtk/gtk.h>
-#include <e-attachment-view.h>
 
 /* Standard GObject macros */
 #define E_TYPE_ATTACHMENT_PANED \
@@ -61,8 +60,6 @@
 
 GType		e_attachment_paned_get_type	(void);
 GtkWidget *	e_attachment_paned_new		(void);
-EAttachmentView *
-		e_attachment_paned_get_view	(EAttachmentPaned *paned);
 GtkWidget *	e_attachment_paned_get_content_area
 						(EAttachmentPaned *paned);
 gint		e_attachment_paned_get_active_view

Modified: branches/kill-bonobo/widgets/misc/e-attachment-store.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-store.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-store.c	Tue Mar 24 02:05:26 2009
@@ -34,12 +34,6 @@
 
 #define DEFAULT_ICON_NAME	"mail-attachment"
 
-/* XXX Unfortunate that we have to define this here.  Would
- *     prefer the attachment view classes pick their own size,
- *     but GtkIconView requires a dedicated pixbuf column. */
-#define LARGE_ICON_SIZE		GTK_ICON_SIZE_DIALOG
-#define SMALL_ICON_SIZE		GTK_ICON_SIZE_MENU
-
 struct _EAttachmentStorePrivate {
 	GHashTable *activity_index;
 	GHashTable *attachment_index;
@@ -56,7 +50,7 @@
 	PROP_BACKGROUND_OPTIONS,
 	PROP_CURRENT_FOLDER,
 	PROP_NUM_ATTACHMENTS,
-	PROP_NUM_DOWNLOADING,
+	PROP_NUM_LOADING,
 	PROP_TOTAL_SIZE
 };
 
@@ -133,7 +127,7 @@
 
 	g_hash_table_remove (hash_table, activity);
 
-	g_object_notify (G_OBJECT (store), "num-downloading");
+	g_object_notify (G_OBJECT (store), "num-loading");
 }
 
 static void
@@ -178,10 +172,6 @@
 
 	e_activity_complete (activity);
 
-	path = gtk_tree_model_get_path (model, &iter);
-	gtk_tree_model_row_changed (model, path, &iter);
-	gtk_tree_path_free (path);
-
 	g_object_unref (attachment);
 	g_object_unref (activity);
 
@@ -247,6 +237,7 @@
 
 	reference = gtk_tree_row_reference_copy (reference);
 
+	hash_table = store->priv->activity_index;
 	g_hash_table_insert (hash_table, g_object_ref (activity), reference);
 
 	g_signal_connect_swapped (
@@ -271,7 +262,7 @@
 	e_file_activity_set_file (E_FILE_ACTIVITY (activity), destination);
 	g_signal_emit (store, signals[NEW_ACTIVITY], 0, activity);
 
-	g_object_notify (G_OBJECT (store), "num-downloading");
+	g_object_notify (G_OBJECT (store), "num-loading");
 
 	g_object_unref (activity);
 	g_object_unref (destination);
@@ -350,10 +341,10 @@
 				E_ATTACHMENT_STORE (object)));
 			return;
 
-		case PROP_NUM_DOWNLOADING:
+		case PROP_NUM_LOADING:
 			g_value_set_uint (
 				value,
-				e_attachment_store_get_num_downloading (
+				e_attachment_store_get_num_loading (
 				E_ATTACHMENT_STORE (object)));
 			return;
 
@@ -427,31 +418,25 @@
 {
 	EAttachmentStorePrivate *priv;
 	EAttachment *attachment;
-	GtkIconTheme *icon_theme;
-	GdkPixbuf *large_pixbuf;
-	GdkPixbuf *small_pixbuf;
+	GFile *file;
 	GIcon *icon;
+	GList *list;
 	const gchar *content_type;
 	const gchar *display_name;
 	const gchar *thumbnail_path;
 	gchar *content_description;
 	gchar *display_size;
-	gchar *icon_caption;
-	gint large_icon_size;
-	gint small_icon_size;
+	gchar *caption;
+	gboolean loading;
+	gboolean saving;
 	guint64 size;
 	gint column_id;
-	GError *error = NULL;
 
 	priv = E_ATTACHMENT_STORE_GET_PRIVATE (model);
 
 	if (priv->ignore_row_changed)
 		return;
 
-	icon_theme = gtk_icon_theme_get_default ();
-	gtk_icon_size_lookup (LARGE_ICON_SIZE, &large_icon_size, NULL);
-	gtk_icon_size_lookup (SMALL_ICON_SIZE, &small_icon_size, NULL);
-
 	column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT;
 	gtk_tree_model_get (model, iter, column_id, &attachment, -1);
 	g_return_if_fail (E_IS_ATTACHMENT (attachment));
@@ -459,6 +444,8 @@
 	content_type = e_attachment_get_content_type (attachment);
 	display_name = e_attachment_get_display_name (attachment);
 	thumbnail_path = e_attachment_get_thumbnail_path (attachment);
+	loading = e_attachment_get_loading (attachment);
+	saving = e_attachment_get_saving (attachment);
 	icon = e_attachment_get_icon (attachment);
 	size = e_attachment_get_size (attachment);
 
@@ -467,82 +454,46 @@
 	display_size = g_format_size_for_display ((goffset) size);
 
 	if (size > 0)
-		icon_caption = g_strdup_printf (
+		caption = g_strdup_printf (
 			"%s\n(%s)", display_name, display_size);
 	else
-		icon_caption = g_strdup (display_name);
+		caption = g_strdup (display_name);
 
 	/* Prefer the thumbnail if we have one. */
-	if (thumbnail_path != NULL) {
-		gint width = -1;
-		gint height = -1;
-
-		gdk_pixbuf_get_file_info (thumbnail_path, &width, &height);
-
-		large_pixbuf = gdk_pixbuf_new_from_file_at_scale (
-			thumbnail_path,
-			(width > height) ? large_icon_size : -1,
-			(width > height) ? -1 : large_icon_size,
-			TRUE, &error);
-
-		if (error != NULL) {
-			g_warning ("%s", error->message);
-			g_clear_error (&error);
-		}
+	if (thumbnail_path != NULL && *thumbnail_path != '\0') {
+		file = g_file_new_for_path (thumbnail_path);
+		icon = g_file_icon_new (file);
+		g_object_unref (file);
+
+	/* Else use the standard icon for the content type. */
+	} else if (icon != NULL)
+		g_object_ref (icon);
 
-		small_pixbuf = gdk_pixbuf_new_from_file_at_scale (
-			thumbnail_path,
-			(width > height) ? small_icon_size : -1,
-			(width > height) ? -1 : small_icon_size,
-			TRUE, &error);
-
-		if (error != NULL) {
-			g_warning ("%s", error->message);
-			g_clear_error (&error);
-		}
+	/* Last ditch fallback.  (GFileInfo not yet loaded?) */
+	else
+		icon = g_themed_icon_new (DEFAULT_ICON_NAME);
 
-	/* Otherwise fall back to the icon theme. */
-	} else {
-		GtkIconInfo *icon_info = NULL;
-		const gchar *filename;
-
-		if (G_IS_ICON (icon))
-			icon_info = gtk_icon_theme_lookup_by_gicon (
-				icon_theme, icon, large_icon_size, 0);
-		if (icon_info == NULL)
-			icon_info = gtk_icon_theme_lookup_icon (
-				icon_theme, DEFAULT_ICON_NAME,
-				large_icon_size, 0);
-		g_return_if_fail (icon_info != NULL);
-
-		filename = gtk_icon_info_get_filename (icon_info);
-		large_pixbuf = gdk_pixbuf_new_from_file (filename, &error);
-		gtk_icon_info_free (icon_info);
-
-		if (error != NULL) {
-			g_warning ("%s", error->message);
-			g_clear_error (&error);
+	/* Apply emblems. */
+	list = e_attachment_list_emblems (attachment);
+	if (list != NULL) {
+		GIcon *emblemed_icon;
+		GEmblem *emblem;
+
+		emblem = G_EMBLEM (list->data);
+		emblemed_icon = g_emblemed_icon_new (icon, emblem);
+		list = g_list_delete_link (list, list);
+		g_object_unref (emblem);
+
+		while (list != NULL) {
+			emblem = G_EMBLEM (list->data);
+			g_emblemed_icon_add_emblem (
+				G_EMBLEMED_ICON (emblemed_icon), emblem);
+			list = g_list_delete_link (list, list);
+			g_object_unref (emblem);
 		}
 
-		icon_info = NULL;
-
-		if (G_IS_ICON (icon))
-			icon_info = gtk_icon_theme_lookup_by_gicon (
-				icon_theme, icon, small_icon_size, 0);
-		if (icon_info == NULL)
-			icon_info = gtk_icon_theme_lookup_icon (
-				icon_theme, DEFAULT_ICON_NAME,
-				small_icon_size, 0);
-		g_return_if_fail (icon_info != NULL);
-
-		filename = gtk_icon_info_get_filename (icon_info);
-		small_pixbuf = gdk_pixbuf_new_from_file (filename, &error);
-		gtk_icon_info_free (icon_info);
-
-		if (error != NULL) {
-			g_warning ("%s", error->message);
-			g_clear_error (&error);
-		}
+		g_object_unref (icon);
+		icon = emblemed_icon;
 	}
 
 	/* We're about to trigger another "row-changed"
@@ -553,20 +504,16 @@
 		GTK_LIST_STORE (model), iter,
 		E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, content_description,
 		E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME, display_name,
-		E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION, icon_caption,
-		E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF, large_pixbuf,
-		E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF, small_pixbuf,
+		E_ATTACHMENT_STORE_COLUMN_CAPTION, caption,
+		E_ATTACHMENT_STORE_COLUMN_ICON, icon,
+		E_ATTACHMENT_STORE_COLUMN_LOADING, loading,
+		E_ATTACHMENT_STORE_COLUMN_SAVING, saving,
 		E_ATTACHMENT_STORE_COLUMN_SIZE, size,
 		-1);
 
 	priv->ignore_row_changed = FALSE;
 
-	if (large_pixbuf != NULL)
-		g_object_unref (large_pixbuf);
-
-	if (small_pixbuf != NULL)
-		g_object_unref (small_pixbuf);
-
+	g_object_unref (icon);
 	g_free (content_description);
 	g_free (display_size);
 }
@@ -633,10 +580,10 @@
 
 	g_object_class_install_property (
 		object_class,
-		PROP_NUM_DOWNLOADING,
+		PROP_NUM_LOADING,
 		g_param_spec_uint (
-			"num-downloading",
-			"Num Downloading",
+			"num-loading",
+			"Num Loading",
 			NULL,
 			0,
 			G_MAXUINT,
@@ -686,11 +633,12 @@
 
 	types[column++] = E_TYPE_ACTIVITY;	/* COLUMN_ACTIVITY */
 	types[column++] = E_TYPE_ATTACHMENT;	/* COLUMN_ATTACHMENT */
+	types[column++] = G_TYPE_STRING;	/* COLUMN_CAPTION */
 	types[column++] = G_TYPE_STRING;	/* COLUMN_CONTENT_TYPE */
 	types[column++] = G_TYPE_STRING;	/* COLUMN_DISPLAY_NAME */
-	types[column++] = G_TYPE_STRING;	/* COLUMN_ICON_CAPTION */
-	types[column++] = GDK_TYPE_PIXBUF;	/* COLUMN_LARGE_PIXBUF */
-	types[column++] = GDK_TYPE_PIXBUF;	/* COLUMN_SMALL_PIXBUF */
+	types[column++] = G_TYPE_ICON;		/* COLUMN_ICON */
+	types[column++] = G_TYPE_BOOLEAN;	/* COLUMN_LOADING */
+	types[column++] = G_TYPE_BOOLEAN;	/* COLUMN_SAVING */
 	types[column++] = G_TYPE_UINT64;	/* COLUMN_SIZE */
 
 	g_assert (column == E_ATTACHMENT_STORE_NUM_COLUMNS);
@@ -774,7 +722,7 @@
 	/* This lets the attachment tell us when to update. */
 	_e_attachment_set_reference (attachment, reference);
 
-	if (!g_file_is_native (file))
+	if (file != NULL && !g_file_is_native (file))
 		attachment_store_copy_async (store, attachment);
 
 	g_object_freeze_notify (G_OBJECT (store));
@@ -897,7 +845,7 @@
 }
 
 guint
-e_attachment_store_get_num_downloading (EAttachmentStore *store)
+e_attachment_store_get_num_loading (EAttachmentStore *store)
 {
 	g_return_val_if_fail (E_IS_ATTACHMENT_STORE (store), 0);
 

Modified: branches/kill-bonobo/widgets/misc/e-attachment-store.h
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-store.h	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-store.h	Tue Mar 24 02:05:26 2009
@@ -62,11 +62,12 @@
 enum {
 	E_ATTACHMENT_STORE_COLUMN_ACTIVITY,	/* E_TYPE_ACTIVITY */
 	E_ATTACHMENT_STORE_COLUMN_ATTACHMENT,	/* E_TYPE_ATTACHMENT */
+	E_ATTACHMENT_STORE_COLUMN_CAPTION,	/* G_TYPE_STRING */
 	E_ATTACHMENT_STORE_COLUMN_CONTENT_TYPE, /* G_TYPE_STRING */
 	E_ATTACHMENT_STORE_COLUMN_DISPLAY_NAME,	/* G_TYPE_STRING */
-	E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION,	/* G_TYPE_STRING */
-	E_ATTACHMENT_STORE_COLUMN_LARGE_PIXBUF,	/* GDK_TYPE_PIXBUF */
-	E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF,	/* GDK_TYPE_PIXBUF */
+	E_ATTACHMENT_STORE_COLUMN_ICON,		/* G_TYPE_ICON */
+	E_ATTACHMENT_STORE_COLUMN_LOADING,	/* G_TYPE_BOOLEAN */
+	E_ATTACHMENT_STORE_COLUMN_SAVING,	/* G_TYPE_BOOLEAN */
 	E_ATTACHMENT_STORE_COLUMN_SIZE,		/* G_TYPE_UINT64 */
 	E_ATTACHMENT_STORE_NUM_COLUMNS
 };
@@ -90,7 +91,7 @@
 						 const gchar *current_folder);
 guint		e_attachment_store_get_num_attachments
 						(EAttachmentStore *store);
-guint		e_attachment_store_get_num_downloading
+guint		e_attachment_store_get_num_loading
 						(EAttachmentStore *store);
 guint64		e_attachment_store_get_total_size
 						(EAttachmentStore *store);

Modified: branches/kill-bonobo/widgets/misc/e-attachment-tree-view.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-tree-view.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-tree-view.c	Tue Mar 24 02:05:26 2009
@@ -36,9 +36,48 @@
 	EAttachmentViewPrivate view_priv;
 };
 
+enum {
+	PROP_0,
+	PROP_EDITABLE
+};
+
 static gpointer parent_class;
 
 static void
+attachment_tree_view_set_property (GObject *object,
+                                   guint property_id,
+                                   const GValue *value,
+                                   GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_EDITABLE:
+			e_attachment_view_set_editable (
+				E_ATTACHMENT_VIEW (object),
+				g_value_get_boolean (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+attachment_tree_view_get_property (GObject *object,
+                                   guint property_id,
+                                   GValue *value,
+                                   GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_EDITABLE:
+			g_value_set_boolean (
+				value, e_attachment_view_get_editable (
+				E_ATTACHMENT_VIEW (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
 attachment_tree_view_dispose (GObject *object)
 {
 	e_attachment_view_dispose (E_ATTACHMENT_VIEW (object));
@@ -267,6 +306,8 @@
 	g_type_class_add_private (class, sizeof (EAttachmentViewPrivate));
 
 	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = attachment_tree_view_set_property;
+	object_class->get_property = attachment_tree_view_get_property;
 	object_class->dispose = attachment_tree_view_dispose;
 	object_class->finalize = attachment_tree_view_finalize;
 
@@ -276,6 +317,9 @@
 	widget_class->drag_motion = attachment_tree_view_drag_motion;
 	widget_class->drag_data_received = attachment_tree_view_drag_data_received;
 	widget_class->popup_menu = attachment_tree_view_popup_menu;
+
+	g_object_class_override_property (
+		object_class, PROP_EDITABLE, "editable");
 }
 
 static void
@@ -318,9 +362,11 @@
 	renderer = gtk_cell_renderer_pixbuf_new ();
 	gtk_tree_view_column_pack_start (column, renderer, FALSE);
 
+	g_object_set (renderer, "stock-size", GTK_ICON_SIZE_MENU, NULL);
+
 	gtk_tree_view_column_add_attribute (
-		column, renderer, "pixbuf",
-		E_ATTACHMENT_STORE_COLUMN_SMALL_PIXBUF);
+		column, renderer, "gicon",
+		E_ATTACHMENT_STORE_COLUMN_ICON);
 
 	renderer = gtk_cell_renderer_text_new ();
 	g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);

Modified: branches/kill-bonobo/widgets/misc/e-attachment-view.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-view.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-view.c	Tue Mar 24 02:05:26 2009
@@ -25,6 +25,7 @@
 #include <glib/gi18n.h>
 #include <camel/camel-stream-mem.h>
 
+#include "e-util/e-binding.h"
 #include "e-util/e-plugin-ui.h"
 #include "e-util/e-util.h"
 #include "e-attachment-dialog.h"
@@ -123,6 +124,30 @@
 }
 
 static void
+action_open_in_cb (GtkAction *action,
+                   EAttachmentView *view)
+{
+	GAppInfo *app_info;
+	EActivity *activity;
+	EAttachment *attachment;
+
+	app_info = g_object_get_data (G_OBJECT (action), "app-info");
+	g_return_if_fail (G_IS_APP_INFO (app_info));
+
+	attachment = g_object_get_data (G_OBJECT (action), "attachment");
+	g_return_if_fail (E_IS_ATTACHMENT (attachment));
+
+	activity = e_file_activity_newv (
+		_("Opening attachment in %s"),
+		g_app_info_get_name (app_info));
+
+	e_attachment_launch_async (
+		attachment, E_FILE_ACTIVITY (activity), app_info);
+
+	g_object_unref (activity);
+}
+
+static void
 action_properties_cb (GtkAction *action,
                       EAttachmentView *view)
 {
@@ -407,6 +432,16 @@
 {
 	gint ii;
 
+	g_object_interface_install_property (
+		iface,
+		g_param_spec_boolean (
+			"editable",
+			"Editable",
+			NULL,
+			TRUE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
 	for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) {
 		const gchar *target = drag_info[ii].target;
 		drag_info[ii].atom = gdk_atom_intern (target, FALSE);
@@ -489,6 +524,10 @@
 	if (error != NULL)
 		g_error ("%s", error->message);
 
+	e_mutual_binding_new (
+		G_OBJECT (view), "editable",
+		G_OBJECT (priv->editable_actions), "visible");
+
 	e_plugin_ui_register_manager (ui_manager, "attachment-view", view);
 }
 
@@ -562,6 +601,32 @@
 	return iface->get_store (view);
 }
 
+gboolean
+e_attachment_view_get_editable (EAttachmentView *view)
+{
+	EAttachmentViewPrivate *priv;
+
+	g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE);
+
+	priv = e_attachment_view_get_private (view);
+
+	return priv->editable;
+}
+
+void
+e_attachment_view_set_editable (EAttachmentView *view,
+                                gboolean editable)
+{
+	EAttachmentViewPrivate *priv;
+
+	g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
+
+	priv = e_attachment_view_get_private (view);
+	priv->editable = editable;
+
+	g_object_notify (G_OBJECT (view), "editable");
+}
+
 GList *
 e_attachment_view_get_selected_attachments (EAttachmentView *view)
 {
@@ -1006,27 +1071,29 @@
 e_attachment_view_update_actions (EAttachmentView *view)
 {
 	EAttachmentViewPrivate *priv;
-	GFileInfo *file_info;
+	EAttachment *attachment;
 	GtkAction *action;
-	GList *selected;
+	GList *list, *iter;
 	guint n_selected;
 	gboolean is_image;
 
 	g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
 
 	priv = e_attachment_view_get_private (view);
-	selected = e_attachment_view_get_selected_attachments (view);
-	n_selected = g_list_length (selected);
-
-	is_image = FALSE;
-	file_info = NULL;
+	list = e_attachment_view_get_selected_attachments (view);
+	n_selected = g_list_length (list);
 
 	if (n_selected == 1) {
-		EAttachment *attachment = selected->data;
-		file_info = e_attachment_get_file_info (attachment);
+		attachment = g_object_ref (list->data);
 		is_image = e_attachment_is_image (attachment);
+	} else {
+		attachment = NULL;
+		is_image = FALSE;
 	}
 
+	g_list_foreach (list, (GFunc) g_object_unref, NULL);
+	g_list_free (list);
+
 	action = e_attachment_view_get_action (view, "properties");
 	gtk_action_set_visible (action, n_selected == 1);
 
@@ -1038,4 +1105,67 @@
 
 	action = e_attachment_view_get_action (view, "set-background");
 	gtk_action_set_visible (action, is_image);
+
+	/* Clear out the "openwith" action group. */
+	gtk_ui_manager_remove_ui (priv->ui_manager, priv->merge_id);
+	e_action_group_remove_all_actions (priv->openwith_actions);
+
+	if (attachment == NULL)
+		return;
+
+	list = e_attachment_list_apps (attachment);
+
+	for (iter = list; iter != NULL; iter = iter->next) {
+		GAppInfo *app_info = iter->data;
+		GtkAction *action;
+		const gchar *app_executable;
+		const gchar *app_name;
+		gchar *action_tooltip;
+		gchar *action_label;
+		gchar *action_name;
+
+		if (!g_app_info_should_show (app_info))
+			continue;
+
+		app_executable = g_app_info_get_executable (app_info);
+		app_name = g_app_info_get_name (app_info);
+
+		action_name = g_strdup_printf ("open-in-%s", app_executable);
+		action_label = g_strdup_printf (_("Open in %s..."), app_name);
+
+		action_tooltip = g_strdup_printf (
+			_("Open this attachment in %s"), app_name);
+
+		action = gtk_action_new (
+			action_name, action_label, action_tooltip, NULL);
+
+		g_object_set_data_full (
+			G_OBJECT (action),
+			"app-info", g_object_ref (app_info),
+			(GDestroyNotify) g_object_unref);
+
+		g_object_set_data_full (
+			G_OBJECT (action),
+			"attachment", g_object_ref (attachment),
+			(GDestroyNotify) g_object_unref);
+
+		g_signal_connect (
+			action, "activate",
+			G_CALLBACK (action_open_in_cb), view);
+
+		gtk_action_group_add_action (priv->openwith_actions, action);
+
+		gtk_ui_manager_add_ui (
+			priv->ui_manager, priv->merge_id,
+			"/context/open-actions", action_name,
+			action_name, GTK_UI_MANAGER_AUTO, FALSE);
+
+		g_free (action_name);
+		g_free (action_label);
+		g_free (action_tooltip);
+	}
+
+	g_object_unref (attachment);
+	g_list_foreach (list, (GFunc) g_object_unref, NULL);
+	g_list_free (list);
 }

Modified: branches/kill-bonobo/widgets/misc/e-attachment-view.h
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment-view.h	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment-view.h	Tue Mar 24 02:05:26 2009
@@ -88,6 +88,8 @@
 	GtkSelectionData *selection_data;
 	guint info;
 	guint time;
+
+	guint editable : 1;
 };
 
 GType		e_attachment_view_get_type	(void);
@@ -100,6 +102,9 @@
 		e_attachment_view_get_private	(EAttachmentView *view);
 EAttachmentStore *
 		e_attachment_view_get_store	(EAttachmentView *view);
+gboolean	e_attachment_view_get_editable	(EAttachmentView *view);
+void		e_attachment_view_set_editable	(EAttachmentView *view,
+						 gboolean editable);
 GList *		e_attachment_view_get_selected_attachments
 						(EAttachmentView *view);
 void		e_attachment_view_remove_selected

Modified: branches/kill-bonobo/widgets/misc/e-attachment.c
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment.c	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment.c	Tue Mar 24 02:05:26 2009
@@ -36,6 +36,16 @@
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_ATTACHMENT, EAttachmentPrivate))
 
+/* Emblems */
+#define EMBLEM_LOADING		"emblem-downloads"
+#define EMBLEM_SAVING		"document-save"
+#define EMBLEM_ENCRYPT_WEAK	"security-low"
+#define EMBLEM_ENCRYPT_STRONG	"security-high"
+#define EMBLEM_ENCRYPT_UNKNOWN	"security-medium"
+#define EMBLEM_SIGN_BAD		"stock_signature_bad"
+#define EMBLEM_SIGN_GOOD	"stock_signature-ok"
+#define EMBLEM_SIGN_UNKNOWN	"stock_signature"
+
 /* Attributes needed by EAttachmentStore, et al. */
 #define ATTACHMENT_QUERY "standard::*,preview::*,thumbnail::*"
 
@@ -45,6 +55,11 @@
 	GCancellable *cancellable;
 	CamelMimePart *mime_part;
 	gchar *disposition;
+	guint loading : 1;
+	guint saving  : 1;
+
+	camel_cipher_validity_encrypt_t encrypted;
+	camel_cipher_validity_sign_t signed_;
 
 	/* This is a reference to our row in an EAttachmentStore,
 	 * serving as a means of broadcasting "row-changed" signals.
@@ -56,9 +71,12 @@
 enum {
 	PROP_0,
 	PROP_DISPOSITION,
+	PROP_ENCRYPTED,
 	PROP_FILE,
 	PROP_FILE_INFO,
-	PROP_MIME_PART
+	PROP_LOADING,
+	PROP_MIME_PART,
+	PROP_SIGNED
 };
 
 static gpointer parent_class;
@@ -89,6 +107,8 @@
 
 	gtk_tree_model_get_iter (model, &iter, path);
 	gtk_tree_model_row_changed (model, path, &iter);
+
+	/* XXX This doesn't really belong here. */
 	g_object_notify (G_OBJECT (model), "total-size");
 
 	gtk_tree_path_free (path);
@@ -101,7 +121,7 @@
 	const gchar *key;
 	gchar *charset;
 
-	/* XXX This function doesn't really belong here. */
+	/* XXX This doesn't really belong here. */
 
 	client = gconf_client_get_default ();
 	key = "/apps/evolution/mail/composer/charset";
@@ -149,7 +169,26 @@
 	attachment->priv->file_info = file_info;
 
 	g_object_notify (G_OBJECT (attachment), "file-info");
+	attachment_notify_model (attachment);
+}
+
+static void
+attachment_set_loading (EAttachment *attachment,
+                        gboolean loading)
+{
+	attachment->priv->loading = loading;
+
+	g_object_notify (G_OBJECT (attachment), "loading");
+	attachment_notify_model (attachment);
+}
+
+static void
+attachment_set_saving (EAttachment *attachment,
+                       gboolean saving)
+{
+	attachment->priv->saving = saving;
 
+	g_object_notify (G_OBJECT (attachment), "saving");
 	attachment_notify_model (attachment);
 }
 
@@ -162,7 +201,7 @@
 
 	g_object_freeze_notify (G_OBJECT (attachment));
 
-	/* Cancel any query operations in progress. */
+	/* Cancel any I/O operations in progress. */
 	if (!g_cancellable_is_cancelled (cancellable)) {
 		g_cancellable_cancel (cancellable);
 		g_cancellable_reset (cancellable);
@@ -220,7 +259,8 @@
 	if (file_info == NULL || mime_part == NULL)
 		return;
 
-	/* XXX Note that we skip "standard::size" here. */
+	/* XXX Note that we skip "standard::size" here.
+	 *     The CamelMimePart already knows the size. */
 
 	attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE;
 	string = g_file_info_get_attribute_string (file_info, attribute);
@@ -241,28 +281,55 @@
 }
 
 static void
-attachment_mime_part_to_file_info (EAttachment *attachment)
+attachment_populate_file_info (EAttachment *attachment,
+                               GFileInfo *file_info)
 {
 	CamelContentType *content_type;
 	CamelMimePart *mime_part;
-	GFileInfo *file_info;
 	const gchar *attribute;
 	const gchar *string;
 	gchar *allocated;
 	guint64 v_uint64;
 
-	file_info = e_attachment_get_file_info (attachment);
 	mime_part = e_attachment_get_mime_part (attachment);
 
-	if (file_info == NULL || mime_part == NULL)
-		return;
-
 	attribute = G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE;
 	content_type = camel_mime_part_get_content_type (mime_part);
 	allocated = camel_content_type_simple (content_type);
-	if (allocated != NULL)
+	if (allocated != NULL) {
+		GIcon *icon;
+		gchar *cp;
+
+		/* GIO expects lowercase MIME types. */
+		for (cp = allocated; *cp != '\0'; cp++)
+			*cp = g_ascii_tolower (*cp);
+
+		/* Swap the MIME type for a content type. */
+		cp = g_content_type_from_mime_type (allocated);
+		g_free (allocated);
+		allocated = cp;
+
+		/* Use the MIME part's filename if we have to. */
+		if (g_content_type_is_unknown (allocated)) {
+			string = camel_mime_part_get_filename (mime_part);
+			if (string != NULL) {
+				g_free (allocated);
+				allocated = g_content_type_guess (
+					string, NULL, 0, NULL);
+			}
+		}
+
 		g_file_info_set_attribute_string (
 			file_info, attribute, allocated);
+
+		attribute = G_FILE_ATTRIBUTE_STANDARD_ICON;
+		icon = g_content_type_get_icon (allocated);
+		if (icon != NULL) {
+			g_file_info_set_attribute_object (
+				file_info, attribute, G_OBJECT (icon));
+			g_object_unref (icon);
+		}
+	}
 	g_free (allocated);
 
 	attribute = G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME;
@@ -298,6 +365,12 @@
 				g_value_get_string (value));
 			return;
 
+		case PROP_ENCRYPTED:
+			e_attachment_set_encrypted (
+				E_ATTACHMENT (object),
+				g_value_get_int (value));
+			return;
+
 		case PROP_FILE:
 			e_attachment_set_file (
 				E_ATTACHMENT (object),
@@ -309,6 +382,12 @@
 				E_ATTACHMENT (object),
 				g_value_get_boxed (value));
 			return;
+
+		case PROP_SIGNED:
+			e_attachment_set_signed (
+				E_ATTACHMENT (object),
+				g_value_get_int (value));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -327,6 +406,12 @@
 				E_ATTACHMENT (object)));
 			return;
 
+		case PROP_ENCRYPTED:
+			g_value_set_int (
+				value, e_attachment_get_encrypted (
+				E_ATTACHMENT (object)));
+			return;
+
 		case PROP_FILE:
 			g_value_set_object (
 				value, e_attachment_get_file (
@@ -339,11 +424,23 @@
 				E_ATTACHMENT (object)));
 			return;
 
+		case PROP_LOADING:
+			g_value_set_boolean (
+				value, e_attachment_get_loading (
+				E_ATTACHMENT (object)));
+			return;
+
 		case PROP_MIME_PART:
 			g_value_set_boxed (
 				value, e_attachment_get_mime_part (
 				E_ATTACHMENT (object)));
 			return;
+
+		case PROP_SIGNED:
+			g_value_set_int (
+				value, e_attachment_get_signed (
+				E_ATTACHMENT (object)));
+			return;
 	}
 
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -423,6 +520,20 @@
 			G_PARAM_READWRITE |
 			G_PARAM_CONSTRUCT));
 
+	/* FIXME Define a GEnumClass for this. */
+	g_object_class_install_property (
+		object_class,
+		PROP_ENCRYPTED,
+		g_param_spec_int (
+			"encrypted",
+			"Encrypted",
+			NULL,
+			CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE,
+			CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG,
+			CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
 	g_object_class_install_property (
 		object_class,
 		PROP_FILE,
@@ -446,6 +557,16 @@
 
 	g_object_class_install_property (
 		object_class,
+		PROP_LOADING,
+		g_param_spec_boolean (
+			"loading",
+			"Loading",
+			NULL,
+			FALSE,
+			G_PARAM_READABLE));
+
+	g_object_class_install_property (
+		object_class,
 		PROP_MIME_PART,
 		g_param_spec_boxed (
 			"mime-part",
@@ -453,6 +574,20 @@
 			NULL,
 			E_TYPE_CAMEL_OBJECT,
 			G_PARAM_READWRITE));
+
+	/* FIXME Define a GEnumClass for this. */
+	g_object_class_install_property (
+		object_class,
+		PROP_SIGNED,
+		g_param_spec_int (
+			"signed",
+			"Signed",
+			NULL,
+			CAMEL_CIPHER_VALIDITY_SIGN_NONE,
+			CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY,
+			CAMEL_CIPHER_VALIDITY_SIGN_NONE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
 }
 
 static void
@@ -460,6 +595,8 @@
 {
 	attachment->priv = E_ATTACHMENT_GET_PRIVATE (attachment);
 	attachment->priv->cancellable = g_cancellable_new ();
+	attachment->priv->encrypted = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE;
+	attachment->priv->signed_ = CAMEL_CIPHER_VALIDITY_SIGN_NONE;
 }
 
 GType
@@ -724,8 +861,6 @@
 e_attachment_set_mime_part (EAttachment *attachment,
                             CamelMimePart *mime_part)
 {
-	GFileInfo *file_info;
-
 	g_return_if_fail (E_IS_ATTACHMENT (attachment));
 
 	g_object_freeze_notify (G_OBJECT (attachment));
@@ -738,16 +873,64 @@
 	attachment_reset (attachment);
 	attachment->priv->mime_part = mime_part;
 
-	file_info = g_file_info_new ();
-	attachment_set_file_info (attachment, file_info);
-	attachment_mime_part_to_file_info (attachment);
-	g_object_unref (file_info);
+	if (mime_part != NULL) {
+		GFileInfo *file_info;
+
+		file_info = g_file_info_new ();
+		attachment_populate_file_info (attachment, file_info);
+		attachment_set_file_info (attachment, file_info);
+		g_object_unref (file_info);
+	}
 
 	g_object_notify (G_OBJECT (attachment), "mime-part");
 
 	g_object_thaw_notify (G_OBJECT (attachment));
 }
 
+camel_cipher_validity_encrypt_t
+e_attachment_get_encrypted (EAttachment *attachment)
+{
+	g_return_val_if_fail (
+		E_IS_ATTACHMENT (attachment),
+		CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE);
+
+	return attachment->priv->encrypted;
+}
+
+void
+e_attachment_set_encrypted (EAttachment *attachment,
+                            camel_cipher_validity_encrypt_t encrypted)
+{
+	g_return_if_fail (E_IS_ATTACHMENT (attachment));
+
+	attachment->priv->encrypted = encrypted;
+
+	g_object_notify (G_OBJECT (attachment), "encrypted");
+	attachment_notify_model (attachment);
+}
+
+camel_cipher_validity_sign_t
+e_attachment_get_signed (EAttachment *attachment)
+{
+	g_return_val_if_fail (
+		E_IS_ATTACHMENT (attachment),
+		CAMEL_CIPHER_VALIDITY_SIGN_NONE);
+
+	return attachment->priv->signed_;
+}
+
+void
+e_attachment_set_signed (EAttachment *attachment,
+                         camel_cipher_validity_sign_t signed_)
+{
+	g_return_if_fail (E_IS_ATTACHMENT (attachment));
+
+	attachment->priv->signed_ = signed_;
+
+	g_object_notify (G_OBJECT (attachment), "signed");
+	attachment_notify_model (attachment);
+}
+
 const gchar *
 e_attachment_get_content_type (EAttachment *attachment)
 {
@@ -817,6 +1000,14 @@
 		g_file_info_get_attribute_object (file_info, attribute);
 }
 
+gboolean
+e_attachment_get_loading (EAttachment *attachment)
+{
+	g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE);
+
+	return attachment->priv->loading;
+}
+
 const gchar *
 e_attachment_get_thumbnail_path (EAttachment *attachment)
 {
@@ -834,6 +1025,14 @@
 	return g_file_info_get_attribute_byte_string (file_info, attribute);
 }
 
+gboolean
+e_attachment_get_saving (EAttachment *attachment)
+{
+	g_return_val_if_fail (E_IS_ATTACHMENT (attachment), FALSE);
+
+	return attachment->priv->saving;
+}
+
 guint64
 e_attachment_get_size (EAttachment *attachment)
 {
@@ -881,24 +1080,225 @@
 	return g_content_type_equals (content_type, "message/rfc822");
 }
 
+GList *
+e_attachment_list_apps (EAttachment *attachment)
+{
+	GList *app_info_list;
+	const gchar *content_type;
+	const gchar *display_name;
+	gchar *allocated;
+
+	g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
+
+	content_type = e_attachment_get_content_type (attachment);
+	display_name = e_attachment_get_display_name (attachment);
+	g_return_val_if_fail (content_type != NULL, NULL);
+
+	app_info_list = g_app_info_get_all_for_type (content_type);
+
+	if (app_info_list != NULL || display_name == NULL)
+		goto exit;
+
+	if (!g_content_type_is_unknown (content_type))
+		goto exit;
+
+	allocated = g_content_type_guess (display_name, NULL, 0, NULL);
+	app_info_list = g_app_info_get_all_for_type (allocated);
+	g_free (allocated);
+
+exit:
+	return app_info_list;
+}
+
+GList *
+e_attachment_list_emblems (EAttachment *attachment)
+{
+	GList *list = NULL;
+	GIcon *icon;
+
+	g_return_val_if_fail (E_IS_ATTACHMENT (attachment), NULL);
+
+	if (e_attachment_get_loading (attachment)) {
+		icon = g_themed_icon_new (EMBLEM_LOADING);
+		list = g_list_append (list, g_emblem_new (icon));
+		g_object_unref (icon);
+	}
+
+	if (e_attachment_get_saving (attachment)) {
+		icon = g_themed_icon_new (EMBLEM_SAVING);
+		list = g_list_append (list, g_emblem_new (icon));
+		g_object_unref (icon);
+	}
+
+	switch (e_attachment_get_encrypted (attachment)) {
+		case CAMEL_CIPHER_VALIDITY_ENCRYPT_WEAK:
+			icon = g_themed_icon_new (EMBLEM_ENCRYPT_WEAK);
+			list = g_list_append (list, g_emblem_new (icon));
+			g_object_unref (icon);
+			break;
+
+		case CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED:
+			icon = g_themed_icon_new (EMBLEM_ENCRYPT_UNKNOWN);
+			list = g_list_append (list, g_emblem_new (icon));
+			g_object_unref (icon);
+			break;
+
+		case CAMEL_CIPHER_VALIDITY_ENCRYPT_STRONG:
+			icon = g_themed_icon_new (EMBLEM_ENCRYPT_STRONG);
+			list = g_list_append (list, g_emblem_new (icon));
+			g_object_unref (icon);
+			break;
+
+		default:
+			break;
+	}
+
+	switch (e_attachment_get_signed (attachment)) {
+		case CAMEL_CIPHER_VALIDITY_SIGN_GOOD:
+			icon = g_themed_icon_new (EMBLEM_SIGN_GOOD);
+			list = g_list_append (list, g_emblem_new (icon));
+			g_object_unref (icon);
+			break;
+
+		case CAMEL_CIPHER_VALIDITY_SIGN_BAD:
+			icon = g_themed_icon_new (EMBLEM_SIGN_BAD);
+			list = g_list_append (list, g_emblem_new (icon));
+			g_object_unref (icon);
+			break;
+
+		case CAMEL_CIPHER_VALIDITY_SIGN_UNKNOWN:
+		case CAMEL_CIPHER_VALIDITY_SIGN_NEED_PUBLIC_KEY:
+			icon = g_themed_icon_new (EMBLEM_SIGN_UNKNOWN);
+			list = g_list_append (list, g_emblem_new (icon));
+			g_object_unref (icon);
+			break;
+
+		default:
+			break;
+	}
+
+	return list;
+}
+
+/************************ e_attachment_launch_async() ************************/
+
+static void
+attachment_launch_file (EActivity *activity,
+                        GAppInfo *app_info,
+                        GFile *file)
+{
+	GdkAppLaunchContext *launch_context;
+	GList *file_list;
+	GError *error = NULL;
+
+	file_list = g_list_prepend (NULL, file);
+	launch_context = gdk_app_launch_context_new ();
+
+	g_app_info_launch (
+		app_info, file_list,
+		G_APP_LAUNCH_CONTEXT (launch_context), &error);
+
+	g_list_free (file_list);
+	g_object_unref (launch_context);
+
+	if (error != NULL) {
+		e_activity_set_error (activity, error);
+		g_error_free (error);
+	}
+
+	e_activity_complete (activity);
+	g_object_unref (activity);
+}
+
+void
+e_attachment_launch_async (EAttachment *attachment,
+                           EFileActivity *file_activity,
+                           GAppInfo *app_info)
+{
+	CamelMimePart *mime_part;
+	GFile *file;
+
+	g_return_if_fail (E_IS_ATTACHMENT (attachment));
+	g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity));
+	g_return_if_fail (G_IS_APP_INFO (app_info));
+
+	file = e_attachment_get_file (attachment);
+	mime_part = e_attachment_get_mime_part (attachment);
+	g_return_if_fail (file != NULL || mime_part != NULL);
+
+	/* If the attachment already references a GFile, we can launch
+	 * the application directly.  Otherwise we have to save the MIME
+	 * part to a temporary file and launch the application from that. */
+	if (G_IS_FILE (file)) {
+		EActivity *activity = g_object_ref (file_activity);
+		attachment_launch_file (activity, app_info, file);
+
+	} else if (CAMEL_IS_MIME_PART (mime_part)) {
+		/* XXX Not done yet. */
+	}
+}
+
+/************************* e_attachment_save_async() *************************/
+
+typedef struct _AttachmentSaveContext AttachmentSaveContext;
+
+struct _AttachmentSaveContext {
+	EAttachment *attachment;
+	EFileActivity *file_activity;
+	GOutputStream *output_stream;
+};
+
+static AttachmentSaveContext *
+attachment_save_context_new (EAttachment *attachment,
+                             EFileActivity *file_activity)
+{
+	AttachmentSaveContext *save_context;
+
+	save_context = g_slice_new (AttachmentSaveContext);
+	save_context->attachment = g_object_ref (attachment);
+	save_context->file_activity = g_object_ref (file_activity);
+	save_context->output_stream = NULL;
+
+	attachment_set_saving (save_context->attachment, TRUE);
+
+	return save_context;
+}
+
+static void
+attachment_save_context_free (AttachmentSaveContext *save_context)
+{
+	attachment_set_saving (save_context->attachment, FALSE);
+
+	g_object_unref (save_context->attachment);
+	g_object_unref (save_context->file_activity);
+
+	if (save_context->output_stream != NULL)
+		g_object_unref (save_context->output_stream);
+
+	g_slice_free (AttachmentSaveContext, save_context);
+}
+
 static void
 attachment_save_file_cb (GFile *source,
                          GAsyncResult *result,
-                         EActivity *activity)
+                         AttachmentSaveContext *save_context)
 {
+	EActivity *activity;
 	GError *error = NULL;
 
+	activity = E_ACTIVITY (save_context->file_activity);
+
 	if (!g_file_copy_finish (source, result, &error)) {
 		e_activity_set_error (activity, error);
 		g_error_free (error);
 	}
 
 	e_activity_complete (activity);
-	g_object_unref (activity);
+	attachment_save_context_free (save_context);
 }
 
 static gpointer
-attachment_save_part_thread (EActivity *activity)
+attachment_save_part_thread (AttachmentSaveContext *save_context)
 {
 	GObject *object;
 	EAttachment *attachment;
@@ -910,12 +1310,11 @@
 	CamelStream *stream;
 	GError *error = NULL;
 
-	object = G_OBJECT (activity);
-	attachment = g_object_get_data (object, "attachment");
-	output_stream = g_object_get_data (object, "output-stream");
+	attachment = save_context->attachment;
+	file_activity = save_context->file_activity;
+	output_stream = save_context->output_stream;
 
 	/* Last chance to cancel. */
-	file_activity = E_FILE_ACTIVITY (activity);
 	cancellable = e_file_activity_get_cancellable (file_activity);
 	if (g_cancellable_set_error_if_cancelled (cancellable, &error))
 		goto exit;
@@ -941,12 +1340,12 @@
 
 exit:
 	if (error != NULL) {
-		e_activity_set_error (activity, error);
+		e_activity_set_error (E_ACTIVITY (file_activity), error);
 		g_error_free (error);
 	}
 
-	e_activity_complete_in_idle (activity);
-	g_object_unref (activity);
+	e_activity_complete_in_idle (E_ACTIVITY (file_activity));
+	attachment_save_context_free (save_context);
 
 	return NULL;
 }
@@ -954,30 +1353,28 @@
 static void
 attachment_save_part_cb (GFile *destination,
                          GAsyncResult *result,
-                         EActivity *activity)
+                         AttachmentSaveContext *save_context)
 {
 	GFileOutputStream *output_stream;
+	EActivity *activity;
 	GError *error = NULL;
 
+	activity = E_ACTIVITY (save_context->file_activity);
 	output_stream = g_file_replace_finish (destination, result, &error);
+	save_context->output_stream = G_OUTPUT_STREAM (output_stream);
 
-	if (output_stream != NULL) {
-		g_object_set_data_full (
-			G_OBJECT (activity),
-			"output-stream", output_stream,
-			(GDestroyNotify) g_object_unref);
+	if (output_stream != NULL)
 		g_thread_create (
 			(GThreadFunc) attachment_save_part_thread,
-			activity, FALSE, &error);
-	}
+			save_context, FALSE, &error);
 
 	if (error != NULL) {
 		e_activity_set_error (activity, error);
 		e_activity_complete (activity);
-		g_object_unref (activity);
 		g_error_free (error);
-	}
 
+		attachment_save_context_free (save_context);
+	}
 }
 
 void
@@ -985,14 +1382,15 @@
                          EFileActivity *file_activity,
                          GFile *destination)
 {
+	AttachmentSaveContext *save_context;
 	GFileProgressCallback progress_callback;
 	GCancellable *cancellable;
 	CamelMimePart *mime_part;
 	GFile *source;
 
 	g_return_if_fail (E_IS_ATTACHMENT (attachment));
-	g_return_if_fail (G_IS_FILE (destination));
 	g_return_if_fail (E_IS_FILE_ACTIVITY (file_activity));
+	g_return_if_fail (G_IS_FILE (destination));
 
 	/* The attachment content is either a GFile (on disk) or a
 	 * CamelMimePart (in memory).  Each is saved differently. */
@@ -1001,6 +1399,7 @@
 	mime_part = e_attachment_get_mime_part (attachment);
 	g_return_if_fail (source != NULL || mime_part != NULL);
 
+	save_context = attachment_save_context_new (attachment, file_activity);
 	cancellable = e_file_activity_get_cancellable (file_activity);
 	progress_callback = e_file_activity_progress;
 
@@ -1017,7 +1416,7 @@
 			G_PRIORITY_DEFAULT, cancellable,
 			progress_callback, file_activity,
 			(GAsyncReadyCallback) attachment_save_file_cb,
-			g_object_ref (file_activity));
+			save_context);
 
 	/* CamelMimePart can only be decoded to a file synchronously, so
 	 * we do this in two stages.  Stage one asynchronously opens the
@@ -1034,7 +1433,7 @@
 			G_FILE_CREATE_REPLACE_DESTINATION,
 			G_PRIORITY_DEFAULT, cancellable,
 			(GAsyncReadyCallback) attachment_save_part_cb,
-			g_object_ref (file_activity));
+			save_context);
 	}
 }
 

Modified: branches/kill-bonobo/widgets/misc/e-attachment.h
==============================================================================
--- branches/kill-bonobo/widgets/misc/e-attachment.h	(original)
+++ branches/kill-bonobo/widgets/misc/e-attachment.h	Tue Mar 24 02:05:26 2009
@@ -23,6 +23,7 @@
 #define E_ATTACHMENT_H
 
 #include <gio/gio.h>
+#include <camel/camel-cipher-context.h>
 #include <camel/camel-mime-part.h>
 #include <camel/camel-mime-message.h>
 #include <camel/camel-multipart.h>
@@ -80,14 +81,31 @@
 CamelMimePart *	e_attachment_get_mime_part	(EAttachment *attachment);
 void		e_attachment_set_mime_part	(EAttachment *attachment,
 						 CamelMimePart *mime_part);
+camel_cipher_validity_encrypt_t
+		e_attachment_get_encrypted	(EAttachment *attachment);
+void		e_attachment_set_encrypted	(EAttachment *attachment,
+						 camel_cipher_validity_encrypt_t encrypted);
+camel_cipher_validity_sign_t
+		e_attachment_get_signed		(EAttachment *attachment);
+void		e_attachment_set_signed		(EAttachment *attachment,
+						 camel_cipher_validity_sign_t signed_);
 const gchar *	e_attachment_get_content_type	(EAttachment *attachment);
 const gchar *	e_attachment_get_display_name	(EAttachment *attachment);
 const gchar *	e_attachment_get_description	(EAttachment *attachment);
 GIcon *		e_attachment_get_icon		(EAttachment *attachment);
+gboolean	e_attachment_get_loading	(EAttachment *attachment);
 const gchar *	e_attachment_get_thumbnail_path	(EAttachment *attachment);
+gboolean	e_attachment_get_saving		(EAttachment *attachment);
 guint64		e_attachment_get_size		(EAttachment *attachment);
 gboolean	e_attachment_is_image		(EAttachment *attachment);
 gboolean	e_attachment_is_rfc822		(EAttachment *attachment);
+GList *		e_attachment_list_apps		(EAttachment *attachment);
+GList *		e_attachment_list_emblems	(EAttachment *attachment);
+
+/* Asynchronous Operations */
+void		e_attachment_launch_async	(EAttachment *attachment,
+						 EFileActivity *file_activity,
+						 GAppInfo *app_info);
 void		e_attachment_save_async		(EAttachment *attachment,
 						 EFileActivity *file_activity,
 						 GFile *destination);



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