diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2009-03-21 03:06:59 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2009-03-21 03:06:59 +0800 |
commit | 4cec9fc7169dc3b810321555a70cda916720867d (patch) | |
tree | 8fe739ab0d249fb35bedc572bd34b3717512283b /composer | |
parent | 7a92d9cc82b7775a0f5cb1fde233119d435a79b6 (diff) | |
download | gsoc2013-evolution-4cec9fc7169dc3b810321555a70cda916720867d.tar.gz gsoc2013-evolution-4cec9fc7169dc3b810321555a70cda916720867d.tar.zst gsoc2013-evolution-4cec9fc7169dc3b810321555a70cda916720867d.zip |
Saving progress on a massive attachment handling rewrite.
svn path=/branches/kill-bonobo/; revision=37465
Diffstat (limited to 'composer')
-rw-r--r-- | composer/e-composer-actions.c | 72 | ||||
-rw-r--r-- | composer/e-composer-private.c | 90 | ||||
-rw-r--r-- | composer/e-composer-private.h | 13 | ||||
-rw-r--r-- | composer/e-msg-composer.c | 545 | ||||
-rw-r--r-- | composer/e-msg-composer.h | 14 |
5 files changed, 189 insertions, 545 deletions
diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c index 01c05ecc61..2af7a63fcd 100644 --- a/composer/e-composer-actions.c +++ b/composer/e-composer-actions.c @@ -29,69 +29,13 @@ static void action_attach_cb (GtkAction *action, EMsgComposer *composer) { - EAttachmentBar *bar; - GtkWidget *dialog; - GtkWidget *option; - GSList *uris, *iter; - const gchar *disposition; - gboolean active; - gint response; - - bar = E_ATTACHMENT_BAR (composer->priv->attachment_bar); - - dialog = gtk_file_chooser_dialog_new ( - _("Insert Attachment"), - GTK_WINDOW (composer), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - _("A_ttach"), GTK_RESPONSE_OK, - NULL); - - gtk_dialog_set_default_response ( - GTK_DIALOG (dialog), GTK_RESPONSE_OK); - gtk_file_chooser_set_local_only ( - GTK_FILE_CHOOSER (dialog), FALSE); - gtk_file_chooser_set_select_multiple ( - GTK_FILE_CHOOSER (dialog), TRUE); - gtk_window_set_icon_name ( - GTK_WINDOW (dialog), "mail-message-new"); + EAttachmentView *view; + EAttachmentStore *store; - option = gtk_check_button_new_with_mnemonic ( - _("_Suggest automatic display of attachment")); - gtk_widget_show (option); - gtk_file_chooser_set_extra_widget ( - GTK_FILE_CHOOSER (dialog), option); + view = e_msg_composer_get_attachment_view (composer); + store = e_attachment_view_get_store (view); - response = gtkhtml_editor_file_chooser_dialog_run ( - GTKHTML_EDITOR (composer), dialog); - - if (response != GTK_RESPONSE_OK) - goto exit; - - uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog)); - active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (option)); - disposition = active ? "inline" : "attachment"; - - for (iter = uris; iter != NULL; iter = iter->next) { - CamelURL *url; - - url = camel_url_new (iter->data, NULL); - if (url == NULL) - continue; - - if (!g_ascii_strcasecmp (url->protocol, "file")) - e_attachment_bar_attach (bar, url->path, disposition); - else - e_attachment_bar_attach_remote_file (bar, iter->data, disposition); - - camel_url_free (url); - } - - g_slist_foreach (uris, (GFunc) g_free, NULL); - g_slist_free (uris); - -exit: - gtk_widget_destroy (dialog); + e_attachment_store_run_load_dialog (store, GTK_WINDOW (composer)); } static void @@ -327,10 +271,10 @@ static void action_new_message_cb (GtkAction *action, EMsgComposer *composer) { - GtkWidget *widget; + EMsgComposer *new_composer; - widget = e_msg_composer_new (); - gtk_widget_show (widget); + new_composer = e_msg_composer_new (); + gtk_widget_show (GTK_WIDGET (new_composer)); } static void diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c index f910f978a6..aba1fdbe9f 100644 --- a/composer/e-composer-private.c +++ b/composer/e-composer-private.c @@ -51,22 +51,25 @@ composer_setup_charset_menu (EMsgComposer *composer) static void composer_setup_recent_menu (EMsgComposer *composer) { + EAttachmentView *view; GtkUIManager *manager; GtkAction *action = NULL; - const gchar *path, *action_name; + const gchar *action_name; + const gchar *path; guint merge_id; + view = e_msg_composer_get_attachment_view (composer); manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (composer)); - action_name = "recent-menu"; path = "/main-menu/insert-menu/insert-menu-top/recent-placeholder"; merge_id = gtk_ui_manager_new_merge_id (manager); + action_name = "recent-menu"; - action = e_attachment_bar_recent_action_new ( - e_msg_composer_get_attachment_bar (composer), - action_name, _("Recent _Documents")); + action = e_attachment_view_recent_action_new ( + view, action_name, _("Recent _Documents")); if (action != NULL) { - gtk_action_group_add_action (composer->priv->composer_actions, action); + gtk_action_group_add_action ( + composer->priv->composer_actions, action); gtk_ui_manager_add_ui ( manager, merge_id, path, @@ -85,9 +88,8 @@ e_composer_private_init (EMsgComposer *composer) GtkhtmlEditor *editor; GtkUIManager *manager; - GtkWidget *widget; - GtkWidget *expander; GtkWidget *container; + GtkWidget *widget; GtkWidget *send_widget; const gchar *path; gchar *filename; @@ -138,66 +140,33 @@ e_composer_private_init (EMsgComposer *composer) /* Construct the header table. */ + container = editor->vbox; + widget = e_composer_header_table_new (); gtk_container_set_border_width (GTK_CONTAINER (widget), 6); - gtk_box_pack_start (GTK_BOX (editor->vbox), widget, FALSE, FALSE, 0); - gtk_box_reorder_child (GTK_BOX (editor->vbox), widget, 2); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_box_reorder_child (GTK_BOX (container), widget, 2); priv->header_table = g_object_ref (widget); gtk_widget_show (widget); - /* Construct attachment widgets. - * XXX Move this stuff into a new custom widget. */ + /* Construct the attachment paned. */ - widget = gtk_expander_new (NULL); - gtk_expander_set_expanded (GTK_EXPANDER (widget), FALSE); + widget = e_attachment_paned_new (); gtk_container_set_border_width (GTK_CONTAINER (widget), 6); - gtk_box_pack_start (GTK_BOX (editor->vbox), widget, FALSE, FALSE, 0); - priv->attachment_expander = g_object_ref (widget); - gtk_widget_show (widget); - expander = widget; - - widget = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy ( - GTK_SCROLLED_WINDOW (widget), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type ( - GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (expander), widget); - priv->attachment_scrolled_window = g_object_ref (widget); - gtk_widget_show (widget); - container = widget; - - widget = e_attachment_bar_new (); - GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS); - gtk_container_add (GTK_CONTAINER (container), widget); - priv->attachment_bar = g_object_ref (widget); - gtk_widget_show (widget); - - widget = gtk_hbox_new (FALSE, 0); - gtk_expander_set_label_widget (GTK_EXPANDER (expander), widget); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + priv->attachment_paned = g_object_ref (widget); gtk_widget_show (widget); - container = widget; - widget = gtk_label_new_with_mnemonic (_("Show _Attachment Bar")); - gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 6); - priv->attachment_expander_label = g_object_ref (widget); - gtk_widget_show (widget); + /* Reparent the scrolled window containing the GtkHTML widget + * into the content area of the top attachment pane. */ - widget = gtk_image_new_from_icon_name ( - "mail-attachment", GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_widget_set_size_request (widget, 100, -1); - gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); - priv->attachment_expander_icon = g_object_ref (widget); - gtk_widget_hide (widget); - - widget = gtk_label_new (NULL); - gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); - gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 6); - priv->attachment_expander_num = g_object_ref (widget); - gtk_widget_show (widget); + widget = GTK_WIDGET (gtkhtml_editor_get_html (editor)); + widget = gtk_widget_get_parent (widget); + container = e_attachment_paned_get_content_area ( + E_ATTACHMENT_PANED (priv->attachment_paned)); + gtk_widget_reparent (widget, container); + gtk_box_set_child_packing ( + GTK_BOX (container), widget, TRUE, TRUE, 0, GTK_PACK_START); composer_setup_recent_menu (composer); } @@ -223,6 +192,11 @@ e_composer_private_dispose (EMsgComposer *composer) composer->priv->header_table = NULL; } + if (composer->priv->attachment_paned != NULL) { + g_object_unref (composer->priv->attachment_paned); + composer->priv->attachment_paned = NULL; + } + if (composer->priv->charset_actions != NULL) { g_object_unref (composer->priv->charset_actions); composer->priv->charset_actions = NULL; diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h index 5984d3cb2b..fc30472897 100644 --- a/composer/e-composer-private.h +++ b/composer/e-composer-private.h @@ -25,13 +25,14 @@ #include <camel/camel-iconv.h> -#include "e-attachment-bar.h" #include "e-composer-actions.h" #include "e-composer-autosave.h" #include "e-composer-header-table.h" #include "e-util/e-binding.h" #include "e-util/e-util.h" #include "e-util/gconf-bridge.h" +#include "widgets/misc/e-attachment-paned.h" +#include "widgets/misc/e-attachment-store.h" #define E_MSG_COMPOSER_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -94,6 +95,8 @@ struct _EMsgComposerPrivate { GtkWidget *html_editor; GtkWidget *header_table; + GtkWidget *attachment_paned; + GtkActionGroup *charset_actions; GtkActionGroup *composer_actions; @@ -102,13 +105,6 @@ struct _EMsgComposerPrivate { GtkWidget *focused_entry; - GtkWidget *attachment_bar; - GtkWidget *attachment_scrolled_window; - GtkWidget *attachment_expander; - GtkWidget *attachment_expander_label; - GtkWidget *attachment_expander_icon; - GtkWidget *attachment_expander_num; - GtkWidget *address_dialog; GHashTable *inline_images; @@ -117,7 +113,6 @@ struct _EMsgComposerPrivate { gchar *mime_type, *mime_body, *charset; - guint32 attachment_bar_visible : 1; guint32 is_alternative : 1; guint32 autosaved : 1; guint32 mode_post : 1; diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index ab2dfc8172..138da07389 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -76,13 +76,11 @@ #include <camel/camel-smime-context.h> #endif -#include "mail/em-popup.h" #include "mail/em-utils.h" #include "mail/mail-tools.h" #include "e-msg-composer.h" #include "e-attachment.h" -#include "e-attachment-bar.h" #include "e-composer-autosave.h" #include "e-composer-private.h" #include "e-composer-header-table.h" @@ -178,7 +176,6 @@ static GSList *all_composers = NULL; static GList *add_recipients (GList *list, const gchar *recips); static void handle_mailto (EMsgComposer *composer, const gchar *mailto); -static void handle_uri (EMsgComposer *composer, const gchar *uri, gboolean html_dnd); /* used by e_msg_composer_add_message_attachments () */ static void add_attachments_from_multipart (EMsgComposer *composer, CamelMultipart *multipart, @@ -510,7 +507,8 @@ build_message (EMsgComposer *composer, GtkhtmlEditor *editor; EMsgComposerPrivate *p = composer->priv; - EAttachmentBar *attachment_bar; + EAttachmentView *view; + EAttachmentStore *store; EComposerHeaderTable *table; GtkToggleAction *action; CamelDataWrapper *plain, *html, *current; @@ -538,7 +536,8 @@ build_message (EMsgComposer *composer, editor = GTKHTML_EDITOR (composer); table = e_msg_composer_get_header_table (composer); account = e_composer_header_table_get_account (table); - attachment_bar = E_ATTACHMENT_BAR (p->attachment_bar); + view = e_msg_composer_get_attachment_view (composer); + store = e_attachment_view_get_store (view); session = e_msg_composer_get_session (composer); /* evil kludgy hack for Redirect */ @@ -699,7 +698,7 @@ build_message (EMsgComposer *composer, } else current = plain; - if (e_attachment_bar_get_num_attachments (attachment_bar)) { + if (e_attachment_store_get_num_attachments (store) > 0) { CamelMultipart *multipart = camel_multipart_new (); if (p->is_alternative) { @@ -718,7 +717,8 @@ build_message (EMsgComposer *composer, camel_multipart_add_part (multipart, part); camel_object_unref (part); - e_attachment_bar_to_multipart (attachment_bar, multipart, p->charset); + e_attachment_store_add_to_multipart ( + store, multipart, p->charset); if (p->is_alternative) { for (i = camel_multipart_get_number (multipart); i > 1; i--) { @@ -1252,65 +1252,17 @@ autosave_load_draft (const gchar *filename) /* Miscellaneous callbacks. */ static void -attachment_bar_changed_cb (EAttachmentBar *attachment_bar, - EMsgComposer *composer) +attachment_store_changed_cb (EMsgComposer *composer) { GtkhtmlEditor *editor; - GtkWidget *widget; - guint attachment_num; - - editor = GTKHTML_EDITOR (composer); - attachment_num = e_attachment_bar_get_num_attachments (attachment_bar); - - if (attachment_num > 0) { - gchar *markup; - - markup = g_strdup_printf ( - "<b>%d</b> %s", attachment_num, ngettext ( - "Attachment", "Attachments", attachment_num)); - widget = composer->priv->attachment_expander_num; - gtk_label_set_markup (GTK_LABEL (widget), markup); - g_free (markup); - - gtk_widget_show (composer->priv->attachment_expander_icon); - - widget = composer->priv->attachment_expander; - gtk_expander_set_expanded (GTK_EXPANDER (widget), TRUE); - } else { - widget = composer->priv->attachment_expander_num; - gtk_label_set_text (GTK_LABEL (widget), ""); - - gtk_widget_hide (composer->priv->attachment_expander_icon); - - widget = composer->priv->attachment_expander; - gtk_expander_set_expanded (GTK_EXPANDER (widget), FALSE); - } /* Mark the editor as changed so it prompts about unsaved changes on close. */ + editor = GTKHTML_EDITOR (composer); gtkhtml_editor_set_changed (editor, TRUE); } static void -attachment_expander_notify_cb (GtkExpander *expander, - GParamSpec *pspec, - EMsgComposer *composer) -{ - GtkLabel *label; - const gchar *text; - - label = GTK_LABEL (composer->priv->attachment_expander_label); - - /* Update the expander label */ - if (gtk_expander_get_expanded (expander)) - text = _("Hide _Attachment Bar"); - else - text = _("Show _Attachment Bar"); - - gtk_label_set_text_with_mnemonic (label, text); -} - -static void msg_composer_subject_changed_cb (EMsgComposer *composer) { EComposerHeaderTable *table; @@ -1505,35 +1457,6 @@ msg_composer_account_list_changed_cb (EMsgComposer *composer) g_object_unref (iterator); } -static void -msg_composer_attach_message (EMsgComposer *composer, - CamelMimeMessage *msg) -{ - CamelMimePart *mime_part; - GString *description; - const gchar *subject; - EMsgComposerPrivate *p = composer->priv; - - mime_part = camel_mime_part_new (); - camel_mime_part_set_disposition (mime_part, "inline"); - subject = camel_mime_message_get_subject (msg); - - description = g_string_new (_("Attached message")); - if (subject != NULL) - g_string_append_printf (description, " - %s", subject); - camel_mime_part_set_description (mime_part, description->str); - g_string_free (description, TRUE); - - camel_medium_set_content_object ( - (CamelMedium *) mime_part, (CamelDataWrapper *) msg); - camel_mime_part_set_content_type (mime_part, "message/rfc822"); - - e_attachment_bar_attach_mime_part ( - E_ATTACHMENT_BAR (p->attachment_bar), mime_part); - - camel_object_unref (mime_part); -} - struct _drop_data { EMsgComposer *composer; @@ -1544,23 +1467,9 @@ struct _drop_data { guint32 action; guint info; guint time; - - unsigned int move:1; - unsigned int moved:1; - unsigned int aborted:1; }; -int -e_msg_composer_get_remote_download_count (EMsgComposer *composer) -{ - EAttachmentBar *attachment_bar; - - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), 0); - - attachment_bar = E_ATTACHMENT_BAR (composer->priv->attachment_bar); - return e_attachment_bar_get_download_count (attachment_bar); -} - +#if 0 /* KILL-BONOBO */ static void drop_action (EMsgComposer *composer, GdkDragContext *context, @@ -1570,77 +1479,12 @@ drop_action (EMsgComposer *composer, guint time, gboolean html_dnd) { - char *tmp, *str, **urls; CamelMimePart *mime_part; - CamelStream *stream; CamelMimeMessage *msg; - char *content_type; int i, success = FALSE, delete = FALSE; EMsgComposerPrivate *p = composer->priv; switch (info) { - case DND_TYPE_MESSAGE_RFC822: - d (printf ("dropping a message/rfc822\n")); - /* write the message (s) out to a CamelStream so we can use it */ - stream = camel_stream_mem_new (); - camel_stream_write (stream, (const gchar *)selection->data, selection->length); - camel_stream_reset (stream); - - msg = camel_mime_message_new (); - if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *)msg, stream) != -1) { - msg_composer_attach_message (composer, msg); - success = TRUE; - delete = action == GDK_ACTION_MOVE; - } - - camel_object_unref (msg); - camel_object_unref (stream); - break; - case DND_TYPE_NETSCAPE_URL: - d (printf ("dropping a _NETSCAPE_URL\n")); - tmp = g_strndup ((const gchar *) selection->data, selection->length); - urls = g_strsplit (tmp, "\n", 2); - g_free (tmp); - - /* _NETSCAPE_URL is represented as "URI\nTITLE" */ - handle_uri (composer, urls[0], html_dnd); - - g_strfreev (urls); - success = TRUE; - break; - case DND_TYPE_TEXT_URI_LIST: - d (printf ("dropping a text/uri-list\n")); - tmp = g_strndup ((const gchar *) selection->data, selection->length); - urls = g_strsplit (tmp, "\n", 0); - g_free (tmp); - - for (i = 0; urls[i] != NULL; i++) { - str = g_strstrip (urls[i]); - if (str[0] == '#' || str[0] == '\0') - continue; - - handle_uri (composer, str, html_dnd); - } - - g_strfreev (urls); - success = TRUE; - break; - case DND_TYPE_TEXT_VCARD: - case DND_TYPE_TEXT_CALENDAR: - content_type = gdk_atom_name (selection->type); - d (printf ("dropping a %s\n", content_type)); - - mime_part = camel_mime_part_new (); - camel_mime_part_set_content (mime_part, (const gchar *)selection->data, selection->length, content_type); - camel_mime_part_set_disposition (mime_part, "inline"); - - e_attachment_bar_attach_mime_part (E_ATTACHMENT_BAR (p->attachment_bar), mime_part); - - camel_object_unref (mime_part); - g_free (content_type); - - success = TRUE; - break; case DND_TYPE_X_UID_LIST: { GPtrArray *uids; char *inptr, *inend; @@ -1734,55 +1578,7 @@ drop_action (EMsgComposer *composer, gtk_drag_finish (context, success, delete, time); } - -static void -drop_popup_copy (EPopup *ep, EPopupItem *item, gpointer data) -{ - struct _drop_data *m = data; - - drop_action ( - m->composer, m->context, GDK_ACTION_COPY, - m->selection, m->info, m->time, FALSE); -} - -static void -drop_popup_move (EPopup *ep, EPopupItem *item, gpointer data) -{ - struct _drop_data *m = data; - - drop_action ( - m->composer, m->context, GDK_ACTION_MOVE, - m->selection, m->info, m->time, FALSE); -} - -static void -drop_popup_cancel (EPopup *ep, EPopupItem *item, gpointer data) -{ - struct _drop_data *m = data; - - gtk_drag_finish (m->context, FALSE, FALSE, m->time); -} - -static EPopupItem drop_popup_menu[] = { - { E_POPUP_ITEM, "00.emc.02", N_("_Copy"), drop_popup_copy, NULL, "mail-copy", 0 }, - { E_POPUP_ITEM, "00.emc.03", N_("_Move"), drop_popup_move, NULL, "mail-move", 0 }, - { E_POPUP_BAR, "10.emc" }, - { E_POPUP_ITEM, "99.emc.00", N_("Cancel _Drag"), drop_popup_cancel, NULL, NULL, 0 }, -}; - -static void -drop_popup_free (EPopup *ep, GSList *items, gpointer data) -{ - struct _drop_data *m = data; - - g_slist_free (items); - - g_object_unref (m->context); - g_object_unref (m->composer); - g_free (m->selection->data); - g_free (m->selection); - g_free (m); -} +#endif static void msg_composer_notify_header_cb (EMsgComposer *composer) @@ -2022,33 +1818,14 @@ msg_composer_drag_motion (GtkWidget *widget, gint y, guint time) { - GList *targets; - GdkDragAction actions = 0; - GdkDragAction chosen_action; - - targets = context->targets; - while (targets != NULL) { - gint ii; - - for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) - if (targets->data == (gpointer) drag_info[ii].atom) - actions |= drag_info[ii].actions; - - targets = g_list_next (targets); - } - - actions &= context->actions; - chosen_action = context->suggested_action; - - /* we default to copy */ - if (chosen_action == GDK_ACTION_ASK && - (actions & (GDK_ACTION_MOVE|GDK_ACTION_COPY)) != - (GDK_ACTION_MOVE|GDK_ACTION_COPY)) - chosen_action = GDK_ACTION_COPY; + EMsgComposer *composer; + EAttachmentView *view; - gdk_drag_status (context, chosen_action, time); + /* Widget may be EMsgComposer or GtkHTML. */ + composer = E_MSG_COMPOSER (gtk_widget_get_toplevel (widget)); + view = e_msg_composer_get_attachment_view (composer); - return (chosen_action != 0); + return e_attachment_view_drag_motion (view, context, x, y, time); } static void @@ -2061,46 +1838,14 @@ msg_composer_drag_data_received (GtkWidget *widget, guint time) { EMsgComposer *composer; + EAttachmentView *view; /* Widget may be EMsgComposer or GtkHTML. */ composer = E_MSG_COMPOSER (gtk_widget_get_toplevel (widget)); + view = e_msg_composer_get_attachment_view (composer); - if (selection->data == NULL) - return; - - if (selection->length == -1) - return; - - if (context->action == GDK_ACTION_ASK) { - EMPopup *emp; - GSList *menus = NULL; - GtkMenu *menu; - gint ii; - struct _drop_data *m; - - m = g_malloc0(sizeof (*m)); - m->context = g_object_ref (context); - m->composer = g_object_ref (composer); - m->action = context->action; - m->info = info; - m->time = time; - m->selection = g_malloc0(sizeof (*m->selection)); - m->selection->data = g_malloc (selection->length); - memcpy (m->selection->data, selection->data, selection->length); - m->selection->length = selection->length; - - emp = em_popup_new ("org.gnome.evolution.mail.composer.popup.drop"); - for (ii = 0; ii < G_N_ELEMENTS (drop_popup_menu); ii++) - menus = g_slist_append (menus, &drop_popup_menu[ii]); - - e_popup_add_items ((EPopup *)emp, menus, NULL, drop_popup_free, m); - menu = e_popup_create_menu_once ((EPopup *)emp, NULL, 0); - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, 0, time); - } else { - drop_action ( - composer, context, context->action, selection, - info, time, !GTK_WIDGET_TOPLEVEL (widget)); - } + e_attachment_view_drag_data_received ( + view, context, x, y, selection, info, time); } static void @@ -2147,11 +1892,21 @@ static void msg_composer_paste_clipboard (GtkhtmlEditor *editor) { EMsgComposer *composer; + EAttachmentView *view; + EAttachmentStore *store; + GtkClipboard *clipboard; + GdkPixbuf *pixbuf; GtkWidget *parent; GtkWidget *widget; - GtkClipboard *clipboard; + gchar *filename; + gchar *uri; + gint fd; + GError *error = NULL; composer = E_MSG_COMPOSER (editor); + view = e_msg_composer_get_attachment_view (composer); + store = e_attachment_view_get_store (view); + widget = gtk_window_get_focus (GTK_WINDOW (editor)); parent = gtk_widget_get_parent (widget); @@ -2161,36 +1916,61 @@ msg_composer_paste_clipboard (GtkhtmlEditor *editor) } clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD); - if (clipboard && gtk_clipboard_wait_is_image_available (clipboard)) { - GdkPixbuf *pixbuf; - - pixbuf = gtk_clipboard_wait_for_image (clipboard); - if (pixbuf) { - char *tmpl = g_strconcat (_("Image"), "-XXXXXX", NULL); - char *filename = e_mktemp (tmpl); - - g_free (tmpl); - - if (filename && gdk_pixbuf_save (pixbuf, filename, "png", NULL, NULL)) { - if (gtkhtml_editor_get_html_mode (editor)) { - char *uri = g_strconcat ("file://", filename, NULL); - /* this loads image async, thus cannot remove file from this */ - gtkhtml_editor_insert_image (editor, uri); - g_free (uri); - } else { - /* this loads image immediately, remove file from cache to free up disk space */ - e_attachment_bar_attach (E_ATTACHMENT_BAR (composer->priv->attachment_bar), filename, "image/png"); - g_remove (filename); - } - } - g_free (filename); - g_object_unref (pixbuf); - } - } else { - /* Chain up to parent's paste_clipboard() method. */ - GTKHTML_EDITOR_CLASS (parent_class)->paste_clipboard (editor); + /* Assume the clipboard has an image. The return + * value will be NULL if we assumed wrong. */ + pixbuf = gtk_clipboard_wait_for_image (clipboard); + if (!GDK_IS_PIXBUF (pixbuf)) + goto chainup; + + /* Reserve a temporary file. */ + fd = e_file_open_tmp (&filename, &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_object_unref (pixbuf); + g_error_free (error); + return; } + close (fd); + + /* Save the pixbuf as a temporary file in image/png format. */ + if (!gdk_pixbuf_save (pixbuf, filename, "png", &error, NULL)) { + g_warning ("%s", error->message); + g_object_unref (pixbuf); + g_error_free (error); + g_free (filename); + return; + } + + /* Convert the filename to a URI. */ + uri = g_filename_to_uri (filename, NULL, &error); + if (error != NULL) { + g_warning ("%s", error->message); + g_object_unref (pixbuf); + g_error_free (error); + g_free (filename); + return; + } + + if (gtkhtml_editor_get_html_mode (editor)) + gtkhtml_editor_insert_image (editor, uri); + else { + EAttachment *attachment; + + attachment = e_attachment_new_for_uri (uri); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); + } + + g_object_unref (pixbuf); + g_free (filename); + g_free (uri); + + return; + +chainup: + /* Chain up to parent's paste_clipboard() method. */ + GTKHTML_EDITOR_CLASS (parent_class)->paste_clipboard (editor); } static void @@ -2479,6 +2259,8 @@ msg_composer_class_init (EMsgComposerClass *class) static void msg_composer_init (EMsgComposer *composer) { + EAttachmentView *view; + EAttachmentStore *store; EComposerHeaderTable *table; GtkUIManager *manager; GtkhtmlEditor *editor; @@ -2505,27 +2287,6 @@ msg_composer_init (EMsgComposer *composer) drop_types, G_N_ELEMENTS (drop_types), GDK_ACTION_COPY | GDK_ACTION_ASK | GDK_ACTION_MOVE); - /* XXX I'm not sure why we have to explicitly configure the - * attachment bar as a drag destination when CompEditor - * doesn't and previous Evolution releases (2.22 and - * prior) don't, but this is the only way I could figure - * out how to get drag-and-drop to the attachment bar - * working again. I'm probably overlooking something - * simple... */ - - gtk_drag_dest_set ( - composer->priv->attachment_bar, GTK_DEST_DEFAULT_ALL, - drop_types, G_N_ELEMENTS (drop_types), - GDK_ACTION_COPY | GDK_ACTION_ASK | GDK_ACTION_MOVE); - - g_signal_connect ( - composer->priv->attachment_bar, "drag-motion", - G_CALLBACK (msg_composer_drag_motion), NULL); - - g_signal_connect ( - composer->priv->attachment_bar, "drag-data-received", - G_CALLBACK (msg_composer_drag_data_received), NULL); - g_signal_connect ( html, "drag-data-received", G_CALLBACK (msg_composer_drag_data_received), NULL); @@ -2568,14 +2329,18 @@ msg_composer_init (EMsgComposer *composer) msg_composer_account_changed_cb (composer); msg_composer_account_list_changed_cb (composer); - /* Attachment Bar */ + /* Attachments */ - g_signal_connect ( - composer->priv->attachment_bar, "changed", - G_CALLBACK (attachment_bar_changed_cb), composer); - g_signal_connect_after ( - composer->priv->attachment_expander, "notify::expanded", - G_CALLBACK (attachment_expander_notify_cb), composer); + view = e_msg_composer_get_attachment_view (composer); + store = e_attachment_view_get_store (view); + + g_signal_connect_swapped ( + store, "row-deleted", + G_CALLBACK (attachment_store_changed_cb), composer); + + g_signal_connect_swapped ( + store, "row-inserted", + G_CALLBACK (attachment_store_changed_cb), composer); e_composer_autosave_register (composer); @@ -3445,7 +3210,7 @@ disable_editor (EMsgComposer *composer) action = GTKHTML_EDITOR_ACTION_INSERT_MENU (composer); gtk_action_set_sensitive (action, FALSE); - gtk_widget_set_sensitive (composer->priv->attachment_bar, FALSE); + gtk_widget_set_sensitive (composer->priv->attachment_paned, FALSE); } /** @@ -3589,7 +3354,8 @@ add_recipients (GList *list, const gchar *recips) static void handle_mailto (EMsgComposer *composer, const gchar *mailto) { - EMsgComposerPrivate *priv = composer->priv; + EAttachmentView *view; + EAttachmentStore *store; EComposerHeaderTable *table; GList *to = NULL, *cc = NULL, *bcc = NULL; EDestination **tov, **ccv, **bccv; @@ -3598,9 +3364,10 @@ handle_mailto (EMsgComposer *composer, const gchar *mailto) gsize nread, nwritten; const gchar *p; gint len, clen; - CamelURL *url; table = e_msg_composer_get_header_table (composer); + view = e_msg_composer_get_attachment_view (composer); + store = e_attachment_view_get_store (view); buf = g_strdup (mailto); @@ -3672,20 +3439,11 @@ handle_mailto (EMsgComposer *composer, const gchar *mailto) } } else if (!g_ascii_strcasecmp (header, "attach") || !g_ascii_strcasecmp (header, "attachment")) { - /* Change file url to absolute path */ - if (!g_ascii_strncasecmp (content, "file:", 5)) { - url = camel_url_new (content, NULL); - e_attachment_bar_attach (E_ATTACHMENT_BAR (priv->attachment_bar), - url->path, - "attachment"); - camel_url_free (url); - } else { - e_attachment_bar_attach (E_ATTACHMENT_BAR (priv->attachment_bar), - content, - "attachment"); - } - gtk_widget_show (priv->attachment_expander); - gtk_widget_show (priv->attachment_scrolled_window); + EAttachment *attachment; + + attachment = e_attachment_new_for_uri (content); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); } else if (!g_ascii_strcasecmp (header, "from")) { /* Ignore */ } else if (!g_ascii_strcasecmp (header, "reply-to")) { @@ -3737,45 +3495,6 @@ handle_mailto (EMsgComposer *composer, const gchar *mailto) } } -static void -handle_uri (EMsgComposer *composer, - const gchar *uri, - gboolean html_dnd) -{ - EMsgComposerPrivate *p = composer->priv; - GtkhtmlEditor *editor; - gboolean html_content; - - editor = GTKHTML_EDITOR (composer); - html_content = gtkhtml_editor_get_html_mode (editor); - - if (!g_ascii_strncasecmp (uri, "mailto:", 7)) { - handle_mailto (composer, uri); - } else { - CamelURL *url = camel_url_new (uri, NULL); - gchar *type; - - if (!url) - return; - - if (!g_ascii_strcasecmp (url->protocol, "file")) { - type = e_util_guess_mime_type (uri + strlen ("file://"), TRUE); - if (!type) - return; - - if (strncmp (type, "image", 5) || !html_dnd || (!html_content && !strncmp (type, "image", 5))) { - e_attachment_bar_attach (E_ATTACHMENT_BAR (p->attachment_bar), - url->path, "attachment"); - } - g_free (type); - } else { - e_attachment_bar_attach_remote_file (E_ATTACHMENT_BAR (p->attachment_bar), - uri, "attachment"); - } - camel_url_free (url); - } -} - /** * e_msg_composer_new_from_url: * @url: a mailto URL @@ -3939,21 +3658,28 @@ e_msg_composer_remove_header (EMsgComposer *composer, /** * e_msg_composer_attach: * @composer: a composer object - * @attachment: the CamelMimePart to attach + * @mime_part: the #CamelMimePart to attach * * Attaches @attachment to the message being composed in the composer. **/ void -e_msg_composer_attach (EMsgComposer *composer, CamelMimePart *attachment) +e_msg_composer_attach (EMsgComposer *composer, + CamelMimePart *mime_part) { - EAttachmentBar *bar; - EMsgComposerPrivate *p = composer->priv; + EAttachmentView *view; + EAttachmentStore *store; + EAttachment *attachment; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - g_return_if_fail (CAMEL_IS_MIME_PART (attachment)); + g_return_if_fail (CAMEL_IS_MIME_PART (mime_part)); + + view = e_msg_composer_get_attachment_view (composer); + store = e_attachment_view_get_store (view); - bar = E_ATTACHMENT_BAR (p->attachment_bar); - e_attachment_bar_attach_mime_part (bar, attachment); + attachment = e_attachment_new (); + e_attachment_set_mime_part (attachment, mime_part); + e_attachment_store_add_attachment (store, attachment); + g_object_unref (attachment); } /** @@ -4067,12 +3793,17 @@ CamelMimeMessage * e_msg_composer_get_message (EMsgComposer *composer, gboolean save_html_object_data) { + EAttachmentView *view; + EAttachmentStore *store; GtkhtmlEditor *editor; gboolean html_content; g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); - if (e_msg_composer_get_remote_download_count (composer) != 0) { + 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 (!em_utils_prompt_user (GTK_WINDOW (composer), NULL, "mail-composer:ask-send-message-pending-download", NULL)) { return NULL; @@ -4367,14 +4098,6 @@ e_msg_composer_get_raw_message_text (EMsgComposer *composer) return array; } -EAttachmentBar * -e_msg_composer_get_attachment_bar (EMsgComposer *composer) -{ - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); - - return E_ATTACHMENT_BAR (composer->priv->attachment_bar); -} - void e_msg_composer_set_enable_autosave (EMsgComposer *composer, gboolean enabled) @@ -4529,6 +4252,18 @@ e_msg_composer_get_header_table (EMsgComposer *composer) return E_COMPOSER_HEADER_TABLE (composer->priv->header_table); } +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); +} + void e_msg_composer_set_send_options (EMsgComposer *composer, gboolean send_enable) diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h index 7e0851fb52..42f12bf973 100644 --- a/composer/e-msg-composer.h +++ b/composer/e-msg-composer.h @@ -29,6 +29,7 @@ #include <libedataserver/e-account.h> #include <libebook/e-destination.h> #include <gtkhtml-editor.h> +#include <widgets/misc/e-attachment-view.h> #include "e-composer-header-table.h" @@ -66,8 +67,6 @@ struct _EMsgComposerClass { GtkhtmlEditorClass parent_class; }; -struct _EAttachmentBar; - #define E_MSG_COMPOSER_MAIL 1 #define E_MSG_COMPOSER_POST 2 #define E_MSG_COMPOSER_MAIL_POST E_MSG_COMPOSER_MAIL|E_MSG_COMPOSER_POST @@ -104,7 +103,7 @@ void e_msg_composer_modify_header (EMsgComposer *composer, void e_msg_composer_remove_header (EMsgComposer *composer, const gchar *name); void e_msg_composer_attach (EMsgComposer *composer, - CamelMimePart *attachment); + CamelMimePart *mime_part); CamelMimePart * e_msg_composer_add_inline_image_from_file (EMsgComposer *composer, const gchar *filename); @@ -140,22 +139,19 @@ void e_msg_composer_add_message_attachments gboolean e_msg_composer_request_close_all(void); EMsgComposer * e_msg_composer_load_from_file (const gchar *filename); void e_msg_composer_check_autosave (GtkWindow *parent); -gint e_msg_composer_get_remote_download_count - (EMsgComposer *composer); void e_msg_composer_reply_indent (EMsgComposer *composer); EComposerHeaderTable * e_msg_composer_get_header_table (EMsgComposer *composer); +EAttachmentView * + e_msg_composer_get_attachment_view + (EMsgComposer *composer); void e_msg_composer_set_send_options (EMsgComposer *composer, gboolean send_enable); GByteArray * e_msg_composer_get_raw_message_text (EMsgComposer *composer); -struct _EAttachmentBar * - e_msg_composer_get_attachment_bar - (EMsgComposer *composer); - gboolean e_msg_composer_is_exiting (EMsgComposer *composer); GList * e_load_spell_languages (void); |