1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
10 *
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
13 *
14 *
15 * Authors:
16 * David Trowbridge <trowbrds@cs.colorado.edu>
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #include "evolution-config.h"
23
24 #include "url-editor-dialog.h"
25
26 #include <string.h>
27 #include <glib/gi18n.h>
28
29 #include <e-util/e-util.h>
30 #include <e-util/e-util-private.h>
31
32 #include <shell/e-shell.h>
33
G_DEFINE_TYPE(UrlEditorDialog,url_editor_dialog,GTK_TYPE_DIALOG)34 G_DEFINE_TYPE (
35 UrlEditorDialog,
36 url_editor_dialog,
37 GTK_TYPE_DIALOG)
38
39 static void
40 create_uri (UrlEditorDialog *dialog)
41 {
42 EPublishUri *uri;
43
44 uri = dialog->uri;
45
46 if (uri->service_type == TYPE_URI) {
47 g_free (uri->location);
48 uri->location = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->server_entry)));
49 } else {
50 const gchar *method = "file";
51 gchar *server, *file, *port, *username, *password;
52
53 server = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->server_entry)));
54 file = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->file_entry)));
55 port = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->port_entry)));
56 username = g_uri_escape_string (gtk_entry_get_text (GTK_ENTRY (dialog->username_entry)), "", FALSE);
57 password = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->password_entry)));
58
59 switch (uri->service_type) {
60 case TYPE_SMB:
61 method = "smb";
62 break;
63
64 case TYPE_SFTP:
65 method = "sftp";
66 break;
67
68 case TYPE_ANON_FTP:
69 g_free (username);
70 username = g_strdup ("anonymous");
71 method = "ftp";
72 break;
73
74 case TYPE_FTP:
75 method = "ftp";
76 break;
77
78 case TYPE_DAV:
79 method = "dav";
80 break;
81
82 case TYPE_DAVS:
83 method = "davs";
84 break;
85 }
86
87 g_free (uri->location);
88 uri->location = g_strdup_printf (
89 "%s://%s%s%s%s%s%s%s",
90 method,
91 username, (username[0] != '\0') ? "@" : "",
92 server,
93 (port[0] != '\0') ? ":" : "", port,
94 (file[0] != '/') ? "/" : "", file);
95
96 g_free (server);
97 g_free (file);
98 g_free (port);
99 g_free (username);
100 g_free (password);
101 }
102
103 uri->fb_duration_value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dialog->fb_duration_spin));
104 uri->fb_duration_type = gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->fb_duration_combo));
105 }
106
107 static void
check_input(UrlEditorDialog * dialog)108 check_input (UrlEditorDialog *dialog)
109 {
110 gint n = 0;
111 GList *sources;
112 EPublishUri *uri;
113
114 uri = dialog->uri;
115
116 if (gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->type_selector)) == URI_PUBLISH_AS_ICAL) {
117 gtk_widget_hide (dialog->fb_duration_label);
118 gtk_widget_hide (dialog->fb_duration_spin);
119 gtk_widget_hide (dialog->fb_duration_combo);
120 } else {
121 gtk_widget_show (dialog->fb_duration_label);
122 gtk_widget_show (dialog->fb_duration_spin);
123 gtk_widget_show (dialog->fb_duration_combo);
124 }
125
126 if (gtk_widget_get_sensitive (dialog->events_selector)) {
127 sources = e_source_selector_get_selection (
128 E_SOURCE_SELECTOR (dialog->events_selector));
129 n += g_list_length (sources);
130 g_list_free_full (sources, (GDestroyNotify) g_object_unref);
131 }
132 if (n == 0)
133 goto fail;
134
135 /* This should probably be more complex, since ' ' isn't a valid server name */
136 switch (uri->service_type) {
137 case TYPE_SMB:
138 case TYPE_SFTP:
139 case TYPE_FTP:
140 case TYPE_DAV:
141 case TYPE_DAVS:
142 case TYPE_ANON_FTP:
143 if (!strlen (gtk_entry_get_text (GTK_ENTRY (dialog->server_entry)))) goto fail;
144 if (!strlen (gtk_entry_get_text (GTK_ENTRY (dialog->file_entry)))) goto fail;
145 break;
146 case TYPE_URI:
147 if (!strlen (gtk_entry_get_text (GTK_ENTRY (dialog->server_entry)))) goto fail;
148 break;
149 }
150
151 create_uri (dialog);
152
153 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, TRUE);
154 return;
155 fail:
156 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
157 }
158
159 static void
source_selection_changed(ESourceSelector * selector,UrlEditorDialog * dialog)160 source_selection_changed (ESourceSelector *selector,
161 UrlEditorDialog *dialog)
162 {
163 check_input (dialog);
164 }
165
166 static void
publish_service_changed(GtkComboBox * combo,UrlEditorDialog * dialog)167 publish_service_changed (GtkComboBox *combo,
168 UrlEditorDialog *dialog)
169 {
170 gint selected = gtk_combo_box_get_active (combo);
171 EPublishUri *uri;
172
173 uri = dialog->uri;
174
175 /* Big mess that switches around all the fields to match the source type
176 * the user has selected. Tries to keep field contents where possible */
177 switch (selected) {
178 case TYPE_SMB:
179 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->server_label), "_Server:");
180 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->port_label), "_Port:");
181 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->port_label), "S_hare:");
182 gtk_entry_set_text (GTK_ENTRY (dialog->port_entry), "");
183 gtk_widget_show (dialog->file_hbox);
184 gtk_widget_show (dialog->optional_label);
185 gtk_widget_show (dialog->port_hbox);
186 gtk_widget_show (dialog->username_hbox);
187 gtk_widget_show (dialog->password_hbox);
188 gtk_widget_show (dialog->remember_pw);
189 break;
190 case TYPE_SFTP:
191 case TYPE_FTP:
192 case TYPE_DAV:
193 case TYPE_DAVS:
194 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->server_label), "_Server:");
195 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->port_label), "_Port:");
196 if (uri->service_type == TYPE_SMB)
197 gtk_entry_set_text (GTK_ENTRY (dialog->port_entry), "");
198 else if (uri->service_type == TYPE_URI)
199 gtk_entry_set_text (GTK_ENTRY (dialog->server_entry), "");
200 gtk_widget_show (dialog->file_hbox);
201 gtk_widget_show (dialog->optional_label);
202 gtk_widget_show (dialog->port_hbox);
203 gtk_widget_show (dialog->username_hbox);
204 gtk_widget_show (dialog->password_hbox);
205 gtk_widget_show (dialog->remember_pw);
206 break;
207 case TYPE_ANON_FTP:
208 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->server_label), "_Server:");
209 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->port_label), "_Port:");
210 if (uri->service_type == TYPE_SMB)
211 gtk_entry_set_text (GTK_ENTRY (dialog->port_entry), "");
212 else if (uri->service_type == TYPE_URI)
213 gtk_entry_set_text (GTK_ENTRY (dialog->server_entry), "");
214 gtk_widget_show (dialog->file_hbox);
215 gtk_widget_show (dialog->optional_label);
216 gtk_widget_show (dialog->port_hbox);
217 gtk_widget_hide (dialog->username_hbox);
218 gtk_widget_hide (dialog->password_hbox);
219 gtk_widget_hide (dialog->remember_pw);
220 break;
221 case TYPE_URI:
222 gtk_label_set_text_with_mnemonic (GTK_LABEL (dialog->server_label), "_Location (URI):");
223 if (uri->service_type != TYPE_URI)
224 gtk_entry_set_text (GTK_ENTRY (dialog->server_entry), "");
225 gtk_widget_hide (dialog->file_hbox);
226 gtk_widget_hide (dialog->optional_label);
227 gtk_widget_hide (dialog->port_hbox);
228 gtk_widget_hide (dialog->username_hbox);
229 gtk_widget_hide (dialog->password_hbox);
230 gtk_widget_hide (dialog->remember_pw);
231 }
232 uri->service_type = selected;
233 check_input (dialog);
234 }
235
236 static void
type_selector_changed(GtkComboBox * combo,UrlEditorDialog * dialog)237 type_selector_changed (GtkComboBox *combo,
238 UrlEditorDialog *dialog)
239 {
240 gint selected = gtk_combo_box_get_active (combo);
241 EPublishUri *uri;
242
243 uri = dialog->uri;
244 uri->publish_format = selected;
245
246 check_input (dialog);
247 }
248
249 static void
frequency_changed_cb(GtkComboBox * combo,UrlEditorDialog * dialog)250 frequency_changed_cb (GtkComboBox *combo,
251 UrlEditorDialog *dialog)
252 {
253 gint selected = gtk_combo_box_get_active (combo);
254
255 EPublishUri *uri;
256
257 uri = dialog->uri;
258 uri->publish_frequency = selected;
259 }
260
261 static void
server_entry_changed(GtkEntry * entry,UrlEditorDialog * dialog)262 server_entry_changed (GtkEntry *entry,
263 UrlEditorDialog *dialog)
264 {
265 check_input (dialog);
266 }
267
268 static void
file_entry_changed(GtkEntry * entry,UrlEditorDialog * dialog)269 file_entry_changed (GtkEntry *entry,
270 UrlEditorDialog *dialog)
271 {
272 check_input (dialog);
273 }
274
275 static void
port_entry_changed(GtkEntry * entry,UrlEditorDialog * dialog)276 port_entry_changed (GtkEntry *entry,
277 UrlEditorDialog *dialog)
278 {
279 }
280
281 static void
username_entry_changed(GtkEntry * entry,UrlEditorDialog * dialog)282 username_entry_changed (GtkEntry *entry,
283 UrlEditorDialog *dialog)
284 {
285 }
286
287 static void
password_entry_changed(GtkEntry * entry,UrlEditorDialog * dialog)288 password_entry_changed (GtkEntry *entry,
289 UrlEditorDialog *dialog)
290 {
291 }
292
293 static void
remember_pw_toggled(GtkToggleButton * toggle,UrlEditorDialog * dialog)294 remember_pw_toggled (GtkToggleButton *toggle,
295 UrlEditorDialog *dialog)
296 {
297 }
298
299 static void
set_from_uri(UrlEditorDialog * dialog)300 set_from_uri (UrlEditorDialog *dialog)
301 {
302 EPublishUri *uri;
303 SoupURI *soup_uri;
304 const gchar *scheme;
305 const gchar *user;
306 const gchar *host;
307 const gchar *path;
308 guint port;
309
310 uri = dialog->uri;
311
312 soup_uri = soup_uri_new (uri->location);
313 g_return_if_fail (soup_uri != NULL);
314
315 /* determine our service type */
316 scheme = soup_uri_get_scheme (soup_uri);
317 g_return_if_fail (scheme != NULL);
318
319 if (strcmp (scheme, "smb") == 0)
320 uri->service_type = TYPE_SMB;
321 else if (strcmp (scheme, "sftp") == 0)
322 uri->service_type = TYPE_SFTP;
323 else if (strcmp (scheme, "ftp") == 0)
324 /* we set TYPE_FTP here for now. if we don't find a
325 * username later, we'll change it to TYPE_ANON_FTP */
326 uri->service_type = TYPE_FTP;
327 else if (strcmp (scheme, "dav") == 0)
328 uri->service_type = TYPE_DAV;
329 else if (strcmp (scheme, "davs") == 0)
330 uri->service_type = TYPE_DAVS;
331 else
332 uri->service_type = TYPE_URI;
333
334 user = soup_uri_get_user (soup_uri);
335 host = soup_uri_get_host (soup_uri);
336 port = soup_uri_get_port (soup_uri);
337 path = soup_uri_get_path (soup_uri);
338
339 if (user != NULL)
340 gtk_entry_set_text (GTK_ENTRY (dialog->username_entry), user);
341
342 if (host != NULL)
343 gtk_entry_set_text (GTK_ENTRY (dialog->server_entry), host);
344
345 if (port > 0) {
346 gchar *port_str;
347 port_str = g_strdup_printf ("%d", port);
348 gtk_entry_set_text (GTK_ENTRY (dialog->port_entry), port_str);
349 g_free (port_str);
350 }
351
352 if (path != NULL)
353 gtk_entry_set_text (GTK_ENTRY (dialog->file_entry), path);
354
355 if (uri->service_type == TYPE_URI)
356 gtk_entry_set_text (GTK_ENTRY (dialog->server_entry), uri->location);
357
358 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->publish_service), uri->service_type);
359
360 soup_uri_free (soup_uri);
361 }
362
363 static gboolean
url_editor_dialog_construct(UrlEditorDialog * dialog)364 url_editor_dialog_construct (UrlEditorDialog *dialog)
365 {
366 EShell *shell;
367 GtkWidget *toplevel;
368 GtkWidget *content_area;
369 GtkSizeGroup *group;
370 EPublishUri *uri;
371 ESourceRegistry *registry;
372
373 dialog->builder = gtk_builder_new ();
374 e_load_ui_builder_definition (dialog->builder, "publish-calendar.ui");
375
376 #define GW(name) ((dialog->name) = e_builder_get_widget (dialog->builder, #name))
377 GW (type_selector);
378 GW (fb_duration_label);
379 GW (fb_duration_spin);
380 GW (fb_duration_combo);
381 GW (publish_frequency);
382
383 GW (events_swin);
384
385 GW (publish_service);
386 GW (server_entry);
387 GW (file_entry);
388
389 GW (port_entry);
390 GW (username_entry);
391 GW (password_entry);
392 GW (remember_pw);
393
394 GW (optional_label);
395
396 GW (port_hbox);
397 GW (username_hbox);
398 GW (password_hbox);
399 GW (server_hbox);
400 GW (file_hbox);
401
402 GW (port_label);
403 GW (username_label);
404 GW (password_label);
405 GW (server_label);
406 GW (file_label);
407 #undef GW
408
409 uri = dialog->uri;
410
411 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
412 toplevel = e_builder_get_widget (dialog->builder, "publishing toplevel");
413 gtk_container_add (GTK_CONTAINER (content_area), toplevel);
414
415 gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
416
417 dialog->cancel = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
418 dialog->ok = gtk_dialog_add_button (GTK_DIALOG (dialog), _("_OK"), GTK_RESPONSE_OK);
419 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
420 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
421 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
422
423 shell = e_shell_get_default ();
424 registry = e_shell_get_registry (shell);
425 dialog->events_selector = e_source_selector_new (
426 registry, E_SOURCE_EXTENSION_CALENDAR);
427 gtk_widget_show (dialog->events_selector);
428 gtk_container_add (GTK_CONTAINER (dialog->events_swin), dialog->events_selector);
429
430 group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
431 gtk_size_group_add_widget (group, dialog->type_selector);
432 gtk_size_group_add_widget (group, dialog->publish_frequency);
433 g_object_unref (group);
434
435 group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
436 gtk_size_group_add_widget (group, dialog->publish_service);
437 gtk_size_group_add_widget (group, dialog->server_entry);
438 gtk_size_group_add_widget (group, dialog->file_entry);
439 gtk_size_group_add_widget (group, dialog->port_entry);
440 gtk_size_group_add_widget (group, dialog->username_entry);
441 gtk_size_group_add_widget (group, dialog->password_entry);
442 g_object_unref (group);
443
444 if (uri == NULL) {
445 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->publish_frequency), 0);
446 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->type_selector), 0);
447 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->publish_service), 0);
448
449 dialog->uri = g_new0 (EPublishUri, 1);
450 uri = dialog->uri;
451 uri->enabled = TRUE;
452 } else {
453 ESource *source;
454 GSList *p;
455
456 for (p = uri->events; p; p = g_slist_next (p)) {
457 const gchar *uid = p->data;
458
459 source = e_source_registry_ref_source (
460 registry, uid);
461 e_source_selector_select_source (
462 E_SOURCE_SELECTOR (dialog->events_selector),
463 source);
464 g_object_unref (source);
465 }
466
467 if (uri->location && strlen (uri->location)) {
468 set_from_uri (dialog);
469 }
470
471 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->publish_frequency), uri->publish_frequency);
472 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->type_selector), uri->publish_format);
473
474 uri->password = e_passwords_get_password (uri->location);
475 if (uri->password) {
476 if (strlen (uri->password) != 0) {
477 gtk_entry_set_text (GTK_ENTRY (dialog->password_entry), uri->password);
478 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->remember_pw), TRUE);
479 } else {
480 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->remember_pw), FALSE);
481 }
482 }
483 }
484
485 gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->fb_duration_spin), uri->fb_duration_value);
486 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->fb_duration_combo), uri->fb_duration_type);
487
488 type_selector_changed (GTK_COMBO_BOX (dialog->type_selector), dialog);
489 frequency_changed_cb (GTK_COMBO_BOX (dialog->publish_frequency), dialog);
490 publish_service_changed (GTK_COMBO_BOX (dialog->publish_service), dialog);
491
492 g_signal_connect (
493 dialog->publish_service, "changed",
494 G_CALLBACK (publish_service_changed), dialog);
495 g_signal_connect (
496 dialog->type_selector, "changed",
497 G_CALLBACK (type_selector_changed), dialog);
498 g_signal_connect (
499 dialog->publish_frequency, "changed",
500 G_CALLBACK (frequency_changed_cb), dialog);
501 g_signal_connect (
502 dialog->events_selector, "selection_changed",
503 G_CALLBACK (source_selection_changed), dialog);
504
505 g_signal_connect (
506 dialog->server_entry, "changed",
507 G_CALLBACK (server_entry_changed), dialog);
508 g_signal_connect (
509 dialog->file_entry, "changed",
510 G_CALLBACK (file_entry_changed), dialog);
511 g_signal_connect (
512 dialog->port_entry, "changed",
513 G_CALLBACK (port_entry_changed), dialog);
514 g_signal_connect (
515 dialog->username_entry, "changed",
516 G_CALLBACK (username_entry_changed), dialog);
517 g_signal_connect (
518 dialog->password_entry,"changed",
519 G_CALLBACK (password_entry_changed), dialog);
520 g_signal_connect (
521 dialog->remember_pw, "toggled",
522 G_CALLBACK (remember_pw_toggled), dialog);
523
524 check_input (dialog);
525
526 return TRUE;
527 }
528
529 GtkWidget *
url_editor_dialog_new(GtkTreeModel * url_list_model,EPublishUri * uri)530 url_editor_dialog_new (GtkTreeModel *url_list_model,
531 EPublishUri *uri)
532 {
533 UrlEditorDialog *dialog;
534
535 dialog = (UrlEditorDialog *) g_object_new (URL_EDITOR_DIALOG_TYPE, NULL);
536 dialog->url_list_model = g_object_ref (url_list_model);
537 dialog->uri = uri;
538
539 if (!uri)
540 gtk_window_set_title (GTK_WINDOW (dialog), _("New Location"));
541 else
542 gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Location"));
543
544 if (url_editor_dialog_construct (dialog))
545 return GTK_WIDGET (dialog);
546
547 g_object_unref (dialog);
548 return NULL;
549 }
550
551 static void
url_editor_dialog_dispose(GObject * obj)552 url_editor_dialog_dispose (GObject *obj)
553 {
554 UrlEditorDialog *dialog = (UrlEditorDialog *) obj;
555
556 g_clear_object (&dialog->url_list_model);
557 g_clear_object (&dialog->builder);
558
559 G_OBJECT_CLASS (url_editor_dialog_parent_class)->dispose (obj);
560 }
561
562 static void
url_editor_dialog_class_init(UrlEditorDialogClass * class)563 url_editor_dialog_class_init (UrlEditorDialogClass *class)
564 {
565 GObjectClass *object_class;
566
567 object_class = G_OBJECT_CLASS (class);
568 object_class->dispose = url_editor_dialog_dispose;
569 }
570
571 static void
url_editor_dialog_init(UrlEditorDialog * dialog)572 url_editor_dialog_init (UrlEditorDialog *dialog)
573 {
574 }
575
576 gboolean
url_editor_dialog_run(UrlEditorDialog * dialog)577 url_editor_dialog_run (UrlEditorDialog *dialog)
578 {
579 gint response;
580
581 response = gtk_dialog_run (GTK_DIALOG (dialog));
582 if (response == GTK_RESPONSE_OK) {
583 GList *list, *link;
584
585 g_free (dialog->uri->password);
586 if (dialog->uri->events) {
587 g_slist_foreach (dialog->uri->events, (GFunc) g_free, NULL);
588 dialog->uri->events = NULL;
589 }
590
591 create_uri (dialog);
592
593 dialog->uri->password = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->password_entry)));
594
595 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->remember_pw))) {
596 e_passwords_add_password (dialog->uri->location, dialog->uri->password);
597 e_passwords_remember_password (dialog->uri->location);
598 } else {
599 e_passwords_forget_password (dialog->uri->location);
600 }
601
602 list = e_source_selector_get_selection (
603 E_SOURCE_SELECTOR (dialog->events_selector));
604
605 for (link = list; link != NULL; link = g_list_next (link)) {
606 ESource *source;
607 const gchar *uid;
608
609 source = E_SOURCE (link->data);
610 uid = e_source_get_uid (source);
611 dialog->uri->events = g_slist_append (
612 dialog->uri->events, g_strdup (uid));
613 }
614
615 g_list_free_full (list, (GDestroyNotify) g_object_unref);
616 }
617 gtk_widget_hide (GTK_WIDGET (dialog));
618
619 return response == GTK_RESPONSE_OK;
620 }
621