static void
memo_shell_content_model_row_changed_cb (EMemoShellContent *memo_shell_content,
                                         gint row,
                                         ETableModel *model)
{
	ECalModelComponent *comp_data;
	EMemoTable *memo_table;
	const gchar *current_uid;
	const gchar *uid;

	current_uid = memo_shell_content->priv->current_uid;
	if (current_uid == NULL)
		return;

	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
	if (comp_data == NULL)
		return;

	uid = icalcomponent_get_uid (comp_data->icalcomp);
	if (g_strcmp0 (uid, current_uid) != 0)
		return;

	memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);

	memo_shell_content_cursor_change_cb (
		memo_shell_content, 0, E_TABLE (memo_table));
}
static gpointer
cal_model_calendar_value_at (ETableModel *etm,
                             gint col,
                             gint row)
{
	ECalModelComponent *comp_data;
	ECalModelCalendar *model = (ECalModelCalendar *) etm;

	g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), NULL);

	g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
	g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL);

	if (col < E_CAL_MODEL_FIELD_LAST)
		return table_model_parent_interface->value_at (etm, col, row);

	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
	if (!comp_data)
		return (gpointer) "";

	switch (col) {
	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
		return get_dtend (model, comp_data);
	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
		return get_location (comp_data);
	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
		return get_transparency (comp_data);
	}

	return (gpointer) "";
}
static void
cal_model_calendar_set_value_at (ETableModel *etm,
                                 gint col,
                                 gint row,
                                 gconstpointer value)
{
	ECalModelComponent *comp_data;
	ECalObjModType mod = E_CAL_OBJ_MOD_ALL;
	ECalComponent *comp;
	ECalModelCalendar *model = (ECalModelCalendar *) etm;

	g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
	g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);
	g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm));

	if (col < E_CAL_MODEL_FIELD_LAST) {
		table_model_parent_interface->set_value_at (etm, col, row, value);
		return;
	}

	comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
	if (!comp_data)
		return;

	comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (comp_data->icalcomp));
	if (!comp) {
		return;
	}

	/* ask about mod type */
	if (e_cal_component_is_instance (comp)) {
		if (!e_cal_dialogs_recur_component (comp_data->client, comp, &mod, NULL, FALSE)) {
			g_object_unref (comp);
			return;
		}
	}

	switch (col) {
	case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
		set_dtend ((ECalModel *) model, comp_data, value);
		break;
	case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
		set_location (comp_data, value);
		break;
	case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
		set_transparency (comp_data, value);
		break;
	}

	e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, mod);

	g_object_unref (comp);
}
static void
memo_shell_content_cursor_change_cb (EMemoShellContent *memo_shell_content,
                                     gint row,
                                     ETable *table)
{
	ECalComponentPreview *memo_preview;
	ECalModel *memo_model;
	ECalModelComponent *comp_data;
	EPreviewPane *preview_pane;
	EWebView *web_view;
	const gchar *uid;

	memo_model = e_memo_shell_content_get_memo_model (memo_shell_content);
	preview_pane = e_memo_shell_content_get_preview_pane (memo_shell_content);

	web_view = e_preview_pane_get_web_view (preview_pane);
	memo_preview = E_CAL_COMPONENT_PREVIEW (web_view);

	if (e_table_selected_count (table) != 1) {
		if (memo_shell_content->priv->preview_visible)
			e_cal_component_preview_clear (memo_preview);
		return;
	}

	row = e_table_get_cursor_row (table);
	comp_data = e_cal_model_get_component_at (memo_model, row);

	if (memo_shell_content->priv->preview_visible) {
		ECalComponent *comp;

		comp = e_cal_component_new_from_icalcomponent (
			icalcomponent_new_clone (comp_data->icalcomp));

		e_cal_component_preview_display (
			memo_preview, comp_data->client, comp,
			e_cal_model_get_timezone (memo_model),
			e_cal_model_get_use_24_hour_format (memo_model));

		g_object_unref (comp);
	}

	uid = icalcomponent_get_uid (comp_data->icalcomp);
	g_free (memo_shell_content->priv->current_uid);
	memo_shell_content->priv->current_uid = g_strdup (uid);
}
static void
memo_shell_content_table_foreach_cb (gint model_row,
                                     gpointer user_data)
{
	ECalModelComponent *comp_data;
	icalcomponent *clone;
	icalcomponent *vcal;
	gchar *string;

	struct {
		ECalModel *model;
		GSList *list;
	} *foreach_data = user_data;

	comp_data = e_cal_model_get_component_at (
		foreach_data->model, model_row);

	vcal = e_cal_util_new_top_level ();
	clone = icalcomponent_new_clone (comp_data->icalcomp);
	e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp);
	icalcomponent_add_component (vcal, clone);

	/* String is owned by libical; do not free. */
	string = icalcomponent_as_ical_string (vcal);
	if (string != NULL) {
		ESource *source;
		const gchar *source_uid;

		source = e_client_get_source (E_CLIENT (comp_data->client));
		source_uid = e_source_get_uid (source);

		foreach_data->list = g_slist_prepend (
			foreach_data->list,
			g_strdup_printf ("%s\n%s", source_uid, string));
	}

	icalcomponent_free (vcal);
}