[evolution-patches] Exchange offline-online fix
- From: Arunprakash <arunp novell com>
- To: evolution-patches lists ximian com
- Subject: [evolution-patches] Exchange offline-online fix
- Date: Thu, 21 Jul 2005 16:51:37 +0530
Hi,
Attached patch fixes issues in synchronization
between online and offline modes in exchange.
It fixes #273916, #272986, #311015 and #311020.
Known issues:
* Journal entries are replayed only when the folder which
has pending operations are refreshed in online mode.
* The journal entries will not get written to the disk file.
* While deleting in offline mode, the mail won't be shown in
the Delete Items folder until you go online.
I am working on these.
Please review it.
Thanks,
Arunprakash.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-exchange/ChangeLog,v
retrieving revision 1.356
diff -u -p -r1.356 ChangeLog
--- ChangeLog 20 Jul 2005 06:21:22 -0000 1.356
+++ ChangeLog 21 Jul 2005 11:12:37 -0000
@@ -1,3 +1,44 @@
+2005-07-21 Arunprakash <arunp novell com>
+
+ * camel/camel-exchange-folder.c (refresh_info) : Changed to
+ replay the journal and send refresh command only when in
+ online mode.
+ (transfer_messages_to) : Changed to make use of the "transfer"
+ journal entry instead of "append" journal entry.
+ * camel/camel-exchange-journal.c (exchange_entry_free)
+ (exchange_entry_load) (exchange_entry_write)
+ (exchange_entry_play) : Updated for
+ the two new journal entry types - "transfer" and "delete".
+ (exchange_entry_play_delete) (exchange_entry_play_transfer) : Added
+ newly for the two new journal entries.
+ (exchange_entry_play_append) : Fixed the copying of the fake message
+ info to the original one. Used camel_exchange_folder_remove_message
+ instead of removing internally.
+ (camel_exchange_journal_transfer) (camel_exchange_journal_delete) :
+ Added newly for creating the journal entries.
+ * camel/camel-exchange-journal.h : Added two new journal entries and
+ the methods for creating them.
+ * camel/camel-exchange-store.c (stub_notification) : Skip the
+ remove message if the message is already removed in offline.
+ * camel/camel-exchange-summary.c (info_set_flags) : Added offline
+ support by creating the journal entry.
+ * mail/mail-stub-exchange.c (linestatus_listener) : Added newly
+ to initialize certain values for the backend in online mode.
+ (folder_update_linestatus) : Newly added, to update the flags
+ for each folder in online mode.
+ (mail_stub_exchange_new) : Modified to hold a reference for the
+ exchange stub and connect to the "linestatus-changed" signal.
+ * mail/mail-stub.c (connection_handler) : Fixed the call to
+ unref without ref for the exchange stub.
+ * shell/e-shell-marshal.list : Added an entry for the new
+ "linestatus-changed" signal.
+ * storage/exchange-component.c (exchange_component_get_offline_listener) :
+ Added newly, to return the offline listener.
+ * storage/exchange-offline-listener.c (online_status_changed) :
+ Modified to emit the new "linestatus-changed" signal.
+ (exchange_offline_listener_class_init) : Modified for
+ registering the new signal "linestatus-changed".
+
2005-07-19 Sarfraaz Ahmed <asarfraaz novell com>
* calendar/e-cal-backend-exchange.c (get_static_capabilities): Removed
Index: camel/camel-exchange-folder.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/camel/camel-exchange-folder.c,v
retrieving revision 1.16
diff -u -p -r1.16 camel-exchange-folder.c
--- camel/camel-exchange-folder.c 16 Mar 2005 07:44:08 -0000 1.16
+++ camel/camel-exchange-folder.c 21 Jul 2005 11:12:38 -0000
@@ -197,12 +197,15 @@ static void
refresh_info (CamelFolder *folder, CamelException *ex)
{
CamelExchangeFolder *exch = CAMEL_EXCHANGE_FOLDER (folder);
+ CamelOfflineStore *store = CAMEL_OFFLINE_STORE (folder->parent_store);
+
+ if (store->state != CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ camel_offline_journal_replay (exch->journal, NULL);
- camel_offline_journal_replay (exch->journal, NULL);
-
- camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_REFRESH_FOLDER,
- CAMEL_STUB_ARG_FOLDER, folder->full_name,
- CAMEL_STUB_ARG_END);
+ camel_stub_send (exch->stub, ex, CAMEL_STUB_CMD_REFRESH_FOLDER,
+ CAMEL_STUB_ARG_FOLDER, folder->full_name,
+ CAMEL_STUB_ARG_END);
+ }
}
static void
@@ -619,15 +622,14 @@ transfer_messages_to (CamelFolder *sourc
if (!(message = get_message (source, camel_message_info_uid (info), ex)))
break;
- camel_exchange_journal_append (journal, message, info, NULL, ex);
+ camel_exchange_journal_transfer (journal, exch_source, message,
+ info, uids->pdata[i], NULL,
+ delete_originals, ex);
+
camel_object_unref (message);
if (camel_exception_is_set (ex))
break;
-
- if (delete_originals)
- camel_folder_set_message_flags (source, camel_message_info_uid (info),
- CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
}
goto end;
}
Index: camel/camel-exchange-journal.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/camel/camel-exchange-journal.c,v
retrieving revision 1.3
diff -u -p -r1.3 camel-exchange-journal.c
--- camel/camel-exchange-journal.c 16 Mar 2005 07:44:08 -0000 1.3
+++ camel/camel-exchange-journal.c 21 Jul 2005 11:12:38 -0000
@@ -109,6 +109,8 @@ exchange_entry_free (CamelOfflineJournal
CamelExchangeJournalEntry *exchange_entry = (CamelExchangeJournalEntry *) entry;
g_free (exchange_entry->uid);
+ g_free (exchange_entry->original_uid);
+ g_free (exchange_entry->folder_name);
g_free (exchange_entry);
}
@@ -116,6 +118,7 @@ static EDListNode *
exchange_entry_load (CamelOfflineJournal *journal, FILE *in)
{
CamelExchangeJournalEntry *entry;
+ char *tmp;
entry = g_malloc0 (sizeof (CamelExchangeJournalEntry));
@@ -128,6 +131,33 @@ exchange_entry_load (CamelOfflineJournal
goto exception;
break;
+ case CAMEL_EXCHANGE_JOURNAL_ENTRY_TRANSFER:
+ if (camel_file_util_decode_string (in, &entry->uid) == -1)
+ goto exception;
+ if (camel_file_util_decode_string (in, &entry->original_uid) == -1)
+ goto exception;
+ if (camel_file_util_decode_string (in, &entry->folder_name) == -1)
+ goto exception;
+ if (camel_file_util_decode_string (in, &tmp) == -1)
+ goto exception;
+ if (g_ascii_strcasecmp (tmp, "True") == 0)
+ entry->delete_original = TRUE;
+ else
+ entry->delete_original = FALSE;
+ g_free (tmp);
+ break;
+ case CAMEL_EXCHANGE_JOURNAL_ENTRY_DELETE:
+ if (camel_file_util_decode_string (in, &entry->uid) == -1)
+ goto exception;
+ if (camel_file_util_decode_string (in, &tmp) == -1)
+ goto exception;
+ entry->flags = atoi (tmp);
+ g_free (tmp);
+ if (camel_file_util_decode_string (in, &tmp) == -1)
+ goto exception;
+ entry->set = atoi (tmp);
+ g_free (tmp);
+ break;
default:
goto exception;
}
@@ -136,6 +166,8 @@ exchange_entry_load (CamelOfflineJournal
exception:
+ g_free (entry->folder_name);
+ g_free (entry->original_uid);
g_free (entry->uid);
g_free (entry);
@@ -146,6 +178,7 @@ static int
exchange_entry_write (CamelOfflineJournal *journal, EDListNode *entry, FILE *out)
{
CamelExchangeJournalEntry *exchange_entry = (CamelExchangeJournalEntry *) entry;
+ char *tmp;
if (camel_file_util_encode_uint32 (out, exchange_entry->type) == -1)
return -1;
@@ -155,6 +188,29 @@ exchange_entry_write (CamelOfflineJourna
if (camel_file_util_encode_string (out, exchange_entry->uid))
return -1;
break;
+ case CAMEL_EXCHANGE_JOURNAL_ENTRY_TRANSFER:
+ if (camel_file_util_encode_string (out, exchange_entry->uid))
+ return -1;
+ if (camel_file_util_encode_string (out, exchange_entry->original_uid))
+ return -1;
+ if (camel_file_util_encode_string (out, exchange_entry->folder_name))
+ return -1;
+ tmp = exchange_entry->delete_original ? "True" : "False";
+ if (camel_file_util_encode_string (out, tmp))
+ return -1;
+ break;
+ case CAMEL_EXCHANGE_JOURNAL_ENTRY_DELETE:
+ if (camel_file_util_encode_string (out, exchange_entry->uid))
+ return -1;
+ tmp = g_strdup_printf ("%u", exchange_entry->flags);
+ if (camel_file_util_encode_string (out, tmp))
+ return -1;
+ g_free (tmp);
+ tmp = g_strdup_printf ("%u", exchange_entry->set);
+ if (camel_file_util_encode_string (out, tmp))
+ return -1;
+ g_free (tmp);
+ break;
default:
g_assert_not_reached ();
}
@@ -174,6 +230,26 @@ exchange_message_info_dup_to (CamelMessa
}
static int
+exchange_entry_play_delete (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, CamelException *ex)
+{
+ CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
+
+ camel_stub_send_oneway (exchange_folder->stub,
+ CAMEL_STUB_CMD_SET_MESSAGE_FLAGS,
+ CAMEL_STUB_ARG_FOLDER,
+ ((CamelFolder *)exchange_folder)->full_name,
+ CAMEL_STUB_ARG_STRING,
+ entry->uid,
+ CAMEL_STUB_ARG_UINT32,
+ entry->set,
+ CAMEL_STUB_ARG_UINT32,
+ entry->flags,
+ CAMEL_STUB_ARG_END);
+
+ return 0;
+}
+
+static int
exchange_entry_play_append (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, CamelException *ex)
{
CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
@@ -204,28 +280,112 @@ exchange_entry_play_append (CamelOffline
camel_exception_init (&lex);
camel_folder_append_message (folder, message, info, &uid, &lex);
- camel_object_unref (message);
if (camel_exception_is_set (&lex)) {
camel_exception_xfer (ex, &lex);
return -1;
}
- if (uid != NULL && (real = camel_folder_summary_uid (folder->summary, uid))) {
-
+ real = camel_folder_summary_info_new_from_message (folder->summary, message);
+ camel_object_unref (message);
+
+ if (uid != NULL && real) {
+ real->uid = g_strdup (uid);
exchange_message_info_dup_to ((CamelMessageInfoBase *) real, (CamelMessageInfoBase *) info);
+ camel_folder_summary_add (folder->summary, real);
+ /* FIXME: should a folder_changed event be triggered? */
}
camel_message_info_free (info);
g_free (uid);
done:
- camel_folder_summary_remove_uid (folder->summary, entry->uid);
- camel_data_cache_remove (exchange_folder->cache, "cache", entry->uid, NULL);
+ camel_exchange_folder_remove_message (exchange_folder, entry->uid);
return 0;
}
+static int
+exchange_entry_play_transfer (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, CamelException *ex)
+{
+ CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
+ CamelFolder *folder = journal->folder;
+ CamelMessageInfo *info, *real;
+ GPtrArray *xuids, *uids;
+ CamelException lex;
+ CamelFolder *src;
+ CamelExchangeStore *store;
+ CamelStream *stream;
+ CamelMimeMessage *message;
+
+ if (!exchange_folder->cache || !(stream = camel_data_cache_get (exchange_folder->cache, "cache", entry->uid, ex)))
+ goto done;
+
+ message = camel_mime_message_new ();
+ if (camel_data_wrapper_construct_from_stream ((CamelDataWrapper *) message, stream) == -1) {
+ camel_object_unref (message);
+ camel_object_unref (stream);
+ goto done;
+ }
+
+ camel_object_unref (stream);
+
+ if (!(info = camel_folder_summary_uid (folder->summary, entry->uid))) {
+ /* Note: this should never happen, but rather than crash lets make a new info */
+ info = camel_message_info_new (NULL);
+ }
+
+ if (!entry->folder_name) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("No folder name found\n"));
+ goto exception;
+ }
+
+ store = (CamelExchangeStore *) folder->parent_store;
+ g_mutex_lock (store->folders_lock);
+ src = (CamelFolder *) g_hash_table_lookup (store->folders, entry->folder_name);
+ g_mutex_unlock (store->folders_lock);
+
+ if (src) {
+ uids = g_ptr_array_sized_new (1);
+ g_ptr_array_add (uids, entry->original_uid);
+
+ camel_exception_init (&lex);
+ camel_folder_transfer_messages_to (src, uids, folder, &xuids, entry->delete_original, &lex);
+ if (!camel_exception_is_set (&lex)) {
+ real = camel_folder_summary_info_new_from_message (folder->summary, message);
+ camel_object_unref (message);
+ real->uid = g_strdup ((char *)xuids->pdata[0]);
+ /* Transfer flags */
+ exchange_message_info_dup_to ((CamelMessageInfoBase *) real, (CamelMessageInfoBase *) info);
+ camel_folder_summary_add (folder->summary, real);
+ /* FIXME: should a folder_changed event be triggered? */
+ } else {
+ camel_exception_xfer (ex, &lex);
+ goto exception;
+ }
+
+ g_ptr_array_free (xuids, TRUE);
+ g_ptr_array_free (uids, TRUE);
+ /* camel_object_unref (src); FIXME: should we? */
+ }
+ else {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Folder doesn't exist"));
+ goto exception;
+ }
+
+ camel_message_info_free (info);
+done:
+ camel_exchange_folder_remove_message (exchange_folder, entry->uid);
+
+ return 0;
+
+exception:
+
+ camel_message_info_free (info);
+
+ return -1;
+}
+
static int
exchange_entry_play (CamelOfflineJournal *journal, EDListNode *entry, CamelException *ex)
{
@@ -234,6 +394,10 @@ exchange_entry_play (CamelOfflineJournal
switch (exchange_entry->type) {
case CAMEL_EXCHANGE_JOURNAL_ENTRY_APPEND:
return exchange_entry_play_append (journal, exchange_entry, ex);
+ case CAMEL_EXCHANGE_JOURNAL_ENTRY_TRANSFER:
+ return exchange_entry_play_transfer (journal, exchange_entry, ex);
+ case CAMEL_EXCHANGE_JOURNAL_ENTRY_DELETE:
+ return exchange_entry_play_delete (journal, exchange_entry, ex);
default:
g_assert_not_reached ();
return -1;
@@ -332,3 +496,54 @@ camel_exchange_journal_append (CamelExch
*appended_uid = g_strdup (uid);
}
+
+void
+camel_exchange_journal_transfer (CamelExchangeJournal *exchange_journal, CamelExchangeFolder *source_folder,
+ CamelMimeMessage *message, const CamelMessageInfo *mi,
+ const char *original_uid, char **transferred_uid, gboolean delete_original,
+ CamelException *ex)
+{
+ CamelOfflineJournal *journal = (CamelOfflineJournal *) exchange_journal;
+ CamelExchangeJournalEntry *entry;
+ char *uid;
+
+ if (!update_cache (exchange_journal, message, mi, &uid, ex))
+ return;
+
+ if(delete_original)
+ camel_exchange_folder_remove_message (source_folder, original_uid);
+
+ entry = g_new (CamelExchangeJournalEntry, 1);
+ entry->type = CAMEL_EXCHANGE_JOURNAL_ENTRY_TRANSFER;
+ entry->uid = uid;
+ entry->original_uid = g_strdup (original_uid);
+ entry->folder_name = g_strdup (((CamelFolder *)source_folder)->full_name);
+ entry->delete_original = delete_original;
+
+ e_dlist_addtail (&journal->queue, (EDListNode *) entry);
+
+ if (transferred_uid)
+ *transferred_uid = g_strdup (uid);
+}
+
+void
+camel_exchange_journal_delete (CamelExchangeJournal *exchange_journal,
+ const char *uid, guint32 flags, guint32 set,
+ CamelException *ex)
+{
+ CamelOfflineJournal *journal = (CamelOfflineJournal *) exchange_journal;
+ CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
+ CamelExchangeJournalEntry *entry;
+
+ if (set & flags & CAMEL_MESSAGE_DELETED)
+ camel_exchange_folder_remove_message (exchange_folder, uid);
+
+ entry = g_new0 (CamelExchangeJournalEntry, 1);
+ entry->type = CAMEL_EXCHANGE_JOURNAL_ENTRY_DELETE;
+ entry->uid = g_strdup (uid);
+ entry->flags = flags;
+ entry->set = set;
+
+ e_dlist_addtail (&journal->queue, (EDListNode *) entry);
+}
+
Index: camel/camel-exchange-journal.h
===================================================================
RCS file: /cvs/gnome/evolution-exchange/camel/camel-exchange-journal.h,v
retrieving revision 1.3
diff -u -p -r1.3 camel-exchange-journal.h
--- camel/camel-exchange-journal.h 16 Mar 2005 07:44:08 -0000 1.3
+++ camel/camel-exchange-journal.h 21 Jul 2005 11:12:38 -0000
@@ -50,6 +50,8 @@ typedef struct _CamelExchangeJournalEntr
enum {
CAMEL_EXCHANGE_JOURNAL_ENTRY_APPEND,
+ CAMEL_EXCHANGE_JOURNAL_ENTRY_TRANSFER,
+ CAMEL_EXCHANGE_JOURNAL_ENTRY_DELETE
};
struct _CamelExchangeJournalEntry {
@@ -58,6 +60,11 @@ struct _CamelExchangeJournalEntry {
int type;
char *uid;
+ char *original_uid;
+ char *folder_name;
+ gboolean delete_original;
+ guint32 flags;
+ guint32 set;
};
struct _CamelExchangeJournal {
@@ -79,6 +86,14 @@ CamelOfflineJournal *camel_exchange_jour
void camel_exchange_journal_append (CamelExchangeJournal *journal, CamelMimeMessage *message,
const CamelMessageInfo *mi, char **appended_uid, CamelException *ex);
+void camel_exchange_journal_transfer (CamelExchangeJournal *journal, CamelExchangeFolder *source_folder,
+ CamelMimeMessage *message, const CamelMessageInfo *mi,
+ const char *original_uid, char **transferred_uid,
+ gboolean delete_original, CamelException *ex);
+
+void camel_exchange_journal_delete (CamelExchangeJournal *journal, const char *uid,
+ guint32 flags, guint32 set, CamelException *ex);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Index: camel/camel-exchange-store.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/camel/camel-exchange-store.c,v
retrieving revision 1.17
diff -u -p -r1.17 camel-exchange-store.c
--- camel/camel-exchange-store.c 28 Jun 2005 10:46:34 -0000 1.17
+++ camel/camel-exchange-store.c 21 Jul 2005 11:12:38 -0000
@@ -709,6 +709,7 @@ stub_notification (CamelObject *object,
{
CamelExchangeFolder *folder;
char *folder_name, *uid;
+ CamelMessageInfo *info;
if (camel_stub_marshal_decode_folder (stub->status, &folder_name) == -1 ||
camel_stub_marshal_decode_string (stub->status, &uid) == -1)
@@ -717,8 +718,10 @@ stub_notification (CamelObject *object,
g_mutex_lock (exch->folders_lock);
folder = g_hash_table_lookup (exch->folders, folder_name);
g_mutex_unlock (exch->folders_lock);
- if (folder)
+ if (folder && (info = camel_folder_summary_uid (((CamelFolder *)folder)->summary, uid))) {
+ camel_message_info_free (info);
camel_exchange_folder_remove_message (folder, uid);
+ }
g_free (folder_name);
g_free (uid);
Index: camel/camel-exchange-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/camel/camel-exchange-summary.c,v
retrieving revision 1.3
diff -u -p -r1.3 camel-exchange-summary.c
--- camel/camel-exchange-summary.c 12 Nov 2004 05:56:19 -0000 1.3
+++ camel/camel-exchange-summary.c 21 Jul 2005 11:12:38 -0000
@@ -30,9 +30,11 @@
#include <camel/camel-exchange-summary.h>
#include <camel/camel-file-utils.h>
+#include <camel/camel-offline-store.h>
#include "camel-stub.h"
#include "camel-exchange-folder.h"
+#include "camel-exchange-journal.h"
#define CAMEL_EXCHANGE_SUMMARY_VERSION (1)
@@ -222,21 +224,34 @@ static gboolean
info_set_flags(CamelMessageInfo *info, guint32 flags, guint32 set)
{
int res;
+ CamelFolder *folder = (CamelFolder *) info->summary->folder;
+ CamelOfflineStore *store = (CamelOfflineStore *) folder->parent_store;
if (CAMEL_EXCHANGE_SUMMARY (info->summary)->readonly)
return FALSE;
- res = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->info_set_flags(info, flags, set);
- if (res && info->summary->folder && info->uid) {
- camel_stub_send_oneway (((CamelExchangeFolder *)info->summary->folder)->stub,
- CAMEL_STUB_CMD_SET_MESSAGE_FLAGS,
- CAMEL_STUB_ARG_FOLDER, info->summary->folder->full_name,
- CAMEL_STUB_ARG_STRING, info->uid,
- CAMEL_STUB_ARG_UINT32, set,
- CAMEL_STUB_ARG_UINT32, flags,
- CAMEL_STUB_ARG_END);
+ if (store->state != CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ res = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->info_set_flags(info, flags, set);
+ if (res && info->summary->folder && info->uid) {
+ camel_stub_send_oneway (((CamelExchangeFolder *)info->summary->folder)->stub,
+ CAMEL_STUB_CMD_SET_MESSAGE_FLAGS,
+ CAMEL_STUB_ARG_FOLDER, info->summary->folder->full_name,
+ CAMEL_STUB_ARG_STRING, info->uid,
+ CAMEL_STUB_ARG_UINT32, set,
+ CAMEL_STUB_ARG_UINT32, flags,
+ CAMEL_STUB_ARG_END);
+ }
+ }
+ else {
+ res = CAMEL_FOLDER_SUMMARY_CLASS (parent_class)->info_set_flags(info, flags, set);
+ if(res && info->summary->folder && info->uid) {
+ CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) info->summary->folder;
+ CamelExchangeJournal *journal = (CamelExchangeJournal *) exchange_folder->journal;
+ camel_exchange_journal_delete (journal, info->uid, flags, set, NULL);
+ }
+ else
+ return FALSE;
}
-
return res;
}
Index: mail/mail-stub-exchange.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/mail/mail-stub-exchange.c,v
retrieving revision 1.16
diff -u -p -r1.16 mail-stub-exchange.c
--- mail/mail-stub-exchange.c 28 Jun 2005 09:20:46 -0000 1.16
+++ mail/mail-stub-exchange.c 21 Jul 2005 11:12:39 -0000
@@ -125,6 +125,12 @@ static gboolean process_flags (gpointer
static void storage_folder_changed (EFolder *folder, gpointer user_data);
+static void linestatus_listener (ExchangeOfflineListener *listener,
+ gint linestatus,
+ gpointer data);
+static void folder_update_linestatus (gpointer key, gpointer value, gpointer data);
+
+
static void
class_init (GObjectClass *object_class)
{
@@ -2622,6 +2628,78 @@ stub_connect (MailStub *stub)
mail_stub_return_ok (stub);
}
+static void
+linestatus_listener (ExchangeOfflineListener *listener,
+ gint linestatus,
+ gpointer data)
+{
+ MailStubExchange *mse = MAIL_STUB_EXCHANGE (data);
+ ExchangeAccount *account = mse->account;
+ const char *uri;
+
+ if (linestatus == ONLINE_MODE) {
+ mse->ctx = exchange_account_get_context (account);
+ g_object_ref (mse->ctx);
+
+ mse->mail_submission_uri = exchange_account_get_standard_uri (account, "sendmsg");
+ uri = exchange_account_get_standard_uri (account, "inbox");
+ mse->inbox = exchange_account_get_folder (account, uri);
+ uri = exchange_account_get_standard_uri (account, "deleteditems");
+ mse->deleted_items = exchange_account_get_folder (account, uri);
+ g_hash_table_foreach (mse->folders_by_name,
+ (GHFunc) folder_update_linestatus,
+ GINT_TO_POINTER (linestatus));
+ }
+}
+
+static void
+folder_update_linestatus (gpointer key, gpointer value, gpointer data)
+{
+ MailStubExchangeFolder *mfld = (MailStubExchangeFolder *) value;
+ E2kResult *results;
+ int nresults = 0;
+ E2kHTTPStatus status;
+ const char *prop;
+ gint linestatus = GPOINTER_TO_INT (data);
+
+ if (linestatus == ONLINE_MODE) {
+ status = e_folder_exchange_propfind (mfld->folder, NULL,
+ open_folder_props,
+ n_open_folder_props,
+ &results, &nresults);
+
+ if (status == E2K_HTTP_UNAUTHORIZED) {
+ got_folder_error (mfld, _("Could not open folder: Permission denied"));
+ return;
+ } else if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) {
+ g_warning ("got_folder_props: %d", status);
+ got_folder_error (mfld, _("Could not open folder"));
+ return;
+ }
+
+ if (nresults) {
+ prop = e2k_properties_get_prop (results[0].props, PR_ACCESS);
+ if (prop)
+ mfld->access = atoi (prop);
+ else
+ mfld->access = ~0;
+ } else
+ mfld->access = ~0;
+
+ if (!(mfld->access & MAPI_ACCESS_READ)) {
+ got_folder_error (mfld, _("Could not open folder: Permission denied"));
+ return;
+ }
+
+ prop = e2k_properties_get_prop (results[0].props, PR_DELETED_COUNT_TOTAL);
+ if (prop)
+ mfld->deleted_count = atoi (prop);
+ }
+ else {
+ /* FIXME: need any undo for offline */ ;
+ }
+}
+
/**
* mail_stub_exchange_new:
* @account: the #ExchangeAccount this stub is for
@@ -2640,8 +2718,10 @@ mail_stub_exchange_new (ExchangeAccount
MailStub *stub;
const char *uri;
int mode;
+ ExchangeOfflineListener *listener;
stub = g_object_new (MAIL_TYPE_STUB_EXCHANGE, NULL);
+ g_object_ref (stub);
mail_stub_construct (stub, cmd_fd, status_fd);
exchange_component_is_offline (global_exchange_component, &mode);
@@ -2657,5 +2737,11 @@ mail_stub_exchange_new (ExchangeAccount
uri = exchange_account_get_standard_uri (account, "deleteditems");
mse->deleted_items = exchange_account_get_folder (account, uri);
}
+
+ listener = exchange_component_get_offline_listener (global_exchange_component);
+ g_signal_connect (G_OBJECT (listener), "linestatus-changed",
+ G_CALLBACK (linestatus_listener), mse);
+
return stub;
}
+
Index: mail/mail-stub.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/mail/mail-stub.c,v
retrieving revision 1.7
diff -u -p -r1.7 mail-stub.c
--- mail/mail-stub.c 28 Jun 2005 09:20:46 -0000 1.7
+++ mail/mail-stub.c 21 Jul 2005 11:12:39 -0000
@@ -86,10 +86,10 @@ connection_handler (GIOChannel *source,
guint32 command;
if (condition == G_IO_ERR || condition == G_IO_HUP)
- goto comm_fail;
+ return FALSE;
if (camel_stub_marshal_decode_uint32 (stub->cmd, &command) == -1)
- goto comm_fail;
+ return FALSE;
switch (command) {
case CAMEL_STUB_CMD_CONNECT:
Index: shell/e-shell-marshal.list
===================================================================
RCS file: /cvs/gnome/evolution-exchange/shell/e-shell-marshal.list,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 e-shell-marshal.list
--- shell/e-shell-marshal.list 11 May 2004 15:15:58 -0000 1.1.1.1
+++ shell/e-shell-marshal.list 21 Jul 2005 11:12:39 -0000
@@ -5,3 +5,4 @@ NONE:BOXED,OBJECT
NONE:STRING
NONE:STRING,POINTER,POINTER
NONE:STRING,STRING
+NONE:INT
Index: storage/exchange-component.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/storage/exchange-component.c,v
retrieving revision 1.10
diff -u -p -r1.10 exchange-component.c
--- storage/exchange-component.c 12 Jul 2005 06:32:21 -0000 1.10
+++ storage/exchange-component.c 21 Jul 2005 11:12:39 -0000
@@ -381,3 +381,10 @@ exchange_component_is_interactive (Excha
{
return component->priv->xid != 0;
}
+
+ExchangeOfflineListener *
+exchange_component_get_offline_listener (ExchangeComponent *component)
+{
+ return component->priv->offline_listener;
+}
+
Index: storage/exchange-component.h
===================================================================
RCS file: /cvs/gnome/evolution-exchange/storage/exchange-component.h,v
retrieving revision 1.7
diff -u -p -r1.7 exchange-component.h
--- storage/exchange-component.h 10 Jun 2005 11:35:34 -0000 1.7
+++ storage/exchange-component.h 21 Jul 2005 11:12:39 -0000
@@ -49,6 +49,8 @@ void exchange_component_is_off
void exchange_component_set_offline_listener (ExchangeComponent *component,
ExchangeOfflineListener *listener);
+ExchangeOfflineListener *exchange_component_get_offline_listener (ExchangeComponent *component);
+
#define EXCHANGE_COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Exchange_Component_Factory:" BASE_VERSION
#define EXCHANGE_COMPONENT_IID "OAFIID:GNOME_Evolution_Exchange_Component:" BASE_VERSION
#define EXCHANGE_CALENDAR_FACTORY_ID "OAFIID:GNOME_Evolution_Exchange_Connector_CalFactory:" BASE_VERSION
Index: storage/exchange-offline-listener.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/storage/exchange-offline-listener.c,v
retrieving revision 1.8
diff -u -p -r1.8 exchange-offline-listener.c
--- storage/exchange-offline-listener.c 10 Jun 2005 11:35:34 -0000 1.8
+++ storage/exchange-offline-listener.c 21 Jul 2005 11:12:40 -0000
@@ -30,9 +30,12 @@
#include <libedata-book/e-data-book-factory.h>
#include <libedata-cal/e-data-cal-factory.h>
#include <gconf/gconf-client.h>
+#include <e-shell-marshal.h>
static GObjectClass *parent_class = NULL;
+static guint linestatus_signal_id;
+
struct _ExchangeOfflineListenerPrivate
{
GConfClient *default_client;
@@ -75,6 +78,9 @@ online_status_changed (GConfClient *clie
offline = gconf_value_get_bool (value);
if (priv->offline != offline)
set_online_status (ex_offline_listener ,offline);
+
+ g_signal_emit (ex_offline_listener, linestatus_signal_id,
+ 0, offline ? OFFLINE_MODE : ONLINE_MODE);
}
static void
@@ -170,7 +176,7 @@ exchange_offline_listener_init (Exchange
}
static void
-exchange_offline_listener_class_init (ExchangeOfflineListener *klass)
+exchange_offline_listener_class_init (ExchangeOfflineListenerClass *klass)
{
GObjectClass *object_class;
@@ -179,6 +185,18 @@ exchange_offline_listener_class_init (Ex
object_class = G_OBJECT_CLASS (klass);
object_class->dispose = exchange_offline_listener_dispose;
object_class->finalize = exchange_offline_listener_finalize;
+
+ linestatus_signal_id =
+ g_signal_new ("linestatus-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
+ G_STRUCT_OFFSET (ExchangeOfflineListenerClass, linestatus_notify),
+ NULL,
+ NULL,
+ e_shell_marshal_VOID__INT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_INT);
}
GType
Index: storage/exchange-offline-listener.h
===================================================================
RCS file: /cvs/gnome/evolution-exchange/storage/exchange-offline-listener.h,v
retrieving revision 1.4
diff -u -p -r1.4 exchange-offline-listener.h
--- storage/exchange-offline-listener.h 10 Jun 2005 11:35:34 -0000 1.4
+++ storage/exchange-offline-listener.h 21 Jul 2005 11:12:40 -0000
@@ -59,6 +59,9 @@ struct _ExchangeOfflineListener {
struct _ExchangeOfflineListenerClass {
GObjectClass parent_class;
+
+ /* signal default handlers */
+ void (*linestatus_notify) (ExchangeOfflineListener *listener, guint status);
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]