Index: shell/e-sidebar.h
===================================================================
--- shell/e-sidebar.h	(revision 34363)
+++ 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/Evolution-Shell.idl
===================================================================
--- shell/Evolution-Shell.idl	(revision 34363)
+++ shell/Evolution-Shell.idl	(working copy)
@@ -30,6 +30,7 @@
 		/* Should really use a ComponentView i guess */
 		void setTitle(in string component, in string title);
 		void setComponent(in string component);
+		void setButtonIcon(in string component, in string iconName);
 	};
 
 	interface Shell : Bonobo::Unknown {
Index: shell/e-shell.c
===================================================================
--- shell/e-shell.c	(revision 34363)
+++ shell/e-shell.c	(working copy)
@@ -1379,4 +1379,42 @@
 	return can_quit;
 }
 
+/**
+ * gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
+ * Function used in @ref e_shell_foreach_shell_window.
+ * @param shell Pointer to 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.
+ **/
+
+/**
+ * e_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 shell EShell instance.
+ * @param func Function to be called.
+ * @param user_data User data to pass to func.
+ **/
+void
+e_shell_foreach_shell_window (EShell *shell, EMainShellFunc func, gpointer user_data)
+{
+	EShellPrivate *priv;
+	GList *p;
+
+	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-component-view.c
===================================================================
--- shell/e-component-view.c	(revision 34363)
+++ shell/e-component-view.c	(working copy)
@@ -137,5 +137,15 @@
 	CORBA_exception_free(&ev);
 }
 
+void
+e_component_view_set_button_icon (EComponentView *ecv, const char *iconName)
+{
+	CORBA_Environment ev = { 0 };
+
+	/* save roundtrips, check title is the same */
+	GNOME_Evolution_ShellView_setButtonIcon(ecv->shell_view, ecv->id, iconName, &ev);
+	CORBA_exception_free(&ev);
+}
+
 BONOBO_TYPE_FUNC_FULL (EComponentView, GNOME_Evolution_ComponentView, bonobo_object_get_type(), e_component_view)
 
Index: shell/e-shell-window.c
===================================================================
--- shell/e-shell-window.c	(revision 34363)
+++ 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 34363)
+++ shell/e-shell.h	(working copy)
@@ -133,6 +133,8 @@
 
 const char *e_shell_construct_result_to_string (EShellConstructResult result);
 
+typedef gboolean (*EMainShellFunc) (EShell *shell, EShellWindow *window, gpointer user_data);
+void e_shell_foreach_shell_window (EShell *shell, EMainShellFunc func, gpointer user_data);
 
 #ifdef __cplusplus
 }
Index: shell/e-component-view.h
===================================================================
--- shell/e-component-view.h	(revision 34363)
+++ shell/e-component-view.h	(working copy)
@@ -69,6 +69,7 @@
 EComponentView *e_component_view_new_controls(GNOME_Evolution_ShellView parent, const char *id, struct _BonoboControl *side, struct _BonoboControl *view, struct _BonoboControl *statusbar);
 
 void e_component_view_set_title(EComponentView *ecv, const char *title);
+void e_component_view_set_button_icon (EComponentView *ecv, const char *iconName);
 
 #ifdef __cplusplus
 }
Index: shell/e-shell-view.c
===================================================================
--- shell/e-shell-view.c	(revision 34363)
+++ shell/e-shell-view.c	(working copy)
@@ -32,6 +32,7 @@
 
 #include "e-shell-view.h"
 #include "e-shell-window.h"
+#include "e-util/e-icon-factory.h"
 
 static BonoboObjectClass *parent_class = NULL;
 
@@ -57,7 +58,44 @@
 	e_shell_window_switch_to_component(esw->window, id);
 }
 
+struct change_icon_struct {
+	const char *component_name;
+	GdkPixbuf *icon;
+};
+
+static gboolean
+change_button_icon_func (EShell *shell, EShellWindow *window, gpointer user_data)
+{
+	struct change_icon_struct *cis = (struct change_icon_struct*)user_data;
+
+	g_return_val_if_fail (window != NULL, FALSE);
+	g_return_val_if_fail (cis != NULL, FALSE);
+
+	e_shell_window_change_component_button_icon (window, cis->component_name, cis->icon);
+
+	return TRUE;
+}
+
 static void
+impl_ShellView_setButtonIcon (PortableServer_Servant _servant, const CORBA_char *id, const CORBA_char * iconName, CORBA_Environment * ev)
+{
+	EShellView *esw = (EShellView *)bonobo_object_from_servant(_servant);
+	EShell *shell = e_shell_window_peek_shell (esw->window);
+
+	struct change_icon_struct cis;
+	cis.component_name = id;
+	cis.icon = NULL;
+
+	if (iconName)
+		cis.icon = e_icon_factory_get_icon (iconName, E_ICON_SIZE_BUTTON);
+
+	e_shell_foreach_shell_window (shell, change_button_icon_func, &cis);
+
+	if (cis.icon)
+		g_object_unref (cis.icon);
+}
+
+static void
 impl_dispose (GObject *object)
 {
 	/*EShellView *esv = (EShellView *)object;*/
@@ -86,6 +124,7 @@
 	epv = & klass->epv;
 	epv->setTitle = impl_ShellView_setTitle;
 	epv->setComponent = impl_ShellView_setComponent;
+	epv->setButtonIcon = impl_ShellView_setButtonIcon;
 }
 
 static void
Index: shell/e-shell-window.h
===================================================================
--- shell/e-shell-window.h	(revision 34363)
+++ 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 34363)
+++ shell/ChangeLog	(working copy)
@@ -1,3 +1,22 @@
+2007-10-09  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #329823
+
+	* Evolution-Shell.idl: (setButtonIcon):
+	* 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: (EMainShellFunc), (e_shell_foreach_shell_window):
+	* e-shell.c: (EMainShellFunc), (e_shell_foreach_shell_window):
+	* e-component-view.h: (e_component_view_set_button_icon):
+	* e-component-view.c: (e_component_view_set_button_icon):
+	* e-shell-window.h: (e_shell_window_change_component_button_icon):
+	* e-shell-window.c: (e_shell_window_change_component_button_icon):
+	* e-shell-view.c: (struct change_icon_struct),
+	(change_button_icon_func), (impl_ShellView_setButtonIcon),
+	(e_shell_view_class_init):
+	Added support to change component's button icon.
+
 2007-10-03  Matthew Barnes  <mbarnes@redhat.com>
 
 	* e-shell-window-commands.c (command_about):
Index: shell/e-sidebar.c
===================================================================
--- shell/e-sidebar.c	(revision 34363)
+++ 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 34363)
+++ mail/ChangeLog	(working copy)
@@ -1,3 +1,16 @@
+2007-10-01  Milan Crha  <mcrha@redhat.com>
+
+	** Fix for bug #329823
+
+	* mail-component.h: (mail_indicate_new_mail):
+	* mail-component.c: (mail_indicate_new_mail),
+	(struct _MailComponentPrivate), (impl_dispose), (impl_createView):
+	New function to indicate new mails on sidebar's button and storing
+	component_view in priv struct for later use.
+	* 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-09  Milan Crha  <mcrha@redhat.com>
 
 	** Fix for bug #477045
Index: mail/em-folder-view.c
===================================================================
--- mail/em-folder-view.c	(revision 34363)
+++ mail/em-folder-view.c	(working copy)
@@ -2322,7 +2322,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 34363)
+++ 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 34363)
+++ mail/mail-component.c	(working copy)
@@ -139,6 +139,8 @@
 	char *context_path;	/* current path for right-click menu */
 	
 	CamelStore *local_store;
+
+	EComponentView *component_view;
 };
 
 /* indexed by _mail_component_folder_t */
@@ -455,7 +457,9 @@
 		camel_object_unref (priv->local_store);
 		priv->local_store = NULL;
 	}
-	
+
+	priv->component_view = NULL;
+
 	(* G_OBJECT_CLASS (parent_class)->dispose) (object);
 }
 
@@ -742,6 +746,8 @@
 	g_object_set_data((GObject*)info, "folderview", view_widget);
 	g_object_set_data((GObject*)view_widget, "foldertree", tree_widget);
 
+	priv->component_view = component_view;
+
 	return BONOBO_OBJREF(component_view);
 }
 
@@ -1463,4 +1469,24 @@
 	return mc_default_folders[id].uri;
 }
 
+/**
+ * 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)
+{
+	const char *icon = NULL;
+	MailComponent *mc = mail_component_peek ();
+
+	g_return_if_fail (mc != NULL);
+
+	if (have_new_mail)
+		icon = "mail-unread";
+
+	if (mc->priv->component_view)
+		e_component_view_set_button_icon (mc->priv->component_view, icon);
+}
+
 BONOBO_TYPE_FUNC_FULL (MailComponent, GNOME_Evolution_MailComponent, PARENT_TYPE, mail_component)
Index: mail/mail-component.h
===================================================================
--- mail/mail-component.h	(revision 34363)
+++ 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_ */
