No issues found
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 |
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 }