~ubuntu-branches/ubuntu/intrepid/osmo/intrepid-proposed

« back to all changes in this revision

Viewing changes to src/contacts.c

  • Committer: Bazaar Package Importer
  • Author(s): Eike Nicklas
  • Date: 2008-02-09 12:49:42 UTC
  • Revision ID: james.westby@ubuntu.com-20080209124942-7f8x8oro11pzkiws
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <stdio.h>
 
23
#include <string.h>
 
24
#include <ctype.h>
 
25
#include <time.h>
 
26
#include <stdlib.h>
 
27
#include <glib.h>
 
28
#include <math.h>
 
29
#include <ctype.h>
 
30
#include <limits.h>
 
31
#include <unistd.h>
 
32
#include <sys/stat.h>
 
33
 
 
34
#include "i18n.h"
 
35
#include "contacts.h"
 
36
#include "contacts_items.h"
 
37
#include "gui.h"
 
38
#include "gui_utils.h"
 
39
#include "options_prefs.h"
 
40
#include "stock_icons.h"
 
41
#include "contacts_birthdays.h"
 
42
#include "contacts_import.h"
 
43
#include "contacts_export.h"
 
44
#include "time_utils.h"
 
45
#include "date_utils.h"
 
46
 
 
47
/*------------------------------------------------------------------------------*/
 
48
 
 
49
void
 
50
set_export_active (GUI *appGUI) {
 
51
 
 
52
GtkTreeIter iter;
 
53
guint n;
 
54
gboolean state;
 
55
 
 
56
    n = 0;
 
57
    while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(appGUI->cnt->contacts_filter), &iter, NULL, n++));
 
58
    state = (n == 1) ? FALSE : TRUE;
 
59
    gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/export"), state);
 
60
}
 
61
 
 
62
/*------------------------------------------------------------------------------*/
 
63
 
 
64
void
 
65
show_contacts_desc_panel (gboolean enable, GUI *appGUI) {
 
66
 
 
67
GtkTreeIter  iter;
 
68
GdkRectangle rect, visible_rect;
 
69
GtkTreePath  *visible_path;
 
70
GtkTreeModel *model;
 
71
GtkAdjustment *adj;
 
72
 
 
73
    if(enable == TRUE) {
 
74
 
 
75
        if (gtk_tree_selection_get_selected (appGUI->cnt->contacts_list_selection, &model, &iter)) {
 
76
 
 
77
            gtk_paned_set_position(GTK_PANED(appGUI->cnt->contacts_paned), config.contacts_pane_pos);
 
78
 
 
79
            while (g_main_context_iteration(NULL, FALSE));
 
80
 
 
81
            visible_path = gtk_tree_model_get_path (model, &iter);
 
82
 
 
83
            if (visible_path) {
 
84
 
 
85
                gtk_tree_view_get_cell_area (GTK_TREE_VIEW (appGUI->cnt->contacts_list), visible_path, NULL, &rect);
 
86
                gtk_tree_view_get_visible_rect (GTK_TREE_VIEW (appGUI->cnt->contacts_list), &visible_rect);
 
87
 
 
88
                if (rect.y < visible_rect.y || rect.y > visible_rect.y + visible_rect.height) {
 
89
                        gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (appGUI->cnt->contacts_list), visible_path, NULL, TRUE, 0.5, 0.0);
 
90
                }
 
91
 
 
92
                gtk_tree_path_free(visible_path);
 
93
            }
 
94
 
 
95
        } else {
 
96
            enable = FALSE;
 
97
        }
 
98
 
 
99
    } else {
 
100
 
 
101
        config.contacts_pane_pos = gtk_paned_get_position(GTK_PANED(appGUI->cnt->contacts_paned));
 
102
        gtk_paned_set_position(GTK_PANED(appGUI->cnt->contacts_paned), 99999);
 
103
 
 
104
        adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(appGUI->cnt->contacts_panel_scrolledwindow));
 
105
        gtk_adjustment_set_value (adj, 0.0);
 
106
        gtk_adjustment_value_changed (adj);
 
107
 
 
108
    }
 
109
 
 
110
    appGUI->cnt->contacts_panel_status = enable;
 
111
}
 
112
 
 
113
/*------------------------------------------------------------------------------*/
 
114
 
 
115
gboolean
 
116
find_combo_box_focus_cb (GtkWidget *widget, GtkDirectionType *arg1, gpointer user_data) {
 
117
    return TRUE;
 
118
}
 
119
 
 
120
/*------------------------------------------------------------------------------*/
 
121
 
 
122
void
 
123
contacts_panel_close_desc_cb (GtkWidget *widget, gpointer data) {
 
124
 
 
125
    GUI *appGUI = (GUI *)data;
 
126
 
 
127
    show_contacts_desc_panel(FALSE, appGUI);
 
128
}
 
129
 
 
130
/*------------------------------------------------------------------------------*/
 
131
 
 
132
gboolean
 
133
contacts_list_filter_cb (GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
 
134
 
 
135
const gchar *text;
 
136
gchar *value;
 
137
gint i, j, len, text_len;
 
138
guint32 date;
 
139
 
 
140
    GUI *appGUI = (GUI *)data;
 
141
 
 
142
    if (appGUI->cnt->contacts_filter_disabled == TRUE) {
 
143
        return TRUE;
 
144
    }
 
145
 
 
146
    text = gtk_entry_get_text(GTK_ENTRY(appGUI->cnt->contacts_find_entry));
 
147
 
 
148
    if (text == NULL) {
 
149
        return TRUE;
 
150
    }
 
151
 
 
152
    text_len = strlen(text);
 
153
 
 
154
    if (text_len) {
 
155
 
 
156
        if(config.find_mode == CONTACTS_FF_FIRST_NAME) {
 
157
 
 
158
            gtk_tree_model_get(model, iter, COLUMN_FIRST_NAME, &value, -1);
 
159
            if(value != NULL) {
 
160
                if (strlen(value)) {
 
161
                    if(g_ascii_strncasecmp(g_utf8_casefold(text, -1), g_utf8_casefold(value, -1), text_len))
 
162
                        return FALSE;
 
163
                }
 
164
            } else {
 
165
                return FALSE;
 
166
            }
 
167
 
 
168
        } else if (config.find_mode == CONTACTS_FF_LAST_NAME) {
 
169
 
 
170
            gtk_tree_model_get(model, iter, COLUMN_LAST_NAME, &value, -1);
 
171
            if(value != NULL) {
 
172
                if(strlen(value)) {
 
173
                    if(g_ascii_strncasecmp(g_utf8_casefold(text, -1), g_utf8_casefold(value, -1), text_len))
 
174
                        return FALSE;
 
175
                }
 
176
            } else {
 
177
                return FALSE;
 
178
            }
 
179
 
 
180
        } else if (config.find_mode == CONTACTS_FF_ALL_FIELDS) {
 
181
 
 
182
            for(i=0; i < CONTACTS_NUM_COLUMNS; i++) {
 
183
 
 
184
                if (i != COLUMN_PHOTO && i != COLUMN_ID) {
 
185
                    if (i == COLUMN_BIRTH_DAY_DATE || i == COLUMN_NAME_DAY_DATE) {
 
186
                        gtk_tree_model_get (model, iter, i, &date, -1);
 
187
                        if (date == 0) {
 
188
                            value = NULL;
 
189
                        } else {
 
190
                            if (i == COLUMN_BIRTH_DAY_DATE) {
 
191
                                value = g_strdup((const gchar *)julian_to_str(date, DATE_FULL));
 
192
                            } else {
 
193
                                value = g_strdup((const gchar *)julian_to_str(date, DATE_NAME_DAY));
 
194
                            }
 
195
                        }
 
196
                    } else {
 
197
                        gtk_tree_model_get(model, iter, i, &value, -1);
 
198
                    }
 
199
 
 
200
                    if (value != NULL) {
 
201
 
 
202
                        len = strlen(value) - text_len;
 
203
 
 
204
                        if (len >= 0) {
 
205
                            for(j=0; j <= len; j++) {
 
206
                                if(!g_ascii_strncasecmp(g_utf8_casefold(text, -1), g_utf8_casefold(value+j, -1), text_len))
 
207
                                    return TRUE;
 
208
                            }
 
209
                        }
 
210
 
 
211
                        g_free(value);
 
212
                    }
 
213
                }
 
214
            }
 
215
 
 
216
            return FALSE;
 
217
        }
 
218
    }
 
219
 
 
220
    return TRUE;
 
221
}
 
222
 
 
223
/*------------------------------------------------------------------------------*/
 
224
 
 
225
void
 
226
contacts_select_first_position_in_list(GUI *appGUI) {
 
227
 
 
228
GtkTreeIter     iter;
 
229
GtkTreePath     *path;
 
230
 
 
231
    /* set cursor at first position */
 
232
    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(appGUI->cnt->contacts_list_store), &iter) == TRUE) {
 
233
        path = gtk_tree_model_get_path (GTK_TREE_MODEL(appGUI->cnt->contacts_list_store), &iter);
 
234
        if (path != NULL) {
 
235
            gtk_tree_view_set_cursor (GTK_TREE_VIEW (appGUI->cnt->contacts_list), path, NULL, FALSE);
 
236
            gtk_tree_path_free(path);
 
237
        }
 
238
    }
 
239
}
 
240
 
 
241
/*------------------------------------------------------------------------------*/
 
242
 
 
243
void
 
244
contacts_item_selected_cb (GtkTreeSelection *selection, gpointer data) {
 
245
 
 
246
GtkTreeIter iter;
 
247
GtkTreeModel *model;
 
248
gchar *text;
 
249
GtkTextIter titer;
 
250
GtkTextBuffer *text_buffer;
 
251
gint i, j;
 
252
gchar photo_full_path[PATH_MAX], space_line[PATH_MAX];
 
253
char tmpbuf[BUFFER_SIZE];
 
254
gboolean activate_home_phone, activate_work_phone, activate_cell_phone;
 
255
gboolean activate_email, activate_www;
 
256
guint32 date;
 
257
 
 
258
    GUI *appGUI = (GUI *)data;
 
259
 
 
260
    if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
 
261
 
 
262
        gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/edit"), TRUE);
 
263
        gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/delete"), TRUE);
 
264
        set_export_active (appGUI);
 
265
 
 
266
        text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview));
 
267
        gui_clear_text_buffer (text_buffer, &titer);
 
268
 
 
269
        if (appGUI->cnt->photo_image != NULL) {      /* remove old photo */
 
270
            gtk_widget_destroy(appGUI->cnt->photo_image);
 
271
            appGUI->cnt->photo_image = NULL;
 
272
        }
 
273
 
 
274
        gui_url_remove_links (&appGUI->cnt->contacts_links_list, &appGUI->cnt->contacts_link_index);
 
275
 
 
276
        for(i=0; i < CONTACTS_NUM_COLUMNS; i++) {
 
277
 
 
278
            if (i != COLUMN_ID) {
 
279
 
 
280
                if (i == COLUMN_BIRTH_DAY_DATE || i == COLUMN_NAME_DAY_DATE) {
 
281
                    gtk_tree_model_get (model, &iter, i, &date, -1);
 
282
                    if (date == 0) {
 
283
                        text = NULL;
 
284
                    } else {
 
285
                        if (i == COLUMN_BIRTH_DAY_DATE) {
 
286
                            text = g_strdup((const gchar *)julian_to_str(date, DATE_FULL));
 
287
                        } else {
 
288
                            text = g_strdup((const gchar *)julian_to_str(date, DATE_NAME_DAY));
 
289
                        }
 
290
                    }
 
291
                } else {
 
292
                    gtk_tree_model_get (model, &iter, i, &text, -1);
 
293
                }
 
294
 
 
295
                    if (i != COLUMN_PHOTO && i != COLUMN_ID) {
 
296
 
 
297
                        if (i == COLUMN_FIRST_NAME || i == COLUMN_SECOND_NAME || i == COLUMN_LAST_NAME) {
 
298
 
 
299
                            if (text != NULL) {
 
300
                                gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, text, -1,
 
301
                                                          "big", NULL);
 
302
                                gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, " ", -1,
 
303
                                                          "big", NULL);
 
304
                            }
 
305
 
 
306
                            if (i == COLUMN_LAST_NAME) {
 
307
                                gtk_text_buffer_insert(text_buffer, &titer, "\n", -1);
 
308
                            }
 
309
 
 
310
                        } else if (text != NULL && i!= COLUMN_GROUP) {
 
311
 
 
312
                            gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, "\n", -1, "normal", NULL);
 
313
 
 
314
                            activate_home_phone = (i == COLUMN_HOME_PHONE_2 || i == COLUMN_HOME_PHONE_3 || i == COLUMN_HOME_PHONE_4) && strlen(text);
 
315
                            activate_work_phone = (i == COLUMN_WORK_PHONE_2 || i == COLUMN_WORK_PHONE_3 || i == COLUMN_WORK_PHONE_4) && strlen(text);
 
316
                            activate_cell_phone = (i == COLUMN_WORK_PHONE_2 || i == COLUMN_WORK_PHONE_3 || i == COLUMN_WORK_PHONE_4) && strlen(text);
 
317
                            activate_email = (i == COLUMN_EMAIL_2 || i == COLUMN_EMAIL_3 || i == COLUMN_EMAIL_4) && strlen(text);
 
318
                            activate_www = (i == COLUMN_WWW_2 || i == COLUMN_WWW_3 || i == COLUMN_WWW_4) && strlen(text);
 
319
 
 
320
                            for(j=0;j<PATH_MAX;j++) space_line[j] = ' ';
 
321
 
 
322
                            if ((i >= COLUMN_HOME_PHONE_1 && i <= COLUMN_HOME_PHONE_4)  ||
 
323
                                (i >= COLUMN_WORK_PHONE_1 && i <= COLUMN_WORK_PHONE_4)  ||
 
324
                                (i >= COLUMN_CELL_PHONE_1 && i <= COLUMN_CELL_PHONE_4)  ||
 
325
                                (i >= COLUMN_EMAIL_1 && i <= COLUMN_EMAIL_4) ||
 
326
                                (i >= COLUMN_WWW_1 && i <= COLUMN_WWW_4)) {
 
327
 
 
328
                                if ((activate_home_phone == FALSE && i == COLUMN_HOME_PHONE_1) ||
 
329
                                   (activate_work_phone == FALSE && i == COLUMN_WORK_PHONE_1)  ||
 
330
                                   (activate_cell_phone == FALSE && i == COLUMN_CELL_PHONE_1)  ||
 
331
                                   (activate_email == FALSE && i == COLUMN_EMAIL_1) ||
 
332
                                   (activate_www == FALSE && i == COLUMN_WWW_1)) {
 
333
 
 
334
                                    sprintf(tmpbuf, "%s: ", gettext(appGUI->cnt->contact_fields_tags_name[2*i]));
 
335
                                } else {
 
336
                                    sprintf(tmpbuf, " ");
 
337
                                }
 
338
 
 
339
                            } else {
 
340
                                sprintf(tmpbuf, "%s: ", gettext(appGUI->cnt->contact_fields_tags_name[2*i]));
 
341
                            }
 
342
 
 
343
                            if (i != COLUMN_INFO) {
 
344
                                space_line[appGUI->cnt->longest_tag_name - strlen(tmpbuf) + 2] = '\0';
 
345
                                strcat(tmpbuf, space_line);
 
346
                            }
 
347
                            gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, tmpbuf, -1, "tag_name", NULL);
 
348
 
 
349
                            if (i == COLUMN_INFO) {
 
350
                                gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, "\n", -1, "normal", NULL);
 
351
                            }
 
352
 
 
353
                            if (i == COLUMN_BLOG || (i >= COLUMN_EMAIL_1 && i <= COLUMN_EMAIL_4) || (i >= COLUMN_WWW_1 && i <= COLUMN_WWW_4)) { /* insert link */
 
354
                                gui_url_insert_link(&appGUI->cnt->contacts_links_list, &appGUI->cnt->contacts_link_index, appGUI->cnt->contacts_desc_textview , &titer, config.contact_link_color, config.tags_font_size, text, FALSE, appGUI);
 
355
                            } else {
 
356
                                 gtk_text_buffer_insert_with_tags_by_name (text_buffer, &titer, text, -1, "normal", NULL);
 
357
                            }
 
358
                        }
 
359
                    }
 
360
 
 
361
                    g_free(text);
 
362
            }
 
363
        }
 
364
 
 
365
        /* insert photo */
 
366
        gtk_tree_model_get (model, &iter, COLUMN_PHOTO, &text, -1);
 
367
 
 
368
        if (text != NULL) {
 
369
            strncpy(photo_full_path, text, PATH_MAX-1);
 
370
            insert_photo(photo_full_path, &titer, appGUI);
 
371
            g_free(text);
 
372
        }
 
373
 
 
374
    } else {
 
375
        gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/edit"), FALSE);
 
376
        gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/delete"), FALSE);
 
377
        set_export_active (appGUI);
 
378
    }
 
379
}
 
380
 
 
381
/*------------------------------------------------------------------------------*/
 
382
 
 
383
void
 
384
contacts_desc_scrolled (GtkAdjustment *adj,  gpointer data) {
 
385
 
 
386
gint x, y;
 
387
 
 
388
    GUI *appGUI = (GUI *)data;
 
389
 
 
390
    if (appGUI->cnt->photo_image != NULL) {
 
391
        gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), GTK_TEXT_WINDOW_TEXT,
 
392
                                              appGUI->cnt->contacts_desc_textview->allocation.width-config.photo_width-5, 5, &x, &y);
 
393
        gtk_text_view_move_child(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), appGUI->cnt->photo_image,
 
394
                                 appGUI->cnt->contacts_desc_textview->allocation.width-config.photo_width-5, y);
 
395
    }
 
396
}
 
397
 
 
398
void
 
399
contacts_desc_size_allocate (GtkWidget *widget, GtkAllocation *allocation, gpointer data) {
 
400
 
 
401
    GUI *appGUI = (GUI *)data;
 
402
    contacts_desc_scrolled(NULL, appGUI);
 
403
}
 
404
 
 
405
/*------------------------------------------------------------------------------*/
 
406
 
 
407
void
 
408
add_contacts_toolbar_widget (GtkUIManager *contacts_uim_widget, GtkWidget *widget, gpointer user_data) {
 
409
 
 
410
GtkWidget *handle_box;
 
411
 
 
412
    GUI *appGUI = (GUI *)user_data;
 
413
 
 
414
    if (GTK_IS_TOOLBAR (widget)) {
 
415
 
 
416
        appGUI->cnt->contacts_toolbar = GTK_TOOLBAR (widget);
 
417
 
 
418
        handle_box = gtk_handle_box_new ();
 
419
        gtk_widget_show (handle_box);
 
420
        gtk_container_add (GTK_CONTAINER (handle_box), widget);
 
421
        gtk_box_pack_start (appGUI->cnt->vbox, handle_box, FALSE, FALSE, 0);
 
422
        g_signal_connect_swapped (widget, "destroy", G_CALLBACK (gtk_widget_destroy), handle_box);
 
423
 
 
424
    } else {
 
425
        gtk_box_pack_start (appGUI->cnt->vbox, widget, FALSE, FALSE, 0);
 
426
    }
 
427
 
 
428
    gtk_widget_show (widget);
 
429
}
 
430
 
 
431
/*------------------------------------------------------------------------------*/
 
432
 
 
433
gboolean
 
434
contacts_search_entry_changed_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data) {
 
435
 
 
436
GtkTreePath *path;
 
437
GtkTreeIter iter;
 
438
GtkTextIter titer;
 
439
gint i;
 
440
 
 
441
    GUI *appGUI = (GUI *)user_data;
 
442
 
 
443
    gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter));
 
444
    set_export_active (appGUI);
 
445
 
 
446
    if(strlen(gtk_entry_get_text (GTK_ENTRY(appGUI->cnt->contacts_find_entry)))) {
 
447
 
 
448
        if (config.show_after_search == TRUE) {
 
449
 
 
450
            i = 0;
 
451
            while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(appGUI->cnt->contacts_filter), &iter, NULL, i++));
 
452
 
 
453
            if (i-1 != 0) {
 
454
                show_contacts_desc_panel(TRUE, appGUI);
 
455
 
 
456
                path = gtk_tree_path_new_first();
 
457
                if (path != NULL) {
 
458
                    gtk_tree_view_set_cursor (GTK_TREE_VIEW (appGUI->cnt->contacts_list), path, NULL, FALSE);
 
459
                    g_free(path);
 
460
                }
 
461
            } else {
 
462
                gui_clear_text_buffer (gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview)), &titer);
 
463
            }
 
464
        }
 
465
    }
 
466
    return FALSE;
 
467
}
 
468
 
 
469
/*------------------------------------------------------------------------------*/
 
470
 
 
471
void
 
472
contacts_find_type_selected_cb (GtkComboBox *widget, gpointer user_data) {
 
473
 
 
474
GtkTreePath *path;
 
475
 
 
476
    GUI *appGUI = (GUI *)user_data;
 
477
 
 
478
    config.find_mode = gtk_combo_box_get_active (widget);
 
479
 
 
480
    if(strlen(gtk_entry_get_text (GTK_ENTRY(appGUI->cnt->contacts_find_entry)))) {
 
481
        gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter));
 
482
 
 
483
        path = gtk_tree_path_new_first();
 
484
        if (path != NULL) {
 
485
            gtk_tree_view_set_cursor (GTK_TREE_VIEW (appGUI->cnt->contacts_list), path, NULL, FALSE);
 
486
            g_free(path);
 
487
            show_contacts_desc_panel(TRUE, appGUI);
 
488
        }
 
489
    }
 
490
}
 
491
 
 
492
/*------------------------------------------------------------------------------*/
 
493
 
 
494
gint
 
495
custom_contacts_sort_function (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer user_data) {
 
496
 
 
497
gchar *last_name_a, *last_name_b;
 
498
gchar *group_a, *group_b;
 
499
gchar *first_name_a, *first_name_b;
 
500
gint group_s, first_name_s, last_name_s;
 
501
 
 
502
    GUI *appGUI = (GUI *)user_data;
 
503
 
 
504
    if (appGUI->cnt->contacts_filter_disabled == TRUE)
 
505
        return 0;
 
506
 
 
507
    if(iter_a == NULL || iter_b == NULL) {
 
508
        return 0;
 
509
    }
 
510
 
 
511
    gtk_tree_model_get(model, iter_a,
 
512
                       COLUMN_GROUP, &group_a, COLUMN_FIRST_NAME, &first_name_a, COLUMN_LAST_NAME, &last_name_a, -1);
 
513
    gtk_tree_model_get(model, iter_b,
 
514
                       COLUMN_GROUP, &group_b, COLUMN_FIRST_NAME, &first_name_b, COLUMN_LAST_NAME, &last_name_b, -1);
 
515
 
 
516
    if (group_a == NULL) {
 
517
        group_s = -1;
 
518
    } else if (group_b == NULL) {
 
519
        group_s = 1;
 
520
    } else if (group_a != NULL && group_b != NULL) {
 
521
        group_s = g_utf8_collate(group_a, group_b);
 
522
    } else {
 
523
        group_s = 0;
 
524
    }
 
525
 
 
526
    if (group_a != NULL) {
 
527
        g_free(group_a);
 
528
    }
 
529
    if (group_b != NULL) {
 
530
        g_free(group_b);
 
531
    }
 
532
 
 
533
    if (first_name_a == NULL) {
 
534
        first_name_s = -1;
 
535
    } else if (first_name_b == NULL) {
 
536
        first_name_s = 1;
 
537
    } else if (first_name_a != NULL && first_name_b != NULL) {
 
538
        first_name_s = g_utf8_collate(first_name_a, first_name_b);
 
539
    } else {
 
540
        first_name_s = 0;
 
541
    }
 
542
 
 
543
    if (first_name_a != NULL) {
 
544
        g_free(first_name_a);
 
545
    }
 
546
    if (first_name_b != NULL) {
 
547
        g_free(first_name_b);
 
548
    }
 
549
 
 
550
    if (last_name_a == NULL) {
 
551
        last_name_s = -1;
 
552
    } else if (last_name_b == NULL) {
 
553
        last_name_s = 1;
 
554
    } else if (last_name_a != NULL && last_name_b != NULL) {
 
555
        last_name_s = g_utf8_collate(last_name_a, last_name_b);
 
556
    } else {
 
557
        last_name_s = 0;
 
558
    }
 
559
 
 
560
    if (last_name_a != NULL) {
 
561
        g_free(last_name_a);
 
562
    }
 
563
    if (last_name_b != NULL) {
 
564
        g_free(last_name_b);
 
565
    }
 
566
 
 
567
    switch(config.contacts_sorting_mode) {
 
568
 
 
569
        /* Group, First Name, Last Name */
 
570
        case 0:
 
571
            if (group_s != 0)
 
572
                return group_s;
 
573
            if (first_name_s != 0)
 
574
                return first_name_s;
 
575
            if (last_name_s != 0)
 
576
                return last_name_s;
 
577
            break;
 
578
 
 
579
        /* Group, Last Name, First Name */
 
580
        case 1:
 
581
            if (group_s != 0)
 
582
                return group_s;
 
583
            if (last_name_s != 0)
 
584
                return last_name_s;
 
585
            if (first_name_s != 0)
 
586
                return first_name_s;
 
587
            break;
 
588
 
 
589
        /* Last Name, First Name, Group */
 
590
        case 2:
 
591
            if (last_name_s != 0)
 
592
                return last_name_s;
 
593
            if (first_name_s != 0)
 
594
                return first_name_s;
 
595
            if (group_s != 0)
 
596
                return group_s;
 
597
            break;
 
598
 
 
599
        /* Last Name, Group, First Name */
 
600
        case 3:
 
601
            if (last_name_s != 0)
 
602
                return last_name_s;
 
603
            if (group_s != 0)
 
604
                return group_s;
 
605
            if (first_name_s != 0)
 
606
                return first_name_s;
 
607
            break;
 
608
 
 
609
        /* First Name, Last Name, Group */
 
610
        case 4:
 
611
            if (first_name_s != 0)
 
612
                return first_name_s;
 
613
            if (last_name_s != 0)
 
614
                return last_name_s;
 
615
            if (group_s != 0)
 
616
                return group_s;
 
617
            break;
 
618
 
 
619
        /* First Name, Group, Last Name */
 
620
        case 5:
 
621
            if (first_name_s != 0)
 
622
                return first_name_s;
 
623
            if (group_s != 0)
 
624
                return group_s;
 
625
            if (last_name_s != 0)
 
626
                return last_name_s;
 
627
            break;
 
628
 
 
629
        default:
 
630
            break;
 
631
    }
 
632
 
 
633
    return 0;
 
634
}
 
635
 
 
636
/*------------------------------------------------------------------------------*/
 
637
 
 
638
void
 
639
contacts_add_item_cb (GtkWidget *widget, gpointer data) {
 
640
 
 
641
    GUI *appGUI = (GUI *)data;
 
642
    contacts_add_edit_dialog_show (FALSE, appGUI);
 
643
}
 
644
 
 
645
/*------------------------------------------------------------------------------*/
 
646
 
 
647
void
 
648
contacts_edit_item_cb (GtkWidget *widget, gpointer data) {
 
649
 
 
650
    GUI *appGUI = (GUI *)data;
 
651
 
 
652
    if (gtk_tree_selection_get_selected (appGUI->cnt->contacts_list_selection, NULL, NULL)) {
 
653
        GUI *appGUI = (GUI *)data;
 
654
        contacts_add_edit_dialog_show (TRUE, appGUI);
 
655
    }
 
656
}
 
657
 
 
658
/*------------------------------------------------------------------------------*/
 
659
 
 
660
void
 
661
contacts_remove_item_cb (GtkWidget *widget, gpointer data) {
 
662
 
 
663
    GUI *appGUI = (GUI *)data;
 
664
    contacts_remove_dialog_show(appGUI->cnt->contacts_list, appGUI->cnt->contacts_list_store, appGUI);
 
665
}
 
666
 
 
667
/*------------------------------------------------------------------------------*/
 
668
 
 
669
void
 
670
contacts_birthdays_item_cb (GtkWidget *widget, gpointer data) {
 
671
 
 
672
    GUI *appGUI = (GUI *)data;
 
673
    contacts_create_birthdays_window (appGUI);
 
674
}
 
675
 
 
676
/*------------------------------------------------------------------------------*/
 
677
 
 
678
void
 
679
contacts_export_items_cb (GtkWidget *widget, gpointer data) {
 
680
 
 
681
    GUI *appGUI = (GUI *)data;
 
682
    contacts_create_export_window(appGUI);
 
683
}
 
684
 
 
685
/*------------------------------------------------------------------------------*/
 
686
 
 
687
void
 
688
contacts_import_items_cb (GtkWidget *widget, gpointer data) {
 
689
 
 
690
    GUI *appGUI = (GUI *)data;
 
691
    import_contacts_from_csv_file(appGUI);
 
692
}
 
693
 
 
694
/*------------------------------------------------------------------------------*/
 
695
 
 
696
gint
 
697
contacts_list_dbclick_cb(GtkWidget * widget, GdkEventButton * event, gpointer func_data) {
 
698
 
 
699
    GUI *appGUI = (GUI *)func_data;
 
700
 
 
701
    if ((event->type==GDK_2BUTTON_PRESS) && (event->button == 1)) {
 
702
 
 
703
        if (appGUI->cnt->contacts_panel_status == TRUE) {
 
704
            contacts_edit_item_cb (NULL, appGUI);
 
705
        } else {
 
706
            show_contacts_desc_panel(TRUE, appGUI);
 
707
        }
 
708
        return TRUE;
 
709
    }
 
710
 
 
711
    return FALSE;
 
712
}
 
713
 
 
714
/*------------------------------------------------------------------------------*/
 
715
 
 
716
void
 
717
gui_create_contacts(GUI *appGUI) {
 
718
 
 
719
GtkWidget       *vbox1;
 
720
GtkWidget       *vbox2;
 
721
GtkWidget       *hbox2;
 
722
GtkWidget       *hseparator;
 
723
GtkWidget       *label;
 
724
GtkWidget       *top_scrolledwindow;
 
725
GtkWidget       *top_viewport;
 
726
GtkWidget       *bottom_viewport;
 
727
GtkWidget       *close_button;
 
728
GtkCellRenderer *renderer[CONTACTS_NUM_COLUMNS];
 
729
GType           contact_columns_types[CONTACTS_NUM_COLUMNS];
 
730
GtkTextBuffer   *text_buffer;
 
731
gint            i;
 
732
GError          *error = NULL;
 
733
GtkActionGroup  *action_group = NULL;
 
734
GtkAdjustment   *adjustment;
 
735
char tmpbuf[BUFFER_SIZE];
 
736
 
 
737
static gchar *contact_fields_tags_name[] = {
 
738
    N_("Group"), "group", N_("First name"), "first_name", N_("Second name"), "second_name", 
 
739
    N_("Last name"), "last_name", 
 
740
    N_("Nickname"), "nickname", N_("Birthday date"), "birthday_date", N_("Name day date"), "name_day_date",
 
741
 
 
742
    /*--------------------------------------------------*/
 
743
    N_("Home address"), "home_address", N_("Home postcode"), "home_postcode", N_("Home city"), 
 
744
    "home_city", N_("Home state"), "home_state", N_("Home country"), "home_country",
 
745
    /*--------------------------------------------------*/
 
746
 
 
747
    N_("Organization"), "organization", N_("Department"), "department",
 
748
 
 
749
    /*--------------------------------------------------*/
 
750
    N_("Work address"), "work_address", N_("Work postcode"), "work_postcode", N_("Work city"), 
 
751
    "work_city", N_("Work state"), "work_state", N_("Work country"), "work_country",
 
752
    /*--------------------------------------------------*/
 
753
 
 
754
    N_("Fax"), "work_fax",
 
755
 
 
756
    /*--------------------------------------------------*/
 
757
    N_("Home phone"), "home_phone_1", N_("Home phone 2"), "home_phone_2",
 
758
    N_("Home phone 3"), "home_phone_3", N_("Home phone 4"), "home_phone_4",
 
759
    N_("Work phone"), "work_phone_1", N_("Work phone 2"), "work_phone_2",
 
760
    N_("Work phone 3"), "work_phone_3", N_("Work phone 4"), "work_phone_4",
 
761
    N_("Cell phone"), "cell_phone_1", N_("Cell phone 2"), "cell_phone_2",
 
762
    N_("Cell phone 3"), "cell_phone_3", N_("Cell phone 4"), "cell_phone_4",
 
763
    N_("E-Mail"), "email_1", N_("E-Mail 2"), "email_2", N_("E-Mail 3"), "email_3", 
 
764
    N_("E-Mail 4"), "email_4", N_("WWW"), "www_1", N_("WWW 2"), "www_2", N_("WWW 3"), "www_3", 
 
765
    N_("WWW 4"), "www_4",
 
766
    /*--------------------------------------------------*/
 
767
 
 
768
    N_("IM Gadu-Gadu"), "im_gg", N_("IM Yahoo"), "im_yahoo", N_("IM MSN"), "im_msn",
 
769
    N_("IM ICQ"), "im_icq", N_("IM AOL"), "im_aol",
 
770
    N_("IM Jabber"), "im_jabber", N_("IM Skype"), "im_skype", N_("IM Tlen"), "im_tlen",
 
771
    N_("Blog"), "blog", N_("Photo"), "photo_path", N_("Additional info"), "additional_info", "ID", "id"
 
772
};
 
773
 
 
774
const gchar *ui_info =
 
775
"  <toolbar name=\"toolbar\">\n"
 
776
"    <toolitem name=\"add\" action=\"add\" />\n"
 
777
"    <toolitem name=\"delete\" action=\"delete\" />\n"
 
778
"    <toolitem name=\"edit\" action=\"edit\" />\n"
 
779
"    <separator name=\"sep1\" />\n"
 
780
"    <toolitem name=\"birthdays\" action=\"birthdays\" />\n"
 
781
"    <separator name=\"sep2\" />\n"
 
782
"    <toolitem name=\"import\" action=\"import\" />\n"
 
783
"    <toolitem name=\"export\" action=\"export\" />\n"
 
784
"  </toolbar>\n";
 
785
 
 
786
GtkActionEntry entries[] = {
 
787
    { "add", OSMO_STOCK_CONTACTS_ADD, _("New contact"), NULL, _("New contact"), NULL },
 
788
    { "delete", OSMO_STOCK_CONTACTS_REMOVE, _("Remove contact"), NULL, _("Remove contact"), NULL },
 
789
    { "edit", OSMO_STOCK_CONTACTS_EDIT, _("Edit contact"), NULL, _("Edit contact"), NULL },
 
790
    { "birthdays", OSMO_STOCK_CONTACTS_BIRTHDAYS, _("Show birthdays"), NULL, _("Show birthdays"), NULL },
 
791
    { "import", OSMO_STOCK_CONTACTS_IMPORT, _("Import contacts"), NULL, _("Import contacts"), NULL },
 
792
    { "export", OSMO_STOCK_CONTACTS_EXPORT, _("Export contacts"), NULL, _("Export contacts"), NULL },
 
793
};
 
794
 
 
795
guint n_entries = G_N_ELEMENTS (entries);
 
796
 
 
797
    appGUI->cnt->contact_fields_tags_name = contact_fields_tags_name;
 
798
    appGUI->cnt->longest_tag_name = 0;
 
799
 
 
800
    for(i=0; i < CONTACTS_NUM_COLUMNS; i++) {
 
801
        if (i != COLUMN_ID) {
 
802
            if (appGUI->cnt->longest_tag_name < strlen(gettext(contact_fields_tags_name[i*2]))) {
 
803
                appGUI->cnt->longest_tag_name = strlen(gettext(contact_fields_tags_name[i*2]));
 
804
            }
 
805
        }
 
806
    }
 
807
 
 
808
    vbox1 = gtk_vbox_new (FALSE, 0);
 
809
    gtk_widget_show (vbox1);
 
810
    gtk_container_set_border_width (GTK_CONTAINER (vbox1), 8);
 
811
    sprintf(tmpbuf, "<b>%s</b>", _("Contacts"));
 
812
    gui_add_to_notebook (vbox1, tmpbuf, appGUI);
 
813
 
 
814
    appGUI->cnt->vbox = GTK_BOX(vbox1);
 
815
 
 
816
    if (config.hide_contacts == TRUE) {
 
817
        gtk_widget_hide(GTK_WIDGET(appGUI->cnt->vbox));
 
818
    }
 
819
 
 
820
    /*-------------------------------------------------------------------------------------*/
 
821
 
 
822
    action_group = gtk_action_group_new ("_actions");
 
823
    gtk_action_group_add_actions (action_group, entries, n_entries, NULL);
 
824
    gtk_action_group_set_sensitive(action_group, TRUE);
 
825
 
 
826
    appGUI->cnt->contacts_uim_widget = gtk_ui_manager_new ();
 
827
 
 
828
    gtk_ui_manager_insert_action_group (appGUI->cnt->contacts_uim_widget, action_group, 0);
 
829
    g_signal_connect (appGUI->cnt->contacts_uim_widget, "add_widget", G_CALLBACK (add_contacts_toolbar_widget), appGUI);
 
830
 
 
831
    if (!gtk_ui_manager_add_ui_from_string (appGUI->cnt->contacts_uim_widget, ui_info, -1, &error)) {
 
832
        g_message ("building toolbar failed: %s", error->message);
 
833
        g_error_free (error);
 
834
    }
 
835
    gtk_ui_manager_ensure_update (appGUI->cnt->contacts_uim_widget);
 
836
 
 
837
    gtk_toolbar_set_style (appGUI->cnt->contacts_toolbar, GTK_TOOLBAR_ICONS);
 
838
    gtk_toolbar_set_tooltips (appGUI->cnt->contacts_toolbar, config.enable_tooltips);
 
839
 
 
840
    /*-------------------------------------------------------------------------------------*/
 
841
    /* assign callbacks */
 
842
 
 
843
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/add")), "clicked", 
 
844
                      G_CALLBACK(contacts_add_item_cb), appGUI);
 
845
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/edit")), "clicked", 
 
846
                      G_CALLBACK(contacts_edit_item_cb), appGUI);
 
847
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/delete")), "clicked", 
 
848
                      G_CALLBACK(contacts_remove_item_cb), appGUI);
 
849
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/birthdays")), "clicked", 
 
850
                      G_CALLBACK(contacts_birthdays_item_cb), appGUI);
 
851
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/export")), "clicked", 
 
852
                      G_CALLBACK(contacts_export_items_cb), appGUI);
 
853
    g_signal_connect (G_OBJECT(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/import")), "clicked", 
 
854
                      G_CALLBACK(contacts_import_items_cb), appGUI);
 
855
 
 
856
    /*-------------------------------------------------------------------------------------*/
 
857
 
 
858
    gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/edit"), FALSE);
 
859
    gtk_widget_set_sensitive(gtk_ui_manager_get_widget (appGUI->cnt->contacts_uim_widget, "/toolbar/delete"), FALSE);
 
860
 
 
861
    hseparator = gtk_hseparator_new ();
 
862
    gtk_widget_show (hseparator);
 
863
    gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, FALSE, 6);
 
864
 
 
865
    sprintf(tmpbuf, "<b>%s:</b>", _("Search"));
 
866
    label = gtk_label_new (tmpbuf);
 
867
    gtk_widget_show (label);
 
868
    gtk_label_set_use_markup (GTK_LABEL(label), TRUE);
 
869
    gtk_box_pack_start (GTK_BOX (vbox1), label, FALSE, FALSE, 0);
 
870
    gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
 
871
 
 
872
    hbox2 = gtk_hbox_new (FALSE, 0);
 
873
    gtk_widget_show (hbox2);
 
874
    gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, TRUE, 0);
 
875
 
 
876
    appGUI->cnt->contacts_find_entry = gtk_entry_new();
 
877
    gtk_entry_set_max_length(GTK_ENTRY(appGUI->cnt->contacts_find_entry), 128);
 
878
    gtk_widget_show (appGUI->cnt->contacts_find_entry);
 
879
    g_signal_connect (G_OBJECT(appGUI->cnt->contacts_find_entry), "key_release_event",
 
880
                        G_CALLBACK(contacts_search_entry_changed_cb), appGUI);
 
881
    gtk_box_pack_start (GTK_BOX (hbox2), appGUI->cnt->contacts_find_entry, TRUE, TRUE, 0);
 
882
 
 
883
    appGUI->cnt->contacts_find_combobox = gtk_combo_box_new_text ();
 
884
    gtk_widget_show (appGUI->cnt->contacts_find_combobox);
 
885
    gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), FALSE);
 
886
    gtk_box_pack_start (GTK_BOX (hbox2), appGUI->cnt->contacts_find_combobox, FALSE, FALSE, 0);
 
887
    g_signal_connect (G_OBJECT (appGUI->cnt->contacts_find_combobox), "changed",
 
888
                      G_CALLBACK (contacts_find_type_selected_cb), appGUI);
 
889
    g_signal_connect(G_OBJECT(appGUI->cnt->contacts_find_combobox), "focus",
 
890
                     G_CALLBACK(find_combo_box_focus_cb), appGUI);
 
891
    gtk_combo_box_append_text (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), _("First Name"));
 
892
    gtk_combo_box_append_text (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), _("Last Name"));
 
893
    gtk_combo_box_append_text (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), _("All fields"));
 
894
 
 
895
    hseparator = gtk_hseparator_new ();
 
896
    gtk_widget_show (hseparator);
 
897
    gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, FALSE, 6);
 
898
 
 
899
/******************************************************************************************/
 
900
 
 
901
    appGUI->cnt->contacts_paned = gtk_vpaned_new();
 
902
    gtk_widget_show (appGUI->cnt->contacts_paned);
 
903
    gtk_paned_set_position(GTK_PANED(appGUI->cnt->contacts_paned), 99999);
 
904
    gtk_box_pack_start(GTK_BOX(vbox1), appGUI->cnt->contacts_paned, TRUE, TRUE, 0);
 
905
 
 
906
    top_viewport = gtk_viewport_new (NULL, NULL);
 
907
    gtk_widget_show (top_viewport);
 
908
    gtk_viewport_set_shadow_type (GTK_VIEWPORT (top_viewport), GTK_SHADOW_NONE);
 
909
    gtk_paned_pack1 (GTK_PANED (appGUI->cnt->contacts_paned), top_viewport, FALSE, TRUE);
 
910
 
 
911
    top_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 
912
    gtk_widget_show (top_scrolledwindow);
 
913
    gtk_container_add (GTK_CONTAINER (top_viewport), top_scrolledwindow);
 
914
 
 
915
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (top_scrolledwindow), GTK_SHADOW_IN);
 
916
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (top_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
917
 
 
918
    for(i=0; i< CONTACTS_NUM_COLUMNS; i++) {
 
919
        if (i == COLUMN_BIRTH_DAY_DATE || i == COLUMN_NAME_DAY_DATE || i == COLUMN_ID) {
 
920
            contact_columns_types[i] = G_TYPE_UINT;
 
921
        } else {
 
922
            contact_columns_types[i] = G_TYPE_STRING;
 
923
        }
 
924
    }
 
925
 
 
926
    appGUI->cnt->contacts_list_store = gtk_list_store_newv(CONTACTS_NUM_COLUMNS, &contact_columns_types[0]);
 
927
 
 
928
    appGUI->cnt->contacts_filter = gtk_tree_model_filter_new(GTK_TREE_MODEL(appGUI->cnt->contacts_list_store), NULL);
 
929
    gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter),
 
930
                                            (GtkTreeModelFilterVisibleFunc)contacts_list_filter_cb,
 
931
                                            appGUI, NULL);
 
932
 
 
933
    appGUI->cnt->contacts_sort = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(appGUI->cnt->contacts_filter));
 
934
 
 
935
    appGUI->cnt->contacts_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(appGUI->cnt->contacts_sort));
 
936
    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(appGUI->cnt->contacts_list), config.contacts_rules_hint);
 
937
    gtk_widget_show (appGUI->cnt->contacts_list);
 
938
    GTK_WIDGET_SET_FLAGS (appGUI->cnt->contacts_list, GTK_CAN_DEFAULT);
 
939
    gtk_widget_modify_fg(GTK_WIDGET(appGUI->cnt->contacts_list), GTK_STATE_SELECTED,
 
940
                         (& GTK_WIDGET(appGUI->cnt->contacts_list)->style->base[GTK_STATE_SELECTED]));
 
941
 
 
942
    g_signal_connect(G_OBJECT(appGUI->cnt->contacts_list), "button_press_event",
 
943
                     G_CALLBACK(contacts_list_dbclick_cb), appGUI);
 
944
 
 
945
    appGUI->cnt->contacts_list_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (appGUI->cnt->contacts_list));
 
946
    g_signal_connect(G_OBJECT(appGUI->cnt->contacts_list_selection), "changed",
 
947
                     G_CALLBACK(contacts_item_selected_cb), appGUI);
 
948
 
 
949
    /* columns setup */
 
950
 
 
951
    for (i = COLUMN_GROUP; i < CONTACTS_NUM_COLUMNS; i++) {
 
952
        renderer[i] = gtk_cell_renderer_text_new();
 
953
        appGUI->cnt->contacts_columns[i] = gtk_tree_view_column_new_with_attributes(gettext(contact_fields_tags_name[i*2]),
 
954
                                                              renderer[i], "text", i, NULL);
 
955
        gtk_tree_view_append_column (GTK_TREE_VIEW(appGUI->cnt->contacts_list), appGUI->cnt->contacts_columns[i]);
 
956
 
 
957
        if(i != COLUMN_FIRST_NAME && i != COLUMN_LAST_NAME && i != COLUMN_GROUP) {
 
958
            gtk_tree_view_column_set_visible (appGUI->cnt->contacts_columns[i], FALSE);
 
959
        } else {
 
960
            if (config.hide_group_column == TRUE && i == COLUMN_GROUP) {
 
961
                gtk_tree_view_column_set_visible (appGUI->cnt->contacts_columns[i], FALSE);
 
962
            }
 
963
            gtk_tree_view_column_set_expand (appGUI->cnt->contacts_columns[i], TRUE);
 
964
        }
 
965
    }
 
966
 
 
967
    gtk_container_add (GTK_CONTAINER (top_scrolledwindow), appGUI->cnt->contacts_list);
 
968
    gtk_tree_view_set_enable_search (GTK_TREE_VIEW(appGUI->cnt->contacts_list), FALSE);
 
969
 
 
970
    /* configure sorting */
 
971
 
 
972
    gtk_tree_sortable_set_sort_func((GtkTreeSortable *)appGUI->cnt->contacts_sort, 0,
 
973
                                    (GtkTreeIterCompareFunc)custom_contacts_sort_function, appGUI, NULL);
 
974
 
 
975
    gtk_tree_sortable_set_sort_column_id((GtkTreeSortable *)appGUI->cnt->contacts_sort, COLUMN_FIRST_NAME, config.contacts_sorting_order);
 
976
    gtk_tree_sortable_set_sort_column_id((GtkTreeSortable *)appGUI->cnt->contacts_sort, COLUMN_LAST_NAME, config.contacts_sorting_order);
 
977
    gtk_tree_sortable_set_sort_column_id((GtkTreeSortable *)appGUI->cnt->contacts_sort, COLUMN_GROUP, config.contacts_sorting_order);
 
978
 
 
979
    bottom_viewport = gtk_viewport_new (NULL, NULL);
 
980
    gtk_widget_show (bottom_viewport);
 
981
    gtk_viewport_set_shadow_type (GTK_VIEWPORT (bottom_viewport), GTK_SHADOW_NONE);
 
982
    gtk_paned_pack2 (GTK_PANED (appGUI->cnt->contacts_paned), bottom_viewport, TRUE, TRUE);
 
983
 
 
984
    vbox2 = gtk_vbox_new (FALSE, 0);
 
985
    gtk_widget_show (vbox2);
 
986
    gtk_container_set_border_width (GTK_CONTAINER (vbox2), 0);
 
987
    gtk_container_add (GTK_CONTAINER (bottom_viewport), vbox2);
 
988
 
 
989
    appGUI->cnt->panel_hbox = gtk_hbox_new (FALSE, 0);
 
990
    gtk_box_pack_start (GTK_BOX (vbox2), appGUI->cnt->panel_hbox, FALSE, FALSE, 0);
 
991
    gtk_widget_show(appGUI->cnt->panel_hbox);
 
992
 
 
993
    sprintf(tmpbuf, "%s:", _("Contact details"));
 
994
    label = gtk_label_new (tmpbuf);
 
995
    gtk_widget_show (label);
 
996
    gtk_box_pack_start (GTK_BOX (appGUI->cnt->panel_hbox), label, FALSE, FALSE, 0);
 
997
 
 
998
    if (config.default_stock_icons) {
 
999
        close_button = gui_stock_button(GTK_STOCK_CLOSE, FALSE);
 
1000
    } else {
 
1001
        close_button = gui_stock_button(OSMO_STOCK_BUTTON_CLOSE, FALSE);
 
1002
    }
 
1003
    GTK_WIDGET_UNSET_FLAGS(close_button, GTK_CAN_FOCUS);
 
1004
    gtk_button_set_relief (GTK_BUTTON(close_button), GTK_RELIEF_NONE);
 
1005
    gtk_tooltips_set_tip (appGUI->osmo_tooltips, close_button, _("Close contact panel"), NULL);
 
1006
    gtk_box_pack_end (GTK_BOX (appGUI->cnt->panel_hbox), close_button, FALSE, FALSE, 0);
 
1007
    g_signal_connect (G_OBJECT (close_button), "clicked",
 
1008
                        G_CALLBACK (contacts_panel_close_desc_cb), appGUI);
 
1009
 
 
1010
    appGUI->cnt->contacts_panel_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 
1011
    gtk_widget_show (appGUI->cnt->contacts_panel_scrolledwindow);
 
1012
    gtk_box_pack_start (GTK_BOX (vbox2), appGUI->cnt->contacts_panel_scrolledwindow, TRUE, TRUE, 0);
 
1013
    gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->cnt->contacts_panel_scrolledwindow), GTK_SHADOW_IN);
 
1014
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->cnt->contacts_panel_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
1015
 
 
1016
    appGUI->cnt->contacts_desc_textview = gtk_text_view_new ();
 
1017
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (appGUI->cnt->contacts_desc_textview), GTK_WRAP_WORD);
 
1018
    gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), 4);
 
1019
    gtk_text_view_set_left_margin(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), 4);
 
1020
    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), 4);
 
1021
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), FALSE);
 
1022
    gtk_text_view_set_editable(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), FALSE);
 
1023
    gtk_widget_show (appGUI->cnt->contacts_desc_textview);
 
1024
    gtk_container_add (GTK_CONTAINER (appGUI->cnt->contacts_panel_scrolledwindow), appGUI->cnt->contacts_desc_textview);
 
1025
 
 
1026
    gui_url_setup(&appGUI->cnt->contacts_links_list, &appGUI->cnt->contacts_link_index, appGUI->cnt->contacts_desc_textview, appGUI);
 
1027
 
 
1028
    adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(appGUI->cnt->contacts_panel_scrolledwindow));
 
1029
    g_signal_connect(G_OBJECT(adjustment), "value-changed", G_CALLBACK(contacts_desc_scrolled), appGUI);
 
1030
    g_signal_connect(G_OBJECT(appGUI->cnt->contacts_desc_textview), "size_allocate", 
 
1031
                     G_CALLBACK(contacts_desc_size_allocate), appGUI);
 
1032
 
 
1033
    text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview));
 
1034
 
 
1035
    appGUI->cnt->contact_name_tag_object = gtk_text_buffer_create_tag (text_buffer, "big",
 
1036
                                                          "size", config.name_font_size * PANGO_SCALE, NULL);
 
1037
    appGUI->cnt->contact_tags_value_tag_object = gtk_text_buffer_create_tag (text_buffer, "normal",
 
1038
                                                                "size", config.tags_font_size * PANGO_SCALE, NULL);
 
1039
    appGUI->cnt->contact_color_tag_object = gtk_text_buffer_create_tag (text_buffer, "tag_name",
 
1040
                               "foreground", config.contact_tag_color, "font", "Monospace",
 
1041
                               "size", config.tags_font_size * PANGO_SCALE, "weight", PANGO_WEIGHT_SEMIBOLD, NULL);
 
1042
 
 
1043
    gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->cnt->contacts_find_combobox), config.find_mode);
 
1044
 
 
1045
    appGUI->cnt->contacts_filter_disabled = FALSE;
 
1046
    gtk_tree_sortable_sort_column_changed((GtkTreeSortable *)appGUI->cnt->contacts_sort);
 
1047
    gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(appGUI->cnt->contacts_filter));
 
1048
}
 
1049
 
 
1050
/*------------------------------------------------------------------------------*/
 
1051
 
 
1052
void
 
1053
insert_photo(gchar *photo_filename, GtkTextIter *iter, GUI *appGUI) {
 
1054
 
 
1055
GtkTextBuffer * buffer;
 
1056
GdkPixbuf *pixbuf;
 
1057
guchar *pixels, *p;
 
1058
gint i, d_photo_width, d_photo_height;
 
1059
gint rowstride, channels, bc1, bc2, bc3, bc4;
 
1060
 
 
1061
 
 
1062
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview));
 
1063
 
 
1064
        pixbuf = NULL;
 
1065
 
 
1066
        d_photo_width = config.photo_width;
 
1067
 
 
1068
        pixbuf = gdk_pixbuf_new_from_file_at_size (photo_filename, d_photo_width, -1, NULL);
 
1069
 
 
1070
        if (pixbuf != NULL) {
 
1071
 
 
1072
                d_photo_width = gdk_pixbuf_get_width(pixbuf);
 
1073
                d_photo_height = gdk_pixbuf_get_height(pixbuf);
 
1074
                channels = gdk_pixbuf_get_n_channels (pixbuf);
 
1075
                rowstride = gdk_pixbuf_get_rowstride (pixbuf);
 
1076
                pixels = gdk_pixbuf_get_pixels (pixbuf);
 
1077
 
 
1078
                bc1 = bc3 = 0;
 
1079
                bc2 = bc4 = 255;
 
1080
 
 
1081
                /* horizontal lines */
 
1082
 
 
1083
                for(i=0; i < d_photo_width; i++) {
 
1084
                        p = pixels + i * channels;
 
1085
                        p[0] = p[1] = p[2] = bc1;
 
1086
                        p = pixels + (d_photo_height-1) * rowstride + i * channels;
 
1087
                        p[0] = p[1] = p[2] = bc2;
 
1088
                }
 
1089
 
 
1090
                /* vertical lines */
 
1091
 
 
1092
                for(i=0; i < d_photo_height; i++) {
 
1093
                        p = pixels + i * rowstride;
 
1094
                        p[0] = p[1] = p[2] = bc3;
 
1095
                        p = pixels + i * rowstride + (d_photo_width-1) * channels;
 
1096
                        p[0] = p[1] = p[2] = bc4;
 
1097
                }
 
1098
 
 
1099
                /* insert image */
 
1100
 
 
1101
                appGUI->cnt->photo_image = gtk_image_new_from_pixbuf(pixbuf);
 
1102
 
 
1103
                if (appGUI->cnt->photo_image != NULL) {
 
1104
                    gtk_text_view_add_child_in_window(GTK_TEXT_VIEW(appGUI->cnt->contacts_desc_textview), appGUI->cnt->photo_image, GTK_TEXT_WINDOW_TEXT, 
 
1105
                                                      appGUI->cnt->contacts_desc_textview->allocation.width-d_photo_width-5, 5);
 
1106
                    gtk_widget_show_all(appGUI->cnt->contacts_desc_textview);
 
1107
                }
 
1108
 
 
1109
                g_object_unref (pixbuf);
 
1110
        }
 
1111
 
 
1112
}
 
1113
 
 
1114
/*------------------------------------------------------------------------------*/
 
1115