No issues found
1 /*
2 * evolution-cal-config-caldav.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 <config.h>
20 #include <glib/gi18n-lib.h>
21
22 #include <libebackend/libebackend.h>
23
24 #include <misc/e-cal-source-config.h>
25 #include <misc/e-interval-chooser.h>
26 #include <misc/e-source-config-backend.h>
27
28 #include "e-caldav-chooser.h"
29 #include "e-caldav-chooser-dialog.h"
30
31 #define HTTP_PORT 80
32 #define HTTPS_PORT 443
33
34 typedef ESourceConfigBackend ECalConfigCalDAV;
35 typedef ESourceConfigBackendClass ECalConfigCalDAVClass;
36
37 typedef struct _Context Context;
38
39 struct _Context {
40 ESourceConfigBackend *backend; /* not referenced */
41 ESource *scratch_source; /* not referenced */
42
43 GtkWidget *server_entry;
44 GtkWidget *path_entry;
45 GtkWidget *email_entry;
46 GtkWidget *find_button;
47 GtkWidget *auto_schedule_toggle;
48
49 GSocketConnectable *connectable;
50 };
51
52 /* Module Entry Points */
53 void e_module_load (GTypeModule *type_module);
54 void e_module_unload (GTypeModule *type_module);
55
56 /* Forward Declarations */
57 GType e_cal_config_caldav_get_type (void);
58
59 G_DEFINE_DYNAMIC_TYPE (
60 ECalConfigCalDAV,
61 e_cal_config_caldav,
62 E_TYPE_SOURCE_CONFIG_BACKEND)
63
64 static Context *
65 cal_config_caldav_context_new (ESourceConfigBackend *backend,
66 ESource *scratch_source)
67 {
68 Context *context;
69
70 context = g_slice_new0 (Context);
71 context->backend = backend;
72 context->scratch_source = scratch_source;
73
74 return context;
75 }
76
77 static void
78 cal_config_caldav_context_free (Context *context)
79 {
80 g_object_unref (context->server_entry);
81 g_object_unref (context->path_entry);
82 g_object_unref (context->email_entry);
83 g_object_unref (context->find_button);
84 g_object_unref (context->auto_schedule_toggle);
85
86 if (context->connectable != NULL)
87 g_object_unref (context->connectable);
88
89 g_slice_free (Context, context);
90 }
91
92 static gchar *
93 cal_config_caldav_get_server (ESource *scratch_source)
94 {
95 ESourceAuthentication *authentication_extension;
96 ESourceSecurity *security_extension;
97 const gchar *host;
98 gboolean secure;
99 guint16 default_port;
100 guint16 port;
101
102 authentication_extension = e_source_get_extension (
103 scratch_source, E_SOURCE_EXTENSION_AUTHENTICATION);
104 host = e_source_authentication_get_host (authentication_extension);
105 port = e_source_authentication_get_port (authentication_extension);
106
107 security_extension = e_source_get_extension (
108 scratch_source, E_SOURCE_EXTENSION_SECURITY);
109 secure = e_source_security_get_secure (security_extension);
110 default_port = secure ? HTTPS_PORT: HTTP_PORT;
111
112 if (port == 0)
113 port = default_port;
114
115 if (host == NULL || *host == '\0')
116 return NULL;
117
118 if (port == default_port)
119 return g_strdup (host);
120
121 return g_strdup_printf ("%s:%u", host, port);
122 }
123
124 static void
125 cal_config_caldav_server_changed_cb (GtkEntry *entry,
126 Context *context)
127 {
128 ESourceAuthentication *authentication_extension;
129 ESourceSecurity *security_extension;
130 const gchar *host_and_port;
131 const gchar *host;
132 gboolean secure;
133 guint16 default_port;
134 guint16 port;
135
136 if (context->connectable != NULL) {
137 g_object_unref (context->connectable);
138 context->connectable = NULL;
139 }
140
141 authentication_extension = e_source_get_extension (
142 context->scratch_source, E_SOURCE_EXTENSION_AUTHENTICATION);
143
144 security_extension = e_source_get_extension (
145 context->scratch_source, E_SOURCE_EXTENSION_SECURITY);
146
147 host_and_port = gtk_entry_get_text (entry);
148 secure = e_source_security_get_secure (security_extension);
149 default_port = secure ? HTTPS_PORT : HTTP_PORT;
150
151 if (host_and_port != NULL && *host_and_port != '\0')
152 context->connectable = g_network_address_parse (
153 host_and_port, default_port, NULL);
154
155 if (context->connectable != NULL) {
156 GNetworkAddress *address;
157
158 address = G_NETWORK_ADDRESS (context->connectable);
159 host = g_network_address_get_hostname (address);
160 port = g_network_address_get_port (address);
161 } else {
162 host = NULL;
163 port = 0;
164 }
165
166 e_source_authentication_set_host (authentication_extension, host);
167 e_source_authentication_set_port (authentication_extension, port);
168 }
169
170 static void
171 cal_config_caldav_run_dialog (GtkButton *button,
172 Context *context)
173 {
174 ESourceConfig *config;
175 ESourceRegistry *registry;
176 ECalClientSourceType source_type;
177 GtkWidget *dialog;
178 GtkWidget *widget;
179 gpointer parent;
180
181 config = e_source_config_backend_get_config (context->backend);
182 registry = e_source_config_get_registry (config);
183
184 parent = gtk_widget_get_toplevel (GTK_WIDGET (config));
185 parent = gtk_widget_is_toplevel (parent) ? parent : NULL;
186
187 source_type = e_cal_source_config_get_source_type (
188 E_CAL_SOURCE_CONFIG (config));
189
190 widget = e_caldav_chooser_new (
191 registry, context->scratch_source, source_type);
192
193 dialog = e_caldav_chooser_dialog_new (
194 E_CALDAV_CHOOSER (widget), parent);
195
196 if (parent != NULL)
197 g_object_bind_property (
198 parent, "icon-name",
199 dialog, "icon-name",
200 G_BINDING_SYNC_CREATE);
201
202 gtk_dialog_run (GTK_DIALOG (dialog));
203
204 gtk_widget_destroy (dialog);
205 }
206
207 static void
208 cal_config_caldav_insert_widgets (ESourceConfigBackend *backend,
209 ESource *scratch_source)
210 {
211 ESourceConfig *config;
212 ESource *collection_source;
213 ESourceExtension *extension;
214 ECalClientSourceType source_type;
215 GtkWidget *widget;
216 Context *context;
217 gchar *text;
218 const gchar *extension_name;
219 const gchar *label;
220 const gchar *uid;
221
222 config = e_source_config_backend_get_config (backend);
223 collection_source = e_source_config_get_collection_source (config);
224
225 e_cal_source_config_add_offline_toggle (
226 E_CAL_SOURCE_CONFIG (config), scratch_source);
227
228 /* If this data source is a collection member,
229 * just add a refresh interval and skip the rest. */
230 if (collection_source != NULL) {
231 e_source_config_add_refresh_interval (config, scratch_source);
232 return;
233 }
234
235 uid = e_source_get_uid (scratch_source);
236 context = cal_config_caldav_context_new (backend, scratch_source);
237
238 g_object_set_data_full (
239 G_OBJECT (backend), uid, context,
240 (GDestroyNotify) cal_config_caldav_context_free);
241
242 widget = gtk_entry_new ();
243 e_source_config_insert_widget (
244 config, scratch_source, _("Server:"), widget);
245 context->server_entry = g_object_ref (widget);
246 gtk_widget_show (widget);
247
248 /* Connect the signal before initializing the entry text. */
249 g_signal_connect (
250 widget, "changed",
251 G_CALLBACK (cal_config_caldav_server_changed_cb), context);
252
253 text = cal_config_caldav_get_server (scratch_source);
254 if (text != NULL) {
255 gtk_entry_set_text (GTK_ENTRY (context->server_entry), text);
256 g_free (text);
257 }
258
259 e_source_config_add_secure_connection_for_webdav (
260 config, scratch_source);
261
262 e_source_config_add_user_entry (config, scratch_source);
263
264 source_type = e_cal_source_config_get_source_type (
265 E_CAL_SOURCE_CONFIG (config));
266
267 switch (source_type) {
268 case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
269 label = _("Find Calendars");
270 break;
271 case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
272 label = _("Find Memo Lists");
273 break;
274 case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
275 label = _("Find Task Lists");
276 break;
277 default:
278 g_return_if_reached ();
279 }
280
281 widget = gtk_button_new_with_label (label);
282 e_source_config_insert_widget (
283 config, scratch_source, NULL, widget);
284 context->find_button = g_object_ref (widget);
285 gtk_widget_show (widget);
286
287 g_signal_connect (
288 widget, "clicked",
289 G_CALLBACK (cal_config_caldav_run_dialog), context);
290
291 widget = gtk_entry_new ();
292 e_source_config_insert_widget (
293 config, scratch_source, _("Path:"), widget);
294 context->path_entry = g_object_ref (widget);
295 gtk_widget_show (widget);
296
297 widget = gtk_entry_new ();
298 e_source_config_insert_widget (
299 config, scratch_source, _("Email:"), widget);
300 context->email_entry = g_object_ref (widget);
301 gtk_widget_show (widget);
302
303 widget = gtk_check_button_new_with_label (
304 _("Server handles meeting invitations"));
305 e_source_config_insert_widget (
306 config, scratch_source, NULL, widget);
307 context->auto_schedule_toggle = g_object_ref (widget);
308 gtk_widget_show (widget);
309
310 e_source_config_add_refresh_interval (config, scratch_source);
311
312 extension_name = E_SOURCE_EXTENSION_WEBDAV_BACKEND;
313 extension = e_source_get_extension (scratch_source, extension_name);
314
315 g_object_bind_property (
316 extension, "calendar-auto-schedule",
317 context->auto_schedule_toggle, "active",
318 G_BINDING_BIDIRECTIONAL |
319 G_BINDING_SYNC_CREATE);
320
321 g_object_bind_property (
322 extension, "email-address",
323 context->email_entry, "text",
324 G_BINDING_BIDIRECTIONAL |
325 G_BINDING_SYNC_CREATE);
326
327 g_object_bind_property (
328 extension, "resource-path",
329 context->path_entry, "text",
330 G_BINDING_BIDIRECTIONAL |
331 G_BINDING_SYNC_CREATE);
332 }
333
334 static gboolean
335 cal_config_caldav_check_complete (ESourceConfigBackend *backend,
336 ESource *scratch_source)
337 {
338 ESourceConfig *config;
339 ESource *collection_source;
340 Context *context;
341 const gchar *uid;
342 gboolean complete;
343
344 config = e_source_config_backend_get_config (backend);
345 collection_source = e_source_config_get_collection_source (config);
346
347 if (collection_source != NULL)
348 return TRUE;
349
350 uid = e_source_get_uid (scratch_source);
351 context = g_object_get_data (G_OBJECT (backend), uid);
352 g_return_val_if_fail (context != NULL, FALSE);
353
354 complete = (context->connectable != NULL);
355
356 gtk_widget_set_sensitive (context->find_button, complete);
357
358 return complete;
359 }
360
361 static void
362 e_cal_config_caldav_class_init (ESourceConfigBackendClass *class)
363 {
364 EExtensionClass *extension_class;
365
366 extension_class = E_EXTENSION_CLASS (class);
367 extension_class->extensible_type = E_TYPE_CAL_SOURCE_CONFIG;
368
369 class->parent_uid = "caldav-stub";
370 class->backend_name = "caldav";
371 class->insert_widgets = cal_config_caldav_insert_widgets;
372 class->check_complete = cal_config_caldav_check_complete;
373 }
374
375 static void
376 e_cal_config_caldav_class_finalize (ESourceConfigBackendClass *class)
377 {
378 }
379
380 static void
381 e_cal_config_caldav_init (ESourceConfigBackend *backend)
382 {
383 }
384
385 G_MODULE_EXPORT void
386 e_module_load (GTypeModule *type_module)
387 {
388 e_caldav_chooser_type_register (type_module);
389 e_caldav_chooser_dialog_type_register (type_module);
390 e_cal_config_caldav_register_type (type_module);
391 }
392
393 G_MODULE_EXPORT void
394 e_module_unload (GTypeModule *type_module)
395 {
396 }