Exemplo n.º 1
0
/**
 * camel_offline_store_set_network_state:
 * @store: a #CamelOfflineStore object
 * @state: the network state
 * @ex: a #CamelException
 *
 * Set the network state to either #CAMEL_OFFLINE_STORE_NETWORK_AVAIL
 * or #CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL.
 **/
void
camel_offline_store_set_network_state (CamelOfflineStore *store, int state, CamelException *ex)
{
	CamelException lex;
	CamelService *service = CAMEL_SERVICE (store);
	gboolean network_state = camel_session_get_network_state (service->session);

	if (store->state == state)
		return;

	camel_exception_init (&lex);
	if (store->state == CAMEL_OFFLINE_STORE_NETWORK_AVAIL) {
		/* network available -> network unavailable */
		if (network_state) {
			if (((CamelStore *) store)->folders) {
				GPtrArray *folders;
				CamelFolder *folder;
				int i, sync;

				sync = camel_url_get_param (((CamelService *) store)->url, "sync_offline") != NULL;

				folders = camel_object_bag_list (((CamelStore *) store)->folders);
				for (i = 0; i < folders->len; i++) {
					folder = folders->pdata[i];

					if (CAMEL_CHECK_TYPE (folder, CAMEL_OFFLINE_FOLDER_TYPE)
					    && (sync || ((CamelOfflineFolder *) folder)->sync_offline)) {
						camel_offline_folder_downsync ((CamelOfflineFolder *) folder, NULL, &lex);
						camel_exception_clear (&lex);
					}

					camel_object_unref (folder);
				}

				g_ptr_array_free (folders, TRUE);
			}

			camel_store_sync (CAMEL_STORE (store), FALSE, &lex);
			camel_exception_clear (&lex);
		}

		if (!camel_service_disconnect (CAMEL_SERVICE (store), network_state, ex))
			return;
	} else {
		/* network unavailable -> network available */
		if (!camel_service_connect (CAMEL_SERVICE (store), ex))
			return;
	}

	store->state = state;
}
static CamelFolderInfo *
vee_store_get_folder_info_sync (CamelStore *store,
                                const gchar *top,
                                CamelStoreGetFolderInfoFlags flags,
                                GCancellable *cancellable,
                                GError **error)
{
	CamelFolderInfo *info, *res = NULL, *tail;
	GPtrArray *folders;
	GHashTable *infos_hash;
	gint i;

	d (printf ("Get folder info '%s'\n", top ? top:"<null>"));

	infos_hash = g_hash_table_new (g_str_hash, g_str_equal);
	folders = camel_object_bag_list (store->folders);
	qsort (folders->pdata, folders->len, sizeof (folders->pdata[0]), vee_folder_cmp);
	for (i = 0; i < folders->len; i++) {
		CamelVeeFolder *folder = folders->pdata[i];
		const gchar *full_name;
		const gchar *display_name;
		gint add = FALSE;
		gchar *pname, *tmp;
		CamelFolderInfo *pinfo;

		full_name = camel_folder_get_full_name (CAMEL_FOLDER (folder));
		display_name = camel_folder_get_display_name (CAMEL_FOLDER (folder));

		/* check we have to include this one */
		if (top) {
			gint namelen = strlen (full_name);
			gint toplen = strlen (top);

			add = ((namelen == toplen
				&& strcmp (full_name, top) == 0)
			       || ((namelen > toplen)
				   && strncmp (full_name, top, toplen) == 0
				   && full_name[toplen] == '/'
				   && ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)
				       || strchr (full_name + toplen + 1, '/') == NULL)));
		} else {
			add = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE)
				|| strchr (full_name, '/') == NULL;
		}

		if (add) {
			gint32 unread;

			unread = camel_folder_get_unread_message_count (
				CAMEL_FOLDER (folder));

			info = camel_folder_info_new ();
			info->full_name = g_strdup (full_name);
			info->display_name = g_strdup (display_name);
			info->unread = unread;
			info->flags =
				CAMEL_FOLDER_NOCHILDREN |
				CAMEL_FOLDER_VIRTUAL;
			g_hash_table_insert (infos_hash, info->full_name, info);

			if (res == NULL)
				res = info;
		} else {
			info = NULL;
		}

		/* check for parent, if present, update flags and if adding, update parent linkage */
		pname = g_strdup (full_name);
		d (printf ("looking up parent of '%s'\n", pname));
		tmp = strrchr (pname, '/');
		if (tmp) {
			*tmp = 0;
			pinfo = g_hash_table_lookup (infos_hash, pname);
		} else
			pinfo = NULL;

		if (pinfo) {
			pinfo->flags = (pinfo->flags & ~(CAMEL_FOLDER_CHILDREN | CAMEL_FOLDER_NOCHILDREN)) | CAMEL_FOLDER_CHILDREN;
			d (printf ("updating parent flags for children '%s' %08x\n", pinfo->full_name, pinfo->flags));
			tail = pinfo->child;
			if (tail == NULL)
				pinfo->child = info;
		} else if (info != res) {
			tail = res;
		} else {
			tail = NULL;
		}

		if (info && tail) {
			while (tail->next)
				tail = tail->next;
			tail->next = info;
			info->parent = pinfo;
		}

		g_free (pname);
		g_object_unref (folder);
	}
	g_ptr_array_free (folders, TRUE);
	g_hash_table_destroy (infos_hash);

	/* and add UNMATCHED, if scanning from top/etc and it's enabled */
	if (camel_vee_store_get_unmatched_enabled (CAMEL_VEE_STORE (store)) &&
	    (top == NULL || top[0] == 0 || strncmp (top, CAMEL_UNMATCHED_NAME, strlen (CAMEL_UNMATCHED_NAME)) == 0)) {
		info = vee_store_create_unmatched_fi ();

		if (res == NULL)
			res = info;
		else {
			tail = res;
			while (tail->next)
				tail = tail->next;
			tail->next = info;
		}
	}

	return res;
}