void
modest_platform_on_new_msg (void)
{
-/* HildonNotification *not; */
+ HildonNotification *not;
-/* /\* Create a new notification. FIXME put the right values, need */
-/* some more specs *\/ */
-/* not = hildon_notification_new ("TODO: (new email) Summary", */
-/* "TODO: (new email) Description", */
-/* "qgn_contact_group_chat_invitation", */
-/* "system.note.dialog"); */
+ /* Create a new notification. FIXME put the right values, need
+ some more specs */
+ not = hildon_notification_new ("TODO: (new email) Summary",
+ "TODO: (new email) Description",
+ "qgn_contact_group_chat_invitation",
+ "system.note.dialog");
-/* /\* Play sound SR-SND-18. TODO: play the right file *\/ */
-/* hildon_notification_set_sound (not, "/usr/share/sounds/ui-new_email.wav"); */
+ /* Play sound SR-SND-18. TODO: play the right file */
+ hildon_notification_set_sound (not, "/usr/share/sounds/ui-new_email.wav");
-/* /\* Set the led pattern *\/ */
-/* notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (not), "led-pattern", 3); */
+ /* Set the led pattern */
+ notify_notification_set_hint_int32 (NOTIFY_NOTIFICATION (not), "led-pattern", 3);
-/* /\* Notify. We need to do this in an idle because this function */
-/* could be called from a thread *\/ */
-/* if (!notify_notification_show (NOTIFY_NOTIFICATION (not), NULL)) */
-/* g_error ("Failed to send notification"); */
+ /* Notify. We need to do this in an idle because this function
+ could be called from a thread */
+ if (!notify_notification_show (NOTIFY_NOTIFICATION (not), NULL))
+ g_error ("Failed to send notification");
-/* g_object_unref (not); */
+ g_object_unref (not);
}
gint retrieve_limit;
gchar *retrieve_type;
gchar *account_name;
+ UpdateAccountCallback callback;
+ gpointer user_data;
} UpdateAccountInfo;
/***** I N T E R N A L F O L D E R O B S E R V E R *****/
static gboolean first_time = TRUE;
UpdateAccountInfo *info;
TnyList *all_folders = NULL;
- GPtrArray *new_headers;
+ GPtrArray *new_headers = NULL;
TnyIterator *iter = NULL;
TnyFolderStoreQuery *query = NULL;
- ModestMailOperationPrivate *priv;
- ModestTnySendQueue *send_queue;
+ ModestMailOperationPrivate *priv = NULL;
+ ModestTnySendQueue *send_queue = NULL;
info = (UpdateAccountInfo *) thr_user_data;
priv = MODEST_MAIL_OPERATION_GET_PRIVATE(info->mail_op);
/* Refresh the folder */
/* Our observer receives notification of new emails during folder refreshes,
* so we can use observer->new_headers.
- * TODO: This does not seem to be providing accurate numbers.
- * Possibly the observer is notified asynchronously.
*/
observer = g_object_new (internal_folder_observer_get_type (), NULL);
tny_folder_add_observer (TNY_FOLDER (folder), TNY_FOLDER_OBSERVER (observer));
* user to download them all,
* as per the UI spec "Retrieval Limits" section in 4.4:
*/
- printf ("************************** DEBUG: %s: account=%s, len=%d, retrieve_limit = %d\n", __FUNCTION__,
- tny_account_get_id (priv->account), new_headers->len, info->retrieve_limit);
if (new_headers->len > info->retrieve_limit) {
- /* TODO: Ask the user, instead of just failing, showing mail_nc_msg_count_limit_exceeded,
- * with 'Get all' and 'Newest only' buttons. */
+ /* TODO: Ask the user, instead of just
+ * failing, showing
+ * mail_nc_msg_count_limit_exceeded, with 'Get
+ * all' and 'Newest only' buttons. */
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_RETRIEVAL_NUMBER_LIMIT,
"The number of messages to retrieve exceeds the chosen limit for account %s\n",
freed before this idle happens, but the mail operation will
be still alive */
g_idle_add (notify_update_account_queue, g_object_ref (info->mail_op));
+
+ if (info->callback)
+ info->callback (info->mail_op,
+ (new_headers) ? new_headers->len : 0,
+ info->user_data);
/* Frees */
g_object_unref (query);
gboolean
modest_mail_operation_update_account (ModestMailOperation *self,
- const gchar *account_name)
+ const gchar *account_name,
+ UpdateAccountCallback callback,
+ gpointer user_data)
{
GThread *thread;
UpdateAccountInfo *info;
g_return_val_if_fail (MODEST_IS_MAIL_OPERATION (self), FALSE);
g_return_val_if_fail (account_name, FALSE);
- /* Make sure that we have a connection, and request one
- * if necessary:
- * TODO: Is there some way to trigger this for every attempt to
- * use the network? */
- if (!modest_platform_connect_and_wait(NULL))
- return FALSE;
-
/* Init mail operation. Set total and done to 0, and do not
update them, this way the progress objects will know that
we have no clue about the number of the objects */
priv->total = 0;
priv->done = 0;
priv->status = MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS;
-
+
+ /* Make sure that we have a connection, and request one
+ * if necessary:
+ * TODO: Is there some way to trigger this for every attempt to
+ * use the network? */
+ if (!modest_platform_connect_and_wait(NULL))
+ goto error;
+
/* Get the Modest account */
modest_account = (TnyStoreAccount *)
modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
TNY_ACCOUNT_TYPE_STORE);
if (!modest_account) {
- priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
"cannot get tny store account for %s\n", account_name);
- modest_mail_operation_notify_end (self);
-
- return FALSE;
+ goto error;
}
modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
account_name);
if (!transport_account) {
- priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
g_set_error (&(priv->error), MODEST_MAIL_OPERATION_ERROR,
MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
"cannot get tny transport account for %s\n", account_name);
- modest_mail_operation_notify_end (self);
-
- return FALSE;
+ goto error;
}
/* Create the helper object */
info->mail_op = self;
info->account = modest_account;
info->transport_account = transport_account;
+ info->callback = callback;
+ info->user_data = user_data;
/* Get the message size limit */
info->max_size = modest_conf_get_int (modest_runtime_get_conf (),
thread = g_thread_create (update_account_thread, info, FALSE, NULL);
return TRUE;
+
+ error:
+ priv->status = MODEST_MAIL_OPERATION_STATUS_FAILED;
+ if (callback)
+ callback (self, 0, user_data);
+ modest_mail_operation_notify_end (self);
+ return FALSE;
}
/* ******************************************************************* */
TnyFolder *folder,
gpointer user_data);
+/**
+ * UpdateAccountCallback:
+ *
+ * @obj: a #GObject generic object which has created current mail operation.
+ * @new_messages: the amount of new messages received
+ * @user_data: generic data passed to user defined function.
+ *
+ * This is the callback of the update_account operation. It informs
+ * the caller about the amount of new messages that have been
+ * downloaded
+ */
+typedef void (*UpdateAccountCallback) (ModestMailOperation *self,
+ gint new_messages,
+ gpointer user_data);
+
/* This struct represents the internal state of a mail operation in a
given time */
typedef struct {
* Returns: TRUE if the mail operation could be started, or FALSE otherwise
**/
gboolean modest_mail_operation_update_account (ModestMailOperation *self,
- const gchar *account_name);
+ const gchar *account_name,
+ UpdateAccountCallback callback,
+ gpointer user_data);
/* Functions that perform store operations */
}
}
+static void
+new_messages_arrived (ModestMailOperation *self,
+ gint new_messages,
+ gpointer user_data)
+{
+ if (new_messages == 0)
+ return;
+
+ modest_platform_on_new_msg ();
+}
+
/*
* This function performs the send & receive required actions. The
* window is used to create the mail operation. Typically it should
internally, so the progress objects will receive the proper
progress information */
modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
- modest_mail_operation_update_account (mail_op, acc_name);
+ modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
g_object_unref (G_OBJECT (mail_op));
/* Free */
TnyFolder *folder,
gpointer user_data)
{
-/* printf ("DEBUG: %s\n", __FUNCTION__); */
ModestMainWindow *win = NULL;
GtkWidget *header_view;
} else {
/* Update the active account */
modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
- /* Do not show folder */
- modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
+ /* Save only if we're seeing headers */
+ if (modest_main_window_get_contents_style (main_window) ==
+ MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
+ modest_widget_memory_save (conf, G_OBJECT (header_view),
+ MODEST_CONF_HEADER_VIEW_KEY);
modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
}
}
return FALSE;
if (type == TNY_FOLDER_TYPE_ROOT) {
- /* TNY_FOLDER_TYPE_ROOT means that the instance is an account instead of a folder. */
+ /* TNY_FOLDER_TYPE_ROOT means that the instance is an
+ account instead of a folder. */
if (TNY_IS_ACCOUNT (instance)) {
TnyAccount *acc = TNY_ACCOUNT (instance);
const gchar *account_id = tny_account_get_id (acc);
if (resizable)
gtk_tree_view_column_set_expand (column, TRUE);
- if (show_as_text)
+ if (show_as_text)
gtk_tree_view_column_add_attribute (column, renderer, "text",
sort_col_id);
if (sort_col_id >= 0)
if (priv->folder) {
tny_folder_remove_observer (priv->folder, TNY_FOLDER_OBSERVER (obj));
g_object_unref (G_OBJECT (priv->folder));
- priv->folder = NULL;
+ priv->folder = NULL;
}
G_OBJECT_CLASS(parent_class)->dispose (obj);
priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder));
tny_folder_monitor_add_list (priv->monitor, TNY_LIST (headers));
tny_folder_monitor_start (priv->monitor);
- tny_folder_add_observer (folder, TNY_FOLDER_OBSERVER (self));
g_mutex_unlock (priv->observers_lock);
sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(headers));
return priv->sort_type[style][type];
}
+typedef struct {
+ ModestHeaderView *header_view;
+ RefreshAsyncUserCallback cb;
+ gpointer user_data;
+} SetFolderHelper;
+
+static void
+folder_refreshed_cb (const GObject *obj,
+ TnyFolder *folder,
+ gpointer user_data)
+{
+ ModestHeaderViewPrivate *priv;
+ SetFolderHelper *info;
+
+ info = (SetFolderHelper*) user_data;
+
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE(info->header_view);
+
+ /* User callback */
+ if (info->cb)
+ info->cb (obj, folder, info->user_data);
+
+ /* Start the folder count changes observer. We do not need it
+ before the refresh. Note that the monitor could still be
+ called for this refresh but now we know that the callback
+ was previously called */
+ g_mutex_lock (priv->observers_lock);
+ tny_folder_add_observer (folder, TNY_FOLDER_OBSERVER (info->header_view));
+ g_mutex_unlock (priv->observers_lock);
+
+ /* Frees */
+ g_free (info);
+}
+
void
modest_header_view_set_folder (ModestHeaderView *self,
TnyFolder *folder,
ModestHeaderViewPrivate *priv;
ModestWindowMgr *mgr = NULL;
GObject *source = NULL;
+ SetFolderHelper *info;
priv = MODEST_HEADER_VIEW_GET_PRIVATE(self);
/* no message selected */
g_signal_emit (G_OBJECT(self), signals[HEADER_SELECTED_SIGNAL], 0, NULL);
+ info = g_malloc0 (sizeof(SetFolderHelper));
+ info->header_view = self;
+ info->cb = callback;
+ info->user_data = user_data;
+
/* Create the mail operation (source will be the parent widget) */
mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, source);
modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
mail_op);
/* Refresh the folder asynchronously */
- modest_mail_operation_refresh_folder (mail_op, folder,
- callback,
- user_data);
+ modest_mail_operation_refresh_folder (mail_op,
+ folder,
+ folder_refreshed_cb,
+ info);
/* Free */
g_object_unref (mail_op);
return FALSE;
}
-static gboolean
-idle_notify_added_headers (gpointer data)
-{
- modest_platform_on_new_msg ();
-
- return FALSE;
-}
-
static void
idle_notify_headers_count_changed_destroy (gpointer data)
{
folder_monitor_update (TnyFolderObserver *self,
TnyFolderChange *change)
{
+ ModestHeaderViewPrivate *priv;
TnyFolderChangeChanged changed;
HeadersCountChangedHelper *helper = NULL;
changed = tny_folder_change_get_changed (change);
-
- /* We need an idle because this function is called from within
- a thread, so it could cause problems if the modest platform
- code calls dbus for example */
- if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS)
- g_idle_add (idle_notify_added_headers, NULL);
+ /* Do not notify the observers if the folder of the header
+ view has changed before this call to the observer
+ happens */
+ priv = MODEST_HEADER_VIEW_GET_PRIVATE (MODEST_HEADER_VIEW (self));
+ if (tny_folder_change_get_folder (change) != priv->folder)
+ return;
+
/* Check folder count */
if ((changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) ||
(changed & TNY_FOLDER_CHANGE_CHANGED_REMOVED_HEADERS)) {