/** * 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; }
/** * 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; }
/** * 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); }
/** * 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; }
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); }