aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2009-03-24 10:05:26 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2009-03-24 10:05:26 +0800
commit6e163b39c75dbba470d073b4f79a897aa6fb0e54 (patch)
tree86e93752711579676337bb7cfef18c903b6c7538
parent4cec9fc7169dc3b810321555a70cda916720867d (diff)
downloadgsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.tar
gsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.tar.gz
gsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.tar.bz2
gsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.tar.lz
gsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.tar.xz
gsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.tar.zst
gsoc2013-evolution-6e163b39c75dbba470d073b4f79a897aa6fb0e54.zip
Saving progress again on the attachment rewrite.
svn path=/branches/kill-bonobo/; revision=37470
-rw-r--r--calendar/gui/dialogs/comp-editor.c39
-rw-r--r--composer/e-msg-composer.c8
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/e-mail-attachment-bar.c656
-rw-r--r--mail/e-mail-attachment-bar.h77
-rw-r--r--mail/em-format-html-display.c235
-rw-r--r--mail/em-format-html.c4
-rw-r--r--widgets/misc/e-activity.c36
-rw-r--r--widgets/misc/e-attachment-dialog.c25
-rw-r--r--widgets/misc/e-attachment-icon-view.c70
-rw-r--r--widgets/misc/e-attachment-paned.c176
-rw-r--r--widgets/misc/e-attachment-paned.h3
-rw-r--r--widgets/misc/e-attachment-store.c170
-rw-r--r--widgets/misc/e-attachment-store.h9
-rw-r--r--widgets/misc/e-attachment-tree-view.c50
-rw-r--r--widgets/misc/e-attachment-view.c148
-rw-r--r--widgets/misc/e-attachment-view.h5
-rw-r--r--widgets/misc/e-attachment.c479
-rw-r--r--widgets/misc/e-attachment.h18
19 files changed, 1769 insertions, 441 deletions
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index e3b1bac053..7e51411002 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -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 @@ drag_data_received (CompEditor *editor,
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 @@ drag_motion (CompEditor *editor,
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 @@ drag_motion (CompEditor *editor,
static GSList *
get_attachment_list (CompEditor *editor)
{
- EAttachmentPaned *paned;
EAttachmentStore *store;
EAttachmentView *view;
GtkTreeModel *model;
@@ -275,8 +271,7 @@ get_attachment_list (CompEditor *editor)
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 @@ static void
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 @@ action_save_cb (GtkAction *action,
CompEditor *editor)
{
CompEditorPrivate *priv = editor->priv;
- EAttachmentPaned *paned;
EAttachmentStore *store;
EAttachmentView *view;
ECalComponentText text;
@@ -823,11 +815,10 @@ action_save_cb (GtkAction *action,
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 @@ static void
comp_editor_init (CompEditor *editor)
{
CompEditorPrivate *priv;
- EAttachmentPaned *paned;
EAttachmentView *view;
GtkActionGroup *action_group;
GtkAction *action;
@@ -1626,8 +1616,7 @@ comp_editor_init (CompEditor *editor)
/* 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 @@ comp_editor_get_client (CompEditor *editor)
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 @@ set_attachment_list (CompEditor *editor, GSList *attach_list)
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 @@ comp_editor_close (CompEditor *editor)
GSList *
comp_editor_get_mime_attach_list (CompEditor *editor)
{
- EAttachmentPaned *paned;
EAttachmentStore *store;
EAttachmentView *view;
GtkTreeModel *model;
@@ -2637,8 +2621,7 @@ comp_editor_get_mime_attach_list (CompEditor *editor)
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);
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 138da07389..f77addfa58 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -3803,7 +3803,7 @@ e_msg_composer_get_message (EMsgComposer *composer,
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 @@ e_msg_composer_get_header_table (EMsgComposer *composer)
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
diff --git a/mail/Makefile.am b/mail/Makefile.am
index ef5b769ce4..f2b3119308 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -35,6 +35,8 @@ module_LTLIBRARIES = \
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 \
diff --git a/mail/e-mail-attachment-bar.c b/mail/e-mail-attachment-bar.c
new file mode 100644
index 0000000000..4424a84684
--- /dev/null
+++ b/mail/e-mail-attachment-bar.c
@@ -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");
+}
diff --git a/mail/e-mail-attachment-bar.h b/mail/e-mail-attachment-bar.h
new file mode 100644
index 0000000000..e32f6e2ede
--- /dev/null
+++ b/mail/e-mail-attachment-bar.h
@@ -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 */
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 242dcdceb8..7ccdc07e63 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -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 const char *smime_sign_colour[5] = {
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 @@ struct _attach_puri {
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 @@ efhd_format_attachment (EMFormat *emf,
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 @@ static EMFormatHandler type_builtin_table[] = {
{ "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 @@ efhd_attachment_image(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObjec
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 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
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 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
} 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 @@ efhd_attachment_button(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObje
gtk_widget_hide(info->down);
gtk_container_add((GtkContainer *)eb, mainbox);
-#endif
return TRUE;
}
@@ -1481,23 +1475,6 @@ efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri)
}
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 @@ static EPopupItem efhd_bar_menu_items[] = {
#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);
-
- nattachments = e_attachment_store_get_num_attachments (store);
-
- if (nattachments > 0) {
- char *txt;
+ EMFormatHTMLDisplay *efhd;
+ GtkWidget *widget;
+ gint width;
- /* 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);
+ efhd = EM_FORMAT_HTML_DISPLAY (efh);
- /* 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"));
+ widget = GTK_WIDGET (efh->html);
+ width = widget->allocation.width - 12;
- 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);
-
- gtk_container_add ((GtkContainer *)eb, vbox);
- gtk_widget_show ((GtkWidget *)eb);
+ GtkWidget *widget;
- /* Lets hide it by default and show only when there are attachments */
- priv->attachment_area = vbox;
- gtk_widget_hide_all (priv->attachment_area);
+ widget = e_mail_attachment_bar_new ();
+ gtk_container_add (GTK_CONTAINER (eb), widget);
+ priv->attachment_bar = g_object_ref (widget);
+ gtk_widget_show (widget);
- 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)
diff --git a/mail/em-format-html.c b/mail/em-format-html.c
index 6308947a26..fae1566876 100644
--- a/mail/em-format-html.c
+++ b/mail/em-format-html.c
@@ -200,10 +200,6 @@ efh_format_exec (struct _format_msg *m)
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);
diff --git a/widgets/misc/e-activity.c b/widgets/misc/e-activity.c
index c65c3aaa0a..d40d5aacbe 100644
--- a/widgets/misc/e-activity.c
+++ b/widgets/misc/e-activity.c
@@ -69,6 +69,7 @@ activity_idle_cancel_cb (EActivity *activity)
{
activity->priv->idle_id = 0;
e_activity_cancel (activity);
+ g_object_unref (activity);
return FALSE;
}
@@ -78,6 +79,7 @@ activity_idle_complete_cb (EActivity *activity)
{
activity->priv->idle_id = 0;
e_activity_complete (activity);
+ g_object_unref (activity);
return FALSE;
}
@@ -474,13 +476,24 @@ e_activity_cancel (EActivity *activity)
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 @@ e_activity_complete (EActivity *activity)
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
diff --git a/widgets/misc/e-attachment-dialog.c b/widgets/misc/e-attachment-dialog.c
index f697df1fe9..da3c3a855c 100644
--- a/widgets/misc/e-attachment-dialog.c
+++ b/widgets/misc/e-attachment-dialog.c
@@ -52,6 +52,7 @@ attachment_dialog_update (EAttachmentDialog *dialog)
const gchar *display_name;
const gchar *description;
const gchar *disposition;
+ gchar *type_description = NULL;
gboolean sensitive;
gboolean active;
@@ -71,32 +72,42 @@ attachment_dialog_update (EAttachmentDialog *dialog)
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
diff --git a/widgets/misc/e-attachment-icon-view.c b/widgets/misc/e-attachment-icon-view.c
index 8d39a76d75..6d27429743 100644
--- a/widgets/misc/e-attachment-icon-view.c
+++ b/widgets/misc/e-attachment-icon-view.c
@@ -35,9 +35,48 @@ struct _EAttachmentIconViewPrivate {
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 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class)
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 @@ attachment_icon_view_class_init (EAttachmentIconViewClass *class)
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 @@ attachment_icon_view_iface_init (EAttachmentViewIface *iface)
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 @@ attachment_icon_view_init (EAttachmentIconView *icon_view)
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);
+ 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_icon_view_set_text_column (
- GTK_ICON_VIEW (icon_view),
- E_ATTACHMENT_STORE_COLUMN_ICON_CAPTION);
+ gtk_cell_layout_add_attribute (
+ cell_layout, renderer, "text",
+ E_ATTACHMENT_STORE_COLUMN_CAPTION);
}
GType
diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c
index bb919e9789..5134282526 100644
--- a/widgets/misc/e-attachment-paned.c
+++ b/widgets/misc/e-attachment-paned.c
@@ -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 @@ struct _EAttachmentPanedPrivate {
enum {
PROP_0,
PROP_ACTIVE_VIEW,
+ PROP_EDITABLE,
PROP_EXPANDED
};
@@ -118,7 +120,7 @@ attachment_paned_update_status (EAttachmentPaned *paned)
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 @@ attachment_paned_update_status (EAttachmentPaned *paned)
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 @@ attachment_paned_set_property (GObject *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_attachment_paned_set_expanded (
E_ATTACHMENT_PANED (object),
@@ -172,9 +180,9 @@ attachment_paned_set_property (GObject *object,
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 @@ attachment_paned_get_property (GObject *object,
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 @@ attachment_paned_constructed (GObject *object)
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 @@ attachment_paned_constructed (GObject *object)
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 @@ attachment_paned_class_init (EAttachmentPanedClass *class)
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 @@ attachment_paned_init (EAttachmentPaned *paned)
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 @@ e_attachment_paned_get_type (void)
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 @@ e_attachment_paned_new (void)
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)
{
diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h
index c6cad5226f..c15d642771 100644
--- a/widgets/misc/e-attachment-paned.h
+++ b/widgets/misc/e-attachment-paned.h
@@ -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 @@ struct _EAttachmentPanedClass {
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
diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c
index 2658dd06c9..bd6cb18481 100644
--- a/widgets/misc/e-attachment-store.c
+++ b/widgets/misc/e-attachment-store.c
@@ -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 @@ enum {
PROP_BACKGROUND_OPTIONS,
PROP_CURRENT_FOLDER,
PROP_NUM_ATTACHMENTS,
- PROP_NUM_DOWNLOADING,
+ PROP_NUM_LOADING,
PROP_TOTAL_SIZE
};
@@ -133,7 +127,7 @@ attachment_store_remove_activity (EAttachmentStore *store,
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 @@ attachment_store_copy_ready (GFile *source,
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 @@ attachment_store_copy_async (EAttachmentStore *store,
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 @@ attachment_store_copy_async (EAttachmentStore *store,
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 @@ attachment_store_get_property (GObject *object,
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 @@ attachment_store_row_changed (GtkTreeModel *model,
{
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 @@ attachment_store_row_changed (GtkTreeModel *model,
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 @@ attachment_store_row_changed (GtkTreeModel *model,
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);
+ 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);
- 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);
- }
+ /* 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);
- }
-
- /* 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);
+ /* Last ditch fallback. (GFileInfo not yet loaded?) */
+ else
+ icon = g_themed_icon_new (DEFAULT_ICON_NAME);
+
+ /* 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 @@ attachment_store_row_changed (GtkTreeModel *model,
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 @@ attachment_store_class_init (EAttachmentStoreClass *class)
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 @@ attachment_store_init (EAttachmentStore *store)
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 @@ e_attachment_store_add_attachment (EAttachmentStore *store,
/* 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 @@ e_attachment_store_get_num_attachments (EAttachmentStore *store)
}
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);
diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h
index 906aee6638..971868258f 100644
--- a/widgets/misc/e-attachment-store.h
+++ b/widgets/misc/e-attachment-store.h
@@ -62,11 +62,12 @@ struct _EAttachmentStoreClass {
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 @@ void e_attachment_store_set_current_folder
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);
diff --git a/widgets/misc/e-attachment-tree-view.c b/widgets/misc/e-attachment-tree-view.c
index 817a6c7dab..df01e07040 100644
--- a/widgets/misc/e-attachment-tree-view.c
+++ b/widgets/misc/e-attachment-tree-view.c
@@ -36,9 +36,48 @@ struct _EAttachmentTreeViewPrivate {
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 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class)
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 @@ attachment_tree_view_class_init (EAttachmentTreeViewClass *class)
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 @@ attachment_tree_view_init (EAttachmentTreeView *tree_view)
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);
diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c
index 198ce75d31..bdb0a0067e 100644
--- a/widgets/misc/e-attachment-view.c
+++ b/widgets/misc/e-attachment-view.c
@@ -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 @@ action_drag_move_cb (GtkAction *action,
}
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 @@ attachment_view_class_init (EAttachmentViewIface *iface)
{
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 @@ e_attachment_view_init (EAttachmentView *view)
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 @@ e_attachment_view_get_store (EAttachmentView *view)
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 @@ void
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 @@ e_attachment_view_update_actions (EAttachmentView *view)
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);
}
diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h
index a00308d2d5..e6e04a82a3 100644
--- a/widgets/misc/e-attachment-view.h
+++ b/widgets/misc/e-attachment-view.h
@@ -88,6 +88,8 @@ struct _EAttachmentViewPrivate {
GtkSelectionData *selection_data;
guint info;
guint time;
+
+ guint editable : 1;
};
GType e_attachment_view_get_type (void);
@@ -100,6 +102,9 @@ EAttachmentViewPrivate *
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
diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c
index 6f9e80f02b..015a706dc4 100644
--- a/widgets/misc/e-attachment.c
+++ b/widgets/misc/e-attachment.c
@@ -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 @@ struct _EAttachmentPrivate {
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 @@ struct _EAttachmentPrivate {
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 @@ attachment_notify_model (EAttachment *attachment)
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 @@ attachment_get_default_charset (void)
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_set_file_info (EAttachment *attachment,
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 @@ attachment_reset (EAttachment *attachment)
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 @@ attachment_file_info_to_mime_part (EAttachment *attachment,
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 @@ attachment_file_info_to_mime_part (EAttachment *attachment,
}
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 @@ attachment_set_property (GObject *object,
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 @@ attachment_set_property (GObject *object,
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 @@ attachment_get_property (GObject *object,
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 @@ attachment_get_property (GObject *object,
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 @@ attachment_class_init (EAttachmentClass *class)
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 @@ attachment_class_init (EAttachmentClass *class)
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 @@ attachment_class_init (EAttachmentClass *class)
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_init (EAttachment *attachment)
{
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 @@ void
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 @@ e_attachment_set_mime_part (EAttachment *attachment,
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 @@ e_attachment_get_icon (EAttachment *attachment)
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 @@ e_attachment_get_thumbnail_path (EAttachment *attachment)
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 @@ e_attachment_is_rfc822 (EAttachment *attachment)
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 @@ attachment_save_part_thread (EActivity *activity)
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 @@ attachment_save_part_thread (EActivity *activity)
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 @@ exit:
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 @@ e_attachment_save_async (EAttachment *attachment,
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 @@ e_attachment_save_async (EAttachment *attachment,
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 @@ e_attachment_save_async (EAttachment *attachment,
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 @@ e_attachment_save_async (EAttachment *attachment,
G_FILE_CREATE_REPLACE_DESTINATION,
G_PRIORITY_DEFAULT, cancellable,
(GAsyncReadyCallback) attachment_save_part_cb,
- g_object_ref (file_activity));
+ save_context);
}
}
diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h
index a7bb85dd75..d9ef68bf39 100644
--- a/widgets/misc/e-attachment.h
+++ b/widgets/misc/e-attachment.h
@@ -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 @@ GFileInfo * e_attachment_get_file_info (EAttachment *attachment);
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);