From e4bdc1e6a762058e4e289d6d7710dcadda1caca1 Mon Sep 17 00:00:00 2001 From: Srinivasa Ragavan Date: Fri, 2 Jun 2006 18:12:08 +0000 Subject: Added support for Vertical View in Evolution Mailer with custom message list. svn path=/trunk/; revision=32071 --- mail/ChangeLog | 29 ++++++++ mail/em-folder-browser.c | 106 +++++++++++++++++++++++++++-- mail/em-folder-browser.h | 1 + mail/em-folder-view.c | 38 +++++++++-- mail/em-folder-view.h | 1 + mail/evolution-mail.schemas.in.in | 42 ++++++++++++ mail/message-list.c | 139 +++++++++++++++++++++++++++++++++++--- mail/message-list.etspec | 9 ++- mail/message-list.h | 3 + 9 files changed, 345 insertions(+), 23 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 4db84b06ba..d33a0b4442 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,32 @@ +2006-06-02 Srinivasa Ragavan + + ** Added support for Vertical View in evolution in addition to the + existing classical view. It also supports a composite headers to be + shown in a multilined column. + + * em-folder-browser.c: (emfb_pane_realised), + (emfb_pane_button_release_event), (emfb_init), + (em_folder_browser_show_preview), (em_folder_browser_show_wide), + (emfb_show_next), (emfb_show_below), (emfb_activate): Added code to + handle the new wide mode in Evolution. + * em-folder-browser.h: + * em-folder-view.c: (emfv_setup_view_instance), + (em_folder_view_setup_view_instance): Added code to handle the default + view in the wide mode for normal and sent/draft folders. + * em-folder-view.h: + * evolution-mail.schemas.in.in: Added schema for hpane size, showing + email in the composite headers and toggling wide more. + + * message-list.c: (ml_duplicate_value), (ml_free_value), + (ml_initialize_value), (ml_value_is_empty), (ml_value_to_string), + (sanitize_recipients), (ml_tree_value_at), (create_composite_cell), + (message_list_create_extras): Added a new composite header + render_composite_from/recipient which shows the headers in a + multilined column. + * message-list.etspec: Added three new columns, Recipent, Messages + column for normal folders and Messages column for sent/draft folders. + * message-list.h: + 2006-05-30 Li Yuan Fix for #341381. diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c index 56f7a9b3f6..830e2a287d 100644 --- a/mail/em-folder-browser.c +++ b/mail/em-folder-browser.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -114,6 +115,8 @@ struct _EMFolderBrowserPrivate { char *select_uid; guint folder_changed_id; + int show_wide:1; + EMMenu *menu; /* toplevel menu manager */ }; @@ -154,7 +157,11 @@ emfb_pane_realised(GtkWidget *w, EMFolderBrowser *emfb) GConfClient *gconf; gconf = mail_config_get_gconf_client (); - gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL)); + + if (emfb->priv->show_wide) + gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/hpaned_size", NULL)); + else + gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL)); } static gboolean @@ -162,9 +169,15 @@ emfb_pane_button_release_event(GtkWidget *w, GdkEventButton *e, EMFolderBrowser { GConfClient *gconf = mail_config_get_gconf_client (); - if (GTK_WIDGET_REALIZED (w)) - gconf_client_set_int(gconf, "/apps/evolution/mail/display/paned_size", - gtk_paned_get_position(GTK_PANED(w)), NULL); + if (GTK_WIDGET_REALIZED (w)) { + if (emfb->priv->show_wide) + gconf_client_set_int(gconf, "/apps/evolution/mail/display/hpaned_size", + gtk_paned_get_position(GTK_PANED(w)), NULL); + else + gconf_client_set_int(gconf, "/apps/evolution/mail/display/paned_size", + gtk_paned_get_position(GTK_PANED(w)), NULL); + + } return FALSE; } @@ -221,7 +234,9 @@ emfb_init(GObject *o) gtk_box_pack_start((GtkBox *)emfb, (GtkWidget *)emfb->search, FALSE, TRUE, 0); } - emfb->vpane = gtk_vpaned_new(); + emfb->priv->show_wide = gconf_client_get_bool(mail_config_get_gconf_client(), "/apps/evolution/mail/display/show_wide", NULL); + emfb->vpane = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new(); + g_signal_connect(emfb->vpane, "realize", G_CALLBACK(emfb_pane_realised), emfb); emfb->priv->vpane_resize_id = g_signal_connect(emfb->vpane, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb); @@ -345,7 +360,7 @@ void em_folder_browser_show_preview(EMFolderBrowser *emfb, gboolean state) GConfClient *gconf = mail_config_get_gconf_client (); int paned_size /*, y*/; - paned_size = gconf_client_get_int(gconf, "/apps/evolution/mail/display/paned_size", NULL); + paned_size = gconf_client_get_int(gconf, emfb->priv->show_wide ? "/apps/evolution/mail/display/hpaned_size":"/apps/evolution/mail/display/paned_size", NULL); /*y = save_cursor_pos (emfb);*/ gtk_paned_set_position (GTK_PANED (emfb->vpane), paned_size); @@ -376,6 +391,39 @@ void em_folder_browser_show_preview(EMFolderBrowser *emfb, gboolean state) /* FIXME: need to update menu's to reflect ui changes */ } +void em_folder_browser_show_wide(EMFolderBrowser *emfb, gboolean state) +{ + GtkWidget *w; + + if ((emfb->priv->show_wide && state) + || emfb->view.list == NULL + || emfb->view.preview_active == 0) { + emfb->priv->show_wide = state; + return; + } + + emfb->priv->show_wide = state; + + w = emfb->priv->show_wide?gtk_hpaned_new():gtk_vpaned_new(); + + g_signal_handler_disconnect(emfb->vpane, emfb->priv->vpane_resize_id); + g_signal_connect(w, "realize", G_CALLBACK(emfb_pane_realised), emfb); + emfb->priv->vpane_resize_id = g_signal_connect(w, "button_release_event", G_CALLBACK(emfb_pane_button_release_event), emfb); + + gtk_widget_show(w); + if (emfb->priv->show_wide) + gtk_paned_set_position((GtkPaned *)w, gconf_client_get_int(mail_config_get_gconf_client (), "/apps/evolution/mail/display/hpaned_size", NULL)); + else + gtk_paned_set_position((GtkPaned *)w, gconf_client_get_int(mail_config_get_gconf_client (), "/apps/evolution/mail/display/paned_size", NULL)); + gtk_box_pack_start_defaults((GtkBox *)emfb, w); + gtk_widget_reparent((GtkWidget *)emfb->view.list, w); + gtk_widget_reparent((GtkWidget *)emfb->priv->preview, w); + gtk_widget_destroy(emfb->vpane); + emfb->vpane = w; + if (((EMFolderView *)emfb)->folder) + em_folder_view_setup_view_instance ((EMFolderView *) emfb); +} + /* ********************************************************************** */ /* FIXME: Need to separate system rules from user ones */ @@ -944,6 +992,36 @@ emfb_view_preview(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_E em_folder_browser_show_preview((EMFolderBrowser *)emfv, state[0] != '0'); } +static void +emfb_show_next(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data) +{ + GConfClient *gconf; + EMFolderBrowser *emfb = data; + + if (type != Bonobo_UIComponent_STATE_CHANGED) + return; + + gconf = mail_config_get_gconf_client (); + gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_wide", state[0] != '0', NULL); + + em_folder_browser_show_wide(emfb, state[0] != '0'); +} + +static void +emfb_show_below(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data) +{ + GConfClient *gconf; + EMFolderBrowser *emfb = data; + + if (type != Bonobo_UIComponent_STATE_CHANGED) + return; + + gconf = mail_config_get_gconf_client (); + gconf_client_set_bool(gconf, "/apps/evolution/mail/display/show_wide", state[0] == '0', NULL); + + em_folder_browser_show_wide(emfb, state[0] == '0'); +} + static void emfb_list_scrolled (MessageList *ml, EMFolderBrowser *emfb) { @@ -1173,7 +1251,7 @@ emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) preview settings - see folder_browser_set_message_preview() internals for details) */ g_signal_handler_block(emfb->vpane, emfb->priv->vpane_resize_id); - gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int (gconf, "/apps/evolution/mail/display/paned_size", NULL)); + gtk_paned_set_position((GtkPaned *)emfb->vpane, gconf_client_get_int (gconf, emfb->priv->show_wide ? "/apps/evolution/mail/display/hpaned_size": "/apps/evolution/mail/display/paned_size", NULL)); g_signal_handler_unblock(emfb->vpane, emfb->priv->vpane_resize_id); /* (Pre)view toggle */ @@ -1222,6 +1300,20 @@ emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, int act) bonobo_ui_component_add_listener(uic, "ViewThreaded", emfb_view_threaded, emfv); message_list_set_threaded(emfv->list, state); + /* Show wide display */ + state = gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_wide", NULL); + if (state) { + bonobo_ui_component_set_prop(uic, "/commands/ViewAfter", "state", "1", NULL); + bonobo_ui_component_set_prop(uic, "/commands/ViewBelow", "state", "0", NULL); + } else { + bonobo_ui_component_set_prop(uic, "/commands/ViewAfter", "state", "0", NULL); + bonobo_ui_component_set_prop(uic, "/commands/ViewBelow", "state", "1", NULL); + } + + bonobo_ui_component_add_listener(uic, "ViewAfter", emfb_show_next, emfv); + bonobo_ui_component_add_listener(uic, "ViewBelow", emfb_show_below, emfv); + /* em_folder_browser_show_wide((EMFolderBrowser *)emfv, state); */ + /* FIXME: Selection state */ /* FIXME: property menu customisation */ diff --git a/mail/em-folder-browser.h b/mail/em-folder-browser.h index b414a19489..f31f78fd93 100644 --- a/mail/em-folder-browser.h +++ b/mail/em-folder-browser.h @@ -51,6 +51,7 @@ GType em_folder_browser_get_type(void); GtkWidget *em_folder_browser_new(void); void em_folder_browser_show_preview(EMFolderBrowser *emfv, gboolean state); +void em_folder_browser_show_wide(EMFolderBrowser *emfv, gboolean state); #ifdef __cplusplus } diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c index 7add999ec3..5b002cdaa9 100644 --- a/mail/em-folder-view.c +++ b/mail/em-folder-view.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -501,7 +502,8 @@ emfv_setup_view_instance(EMFolderView *emfv) char *id; static GalViewCollection *collection = NULL; CamelFolderInfo *fi = NULL; - + gboolean show_wide = gconf_client_get_bool (mail_config_get_gconf_client (), "/apps/evolution/mail/display/show_wide", NULL); + g_assert(emfv->folder); g_assert(emfv->folder_uri); @@ -558,21 +560,44 @@ emfv_setup_view_instance(EMFolderView *emfv) /* TODO: should this go through mail-config api? */ id = mail_config_folder_to_safe_url (emfv->folder); p->view_instance = gal_view_instance_new (collection, id); + + if (show_wide) { + char *safe_id, *filename; + + /* Force to use the wide view */ + g_free (p->view_instance->custom_filename); + g_free (p->view_instance->current_view_filename); + safe_id = g_strdup (id); + e_filename_make_safe (safe_id); + filename = g_strdup_printf ("custom_wide_view-%s.xml", safe_id); + p->view_instance->custom_filename = g_concat_dir_and_file (collection->local_dir, filename); + g_free (filename); + filename = g_strdup_printf ("current_wide_view-%s.xml", safe_id); + p->view_instance->current_view_filename = g_concat_dir_and_file (collection->local_dir, filename); + g_free (safe_id); + } g_free (id); fi = camel_store_get_folder_info (emfv->folder->parent_store, emfv->folder->full_name, CAMEL_STORE_FOLDER_INFO_SUBSCRIBED, NULL); - if (outgoing || (fi && ((fi->flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_SENT))) - gal_view_instance_set_default_view(p->view_instance, "As_Sent_Folder"); + if (outgoing || (fi && ((fi->flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_SENT))) { + if (show_wide) + gal_view_instance_set_default_view(p->view_instance, "Wide_View_Sent"); + else + gal_view_instance_set_default_view(p->view_instance, "As_Sent_Folder"); + } else if (show_wide){ + gal_view_instance_set_default_view(p->view_instance, "Wide_View_Normal"); + } + gal_view_instance_load(p->view_instance); if (!gal_view_instance_exists(p->view_instance)) { struct stat st; char *path; - + path = mail_config_folder_to_cachename (emfv->folder, "et-header-"); if (path && g_stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) { ETableSpecification *spec; @@ -610,6 +635,11 @@ emfv_setup_view_instance(EMFolderView *emfv) } } +void em_folder_view_setup_view_instance (EMFolderView *emfv) +{ + emfv_setup_view_instance (emfv); +} + /* ********************************************************************** */ static void diff --git a/mail/em-folder-view.h b/mail/em-folder-view.h index 87dff43634..8c8669c897 100644 --- a/mail/em-folder-view.h +++ b/mail/em-folder-view.h @@ -138,6 +138,7 @@ guint32 em_folder_view_disable_mask(EMFolderView *emfv); void em_folder_view_set_statusbar(EMFolderView *emfv, gboolean statusbar); void em_folder_view_set_hide_deleted(EMFolderView *emfv, gboolean status); +void em_folder_view_setup_view_instance (EMFolderView *emfv); #ifdef __cplusplus } diff --git a/mail/evolution-mail.schemas.in.in b/mail/evolution-mail.schemas.in.in index f4466ac44e..ce437bbd80 100644 --- a/mail/evolution-mail.schemas.in.in +++ b/mail/evolution-mail.schemas.in.in @@ -317,6 +317,20 @@ + + /schemas/apps/evolution/mail/display/show_email + /apps/evolution/mail/display/show_email + evolution-mail + bool + false + + Show the sender email in the messages column in the message list + + Show the email of the sender in the messages composite column in the message list + + + + /schemas/apps/evolution/mail/display/mark_seen_timeout /apps/evolution/mail/display/mark_seen_timeout @@ -373,6 +387,34 @@ + + /schemas/apps/evolution/mail/display/hpaned_size + /apps/evolution/mail/display/hpaned_size + evolution-mail + int + 450 + + Width of the message-list pane + + Width of the message-list pane. + + + + + + /schemas/apps/evolution/mail/display/show_wide + /apps/evolution/mail/display/show_wide + evolution-mail + bool + false + + Use side-by-side or wide layout + + If the "Preview" pane is on, then show it side-by-side rather than vertically. + + + + /schemas/apps/evolution/mail/display/fonts/variable /apps/evolution/mail/display/fonts/variable diff --git a/mail/message-list.c b/mail/message-list.c index 999fef410c..3358e75833 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -900,7 +900,10 @@ ml_duplicate_value (ETreeModel *etm, int col, const void *value, void *data) case COL_FROM: case COL_SUBJECT: case COL_TO: - case COL_SENDER: + case COL_SENDER: + case COL_RECIPIENTS: + case COL_MIXED_SENDER: + case COL_MIXED_RECIPIENTS: case COL_FOLLOWUP_FLAG: case COL_LOCATION: return g_strdup (value); @@ -932,7 +935,10 @@ ml_free_value (ETreeModel *etm, int col, void *value, void *data) case COL_TO: case COL_FOLLOWUP_FLAG: case COL_LOCATION: - case COL_SENDER: + case COL_SENDER: + case COL_RECIPIENTS: + case COL_MIXED_SENDER: + case COL_MIXED_RECIPIENTS: g_free (value); break; default: @@ -963,6 +969,9 @@ ml_initialize_value (ETreeModel *etm, int col, void *data) case COL_FOLLOWUP_FLAG: case COL_LOCATION: case COL_SENDER: + case COL_RECIPIENTS: + case COL_MIXED_SENDER: + case COL_MIXED_RECIPIENTS: return g_strdup (""); default: g_assert_not_reached (); @@ -993,7 +1002,10 @@ ml_value_is_empty (ETreeModel *etm, int col, const void *value, void *data) case COL_TO: case COL_FOLLOWUP_FLAG: case COL_LOCATION: - case COL_SENDER: + case COL_SENDER: + case COL_RECIPIENTS: + case COL_MIXED_SENDER: + case COL_MIXED_RECIPIENTS: return !(value && *(char *)value); default: g_assert_not_reached (); @@ -1058,7 +1070,10 @@ ml_value_to_string (ETreeModel *etm, int col, const void *value, void *data) case COL_TO: case COL_FOLLOWUP_FLAG: case COL_LOCATION: - case COL_SENDER: + case COL_SENDER: + case COL_RECIPIENTS: + case COL_MIXED_SENDER: + case COL_MIXED_RECIPIENTS: return g_strdup (value); default: g_assert_not_reached (); @@ -1146,6 +1161,49 @@ subtree_earliest(MessageList *ml, ETreePath node, int sent) return earliest; } +static gchar * +sanitize_recipients (const gchar *string) +{ + GString *gstring; + gboolean quoted = FALSE; + const gchar *p; + GString *recipients = g_string_new (""); + char *single_add; + char **name; + + if (!string || !*string) + return ""; + + gstring = g_string_new (""); + + for (p = string; *p; p = g_utf8_next_char (p)) { + gunichar c = g_utf8_get_char (p); + + if (c == '"') + quoted = ~quoted; + else if (c == ',' && !quoted) { + single_add = g_string_free (gstring, FALSE); + name = g_strsplit(single_add,"<",2); + g_string_append (recipients, *name); + g_string_append (recipients, ","); + g_free (single_add); + g_strfreev (name); + gstring = g_string_new (""); + continue; + } + + g_string_append_unichar (gstring, c); + } + + single_add = g_string_free (gstring, FALSE); + name = g_strsplit(single_add,"<",2); + g_string_append (recipients, *name); + g_free (single_add); + g_strfreev (name); + + return g_string_free (recipients, FALSE); +} + static void * ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data) { @@ -1296,17 +1354,23 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data) camel_object_get(folder, NULL, CAMEL_OBJECT_DESCRIPTION, &name, 0); return name; } - case COL_SENDER:{ + case COL_MIXED_RECIPIENTS: + case COL_RECIPIENTS:{ char **sender_name; + str = camel_message_info_to (msg_info); + + return sanitize_recipients(str); + } + case COL_MIXED_SENDER: + case COL_SENDER:{ + char **sender_name = NULL; str = camel_message_info_from (msg_info); if(str!=""){ sender_name=g_strsplit(str,"<",2); return (void *)(*sender_name); } else - return (void *)(""); - - g_strfreev(sender_name); + return (void *)(""); } default: g_assert_not_reached (); @@ -1408,6 +1472,56 @@ filter_date (time_t date) return g_strdup (buf); } +static ECell * create_composite_cell (int col) +{ + ECell *cell_vbox, *cell_hbox, *cell_sub, *cell_date, *cell_from, *cell_tree, *cell_attach; + GdkPixbuf *images [7]; + GConfClient *gconf; + char *fixed_name = NULL; + gboolean show_email; + int i; + int alt_col = (col == COL_FROM) ? COL_SENDER : COL_RECIPIENTS; + + gconf = mail_config_get_gconf_client (); + fixed_name = gconf_client_get_string (gconf, "/desktop/gnome/interface/monospace_font_name", NULL); + show_email = gconf_client_get_bool (gconf, "/apps/evolution/mail/display/show_email", NULL); + + cell_vbox = e_cell_vbox_new (); + + cell_hbox = e_cell_hbox_new (); + + for (i = 0; i < 2; i++) + images [i] = states_pixmaps [i + 5].pixbuf; + cell_attach = e_cell_toggle_new (0, 2, images); + + cell_date = e_cell_date_new(NULL, GTK_JUSTIFY_RIGHT); + g_object_set (G_OBJECT (cell_date), + "bold_column", COL_UNREAD, + "color_column", COL_COLOUR, + NULL); + + cell_from = e_cell_text_new(NULL, GTK_JUSTIFY_LEFT); + g_object_set (G_OBJECT (cell_from), + "bold_column", COL_UNREAD, + "color_column", COL_COLOUR, + NULL); + + e_cell_hbox_append (cell_hbox, cell_from, show_email ? col : alt_col, 68); + e_cell_hbox_append (cell_hbox, cell_attach, COL_ATTACHMENT, 5); + e_cell_hbox_append (cell_hbox, cell_date, COL_SENT, 27); + + cell_sub = e_cell_text_new(fixed_name? fixed_name:NULL, GTK_JUSTIFY_LEFT); + g_object_set (G_OBJECT (cell_sub), +/* "bold_column", COL_UNREAD, */ + "color_column", COL_COLOUR, + NULL); + cell_tree = e_cell_tree_new (NULL, NULL, TRUE, cell_sub); + e_cell_vbox_append (cell_vbox, cell_hbox, COL_FROM); + e_cell_vbox_append (cell_vbox, cell_tree, COL_SUBJECT); + + return cell_vbox; +} + static ETableExtras * message_list_create_extras (void) { @@ -1415,7 +1529,7 @@ message_list_create_extras (void) GdkPixbuf *images [7]; ETableExtras *extras; ECell *cell; - + extras = e_table_extras_new (); e_table_extras_add_pixbuf (extras, "status", states_pixmaps [0].pixbuf); e_table_extras_add_pixbuf (extras, "score", states_pixmaps [13].pixbuf); @@ -1475,6 +1589,13 @@ message_list_create_extras (void) NULL); e_table_extras_add_cell (extras, "render_size", cell); + /* Composite cell for wide view */ + cell = create_composite_cell (COL_FROM); + e_table_extras_add_cell (extras, "render_composite_from", cell); + + cell = create_composite_cell (COL_TO); + e_table_extras_add_cell (extras, "render_composite_to", cell); + return extras; } diff --git a/mail/message-list.etspec b/mail/message-list.etspec index 2bb1ecf0c4..84587e367f 100644 --- a/mail/message-list.etspec +++ b/mail/message-list.etspec @@ -7,15 +7,15 @@ - + - + - + @@ -28,6 +28,9 @@ + + + diff --git a/mail/message-list.h b/mail/message-list.h index 4033d037a5..2b77d0b96b 100644 --- a/mail/message-list.h +++ b/mail/message-list.h @@ -57,6 +57,9 @@ enum { COL_FOLLOWUP_DUE_BY, COL_LOCATION, /* vfolder location? */ COL_SENDER, + COL_RECIPIENTS, + COL_MIXED_SENDER, + COL_MIXED_RECIPIENTS, /* normalised strings */ COL_FROM_NORM, -- cgit v1.2.3