}
static void
-append_changed_uids (gchar *key,
- CamelMessageInfoBase *info,
- GPtrArray *array)
+gather_dirty_uids (gpointer key,
+ gpointer value,
+ gpointer user_data)
{
- if (info->dirty || info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)
- g_ptr_array_add (array, (gpointer) camel_pstring_strdup ((camel_message_info_uid (info))));
+ const gchar *uid = key;
+ CamelMessageInfoBase *info = value;
+ GHashTable *hash = user_data;
+
+ if (info->dirty)
+ g_hash_table_insert (hash, (gpointer) camel_pstring_strdup (uid), GINT_TO_POINTER (1));
+}
+
+static void
+gather_changed_uids (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ const gchar *uid = key;
+ guint32 flags = GPOINTER_TO_UINT (value);
+ GHashTable *hash = user_data;
+
+ if ((flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0)
+ g_hash_table_insert (hash, (gpointer) camel_pstring_strdup (uid), GINT_TO_POINTER (1));
}
/**
GPtrArray *
camel_folder_summary_get_changed (CamelFolderSummary *summary)
{
- GPtrArray *res = g_ptr_array_new ();
-
- /* FIXME[disk-summary] sucks, this function returns from memory.
- * We need to have collate or something to get the modified ones
- * from DB and merge */
+ GPtrArray *res;
+ GHashTable *hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) camel_pstring_free, NULL);
camel_folder_summary_lock (summary);
- g_hash_table_foreach (summary->priv->loaded_infos, (GHFunc) append_changed_uids, res);
+
+ g_hash_table_foreach (summary->priv->loaded_infos, gather_dirty_uids, hash);
+ g_hash_table_foreach (summary->priv->uids, gather_changed_uids, hash);
+
+ res = g_ptr_array_sized_new (g_hash_table_size (hash));
+ g_hash_table_foreach (hash, folder_summary_dupe_uids_to_array, res);
+
camel_folder_summary_unlock (summary);
+ g_hash_table_destroy (hash);
+
return res;
}
g_array_free (user_set, TRUE);
}
+static void
+imapx_unset_folder_flagged_flag (CamelFolderSummary *summary,
+ GPtrArray *changed_uids)
+{
+ CamelMessageInfo *info;
+ gboolean changed = FALSE;
+ gint ii;
+
+ g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary));
+ g_return_if_fail (changed_uids != NULL);
+
+ for (ii = 0; ii < changed_uids->len; ii++) {
+ info = camel_folder_summary_get (summary, changed_uids->pdata[ii]);
+
+ if (info) {
+ CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
+
+ /* some infos could be only 'dirty' (needed to save into summary) */
+ if ((mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) != 0) {
+ mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
+ mi->dirty = TRUE;
+ changed = TRUE;
+ }
+
+ camel_message_info_unref (info);
+ }
+ }
+
+ if (changed) {
+ camel_folder_summary_touch (summary);
+ camel_folder_summary_save_to_db (summary, NULL);
+ }
+}
+
static gboolean
imapx_server_sync_changes (CamelIMAPXServer *is,
CamelIMAPXMailbox *mailbox,
if (nothing_to_do) {
imapx_sync_free_user (on_user);
imapx_sync_free_user (off_user);
+ imapx_unset_folder_flagged_flag (folder->summary, changed_uids);
camel_folder_free_uids (folder, changed_uids);
g_object_unref (folder);
return TRUE;
gboolean changed = FALSE;
CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
+ /* This makes sure that server flags has precedence from locally stored flags,
+ thus a user actually sees what is stored on the server, but only if the message
+ was not changed locally and is ready to be saved */
+ if (!(camel_message_info_flags (info) & CAMEL_MESSAGE_FOLDER_FLAGGED) &&
+ (camel_message_info_flags (info) & CAMEL_IMAPX_SERVER_FLAGS) != (server_flags & CAMEL_IMAPX_SERVER_FLAGS)) {
+ xinfo->server_flags = (xinfo->server_flags & ~CAMEL_IMAPX_SERVER_FLAGS) |
+ (camel_message_info_flags (info) & CAMEL_IMAPX_SERVER_FLAGS);
+ }
+
if (server_flags != xinfo->server_flags) {
guint32 server_set, server_cleared;