Пример #1
0
static GSList *open_ebooks(void)
{
	GError *gerr = NULL;
	ESourceList *src_list;
	GSList *list;
	char *default_src = NULL;
	GSList *ebooks = NULL;

	if (e_book_get_addressbooks(&src_list, &gerr) == FALSE) {
		error("Can't list user's address books: %s", gerr->message);
		g_error_free(gerr);
		return NULL;
	}

	list = e_source_list_peek_groups(src_list);
	while (list != NULL) {
		ESourceGroup *group = E_SOURCE_GROUP(list->data);
		GSList *sources = e_source_group_peek_sources(group);

		ebooks = traverse_sources(ebooks, sources, &default_src);

		list = list->next;
	}

	g_free(default_src);
	g_object_unref(src_list);

	return ebooks;
}
Пример #2
0
GList *
evo_environment_list_cal_sources(ECalSourceType type)
{
    GList *paths = NULL;
	ESourceList *sources = NULL;
	ESource *source = NULL;
	
	if (!e_cal_get_sources(&sources, type, NULL)) {
		return NULL;
	}

	GSList *g = NULL;
	for (g = e_source_list_peek_groups (sources); g; g = g->next) {
		ESourceGroup *group = E_SOURCE_GROUP (g->data);
		GSList *s = NULL;
		for (s = e_source_group_peek_sources (group); s; s = s->next) {
			source = E_SOURCE (s->data);
			evo_location_t *path = g_malloc0(sizeof(evo_location_t));
            //FIXME: Word around #442187
			//if (!first) {
			//	first = TRUE;
			//	path->uri = g_strdup("default");
			//} else {
				path->uri = g_strdup(e_source_get_uri(source));
			//}
			path->name = g_strdup(e_source_peek_name(source));
			paths = g_list_append(paths, path);
		}
	}
	return paths;
}
Пример #3
0
static void
process_removal_in_hash (const gchar *uri,
                         gpointer value,
                         ProcessRemovalsData *prd)
{
	GSList *groups, *sources, *p, *q;
	gboolean found = FALSE;

	/* search the list of selected calendars */
	groups = e_source_list_peek_groups (prd->source_list);
	for (p = groups; p != NULL; p = p->next) {
		ESourceGroup *group = E_SOURCE_GROUP (p->data);

		sources = e_source_group_peek_sources (group);
		for (q = sources; q != NULL; q = q->next) {
			ESource *source = E_SOURCE (q->data);
			gchar *source_uri;
			const gchar *completion = e_source_get_property (source, "alarm");

			source_uri = e_source_get_uri (source);
			if (strcmp (source_uri, uri) == 0)
				if (!completion || !g_ascii_strcasecmp (completion, "true"))
					found = TRUE;

			g_free (source_uri);

			if (found)
				return;
		}
	}

	/* not found, so list it for removal */
	prd->removals = g_list_prepend (prd->removals, (gpointer) uri);
}
Пример #4
0
static void
connect_list (void)
{
	GSList *groups, *p;

	g_signal_connect (list, "changed", G_CALLBACK (list_changed_callback), NULL);
	g_signal_connect (list, "group_added", G_CALLBACK (group_added_callback), NULL);
	g_signal_connect (list, "group_removed", G_CALLBACK (group_removed_callback), NULL);

	groups = e_source_list_peek_groups (list);
	for (p = groups; p != NULL; p = p->next)
		connect_group (E_SOURCE_GROUP (p->data));
}
Пример #5
0
static void
dump_list (void)
{
	GSList *groups, *p;

	groups = e_source_list_peek_groups (list);
	if (groups == NULL) {
		g_print ("(No items)\n");
		return;
	}

	for (p = groups; p != NULL; p = p->next)
		dump_group (E_SOURCE_GROUP (p->data));
}
Пример #6
0
static void
impl_finalize (GObject *object)
{
	ESourceGroupPrivate *priv = E_SOURCE_GROUP (object)->priv;

	g_free (priv->uid);
	g_free (priv->name);
	g_free (priv->base_uri);

	g_hash_table_destroy (priv->properties);

	g_free (priv);

	(* G_OBJECT_CLASS (e_source_group_parent_class)->finalize) (object);
}
Пример #7
0
ESource *
evo_environment_find_source(ESourceList *list, const char *uri)
{
	GSList *g;
	for (g = e_source_list_peek_groups (list); g; g = g->next) {
		ESourceGroup *group = E_SOURCE_GROUP (g->data);
		GSList *s;
		for (s = e_source_group_peek_sources (group); s; s = s->next) {
			ESource *source = E_SOURCE (s->data);
			if (!strcmp(e_source_get_uri(source), uri))
				return source;
		}
	}
	return NULL;
}
Пример #8
0
static ESource *
get_source (ESourceList *list)
{
	CamelURL *url;
	gchar *url_string;
	GSList *p, *l;
	gchar **temp;
	gchar *uri;

	/* FIXME Wow... just... wow.  If ever one needed proof that
	 *       URL-based accounts were a bad idea, here ya go. */

	url = g_malloc0 (sizeof (CamelURL));
	camel_settings_save_to_url (settings, url);
	url_string = camel_url_to_string (url, 0);
	temp = g_strsplit (url_string, ";", -1);
	g_free (url_string);
	camel_url_free (url);

	uri = temp[0];

	l = e_source_list_peek_groups (list);

	for (p = l; p != NULL; p = p->next) {
		gchar *so_uri;
		GSList *r, *s;
		ESourceGroup *group = E_SOURCE_GROUP (p->data);

		s = e_source_group_peek_sources (group);
		for (r = s; r != NULL; r = r->next) {
			ESource *so = E_SOURCE (r->data);
			so_uri = e_source_get_uri (so);

			if (so_uri) {
				if (!strcmp (so_uri, uri)) {
					g_free (so_uri), so_uri = NULL;
					g_strfreev (temp);
					return E_SOURCE (r->data);
				}
				g_free (so_uri), so_uri = NULL;
			}
		}
	}

	g_strfreev (temp);

	return NULL;
}
Пример #9
0
static void
alarm_notify_load_calendars (AlarmNotify *an,
                             ECalSourceType source_type)
{
	ESourceList *source_list;
	GSList *groups, *sources, *p, *q;

	if (!e_cal_get_sources (&source_list, source_type, NULL)) {
		d (printf("%s:%d (load_calendars) - Cannont get sources\n ", __FILE__, __LINE__));
		an->priv->source_lists[source_type] = NULL;

		return;
	}

	groups = e_source_list_peek_groups (source_list);
	for (p = groups; p != NULL; p = p->next) {
		ESourceGroup *group = E_SOURCE_GROUP (p->data);

		sources = e_source_group_peek_sources (group);
		for (q = sources; q != NULL; q = q->next) {
			ESource *source = E_SOURCE (q->data);
			gchar *uri;
			const gchar *completion = e_source_get_property (source, "alarm");

			if (completion  && (!g_ascii_strcasecmp (completion, "false") ||
						!g_ascii_strcasecmp (completion, "never")))
				continue;

			uri = e_source_get_uri (source);
			d (printf("%s:%d (load_calendars) - Loading Calendar %s \n", __FILE__, __LINE__, uri));
			alarm_notify_add_calendar (an, source_type, source, FALSE);
			g_free (uri);

		}
	}

	g_signal_connect_object (
		source_list, "changed",
		G_CALLBACK (alarm_notify_list_changed_cb), an, 0);
	an->priv->source_lists[source_type] = source_list;
}
ESourceGroup *
e_source_list_peek_group_by_base_uri (ESourceList *list, const gchar *base_uri)
{
        GSList *p;
        gint len;

        g_return_val_if_fail (E_IS_SOURCE_LIST (list), NULL);
        g_return_val_if_fail (base_uri != NULL, NULL);

        len = strlen (base_uri);

        for (p = e_source_list_peek_groups (list); p != NULL; p = p->next) {
                ESourceGroup *group = E_SOURCE_GROUP (p->data);
                const gchar *buri = e_source_group_peek_base_uri (group);

                if (buri && g_ascii_strncasecmp (buri, base_uri, len) == 0)
                        return group;
        }

        return NULL;
}
Пример #11
0
static void
impl_dispose (GObject *object)
{
	ESourceGroupPrivate *priv = E_SOURCE_GROUP (object)->priv;

	if (priv->sources != NULL) {
		GSList *p;

		for (p = priv->sources; p != NULL; p = p->next) {
			ESource *source = E_SOURCE (p->data);

			g_signal_handlers_disconnect_by_func (source,
							      G_CALLBACK (source_changed_callback),
							      object);
			g_object_unref (source);
		}

		g_slist_free (priv->sources);
		priv->sources = NULL;
	}

	(* G_OBJECT_CLASS (e_source_group_parent_class)->dispose) (object);
}
Пример #12
0
static void
alarm_notify_list_changed_cb (ESourceList *source_list,
                              AlarmNotify *an)
{
	GSList *groups, *sources, *p, *q;
	ECalSourceType source_type = E_CAL_SOURCE_TYPE_LAST;
	ProcessRemovalsData prd;
	GList *l;
	gint i;

	g_signal_handlers_block_by_func (
		source_list, alarm_notify_list_changed_cb, an);

	/* Figure out the source type */
	for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
		if (source_list == an->priv->source_lists[i]) {
			source_type = i;
			break;
		}
	}
	if (source_type == E_CAL_SOURCE_TYPE_LAST)
		return;

	/* process the additions */
	groups = e_source_list_peek_groups (source_list);
	for (p = groups; p != NULL; p = p->next) {
		ESourceGroup *group = E_SOURCE_GROUP (p->data);

		sources = e_source_group_peek_sources (group);
		for (q = sources; q != NULL; q = q->next) {
			ESource *source = E_SOURCE (q->data);
			gchar *uri;
			const gchar *completion = e_source_get_property (source, "alarm");

			if (completion  && (!g_ascii_strcasecmp (completion, "false") ||
						!g_ascii_strcasecmp (completion, "never")))
				continue;

			uri = e_source_get_uri (source);
			if (!g_hash_table_lookup (an->priv->uri_client_hash[source_type], uri)) {
				d (printf("%s:%d (list_changed_cb) - Adding Calendar %s\n", __FILE__, __LINE__, uri));
				alarm_notify_add_calendar (an, source_type, source, FALSE);
			}
			g_free (uri);
		}
	}

	/* process the removals */
	prd.an = an;
	prd.source_list = an->priv->source_lists[source_type];
	prd.removals = NULL;
	g_hash_table_foreach (an->priv->uri_client_hash[source_type], (GHFunc) process_removal_in_hash, &prd);

	for (l = prd.removals; l; l = l->next) {
		d (printf("%s:%d (list_changed_cb) - Removing Calendar %s\n", __FILE__, __LINE__, (gchar *)l->data));
		alarm_notify_remove_calendar (an, source_type, l->data);
	}
	g_list_free (prd.removals);
	g_signal_handlers_unblock_by_func (
		source_list, alarm_notify_list_changed_cb, an);

}
Пример #13
0
void
dates_autoselect_calendars (DatesData *d, ESourceList * cal_list)
{
	GSList *selected_list;

	if (!cal_list)
		return;

	selected_list = gconf_client_get_list (gconf_client_get_default (),
					       CALENDAR_GCONF_SELECTED,
					       GCONF_VALUE_STRING, NULL);

	if (!selected_list) {
		/* select all available calendars */
		GSList *list = NULL, *groups, *g;
		groups = e_source_list_peek_groups (cal_list);
#ifdef DEBUG
		if (d->debug & DATES_DEBUG_CALENDAR)
			g_debug ("Attempting to autoselect");
#endif
		
		for (g = groups; g; g = g->next) {
			GSList *sources, *s;
			sources =
				e_source_group_peek_sources (E_SOURCE_GROUP (g->data));
			for (s = sources; s; s = s->next) {
				ESource *source = E_SOURCE (s->data);
				ECal *ecal;
				gchar * uid;
			
				ecal = dates_load_esource (source,
							   E_CAL_SOURCE_TYPE_EVENT,
							   NULL, d);
				if (!ecal)
				{
#ifdef DEBUG
					if (d->debug & DATES_DEBUG_CALENDAR)
						g_debug ("No ecal");
#endif
					
					continue;
				}
				
				uid = (gchar *)e_source_peek_uid (e_cal_get_source (ecal));
				list = g_slist_prepend (list, uid);
			}
		}

		if (list)
		{
#ifdef DEBUG
			if (d->debug & DATES_DEBUG_CALENDAR)
				g_debug ("Setting new list");
#endif
			gconf_client_set_list (gconf_client_get_default (),
					       CALENDAR_GCONF_SELECTED,
					       GCONF_VALUE_STRING,
					       list, NULL);
		}
	}
	else
#ifdef DEBUG
		if (d->debug & DATES_DEBUG_CALENDAR)
			g_debug ("Have selected list");
#endif
}
Пример #14
0
void
dates_update_calendars (ESourceList *cal_list, DatesData *d)
{
    GSList *groups, *g;

    /* TODO: Don't reload *all* calendars on update */
    d->dcal = NULL;
    gtk_list_store_clear (d->cal_list_store);
    dates_view_remove_all_calendars (d->view);
    groups = e_source_list_peek_groups (cal_list);

#ifdef DEBUG
    if (d->debug & DATES_DEBUG_CALENDAR)
	g_debug ("Updating Calendars");
#endif

    /* Disable creating of calendars until we know there's a valid
     * calendar to add events to.
     */
	d->cal_loaded = FALSE;
	
	if (d->TBNew)
	{
#ifdef DEBUG
		if (d->debug & DATES_DEBUG_CALENDAR)
			g_debug ("*** Setting TBNew button insensitive ***");
#endif
		gtk_widget_set_sensitive (d->TBNew, FALSE);
	}
	
    for (g = groups; g; g = g->next) {
	GSList *sources, *s;
#ifdef DEBUG
	if (d->debug & DATES_DEBUG_CALENDAR)
	    g_debug ("Group %s (%s)",
		     e_source_group_peek_name (
			 E_SOURCE_GROUP (g->data)),
		     e_source_group_peek_base_uri (
			 E_SOURCE_GROUP (g->data)));
#endif
	sources = e_source_group_peek_sources (
	    E_SOURCE_GROUP (g->data));
	for (s = sources; s; s = s->next) {
	    ESource *source = E_SOURCE (s->data);
	    ECal *ecal;
			
	    ecal = dates_load_esource (source,
				 E_CAL_SOURCE_TYPE_EVENT, NULL, d);
	    if (!ecal) {
#ifdef DEBUG
		if (d->debug & DATES_DEBUG_CALENDAR)
		    g_debug ("No EVENTS in this source");
#endif
		continue;
	    }

#ifdef DEBUG
	    if (d->debug & DATES_DEBUG_CALENDAR)
		g_debug ("Found EVENTS in this source");
#endif

	    g_signal_connect (G_OBJECT (ecal), "cal_opened",
			      G_CALLBACK (dates_cal_open_cb), d);

	    e_cal_open_async (ecal, FALSE);
	    
	    /* 
	     * Set the calendar mode to CAL_MODE_REMOTE. This is necessary to get the
	     * remote (webcal) calendars to work. It doesn't seem to have any effect
	     * on the file backend.
	     */
	    e_cal_set_mode (ecal, CAL_MODE_REMOTE);
	}
    }	
}
Пример #15
0
static void
create_memo_sources (EShellBackend *shell_backend,
                     ESourceList *source_list,
                     ESourceGroup **on_this_computer,
                     ESourceGroup **on_the_web,
                     ESource **personal_source)
{
	EShell *shell;
	EShellSettings *shell_settings;
	GSList *groups;
	ESourceGroup *group;

	*on_this_computer = NULL;
	*on_the_web = NULL;
	*personal_source = NULL;

	shell = e_shell_backend_get_shell (shell_backend);
	shell_settings = e_shell_get_shell_settings (shell);

	groups = e_source_list_peek_groups (source_list);
	if (groups) {
		/* groups are already there, we need to search for things... */
		GSList *g;
		gchar *base_dir, *base_uri;

		base_dir = g_build_filename (e_shell_backend_get_data_dir (shell_backend), "local", NULL);
		base_uri = g_filename_to_uri (base_dir, NULL, NULL);

		for (g = groups; g; g = g->next) {
			group = E_SOURCE_GROUP (g->data);

			if (strcmp (base_uri, e_source_group_peek_base_uri (group)) == 0)
				e_source_group_set_base_uri (group, LOCAL_BASE_URI);

			if (!*on_this_computer && !strcmp (LOCAL_BASE_URI, e_source_group_peek_base_uri (group)))
				*on_this_computer = g_object_ref (group);
			else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group)))
				*on_the_web = g_object_ref (group);
		}

		g_free (base_dir);
		g_free (base_uri);
	}

	if (*on_this_computer) {
		/* make sure "Personal" shows up as a source under
		 * this group */
		GSList *sources = e_source_group_peek_sources (*on_this_computer);
		GSList *s;
		for (s = sources; s; s = s->next) {
			ESource *source = E_SOURCE (s->data);
			const gchar *relative_uri;

			relative_uri = e_source_peek_relative_uri (source);
			if (relative_uri == NULL)
				continue;
			if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
				*personal_source = g_object_ref (source);
				break;
			}
		}
	} else {
		/* create the local source group */
		group = e_source_group_new (_("On This Computer"), LOCAL_BASE_URI);
		e_source_list_add_group (source_list, group, -1);

		*on_this_computer = group;
	}

	if (!*personal_source) {
		GSList *selected;
		gchar *primary_memo_list;

		/* Create the default Person memo list */
		ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
		e_source_group_add_source (*on_this_computer, source, -1);

		primary_memo_list = e_shell_settings_get_string (
			shell_settings, "cal-primary-memo-list");

		selected = e_memo_shell_backend_get_selected_memo_lists (
			E_MEMO_SHELL_BACKEND (shell_backend));

		if (primary_memo_list == NULL && selected == NULL) {
			GSList link;

			e_shell_settings_set_string (
				shell_settings, "cal-primary-memo-list",
				e_source_peek_uid (source));

			link.data = (gpointer) e_source_peek_uid (source);
			link.next = NULL;

			e_memo_shell_backend_set_selected_memo_lists (
				E_MEMO_SHELL_BACKEND (shell_backend), &link);
		}

		g_slist_foreach (selected, (GFunc) g_free, NULL);
		g_slist_free (selected);

		e_source_set_color_spec (source, "#BECEDD");
		*personal_source = source;
	}

	if (!*on_the_web) {
		/* Create the Webcal source group */
		group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI);
		e_source_list_add_group (source_list, group, -1);

		*on_the_web = group;
	}
}
Пример #16
0
static void
ensure_sources (MemosComponent *component)
{
	GSList *groups;
	ESourceList *source_list;
	ESourceGroup *group;
	ESourceGroup *on_this_computer;
	ESourceGroup *on_the_web;
	ESource *personal_source;
	char *base_uri, *base_uri_proto;
	const gchar *base_dir;

	on_this_computer = NULL;
	on_the_web = NULL;
	personal_source = NULL;

	if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) {
		g_warning ("Could not get memo source list from GConf!");
		return;
	}

	base_dir = memos_component_peek_base_directory (component);
	base_uri = g_build_filename (base_dir, "local", NULL);

	base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL);

	groups = e_source_list_peek_groups (source_list);
	if (groups) {
		/* groups are already there, we need to search for things... */
		GSList *g;

		for (g = groups; g; g = g->next) {

			group = E_SOURCE_GROUP (g->data);

			/* compare only file:// part. If user home dir name changes we do not want to create
			   one more group  */

			if (!on_this_computer && !strncmp (base_uri_proto, e_source_group_peek_base_uri (group), 7))
				on_this_computer = group;
			else if (!on_the_web && !strcmp (WEB_BASE_URI, e_source_group_peek_base_uri (group)))
				on_the_web = group;
		}
	}

	if (on_this_computer) {
		/* make sure "Personal" shows up as a source under
		   this group */
		GSList *sources = e_source_group_peek_sources (on_this_computer);
		GSList *s;
		for (s = sources; s; s = s->next) {
			ESource *source = E_SOURCE (s->data);
			const gchar *relative_uri;

			relative_uri = e_source_peek_relative_uri (source);
			if (relative_uri == NULL)
				continue;
			if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) {
				personal_source = source;
				break;
			}
		}
		/* Make sure we have the correct base uri. This can change when user's
		   homedir name changes */
		if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) {
		    e_source_group_set_base_uri (on_this_computer, base_uri_proto);

		    /* *sigh* . We shouldn't  need this sync call here as set_base_uri
		       call results in synching to gconf, but that happens in idle loop
		       and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/
		    e_source_list_sync (source_list,NULL);
		}
	}
	else {
		/* create the local source group */
		group = e_source_group_new (_("On This Computer"), base_uri_proto);
		e_source_list_add_group (source_list, group, -1);

		on_this_computer = group;
	}

	if (!personal_source) {
		GSList *memos_selected;
		/* Create the default Person addressbook */
		ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI);
		e_source_group_add_source (on_this_computer, source, -1);

		memos_selected = calendar_config_get_memos_selected ();

		if (!calendar_config_get_primary_memos () && !memos_selected) {
			GSList selected;

			calendar_config_set_primary_memos (e_source_peek_uid (source));

			selected.data = (gpointer)e_source_peek_uid (source);
			selected.next = NULL;
			calendar_config_set_memos_selected (&selected);
		}

		if (memos_selected) {
			g_slist_foreach (memos_selected, (GFunc) g_free, NULL);
			g_slist_free (memos_selected);
		}

		e_source_set_color_spec (source, "#BECEDD");
		personal_source = source;
	}

	if (!on_the_web) {
		/* Create the LDAP source group */
		group = e_source_group_new (_("On The Web"), WEB_BASE_URI);
		e_source_list_add_group (source_list, group, -1);

		on_the_web = group;
	}

	component->priv->source_list = source_list;
	g_free (base_uri_proto);
	g_free (base_uri);
}
Пример #17
0
/* sync finish phase */
static gboolean eee_accounts_manager_sync_phase2(EeeAccountsManager *self)
{
    GSList *iter, *iter2, *iter_next, *iter2_next;

    g_return_val_if_fail(IS_EEE_ACCOUNTS_MANAGER(self), FALSE);

    // unmark groups/sources
    for (iter = e_source_list_peek_groups(self->priv->eslist); iter; iter = iter->next)
    {
        ESourceGroup *group = E_SOURCE_GROUP(iter->data);

        if (!e_source_group_is_3e(group))
        {
            continue;
        }

        g_object_set_data(G_OBJECT(group), "synced", (gpointer)FALSE);
        for (iter2 = e_source_group_peek_sources(group); iter2; iter2 = iter2->next)
        {
            ESource *source = E_SOURCE(iter2->data);
            g_object_set_data(G_OBJECT(source), "synced", (gpointer)FALSE);
        }
    }

    // go through synced account description structures and update ESourceList
    // accordingly
    for (iter = self->priv->sync_accounts; iter; iter = iter->next)
    {
        EeeAccount *account = iter->data;
        EeeAccount *current_account;
        ESourceGroup *group;
        char *group_name = g_strdup_printf("3e: %s", account->name);

        // find ESourceGroup and EeeAccount
#if EVOLUTION_VERSION >= 232
        group = e_source_list_peek_group_by_properties(self->priv->eslist, "name", group_name, NULL);
#else
        group = e_source_list_peek_group_by_name(self->priv->eslist, group_name);
#endif /* EVOLUTION_VERSION >= 232 */
        current_account = eee_accounts_manager_find_account_by_name(self, account->name);

        if (account->state == EEE_ACCOUNT_STATE_DISABLED)
        {
            if (current_account)
            {
                eee_accounts_manager_remove_account(self, current_account);
            }
            if (group)
            {
                e_source_list_remove_group(self->priv->eslist, group);
            }
            g_object_unref(account);
            continue;
        }

        // create account if it does not exist
        if (current_account == NULL)
        {
            eee_accounts_manager_add_account(self, g_object_ref(account));
        }
        else
        {
            eee_account_copy(current_account, account);
        }

        // create group if it does not exist
        if (group == NULL)
        {
            group = e_source_group_new(group_name, EEE_URI_PREFIX);
            e_source_list_add_group(self->priv->eslist, group, -1);
            g_object_unref(group);
        }
        g_free(group_name);

        // check group sources if account is available, otherwise just mark them as
        // synced
        if (account->state == EEE_ACCOUNT_STATE_NOTAVAIL)
        {
            GSList *iter_grp, *iter_src;
            for (iter_grp = e_source_list_peek_groups(self->priv->eslist); iter_grp; iter_grp = iter_grp->next)
            {
                ESourceGroup *group = iter_grp->data;
                for (iter_src = e_source_group_peek_sources(group); iter_src; iter_src = iter_src->next)
                {
                    ESource *source = iter_src->data;
                    const char *account_name = e_source_get_property(source, "eee-account");
                    if (account_name && !strcmp(account_name, account->name))
                    {
                        g_object_set_data(G_OBJECT(source), "synced", (gpointer)TRUE);
                        g_object_set_data(G_OBJECT(group), "synced", (gpointer)TRUE);
                    }
                }
            }
        }
        else
        {
            GArray * cals = eee_account_peek_calendars (account);
            guint i;
            for (i = 0; i < cals->len; i++)
            {
                ESCalendarInfo *cal = g_array_index (cals, ESCalendarInfo *, i);
                ESource *source;

                if (!strcmp(cal->owner, account->name))
                {
                    // calendar owned by owner of account that represents current group
                    source = e_source_group_peek_source_by_calname(group, cal->name);
                    if (source == NULL)
                    {
                        source = e_source_new_3e_with_attrs(cal->name, cal->owner, account, cal->perm, cal->attrs);
                        e_source_group_add_source(group, source, -1);
                        g_object_unref(source);
                    }
                    else
                    {
                        e_source_set_3e_properties_with_attrs(source, cal->name, cal->owner, account, cal->perm, cal->attrs);
                    }
                }
                else
                {
                    char *owner_group_name = g_strdup_printf("3e: %s", cal->owner);
                    // shared calendar, it should be put into another group
#if EVOLUTION_VERSION >= 232
                    ESourceGroup *owner_group = e_source_list_peek_group_by_properties(self->priv->eslist, "name", owner_group_name, NULL);
#else
                    ESourceGroup *owner_group = e_source_list_peek_group_by_name(self->priv->eslist, owner_group_name);
#endif /* EVOLUTION_VERSION >= 232 */
                    if (owner_group == NULL)
                    {
                        owner_group = e_source_group_new(owner_group_name, EEE_URI_PREFIX);
                        e_source_list_add_group(self->priv->eslist, owner_group, -1);
                        g_object_unref(owner_group);
                    }
                    g_object_set_data(G_OBJECT(owner_group), "synced", (gpointer)TRUE);

                    source = e_source_group_peek_source_by_calname(owner_group, cal->name);
                    if (source == NULL)
                    {
                        source = e_source_new_3e_with_attrs(cal->name, cal->owner, account, cal->perm, cal->attrs);
                        e_source_group_add_source(owner_group, source, -1);
                        g_object_unref(source);
                    }
                    else
                    {
                        e_source_set_3e_properties_with_attrs(source, cal->name, cal->owner, account, cal->perm, cal->attrs);
                    }
                }
                g_object_set_data(G_OBJECT(source), "synced", (gpointer)TRUE);
            }
        }

        g_object_set_data(G_OBJECT(group), "synced", (gpointer)TRUE);
        g_object_unref(account);
    }

    g_slist_free(self->priv->sync_accounts);
    self->priv->sync_accounts = NULL;

    // remove non-marked sources/groups
    for (iter = e_source_list_peek_groups(self->priv->eslist); iter; iter = iter_next)
    {
        ESourceGroup *group = E_SOURCE_GROUP(iter->data);
        iter_next = iter->next;

        if (!e_source_group_is_3e(group))
        {
            continue;
        }

        if (g_object_get_data(G_OBJECT(group), "synced"))
        {
            for (iter2 = e_source_group_peek_sources(group); iter2; iter2 = iter2_next)
            {
                ESource *source = E_SOURCE(iter2->data);
                iter2_next = iter2->next;

                if (!g_object_get_data(G_OBJECT(source), "synced"))
                {
                    e_source_group_remove_source(group, source);
                }
            }
        }
        else
        {
            e_source_list_remove_group(self->priv->eslist, group);
        }
    }

    e_source_list_sync(self->priv->eslist, NULL);

    return TRUE;
}