1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * SPDX-FileCopyrightText: (C) 2012 Red Hat, Inc. (www.redhat.com)
4 * SPDX-License-Identifier: LGPL-2.1-or-later
5 */
6
7 #include "evolution-ews-config.h"
8
9 #include <string.h>
10 #include <unistd.h>
11
12 #include <gtk/gtk.h>
13 #include <glib/gi18n-lib.h>
14
15 #include <e-util/e-util.h>
16
17 #include "common/camel-ews-settings.h"
18 #include "common/e-ews-connection.h"
19 #include "common/e-ews-connection-utils.h"
20 #include "common/e-ews-oof-settings.h"
21
22 #include "e-ews-config-utils.h"
23
24 #include "e-mail-config-ews-ooo-page.h"
25
26 typedef struct _AsyncContext AsyncContext;
27
28 struct _EMailConfigEwsOooPagePrivate {
29 ESourceRegistry *registry;
30 ESource *account_source;
31 ESource *identity_source;
32 ESource *collection_source;
33
34 /* The try_password() method deposits results here.
35 * This avoids calling GTK+ functions from multiple threads. */
36 EEwsOofSettings *oof_settings;
37 GMutex oof_settings_lock;
38
39 GCancellable *refresh_cancellable;
40
41 /* to not save unchanged state */
42 gboolean changed;
43
44 GtkWidget *enabled_radio_button; /* not referenced */
45 GtkWidget *disabled_radio_button; /* not referenced */
46 GtkWidget *scheduled_radio_button; /* not referenced */
47 GtkWidget *start_time; /* not referenced */
48 GtkWidget *end_time; /* not referenced */
49 GtkWidget *external_audience; /* not referenced */
50 GtkTextBuffer *internal_reply; /* not referenced */
51 GtkTextBuffer *external_reply; /* not referenced */
52 };
53
54 struct _AsyncContext {
55 EMailConfigEwsOooPage *page;
56 EActivity *activity;
57 ESource *source;
58 GObject *settings;
59 };
60
61 enum {
62 PROP_0,
63 PROP_ACCOUNT_SOURCE,
64 PROP_COLLECTION_SOURCE,
65 PROP_IDENTITY_SOURCE,
66 PROP_REGISTRY
67 };
68
69 /* Forward Declarations */
70 static void e_mail_config_ews_ooo_page_interface_init
71 (EMailConfigPageInterface *iface);
72
73 G_DEFINE_DYNAMIC_TYPE_EXTENDED (EMailConfigEwsOooPage, e_mail_config_ews_ooo_page, E_TYPE_MAIL_CONFIG_ACTIVITY_PAGE, 0,
74 G_ADD_PRIVATE_DYNAMIC (EMailConfigEwsOooPage)
75 G_IMPLEMENT_INTERFACE_DYNAMIC (E_TYPE_MAIL_CONFIG_PAGE, e_mail_config_ews_ooo_page_interface_init))
76
77 static void
async_context_free(gpointer ptr)78 async_context_free (gpointer ptr)
79 {
80 AsyncContext *async_context = ptr;
81
82 if (!async_context)
83 return;
84
85 if (async_context->settings)
86 g_object_thaw_notify (async_context->settings);
87
88 g_clear_object (&async_context->page);
89 g_clear_object (&async_context->activity);
90 g_clear_object (&async_context->source);
91 g_clear_object (&async_context->settings);
92
93 g_slice_free (AsyncContext, async_context);
94 }
95
96 static CamelSettings *
mail_config_ews_ooo_page_get_settings(EMailConfigEwsOooPage * page)97 mail_config_ews_ooo_page_get_settings (EMailConfigEwsOooPage *page)
98 {
99 ESource *source;
100 ESourceCamel *extension;
101 const gchar *extension_name;
102
103 source = e_mail_config_ews_ooo_page_get_collection_source (page);
104
105 extension_name = e_source_camel_get_extension_name ("ews");
106 extension = e_source_get_extension (source, extension_name);
107
108 return e_source_camel_get_settings (extension);
109 }
110
111 static const gchar *
mail_config_ews_ooo_page_get_mailbox(EMailConfigEwsOooPage * page)112 mail_config_ews_ooo_page_get_mailbox (EMailConfigEwsOooPage *page)
113 {
114 ESourceRegistry *registry;
115 ESource *collection_source;
116 GList *list, *link;
117 const gchar *collection_uid;
118 const gchar *extension_name;
119 const gchar *mailbox = NULL;
120
121 /* Find the mail identity source that belongs to
122 * our collection and return its email address. */
123
124 collection_source =
125 e_mail_config_ews_ooo_page_get_collection_source (page);
126 collection_uid = e_source_get_uid (collection_source);
127
128 extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
129 registry = e_mail_config_ews_ooo_page_get_registry (page);
130 list = e_source_registry_list_sources (registry, extension_name);
131
132 for (link = list; link != NULL; link = g_list_next (link)) {
133 ESource *source = E_SOURCE (link->data);
134 ESourceMailIdentity *extension;
135 const gchar *parent_uid;
136
137 parent_uid = e_source_get_parent (source);
138 if (g_strcmp0 (parent_uid, collection_uid) != 0)
139 continue;
140
141 extension = e_source_get_extension (source, extension_name);
142 mailbox = e_source_mail_identity_get_address (extension);
143 break;
144 }
145
146 g_list_free_full (list, g_object_unref);
147
148 return mailbox;
149 }
150
151 static void
mail_config_ews_ooo_page_display_settings(EMailConfigEwsOooPage * page,EEwsOofSettings * oof_settings)152 mail_config_ews_ooo_page_display_settings (EMailConfigEwsOooPage *page,
153 EEwsOofSettings *oof_settings)
154 {
155 GtkWidget *button;
156 GDateTime *date_time;
157
158 switch (e_ews_oof_settings_get_state (oof_settings)) {
159 default:
160 /* fall through */
161 case E_EWS_OOF_STATE_DISABLED:
162 button = page->priv->disabled_radio_button;
163 break;
164 case E_EWS_OOF_STATE_ENABLED:
165 button = page->priv->enabled_radio_button;
166 break;
167 case E_EWS_OOF_STATE_SCHEDULED:
168 button = page->priv->scheduled_radio_button;
169 break;
170 }
171
172 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
173
174 gtk_combo_box_set_active (
175 GTK_COMBO_BOX (page->priv->external_audience),
176 e_ews_oof_settings_get_external_audience (oof_settings));
177
178 date_time = e_ews_oof_settings_ref_start_time (oof_settings);
179 e_date_edit_set_time (
180 E_DATE_EDIT (page->priv->start_time),
181 (time_t) g_date_time_to_unix (date_time));
182 g_date_time_unref (date_time);
183
184 date_time = e_ews_oof_settings_ref_end_time (oof_settings);
185 e_date_edit_set_time (
186 E_DATE_EDIT (page->priv->end_time),
187 (time_t) g_date_time_to_unix (date_time));
188 g_date_time_unref (date_time);
189
190 gtk_text_buffer_set_text (
191 page->priv->internal_reply,
192 e_ews_oof_settings_get_internal_reply (oof_settings), -1);
193
194 gtk_text_buffer_set_text (
195 page->priv->external_reply,
196 e_ews_oof_settings_get_external_reply (oof_settings), -1);
197 }
198
199 static void
mail_config_ews_ooo_page_set_account_source(EMailConfigEwsOooPage * page,ESource * account_source)200 mail_config_ews_ooo_page_set_account_source (EMailConfigEwsOooPage *page,
201 ESource *account_source)
202 {
203 g_return_if_fail (E_IS_SOURCE (account_source));
204 g_return_if_fail (page->priv->account_source == NULL);
205
206 page->priv->account_source = g_object_ref (account_source);
207 }
208
209 static void
mail_config_ews_ooo_page_set_collection_source(EMailConfigEwsOooPage * page,ESource * collection_source)210 mail_config_ews_ooo_page_set_collection_source (EMailConfigEwsOooPage *page,
211 ESource *collection_source)
212 {
213 g_return_if_fail (E_IS_SOURCE (collection_source));
214 g_return_if_fail (page->priv->collection_source == NULL);
215
216 page->priv->collection_source = g_object_ref (collection_source);
217 }
218
219 static void
mail_config_ews_ooo_page_set_identity_source(EMailConfigEwsOooPage * page,ESource * identity_source)220 mail_config_ews_ooo_page_set_identity_source (EMailConfigEwsOooPage *page,
221 ESource *identity_source)
222 {
223 g_return_if_fail (E_IS_SOURCE (identity_source));
224 g_return_if_fail (page->priv->identity_source == NULL);
225
226 page->priv->identity_source = g_object_ref (identity_source);
227 }
228
229 static void
mail_config_ews_ooo_page_set_registry(EMailConfigEwsOooPage * page,ESourceRegistry * registry)230 mail_config_ews_ooo_page_set_registry (EMailConfigEwsOooPage *page,
231 ESourceRegistry *registry)
232 {
233 g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
234 g_return_if_fail (page->priv->registry == NULL);
235
236 page->priv->registry = g_object_ref (registry);
237 }
238
239 static void
mail_config_ews_ooo_page_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)240 mail_config_ews_ooo_page_set_property (GObject *object,
241 guint property_id,
242 const GValue *value,
243 GParamSpec *pspec)
244 {
245 switch (property_id) {
246 case PROP_ACCOUNT_SOURCE:
247 mail_config_ews_ooo_page_set_account_source (
248 E_MAIL_CONFIG_EWS_OOO_PAGE (object),
249 g_value_get_object (value));
250 return;
251
252 case PROP_COLLECTION_SOURCE:
253 mail_config_ews_ooo_page_set_collection_source (
254 E_MAIL_CONFIG_EWS_OOO_PAGE (object),
255 g_value_get_object (value));
256 return;
257
258 case PROP_IDENTITY_SOURCE:
259 mail_config_ews_ooo_page_set_identity_source (
260 E_MAIL_CONFIG_EWS_OOO_PAGE (object),
261 g_value_get_object (value));
262 return;
263
264 case PROP_REGISTRY:
265 mail_config_ews_ooo_page_set_registry (
266 E_MAIL_CONFIG_EWS_OOO_PAGE (object),
267 g_value_get_object (value));
268 return;
269 }
270
271 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
272 }
273
274 static void
mail_config_ews_ooo_page_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)275 mail_config_ews_ooo_page_get_property (GObject *object,
276 guint property_id,
277 GValue *value,
278 GParamSpec *pspec)
279 {
280 switch (property_id) {
281 case PROP_ACCOUNT_SOURCE:
282 g_value_set_object (
283 value,
284 e_mail_config_ews_ooo_page_get_account_source (
285 E_MAIL_CONFIG_EWS_OOO_PAGE (object)));
286 return;
287
288 case PROP_COLLECTION_SOURCE:
289 g_value_set_object (
290 value,
291 e_mail_config_ews_ooo_page_get_collection_source (
292 E_MAIL_CONFIG_EWS_OOO_PAGE (object)));
293 return;
294
295 case PROP_IDENTITY_SOURCE:
296 g_value_set_object (
297 value,
298 e_mail_config_ews_ooo_page_get_identity_source (
299 E_MAIL_CONFIG_EWS_OOO_PAGE (object)));
300 return;
301
302 case PROP_REGISTRY:
303 g_value_set_object (
304 value,
305 e_mail_config_ews_ooo_page_get_registry (
306 E_MAIL_CONFIG_EWS_OOO_PAGE (object)));
307 return;
308 }
309
310 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
311 }
312
313 static void
mail_config_ews_ooo_page_dispose(GObject * object)314 mail_config_ews_ooo_page_dispose (GObject *object)
315 {
316 EMailConfigEwsOooPage *ooo_page = E_MAIL_CONFIG_EWS_OOO_PAGE (object);
317
318 if (ooo_page->priv->refresh_cancellable) {
319 g_cancellable_cancel (ooo_page->priv->refresh_cancellable);
320 g_clear_object (&ooo_page->priv->refresh_cancellable);
321 }
322
323 g_clear_object (&ooo_page->priv->registry);
324 g_clear_object (&ooo_page->priv->account_source);
325 g_clear_object (&ooo_page->priv->collection_source);
326 g_clear_object (&ooo_page->priv->identity_source);
327 g_clear_object (&ooo_page->priv->oof_settings);
328
329 /* Chain up to parent's dispose() method. */
330 G_OBJECT_CLASS (e_mail_config_ews_ooo_page_parent_class)->dispose (object);
331 }
332
333 static void
mail_config_ews_ooo_page_finalize(GObject * object)334 mail_config_ews_ooo_page_finalize (GObject *object)
335 {
336 EMailConfigEwsOooPage *ooo_page = E_MAIL_CONFIG_EWS_OOO_PAGE (object);
337
338 g_mutex_clear (&ooo_page->priv->oof_settings_lock);
339
340 /* Chain up to parent's finalize() method. */
341 G_OBJECT_CLASS (e_mail_config_ews_ooo_page_parent_class)->finalize (object);
342 }
343
344 static void
mail_config_ews_ooo_page_constructed(GObject * object)345 mail_config_ews_ooo_page_constructed (GObject *object)
346 {
347 EMailConfigEwsOooPage *page;
348 GtkLabel *label;
349 GtkWidget *grid;
350 GtkWidget *widget;
351 GtkWidget *container;
352 GtkWidget *main_box;
353 GtkSizeGroup *size_group;
354 GtkTextBuffer *text_buffer;
355 GSList *group = NULL;
356 const gchar *text;
357 gchar *markup;
358
359 page = E_MAIL_CONFIG_EWS_OOO_PAGE (object);
360
361 /* Chain up to parent's constructed() method. */
362 G_OBJECT_CLASS (e_mail_config_ews_ooo_page_parent_class)->constructed (object);
363
364 main_box = e_mail_config_activity_page_get_internal_box (E_MAIL_CONFIG_ACTIVITY_PAGE (page));
365 gtk_box_set_spacing (GTK_BOX (main_box), 12);
366
367 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
368
369 text = _("Out of Office");
370 markup = g_markup_printf_escaped ("<b>%s</b>", text);
371 widget = gtk_label_new (markup);
372 gtk_label_set_use_markup (GTK_LABEL (widget), TRUE);
373 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
374 gtk_box_pack_start (GTK_BOX (main_box), widget, FALSE, FALSE, 0);
375 gtk_widget_show (widget);
376 g_free (markup);
377
378 widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
379 gtk_widget_set_margin_left (widget, 12);
380 gtk_box_pack_start (GTK_BOX (main_box), widget, FALSE, FALSE, 0);
381 gtk_widget_show (widget);
382
383 container = widget;
384
385 text = _("The messages specified below will be automatically sent to "
386 "each internal and external person who sends a mail to you.");
387 widget = gtk_label_new (text);
388 gtk_label_set_width_chars (GTK_LABEL (widget), 20);
389 gtk_label_set_max_width_chars (GTK_LABEL (widget), 80);
390 gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
391 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
392 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
393 gtk_widget_show (widget);
394
395 text = _("Do _not send Out of Office replies");
396 widget = gtk_radio_button_new_with_mnemonic (group, text);
397 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
398 page->priv->disabled_radio_button = widget; /* do not reference */
399 gtk_widget_show (widget);
400
401 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
402
403 text = _("_Send Out of Office replies");
404 widget = gtk_radio_button_new_with_mnemonic (group, text);
405 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
406 page->priv->enabled_radio_button = widget; /* do not reference */
407 gtk_widget_show (widget);
408
409 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (widget));
410
411 text = _("Send Out of Office replies only _during this time period:");
412 widget = gtk_radio_button_new_with_mnemonic (group, text);
413 gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
414 page->priv->scheduled_radio_button = widget; /* do not reference */
415 gtk_widget_show (widget);
416
417 widget = gtk_grid_new ();
418 gtk_grid_set_row_spacing (GTK_GRID (widget), 6);
419 gtk_grid_set_column_spacing (GTK_GRID (widget), 6);
420 gtk_box_pack_start (GTK_BOX (main_box), widget, TRUE, TRUE, 0);
421 gtk_widget_show (widget);
422
423 e_binding_bind_property (
424 page->priv->disabled_radio_button, "active",
425 widget, "sensitive",
426 G_BINDING_SYNC_CREATE |
427 G_BINDING_INVERT_BOOLEAN);
428
429 grid = widget;
430
431 widget = gtk_label_new_with_mnemonic (_("_From:"));
432 gtk_widget_set_margin_left (widget, 12);
433 gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
434 gtk_grid_attach (GTK_GRID (grid), widget, 0, 1, 1, 1);
435 gtk_size_group_add_widget (size_group, widget);
436 gtk_widget_show (widget);
437
438 e_binding_bind_property (
439 page->priv->scheduled_radio_button, "active",
440 widget, "sensitive",
441 G_BINDING_SYNC_CREATE);
442
443 label = GTK_LABEL (widget);
444
445 widget = e_date_edit_new ();
446 gtk_label_set_mnemonic_widget (label, widget);
447 gtk_grid_attach (GTK_GRID (grid), widget, 1, 1, 1, 1);
448 page->priv->start_time = widget; /* do not reference */
449 gtk_widget_show (widget);
450
451 e_binding_bind_property (
452 page->priv->scheduled_radio_button, "active",
453 widget, "sensitive",
454 G_BINDING_SYNC_CREATE);
455
456 widget = gtk_label_new_with_mnemonic (_("_To:"));
457 gtk_widget_set_margin_left (widget, 12);
458 gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
459 gtk_grid_attach (GTK_GRID (grid), widget, 0, 2, 1, 1);
460 gtk_size_group_add_widget (size_group, widget);
461 gtk_widget_show (widget);
462
463 e_binding_bind_property (
464 page->priv->scheduled_radio_button, "active",
465 widget, "sensitive",
466 G_BINDING_SYNC_CREATE);
467
468 label = GTK_LABEL (widget);
469
470 widget = e_date_edit_new ();
471 gtk_label_set_mnemonic_widget (label, widget);
472 gtk_grid_attach (GTK_GRID (grid), widget, 1, 2, 1, 1);
473 page->priv->end_time = widget; /* do not reference */
474 gtk_widget_show (widget);
475
476 e_binding_bind_property (
477 page->priv->scheduled_radio_button, "active",
478 widget, "sensitive",
479 G_BINDING_SYNC_CREATE);
480
481 widget = gtk_label_new_with_mnemonic (_("I_nternal:"));
482 gtk_widget_set_margin_top (widget, 12);
483 gtk_widget_set_margin_left (widget, 12);
484 gtk_widget_set_valign (widget, GTK_ALIGN_START);
485 gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
486 gtk_grid_attach (GTK_GRID (grid), widget, 0, 3, 1, 1);
487 gtk_size_group_add_widget (size_group, widget);
488 gtk_widget_show (widget);
489
490 text = _("Message to be sent within the organization");
491 gtk_widget_set_tooltip_text (widget, text);
492
493 label = GTK_LABEL (widget);
494
495 widget = gtk_scrolled_window_new (NULL, NULL);
496 gtk_scrolled_window_set_policy (
497 GTK_SCROLLED_WINDOW (widget),
498 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
499 gtk_scrolled_window_set_shadow_type (
500 GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
501 gtk_widget_set_margin_top (widget, 12);
502 gtk_widget_set_hexpand (widget, TRUE);
503 gtk_widget_set_vexpand (widget, TRUE);
504 gtk_grid_attach (GTK_GRID (grid), widget, 1, 3, 1, 1);
505 gtk_widget_show (widget);
506
507 container = widget;
508
509 widget = gtk_text_view_new ();
510 gtk_label_set_mnemonic_widget (label, widget);
511 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (widget), GTK_WRAP_WORD);
512 gtk_container_add (GTK_CONTAINER (container), widget);
513 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
514 page->priv->internal_reply = text_buffer; /* do not reference */
515 e_spell_text_view_attach (GTK_TEXT_VIEW (widget));
516 gtk_widget_show (widget);
517
518 widget = gtk_label_new_with_mnemonic (_("E_xternal:"));
519 gtk_widget_set_margin_top (widget, 12);
520 gtk_widget_set_margin_left (widget, 12);
521 gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
522 gtk_grid_attach (GTK_GRID (grid), widget, 0, 4, 1, 1);
523 gtk_size_group_add_widget (size_group, widget);
524 gtk_widget_show (widget);
525
526 text = _("Message to be sent outside the organization");
527 gtk_widget_set_tooltip_text (widget, text);
528
529 label = GTK_LABEL (widget);
530
531 /* The order of the combo box items needs to stay
532 * syncrhonized with the EEwsExternalAudience enum. */
533 widget = gtk_combo_box_text_new ();
534 gtk_combo_box_text_append_text (
535 GTK_COMBO_BOX_TEXT (widget),
536 _("Do not reply to senders outside the organization"));
537 gtk_combo_box_text_append_text (
538 GTK_COMBO_BOX_TEXT (widget),
539 _("Reply only to known senders outside the organization"));
540 gtk_combo_box_text_append_text (
541 GTK_COMBO_BOX_TEXT (widget),
542 _("Reply to any sender outside the organization"));
543 gtk_widget_set_margin_top (widget, 12);
544 gtk_grid_attach (GTK_GRID (grid), widget, 1, 4, 1, 1);
545 page->priv->external_audience = widget; /* do not reference */
546 gtk_widget_show (widget);
547
548 widget = gtk_scrolled_window_new (NULL, NULL);
549 gtk_scrolled_window_set_policy (
550 GTK_SCROLLED_WINDOW (widget),
551 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
552 gtk_scrolled_window_set_shadow_type (
553 GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
554 gtk_widget_set_hexpand (widget, TRUE);
555 gtk_widget_set_vexpand (widget, TRUE);
556 gtk_grid_attach (GTK_GRID (grid), widget, 1, 5, 1, 1);
557 gtk_widget_show (widget);
558
559 container = widget;
560
561 widget = gtk_text_view_new ();
562 gtk_label_set_mnemonic_widget (label, widget);
563 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (widget), GTK_WRAP_WORD);
564 gtk_container_add (GTK_CONTAINER (container), widget);
565 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
566 page->priv->external_reply = text_buffer; /* do not reference */
567 e_spell_text_view_attach (GTK_TEXT_VIEW (widget));
568 gtk_widget_show (widget);
569
570 /* XXX Bit of a hack. Since the enum value for "none" is zero,
571 * sensitize the text view if the combo box has a non-zero
572 * "active" value (in other words, anything but "none"). */
573 e_binding_bind_property (
574 page->priv->external_audience, "active",
575 widget, "sensitive",
576 G_BINDING_SYNC_CREATE);
577
578 g_object_unref (size_group);
579
580 e_mail_config_page_set_content (E_MAIL_CONFIG_PAGE (page), main_box);
581
582 e_mail_config_ews_ooo_page_refresh (page);
583 }
584
585 /* Helper for mail_config_ews_ooo_page_submit() */
586 static void
mail_config_ews_ooo_page_submit_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)587 mail_config_ews_ooo_page_submit_cb (GObject *source_object,
588 GAsyncResult *result,
589 gpointer user_data)
590 {
591 GSimpleAsyncResult *simple;
592 GError *error = NULL;
593
594 simple = G_SIMPLE_ASYNC_RESULT (user_data);
595
596 e_ews_oof_settings_submit_finish (
597 E_EWS_OOF_SETTINGS (source_object), result, &error);
598
599 if (error != NULL)
600 g_simple_async_result_take_error (simple, error);
601
602 g_simple_async_result_complete (simple);
603
604 g_object_unref (simple);
605 }
606
607 static void
ews_oof_settings_changed(gboolean * pchanged)608 ews_oof_settings_changed (gboolean *pchanged)
609 {
610 g_return_if_fail (pchanged != NULL);
611
612 *pchanged = TRUE;
613 }
614
615 static void
mail_config_ews_ooo_page_submit(EMailConfigPage * page,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)616 mail_config_ews_ooo_page_submit (EMailConfigPage *page,
617 GCancellable *cancellable,
618 GAsyncReadyCallback callback,
619 gpointer user_data)
620 {
621 EMailConfigEwsOooPage *ooo_page;
622 GSimpleAsyncResult *simple;
623 GtkToggleButton *toggle_button;
624 GtkTextBuffer *text_buffer;
625 GtkTextIter start, end;
626 GDateTime *date_time;
627 gchar *text;
628 time_t tm;
629 gulong signal_id;
630
631 ooo_page = E_MAIL_CONFIG_EWS_OOO_PAGE (page);
632
633 g_mutex_lock (&ooo_page->priv->oof_settings_lock);
634
635 /* It may be that the Out of Office settings are still
636 * loading or have failed to load, in which case there
637 * are obviously no changes to submit. */
638 if (!ooo_page->priv->oof_settings) {
639 g_mutex_unlock (&ooo_page->priv->oof_settings_lock);
640
641 simple = g_simple_async_result_new (
642 G_OBJECT (page), callback, user_data,
643 mail_config_ews_ooo_page_submit);
644 g_simple_async_result_complete (simple);
645 g_object_unref (simple);
646
647 return;
648 }
649
650 signal_id = g_signal_connect_swapped (
651 ooo_page->priv->oof_settings, "notify",
652 G_CALLBACK (ews_oof_settings_changed), &ooo_page->priv->changed);
653
654 toggle_button = GTK_TOGGLE_BUTTON (ooo_page->priv->enabled_radio_button);
655 if (gtk_toggle_button_get_active (toggle_button))
656 e_ews_oof_settings_set_state (
657 ooo_page->priv->oof_settings,
658 E_EWS_OOF_STATE_ENABLED);
659
660 toggle_button = GTK_TOGGLE_BUTTON (ooo_page->priv->disabled_radio_button);
661 if (gtk_toggle_button_get_active (toggle_button))
662 e_ews_oof_settings_set_state (
663 ooo_page->priv->oof_settings,
664 E_EWS_OOF_STATE_DISABLED);
665
666 toggle_button = GTK_TOGGLE_BUTTON (ooo_page->priv->scheduled_radio_button);
667 if (gtk_toggle_button_get_active (toggle_button))
668 e_ews_oof_settings_set_state (
669 ooo_page->priv->oof_settings,
670 E_EWS_OOF_STATE_SCHEDULED);
671
672 tm = e_date_edit_get_time (E_DATE_EDIT (ooo_page->priv->start_time));
673 date_time = g_date_time_new_from_unix_utc ((gint64) tm);
674 e_ews_oof_settings_set_start_time (ooo_page->priv->oof_settings, date_time);
675 g_date_time_unref (date_time);
676
677 tm = e_date_edit_get_time (E_DATE_EDIT (ooo_page->priv->end_time));
678 date_time = g_date_time_new_from_unix_utc ((gint64) tm);
679 e_ews_oof_settings_set_end_time (ooo_page->priv->oof_settings, date_time);
680 g_date_time_unref (date_time);
681
682 text_buffer = ooo_page->priv->internal_reply;
683 gtk_text_buffer_get_bounds (text_buffer, &start, &end);
684 text = gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE);
685 e_ews_oof_settings_set_internal_reply (ooo_page->priv->oof_settings, text);
686 g_free (text);
687
688 e_ews_oof_settings_set_external_audience (ooo_page->priv->oof_settings,
689 gtk_combo_box_get_active (GTK_COMBO_BOX (ooo_page->priv->external_audience)));
690
691 text_buffer = ooo_page->priv->external_reply;
692 gtk_text_buffer_get_bounds (text_buffer, &start, &end);
693 text = gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE);
694 e_ews_oof_settings_set_external_reply (ooo_page->priv->oof_settings, text);
695 g_free (text);
696
697 simple = g_simple_async_result_new (
698 G_OBJECT (page), callback, user_data,
699 mail_config_ews_ooo_page_submit);
700
701 g_signal_handler_disconnect (ooo_page->priv->oof_settings, signal_id);
702
703 if (ooo_page->priv->changed) {
704 g_simple_async_result_set_check_cancellable (simple, cancellable);
705
706 e_ews_oof_settings_submit (
707 ooo_page->priv->oof_settings, cancellable,
708 mail_config_ews_ooo_page_submit_cb,
709 g_object_ref (simple));
710 } else {
711 g_simple_async_result_complete (simple);
712 }
713
714 g_object_unref (simple);
715
716 g_mutex_unlock (&ooo_page->priv->oof_settings_lock);
717 }
718
719 static gboolean
mail_config_ews_ooo_page_submit_finish(EMailConfigPage * page,GAsyncResult * result,GError ** error)720 mail_config_ews_ooo_page_submit_finish (EMailConfigPage *page,
721 GAsyncResult *result,
722 GError **error)
723 {
724 GSimpleAsyncResult *simple;
725
726 g_return_val_if_fail (
727 g_simple_async_result_is_valid (
728 result, G_OBJECT (page),
729 mail_config_ews_ooo_page_submit), FALSE);
730
731 simple = G_SIMPLE_ASYNC_RESULT (result);
732
733 /* Assume success unless a GError is set. */
734 return !g_simple_async_result_propagate_error (simple, error);
735 }
736
737 static ESourceAuthenticationResult
mail_config_ews_ooo_page_try_credentials_sync(EEwsConnection * connection,const ENamedParameters * credentials,gpointer user_data,GCancellable * cancellable,GError ** error)738 mail_config_ews_ooo_page_try_credentials_sync (EEwsConnection *connection,
739 const ENamedParameters *credentials,
740 gpointer user_data,
741 GCancellable *cancellable,
742 GError **error)
743 {
744 AsyncContext *async_context = user_data;
745 EMailConfigEwsOooPage *page;
746 ESourceAuthenticationResult result;
747 EEwsOofSettings *oof_settings;
748 const gchar *mailbox;
749 GError *local_error = NULL;
750
751 page = async_context->page;
752
753 mailbox = mail_config_ews_ooo_page_get_mailbox (page);
754 e_ews_connection_set_mailbox (connection, mailbox);
755
756 oof_settings = e_ews_oof_settings_new_sync (connection, cancellable, &local_error);
757
758 if (oof_settings != NULL) {
759 result = E_SOURCE_AUTHENTICATION_ACCEPTED;
760 g_warn_if_fail (local_error == NULL);
761
762 /* The page takes ownership of the settings. */
763 g_mutex_lock (&page->priv->oof_settings_lock);
764 if (page->priv->oof_settings != NULL)
765 g_object_unref (oof_settings);
766 page->priv->oof_settings = oof_settings;
767 page->priv->changed = FALSE;
768 g_mutex_unlock (&page->priv->oof_settings_lock);
769
770 } else if (g_error_matches (local_error, SOUP_HTTP_ERROR, SOUP_STATUS_UNAUTHORIZED)) {
771 result = E_SOURCE_AUTHENTICATION_REJECTED;
772 g_error_free (local_error);
773
774 } else {
775 result = E_SOURCE_AUTHENTICATION_ERROR;
776 g_propagate_error (error, local_error);
777 }
778
779 return result;
780 }
781
782 static void
mail_config_ews_ooo_page_refresh_thread_cb(GObject * with_object,gpointer user_data,GCancellable * cancellable,GError ** perror)783 mail_config_ews_ooo_page_refresh_thread_cb (GObject *with_object,
784 gpointer user_data,
785 GCancellable *cancellable,
786 GError **perror)
787 {
788 AsyncContext *async_context = user_data;
789 CamelEwsSettings *ews_settings;
790 EEwsConnection *connection;
791
792 if (g_cancellable_set_error_if_cancelled (cancellable, perror))
793 return;
794
795 ews_settings = CAMEL_EWS_SETTINGS (async_context->settings);
796 connection = e_ews_config_utils_open_connection_for (async_context->source, ews_settings, NULL,
797 mail_config_ews_ooo_page_try_credentials_sync, async_context, cancellable, perror);
798
799 g_clear_object (&connection);
800 }
801
802 static void
mail_config_ews_ooo_page_refresh_idle_cb(GObject * with_object,gpointer user_data,GCancellable * cancellable,GError ** perror)803 mail_config_ews_ooo_page_refresh_idle_cb (GObject *with_object,
804 gpointer user_data,
805 GCancellable *cancellable,
806 GError **perror)
807 {
808 AsyncContext *async_context;
809 EAlertSink *alert_sink;
810 GError *error = NULL;
811
812 async_context = (AsyncContext *) user_data;
813
814 if (perror) {
815 error = *perror;
816 *perror = NULL;
817 }
818
819 alert_sink = e_activity_get_alert_sink (async_context->activity);
820
821 if (e_activity_handle_cancellation (async_context->activity, error)) {
822 g_error_free (error);
823
824 } else if (error != NULL) {
825 e_alert_submit (
826 alert_sink,
827 "ews:query-ooo-error",
828 error->message, NULL);
829 g_error_free (error);
830
831 } else {
832 EMailConfigEwsOooPage *page = async_context->page;
833
834 g_mutex_lock (&page->priv->oof_settings_lock);
835
836 if (page->priv->oof_settings != NULL)
837 mail_config_ews_ooo_page_display_settings (
838 page, page->priv->oof_settings);
839
840 g_mutex_unlock (&page->priv->oof_settings_lock);
841 }
842 }
843
844 static void
e_mail_config_ews_ooo_page_class_init(EMailConfigEwsOooPageClass * class)845 e_mail_config_ews_ooo_page_class_init (EMailConfigEwsOooPageClass *class)
846 {
847 GObjectClass *object_class;
848
849 object_class = G_OBJECT_CLASS (class);
850 object_class->set_property = mail_config_ews_ooo_page_set_property;
851 object_class->get_property = mail_config_ews_ooo_page_get_property;
852 object_class->dispose = mail_config_ews_ooo_page_dispose;
853 object_class->finalize = mail_config_ews_ooo_page_finalize;
854 object_class->constructed = mail_config_ews_ooo_page_constructed;
855
856 g_object_class_install_property (
857 object_class,
858 PROP_ACCOUNT_SOURCE,
859 g_param_spec_object (
860 "account-source",
861 "Account Source",
862 "Mail account source being edited",
863 E_TYPE_SOURCE,
864 G_PARAM_READWRITE |
865 G_PARAM_CONSTRUCT_ONLY));
866
867 g_object_class_install_property (
868 object_class,
869 PROP_COLLECTION_SOURCE,
870 g_param_spec_object (
871 "collection-source",
872 "Collection Source",
873 "Collection source being edited",
874 E_TYPE_SOURCE,
875 G_PARAM_READWRITE |
876 G_PARAM_CONSTRUCT_ONLY));
877
878 g_object_class_install_property (
879 object_class,
880 PROP_IDENTITY_SOURCE,
881 g_param_spec_object (
882 "identity-source",
883 "Identity Source",
884 "Mail identity source being edited",
885 E_TYPE_SOURCE,
886 G_PARAM_READWRITE |
887 G_PARAM_CONSTRUCT_ONLY));
888
889 g_object_class_install_property (
890 object_class,
891 PROP_REGISTRY,
892 g_param_spec_object (
893 "registry",
894 "Registry",
895 "Data source registry",
896 E_TYPE_SOURCE_REGISTRY,
897 G_PARAM_READWRITE |
898 G_PARAM_CONSTRUCT_ONLY));
899 }
900
901 static void
e_mail_config_ews_ooo_page_interface_init(EMailConfigPageInterface * iface)902 e_mail_config_ews_ooo_page_interface_init (EMailConfigPageInterface *iface)
903 {
904 iface->title = _("Out of Office");
905 iface->sort_order = E_MAIL_CONFIG_EWS_OOO_PAGE_SORT_ORDER;
906 iface->submit = mail_config_ews_ooo_page_submit;
907 iface->submit_finish = mail_config_ews_ooo_page_submit_finish;
908 }
909
910 static void
e_mail_config_ews_ooo_page_class_finalize(EMailConfigEwsOooPageClass * class)911 e_mail_config_ews_ooo_page_class_finalize (EMailConfigEwsOooPageClass *class)
912 {
913 }
914
915 static void
e_mail_config_ews_ooo_page_init(EMailConfigEwsOooPage * page)916 e_mail_config_ews_ooo_page_init (EMailConfigEwsOooPage *page)
917 {
918 page->priv = e_mail_config_ews_ooo_page_get_instance_private (page);
919
920 g_mutex_init (&page->priv->oof_settings_lock);
921 }
922
923 void
e_mail_config_ews_ooo_page_type_register(GTypeModule * type_module)924 e_mail_config_ews_ooo_page_type_register (GTypeModule *type_module)
925 {
926 /* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
927 * function, so we have to wrap it with a public function in
928 * order to register types from a separate compilation unit. */
929 e_mail_config_ews_ooo_page_register_type (type_module);
930 }
931
932 EMailConfigPage *
e_mail_config_ews_ooo_page_new(ESourceRegistry * registry,ESource * account_source,ESource * identity_source,ESource * collection_source)933 e_mail_config_ews_ooo_page_new (ESourceRegistry *registry,
934 ESource *account_source,
935 ESource *identity_source,
936 ESource *collection_source)
937 {
938 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
939 g_return_val_if_fail (E_IS_SOURCE (account_source), NULL);
940 g_return_val_if_fail (E_IS_SOURCE (identity_source), NULL);
941 g_return_val_if_fail (E_IS_SOURCE (collection_source), NULL);
942
943 return g_object_new (
944 E_TYPE_MAIL_CONFIG_EWS_OOO_PAGE,
945 "registry", registry,
946 "account-source", account_source,
947 "identity-source", identity_source,
948 "collection-source", collection_source,
949 NULL);
950 }
951
952 void
e_mail_config_ews_ooo_page_refresh(EMailConfigEwsOooPage * page)953 e_mail_config_ews_ooo_page_refresh (EMailConfigEwsOooPage *page)
954 {
955 ESource *source;
956 EActivity *activity;
957 GCancellable *cancellable;
958 CamelSettings *settings;
959 AsyncContext *async_context;
960
961 g_return_if_fail (E_IS_MAIL_CONFIG_EWS_OOO_PAGE (page));
962
963 source = e_mail_config_ews_ooo_page_get_collection_source (page);
964
965 if (page->priv->refresh_cancellable) {
966 g_cancellable_cancel (page->priv->refresh_cancellable);
967 g_clear_object (&page->priv->refresh_cancellable);
968 }
969
970 activity = e_mail_config_activity_page_new_activity (
971 E_MAIL_CONFIG_ACTIVITY_PAGE (page));
972 cancellable = e_activity_get_cancellable (activity);
973 page->priv->refresh_cancellable = g_object_ref (cancellable);
974
975 e_activity_set_text (
976 activity, _("Retrieving “Out of Office” settings"));
977
978 settings = mail_config_ews_ooo_page_get_settings (page);
979
980 async_context = g_slice_new0 (AsyncContext);
981 async_context->page = g_object_ref (page);
982 async_context->activity = activity; /* takes ownership */
983 async_context->source = g_object_ref (source);
984 async_context->settings = G_OBJECT (g_object_ref (settings));
985
986 /* Property changes can cause update of the UI, but this runs in a thread,
987 thus freeze the notify till be back in UI thread */
988 g_object_freeze_notify (async_context->settings);
989
990 e_ews_config_utils_run_in_thread (G_OBJECT (page),
991 mail_config_ews_ooo_page_refresh_thread_cb,
992 mail_config_ews_ooo_page_refresh_idle_cb,
993 async_context, async_context_free, cancellable);
994 }
995
996 ESourceRegistry *
e_mail_config_ews_ooo_page_get_registry(EMailConfigEwsOooPage * page)997 e_mail_config_ews_ooo_page_get_registry (EMailConfigEwsOooPage *page)
998 {
999 g_return_val_if_fail (E_IS_MAIL_CONFIG_EWS_OOO_PAGE (page), NULL);
1000
1001 return page->priv->registry;
1002 }
1003
1004 ESource *
e_mail_config_ews_ooo_page_get_account_source(EMailConfigEwsOooPage * page)1005 e_mail_config_ews_ooo_page_get_account_source (EMailConfigEwsOooPage *page)
1006 {
1007 g_return_val_if_fail (E_IS_MAIL_CONFIG_EWS_OOO_PAGE (page), NULL);
1008
1009 return page->priv->account_source;
1010 }
1011
1012 ESource *
e_mail_config_ews_ooo_page_get_identity_source(EMailConfigEwsOooPage * page)1013 e_mail_config_ews_ooo_page_get_identity_source (EMailConfigEwsOooPage *page)
1014 {
1015 g_return_val_if_fail (E_IS_MAIL_CONFIG_EWS_OOO_PAGE (page), NULL);
1016
1017 return page->priv->identity_source;
1018 }
1019
1020 ESource *
e_mail_config_ews_ooo_page_get_collection_source(EMailConfigEwsOooPage * page)1021 e_mail_config_ews_ooo_page_get_collection_source (EMailConfigEwsOooPage *page)
1022 {
1023 g_return_val_if_fail (E_IS_MAIL_CONFIG_EWS_OOO_PAGE (page), NULL);
1024
1025 return page->priv->collection_source;
1026 }
1027
1028