From 887999180be5c0a262c26194c42c78a29d597f2d Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Fri, 1 Dec 2006 11:44:29 +0000 Subject: [PATCH] * Added support to asynchronously update an account * Added new test pmo-trunk-r512 --- src/modest-mail-operation.c | 142 +++++++++++++++++++++++++++++++------------ src/modest-mail-operation.h | 16 ++++- tests/Makefile.am | 23 ++++++- tests/update-account.c | 112 ++++++++++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 44 deletions(-) create mode 100644 tests/update-account.c diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index 84a2dd4..9582a4b 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -43,8 +43,8 @@ #include #include -#include -#include +#include "modest-text-utils.h" +#include "modest-tny-msg-actions.h" #include "modest-tny-platform-factory.h" /* 'private'/'protected' functions */ @@ -62,6 +62,13 @@ enum _ModestMailOperationErrorCode { MODEST_MAIL_OPERATION_NUM_ERROR_CODES }; +typedef struct +{ + ModestMailOperation *mail_op; + GCallback cb; + gpointer user_data; +} AsyncHelper; + static void set_error (ModestMailOperation *mail_operation, ModestMailOperationErrorCode error_code, const gchar *fmt, ...); @@ -97,15 +104,18 @@ static TnyFolder * modest_mail_operation_find_trash_folder (ModestMailOperation TnyStoreAccount *store_account); -/* list my signals */ -enum { - /* MY_SIGNAL_1, */ - /* MY_SIGNAL_2, */ - LAST_SIGNAL +enum _ModestMailOperationSignals +{ + PROGRESS_CHANGED_SIGNAL, + + NUM_SIGNALS }; typedef struct _ModestMailOperationPrivate ModestMailOperationPrivate; struct _ModestMailOperationPrivate { + guint done; + guint total; + GMutex *cb_lock; ModestMailOperationStatus status; GError *error; }; @@ -120,8 +130,7 @@ static gboolean is_ascii(const gchar *s); /* globals */ static GObjectClass *parent_class = NULL; -/* uncomment the following if you have defined any signals */ -/* static guint signals[LAST_SIGNAL] = {0}; */ +static guint signals[NUM_SIGNALS] = {0}; GType modest_mail_operation_get_type (void) @@ -159,11 +168,14 @@ modest_mail_operation_class_init (ModestMailOperationClass *klass) g_type_class_add_private (gobject_class, sizeof(ModestMailOperationPrivate)); /* signal definitions go here, e.g.: */ -/* signals[MY_SIGNAL_1] = */ -/* g_signal_new ("my_signal_1",....); */ -/* signals[MY_SIGNAL_2] = */ -/* g_signal_new ("my_signal_2",....); */ -/* etc. */ + signals[PROGRESS_CHANGED_SIGNAL] = + g_signal_new ("progress_changed", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (ModestMailOperationClass, progress_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } static void @@ -173,8 +185,11 @@ modest_mail_operation_init (ModestMailOperation *obj) priv = MODEST_MAIL_OPERATION_GET_PRIVATE(obj); - priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID; - priv->error = NULL; + priv->status = MODEST_MAIL_OPERATION_STATUS_INVALID; + priv->error = NULL; + priv->done = 0; + priv->total = 0; + priv->cb_lock = g_mutex_new (); } static void @@ -189,6 +204,8 @@ modest_mail_operation_finalize (GObject *obj) priv->error = NULL; } + g_mutex_free (priv->cb_lock); + G_OBJECT_CLASS(parent_class)->finalize (obj); } @@ -483,16 +500,52 @@ modest_mail_operation_create_reply_mail (TnyMsg *msg, return new_msg; } +static void +status_update_cb (TnyFolder *folder, const gchar *what, gint status, gpointer user_data) +{ + g_print ("%s status: %d\n", what, status); +} + +static void +folder_refresh_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data) +{ + AsyncHelper *helper = NULL; + ModestMailOperation *mail_op = NULL; + ModestMailOperationPrivate *priv = NULL; + + helper = (AsyncHelper *) user_data; + mail_op = MODEST_MAIL_OPERATION (helper->mail_op); + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(mail_op); + + g_mutex_lock (priv->cb_lock); + + priv->done++; + + if (cancelled) + priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELLED; + else + g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); + + g_mutex_unlock (priv->cb_lock); + + if (priv->done == priv->total) { + ((ModestUpdateAccountCallback) (helper->cb)) (mail_op, helper->user_data); + g_slice_free (AsyncHelper, helper); + } +} + void modest_mail_operation_update_account (ModestMailOperation *mail_op, - TnyStoreAccount *store_account) + TnyStoreAccount *store_account, + ModestUpdateAccountCallback callback, + gpointer user_data) { - TnyStoreAccount *storage_account; ModestMailOperationPrivate *priv; TnyList *folders; TnyIterator *ifolders; TnyFolder *cur_folder; TnyFolderStoreQuery *query; + AsyncHelper *helper; g_return_if_fail (MODEST_IS_MAIL_OPERATION (mail_op)); g_return_if_fail (TNY_IS_STORE_ACCOUNT(store_account)); @@ -503,20 +556,27 @@ modest_mail_operation_update_account (ModestMailOperation *mail_op, folders = TNY_LIST (tny_simple_list_new ()); query = tny_folder_store_query_new (); tny_folder_store_query_add_item (query, NULL, TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED); - tny_folder_store_get_folders (TNY_FOLDER_STORE (storage_account), + tny_folder_store_get_folders (TNY_FOLDER_STORE (store_account), folders, query, NULL); /* FIXME */ g_object_unref (query); ifolders = tny_list_create_iterator (folders); + priv->total = tny_list_get_length (folders); + priv->done = 0; + gint i =0; /* Async refresh folders */ for (tny_iterator_first (ifolders); !tny_iterator_is_done (ifolders); tny_iterator_next (ifolders)) { cur_folder = TNY_FOLDER (tny_iterator_get_current (ifolders)); + helper = g_slice_new0 (AsyncHelper); + helper->mail_op = mail_op; + helper->user_data = user_data; + helper->cb = callback; tny_folder_refresh_async (cur_folder, folder_refresh_cb, - status_update_cb, mail_op); + status_update_cb, helper); } g_object_unref (ifolders); @@ -553,6 +613,28 @@ modest_mail_operation_cancel (ModestMailOperation *mail_op) /* TODO */ } +guint +modest_mail_operation_get_task_done (ModestMailOperation *mail_op) +{ + ModestMailOperationPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (mail_op), 0); + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op); + return priv->done; +} + +guint +modest_mail_operation_get_task_total (ModestMailOperation *mail_op) +{ + ModestMailOperationPrivate *priv; + + g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (mail_op), 0); + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE (mail_op); + return priv->total; +} + /* ******************************************************************* */ /* ************************** STORE ACTIONS ************************* */ /* ******************************************************************* */ @@ -892,26 +974,6 @@ set_error (ModestMailOperation *mail_op, } static void -status_update_cb (TnyFolder *folder, const gchar *what, gint status, gpointer user_data) -{ - /* TODO: update main window progress bar */ -} - -static void -folder_refresh_cb (TnyFolder *folder, gboolean cancelled, GError **err, gpointer user_data) -{ - if (cancelled) { - ModestMailOperation *mail_op; - ModestMailOperationPrivate *priv; - - mail_op = MODEST_MAIL_OPERATION (user_data); - priv = MODEST_MAIL_OPERATION_GET_PRIVATE(mail_op); - - priv->status = MODEST_MAIL_OPERATION_STATUS_CANCELLED; - } -} - -static void add_attachments (TnyMsg *msg, const GList *attachments_list) { GList *pos; diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index 8f0baa7..b479571 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -76,6 +76,8 @@ typedef enum _ModestMailOperationStatus { MODEST_MAIL_OPERATION_STATUS_CANCELLED } ModestMailOperationStatus; +typedef void (*ModestUpdateAccountCallback) (ModestMailOperation *mail_op, gpointer user_data); + struct _ModestMailOperation { GObject parent; /* insert public members, if any */ @@ -83,8 +85,9 @@ struct _ModestMailOperation { struct _ModestMailOperationClass { GObjectClass parent_class; - /* insert signal callback declarations, eg. */ - /* void (* my_event) (ModestMailOperation* obj); */ + + /* Signals */ + void (*progress_changed) (ModestMailOperation *mail_op, gpointer user_data); }; /* member functions */ @@ -118,7 +121,9 @@ TnyMsg* modest_mail_operation_create_reply_mail (TnyMsg *msg, ModestMailOperationReplyMode reply_mode); void modest_mail_operation_update_account (ModestMailOperation *mail_op, - TnyStoreAccount *store_account); + TnyStoreAccount *store_account, + ModestUpdateAccountCallback callback, + gpointer user_data); /* Functions that perform store operations */ TnyFolder* modest_mail_operation_create_folder (ModestMailOperation *mail_op, @@ -156,6 +161,11 @@ void modest_mail_operation_remove_msg (ModestMailOperation *mail_op gboolean remove_to_trash); /* Functions to control mail operations */ +guint modest_mail_operation_get_task_done (ModestMailOperation *mail_op); + +guint modest_mail_operation_get_task_total (ModestMailOperation *mail_op); + + ModestMailOperationStatus modest_mail_operation_get_status (ModestMailOperation *mail_op); const GError* modest_mail_operation_get_error (ModestMailOperation *mail_op); diff --git a/tests/Makefile.am b/tests/Makefile.am index e973fc8..d3be016 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,7 +8,8 @@ INCLUDES=\ -DMODESTLOCALEDIR=\""$(modestlocaledir)"\" bin_PROGRAMS=\ - folder-xfer + folder-xfer\ + update-account folder_xfer_SOURCES=\ folder-transfer.c @@ -29,3 +30,23 @@ folder_xfer_LDADD = \ ${top_srcdir}/src/modest-mail-operation.o \ ${top_srcdir}/src/modest-tny-msg-actions.o \ ${top_srcdir}/src/modest-text-utils.o + +update_account_SOURCES=\ + update-account.c + +update_account_LDADD = \ + $(MODEST_GSTUFF_LIBS) \ + $(MODEST_LIBTINYMAIL_GNOME_DESKTOP_LIBS) \ + $(MODEST_LIBTINYMAIL_MAEMO_LIBS) \ + ${top_srcdir}/src/$(MODEST_PLATFORM)/libmodest-ui.la \ + ${top_srcdir}/src/widgets/libmodest-widgets.la \ + ${top_srcdir}/src/modest-account-mgr.o \ + ${top_srcdir}/src/modest-tny-platform-factory.o \ + ${top_srcdir}/src/modest-conf.o \ + ${top_srcdir}/src/modest-protocol-mgr.o \ + ${top_srcdir}/src/modest-pair.o \ + ${top_srcdir}/src/modest-marshal.o \ + ${top_srcdir}/src/modest-tny-account-store.o \ + ${top_srcdir}/src/modest-mail-operation.o \ + ${top_srcdir}/src/modest-tny-msg-actions.o \ + ${top_srcdir}/src/modest-text-utils.o \ No newline at end of file diff --git a/tests/update-account.c b/tests/update-account.c new file mode 100644 index 0000000..35f657c --- /dev/null +++ b/tests/update-account.c @@ -0,0 +1,112 @@ +/* Copyright (c) 2006, Nokia Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the Nokia Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include + +GMainLoop *main_loop; + +static void +update_cb (ModestMailOperation *mail_op, gpointer user_data) +{ + g_object_unref (G_OBJECT (mail_op)); + g_main_loop_quit (main_loop); +} + +static void +progress_cb (ModestMailOperation *mail_op, gpointer user_data) +{ + g_print ("Refreshed %d of %d\n", + modest_mail_operation_get_task_done (mail_op), + modest_mail_operation_get_task_total (mail_op)); +} + +static gboolean +func (gpointer_data) +{ + TnyStoreAccount *account; + TnyIterator *iter; + TnyPlatformFactory *fact = NULL; + ModestAccountMgr *acc_mgr = NULL; + ModestMailOperation *mail_op = NULL; + TnyAccountStore *account_store = NULL; + TnyList *accounts; + + fact = TNY_PLATFORM_FACTORY (modest_tny_platform_factory_get_instance ()); + acc_mgr = MODEST_ACCOUNT_MGR (modest_tny_platform_factory_get_modest_account_mgr_instance (fact)); + account_store = tny_platform_factory_new_account_store (fact); + + /* Get accounts */ + accounts = tny_simple_list_new (); + + tny_account_store_get_accounts (account_store, accounts, + TNY_ACCOUNT_STORE_STORE_ACCOUNTS); + + iter = tny_list_create_iterator (accounts); + account = TNY_STORE_ACCOUNT (tny_iterator_get_current (iter)); + + g_object_unref (G_OBJECT (iter)); + g_object_unref (G_OBJECT (accounts)); + + mail_op = modest_mail_operation_new (); + + g_signal_connect (G_OBJECT (mail_op), "progress_changed", + G_CALLBACK (progress_cb), NULL); + modest_mail_operation_update_account (mail_op, account, update_cb, NULL); + + return FALSE; +} + +int +main (int argc, char **argv) +{ + guint id; + + g_type_init (); + g_thread_init(NULL); + + main_loop = g_main_loop_new (NULL, FALSE); + id = g_timeout_add(1000, func, main_loop); + g_main_loop_run(main_loop); + + return 0; +} -- 1.7.9.5