Index: shell/e-sidebar.h
===================================================================
--- shell/e-sidebar.h	(revision 34345)
+++ shell/e-sidebar.h	(working copy)
@@ -73,6 +73,10 @@
 void  e_sidebar_select_button  (ESidebar *sidebar,
 				int       id);
 
+void e_sidebar_change_button_icon (ESidebar *sidebar,
+				   GdkPixbuf  *icon,
+				   int button_id);
+
 ESidebarMode e_sidebar_get_mode (ESidebar *sidebar);
 void e_sidebar_set_mode (ESidebar *sidebar, ESidebarMode mode);
 
Index: shell/e-shell.c
===================================================================
--- shell/e-shell.c	(revision 34345)
+++ shell/e-shell.c	(working copy)
@@ -1379,4 +1379,43 @@
 	return can_quit;
 }
 
+/**
+ * gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
+ * Function used in @ref main_shell_foreach_shell_window.
+ * @param shell Pointer to main EShell.
+ * @param window Pointer to EShellWindow.
+ * @param user_data User's data passed to @ref main_shell_foreach_shell_window.
+ * @return TRUE if need to go to next window, FALSE when stop looking for next window.
+ **/
+
+/**
+ * main_shell_foreach_shell_window
+ * This will call function callback for all known EShellWindow of main shell.
+ * When there is no shell active, then this will do nothing.
+ * @param func Function to be called.
+ * @param user_data User data to pass to func.
+ **/
+void
+main_shell_foreach_shell_window (EMainShellFunc func, gpointer user_data)
+{
+	EShell *shell;
+	EShellPrivate *priv;
+	GList *p;
+
+	shell = get_main_shell ();
+	if (!shell)
+		return;
+
+	priv = shell->priv;
+
+	for (p = priv->windows; p != NULL; p = p->next) {
+		EShellWindow *window;
+
+		window = E_SHELL_WINDOW (p->data);
+
+		if (window && !func (shell, window, user_data))
+			break;
+	}
+}
+
 BONOBO_TYPE_FUNC_FULL (EShell, GNOME_Evolution_Shell, PARENT_TYPE, e_shell)
Index: shell/e-shell-window.c
===================================================================
--- shell/e-shell-window.c	(revision 34345)
+++ shell/e-shell-window.c	(working copy)
@@ -1287,3 +1287,36 @@
 	}
 }
 
+/**
+ * e_shell_window_change_component_button_icon
+ * Changes icon of components button at sidebar. For more info how this behaves see
+ * info at @ref e_sidebar_change_button_icon.
+ * @param window EShellWindow instance.
+ * @param component_id ID of the component.
+ * @param icon Icon buffer.
+ **/
+void
+e_shell_window_change_component_button_icon (EShellWindow *window, const char *component_id, GdkPixbuf *icon)
+{
+	EShellWindowPrivate *priv;
+	GSList *p;
+
+	g_return_if_fail (window != NULL);
+	g_return_if_fail (component_id != NULL);
+
+	priv = window->priv;
+
+	if (priv->destroyed)
+		return;
+
+	for (p = priv->component_views; p != NULL; p = p->next) {
+		ComponentView *this_view = p->data;
+
+		if (strcmp (this_view->component_id, component_id) == 0
+		    || (this_view->component_alias != NULL
+			&& strcmp (this_view->component_alias, component_id) == 0)) {
+			e_sidebar_change_button_icon (E_SIDEBAR (priv->sidebar), icon, this_view->button_id);
+			break;
+		}
+	}
+}
Index: shell/e-shell.h
===================================================================
--- shell/e-shell.h	(revision 34345)
+++ shell/e-shell.h	(working copy)
@@ -133,7 +133,11 @@
 
 const char *e_shell_construct_result_to_string (EShellConstructResult result);
 
+EShell *get_main_shell (void);
 
+typedef gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
+void main_shell_foreach_shell_window (EMainShellFunc func, gpointer user_data);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
Index: shell/e-shell-window.h
===================================================================
--- shell/e-shell-window.h	(revision 34345)
+++ shell/e-shell-window.h	(working copy)
@@ -73,4 +73,6 @@
 void  e_shell_window_save_defaults  (EShellWindow *window);
 void  e_shell_window_show_settings  (EShellWindow *window);
 
+void e_shell_window_change_component_button_icon (EShellWindow *window, const char *component_id, GdkPixbuf *icon);
+
 #endif /* _E_SHELL_WINDOW_H_ */
Index: shell/ChangeLog
===================================================================
--- shell/ChangeLog	(revision 34345)
+++ shell/ChangeLog	(working copy)
@@ -1,3 +1,18 @@
+2007-10-03  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #329823
+
+	* e-sidebar.h: (e_sidebar_change_button_icon):
+	* e-sidebar.c: (struct Button), (button_new), (button_free),
+	(e_sidebar_change_button_icon):
+	* e-shell.h: (get_main_shell), (EMainShellFunc),
+	(main_shell_foreach_shell_window):
+	* e-shell.c: (main_shell_foreach_shell_window):
+	* main.c: (get_main_shell):
+	* e-shell-window.h: (e_shell_window_change_component_button_icon):
+	* e-shell-window.c: (e_shell_window_change_component_button_icon):
+	Added support to access main shell and change icons on buttons.
+
 2007-10-02  Matthew Barnes  <mbarnes@redhat.com>
 
 	** Fixes part of bug #469657
Index: shell/main.c
===================================================================
--- shell/main.c	(revision 34345)
+++ shell/main.c	(working copy)
@@ -451,6 +451,12 @@
 #define setup_segv_redirect() 0
 #endif
 
+EShell *
+get_main_shell (void)
+{
+	return shell;
+}
+
 static const GOptionEntry options[] = {
 	{ "component", 'c', 0, G_OPTION_ARG_STRING, &default_component_id,
 	  N_("Start Evolution activating the specified component"), NULL },
Index: shell/e-sidebar.c
===================================================================
--- shell/e-sidebar.c	(revision 34345)
+++ shell/e-sidebar.c	(working copy)
@@ -43,6 +43,7 @@
 	GtkWidget *icon;
 	GtkWidget *hbox;
 	GtkTooltips *tooltips;
+	GdkPixbuf *default_icon;
 	int id;
 } Button;
 
@@ -89,6 +90,7 @@
 	button->hbox = hbox;
 	button->tooltips = tooltips;
 	button->id = id;
+	button->default_icon = NULL;
 
 	g_object_ref (button_widget);
 	g_object_ref (label);
@@ -107,6 +109,8 @@
 	g_object_unref (button->icon);
 	g_object_unref (button->hbox);
 	g_object_unref (button->tooltips);
+	if (button->default_icon)
+		g_object_unref (button->default_icon);
 	g_free (button);
 }
 
@@ -578,8 +582,47 @@
 	gtk_widget_queue_resize (GTK_WIDGET (sidebar));
 }
 
+/**
+ * e_sidebar_change_button_icon
+ * This will change icon in icon_widget of the button of known component.
+ * You cannot change icon as in a stack, only one default icon will be stored.
+ * @param sidebar ESidebar instance.
+ * @param icon Pointer to buffer with icon. Can by NULL, in this case the icon will be
+ *             put back to default one for the component.
+ * @param button_id Component's button ID, for which change the icon.
+ **/
 
 void
+e_sidebar_change_button_icon (ESidebar *sidebar, GdkPixbuf  *icon, int button_id)
+{
+	GSList *p;
+
+	g_return_if_fail (sidebar != NULL);
+
+	for (p = sidebar->priv->buttons; p != NULL; p = p->next) {
+		Button *button = p->data;
+
+		if (button->id == button_id) {
+			if (!button->icon)
+				break;
+
+			if (icon) {
+				if (!button->default_icon)
+					button->default_icon = gdk_pixbuf_copy (gtk_image_get_pixbuf (GTK_IMAGE (button->icon)));
+
+				gtk_image_set_from_pixbuf (GTK_IMAGE (button->icon), icon);
+			} else if (button->default_icon) {
+				gtk_image_set_from_pixbuf (GTK_IMAGE (button->icon), button->default_icon);
+				g_object_unref (button->default_icon);
+				button->default_icon = NULL;
+			}
+
+			break;
+		}
+	}
+}
+
+void
 e_sidebar_select_button (ESidebar *sidebar, int id)
 {
 	update_buttons (sidebar, id);
Index: mail/ChangeLog
===================================================================
--- mail/ChangeLog	(revision 34346)
+++ mail/ChangeLog	(working copy)
@@ -1,3 +1,15 @@
+2007-10-03  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #329823
+
+	* mail-component.h: (mail_indicate_new_mail):
+	* mail-component.c: (change_button_icon_func),
+	(mail_indicate_new_mail):
+	New function to indicate new mails on sidebar's button.
+	* em-folder-view.c: (emfv_list_done_message_selected):
+	* mail-folder-cache.c: (real_flush_updates):
+	Indicate changes like for plugins for new mails.
+
 2007-10-03  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #473903
Index: mail/em-folder-view.c
===================================================================
--- mail/em-folder-view.c	(revision 34345)
+++ mail/em-folder-view.c	(working copy)
@@ -2319,7 +2319,9 @@
 	}
 
 	e_profile_event_emit("goto.loaded", emfv->displayed_uid, 0);
-		
+
+	mail_indicate_new_mail (FALSE);
+
 	/** @Event: message.reading
 	 * @Title: Viewing a message
 	 * @Target: EMEventTargetMessage
Index: mail/mail-folder-cache.c
===================================================================
--- mail/mail-folder-cache.c	(revision 34345)
+++ mail/mail-folder-cache.c	(working copy)
@@ -251,6 +251,10 @@
 			EMEventTargetFolder *t = em_event_target_new_folder(e, up->uri, up->new);
 
 			t->is_inbox = em_folder_tree_model_is_type_inbox (model, up->store, up->full_name);
+
+			if (t->new > 0)
+				mail_indicate_new_mail (TRUE);
+
 			/** @Event: folder.changed
 			 * @Title: Folder changed
 			 * @Target: EMEventTargetFolder
Index: mail/mail-component.c
===================================================================
--- mail/mail-component.c	(revision 34345)
+++ mail/mail-component.c	(working copy)
@@ -50,6 +50,7 @@
 #include "misc/e-info-label.h"
 #include "e-util/e-error.h"
 #include "e-util/e-util-private.h"
+#include "e-util/e-icon-factory.h"
 
 #include "em-search-context.h"
 #include "mail-config.h"
@@ -66,6 +67,7 @@
 #include "e-activity-handler.h"
 #include "shell/e-user-creatable-items-handler.h"
 #include "shell/e-component-view.h"
+#include "shell/e-shell.h"
 
 #include "composer/e-msg-composer.h"
 
@@ -1463,4 +1465,35 @@
 	return mc_default_folders[id].uri;
 }
 
+static gboolean
+change_button_icon_func (EShell *shell, EShellWindow *window, gpointer user_data)
+{
+	g_return_val_if_fail (window != NULL, FALSE);
+
+	e_shell_window_change_component_button_icon (window, "mail", (GdkPixbuf *)user_data);
+
+	return TRUE;
+}
+
+/**
+ * mail_indicate_new_mail
+ * Indicates new mail in a shell window.
+ * @param have_new_mail TRUE when have new mail, false otherwise.
+ **/
+void
+mail_indicate_new_mail (gboolean have_new_mail)
+{
+	GdkPixbuf *icon;
+
+	if (have_new_mail)
+		icon = e_icon_factory_get_icon ("mail-unread", E_ICON_SIZE_BUTTON);
+	else
+		icon = NULL;
+
+	main_shell_foreach_shell_window (change_button_icon_func, icon);
+
+	if (icon)
+		g_object_unref (icon);
+}
+
 BONOBO_TYPE_FUNC_FULL (MailComponent, GNOME_Evolution_MailComponent, PARENT_TYPE, mail_component)
Index: mail/mail-component.h
===================================================================
--- mail/mail-component.h	(revision 34345)
+++ mail/mail-component.h	(working copy)
@@ -99,4 +99,7 @@
 const char *mail_component_get_folder_uri(MailComponent *mc, enum _mail_component_folder_t id);
 
 int status_check (GNOME_Evolution_ShellState shell_state);
+
+void mail_indicate_new_mail (gboolean have_new_mail);
+
 #endif /* _MAIL_COMPONENT_H_ */
