1 /*
2 *  RAL -- Rubrica Addressbook Library
3 *  file: ref.c
4 *
5 *  Copyright (C) Nicola Fragale <nicolafragale@libero.it>
6 *
7 *  This program is free software; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation; either version 3 of the License, or
10 *  (at your option) any later version.
11 *
12 *  This program is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *  GNU General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with this program; if not, write to the Free Software
19 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 #include <gtk/gtk.h>
23 #include <glib.h>
24 #include <glib/gi18n-lib.h>
25 #include <gconf/gconf-client.h>
26 #include <errno.h>
27 
28 #include "libral.h"
29 
30 #include "cards_view.h"
31 #include "preferences.h"
32 #include "rubrica-marshal.h"
33 #include "rubrica-enum-types.h"
34 #include "types.h"
35 
36 
37 
38 enum {
39   PROP_0,
40   VIEW_HAS_CHANGED,
41   VIEW_BROTHER,
42   VIEW_MARKED_CARDS,
43 };
44 
45 /*    signals enumeration
46  */
47 enum {
48   MARK,
49   LAST_SIGNAL,
50 };
51 
52 
53 static guint cards_view_signals[LAST_SIGNAL] = {0};
54 
55 static GObjectClass* parent_class = NULL;
56 static gint order[COLUMNS] = {0};
57 
58 
59 struct _RubricaCardsViewPrivate {
60   RAbook*    abook;
61   GtkWidget* brother;
62   gboolean   change;
63 
64   gboolean dispose_has_run;
65 };
66 
67 
68 
69 #define RUBRICA_CARDS_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o),  \
70                                            RUBRICA_CARDS_VIEW_TYPE,          \
71                                            RubricaCardsViewPrivate))
72 
73 
74 
75 static void rubrica_cards_view_class_init   (RubricaCardsViewClass* klass);
76 static void rubrica_cards_view_init         (RubricaCardsView* obj);
77 
78 static void rubrica_cards_view_finalize     (RubricaCardsView* self);
79 static void rubrica_cards_view_dispose      (RubricaCardsView* self);
80 
81 
82 static void rubrica_cards_view_set_property (GObject* obj, guint property_id,
83 					     GValue* value,  GParamSpec* spec);
84 static void rubrica_cards_view_get_property (GObject* obj, guint property_id,
85 					     GValue* value, GParamSpec* spec);
86 
87 
88 /* Private
89  */
90 static void     cards_view_load_file    (RubricaCardsView* view, gchar* file);
91 static void     cards_update_infos      (RubricaCardsView* view);
92 
93 static void     cards_view_add_card     (RubricaCardsView* view, RCard* card,
94 					 gboolean scrool);
95 static gboolean cards_view_delete_card  (GtkTreeModel *model,
96 					 GtkTreePath *path,
97 					 GtkTreeIter *iter, gpointer data);
98 static void     cards_view_show_column  (GConfClient *client, guint cnxn_id,
99 					 GConfEntry *entry, gpointer data);
100 static void     cards_view_setup_column (GtkTreeViewColumn* column,
101 					 gchar* key);
102 static void     cards_view_add_columns  (RubricaCardsView* view);
103 
104 // Callbacks
105 static void     on_open_file_failed_cb  (RAbook* book, gint error,
106 					 gpointer data);
107 static gboolean on_print_card_toggled   (GtkCellRendererToggle *cell,
108 					 gchar *path,  gpointer data);
109 
110 
111 
112 static void
cards_view_load_file(RubricaCardsView * view,gchar * filename)113 cards_view_load_file(RubricaCardsView* view, gchar* filename)
114 {
115   RubricaCardsViewPrivate* priv = RUBRICA_CARDS_VIEW_GET_PRIVATE(view);
116 
117   if (r_abook_open_file(R_ABOOK(priv->abook), filename))
118     {
119       RCard* card;
120 
121       r_abook_reset_book(priv->abook);
122       card = r_abook_get_card(priv->abook);
123       for (; card; card = r_abook_get_next_card(priv->abook))
124 	cards_view_add_card(view, card, FALSE);
125 
126       cards_update_infos(view);
127     }
128 }
129 
130 
131 static void
cards_update_infos(RubricaCardsView * view)132 cards_update_infos(RubricaCardsView* view)
133 {
134   gint items, deleted;
135   gchar* message;
136 
137   items   = r_abook_get_items(view->priv->abook);
138   deleted = r_abook_get_deleted(view->priv->abook);
139   message = g_strdup_printf(_("Cards in this addressbook: %-5d "
140 			      "Deleted cards: %-5d"), items, deleted);
141   g_object_set(view, "view-message", message, NULL);
142 
143   g_signal_emit_by_name(view, "view-changed", message, G_TYPE_STRING);
144 }
145 
146 
147 static void
cards_view_add_card(RubricaCardsView * view,RCard * card,gboolean scrool)148 cards_view_add_card(RubricaCardsView* view, RCard* card, gboolean scrool)
149 {
150   GtkWidget    *tree;
151   GtkTreeModel *model;
152   GtkTreeIter  iter;
153   GtkTreePath *path;
154   GtkTreeSelection *selection;
155   RInfos *infos;
156 
157   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(view));
158   g_return_if_fail(IS_R_CARD(card));
159 
160   infos = r_card_get_infos(R_CARD(card));
161   tree  = rubrica_view_get_tree(RUBRICA_VIEW(view));
162   model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
163   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
164 
165   gtk_list_store_append(GTK_LIST_STORE(model), &iter);
166   if (r_card_is_personal(card))
167     {
168       gtk_list_store_set(GTK_LIST_STORE(model), &iter,
169 			 PRINT_COLUMN,      FALSE,
170 			 CARD_COLUMN,       r_infos_get_label(infos),
171 			 FIRST_NAME_COLUMN, r_infos_get_first(infos),
172 			 LAST_NAME_COLUMN,  r_infos_get_last(infos),
173 			 PROFESSION_COLUMN, r_infos_get_profession(infos),
174 			 CITY_COLUMN,       r_infos_get_city(infos),
175 			 COUNTRY_COLUMN,    r_infos_get_country(infos),
176 			 WEB_CARD_COLUMN,   r_infos_get_web(infos),
177 			 EMAIL_CARD_COLUMN, r_infos_get_email(infos),
178 			 TELEPHONE_COLUMN,  r_infos_get_telephone(infos),
179 			 ASSIGNMENT_COLUMN, r_infos_get_assignment(infos),
180 			 ID_COLUMN,         r_infos_get_id(infos),
181 			 -1);
182     }
183   else
184     {
185       gtk_list_store_set(GTK_LIST_STORE(model), &iter,
186 			 PRINT_COLUMN,      FALSE,
187 			 CARD_COLUMN,       r_infos_get_label(infos),
188 			 CITY_COLUMN,       r_infos_get_city(infos),
189 			 COUNTRY_COLUMN,    r_infos_get_country(infos),
190 			 WEB_CARD_COLUMN,   r_infos_get_web(infos),
191 			 EMAIL_CARD_COLUMN, r_infos_get_email(infos),
192 			 TELEPHONE_COLUMN,  r_infos_get_telephone(infos),
193 			 ID_COLUMN,         r_infos_get_id(infos),
194 			 -1);
195     }
196 
197   if (scrool)
198     {
199       path = gtk_tree_model_get_path(model, &iter);
200       gtk_tree_selection_select_iter (selection, &iter);
201       gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(tree), path, NULL,
202 				   TRUE, 0.5, 0.0);
203     }
204 
205   r_card_free_infos(infos);
206 }
207 
208 
209 static gboolean
cards_view_delete_card(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)210 cards_view_delete_card (GtkTreeModel *model, GtkTreePath *path,
211 			GtkTreeIter *iter, gpointer data)
212 {
213   gulong card_id = (glong) data;
214   gulong id;
215 
216   gtk_tree_model_get(model, iter, ID_COLUMN, &id, -1);
217   if (id == card_id)
218     {
219       gtk_list_store_remove(GTK_LIST_STORE(model), iter);
220 
221       return TRUE;
222     }
223 
224   return FALSE;
225 }
226 
227 
228 static void
cards_view_show_column(GConfClient * client,guint cnxn_id,GConfEntry * entry,gpointer data)229 cards_view_show_column(GConfClient *client, guint cnxn_id,
230 		       GConfEntry *entry, gpointer data)
231 {
232   gboolean bool;
233   GtkTreeViewColumn* column = (GtkTreeViewColumn*) data;
234 
235   bool = gconf_value_get_bool (entry->value);
236   gtk_tree_view_column_set_visible(column, bool);
237 }
238 
239 
240 static void
cards_view_setup_column(GtkTreeViewColumn * column,gchar * key)241 cards_view_setup_column (GtkTreeViewColumn* column, gchar* key)
242 {
243   GConfClient* client;
244   gboolean bool;
245 
246   client = gconf_client_get_default();
247 
248   bool = gconf_client_get_bool(client, key, NULL);
249   gtk_tree_view_column_set_visible(column, bool);
250 
251   gconf_client_notify_add(client, key, cards_view_show_column, column,
252 			  NULL, NULL);
253 
254   g_object_unref(client);
255 }
256 
257 
258 static void
cards_view_add_columns(RubricaCardsView * view)259 cards_view_add_columns (RubricaCardsView* view)
260 {
261   GtkTreeView *tree;
262   GtkTreeViewColumn* column;
263   GtkCellRenderer *renderer;
264   GtkTreeModel *model;
265   gint col;
266 
267   tree  = (GtkTreeView *) rubrica_view_get_tree(RUBRICA_VIEW(view));
268   model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
269 
270   renderer = gtk_cell_renderer_toggle_new();
271   col = gtk_tree_view_insert_column_with_attributes(tree, -1, _("Print"),
272 					      renderer, "active",
273 					      PRINT_COLUMN, NULL);
274   order[PRINT_COLUMN] = col;
275   column = gtk_tree_view_get_column(tree, col-1);
276   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
277   cards_view_setup_column(column, RUBRICA_GCONF_PRINT_CARD);
278   g_signal_connect_after(G_OBJECT(renderer), "toggled",
279 			 G_CALLBACK(on_print_card_toggled), view);
280 
281   renderer = gtk_cell_renderer_text_new();
282   col = gtk_tree_view_insert_column_with_attributes(tree, -1, _("Card"),
283 						    renderer, "text",
284 						    CARD_COLUMN, NULL);
285   order[CARD_COLUMN] = col;
286   column = gtk_tree_view_get_column(tree, col-1);
287   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
288   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
289 					  CARD_COLUMN);
290   cards_view_setup_column(column, RUBRICA_GCONF_CARD);
291 
292   renderer = gtk_cell_renderer_text_new();
293   col = gtk_tree_view_insert_column_with_attributes(tree, -1,
294 						    _("First Name"),
295 						    renderer, "text",
296 						    FIRST_NAME_COLUMN,
297 						    NULL);
298   order[FIRST_NAME_COLUMN] = col;
299   column = gtk_tree_view_get_column(tree, col-1);
300   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
301   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
302 					  FIRST_NAME_COLUMN);
303   cards_view_setup_column(column, RUBRICA_GCONF_FIRST_NAME);
304 
305   renderer = gtk_cell_renderer_text_new();
306   col = gtk_tree_view_insert_column_with_attributes (tree, -1,
307 						     _("Last Name"),
308 						     renderer, "text",
309 						     LAST_NAME_COLUMN,
310 						     NULL);
311   order[LAST_NAME_COLUMN] = col;
312   column = gtk_tree_view_get_column(tree, col-1);
313   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
314   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
315 					  LAST_NAME_COLUMN);
316   cards_view_setup_column(column, RUBRICA_GCONF_LAST_NAME);
317 
318   renderer = gtk_cell_renderer_text_new();
319   col = gtk_tree_view_insert_column_with_attributes (tree, -1,
320 						     _("Profession"),
321 						     renderer,  "text",
322 						     PROFESSION_COLUMN,
323 						     NULL);
324   order[PROFESSION_COLUMN] = col;
325   column = gtk_tree_view_get_column(tree, col-1);
326   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
327   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
328 					  PROFESSION_COLUMN);
329   cards_view_setup_column(column, RUBRICA_GCONF_PROFESSION);
330 
331   renderer = gtk_cell_renderer_text_new();
332   col = gtk_tree_view_insert_column_with_attributes (tree, -1, _("City"),
333 						     renderer, "text",
334 						     CITY_COLUMN, NULL);
335   order[CITY_COLUMN] = col;
336   column = gtk_tree_view_get_column(tree, col-1);
337   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
338   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
339 					  CITY_COLUMN);
340   cards_view_setup_column(column, RUBRICA_GCONF_CITY);
341 
342   renderer = gtk_cell_renderer_text_new();
343   col = gtk_tree_view_insert_column_with_attributes (tree, -1,
344 						     _("Country"),
345 						     renderer, "text",
346 						     COUNTRY_COLUMN,
347 						     NULL);
348   order[COUNTRY_COLUMN] = col;
349   column = gtk_tree_view_get_column(tree, col-1);
350   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
351   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
352 					  COUNTRY_COLUMN);
353   cards_view_setup_column(column, RUBRICA_GCONF_COUNTRY);
354 
355   renderer = gtk_cell_renderer_text_new();
356   col = gtk_tree_view_insert_column_with_attributes (tree, -1, _("Web"),
357 						     renderer, "text",
358 						     WEB_CARD_COLUMN,
359 						     NULL);
360   order[WEB_CARD_COLUMN] = col;
361   column = gtk_tree_view_get_column(tree, col-1);
362   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
363   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
364 					  WEB_CARD_COLUMN);
365   cards_view_setup_column(column, RUBRICA_GCONF_WEB);
366 
367   renderer = gtk_cell_renderer_text_new();
368   col = gtk_tree_view_insert_column_with_attributes (tree, -1, _("Email"),
369 						     renderer, "text",
370 						     EMAIL_CARD_COLUMN,
371 						     NULL);
372   order[EMAIL_CARD_COLUMN] = col;
373   column = gtk_tree_view_get_column(tree, col-1);
374   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
375   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
376 					  EMAIL_CARD_COLUMN);
377   cards_view_setup_column(column, RUBRICA_GCONF_EMAIL);
378 
379   renderer = gtk_cell_renderer_text_new();
380   col = gtk_tree_view_insert_column_with_attributes (tree, -1,
381 						     _("Telephone"),
382 						     renderer, "text",
383 						     TELEPHONE_COLUMN,
384 						     NULL);
385   order[TELEPHONE_COLUMN] = col;
386   column = gtk_tree_view_get_column(tree, col-1);
387   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
388   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
389 					  TELEPHONE_COLUMN);
390   cards_view_setup_column(column, RUBRICA_GCONF_TELEPHONE);
391 
392   renderer = gtk_cell_renderer_text_new();
393   col = gtk_tree_view_insert_column_with_attributes (tree, -1,
394 						     _("Company"),
395 						     renderer, "text",
396 						     COMPANY_COLUMN, NULL);
397   order[COMPANY_COLUMN] = col;
398   column = gtk_tree_view_get_column(tree, col-1);
399   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
400   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
401 					  COMPANY_COLUMN);
402   cards_view_setup_column(column, RUBRICA_GCONF_COMPANY);
403 
404   renderer = gtk_cell_renderer_text_new();
405   col = gtk_tree_view_insert_column_with_attributes (tree, -1,
406 						     _("Assignment"),
407 						     renderer, "text",
408 						     ASSIGNMENT_COLUMN,
409 						     NULL);
410   order[ASSIGNMENT_COLUMN] = col;
411   column = gtk_tree_view_get_column(tree, col-1);
412   gtk_tree_view_column_set_reorderable(GTK_TREE_VIEW_COLUMN(column), TRUE);
413   gtk_tree_view_column_set_sort_column_id(GTK_TREE_VIEW_COLUMN(column),
414 					  ASSIGNMENT_COLUMN);
415   cards_view_setup_column(column, RUBRICA_GCONF_ASSIGNMENT);
416 
417   gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
418 				       CARD_COLUMN, GTK_SORT_ASCENDING);
419 
420   gtk_tree_view_set_enable_search(GTK_TREE_VIEW(tree), TRUE);
421   rubrica_preferences_setup_search_on(GTK_TREE_VIEW(tree));
422 }
423 
424 
425 /*    Callbacks
426 */
427 static void
on_open_file_failed_cb(RAbook * book,gint error,gpointer data)428 on_open_file_failed_cb(RAbook* book, gint error, gpointer data)
429 {
430   GtkWidget* dialog;
431   gchar* file;
432 
433   g_object_get(book, "addressbook-name", &file, NULL);
434 
435   dialog = gtk_message_dialog_new (NULL,
436 				   GTK_DIALOG_DESTROY_WITH_PARENT,
437 				   GTK_MESSAGE_ERROR,
438 				   GTK_BUTTONS_CLOSE,
439 				   _("Error loading file '%s': %s"),
440 				   file, g_strerror (errno));
441 
442   gtk_dialog_run (GTK_DIALOG (dialog));
443   gtk_widget_destroy (dialog);
444 }
445 
446 
447 static gboolean
on_print_card_toggled(GtkCellRendererToggle * cell,gchar * path_str,gpointer data)448 on_print_card_toggled (GtkCellRendererToggle *cell, gchar *path_str,
449 		       gpointer data)
450 {
451   RubricaCardsView* view = (RubricaCardsView*) data;
452   GtkTreeView *tree;
453   GtkTreeModel *model;
454   GtkTreeIter iter;
455   GtkTreePath *path;
456   gboolean status;
457   glong id;
458 
459   tree  = (GtkTreeView *) rubrica_view_get_tree(RUBRICA_VIEW(view));
460   model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
461   path  = gtk_tree_path_new_from_string(path_str);
462 
463   gtk_tree_model_get_iter (model, &iter, path);
464   gtk_tree_model_get (model, &iter,
465 		      PRINT_COLUMN, &status,
466 		      ID_COLUMN, &id,
467 		      -1);
468   status ^= 1;
469   gtk_list_store_set(GTK_LIST_STORE(model), &iter, PRINT_COLUMN, status, -1);
470   gtk_tree_path_free(path);
471 
472   if (status)
473     g_signal_emit(view, cards_view_signals[MARK], 0, id, CARD_MARKED_PRINT);
474   else
475     g_signal_emit(view, cards_view_signals[MARK], 0, id, CARD_UNMARKED_PRINT);
476 
477   // returning FALSE it doesn't block signal for other callbacks
478   return FALSE;
479 }
480 
481 
482 
483 /*  Public
484 */
485 GType
rubrica_cards_view_get_type()486 rubrica_cards_view_get_type()
487 {
488   static GType cards_view_type = 0;
489 
490   if (!cards_view_type)
491     {
492       static const GTypeInfo cards_view_info =
493 	{
494 	  sizeof(RubricaCardsViewClass),
495 	  NULL,
496 	  NULL,
497 	  (GClassInitFunc) rubrica_cards_view_class_init,
498 	  NULL,
499 	  NULL,
500 	  sizeof(RubricaCardsView),
501 	  0,
502 	  (GInstanceInitFunc) rubrica_cards_view_init
503 	};
504 
505       cards_view_type = g_type_register_static (RUBRICA_VIEW_TYPE,
506 						"RubricaCardsView",
507 						&cards_view_info, 0);
508     }
509 
510 
511 
512   return cards_view_type;
513 }
514 
515 
516 static void
rubrica_cards_view_dispose(RubricaCardsView * self)517 rubrica_cards_view_dispose (RubricaCardsView* self)
518 {
519   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(self));
520 
521   if (self->priv->dispose_has_run)
522     return;
523 
524   self->priv->dispose_has_run = TRUE;
525 }
526 
527 
528 static void
rubrica_cards_view_finalize(RubricaCardsView * self)529 rubrica_cards_view_finalize (RubricaCardsView* self)
530 {
531   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(self));
532 }
533 
534 
535 static void
rubrica_cards_view_class_init(RubricaCardsViewClass * klass)536 rubrica_cards_view_class_init(RubricaCardsViewClass* klass)
537 {
538   GObjectClass *object_class = G_OBJECT_CLASS (klass);
539   GParamSpec* pspec;
540 
541   parent_class = g_type_class_peek_parent (klass);
542 
543   object_class->finalize = (GObjectFinalizeFunc) rubrica_cards_view_finalize;
544   object_class->dispose  = (GObjectFinalizeFunc) rubrica_cards_view_dispose;
545 
546   object_class->set_property = (gpointer) rubrica_cards_view_set_property;
547   object_class->get_property = (gpointer) rubrica_cards_view_get_property;
548 
549   g_type_class_add_private (klass, sizeof(RubricaCardsViewPrivate));
550 
551   /**
552    * RubricaCardsView::marked-card:
553    *
554    * The "mark" signal
555    */
556   cards_view_signals[MARK] =
557     g_signal_new("mark",
558 		 RUBRICA_CARDS_VIEW_TYPE,
559 		 G_SIGNAL_RUN_LAST,
560 		 G_STRUCT_OFFSET(RubricaCardsViewClass, mark),
561 		 NULL,
562 		 NULL,
563 		 rubrica_marshal_VOID__LONG_ENUM,
564 		 G_TYPE_NONE,
565 		 2,
566 		 G_TYPE_LONG,
567 		 RUBRICA_TYPE_CARDS_VIEW_MARK);
568 
569   /**
570    * RubricaCardsView:change
571    *
572    * does the addressbook change?
573    */
574   pspec = g_param_spec_boolean("has-changed",
575 			       "has changed",
576 			       "does view changed?",
577 			       FALSE,
578 			       G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
579   g_object_class_install_property(object_class, VIEW_HAS_CHANGED, pspec);
580 
581   /**
582    * RubricaCardsView:brother
583    *
584    * the object that replace the notebook's tab
585    */
586   pspec = g_param_spec_object("view-brother",
587 			      "view brother",
588 			      "the object that replace the notebook's tab",
589 			      GTK_TYPE_WIDGET,
590 			      G_PARAM_READWRITE);
591   g_object_class_install_property(object_class, VIEW_BROTHER, pspec);
592 }
593 
594 
595 static void
rubrica_cards_view_init(RubricaCardsView * self)596 rubrica_cards_view_init(RubricaCardsView* self)
597 {
598   GtkTreeModel* model;
599   gchar* message;
600 
601   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(self));
602 
603   self->priv = RUBRICA_CARDS_VIEW_GET_PRIVATE(self);
604 
605   self->priv->abook   = r_abook_new();
606   self->priv->brother = NULL;
607   self->priv->change  = FALSE;
608 
609   model = (GtkTreeModel*) gtk_list_store_new(COLUMNS,
610 					     G_TYPE_INT,     /* print card */
611 					     G_TYPE_STRING,  /* card label */
612 					     G_TYPE_STRING,  /* first name */
613 					     G_TYPE_STRING,  /* last name  */
614 					     G_TYPE_STRING,  /* profession */
615 					     G_TYPE_STRING,  /* city       */
616 					     G_TYPE_STRING,  /* country    */
617 					     G_TYPE_STRING,  /* web        */
618 					     G_TYPE_STRING,  /* email      */
619 					     G_TYPE_STRING,  /* telephone  */
620 					     G_TYPE_STRING,  /* company    */
621 					     G_TYPE_STRING,  /* assigment  */
622 					     G_TYPE_INT);    /* card's id  */
623 
624   rubrica_view_set_model(RUBRICA_VIEW(self), model);
625 
626   cards_view_add_columns(self);
627 
628   //  tree = rubrica_view_get_tree(RUBRICA_VIEW(self));
629 
630   message = g_strdup_printf(_("Cards in this addressbook: %-5d "
631 			      "Deleted cards: %-5d"), 0, 0);
632   g_object_set(self, "view-message", message, NULL);
633 
634   g_signal_connect(self->priv->abook, "open_fail",
635 		   G_CALLBACK (on_open_file_failed_cb), self);
636 
637   g_object_set(self->priv->abook, "addressbook-name", _("no name"), NULL);
638 
639   self->priv->dispose_has_run = FALSE;
640 }
641 
642 
643 static void
rubrica_cards_view_set_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)644 rubrica_cards_view_set_property (GObject* obj, guint property_id,
645 				 GValue* value, GParamSpec* spec)
646 {
647   RubricaCardsView* self = (RubricaCardsView*) obj;
648   RubricaCardsViewPrivate* priv = RUBRICA_CARDS_VIEW_GET_PRIVATE(self);
649 
650   switch (property_id)
651     {
652     case VIEW_HAS_CHANGED:
653       priv->change = g_value_get_boolean(value);
654       break;
655 
656     case VIEW_BROTHER:
657       priv->brother = g_value_get_object(value);
658       break;
659 
660     default:
661       break;
662     }
663 }
664 
665 
666 static void
rubrica_cards_view_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)667 rubrica_cards_view_get_property (GObject* obj, guint property_id,
668 				 GValue* value, GParamSpec* spec)
669 {
670   RubricaCardsView* self = (RubricaCardsView*) obj;
671   RubricaCardsViewPrivate* priv = RUBRICA_CARDS_VIEW_GET_PRIVATE(self);
672 
673   switch (property_id)
674     {
675     case VIEW_HAS_CHANGED:
676       g_value_set_boolean(value, priv->change);
677       break;
678 
679     case VIEW_BROTHER:
680       g_value_set_object(value, priv->brother);
681      break;
682 
683     default:
684       break;
685     }
686 }
687 
688 
689 
690 
691 /*   Public
692 */
693 /**
694  * rubrica_cards_view_new
695  *
696  * create a #RubricaCardsView
697  *
698  * returns: a new #RubricaCardsView*
699  */
700 GtkWidget*
rubrica_cards_view_new(gchar * file)701 rubrica_cards_view_new(gchar* file)
702 {
703   GtkWidget* view;
704 
705   view = GTK_WIDGET(g_object_new(RUBRICA_CARDS_VIEW_TYPE,
706 				 "child-type", "Addressbook", NULL));
707 
708   if (file)
709     cards_view_load_file(RUBRICA_CARDS_VIEW(view), file);
710 
711   return view;
712 }
713 
714 
715 gchar*
rubrica_cards_view_get_addressbook_name(RubricaCardsView * view)716 rubrica_cards_view_get_addressbook_name(RubricaCardsView* view)
717 {
718   gchar* name = NULL;
719 
720   g_return_val_if_fail(IS_RUBRICA_CARDS_VIEW(view), NULL);
721 
722   g_object_get(view->priv->abook, "addressbook-name", &name, NULL);
723 
724   return name;
725 }
726 
727 
728 RAbook*
rubrica_cards_view_get_addressbook(RubricaCardsView * view)729 rubrica_cards_view_get_addressbook(RubricaCardsView* view)
730 {
731   if (!view)
732     return NULL;
733 
734   g_return_val_if_fail(IS_RUBRICA_CARDS_VIEW(view), NULL);
735 
736   return (RAbook*) view->priv->abook;
737 }
738 
739 
740 void
rubrica_cards_view_add_card(RubricaCardsView * view,RCard * card)741 rubrica_cards_view_add_card (RubricaCardsView* view, RCard* card)
742 {
743 
744   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(view));
745 
746   cards_view_add_card(view, card, TRUE);
747   cards_update_infos(view);
748 }
749 
750 
751 void
rubrica_cards_view_delete_card(RubricaCardsView * view,RCard * card)752 rubrica_cards_view_delete_card(RubricaCardsView* view, RCard* card)
753 {
754   GtkWidget    *tree;
755   GtkTreeModel *model;
756   GtkTreeIter   iter;
757   GtkTreeSelection *selection;
758 
759   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(view));
760 
761   tree      = rubrica_view_get_tree(RUBRICA_VIEW(view));
762   model     = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
763   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
764 
765   if (gtk_tree_selection_get_selected(selection, NULL, &iter))
766     gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
767   else
768     {
769       glong id;
770 
771       g_object_get(card, "card-id", &id, NULL);
772 
773       gtk_tree_model_foreach(model, cards_view_delete_card, (gpointer) id);
774     }
775 
776   cards_update_infos(view);
777 }
778 
779 
780 void
rubrica_cards_view_modify_card(RubricaCardsView * view,RCard * card)781 rubrica_cards_view_modify_card(RubricaCardsView* view, RCard* card)
782 {
783   GtkWidget        *tree;
784   GtkTreeModel     *model;
785   GtkTreeSelection *selection;
786   GtkTreeIter       iter;
787 
788   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(view));
789 
790   tree  = rubrica_view_get_tree(RUBRICA_VIEW(view));
791   model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
792   selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
793 
794   if (gtk_tree_selection_get_selected(selection, NULL, &iter))
795     {
796       RInfos* infos;
797 
798       infos = r_card_get_infos(R_CARD(card));
799 
800       gtk_list_store_set(GTK_LIST_STORE(model), &iter,
801 			 CARD_COLUMN,       r_infos_get_label(infos),
802 			 FIRST_NAME_COLUMN, r_infos_get_first(infos),
803 			 LAST_NAME_COLUMN,  r_infos_get_last(infos),
804 			 PROFESSION_COLUMN, r_infos_get_profession(infos),
805 			 CITY_COLUMN,       r_infos_get_city(infos),
806 			 COUNTRY_COLUMN,    r_infos_get_country(infos),
807 			 WEB_CARD_COLUMN,   r_infos_get_web(infos),
808 			 EMAIL_CARD_COLUMN, r_infos_get_email(infos),
809 			 TELEPHONE_COLUMN,  r_infos_get_telephone(infos),
810 			 ASSIGNMENT_COLUMN, r_infos_get_assignment(infos),
811 			 ID_COLUMN,         r_infos_get_id(infos),
812 			 -1);
813 
814       r_card_free_infos(infos);
815       gtk_tree_selection_select_iter (selection, &iter);
816    }
817 
818   cards_update_infos(view);
819 }
820 
821 
822 void
rubrica_cards_view_display_results(RubricaCardsView * view,GList * list)823 rubrica_cards_view_display_results (RubricaCardsView* view, GList* list)
824 {
825   GtkWidget    *tree;
826   GtkTreeModel *model;
827 
828   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(view));
829 
830   tree  = rubrica_view_get_tree(RUBRICA_VIEW(view));
831   model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
832 
833   gtk_list_store_clear(GTK_LIST_STORE(model));
834   for (; list; list = list->next)
835     {
836       RCard* card;
837       glong id = (glong) list->data;
838 
839       card = r_abook_get_card_by_id(view->priv->abook, id);
840       cards_view_add_card(view, card, FALSE);
841     }
842 
843   cards_update_infos(view);
844 }
845 
846 
847 void
rubrica_cards_view_update_infos(RubricaCardsView * view)848 rubrica_cards_view_update_infos (RubricaCardsView* view)
849 {
850   g_return_if_fail(IS_RUBRICA_CARDS_VIEW(view));
851 
852   cards_update_infos(view);
853 }
854 
855 
856 GList*
rubrica_cards_view_get_selected_cards(RubricaCardsView * view)857 rubrica_cards_view_get_selected_cards(RubricaCardsView* view)
858 {
859   GtkTreeModel* model;
860   GtkTreeIter iter;
861   GList* cards = NULL;
862 
863   g_return_val_if_fail(IS_RUBRICA_CARDS_VIEW(view), NULL);
864 
865   model = rubrica_view_get_model(RUBRICA_VIEW(view));
866 
867   if (gtk_tree_model_get_iter_first(model, &iter))
868     {
869       gulong id;
870       gint printable;
871 
872       do
873 	{
874 	  gtk_tree_model_get(model, &iter,
875 			     PRINT_COLUMN, &printable,
876 			     ID_COLUMN, &id, -1);
877 	  if (printable)
878 	    cards = g_list_append(cards, (gpointer) id);
879 	}
880       while (gtk_tree_model_iter_next(model, &iter));
881     }
882 
883   return cards;
884 }
885