aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-09-19 03:57:27 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-09-19 04:40:19 +0800
commita98c07a569292fa66f91d3fa4bd32f32adff1880 (patch)
tree98caa43594f61662289fd696b409978946e92255
parentb145c0a2522c5c9942c0827bf03baefea68f5d99 (diff)
downloadgsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.tar
gsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.tar.gz
gsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.tar.bz2
gsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.tar.lz
gsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.tar.xz
gsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.tar.zst
gsoc2013-evolution-a98c07a569292fa66f91d3fa4bd32f32adff1880.zip
Add a GCancellable to EActivity.
EActivity now uses a GCancellable to manage cancellations, instead of having its own redundant cancellation API. API changes are as follows: + e_activity_get_cancellable() + e_activity_set_cancellable() - e_activity_cancel() - e_activity_is_cancelled() - e_activity_get_allow_cancel() - e_activity_set_allow_cancel() EActivity's "cancelled" signal remains, but only as a repeater for GCancellable::cancelled signals. It should not be emitted directly. The presence of a GCancellable implies that cancellation is allowed. EActivity does not create its own default GCancellable, it has to be given one. If a CamelOperation (cast as a GCancellable) is given, EActivity will configure itself to listen for status updates from the CamelOperation and propagate the information to its own "primary-text" and "percent" properties. These changes allowed me to start cleaning up some of the incredibly convoluted logic in mail-mt.c -- in particular, mail_operation_status() is completely gone now. mail-mt.c is still in a transitional state -- much more significant changes coming soon.
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c3
-rw-r--r--doc/reference/shell/eshell-sections.txt6
-rw-r--r--doc/reference/shell/tmpl/e-activity.sgml25
-rw-r--r--doc/reference/shell/tmpl/eshell-unused.sgml31
-rw-r--r--e-util/e-activity.c170
-rw-r--r--e-util/e-activity.h10
-rw-r--r--e-util/e-io-activity.c82
-rw-r--r--e-util/e-io-activity.h3
-rw-r--r--e-util/e-timeout-activity.c2
-rw-r--r--mail/mail-mt.c296
-rw-r--r--modules/calendar/e-cal-shell-view-memopad.c3
-rw-r--r--modules/calendar/e-cal-shell-view-private.c3
-rw-r--r--modules/calendar/e-cal-shell-view-taskpad.c3
-rw-r--r--modules/calendar/e-memo-shell-view-private.c3
-rw-r--r--modules/calendar/e-task-shell-view-private.c3
-rw-r--r--shell/e-shell-taskbar.c21
-rw-r--r--shell/e-shell.c21
-rw-r--r--widgets/misc/e-activity-proxy.c27
18 files changed, 288 insertions, 424 deletions
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index bb6e58f7b6..957d85e30f 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -1082,8 +1082,9 @@ status_message (EAddressbookView *view,
}
} else if (activity == NULL) {
- activity = e_activity_new (status);
+ activity = e_activity_new ();
view->priv->activity = activity;
+ e_activity_set_primary_text (activity, status);
e_shell_backend_add_activity (shell_backend, activity);
} else
diff --git a/doc/reference/shell/eshell-sections.txt b/doc/reference/shell/eshell-sections.txt
index 05ac15878e..d8b8a5cbd5 100644
--- a/doc/reference/shell/eshell-sections.txt
+++ b/doc/reference/shell/eshell-sections.txt
@@ -461,14 +461,12 @@ EActionComboBoxPrivate
EActivity
e_activity_new
e_activity_newv
-e_activity_cancel
e_activity_complete
e_activity_clicked
e_activity_describe
-e_activity_is_cancelled
e_activity_is_completed
-e_activity_get_allow_cancel
-e_activity_set_allow_cancel
+e_activity_get_cancellable
+e_activity_set_cancellable
e_activity_get_clickable
e_activity_set_clickable
e_activity_get_icon_name
diff --git a/doc/reference/shell/tmpl/e-activity.sgml b/doc/reference/shell/tmpl/e-activity.sgml
index d56bd0776a..871758fb5e 100644
--- a/doc/reference/shell/tmpl/e-activity.sgml
+++ b/doc/reference/shell/tmpl/e-activity.sgml
@@ -31,7 +31,7 @@ e-activity
</para>
-@primary_text:
+@void:
@Returns:
@@ -45,14 +45,6 @@ e-activity
@Returns:
-<!-- ##### FUNCTION e_activity_cancel ##### -->
-<para>
-
-</para>
-
-@activity:
-
-
<!-- ##### FUNCTION e_activity_complete ##### -->
<para>
@@ -78,15 +70,6 @@ e-activity
@Returns:
-<!-- ##### FUNCTION e_activity_is_cancelled ##### -->
-<para>
-
-</para>
-
-@activity:
-@Returns:
-
-
<!-- ##### FUNCTION e_activity_is_completed ##### -->
<para>
@@ -96,7 +79,7 @@ e-activity
@Returns:
-<!-- ##### FUNCTION e_activity_get_allow_cancel ##### -->
+<!-- ##### FUNCTION e_activity_get_cancellable ##### -->
<para>
</para>
@@ -105,13 +88,13 @@ e-activity
@Returns:
-<!-- ##### FUNCTION e_activity_set_allow_cancel ##### -->
+<!-- ##### FUNCTION e_activity_set_cancellable ##### -->
<para>
</para>
@activity:
-@allow_cancel:
+@cancellable:
<!-- ##### FUNCTION e_activity_get_clickable ##### -->
diff --git a/doc/reference/shell/tmpl/eshell-unused.sgml b/doc/reference/shell/tmpl/eshell-unused.sgml
index 15c9658da6..59aed5d191 100644
--- a/doc/reference/shell/tmpl/eshell-unused.sgml
+++ b/doc/reference/shell/tmpl/eshell-unused.sgml
@@ -95,6 +95,37 @@ e-shell-window.sgml
@window:
+<!-- ##### FUNCTION e_activity_cancel ##### -->
+<para>
+
+</para>
+
+@activity:
+
+<!-- ##### FUNCTION e_activity_get_allow_cancel ##### -->
+<para>
+
+</para>
+
+@activity:
+@Returns:
+
+<!-- ##### FUNCTION e_activity_is_cancelled ##### -->
+<para>
+
+</para>
+
+@activity:
+@Returns:
+
+<!-- ##### FUNCTION e_activity_set_allow_cancel ##### -->
+<para>
+
+</para>
+
+@activity:
+@allow_cancel:
+
<!-- ##### FUNCTION e_get_user_data_dir ##### -->
<para>
diff --git a/e-util/e-activity.c b/e-util/e-activity.c
index 631915db89..f90361d7f2 100644
--- a/e-util/e-activity.c
+++ b/e-util/e-activity.c
@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <glib/gi18n.h>
+#include <camel/camel.h>
#include "e-util/e-util.h"
@@ -31,20 +32,20 @@
((obj), E_TYPE_ACTIVITY, EActivityPrivate))
struct _EActivityPrivate {
+ GCancellable *cancellable;
+
gchar *icon_name;
gchar *primary_text;
gchar *secondary_text;
gdouble percent;
- guint allow_cancel : 1;
- guint cancelled : 1;
guint clickable : 1;
guint completed : 1;
};
enum {
PROP_0,
- PROP_ALLOW_CANCEL,
+ PROP_CANCELLABLE,
PROP_CLICKABLE,
PROP_ICON_NAME,
PROP_PERCENT,
@@ -67,6 +68,19 @@ G_DEFINE_TYPE (
e_activity,
G_TYPE_OBJECT)
+static void
+activity_camel_status_cb (EActivity *activity,
+ const gchar *description,
+ gint percent)
+{
+ /* CamelOperation::status signals are always emitted from idle
+ * callbacks, so we don't have to screw around with locking. */
+
+ g_object_set (
+ activity, "percent", (gdouble) percent,
+ "primary-text", description, NULL);
+}
+
static gboolean
activity_describe_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
@@ -82,16 +96,24 @@ activity_describe_accumulator (GSignalInvocationHint *ihint,
}
static void
+activity_emit_cancelled (EActivity *activity)
+{
+ /* This signal should only be emitted via our GCancellable,
+ * which is why we don't expose this function publicly. */
+ g_signal_emit (activity, signals[CANCELLED], 0);
+}
+
+static void
activity_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_ALLOW_CANCEL:
- e_activity_set_allow_cancel (
+ case PROP_CANCELLABLE:
+ e_activity_set_cancellable (
E_ACTIVITY (object),
- g_value_get_boolean (value));
+ g_value_get_object (value));
return;
case PROP_CLICKABLE:
@@ -135,9 +157,9 @@ activity_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_ALLOW_CANCEL:
- g_value_set_boolean (
- value, e_activity_get_allow_cancel (
+ case PROP_CANCELLABLE:
+ g_value_set_object (
+ value, e_activity_get_cancellable (
E_ACTIVITY (object)));
return;
@@ -176,6 +198,26 @@ activity_get_property (GObject *object,
}
static void
+activity_dispose (GObject *object)
+{
+ EActivityPrivate *priv;
+
+ priv = E_ACTIVITY_GET_PRIVATE (object);
+
+ if (priv->cancellable != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->cancellable,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->cancellable);
+ priv->cancellable = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_activity_parent_class)->dispose (object);
+}
+
+static void
activity_finalize (GObject *object)
{
EActivityPrivate *priv;
@@ -191,12 +233,6 @@ activity_finalize (GObject *object)
}
static void
-activity_cancelled (EActivity *activity)
-{
- activity->priv->cancelled = TRUE;
-}
-
-static void
activity_completed (EActivity *activity)
{
activity->priv->completed = TRUE;
@@ -212,21 +248,22 @@ static gchar *
activity_describe (EActivity *activity)
{
GString *string;
+ GCancellable *cancellable;
const gchar *text;
- gboolean cancelled;
- gboolean completed;
gdouble percent;
string = g_string_sized_new (256);
+ cancellable = e_activity_get_cancellable (activity);
text = e_activity_get_primary_text (activity);
- cancelled = e_activity_is_cancelled (activity);
- completed = e_activity_is_completed (activity);
percent = e_activity_get_percent (activity);
- if (cancelled) {
+ if (text == NULL)
+ return NULL;
+
+ if (g_cancellable_is_cancelled (cancellable)) {
/* Translators: This is a cancelled activity. */
g_string_printf (string, _("%s (cancelled)"), text);
- } else if (completed) {
+ } else if (e_activity_is_completed (activity)) {
/* Translators: This is a completed activity. */
g_string_printf (string, _("%s (completed)"), text);
} else if (percent < 0.0) {
@@ -254,21 +291,21 @@ e_activity_class_init (EActivityClass *class)
object_class = G_OBJECT_CLASS (class);
object_class->set_property = activity_set_property;
object_class->get_property = activity_get_property;
+ object_class->dispose = activity_dispose;
object_class->finalize = activity_finalize;
- class->cancelled = activity_cancelled;
class->completed = activity_completed;
class->clicked = activity_clicked;
class->describe = activity_describe;
g_object_class_install_property (
object_class,
- PROP_ALLOW_CANCEL,
- g_param_spec_boolean (
- "allow-cancel",
+ PROP_CANCELLABLE,
+ g_param_spec_object (
+ "cancellable",
NULL,
NULL,
- FALSE,
+ G_TYPE_CANCELLABLE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
@@ -373,11 +410,9 @@ e_activity_init (EActivity *activity)
}
EActivity *
-e_activity_new (const gchar *primary_text)
+e_activity_new (void)
{
- return g_object_new (
- E_TYPE_ACTIVITY,
- "primary-text", primary_text, NULL);
+ return g_object_new (E_TYPE_ACTIVITY, NULL);
}
EActivity *
@@ -387,9 +422,11 @@ e_activity_newv (const gchar *format, ...)
gchar *primary_text;
va_list args;
+ activity = e_activity_new ();
+
va_start (args, format);
primary_text = g_strdup_vprintf (format, args);
- activity = e_activity_new (primary_text);
+ e_activity_set_primary_text (activity, primary_text);
g_free (primary_text);
va_end (args);
@@ -397,28 +434,15 @@ e_activity_newv (const gchar *format, ...)
}
void
-e_activity_cancel (EActivity *activity)
-{
- g_return_if_fail (E_IS_ACTIVITY (activity));
-
- if (!activity->priv->allow_cancel)
- return;
-
- if (activity->priv->cancelled)
- return;
-
- if (activity->priv->completed)
- return;
-
- g_signal_emit (activity, signals[CANCELLED], 0);
-}
-
-void
e_activity_complete (EActivity *activity)
{
+ GCancellable *cancellable;
+
g_return_if_fail (E_IS_ACTIVITY (activity));
- if (activity->priv->cancelled)
+ cancellable = e_activity_get_cancellable (activity);
+
+ if (g_cancellable_is_cancelled (cancellable))
return;
if (activity->priv->completed)
@@ -449,14 +473,6 @@ e_activity_describe (EActivity *activity)
}
gboolean
-e_activity_is_cancelled (EActivity *activity)
-{
- g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
-
- return activity->priv->cancelled;
-}
-
-gboolean
e_activity_is_completed (EActivity *activity)
{
g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
@@ -464,23 +480,47 @@ e_activity_is_completed (EActivity *activity)
return activity->priv->completed;
}
-gboolean
-e_activity_get_allow_cancel (EActivity *activity)
+GCancellable *
+e_activity_get_cancellable (EActivity *activity)
{
- g_return_val_if_fail (E_IS_ACTIVITY (activity), FALSE);
+ g_return_val_if_fail (E_IS_ACTIVITY (activity), NULL);
- return activity->priv->allow_cancel;
+ return activity->priv->cancellable;
}
void
-e_activity_set_allow_cancel (EActivity *activity,
- gboolean allow_cancel)
+e_activity_set_cancellable (EActivity *activity,
+ GCancellable *cancellable)
{
g_return_if_fail (E_IS_ACTIVITY (activity));
- activity->priv->allow_cancel = allow_cancel;
+ if (cancellable != NULL) {
+ g_return_if_fail (G_IS_CANCELLABLE (cancellable));
+ g_object_ref (cancellable);
+ }
+
+ if (activity->priv->cancellable != NULL) {
+ g_signal_handlers_disconnect_matched (
+ activity->priv->cancellable,
+ G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, activity);
+ g_object_unref (activity->priv->cancellable);
+ }
+
+ activity->priv->cancellable = cancellable;
+
+ if (G_IS_CANCELLABLE (cancellable))
+ g_signal_connect_swapped (
+ cancellable, "cancelled",
+ G_CALLBACK (activity_emit_cancelled), activity);
+
+ /* If this is a CamelOperation, listen for status updates
+ * from it and propagate them to our own status properties. */
+ if (CAMEL_IS_OPERATION (cancellable))
+ g_signal_connect_swapped (
+ cancellable, "status",
+ G_CALLBACK (activity_camel_status_cb), activity);
- g_object_notify (G_OBJECT (activity), "allow-cancel");
+ g_object_notify (G_OBJECT (activity), "cancellable");
}
gboolean
diff --git a/e-util/e-activity.h b/e-util/e-activity.h
index b396e3a630..4573fada57 100644
--- a/e-util/e-activity.h
+++ b/e-util/e-activity.h
@@ -65,18 +65,16 @@ struct _EActivityClass {
};
GType e_activity_get_type (void);
-EActivity * e_activity_new (const gchar *primary_text);
+EActivity * e_activity_new (void);
EActivity * e_activity_newv (const gchar *format,
...) G_GNUC_PRINTF (1, 2);
-void e_activity_cancel (EActivity *activity);
void e_activity_complete (EActivity *activity);
void e_activity_clicked (EActivity *activity);
gchar * e_activity_describe (EActivity *activity);
-gboolean e_activity_is_cancelled (EActivity *activity);
gboolean e_activity_is_completed (EActivity *activity);
-gboolean e_activity_get_allow_cancel (EActivity *activity);
-void e_activity_set_allow_cancel (EActivity *activity,
- gboolean allow_cancel);
+GCancellable * e_activity_get_cancellable (EActivity *activity);
+void e_activity_set_cancellable (EActivity *activity,
+ GCancellable *cancellable);
gboolean e_activity_get_clickable (EActivity *activity);
void e_activity_set_clickable (EActivity *activity,
gboolean clickable);
diff --git a/e-util/e-io-activity.c b/e-util/e-io-activity.c
index c8eb761708..e519fea18b 100644
--- a/e-util/e-io-activity.c
+++ b/e-util/e-io-activity.c
@@ -27,13 +27,11 @@
struct _EIOActivityPrivate {
GAsyncResult *async_result;
- GCancellable *cancellable;
};
enum {
PROP_0,
- PROP_ASYNC_RESULT,
- PROP_CANCELLABLE
+ PROP_ASYNC_RESULT
};
G_DEFINE_TYPE (
@@ -53,12 +51,6 @@ io_activity_set_property (GObject *object,
E_IO_ACTIVITY (object),
g_value_get_object (value));
return;
-
- case PROP_CANCELLABLE:
- e_io_activity_set_cancellable (
- E_IO_ACTIVITY (object),
- g_value_get_object (value));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -76,12 +68,6 @@ io_activity_get_property (GObject *object,
value, e_io_activity_get_async_result (
E_IO_ACTIVITY (object)));
return;
-
- case PROP_CANCELLABLE:
- g_value_set_object (
- value, e_io_activity_get_cancellable (
- E_IO_ACTIVITY (object)));
- return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -99,32 +85,11 @@ io_activity_dispose (GObject *object)
priv->async_result = NULL;
}
- if (priv->cancellable != NULL) {
- g_object_unref (priv->cancellable);
- priv->cancellable = NULL;
- }
-
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_io_activity_parent_class)->dispose (object);
}
static void
-io_activity_cancelled (EActivity *activity)
-{
- EIOActivity *io_activity;
- GCancellable *cancellable;
-
- /* Chain up to parent's cancelled() method. */
- E_ACTIVITY_CLASS (e_io_activity_parent_class)->cancelled (activity);
-
- io_activity = E_IO_ACTIVITY (activity);
- cancellable = e_io_activity_get_cancellable (io_activity);
-
- if (cancellable != NULL)
- g_cancellable_cancel (cancellable);
-}
-
-static void
io_activity_completed (EActivity *activity)
{
EIOActivity *io_activity;
@@ -158,7 +123,6 @@ e_io_activity_class_init (EIOActivityClass *class)
object_class->dispose = io_activity_dispose;
activity_class = E_ACTIVITY_CLASS (class);
- activity_class->cancelled = io_activity_cancelled;
activity_class->completed = io_activity_completed;
g_object_class_install_property (
@@ -171,17 +135,6 @@ e_io_activity_class_init (EIOActivityClass *class)
G_TYPE_ASYNC_RESULT,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_CANCELLABLE,
- g_param_spec_object (
- "cancellable",
- "Cancellable",
- NULL,
- G_TYPE_CANCELLABLE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
}
static void
@@ -236,36 +189,3 @@ e_io_activity_set_async_result (EIOActivity *io_activity,
g_object_notify (G_OBJECT (io_activity), "async-result");
}
-GCancellable *
-e_io_activity_get_cancellable (EIOActivity *io_activity)
-{
- g_return_val_if_fail (E_IS_IO_ACTIVITY (io_activity), NULL);
-
- return io_activity->priv->cancellable;
-}
-
-void
-e_io_activity_set_cancellable (EIOActivity *io_activity,
- GCancellable *cancellable)
-{
- g_return_if_fail (E_IS_IO_ACTIVITY (io_activity));
-
- if (cancellable != NULL) {
- g_return_if_fail (G_IS_CANCELLABLE (cancellable));
- g_object_ref (cancellable);
- }
-
- if (io_activity->priv->cancellable != NULL)
- g_object_unref (io_activity->priv->cancellable);
-
- io_activity->priv->cancellable = cancellable;
-
- g_object_freeze_notify (G_OBJECT (io_activity));
-
- e_activity_set_allow_cancel (
- E_ACTIVITY (io_activity), (cancellable != NULL));
-
- g_object_notify (G_OBJECT (io_activity), "cancellable");
-
- g_object_thaw_notify (G_OBJECT (io_activity));
-}
diff --git a/e-util/e-io-activity.h b/e-util/e-io-activity.h
index 773417472d..20a7a06082 100644
--- a/e-util/e-io-activity.h
+++ b/e-util/e-io-activity.h
@@ -66,9 +66,6 @@ EActivity * e_io_activity_new (const gchar *primary_text,
GAsyncResult * e_io_activity_get_async_result (EIOActivity *io_activity);
void e_io_activity_set_async_result (EIOActivity *io_activity,
GAsyncResult *async_result);
-GCancellable * e_io_activity_get_cancellable (EIOActivity *io_activity);
-void e_io_activity_set_cancellable (EIOActivity *io_activity,
- GCancellable *cancellable);
G_END_DECLS
diff --git a/e-util/e-timeout-activity.c b/e-util/e-timeout-activity.c
index 4ddf39f89c..b5a48f0520 100644
--- a/e-util/e-timeout-activity.c
+++ b/e-util/e-timeout-activity.c
@@ -168,7 +168,7 @@ e_timeout_activity_set_timeout (ETimeoutActivity *timeout_activity,
g_return_if_fail (E_IS_TIMEOUT_ACTIVITY (timeout_activity));
if (timeout_activity->priv->timeout_id > 0)
- e_activity_cancel (E_ACTIVITY (timeout_activity));
+ g_source_remove (timeout_activity->priv->timeout_id);
timeout_activity->priv->timeout_id = g_timeout_add_seconds (
seconds, (GSourceFunc) timeout_activity_cb, timeout_activity);
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index ce26572756..76e2629121 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -40,16 +40,8 @@
* to rework or get rid of the functions that use this. */
const gchar *shell_builtin_backend = "mail";
-static void mail_operation_status (CamelOperation *op,
- const gchar *what,
- gint pc,
- gpointer data);
-
/* background operation status stuff */
struct _MailMsgPrivate {
- /* XXX We need to keep track of the state external to the
- * pointer itself for locking/race conditions. */
- gint activity_state;
EActivity *activity;
GtkWidget *error;
gboolean cancelable;
@@ -64,6 +56,28 @@ static GCond *mail_msg_cond;
MailAsyncEvent *mail_async_event;
+static void
+mail_msg_cancelled (CamelOperation *operation,
+ gpointer user_data)
+{
+ mail_msg_cancel (GPOINTER_TO_UINT (user_data));
+}
+
+static gboolean
+mail_msg_submit (EActivity *activity)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (
+ shell, shell_builtin_backend);
+
+ e_shell_backend_add_activity (shell_backend, activity);
+
+ return FALSE;
+}
+
gpointer
mail_msg_new (MailMsgInfo *info)
{
@@ -78,14 +92,22 @@ mail_msg_new (MailMsgInfo *info)
msg->cancel = camel_operation_new ();
msg->priv = g_slice_new0 (MailMsgPrivate);
+ msg->priv->activity = e_activity_new ();
msg->priv->cancelable = TRUE;
+ e_activity_set_percent (msg->priv->activity, 0.0);
+
+ e_activity_set_cancellable (
+ msg->priv->activity,
+ G_CANCELLABLE (msg->cancel));
+
g_signal_connect (
- msg->cancel, "status",
- G_CALLBACK (mail_operation_status),
+ msg->cancel, "cancelled",
+ G_CALLBACK (mail_msg_cancelled),
GINT_TO_POINTER (msg->seq));
- g_hash_table_insert (mail_msg_active_table, GINT_TO_POINTER (msg->seq), msg);
+ g_hash_table_insert (
+ mail_msg_active_table, GINT_TO_POINTER (msg->seq), msg);
d(printf("New message %p\n", msg));
@@ -94,28 +116,6 @@ mail_msg_new (MailMsgInfo *info)
return msg;
}
-static void
-end_event_callback (CamelObject *o, EActivity *activity, gpointer error)
-{
- EShell *shell;
- EShellBackend *shell_backend;
-
- shell = e_shell_get_default ();
- shell_backend = e_shell_get_backend_by_name (
- shell, shell_builtin_backend);
-
- if (activity != NULL) {
- e_activity_complete (activity);
- g_object_unref (activity);
- }
-
- if (error != NULL) {
- activity = e_alert_activity_new_warning (error);
- e_shell_backend_add_activity (shell_backend, activity);
- g_object_unref (activity);
- }
-}
-
#ifdef MALLOC_CHECK
#include <mcheck.h>
@@ -140,11 +140,31 @@ checkmem (gpointer p)
}
#endif
-static void
+static gboolean
mail_msg_free (MailMsg *mail_msg)
{
- if (mail_msg->priv->activity != NULL)
+ EShell *shell;
+ EShellBackend *shell_backend;
+
+ /* This is an idle callback. */
+
+ shell = e_shell_get_default ();
+ shell_backend = e_shell_get_backend_by_name (
+ shell, shell_builtin_backend);
+
+ g_mutex_lock (mail_msg_lock);
+
+ g_hash_table_remove (
+ mail_msg_active_table,
+ GINT_TO_POINTER (mail_msg->seq));
+ g_cond_broadcast (mail_msg_cond);
+
+ g_mutex_unlock (mail_msg_lock);
+
+ if (mail_msg->priv->activity != NULL) {
+ e_activity_complete (mail_msg->priv->activity);
g_object_unref (mail_msg->priv->activity);
+ }
if (mail_msg->cancel != NULL)
g_object_unref (mail_msg->cancel);
@@ -152,8 +172,20 @@ mail_msg_free (MailMsg *mail_msg)
if (mail_msg->error != NULL)
g_error_free (mail_msg->error);
+ if (mail_msg->priv->error != NULL) {
+ EActivity *activity;
+ GtkWidget *widget;
+
+ widget = mail_msg->priv->error;
+ activity = e_alert_activity_new_warning (widget);
+ e_shell_backend_add_activity (shell_backend, activity);
+ g_object_unref (activity);
+ }
+
g_slice_free (MailMsgPrivate, mail_msg->priv);
g_slice_free1 (mail_msg->info->size, mail_msg);
+
+ return FALSE;
}
gpointer
@@ -172,8 +204,6 @@ void
mail_msg_unref (gpointer msg)
{
MailMsg *mail_msg = msg;
- EActivity *activity = NULL;
- GtkWidget *error = NULL;
g_return_if_fail (mail_msg != NULL);
g_return_if_fail (mail_msg->ref_count > 0);
@@ -191,36 +221,9 @@ mail_msg_unref (gpointer msg)
if (mail_msg->info->free)
mail_msg->info->free (mail_msg);
- g_mutex_lock (mail_msg_lock);
-
- g_hash_table_remove (
- mail_msg_active_table, GINT_TO_POINTER (mail_msg->seq));
- g_cond_broadcast (mail_msg_cond);
-
- /* We need to make sure we dont lose a reference here YUCK YUCK */
- /* This is tightly integrated with the code in do_op_status,
- as it closely relates to the CamelOperation setup in msg_new () above */
- if (mail_msg->priv->activity_state == 1) {
- /* tell the other to free it itself */
- mail_msg->priv->activity_state = 3;
- g_mutex_unlock (mail_msg_lock);
- return;
- } else {
- activity = mail_msg->priv->activity;
- if (activity != NULL)
- g_object_ref (activity);
- error = mail_msg->priv->error;
- }
-
- g_mutex_unlock (mail_msg_lock);
-
- mail_msg_free (mail_msg);
-
- if (activity != NULL)
- mail_async_event_emit (
- mail_async_event, MAIL_ASYNC_GUI,
- (MailAsyncFunc) end_event_callback,
- NULL, activity, error);
+ /* Destroy the message from an idle callback
+ * so we know we're in the main loop thread. */
+ g_idle_add ((GSourceFunc) mail_msg_free, mail_msg);
}
/* hash table of ops->dialogue of active errors */
@@ -442,6 +445,11 @@ mail_msg_idle_cb (void)
G_UNLOCK (idle_source_id);
/* check the main loop queue */
while ((msg = g_async_queue_try_pop (main_loop_queue)) != NULL) {
+ g_idle_add_full (
+ G_PRIORITY_DEFAULT,
+ (GSourceFunc) mail_msg_submit,
+ g_object_ref (msg->priv->activity),
+ (GDestroyNotify) g_object_unref);
if (msg->info->exec != NULL)
msg->info->exec (msg);
if (msg->info->done != NULL)
@@ -469,6 +477,12 @@ mail_msg_proxy (MailMsg *msg)
g_free (text);
}
+ g_idle_add_full (
+ G_PRIORITY_DEFAULT,
+ (GSourceFunc) mail_msg_submit,
+ g_object_ref (msg->priv->activity),
+ (GDestroyNotify) g_object_unref);
+
if (msg->info->exec != NULL)
msg->info->exec (msg);
@@ -840,154 +854,6 @@ mail_call_main (mail_call_t type, MailMainFunc func, ...)
return ret;
}
-/* ******************************************************************************** */
-
-struct _op_status_msg {
- MailMsg base;
-
- CamelOperation *op;
- gchar *what;
- gint pc;
- gpointer data;
-};
-
-static void
-op_cancelled_cb (EActivity *activity,
- gpointer user_data)
-{
- mail_msg_cancel (GPOINTER_TO_UINT (user_data));
-}
-
-static void
-op_status_exec (struct _op_status_msg *m)
-{
- EShell *shell;
- EShellBackend *shell_backend;
- MailMsg *msg;
- MailMsgPrivate *data;
- gchar *out, *p, *o, c;
- gint pc;
-
- g_return_if_fail (mail_in_main_thread ());
-
- shell = e_shell_get_default ();
- shell_backend = e_shell_get_backend_by_name (
- shell, shell_builtin_backend);
-
- g_mutex_lock (mail_msg_lock);
-
- msg = g_hash_table_lookup (mail_msg_active_table, m->data);
-
- if (msg == NULL) {
- g_mutex_unlock (mail_msg_lock);
- return;
- }
-
- data = msg->priv;
-
- out = g_alloca (strlen (m->what) * 2 + 1);
- o = out;
- p = m->what;
- while ((c = *p++)) {
- if (c == '%')
- *o++ = '%';
- *o++ = c;
- }
- *o = 0;
-
- pc = m->pc;
-
- if (data->activity == NULL) {
- gchar *what;
-
- /* its being created/removed? well leave it be */
- if (data->activity_state == 1 || data->activity_state == 3) {
- g_mutex_unlock (mail_msg_lock);
- return;
- } else {
- data->activity_state = 1;
-
- g_mutex_unlock (mail_msg_lock);
- if (msg->info->desc)
- what = msg->info->desc (msg);
- else if (m->what)
- what = g_strdup (m->what);
- /* uncommenting because message is not very useful for a user, see bug 271734*/
- else {
- what = g_strdup("");
- }
-
- data->activity = e_activity_new (what);
- e_activity_set_allow_cancel (data->activity, TRUE);
- e_activity_set_percent (data->activity, 0.0);
- e_shell_backend_add_activity (shell_backend, data->activity);
-
- g_signal_connect (
- data->activity, "cancelled",
- G_CALLBACK (op_cancelled_cb),
- GUINT_TO_POINTER (msg->seq));
-
- g_free (what);
- g_mutex_lock (mail_msg_lock);
- if (data->activity_state == 3) {
- EActivity *activity;
-
- activity = g_object_ref (data->activity);
-
- g_mutex_unlock (mail_msg_lock);
- mail_msg_free (msg);
-
- if (activity != 0)
- mail_async_event_emit (
- mail_async_event, MAIL_ASYNC_GUI, (MailAsyncFunc) end_event_callback,
- NULL, activity, NULL);
- } else {
- data->activity_state = 2;
- g_mutex_unlock (mail_msg_lock);
- }
- return;
- }
- } else if (data->activity != NULL) {
- e_activity_set_primary_text (data->activity, out);
- e_activity_set_percent (data->activity, pc);
- g_mutex_unlock (mail_msg_lock);
- } else {
- g_mutex_unlock (mail_msg_lock);
- }
-}
-
-static void
-op_status_free (struct _op_status_msg *m)
-{
- g_free (m->what);
-}
-
-static MailMsgInfo op_status_info = {
- sizeof (struct _op_status_msg),
- (MailMsgDescFunc) NULL,
- (MailMsgExecFunc) op_status_exec,
- (MailMsgDoneFunc) NULL,
- (MailMsgFreeFunc) op_status_free
-};
-
-static void
-mail_operation_status (CamelOperation *op,
- const gchar *what,
- gint pc,
- gpointer data)
-{
- struct _op_status_msg *m;
-
- d(printf("got operation statys: %s %d%%\n", what, pc));
-
- m = mail_msg_new (&op_status_info);
- m->op = op;
- m->what = g_strdup (what);
- m->pc = pc;
- m->data = data;
- mail_msg_main_loop_push (m);
-}
-
void
mail_mt_set_backend (gchar *backend)
{
diff --git a/modules/calendar/e-cal-shell-view-memopad.c b/modules/calendar/e-cal-shell-view-memopad.c
index 267f8145f6..7fdf356304 100644
--- a/modules/calendar/e-cal-shell-view-memopad.c
+++ b/modules/calendar/e-cal-shell-view-memopad.c
@@ -435,8 +435,9 @@ e_cal_shell_view_memopad_set_status_message (ECalShellView *cal_shell_view,
}
} else if (activity == NULL) {
- activity = e_activity_new (status_message);
+ activity = e_activity_new ();
e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
e_shell_backend_add_activity (shell_backend, activity);
} else {
diff --git a/modules/calendar/e-cal-shell-view-private.c b/modules/calendar/e-cal-shell-view-private.c
index a02888db8e..c5a9f22f03 100644
--- a/modules/calendar/e-cal-shell-view-private.c
+++ b/modules/calendar/e-cal-shell-view-private.c
@@ -810,8 +810,9 @@ e_cal_shell_view_set_status_message (ECalShellView *cal_shell_view,
activity = NULL;
}
} else if (activity == NULL) {
- activity = e_activity_new (status_message);
+ activity = e_activity_new ();
e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
e_shell_backend_add_activity (shell_backend, activity);
} else {
e_activity_set_percent (activity, percent);
diff --git a/modules/calendar/e-cal-shell-view-taskpad.c b/modules/calendar/e-cal-shell-view-taskpad.c
index c7269bcfd1..a00e630afd 100644
--- a/modules/calendar/e-cal-shell-view-taskpad.c
+++ b/modules/calendar/e-cal-shell-view-taskpad.c
@@ -562,8 +562,9 @@ e_cal_shell_view_taskpad_set_status_message (ECalShellView *cal_shell_view,
}
} else if (activity == NULL) {
- activity = e_activity_new (status_message);
+ activity = e_activity_new ();
e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
e_shell_backend_add_activity (shell_backend, activity);
} else {
diff --git a/modules/calendar/e-memo-shell-view-private.c b/modules/calendar/e-memo-shell-view-private.c
index 061e3c0170..a33296daf5 100644
--- a/modules/calendar/e-memo-shell-view-private.c
+++ b/modules/calendar/e-memo-shell-view-private.c
@@ -375,8 +375,9 @@ e_memo_shell_view_set_status_message (EMemoShellView *memo_shell_view,
}
} else if (activity == NULL) {
- activity = e_activity_new (status_message);
+ activity = e_activity_new ();
e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
e_shell_backend_add_activity (shell_backend, activity);
} else {
diff --git a/modules/calendar/e-task-shell-view-private.c b/modules/calendar/e-task-shell-view-private.c
index e5cf75711c..5e1b352ecd 100644
--- a/modules/calendar/e-task-shell-view-private.c
+++ b/modules/calendar/e-task-shell-view-private.c
@@ -524,8 +524,9 @@ e_task_shell_view_set_status_message (ETaskShellView *task_shell_view,
}
} else if (activity == NULL) {
- activity = e_activity_new (status_message);
+ activity = e_activity_new ();
e_activity_set_percent (activity, percent);
+ e_activity_set_primary_text (activity, status_message);
e_shell_backend_add_activity (shell_backend, activity);
} else {
diff --git a/shell/e-shell-taskbar.c b/shell/e-shell-taskbar.c
index a82d3d6246..47f900ae3e 100644
--- a/shell/e-shell-taskbar.c
+++ b/shell/e-shell-taskbar.c
@@ -96,12 +96,13 @@ shell_taskbar_activity_add (EShellTaskbar *shell_taskbar,
GtkBox *box;
GtkWidget *proxy;
+ /* Proxy widgets manage their own visibility.
+ * Don't call gtk_widget_show() on it here. */
proxy = e_activity_proxy_new (activity);
box = GTK_BOX (shell_taskbar->priv->hbox);
gtk_box_pack_start (box, proxy, TRUE, TRUE, 0);
gtk_box_reorder_child (box, proxy, 0);
gtk_widget_show (GTK_WIDGET (box));
- gtk_widget_show (proxy);
g_hash_table_insert (
shell_taskbar->priv->proxy_table,
@@ -176,13 +177,14 @@ shell_taskbar_get_property (GObject *object,
}
static gboolean
-disconnect_remove (EActivity *activity,
- EActivityProxy *proxy,
- EShellTaskbar *shell_taskbar)
+disconnect_remove (EActivity *activity,
+ EActivityProxy *proxy,
+ EShellTaskbar *shell_taskbar)
{
- g_signal_handlers_disconnect_matched
- (activity, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, shell_taskbar);
+ g_signal_handlers_disconnect_matched (
+ activity, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, shell_taskbar);
+
return TRUE;
}
@@ -217,9 +219,8 @@ shell_taskbar_dispose (GObject *object)
priv->hbox = NULL;
}
- g_hash_table_foreach_remove (priv->proxy_table,
- (GHRFunc) disconnect_remove,
- object);
+ g_hash_table_foreach_remove (
+ priv->proxy_table, (GHRFunc) disconnect_remove, object);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_shell_taskbar_parent_class)->dispose (object);
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 93832ec7fe..28abe028dc 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -240,8 +240,11 @@ shell_prepare_for_offline (EShell *shell)
if (shell->priv->preparing_for_line_change != NULL)
return;
- shell->priv->preparing_for_line_change =
- e_activity_new (_("Preparing to go offline..."));
+ shell->priv->preparing_for_line_change = e_activity_new ();
+
+ e_activity_set_primary_text (
+ shell->priv->preparing_for_line_change,
+ _("Preparing to go offline..."));
g_object_add_toggle_ref (
G_OBJECT (shell->priv->preparing_for_line_change),
@@ -290,8 +293,11 @@ shell_prepare_for_online (EShell *shell)
if (shell->priv->preparing_for_line_change != NULL)
return;
- shell->priv->preparing_for_line_change =
- e_activity_new (_("Preparing to go online..."));
+ shell->priv->preparing_for_line_change = e_activity_new ();
+
+ e_activity_set_primary_text (
+ shell->priv->preparing_for_line_change,
+ _("Preparing to go online..."));
g_object_add_toggle_ref (
G_OBJECT (shell->priv->preparing_for_line_change),
@@ -349,8 +355,11 @@ shell_prepare_for_quit (EShell *shell)
if (shell->priv->preparing_for_quit != NULL)
return;
- shell->priv->preparing_for_quit =
- e_activity_new (_("Preparing to quit..."));
+ shell->priv->preparing_for_quit = e_activity_new ();
+
+ e_activity_set_primary_text (
+ shell->priv->preparing_for_quit,
+ _("Preparing to quit..."));
g_object_add_toggle_ref (
G_OBJECT (shell->priv->preparing_for_quit),
diff --git a/widgets/misc/e-activity-proxy.c b/widgets/misc/e-activity-proxy.c
index 8e20e67d5d..e96f18ed63 100644
--- a/widgets/misc/e-activity-proxy.c
+++ b/widgets/misc/e-activity-proxy.c
@@ -47,19 +47,33 @@ G_DEFINE_TYPE (
GTK_TYPE_EVENT_BOX)
static void
+activity_proxy_cancel (EActivity *activity)
+{
+ GCancellable *cancellable;
+
+ /* We shouldn't get here unless the EActivity has a GCancellable,
+ * since otherwise the cancel button is invisible and unclickable.
+ * g_cancellable_cancel() will emit a warning if this breaks. */
+
+ cancellable = e_activity_get_cancellable (activity);
+ g_cancellable_cancel (cancellable);
+}
+
+static void
activity_proxy_update (EActivityProxy *proxy)
{
- EActivity *activity = proxy->priv->activity;
+ EActivity *activity;
+ GCancellable *cancellable;
const gchar *icon_name;
- gboolean allow_cancel;
gboolean cancelled;
gboolean clickable;
gboolean completed;
gboolean sensitive;
gchar *description;
- allow_cancel = e_activity_get_allow_cancel (activity);
- cancelled = e_activity_is_cancelled (activity);
+ activity = proxy->priv->activity;
+ cancellable = e_activity_get_cancellable (activity);
+ cancelled = g_cancellable_is_cancelled (cancellable);
clickable = e_activity_get_clickable (activity);
completed = e_activity_is_completed (activity);
icon_name = e_activity_get_icon_name (activity);
@@ -67,6 +81,7 @@ activity_proxy_update (EActivityProxy *proxy)
description = e_activity_describe (activity);
gtk_widget_set_tooltip_text (GTK_WIDGET (proxy), description);
gtk_label_set_text (GTK_LABEL (proxy->priv->label), description);
+ gtk_widget_set_visible (GTK_WIDGET (proxy), (description != NULL));
g_free (description);
/* Note, an activity requires an icon name in order to
@@ -93,7 +108,7 @@ activity_proxy_update (EActivityProxy *proxy)
gtk_widget_hide (proxy->priv->image);
}
- if (allow_cancel)
+ if (cancellable != NULL)
gtk_widget_show (proxy->priv->cancel);
else
gtk_widget_hide (proxy->priv->cancel);
@@ -202,7 +217,7 @@ activity_proxy_constructed (GObject *object)
g_signal_connect_swapped (
proxy->priv->cancel, "clicked",
- G_CALLBACK (e_activity_cancel), proxy->priv->activity);
+ G_CALLBACK (activity_proxy_cancel), proxy->priv->activity);
g_signal_connect_swapped (
proxy->priv->activity, "cancelled",