evolution-3.6.4/addressbook/gui/widgets/e-minicard-view.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-minicard-view.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-minicard-view.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  * 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  *		Chris Lahey <clahey@ximian.com>
 18  *
 19  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 20  *
 21  */
 22 
 23 #ifdef HAVE_CONFIG_H
 24 #include <config.h>
 25 #endif
 26 
 27 #include "e-minicard-view.h"
 28 
 29 #include "eab-gui-util.h"
 30 #include "util/eab-book-util.h"
 31 #include "e-util/e-util.h"
 32 
 33 #include <gtk/gtk.h>
 34 #include <gdk/gdkkeysyms.h>
 35 #include <misc/e-canvas.h>
 36 #include <glib/gi18n.h>
 37 #include <string.h>
 38 #include "e-util/e-util.h"
 39 #include "ea-addressbook.h"
 40 
 41 static void e_minicard_view_drag_data_get (GtkWidget *widget,
 42 					  GdkDragContext *context,
 43 					  GtkSelectionData *selection_data,
 44 					  guint info,
 45 					  guint time,
 46 					  EMinicardView *view);
 47 
 48 enum {
 49 	PROP_0,
 50 	PROP_ADAPTER,
 51 	PROP_CLIENT,
 52 	PROP_QUERY,
 53 	PROP_EDITABLE
 54 };
 55 
 56 enum {
 57 	CREATE_CONTACT,
 58 	CREATE_CONTACT_LIST,
 59 	RIGHT_CLICK,
 60 	LAST_SIGNAL
 61 };
 62 
 63 static guint signals[LAST_SIGNAL] = {0, };
 64 
 65 enum DndTargetType {
 66 	DND_TARGET_TYPE_VCARD_LIST,
 67 	DND_TARGET_TYPE_SOURCE_VCARD_LIST
 68 };
 69 #define VCARD_LIST_TYPE "text/x-vcard"
 70 #define SOURCE_VCARD_LIST_TYPE "text/x-source-vcard"
 71 static GtkTargetEntry drag_types[] = {
 72 	{ (gchar *) SOURCE_VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD_LIST },
 73 	{ (gchar *) VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST }
 74 };
 75 
 76 G_DEFINE_TYPE (EMinicardView, e_minicard_view, E_TYPE_REFLOW)
 77 
 78 static void
 79 e_minicard_view_drag_data_get (GtkWidget *widget,
 80                               GdkDragContext *context,
 81                               GtkSelectionData *selection_data,
 82                               guint info,
 83                               guint time,
 84                               EMinicardView *view)
 85 {
 86 	GdkAtom target;
 87 
 88 	if (!E_IS_MINICARD_VIEW (view))
 89 		return;
 90 
 91 	target = gtk_selection_data_get_target (selection_data);
 92 
 93 	switch (info) {
 94 	case DND_TARGET_TYPE_VCARD_LIST: {
 95 		gchar *value;
 96 
 97 		value = eab_contact_list_to_string (view->drag_list);
 98 
 99 		gtk_selection_data_set (
100 			selection_data, target, 8,
101 			(guchar *) value, strlen (value));
102 		g_free (value);
103 		break;
104 	}
105 	case DND_TARGET_TYPE_SOURCE_VCARD_LIST: {
106 		EBookClient *book_client = NULL;
107 		gchar *value;
108 
109 		g_object_get (view->adapter, "book_client", &book_client, NULL);
110 		value = eab_book_and_contact_list_to_string (book_client, view->drag_list);
111 
112 		gtk_selection_data_set (
113 			selection_data, target, 8,
114 			(guchar *) value, strlen (value));
115 
116 		g_object_unref (book_client);
117 		g_free (value);
118 		break;
119 	}
120 	}
121 }
122 
123 static void
124 clear_drag_data (EMinicardView *view)
125 {
126 	e_client_util_free_object_slist (view->drag_list);
127 	view->drag_list = NULL;
128 }
129 
130 static gint
131 e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter,
132                             GdkEvent *event,
133                             EMinicardView *view)
134 {
135 	GdkDragContext *context;
136 	GtkTargetList *target_list;
137 	GdkDragAction actions = GDK_ACTION_MOVE | GDK_ACTION_COPY;
138 
139 	clear_drag_data (view);
140 
141 	view->drag_list = e_minicard_view_get_card_list (view);
142 
143 	g_print ("dragging %d card(s)\n", g_slist_length (view->drag_list));
144 
145 	target_list = gtk_target_list_new (drag_types, G_N_ELEMENTS (drag_types));
146 
147 	context = gtk_drag_begin (
148 		GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
149 		target_list, actions, 1/*XXX */, event);
150 
151 	if (!view->canvas_drag_data_get_id)
152 		view->canvas_drag_data_get_id = g_signal_connect (
153 			GNOME_CANVAS_ITEM (view)->canvas, "drag_data_get",
154 			G_CALLBACK (e_minicard_view_drag_data_get), view);
155 
156 	gtk_drag_set_icon_default (context);
157 
158 	return TRUE;
159 }
160 
161 static void
162 set_empty_message (EMinicardView *view)
163 {
164 	gchar *empty_message;
165 	gboolean editable = FALSE, perform_initial_query = FALSE, searching = FALSE;
166 
167 	if (view->adapter) {
168 		EAddressbookModel *model = NULL;
169 		EBookClient *book_client = NULL;
170 
171 		g_object_get (
172 			view->adapter,
173 			"editable", &editable,
174 			"model", &model,
175 			"client", &book_client,
176 			NULL);
177 
178 		if (book_client && !e_client_check_capability (E_CLIENT (book_client), "do-initial-query"))
179 			perform_initial_query = TRUE;
180 
181 		searching = model && e_addressbook_model_can_stop (model);
182 
183 		if (book_client)
184 			g_object_unref (book_client);
185 		if (model)
186 			g_object_unref (model);
187 	}
188 
189 	if (searching) {
190 		empty_message = _("\n\nSearching for the Contacts...");
191 	} else if (editable) {
192 		if (perform_initial_query)
193 			empty_message = _("\n\nSearch for the Contact\n\n"
194 					  "or double-click here to create a new Contact.");
195 		else
196 			empty_message = _("\n\nThere are no items to show in this view.\n\n"
197 					  "Double-click here to create a new Contact.");
198 	} else {
199 		if (perform_initial_query)
200 			empty_message = _("\n\nSearch for the Contact.");
201 		else
202 			empty_message = _("\n\nThere are no items to show in this view.");
203 	}
204 
205 	g_object_set (
206 		view,
207 		"empty_message", empty_message,
208 		NULL);
209 }
210 
211 static void
212 writable_status_change (EAddressbookModel *model,
213                         gboolean writable,
214                         EMinicardView *view)
215 {
216 	set_empty_message (view);
217 }
218 
219 static void
220 stop_state_changed (EAddressbookModel *model,
221                     EMinicardView *view)
222 {
223 	set_empty_message (view);
224 }
225 
226 static void
227 adapter_changed (EMinicardView *view)
228 {
229 	set_empty_message (view);
230 
231 	g_signal_connect (
232 		view->adapter, "drag_begin",
233 		G_CALLBACK (e_minicard_view_drag_begin), view);
234 }
235 
236 static void
237 e_minicard_view_set_property (GObject *object,
238                               guint property_id,
239                               const GValue *value,
240                               GParamSpec *pspec)
241 {
242 	EMinicardView *view;
243 
244 	view = E_MINICARD_VIEW (object);
245 
246 	switch (property_id) {
247 	case PROP_ADAPTER:
248 		if (view->adapter) {
249 			if (view->writable_status_id || view->stop_state_id) {
250 				EAddressbookModel *model;
251 				g_object_get (
252 					view->adapter,
253 					"model", &model,
254 					NULL);
255 				if (model) {
256 					if (view->writable_status_id)
257 						g_signal_handler_disconnect (model, view->writable_status_id);
258 					if (view->stop_state_id)
259 						g_signal_handler_disconnect (model, view->stop_state_id);
260 				}
261 			}
262 
263 			g_object_unref (view->adapter);
264 		}
265 		view->writable_status_id = 0;
266 		view->stop_state_id = 0;
267 		view->adapter = g_value_get_object (value);
268 		g_object_ref (view->adapter);
269 		adapter_changed (view);
270 		g_object_set (
271 			view,
272 			"model", view->adapter,
273 			NULL);
274 		if (view->adapter) {
275 			EAddressbookModel *model;
276 			g_object_get (
277 				view->adapter,
278 				"model", &model,
279 				NULL);
280 			if (model) {
281 				view->writable_status_id = g_signal_connect (
282 					model, "writable_status",
283 					G_CALLBACK (writable_status_change), view);
284 				view->stop_state_id = g_signal_connect (
285 					model, "stop_state_changed",
286 					G_CALLBACK (stop_state_changed), view);
287 			}
288 
289 		}
290 		break;
291 	case PROP_CLIENT:
292 		g_object_set (
293 			view->adapter,
294 			"client", g_value_get_object (value),
295 			NULL);
296 		set_empty_message (view);
297 		break;
298 	case PROP_QUERY:
299 		g_object_set (
300 			view->adapter,
301 			"query", g_value_get_string (value),
302 			NULL);
303 		break;
304 	case PROP_EDITABLE:
305 		g_object_set (
306 			view->adapter,
307 			"editable", g_value_get_boolean (value),
308 			NULL);
309 		set_empty_message (view);
310 		break;
311 	default:
312 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
313 		break;
314 	}
315 }
316 
317 static void
318 e_minicard_view_get_property (GObject *object,
319                               guint property_id,
320                               GValue *value,
321                               GParamSpec *pspec)
322 {
323 	EMinicardView *view;
324 
325 	view = E_MINICARD_VIEW (object);
326 
327 	switch (property_id) {
328 	case PROP_ADAPTER:
329 		g_value_set_object (value, view->adapter);
330 		break;
331 	case PROP_CLIENT:
332 		g_object_get_property (
333 			G_OBJECT (view->adapter),
334 			"client", value);
335 		break;
336 	case PROP_QUERY:
337 		g_object_get_property (
338 			G_OBJECT (view->adapter),
339 			"query", value);
340 		break;
341 	case PROP_EDITABLE:
342 		g_object_get_property (
343 			G_OBJECT (view->adapter),
344 			"editable", value);
345 		break;
346 	default:
347 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
348 		break;
349 	}
350 }
351 
352 static void
353 e_minicard_view_dispose (GObject *object)
354 {
355 	EMinicardView *view = E_MINICARD_VIEW (object);
356 
357 	clear_drag_data (view);
358 
359 	if (view->canvas_drag_data_get_id) {
360 		g_signal_handler_disconnect (
361 			GNOME_CANVAS_ITEM (view)->canvas,
362 			view->canvas_drag_data_get_id);
363 		view->canvas_drag_data_get_id = 0;
364 	}
365 
366 	if (view->adapter) {
367 		if (view->writable_status_id || view->stop_state_id) {
368 			EAddressbookModel *model;
369 			g_object_get (
370 				view->adapter,
371 				"model", &model,
372 				NULL);
373 			if (model) {
374 				if (view->writable_status_id)
375 					g_signal_handler_disconnect (model, view->writable_status_id);
376 				if (view->stop_state_id)
377 					g_signal_handler_disconnect (model, view->stop_state_id);
378 			}
379 		}
380 
381 		g_object_unref (view->adapter);
382 	}
383 	view->writable_status_id = 0;
384 	view->stop_state_id = 0;
385 	view->adapter = NULL;
386 
387 	/* Chain up to parent's dispose() method. */
388 	G_OBJECT_CLASS (e_minicard_view_parent_class)->dispose (object);
389 }
390 
391 static guint
392 e_minicard_view_right_click (EMinicardView *view,
393                              GdkEvent *event)
394 {
395 	guint ret_val = 0;
396 	g_signal_emit (
397 		view, signals[RIGHT_CLICK], 0,
398 		event, &ret_val);
399 	return ret_val;
400 }
401 
402 static gboolean
403 e_minicard_view_event (GnomeCanvasItem *item,
404                        GdkEvent *event)
405 {
406 	EMinicardView *view;
407 
408 	view = E_MINICARD_VIEW (item);
409 
410 	switch (event->type) {
411 	case GDK_2BUTTON_PRESS:
412 		if (((GdkEventButton *) event)->button == 1) {
413 			gboolean editable;
414 
415 			g_object_get (view->adapter, "editable", &editable, NULL);
416 
417 			if (editable)
418 				e_minicard_view_create_contact (view);
419 			return TRUE;
420 		}
421 	case GDK_BUTTON_PRESS:
422 		if (event->button.button == 3) {
423 			e_minicard_view_right_click (view, event);
424 		}
425 		break;
426 	case GDK_KEY_PRESS:
427 		if (event->key.keyval & GDK_SHIFT_MASK &&
428 			event->key.keyval == GDK_KEY_F10) {
429 			e_minicard_view_right_click (view, event);
430 		}
431 		break;
432 	default:
433 		break;
434 	}
435 
436 	return GNOME_CANVAS_ITEM_CLASS (e_minicard_view_parent_class)->
437 		event (item, event);
438 }
439 
440 static gint
441 e_minicard_view_selection_event (EReflow *reflow,
442                                  GnomeCanvasItem *item,
443                                  GdkEvent *event)
444 {
445 	EMinicardView *view;
446 	gint return_val = FALSE;
447 
448 	view = E_MINICARD_VIEW (reflow);
449 	return_val = E_REFLOW_CLASS (e_minicard_view_parent_class)->
450 		selection_event (reflow, item, event);
451 
452 	switch (event->type) {
453 	case GDK_FOCUS_CHANGE:
454 		if (event->focus_change.in) {
455 			gint i;
456 			for (i = 0; i < reflow->count; i++) {
457 				if (reflow->items[i] == item) {
458 					e_selection_model_maybe_do_something (reflow->selection, i, 0, 0);
459 					break;
460 				}
461 			}
462 		}
463 		break;
464 	case GDK_BUTTON_PRESS:
465 		if (event->button.button == 3) {
466 			return_val = e_minicard_view_right_click (view, event);
467 			if (!return_val)
468 				e_selection_model_right_click_up (reflow->selection);
469 		}
470 		break;
471 	default:
472 		break;
473 	}
474 	return return_val;
475 }
476 
477 static void
478 e_minicard_view_class_init (EMinicardViewClass *class)
479 {
480 	GObjectClass *object_class;
481 	GnomeCanvasItemClass *item_class;
482 	EReflowClass *reflow_class;
483 
484 	object_class = G_OBJECT_CLASS (class);
485 	item_class = (GnomeCanvasItemClass *) class;
486 	reflow_class = (EReflowClass *) class;
487 
488 	object_class->set_property    = e_minicard_view_set_property;
489 	object_class->get_property    = e_minicard_view_get_property;
490 	object_class->dispose         = e_minicard_view_dispose;
491 
492 	g_object_class_install_property (
493 		object_class,
494 		PROP_ADAPTER,
495 		g_param_spec_object (
496 			"adapter",
497 			"Adapter",
498 			NULL,
499 			E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER,
500 			G_PARAM_READWRITE));
501 
502 	g_object_class_install_property (
503 		object_class,
504 		PROP_CLIENT,
505 		g_param_spec_object (
506 			"client",
507 			"EBookClient",
508 			NULL,
509 			E_TYPE_BOOK_CLIENT,
510 			G_PARAM_READWRITE));
511 
512 	g_object_class_install_property (
513 		object_class,
514 		PROP_QUERY,
515 		g_param_spec_string (
516 			"query",
517 			"Query",
518 			NULL,
519 			NULL,
520 			G_PARAM_READWRITE));
521 
522 	g_object_class_install_property (
523 		object_class,
524 		PROP_EDITABLE,
525 		g_param_spec_boolean (
526 			"editable",
527 			"Editable",
528 			NULL,
529 			FALSE,
530 			G_PARAM_READWRITE));
531 
532 	signals[CREATE_CONTACT] = g_signal_new (
533 		"create-contact",
534 		G_OBJECT_CLASS_TYPE (object_class),
535 		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
536 		0, NULL, NULL,
537 		g_cclosure_marshal_VOID__VOID,
538 		G_TYPE_NONE, 0);
539 
540 	signals[CREATE_CONTACT_LIST] = g_signal_new (
541 		"create-contact-list",
542 		G_OBJECT_CLASS_TYPE (object_class),
543 		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
544 		0, NULL, NULL,
545 		g_cclosure_marshal_VOID__VOID,
546 		G_TYPE_NONE, 0);
547 
548 	signals[RIGHT_CLICK] = g_signal_new (
549 		"right_click",
550 		G_OBJECT_CLASS_TYPE (object_class),
551 		G_SIGNAL_RUN_LAST,
552 		G_STRUCT_OFFSET (EMinicardViewClass, right_click),
553 		NULL, NULL,
554 		e_marshal_INT__POINTER,
555 		G_TYPE_INT, 1,
556 		G_TYPE_POINTER);
557 
558 	item_class->event             = e_minicard_view_event;
559 
560 	reflow_class->selection_event = e_minicard_view_selection_event;
561 	/* GnomeCanvasItem method overrides */
562 
563 	/* init the accessibility support for e_minicard_view */
564 	e_minicard_view_a11y_init ();
565 }
566 
567 static void
568 e_minicard_view_init (EMinicardView *view)
569 {
570 	view->drag_list = NULL;
571 	view->adapter = NULL;
572 	view->canvas_drag_data_get_id = 0;
573 	view->writable_status_id = 0;
574 	view->stop_state_id = 0;
575 
576 	set_empty_message (view);
577 }
578 
579 void
580 e_minicard_view_jump_to_letter (EMinicardView *view,
581                                 gunichar letter)
582 {
583 #if 0
584 	gchar uft_str[6 + 1];
585 
586 	utf_str[g_unichar_to_utf8 (letter, utf_str)] = '\0';
587 	e_reflow_sorted_jump (
588 		E_REFLOW_SORTED (view),
589 		(GCompareFunc) compare_to_utf_str,
590 		utf_str);
591 #endif
592 }
593 
594 typedef struct {
595 	GSList *list;
596 	EAddressbookReflowAdapter *adapter;
597 } ModelAndList;
598 
599 static void
600 add_to_list (gint index,
601              gpointer closure)
602 {
603 	ModelAndList *mal = closure;
604 	mal->list = g_slist_prepend (
605 		mal->list, e_addressbook_reflow_adapter_get_contact (
606 		mal->adapter, index));
607 }
608 
609 GSList *
610 e_minicard_view_get_card_list (EMinicardView *view)
611 {
612 	ModelAndList mal;
613 
614 	mal.adapter = view->adapter;
615 	mal.list = NULL;
616 
617 	e_selection_model_foreach (E_REFLOW (view)->selection, add_to_list, &mal);
618 
619 	return g_slist_reverse (mal.list);
620 }
621 
622 void
623 e_minicard_view_create_contact (EMinicardView *view)
624 {
625 	g_return_if_fail (E_IS_MINICARD_VIEW (view));
626 
627 	g_signal_emit (view, signals[CREATE_CONTACT], 0);
628 }
629 
630 void
631 e_minicard_view_create_contact_list (EMinicardView *view)
632 {
633 	g_return_if_fail (E_IS_MINICARD_VIEW (view));
634 
635 	g_signal_emit (view, signals[CREATE_CONTACT_LIST], 0);
636 }