evolution-3.6.4/modules/calendar/e-memo-shell-backend.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-memo-shell-backend.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-memo-shell-backend.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * e-memo-shell-backend.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  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 19  *
 20  */
 21 
 22 #ifdef HAVE_CONFIG_H
 23 #include <config.h>
 24 #endif
 25 
 26 #include "e-memo-shell-backend.h"
 27 
 28 #include <string.h>
 29 #include <glib/gi18n.h>
 30 #include <libecal/libecal.h>
 31 #include <libedataserverui/libedataserverui.h>
 32 
 33 #include "shell/e-shell.h"
 34 #include "shell/e-shell-backend.h"
 35 #include "shell/e-shell-window.h"
 36 #include "widgets/misc/e-cal-source-config.h"
 37 #include "widgets/misc/e-source-config-dialog.h"
 38 
 39 #include "calendar/gui/comp-util.h"
 40 #include "calendar/gui/dialogs/memo-editor.h"
 41 
 42 #include "e-memo-shell-migrate.h"
 43 #include "e-memo-shell-view.h"
 44 
 45 #define E_MEMO_SHELL_BACKEND_GET_PRIVATE(obj) \
 46 	(G_TYPE_INSTANCE_GET_PRIVATE \
 47 	((obj), E_TYPE_MEMO_SHELL_BACKEND, EMemoShellBackendPrivate))
 48 
 49 #define E_MEMO_SHELL_BACKEND_GET_PRIVATE(obj) \
 50 	(G_TYPE_INSTANCE_GET_PRIVATE \
 51 	((obj), E_TYPE_MEMO_SHELL_BACKEND, EMemoShellBackendPrivate))
 52 
 53 struct _EMemoShellBackendPrivate {
 54 	gint placeholder;
 55 };
 56 
 57 G_DEFINE_DYNAMIC_TYPE (
 58 	EMemoShellBackend,
 59 	e_memo_shell_backend,
 60 	E_TYPE_SHELL_BACKEND)
 61 
 62 static void
 63 memo_shell_backend_new_memo (ESource *source,
 64                              GAsyncResult *result,
 65                              EShell *shell,
 66                              CompEditorFlags flags)
 67 {
 68 	EClient *client = NULL;
 69 	ECalClient *cal_client;
 70 	ECalComponent *comp;
 71 	CompEditor *editor;
 72 	GError *error = NULL;
 73 
 74 	e_client_utils_open_new_finish (source, result, &client, &error);
 75 
 76 	/* XXX Handle errors better. */
 77 	if (error != NULL) {
 78 		g_warn_if_fail (client == NULL);
 79 		g_warning (
 80 			"%s: Failed to open '%s': %s",
 81 			G_STRFUNC, e_source_get_display_name (source),
 82 			error->message);
 83 		g_error_free (error);
 84 		return;
 85 	}
 86 
 87 	g_return_if_fail (E_IS_CAL_CLIENT (client));
 88 
 89 	cal_client = E_CAL_CLIENT (client);
 90 	comp = cal_comp_memo_new_with_defaults (cal_client);
 91 	cal_comp_update_time_by_active_window (comp, shell);
 92 	editor = memo_editor_new (cal_client, shell, flags);
 93 	comp_editor_edit_comp (editor, comp);
 94 
 95 	gtk_window_present (GTK_WINDOW (editor));
 96 
 97 	g_object_unref (comp);
 98 	g_object_unref (client);
 99 }
100 
101 static void
102 memo_shell_backend_memo_new_cb (GObject *source_object,
103                                 GAsyncResult *result,
104                                 gpointer shell)
105 {
106 	CompEditorFlags flags = 0;
107 
108 	flags |= COMP_EDITOR_NEW_ITEM;
109 
110 	memo_shell_backend_new_memo (
111 		E_SOURCE (source_object), result, shell, flags);
112 
113 	g_object_unref (shell);
114 }
115 
116 static void
117 memo_shell_backend_memo_shared_new_cb (GObject *source_object,
118                                        GAsyncResult *result,
119                                        gpointer shell)
120 {
121 	CompEditorFlags flags = 0;
122 
123 	flags |= COMP_EDITOR_NEW_ITEM;
124 	flags |= COMP_EDITOR_IS_SHARED;
125 	flags |= COMP_EDITOR_USER_ORG;
126 
127 	memo_shell_backend_new_memo (
128 		E_SOURCE (source_object), result, shell, flags);
129 
130 	g_object_unref (shell);
131 }
132 
133 static void
134 action_memo_new_cb (GtkAction *action,
135                     EShellWindow *shell_window)
136 {
137 	EShell *shell;
138 	ESource *source;
139 	ESourceRegistry *registry;
140 	EClientSourceType source_type;
141 	const gchar *action_name;
142 
143 	/* This callback is used for both memos and shared memos. */
144 
145 	shell = e_shell_window_get_shell (shell_window);
146 
147 	registry = e_shell_get_registry (shell);
148 	source_type = E_CLIENT_SOURCE_TYPE_MEMOS;
149 	source = e_source_registry_ref_default_memo_list (registry);
150 
151 	/* Use a callback function appropriate for the action.
152 	 * FIXME Need to obtain a better default time zone. */
153 	action_name = gtk_action_get_name (action);
154 	if (g_strcmp0 (action_name, "memo-shared-new") == 0)
155 		e_client_utils_open_new (
156 			source, source_type, FALSE, NULL,
157 			memo_shell_backend_memo_shared_new_cb,
158 			g_object_ref (shell));
159 	else
160 		e_client_utils_open_new (
161 			source, source_type, FALSE, NULL,
162 			memo_shell_backend_memo_new_cb,
163 			g_object_ref (shell));
164 
165 	g_object_unref (source);
166 }
167 
168 static void
169 action_memo_list_new_cb (GtkAction *action,
170                          EShellWindow *shell_window)
171 {
172 	EShell *shell;
173 	ESourceRegistry *registry;
174 	ECalClientSourceType source_type;
175 	GtkWidget *config;
176 	GtkWidget *dialog;
177 	const gchar *icon_name;
178 
179 	shell = e_shell_window_get_shell (shell_window);
180 
181 	registry = e_shell_get_registry (shell);
182 	source_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
183 	config = e_cal_source_config_new (registry, NULL, source_type);
184 
185 	dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config));
186 
187 	gtk_window_set_transient_for (
188 		GTK_WINDOW (dialog), GTK_WINDOW (shell_window));
189 
190 	icon_name = gtk_action_get_icon_name (action);
191 	gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name);
192 
193 	gtk_window_set_title (GTK_WINDOW (dialog), _("New Memo List"));
194 
195 	gtk_widget_show (dialog);
196 }
197 
198 static GtkActionEntry item_entries[] = {
199 
200 	{ "memo-new",
201 	  "stock_insert-note",
202 	  NC_("New", "Mem_o"),
203 	  "<Shift><Control>o",
204 	  N_("Create a new memo"),
205 	  G_CALLBACK (action_memo_new_cb) },
206 
207 	{ "memo-shared-new",
208 	  "stock_insert-note",
209 	  NC_("New", "_Shared Memo"),
210 	  "<Shift><Control>h",
211 	  N_("Create a new shared memo"),
212 	  G_CALLBACK (action_memo_new_cb) }
213 };
214 
215 static GtkActionEntry source_entries[] = {
216 
217 	{ "memo-list-new",
218 	  "stock_notes",
219 	  NC_("New", "Memo Li_st"),
220 	  NULL,
221 	  N_("Create a new memo list"),
222 	  G_CALLBACK (action_memo_list_new_cb) }
223 };
224 
225 static gboolean
226 memo_shell_backend_handle_uri_cb (EShellBackend *shell_backend,
227                                   const gchar *uri)
228 {
229 	EShell *shell;
230 	CompEditor *editor;
231 	CompEditorFlags flags = 0;
232 	ECalClient *client;
233 	ECalComponent *comp;
234 	ESource *source;
235 	ESourceRegistry *registry;
236 	ECalClientSourceType source_type;
237 	SoupURI *soup_uri;
238 	icalcomponent *icalcomp;
239 	const gchar *cp;
240 	gchar *source_uid = NULL;
241 	gchar *comp_uid = NULL;
242 	gchar *comp_rid = NULL;
243 	gboolean handled = FALSE;
244 	GError *error = NULL;
245 
246 	source_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
247 	shell = e_shell_backend_get_shell (shell_backend);
248 
249 	if (strncmp (uri, "memo:", 5) != 0)
250 		return FALSE;
251 
252 	soup_uri = soup_uri_new (uri);
253 
254 	if (soup_uri == NULL)
255 		return FALSE;
256 
257 	cp = soup_uri_get_query (soup_uri);
258 	if (cp == NULL)
259 		goto exit;
260 
261 	while (*cp != '\0') {
262 		gchar *header;
263 		gchar *content;
264 		gsize header_len;
265 		gsize content_len;
266 
267 		header_len = strcspn (cp, "=&");
268 
269 		/* If it's malformed, give up. */
270 		if (cp[header_len] != '=')
271 			break;
272 
273 		header = (gchar *) cp;
274 		header[header_len] = '\0';
275 		cp += header_len + 1;
276 
277 		content_len = strcspn (cp, "&");
278 
279 		content = g_strndup (cp, content_len);
280 		if (g_ascii_strcasecmp (header, "source-uid") == 0)
281 			source_uid = g_strdup (content);
282 		else if (g_ascii_strcasecmp (header, "comp-uid") == 0)
283 			comp_uid = g_strdup (content);
284 		else if (g_ascii_strcasecmp (header, "comp-rid") == 0)
285 			comp_rid = g_strdup (content);
286 		g_free (content);
287 
288 		cp += content_len;
289 		if (*cp == '&') {
290 			cp++;
291 			if (strcmp (cp, "amp;") == 0)
292 				cp += 4;
293 		}
294 	}
295 
296 	if (source_uid == NULL || comp_uid == NULL)
297 		goto exit;
298 
299 	/* URI is valid, so consider it handled.  Whether
300 	 * we successfully open it is another matter... */
301 	handled = TRUE;
302 
303 	registry = e_shell_get_registry (shell);
304 	source = e_source_registry_ref_source (registry, source_uid);
305 	if (source == NULL) {
306 		g_printerr ("No source for UID '%s'\n", source_uid);
307 		goto exit;
308 	}
309 
310 	client = e_cal_client_new (source, source_type, &error);
311 
312 	if (client != NULL)
313 		e_client_open_sync (E_CLIENT (client), TRUE, NULL, &error);
314 
315 	if (error != NULL) {
316 		g_warning (
317 			"%s: Failed to create/open client: %s",
318 			G_STRFUNC, error->message);
319 		if (client != NULL)
320 			g_object_unref (client);
321 		g_object_unref (source);
322 		g_error_free (error);
323 		goto exit;
324 	}
325 
326 	g_object_unref (source);
327 	source = NULL;
328 
329 	/* XXX Copied from e_memo_shell_view_open_memo().
330 	 *     Clearly a new utility function is needed. */
331 
332 	editor = comp_editor_find_instance (comp_uid);
333 
334 	if (editor != NULL)
335 		goto present;
336 
337 	e_cal_client_get_object_sync (
338 		client, comp_uid, comp_rid, &icalcomp, NULL, &error);
339 
340 	if (error != NULL) {
341 		g_warning (
342 			"%s: Failed to get object: %s",
343 			G_STRFUNC, error->message);
344 		g_object_unref (client);
345 		g_error_free (error);
346 		goto exit;
347 	}
348 
349 	comp = e_cal_component_new ();
350 	if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
351 		g_warning ("%s: Failed to set icalcomp to comp\n", G_STRFUNC);
352 		icalcomponent_free (icalcomp);
353 		icalcomp = NULL;
354 	}
355 
356 	if (e_cal_component_has_organizer (comp))
357 		flags |= COMP_EDITOR_IS_SHARED;
358 
359 	if (itip_organizer_is_user (registry, comp, client))
360 		flags |= COMP_EDITOR_USER_ORG;
361 
362 	editor = memo_editor_new (client, shell, flags);
363 	comp_editor_edit_comp (editor, comp);
364 
365 	g_object_unref (comp);
366 
367 present:
368 	gtk_window_present (GTK_WINDOW (editor));
369 
370 	g_object_unref (client);
371 
372 exit:
373 	g_free (source_uid);
374 	g_free (comp_uid);
375 	g_free (comp_rid);
376 
377 	soup_uri_free (soup_uri);
378 
379 	return handled;
380 }
381 
382 static void
383 memo_shell_backend_window_added_cb (EShellBackend *shell_backend,
384                                     GtkWindow *window)
385 {
386 	const gchar *module_name;
387 
388 	if (!E_IS_SHELL_WINDOW (window))
389 		return;
390 
391 	module_name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
392 
393 	e_shell_window_register_new_item_actions (
394 		E_SHELL_WINDOW (window), module_name,
395 		item_entries, G_N_ELEMENTS (item_entries));
396 
397 	e_shell_window_register_new_source_actions (
398 		E_SHELL_WINDOW (window), module_name,
399 		source_entries, G_N_ELEMENTS (source_entries));
400 }
401 
402 static void
403 memo_shell_backend_constructed (GObject *object)
404 {
405 	EShell *shell;
406 	EShellBackend *shell_backend;
407 
408 	shell_backend = E_SHELL_BACKEND (object);
409 	shell = e_shell_backend_get_shell (shell_backend);
410 
411 	g_signal_connect_swapped (
412 		shell, "handle-uri",
413 		G_CALLBACK (memo_shell_backend_handle_uri_cb),
414 		shell_backend);
415 
416 	g_signal_connect_swapped (
417 		shell, "window-added",
418 		G_CALLBACK (memo_shell_backend_window_added_cb),
419 		shell_backend);
420 
421 	/* Chain up to parent's constructed() method. */
422 	G_OBJECT_CLASS (e_memo_shell_backend_parent_class)->constructed (object);
423 }
424 
425 static void
426 e_memo_shell_backend_class_init (EMemoShellBackendClass *class)
427 {
428 	GObjectClass *object_class;
429 	EShellBackendClass *shell_backend_class;
430 
431 	g_type_class_add_private (class, sizeof (EMemoShellBackendPrivate));
432 
433 	object_class = G_OBJECT_CLASS (class);
434 	object_class->constructed = memo_shell_backend_constructed;
435 
436 	shell_backend_class = E_SHELL_BACKEND_CLASS (class);
437 	shell_backend_class->shell_view_type = E_TYPE_MEMO_SHELL_VIEW;
438 	shell_backend_class->name = "memos";
439 	shell_backend_class->aliases = "";
440 	shell_backend_class->schemes = "memo";
441 	shell_backend_class->sort_order = 600;
442 	shell_backend_class->preferences_page = "calendar-and-tasks";
443 	shell_backend_class->start = NULL;
444 	shell_backend_class->migrate = e_memo_shell_backend_migrate;
445 
446 	/* Register relevant ESource extensions. */
447 	E_TYPE_SOURCE_MEMO_LIST;
448 }
449 
450 static void
451 e_memo_shell_backend_class_finalize (EMemoShellBackendClass *class)
452 {
453 }
454 
455 static void
456 e_memo_shell_backend_init (EMemoShellBackend *memo_shell_backend)
457 {
458 	memo_shell_backend->priv =
459 		E_MEMO_SHELL_BACKEND_GET_PRIVATE (memo_shell_backend);
460 }
461 
462 void
463 e_memo_shell_backend_type_register (GTypeModule *type_module)
464 {
465 	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
466 	 *     function, so we have to wrap it with a public function in
467 	 *     order to register types from a separate compilation unit. */
468 	e_memo_shell_backend_register_type (type_module);
469 }