1
2 /*
3 * Osmo - a handy personal organizer
4 *
5 * Copyright (C) 2007 Tomasz Maka <pasp@users.sourceforge.net>
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 2 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 "about.h"
23 #include "backup.h"
24 #include "contacts.h"
25 #include "i18n.h"
26 #include "contacts_items.h"
27 #include "utils.h"
28 #include "utils_date.h"
29 #include "utils_gui.h"
30 #include "options_prefs.h"
31 #include "preferences_gui.h"
32 #include "stock_icons.h"
33 #include "contacts_birthdays.h"
34 #include "contacts_import.h"
35 #include "contacts_export.h"
36 #include "calendar_utils.h"
37
38 #ifdef CONTACTS_ENABLED
39
40 /*============================================================================*/
41
42 static void
show_preferences_window_cb(GtkToolButton * toolbutton,gpointer data)43 show_preferences_window_cb (GtkToolButton *toolbutton, gpointer data)
44 {
45 GUI *appGUI = (GUI *) data;
46 appGUI->opt->window = opt_create_preferences_window (appGUI);
47 gtk_widget_show (appGUI->opt->window);
48
49 gint page = gtk_notebook_page_num (GTK_NOTEBOOK (appGUI->opt->notebook), appGUI->opt->contacts);
50 gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->opt->notebook), page);
51 }
52
53 /*------------------------------------------------------------------------------*/
54
55
56 void
set_export_active(GUI * appGUI)57 set_export_active (GUI *appGUI) {
58
59 GtkTreeIter iter;
60 gboolean state;
61
62 state = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(appGUI->cnt->contacts_filter), &iter);
63 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->export_toolbar_button), state);
64 }
65
66 /*------------------------------------------------------------------------------*/
67
68 gboolean
find_combo_box_focus_cb(GtkWidget * widget,GtkDirectionType * arg1,gpointer user_data)69 find_combo_box_focus_cb (GtkWidget *widget, GtkDirectionType *arg1, gpointer user_data) {
70 return TRUE;
71 }
72
73 /*------------------------------------------------------------------------------*/
74
75 void
contacts_panel_close_desc_cb(GtkWidget * widget,gpointer data)76 contacts_panel_close_desc_cb (GtkWidget *widget, gpointer data) {
77 GtkPaned *paned;
78 gint max_position;
79 GUI *appGUI = (GUI *)data;
80
81 paned = GTK_PANED (appGUI->cnt->contacts_paned);
82 g_object_get(paned, "max-position", &max_position, NULL);
83 gtk_paned_set_position(paned, max_position);
84 }
85
86 /*------------------------------------------------------------------------------*/
87
88 gboolean
contacts_list_filter_cb(GtkTreeModel * model,GtkTreeIter * iter,gpointer data)89 contacts_list_filter_cb (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
90
91 const gchar *text;
92 gchar *value = NULL;
93 gint i;
94 guint32 date;
95 gboolean result;
96
97 GUI *appGUI = (GUI *)data;
98
99 text = gtk_entry_get_text(GTK_ENTRY(appGUI->cnt->contacts_find_entry));
100
101 if (text == NULL) {
102 return TRUE;
103 }
104 if (!g_utf8_strlen(text, -1)) {
105 return TRUE;
106 }
107
108 if (config.find_mode == CONTACTS_FF_ALL_FIELDS) {
109 result = FALSE;
110 for (i = 0; i < CONTACTS_NUM_COLUMNS && !result; i++) {
111
112 if (i != COLUMN_PHOTO && i != COLUMN_ID) {
113 if (i == COLUMN_BIRTH_DAY_DATE || i == COLUMN_NAME_DAY_DATE) {
114 gtk_tree_model_get(model, iter, i, &date, -1);
115 if (date == 0) {
116 value = NULL;
117 } else {
118 if (i == COLUMN_BIRTH_DAY_DATE) {
119 value = g_strdup((const gchar *) julian_to_str(date, DATE_FULL, config.override_locale_settings));
120 } else {
121 value = g_strdup((const gchar *) julian_to_str(date, DATE_NAME_DAY, config.override_locale_settings));
122 }
123 }
124 } else {
125 gtk_tree_model_get(model, iter, i, &value, -1);
126 }
127
128 if (value != NULL) {
129 result = utl_text_strcasestr(value, text);
130 g_free(value);
131 }
132 }
133 }
134 } else {
135 if (config.find_mode == CONTACTS_FF_FIRST_NAME) {
136 gtk_tree_model_get(model, iter, COLUMN_FIRST_NAME, &value, -1);
137 } else if (config.find_mode == CONTACTS_FF_LAST_NAME) {
138 gtk_tree_model_get(model, iter, COLUMN_LAST_NAME, &value, -1);
139 } else if (config.find_mode == CONTACTS_FF_TAGS) {
140 gtk_tree_model_get(model, iter, COLUMN_TAGS, &value, -1);
141 }
142
143 if (value == NULL) {
144 result = FALSE;
145 } else {
146 result = utl_text_strcasestr(value, text);
147 }
148 g_free(value);
149 }
150
151 return result;
152 }
153
154 /*------------------------------------------------------------------------------*/
155
156 void
contacts_select_first_position_in_list(GUI * appGUI)157 contacts_select_first_position_in_list (GUI *appGUI) {
158
159 GtkTreeIter iter;
160 GtkTreePath *path;
161
162 /* set cursor at first position */
163 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(appGUI->cnt->contacts_list_store), &iter) == TRUE) {
164 path = gtk_tree_model_get_path (GTK_TREE_MODEL(appGUI->cnt->contacts_list_store), &iter);
165 if (path != NULL) {
166 gtk_tree_view_set_cursor (GTK_TREE_VIEW (appGUI->cnt->contacts_list), path, NULL, FALSE);
167 gtk_tree_path_free (path);
168 }
169 }
170 }
171
172 /*------------------------------------------------------------------------------*/
173
174 void
contacts_item_selected_cb(GtkTreeSelection * selection,GUI * appGUI)175 contacts_item_selected_cb (GtkTreeSelection *selection, GUI *appGUI)
176 {
177 GtkTreeModel *model;
178 GtkTreeIter iter;
179 gint selection_size;
180 gboolean address_available = FALSE, additional_info = FALSE;
181 guint32 date;
182 gchar *fname, *sname, *lname, *html, *photo;
183 gchar tmpbuf[BUFFER_SIZE], htmpbuf[BUFFER_SIZE];
184 gint i;
185
186 selection_size = gtk_tree_selection_count_selected_rows(selection);
187 if (selection_size > 1) {
188 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->edit_toolbar_button), FALSE);
189 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->delete_toolbar_button), TRUE);
190 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->map_location_toolbar_button), FALSE);
191
192 #ifdef HAVE_LIBWEBKIT
193 webkit_web_view_load_html(appGUI->cnt->html_webkitview, "", "file://");
194 #endif /* LIBWEBKIT */
195 } else if (selection_size == 1) {
196 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->edit_toolbar_button), TRUE);
197 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->delete_toolbar_button), TRUE);
198
199 address_available = check_address(HOME_ADDRESS, appGUI);
200 if (address_available == FALSE) {
201 address_available = check_address(WORK_ADDRESS, appGUI);
202 }
203
204 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->map_location_toolbar_button), address_available);
205
206 /****************************************************************/
207
208 html = g_strdup_printf(
209 "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"
210 "<style type=\"text/css\">\n"
211 "body { font-size: %dpx; }\n"
212 "h1 { font-size: %dpx; font-weight: bold; font-style: italic; }\n"
213 "pre { white-space: pre; margin-top: 0; margin-left: 2px; margin-bottom: 2px; }\n"
214 "a { color: %s; }\n"
215 "table { width: 100%%; }\n"
216 "td.tag { width: 30%%; }\n"
217 "td.value { width: 70%%; }\n"
218 ".tag { font-weight: bold; color: %s; }\n"
219 #ifdef HAVE_LIBWEBKIT
220 ".photo { position: absolute; top: 4; right: 4; width: %dpx; border: 1px solid #000; float: right; }\n"
221 #endif /* HAVE_LIBWEBKIT */
222 "</style>\n</head>\n\n<body>\n",
223 config.contact_item_font_size, config.contact_name_font_size,
224 config.contact_link_color, config.contact_tag_color, config.photo_width);
225
226 /****************************************************************/
227
228 iter = utl_gui_get_first_selection_iter(selection, &model);
229 gtk_tree_model_get(model, &iter,
230 COLUMN_FIRST_NAME, &fname,
231 COLUMN_SECOND_NAME, &sname,
232 COLUMN_LAST_NAME, &lname,
233 COLUMN_PHOTO, &photo,
234 -1);
235
236 if (!fname) fname = g_strdup("");
237 if (!sname) sname = g_strdup("");
238 if (!lname) lname = g_strdup("");
239
240 g_snprintf(htmpbuf, BUFFER_SIZE, "<h1>%s %s %s</h1>\n", fname, sname, lname);
241 html = utl_strconcat(html, htmpbuf, NULL);
242 g_free(fname);
243 g_free(sname);
244 g_free(lname);
245
246 /* insert photo */
247 if (photo != NULL) {
248 #ifdef HAVE_LIBWEBKIT
249 g_snprintf(htmpbuf, BUFFER_SIZE, "<img src=\"file://%s\" alt=\"\" class=\"photo\">", photo);
250 #endif /* HAVE_LIBWEBKIT */
251 html = utl_strconcat(html, htmpbuf, NULL);
252 g_free(photo);
253 }
254
255 g_snprintf(htmpbuf, BUFFER_SIZE, "<table>\n");
256 html = utl_strconcat(html, htmpbuf, NULL);
257
258 for (i = 0; i < CONTACTS_NUM_COLUMNS; i++) {
259 gchar *text;
260 if ((i == COLUMN_ID) ||
261 (i == COLUMN_PHOTO) ||
262 (i == COLUMN_FIRST_NAME) ||
263 (i == COLUMN_SECOND_NAME) ||
264 (i == COLUMN_LAST_NAME) ||
265 (i == COLUMN_GROUP))
266 continue;
267
268 if (i == COLUMN_BIRTH_DAY_DATE || i == COLUMN_NAME_DAY_DATE) {
269 gtk_tree_model_get(model, &iter, i, &date, -1);
270 if (date == 0) {
271 text = NULL;
272 } else {
273 if (i == COLUMN_BIRTH_DAY_DATE) {
274 text = g_strdup((const gchar *) julian_to_str(date, DATE_FULL, config.override_locale_settings));
275 } else {
276 text = g_strdup((const gchar *) julian_to_str(date, DATE_NAME_DAY, config.override_locale_settings));
277 }
278 }
279 } else {
280 gtk_tree_model_get(model, &iter, i, &text, -1);
281 }
282
283 if (text == NULL || !strlen(text)) {
284 g_free(text);
285 continue;
286 }
287
288 g_snprintf(htmpbuf, BUFFER_SIZE, "<tr>");
289 html = utl_strconcat(html, htmpbuf, NULL);
290
291 if ((i >= COLUMN_HOME_PHONE_2 && i <= COLUMN_HOME_PHONE_4) ||
292 (i >= COLUMN_WORK_PHONE_2 && i <= COLUMN_WORK_PHONE_4) ||
293 (i >= COLUMN_CELL_PHONE_2 && i <= COLUMN_CELL_PHONE_4) ||
294 (i >= COLUMN_EMAIL_2 && i <= COLUMN_EMAIL_4) ||
295 (i >= COLUMN_WWW_2 && i <= COLUMN_WWW_4)) {
296 tmpbuf[0] = '\0';
297 } else {
298 g_snprintf(tmpbuf, BUFFER_SIZE, "%s:", gettext(appGUI->cnt->contact_fields_tags_name[2 * i]));
299 }
300
301 if (i == COLUMN_INFO) {
302
303 gchar *tmp = utl_text_to_html(text, FALSE, TRUE);
304
305 if (tmp != NULL) {
306 additional_info = TRUE;
307
308 gchar *tmp2 = utl_text_replace(tmp, REGEX_URL, "<a href=\"\\0\">\\0</a>");
309 g_free(tmp);
310 gchar *tmp3 = utl_text_replace(tmp2, REGEX_EMAIL, "<a href=\"mailto:\\0\">\\0</a>");
311 g_free(tmp2);
312
313 g_snprintf(htmpbuf, BUFFER_SIZE,
314 "<td colspan=\"2\" class=\"tag\">%s</td></tr></table>\n<pre>%s</pre>\n", tmpbuf, tmp3);
315
316 html = utl_strconcat(html, htmpbuf, NULL);
317 g_free(tmp3);
318 }
319
320 } else {
321
322 g_snprintf(htmpbuf, BUFFER_SIZE, "<td class=\"tag\">%s</td>", tmpbuf);
323 html = utl_strconcat(html, htmpbuf, NULL);
324
325 }
326
327 if (i == COLUMN_BLOG || (i >= COLUMN_EMAIL_1 && i <= COLUMN_EMAIL_4) || (i >= COLUMN_WWW_1 && i <= COLUMN_WWW_4)) {
328
329 gchar *protocol;
330 if (i >= COLUMN_EMAIL_1 && i <= COLUMN_EMAIL_4) {
331 protocol = "mailto:";
332 } else if (!utl_text_match(text, REGEX_URI_PROTO)) {
333 protocol = "http://";
334 } else {
335 protocol = "";
336 }
337 g_snprintf(htmpbuf, BUFFER_SIZE, "<td class=\"value\"><a href=\"%s%s\">%s</a></td></tr>\n", protocol, text, text);
338 html = utl_strconcat(html, htmpbuf, NULL);
339
340 } else if (i != COLUMN_INFO) {
341
342 g_snprintf(htmpbuf, BUFFER_SIZE, "<td class=\"value\">%s</td></tr>\n", text);
343 html = utl_strconcat(html, htmpbuf, NULL);
344
345 }
346 g_free(text);
347 }
348
349 if (additional_info == TRUE) {
350 g_snprintf(htmpbuf, BUFFER_SIZE, "</body>\n</html>\n");
351 } else {
352 g_snprintf(htmpbuf, BUFFER_SIZE, "</table>\n</body>\n</html>\n");
353 }
354 html = utl_strconcat(html, htmpbuf, NULL);
355
356 #ifdef HAVE_LIBWEBKIT
357 webkit_web_view_load_html(appGUI->cnt->html_webkitview, html, "file://");
358 #endif /* LIBWEBKIT */
359
360 g_free(html);
361 } else {
362
363 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->edit_toolbar_button), FALSE);
364 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->delete_toolbar_button), FALSE);
365 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->map_location_toolbar_button), FALSE);
366
367 #ifdef HAVE_LIBWEBKIT
368 webkit_web_view_load_html(appGUI->cnt->html_webkitview, "", "file://");
369 #endif /* LIBWEBKIT */
370 }
371 set_export_active(appGUI);
372 }
373
374 /*------------------------------------------------------------------------------*/
375
376 gboolean
contacts_search_entry_changed_cb(GtkEditable * editable,gpointer user_data)377 contacts_search_entry_changed_cb (GtkEditable *editable, gpointer user_data) {
378 GUI *appGUI = (GUI *)user_data;
379
380 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter));
381 set_export_active (appGUI);
382
383 return FALSE;
384 }
385
386 /*------------------------------------------------------------------------------*/
387
388 void
contacts_find_type_selected_cb(GtkComboBox * widget,gpointer user_data)389 contacts_find_type_selected_cb (GtkComboBox *widget, gpointer user_data) {
390
391 GtkTreeIter iter;
392 gboolean has_next;
393
394 GUI *appGUI = (GUI *)user_data;
395
396 config.find_mode = gtk_combo_box_get_active (widget);
397
398 if(strlen(gtk_entry_get_text (GTK_ENTRY(appGUI->cnt->contacts_find_entry)))) {
399 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter));
400
401 has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->cnt->contacts_filter), &iter);
402 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->export_toolbar_button), has_next);
403 if (has_next) {
404 GtkTreePath *path = gtk_tree_path_new_first();
405 if (path != NULL) {
406 gtk_tree_view_set_cursor(GTK_TREE_VIEW(appGUI->cnt->contacts_list), path, NULL, FALSE);
407 }
408 gtk_tree_path_free(path);
409 }
410 }
411 }
412
413 /*------------------------------------------------------------------------------*/
414
415 gint
contacts_column_sort_function(GtkTreeModel * model,GtkTreeIter * iter_a,GtkTreeIter * iter_b,gint sort_column,GUI * appGUI)416 contacts_column_sort_function (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gint sort_column, GUI *appGUI)
417 {
418 gchar *last_name_a, *last_name_b;
419 gchar *group_a, *group_b;
420 gchar *first_name_a, *first_name_b;
421 gint diff;
422
423 if (iter_a == NULL || iter_b == NULL) {
424 return 0;
425 }
426
427
428 switch(sort_column) {
429 case COLUMN_GROUP:
430 gtk_tree_model_get(model, iter_a, COLUMN_GROUP, &group_a, -1);
431 gtk_tree_model_get(model, iter_b, COLUMN_GROUP, &group_b, -1);
432 diff = utl_text_strcmp(group_a, group_b);
433 g_free(group_a);
434 g_free(group_b);
435 break;
436 case COLUMN_FIRST_NAME:
437 gtk_tree_model_get(model, iter_a, COLUMN_FIRST_NAME, &first_name_a, -1);
438 gtk_tree_model_get(model, iter_b, COLUMN_FIRST_NAME, &first_name_b, -1);
439 diff = utl_text_strcmp(first_name_a, first_name_b);
440 g_free(first_name_a);
441 g_free(first_name_b);
442 break;
443 case COLUMN_LAST_NAME:
444 gtk_tree_model_get(model, iter_a, COLUMN_LAST_NAME, &last_name_a, -1);
445 gtk_tree_model_get(model, iter_b, COLUMN_LAST_NAME, &last_name_b, -1);
446 diff = utl_text_strcmp(last_name_a, last_name_b);
447 g_free(last_name_a);
448 g_free(last_name_b);
449 break;
450 default:
451 diff = 0;
452 }
453 return diff;
454 }
455
456 /*------------------------------------------------------------------------------*/
457
458 gint
contacts_column_sort_by_group_function(GtkTreeModel * model,GtkTreeIter * iter_a,GtkTreeIter * iter_b,gpointer user_data)459 contacts_column_sort_by_group_function (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
460 {
461 return contacts_column_sort_function(model, iter_a, iter_b, COLUMN_GROUP, (GUI *)user_data);
462 }
463
464 /*------------------------------------------------------------------------------*/
465
466 gint
contacts_column_sort_by_first_name_function(GtkTreeModel * model,GtkTreeIter * iter_a,GtkTreeIter * iter_b,gpointer user_data)467 contacts_column_sort_by_first_name_function (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
468 {
469 return contacts_column_sort_function(model, iter_a, iter_b, COLUMN_FIRST_NAME, (GUI *)user_data);
470 }
471
472 /*------------------------------------------------------------------------------*/
473
474 gint
contacts_column_sort_by_last_name_function(GtkTreeModel * model,GtkTreeIter * iter_a,GtkTreeIter * iter_b,gpointer user_data)475 contacts_column_sort_by_last_name_function (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data)
476 {
477 return contacts_column_sort_function(model, iter_a, iter_b, COLUMN_LAST_NAME, (GUI *)user_data);
478 }
479
480
481 /*------------------------------------------------------------------------------*/
482
contacts_sort_column_changed_cb(GtkTreeSortable * sortable,gpointer user_data)483 void contacts_sort_column_changed_cb (GtkTreeSortable *sortable, gpointer user_data)
484 {
485 GtkSortType sort_order;
486
487 gtk_tree_sortable_get_sort_column_id(sortable, &config.contacts_sorting_column, &sort_order);
488 config.contacts_sorting_order = sort_order;
489 }
490 /*------------------------------------------------------------------------------*/
491
492 static void
contacts_add_item_cb(GtkToolButton * toolbutton,gpointer data)493 contacts_add_item_cb (GtkToolButton *toolbutton, gpointer data) {
494
495 GUI *appGUI = (GUI *)data;
496 contacts_add_edit_dialog_show (FALSE, appGUI);
497 }
498
499 /*------------------------------------------------------------------------------*/
500
501 static void
contacts_edit_item_cb(GtkToolButton * toolbutton,gpointer data)502 contacts_edit_item_cb (GtkToolButton *toolbutton, gpointer data) {
503
504 GUI *appGUI = (GUI *)data;
505
506 if (gtk_tree_selection_count_selected_rows (appGUI->cnt->contacts_list_selection) == 1) {
507 contacts_add_edit_dialog_show (TRUE, appGUI);
508 }
509 }
510
511 /*------------------------------------------------------------------------------*/
512
513 static void
contacts_remove_item_cb(GtkToolButton * toolbutton,gpointer data)514 contacts_remove_item_cb (GtkToolButton *toolbutton, gpointer data) {
515
516 GUI *appGUI = (GUI *)data;
517 contacts_remove_dialog_show(appGUI);
518 }
519
520 /*------------------------------------------------------------------------------*/
521
522 static void
contacts_birthdays_item_cb(GtkToolButton * toolbutton,gpointer data)523 contacts_birthdays_item_cb (GtkToolButton *toolbutton, gpointer data) {
524
525 GUI *appGUI = (GUI *)data;
526 contacts_create_birthdays_window (appGUI);
527 }
528
529 /*------------------------------------------------------------------------------*/
530
531 static void
contacts_map_location_cb(GtkToolButton * toolbutton,gpointer data)532 contacts_map_location_cb (GtkToolButton *toolbutton, gpointer data) {
533
534 gint response = -1;
535 GtkWidget *info_dialog = NULL;
536 GtkWidget *hbox;
537 GtkWidget *home_addr_radiobutton;
538 GtkWidget *work_addr_radiobutton;
539 GSList *hw_radiobutton_group = NULL;
540
541
542 GUI *appGUI = (GUI *)data;
543
544 if (gtk_tree_selection_count_selected_rows (appGUI->cnt->contacts_list_selection) == 1) {
545
546 if (check_address (HOME_ADDRESS, appGUI) && check_address (WORK_ADDRESS, appGUI)) {
547 GtkWidget *message_area;
548
549 info_dialog = gtk_message_dialog_new (GTK_WINDOW(appGUI->main_window),
550 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
551 GTK_MESSAGE_INFO, GTK_BUTTONS_OK_CANCEL,
552 "\n%s:", _("Please select address"));
553
554 gtk_window_set_title(GTK_WINDOW(info_dialog), _("Information"));
555 gtk_widget_show (info_dialog);
556
557 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
558 message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(info_dialog));
559 gtk_box_pack_start (GTK_BOX(message_area), hbox, FALSE, TRUE, 2);
560 gtk_widget_show (hbox);
561
562 work_addr_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Work"));
563 gtk_widget_show (work_addr_radiobutton);
564 gtk_box_pack_end (GTK_BOX(hbox), work_addr_radiobutton, FALSE, TRUE, 2);
565 gtk_radio_button_set_group (GTK_RADIO_BUTTON (work_addr_radiobutton), hw_radiobutton_group);
566 hw_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (work_addr_radiobutton));
567
568 home_addr_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Home"));
569 gtk_widget_show (home_addr_radiobutton);
570 gtk_box_pack_end (GTK_BOX(hbox), home_addr_radiobutton, FALSE, TRUE, 2);
571 gtk_radio_button_set_group (GTK_RADIO_BUTTON (home_addr_radiobutton), hw_radiobutton_group);
572 hw_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (home_addr_radiobutton));
573
574 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (home_addr_radiobutton), TRUE);
575
576 response = gtk_dialog_run(GTK_DIALOG(info_dialog));
577
578 if (response == GTK_RESPONSE_OK) {
579 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (home_addr_radiobutton)) == TRUE) {
580 show_contact_location_on_map (HOME_ADDRESS, appGUI);
581 } else {
582 show_contact_location_on_map (WORK_ADDRESS, appGUI);
583 }
584 }
585
586 gtk_widget_destroy(info_dialog);
587
588 } else {
589 if (check_address (HOME_ADDRESS, appGUI)) {
590 show_contact_location_on_map (HOME_ADDRESS, appGUI);
591 } else {
592 show_contact_location_on_map (WORK_ADDRESS, appGUI);
593 }
594 }
595 }
596 }
597
598 /*------------------------------------------------------------------------------*/
599
600 static void
contacts_export_items_cb(GtkToolButton * toolbutton,gpointer data)601 contacts_export_items_cb (GtkToolButton *toolbutton, gpointer data) {
602
603 GUI *appGUI = (GUI *)data;
604 contacts_create_export_window(appGUI);
605 }
606
607 /*------------------------------------------------------------------------------*/
608
609 static void
contacts_import_items_cb(GtkToolButton * toolbutton,gpointer data)610 contacts_import_items_cb (GtkToolButton *toolbutton, gpointer data) {
611
612 GUI *appGUI = (GUI *)data;
613 import_contacts_from_csv_file (appGUI);
614 }
615
616 /*------------------------------------------------------------------------------*/
617
618 gint
contacts_list_dbclick_cb(GtkWidget * widget,GdkEventButton * event,gpointer func_data)619 contacts_list_dbclick_cb(GtkWidget * widget, GdkEventButton * event, gpointer func_data) {
620
621 GUI *appGUI = (GUI *)func_data;
622
623 if ((event->type==GDK_2BUTTON_PRESS) && (event->button == 1)) {
624 contacts_edit_item_cb (NULL, appGUI);
625 return TRUE;
626 }
627
628 return FALSE;
629 }
630
631 /*------------------------------------------------------------------------------*/
632
633 void
contacts_selection_activate(gboolean active,GUI * appGUI)634 contacts_selection_activate (gboolean active, GUI *appGUI) {
635 if (active == TRUE) {
636 g_signal_connect(G_OBJECT(appGUI->cnt->contacts_list_selection), "changed",
637 G_CALLBACK(contacts_item_selected_cb), appGUI);
638 } else {
639 g_signal_handlers_disconnect_by_func (G_OBJECT (appGUI->cnt->contacts_list_selection),
640 G_CALLBACK (contacts_item_selected_cb), appGUI);
641 }
642 }
643
644 /*------------------------------------------------------------------------------*/
645
646 void
store_contact_columns_info(GUI * appGUI)647 store_contact_columns_info (GUI *appGUI) {
648
649 gint n;
650
651 config.contacts_column_idx_0 = utl_gui_get_column_position (appGUI->cnt->contacts_columns[COLUMN_GROUP],
652 GTK_TREE_VIEW(appGUI->cnt->contacts_list), MAX_VISIBLE_CONTACT_COLUMNS, appGUI);
653 config.contacts_column_idx_1 = utl_gui_get_column_position (appGUI->cnt->contacts_columns[COLUMN_FIRST_NAME],
654 GTK_TREE_VIEW(appGUI->cnt->contacts_list), MAX_VISIBLE_CONTACT_COLUMNS, appGUI);
655 config.contacts_column_idx_2 = utl_gui_get_column_position (appGUI->cnt->contacts_columns[COLUMN_LAST_NAME],
656 GTK_TREE_VIEW(appGUI->cnt->contacts_list), MAX_VISIBLE_CONTACT_COLUMNS, appGUI);
657
658 n = gtk_tree_view_column_get_width(gtk_tree_view_get_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), 0));
659 if (n > 1) {
660 config.contacts_column_idx_0_width = n;
661 }
662 n = gtk_tree_view_column_get_width(gtk_tree_view_get_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), 1));
663 if (n > 1) {
664 config.contacts_column_idx_1_width = n;
665 }
666 n = gtk_tree_view_column_get_width(gtk_tree_view_get_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), 2));
667 if (n > 1) {
668 config.contacts_column_idx_2_width = n;
669 }
670 }
671
672 /*------------------------------------------------------------------------------*/
673
674 void
set_contacts_columns_width(GUI * appGUI)675 set_contacts_columns_width (GUI *appGUI) {
676
677 GtkTreeViewColumn *col;
678 gint w;
679
680 w = 2 * utl_gui_get_sw_vscrollbar_width (appGUI->cnt->scrolled_win);
681
682 col = gtk_tree_view_get_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), COLUMN_GROUP);
683 if (gtk_tree_view_column_get_visible(col) == TRUE && config.contacts_column_idx_0_width > 0) {
684 gtk_tree_view_column_set_fixed_width (col, config.contacts_column_idx_0_width);
685 }
686 col = gtk_tree_view_get_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), COLUMN_FIRST_NAME);
687 if (gtk_tree_view_column_get_visible(col) == TRUE && config.contacts_column_idx_1_width > 0) {
688 gtk_tree_view_column_set_fixed_width (col, config.contacts_column_idx_1_width);
689 }
690 col = gtk_tree_view_get_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), COLUMN_LAST_NAME);
691 if (gtk_tree_view_column_get_visible(col) == TRUE && config.contacts_column_idx_2_width > w) {
692 gtk_tree_view_column_set_fixed_width (col, config.contacts_column_idx_2_width - w);
693 }
694 }
695
696 /*------------------------------------------------------------------------------*/
697
698 void
cnt_clear_find_cb(GtkWidget * widget,gpointer user_data)699 cnt_clear_find_cb (GtkWidget *widget, gpointer user_data)
700 {
701 GUI *appGUI = (GUI *) user_data;
702 if (strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->cnt->contacts_find_entry)))) {
703 gtk_entry_set_text(GTK_ENTRY(appGUI->cnt->contacts_find_entry), "");
704 }
705 gtk_widget_grab_focus (appGUI->cnt->contacts_find_entry);
706 }
707
708 /*------------------------------------------------------------------------------*/
709
710 static void
create_contact_fields(GUI * appGUI)711 create_contact_fields(GUI *appGUI)
712 {
713 static gchar *contact_fields_tags_name[] = {
714 N_("Group"), "group",
715 N_("First name"), "first_name", N_("Last name"), "last_name",
716 N_("Second name"), "second_name",
717 N_("Nickname"), "nickname", N_("Tags"), "tags",
718 N_("Birthday date"), "birthday_date", N_("Name day date"), "name_day_date",
719
720 /*--------------------------------------------------*/
721 N_("Home address"), "home_address", N_("Home postcode"), "home_postcode", N_("Home city"),
722 "home_city", N_("Home state"), "home_state", N_("Home country"), "home_country",
723 /*--------------------------------------------------*/
724
725 N_("Organization"), "organization", N_("Department"), "department",
726
727 /*--------------------------------------------------*/
728 N_("Work address"), "work_address", N_("Work postcode"), "work_postcode", N_("Work city"),
729 "work_city", N_("Work state"), "work_state", N_("Work country"), "work_country",
730 /*--------------------------------------------------*/
731
732 N_("Fax"), "work_fax",
733
734 /*--------------------------------------------------*/
735 N_("Home phone"), "home_phone_1", N_("Home phone 2"), "home_phone_2",
736 N_("Home phone 3"), "home_phone_3", N_("Home phone 4"), "home_phone_4",
737 N_("Work phone"), "work_phone_1", N_("Work phone 2"), "work_phone_2",
738 N_("Work phone 3"), "work_phone_3", N_("Work phone 4"), "work_phone_4",
739 N_("Cell phone"), "cell_phone_1", N_("Cell phone 2"), "cell_phone_2",
740 N_("Cell phone 3"), "cell_phone_3", N_("Cell phone 4"), "cell_phone_4",
741 N_("E-Mail"), "email_1", N_("E-Mail 2"), "email_2", N_("E-Mail 3"), "email_3",
742 N_("E-Mail 4"), "email_4", N_("WWW"), "www_1", N_("WWW 2"), "www_2", N_("WWW 3"), "www_3",
743 N_("WWW 4"), "www_4",
744 /*--------------------------------------------------*/
745
746 N_("IM Gadu-Gadu"), "im_gg", N_("IM Yahoo"), "im_yahoo", N_("IM MSN"), "im_msn",
747 N_("IM ICQ"), "im_icq", N_("IM AOL"), "im_aol",
748 N_("IM Jabber"), "im_jabber", N_("IM Skype"), "im_skype", N_("IM Tlen"), "im_tlen",
749 N_("Blog"), "blog", N_("Photo"), "photo_path", N_("Additional info"), "additional_info", "ID", "id"
750 };
751
752 appGUI->cnt->contact_fields_tags_name = contact_fields_tags_name;
753 }
754
755 /*------------------------------------------------------------------------------*/
756
757 void
create_contacts_list_store(GUI * appGUI)758 create_contacts_list_store(GUI* appGUI)
759 {
760 GType contact_columns_types[CONTACTS_NUM_COLUMNS];
761 gint i;
762
763 for(i=0; i< CONTACTS_NUM_COLUMNS; i++) {
764 if (i == COLUMN_BIRTH_DAY_DATE || i == COLUMN_NAME_DAY_DATE || i == COLUMN_ID) {
765 contact_columns_types[i] = G_TYPE_UINT;
766 } else {
767 contact_columns_types[i] = G_TYPE_STRING;
768 }
769 }
770 appGUI->cnt->contacts_list_store = gtk_list_store_newv(CONTACTS_NUM_COLUMNS, &contact_columns_types[0]);
771 }
772 /*------------------------------------------------------------------------------*/
773
774 #if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
775
776 static void
button_create_backup_cb(GtkToolButton * toolbutton,gpointer data)777 button_create_backup_cb(GtkToolButton *toolbutton, gpointer data) {
778 GUI *appGUI = (GUI *) data;
779 backup_create(appGUI);
780 }
781
782 static void
button_restore_backup_cb(GtkToolButton * toolbutton,gpointer data)783 button_restore_backup_cb(GtkToolButton *toolbutton, gpointer data) {
784 GUI *appGUI = (GUI *) data;
785 backup_restore(appGUI);
786 }
787
788 #endif /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */
789
790 /*------------------------------------------------------------------------------*/
791
792 void
contacts_paned_position_change_cb(GObject * gobject,GParamSpec * pspec,GUI * appGUI)793 contacts_paned_position_change_cb (GObject *gobject, GParamSpec *pspec, GUI *appGUI)
794 {
795 config.contacts_pane_pos = gtk_paned_get_position (GTK_PANED (appGUI->cnt->contacts_paned));
796 }
797
798 /*------------------------------------------------------------------------------*/
799
800 void
gui_create_contacts(GUI * appGUI)801 gui_create_contacts(GUI *appGUI) {
802
803 GtkWidget *vbox1;
804 GtkWidget *vbox2;
805 GtkWidget *vbox3;
806 GtkWidget *hbox2;
807 GtkWidget *frame;
808 GtkWidget *hseparator;
809 GtkWidget *label;
810 GtkWidget *top_viewport;
811 GtkWidget *bottom_viewport;
812 GtkWidget *close_button;
813 GtkCellRenderer *renderer[CONTACTS_NUM_COLUMNS];
814 gint i, n;
815 gchar tmpbuf[BUFFER_SIZE];
816
817 gint columns_order[MAX_VISIBLE_CONTACT_COLUMNS];
818
819 gint co_columns[MAX_VISIBLE_CONTACT_COLUMNS] = {
820 COLUMN_GROUP, COLUMN_FIRST_NAME, COLUMN_LAST_NAME
821 };
822
823 create_contact_fields(appGUI);
824
825 vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
826 gtk_widget_show (vbox1);
827 gtk_container_set_border_width (GTK_CONTAINER (vbox1), 0);
828 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s</b>", _("Contacts"));
829 gui_add_to_notebook (vbox1, tmpbuf, appGUI);
830
831 appGUI->cnt->vbox = GTK_BOX(vbox1);
832
833 if (config.hide_contacts == TRUE) {
834 gtk_widget_hide(GTK_WIDGET(appGUI->cnt->vbox));
835 }
836
837 /*-------------------------------------------------------------------------------------*/
838 appGUI->cnt->contacts_toolbar = GTK_TOOLBAR(gtk_toolbar_new());
839 gtk_box_pack_start(GTK_BOX(vbox1), GTK_WIDGET(appGUI->cnt->contacts_toolbar), FALSE, FALSE, 0);
840
841 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_CONTACTS_ADD, _("New contact"), contacts_add_item_cb), -1);
842 appGUI->cnt->edit_toolbar_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_CONTACTS_EDIT, _("Edit contact"), contacts_edit_item_cb);
843 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, appGUI->cnt->edit_toolbar_button, -1);
844 appGUI->cnt->delete_toolbar_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_CONTACTS_REMOVE, _("Remove contact"), contacts_remove_item_cb);
845 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, appGUI->cnt->delete_toolbar_button, -1);
846 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gtk_separator_tool_item_new(), -1);
847 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_CONTACTS_BIRTHDAYS, _("Show birthdays"), contacts_birthdays_item_cb), -1);
848 appGUI->cnt->map_location_toolbar_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_OPEN_URL, _("Show contact location on the map"), contacts_map_location_cb);
849 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, appGUI->cnt->map_location_toolbar_button, -1);
850 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gtk_separator_tool_item_new(), -1);
851 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_CONTACTS_IMPORT, _("Import contacts"), contacts_import_items_cb), -1);
852 appGUI->cnt->export_toolbar_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_CONTACTS_EXPORT, _("Export contacts"), contacts_export_items_cb);
853 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, appGUI->cnt->export_toolbar_button, -1);
854 gui_append_toolbar_spring(appGUI->cnt->contacts_toolbar);
855 #if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
856 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gtk_separator_tool_item_new(), -1);
857 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_BACKUP, _("Backup data"), button_create_backup_cb), -1);
858 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_RESTORE, _("Restore data"), button_restore_backup_cb), -1);
859 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gtk_separator_tool_item_new(), -1);
860 #endif /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */
861 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_PREFERENCES, _("Preferences"), show_preferences_window_cb), -1);
862 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_ABOUT, _("About"), gui_show_about_window_cb), -1);
863 appGUI->cnt->quit_toolbar_button = gui_create_toolbar_button(appGUI, "application-exit", _("Quit"), gui_quit_osmo_cb);
864 gtk_toolbar_insert(appGUI->cnt->contacts_toolbar, appGUI->cnt->quit_toolbar_button, -1);
865
866 gtk_toolbar_set_style (appGUI->cnt->contacts_toolbar, GTK_TOOLBAR_ICONS);
867 gtk_toolbar_set_icon_size(appGUI->cnt->contacts_toolbar, GTK_ICON_SIZE_LARGE_TOOLBAR);
868 gtk_widget_show_all(GTK_WIDGET(appGUI->cnt->contacts_toolbar));
869
870 /*-------------------------------------------------------------------------------------*/
871
872 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->edit_toolbar_button), FALSE);
873 gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cnt->delete_toolbar_button), FALSE);
874
875 /******************************************************************************************/
876
877 if (!config.gui_layout) {
878 appGUI->cnt->contacts_paned = gtk_paned_new(GTK_ORIENTATION_VERTICAL );
879 } else {
880 appGUI->cnt->contacts_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
881 }
882
883 gtk_widget_show (appGUI->cnt->contacts_paned);
884 gtk_box_pack_start(GTK_BOX(vbox1), appGUI->cnt->contacts_paned, TRUE, TRUE, 0);
885
886 top_viewport = gtk_viewport_new (NULL, NULL);
887 gtk_widget_show (top_viewport);
888 gtk_viewport_set_shadow_type (GTK_VIEWPORT (top_viewport), GTK_SHADOW_NONE);
889 gtk_paned_pack1 (GTK_PANED (appGUI->cnt->contacts_paned), top_viewport, FALSE, TRUE);
890
891 vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
892 gtk_widget_show (vbox3);
893 gtk_container_add (GTK_CONTAINER (top_viewport), vbox3);
894 gtk_widget_set_margin_left (vbox3, 8);
895 gtk_widget_set_margin_right (vbox3, 8);
896 gtk_widget_set_margin_bottom (vbox3, 8);
897
898 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
899 gtk_widget_show (hseparator);
900 gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, FALSE, 6);
901
902 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Search"));
903 label = gtk_label_new (tmpbuf);
904 gtk_widget_show (label);
905 gtk_label_set_use_markup (GTK_LABEL(label), TRUE);
906 gtk_box_pack_start (GTK_BOX (vbox3), label, FALSE, FALSE, 0);
907 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
908 gtk_widget_set_halign(label, GTK_ALIGN_START);
909
910 hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
911 gtk_widget_show (hbox2);
912 gtk_box_pack_start (GTK_BOX (vbox3), hbox2, FALSE, TRUE, 0);
913
914 appGUI->cnt->contacts_find_entry = gtk_entry_new();
915 gtk_entry_set_max_length(GTK_ENTRY(appGUI->cnt->contacts_find_entry), 128);
916 gtk_widget_show (appGUI->cnt->contacts_find_entry);
917 g_signal_connect (G_OBJECT(appGUI->cnt->contacts_find_entry), "changed",
918 G_CALLBACK(contacts_search_entry_changed_cb), appGUI);
919 gtk_box_pack_start (GTK_BOX (hbox2), appGUI->cnt->contacts_find_entry, TRUE, TRUE, 0);
920
921 appGUI->cnt->contacts_find_clear_button = gtk_button_new_from_icon_name ("edit-clear", GTK_ICON_SIZE_BUTTON);
922 gtk_widget_show (appGUI->cnt->contacts_find_clear_button);
923 gtk_widget_set_can_focus (appGUI->cnt->contacts_find_clear_button, FALSE);
924 gtk_button_set_relief (GTK_BUTTON(appGUI->cnt->contacts_find_clear_button), GTK_RELIEF_NONE);
925 if (config.enable_tooltips) {
926 gtk_widget_set_tooltip_text (appGUI->cnt->contacts_find_clear_button, _("Clear"));
927 }
928 g_signal_connect (G_OBJECT (appGUI->cnt->contacts_find_clear_button), "clicked",
929 G_CALLBACK (cnt_clear_find_cb), appGUI);
930 gtk_box_pack_start (GTK_BOX (hbox2), appGUI->cnt->contacts_find_clear_button, FALSE, FALSE, 0);
931
932 appGUI->cnt->contacts_find_combobox = gtk_combo_box_text_new ();
933 gtk_widget_show (appGUI->cnt->contacts_find_combobox);
934 gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), FALSE);
935 gtk_box_pack_start (GTK_BOX (hbox2), appGUI->cnt->contacts_find_combobox, FALSE, FALSE, 0);
936 g_signal_connect (G_OBJECT (appGUI->cnt->contacts_find_combobox), "changed",
937 G_CALLBACK (contacts_find_type_selected_cb), appGUI);
938 g_signal_connect(G_OBJECT(appGUI->cnt->contacts_find_combobox), "focus",
939 G_CALLBACK(find_combo_box_focus_cb), appGUI);
940 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->cnt->contacts_find_combobox), NULL, _("First Name"));
941 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->cnt->contacts_find_combobox), NULL, _("Last Name"));
942 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->cnt->contacts_find_combobox), NULL, _("Tags"));
943 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->cnt->contacts_find_combobox), NULL, _("All fields"));
944
945 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
946 gtk_widget_show (hseparator);
947 gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, FALSE, 6);
948
949 appGUI->cnt->scrolled_win = gtk_scrolled_window_new (NULL, NULL);
950 gtk_widget_show (appGUI->cnt->scrolled_win);
951 gtk_box_pack_start (GTK_BOX (vbox3), appGUI->cnt->scrolled_win, TRUE, TRUE, 0);
952
953 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->cnt->scrolled_win), GTK_SHADOW_IN);
954 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->cnt->scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
955
956 create_contacts_list_store(appGUI);
957
958 appGUI->cnt->contacts_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(appGUI->cnt->contacts_list_store), NULL);
959 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter),
960 (GtkTreeModelFilterVisibleFunc)contacts_list_filter_cb,
961 appGUI, NULL);
962
963 appGUI->cnt->contacts_sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(appGUI->cnt->contacts_filter));
964
965 appGUI->cnt->contacts_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(appGUI->cnt->contacts_sort));
966 gtk_widget_show (appGUI->cnt->contacts_list);
967 gtk_widget_set_can_default (appGUI->cnt->contacts_list, TRUE);
968 gtk_tree_view_set_enable_search (GTK_TREE_VIEW(appGUI->cnt->contacts_list), FALSE);
969
970 g_signal_connect(G_OBJECT(appGUI->cnt->contacts_list), "button_press_event",
971 G_CALLBACK(contacts_list_dbclick_cb), appGUI);
972
973 appGUI->cnt->contacts_list_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (appGUI->cnt->contacts_list));
974 gtk_tree_selection_set_mode (appGUI->cnt->contacts_list_selection, GTK_SELECTION_MULTIPLE);
975 contacts_selection_activate (TRUE, appGUI);
976
977 /* columns setup */
978
979 for (i = COLUMN_GROUP; i < CONTACTS_NUM_COLUMNS; i++) {
980 renderer[i] = gtk_cell_renderer_text_new();
981 appGUI->cnt->contacts_columns[i] = gtk_tree_view_column_new_with_attributes(gettext(appGUI->cnt->contact_fields_tags_name[i*2]),
982 renderer[i], "text", i, NULL);
983 gtk_tree_view_append_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), appGUI->cnt->contacts_columns[i]);
984
985 if(i != COLUMN_FIRST_NAME && i != COLUMN_LAST_NAME && i != COLUMN_GROUP) {
986 gtk_tree_view_column_set_visible (appGUI->cnt->contacts_columns[i], FALSE);
987 } else {
988
989 if (config.hide_group_column == TRUE && i == COLUMN_GROUP) {
990 gtk_tree_view_column_set_visible (appGUI->cnt->contacts_columns[i], FALSE);
991 }
992
993 gtk_tree_view_column_set_reorderable (appGUI->cnt->contacts_columns[i], TRUE);
994 gtk_tree_view_column_set_resizable (appGUI->cnt->contacts_columns[i], TRUE);
995 gtk_tree_view_column_set_sizing (appGUI->cnt->contacts_columns[i], GTK_TREE_VIEW_COLUMN_FIXED);
996
997 }
998 }
999
1000
1001 /* restore columns order */
1002
1003 columns_order[0] = config.contacts_column_idx_0;
1004 columns_order[1] = config.contacts_column_idx_1;
1005 columns_order[2] = config.contacts_column_idx_2;
1006
1007 n = MAX_VISIBLE_CONTACT_COLUMNS-1;
1008
1009 while (n >= 0) {
1010 for (i = 0; i < MAX_VISIBLE_CONTACT_COLUMNS; i++) {
1011 if (n == columns_order[i]) {
1012 gtk_tree_view_move_column_after(GTK_TREE_VIEW(appGUI->cnt->contacts_list),
1013 appGUI->cnt->contacts_columns[co_columns[i]], NULL);
1014 n--;
1015 }
1016 }
1017 }
1018
1019 set_contacts_columns_width (appGUI);
1020
1021 gtk_container_add (GTK_CONTAINER (appGUI->cnt->scrolled_win), appGUI->cnt->contacts_list);
1022
1023 /* configure sorting */
1024 for (i = 0; i < MAX_VISIBLE_CONTACT_COLUMNS; i++) {
1025 gtk_tree_view_column_set_sort_column_id (appGUI->cnt->contacts_columns[co_columns[i]], co_columns[i]);
1026 }
1027 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (appGUI->cnt->contacts_sort), COLUMN_GROUP,
1028 contacts_column_sort_by_group_function, appGUI, NULL);
1029 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (appGUI->cnt->contacts_sort), COLUMN_FIRST_NAME,
1030 contacts_column_sort_by_first_name_function, appGUI, NULL);
1031 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (appGUI->cnt->contacts_sort), COLUMN_LAST_NAME,
1032 contacts_column_sort_by_last_name_function, appGUI, NULL);
1033
1034
1035 /* restore sorting */
1036 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE (appGUI->cnt->contacts_sort),
1037 config.contacts_sorting_column, config.contacts_sorting_order);
1038
1039 g_signal_connect (appGUI->cnt->contacts_sort, "sort-column-changed", G_CALLBACK (contacts_sort_column_changed_cb), appGUI);
1040
1041 bottom_viewport = gtk_viewport_new (NULL, NULL);
1042 gtk_widget_show (bottom_viewport);
1043 gtk_viewport_set_shadow_type (GTK_VIEWPORT (bottom_viewport), GTK_SHADOW_NONE);
1044 gtk_paned_pack2 (GTK_PANED (appGUI->cnt->contacts_paned), bottom_viewport, TRUE, TRUE);
1045
1046 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1047 gtk_widget_show (vbox2);
1048 gtk_container_set_border_width (GTK_CONTAINER (vbox2), 0);
1049 gtk_container_add (GTK_CONTAINER (bottom_viewport), vbox2);
1050
1051 appGUI->cnt->panel_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1052 gtk_box_pack_start (GTK_BOX (vbox2), appGUI->cnt->panel_hbox, FALSE, FALSE, 0);
1053 gtk_widget_show(appGUI->cnt->panel_hbox);
1054
1055 frame = gtk_frame_new (NULL);
1056 gtk_widget_show (frame);
1057 gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, 0);
1058 gtk_widget_set_margin_left(GTK_WIDGET(frame), 8);
1059 gtk_widget_set_margin_right(GTK_WIDGET(frame), 8);
1060 gtk_widget_set_margin_bottom(GTK_WIDGET(frame), 8);
1061 gtk_frame_set_label_align (GTK_FRAME (frame), 0.98, 0.5);
1062 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
1063
1064 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s</b>", _("Contact details"));
1065 label = gtk_label_new (tmpbuf);
1066 gtk_widget_show (label);
1067 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
1068 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
1069
1070 if (!config.gui_layout) {
1071 close_button = gtk_button_new_from_icon_name ("window-close", GTK_ICON_SIZE_BUTTON);
1072 gtk_widget_set_can_focus(close_button, FALSE);
1073 gtk_button_set_relief (GTK_BUTTON(close_button), GTK_RELIEF_NONE);
1074 if (config.enable_tooltips) {
1075 gtk_widget_set_tooltip_text (close_button, _("Close contact panel"));
1076 }
1077 gtk_widget_show (close_button);
1078 gtk_box_pack_end (GTK_BOX (appGUI->cnt->panel_hbox), close_button, FALSE, FALSE, 0);
1079 g_signal_connect (G_OBJECT (close_button), "clicked", G_CALLBACK (contacts_panel_close_desc_cb), appGUI);
1080 }
1081
1082 appGUI->cnt->contacts_panel_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
1083 gtk_widget_show (appGUI->cnt->contacts_panel_scrolledwindow);
1084 gtk_container_add (GTK_CONTAINER (frame), appGUI->cnt->contacts_panel_scrolledwindow);
1085 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->cnt->contacts_panel_scrolledwindow), GTK_SHADOW_NONE);
1086 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->cnt->contacts_panel_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1087
1088 #ifdef HAVE_LIBWEBKIT
1089 appGUI->cnt->html_webkitview = utl_create_webkit_web_view(appGUI);
1090 webkit_settings_set_default_font_size (webkit_web_view_get_settings(appGUI->cnt->html_webkitview), config.contact_item_font_size);
1091
1092 g_signal_connect (appGUI->cnt->html_webkitview, "context-menu",
1093 G_CALLBACK (utl_webkit_on_menu), appGUI);
1094 g_signal_connect (appGUI->cnt->html_webkitview, "decide-policy",
1095 G_CALLBACK (utl_webkit_link_clicked), appGUI);
1096
1097 gtk_widget_show (GTK_WIDGET(appGUI->cnt->html_webkitview));
1098 gtk_container_add (GTK_CONTAINER (appGUI->cnt->contacts_panel_scrolledwindow),
1099 GTK_WIDGET(appGUI->cnt->html_webkitview));
1100 #endif /* LIBWEBKIT */
1101
1102 gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), config.find_mode);
1103
1104 gtk_tree_sortable_sort_column_changed((GtkTreeSortable *)appGUI->cnt->contacts_sort);
1105 gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter));
1106
1107 g_signal_connect(G_OBJECT(appGUI->cnt->contacts_paned), "notify::position", G_CALLBACK(contacts_paned_position_change_cb), appGUI);
1108 gtk_paned_set_position(GTK_PANED(appGUI->cnt->contacts_paned), config.contacts_pane_pos);
1109
1110 gtk_widget_grab_focus (appGUI->cnt->contacts_find_entry);
1111 }
1112
1113 /*------------------------------------------------------------------------------*/
1114
1115 gboolean
check_address(gint address_type,GUI * appGUI)1116 check_address (gint address_type, GUI *appGUI) {
1117
1118 GtkTreeIter iter;
1119 GtkTreeModel *model;
1120 gchar *text = NULL;
1121 gint n = 0;
1122 gint c1, c2, c3;
1123
1124 if (gtk_tree_selection_count_selected_rows(appGUI->cnt->contacts_list_selection) == 1) {
1125
1126 if (address_type == HOME_ADDRESS) {
1127 c1 = COLUMN_HOME_ADDRESS;
1128 c2 = COLUMN_HOME_CITY;
1129 c3 = COLUMN_HOME_COUNTRY;
1130 } else {
1131 c1 = COLUMN_WORK_ADDRESS;
1132 c2 = COLUMN_WORK_CITY;
1133 c3 = COLUMN_WORK_COUNTRY;
1134 }
1135
1136 iter = utl_gui_get_first_selection_iter(appGUI->cnt->contacts_list_selection, &model);
1137
1138 gtk_tree_model_get (model, &iter, c1, &text, -1);
1139 if (text == NULL) return FALSE;
1140 if (strlen(text)) n++;
1141 g_free (text);
1142 gtk_tree_model_get (model, &iter, c2, &text, -1);
1143 if (text == NULL) return FALSE;
1144 if (strlen(text)) n++;
1145 g_free (text);
1146 gtk_tree_model_get (model, &iter, c3, &text, -1);
1147 if (text == NULL) return FALSE;
1148 if (strlen(text)) n++;
1149 g_free (text);
1150 }
1151
1152 return (n == 3);
1153 }
1154
1155 /*------------------------------------------------------------------------------*/
1156
1157 void
show_contact_location_on_map(gint address_type,GUI * appGUI)1158 show_contact_location_on_map (gint address_type, GUI *appGUI) {
1159
1160 GtkTreeIter iter;
1161 GtkTreeModel *model;
1162 gboolean pn_flag = FALSE;
1163 gint i;
1164 gchar *text = NULL, *mapsURL = NULL;
1165 gchar maps_url[BUFFER_SIZE];
1166 gint cbegin, cend, cskip1, cskip2;
1167
1168 if (gtk_tree_selection_count_selected_rows(appGUI->cnt->contacts_list_selection) == 1) {
1169
1170 if (address_type == HOME_ADDRESS) {
1171 cbegin = COLUMN_HOME_ADDRESS;
1172 cend = COLUMN_HOME_COUNTRY;
1173 cskip1 = COLUMN_HOME_POST_CODE;
1174 cskip2 = COLUMN_HOME_STATE;
1175 } else {
1176 cbegin = COLUMN_WORK_ADDRESS;
1177 cend = COLUMN_WORK_COUNTRY;
1178 cskip1 = COLUMN_WORK_POST_CODE;
1179 cskip2 = COLUMN_WORK_STATE;
1180 }
1181
1182 iter = utl_gui_get_first_selection_iter(appGUI->cnt->contacts_list_selection, &model);
1183
1184 i = config.maps_provider % 3;
1185 if (i == 0) {
1186 g_snprintf(maps_url, BUFFER_SIZE, "%s", GOOGLE_MAPS_QUERY);
1187 } else if (i == 1) {
1188 g_snprintf(maps_url, BUFFER_SIZE, "%s", BING_MAPS_QUERY);
1189 } else {
1190 g_snprintf(maps_url, BUFFER_SIZE, "%s", OSM_MAPS_QUERY);
1191 }
1192
1193 for (i = cbegin; i <= cend; i++) {
1194
1195 if (i == cskip1 || i == cskip2) continue;
1196
1197 gtk_tree_model_get (model, &iter, i, &text, -1);
1198 if (text != NULL) {
1199 if (pn_flag) {
1200 g_strlcat (maps_url, ",", BUFFER_SIZE);
1201 }
1202 g_strlcat (maps_url, text, BUFFER_SIZE);
1203 pn_flag = TRUE;
1204 g_free (text);
1205 }
1206 }
1207
1208 mapsURL = utl_text_to_html(maps_url, TRUE, FALSE);
1209 utl_run_helper(mapsURL, WWW);
1210 free(mapsURL);
1211 }
1212 }
1213
1214 /*------------------------------------------------------------------------------*/
1215
1216 gboolean
queryFilter(GtkTreeModel * model,GtkTreeIter * iter,gpointer data)1217 queryFilter(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
1218 {
1219 gboolean matches;
1220 gchar* value;
1221 gchar* matchWith = data;
1222
1223
1224 /* we don't want to match the empty string to match everything */
1225 if (!g_utf8_strlen(matchWith, -1)) return FALSE;
1226
1227 /* try first name */
1228 value = NULL;
1229 gtk_tree_model_get(model, iter, COLUMN_FIRST_NAME, &value, -1);
1230 if(value != NULL)
1231 {
1232 matches = utl_text_strcasestr(value, matchWith);
1233 g_free (value);
1234 if (matches) return TRUE;
1235 }
1236 /* and last name */
1237 value = NULL;
1238 gtk_tree_model_get(model, iter, COLUMN_LAST_NAME, &value, -1);
1239 if(value != NULL)
1240 {
1241 matches = utl_text_strcasestr(value, matchWith);
1242 g_free (value);
1243 if (matches) return TRUE;
1244 }
1245
1246 return FALSE;
1247 }
1248
1249 gint
query(GUI * appGUI,gchar * matchWith)1250 query(GUI* appGUI, gchar *matchWith)
1251 {
1252 GtkTreeIter sort_iter;
1253 gboolean valid;
1254 gchar *text;
1255 gint n = 0, col;
1256
1257 create_contact_fields(appGUI);
1258 create_contacts_list_store(appGUI);
1259 read_contacts_entries(appGUI);
1260
1261 appGUI->cnt->contacts_filter = gtk_tree_model_filter_new (GTK_TREE_MODEL(appGUI->cnt->contacts_list_store),
1262 NULL);
1263
1264 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter),
1265 queryFilter, /* < this is where the actual filtering takes place */
1266 matchWith, NULL);
1267
1268 /* FIXME: for some reason mutt ignores the first line */
1269 printf("\n");
1270
1271 /* here we loop over all matching contacts and print the e-mail adresses */
1272
1273 appGUI->cnt->contacts_sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(appGUI->cnt->contacts_filter));
1274 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(appGUI->cnt->contacts_sort), &sort_iter);
1275
1276 while (valid) {
1277 GtkTreeIter filter_iter, iter;
1278 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(appGUI->cnt->contacts_sort), &filter_iter, &sort_iter);
1279 gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter), &iter, &filter_iter);
1280
1281 for (col = COLUMN_EMAIL_1; col <= COLUMN_EMAIL_4; col++) {
1282
1283 gtk_tree_model_get(GTK_TREE_MODEL(appGUI->cnt->contacts_list_store),
1284 &iter, col, &text, -1);
1285 if (text) {
1286 printf("%s\n", text);
1287 n++;
1288 }
1289 }
1290 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(appGUI->cnt->contacts_sort), &sort_iter);
1291 }
1292
1293 return n; /* returns number of found emails */
1294 }
1295
1296 /*------------------------------------------------------------------------------*/
1297 #endif /* CONTACTS_ENABLED */
1298
1299