No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Rodrigo Moya <rodrigo@novell.com>
18 * Philip Van Hoof <pvanhoof@gnome.org>
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 *
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <string.h>
29 #include <glib/gi18n.h>
30
31 #include "format-handler.h"
32
33 static void
34 display_error_message (GtkWidget *parent,
35 const gchar *message)
36 {
37 GtkWidget *dialog;
38
39 dialog = gtk_message_dialog_new (GTK_WINDOW (parent), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", message);
40 gtk_dialog_run (GTK_DIALOG (dialog));
41 gtk_widget_destroy (dialog);
42 }
43
44 typedef struct {
45 GHashTable *zones;
46 ECalClient *client;
47 } CompTzData;
48
49 static void
50 insert_tz_comps (icalparameter *param,
51 gpointer cb_data)
52 {
53 const gchar *tzid;
54 CompTzData *tdata = cb_data;
55 icaltimezone *zone = NULL;
56 icalcomponent *tzcomp;
57 GError *error = NULL;
58
59 tzid = icalparameter_get_tzid (param);
60
61 if (g_hash_table_lookup (tdata->zones, tzid))
62 return;
63
64 if (!e_cal_client_get_timezone_sync (tdata->client, tzid, &zone, NULL, &error)) {
65 g_warning ("Could not get the timezone information for %s : %s \n", tzid, error->message);
66 g_error_free (error);
67 return;
68 }
69
70 tzcomp = icalcomponent_new_clone (icaltimezone_get_component (zone));
71 g_hash_table_insert (tdata->zones, (gpointer) tzid, (gpointer) tzcomp);
72 }
73
74 static void
75 append_tz_to_comp (gpointer key,
76 gpointer value,
77 icalcomponent *toplevel)
78 {
79 icalcomponent_add_component (toplevel, (icalcomponent *) value);
80 }
81
82 static void
83 do_save_calendar_ical (FormatHandler *handler,
84 ESourceSelector *selector,
85 ECalClientSourceType type,
86 gchar *dest_uri)
87 {
88 ESource *primary_source;
89 ECalClient *source_client;
90 GError *error = NULL;
91 GSList *objects = NULL;
92 icalcomponent *top_level = NULL;
93
94 if (!dest_uri)
95 return;
96
97 /* open source client */
98 primary_source = e_source_selector_ref_primary_selection (selector);
99 source_client = e_cal_client_new (primary_source, type, &error);
100 g_object_unref (primary_source);
101
102 if (!source_client || !e_client_open_sync (E_CLIENT (source_client), TRUE, NULL, &error)) {
103 display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (selector)), error->message);
104 if (source_client)
105 g_object_unref (source_client);
106 g_error_free (error);
107 return;
108 }
109
110 /* create destination file */
111 top_level = e_cal_util_new_top_level ();
112
113 error = NULL;
114 if (e_cal_client_get_object_list_sync (source_client, "#t", &objects, NULL, &error)) {
115 CompTzData tdata;
116 GOutputStream *stream;
117 GSList *iter;
118
119 tdata.zones = g_hash_table_new (g_str_hash, g_str_equal);
120 tdata.client = source_client;
121
122 for (iter = objects; iter; iter = iter->next) {
123 icalcomponent *icalcomp = icalcomponent_new_clone (iter->data);
124
125 icalcomponent_foreach_tzid (icalcomp, insert_tz_comps, &tdata);
126 icalcomponent_add_component (top_level, icalcomp);
127 }
128
129 g_hash_table_foreach (tdata.zones, (GHFunc) append_tz_to_comp, top_level);
130
131 g_hash_table_destroy (tdata.zones);
132 tdata.zones = NULL;
133
134 /* save the file */
135 stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (selector))), dest_uri, &error);
136
137 if (stream) {
138 gchar *ical_str = icalcomponent_as_ical_string_r (top_level);
139
140 g_output_stream_write_all (stream, ical_str, strlen (ical_str), NULL, NULL, &error);
141 g_output_stream_close (stream, NULL, NULL);
142
143 g_object_unref (stream);
144 g_free (ical_str);
145 }
146
147 e_cal_client_free_icalcomp_slist (objects);
148 }
149
150 if (error) {
151 display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (selector)), error->message);
152 g_error_free (error);
153 }
154
155 /* terminate */
156 g_object_unref (source_client);
157 icalcomponent_free (top_level);
158 }
159
160 FormatHandler *ical_format_handler_new (void)
161 {
162 FormatHandler *handler = g_new (FormatHandler, 1);
163
164 handler->isdefault = TRUE;
165 handler->combo_label = _("iCalendar (.ics)");
166 handler->filename_ext = ".ics";
167 handler->options_widget = NULL;
168 handler->save = do_save_calendar_ical;
169 handler->data = NULL;
170
171 return handler;
172 }