Experimental patch to implement sent and sending signal on tny-camel-send-queue
- From: Javier Fernandez <jfernandez igalia com>
- To: tinymail-devel-list gnome org
- Subject: Experimental patch to implement sent and sending signal on tny-camel-send-queue
- Date: Tue, 19 Jun 2007 17:22:03 +0200
This patch implements two new signals to detect when a message is being
processed into send queue and when its finally sent.
--
Javier Fernández García-Boente
Ingeniero en Informática
mailto:jfernandez igalia com
Igalia http://www.igalia.com
Telf. +34 981 91 39 91
Fax. +34 981 91 39 49
Index: libtinymail-camel/tny-camel-send-queue.c
===================================================================
--- libtinymail-camel/tny-camel-send-queue.c (revision 2224)
+++ libtinymail-camel/tny-camel-send-queue.c (working copy)
@@ -28,6 +28,8 @@
#include <tny-folder.h>
#include <tny-error.h>
+
+#include <tny-folder-observer.h>
#include <tny-camel-folder.h>
#include <tny-transport-account.h>
@@ -53,6 +55,14 @@
gint i, total;
} ErrorInfo;
+typedef struct {
+ TnySendQueue *self;
+ TnyMsg *msg;
+ TnyHeader *header;
+ gint i, total;
+ guint signal_id;
+} ControlInfo;
+
static gboolean
emit_error_on_mainloop (gpointer data)
{
@@ -62,6 +72,15 @@
return FALSE;
}
+static gboolean
+emit_control_signals_on_mainloop (gpointer data)
+{
+ ControlInfo *info = data;
+ g_signal_emit (info->self, tny_send_queue_signals [info->signal_id],
+ 0, info->header, info->msg, info->i, info->total);
+ return FALSE;
+}
+
static void
destroy_error_info (gpointer data)
{
@@ -78,6 +97,20 @@
}
static void
+destroy_control_info (gpointer data)
+{
+ ControlInfo *info = data;
+
+ if (info->msg)
+ g_object_unref (G_OBJECT (info->msg));
+ if (info->header)
+ g_object_unref (G_OBJECT (info->header));
+ if (info->self)
+ g_object_unref (G_OBJECT (info->self));
+
+ g_slice_free (ControlInfo, info);
+}
+
emit_error (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *error, int i, int total)
{
ErrorInfo *info = g_slice_new0 (ErrorInfo);
@@ -100,6 +133,28 @@
return;
}
+static void
+emit_control (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint signal_id, int i, int total)
+{
+ ControlInfo *info = g_slice_new0 (ControlInfo);
+
+ if (self)
+ info->self = TNY_SEND_QUEUE (g_object_ref (G_OBJECT (self)));
+ if (msg)
+ info->msg = TNY_MSG (g_object_ref (G_OBJECT (msg)));
+ if (header)
+ info->header = TNY_HEADER (g_object_ref (G_OBJECT (header)));
+
+ info->signal_id = signal_id;
+ info->i = i;
+ info->total = total;
+
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ emit_control_signals_on_mainloop, info, destroy_control_info);
+
+ return;
+}
+
static gpointer
thread_main (gpointer data)
{
@@ -131,8 +186,9 @@
goto errorhandler;
}
+ /* I dont expect total is being changed */
length = tny_list_get_length (list);
- priv->total = length;
+/* priv->total = length; */
}
g_mutex_unlock (priv->todo_lock);
@@ -165,10 +221,10 @@
goto errorhandler;
}
+ /* I dont expect total is being changed */
length = tny_list_get_length (headers);
+/* priv->total = length; */
- priv->total = length;
-
if (length <= 0)
{
g_object_unref (G_OBJECT (headers));
@@ -185,7 +241,6 @@
}
g_mutex_unlock (priv->todo_lock);
-
if (header && TNY_IS_HEADER (header))
{
TnyList *hassent = tny_simple_list_new ();
@@ -194,6 +249,9 @@
tny_list_prepend (hassent, G_OBJECT (header));
msg = tny_folder_get_msg (outbox, header, &err);
+ /* Emits msg-sending signal to inform a new msg is being sent */
+ emit_control (self, header, msg, TNY_SEND_QUEUE_MSG_SENDING, i, priv->total);
+
/* hassent is owner now */
g_object_unref (G_OBJECT (header));
@@ -222,9 +280,13 @@
priv->do_continue = FALSE;
g_error_free (newerr);
}
- priv->total--;
+/* priv->total--; */
}
}
+
+ /* Emits msg-sent signal to inform msg has been sent */
+ emit_control (self, header, msg, TNY_SEND_QUEUE_MSG_SENT, i, priv->total);
+
g_mutex_unlock (priv->todo_lock);
g_object_unref (G_OBJECT (hassent));
@@ -352,61 +414,128 @@
static void
tny_camel_send_queue_add_default (TnySendQueue *self, TnyMsg *msg, GError **err)
{
- TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
+ TnyFolder *outbox = tny_send_queue_get_outbox (self);
g_assert (TNY_IS_CAMEL_MSG (msg));
- g_mutex_lock (priv->todo_lock);
- {
- TnyFolder *outbox;
- TnyList *headers = tny_simple_list_new ();
+ if (!outbox || !TNY_IS_FOLDER (outbox)) {
+ g_set_error (err, TNY_SEND_QUEUE_ERROR,
+ TNY_SEND_QUEUE_ERROR_ADD,
+ "Operating can't continue: send queue not ready "
+ "because it does not have a valid outbox. "
+ "This problem indicates a bug in the software.");
+ return;
+ }
- outbox = tny_send_queue_get_outbox (self);
+ tny_folder_add_msg (outbox, msg, err);
- if (!outbox || !TNY_IS_FOLDER (outbox))
- {
- g_set_error (err, TNY_SEND_QUEUE_ERROR,
- TNY_SEND_QUEUE_ERROR_ADD,
- "Operating can't continue: send queue not ready "
- "because it does not have a valid outbox. "
- "This problem indicates a bug in the software.");
- g_object_unref (headers);
- g_mutex_unlock (priv->todo_lock);
- return;
- }
+ g_object_unref (outbox);
+ return;
+}
- tny_folder_get_headers (outbox, headers, TRUE, err);
+/* static void */
+/* tny_camel_send_queue_add_default (TnySendQueue *self, TnyMsg *msg, GError **err) */
+/* { */
+/* TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self); */
- if (err!= NULL && *err != NULL)
- {
- g_object_unref (G_OBJECT (headers));
- g_object_unref (G_OBJECT (outbox));
- g_mutex_unlock (priv->todo_lock);
- return;
- }
+/* g_assert (TNY_IS_CAMEL_MSG (msg)); */
- priv->total = tny_list_get_length (headers);
- g_object_unref (G_OBJECT (headers));
+/* g_mutex_lock (priv->todo_lock); */
+/* { */
+/* TnyFolder *outbox; */
+/* TnyList *headers = tny_simple_list_new (); */
- tny_folder_add_msg (outbox, msg, err);
+/* outbox = tny_send_queue_get_outbox (self); */
- if (err!= NULL && *err != NULL)
- {
- g_object_unref (G_OBJECT (outbox));
- g_mutex_unlock (priv->todo_lock);
- return;
- }
+/* if (!outbox || !TNY_IS_FOLDER (outbox)) */
+/* { */
+/* g_set_error (err, TNY_SEND_QUEUE_ERROR, */
+/* TNY_SEND_QUEUE_ERROR_ADD, */
+/* "Operating can't continue: send queue not ready " */
+/* "because it does not have a valid outbox. " */
+/* "This problem indicates a bug in the software."); */
+/* g_object_unref (headers); */
+/* g_mutex_unlock (priv->todo_lock); */
+/* return; */
+/* } */
- priv->total++;
+/* tny_folder_get_headers (outbox, headers, TRUE, err); */
+/* if (err!= NULL && *err != NULL) */
+/* { */
+/* g_object_unref (G_OBJECT (headers)); */
+/* g_object_unref (G_OBJECT (outbox)); */
+/* g_mutex_unlock (priv->todo_lock); */
+/* return; */
+/* } */
+
+/* priv->total = tny_list_get_length (headers); */
+/* g_object_unref (G_OBJECT (headers)); */
+
+/* tny_folder_add_msg (outbox, msg, err); */
+
+/* if (err!= NULL && *err != NULL) */
+/* { */
+/* g_object_unref (G_OBJECT (outbox)); */
+/* g_mutex_unlock (priv->todo_lock); */
+/* return; */
+/* } */
+
+/* priv->total++; */
+
+/* if (priv->total >= 1 && !priv->thread && !priv->creating_spin) */
+/* create_worker (self); */
+
+/* g_object_unref (G_OBJECT (outbox)); */
+/* } */
+
+/* g_mutex_unlock (priv->todo_lock); */
+
+/* return; */
+/* } */
+
+static void
+tny_camel_send_queue_update (TnyFolderObserver *self, TnyFolderChange *change)
+{
+ TNY_CAMEL_SEND_QUEUE_GET_CLASS (self)->update_func (self, change);
+ return;
+}
+
+static void
+tny_camel_send_queue_update_default (TnyFolderObserver *self, TnyFolderChange *change)
+{
+ TnyCamelSendQueuePriv *priv = TNY_CAMEL_SEND_QUEUE_GET_PRIVATE (self);
+ TnyFolder *outbox;
+ TnyFolderChangeChanged changed;
+ ErrorInfo *info;
+ TnyList *headers;
+ gint i = 0;
+
+ g_mutex_lock (priv->todo_lock);
+
+ changed = tny_folder_change_get_changed (change);
+
+ if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
+ outbox = tny_send_queue_get_outbox (TNY_SEND_QUEUE (self));
+
+ /* The added headers */
+ headers = tny_simple_list_new ();
+ tny_folder_change_get_added_headers (change, headers);
+
+ priv->total = tny_list_get_length (headers);
+ g_object_unref (G_OBJECT (headers));
+
if (priv->total >= 1 && !priv->thread && !priv->creating_spin)
- create_worker (self);
+ create_worker (TNY_SEND_QUEUE(self));
g_object_unref (G_OBJECT (outbox));
}
+
g_mutex_unlock (priv->todo_lock);
-
+
return;
+
+
}
@@ -684,9 +813,9 @@
class->get_outbox_func = tny_camel_send_queue_get_outbox_default;
class->get_sentbox_func = tny_camel_send_queue_get_sentbox_default;
class->cancel_func = tny_camel_send_queue_cancel_default;
+ class->update_func = tny_camel_send_queue_update_default;
object_class->finalize = tny_camel_send_queue_finalize;
-
g_type_class_add_private (object_class, sizeof (TnyCamelSendQueuePriv));
return;
@@ -710,6 +839,12 @@
return;
}
+static void
+tny_folder_observer_init (TnyFolderObserverIface *klass)
+{
+ klass->update_func = tny_camel_send_queue_update;
+}
+
/**
* tny_camel_send_queue_get_type:
*
@@ -754,6 +889,13 @@
NULL /* interface_data */
};
+ static const GInterfaceInfo tny_folder_observer_info = {
+ (GInterfaceInitFunc) tny_folder_observer_init,
+ NULL,
+ NULL
+ };
+
+
type = g_type_register_static (G_TYPE_OBJECT,
"TnyCamelSendQueue",
&info, 0);
@@ -761,6 +903,9 @@
g_type_add_interface_static (type, TNY_TYPE_SEND_QUEUE,
&tny_send_queue_info);
+
+ g_type_add_interface_static (type, TNY_TYPE_FOLDER_OBSERVER,
+ &tny_folder_observer_info);
}
return type;
Index: libtinymail-camel/tny-camel-send-queue.h
===================================================================
--- libtinymail-camel/tny-camel-send-queue.h (revision 2224)
+++ libtinymail-camel/tny-camel-send-queue.h (working copy)
@@ -53,6 +53,7 @@
TnyFolder* (*get_sentbox_func) (TnySendQueue *self);
TnyFolder* (*get_outbox_func) (TnySendQueue *self);
void (*cancel_func) (TnySendQueue *self, gboolean remove, GError **err);
+ void (*update_func) (TnyFolderObserver *self, TnyFolderChange *change);
};
GType tny_camel_send_queue_get_type (void);
Index: tests/c-demo/tny-demoui-summary-view.c
===================================================================
--- tests/c-demo/tny-demoui-summary-view.c (revision 2224)
+++ tests/c-demo/tny-demoui-summary-view.c (working copy)
@@ -111,6 +111,10 @@
(G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_DEMOUI_SUMMARY_VIEW, TnyDemouiSummaryViewPriv))
+static gboolean filter_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data);
+
static gboolean
cleanup_statusbar (gpointer data)
{
@@ -759,7 +763,7 @@
GtkTreeModel *model;
GtkTreeModel *hmodel;
GtkTreeView *header_view = GTK_TREE_VIEW (priv->header_view);
- GtkTreeModel *sortable;
+ GtkTreeModel *sortable, *filter_model;
GtkSelectionMode mode;
mode = gtk_tree_selection_get_mode (selection);
@@ -825,13 +829,25 @@
tny_gtk_header_list_model_sent_date_sort_func,
NULL, NULL);
- set_header_view_model (header_view, sortable);
+ /* Create a tree model filter to hide and show rows for cut operations */
+ filter_model = gtk_tree_model_filter_new (sortable, NULL);
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (filter_model),
+ filter_row,
+ self,
+ NULL);
+ /* Hide headers with attachment */
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (filter_model));
+
+ set_header_view_model (header_view, filter_model);
+/* set_header_view_model (header_view, sortable); */
+
tny_folder_refresh_async (folder,
refresh_current_folder,
status_update, self);
g_object_unref (G_OBJECT (folder));
+
}
}
} else {
@@ -1900,3 +1916,23 @@
return type;
}
+
+static gboolean
+filter_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+
+ TnyHeaderFlags flags;
+
+ /* Get header from model */
+ gtk_tree_model_get (model, iter,
+ TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags,
+ -1);
+
+ /* Set visibility */
+ if (flags & TNY_HEADER_FLAG_ATTACHMENTS)
+ return FALSE;
+
+ return TRUE;
+}
Index: libtinymail-queues/tny-generic-send-queue.c
===================================================================
--- libtinymail-queues/tny-generic-send-queue.c (revision 2224)
+++ libtinymail-queues/tny-generic-send-queue.c (working copy)
@@ -182,6 +182,10 @@
info->self = TNY_GENERIC_SEND_QUEUE (g_object_ref (self));
info->msg = tny_folder_get_msg (outbox, header, &err);
+ /* Emits msg-sending signal to inform a new msg is being sent */
+ g_signal_emit (self, tny_send_queue_signals [TNY_SEND_QUEUE_MSG_SENDING],
+ 0, info->msg, err, i, total);
+
if (err != NULL)
{
emit_error (TNY_SEND_QUEUE (self), NULL, err, info->i, info->total);
@@ -205,7 +209,11 @@
tny_queue_task_set_callback (task, generic_send_callback);
item = tny_queue_add_task (priv->queue, task);
-
+
+ /* Emits msg-sent signal to inform msg has been sent */
+ g_signal_emit (self, tny_send_queue_signals [TNY_SEND_QUEUE_MSG_SENT],
+ 0, info->msg, err, i, total);
+
g_object_unref (header);
tny_iterator_next (iter);
i++;
Index: libtinymail/tny-signals-marshal.list
===================================================================
--- libtinymail/tny-signals-marshal.list (revision 2224)
+++ libtinymail/tny-signals-marshal.list (working copy)
@@ -1 +1,2 @@
VOID:OBJECT,OBJECT,POINTER
+VOID:OBJECT,OBJECT,INT,INT
Index: libtinymail/tny-send-queue.c
===================================================================
--- libtinymail/tny-send-queue.c (revision 2224)
+++ libtinymail/tny-send-queue.c (working copy)
@@ -143,6 +143,27 @@
if (!initialized)
{
/**
+ * TnySendQueue::msg-sending
+ * @self: the object on which the signal is emitted
+ * @arg1: The message that is being
+ * @arg2: The current nth number of the message that is being sending
+ * @arg3: The total amount of messages currently being processed
+ *
+ * API WARNING: This API might change
+ *
+ * Emitted when a message is being proccessed to sending it
+ **/
+ tny_send_queue_signals[TNY_SEND_QUEUE_MSG_SENDING] =
+ g_signal_new ("msg_sending",
+ TNY_TYPE_SEND_QUEUE,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TnySendQueueIface, msg_sending),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ tny_marshal_VOID__OBJECT_OBJECT_INT_INT,
+ G_TYPE_NONE, 4, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_UINT, G_TYPE_UINT);
+
+/**
* TnySendQueue::msg-sent
* @self: the object on which the signal is emitted
* @arg1: The message that got sent
@@ -151,13 +172,13 @@
* Emitted when a message got sent
**/
tny_send_queue_signals[TNY_SEND_QUEUE_MSG_SENT] =
- g_signal_new ("msg_sent",
- TNY_TYPE_SEND_QUEUE,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (TnySendQueueIface, msg_sent),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, TNY_TYPE_MSG);
+ g_signal_new ("msg_sent",
+ TNY_TYPE_SEND_QUEUE,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TnySendQueueIface, msg_sent),
+ NULL, NULL,
+ tny_marshal_VOID__OBJECT_OBJECT_INT_INT,
+ G_TYPE_NONE, 4, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_UINT, G_TYPE_UINT);
/**
* TnySendQueue::error-happened
@@ -171,14 +192,14 @@
* Emitted when a message didn't get sent because of an error
**/
tny_send_queue_signals[TNY_SEND_QUEUE_ERROR_HAPPENED] =
- g_signal_new ("error_happened",
- TNY_TYPE_SEND_QUEUE,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (TnySendQueueIface, error_happened),
- NULL, NULL,
- tny_marshal_VOID__OBJECT_OBJECT_POINTER,
- G_TYPE_NONE, 3, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_POINTER);
-
+ g_signal_new ("error_happened",
+ TNY_TYPE_SEND_QUEUE,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (TnySendQueueIface, error_happened),
+ NULL, NULL,
+ tny_marshal_VOID__OBJECT_OBJECT_POINTER,
+ G_TYPE_NONE, 3, TNY_TYPE_HEADER, TNY_TYPE_MSG, G_TYPE_POINTER);
+
initialized = TRUE;
}
}
Index: libtinymail/tny-send-queue.h
===================================================================
--- libtinymail/tny-send-queue.h (revision 2224)
+++ libtinymail/tny-send-queue.h (working copy)
@@ -40,6 +40,7 @@
enum _TnySendQueueSignal
{
+ TNY_SEND_QUEUE_MSG_SENDING,
TNY_SEND_QUEUE_MSG_SENT,
TNY_SEND_QUEUE_ERROR_HAPPENED,
TNY_SEND_QUEUE_LAST_SIGNAL
@@ -53,7 +54,8 @@
GTypeInterface parent;
/* Signals */
- void (*msg_sent) (TnySendQueue *self, TnyMsg *msg, gpointer user_data);
+ void (*msg_sending) (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint nth, guint total);
+ void (*msg_sent) (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, guint nth, guint total);
void (*error_happened) (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, gpointer user_data);
/* methods */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]