From f5bed9bf7b143fff9bd258ea31fdac192e00a0d9 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 27 Nov 2007 20:24:44 +0000 Subject: ** Fixes bug #495123 2007-11-27 Matthew Barnes ** Fixes bug #495123 * composer/Makefile.am: Add a bunch of files for managing composer headers. * composer/e-msg-composer.c (build_message), (from_changed_cb), (set_editor_signature), (e_msg_composer_set_body), (e_msg_composer_get_preferred_account): * plugins/exchange-operations/exchange-mail-send-options.c (append_to_header): Use e_msg_composer_hdrs_get_from_account() to obtain the EAccount. * composer/e-msg-composer-hdrs.c: * composer/e-msg-composer-hdrs.h: Massive refactoring to use new EComposerHeader classes. * composer/e-composer-header.c: * composer/e-composer-header.h: * composer/e-composer-from-header.c: * composer/e-composer-from-header.h: * composer/e-composer-name-header.c: * composer/e-composer-name-header.h: * composer/e-composer-post-header.c: * composer/e-composer-post-header.h: * composer/e-composer-text-header.c: * composer/e-composer-text-header.h: New GObject classes manage different types of composer headers. See bug #495123 for a more detailed description of each class. * mail/mail-session.c (mail_session_init): Pass the CamelSession to the EAccountComboBox class (ugly hack). * widgets/misc/Makefile.am: Add e-account-combo-box.[ch]. * widgets/misc/e-account-combo-box.c: * widgets/misc/e-account-combo-box.h: New widget renders an EAccountList as a combo box. Also listens for changes to the EAccountList and updates itself accordingly. svn path=/trunk/; revision=34600 --- composer/e-msg-composer-hdrs.c | 1396 +++++++++------------------------------- 1 file changed, 290 insertions(+), 1106 deletions(-) (limited to 'composer/e-msg-composer-hdrs.c') diff --git a/composer/e-msg-composer-hdrs.c b/composer/e-msg-composer-hdrs.c index 523c66f695..02208c14fa 100644 --- a/composer/e-msg-composer-hdrs.c +++ b/composer/e-msg-composer-hdrs.c @@ -26,753 +26,82 @@ #include #endif -#include - #include #include -#include -#include -#include -#include #include #include -#include -#include #include "Composer.h" -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "e-util/e-error.h" -#include "e-util/e-icon-factory.h" - #include #include #include #include "e-msg-composer-hdrs.h" #include "mail/mail-config.h" #include "mail/mail-session.h" -/*#include "mail/em-folder-selection-button.h"*/ -#include "mail/em-folder-selector.h" - -/* another 'temporary' kludge, so we dont need to build idl's for the MailComponent */ -/*#include "mail/mail-component.h"*/ -struct _MailComponent *mail_component_peek(void); -extern struct _EMFolderTreeModel *mail_component_peek_tree_model(struct _MailComponent *); - -#include "mail/em-folder-tree.h" +#include "e-account-combo-box.h" -/* TEMPORARY KLUDGE */ -#include "addressbook/gui/contact-editor/e-contact-editor.h" -#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h" +#include "e-composer-header.h" +#include "e-composer-from-header.h" +#include "e-composer-name-header.h" +#include "e-composer-post-header.h" +#include "e-composer-text-header.h" - - -/* Indexes in the GtkTable assigned to various items */ - -#define LINE_FROM 0 -#define LINE_REPLYTO 1 -#define LINE_TO 2 -#define LINE_CC 3 -#define LINE_BCC 4 -#define LINE_POSTTO 5 -#define LINE_SUBJECT 6 +#define E_MSG_COMPOSER_HDRS_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MSG_COMPOSER_HDRS, EMsgComposerHdrsPrivate)) - -typedef struct { - GtkWidget *label; - GtkWidget *entry; - guint visible:1; -} EMsgComposerHdrPair; - -struct _EMsgComposerHdrsPrivate { - ENameSelector *name_selector; - - /* ui component */ - BonoboUIComponent *uic; - - /* The tooltips. */ - GtkTooltips *tooltips; - - EAccountList *accounts; - GSList *from_options; - - gboolean post_custom; - - /* Standard headers. */ - EMsgComposerHdrPair from, reply_to, to, cc, bcc, post_to, subject; +/* Headers, listed in the order that they should appear in the table. */ +enum { + HEADER_FROM, + HEADER_REPLY_TO, + HEADER_TO, + HEADER_CC, + HEADER_BCC, + HEADER_POST_TO, + HEADER_SUBJECT, + NUM_HEADERS }; - -static GtkTableClass *parent_class = NULL; - enum { - SHOW_ADDRESS_DIALOG, SUBJECT_CHANGED, HDRS_CHANGED, FROM_CHANGED, LAST_SIGNAL }; -static int signals[LAST_SIGNAL]; - - -static void -addressbook_dialog_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer user_data) -{ - gtk_widget_hide (GTK_WIDGET (name_selector_dialog)); -} - -static void -setup_name_selector (EMsgComposerHdrs *hdrs) -{ - EMsgComposerHdrsPrivate *priv; - ENameSelectorDialog *name_selector_dialog; - - priv = hdrs->priv; - - g_return_if_fail (priv->name_selector == NULL); - - priv->name_selector = e_name_selector_new (); - name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector); - g_signal_connect (name_selector_dialog, "response", - G_CALLBACK (addressbook_dialog_response), hdrs); -} - -typedef struct { - EMsgComposerHdrs *hdrs; - char *string; -} EMsgComposerHdrsAndString; - -static void -e_msg_composer_hdrs_and_string_free (EMsgComposerHdrsAndString *emchas) -{ - if (emchas->hdrs) - g_object_unref (emchas->hdrs); - g_free (emchas->string); - g_free (emchas); -} - -static EMsgComposerHdrsAndString * -e_msg_composer_hdrs_and_string_create (EMsgComposerHdrs *hdrs, const char *string) -{ - EMsgComposerHdrsAndString *emchas; - - emchas = g_new (EMsgComposerHdrsAndString, 1); - emchas->hdrs = hdrs; - emchas->string = g_strdup (string); - if (emchas->hdrs) - g_object_ref (emchas->hdrs); - - return emchas; -} - -static void -address_button_clicked_cb (GtkButton *button, gpointer data) -{ - EMsgComposerHdrsAndString *emchas; - EMsgComposerHdrs *hdrs; - EMsgComposerHdrsPrivate *priv; - ENameSelectorDialog *name_selector_dialog; - guint index = 0; +struct _EMsgComposerHdrsPrivate { + ENameSelector *name_selector; - emchas = data; - hdrs = emchas->hdrs; - priv = hdrs->priv; + /* ui component */ + BonoboUIComponent *uic; - if (button == (GtkButton *) hdrs->priv->to.label) { - gtk_widget_grab_focus (hdrs->priv->to.entry); - index = 0; - printf("index:%d\n", index); - } - else if (button == (GtkButton *) priv->cc.label) { - gtk_widget_grab_focus (hdrs->priv->cc.entry); - index = 1; - printf("index:%d\n", index); - } - else if (button == (GtkButton *) priv->bcc.label) { - gtk_widget_grab_focus (hdrs->priv->bcc.entry); - index = 2; - printf("index:%d\n", index); - } + EComposerHeader *headers[NUM_HEADERS]; +}; - name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector); - e_name_selector_dialog_set_destination_index (name_selector_dialog, index); - gtk_widget_show (GTK_WIDGET (name_selector_dialog)); -} +static gpointer parent_class; +static guint signal_ids[LAST_SIGNAL]; static void -from_changed (GtkWidget *item, gpointer data) +from_changed (EComposerFromHeader *from_header, EMsgComposerHdrs *hdrs) { - EMsgComposerHdrs *hdrs = E_MSG_COMPOSER_HDRS (data); - const char *reply_to; - GList *post_items = NULL; + EComposerHeader *header; + EAccount *account; - /* this will retrieve items relative to the previous account */ - if (!hdrs->priv->post_custom) - post_items = e_msg_composer_hdrs_get_post_to(hdrs); + account = e_composer_from_header_get_active (from_header); - hdrs->account = g_object_get_data ((GObject *) item, "account"); + header = hdrs->priv->headers[HEADER_POST_TO]; + e_composer_post_header_set_account ( + E_COMPOSER_POST_HEADER (header), account); /* we do this rather than calling e_msg_composer_hdrs_set_reply_to() because we don't want to change the visibility of the header */ - reply_to = hdrs->account->id->reply_to; - gtk_entry_set_text (GTK_ENTRY (hdrs->priv->reply_to.entry), reply_to ? reply_to : ""); - - /* folders should be made relative to the new from */ - if (!hdrs->priv->post_custom) { - e_msg_composer_hdrs_set_post_to_list (hdrs, post_items); - g_list_foreach (post_items, (GFunc)g_free, NULL); - g_list_free(post_items); - } - - g_signal_emit (hdrs, signals [FROM_CHANGED], 0); -} - -static gboolean -account_can_send (EAccount *account) -{ - static CamelStore *store; - CamelException ex; - gboolean result = FALSE; - - if (!account->parent_uid) - return TRUE; - - if (!(store = (CamelStore *) camel_session_get_service (session, e_account_get_string(account, E_ACCOUNT_SOURCE_URL), CAMEL_PROVIDER_STORE, &ex))) { - camel_exception_clear (&ex); - return result; - } else if (store->mode & CAMEL_STORE_WRITE) - result = TRUE; - - camel_object_unref (store); - return result; -} - -static void -account_added_cb (EAccountList *accounts, EAccount *account, EMsgComposerHdrs *hdrs) -{ - GtkWidget *item, *menu, *omenu, *toplevel; - char *label; - - omenu = e_msg_composer_hdrs_get_from_omenu (hdrs); - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (omenu)); - - if (account_can_send (account)) { - label = g_strdup_printf ("%s <%s>", account->id->name, account->id->address); - item = gtk_menu_item_new_with_label (label); - gtk_widget_show (item); - g_free (label); - - g_object_ref (account); - g_object_set_data ((GObject *) item, "account", account); - g_signal_connect (item, "activate", G_CALLBACK (from_changed), hdrs); - - /* this is so we can later set which one we want */ - hdrs->priv->from_options = g_slist_append (hdrs->priv->from_options, item); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - toplevel = gtk_widget_get_toplevel ((GtkWidget *) hdrs); - gtk_widget_set_sensitive (toplevel, TRUE); - } -} - -static void -account_changed_cb (EAccountList *accounts, EAccount *account, EMsgComposerHdrs *hdrs) -{ - GtkWidget *item, *label; - EAccount *acnt; - GSList *node; - char *text; - - node = hdrs->priv->from_options; - while (node != NULL) { - item = node->data; - acnt = g_object_get_data ((GObject *) item, "account"); - if (acnt == account) { - text = g_strdup_printf ("%s <%s>", account->id->name, account->id->address); - label = gtk_bin_get_child ((GtkBin *) item); - gtk_label_set_text ((GtkLabel *) label, text); - g_free (text); - break; - } - - node = node->next; - } -} - -static void -account_removed_cb (EAccountList *accounts, EAccount *account, EMsgComposerHdrs *hdrs) -{ - struct _EMsgComposerHdrsPrivate *priv = hdrs->priv; - GtkWidget *item, *omenu, *toplevel; - EAccount *acnt; - GSList *node; - - node = priv->from_options; - while (node != NULL) { - item = node->data; - acnt = g_object_get_data ((GObject *) item, "account"); - if (acnt == account) { - if (hdrs->account == account) - hdrs->account = NULL; - - priv->from_options = g_slist_delete_link (priv->from_options, node); - g_object_unref (account); - gtk_widget_destroy (item); - break; - } - - node = node->next; - } - - if (hdrs->account == NULL) { - if (priv->from_options) { - /* the previously selected account was removed, - default the new selection to the first account in - the menu list */ - omenu = e_msg_composer_hdrs_get_from_omenu (hdrs); - - item = priv->from_options->data; - gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), 0); - g_signal_emit_by_name (item, "activate", hdrs); - } else { - toplevel = gtk_widget_get_toplevel ((GtkWidget *) hdrs); - gtk_widget_set_sensitive (toplevel, FALSE); - - /* FIXME: this should offer a 'configure account' button, can we do that? */ - e_error_run((GtkWindow *)toplevel, "mail-composer:all-accounts-deleted", NULL); - } - } -} - -static GtkWidget * -create_from_optionmenu (EMsgComposerHdrs *hdrs) -{ - struct _EMsgComposerHdrsPrivate *priv = hdrs->priv; - GtkWidget *hbox, *omenu, *menu, *item, *first = NULL; - int i = 0, history = 0, m, matches; - GPtrArray *addresses; - GConfClient *gconf; - EAccount *account; - EIterator *iter; - char *uid; - - omenu = gtk_option_menu_new (); - menu = gtk_menu_new (); - - gconf = gconf_client_get_default (); - uid = gconf_client_get_string (gconf, "/apps/evolution/mail/default_account", NULL); - g_object_unref (gconf); - - /* Make list of account email addresses */ - addresses = g_ptr_array_new (); - iter = e_list_get_iterator ((EList *) priv->accounts); - while (e_iterator_is_valid (iter)) { - account = (EAccount *) e_iterator_get (iter); - - if (account->id->address && account_can_send (account) && account->enabled) - g_ptr_array_add (addresses, account->id->address); - - e_iterator_next (iter); - } - - e_iterator_reset (iter); - - while (e_iterator_is_valid (iter)) { - char *label; - - account = (EAccount *) e_iterator_get (iter); - - /* this should never ever fail */ - if (!account || !account->name || !account->id) { - g_warning ("account details are bad\n"); - continue; - } - - if (account->id->address && *account->id->address && account_can_send (account) && account->enabled) { - /* If the account has a unique email address, just - * show that. Otherwise include the account name. - */ - for (m = matches = 0; m < addresses->len; m++) { - if (!strcmp (account->id->address, addresses->pdata[m])) - matches++; - } - - if (matches > 1) - label = g_strdup_printf ("%s <%s> (%s)", account->id->name, - account->id->address, account->name); - else - label = g_strdup_printf ("%s <%s>", account->id->name, account->id->address); - - item = gtk_menu_item_new_with_label (label); - g_free (label); - - g_object_ref (account); - g_object_set_data ((GObject *) item, "account", account); - g_signal_connect (item, "activate", G_CALLBACK (from_changed), hdrs); - - if (uid && !strcmp (account->uid, uid)) { - first = item; - history = i; - } - - /* this is so we can later set which one we want */ - hdrs->priv->from_options = g_slist_append (hdrs->priv->from_options, item); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); - i++; - } - - e_iterator_next (iter); - } - - g_free (uid); - g_object_unref (iter); - - g_ptr_array_free (addresses, TRUE); - - gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); - - if (first) { - gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), history); - g_signal_emit_by_name (first, "activate", hdrs); - } - - hbox = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start_defaults (GTK_BOX (hbox), omenu); - gtk_widget_show (omenu); - gtk_widget_show (hbox); - - g_object_set_data ((GObject *) hbox, "from_menu", omenu); - - /* listen for changes to the account list so we can auto-update the from menu */ - g_signal_connect (priv->accounts, "account-added", G_CALLBACK (account_added_cb), hdrs); - g_signal_connect (priv->accounts, "account-changed", G_CALLBACK (account_changed_cb), hdrs); - g_signal_connect (priv->accounts, "account-removed", G_CALLBACK (account_removed_cb), hdrs); - - return hbox; -} - -static void -addressbook_entry_changed (GtkWidget *entry, - gpointer user_data) -{ - EMsgComposerHdrs *hdrs = E_MSG_COMPOSER_HDRS (user_data); - - g_signal_emit (hdrs, signals[HDRS_CHANGED], 0); -} + header = hdrs->priv->headers[HEADER_REPLY_TO]; + e_composer_text_header_set_text ( + E_COMPOSER_TEXT_HEADER (header), account->id->reply_to); -static gboolean -entry_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) -{ - const char *text; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE); - g_return_val_if_fail (tooltip != NULL, FALSE); - - if (keyboard_mode) - return FALSE; - - text = gtk_entry_get_text (GTK_ENTRY (widget)); - - if (!text || !*text) - return FALSE; - - gtk_tooltip_set_text (tooltip, text); - - return TRUE; -} - -/** - * connect_entry_for_tooltip - * This connects "tooltip" callback to entry. - * If entry has tooltip depends on the length of the text inside it. - * @param entry GtkEntry widget, to connect to. - **/ -static void -connect_entry_for_tooltip (GtkWidget *entry) -{ - g_return_if_fail (entry != NULL); - g_return_if_fail (GTK_IS_ENTRY (entry)); - - g_signal_connect (G_OBJECT (entry), "query-tooltip", G_CALLBACK (entry_query_tooltip), NULL); - gtk_widget_set_has_tooltip (entry, TRUE); -} - -static GtkWidget * -create_addressbook_entry (EMsgComposerHdrs *hdrs, const char *name) -{ - EMsgComposerHdrsPrivate *priv; - ENameSelectorModel *name_selector_model; - ENameSelectorEntry *name_selector_entry; - - priv = hdrs->priv; - - name_selector_model = e_name_selector_peek_model (priv->name_selector); - e_name_selector_model_add_section (name_selector_model, name, name, NULL); - - name_selector_entry = (ENameSelectorEntry *)e_name_selector_peek_section_list (priv->name_selector, name); - g_signal_connect (name_selector_entry, "changed", G_CALLBACK (addressbook_entry_changed), hdrs); - connect_entry_for_tooltip (GTK_WIDGET (name_selector_entry)); - - e_name_selector_entry_set_contact_editor_func (name_selector_entry, e_contact_editor_new); - e_name_selector_entry_set_contact_list_editor_func (name_selector_entry, e_contact_list_editor_new); - - return GTK_WIDGET (name_selector_entry); - -#if 0 - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_addSection ( - corba_select_names, name, name, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - return NULL; - } - - corba_control = - GNOME_Evolution_Addressbook_SelectNames_getEntryBySection ( - corba_select_names, name, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - control_widget = bonobo_widget_new_control_from_objref ( - corba_control, bonobo_ui_component_get_container (priv->uic)); - - cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (control_widget)); - pb = bonobo_control_frame_get_control_property_bag (cf, NULL); - - bonobo_control_frame_set_autoactivate (cf, TRUE); - - bonobo_event_source_client_add_listener ( - pb, addressbook_entry_changed, - "Bonobo/Property:change:entry_changed", - NULL, hdrs); - - return control_widget; -#endif -} - -static void -post_browser_response (EMFolderSelector *emfs, int response, EMsgComposerHdrs *hdrs) -{ - if (response == GTK_RESPONSE_OK) { - GList *uris = em_folder_selector_get_selected_uris (emfs); - - e_msg_composer_hdrs_set_post_to_list (hdrs, uris); - hdrs->priv->post_custom = FALSE; - g_list_foreach (uris, (GFunc) g_free, NULL); - g_list_free (uris); - } - - gtk_widget_destroy ((GtkWidget *) emfs); -} - -static void -post_browser_clicked_cb (GtkButton *button, EMsgComposerHdrs *hdrs) -{ - EMFolderTreeModel *model; - EMFolderTree *emft; - GtkWidget *dialog; - GList *post_items; - - gtk_widget_grab_focus(hdrs->priv->post_to.entry); - model = mail_component_peek_tree_model (mail_component_peek ()); - emft = (EMFolderTree *) em_folder_tree_new_with_model (model); - em_folder_tree_set_multiselect (emft, TRUE); - em_folder_tree_set_excluded(emft, EMFT_EXCLUDE_NOSELECT|EMFT_EXCLUDE_VIRTUAL|EMFT_EXCLUDE_VTRASH); - - dialog = em_folder_selector_new (emft, EM_FOLDER_SELECTOR_CAN_CREATE, - _("Posting destination"), - _("Choose folders to post the message to."), NULL); - - post_items = e_msg_composer_hdrs_get_post_to (hdrs); - em_folder_selector_set_selected_list ((EMFolderSelector *) dialog, post_items); - g_list_foreach (post_items, (GFunc) g_free, NULL); - g_list_free (post_items); - - g_signal_connect (dialog, "response", G_CALLBACK (post_browser_response), hdrs); - gtk_widget_show (dialog); -} - -static void -post_entry_changed_cb (GtkButton *button, EMsgComposerHdrs *hdrs) -{ - hdrs->priv->post_custom = TRUE; -} - -static EMsgComposerHdrPair -header_new_recipient (EMsgComposerHdrs *hdrs, const char *name, const char *tip) -{ - EMsgComposerHdrPair ret; - - ret.label = gtk_button_new_with_mnemonic (name); - GTK_OBJECT_UNSET_FLAGS (ret.label, GTK_CAN_FOCUS); - g_signal_connect_data (ret.label, "clicked", - G_CALLBACK (address_button_clicked_cb), - e_msg_composer_hdrs_and_string_create (hdrs, name), - (GClosureNotify) e_msg_composer_hdrs_and_string_free, - 0); - - gtk_tooltips_set_tip (hdrs->priv->tooltips, ret.label, - _("Click here for the address book"), - NULL); - - ret.entry = create_addressbook_entry (hdrs, name); - ret.visible = FALSE; - - return ret; -} - -static void -entry_changed (GtkWidget *entry, EMsgComposerHdrs *hdrs) -{ - const char *subject; - - subject = e_msg_composer_hdrs_get_subject (hdrs); - g_signal_emit (hdrs, signals[SUBJECT_CHANGED], 0, subject); - g_signal_emit (hdrs, signals[HDRS_CHANGED], 0); -} - -static void -create_headers (EMsgComposerHdrs *hdrs) -{ - EMsgComposerHdrsPrivate *priv = hdrs->priv; - AtkObject *a11y; - - /* - * Reply-To: - * - * Create this before we call create_from_optionmenu, - * because that causes from_changed to be called, which - * expects the reply_to fields to be initialized. - */ - priv->reply_to.label = gtk_label_new_with_mnemonic (_("_Reply-To:")); - priv->reply_to.entry = gtk_entry_new (); - gtk_label_set_mnemonic_widget((GtkLabel *)priv->reply_to.label, priv->reply_to.entry); - - /* - * From - */ - priv->from.label = gtk_label_new_with_mnemonic (_("Fr_om:")); - priv->from.entry = create_from_optionmenu (hdrs); - gtk_label_set_mnemonic_widget((GtkLabel *)priv->from.label, e_msg_composer_hdrs_get_from_omenu (hdrs)); - - /* - * Subject - */ - priv->subject.label = gtk_label_new_with_mnemonic (_("S_ubject:")); - priv->subject.entry = gtk_entry_new (); - gtk_label_set_mnemonic_widget((GtkLabel *)priv->subject.label, priv->subject.entry); - g_signal_connect(priv->subject.entry, "changed", G_CALLBACK(entry_changed), hdrs); - connect_entry_for_tooltip (priv->subject.entry); - - /* - * To, CC, and Bcc - */ - priv->to = header_new_recipient ( - hdrs, _("_To:"), - _("Enter the recipients of the message")); - - priv->cc = header_new_recipient ( - hdrs, _("_Cc:"), - _("Enter the addresses that will receive a carbon copy of the message")); - - priv->bcc = header_new_recipient ( - hdrs, _("_Bcc:"), - _("Enter the addresses that will receive a carbon copy of " - "the message without appearing in the recipient list of " - "the message.")); - - /* - * Post-To - */ - priv->post_to.label = gtk_button_new_with_mnemonic (_("_Post To:")); - GTK_OBJECT_UNSET_FLAGS (priv->post_to.label, GTK_CAN_FOCUS); - g_signal_connect (priv->post_to.label, "clicked", - G_CALLBACK (post_browser_clicked_cb), hdrs); - gtk_tooltips_set_tip (hdrs->priv->tooltips, priv->post_to.label, - _("Click here to select folders to post to"), - NULL); - - priv->post_to.entry = gtk_entry_new (); - if ((a11y = gtk_widget_get_accessible (priv->post_to.entry))) - atk_object_set_name (a11y, _("Post To:")); - - g_signal_connect(priv->post_to.entry, "changed", - G_CALLBACK (post_entry_changed_cb), hdrs); - - connect_entry_for_tooltip (priv->post_to.entry); -} - -static void -attach_couple (EMsgComposerHdrs *hdrs, EMsgComposerHdrPair *pair, int line) -{ - gtk_table_attach (GTK_TABLE (hdrs), - pair->label, 0, 1, - line, line + 1, - GTK_FILL, GTK_FILL, 3, 3); - - if (line == LINE_TO || line == LINE_CC || line == LINE_BCC) { - gtk_table_attach (GTK_TABLE (hdrs), - pair->entry, 1, 2, - line, line + 1, - GTK_FILL | GTK_EXPAND, 0, 3, 3); - } - else { - gtk_table_attach (GTK_TABLE (hdrs), - pair->entry, 1, 2, - line, line + 1, - GTK_FILL | GTK_EXPAND, 0, 3, 3); - } -} - -static void -attach_headers (EMsgComposerHdrs *hdrs) -{ - EMsgComposerHdrsPrivate *p = hdrs->priv; - - attach_couple (hdrs, &p->from, LINE_FROM); - attach_couple (hdrs, &p->reply_to, LINE_REPLYTO); - attach_couple (hdrs, &p->to, LINE_TO); - attach_couple (hdrs, &p->cc, LINE_CC); - attach_couple (hdrs, &p->bcc, LINE_BCC); - attach_couple (hdrs, &p->post_to, LINE_POSTTO); - attach_couple (hdrs, &p->subject, LINE_SUBJECT); -} - -static void -set_pair_visibility (EMsgComposerHdrs *h, EMsgComposerHdrPair *pair, int visible) -{ - if (visible /*& h->visible_mask*/) { - gtk_widget_show (pair->label); - gtk_widget_show (pair->entry); - } else { - gtk_widget_hide (pair->label); - gtk_widget_hide (pair->entry); - } - - pair->visible = TRUE; + g_signal_emit (hdrs, signal_ids[FROM_CHANGED], 0); } static void @@ -786,13 +115,27 @@ headers_set_visibility (EMsgComposerHdrs *h, int visible_flags) else visible_flags |= E_MSG_COMPOSER_VISIBLE_POSTTO; - set_pair_visibility (h, &p->from, visible_flags & E_MSG_COMPOSER_VISIBLE_FROM); - set_pair_visibility (h, &p->reply_to, visible_flags & E_MSG_COMPOSER_VISIBLE_REPLYTO); - set_pair_visibility (h, &p->to, visible_flags & E_MSG_COMPOSER_VISIBLE_TO); - set_pair_visibility (h, &p->cc, visible_flags & E_MSG_COMPOSER_VISIBLE_CC); - set_pair_visibility (h, &p->bcc, visible_flags & E_MSG_COMPOSER_VISIBLE_BCC); - set_pair_visibility (h, &p->post_to, visible_flags & E_MSG_COMPOSER_VISIBLE_POSTTO); - set_pair_visibility (h, &p->subject, visible_flags & E_MSG_COMPOSER_VISIBLE_SUBJECT); + e_composer_header_set_visible ( + p->headers[HEADER_FROM], + visible_flags & E_MSG_COMPOSER_VISIBLE_FROM); + e_composer_header_set_visible ( + p->headers[HEADER_REPLY_TO], + visible_flags & E_MSG_COMPOSER_VISIBLE_REPLYTO); + e_composer_header_set_visible ( + p->headers[HEADER_TO], + visible_flags & E_MSG_COMPOSER_VISIBLE_TO); + e_composer_header_set_visible ( + p->headers[HEADER_CC], + visible_flags & E_MSG_COMPOSER_VISIBLE_CC); + e_composer_header_set_visible ( + p->headers[HEADER_BCC], + visible_flags & E_MSG_COMPOSER_VISIBLE_BCC); + e_composer_header_set_visible ( + p->headers[HEADER_POST_TO], + visible_flags & E_MSG_COMPOSER_VISIBLE_POSTTO); + e_composer_header_set_visible ( + p->headers[HEADER_SUBJECT], + visible_flags & E_MSG_COMPOSER_VISIBLE_SUBJECT); } static void @@ -826,91 +169,78 @@ e_msg_composer_hdrs_set_visible (EMsgComposerHdrs *hdrs, int visible_flags) gtk_widget_queue_resize (GTK_WIDGET (hdrs)); } -static void -setup_headers (EMsgComposerHdrs *hdrs, int visible_flags) +static GObject * +msg_composer_hdrs_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { - create_headers (hdrs); - attach_headers (hdrs); + GObject *object; + EMsgComposerHdrsPrivate *priv; + guint rows, ii; - headers_set_sensitivity (hdrs); - headers_set_visibility (hdrs, visible_flags); -} + /* Chain up to parent's constructor() method. */ + object = G_OBJECT_CLASS (parent_class)->constructor ( + type, n_construct_properties, construct_properties); - -/* GtkObject methods. */ + priv = E_MSG_COMPOSER_HDRS_GET_PRIVATE (object); -static void -destroy (GtkObject *object) -{ - EMsgComposerHdrs *hdrs; - EMsgComposerHdrsPrivate *priv; - GSList *l, *n; + rows = G_N_ELEMENTS (priv->headers); + gtk_table_resize (GTK_TABLE (object), rows, 2); + gtk_table_set_row_spacings (GTK_TABLE (object), 0); + gtk_table_set_col_spacings (GTK_TABLE (object), 6); - hdrs = E_MSG_COMPOSER_HDRS (object); - priv = hdrs->priv; + /* Use "ypadding" instead of "row-spacing" because some rows may + * be invisible and we don't want spacing around them. */ - if (priv) { - if (priv->name_selector != NULL) { - g_object_unref (priv->name_selector); - priv->name_selector = NULL; - } + for (ii = 0; ii < rows; ii++) { + gtk_table_attach ( + GTK_TABLE (object), priv->headers[ii]->title_widget, + 0, 1, ii, ii + 1, GTK_FILL, GTK_FILL, 0, 3); + gtk_table_attach ( + GTK_TABLE (object), priv->headers[ii]->input_widget, + 1, 2, ii, ii + 1, GTK_FILL | GTK_EXPAND, 0, 0, 3); + } - if (priv->tooltips) { - gtk_object_destroy (GTK_OBJECT (priv->tooltips)); - g_object_unref (priv->tooltips); - priv->tooltips = NULL; - } + return object; +} - if (priv->accounts) { - g_signal_handlers_disconnect_matched(priv->accounts, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, hdrs); - g_object_unref (priv->accounts); - priv->accounts = NULL; - } +static void +msg_composer_hdrs_dispose (GObject *object) +{ + EMsgComposerHdrsPrivate *priv; + gint ii; - l = priv->from_options; - while (l) { - EAccount *account; - GtkWidget *item = l->data; + priv = E_MSG_COMPOSER_HDRS_GET_PRIVATE (object); - account = g_object_get_data ((GObject *) item, "account"); - g_object_unref (account); + if (priv->name_selector != NULL) { + g_object_unref (priv->name_selector); + priv->name_selector = NULL; + } - n = l->next; - g_slist_free_1 (l); - l = n; + for (ii = 0; ii < G_N_ELEMENTS (priv->headers); ii++) { + if (priv->headers[ii] != NULL) { + g_object_unref (priv->headers[ii]); + priv->headers[ii] = NULL; } - - priv->from_options = NULL; - - g_free (priv); - hdrs->priv = NULL; } - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } - static void -class_init (EMsgComposerHdrsClass *class) +msg_composer_hdrs_class_init (EMsgComposerHdrsClass *class) { - GtkObjectClass *object_class; + GObjectClass *object_class; - object_class = GTK_OBJECT_CLASS (class); - object_class->destroy = destroy; + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMsgComposerHdrsPrivate)); - parent_class = g_type_class_ref (gtk_table_get_type ()); + object_class = G_OBJECT_CLASS (class); + object_class->constructor = msg_composer_hdrs_constructor; + object_class->dispose = msg_composer_hdrs_dispose; - signals[SHOW_ADDRESS_DIALOG] = - g_signal_new ("show_address_dialog", - E_TYPE_MSG_COMPOSER_HDRS, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(EMsgComposerHdrsClass, show_address_dialog), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[SUBJECT_CHANGED] = + signal_ids[SUBJECT_CHANGED] = g_signal_new ("subject_changed", E_TYPE_MSG_COMPOSER_HDRS, G_SIGNAL_RUN_LAST, @@ -920,7 +250,7 @@ class_init (EMsgComposerHdrsClass *class) G_TYPE_NONE, 1, G_TYPE_STRING); - signals[HDRS_CHANGED] = + signal_ids[HDRS_CHANGED] = g_signal_new ("hdrs_changed", E_TYPE_MSG_COMPOSER_HDRS, G_SIGNAL_RUN_LAST, @@ -929,7 +259,7 @@ class_init (EMsgComposerHdrsClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - signals[FROM_CHANGED] = + signal_ids[FROM_CHANGED] = g_signal_new ("from_changed", E_TYPE_MSG_COMPOSER_HDRS, G_SIGNAL_RUN_LAST, @@ -940,43 +270,77 @@ class_init (EMsgComposerHdrsClass *class) } static void -init (EMsgComposerHdrs *hdrs) +msg_composer_hdrs_init (EMsgComposerHdrs *hdrs) { - EMsgComposerHdrsPrivate *priv; + EComposerHeader *header; + ENameSelector *name_selector; + + hdrs->priv = E_MSG_COMPOSER_HDRS_GET_PRIVATE (hdrs); + + name_selector = e_name_selector_new (); + + hdrs->priv->name_selector = name_selector; + + header = e_composer_from_header_new (_("Fr_om:")); + g_signal_connect ( + header, "changed", + G_CALLBACK (from_changed), hdrs); + hdrs->priv->headers[HEADER_FROM] = header; + + header = e_composer_text_header_new_label (_("_Reply-To:")); + hdrs->priv->headers[HEADER_REPLY_TO] = header; - priv = g_new0 (EMsgComposerHdrsPrivate, 1); + header = e_composer_name_header_new (_("_To:"), name_selector); + e_composer_header_set_input_tooltip ( + header, _("Enter the recipients of the message")); + hdrs->priv->headers[HEADER_TO] = header; - priv->tooltips = gtk_tooltips_new (); - g_object_ref_sink (priv->tooltips); + header = e_composer_name_header_new (_("_Cc:"), name_selector); + e_composer_header_set_input_tooltip ( + header, _("Enter the addresses that will receive a " + "carbon copy of the message")); + hdrs->priv->headers[HEADER_CC] = header; - priv->accounts = mail_config_get_accounts (); - g_object_ref (priv->accounts); + header = e_composer_name_header_new (_("_Bcc:"), name_selector); + e_composer_header_set_input_tooltip ( + header, _("Enter the addresses that will receive a " + "carbon copy of the message without appearing in the " + "recipient list of the message")); + hdrs->priv->headers[HEADER_BCC] = header; - priv->post_custom = FALSE; + header = e_composer_post_header_new (_("_Post To:")); + hdrs->priv->headers[HEADER_POST_TO] = header; - hdrs->priv = priv; + header = e_composer_text_header_new_label (_("S_ubject:")); + hdrs->priv->headers[HEADER_SUBJECT] = header; + + /* Do this after all the headers are initialized. */ + e_composer_from_header_set_account_list ( + E_COMPOSER_FROM_HEADER (hdrs->priv->headers[HEADER_FROM]), + mail_config_get_accounts ()); } - GType e_msg_composer_hdrs_get_type (void) { static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { sizeof (EMsgComposerHdrsClass), - NULL, - NULL, - (GClassInitFunc) class_init, - NULL, - NULL, + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) msg_composer_hdrs_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ sizeof (EMsgComposerHdrs), - 0, - (GInstanceInitFunc) init, + 0, /* n_preallocs */ + (GInstanceInitFunc) msg_composer_hdrs_init, + NULL /* value_table */ }; - type = g_type_register_static (gtk_table_get_type (), "EMsgComposerHdrs", &info, 0); + type = g_type_register_static ( + GTK_TYPE_TABLE, "EMsgComposerHdrs", &type_info, 0); } return type; @@ -988,17 +352,16 @@ e_msg_composer_hdrs_new (BonoboUIComponent *uic, int visible_mask, int visible_f EMsgComposerHdrs *new; EMsgComposerHdrsPrivate *priv; - new = g_object_new (e_msg_composer_hdrs_get_type (), NULL); + new = g_object_new (E_TYPE_MSG_COMPOSER_HDRS, NULL); priv = new->priv; priv->uic = uic; g_object_ref_sink (new); - setup_name_selector (new); - new->visible_mask = visible_mask; - setup_headers (new, visible_flags); + headers_set_sensitivity (new); + headers_set_visibility (new, visible_flags); return GTK_WIDGET (new); } @@ -1094,6 +457,7 @@ e_msg_composer_hdrs_to_message_internal (EMsgComposerHdrs *hdrs, EDestination **to_destv, **cc_destv, **bcc_destv; CamelInternetAddress *addr; const char *subject; + gboolean visible; char *header; g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); @@ -1118,7 +482,15 @@ e_msg_composer_hdrs_to_message_internal (EMsgComposerHdrs *hdrs, camel_object_unref (addr); } - if (hdrs->priv->to.visible || hdrs->priv->cc.visible || hdrs->priv->bcc.visible) { + visible = + e_composer_header_get_visible ( + hdrs->priv->headers[HEADER_TO]) || + e_composer_header_get_visible ( + hdrs->priv->headers[HEADER_CC]) || + e_composer_header_get_visible ( + hdrs->priv->headers[HEADER_BCC]); + + if (visible) { to_destv = e_msg_composer_hdrs_get_to (hdrs); cc_destv = e_msg_composer_hdrs_get_cc (hdrs); bcc_destv = e_msg_composer_hdrs_get_bcc (hdrs); @@ -1132,7 +504,10 @@ e_msg_composer_hdrs_to_message_internal (EMsgComposerHdrs *hdrs, e_destination_freev (bcc_destv); } - if (hdrs->priv->post_to.visible) { + visible = e_composer_header_get_visible ( + hdrs->priv->headers[HEADER_POST_TO]); + + if (visible) { GList *post, *l; camel_medium_remove_header((CamelMedium *)msg, "X-Evolution-PostTo"); @@ -1161,133 +536,93 @@ e_msg_composer_hdrs_to_redirect (EMsgComposerHdrs *hdrs, e_msg_composer_hdrs_to_message_internal (hdrs, msg, TRUE); } - -/* FIXME: yea, this could be better... but it's doubtful it'll be used much */ -void -e_msg_composer_hdrs_set_from_account (EMsgComposerHdrs *hdrs, - const char *account_name) +EAccount * +e_msg_composer_hdrs_get_from_account (EMsgComposerHdrs *hdrs) { - GtkOptionMenu *omenu; - GConfClient *gconf; - GtkWidget *item; - char *uid = NULL; - GSList *l; - int i = 0; + EComposerFromHeader *header; - g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - omenu = GTK_OPTION_MENU (e_msg_composer_hdrs_get_from_omenu (hdrs)); + header = E_COMPOSER_FROM_HEADER (hdrs->priv->headers[HEADER_FROM]); + return e_composer_from_header_get_active (header); +} - if (!account_name) { - gconf = gconf_client_get_default (); - uid = gconf_client_get_string (gconf, "/apps/evolution/mail/default_account", NULL); - g_object_unref (gconf); - } +gboolean +e_msg_composer_hdrs_set_from_account (EMsgComposerHdrs *hdrs, + const gchar *account_name) +{ + EComposerFromHeader *header; - /* find the item that represents the account and activate it */ - l = hdrs->priv->from_options; - while (l) { - EAccount *account; - item = l->data; - - account = g_object_get_data ((GObject *) item, "account"); - if (account_can_send (account)) { - if (account_name) { - if (account->name && !strcmp (account_name, account->name)) { - /* set the correct optionlist item */ - gtk_option_menu_set_history (omenu, i); - g_signal_emit_by_name (item, "activate", hdrs); - g_free (uid); - - return; - } - } else if (uid && !strcmp (account->uid, uid)) { - /* set the default optionlist item */ - gtk_option_menu_set_history (omenu, i); - g_signal_emit_by_name (item, "activate", hdrs); - g_free (uid); + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), FALSE); - return; - } - } - l = l->next; - i++; - } - - g_free (uid); + header = E_COMPOSER_FROM_HEADER (hdrs->priv->headers[HEADER_FROM]); + return e_composer_from_header_set_active_name (header, account_name); } void e_msg_composer_hdrs_set_reply_to (EMsgComposerHdrs *hdrs, - const char *reply_to) + const gchar *text) { - g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - - gtk_entry_set_text (GTK_ENTRY (hdrs->priv->reply_to.entry), reply_to ? reply_to : ""); - - if (reply_to && *reply_to) - set_pair_visibility (hdrs, &hdrs->priv->cc, TRUE); -} + EComposerHeader *header; -static void -destinations_to_name_selector_entry (ENameSelectorEntry *name_selector_entry, EDestination **destv) -{ - EDestinationStore *destination_store; - GList *destinations; - GList *l; - gint i; - - /* First clear the store */ - destination_store = e_name_selector_entry_peek_destination_store (name_selector_entry); - destinations = e_destination_store_list_destinations (destination_store); - - for (l = destinations; l; l = g_list_next (l)) { - EDestination *destination = l->data; - e_destination_store_remove_destination (destination_store, destination); - } + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - g_list_free (destinations); + header = hdrs->priv->headers[HEADER_REPLY_TO]; - if (!destv) - return; + e_composer_text_header_set_text ( + E_COMPOSER_TEXT_HEADER (header), text); - for (i = 0; destv [i]; i++) - e_destination_store_append_destination (destination_store, destv [i]); + if (*text != '\0') + e_composer_header_set_visible (header, TRUE); } void e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs, EDestination **to_destv) { + EComposerHeader *header; + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - destinations_to_name_selector_entry (E_NAME_SELECTOR_ENTRY (hdrs->priv->to.entry), to_destv); + header = hdrs->priv->headers[HEADER_TO]; + + e_composer_name_header_set_destinations ( + E_COMPOSER_NAME_HEADER (header), to_destv); } void e_msg_composer_hdrs_set_cc (EMsgComposerHdrs *hdrs, EDestination **cc_destv) { + EComposerHeader *header; + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - destinations_to_name_selector_entry (E_NAME_SELECTOR_ENTRY (hdrs->priv->cc.entry), cc_destv); + header = hdrs->priv->headers[HEADER_CC]; + + e_composer_name_header_set_destinations ( + E_COMPOSER_NAME_HEADER (header), cc_destv); - if (cc_destv && *cc_destv) - set_pair_visibility (hdrs, &hdrs->priv->cc, TRUE); + if (cc_destv != NULL && *cc_destv != NULL) + e_composer_header_set_visible (header, TRUE); } void e_msg_composer_hdrs_set_bcc (EMsgComposerHdrs *hdrs, EDestination **bcc_destv) { + EComposerHeader *header; + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - destinations_to_name_selector_entry (E_NAME_SELECTOR_ENTRY (hdrs->priv->bcc.entry), bcc_destv); + header = hdrs->priv->headers[HEADER_BCC]; - if (bcc_destv && *bcc_destv) - set_pair_visibility (hdrs, &hdrs->priv->bcc, TRUE); -} + e_composer_name_header_set_destinations ( + E_COMPOSER_NAME_HEADER (header), bcc_destv); + if (bcc_destv != NULL && *bcc_destv != NULL) + e_composer_header_set_visible (header, TRUE); +} void e_msg_composer_hdrs_set_post_to (EMsgComposerHdrs *hdrs, @@ -1306,175 +641,82 @@ e_msg_composer_hdrs_set_post_to (EMsgComposerHdrs *hdrs, g_list_free (list); } -static GList * -newsgroups_list_split (const char *list) -{ - GList *lst = NULL; - char *tmp; - char **items, **cur_ptr; - - cur_ptr = items = g_strsplit (list, ",", 0); - - while ((tmp = *cur_ptr) != NULL) { - g_strstrip (tmp); - - if (tmp[0]) - lst = g_list_append (lst, g_strdup (tmp)); - - cur_ptr++; - } - - g_strfreev (items); - - return lst; -} - -static char * -get_account_store_url (EMsgComposerHdrs *hdrs) -{ - CamelURL *url; - char *ret = NULL; - - if (hdrs->account->source - && hdrs->account->source->url - && hdrs->account->source->url[0] - && (url = camel_url_new (hdrs->account->source->url, NULL))) { - ret = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); - camel_url_free (url); - } - - return ret; -} - -static char * -folder_name_to_string (EMsgComposerHdrs *hdrs, const char *uri) -{ - char *storeurl = get_account_store_url (hdrs); - int len; - - if (storeurl) { - len = strlen (storeurl); - - if (g_ascii_strncasecmp (uri, storeurl, len) == 0) { - g_free (storeurl); - return g_strdup (uri + len); - } - - g_free (storeurl); - } - - return g_strdup (uri); -} - void e_msg_composer_hdrs_set_post_to_list (EMsgComposerHdrs *hdrs, GList *urls) { - GString *caption; - char *tmp; - gboolean post_custom; - - if (hdrs->priv->post_to.entry == NULL) - return; - - caption = g_string_new(""); - while (urls) { - tmp = folder_name_to_string(hdrs, (char *)urls->data); - if (tmp) { - if (caption->len) - g_string_append(caption, ", "); - g_string_append(caption, tmp); - } + EComposerHeader *header; - urls = g_list_next (urls); - } + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); - post_custom = hdrs->priv->post_custom; - gtk_entry_set_text(GTK_ENTRY(hdrs->priv->post_to.entry), caption->str); - hdrs->priv->post_custom = post_custom; + header = hdrs->priv->headers[HEADER_POST_TO]; - g_string_free(caption, TRUE); + e_composer_post_header_set_folders ( + E_COMPOSER_POST_HEADER (header), urls); } void -e_msg_composer_hdrs_set_post_to_base (EMsgComposerHdrs *hdrs, const char *base, const char *post_to) +e_msg_composer_hdrs_set_post_to_base (EMsgComposerHdrs *hdrs, + const gchar *base, + const gchar *post_to) { - GList *lst, *curlist; - char *tmp, *tmp2; - gboolean post_custom; - GString *caption; - - /* split to newsgroup names */ - lst = newsgroups_list_split(post_to); - curlist = lst; - - caption = g_string_new(""); - while (curlist) { - /* FIXME: this doens't handle all folder names properly */ - tmp2 = g_strdup_printf ("%s/%s", base, (char *)curlist->data); - tmp = folder_name_to_string (hdrs, tmp2); - g_free (tmp2); - if (tmp) { - if (caption->len) - g_string_append(caption, ", "); - g_string_append(caption, tmp); - } - curlist = g_list_next(curlist); - } + EComposerHeader *header; - post_custom = hdrs->priv->post_custom; - gtk_entry_set_text(GTK_ENTRY(hdrs->priv->post_to.entry), caption->str); - hdrs->priv->post_custom = post_custom; + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); + + header = hdrs->priv->headers[HEADER_POST_TO]; - g_string_free(caption, TRUE); - g_list_foreach(lst, (GFunc)g_free, NULL); - g_list_free(lst); + e_composer_post_header_set_folders_base ( + E_COMPOSER_POST_HEADER (header), base, post_to); } void e_msg_composer_hdrs_set_subject (EMsgComposerHdrs *hdrs, - const char *subject) + const gchar *subject) { + EComposerHeader *header; + g_return_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs)); g_return_if_fail (subject != NULL); - gtk_entry_set_text ((GtkEntry *) hdrs->priv->subject.entry, subject); + header = hdrs->priv->headers[HEADER_SUBJECT]; + + e_composer_text_header_set_text ( + E_COMPOSER_TEXT_HEADER (header), subject); } CamelInternetAddress * e_msg_composer_hdrs_get_from (EMsgComposerHdrs *hdrs) { - CamelInternetAddress *addr; - EAccount *account; + EComposerHeader *header; g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - if (!(account = hdrs->account)) { - /* FIXME: perhaps we should try the default account? */ - return NULL; - } - - addr = camel_internet_address_new (); - camel_internet_address_add (addr, account->id->name, account->id->address); + header = hdrs->priv->headers[HEADER_FROM]; - return addr; + return e_composer_from_header_get_active_address ( + E_COMPOSER_FROM_HEADER (header)); } CamelInternetAddress * e_msg_composer_hdrs_get_reply_to (EMsgComposerHdrs *hdrs) { CamelInternetAddress *addr; - const char *reply_to; + EComposerHeader *header; + const gchar *text; g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - reply_to = gtk_entry_get_text (GTK_ENTRY (hdrs->priv->reply_to.entry)); + header = hdrs->priv->headers[HEADER_REPLY_TO]; + + text = e_composer_text_header_get_text ( + E_COMPOSER_TEXT_HEADER (header)); - if (!reply_to || *reply_to == '\0') + if (text == NULL || *text == '\0') return NULL; addr = camel_internet_address_new (); - if (camel_address_unformat (CAMEL_ADDRESS (addr), reply_to) == -1) { + if (camel_address_unformat (CAMEL_ADDRESS (addr), text) == -1) { camel_object_unref (CAMEL_OBJECT (addr)); return NULL; } @@ -1482,66 +724,37 @@ e_msg_composer_hdrs_get_reply_to (EMsgComposerHdrs *hdrs) return addr; } -static EDestination ** -destination_list_to_destv (GList *destinations) -{ - EDestination **destv; - GList *l; - gint n, i; - - n = g_list_length (destinations); - - destv = g_new0 (EDestination *, n + 1); - - for (i = 0, l = destinations; l; i++, l = g_list_next (l)) { - EDestination *destination = l->data; - - /* Need to ref, as users expect to own it */ - g_object_ref (destination); - destv [i] = l->data; - } - - return destv; -} - -static EDestination ** -e_msg_composer_hdrs_get_internal (EMsgComposerHdrs *hdrs, ENameSelectorEntry *entry) -{ - EDestinationStore *destination_store; - GList *destinations; - EDestination **destv = NULL; - - destination_store = e_name_selector_entry_peek_destination_store (entry); - destinations = e_destination_store_list_destinations (destination_store); - - destv = destination_list_to_destv (destinations); - - g_list_free (destinations); - return destv; -} - EDestination ** e_msg_composer_hdrs_get_to (EMsgComposerHdrs *hdrs) { + EComposerNameHeader *header; + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return e_msg_composer_hdrs_get_internal (hdrs, E_NAME_SELECTOR_ENTRY (hdrs->priv->to.entry)); + header = E_COMPOSER_NAME_HEADER (hdrs->priv->headers[HEADER_TO]); + return e_composer_name_header_get_destinations (header); } EDestination ** e_msg_composer_hdrs_get_cc (EMsgComposerHdrs *hdrs) { + EComposerNameHeader *header; + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return e_msg_composer_hdrs_get_internal (hdrs, E_NAME_SELECTOR_ENTRY (hdrs->priv->cc.entry)); + header = E_COMPOSER_NAME_HEADER (hdrs->priv->headers[HEADER_CC]); + return e_composer_name_header_get_destinations (header); } EDestination ** e_msg_composer_hdrs_get_bcc (EMsgComposerHdrs *hdrs) { + EComposerNameHeader *header; + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return e_msg_composer_hdrs_get_internal (hdrs, E_NAME_SELECTOR_ENTRY (hdrs->priv->bcc.entry)); + header = E_COMPOSER_NAME_HEADER (hdrs->priv->headers[HEADER_BCC]); + return e_composer_name_header_get_destinations (header); } EDestination ** @@ -1595,47 +808,27 @@ e_msg_composer_hdrs_get_recipients (EMsgComposerHdrs *hdrs) GList * e_msg_composer_hdrs_get_post_to (EMsgComposerHdrs *hdrs) { - GList *uris, *cur; - char *storeurl = NULL, *tmp; + EComposerHeader *header; g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - if (hdrs->priv->post_to.entry == NULL) - return NULL; - - tmp = g_strdup (gtk_entry_get_text (GTK_ENTRY (hdrs->priv->post_to.entry))); - uris = newsgroups_list_split (tmp); - g_free (tmp); - - cur = uris; - while (cur) { - /* FIXME: this is a bit of a hack, should use camelurl's etc */ - if (strstr ((char *) cur->data, ":/") == NULL) { - /* relative folder name: convert to absolute */ - if (!storeurl) - storeurl = get_account_store_url (hdrs); - if (!storeurl) - break; - tmp = g_strconcat (storeurl, cur->data, NULL); - g_free (cur->data); - cur->data = tmp; - } - - cur = cur->next; - } - - g_free (storeurl); + header = hdrs->priv->headers[HEADER_POST_TO]; - return uris; + return e_composer_post_header_get_folders ( + E_COMPOSER_POST_HEADER (header)); } -const char * +const gchar * e_msg_composer_hdrs_get_subject (EMsgComposerHdrs *hdrs) { + GtkWidget *widget; + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return gtk_entry_get_text ((GtkEntry *) hdrs->priv->subject.entry); + widget = e_msg_composer_hdrs_get_subject_entry (hdrs); + + return gtk_entry_get_text (GTK_ENTRY (widget)); } @@ -1644,7 +837,7 @@ e_msg_composer_hdrs_get_reply_to_entry (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->reply_to.entry; + return hdrs->priv->headers[HEADER_REPLY_TO]->input_widget; } GtkWidget * @@ -1652,7 +845,7 @@ e_msg_composer_hdrs_get_to_entry (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->to.entry; + return hdrs->priv->headers[HEADER_TO]->input_widget; } GtkWidget * @@ -1660,7 +853,7 @@ e_msg_composer_hdrs_get_cc_entry (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->cc.entry; + return hdrs->priv->headers[HEADER_CC]->input_widget; } GtkWidget * @@ -1668,7 +861,7 @@ e_msg_composer_hdrs_get_bcc_entry (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->bcc.entry; + return hdrs->priv->headers[HEADER_BCC]->input_widget; } GtkWidget * @@ -1676,7 +869,7 @@ e_msg_composer_hdrs_get_post_to_label (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->post_to.entry; + return hdrs->priv->headers[HEADER_POST_TO]->input_widget; } GtkWidget * @@ -1684,7 +877,7 @@ e_msg_composer_hdrs_get_subject_entry (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->subject.entry; + return hdrs->priv->headers[HEADER_SUBJECT]->input_widget; } GtkWidget * @@ -1692,14 +885,5 @@ e_msg_composer_hdrs_get_from_hbox (EMsgComposerHdrs *hdrs) { g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - return hdrs->priv->from.entry; + return hdrs->priv->headers[HEADER_FROM]->input_widget; } - -GtkWidget * -e_msg_composer_hdrs_get_from_omenu (EMsgComposerHdrs *hdrs) -{ - g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); - - return GTK_WIDGET (g_object_get_data ((GObject *) hdrs->priv->from.entry, "from_menu")); -} - -- cgit v1.2.3