diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2007-12-02 09:41:04 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2007-12-02 09:41:04 +0800 |
commit | 8266bb685a189d8560450ff161efdd5629849f11 (patch) | |
tree | f86f9368649f2a036730a704fb97c12160c10365 | |
parent | 253452654a4bc2fdd44f61446890ccf556c82958 (diff) | |
download | gsoc2013-evolution-8266bb685a189d8560450ff161efdd5629849f11.tar.gz gsoc2013-evolution-8266bb685a189d8560450ff161efdd5629849f11.tar.zst gsoc2013-evolution-8266bb685a189d8560450ff161efdd5629849f11.zip |
** Fixes part of bug #495123
2007-12-01 Matthew Barnes <mbarnes@redhat.com>
** Fixes part of bug #495123
* composer/e-msg-composer.c:
* composer/e-msg-composer-hdrs.h:
* composer/e-msg-composer-hdrs.c:
Move signature handling to e-msg-composer-hdrs.c.
Use an ESignatureComboBox.
* composer/e-composer-from-header.h:
* composer/e-composer-from-header.c:
Clean up the GtkHBox hack. The signature combo is now packed
directly into the GtkTable.
* composer/e-composer-name-header.c:
* composer/e-composer-text-header.c:
Code cleanup.
* widgets/misc/Makefile.am:
Add e-signature-combo-box.[ch].
* widget/misc/e-account-combo-box.c (account_combo_box_refresh_cb):
Make sure the EAccount isn't lost while swapping models.
* widget/misc/e-signature-combo-box.c:
* widget/misc/e-signature-combo-box.h:
New widget renders an ESignatureList as a combo box. Also listens
for changes to the ESignatureList and updates itself accordingly.
svn path=/trunk/; revision=34620
-rw-r--r-- | composer/ChangeLog | 19 | ||||
-rw-r--r-- | composer/e-composer-from-header.c | 53 | ||||
-rw-r--r-- | composer/e-composer-from-header.h | 2 | ||||
-rw-r--r-- | composer/e-composer-name-header.c | 18 | ||||
-rw-r--r-- | composer/e-composer-text-header.c | 19 | ||||
-rw-r--r-- | composer/e-msg-composer-hdrs.c | 82 | ||||
-rw-r--r-- | composer/e-msg-composer-hdrs.h | 4 | ||||
-rw-r--r-- | composer/e-msg-composer.c | 310 | ||||
-rw-r--r-- | widgets/misc/ChangeLog | 15 | ||||
-rw-r--r-- | widgets/misc/Makefile.am | 3 | ||||
-rw-r--r-- | widgets/misc/e-account-combo-box.c | 4 | ||||
-rw-r--r-- | widgets/misc/e-signature-combo-box.c | 338 | ||||
-rw-r--r-- | widgets/misc/e-signature-combo-box.h | 55 |
13 files changed, 606 insertions, 316 deletions
diff --git a/composer/ChangeLog b/composer/ChangeLog index 9a08ccf025..96984e9059 100644 --- a/composer/ChangeLog +++ b/composer/ChangeLog @@ -1,3 +1,22 @@ +2007-12-01 Matthew Barnes <mbarnes@redhat.com> + + ** Fixes part of bug #495123 + + * e-msg-composer.c: + * e-msg-composer-hdrs.h: + * e-msg-composer-hdrs.c: + Move signature handling to e-msg-composer-hdrs.c. + Use an ESignatureComboBox. + + * e-composer-from-header.h: + * e-composer-from-header.c: + Clean up the GtkHBox hack. The signature combo is now packed + directly into the GtkTable. + + * e-composer-name-header.c: + * e-composer-text-header.c: + Code cleanup. + 2007-11-29 Milan Crha <mcrha@redhat.com> ** Part of fix for bug #271551 diff --git a/composer/e-composer-from-header.c b/composer/e-composer-from-header.c index de4f8ac8e0..55f525326e 100644 --- a/composer/e-composer-from-header.c +++ b/composer/e-composer-from-header.c @@ -1,12 +1,8 @@ #include "e-composer-from-header.h" -#define E_COMPOSER_FROM_HEADER_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_COMPOSER_FROM_HEADER, EComposerFromHeaderPrivate)) - -struct _EComposerFromHeaderPrivate { - GtkWidget *combo_box; -}; +/* Convenience macro */ +#define E_COMPOSER_FROM_HEADER_GET_COMBO_BOX(header) \ + (E_ACCOUNT_COMBO_BOX (E_COMPOSER_HEADER (header)->input_widget)) static gpointer parent_class; @@ -18,50 +14,21 @@ composer_from_header_changed_cb (EAccountComboBox *combo_box, } static void -composer_from_header_dispose (GObject *object) -{ - EComposerFromHeaderPrivate *priv; - - priv = E_COMPOSER_FROM_HEADER_GET_PRIVATE (object); - - if (priv->combo_box != NULL) { - g_object_unref (priv->combo_box); - priv->combo_box = NULL; - } - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void composer_from_header_class_init (EComposerFromHeaderClass *class) { - GObjectClass *object_class; - parent_class = g_type_class_peek_parent (class); - g_type_class_add_private (class, sizeof (EComposerFromHeaderPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = composer_from_header_dispose; } static void composer_from_header_init (EComposerFromHeader *header) { - GtkWidget *hbox; GtkWidget *widget; - header->priv = E_COMPOSER_FROM_HEADER_GET_PRIVATE (header); - - hbox = g_object_ref_sink (gtk_hbox_new (FALSE, 6)); - E_COMPOSER_HEADER (header)->input_widget = hbox; - - widget = e_account_combo_box_new (); + widget = g_object_ref_sink (e_account_combo_box_new ()); g_signal_connect ( widget, "changed", G_CALLBACK (composer_from_header_changed_cb), header); - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - header->priv->combo_box = g_object_ref_sink (widget); + E_COMPOSER_HEADER (header)->input_widget = widget; gtk_widget_show (widget); } @@ -108,7 +75,7 @@ e_composer_from_header_set_account_list (EComposerFromHeader *header, g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header)); - combo_box = E_ACCOUNT_COMBO_BOX (header->priv->combo_box); + combo_box = E_COMPOSER_FROM_HEADER_GET_COMBO_BOX (header); e_account_combo_box_set_account_list (combo_box, account_list); } @@ -119,7 +86,7 @@ e_composer_from_header_get_active (EComposerFromHeader *header) g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - combo_box = E_ACCOUNT_COMBO_BOX (header->priv->combo_box); + combo_box = E_COMPOSER_FROM_HEADER_GET_COMBO_BOX (header); return e_account_combo_box_get_active (combo_box); } @@ -131,7 +98,7 @@ e_composer_from_header_set_active (EComposerFromHeader *header, g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), FALSE); - combo_box = E_ACCOUNT_COMBO_BOX (header->priv->combo_box); + combo_box = E_COMPOSER_FROM_HEADER_GET_COMBO_BOX (header); return e_account_combo_box_set_active (combo_box, account); } @@ -142,7 +109,7 @@ e_composer_from_header_get_active_name (EComposerFromHeader *header) g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - combo_box = E_ACCOUNT_COMBO_BOX (header->priv->combo_box); + combo_box = E_COMPOSER_FROM_HEADER_GET_COMBO_BOX (header); return e_account_combo_box_get_active_name (combo_box); } @@ -154,7 +121,7 @@ e_composer_from_header_set_active_name (EComposerFromHeader *header, g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), FALSE); - combo_box = E_ACCOUNT_COMBO_BOX (header->priv->combo_box); + combo_box = E_COMPOSER_FROM_HEADER_GET_COMBO_BOX (header); return e_account_combo_box_set_active_name (combo_box, account_name); } diff --git a/composer/e-composer-from-header.h b/composer/e-composer-from-header.h index 39fb09ca6b..cc5aa78235 100644 --- a/composer/e-composer-from-header.h +++ b/composer/e-composer-from-header.h @@ -33,11 +33,9 @@ G_BEGIN_DECLS typedef struct _EComposerFromHeader EComposerFromHeader; typedef struct _EComposerFromHeaderClass EComposerFromHeaderClass; -typedef struct _EComposerFromHeaderPrivate EComposerFromHeaderPrivate; struct _EComposerFromHeader { EComposerHeader parent; - EComposerFromHeaderPrivate *priv; }; struct _EComposerFromHeaderClass { diff --git a/composer/e-composer-name-header.c b/composer/e-composer-name-header.c index f54b50d87e..d9af95c500 100644 --- a/composer/e-composer-name-header.c +++ b/composer/e-composer-name-header.c @@ -10,6 +10,10 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_COMPOSER_NAME_HEADER, EComposerNameHeaderPrivate)) +/* Convenience macro */ +#define E_COMPOSER_NAME_HEADER_GET_ENTRY(header) \ + (E_NAME_SELECTOR_ENTRY (E_COMPOSER_HEADER (header)->input_widget)) + enum { PROP_0, PROP_NAME_SELECTOR @@ -250,15 +254,14 @@ e_composer_name_header_get_destinations (EComposerNameHeader *header) { EDestinationStore *store; EDestination **destinations; - GtkWidget *input_widget; + ENameSelectorEntry *entry; GList *list, *iter; gint ii = 0; g_return_val_if_fail (E_IS_COMPOSER_NAME_HEADER (header), NULL); - input_widget = E_COMPOSER_HEADER (header)->input_widget; - store = e_name_selector_entry_peek_destination_store ( - E_NAME_SELECTOR_ENTRY (input_widget)); + entry = E_COMPOSER_NAME_HEADER_GET_ENTRY (header); + store = e_name_selector_entry_peek_destination_store (entry); list = e_destination_store_list_destinations (store); destinations = g_new0 (EDestination *, g_list_length (list) + 1); @@ -276,15 +279,14 @@ e_composer_name_header_set_destinations (EComposerNameHeader *header, EDestination **destinations) { EDestinationStore *store; - GtkWidget *input_widget; + ENameSelectorEntry *entry; GList *list, *iter; gint ii; g_return_if_fail (E_IS_COMPOSER_NAME_HEADER (header)); - input_widget = E_COMPOSER_HEADER (header)->input_widget; - store = e_name_selector_entry_peek_destination_store ( - E_NAME_SELECTOR_ENTRY (input_widget)); + entry = E_COMPOSER_NAME_HEADER_GET_ENTRY (header); + store = e_name_selector_entry_peek_destination_store (entry); /* Clear the destination store. */ list = e_destination_store_list_destinations (store); diff --git a/composer/e-composer-text-header.c b/composer/e-composer-text-header.c index 4ef761e450..6d3626218f 100644 --- a/composer/e-composer-text-header.c +++ b/composer/e-composer-text-header.c @@ -1,5 +1,9 @@ #include "e-composer-text-header.h" +/* Convenience macro */ +#define E_COMPOSER_TEXT_HEADER_GET_ENTRY(header) \ + (GTK_ENTRY (E_COMPOSER_HEADER (header)->input_widget)) + static gpointer parent_class; static void @@ -96,25 +100,22 @@ e_composer_text_header_new_button (const gchar *label) const gchar * e_composer_text_header_get_text (EComposerTextHeader *header) { - GtkWidget *input_widget; + GtkEntry *entry; g_return_val_if_fail (E_IS_COMPOSER_TEXT_HEADER (header), NULL); - input_widget = E_COMPOSER_HEADER (header)->input_widget; - return gtk_entry_get_text (GTK_ENTRY (input_widget)); + entry = E_COMPOSER_TEXT_HEADER_GET_ENTRY (header); + return gtk_entry_get_text (entry); } void e_composer_text_header_set_text (EComposerTextHeader *header, const gchar *text) { - GtkWidget *input_widget; + GtkEntry *entry; g_return_if_fail (E_IS_COMPOSER_TEXT_HEADER (header)); - if (text == NULL) - text = ""; - - input_widget = E_COMPOSER_HEADER (header)->input_widget; - gtk_entry_set_text (GTK_ENTRY (input_widget), text); + entry = E_COMPOSER_TEXT_HEADER_GET_ENTRY (header); + gtk_entry_set_text (entry, (text != NULL) ? text : ""); } diff --git a/composer/e-msg-composer-hdrs.c b/composer/e-msg-composer-hdrs.c index 02208c14fa..471cc40dc2 100644 --- a/composer/e-msg-composer-hdrs.c +++ b/composer/e-msg-composer-hdrs.c @@ -41,6 +41,7 @@ #include "mail/mail-config.h" #include "mail/mail-session.h" #include "e-account-combo-box.h" +#include "e-signature-combo-box.h" #include "e-composer-header.h" #include "e-composer-from-header.h" @@ -68,6 +69,7 @@ enum { SUBJECT_CHANGED, HDRS_CHANGED, FROM_CHANGED, + SIGNATURE_CHANGED, LAST_SIGNAL }; @@ -78,6 +80,7 @@ struct _EMsgComposerHdrsPrivate { BonoboUIComponent *uic; EComposerHeader *headers[NUM_HEADERS]; + GtkWidget *signature_combo_box; }; static gpointer parent_class; @@ -105,6 +108,12 @@ from_changed (EComposerFromHeader *from_header, EMsgComposerHdrs *hdrs) } static void +signature_changed (EMsgComposerHdrs *hdrs) +{ + g_signal_emit (hdrs, signal_ids[SIGNATURE_CHANGED], 0); +} + +static void headers_set_visibility (EMsgComposerHdrs *h, int visible_flags) { EMsgComposerHdrsPrivate *p = h->priv; @@ -176,6 +185,7 @@ msg_composer_hdrs_constructor (GType type, { GObject *object; EMsgComposerHdrsPrivate *priv; + GtkWidget *widget; guint rows, ii; /* Chain up to parent's constructor() method. */ @@ -185,7 +195,7 @@ msg_composer_hdrs_constructor (GType type, priv = E_MSG_COMPOSER_HDRS_GET_PRIVATE (object); rows = G_N_ELEMENTS (priv->headers); - gtk_table_resize (GTK_TABLE (object), rows, 2); + gtk_table_resize (GTK_TABLE (object), rows, 4); gtk_table_set_row_spacings (GTK_TABLE (object), 0); gtk_table_set_col_spacings (GTK_TABLE (object), 6); @@ -198,9 +208,27 @@ msg_composer_hdrs_constructor (GType type, 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); + 1, 4, ii, ii + 1, GTK_FILL | GTK_EXPAND, 0, 0, 3); } + /* Leave room in the "From" row for signature stuff. */ + gtk_container_child_set ( + GTK_CONTAINER (object), + priv->headers[HEADER_FROM]->input_widget, + "right-attach", 2, NULL); + + /* Now add the signature stuff. */ + widget = gtk_label_new_with_mnemonic (_("Si_gnature:")); + gtk_table_attach ( + GTK_TABLE (object), widget, + 2, 3, HEADER_FROM, HEADER_FROM + 1, 0, 0, 0, 3); + gtk_table_attach ( + GTK_TABLE (object), priv->signature_combo_box, + 3, 4, HEADER_FROM, HEADER_FROM + 1, 0, 0, 0, 3); + gtk_label_set_mnemonic_widget ( + GTK_LABEL (widget), priv->signature_combo_box); + gtk_widget_show (widget); + return object; } @@ -224,6 +252,11 @@ msg_composer_hdrs_dispose (GObject *object) } } + if (priv->signature_combo_box != NULL) { + g_object_unref (priv->signature_combo_box); + priv->signature_combo_box = NULL; + } + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -267,6 +300,14 @@ msg_composer_hdrs_class_init (EMsgComposerHdrsClass *class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signal_ids[SIGNATURE_CHANGED] = + g_signal_new ("signature_changed", + E_TYPE_MSG_COMPOSER_HDRS, + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -274,6 +315,7 @@ msg_composer_hdrs_init (EMsgComposerHdrs *hdrs) { EComposerHeader *header; ENameSelector *name_selector; + GtkWidget *widget; hdrs->priv = E_MSG_COMPOSER_HDRS_GET_PRIVATE (hdrs); @@ -318,6 +360,19 @@ msg_composer_hdrs_init (EMsgComposerHdrs *hdrs) e_composer_from_header_set_account_list ( E_COMPOSER_FROM_HEADER (hdrs->priv->headers[HEADER_FROM]), mail_config_get_accounts ()); + + widget = e_signature_combo_box_new (); + e_signature_combo_box_set_signature_list ( + E_SIGNATURE_COMBO_BOX (widget), + mail_config_get_signatures ()); + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (signature_changed), hdrs); + g_signal_connect_swapped ( + widget, "refreshed", + G_CALLBACK (signature_changed), hdrs); + hdrs->priv->signature_combo_box = g_object_ref_sink (widget); + gtk_widget_show (widget); } GType @@ -559,6 +614,29 @@ e_msg_composer_hdrs_set_from_account (EMsgComposerHdrs *hdrs, return e_composer_from_header_set_active_name (header, account_name); } +ESignature * +e_msg_composer_hdrs_get_signature (EMsgComposerHdrs *hdrs) +{ + ESignatureComboBox *combo_box; + + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), NULL); + + combo_box = E_SIGNATURE_COMBO_BOX (hdrs->priv->signature_combo_box); + return e_signature_combo_box_get_active (combo_box); +} + +gboolean +e_msg_composer_hdrs_set_signature (EMsgComposerHdrs *hdrs, + ESignature *signature) +{ + ESignatureComboBox *combo_box; + + g_return_val_if_fail (E_IS_MSG_COMPOSER_HDRS (hdrs), FALSE); + + combo_box = E_SIGNATURE_COMBO_BOX (hdrs->priv->signature_combo_box); + return e_signature_combo_box_set_active (combo_box, signature); +} + void e_msg_composer_hdrs_set_reply_to (EMsgComposerHdrs *hdrs, const gchar *text) diff --git a/composer/e-msg-composer-hdrs.h b/composer/e-msg-composer-hdrs.h index 1e983272a5..41a4299cc6 100644 --- a/composer/e-msg-composer-hdrs.h +++ b/composer/e-msg-composer-hdrs.h @@ -28,6 +28,7 @@ #include <bonobo/bonobo-ui-component.h> +#include <e-util/e-signature.h> #include <libedataserver/e-account.h> #include <camel/camel-mime-message.h> #include <libebook/e-destination.h> @@ -118,6 +119,9 @@ void e_msg_composer_hdrs_to_redirect (EMsgComposerHdrs *hdrs, EAccount * e_msg_composer_hdrs_get_from_account (EMsgComposerHdrs *hdrs); gboolean e_msg_composer_hdrs_set_from_account (EMsgComposerHdrs *hdrs, const char *account_name); +ESignature *e_msg_composer_hdrs_get_signature (EMsgComposerHdrs *hdrs); +gboolean e_msg_composer_hdrs_set_signature (EMsgComposerHdrs *hdrs, + ESignature *signature); void e_msg_composer_hdrs_set_reply_to (EMsgComposerHdrs *hdrs, const char *reply_to); void e_msg_composer_hdrs_set_to (EMsgComposerHdrs *hdrs, diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index 087e36ce39..8c47ceaaec 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -88,6 +88,7 @@ #include "e-util/e-util-private.h" #include "e-util/e-util.h" #include <mail/em-event.h> +#include "e-signature-combo-box.h" #include <camel/camel-session.h> #include <camel/camel-charset-map.h> @@ -188,7 +189,7 @@ struct _EMsgComposerPrivate { char *mime_type, *mime_body, *charset; char *autosave_file; - int autosave_fd; + int autosave_fd; guint32 enable_autosave : 1; guint32 attachment_bar_visible : 1; @@ -214,12 +215,6 @@ struct _EMsgComposerPrivate { guint32 in_signature_insert : 1; - struct _ESignature *signature; - struct _GtkOptionMenu *sig_menu; - guint sig_added_id; - guint sig_removed_id; - guint sig_changed_id; - CamelMimeMessage *redirect; guint notify_id; @@ -1247,23 +1242,27 @@ decode_signature_name (const char *name) static char * get_signature_html (EMsgComposer *composer) { - EMsgComposerPrivate *p = composer->priv; + EMsgComposerHdrs *hdrs; char *text = NULL, *html = NULL; + ESignature *signature; gboolean format_html; - if (!p->signature) + hdrs = E_MSG_COMPOSER_HDRS (composer->priv->hdrs); + signature = e_msg_composer_hdrs_get_signature (hdrs); + + if (!signature) return NULL; - if (!p->signature->autogen) { - if (!p->signature->filename) + if (!signature->autogen) { + if (!signature->filename) return NULL; - format_html = p->signature->html; + format_html = signature->html; - if (p->signature->script) { - text = mail_config_signature_run_script (p->signature->filename); + if (signature->script) { + text = mail_config_signature_run_script (signature->filename); } else { - text = e_msg_composer_get_sig_file_content (p->signature->filename, format_html); + text = e_msg_composer_get_sig_file_content (signature->filename, format_html); } } else { EAccountIdentity *id; @@ -1271,8 +1270,7 @@ get_signature_html (EMsgComposer *composer) char *address; char *name; - id = e_msg_composer_hdrs_get_from_account ( - E_MSG_COMPOSER_HDRS (p->hdrs))->id; + id = e_msg_composer_hdrs_get_from_account (hdrs)->id; address = id->address ? camel_text_to_html (id->address, CONVERT_SPACES, 0) : NULL; name = id->name ? camel_text_to_html (id->name, CONVERT_SPACES, 0) : NULL; organization = id->organization ? camel_text_to_html (id->organization, CONVERT_SPACES, 0) : NULL; @@ -1296,8 +1294,8 @@ get_signature_html (EMsgComposer *composer) if (text) { char *encoded_uid = NULL; - if (p->signature) - encoded_uid = encode_signature_name (p->signature->uid); + if (signature) + encoded_uid = encode_signature_name (signature->uid); /* The signature dash convention ("-- \n") is specified in the * "Son of RFC 1036": http://www.chemie.fu-berlin.de/outerspace/netnews/son-of-1036.html, @@ -1606,7 +1604,7 @@ autosave_load_draft (const char *filename) static gboolean autosave_is_owned (AutosaveManager *am, const char *file) { - return g_hash_table_lookup (am->table, file) != NULL; + return g_hash_table_lookup (am->table, file) != NULL; } static void @@ -2011,7 +2009,7 @@ menu_send_options_cb (BonoboUIComponent *component, void *data, const char *path EMsgComposer *composer = data; target = em_event_target_new_composer (e, composer, EM_EVENT_COMPOSER_SEND_OPTION); - e_msg_composer_set_send_options (composer, FALSE); + e_msg_composer_set_send_options (composer, FALSE); e_event_emit((EEvent *)e, "composer.selectsendoption", (EEventTarget *)target); if (!composer->priv->send_invoked) { e_error_run ((GtkWindow *)composer, "mail-composer:send-options-support", NULL); @@ -2296,176 +2294,6 @@ static EPixmap pixcache [] = { static void -signature_activate_cb (GtkWidget *menu, EMsgComposer *composer) -{ - GtkWidget *active; - ESignature *sig; - EMsgComposerPrivate *p = composer->priv; - - active = gtk_menu_get_active (GTK_MENU (menu)); - sig = g_object_get_data ((GObject *) active, "sig"); - - if (p->signature != sig) { - p->signature = sig; - e_msg_composer_show_sig_file (composer); - } -} - -static void -signature_added (ESignatureList *signatures, ESignature *sig, EMsgComposer *composer) -{ - GtkWidget *menu, *item; - EMsgComposerPrivate *p = composer->priv; - - menu = gtk_option_menu_get_menu (p->sig_menu); - - if (sig->autogen) - item = gtk_menu_item_new_with_label (_("Autogenerated")); - else - item = gtk_menu_item_new_with_label (sig->name); - g_object_set_data ((GObject *) item, "sig", sig); - gtk_widget_show (item); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); -} - -static void -signature_removed (ESignatureList *signatures, ESignature *sig, EMsgComposer *composer) -{ - GtkWidget *menu; - ESignature *cur; - GList *items; - EMsgComposerPrivate *p = composer->priv; - - if (p->signature == sig) { - p->signature = NULL; - e_msg_composer_show_sig_file (composer); - } - - menu = gtk_option_menu_get_menu (p->sig_menu); - items = GTK_MENU_SHELL (menu)->children; - while (items != NULL) { - cur = g_object_get_data (items->data, "sig"); - if (cur == sig) { - gtk_widget_destroy (items->data); - break; - } - items = items->next; - } -} - -static void -menu_item_set_label (GtkMenuItem *item, const char *label) -{ - GtkWidget *widget; - - widget = gtk_bin_get_child ((GtkBin *) item); - if (GTK_IS_LABEL (widget)) - gtk_label_set_text ((GtkLabel *) widget, label); -} - -static void -signature_changed (ESignatureList *signatures, ESignature *sig, EMsgComposer *composer) -{ - GtkWidget *menu; - ESignature *cur; - GList *items; - EMsgComposerPrivate *p = composer->priv; - - menu = gtk_option_menu_get_menu (p->sig_menu); - items = GTK_MENU_SHELL (menu)->children; - while (items != NULL) { - cur = g_object_get_data (items->data, "sig"); - if (cur == sig) { - menu_item_set_label (items->data, sig->name); - break; - } - items = items->next; - } -} - -static void -sig_select_item (EMsgComposer *composer) -{ - ESignature *cur; - GtkWidget *menu; - GList *items; - int i = 0; - EMsgComposerPrivate *p = composer->priv; - - if (!p->signature) { - gtk_option_menu_set_history (p->sig_menu, 0); - return; - } - - menu = gtk_option_menu_get_menu (p->sig_menu); - items = GTK_MENU_SHELL (menu)->children; - while (items != NULL) { - cur = g_object_get_data ((GObject *) items->data, "sig"); - if (cur == p->signature) { - gtk_option_menu_set_history (p->sig_menu, i); - return; - } - items = items->next; - i++; - } -} - -static void -setup_signatures_menu (EMsgComposer *composer) -{ - GtkWidget *hbox, *hspace, *label; - ESignatureList *signatures; - GtkWidget *menu, *item; - ESignature *sig; - EIterator *it; - EMsgComposerPrivate *p = composer->priv; - - hbox = e_msg_composer_hdrs_get_from_hbox (E_MSG_COMPOSER_HDRS (p->hdrs)); - - label = gtk_label_new_with_mnemonic (_("Si_gnature:")); - gtk_widget_show (label); - - p->sig_menu = (GtkOptionMenu *) gtk_option_menu_new (); - - gtk_label_set_mnemonic_widget ((GtkLabel *) label, (GtkWidget *)p->sig_menu); - - gtk_box_pack_end_defaults (GTK_BOX (hbox), (GtkWidget *) p->sig_menu); - gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, TRUE, 0); - hspace = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hspace); - gtk_box_pack_start (GTK_BOX (hbox), hspace, FALSE, FALSE, 0); - - menu = gtk_menu_new (); - gtk_widget_show (menu); - gtk_option_menu_set_menu (p->sig_menu, menu); - - item = gtk_menu_item_new_with_label (_("None")); - gtk_widget_show (item); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - - signatures = mail_config_get_signatures (); - it = e_list_get_iterator ((EList *) signatures); - - while (e_iterator_is_valid (it)) { - sig = (ESignature *) e_iterator_get (it); - signature_added (signatures, sig, composer); - e_iterator_next (it); - } - - g_object_unref (it); - - g_signal_connect (menu, "selection-done", G_CALLBACK (signature_activate_cb), composer); - - gtk_widget_show ((GtkWidget *) p->sig_menu); - - p->sig_added_id = g_signal_connect (signatures, "signature-added", G_CALLBACK (signature_added), composer); - p->sig_removed_id = g_signal_connect (signatures, "signature-removed", G_CALLBACK (signature_removed), composer); - p->sig_changed_id = g_signal_connect (signatures, "signature-changed", G_CALLBACK (signature_changed), composer); -} - -static void setup_ui (EMsgComposer *composer) { EMMenuTargetWidget *target; @@ -2672,7 +2500,7 @@ attachment_bar_changed_cb (EAttachmentBar *bar, /* Mark the composer as changed so it prompts about unsaved - changes on close */ + changes on close */ e_msg_composer_set_changed (composer); } static void @@ -2851,11 +2679,8 @@ from_changed_cb (EMsgComposerHdrs *hdrs, void *data) static void composer_finalise (GObject *object) { - EMsgComposer *composer; - EMsgComposerPrivate *p; - - composer = E_MSG_COMPOSER (object); - p = composer->priv; + EMsgComposer *composer = E_MSG_COMPOSER (object); + EMsgComposerPrivate *p = composer->priv; if (p->extra_hdr_names) { int i; @@ -2908,7 +2733,6 @@ destroy (GtkObject *object) EMsgComposer *composer = (EMsgComposer *)object; EMsgComposerPrivate *p = composer->priv; CORBA_Environment ev; - ESignatureList *signatures; CORBA_exception_init (&ev); @@ -2939,7 +2763,7 @@ destroy (GtkObject *object) } /* FIXME? I assume the Bonobo widget will get destroyed - normally? */ + normally? */ if (p->address_dialog != NULL) { gtk_widget_destroy (p->address_dialog); p->address_dialog = NULL; @@ -2981,23 +2805,6 @@ destroy (GtkObject *object) p->eeditor_listener = NULL; } - signatures = mail_config_get_signatures (); - - if (p->sig_added_id != 0) { - g_signal_handler_disconnect (signatures, p->sig_added_id); - p->sig_added_id = 0; - } - - if (p->sig_removed_id != 0) { - g_signal_handler_disconnect (signatures, p->sig_removed_id); - p->sig_removed_id = 0; - } - - if (p->sig_changed_id != 0) { - g_signal_handler_disconnect (signatures, p->sig_changed_id); - p->sig_changed_id = 0; - } - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -3925,14 +3732,14 @@ button_press_event (GtkWidget *widget, GdkEventButton *event) static gint key_press_event(GtkWidget *widget, GdkEventKey *event) { - EAttachmentBar *bar = E_ATTACHMENT_BAR(widget); + EAttachmentBar *bar = E_ATTACHMENT_BAR(widget); - if (event->keyval == GDK_Delete) { - e_attachment_bar_remove_selected (bar); - return TRUE; - } + if (event->keyval == GDK_Delete) { + e_attachment_bar_remove_selected (bar); + return TRUE; + } - return FALSE; + return FALSE; } static EMsgComposer * @@ -3999,10 +3806,11 @@ create_composer (int visible_mask) G_CALLBACK (hdrs_changed_cb), composer); g_signal_connect (p->hdrs, "from_changed", G_CALLBACK (from_changed_cb), composer); + g_signal_connect_swapped ( + p->hdrs, "signature_changed", + G_CALLBACK (e_msg_composer_show_sig_file), composer); gtk_widget_show (p->hdrs); - setup_signatures_menu (composer); - from_changed_cb((EMsgComposerHdrs *)p->hdrs, composer); /* Editor component. */ @@ -4047,7 +3855,7 @@ create_composer (int visible_mask) gtk_box_pack_start (GTK_BOX (vbox), p->eeditor, TRUE, TRUE, 0); /* Attachment editor, wrapped into an EScrollFrame. It's - hidden in an EExpander. */ + hidden in an EExpander. */ p->attachment_scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (p->attachment_scrolled_window), @@ -4143,22 +3951,18 @@ create_composer (int visible_mask) static void set_editor_signature (EMsgComposer *composer) { - EAccountIdentity *id; - EMsgComposerPrivate *p = composer->priv; + EMsgComposerHdrs *hdrs; + ESignature *signature; EAccount *account; + const gchar *uid; - account = e_msg_composer_hdrs_get_from_account ( - E_MSG_COMPOSER_HDRS (p->hdrs)); - + hdrs = E_MSG_COMPOSER_HDRS (composer->priv->hdrs); + account = e_msg_composer_hdrs_get_from_account (hdrs); g_return_if_fail (account != NULL); - id = account->id; - if (id->sig_uid) - p->signature = mail_config_get_signature_by_uid (id->sig_uid); - else - p->signature = NULL; - - sig_select_item (composer); + uid = account->id->sig_uid; + signature = uid ? mail_config_get_signature_by_uid (uid) : NULL; + e_msg_composer_hdrs_set_signature (hdrs, signature); } /** @@ -4238,7 +4042,7 @@ e_msg_composer_set_pending_body (EMsgComposer *composer, char *text, ssize_t len char *old; old = g_object_get_data ((GObject *) composer, "body:text"); - g_free (old); + g_free (old); g_object_set_data ((GObject *) composer, "body:text", text); g_object_set_data ((GObject *) composer, "body:len", GSIZE_TO_POINTER (len)); } @@ -4246,7 +4050,7 @@ e_msg_composer_set_pending_body (EMsgComposer *composer, char *text, ssize_t len static void e_msg_composer_flush_pending_body (EMsgComposer *composer, gboolean apply) { - char *body; + char *body; ssize_t len; body = g_object_get_data ((GObject *) composer, "body:text"); @@ -4368,9 +4172,9 @@ handle_multipart_signed (EMsgComposer *composer, CamelMultipart *multipart, int multipart = CAMEL_MULTIPART (content); /* Note: depth is preserved here because we're not - counting multipart/signed as a multipart, instead - we want to treat the content part as our mime part - here. */ + counting multipart/signed as a multipart, instead + we want to treat the content part as our mime part + here. */ if (CAMEL_IS_MULTIPART_SIGNED (content)) { /* handle the signed content and configure the composer to sign outgoing messages */ @@ -4427,9 +4231,9 @@ handle_multipart_encrypted (EMsgComposer *composer, CamelMimePart *multipart, in CamelMultipart *content_multipart = CAMEL_MULTIPART (content); /* Note: depth is preserved here because we're not - counting multipart/encrypted as a multipart, instead - we want to treat the content part as our mime part - here. */ + counting multipart/encrypted as a multipart, instead + we want to treat the content part as our mime part + here. */ if (CAMEL_IS_MULTIPART_SIGNED (content)) { /* handle the signed content and configure the composer to sign outgoing messages */ @@ -4577,8 +4381,10 @@ set_signature_gui (EMsgComposer *composer) { CORBA_Environment ev; EMsgComposerPrivate *p = composer->priv; + EMsgComposerHdrs *hdrs; + ESignature *signature = NULL; - p->signature = NULL; + hdrs = E_MSG_COMPOSER_HDRS (composer->priv->hdrs); CORBA_exception_init (&ev); if (GNOME_GtkHTML_Editor_Engine_searchByData (p->eeditor_engine, 1, "ClueFlow", "signature", "1", &ev)) { @@ -4588,17 +4394,17 @@ set_signature_gui (EMsgComposer *composer) if (ev._major == CORBA_NO_EXCEPTION && str) { if (!strncmp (str, "uid:", 4)) { name = decode_signature_name (str + 4); - p->signature = mail_config_get_signature_by_uid (name); + signature = mail_config_get_signature_by_uid (name); g_free (name); } else if (!strncmp (str, "name:", 5)) { name = decode_signature_name (str + 4); - p->signature = mail_config_get_signature_by_name (name); + signature = mail_config_get_signature_by_name (name); g_free (name); } CORBA_free (str); } - sig_select_item (composer); + e_msg_composer_hdrs_set_signature (hdrs, signature); } CORBA_exception_free (&ev); } @@ -5037,7 +4843,7 @@ handle_mailto (EMsgComposer *composer, const char *mailto) "attachment"); } gtk_widget_show (priv->attachment_expander); - gtk_widget_show (priv->attachment_scrolled_window); + gtk_widget_show (priv->attachment_scrolled_window); } else if (!g_ascii_strcasecmp (header, "from")) { /* Ignore */ } else if (!g_ascii_strcasecmp (header, "reply-to")) { @@ -5193,7 +4999,7 @@ void e_msg_composer_set_body_text (EMsgComposer *composer, const char *text, ssize_t len) { g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - g_return_if_fail (text != NULL); + g_return_if_fail (text != NULL); set_editor_text (composer, text, len, TRUE, *text == '\0'); } @@ -6447,7 +6253,7 @@ e_msg_composer_get_raw_message_text (EMsgComposer *composer) data = get_text (p->persist_stream_interface, "text/plain"); if (data) - return (const gchar *)data->data; + return (const gchar *)data->data; return NULL; } diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 559bf58055..93934b2bbc 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,18 @@ +2007-12-01 Matthew Barnes <mbarnes@redhat.com> + + ** Fixes part of bug #495123 + + * Makefile.am: + Add e-signature-combo-box.[ch]. + + * e-account-combo-box.c (account_combo_box_refresh_cb): + Make sure the EAccount isn't lost while swapping models. + + * e-signature-combo-box.c: + * e-signature-combo-box.h: + New widget renders an ESignatureList as a combo box. Also listens + for changes to the ESignatureList and updates itself accordingly. + 2007-11-27 Matthew Barnes <mbarnes@redhat.com> ** Fixes part of bug #495123 diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index c35d7a9f2c..267ded9aab 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -76,6 +76,7 @@ widgetsinclude_HEADERS = \ e-selection-model-array.h \ e-selection-model-simple.h \ e-selection-model.h \ + e-signature-combo-box.h \ e-unicode.h \ e-colors.h @@ -122,6 +123,7 @@ libemiscwidgets_la_SOURCES = \ e-selection-model-array.c \ e-selection-model-simple.c \ e-selection-model.c \ + e-signature-combo-box.c \ e-unicode.c \ e-colors.c @@ -136,6 +138,7 @@ libemiscwidgets_la_LIBADD = $(top_builddir)/e-util/libeutil.la \ $(top_builddir)/a11y/libevolution-a11y.la \ $(CAMEL_LIBS) \ $(GNOME_PLATFORM_LIBS) \ + $(EVOLUTON_MAIL_LIBS) \ $(ICONV_LIBS) libefilterbar_la_SOURCES = \ diff --git a/widgets/misc/e-account-combo-box.c b/widgets/misc/e-account-combo-box.c index 064ed2bd10..6a96644bfd 100644 --- a/widgets/misc/e-account-combo-box.c +++ b/widgets/misc/e-account-combo-box.c @@ -155,8 +155,12 @@ account_combo_box_refresh_cb (EAccountList *account_list, skip: /* Restore the previously selected account. */ account = e_account_combo_box_get_active (combo_box); + if (account != NULL) + g_object_ref (account); gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), model); e_account_combo_box_set_active (combo_box, account); + if (account != NULL) + g_object_unref (account); } static GObject * diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c new file mode 100644 index 0000000000..be19755ef6 --- /dev/null +++ b/widgets/misc/e-signature-combo-box.c @@ -0,0 +1,338 @@ +#include "e-signature-combo-box.h" + +#include <glib/gi18n.h> + +#define E_SIGNATURE_COMBO_BOX_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SIGNATURE_COMBO_BOX, ESignatureComboBoxPrivate)) + +enum { + COLUMN_STRING, + COLUMN_SIGNATURE +}; + +enum { + REFRESHED, + LAST_SIGNAL +}; + +struct _ESignatureComboBoxPrivate { + ESignatureList *signature_list; + GHashTable *index; +}; + +static gpointer parent_class; +static guint signal_ids[LAST_SIGNAL]; + +static void +signature_combo_box_refresh_cb (ESignatureList *signature_list, + ESignature *unused, + ESignatureComboBox *combo_box) +{ + GtkListStore *store; + GtkTreeModel *model; + GtkTreeIter tree_iter; + EIterator *signature_iter; + ESignature *signature; + GHashTable *index; + GList *list = NULL; + GList *iter; + + store = gtk_list_store_new (2, G_TYPE_STRING, E_TYPE_SIGNATURE); + model = GTK_TREE_MODEL (store); + index = combo_box->priv->index; + + g_hash_table_remove_all (index); + + gtk_list_store_append (store, &tree_iter); + gtk_list_store_set ( + store, &tree_iter, + COLUMN_STRING, _("None"), + COLUMN_SIGNATURE, NULL, -1); + + if (signature_list == NULL) + goto skip; + + /* Build a list of ESignatures to display. */ + signature_iter = e_list_get_iterator (E_LIST (signature_list)); + while (e_iterator_is_valid (signature_iter)) { + + /* XXX EIterator misuses const. */ + signature = (ESignature *) e_iterator_get (signature_iter); + list = g_list_prepend (list, signature); + e_iterator_next (signature_iter); + } + g_object_unref (signature_iter); + + list = g_list_reverse (list); + + /* Populate the list store and index. */ + for (iter = list; iter != NULL; iter = iter->next) { + GtkTreeRowReference *reference; + GtkTreePath *path; + const gchar *string; + + signature = iter->data; + + if (signature->autogen) + string = _("Autogenerated"); + else + string = signature->name; + + gtk_list_store_append (store, &tree_iter); + gtk_list_store_set ( + store, &tree_iter, + COLUMN_STRING, string, + COLUMN_SIGNATURE, signature, -1); + + path = gtk_tree_model_get_path (model, &tree_iter); + reference = gtk_tree_row_reference_new (model, path); + g_hash_table_insert (index, signature, reference); + gtk_tree_path_free (path); + } + +skip: + /* Restore the previously selected signature. */ + signature = e_signature_combo_box_get_active (combo_box); + if (signature != NULL) + g_object_ref (signature); + gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), model); + e_signature_combo_box_set_active (combo_box, signature); + if (signature != NULL) + g_object_unref (signature); + + g_signal_emit (combo_box, signal_ids[REFRESHED], 0); +} + +static GObject * +signature_combo_box_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GObject *object; + GtkCellRenderer *renderer; + + /* Chain up to parent's constructor() method. */ + object = G_OBJECT_CLASS (parent_class)->constructor ( + type, n_construct_properties, construct_properties); + + renderer = gtk_cell_renderer_text_new (); + + gtk_cell_layout_pack_start ( + GTK_CELL_LAYOUT (object), renderer, TRUE); + gtk_cell_layout_add_attribute ( + GTK_CELL_LAYOUT (object), renderer, "text", COLUMN_STRING); + + e_signature_combo_box_set_signature_list ( + E_SIGNATURE_COMBO_BOX (object), NULL); + + return object; +} + +static void +signature_combo_box_dispose (GObject *object) +{ + ESignatureComboBoxPrivate *priv; + + priv = E_SIGNATURE_COMBO_BOX_GET_PRIVATE (object); + + if (priv->signature_list != NULL) { + g_signal_handlers_disconnect_by_func ( + priv->signature_list, + signature_combo_box_refresh_cb, object); + g_object_unref (priv->signature_list); + priv->signature_list = NULL; + } + + g_hash_table_remove_all (priv->index); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +signature_combo_box_finalize (GObject *object) +{ + ESignatureComboBoxPrivate *priv; + + priv = E_SIGNATURE_COMBO_BOX_GET_PRIVATE (object); + + g_hash_table_destroy (priv->index); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +signature_combo_box_class_init (ESignatureComboBoxClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESignatureComboBoxPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructor = signature_combo_box_constructor; + object_class->dispose = signature_combo_box_dispose; + object_class->finalize = signature_combo_box_finalize; + + signal_ids[REFRESHED] = g_signal_new ( + "refreshed", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +signature_combo_box_init (ESignatureComboBox *combo_box) +{ + GHashTable *index; + + /* Reverse-lookup index */ + index = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) gtk_tree_row_reference_free); + + combo_box->priv = E_SIGNATURE_COMBO_BOX_GET_PRIVATE (combo_box); + combo_box->priv->index = index; +} + +GType +e_signature_combo_box_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESignatureComboBoxClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) signature_combo_box_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESignatureComboBox), + 0, /* n_preallocs */ + (GInstanceInitFunc) signature_combo_box_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_COMBO_BOX, "ESignatureComboBox", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_signature_combo_box_new (void) +{ + return g_object_new (E_TYPE_SIGNATURE_COMBO_BOX, NULL); +} + +void +e_signature_combo_box_set_signature_list (ESignatureComboBox *combo_box, + ESignatureList *signature_list) +{ + ESignatureComboBoxPrivate *priv; + + g_return_if_fail (E_IS_SIGNATURE_COMBO_BOX (combo_box)); + + if (signature_list != NULL) + g_return_if_fail (E_IS_SIGNATURE_LIST (signature_list)); + + priv = E_SIGNATURE_COMBO_BOX_GET_PRIVATE (combo_box); + + if (priv->signature_list != NULL) { + g_signal_handlers_disconnect_by_func ( + priv->signature_list, + signature_combo_box_refresh_cb, combo_box); + g_object_unref (priv->signature_list); + priv->signature_list = NULL; + } + + if (signature_list != NULL) { + priv->signature_list = g_object_ref (signature_list); + + /* Listen for changes to the signature list. */ + g_signal_connect ( + priv->signature_list, "signature-added", + G_CALLBACK (signature_combo_box_refresh_cb), + combo_box); + g_signal_connect ( + priv->signature_list, "signature-changed", + G_CALLBACK (signature_combo_box_refresh_cb), + combo_box); + g_signal_connect ( + priv->signature_list, "signature-removed", + G_CALLBACK (signature_combo_box_refresh_cb), + combo_box); + } + + signature_combo_box_refresh_cb (signature_list, NULL, combo_box); +} + +ESignature * +e_signature_combo_box_get_active (ESignatureComboBox *combo_box) +{ + ESignature *signature; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean iter_set; + + g_return_val_if_fail (E_IS_SIGNATURE_COMBO_BOX (combo_box), NULL); + + iter_set = gtk_combo_box_get_active_iter ( + GTK_COMBO_BOX (combo_box), &iter); + if (!iter_set) + return NULL; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + gtk_tree_model_get (model, &iter, COLUMN_SIGNATURE, &signature, -1); + + return signature; +} + +gboolean +e_signature_combo_box_set_active (ESignatureComboBox *combo_box, + ESignature *signature) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + gboolean iter_set; + + g_return_val_if_fail (E_IS_SIGNATURE_COMBO_BOX (combo_box), FALSE); + + if (signature != NULL) + g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE); + + /* NULL means select "None" (always the first item). */ + if (signature == NULL) { + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); + return TRUE; + } + + /* Lookup the tree row reference for the signature. */ + reference = g_hash_table_lookup (combo_box->priv->index, signature); + if (reference == NULL) + return FALSE; + + /* Convert the reference to a tree iterator. */ + path = gtk_tree_row_reference_get_path (reference); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + iter_set = gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + if (!iter_set) + return FALSE; + + /* Activate the corresponding combo box item. */ + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box), &iter); + + return TRUE; +} diff --git a/widgets/misc/e-signature-combo-box.h b/widgets/misc/e-signature-combo-box.h new file mode 100644 index 0000000000..31786978ef --- /dev/null +++ b/widgets/misc/e-signature-combo-box.h @@ -0,0 +1,55 @@ +#ifndef E_SIGNATURE_COMBO_BOX_H +#define E_SIGNATURE_COMBO_BOX_H + +#include <gtk/gtk.h> +#include "e-util/e-signature.h" +#include "e-util/e-signature-list.h" + +/* Standard GObject macros */ +#define E_TYPE_SIGNATURE_COMBO_BOX \ + (e_signature_combo_box_get_type ()) +#define E_SIGNATURE_COMBO_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SIGNATURE_COMBO_BOX, ESignatureComboBox)) +#define E_SIGNATURE_COMBO_BOX_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SIGNATURE_COMBO_BOX, ESignatureComboBoxClass)) +#define E_IS_SIGNATURE_COMBO_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SIGNATURE_COMBO_BOX)) +#define E_IS_SIGNATURE_COMBO_BOX_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SIGNATURE_COMBO_BOX)) +#define E_SIGNATURE_COMBO_BOX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SIGNATURE_COMBO_BOX, ESignatureComboBoxClass)) + +G_BEGIN_DECLS + +typedef struct _ESignatureComboBox ESignatureComboBox; +typedef struct _ESignatureComboBoxClass ESignatureComboBoxClass; +typedef struct _ESignatureComboBoxPrivate ESignatureComboBoxPrivate; + +struct _ESignatureComboBox { + GtkComboBox parent; + ESignatureComboBoxPrivate *priv; +}; + +struct _ESignatureComboBoxClass { + GtkComboBoxClass parent_class; +}; + +GType e_signature_combo_box_get_type (void); +GtkWidget * e_signature_combo_box_new (void); +void e_signature_combo_box_set_signature_list + (ESignatureComboBox *combo_box, + ESignatureList *signature_list); +ESignature * e_signature_combo_box_get_active + (ESignatureComboBox *combo_box); +gboolean e_signature_combo_box_set_active + (ESignatureComboBox *combo_box, + ESignature *signature); + +G_END_DECLS + +#endif /* E_SIGNATURE_COMBO_BOX_H */ |