No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | e-memo-list-selector.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None | |
clang-analyzer | no-output-found | e-memo-list-selector.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* e-memo-list-selector.c
3 *
4 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include <config.h>
22
23 #include "e-memo-list-selector.h"
24
25 #include <string.h>
26 #include <libecal/libecal.h>
27
28 #include "e-util/e-selection.h"
29 #include "calendar/gui/comp-util.h"
30
31 #define E_MEMO_LIST_SELECTOR_GET_PRIVATE(obj) \
32 (G_TYPE_INSTANCE_GET_PRIVATE \
33 ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorPrivate))
34
35 struct _EMemoListSelectorPrivate {
36 gint dummy_value;
37 };
38
39 G_DEFINE_TYPE (
40 EMemoListSelector,
41 e_memo_list_selector,
42 E_TYPE_SOURCE_SELECTOR)
43
44 static gboolean
45 memo_list_selector_update_single_object (ECalClient *client,
46 icalcomponent *icalcomp)
47 {
48 gchar *uid = NULL;
49 icalcomponent *tmp_icalcomp;
50
51 uid = (gchar *) icalcomponent_get_uid (icalcomp);
52
53 if (e_cal_client_get_object_sync (client, uid, NULL, &tmp_icalcomp, NULL, NULL)) {
54 icalcomponent_free (tmp_icalcomp);
55
56 return e_cal_client_modify_object_sync (
57 client, icalcomp, CALOBJ_MOD_ALL, NULL, NULL);
58 }
59
60 if (!e_cal_client_create_object_sync (client, icalcomp, &uid, NULL, NULL))
61 return FALSE;
62
63 if (uid)
64 icalcomponent_set_uid (icalcomp, uid);
65
66 g_free (uid);
67
68 return TRUE;
69 }
70
71 static gboolean
72 memo_list_selector_update_objects (ECalClient *client,
73 icalcomponent *icalcomp)
74 {
75 icalcomponent *subcomp;
76 icalcomponent_kind kind;
77
78 kind = icalcomponent_isa (icalcomp);
79 if (kind == ICAL_VJOURNAL_COMPONENT)
80 return memo_list_selector_update_single_object (
81 client, icalcomp);
82 else if (kind != ICAL_VCALENDAR_COMPONENT)
83 return FALSE;
84
85 subcomp = icalcomponent_get_first_component (
86 icalcomp, ICAL_ANY_COMPONENT);
87 while (subcomp != NULL) {
88 gboolean success;
89
90 kind = icalcomponent_isa (subcomp);
91 if (kind == ICAL_VTIMEZONE_COMPONENT) {
92 icaltimezone *zone;
93 GError *error = NULL;
94
95 zone = icaltimezone_new ();
96 icaltimezone_set_component (zone, subcomp);
97
98 e_cal_client_add_timezone_sync (client, zone, NULL, &error);
99 icaltimezone_free (zone, 1);
100 if (error != NULL) {
101 g_warning (
102 "%s: Failed to add timezone: %s",
103 G_STRFUNC, error->message);
104 g_error_free (error);
105 return FALSE;
106 }
107 } else if (kind == ICAL_VJOURNAL_COMPONENT) {
108 success = memo_list_selector_update_single_object (
109 client, subcomp);
110 if (!success)
111 return FALSE;
112 }
113
114 subcomp = icalcomponent_get_next_component (
115 icalcomp, ICAL_ANY_COMPONENT);
116 }
117
118 return TRUE;
119 }
120
121 static void
122 client_opened_cb (GObject *source_object,
123 GAsyncResult *result,
124 gpointer user_data)
125 {
126 ESource *source = E_SOURCE (source_object);
127 EClient *client = NULL;
128 gchar *uid = user_data;
129 GError *error = NULL;
130
131 g_return_if_fail (uid != NULL);
132
133 e_client_utils_open_new_finish (source, result, &client, &error);
134
135 if (error != NULL) {
136 g_warn_if_fail (client == NULL);
137 g_warning (
138 "%s: Failed to open memo list: %s",
139 G_STRFUNC, error->message);
140 g_error_free (error);
141 goto exit;
142 }
143
144 g_return_if_fail (E_IS_CLIENT (client));
145
146 if (!e_client_is_readonly (client))
147 e_cal_client_remove_object_sync (
148 E_CAL_CLIENT (client), uid, NULL,
149 CALOBJ_MOD_THIS, NULL, NULL);
150
151 g_object_unref (client);
152
153 exit:
154 g_free (uid);
155 }
156
157 static gboolean
158 memo_list_selector_process_data (ESourceSelector *selector,
159 ECalClient *client,
160 const gchar *source_uid,
161 icalcomponent *icalcomp,
162 GdkDragAction action)
163 {
164 ESource *source;
165 ESourceRegistry *registry;
166 icalcomponent *tmp_icalcomp = NULL;
167 const gchar *uid;
168 gchar *old_uid = NULL;
169 gboolean success = FALSE;
170 GError *error = NULL;
171
172 /* FIXME Deal with GDK_ACTION_ASK. */
173 if (action == GDK_ACTION_COPY) {
174 old_uid = g_strdup (icalcomponent_get_uid (icalcomp));
175 uid = e_cal_component_gen_uid ();
176 icalcomponent_set_uid (icalcomp, uid);
177 }
178
179 uid = icalcomponent_get_uid (icalcomp);
180 if (old_uid == NULL)
181 old_uid = g_strdup (uid);
182
183 if (e_cal_client_get_object_sync (client, uid, NULL, &tmp_icalcomp, NULL, &error)) {
184 icalcomponent_free (tmp_icalcomp);
185 success = TRUE;
186 goto exit;
187 }
188
189 if (error != NULL && !g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) {
190 g_message (
191 "Failed to search the object in destination "
192 "task list: %s", error->message);
193 g_error_free (error);
194 goto exit;
195 }
196
197 if (error)
198 g_error_free (error);
199
200 success = memo_list_selector_update_objects (client, icalcomp);
201
202 if (!success || action != GDK_ACTION_MOVE)
203 goto exit;
204
205 registry = e_source_selector_get_registry (selector);
206 source = e_source_registry_ref_source (registry, source_uid);
207
208 if (source != NULL) {
209 e_client_utils_open_new (
210 source, E_CLIENT_SOURCE_TYPE_MEMOS, TRUE, NULL,
211 client_opened_cb, g_strdup (old_uid));
212 g_object_unref (source);
213 }
214
215 exit:
216 g_free (old_uid);
217
218 return success;
219 }
220
221 struct DropData
222 {
223 ESourceSelector *selector;
224 GdkDragAction action;
225 GSList *list;
226 };
227
228 static void
229 client_opened_for_drop_cb (GObject *source_object,
230 GAsyncResult *result,
231 gpointer user_data)
232 {
233 ESource *source = E_SOURCE (source_object);
234 struct DropData *dd = user_data;
235 EClient *client = NULL;
236 ECalClient *cal_client;
237 GSList *iter;
238 GError *error = NULL;
239
240 g_return_if_fail (dd != NULL);
241
242 e_client_utils_open_new_finish (source, result, &client, &error);
243
244 if (error != NULL) {
245 g_warn_if_fail (client == NULL);
246 g_warning (
247 "%s: Failed to open memo list: %s",
248 G_STRFUNC, error->message);
249 g_error_free (error);
250 goto exit;
251 }
252
253 g_return_if_fail (E_IS_CLIENT (client));
254
255 cal_client = E_CAL_CLIENT (client);
256
257 for (iter = dd->list; iter != NULL; iter = iter->next) {
258 gchar *source_uid = iter->data;
259 icalcomponent *icalcomp;
260 gchar *component_string;
261
262 /* Each string is "source_uid\ncomponent_string". */
263 component_string = strchr (source_uid, '\n');
264 if (component_string == NULL)
265 continue;
266
267 *component_string++ = '\0';
268 icalcomp = icalparser_parse_string (component_string);
269 if (icalcomp == NULL)
270 continue;
271
272 memo_list_selector_process_data (
273 dd->selector, cal_client, source_uid,
274 icalcomp, dd->action);
275
276 icalcomponent_free (icalcomp);
277 }
278
279 g_object_unref (client);
280
281 exit:
282 g_slist_foreach (dd->list, (GFunc) g_free, NULL);
283 g_slist_free (dd->list);
284 g_object_unref (dd->selector);
285 g_free (dd);
286 }
287
288 static void
289 memo_list_selector_constructed (GObject *object)
290 {
291 ESourceSelector *selector;
292 ESourceRegistry *registry;
293 ESource *source;
294
295 selector = E_SOURCE_SELECTOR (object);
296 registry = e_source_selector_get_registry (selector);
297 source = e_source_registry_ref_default_memo_list (registry);
298 e_source_selector_set_primary_selection (selector, source);
299 g_object_unref (source);
300
301 /* Chain up to parent's constructed() method. */
302 G_OBJECT_CLASS (e_memo_list_selector_parent_class)->
303 constructed (object);
304 }
305
306 static gboolean
307 memo_list_selector_data_dropped (ESourceSelector *selector,
308 GtkSelectionData *selection_data,
309 ESource *destination,
310 GdkDragAction action,
311 guint info)
312 {
313 struct DropData *dd;
314
315 dd = g_new0 (struct DropData, 1);
316 dd->selector = g_object_ref (selector);
317 dd->action = action;
318 dd->list = cal_comp_selection_get_string_list (selection_data);
319
320 e_client_utils_open_new (
321 destination, E_CLIENT_SOURCE_TYPE_MEMOS, TRUE, NULL,
322 client_opened_for_drop_cb, dd);
323
324 return TRUE;
325 }
326
327 static void
328 e_memo_list_selector_class_init (EMemoListSelectorClass *class)
329 {
330 GObjectClass *object_class;
331 ESourceSelectorClass *source_selector_class;
332
333 g_type_class_add_private (class, sizeof (EMemoListSelectorPrivate));
334
335 object_class = G_OBJECT_CLASS (class);
336 object_class->constructed = memo_list_selector_constructed;
337
338 source_selector_class = E_SOURCE_SELECTOR_CLASS (class);
339 source_selector_class->data_dropped = memo_list_selector_data_dropped;
340 }
341
342 static void
343 e_memo_list_selector_init (EMemoListSelector *selector)
344 {
345 selector->priv = E_MEMO_LIST_SELECTOR_GET_PRIVATE (selector);
346
347 gtk_drag_dest_set (
348 GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
349 NULL, 0, GDK_ACTION_COPY | GDK_ACTION_MOVE);
350
351 e_drag_dest_add_calendar_targets (GTK_WIDGET (selector));
352 }
353
354 GtkWidget *
355 e_memo_list_selector_new (ESourceRegistry *registry)
356 {
357 g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
358
359 return g_object_new (
360 E_TYPE_MEMO_LIST_SELECTOR,
361 "extension-name", E_SOURCE_EXTENSION_MEMO_LIST,
362 "registry", registry, NULL);
363 }