1 /*
2 * e-mail-signature-script-dialog.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18 #include "evolution-config.h"
19
20 #include <glib/gi18n-lib.h>
21
22 #include "e-mail-signature-script-dialog.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
G_DEFINE_TYPE(EMailSignatureScriptDialog,e_mail_signature_script_dialog,GTK_TYPE_DIALOG)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
mail_signature_script_dialog_filter_cb(const GtkFileFilterInfo * filter_info)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
mail_signature_script_dialog_update_status(EMailSignatureScriptDialog * dialog)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
mail_signature_script_dialog_file_set_cb(GtkFileChooserButton * button,EMailSignatureScriptDialog * dialog)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
mail_signature_script_dialog_query_cb(GFile * file,GAsyncResult * result,EMailSignatureScriptDialog * dialog)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
mail_signature_script_dialog_set_registry(EMailSignatureScriptDialog * dialog,ESourceRegistry * registry)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
mail_signature_script_dialog_set_source(EMailSignatureScriptDialog * dialog,ESource * source)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
mail_signature_script_dialog_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)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
mail_signature_script_dialog_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)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
mail_signature_script_dialog_dispose(GObject * object)308 mail_signature_script_dialog_dispose (GObject *object)
309 {
310 EMailSignatureScriptDialogPrivate *priv;
311
312 priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object);
313 g_clear_object (&priv->registry);
314 g_clear_object (&priv->source);
315
316 /* Chain up to parent's dispose() method. */
317 G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)->
318 dispose (object);
319 }
320
321 static void
mail_signature_script_dialog_finalize(GObject * object)322 mail_signature_script_dialog_finalize (GObject *object)
323 {
324 EMailSignatureScriptDialogPrivate *priv;
325
326 priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (object);
327
328 g_free (priv->symlink_target);
329
330 /* Chain up to parent's finalize() method. */
331 G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)->
332 finalize (object);
333 }
334
335 static void
mail_signature_script_dialog_constructed(GObject * object)336 mail_signature_script_dialog_constructed (GObject *object)
337 {
338 EMailSignatureScriptDialog *dialog;
339 GtkFileFilter *filter;
340 GtkWidget *container;
341 GtkWidget *widget;
342 ESource *source;
343 const gchar *display_name;
344 gchar *markup;
345
346 /* Chain up to parent's constructed() method. */
347 G_OBJECT_CLASS (e_mail_signature_script_dialog_parent_class)->constructed (object);
348
349 dialog = E_MAIL_SIGNATURE_SCRIPT_DIALOG (object);
350
351 source = e_mail_signature_script_dialog_get_source (dialog);
352 display_name = e_source_get_display_name (source);
353
354 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
355
356 gtk_dialog_add_button (
357 GTK_DIALOG (dialog),
358 _("_Cancel"), GTK_RESPONSE_CANCEL);
359
360 gtk_dialog_add_button (
361 GTK_DIALOG (dialog),
362 _("_Save"), GTK_RESPONSE_OK);
363
364 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
365
366 container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
367
368 widget = gtk_table_new (4, 2, FALSE);
369 gtk_table_set_col_spacings (GTK_TABLE (widget), 6);
370 gtk_table_set_row_spacings (GTK_TABLE (widget), 6);
371 gtk_table_set_row_spacing (GTK_TABLE (widget), 0, 12);
372 gtk_container_set_border_width (GTK_CONTAINER (widget), 5);
373 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
374 gtk_widget_show (widget);
375
376 container = widget;
377
378 widget = gtk_image_new_from_icon_name (
379 "dialog-information", GTK_ICON_SIZE_DIALOG);
380 gtk_table_attach (
381 GTK_TABLE (container), widget,
382 0, 1, 0, 1, 0, 0, 0, 0);
383 gtk_widget_show (widget);
384
385 widget = gtk_label_new (_(
386 "The output of this script will be used as your\n"
387 "signature. The name you specify will be used\n"
388 "for display purposes only."));
389 gtk_table_attach (
390 GTK_TABLE (container), widget,
391 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
392 gtk_widget_show (widget);
393
394 widget = gtk_entry_new ();
395 gtk_entry_set_text (GTK_ENTRY (widget), display_name);
396 gtk_entry_set_activates_default (GTK_ENTRY (widget), TRUE);
397 gtk_table_attach (
398 GTK_TABLE (container), widget,
399 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 0, 0);
400 dialog->priv->entry = widget; /* not referenced */
401 gtk_widget_show (widget);
402
403 e_binding_bind_property (
404 widget, "text",
405 source, "display-name",
406 G_BINDING_DEFAULT);
407
408 widget = gtk_label_new_with_mnemonic (_("_Name:"));
409 gtk_label_set_mnemonic_widget (
410 GTK_LABEL (widget), dialog->priv->entry);
411 gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
412 gtk_table_attach (
413 GTK_TABLE (container), widget,
414 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
415 gtk_widget_show (widget);
416
417 widget = gtk_file_chooser_button_new (
418 NULL, GTK_FILE_CHOOSER_ACTION_OPEN);
419 gtk_table_attach (
420 GTK_TABLE (container), widget,
421 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 0, 0);
422 dialog->priv->file_chooser = widget; /* not referenced */
423 gtk_widget_show (widget);
424
425 /* Restrict file selection to executable files. */
426 filter = gtk_file_filter_new ();
427 gtk_file_filter_add_custom (
428 filter, GTK_FILE_FILTER_FILENAME,
429 (GtkFileFilterFunc) mail_signature_script_dialog_filter_cb,
430 NULL, NULL);
431 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (widget), filter);
432
433 /* We create symbolic links to script files from the "signatures"
434 * directory, so restrict the selection to local files only. */
435 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (widget), TRUE);
436
437 widget = gtk_label_new_with_mnemonic (_("S_cript:"));
438 gtk_label_set_mnemonic_widget (
439 GTK_LABEL (widget), dialog->priv->file_chooser);
440 gtk_table_attach (
441 GTK_TABLE (container), widget,
442 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
443 gtk_widget_show (widget);
444
445 /* This is just a placeholder. */
446 widget = gtk_label_new (NULL);
447 gtk_table_attach (
448 GTK_TABLE (container), widget,
449 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
450 gtk_widget_show (widget);
451
452 widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
453 gtk_table_attach (
454 GTK_TABLE (container), widget,
455 1, 2, 3, 4, 0, 0, 0, 0);
456 dialog->priv->alert = widget; /* not referenced */
457 gtk_widget_show (widget);
458
459 container = widget;
460
461 widget = gtk_image_new_from_icon_name (
462 "dialog-warning", GTK_ICON_SIZE_MENU);
463 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
464 gtk_widget_show (widget);
465
466 markup = g_markup_printf_escaped (
467 "<small>%s</small>",
468 _("Script file must be executable."));
469 widget = gtk_label_new (markup);
470 gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
471 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
472 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
473 gtk_widget_show (widget);
474 g_free (markup);
475
476 g_signal_connect (
477 dialog->priv->file_chooser, "file-set",
478 G_CALLBACK (mail_signature_script_dialog_file_set_cb), dialog);
479
480 g_signal_connect_swapped (
481 dialog->priv->entry, "changed",
482 G_CALLBACK (mail_signature_script_dialog_update_status), dialog);
483
484 mail_signature_script_dialog_update_status (dialog);
485 }
486
487 static void
e_mail_signature_script_dialog_class_init(EMailSignatureScriptDialogClass * class)488 e_mail_signature_script_dialog_class_init (EMailSignatureScriptDialogClass *class)
489 {
490 GObjectClass *object_class;
491
492 g_type_class_add_private (
493 class, sizeof (EMailSignatureScriptDialogPrivate));
494
495 object_class = G_OBJECT_CLASS (class);
496 object_class->set_property = mail_signature_script_dialog_set_property;
497 object_class->get_property = mail_signature_script_dialog_get_property;
498 object_class->dispose = mail_signature_script_dialog_dispose;
499 object_class->finalize = mail_signature_script_dialog_finalize;
500 object_class->constructed = mail_signature_script_dialog_constructed;
501
502 g_object_class_install_property (
503 object_class,
504 PROP_REGISTRY,
505 g_param_spec_object (
506 "registry",
507 "Registry",
508 "Data source registry",
509 E_TYPE_SOURCE_REGISTRY,
510 G_PARAM_READWRITE |
511 G_PARAM_CONSTRUCT_ONLY |
512 G_PARAM_STATIC_STRINGS));
513
514 g_object_class_install_property (
515 object_class,
516 PROP_SOURCE,
517 g_param_spec_object (
518 "source",
519 "Source",
520 NULL,
521 E_TYPE_SOURCE,
522 G_PARAM_READWRITE |
523 G_PARAM_CONSTRUCT_ONLY |
524 G_PARAM_STATIC_STRINGS));
525
526 g_object_class_install_property (
527 object_class,
528 PROP_SYMLINK_TARGET,
529 g_param_spec_string (
530 "symlink-target",
531 "Symlink Target",
532 NULL,
533 NULL,
534 G_PARAM_READWRITE |
535 G_PARAM_STATIC_STRINGS));
536 }
537
538 static void
e_mail_signature_script_dialog_init(EMailSignatureScriptDialog * dialog)539 e_mail_signature_script_dialog_init (EMailSignatureScriptDialog *dialog)
540 {
541 dialog->priv = E_MAIL_SIGNATURE_SCRIPT_DIALOG_GET_PRIVATE (dialog);
542 }
543
544 GtkWidget *
e_mail_signature_script_dialog_new(ESourceRegistry * registry,GtkWindow * parent,ESource * source)545 e_mail_signature_script_dialog_new (ESourceRegistry *registry,
546 GtkWindow *parent,
547 ESource *source)
548 {
549 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
550
551 if (source != NULL)
552 g_return_val_if_fail (E_IS_SOURCE (source), NULL);
553
554 return g_object_new (
555 E_TYPE_MAIL_SIGNATURE_SCRIPT_DIALOG,
556 "registry", registry,
557 "transient-for", parent,
558 "source", source, NULL);
559 }
560
561 ESourceRegistry *
e_mail_signature_script_dialog_get_registry(EMailSignatureScriptDialog * dialog)562 e_mail_signature_script_dialog_get_registry (EMailSignatureScriptDialog *dialog)
563 {
564 g_return_val_if_fail (
565 E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
566
567 return dialog->priv->registry;
568 }
569
570 ESource *
e_mail_signature_script_dialog_get_source(EMailSignatureScriptDialog * dialog)571 e_mail_signature_script_dialog_get_source (EMailSignatureScriptDialog *dialog)
572 {
573 g_return_val_if_fail (
574 E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
575
576 return dialog->priv->source;
577 }
578
579 const gchar *
e_mail_signature_script_dialog_get_symlink_target(EMailSignatureScriptDialog * dialog)580 e_mail_signature_script_dialog_get_symlink_target (EMailSignatureScriptDialog *dialog)
581 {
582 g_return_val_if_fail (
583 E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog), NULL);
584
585 return dialog->priv->symlink_target;
586 }
587
588 void
e_mail_signature_script_dialog_set_symlink_target(EMailSignatureScriptDialog * dialog,const gchar * symlink_target)589 e_mail_signature_script_dialog_set_symlink_target (EMailSignatureScriptDialog *dialog,
590 const gchar *symlink_target)
591 {
592 GtkFileChooser *file_chooser;
593
594 g_return_if_fail (E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog));
595 g_return_if_fail (symlink_target != NULL);
596
597 g_free (dialog->priv->symlink_target);
598 dialog->priv->symlink_target = g_strdup (symlink_target);
599
600 file_chooser = GTK_FILE_CHOOSER (dialog->priv->file_chooser);
601 gtk_file_chooser_set_filename (file_chooser, symlink_target);
602
603 g_object_notify (G_OBJECT (dialog), "symlink-target");
604
605 mail_signature_script_dialog_update_status (dialog);
606 }
607
608 /****************** e_mail_signature_script_dialog_commit() ******************/
609
610 static void
mail_signature_script_dialog_symlink_cb(GObject * object,GAsyncResult * result,gpointer user_data)611 mail_signature_script_dialog_symlink_cb (GObject *object,
612 GAsyncResult *result,
613 gpointer user_data)
614 {
615 GSimpleAsyncResult *simple;
616 GError *error = NULL;
617
618 simple = G_SIMPLE_ASYNC_RESULT (user_data);
619
620 e_source_mail_signature_symlink_finish (
621 E_SOURCE (object), result, &error);
622
623 if (error != NULL)
624 g_simple_async_result_take_error (simple, error);
625
626 g_simple_async_result_complete (simple);
627
628 g_object_unref (simple);
629 }
630
631 static void
mail_signature_script_dialog_commit_cb(GObject * object,GAsyncResult * result,gpointer user_data)632 mail_signature_script_dialog_commit_cb (GObject *object,
633 GAsyncResult *result,
634 gpointer user_data)
635 {
636 GSimpleAsyncResult *simple;
637 AsyncContext *async_context;
638 GError *error = NULL;
639
640 simple = G_SIMPLE_ASYNC_RESULT (user_data);
641 async_context = g_simple_async_result_get_op_res_gpointer (simple);
642
643 e_source_registry_commit_source_finish (
644 E_SOURCE_REGISTRY (object), result, &error);
645
646 if (error != NULL) {
647 g_simple_async_result_take_error (simple, error);
648 g_simple_async_result_complete (simple);
649 g_object_unref (simple);
650 return;
651 }
652
653 /* We can call this on our scratch source because only its UID is
654 * really needed, which even a new scratch source already knows. */
655 e_source_mail_signature_symlink (
656 async_context->source,
657 async_context->symlink_target,
658 G_PRIORITY_DEFAULT,
659 async_context->cancellable,
660 mail_signature_script_dialog_symlink_cb,
661 simple);
662 }
663
664 void
e_mail_signature_script_dialog_commit(EMailSignatureScriptDialog * dialog,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)665 e_mail_signature_script_dialog_commit (EMailSignatureScriptDialog *dialog,
666 GCancellable *cancellable,
667 GAsyncReadyCallback callback,
668 gpointer user_data)
669 {
670 GSimpleAsyncResult *simple;
671 AsyncContext *async_context;
672 ESourceRegistry *registry;
673 ESource *source;
674 const gchar *symlink_target;
675
676 g_return_if_fail (E_IS_MAIL_SIGNATURE_SCRIPT_DIALOG (dialog));
677
678 registry = e_mail_signature_script_dialog_get_registry (dialog);
679 source = e_mail_signature_script_dialog_get_source (dialog);
680
681 symlink_target =
682 e_mail_signature_script_dialog_get_symlink_target (dialog);
683
684 async_context = g_slice_new0 (AsyncContext);
685 async_context->source = g_object_ref (source);
686 async_context->symlink_target = g_strdup (symlink_target);
687
688 if (G_IS_CANCELLABLE (cancellable))
689 async_context->cancellable = g_object_ref (cancellable);
690
691 simple = g_simple_async_result_new (
692 G_OBJECT (dialog), callback, user_data,
693 e_mail_signature_script_dialog_commit);
694
695 g_simple_async_result_set_op_res_gpointer (
696 simple, async_context, (GDestroyNotify) async_context_free);
697
698 e_source_registry_commit_source (
699 registry, source,
700 async_context->cancellable,
701 mail_signature_script_dialog_commit_cb,
702 simple);
703 }
704
705 gboolean
e_mail_signature_script_dialog_commit_finish(EMailSignatureScriptDialog * dialog,GAsyncResult * result,GError ** error)706 e_mail_signature_script_dialog_commit_finish (EMailSignatureScriptDialog *dialog,
707 GAsyncResult *result,
708 GError **error)
709 {
710 GSimpleAsyncResult *simple;
711
712 g_return_val_if_fail (
713 g_simple_async_result_is_valid (
714 result, G_OBJECT (dialog),
715 e_mail_signature_script_dialog_commit), FALSE);
716
717 simple = G_SIMPLE_ASYNC_RESULT (result);
718
719 /* Assume success unless a GError is set. */
720 return !g_simple_async_result_propagate_error (simple, error);
721 }
722
723