No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-mail-config-window.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-mail-config-window.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /*
2 * e-mail-config-window.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-config-window.h"
20
21 #include <config.h>
22 #include <glib/gi18n-lib.h>
23
24 #include <libevolution-utils/e-alert-dialog.h>
25 #include <libevolution-utils/e-alert-sink.h>
26 #include <misc/e-alert-bar.h>
27
28 #include <mail/e-mail-config-notebook.h>
29 #include <mail/e-mail-config-sidebar.h>
30
31 #define E_MAIL_CONFIG_WINDOW_GET_PRIVATE(obj) \
32 (G_TYPE_INSTANCE_GET_PRIVATE \
33 ((obj), E_TYPE_MAIL_CONFIG_WINDOW, EMailConfigWindowPrivate))
34
35 struct _EMailConfigWindowPrivate {
36 EMailSession *session;
37 ESource *original_source;
38
39 /* Scratch Sources */
40 ESource *account_source;
41 ESource *identity_source;
42 ESource *transport_source;
43 ESource *collection_source; /* optional */
44
45 GtkWidget *notebook; /* not referenced */
46 GtkWidget *alert_bar; /* not referenced */
47 };
48
49 enum {
50 PROP_0,
51 PROP_ORIGINAL_SOURCE,
52 PROP_SESSION
53 };
54
55 enum {
56 CHANGES_COMMITTED,
57 LAST_SIGNAL
58 };
59
60 /* Forward Declarations */
61 static void e_mail_config_window_alert_sink_init
62 (EAlertSinkInterface *interface);
63
64 static guint signals[LAST_SIGNAL];
65
66 G_DEFINE_TYPE_WITH_CODE (
67 EMailConfigWindow,
68 e_mail_config_window,
69 GTK_TYPE_DIALOG,
70 G_IMPLEMENT_INTERFACE (
71 E_TYPE_ALERT_SINK,
72 e_mail_config_window_alert_sink_init))
73
74 static ESource *
75 mail_config_window_clone_source (ESource *source)
76 {
77 ESource *clone;
78 GDBusObject *dbus_object;
79
80 dbus_object = e_source_ref_dbus_object (source);
81
82 clone = e_source_new (dbus_object, NULL, NULL);
83
84 if (dbus_object != NULL)
85 g_object_unref (dbus_object);
86
87 return clone;
88 }
89
90 static void
91 mail_config_window_setup_scratch_sources (EMailConfigWindow *window)
92 {
93 ESource *source;
94 ESource *scratch_source;
95 ESourceRegistry *registry;
96 ESourceMailAccount *account_ext;
97 ESourceMailSubmission *submission_ext;
98 EMailSession *session;
99 const gchar *extension_name;
100 const gchar *uid;
101
102 session = e_mail_config_window_get_session (window);
103 registry = e_mail_session_get_registry (session);
104
105 source = window->priv->original_source;
106 scratch_source = mail_config_window_clone_source (source);
107 window->priv->account_source = scratch_source;
108
109 extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
110 account_ext = e_source_get_extension (source, extension_name);
111 uid = e_source_mail_account_get_identity_uid (account_ext);
112 source = e_source_registry_ref_source (registry, uid);
113 scratch_source = mail_config_window_clone_source (source);
114 window->priv->identity_source = scratch_source;
115 g_object_unref (source);
116
117 extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION;
118 submission_ext = e_source_get_extension (source, extension_name);
119 uid = e_source_mail_submission_get_transport_uid (submission_ext);
120 source = e_source_registry_ref_source (registry, uid);
121 scratch_source = mail_config_window_clone_source (source);
122 window->priv->transport_source = scratch_source;
123 g_object_unref (source);
124
125 extension_name = E_SOURCE_EXTENSION_COLLECTION;
126 source = e_source_registry_find_extension (
127 registry, window->priv->original_source, extension_name);
128 if (source != NULL) {
129 scratch_source = mail_config_window_clone_source (source);
130 window->priv->collection_source = scratch_source;
131 g_object_unref (source);
132 }
133 }
134
135 static void
136 mail_config_window_commit_cb (GObject *object,
137 GAsyncResult *result,
138 gpointer user_data)
139 {
140 EMailConfigWindow *window;
141 EMailConfigNotebook *notebook;
142 GdkWindow *gdk_window;
143 GError *error = NULL;
144
145 window = E_MAIL_CONFIG_WINDOW (user_data);
146 notebook = E_MAIL_CONFIG_NOTEBOOK (object);
147
148 /* Set the cursor back to normal. */
149 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
150 gdk_window_set_cursor (gdk_window, NULL);
151
152 /* Allow user interaction with window content. */
153 gtk_widget_set_sensitive (GTK_WIDGET (window), TRUE);
154
155 e_mail_config_notebook_commit_finish (notebook, result, &error);
156
157 /* Ignore cancellations. */
158 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
159 g_object_unref (window);
160 g_error_free (error);
161
162 } else if (error != NULL) {
163 e_alert_submit (
164 E_ALERT_SINK (window),
165 "system:simple-error",
166 error->message, NULL);
167 g_object_unref (window);
168 g_error_free (error);
169
170 } else {
171 g_signal_emit (window, signals[CHANGES_COMMITTED], 0);
172 gtk_widget_destroy (GTK_WIDGET (window));
173 }
174 }
175
176 static void
177 mail_config_window_commit (EMailConfigWindow *window)
178 {
179 GdkCursor *gdk_cursor;
180 GdkWindow *gdk_window;
181 EMailConfigNotebook *notebook;
182
183 notebook = E_MAIL_CONFIG_NOTEBOOK (window->priv->notebook);
184
185 /* Clear any previous alerts. */
186 e_alert_bar_clear (E_ALERT_BAR (window->priv->alert_bar));
187
188 /* Make the cursor appear busy. */
189 gdk_cursor = gdk_cursor_new (GDK_WATCH);
190 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
191 gdk_window_set_cursor (gdk_window, gdk_cursor);
192 g_object_unref (gdk_cursor);
193
194 /* Prevent user interaction with window content. */
195 gtk_widget_set_sensitive (GTK_WIDGET (window), FALSE);
196
197 /* XXX This operation is not cancellable. */
198 e_mail_config_notebook_commit (
199 notebook, NULL,
200 mail_config_window_commit_cb,
201 g_object_ref (window));
202 }
203
204 static void
205 mail_config_window_set_original_source (EMailConfigWindow *window,
206 ESource *original_source)
207 {
208 g_return_if_fail (E_IS_SOURCE (original_source));
209 g_return_if_fail (window->priv->original_source == NULL);
210
211 window->priv->original_source = g_object_ref (original_source);
212 }
213
214 static void
215 mail_config_window_set_session (EMailConfigWindow *window,
216 EMailSession *session)
217 {
218 g_return_if_fail (E_IS_MAIL_SESSION (session));
219 g_return_if_fail (window->priv->session == NULL);
220
221 window->priv->session = g_object_ref (session);
222 }
223
224 static void
225 mail_config_window_set_property (GObject *object,
226 guint property_id,
227 const GValue *value,
228 GParamSpec *pspec)
229 {
230 switch (property_id) {
231 case PROP_ORIGINAL_SOURCE:
232 mail_config_window_set_original_source (
233 E_MAIL_CONFIG_WINDOW (object),
234 g_value_get_object (value));
235 return;
236
237 case PROP_SESSION:
238 mail_config_window_set_session (
239 E_MAIL_CONFIG_WINDOW (object),
240 g_value_get_object (value));
241 return;
242 }
243
244 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
245 }
246
247 static void
248 mail_config_window_get_property (GObject *object,
249 guint property_id,
250 GValue *value,
251 GParamSpec *pspec)
252 {
253 switch (property_id) {
254 case PROP_ORIGINAL_SOURCE:
255 g_value_set_object (
256 value,
257 e_mail_config_window_get_original_source (
258 E_MAIL_CONFIG_WINDOW (object)));
259 return;
260
261 case PROP_SESSION:
262 g_value_set_object (
263 value,
264 e_mail_config_window_get_session (
265 E_MAIL_CONFIG_WINDOW (object)));
266 return;
267 }
268
269 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
270 }
271
272 static void
273 mail_config_window_dispose (GObject *object)
274 {
275 EMailConfigWindowPrivate *priv;
276
277 priv = E_MAIL_CONFIG_WINDOW_GET_PRIVATE (object);
278
279 if (priv->session != NULL) {
280 g_object_unref (priv->session);
281 priv->session = NULL;
282 }
283
284 if (priv->original_source != NULL) {
285 g_object_unref (priv->original_source);
286 priv->original_source = NULL;
287 }
288
289 if (priv->account_source != NULL) {
290 g_object_unref (priv->account_source);
291 priv->account_source = NULL;
292 }
293
294 if (priv->identity_source != NULL) {
295 g_object_unref (priv->identity_source);
296 priv->identity_source = NULL;
297 }
298
299 if (priv->transport_source != NULL) {
300 g_object_unref (priv->transport_source);
301 priv->transport_source = NULL;
302 }
303
304 if (priv->collection_source != NULL) {
305 g_object_unref (priv->collection_source);
306 priv->collection_source = NULL;
307 }
308
309 /* Chain up to parent's dispose() method. */
310 G_OBJECT_CLASS (e_mail_config_window_parent_class)->dispose (object);
311 }
312
313 static void
314 mail_config_window_constructed (GObject *object)
315 {
316 EMailConfigWindow *window;
317 GtkWidget *container;
318 GtkWidget *widget;
319
320 window = E_MAIL_CONFIG_WINDOW (object);
321
322 /* Chain up to parent's constructed() method. */
323 G_OBJECT_CLASS (e_mail_config_window_parent_class)->
324 constructed (object);
325
326 mail_config_window_setup_scratch_sources (window);
327
328 gtk_container_set_border_width (GTK_CONTAINER (window), 5);
329 gtk_window_set_title (GTK_WINDOW (window), _("Account Editor"));
330 gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
331
332 gtk_dialog_add_buttons (
333 GTK_DIALOG (window),
334 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
335 GTK_STOCK_OK, GTK_RESPONSE_OK,
336 NULL);
337
338 container = gtk_dialog_get_content_area (GTK_DIALOG (window));
339
340 widget = gtk_grid_new ();
341 gtk_grid_set_column_spacing (GTK_GRID (widget), 12);
342 gtk_container_set_border_width (GTK_CONTAINER (widget), 5);
343 gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
344 gtk_widget_show (widget);
345
346 container = widget;
347
348 widget = e_alert_bar_new ();
349 gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 3, 1);
350 window->priv->alert_bar = widget; /* not referenced */
351 /* EAlertBar controls its own visibility. */
352
353 /* Add an extra-wide margin to the left and bottom.
354 *
355 * XXX The bottom margin is tricky. We want a 24px margin between
356 * the notebook and the dialog action buttons, but we have to
357 * take style property defaults into consideration:
358 *
359 * 24 - action-area-border (5) - content-area-border (2) = 17
360 */
361 widget = e_mail_config_notebook_new (
362 window->priv->session,
363 window->priv->account_source,
364 window->priv->identity_source,
365 window->priv->transport_source,
366 window->priv->collection_source);
367 gtk_widget_set_hexpand (widget, TRUE);
368 gtk_widget_set_vexpand (widget, TRUE);
369 gtk_widget_set_margin_bottom (widget, 17);
370 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
371 gtk_grid_attach (GTK_GRID (container), widget, 2, 1, 1, 1);
372 window->priv->notebook = widget; /* not referenced */
373 gtk_widget_show (widget);
374
375 widget = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
376 gtk_widget_set_vexpand (widget, TRUE);
377 gtk_widget_set_valign (widget, GTK_ALIGN_FILL);
378 gtk_grid_attach (GTK_GRID (container), widget, 1, 1, 1, 1);
379 gtk_widget_show (widget);
380
381 widget = e_mail_config_sidebar_new (
382 E_MAIL_CONFIG_NOTEBOOK (window->priv->notebook));
383 gtk_widget_set_vexpand (widget, TRUE);
384 gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 1, 1);
385 gtk_widget_show (widget);
386
387 /* Make the Apply button insensitive when required
388 * fields in the notebook pages are incomplete. */
389
390 widget = gtk_dialog_get_widget_for_response (
391 GTK_DIALOG (window), GTK_RESPONSE_OK);
392
393 g_object_bind_property (
394 window->priv->notebook, "complete",
395 widget, "sensitive",
396 G_BINDING_SYNC_CREATE);
397 }
398
399 static void
400 mail_config_window_response (GtkDialog *dialog,
401 gint response_id)
402 {
403 /* Do not chain up. GtkDialog does not implement this method. */
404
405 switch (response_id) {
406 case GTK_RESPONSE_OK:
407 mail_config_window_commit (
408 E_MAIL_CONFIG_WINDOW (dialog));
409 break;
410 case GTK_RESPONSE_CANCEL:
411 gtk_widget_destroy (GTK_WIDGET (dialog));
412 break;
413 default:
414 break;
415 }
416 }
417
418 static void
419 mail_config_window_submit_alert (EAlertSink *alert_sink,
420 EAlert *alert)
421 {
422 EMailConfigWindowPrivate *priv;
423 EAlertBar *alert_bar;
424 GtkWidget *dialog;
425 GtkWindow *parent;
426
427 priv = E_MAIL_CONFIG_WINDOW_GET_PRIVATE (alert_sink);
428
429 switch (e_alert_get_message_type (alert)) {
430 case GTK_MESSAGE_INFO:
431 case GTK_MESSAGE_WARNING:
432 case GTK_MESSAGE_ERROR:
433 alert_bar = E_ALERT_BAR (priv->alert_bar);
434 e_alert_bar_add_alert (alert_bar, alert);
435 break;
436
437 default:
438 parent = GTK_WINDOW (alert_sink);
439 dialog = e_alert_dialog_new (parent, alert);
440 gtk_dialog_run (GTK_DIALOG (dialog));
441 gtk_widget_destroy (dialog);
442 break;
443 }
444 }
445
446 static void
447 e_mail_config_window_class_init (EMailConfigWindowClass *class)
448 {
449 GObjectClass *object_class;
450 GtkDialogClass *dialog_class;
451
452 g_type_class_add_private (class, sizeof (EMailConfigWindowPrivate));
453
454 object_class = G_OBJECT_CLASS (class);
455 object_class->set_property = mail_config_window_set_property;
456 object_class->get_property = mail_config_window_get_property;
457 object_class->dispose = mail_config_window_dispose;
458 object_class->constructed = mail_config_window_constructed;
459
460 dialog_class = GTK_DIALOG_CLASS (class);
461 dialog_class->response = mail_config_window_response;
462
463 g_object_class_install_property (
464 object_class,
465 PROP_ORIGINAL_SOURCE,
466 g_param_spec_object (
467 "original-source",
468 "Original Source",
469 "Original mail account source",
470 E_TYPE_SOURCE,
471 G_PARAM_READWRITE |
472 G_PARAM_CONSTRUCT_ONLY |
473 G_PARAM_STATIC_STRINGS));
474
475 g_object_class_install_property (
476 object_class,
477 PROP_SESSION,
478 g_param_spec_object (
479 "session",
480 "Session",
481 "Mail session",
482 E_TYPE_MAIL_SESSION,
483 G_PARAM_READWRITE |
484 G_PARAM_CONSTRUCT_ONLY |
485 G_PARAM_STATIC_STRINGS));
486
487 signals[CHANGES_COMMITTED] = g_signal_new (
488 "changes-committed",
489 G_OBJECT_CLASS_TYPE (object_class),
490 G_SIGNAL_RUN_LAST,
491 G_STRUCT_OFFSET (EMailConfigWindowClass, changes_committed),
492 NULL, NULL,
493 g_cclosure_marshal_VOID__VOID,
494 G_TYPE_NONE, 0);
495 }
496
497 static void
498 e_mail_config_window_alert_sink_init (EAlertSinkInterface *interface)
499 {
500 interface->submit_alert = mail_config_window_submit_alert;
501 }
502
503 static void
504 e_mail_config_window_init (EMailConfigWindow *window)
505 {
506 window->priv = E_MAIL_CONFIG_WINDOW_GET_PRIVATE (window);
507 }
508
509 GtkWidget *
510 e_mail_config_window_new (EMailSession *session,
511 ESource *original_source)
512 {
513 g_return_val_if_fail (E_IS_MAIL_SESSION (session), NULL);
514 g_return_val_if_fail (E_IS_SOURCE (original_source), NULL);
515
516 return g_object_new (
517 E_TYPE_MAIL_CONFIG_WINDOW,
518 "original-source", original_source,
519 "session", session, NULL);
520 }
521
522 EMailSession *
523 e_mail_config_window_get_session (EMailConfigWindow *window)
524 {
525 g_return_val_if_fail (E_IS_MAIL_CONFIG_WINDOW (window), NULL);
526
527 return window->priv->session;
528 }
529
530 ESource *
531 e_mail_config_window_get_original_source (EMailConfigWindow *window)
532 {
533 g_return_val_if_fail (E_IS_MAIL_CONFIG_WINDOW (window), NULL);
534
535 return window->priv->original_source;
536 }