No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-signature-script-dialog.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-signature-script-dialog.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-signature-script-dialog.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 */
18
19 #include "e-mail-signature-script-dialog.h"
20
21 #include <config.h>
22 #include <glib/gi18n-lib.h>
23
24 #define E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE(obj) \
25 (G_TYPE_INSTANCE_GET_PRIVATE \
26 ((obj), E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG, \
27 EMailSignatureScriptDialogPrivate))
28
29 typedef struct _AsyncContext AsyncContext;
30
31 struct _EMailSignatureScriptDialogPrivate {
32 ESourceRegistry *registry;
33 ESource *source;
34
35 GtkWidget *entry; /* not referenced */
36 GtkWidget *file_chooser; /* not referenced */
37 GtkWidget *alert; /* not referenced */
38
39 gchar *symlink_target;
40 };
41
42 struct _AsyncContext {
43 ESource *source;
44 GCancellable *cancellable;
45 gchar *symlink_target;
46 };
47
48 enum {
49 PROP_0,
50 PROP_REGISTRY,
51 PROP_SOURCE,
52 PROP_SYMLINK_TARGET
53 };
54
55 G_DEFINE_TYPE (
56 EMailSignatureScriptDialog,
57 e_mail_signature_script_dialog,
58 GTK_TYPE_DIALOG)
59
60 static void
61 async_context_free (AsyncContext *async_context)
62 {
63 if (async_context->source != NULL)
64 g_object_unref (async_context->source);
65
66 if (async_context->cancellable != NULL)
67 g_object_unref (async_context->cancellable);
68
69 g_free (async_context->symlink_target);
70
71 g_slice_free (AsyncContext, async_context);
72 }
73
74 static gboolean
75 mail_signature_script_dialog_filter_cb (const GtkFileFilterInfo *filter_info)
76 {
77 return g_file_test (filter_info->filename, G_FILE_TEST_IS_EXECUTABLE);
78 }
79
80 static void
81 mail_signature_script_dialog_update_status (EMailSignatureScriptDialog *dialog)
82 {
83 ESource *source;
84 const gchar *display_name;
85 const gchar *symlink_target;
86 gboolean show_alert;
87 gboolean sensitive;
88
89 source = e_mail_signature_script_dialog_get_source (dialog);
90
91 display_name = e_source_get_display_name (source);
92 sensitive = (display_name != NULL && *display_name != '\0');
93
94 symlink_target =
95 e_mail_signature_script_dialog_get_symlink_target (dialog);
96
97 if (symlink_target != NULL) {
98 gboolean executable;
99
100 executable = g_file_test (
101 symlink_target, G_FILE_TEST_IS_EXECUTABLE);
102
103 show_alert = !executable;
104 sensitive &= executable;
105 } else {
106 sensitive = FALSE;
107 show_alert = FALSE;
108 }
109
110 if (show_alert)
111 gtk_widget_show (dialog->priv->alert);
112 else
113 gtk_widget_hide (dialog->priv->alert);
114
115 gtk_dialog_set_response_sensitive (
116 GTK_DIALOG (dialog), GTK_RESPONSE_OK, sensitive);
117 }
118
119 static void
120 mail_signature_script_dialog_file_set_cb (GtkFileChooserButton *button,
121 EMailSignatureScriptDialog *dialog)
122 {
123 ESource *source;
124 ESourceMailSignature *extension;
125 GtkFileChooser *file_chooser;
126 const gchar *extension_name;
127 gchar *filename;
128
129 file_chooser = GTK_FILE_CHOOSER (button);
130 filename = gtk_file_chooser_get_filename (file_chooser);
131
132 g_free (dialog->priv->symlink_target);
133 dialog->priv->symlink_target = filename; /* takes ownership */
134
135 /* Invalidate the saved MIME type. */
136 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
137 source = e_mail_signature_script_dialog_get_source (dialog);
138 extension = e_source_get_extension (source, extension_name);
139 e_source_mail_signature_set_mime_type (extension, NULL);
140
141 g_object_notify (G_OBJECT (dialog), "symlink-target");
142
143 mail_signature_script_dialog_update_status (dialog);
144 }
145
146 static void
147 mail_signature_script_dialog_query_cb (GFile *file,
148 GAsyncResult *result,
149 EMailSignatureScriptDialog *dialog)
150 {
151 GFileInfo *file_info;
152 const gchar *symlink_target;
153 GError *error = NULL;
154
155 file_info = g_file_query_info_finish (file, result, &error);
156
157 /* Ignore cancellations. */
158 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
159 g_warn_if_fail (file_info == NULL);
160 g_object_unref (dialog);
161 g_error_free (error);
162 return;
163
164 } else if (error != NULL) {
165 g_warn_if_fail (file_info == NULL);
166 g_warning ("%s", error->message);
167 g_object_unref (dialog);
168 g_error_free (error);
169 return;
170 }
171
172 g_return_if_fail (G_IS_FILE_INFO (file_info));
173
174 symlink_target = g_file_info_get_symlink_target (file_info);
175
176 e_mail_signature_script_dialog_set_symlink_target (
177 dialog, symlink_target);
178
179 g_object_unref (file_info);
180 g_object_unref (dialog);
181 }
182
183 static void
184 mail_signature_script_dialog_set_registry (EMailSignatureScriptDialog *dialog,
185 ESourceRegistry *registry)
186 {
187 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
188 g_return_if_fail (dialog->priv->registry == NULL);
189
190 dialog->priv->registry = g_object_ref (registry);
191 }
192
193 static void
194 mail_signature_script_dialog_set_source (EMailSignatureScriptDialog *dialog,
195 ESource *source)
196 {
197 GDBusObject *dbus_object = NULL;
198 const gchar *extension_name;
199 GError *error = NULL;
200
201 g_return_if_fail (source == NULL || E_IS_SOURCE (source));
202 g_return_if_fail (dialog->priv->source == NULL);
203
204 if (source != NULL)
205 dbus_object = e_source_ref_dbus_object (source);
206
207 /* Clone the source so we can make changes to it freely. */
208 dialog->priv->source = e_source_new (dbus_object, NULL, &error);
209
210 /* This should rarely fail. If the file was loaded successfully
211 * once then it should load successfully here as well, unless an
212 * I/O error occurs. */
213 if (error != NULL) {
214 g_warning ("%s: %s", G_STRFUNC, error->message);
215 g_error_free (error);
216 }
217
218 /* Make sure the source has a mail signature extension. */
219 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
220 e_source_get_extension (dialog->priv->source, extension_name);
221
222 /* If we're editing an existing signature, query the symbolic
223 * link target of the signature file so we can initialize the
224 * file chooser button. Note: The asynchronous callback will
225 * run after the dialog initialization is complete. */
226 if (dbus_object != NULL) {
227 ESourceMailSignature *extension;
228 const gchar *extension_name;
229 GFile *file;
230
231 extension_name = E_SOURCE_EXTENSION_MAIL_SIGNATURE;
232 extension = e_source_get_extension (source, extension_name);
233 file = e_source_mail_signature_get_file (extension);
234
235 g_file_query_info_async (
236 file, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET,
237 G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
238 NULL, (GAsyncReadyCallback)
239 mail_signature_script_dialog_query_cb,
240 g_object_ref (dialog));
241
242 g_object_unref (dbus_object);
243 }
244 }
245
246 static void
247 mail_signature_script_dialog_set_property (GObject *object,
248 guint property_id,
249 const GValue *value,
250 GParamSpec *pspec)
251 {
252 switch (property_id) {
253 case PROP_REGISTRY:
254 mail_signature_script_dialog_set_registry (
255 E_MAIL_SIGNATURE_SCRIPT_DIALOG (object),
256 g_value_get_object (value));
257 return;
258
259 case PROP_SOURCE:
260 mail_signature_script_dialog_set_source (
261 E_MAIL_SIGNATURE_SCRIPT_DIALOG (object),
262 g_value_get_object (value));
263 return;
264
265 case PROP_SYMLINK_TARGET:
266 e_mail_signature_script_dialog_set_symlink_target (
267 E_MAIL_SIGNATURE_SCRIPT_DIALOG (object),
268 g_value_get_string (value));
269 return;
270 }
271
272 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
273 }
274
275 static void
276 mail_signature_script_dialog_get_property (GObject *object,
277 guint property_id,
278 GValue *value,
279 GParamSpec *pspec)
280 {
281 switch (property_id) {
282 case PROP_REGISTRY:
283 g_value_set_object (
284 value,
285 e_mail_signature_script_dialog_get_registry (
286 E_MAIL_SIGNATURE_SCRIPT_DIALOG (object)));
287 return;
288
289 case PROP_SOURCE:
290 g_value_set_object (
291 value,
292 e_mail_signature_script_dialog_get_source (
293 E_MAIL_SIGNATURE_SCRIPT_DIALOG (object)));
294 return;
295
296 case PROP_SYMLINK_TARGET:
297 g_value_set_string (
298 value,
299 e_mail_signature_script_dialog_get_symlink_target (
300 E_MAIL_SIGNATURE_SCRIPT_DIALOG (object)));
301 return;
302 }
303
304 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
305 }
306
307 static void
308 mail_signature_script_dialog_dispose (GObject *object)
309 {
310 EMailSignatureScriptDialogPrivate *priv;
311
312 priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object);
313
314 if (priv->registry != NULL) {
315 g_object_unref (priv->registry);
316 priv->registry = NULL;
317 }
318
319 if (priv->source != NULL) {
320 g_object_unref (priv->source);
321 priv->source = NULL;
322 }
323
324 /* Chain up to parent's dispose() method. */
325 G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)->
326 dispose (object);
327 }
328
329 static void
330 mail_signature_script_dialog_finalize (GObject *object)
331 {
332 EMailSignatureScriptDialogPrivate *priv;
333
334 priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object);
335
336 g_free (priv->symlink_target);
337
338 /* Chain up to parent's finalize() method. */
339 G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)->
340 finalize (object);
341 }
342
343 static void
344 mail_signature_script_dialog_constructed (GObject *object)
345 {
346 EMailSignatureScriptDialog *dialog;
347 GtkFileFilter *filter;
348 GtkWidget *container;
349 GtkWidget *widget;
350 ESource *source;
351 const gchar *display_name;
352 gchar *markup;
353
354 /* Chain up to parent's constructed() method. */
355 G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)->
356 constructed (object);
357
358 dialog = E_MAIL_SIGNATURE_SCRIPT_DIALOG (object);
359
360 source = e_mail_signature_script_dialog_get_source (dialog);
361 display_name = e_source_get_display_name (source);
362
363 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
364
365 gtk_dialog_add_button (
366 GTK_DIALOG (dialog),
367 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
368
369 gtk_dialog_add_button (
370 GTK_DIALOG (dialog),
371 GTK_STOCK_SAVE, GTK_RESPONSE_OK);
372
373 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
374
375 container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
376
377 widget = gtk_table_new (4, 2, FALSE);
378 gtk_table_set_col_spacings (GTK_TABLE (widget), 6);
379 gtk_table_set_row_spacings (GTK_TABLE (widget), 6);
380 gtk_table_set_row_spacing (GTK_TABLE (widget), 0, 12);
381 gtk_container_set_border_width (GTK_CONTAINER (widget), 5);
382 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
383 gtk_widget_show (widget);
384
385 container = widget;
386
387 widget = gtk_image_new_from_stock (
388 GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_DIALOG);
389 gtk_table_attach (
390 GTK_TABLE (container), widget,
391 0, 1, 0, 1, 0, 0, 0, 0);
392 gtk_widget_show (widget);
393
394 widget = gtk_label_new (_(
395 "The output of this script will be used as your\n"
396 "signature. The name you specify will be used\n"
397 "for display purposes only."));
398 gtk_table_attach (
399 GTK_TABLE (container), widget,
400 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
401 gtk_widget_show (widget);
402
403 widget = gtk_entry_new ();
404 gtk_entry_set_text (GTK_ENTRY (widget), display_name);
405 gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
406 gtk_table_attach (
407 GTK_TABLE (container), widget,
408 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
409 dialog->priv->entry = widget; /* not referenced */
410 gtk_widget_show (widget);
411
412 g_object_bind_property (
413 widget, "text",
414 source, "display-name",
415 G_BINDING_DEFAULT);
416
417 widget = gtk_label_new_with_mnemonic (_("_Name:"));
418 gtk_label_set_mnemonic_widget (
419 GTK_LABEL (widget), dialog->priv->entry);
420 gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
421 gtk_table_attach (
422 GTK_TABLE (container), widget,
423 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
424 gtk_widget_show (widget);
425
426 widget = gtk_file_chooser_button_new (
427 NULL, GTK_FILE_CHOOSER_ACTION_OPEN);
428 gtk_table_attach (
429 GTK_TABLE (container), widget,
430 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
431 dialog->priv->file_chooser = widget; /* not referenced */
432 gtk_widget_show (widget);
433
434 /* Restrict file selection to executable files. */
435 filter = gtk_file_filter_new ();
436 gtk_file_filter_add_custom (
437 filter, GTK_FILE_FILTER_FILENAME,
438 (GtkFileFilterFunc) mail_signature_script_dialog_filter_cb,
439 NULL, NULL);
440 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), filter);
441
442 /* We create symbolic links to script files from the "signatures"
443 * directory, so restrict the selection to local files only. */
444 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
445
446 widget = gtk_label_new_with_mnemonic (_("S_cript:"));
447 gtk_label_set_mnemonic_widget (
448 GTK_LABEL (widget), dialog->priv->file_chooser);
449 gtk_table_attach (
450 GTK_TABLE (container), widget,
451 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
452 gtk_widget_show (widget);
453
454 /* This is just a placeholder. */
455 widget = gtk_label_new (NULL);
456 gtk_table_attach (
457 GTK_TABLE (container), widget,
458 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
459 gtk_widget_show (widget);
460
461 widget = gtk_hbox_new (FALSE, 6);
462 gtk_table_attach (
463 GTK_TABLE (container), widget,
464 1, 2, 3, 4, 0, 0, 0, 0);
465 dialog->priv->alert = widget; /* not referenced */
466 gtk_widget_show (widget);
467
468 container = widget;
469
470 widget = gtk_image_new_from_stock (
471 GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
472 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
473 gtk_widget_show (widget);
474
475 markup = g_markup_printf_escaped (
476 "<small>%s</small>",
477 _("Script file must be executable."));
478 widget = gtk_label_new (markup);
479 gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
480 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
481 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
482 gtk_widget_show (widget);
483 g_free (markup);
484
485 g_signal_connect (
486 dialog->priv->file_chooser, "file-set",
487 G_CALLBACK (mail_signature_script_dialog_file_set_cb), dialog);
488
489 g_signal_connect_swapped (
490 dialog->priv->entry, "changed",
491 G_CALLBACK (mail_signature_script_dialog_update_status), dialog);
492
493 mail_signature_script_dialog_update_status (dialog);
494 }
495
496 static void
497 e_mail_signature_script_dialog_class_init (EMailSignatureScriptDialogClass *class)
498 {
499 GObjectClass *object_class;
500
501 g_type_class_add_private (
502 class, sizeof (EMailSignatureScriptDialogPrivate));
503
504 object_class = G_OBJECT_CLASS (class);
505 object_class->set_property = mail_signature_script_dialog_set_property;
506 object_class->get_property = mail_signature_script_dialog_get_property;
507 object_class->dispose = mail_signature_script_dialog_dispose;
508 object_class->finalize = mail_signature_script_dialog_finalize;
509 object_class->constructed = mail_signature_script_dialog_constructed;
510
511 g_object_class_install_property (
512 object_class,
513 PROP_REGISTRY,
514 g_param_spec_object (
515 "registry",
516 "Registry",
517 "Data source registry",
518 E_TYPE_SOURCE_REGISTRY,
519 G_PARAM_READWRITE |
520 G_PARAM_CONSTRUCT_ONLY |
521 G_PARAM_STATIC_STRINGS));
522
523 g_object_class_install_property (
524 object_class,
525 PROP_SOURCE,
526 g_param_spec_object (
527 "source",
528 "Source",
529 NULL,
530 E_TYPE_SOURCE,
531 G_PARAM_READWRITE |
532 G_PARAM_CONSTRUCT_ONLY |
533 G_PARAM_STATIC_STRINGS));
534
535 g_object_class_install_property (
536 object_class,
537 PROP_SYMLINK_TARGET,
538 g_param_spec_string (
539 "symlink-target",
540 "Symlink Target",
541 NULL,
542 NULL,
543 G_PARAM_READWRITE |
544 G_PARAM_STATIC_STRINGS));
545 }
546
547 static void
548 e_mail_signature_script_dialog_init (EMailSignatureScriptDialog *dialog)
549 {
550 dialog->priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (dialog);
551 }
552
553 GtkWidget *
554 e_mail_signature_script_dialog_new (ESourceRegistry *registry,
555 GtkWindow *parent,
556 ESource *source)
557 {
558 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
559
560 if (source != NULL)
561 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
562
563 return g_object_new (
564 E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG,
565 "registry", registry,
566 "transient-for", parent,
567 "source", source, NULL);
568 }
569
570 ESourceRegistry *
571 e_mail_signature_script_dialog_get_registry (EMailSignatureScriptDialog *dialog)
572 {
573 g_return_val_if_fail (
574 E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
575
576 return dialog->priv->registry;
577 }
578
579 ESource *
580 e_mail_signature_script_dialog_get_source (EMailSignatureScriptDialog *dialog)
581 {
582 g_return_val_if_fail (
583 E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
584
585 return dialog->priv->source;
586 }
587
588 const gchar *
589 e_mail_signature_script_dialog_get_symlink_target (EMailSignatureScriptDialog *dialog)
590 {
591 g_return_val_if_fail (
592 E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
593
594 return dialog->priv->symlink_target;
595 }
596
597 void
598 e_mail_signature_script_dialog_set_symlink_target (EMailSignatureScriptDialog *dialog,
599 const gchar *symlink_target)
600 {
601 GtkFileChooser *file_chooser;
602
603 g_return_if_fail (E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog));
604 g_return_if_fail (symlink_target != NULL);
605
606 g_free (dialog->priv->symlink_target);
607 dialog->priv->symlink_target = g_strdup (symlink_target);
608
609 file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser);
610 gtk_file_chooser_set_filename (file_chooser, symlink_target);
611
612 g_object_notify (G_OBJECT (dialog), "symlink-target");
613
614 mail_signature_script_dialog_update_status (dialog);
615 }
616
617 /****************** e_mail_signature_script_dialog_commit() ******************/
618
619 static void
620 mail_signature_script_dialog_symlink_cb (GObject *object,
621 GAsyncResult *result,
622 gpointer user_data)
623 {
624 GSimpleAsyncResult *simple;
625 GError *error = NULL;
626
627 simple = G_SIMPLE_ASYNC_RESULT (user_data);
628
629 e_source_mail_signature_symlink_finish (
630 E_SOURCE (object), result, &error);
631
632 if (error != NULL)
633 g_simple_async_result_take_error (simple, error);
634
635 g_simple_async_result_complete (simple);
636
637 g_object_unref (simple);
638 }
639
640 static void
641 mail_signature_script_dialog_commit_cb (GObject *object,
642 GAsyncResult *result,
643 gpointer user_data)
644 {
645 GSimpleAsyncResult *simple;
646 AsyncContext *async_context;
647 GError *error = NULL;
648
649 simple = G_SIMPLE_ASYNC_RESULT (user_data);
650 async_context = g_simple_async_result_get_op_res_gpointer (simple);
651
652 e_source_registry_commit_source_finish (
653 E_SOURCE_REGISTRY (object), result, &error);
654
655 if (error != NULL) {
656 g_simple_async_result_take_error (simple, error);
657 g_simple_async_result_complete (simple);
658 g_object_unref (simple);
659 return;
660 }
661
662 /* We can call this on our scratch source because only its UID is
663 * really needed, which even a new scratch source already knows. */
664 e_source_mail_signature_symlink (
665 async_context->source,
666 async_context->symlink_target,
667 G_PRIORITY_DEFAULT,
668 async_context->cancellable,
669 mail_signature_script_dialog_symlink_cb,
670 simple);
671 }
672
673 void
674 e_mail_signature_script_dialog_commit (EMailSignatureScriptDialog *dialog,
675 GCancellable *cancellable,
676 GAsyncReadyCallback callback,
677 gpointer user_data)
678 {
679 GSimpleAsyncResult *simple;
680 AsyncContext *async_context;
681 ESourceRegistry *registry;
682 ESource *source;
683 const gchar *symlink_target;
684
685 g_return_if_fail (E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog));
686
687 registry = e_mail_signature_script_dialog_get_registry (dialog);
688 source = e_mail_signature_script_dialog_get_source (dialog);
689
690 symlink_target =
691 e_mail_signature_script_dialog_get_symlink_target (dialog);
692
693 async_context = g_slice_new0 (AsyncContext);
694 async_context->source = g_object_ref (source);
695 async_context->symlink_target = g_strdup (symlink_target);
696
697 if (G_IS_CANCELLABLE (cancellable))
698 async_context->cancellable = g_object_ref (cancellable);
699
700 simple = g_simple_async_result_new (
701 G_OBJECT (dialog), callback, user_data,
702 e_mail_signature_script_dialog_commit);
703
704 g_simple_async_result_set_op_res_gpointer (
705 simple, async_context, (GDestroyNotify) async_context_free);
706
707 e_source_registry_commit_source (
708 registry, source,
709 async_context->cancellable,
710 mail_signature_script_dialog_commit_cb,
711 simple);
712 }
713
714 gboolean
715 e_mail_signature_script_dialog_commit_finish (EMailSignatureScriptDialog *dialog,
716 GAsyncResult *result,
717 GError **error)
718 {
719 GSimpleAsyncResult *simple;
720
721 g_return_val_if_fail (
722 g_simple_async_result_is_valid (
723 result, G_OBJECT (dialog),
724 e_mail_signature_script_dialog_commit), FALSE);
725
726 simple = G_SIMPLE_ASYNC_RESULT (result);
727
728 /* Assume success unless a GError is set. */
729 return !g_simple_async_result_propagate_error (simple, error);
730 }