diff options
-rw-r--r-- | composer/e-composer-actions.c | 132 | ||||
-rw-r--r-- | composer/e-composer-actions.h | 6 | ||||
-rw-r--r-- | composer/e-composer-header-table.c | 547 | ||||
-rw-r--r-- | composer/e-composer-header-table.h | 14 | ||||
-rw-r--r-- | composer/e-composer-header.c | 30 | ||||
-rw-r--r-- | composer/e-composer-header.h | 2 | ||||
-rw-r--r-- | composer/e-composer-private.c | 41 | ||||
-rw-r--r-- | composer/e-composer-private.h | 11 | ||||
-rw-r--r-- | composer/e-msg-composer.c | 177 | ||||
-rw-r--r-- | composer/e-msg-composer.h | 5 | ||||
-rw-r--r-- | composer/evolution-composer.ui | 7 | ||||
-rw-r--r-- | mail/em-composer-utils.c | 220 | ||||
-rw-r--r-- | mail/em-composer-utils.h | 4 | ||||
-rw-r--r-- | mail/em-folder-browser.c | 9 | ||||
-rw-r--r-- | mail/em-folder-view.c | 16 | ||||
-rw-r--r-- | mail/evolution-mail.schemas.in | 62 | ||||
-rw-r--r-- | ui/evolution-mail-message.xml | 9 |
17 files changed, 511 insertions, 781 deletions
diff --git a/composer/e-composer-actions.c b/composer/e-composer-actions.c index 56ec7c5db1..247ac7794f 100644 --- a/composer/e-composer-actions.c +++ b/composer/e-composer-actions.c @@ -308,104 +308,6 @@ action_smime_sign_cb (GtkToggleAction *action, gtkhtml_editor_set_changed (editor, TRUE); } -static void -action_view_bcc_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_BCC, active); -} - -static void -action_view_cc_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_CC, active); -} - -static void -action_view_from_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_FROM, active); -} - -static void -action_view_post_to_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_POST_TO, active); -} - -static void -action_view_reply_to_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_REPLY_TO, active); -} - -static void -action_view_subject_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_SUBJECT, active); -} - -static void -action_view_to_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EComposerHeaderTable *table; - gboolean active; - - table = e_msg_composer_get_header_table (composer); - active = gtk_toggle_action_get_active (action); - - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_TO, active); -} - static GtkActionEntry entries[] = { { "attach", @@ -542,7 +444,7 @@ static GtkToggleActionEntry toggle_entries[] = { N_("S/MIME Sig_n"), NULL, N_("Sign this message with your S/MIME Signature Certificate"), - G_CALLBACK (action_smime_sign_cb), + NULL, /* Handled by property bindings */ FALSE }, { "view-bcc", @@ -550,7 +452,7 @@ static GtkToggleActionEntry toggle_entries[] = { N_("_Bcc Field"), NULL, N_("Toggles whether the BCC field is displayed"), - G_CALLBACK (action_view_bcc_cb), + NULL, /* Handled by property bindings */ FALSE }, { "view-cc", @@ -558,7 +460,7 @@ static GtkToggleActionEntry toggle_entries[] = { N_("_Cc Field"), NULL, N_("Toggles whether the CC field is displayed"), - G_CALLBACK (action_view_cc_cb), + NULL, /* Handled by property bindings */ FALSE }, { "view-from", @@ -566,15 +468,7 @@ static GtkToggleActionEntry toggle_entries[] = { N_("_From Field"), NULL, N_("Toggles whether the From chooser is displayed"), - G_CALLBACK (action_view_from_cb), - FALSE }, - - { "view-post-to", - NULL, - N_("_Post-To Field"), - NULL, - N_("Toggles whether the Post-To field is displayed"), - G_CALLBACK (action_view_post_to_cb), + NULL, /* Handled by property bindings */ FALSE }, { "view-reply-to", @@ -582,24 +476,8 @@ static GtkToggleActionEntry toggle_entries[] = { N_("_Reply-To Field"), NULL, N_("Toggles whether the Reply-To field is displayed"), - G_CALLBACK (action_view_reply_to_cb), + NULL, /* Handled by property bindings */ FALSE }, - - { "view-subject", - NULL, - N_("_Subject Field"), - NULL, - N_("Toggles whether the Subject field is displayed"), - G_CALLBACK (action_view_subject_cb), - FALSE }, - - { "view-to", - NULL, - N_("_To Field"), - NULL, - N_("Toggles whether the To field is displayed"), - G_CALLBACK (action_view_to_cb), - FALSE } }; void diff --git a/composer/e-composer-actions.h b/composer/e-composer-actions.h index c17f3ebc32..da3e470d81 100644 --- a/composer/e-composer-actions.h +++ b/composer/e-composer-actions.h @@ -61,13 +61,7 @@ E_COMPOSER_ACTION ((composer), "view-cc") #define E_COMPOSER_ACTION_VIEW_FROM(composer) \ E_COMPOSER_ACTION ((composer), "view-from") -#define E_COMPOSER_ACTION_VIEW_POST_TO(composer) \ - E_COMPOSER_ACTION ((composer), "view-post-to") #define E_COMPOSER_ACTION_VIEW_REPLY_TO(composer) \ E_COMPOSER_ACTION ((composer), "view-reply-to") -#define E_COMPOSER_ACTION_VIEW_SUBJECT(composer) \ - E_COMPOSER_ACTION ((composer), "view-subject") -#define E_COMPOSER_ACTION_VIEW_TO(composer) \ - E_COMPOSER_ACTION ((composer), "view-to") #endif /* E_COMPOSER_ACTIONS_H */ diff --git a/composer/e-composer-header-table.c b/composer/e-composer-header-table.c index d539565ad2..267bfbf1e7 100644 --- a/composer/e-composer-header-table.c +++ b/composer/e-composer-header-table.c @@ -22,7 +22,9 @@ #include <camel/camel-internet-address.h> #include <libedataserverui/e-name-selector.h> -#include "e-signature-combo-box.h" +#include "e-util/e-binding.h" +#include "e-util/gconf-bridge.h" +#include "widgets/misc/e-signature-combo-box.h" #include "e-composer-from-header.h" #include "e-composer-name-header.h" @@ -33,34 +35,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_COMPOSER_HEADER_TABLE, EComposerHeaderTablePrivate)) -#define E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER(table) \ - (E_COMPOSER_FROM_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_FROM))) - -#define E_COMPOSER_HEADER_TABLE_GET_REPLY_TO_HEADER(table) \ - (E_COMPOSER_TEXT_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_REPLY_TO))) - -#define E_COMPOSER_HEADER_TABLE_GET_TO_HEADER(table) \ - (E_COMPOSER_NAME_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_TO))) - -#define E_COMPOSER_HEADER_TABLE_GET_CC_HEADER(table) \ - (E_COMPOSER_NAME_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_CC))) - -#define E_COMPOSER_HEADER_TABLE_GET_BCC_HEADER(table) \ - (E_COMPOSER_NAME_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_BCC))) - -#define E_COMPOSER_HEADER_TABLE_GET_POST_TO_HEADER(table) \ - (E_COMPOSER_POST_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_POST_TO))) - -#define E_COMPOSER_HEADER_TABLE_GET_SUBJECT_HEADER(table) \ - (E_COMPOSER_TEXT_HEADER (e_composer_header_table_get_header \ - (E_COMPOSER_HEADER_TABLE (table), E_COMPOSER_HEADER_SUBJECT))) - #define HEADER_TOOLTIP_TO \ _("Enter the recipients of the message") #define HEADER_TOOLTIP_CC \ @@ -71,6 +45,8 @@ "carbon copy of the message without appearing " \ "in the recipient list of the message") +#define GCONF_KEY_PREFIX "/apps/evolution/mail/composer" + enum { PROP_0, PROP_ACCOUNT, @@ -88,6 +64,7 @@ enum { struct _EComposerHeaderTablePrivate { EComposerHeader *headers[E_COMPOSER_NUM_HEADERS]; + guint gconf_bindings[E_COMPOSER_NUM_HEADERS]; GtkWidget *signature_label; GtkWidget *signature_combo_box; ENameSelector *name_selector; @@ -296,26 +273,160 @@ skip_custom: } static void +composer_header_table_setup_mail_headers (EComposerHeaderTable *table) +{ + GConfBridge *bridge; + gint ii; + + bridge = gconf_bridge_get (); + + for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { + EComposerHeader *header; + const gchar *key; + guint binding_id; + + binding_id = table->priv->gconf_bindings[ii]; + header = e_composer_header_table_get_header (table, ii); + + if (binding_id > 0) + gconf_bridge_unbind (bridge, binding_id); + + switch (ii) { + case E_COMPOSER_HEADER_BCC: + key = GCONF_KEY_PREFIX "/show_mail_bcc"; + break; + + case E_COMPOSER_HEADER_CC: + key = GCONF_KEY_PREFIX "/show_mail_cc"; + break; + + case E_COMPOSER_HEADER_FROM: + key = GCONF_KEY_PREFIX "/show_mail_from"; + break; + + case E_COMPOSER_HEADER_REPLY_TO: + key = GCONF_KEY_PREFIX "/show_mail_reply_to"; + break; + + default: + key = NULL; + break; + } + + switch (ii) { + case E_COMPOSER_HEADER_BCC: + case E_COMPOSER_HEADER_CC: + case E_COMPOSER_HEADER_FROM: + case E_COMPOSER_HEADER_REPLY_TO: + case E_COMPOSER_HEADER_SUBJECT: + case E_COMPOSER_HEADER_TO: + e_composer_header_set_sensitive (header, TRUE); + e_composer_header_set_visible (header, TRUE); + break; + + default: + e_composer_header_set_sensitive (header, FALSE); + e_composer_header_set_visible (header, FALSE); + break; + } + + if (key != NULL) + binding_id = gconf_bridge_bind_property ( + bridge, key, G_OBJECT (header), "visible"); + else + binding_id = 0; + + table->priv->gconf_bindings[ii] = binding_id; + } +} + +static void +composer_header_table_setup_post_headers (EComposerHeaderTable *table) +{ + GConfBridge *bridge; + gint ii; + + bridge = gconf_bridge_get (); + + for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { + EComposerHeader *header; + const gchar *key; + guint binding_id; + + binding_id = table->priv->gconf_bindings[ii]; + header = e_composer_header_table_get_header (table, ii); + + if (binding_id > 0) + gconf_bridge_unbind (bridge, binding_id); + + switch (ii) { + case E_COMPOSER_HEADER_FROM: + key = GCONF_KEY_PREFIX "/show_post_from"; + break; + + case E_COMPOSER_HEADER_REPLY_TO: + key = GCONF_KEY_PREFIX "/show_post_reply_to"; + break; + + default: + key = NULL; + break; + } + + switch (ii) { + case E_COMPOSER_HEADER_FROM: + case E_COMPOSER_HEADER_POST_TO: + case E_COMPOSER_HEADER_REPLY_TO: + case E_COMPOSER_HEADER_SUBJECT: + e_composer_header_set_sensitive (header, TRUE); + e_composer_header_set_visible (header, TRUE); + break; + + default: /* this includes TO, CC and BCC */ + e_composer_header_set_sensitive (header, FALSE); + e_composer_header_set_visible (header, FALSE); + break; + } + + if (key != NULL) + binding_id = gconf_bridge_bind_property ( + bridge, key, G_OBJECT (header), "visible"); + else + binding_id = 0; + + table->priv->gconf_bindings[ii] = binding_id; + } +} + +static void composer_header_table_from_changed_cb (EComposerHeaderTable *table) { EAccount *account; + EComposerHeader *header; + EComposerHeaderType type; EComposerPostHeader *post_header; EComposerTextHeader *text_header; EDestination **old_destinations; EDestination **new_destinations; const gchar *reply_to; + const gchar *source_url; gboolean always_cc; gboolean always_bcc; /* Keep "Post-To" and "Reply-To" synchronized with "From" */ account = e_composer_header_table_get_account (table); + source_url = e_account_get_string (account, E_ACCOUNT_SOURCE_URL); - post_header = E_COMPOSER_HEADER_TABLE_GET_POST_TO_HEADER (table); + type = E_COMPOSER_HEADER_POST_TO; + header = e_composer_header_table_get_header (table, type); + post_header = E_COMPOSER_POST_HEADER (header); e_composer_post_header_set_account (post_header, account); + type = E_COMPOSER_HEADER_REPLY_TO; + header = e_composer_header_table_get_header (table, type); reply_to = (account != NULL) ? account->id->reply_to : NULL; - text_header = E_COMPOSER_HEADER_TABLE_GET_REPLY_TO_HEADER (table); + text_header = E_COMPOSER_TEXT_HEADER (header); e_composer_text_header_set_text (text_header, reply_to); always_cc = (account != NULL && account->always_cc); @@ -338,6 +449,27 @@ composer_header_table_from_changed_cb (EComposerHeaderTable *table) old_destinations, always_bcc ? account->bcc_addrs : NULL); e_composer_header_table_set_destinations_bcc (table, new_destinations); e_destination_freev (new_destinations); + + /* XXX We should NOT be checking specific account types here. + * Would prefer EAccount have a "send_method" enum item: + * + * E_ACCOUNT_SEND_METHOD_MAIL + * E_ACCOUNT_SEND_METHOD_POST + * + * And that would dictate which set of headers we show + * in the composer when an account is selected. Alas, + * EAccount has no private storage, so it would require + * an ABI break and I don't want to deal with that now. + * (But would anything besides Evolution be affected?) + * + * Currently only NNTP accounts use the "POST" fields. + */ + if (source_url == NULL) + composer_header_table_setup_mail_headers (table); + else if (g_ascii_strncasecmp (source_url, "nntp:", 5) == 0) + composer_header_table_setup_post_headers (table); + else + composer_header_table_setup_mail_headers (table); } static GObject * @@ -380,6 +512,14 @@ composer_header_table_constructor (GType type, priv->headers[ii]->input_widget, "right-attach", 2, NULL); + e_binding_new ( + G_OBJECT (priv->headers[ii]->input_widget), "visible", + G_OBJECT (priv->signature_label), "visible"); + + e_binding_new ( + G_OBJECT (priv->headers[ii]->input_widget), "visible", + G_OBJECT (priv->signature_combo_box), "visible"); + /* Now add the signature stuff. */ gtk_table_attach ( GTK_TABLE (object), priv->signature_label, @@ -686,6 +826,24 @@ composer_header_table_class_init (EComposerHeaderTableClass *class) element_spec, G_PARAM_READWRITE)); + /* floating reference */ + element_spec = g_param_spec_string ( + "value-array-element", + NULL, + NULL, + NULL, + G_PARAM_READWRITE); + + g_object_class_install_property ( + object_class, + PROP_POST_TO, + g_param_spec_value_array ( + "post-to", + NULL, + NULL, + element_spec, + G_PARAM_READWRITE)); + g_object_class_install_property ( object_class, PROP_REPLY_TO, @@ -733,6 +891,7 @@ composer_header_table_init (EComposerHeaderTable *table) EComposerHeader *header; ENameSelector *name_selector; GtkWidget *widget; + gint ii; table->priv = E_COMPOSER_HEADER_TABLE_GET_PRIVATE (table); @@ -784,6 +943,22 @@ composer_header_table_init (EComposerHeaderTable *table) gtk_label_set_mnemonic_widget ( GTK_LABEL (widget), table->priv->signature_combo_box); table->priv->signature_label = g_object_ref_sink (widget); + + /* XXX EComposerHeader ought to do this itself, but I need to + * make the title_widget and input_widget members private. */ + for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { + GObject *src_object; + GObject *dst_object; + + header = table->priv->headers[ii]; + src_object = G_OBJECT (header); + + dst_object = G_OBJECT (header->title_widget); + e_binding_new (src_object, "visible", dst_object, "visible"); + + dst_object = G_OBJECT (header->input_widget); + e_binding_new (src_object, "visible", dst_object, "visible"); + } } GType @@ -829,126 +1004,103 @@ e_composer_header_table_get_header (EComposerHeaderTable *table, return table->priv->headers[type]; } -gboolean -e_composer_header_table_get_header_visible (EComposerHeaderTable *table, - EComposerHeaderType type) -{ - EComposerHeader *header; - - header = e_composer_header_table_get_header (table, type); - return e_composer_header_get_visible (header); -} - -void -e_composer_header_table_set_header_visible (EComposerHeaderTable *table, - EComposerHeaderType type, - gboolean visible) -{ - EComposerHeader *header; - - header = e_composer_header_table_get_header (table, type); - e_composer_header_set_visible (header, visible); - - /* Signature widgets track the "From" header. */ - if (type == E_COMPOSER_HEADER_FROM) { - if (visible) { - gtk_widget_show (table->priv->signature_label); - gtk_widget_show (table->priv->signature_combo_box); - } else { - gtk_widget_hide (table->priv->signature_label); - gtk_widget_hide (table->priv->signature_combo_box); - } - } -} - -gboolean -e_composer_header_table_get_header_sensitive (EComposerHeaderTable *table, - EComposerHeaderType type) -{ - EComposerHeader *header; - - header = e_composer_header_table_get_header (table, type); - return e_composer_header_get_sensitive (header); -} - -void -e_composer_header_table_set_header_sensitive (EComposerHeaderTable *table, - EComposerHeaderType type, - gboolean sensitive) -{ - EComposerHeader *header; - - header = e_composer_header_table_get_header (table, type); - e_composer_header_set_sensitive (header, sensitive); -} - EAccount * e_composer_header_table_get_account (EComposerHeaderTable *table) { - EComposerFromHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerFromHeader *from_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER (table); - return e_composer_from_header_get_active (header); + type = E_COMPOSER_HEADER_FROM; + header = e_composer_header_table_get_header (table, type); + from_header = E_COMPOSER_FROM_HEADER (header); + + return e_composer_from_header_get_active (from_header); } gboolean e_composer_header_table_set_account (EComposerHeaderTable *table, EAccount *account) { - EComposerFromHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerFromHeader *from_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), FALSE); - header = E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER (table); - return e_composer_from_header_set_active (header, account); + type = E_COMPOSER_HEADER_FROM; + header = e_composer_header_table_get_header (table, type); + from_header = E_COMPOSER_FROM_HEADER (header); + + return e_composer_from_header_set_active (from_header, account); } EAccountList * e_composer_header_table_get_account_list (EComposerHeaderTable *table) { - EComposerFromHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerFromHeader *from_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER (table); - return e_composer_from_header_get_account_list (header); + type = E_COMPOSER_HEADER_FROM; + header = e_composer_header_table_get_header (table, type); + from_header = E_COMPOSER_FROM_HEADER (header); + + return e_composer_from_header_get_account_list (from_header); } void e_composer_header_table_set_account_list (EComposerHeaderTable *table, EAccountList *account_list) { - EComposerFromHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerFromHeader *from_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER (table); - e_composer_from_header_set_account_list (header, account_list); + type = E_COMPOSER_HEADER_FROM; + header = e_composer_header_table_get_header (table, type); + from_header = E_COMPOSER_FROM_HEADER (header); + + e_composer_from_header_set_account_list (from_header, account_list); } const gchar * e_composer_header_table_get_account_name (EComposerHeaderTable *table) { - EComposerFromHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerFromHeader *from_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER (table); - return e_composer_from_header_get_active_name (header); + type = E_COMPOSER_HEADER_FROM; + header = e_composer_header_table_get_header (table, type); + from_header = E_COMPOSER_FROM_HEADER (header); + + return e_composer_from_header_get_active_name (from_header); } gboolean e_composer_header_table_set_account_name (EComposerHeaderTable *table, const gchar *account_name) { - EComposerFromHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerFromHeader *from_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), FALSE); - header = E_COMPOSER_HEADER_TABLE_GET_FROM_HEADER (table); - return e_composer_from_header_set_active_name (header, account_name); + type = E_COMPOSER_HEADER_FROM; + header = e_composer_header_table_get_header (table, type); + from_header = E_COMPOSER_FROM_HEADER (header); + + return e_composer_from_header_set_active_name (from_header, account_name); } EDestination ** @@ -994,133 +1146,179 @@ e_composer_header_table_get_destinations (EComposerHeaderTable *table) EDestination ** e_composer_header_table_get_destinations_bcc (EComposerHeaderTable *table) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_BCC_HEADER (table); - return e_composer_name_header_get_destinations (header); + type = E_COMPOSER_HEADER_BCC; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + return e_composer_name_header_get_destinations (name_header); } void e_composer_header_table_add_destinations_bcc (EComposerHeaderTable *table, EDestination **destinations) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_BCC_HEADER (table); - e_composer_name_header_add_destinations (header, destinations); + type = E_COMPOSER_HEADER_BCC; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + e_composer_name_header_add_destinations (name_header, destinations); if (destinations != NULL && *destinations != NULL) - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_BCC, TRUE); + e_composer_header_set_visible (header, TRUE); } void e_composer_header_table_set_destinations_bcc (EComposerHeaderTable *table, EDestination **destinations) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_BCC_HEADER (table); - e_composer_name_header_set_destinations (header, destinations); + type = E_COMPOSER_HEADER_BCC; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + e_composer_name_header_set_destinations (name_header, destinations); if (destinations != NULL && *destinations != NULL) - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_BCC, TRUE); + e_composer_header_set_visible (header, TRUE); } EDestination ** e_composer_header_table_get_destinations_cc (EComposerHeaderTable *table) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_CC_HEADER (table); - return e_composer_name_header_get_destinations (header); + type = E_COMPOSER_HEADER_CC; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + return e_composer_name_header_get_destinations (name_header); } void e_composer_header_table_add_destinations_cc (EComposerHeaderTable *table, EDestination **destinations) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_CC_HEADER (table); - e_composer_name_header_add_destinations (header, destinations); + type = E_COMPOSER_HEADER_CC; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + e_composer_name_header_add_destinations (name_header, destinations); if (destinations != NULL && *destinations != NULL) - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_CC, TRUE); + e_composer_header_set_visible (header, TRUE); } void e_composer_header_table_set_destinations_cc (EComposerHeaderTable *table, EDestination **destinations) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_CC_HEADER (table); - e_composer_name_header_set_destinations (header, destinations); + type = E_COMPOSER_HEADER_CC; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + e_composer_name_header_set_destinations (name_header, destinations); if (destinations != NULL && *destinations != NULL) - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_CC, TRUE); + e_composer_header_set_visible (header, TRUE); } EDestination ** e_composer_header_table_get_destinations_to (EComposerHeaderTable *table) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_TO_HEADER (table); - return e_composer_name_header_get_destinations (header); + type = E_COMPOSER_HEADER_TO; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + return e_composer_name_header_get_destinations (name_header); } void e_composer_header_table_add_destinations_to (EComposerHeaderTable *table, EDestination **destinations) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_TO_HEADER (table); - e_composer_name_header_add_destinations (header, destinations); + type = E_COMPOSER_HEADER_TO; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + e_composer_name_header_add_destinations (name_header, destinations); } void e_composer_header_table_set_destinations_to (EComposerHeaderTable *table, EDestination **destinations) { - EComposerNameHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerNameHeader *name_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_TO_HEADER (table); - e_composer_name_header_set_destinations (header, destinations); + type = E_COMPOSER_HEADER_TO; + header = e_composer_header_table_get_header (table, type); + name_header = E_COMPOSER_NAME_HEADER (header); + + e_composer_name_header_set_destinations (name_header, destinations); } GList * e_composer_header_table_get_post_to (EComposerHeaderTable *table) { - EComposerPostHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerPostHeader *post_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_POST_TO_HEADER (table); - return e_composer_post_header_get_folders (header); + type = E_COMPOSER_HEADER_POST_TO; + header = e_composer_header_table_get_header (table, type); + post_header = E_COMPOSER_POST_HEADER (header); + + return e_composer_post_header_get_folders (post_header); } void @@ -1128,51 +1326,70 @@ e_composer_header_table_set_post_to_base (EComposerHeaderTable *table, const gchar *base_url, const gchar *folders) { - EComposerPostHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerPostHeader *post_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_POST_TO_HEADER (table); - e_composer_post_header_set_folders_base (header, base_url, folders); + type = E_COMPOSER_HEADER_POST_TO; + header = e_composer_header_table_get_header (table, type); + post_header = E_COMPOSER_POST_HEADER (header); + + e_composer_post_header_set_folders_base (post_header, base_url, folders); } void e_composer_header_table_set_post_to_list (EComposerHeaderTable *table, GList *folders) { - EComposerPostHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerPostHeader *post_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_POST_TO_HEADER (table); - e_composer_post_header_set_folders (header, folders); + type = E_COMPOSER_HEADER_POST_TO; + header = e_composer_header_table_get_header (table, type); + post_header = E_COMPOSER_POST_HEADER (header); + + e_composer_post_header_set_folders (post_header, folders); } const gchar * e_composer_header_table_get_reply_to (EComposerHeaderTable *table) { - EComposerTextHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerTextHeader *text_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_REPLY_TO_HEADER (table); - return e_composer_text_header_get_text (header); + type = E_COMPOSER_HEADER_REPLY_TO; + header = e_composer_header_table_get_header (table, type); + text_header = E_COMPOSER_TEXT_HEADER (header); + + return e_composer_text_header_get_text (text_header); } void e_composer_header_table_set_reply_to (EComposerHeaderTable *table, const gchar *reply_to) { - EComposerTextHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerTextHeader *text_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_REPLY_TO_HEADER (table); - e_composer_text_header_set_text (header, reply_to); + type = E_COMPOSER_HEADER_REPLY_TO; + header = e_composer_header_table_get_header (table, type); + text_header = E_COMPOSER_TEXT_HEADER (header); + + e_composer_text_header_set_text (text_header, reply_to); if (reply_to != NULL && *reply_to != '\0') - e_composer_header_table_set_header_visible ( - table, E_COMPOSER_HEADER_REPLY_TO, TRUE); + e_composer_header_set_visible (header, TRUE); } ESignature * @@ -1224,22 +1441,32 @@ e_composer_header_table_set_signature_list (EComposerHeaderTable *table, const gchar * e_composer_header_table_get_subject (EComposerHeaderTable *table) { - EComposerTextHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerTextHeader *text_header; g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - header = E_COMPOSER_HEADER_TABLE_GET_SUBJECT_HEADER (table); - return e_composer_text_header_get_text (header); + type = E_COMPOSER_HEADER_SUBJECT; + header = e_composer_header_table_get_header (table, type); + text_header = E_COMPOSER_TEXT_HEADER (header); + + return e_composer_text_header_get_text (text_header); } void e_composer_header_table_set_subject (EComposerHeaderTable *table, const gchar *subject) { - EComposerTextHeader *header; + EComposerHeader *header; + EComposerHeaderType type; + EComposerTextHeader *text_header; g_return_if_fail (E_IS_COMPOSER_HEADER_TABLE (table)); - header = E_COMPOSER_HEADER_TABLE_GET_SUBJECT_HEADER (table); - e_composer_text_header_set_text (header, subject); + type = E_COMPOSER_HEADER_SUBJECT; + header = e_composer_header_table_get_header (table, type); + text_header = E_COMPOSER_TEXT_HEADER (header); + + e_composer_text_header_set_text (text_header, subject); } diff --git a/composer/e-composer-header-table.h b/composer/e-composer-header-table.h index 91d64fe22a..817863031c 100644 --- a/composer/e-composer-header-table.h +++ b/composer/e-composer-header-table.h @@ -79,20 +79,6 @@ GtkWidget * e_composer_header_table_new (void); EComposerHeader * e_composer_header_table_get_header (EComposerHeaderTable *table, EComposerHeaderType type); -gboolean e_composer_header_table_get_header_sensitive - (EComposerHeaderTable *table, - EComposerHeaderType type); -void e_composer_header_table_set_header_sensitive - (EComposerHeaderTable *table, - EComposerHeaderType type, - gboolean sensitive); -gboolean e_composer_header_table_get_header_visible - (EComposerHeaderTable *table, - EComposerHeaderType type); -void e_composer_header_table_set_header_visible - (EComposerHeaderTable *table, - EComposerHeaderType type, - gboolean visible); EAccount * e_composer_header_table_get_account (EComposerHeaderTable *table); gboolean e_composer_header_table_set_account diff --git a/composer/e-composer-header.c b/composer/e-composer-header.c index 8cbcf64f1f..272556969d 100644 --- a/composer/e-composer-header.c +++ b/composer/e-composer-header.c @@ -41,6 +41,9 @@ enum { struct _EComposerHeaderPrivate { gchar *label; gboolean button; + + guint sensitive : 1; + guint visible : 1; }; static gpointer parent_class; @@ -302,15 +305,9 @@ e_composer_header_get_label (EComposerHeader *header) gboolean e_composer_header_get_sensitive (EComposerHeader *header) { - gboolean sensitive; - g_return_val_if_fail (E_IS_COMPOSER_HEADER (header), FALSE); - sensitive = GTK_WIDGET_SENSITIVE (header->title_widget); - if (GTK_WIDGET_SENSITIVE (header->input_widget) != sensitive) - g_warning ("%s: Sensitivity is out of sync", G_STRFUNC); - - return sensitive; + return header->priv->sensitive; } void @@ -319,8 +316,7 @@ e_composer_header_set_sensitive (EComposerHeader *header, { g_return_if_fail (E_IS_COMPOSER_HEADER (header)); - gtk_widget_set_sensitive (header->title_widget, sensitive); - gtk_widget_set_sensitive (header->input_widget, sensitive); + header->priv->sensitive = sensitive; g_object_notify (G_OBJECT (header), "sensitive"); } @@ -328,15 +324,9 @@ e_composer_header_set_sensitive (EComposerHeader *header, gboolean e_composer_header_get_visible (EComposerHeader *header) { - gboolean visible; - g_return_val_if_fail (E_IS_COMPOSER_HEADER (header), FALSE); - visible = GTK_WIDGET_VISIBLE (header->title_widget); - if (GTK_WIDGET_VISIBLE (header->input_widget) != visible) - g_warning ("%s: Visibility is out of sync", G_STRFUNC); - - return visible; + return header->priv->visible; } void @@ -345,13 +335,7 @@ e_composer_header_set_visible (EComposerHeader *header, { g_return_if_fail (E_IS_COMPOSER_HEADER (header)); - if (visible) { - gtk_widget_show (header->title_widget); - gtk_widget_show (header->input_widget); - } else { - gtk_widget_hide (header->title_widget); - gtk_widget_hide (header->input_widget); - } + header->priv->visible = visible; g_object_notify (G_OBJECT (header), "visible"); } diff --git a/composer/e-composer-header.h b/composer/e-composer-header.h index d1edd110fe..db9582dc3f 100644 --- a/composer/e-composer-header.h +++ b/composer/e-composer-header.h @@ -59,7 +59,7 @@ struct _EComposerHeaderClass { GType e_composer_header_get_type (void); gchar * e_composer_header_get_label (EComposerHeader *header); gboolean e_composer_header_get_sensitive (EComposerHeader *header); -void e_composer_header_set_sensitive (EComposerHeader *header, +void e_composer_header_set_sensitive (EComposerHeader *header, gboolean sensitive); gboolean e_composer_header_get_visible (EComposerHeader *header); void e_composer_header_set_visible (EComposerHeader *header, diff --git a/composer/e-composer-private.c b/composer/e-composer-private.c index 1729aae9fa..fe5b66ceee 100644 --- a/composer/e-composer-private.c +++ b/composer/e-composer-private.c @@ -90,6 +90,7 @@ e_composer_private_init (EMsgComposer *composer) GtkWidget *send_widget; const gchar *path; gchar *filename; + gint ii; GError *error = NULL; editor = GTKHTML_EDITOR (composer); @@ -165,6 +166,46 @@ e_composer_private_init (EMsgComposer *composer) GTK_BOX (container), widget, TRUE, TRUE, 0, GTK_PACK_START); composer_setup_recent_menu (composer); + + /* Bind headers to their corresponding actions. */ + + for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { + EComposerHeaderTable *table; + EComposerHeader *header; + GtkAction *action; + + table = E_COMPOSER_HEADER_TABLE (priv->header_table); + header = e_composer_header_table_get_header (table, ii); + + switch (ii) { + case E_COMPOSER_HEADER_BCC: + action = ACTION (VIEW_BCC); + break; + + case E_COMPOSER_HEADER_CC: + action = ACTION (VIEW_CC); + break; + + case E_COMPOSER_HEADER_FROM: + action = ACTION (VIEW_FROM); + break; + + case E_COMPOSER_HEADER_REPLY_TO: + action = ACTION (VIEW_REPLY_TO); + break; + + default: + continue; + } + + e_mutual_binding_new ( + G_OBJECT (header), "sensitive", + G_OBJECT (action), "sensitive"); + + e_mutual_binding_new ( + G_OBJECT (header), "visible", + G_OBJECT (action), "active"); + } } void diff --git a/composer/e-composer-private.h b/composer/e-composer-private.h index 669af31235..8dc9b4be93 100644 --- a/composer/e-composer-private.h +++ b/composer/e-composer-private.h @@ -28,6 +28,7 @@ #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/gconf-bridge.h" #include "widgets/misc/e-attachment-paned.h" #include "widgets/misc/e-attachment-store.h" @@ -65,16 +66,6 @@ COMPOSER_GCONF_PREFIX "/send_html" #define COMPOSER_GCONF_SPELL_LANGUAGES_KEY \ COMPOSER_GCONF_PREFIX "/spell_languages" -#define COMPOSER_GCONF_VIEW_BCC_KEY \ - COMPOSER_GCONF_PREFIX "/view/Bcc" -#define COMPOSER_GCONF_VIEW_CC_KEY \ - COMPOSER_GCONF_PREFIX "/view/Cc" -#define COMPOSER_GCONF_VIEW_FROM_KEY \ - COMPOSER_GCONF_PREFIX "/view/From" -#define COMPOSER_GCONF_VIEW_POST_TO_KEY \ - COMPOSER_GCONF_PREFIX "/view/PostTo" -#define COMPOSER_GCONF_VIEW_REPLY_TO_KEY \ - COMPOSER_GCONF_PREFIX "/view/ReplyTo" #define COMPOSER_GCONF_WINDOW_PREFIX \ COMPOSER_GCONF_PREFIX "/window" diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index 9325e0b770..9b526f63ac 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -113,37 +113,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_MSG_COMPOSER, EMsgComposerPrivate)) -#define E_MSG_COMPOSER_VISIBLE_MASK_SENDER \ - (E_MSG_COMPOSER_VISIBLE_FROM | \ - E_MSG_COMPOSER_VISIBLE_REPLYTO) - -#define E_MSG_COMPOSER_VISIBLE_MASK_BASIC \ - (E_MSG_COMPOSER_VISIBLE_MASK_SENDER | \ - E_MSG_COMPOSER_VISIBLE_SUBJECT) - -#define E_MSG_COMPOSER_VISIBLE_MASK_RECIPIENTS \ - (E_MSG_COMPOSER_VISIBLE_TO | \ - E_MSG_COMPOSER_VISIBLE_CC | \ - E_MSG_COMPOSER_VISIBLE_BCC) - -#define E_MSG_COMPOSER_VISIBLE_MASK_MAIL \ - (E_MSG_COMPOSER_VISIBLE_MASK_BASIC | \ - E_MSG_COMPOSER_VISIBLE_MASK_RECIPIENTS) - -#define E_MSG_COMPOSER_VISIBLE_MASK_POST \ - (E_MSG_COMPOSER_VISIBLE_MASK_BASIC | \ - E_MSG_COMPOSER_VISIBLE_POSTTO) - -typedef enum { - E_MSG_COMPOSER_VISIBLE_FROM = (1 << 0), - E_MSG_COMPOSER_VISIBLE_REPLYTO = (1 << 1), - E_MSG_COMPOSER_VISIBLE_TO = (1 << 2), - E_MSG_COMPOSER_VISIBLE_CC = (1 << 3), - E_MSG_COMPOSER_VISIBLE_BCC = (1 << 4), - E_MSG_COMPOSER_VISIBLE_POSTTO = (1 << 5), - E_MSG_COMPOSER_VISIBLE_SUBJECT = (1 << 7) -} EMsgComposerHeaderVisibleFlags; - enum { SEND, SAVE_DRAFT, @@ -399,6 +368,7 @@ build_message_headers (EMsgComposer *composer, gboolean redirect) { EComposerHeaderTable *table; + EComposerHeader *header; EAccount *account; const gchar *subject; const gchar *reply_to; @@ -449,9 +419,9 @@ build_message_headers (EMsgComposer *composer, } /* To:, Cc:, Bcc: */ - if (e_composer_header_table_get_header_visible (table, E_COMPOSER_HEADER_TO) || - e_composer_header_table_get_header_visible (table, E_COMPOSER_HEADER_CC) || - e_composer_header_table_get_header_visible (table, E_COMPOSER_HEADER_BCC)) { + header = e_composer_header_table_get_header ( + table, E_COMPOSER_HEADER_TO); + if (e_composer_header_get_visible (header)) { EDestination **to, **cc, **bcc; to = e_composer_header_table_get_destinations_to (table); @@ -466,7 +436,9 @@ build_message_headers (EMsgComposer *composer, } /* X-Evolution-PostTo: */ - if (e_composer_header_table_get_header_visible (table, E_COMPOSER_HEADER_POST_TO)) { + header = e_composer_header_table_get_header ( + table, E_COMPOSER_HEADER_POST_TO); + if (e_composer_header_get_visible (header)) { CamelMedium *medium = CAMEL_MEDIUM (msg); const gchar *name = "X-Evolution-PostTo"; GList *list, *iter; @@ -1541,36 +1513,6 @@ msg_composer_constructor (GType type, G_OBJECT (composer), "current-folder"); g_array_append_val (array, binding_id); - binding_id = gconf_bridge_bind_property ( - gconf_bridge_get (), - COMPOSER_GCONF_VIEW_BCC_KEY, - G_OBJECT (ACTION (VIEW_BCC)), "active"); - g_array_append_val (array, binding_id); - - binding_id = gconf_bridge_bind_property ( - gconf_bridge_get (), - COMPOSER_GCONF_VIEW_CC_KEY, - G_OBJECT (ACTION (VIEW_CC)), "active"); - g_array_append_val (array, binding_id); - - binding_id = gconf_bridge_bind_property ( - gconf_bridge_get (), - COMPOSER_GCONF_VIEW_FROM_KEY, - G_OBJECT (ACTION (VIEW_FROM)), "active"); - g_array_append_val (array, binding_id); - - binding_id = gconf_bridge_bind_property ( - gconf_bridge_get (), - COMPOSER_GCONF_VIEW_POST_TO_KEY, - G_OBJECT (ACTION (VIEW_POST_TO)), "active"); - g_array_append_val (array, binding_id); - - binding_id = gconf_bridge_bind_property ( - gconf_bridge_get (), - COMPOSER_GCONF_VIEW_REPLY_TO_KEY, - G_OBJECT (ACTION (VIEW_REPLY_TO)), "active"); - g_array_append_val (array, binding_id); - binding_id = gconf_bridge_bind_window ( gconf_bridge_get (), COMPOSER_GCONF_WINDOW_PREFIX, @@ -2322,87 +2264,6 @@ e_msg_composer_get_type (void) /* Callbacks. */ -static EMsgComposer * -create_composer (gint visible_mask) -{ - EMsgComposer *composer; - EComposerHeaderTable *table; - GtkToggleAction *action; - gboolean active; - - composer = g_object_new (E_TYPE_MSG_COMPOSER, NULL); - table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table); - - /* Configure View Menu */ - - /* If we're mailing, you cannot disable "To". */ - action = GTK_TOGGLE_ACTION (ACTION (VIEW_TO)); - active = visible_mask & E_MSG_COMPOSER_VISIBLE_TO; - gtk_action_set_sensitive (ACTION (VIEW_TO), active); - gtk_toggle_action_set_active (action, active); - - /* Ditto for "Post-To". */ - action = GTK_TOGGLE_ACTION (ACTION (VIEW_POST_TO)); - active = visible_mask & E_MSG_COMPOSER_VISIBLE_POSTTO; - gtk_action_set_sensitive (ACTION (VIEW_POST_TO), active); - gtk_toggle_action_set_active (action, active); - - /* Disable "Cc" if we're posting. */ - if (!(visible_mask & E_MSG_COMPOSER_VISIBLE_CC)) { - action = GTK_TOGGLE_ACTION (ACTION (VIEW_CC)); - gtk_toggle_action_set_active (action, FALSE); - } - - /* Disable "Bcc" if we're posting. */ - if (!(visible_mask & E_MSG_COMPOSER_VISIBLE_BCC)) { - action = GTK_TOGGLE_ACTION (ACTION (VIEW_BCC)); - gtk_toggle_action_set_active (action, FALSE); - } - - action = GTK_TOGGLE_ACTION (ACTION (VIEW_SUBJECT)); - gtk_toggle_action_set_active (action, TRUE); - - return composer; -} - -/** - * e_msg_composer_new_with_type: - * - * Create a new message composer widget. The type can be - * E_MSG_COMPOSER_MAIL, E_MSG_COMPOSER_POST or E_MSG_COMPOSER_MAIL_POST. - * - * Returns: A pointer to the newly created widget - **/ - -EMsgComposer * -e_msg_composer_new_with_type (int type) -{ - EMsgComposer *composer; - gint visible_mask; - - switch (type) { - case E_MSG_COMPOSER_MAIL: - visible_mask = E_MSG_COMPOSER_VISIBLE_MASK_MAIL; - break; - - case E_MSG_COMPOSER_POST: - visible_mask = E_MSG_COMPOSER_VISIBLE_MASK_POST; - break; - - default: - visible_mask = - E_MSG_COMPOSER_VISIBLE_MASK_MAIL | - E_MSG_COMPOSER_VISIBLE_MASK_POST; - break; - } - - composer = create_composer (visible_mask); - - set_editor_text (composer, "", TRUE); - - return composer; -} - /** * e_msg_composer_new: * @@ -2413,7 +2274,7 @@ e_msg_composer_new_with_type (int type) EMsgComposer * e_msg_composer_new (void) { - return e_msg_composer_new_with_type (E_MSG_COMPOSER_MAIL); + return g_object_new (E_TYPE_MSG_COMPOSER, NULL); } static void @@ -2839,25 +2700,13 @@ e_msg_composer_new_with_message (CamelMimeMessage *message) GtkToggleAction *action; struct _camel_header_raw *xev; gint len, i; - EMsgComposerPrivate *p; for (headers = CAMEL_MIME_PART (message)->headers;headers;headers = headers->next) { if (!strcmp (headers->name, "X-Evolution-PostTo")) postto = g_list_append (postto, g_strstrip (g_strdup (headers->value))); } - if (postto != NULL) - composer = create_composer (E_MSG_COMPOSER_VISIBLE_MASK_POST); - else - composer = create_composer (E_MSG_COMPOSER_VISIBLE_MASK_MAIL); - p = composer->priv; - - if (!composer) { - g_list_foreach (postto, (GFunc)g_free, NULL); - g_list_free (postto); - return NULL; - } - + composer = e_msg_composer_new (); table = e_msg_composer_get_header_table (composer); if (postto) { @@ -3061,8 +2910,12 @@ e_msg_composer_new_with_message (CamelMimeMessage *message) while (headers) { if (g_ascii_strcasecmp (headers->name, "References") == 0 || g_ascii_strcasecmp (headers->name, "In-Reply-To") == 0) { - g_ptr_array_add (p->extra_hdr_names, g_strdup (headers->name)); - g_ptr_array_add (p->extra_hdr_values, g_strdup (headers->value)); + g_ptr_array_add ( + composer->priv->extra_hdr_names, + g_strdup (headers->name)); + g_ptr_array_add ( + composer->priv->extra_hdr_values, + g_strdup (headers->value)); } headers = headers->next; diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h index 54520ec941..7a279ba230 100644 --- a/composer/e-msg-composer.h +++ b/composer/e-msg-composer.h @@ -68,13 +68,8 @@ struct _EMsgComposerClass { 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 - GType e_msg_composer_get_type (void); EMsgComposer * e_msg_composer_new (void); -EMsgComposer * e_msg_composer_new_with_type (gint type); EMsgComposer * e_msg_composer_new_with_message (CamelMimeMessage *msg); EMsgComposer * e_msg_composer_new_from_url (const gchar *url); EMsgComposer * e_msg_composer_new_redirect (CamelMimeMessage *message, diff --git a/composer/evolution-composer.ui b/composer/evolution-composer.ui index dc77aae183..c22368383c 100644 --- a/composer/evolution-composer.ui +++ b/composer/evolution-composer.ui @@ -9,9 +9,9 @@ <menuitem action='save'/> <menuitem action='save-as'/> <menuitem action='save-draft'/> - <placeholder name='template-holder'/> + <placeholder name='template-holder'/> <separator/> - <placeholder name='external-editor-holder'/> + <placeholder name='external-editor-holder'/> <separator/> <separator/> <menuitem action='print-preview'/> @@ -29,12 +29,9 @@ <placeholder name='pre-insert-menu'> <menu action='view-menu'> <menuitem action='view-from'/> - <menuitem action='view-to'/> - <menuitem action='view-post-to'/> <menuitem action='view-reply-to'/> <menuitem action='view-cc'/> <menuitem action='view-bcc'/> - <menuitem action='view-subject'/> </menu> </placeholder> <menu action='insert-menu'> diff --git a/mail/em-composer-utils.c b/mail/em-composer-utils.c index 0f9945b7d7..f427feca6d 100644 --- a/mail/em-composer-utils.c +++ b/mail/em-composer-utils.c @@ -660,13 +660,18 @@ create_new_composer (const char *subject, const char *fromuri, gboolean use_defa EAccount *account = NULL; composer = e_msg_composer_new (); - if (composer == NULL) - return NULL; + table = e_msg_composer_get_header_table (composer); + + if (fromuri != NULL) { + GList *list; - if (fromuri) account = mail_config_get_account_by_source_url(fromuri); - table = e_msg_composer_get_header_table (composer); + list = g_list_prepend (NULL, (gpointer) fromuri); + e_composer_header_table_set_post_to_list (table, list); + g_list_free (list); + } + e_composer_header_table_set_account (table, account); e_composer_header_table_set_subject (table, subject); @@ -729,82 +734,6 @@ em_utils_compose_new_message_with_mailto (const char *url, const char *fromuri) gdk_window_raise (((GtkWidget *) composer)->window); } -/** - * em_utils_post_to_folder: - * @folder: folder - * - * Opens a new composer window as a child window of @parent's toplevel - * window. If @folder is non-NULL, the composer will default to posting - * mail to the folder specified by @folder. - **/ -void -em_utils_post_to_folder (CamelFolder *folder) -{ - EMsgComposer *composer; - EComposerHeaderTable *table; - EAccount *account; - - composer = e_msg_composer_new_with_type (E_MSG_COMPOSER_POST); - table = e_msg_composer_get_header_table (composer); - - if (folder != NULL) { - char *url = mail_tools_folder_to_url (folder); - GList *list = g_list_prepend (NULL, url); - - e_composer_header_table_set_post_to_list (table, list); - - g_list_free (list); - g_free (url); - - url = camel_url_to_string (CAMEL_SERVICE (folder->parent_store)->url, CAMEL_URL_HIDE_ALL); - account = mail_config_get_account_by_source_url (url); - g_free (url); - - if (account) - e_composer_header_table_set_account_name ( - table, account->name); - } - - em_composer_utils_setup_default_callbacks (composer); - - composer_set_no_change (composer, TRUE, TRUE); - - gtk_widget_show ((GtkWidget *) composer); - gdk_window_raise (((GtkWidget *) composer)->window); -} - -/** - * em_utils_post_to_url: - * @url: mailto url - * - * Opens a new composer window as a child window of @parent's toplevel - * window. If @url is non-NULL, the composer will default to posting - * mail to the folder specified by @url. - **/ -void -em_utils_post_to_url (const char *url) -{ - EMsgComposer *composer; - EComposerHeaderTable *table; - - composer = e_msg_composer_new_with_type (E_MSG_COMPOSER_POST); - table = e_msg_composer_get_header_table (composer); - - if (url != NULL) { - GList *list = NULL; - - list = g_list_prepend (list, (gpointer) url); - e_composer_header_table_set_post_to_list (table, list); - g_list_free (list); - } - - em_composer_utils_setup_default_callbacks (composer); - - composer_set_no_change (composer, TRUE, TRUE); - - gtk_widget_show ((GtkWidget *) composer); -} - /* Editing messages... */ static void @@ -1763,18 +1692,12 @@ reply_get_composer (CamelMimeMessage *message, EAccount *account, g_return_val_if_fail (to == NULL || CAMEL_IS_INTERNET_ADDRESS (to), NULL); g_return_val_if_fail (cc == NULL || CAMEL_IS_INTERNET_ADDRESS (cc), NULL); + composer = e_msg_composer_new (); + /* construct the tov/ccv */ tov = em_utils_camel_address_to_destination (to); ccv = em_utils_camel_address_to_destination (cc); - if (tov || ccv) { - if (postto && camel_address_length((CamelAddress *)postto)) - composer = e_msg_composer_new_with_type (E_MSG_COMPOSER_MAIL_POST); - else - composer = e_msg_composer_new_with_type (E_MSG_COMPOSER_MAIL); - } else - composer = e_msg_composer_new_with_type (E_MSG_COMPOSER_POST); - /* Set the subject of the new message. */ if ((subject = (char *) camel_mime_message_get_subject (message))) { if (g_ascii_strncasecmp (subject, "Re: ", 4) != 0) @@ -2403,124 +2326,3 @@ em_utils_reply_to_message(CamelFolder *folder, const char *uid, CamelMimeMessage gtk_widget_show (GTK_WIDGET (composer)); } - -/* Posting replies... */ - -static void -post_reply_to_message (CamelFolder *folder, const char *uid, CamelMimeMessage *message, void *user_data) -{ - /* FIXME: would be nice if this shared more code with reply_get_composer() */ - const char *message_id, *references; - CamelInternetAddress *to; - EDestination **tov = NULL; - CamelFolder *real_folder; - EMsgComposer *composer; - EComposerHeaderTable *table; - char *subject, *url; - EAccount *account; - char *real_uid; - guint32 flags; - GList *list = NULL; - - if (message == NULL) - return; - - if (CAMEL_IS_VEE_FOLDER (folder)) { - CamelMessageInfo *info; - - info = camel_folder_get_message_info (folder, uid); - real_folder = camel_vee_folder_get_location ((CamelVeeFolder *) folder, (struct _CamelVeeMessageInfo *) info, &real_uid); - camel_folder_free_message_info (folder, info); - } else { - real_folder = folder; - camel_object_ref (folder); - real_uid = g_strdup (uid); - } - - account = guess_account (message, real_folder); - flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN; - - to = camel_internet_address_new(); - get_reply_sender (message, to, NULL); - - composer = e_msg_composer_new_with_type (E_MSG_COMPOSER_MAIL_POST); - - /* construct the tov/ccv */ - tov = em_utils_camel_address_to_destination (to); - - /* Set the subject of the new message. */ - if ((subject = (char *) camel_mime_message_get_subject (message))) { - if (g_ascii_strncasecmp (subject, "Re: ", 4) != 0) - subject = g_strdup_printf ("Re: %s", subject); - else - subject = g_strdup (subject); - } else { - subject = g_strdup (""); - } - - table = e_msg_composer_get_header_table (composer); - e_composer_header_table_set_account (table, account); - e_composer_header_table_set_subject (table, subject); - e_composer_header_table_set_destinations_to (table, tov); - - g_free (subject); - - url = mail_tools_folder_to_url (real_folder); - list = g_list_prepend (list, url); - - e_composer_header_table_set_post_to_list (table, list); - - g_list_free (list); - g_free (url); - - /* Add In-Reply-To and References. */ - message_id = camel_medium_get_header (CAMEL_MEDIUM (message), "Message-Id"); - references = camel_medium_get_header (CAMEL_MEDIUM (message), "References"); - if (message_id) { - char *reply_refs; - - e_msg_composer_add_header (composer, "In-Reply-To", message_id); - - if (references) - reply_refs = g_strdup_printf ("%s %s", references, message_id); - else - reply_refs = g_strdup (message_id); - - e_msg_composer_add_header (composer, "References", reply_refs); - g_free (reply_refs); - } else if (references) { - e_msg_composer_add_header (composer, "References", references); - } - - e_msg_composer_add_message_attachments (composer, message, TRUE); - - composer_set_body (composer, message, NULL); - - em_composer_utils_setup_callbacks (composer, real_folder, real_uid, flags, flags, NULL, NULL); - - composer_set_no_change (composer, TRUE, FALSE); - - gtk_widget_show (GTK_WIDGET (composer)); - - camel_object_unref (real_folder); - camel_object_unref(to); - g_free (real_uid); -} - -/** - * em_utils_post_reply_to_message_by_uid: - * @folder: folder containing message to reply to - * @uid: message uid - * @mode: reply mode - * - * Creates a new composer (post mode) ready to reply to the message - * referenced by @folder and @uid. - **/ -void -em_utils_post_reply_to_message_by_uid (CamelFolder *folder, const char *uid) -{ - g_return_if_fail (CAMEL_IS_FOLDER (folder)); - g_return_if_fail (uid != NULL); - - mail_get_message (folder, uid, post_reply_to_message, NULL, mail_msg_unordered_push); -} diff --git a/mail/em-composer-utils.h b/mail/em-composer-utils.h index d17a98caa3..c46f808879 100644 --- a/mail/em-composer-utils.h +++ b/mail/em-composer-utils.h @@ -50,8 +50,6 @@ void em_utils_compose_new_message (const char *fromuri); /* FIXME: mailto? url? should make up its mind what its called. imho use 'uri' */ void em_utils_compose_new_message_with_mailto (const char *url, const char *fromuri); -void em_utils_post_to_folder (struct _CamelFolder *folder); -void em_utils_post_to_url (const char *url); void em_utils_edit_message (struct _CamelMimeMessage *message, struct _CamelFolder *folder); void em_utils_edit_messages (struct _CamelFolder *folder, GPtrArray *uids, gboolean replace); @@ -79,8 +77,6 @@ enum { void em_utils_reply_to_message (struct _CamelFolder *, const char *uid, struct _CamelMimeMessage *message, int mode, struct _EMFormat *source); -void em_utils_post_reply_to_message_by_uid (struct _CamelFolder *folder, const char *uid); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c index 7a3e690e2b..9a80a0c254 100644 --- a/mail/em-folder-browser.c +++ b/mail/em-folder-browser.c @@ -164,7 +164,6 @@ static const EMFolderViewEnable emfb_enable_map[] = { { "FolderRename", EM_POPUP_SELECT_FOLDER }, { "FolderRefresh", EM_POPUP_SELECT_FOLDER }, { "ChangeFolderProperties", EM_POPUP_SELECT_FOLDER }, - { "MailPost", EM_POPUP_SELECT_FOLDER }, { "MessageMarkAllAsRead", EM_POPUP_SELECT_FOLDER }, { "ViewHideSelected", EM_POPUP_SELECT_MANY }, { "ViewThreadsCollapseAll", EM_FOLDER_VIEW_SELECT_THREADED}, @@ -1694,13 +1693,6 @@ emfb_mail_stop(BonoboUIComponent *uid, void *data, const char *path) } static void -emfb_mail_post(BonoboUIComponent *uid, void *data, const char *path) -{ - EMFolderView *emfv = data; - em_utils_post_to_folder (emfv->folder); -} - -static void emfb_tools_filters(BonoboUIComponent *uid, void *data, const char *path) { EMFolderBrowser *emfb = data; @@ -1779,7 +1771,6 @@ static BonoboUIVerb emfb_verbs[] = { BONOBO_UI_UNSAFE_VERB ("FolderCreate", emfb_folder_create), BONOBO_UI_UNSAFE_VERB ("HelpDebug", emfb_help_debug), - BONOBO_UI_UNSAFE_VERB ("MailPost", emfb_mail_post), BONOBO_UI_UNSAFE_VERB ("MailStop", emfb_mail_stop), BONOBO_UI_UNSAFE_VERB ("ToolsFilters", emfb_tools_filters), BONOBO_UI_UNSAFE_VERB ("ToolsSubscriptions", emfb_tools_subscriptions), diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c index 42037b5a33..e31d8d727c 100644 --- a/mail/em-folder-view.c +++ b/mail/em-folder-view.c @@ -185,7 +185,6 @@ static const EMFolderViewEnable emfv_enable_map[] = { { "MessageFollowUpClear", EM_POPUP_SELECT_MANY|EM_POPUP_SELECT_FLAG_CLEAR }, { "MessageMove", EM_POPUP_SELECT_MANY }, { "MessageOpen", EM_POPUP_SELECT_MANY }, - { "MessagePostReply", EM_POPUP_SELECT_ONE }, { "MessageReplyAll", EM_POPUP_SELECT_ONE }, { "MessageReplyList", EM_POPUP_SELECT_ONE|EM_POPUP_SELECT_MAILING_LIST }, { "MessageReplySender", EM_POPUP_SELECT_ONE }, @@ -1726,20 +1725,6 @@ emfv_message_redirect (BonoboUIComponent *uic, void *data, const char *path) em_utils_redirect_message_by_uid (emfv->folder, emfv->list->cursor_uid); } -static void -emfv_message_post_reply (BonoboUIComponent *uic, void *data, const char *path) -{ - EMFolderView *emfv = data; - - if (emfv->list->cursor_uid == NULL) - return; - - if (!em_utils_check_user_can_send_mail ((GtkWidget *) emfv)) - return; - - em_utils_post_reply_to_message_by_uid (emfv->folder, emfv->list->cursor_uid); -} - static gboolean html_contains_nonwhitespace (const char *html, gint len) { @@ -2073,7 +2058,6 @@ static BonoboUIVerb emfv_message_verbs[] = { BONOBO_UI_UNSAFE_VERB ("MessageFollowUpClear", emfv_message_followup_clear), BONOBO_UI_UNSAFE_VERB ("MessageMove", emfv_message_move), BONOBO_UI_UNSAFE_VERB ("MessageOpen", emfv_message_open), - BONOBO_UI_UNSAFE_VERB ("MessagePostReply", emfv_message_post_reply), BONOBO_UI_UNSAFE_VERB ("MessageReplyAll", emfv_message_reply_all), BONOBO_UI_UNSAFE_VERB ("MessageReplyList", emfv_message_reply_list), BONOBO_UI_UNSAFE_VERB ("MessageReplySender", emfv_message_reply_sender), diff --git a/mail/evolution-mail.schemas.in b/mail/evolution-mail.schemas.in index e63d9eec4a..fbc23eb746 100644 --- a/mail/evolution-mail.schemas.in +++ b/mail/evolution-mail.schemas.in @@ -116,71 +116,91 @@ </schema> <schema> - <key>/schemas/apps/evolution/mail/composer/view/From</key> - <applyto>/apps/evolution/mail/composer/view/From</applyto> + <key>/schemas/apps/evolution/mail/composer/show_mail_bcc</key> + <applyto>/apps/evolution/mail/composer/show_mail_bcc</applyto> + <owner>evolution-mail</owner> + <type>bool</type> + <default>false</default> + <locale name="C"> + <short>Show "Bcc" field when sending a mail message</short> + <long> + Show the "Bcc" field when sending a mail message. This is + controlled from the View menu when a mail account is chosen. + </long> + </locale> + </schema> + + <schema> + <key>/schemas/apps/evolution/mail/composer/show_mail_cc</key> + <applyto>/apps/evolution/mail/composer/show_mail_cc</applyto> <owner>evolution-mail</owner> <type>bool</type> <default>true</default> <locale name="C"> - <short>View/From menu item is checked</short> + <short>Show "Cc" field when sending a mail message</short> <long> - View/From menu item is checked. + Show the "Cc" field when sending a mail message. This is + controlled from the View menu when a mail account is chosen. </long> </locale> </schema> <schema> - <key>/schemas/apps/evolution/mail/composer/view/PostTo</key> - <applyto>/apps/evolution/mail/composer/view/PostTo</applyto> + <key>/schemas/apps/evolution/mail/composer/show_mail_from</key> + <applyto>/apps/evolution/mail/composer/show_mail_from</applyto> <owner>evolution-mail</owner> <type>bool</type> <default>true</default> <locale name="C"> - <short>View/PostTo menu item is checked</short> + <short>Show "From" field when sending a mail message</short> <long> - View/PostTo menu item is checked. + Show the "From" field when sending a mail message. This is + controlled from the View menu when a mail account is chosen. </long> </locale> </schema> <schema> - <key>/schemas/apps/evolution/mail/composer/view/ReplyTo</key> - <applyto>/apps/evolution/mail/composer/view/ReplyTo</applyto> + <key>/schemas/apps/evolution/mail/composer/show_mail_reply_to</key> + <applyto>/apps/evolution/mail/composer/show_mail_reply_to</applyto> <owner>evolution-mail</owner> <type>bool</type> <default>false</default> <locale name="C"> - <short>View/ReplyTo menu item is checked</short> + <short>Show "Reply To" field when sending a mail message</short> <long> - View/ReplyTo menu item is checked. + Show the "Reply To" field when sending a mail message. This + is controlled from the View menu when a mail account is chosen. </long> </locale> </schema> <schema> - <key>/schemas/apps/evolution/mail/composer/view/Cc</key> - <applyto>/apps/evolution/mail/composer/view/Cc</applyto> + <key>/schemas/apps/evolution/mail/composer/show_post_from</key> + <applyto>/apps/evolution/mail/composer/show_post_from</applyto> <owner>evolution-mail</owner> <type>bool</type> - <default>false</default> + <default>true</default> <locale name="C"> - <short>View/Cc menu item is checked</short> + <short>Show "From" field when posting to a newsgroup</short> <long> - View/Cc menu item is checked. + Show the "From" field when posting to a newsgroup. This is + controlled from the View menu when a news account is chosen. </long> </locale> </schema> <schema> - <key>/schemas/apps/evolution/mail/composer/view/Bcc</key> - <applyto>/apps/evolution/mail/composer/view/Bcc</applyto> + <key>/schemas/apps/evolution/mail/composer/show_post_reply_to</key> + <applyto>/apps/evolution/mail/composer/show_post_reply_to</applyto> <owner>evolution-mail</owner> <type>bool</type> <default>false</default> <locale name="C"> - <short>View/Bcc menu item is checked</short> + <short>Show "Reply To" field when posting to a newsgroup</short> <long> - View/Bcc menu item is checked. + Show the "Reply To" field when posting to a newsgroup. This + is controlled from the View menu when a news account is chosen. </long> </locale> </schema> diff --git a/ui/evolution-mail-message.xml b/ui/evolution-mail-message.xml index 0acbc44647..f90e737c24 100644 --- a/ui/evolution-mail-message.xml +++ b/ui/evolution-mail-message.xml @@ -127,13 +127,6 @@ _tip="Open the selected messages in a new window" accel="*Control*o"/> - <cmd name="MailPost" - _tip="Post a message to a Public folder"/> - - <cmd name="MessagePostReply" - _tip="Post a reply to a message in a Public folder" - accel=""/> - <cmd name="MessageRedirect" _tip="Redirect (bounce) the selected message to someone" accel=""/> @@ -301,7 +294,6 @@ <submenu name="Message" _label="_Message"> <placeholder name="MessageTopActions"> <menuitem name="ActionCompose" verb="MailCompose" _label="Compose _New Message"/> - <menuitem name="MailPost" verb="" _label="Pos_t New Message to Folder"/> <menuitem name="MessageOpen" verb="" _label="_Open in New Window"/> <menuitem name="MessageEdit" verb="" _label="_Edit as New Message..."/> <menuitem name="AddSenderToAddressbook" verb="" _label="A_dd Sender to Address Book"/> @@ -325,7 +317,6 @@ <menuitem name="MessageReplySender" verb="" _label="_Reply to Sender"/> <menuitem name="MessageReplyList" verb="" _label="Reply to _List"/> <menuitem name="MessageReplyAll" verb="" _label="Reply to _All"/> - <menuitem name="MessagePostReply" verb="" _label="Post a Repl_y"/> <menuitem name="MessageForward" verb="" _label="_Forward"/> <submenu name="ForwardAs" _label="F_orward As..."> <menuitem verb="MessageForwardAttached" _label="_Attached"/> |