evolution r36573 - in branches/kill-bonobo: calendar/gui calendar/modules shell



Author: mbarnes
Date: Mon Oct  6 17:41:31 2008
New Revision: 36573
URL: http://svn.gnome.org/viewvc/evolution?rev=36573&view=rev

Log:
Baseline cut at the Calendar sidebar and module.  Pretty much identical
to Tasks and Memos so far.  Now for the interesting part...


Modified:
   branches/kill-bonobo/calendar/gui/calendar-component.c
   branches/kill-bonobo/calendar/gui/gnome-cal.c
   branches/kill-bonobo/calendar/gui/memos-component.c
   branches/kill-bonobo/calendar/modules/e-cal-shell-module.c
   branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.c
   branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h
   branches/kill-bonobo/shell/e-shell-nm.c

Modified: branches/kill-bonobo/calendar/gui/calendar-component.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/calendar-component.c	(original)
+++ branches/kill-bonobo/calendar/gui/calendar-component.c	Mon Oct  6 17:41:31 2008
@@ -87,16 +87,11 @@
 
 	GList *notifications;
 
-	EUserCreatableItemsHandler *creatable_items_handler;
-
-	EActivityHandler *activity_handler;
-
 	float	     vpane_pos;
 } CalendarComponentView;
 
 struct _CalendarComponentPrivate {
 
-	GConfClient *gconf_client;
 	int gconf_notify_id;
 
 	ESourceList *source_list;
@@ -160,54 +155,6 @@
 }
 
 static void
-update_uris_for_selection (CalendarComponentView *component_view)
-{
-	GSList *selection, *l, *uids_selected = NULL;
-
-	selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-
-	for (l = component_view->source_selection; l; l = l->next) {
-		ESource *old_selected_source = l->data;
-
-		if (!is_in_selection (selection, old_selected_source))
-			gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, old_selected_source);
-	}
-
-	for (l = selection; l; l = l->next) {
-		ESource *selected_source = l->data;
-
-		if (gnome_calendar_add_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source))
-			uids_selected = g_slist_append (uids_selected, (char *) e_source_peek_uid (selected_source));
-	}
-
-	e_source_selector_free_selection (component_view->source_selection);
-	component_view->source_selection = selection;
-
-	/* Save the selection for next time we start up */
-	calendar_config_set_calendars_selected (uids_selected);
-	g_slist_free (uids_selected);
-}
-
-static void
-update_uri_for_primary_selection (CalendarComponentView *component_view)
-{
-	ESource *source;
-
-	source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
-	if (!source)
-		return;
-
-	/* Set the default */
-	gnome_calendar_set_default_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, source);
-
-	/* Make sure we are embedded first */
-	calendar_control_sensitize_calendar_commands (component_view->view_control, component_view->calendar, TRUE);
-
-	/* Save the selection for next time we start up */
-	calendar_config_set_primary_calendar (e_source_peek_uid (source));
-}
-
-static void
 update_selection (CalendarComponentView *component_view)
 {
 	GSList *selection, *uids_selected, *l;
@@ -455,18 +402,6 @@
 }
 
 static void
-source_selection_changed_cb (ESourceSelector *selector, CalendarComponentView *component_view)
-{
-	update_uris_for_selection (component_view);
-}
-
-static void
-primary_source_selection_changed_cb (ESourceSelector *selector, CalendarComponentView *component_view)
-{
-	update_uri_for_primary_selection (component_view);
-}
-
-static void
 source_changed_cb (ESource *source, GnomeCalendar *calendar)
 {
 	if (calendar) {
@@ -625,29 +560,6 @@
 }
 
 static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
-			 CORBA_short major,
-			 CORBA_short minor,
-			 CORBA_short revision,
-			 CORBA_Environment *ev)
-{
-	GError *err = NULL;
-	CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
-
-	if (!migrate_calendars (calendar_component, major, minor, revision, &err)) {
-		GNOME_Evolution_Component_UpgradeFailed *failedex;
-
-		failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
-		failedex->what = CORBA_string_dup(_("Failed upgrading calendars."));
-		failedex->why = CORBA_string_dup(err->message);
-		CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
-	}
-
-	if (err)
-		g_error_free(err);
-}
-
-static void
 config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
 {
 	CalendarComponent *calendar_component = data;
@@ -745,70 +657,6 @@
 	return priv->create_ecal;
 }
 
-static gboolean
-create_new_event (CalendarComponent *calendar_component, CalendarComponentView *component_view, gboolean is_allday, gboolean is_meeting)
-{
-	ECal *ecal;
-	ECalendarView *view;
-
-	ecal = setup_create_ecal (calendar_component, component_view);
-	if (!ecal)
-		return FALSE;
-
-	if (component_view && (view = E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (component_view->calendar)))) {
-		e_calendar_view_new_appointment_full (view, is_allday, is_meeting, TRUE);
-	} else {
-		ECalComponent *comp;
-		CompEditor *editor;
-		CompEditorFlags flags;
-
-		flags = COMP_EDITOR_USER_ORG | COMP_EDITOR_NEW_ITEM;
-		if (is_meeting)
-			flags |= COMP_EDITOR_MEETING;
-		comp = cal_comp_event_new_with_current_time (ecal, is_allday);
-		editor = event_editor_new (ecal, flags);
-		e_cal_component_commit_sequence (comp);
-
-		comp_editor_edit_comp (editor, comp);
-		if (is_meeting)
-			event_editor_show_meeting (EVENT_EDITOR (editor));
-		gtk_window_present (GTK_WINDOW (editor));
-
-		e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-	}
-
-	return TRUE;
-}
-
-static void
-create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type_name, void *data)
-{
-	CalendarComponent *calendar_component = data;
-	CalendarComponentPrivate *priv;
-	CalendarComponentView *component_view = NULL;
-	GList *l;
-
-	priv = calendar_component->priv;
-
-	for (l = priv->views; l; l = l->next) {
-		component_view = l->data;
-
-		if (component_view->creatable_items_handler == handler)
-			break;
-
-		component_view = NULL;
-	}
-
-	if (strcmp (item_type_name, CREATE_EVENT_ID) == 0)
-		create_new_event (calendar_component, component_view, FALSE, FALSE);
- 	else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0)
-		create_new_event (calendar_component, component_view, TRUE, FALSE);
-	else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0)
-		create_new_event (calendar_component, component_view, FALSE, TRUE);
-	else if (strcmp (item_type_name, CREATE_CALENDAR_ID) == 0)
-		calendar_setup_new_calendar (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->calendar))));
-}
-
 static CalendarComponentView *
 create_component_view (CalendarComponent *calendar_component)
 {
@@ -881,25 +729,16 @@
 
 	/* Create status bar */
 	statusbar_widget = e_task_bar_new ();
-	component_view->activity_handler = e_activity_handler_new ();
-	e_activity_handler_attach_task_bar (component_view->activity_handler, E_TASK_BAR (statusbar_widget));
 	gtk_widget_show (statusbar_widget);
 
 	component_view->statusbar_control = bonobo_control_new (statusbar_widget);
 
-	gnome_calendar_set_activity_handler (component_view->calendar, component_view->activity_handler);
-
 	/* connect after setting the initial selections, or we'll get unwanted calls
 	   to calendar_control_sensitize_calendar_commands */
-	g_signal_connect (component_view->source_selector, "selection_changed",
-			  G_CALLBACK (source_selection_changed_cb), component_view);
-	g_signal_connect (component_view->source_selector, "primary_selection_changed",
-			  G_CALLBACK (primary_source_selection_changed_cb), component_view);
 	g_signal_connect (component_view->source_selector, "popup_event",
 			  G_CALLBACK (popup_event_cb), component_view);
 
 	/* Set up the "new" item handler */
-	component_view->creatable_items_handler = e_user_creatable_items_handler_new ("calendar", create_local_item_cb, calendar_component);
 	g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view);
 
 	/* Load the selection from the last run */
@@ -952,12 +791,6 @@
 		calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
 	g_list_free (component_view->notifications);
 
-	if (component_view->creatable_items_handler)
-		g_object_unref (component_view->creatable_items_handler);
-
-	if (component_view->activity_handler)
-		g_object_unref (component_view->activity_handler);
-
 	if (component_view->task_source_selection) {
 		g_slist_foreach (component_view->task_source_selection, (GFunc) g_free, NULL);
 		g_slist_free (component_view->task_source_selection);
@@ -992,62 +825,6 @@
 	}
 }
 
-static GNOME_Evolution_ComponentView
-impl_createView (PortableServer_Servant servant,
-		 GNOME_Evolution_ShellView parent,
-		 CORBA_boolean select_item,
-		 CORBA_Environment *ev)
-{
-	CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
-	CalendarComponentPrivate *priv;
-	CalendarComponentView *component_view;
-	EComponentView *ecv;
-
-	priv = calendar_component->priv;
-
-	/* Create the calendar component view */
-	component_view = create_component_view (calendar_component);
-	if (!component_view) {
-		/* FIXME Should we describe the problem in a control? */
-		bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
-
-		return CORBA_OBJECT_NIL;
-	}
-
-	g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, calendar_component);
-	priv->views = g_list_append (priv->views, component_view);
-
-	/* TODO: Make CalendarComponentView just subclass EComponentView */
-	ecv = e_component_view_new_controls (parent, "calendar", component_view->sidebar_control,
-					     component_view->view_control, component_view->statusbar_control);
-
-	return BONOBO_OBJREF(ecv);
-}
-
-
-static void
-impl_requestCreateItem (PortableServer_Servant servant,
-			const CORBA_char *item_type_name,
-			CORBA_Environment *ev)
-{
-	CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
-	gboolean result = FALSE;
-
-	if (strcmp (item_type_name, CREATE_EVENT_ID) == 0)
-		result = create_new_event (calendar_component, NULL, FALSE, FALSE);
- 	else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0)
-		result = create_new_event (calendar_component, NULL, TRUE, FALSE);
-	else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0)
-		result = create_new_event (calendar_component, NULL, FALSE, TRUE);
-	else if (strcmp (item_type_name, CREATE_CALENDAR_ID) == 0)
-		/* FIXME Should we use the last opened window? */
-		calendar_setup_new_calendar (NULL);
-	else
-		bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType);
-
-	if (!result)
-		bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
-}
 
 /* GObject methods.  */
 
@@ -1063,11 +840,6 @@
 		priv->source_list = NULL;
 	}
 
-	if (priv->gconf_client != NULL) {
-		g_object_unref (priv->gconf_client);
-		priv->gconf_client = NULL;
-	}
-
 	if (priv->create_ecal) {
 		g_object_unref (priv->create_ecal);
 		priv->create_ecal = NULL;
@@ -1090,24 +862,6 @@
 }
 
 static void
-impl_finalize (GObject *object)
-{
-	CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv;
-	GList *l;
-
-	for (l = priv->views; l; l = l->next) {
-		CalendarComponentView *component_view = l->data;
-
-		destroy_component_view (component_view);
-	}
-	g_list_free (priv->views);
-
-	g_free (priv);
-
-	(* G_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-static void
 calendar_component_class_init (CalendarComponentClass *class)
 {
 	POA_GNOME_Evolution_Component__epv *epv = &class->epv;
@@ -1115,13 +869,9 @@
 
 	parent_class = g_type_class_peek_parent (class);
 
-	epv->upgradeFromVersion      = impl_upgradeFromVersion;
-	epv->createView              = impl_createView;
-	epv->requestCreateItem       = impl_requestCreateItem;
 	epv->handleURI               = impl_handleURI;
 
 	object_class->dispose  = impl_dispose;
-	object_class->finalize = impl_finalize;
 }
 
 static void
@@ -1130,12 +880,6 @@
 	CalendarComponentPrivate *priv;
 	guint not;
 
-	priv = g_new0 (CalendarComponentPrivate, 1);
-
-	/* EPFIXME: Should use a custom one instead?  Also we should add
-	 * calendar_component_peek_gconf_client().  */
-	priv->gconf_client = gconf_client_get_default ();
-
 	not = calendar_config_add_notification_primary_calendar (config_primary_selection_changed_cb,
 								 component);
 	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
@@ -1147,5 +891,3 @@
 	if (!e_cal_get_sources (&priv->memo_source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL))
 		;
 }
-
-BONOBO_TYPE_FUNC_FULL (CalendarComponent, GNOME_Evolution_Component, PARENT_TYPE, calendar_component)

Modified: branches/kill-bonobo/calendar/gui/gnome-cal.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/gnome-cal.c	(original)
+++ branches/kill-bonobo/calendar/gui/gnome-cal.c	Mon Oct  6 17:41:31 2008
@@ -1319,37 +1319,6 @@
 }
 
 static void
-set_timezone (GnomeCalendar *calendar)
-{
-	GnomeCalendarPrivate *priv;
-	int i;
-
-	priv = calendar->priv;
-
-	priv->zone = calendar_config_get_icaltimezone ();
-
-	for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
-		GList *l;
-
-		for (l = priv->clients_list[i]; l != NULL; l = l->next) {
-			ECal *client = l->data;
-
-			if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
-				/* FIXME Error checking */
-				e_cal_set_default_timezone (client, priv->zone, NULL);
-		}
-
-		if (priv->default_client[i]
-		    && e_cal_get_load_state (priv->default_client[i]) == E_CAL_LOAD_LOADED)
-			/* FIXME Error checking */
-			e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL);
-	}
-
-	if (priv->views [priv->current_view_type])
-		e_calendar_view_set_timezone (priv->views [priv->current_view_type], priv->zone);
-}
-
-static void
 timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
 {
 	GnomeCalendar *calendar = data;
@@ -2993,31 +2962,6 @@
 	return TRUE;
 }
 
-/* Callback when we get an error message from the backend */
-static void
-backend_error_cb (ECal *client, const char *message, gpointer data)
-{
-	GnomeCalendar *gcal;
-	GtkDialog *dialog;
-	char *uristr;
-
-	gcal = GNOME_CALENDAR (data);
-
-	uristr = get_uri_without_password (e_cal_get_uri (client));
-
-	dialog = GTK_DIALOG (gtk_message_dialog_new (
-		GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))),
-		GTK_DIALOG_DESTROY_WITH_PARENT,
-		GTK_MESSAGE_ERROR,
-		GTK_BUTTONS_OK,
-		_("Error on %s:\n %s"),
-		uristr, message));
-	gtk_dialog_run (GTK_DIALOG (dialog));
-	gtk_widget_destroy (GTK_WIDGET (dialog));
-
-	g_free (uristr);
-}
-
 /* Callback when the backend dies */
 static void
 backend_died_cb (ECal *ecal, gpointer data)

Modified: branches/kill-bonobo/calendar/gui/memos-component.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/memos-component.c	(original)
+++ branches/kill-bonobo/calendar/gui/memos-component.c	Mon Oct  6 17:41:31 2008
@@ -157,29 +157,6 @@
 
 /* Evolution::Component CORBA methods */
 
-static void
-impl_upgradeFromVersion (PortableServer_Servant servant,
-			 CORBA_short major,
-			 CORBA_short minor,
-			 CORBA_short revision,
-			 CORBA_Environment *ev)
-{
-	GError *err = NULL;
-	MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant));
-
-	if (!migrate_memos(component, major, minor, revision, &err)) {
-		GNOME_Evolution_Component_UpgradeFailed *failedex;
-
-		failedex = GNOME_Evolution_Component_UpgradeFailed__alloc();
-		failedex->what = CORBA_string_dup(_("Failed upgrading memos."));
-		failedex->why = CORBA_string_dup(err->message);
-		CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex);
-	}
-
-	if (err)
-		g_error_free(err);
-}
-
 static gboolean
 update_single_object (ECal *client, icalcomponent *icalcomp, gboolean fail_on_modify)
 {

Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-module.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-module.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-module.c	Mon Oct  6 17:41:31 2008
@@ -22,6 +22,7 @@
 #include <string.h>
 #include <glib/gi18n.h>
 #include <libecal/e-cal.h>
+#include <libedataserver/e-url.h>
 #include <libedataserver/e-source.h>
 #include <libedataserver/e-source-list.h>
 #include <libedataserver/e-source-group.h>
@@ -30,7 +31,11 @@
 #include "shell/e-shell-module.h"
 #include "shell/e-shell-window.h"
 
+#include "calendar/common/authentication.h"
 #include "calendar/gui/calendar-config.h"
+#include "calendar/gui/comp-util.h"
+#include "calendar/gui/dialogs/calendar-setup.h"
+#include "calendar/gui/dialogs/event-editor.h"
 
 #include "e-cal-shell-view.h"
 #include "e-cal-shell-module-migrate.h"
@@ -284,27 +289,85 @@
 }
 
 static void
-action_appointment_new_cb (GtkAction *action,
-                           EShellWindow *shell_window)
+cal_module_cal_opened_cb (ECal *cal,
+                          ECalendarStatus status,
+                          GtkAction *action)
 {
-}
+	ECalComponent *comp;
+	CompEditor *editor;
+	CompEditorFlags flags = 0;
+	const gchar *action_name;
+	gboolean all_day;
 
-static void
-action_appointment_all_day_new_cb (GtkAction *action,
-                                   EShellWindow *shell_window)
-{
+	/* XXX Handle errors better. */
+	if (status != E_CALENDAR_STATUS_OK)
+		return;
+
+	action_name = gtk_action_get_name (action);
+
+	flags |= COMP_EDITOR_NEW_ITEM;
+	flags |= COMP_EDITOR_USER_ORG;
+	if (strcmp (action_name, "meeting-new") == 0)
+		flags |= COMP_EDITOR_MEETING;
+
+	all_day = (strcmp (action_name, "appointment-all-day-new") == 0);
+
+	editor = event_editor_new (cal, flags);
+	comp = cal_comp_event_new_with_current_time (cal, all_day);
+	comp_editor_edit_comp (editor, comp);
+
+	gtk_window_present (GTK_WINDOW (editor));
+
+	g_object_unref (comp);
+	g_object_unref (cal);
 }
 
 static void
-action_meeting_new_cb (GtkAction *action,
-                       EShellWindow *shell_window)
+action_event_new_cb (GtkAction *action,
+                     EShellWindow *shell_window)
 {
+	ECal *cal = NULL;
+	ECalSourceType source_type;
+	ESourceList *source_list;
+	gchar *uid;
+
+	/* This callback is used for both appointments and meetings. */
+
+	source_type = E_CAL_SOURCE_TYPE_EVENT;
+
+	if (!e_cal_get_sources (&source_list, source_type, NULL)) {
+		g_warning ("Could not get calendar sources from GConf!");
+		return;
+	}
+
+	uid = calendar_config_get_primary_calendar ();
+
+	if (uid != NULL) {
+		ESource *source;
+
+		source = e_source_list_peek_source_by_uid (source_list, uid);
+		if (source != NULL)
+			cal = auth_new_cal_from_source (source, source_type);
+		g_free (uid);
+	}
+
+	if (cal == NULL)
+		cal = auth_new_cal_from_default (source_type);
+
+	g_return_if_fail (cal != NULL);
+
+	g_signal_connect (
+		cal, "cal-opened",
+		G_CALLBACK (cal_module_cal_opened_cb), action);
+
+	e_cal_open_async (cal, FALSE);
 }
 
 static void
 action_calendar_new_cb (GtkAction *action,
                         EShellWindow *shell_window)
 {
+	calendar_setup_new_calendar (GTK_WINDOW (shell_window));
 }
 
 static GtkActionEntry item_entries[] = {
@@ -314,21 +377,21 @@
 	  N_("_Appointment"),  /* XXX Need C_() here */
 	  "<Control>a",
 	  N_("Create a new appointment"),
-	  G_CALLBACK (action_appointment_new_cb) },
+	  G_CALLBACK (action_event_new_cb) },
 
 	{ "appointment-all-day-new",
 	  "stock_new-24h-appointment",
 	  N_("All Day A_ppointment"),
 	  NULL,
 	  N_("Create a new all-day appointment"),
-	  G_CALLBACK (action_appointment_all_day_new_cb) },
+	  G_CALLBACK (action_event_new_cb) },
 
 	{ "meeting-new",
 	  "stock_new-meeting",
 	  N_("M_eeting"),
 	  "<Control>e",
 	  N_("Create a new meeting request"),
-	  G_CALLBACK (action_meeting_new_cb) }
+	  G_CALLBACK (action_event_new_cb) }
 };
 
 static GtkActionEntry source_entries[] = {

Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.c	Mon Oct  6 17:41:31 2008
@@ -24,9 +24,11 @@
 #include <string.h>
 #include <glib/gi18n.h>
 
-#include "e-util/e-util.h"
-#include "calendar/gui/gnome-cal.h"
+#include "e-util/e-error.h"
+#include "calendar/common/authentication.h"
+#include "calendar/gui/calendar-config.h"
 #include "calendar/gui/e-calendar-selector.h"
+#include "calendar/gui/misc.h"
 
 #include "e-cal-shell-view.h"
 
@@ -36,6 +38,9 @@
 
 struct _ECalShellSidebarPrivate {
 	GtkWidget *selector;
+
+	/* UID -> Client */
+	GHashTable *client_table;
 };
 
 enum {
@@ -43,13 +48,261 @@
 	PROP_SELECTOR
 };
 
+enum {
+	CLIENT_ADDED,
+	CLIENT_REMOVED,
+	STATUS_MESSAGE,
+	LAST_SIGNAL
+};
+
 static gpointer parent_class;
+static guint signals[LAST_SIGNAL];
+
+static void
+cal_shell_sidebar_emit_client_added (ECalShellSidebar *cal_shell_sidebar,
+                                     ECal *client)
+{
+	guint signal_id = signals[CLIENT_ADDED];
+
+	g_signal_emit (cal_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+cal_shell_sidebar_emit_client_removed (ECalShellSidebar *cal_shell_sidebar,
+                                       ECal *client)
+{
+	guint signal_id = signals[CLIENT_REMOVED];
+
+	g_signal_emit (cal_shell_sidebar, signal_id, 0, client);
+}
+
+static void
+cal_shell_sidebar_emit_status_message (ECalShellSidebar *cal_shell_sidebar,
+                                       const gchar *status_message)
+{
+	guint signal_id = signals[STATUS_MESSAGE];
+
+	g_signal_emit (cal_shell_sidebar, signal_id, 0, status_message);
+}
+
+static void
+cal_shell_sidebar_update_timezone (ECalShellSidebar *cal_shell_sidebar)
+{
+	GHashTable *client_table;
+	icaltimezone *zone;
+	GList *values;
+
+	zone = calendar_config_get_icaltimezone ();
+	client_table = cal_shell_sidebar->priv->client_table;
+	values = g_hash_table_get_values (client_table);
+
+	while (values != NULL) {
+		ECal *client = values->data;
+
+		if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
+			e_cal_set_default_timezone (client, zone, NULL);
+
+		values = g_list_delete_link (values, values);
+	}
+
+	/* XXX Need to call e_calendar_view_set_timezone() here but the
+	 *     sidebar is not really supposed to access content stuff.
+	 *     I guess we could emit an "update-timezone" signal here,
+	 *     but that feels wrong.  Maybe this whole thing should be
+	 *     in ECalShellView instead. */
+}
+
+static void
+cal_shell_sidebar_backend_died_cb (ECalShellSidebar *cal_shell_sidebar,
+                                   ECal *client)
+{
+	EShellView *shell_view;
+	EShellWindow *shell_window;
+	EShellSidebar *shell_sidebar;
+	GHashTable *client_table;
+	ESource *source;
+	const gchar *uid;
+
+	client_table = cal_shell_sidebar->priv->client_table;
+
+	shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	source = e_cal_get_source (client);
+	uid = e_source_peek_uid (source);
+
+	g_object_ref (source);
+
+	g_hash_table_remove (client_table, uid);
+	cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
+
+	e_error_run (
+		GTK_WINDOW (shell_window),
+		"calendar:calendar-crashed", NULL);
+
+	g_object_unref (source);
+}
+
+static void
+cal_shell_sidebar_backend_error_cb (ECalShellSidebar *cal_shell_sidebar,
+                                    const gchar *message,
+                                    ECal *client)
+{
+	EShellView *shell_view;
+	EShellWindow *shell_window;
+	EShellSidebar *shell_sidebar;
+	GtkWidget *dialog;
+	const gchar *uri;
+	gchar *uri_no_passwd;
+
+	shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	uri = e_cal_get_uri (client);
+	uri_no_passwd = get_uri_without_password (uri);
+
+	dialog = gtk_message_dialog_new (
+		GTK_WINDOW (shell_window),
+		GTK_DIALOG_DESTROY_WITH_PARENT,
+		GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+		_("Error on %s\n%s"),
+		uri_no_passwd, message);
+
+	gtk_dialog_run (GTK_DIALOG (dialog));
+	gtk_widget_destroy (dialog);
+
+	g_free (uri_no_passwd);
+}
+
+static void
+cal_shell_sidebar_client_opened_cb (ECalShellSidebar *cal_shell_sidebar,
+                                    ECalendarStatus status,
+                                    ECal *client)
+{
+	EShellView *shell_view;
+	EShellWindow *shell_window;
+	EShellSidebar *shell_sidebar;
+	ESource *source;
+
+	source = e_cal_get_source (client);
+
+	shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	switch (status) {
+		case E_CALENDAR_STATUS_OK:
+			g_signal_handlers_disconnect_matched (
+				client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+				cal_shell_sidebar_client_opened_cb, NULL);
+
+			cal_shell_sidebar_emit_status_message (
+				cal_shell_sidebar, _("Loading calendars"));
+			cal_shell_sidebar_emit_client_added (
+				cal_shell_sidebar, client);
+			cal_shell_sidebar_emit_status_message (
+				cal_shell_sidebar, NULL);
+			break;
+
+		case E_CALENDAR_STATUS_BUSY:
+			break;
+
+		case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
+			e_error_run (
+				GTK_WINDOW (shell_window),
+				"calendar:prompt-no-contents-offline-calendar",
+				NULL);
+			break;
+
+		default:
+			cal_shell_sidebar_emit_client_removed (
+				cal_shell_sidebar, client);
+			break;
+	}
+}
+
+static void
+cal_shell_sidebar_row_changed_cb (ECalShellSidebar *cal_shell_sidebar,
+                                  GtkTreePath *tree_path,
+                                  GtkTreeIter *tree_iter,
+                                  GtkTreeModel *tree_model)
+{
+	ESourceSelector *selector;
+	ESource *source;
+
+	/* XXX ESourceSelector's underlying tree store has only one
+	 *     column: ESource objects.  While we're not supposed to
+	 *     know this, listening for "row-changed" signals from
+	 *     the model is easier to deal with than the selector's
+	 *     "selection-changed" signal, which doesn't tell you
+	 *     _which_ row changed. */
+
+	selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+	gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1);
+
+	/* XXX This signal gets emitted a lot while the model is being
+	 *     rebuilt, during which time we won't get a valid ESource.
+	 *     ESourceSelector should probably block this signal while
+	 *     rebuilding the model, but we'll be forgiving and not
+	 *     emit a warning. */
+	if (!E_IS_SOURCE (source))
+		return;
+
+	if (e_source_selector_source_is_selected (selector, source))
+		e_cal_shell_sidebar_add_source (cal_shell_sidebar, source);
+	else
+		e_cal_shell_sidebar_remove_source (cal_shell_sidebar, source);
+}
+
+static void
+cal_shell_sidebar_selection_changed_cb (ECalShellSidebar *cal_shell_sidebar,
+                                        ESourceSelector *selector)
+{
+	GSList *list, *iter;
+
+	/* This signal is emitted less frequently than "row-changed",
+	 * especially when the model is being rebuilt.  So we'll take
+	 * it easy on poor GConf. */
+
+	list = e_source_selector_get_selection (selector);
+
+	for (iter = list; iter != NULL; iter = iter->next) {
+		ESource *source = iter->data;
+
+		iter->data = (gpointer) e_source_peek_uid (source);
+		g_object_unref (source);
+	}
+
+	calendar_config_set_calendars_selected (list);
+
+	g_slist_free (list);
+}
+
+static void
+cal_shell_sidebar_primary_selection_changed_cb (ECalShellSidebar *cal_shell_sidebar,
+                                                ESourceSelector *selector)
+{
+	ESource *source;
+	const gchar *uid;
+
+	/* XXX ESourceSelector needs a "primary-selection-uid" property
+	 *     so we can just bind the property with GConfBridge. */
+
+	source = e_source_selector_peek_primary_selection (selector);
+	if (source == NULL)
+		return;
+
+	uid = e_source_peek_uid (source);
+	calendar_config_set_primary_calendar (uid);
+}
 
 static void
 cal_shell_sidebar_get_property (GObject *object,
-                                 guint property_id,
-                                 GValue *value,
-                                 GParamSpec *pspec)
+                                guint property_id,
+                                GValue *value,
+                                GParamSpec *pspec)
 {
 	switch (property_id) {
 		case PROP_SELECTOR:
@@ -74,20 +327,40 @@
 		priv->selector = NULL;
 	}
 
+	g_hash_table_remove_all (priv->client_table);
+
 	/* Chain up to parent's dispose() method. */
 	G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static void
+cal_shell_sidebar_finalize (GObject *object)
+{
+	ECalShellSidebarPrivate *priv;
+
+	priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object);
+
+	g_hash_table_destroy (priv->client_table);
+
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
 cal_shell_sidebar_constructed (GObject *object)
 {
 	ECalShellSidebarPrivate *priv;
 	EShellView *shell_view;
 	EShellSidebar *shell_sidebar;
 	ECalShellView *cal_shell_view;
+	ESourceSelector *selector;
 	ESourceList *source_list;
+	ESource *source;
 	GtkContainer *container;
+	GtkTreeModel *model;
 	GtkWidget *widget;
+	GSList *list, *iter;
+	gchar *uid;
 
 	priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object);
 
@@ -117,6 +390,83 @@
 	gtk_container_add (container, widget);
 	priv->selector = g_object_ref (widget);
 	gtk_widget_show (widget);
+
+	/* Restore the selector state from the last session. */
+
+	selector = E_SOURCE_SELECTOR (priv->selector);
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+	g_signal_connect_swapped (
+		model, "row-changed",
+		G_CALLBACK (cal_shell_sidebar_row_changed_cb),
+		object);
+
+	source = NULL;
+	uid = calendar_config_get_primary_calendar ();
+	if (uid != NULL)
+		source = e_source_list_peek_source_by_uid (source_list, uid);
+	if (source == NULL)
+		source = e_source_list_peek_source_any (source_list);
+	if (source != NULL)
+		e_source_selector_set_primary_selection (selector, source);
+	g_free (uid);
+
+	list = calendar_config_get_tasks_selected ();
+	for (iter = list; iter != NULL; iter = iter->next) {
+		uid = iter->data;
+		source = e_source_list_peek_source_by_uid (source_list, uid);
+		g_free (uid);
+
+		if (source == NULL)
+			continue;
+
+		e_source_selector_select_source (selector, source);
+	}
+	g_slist_free (list);
+
+	/* Listen for subsequent changes to the selector. */
+
+	g_signal_connect_swapped (
+		widget, "selection-changed",
+		G_CALLBACK (cal_shell_sidebar_selection_changed_cb),
+		object);
+
+	g_signal_connect_swapped (
+		widget, "primary-selection-changed",
+		G_CALLBACK (cal_shell_sidebar_primary_selection_changed_cb),
+		object);
+}
+
+static void
+cal_shell_sidebar_client_added (ECalShellSidebar *cal_shell_sidebar,
+                                ECal *client)
+{
+	cal_shell_sidebar_update_timezone (cal_shell_sidebar);
+}
+
+static void
+cal_shell_sidebar_client_removed (ECalShellSidebar *cal_shell_sidebar,
+                                  ECal *client)
+{
+	ESourceSelector *selector;
+	GHashTable *client_table;
+	ESource *source;
+	const gchar *uid;
+
+	client_table = cal_shell_sidebar->priv->client_table;
+	selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+	g_signal_handlers_disconnect_matched (
+		client, G_SIGNAL_MATCH_DATA, 0, 0,
+		NULL, NULL, cal_shell_sidebar);
+
+	source = e_cal_get_source (client);
+	e_source_selector_unselect_source (selector, source);
+
+	uid = e_source_peek_uid (source);
+	g_hash_table_remove (client_table, uid);
+
+	cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
 }
 
 static void
@@ -130,8 +480,12 @@
 	object_class = G_OBJECT_CLASS (class);
 	object_class->get_property = cal_shell_sidebar_get_property;
 	object_class->dispose = cal_shell_sidebar_dispose;
+	object_class->finalize = cal_shell_sidebar_finalize;
 	object_class->constructed = cal_shell_sidebar_constructed;
 
+	class->client_added = cal_shell_sidebar_client_added;
+	class->client_removed = cal_shell_sidebar_client_removed;
+
 	g_object_class_install_property (
 		object_class,
 		PROP_SELECTOR,
@@ -141,14 +495,53 @@
 			_("This widget displays groups of calendars"),
 			E_TYPE_SOURCE_SELECTOR,
 			G_PARAM_READABLE));
+
+	signals[CLIENT_ADDED] = g_signal_new (
+		"client-added",
+		G_OBJECT_CLASS_TYPE (object_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (ECalShellSidebarClass, client_added),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__OBJECT,
+		G_TYPE_NONE, 1,
+		E_TYPE_CAL);
+
+	signals[CLIENT_REMOVED] = g_signal_new (
+		"client-removed",
+		G_OBJECT_CLASS_TYPE (object_class),
+		G_SIGNAL_RUN_LAST,
+		G_STRUCT_OFFSET (ECalShellSidebarClass, client_removed),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__OBJECT,
+		G_TYPE_NONE, 1,
+		E_TYPE_CAL);
+
+	signals[STATUS_MESSAGE] = g_signal_new (
+		"status-message",
+		G_OBJECT_CLASS_TYPE (object_class),
+		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+		G_STRUCT_OFFSET (ECalShellSidebarClass, status_message),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__STRING,
+		G_TYPE_NONE, 1,
+		G_TYPE_STRING);
 }
 
 static void
 cal_shell_sidebar_init (ECalShellSidebar *cal_shell_sidebar)
 {
+	GHashTable *client_table;
+
+	client_table = g_hash_table_new_full (
+		g_str_hash, g_str_equal,
+		(GDestroyNotify) g_free,
+		(GDestroyNotify) g_object_unref);
+
 	cal_shell_sidebar->priv =
 		E_CAL_SHELL_SIDEBAR_GET_PRIVATE (cal_shell_sidebar);
 
+	cal_shell_sidebar->priv->client_table = client_table;
+
 	/* Postpone widget construction until we have a shell view. */
 }
 
@@ -189,11 +582,87 @@
 		"shell-view", shell_view, NULL);
 }
 
-GtkWidget *
+ESourceSelector *
 e_cal_shell_sidebar_get_selector (ECalShellSidebar *cal_shell_sidebar)
 {
 	g_return_val_if_fail (
 		E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL);
 
-	return cal_shell_sidebar->priv->selector;
+	return E_SOURCE_SELECTOR (cal_shell_sidebar->priv->selector);
+}
+
+void
+e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar,
+                                ESource *source)
+{
+	ESourceSelector *selector;
+	GHashTable *client_table;
+	ECal *client;
+	const gchar *uid;
+	const gchar *uri;
+	gchar *message;
+
+	g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar));
+	g_return_if_fail (E_IS_SOURCE (source));
+
+	client_table = cal_shell_sidebar->priv->client_table;
+	selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+	uid = e_source_peek_uid (source);
+	client = g_hash_table_lookup (client_table, uid);
+
+	if (client != NULL)
+		return;
+
+	client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT);
+	g_return_if_fail (client != NULL);
+
+	g_signal_connect_swapped (
+		client, "backend-died",
+		G_CALLBACK (cal_shell_sidebar_backend_died_cb),
+		cal_shell_sidebar);
+
+	g_signal_connect_swapped (
+		client, "backend-error",
+		G_CALLBACK (cal_shell_sidebar_backend_error_cb),
+		cal_shell_sidebar);
+
+	g_hash_table_insert (client_table, g_strdup (uid), client);
+	e_source_selector_select_source (selector, source);
+
+	uri = e_cal_get_uri (client);
+	message = g_strdup_printf (_("Opening calendar at %s"), uri);
+	cal_shell_sidebar_emit_status_message (cal_shell_sidebar, message);
+	g_free (message);
+
+	g_signal_connect_swapped (
+		client, "cal-opened",
+		G_CALLBACK (cal_shell_sidebar_client_opened_cb),
+		cal_shell_sidebar);
+
+	e_cal_open_async (client, FALSE);
+}
+
+void
+e_cal_shell_sidebar_remove_source (ECalShellSidebar *cal_shell_sidebar,
+                                   ESource *source)
+{
+	ESourceSelector *selector;
+	GHashTable *client_table;
+	ECal *client;
+	const gchar *uid;
+
+	g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar));
+	g_return_if_fail (E_IS_SOURCE (source));
+
+	client_table = cal_shell_sidebar->priv->client_table;
+	selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
+
+	uid = e_source_peek_uid (source);
+	client = g_hash_table_lookup (client_table, uid);
+
+	if (client == NULL)
+		return;
+
+	cal_shell_sidebar_emit_client_removed (cal_shell_sidebar, client);
 }

Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h	Mon Oct  6 17:41:31 2008
@@ -22,6 +22,9 @@
 #ifndef E_CAL_SHELL_SIDEBAR_H
 #define E_CAL_SHELL_SIDEBAR_H
 
+#include <libecal/e-cal.h>
+#include <libedataserverui/e-source-selector.h>
+
 #include <shell/e-shell-sidebar.h>
 #include <shell/e-shell-view.h>
 
@@ -57,11 +60,25 @@
 
 struct _ECalShellSidebarClass {
 	EShellSidebarClass parent_class;
+
+	/* Signals */
+	void	(*client_added)			(ECalShellSidebar *cal_shell_sidebar,
+						 ECal *client);
+	void	(*client_removed)		(ECalShellSidebar *cal_shell_sidebar,
+						 ECal *client);
+	void	(*status_message)		(ECalShellSidebar *cal_shell_sidebar,
+						 const gchar *status_message);
 };
 
 GType		e_cal_shell_sidebar_get_type	(void);
 GtkWidget *	e_cal_shell_sidebar_new		(EShellView *shell_view);
-GtkWidget *	e_cal_shell_sidebar_get_selector(ECalShellSidebar *cal_shell_sidebar);
+ESourceSelector *
+		e_cal_shell_sidebar_get_selector(ECalShellSidebar *cal_shell_sidebar);
+void		e_cal_shell_sidebar_add_source	(ECalShellSidebar *cal_shell_sidebar,
+						 ESource *source);
+void		e_cal_shell_sidebar_remove_source
+						(ECalShellSidebar *cal_shell_sidebar,
+						 ESource *source);
 
 G_END_DECLS
 

Modified: branches/kill-bonobo/shell/e-shell-nm.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell-nm.c	(original)
+++ branches/kill-bonobo/shell/e-shell-nm.c	Mon Oct  6 17:41:31 2008
@@ -48,7 +48,8 @@
 
 static DBusHandlerResult
 e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED,
-                         DBusMessage *message, void *user_data)
+                         DBusMessage *message,
+                         gpointer user_data)
 {
 	DBusError error;
 	const gchar *object;
@@ -60,7 +61,7 @@
 	object = dbus_message_get_path (message);
 
 	if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
-		object && !strcmp (object, DBUS_PATH_LOCAL)) {
+		object != NULL && strcmp (object, DBUS_PATH_LOCAL) == 0) {
 		dbus_connection_unref (dbus_connection);
 		dbus_connection = NULL;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]