示例#1
0
/**
 * e_source_util_remove:
 * @source: the #ESource to be removed
 * @alert_sink: an #EAlertSink
 *
 * Requests the D-Bus service to delete the key files for @source and all of
 * its descendants and broadcast their removal to all clients.  If an error
 * occurs, an #EAlert will be posted to @alert_sink.
 *
 * This function does not block.  The returned #EActivity can either be
 * ignored or passed to something that can display activity status to the
 * user, such as e_shell_backend_add_activity().
 *
 * Returns: an #EActivity to track the operation
 **/
EActivity *
e_source_util_remove (ESource *source,
                      EAlertSink *alert_sink)
{
	AsyncContext *async_context;
	GCancellable *cancellable;

	g_return_val_if_fail (E_IS_SOURCE (source), NULL);
	g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);

	cancellable = g_cancellable_new ();

	async_context = g_slice_new0 (AsyncContext);
	async_context->activity = e_activity_new ();

	e_activity_set_alert_sink (async_context->activity, alert_sink);
	e_activity_set_cancellable (async_context->activity, cancellable);

	e_source_remove (
		source, cancellable,
		source_util_remove_cb,
		async_context);

	g_object_unref (cancellable);

	return async_context->activity;
}
示例#2
0
/**
 * e_shell_utils_find_alternate_alert_sink:
 * @widget: a #GtkWidget for which to do the search
 *
 * Search an alternate #EAlertSink in the widget hierarchy up-wards
 * from the @widget (skipping the @widget itself).
 *
 * Returns: (nullable) (transfer none): an alert sink, different than @widget,
 *    or %NULL, when none found
 *
 * Since: 3.24
 **/
EAlertSink *
e_shell_utils_find_alternate_alert_sink (GtkWidget *widget)
{
    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);

    while (widget = gtk_widget_get_parent (widget), widget) {
        if (E_IS_ALERT_SINK (widget))
            return E_ALERT_SINK (widget);
    }

    return NULL;
}
示例#3
0
/**
 * e_alert_sink_submit_alert:
 * @alert_sink: an #EAlertSink
 * @alert: an #EAlert
 *
 * This function is a place to pass #EAlert objects.  Beyond that it has no
 * well-defined behavior.  It's up to the widget implementing the #EAlertSink
 * interface to decide what to do with them.
 **/
void
e_alert_sink_submit_alert (EAlertSink *alert_sink,
                           EAlert *alert)
{
	EAlertSinkInterface *iface;

	g_return_if_fail (E_IS_ALERT_SINK (alert_sink));
	g_return_if_fail (E_IS_ALERT (alert));

	iface = E_ALERT_SINK_GET_INTERFACE (alert_sink);
	g_return_if_fail (iface->submit_alert != NULL);

	iface->submit_alert (alert_sink, alert);
}
示例#4
0
/**
 * e_alert_sink_submit_thread_job:
 * @alert_sink: an #EAlertSink instance
 * @description: user-friendly description of the job, to be shown in UI
 * @alert_ident: in case of an error, this alert identificator is used
 *    for EAlert construction
 * @alert_arg_0: (allow-none): in case of an error, use this string as
 *    the first argument to the EAlert construction; the second argument
 *    is the actual error message; can be #NULL, in which case only
 *    the error message is passed to the EAlert construction
 * @func: function to be run in a dedicated thread
 * @user_data: (allow-none): custom data passed into @func; can be #NULL
 * @free_user_data: (allow-none): function to be called on @user_data,
 *   when the job is over; can be #NULL
 *
 * Runs the @func in a dedicated thread. Any error is propagated to UI.
 * The cancellable passed into the @func is a #CamelOperation, thus
 * the caller can overwrite progress and description message on it.
 *
 * Returns: (transfer full): Newly created #EActivity on success.
 *   The caller is responsible to g_object_unref() it when done with it.
 *
 * Note: The @free_user_data, if set, is called in the main thread.
 *
 * Note: This function should be called only from the main thread.
 *
 * Since: 3.16
 **/
EActivity *
e_alert_sink_submit_thread_job (EAlertSink *alert_sink,
				const gchar *description,
				const gchar *alert_ident,
				const gchar *alert_arg_0,
				EAlertSinkThreadJobFunc func,
				gpointer user_data,
				GDestroyNotify free_user_data)
{
	EActivity *activity;
	GCancellable *cancellable;
	EAlertSinkThreadJobData *job_data;
	GThread *thread;

	g_return_val_if_fail (E_IS_ALERT_SINK (alert_sink), NULL);
	g_return_val_if_fail (description != NULL, NULL);
	g_return_val_if_fail (func != NULL, NULL);

	activity = e_activity_new ();
	cancellable = camel_operation_new ();

	e_activity_set_alert_sink (activity, alert_sink);
	e_activity_set_cancellable (activity, cancellable);
	e_activity_set_text (activity, description);

	camel_operation_push_message (cancellable, "%s", description);

	job_data = g_new0 (EAlertSinkThreadJobData, 1);
	job_data->activity = g_object_ref (activity);
	job_data->alert_ident = g_strdup (alert_ident);
	job_data->alert_arg_0 = g_strdup (alert_arg_0);
	job_data->error = NULL;
	job_data->func = func;
	job_data->user_data = user_data;
	job_data->free_user_data = free_user_data;

	thread = g_thread_try_new (G_STRFUNC, e_alert_sink_thread_job, job_data, &job_data->error);

	g_object_unref (cancellable);

	if (thread) {
		g_thread_unref (thread);
	} else {
		g_prefix_error (&job_data->error, _("Failed to create a thread: "));
		g_timeout_add (1, e_alert_sink_thread_job_done_cb, job_data);
	}

	return activity;
}
示例#5
0
void
mail_filter_delete_folder (CamelStore *store,
                           const gchar *folder_name,
                           EAlertSink *alert_sink)
{
	CamelSession *session;
	EMFilterContext *fc;
	const gchar *config_dir;
	gchar *user, *system;
	GList *deleted;
	gchar *uri;

	g_return_if_fail (CAMEL_IS_STORE (store));
	g_return_if_fail (folder_name != NULL);
	g_return_if_fail (E_IS_ALERT_SINK (alert_sink));

	session = camel_service_ref_session (CAMEL_SERVICE (store));

	uri = e_mail_folder_uri_build (store, folder_name);

	fc = em_filter_context_new (E_MAIL_SESSION (session));
	config_dir = mail_session_get_config_dir ();
	user = g_build_filename (config_dir, "filters.xml", NULL);
	system = g_build_filename (EVOLUTION_PRIVDATADIR, "filtertypes.xml", NULL);
	e_rule_context_load ((ERuleContext *) fc, system, user);
	g_free (system);

	deleted = e_rule_context_delete_uri (
		(ERuleContext *) fc, uri, g_str_equal);
	if (deleted) {
		GString *s;
		guint s_count;
		gchar *info;
		GList *l;

		s = g_string_new ("");
		s_count = 0;
		for (l = deleted; l; l = l->next) {
			const gchar *name = (const gchar *) l->data;

			if (s_count == 0) {
				g_string_append (s, name);
			} else {
				if (s_count == 1) {
					g_string_prepend (s, "    ");
					g_string_append (s, "\n");
				}
				g_string_append_printf (s, "    %s\n", name);
			}
			s_count++;
		}

		info = g_strdup_printf (ngettext (
			/* Translators: The first %s is name of the affected
			 * filter rule(s), the second %s is URI of the removed
			 * folder. For more than one filter rule is each of
			 * them on a separate line, with four spaces in front
			 * of its name, without quotes. */
			"The filter rule \"%s\" has been modified to account "
			"for the deleted folder\n\"%s\".",
			"The following filter rules\n%s have been modified "
			"to account for the deleted folder\n\"%s\".",
			s_count), s->str, folder_name);
		e_alert_submit (
			alert_sink, "mail:filter-updated", info, NULL);
		g_string_free (s, TRUE);
		g_free (info);

		if (e_rule_context_save ((ERuleContext *) fc, user) == -1)
			g_warning ("Could not write out changed filter rules\n");
		e_rule_context_free_uri_list ((ERuleContext *) fc, deleted);
	}

	g_free (user);
	g_object_unref (fc);
	g_free (uri);

	g_object_unref (session);
}