~kroq-gar78/ubuntu/precise/gnome-control-center/fix-885947

« back to all changes in this revision

Viewing changes to capplets/about-me/gnome-about-me.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya
  • Date: 2011-05-17 10:47:27 UTC
  • mfrom: (0.1.11 experimental) (1.1.45 upstream)
  • Revision ID: james.westby@ubuntu.com-20110517104727-lqel6m8vhfw5jby1
Tags: 1:3.0.1.1-1ubuntu1
* Rebase on Debian, remaining Ubuntu changes:
* debian/control:
  - Build-Depend on hardening-wrapper, dpkg-dev and dh-autoreconf
  - Add dependency on ubuntu-system-service
  - Remove dependency on gnome-icon-theme-symbolic
  - Move dependency on apg, gnome-icon-theme-symbolic and accountsservice to
    be a Recommends: until we get them in main
* debian/rules:
  - Use autoreconf
  - Add binary-post-install rule for gnome-control-center-data
  - Run dh-autoreconf
* debian/gnome-control-center.dirs:
* debian/gnome-control-center.links:
  - Add a link to the control center shell for indicators
* debian/patches/00_disable-nm.patch:
  - Temporary patch to disable building with NetworkManager until we get
    the new one in the archive
* debian/patches/01_git_remove_gettext_calls.patch:
  - Remove calls to AM_GNU_GETTEXT, IT_PROG_INTLTOOL should be enough
* debian/patches/01_git_kill_warning.patch:
  - Kill warning
* debian/patches/50_ubuntu_systemwide_prefs.patch:
  - Ubuntu specific proxy preferences
* debian/patches/51_ubuntu_system_keyboard.patch:
  - Implement the global keyboard spec at https://wiki.ubuntu.com/DefaultKeyboardSettings

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* gnome-about-me.c
2
 
 * Copyright (C) 2002 Diego Gonzalez
3
 
 *
4
 
 * Written by: Diego Gonzalez <diego@pemas.net>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2, or (at your option)
9
 
 * any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19
 
 * 02111-1307, USA.
20
 
 */
21
 
 
22
 
#ifdef HAVE_CONFIG_H
23
 
#  include <config.h>
24
 
#endif
25
 
 
26
 
#include <glib/gstdio.h>
27
 
#include <gio/gio.h>
28
 
#include <gconf/gconf-client.h>
29
 
#include <unistd.h>
30
 
#include <libebook/e-book.h>
31
 
#include <dbus/dbus-glib-bindings.h>
32
 
 
33
 
#define GNOME_DESKTOP_USE_UNSTABLE_API
34
 
#include <libgnomeui/gnome-desktop-thumbnail.h>
35
 
 
36
 
#include "e-image-chooser.h"
37
 
#include "gnome-about-me-password.h"
38
 
#include "gnome-about-me-fingerprint.h"
39
 
#include "marshal.h"
40
 
 
41
 
#include "capplet-util.h"
42
 
 
43
 
#define MAX_HEIGHT 150
44
 
#define MAX_WIDTH  150
45
 
 
46
 
#define EMAIL_SLOTS 4
47
 
 
48
 
typedef struct {
49
 
        EContact        *contact;
50
 
        EBook           *book;
51
 
 
52
 
        GtkBuilder      *dialog;
53
 
        GtkWidget       *enable_fingerprint_button;
54
 
        GtkWidget       *disable_fingerprint_button;
55
 
        GtkWidget   *image_chooser;
56
 
 
57
 
        GdkScreen       *screen;
58
 
        GtkIconTheme    *theme;
59
 
        GnomeDesktopThumbnailFactory *thumbs;
60
 
 
61
 
        EContactAddress *addr1;
62
 
        EContactAddress *addr2;
63
 
        gchar           *email[EMAIL_SLOTS];
64
 
        const gchar     *email_types[EMAIL_SLOTS];
65
 
 
66
 
        gboolean         have_image;
67
 
        gboolean         image_changed;
68
 
        gboolean         create_self;
69
 
 
70
 
        gchar           *person;
71
 
        gchar           *login;
72
 
        gchar           *username;
73
 
 
74
 
        guint            commit_timeout_id;
75
 
} GnomeAboutMe;
76
 
 
77
 
static GnomeAboutMe *me = NULL;
78
 
 
79
 
struct WidToCid {
80
 
        gchar *wid;
81
 
        guint  cid;
82
 
};
83
 
 
84
 
enum {
85
 
        ADDRESS_STREET = 1,
86
 
        ADDRESS_POBOX,
87
 
        ADDRESS_LOCALITY,
88
 
        ADDRESS_CODE,
89
 
        ADDRESS_REGION,
90
 
        ADDRESS_COUNTRY
91
 
};
92
 
 
93
 
#define EMAIL_WORK              0
94
 
#define EMAIL_HOME              1
95
 
#define ADDRESS_HOME            21
96
 
#define ADDRESS_WORK            27
97
 
 
98
 
struct WidToCid ids[] = {
99
 
 
100
 
        { "email-work-e",      0                             }, /* 00 */
101
 
        { "email-home-e",      1                             }, /* 01 */
102
 
 
103
 
        { "phone-home-e",      E_CONTACT_PHONE_HOME          }, /* 02 */
104
 
        { "phone-mobile-e",    E_CONTACT_PHONE_MOBILE        }, /* 03 */
105
 
        { "phone-work-e",      E_CONTACT_PHONE_BUSINESS      }, /* 04 */
106
 
        { "phone-work-fax-e",  E_CONTACT_PHONE_BUSINESS_FAX  }, /* 05 */
107
 
 
108
 
        { "im-jabber-e",       E_CONTACT_IM_JABBER_HOME_1    }, /* 06 */
109
 
        { "im-msn-e",          E_CONTACT_IM_MSN_HOME_1       }, /* 07 */
110
 
        { "im-icq-e",          E_CONTACT_IM_ICQ_HOME_1       }, /* 08 */
111
 
        { "im-yahoo-e",        E_CONTACT_IM_YAHOO_HOME_1     }, /* 09 */
112
 
        { "im-aim-e",          E_CONTACT_IM_AIM_HOME_1       }, /* 10 */
113
 
        { "im-groupwise-e",    E_CONTACT_IM_GROUPWISE_HOME_1 }, /* 11 */
114
 
 
115
 
        { "web-homepage-e",    E_CONTACT_HOMEPAGE_URL        }, /* 12 */
116
 
        { "web-calendar-e",    E_CONTACT_CALENDAR_URI        }, /* 13 */
117
 
        { "web-weblog-e",      E_CONTACT_BLOG_URL            }, /* 14 */
118
 
 
119
 
        { "job-profession-e",  E_CONTACT_ROLE                }, /* 15 */
120
 
        { "job-title-e",       E_CONTACT_TITLE               }, /* 16 */
121
 
        { "job-dept-e",        E_CONTACT_ORG_UNIT            }, /* 17 */
122
 
        { "job-assistant-e",   E_CONTACT_ASSISTANT           }, /* 18 */
123
 
        { "job-company-e",     E_CONTACT_ORG                 }, /* 19 */
124
 
        { "job-manager-e",     E_CONTACT_MANAGER             }, /* 20 */
125
 
 
126
 
        { "addr-street-1",     ADDRESS_STREET                }, /* 21 */
127
 
        { "addr-po-1",         ADDRESS_POBOX                 }, /* 22 */
128
 
        { "addr-locality-1",   ADDRESS_LOCALITY              }, /* 23 */
129
 
        { "addr-code-1",       ADDRESS_CODE                  }, /* 24 */
130
 
        { "addr-region-1",     ADDRESS_REGION                }, /* 25 */
131
 
        { "addr-country-1",    ADDRESS_COUNTRY               }, /* 26 */
132
 
 
133
 
        { "addr-street-2",     ADDRESS_STREET                }, /* 27 */
134
 
        { "addr-po-2",         ADDRESS_POBOX                 }, /* 28 */
135
 
        { "addr-locality-2",   ADDRESS_LOCALITY              }, /* 29 */
136
 
        { "addr-code-2",       ADDRESS_CODE                  }, /* 30 */
137
 
        { "addr-region-2",     ADDRESS_REGION                }, /* 31 */
138
 
        { "addr-country-2",    ADDRESS_COUNTRY               }, /* 32 */
139
 
 
140
 
        { NULL,            0                             }
141
 
};
142
 
 
143
 
#define ATTRIBUTE_HOME "HOME"
144
 
#define ATTRIBUTE_WORK "WORK"
145
 
#define ATTRIBUTE_OTHER "OTHER"
146
 
 
147
 
static void about_me_set_address_field (EContactAddress *, guint, gchar *);
148
 
 
149
 
 
150
 
/*** Utility functions ***/
151
 
static void
152
 
about_me_error (GtkWindow *parent, gchar *str)
153
 
{
154
 
        GtkWidget *dialog;
155
 
 
156
 
        dialog = gtk_message_dialog_new (parent,
157
 
                                         GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
158
 
                                         GTK_BUTTONS_OK, str);
159
 
 
160
 
        gtk_dialog_run (GTK_DIALOG (dialog));
161
 
        gtk_widget_destroy (dialog);
162
 
}
163
 
 
164
 
/********************/
165
 
static void
166
 
about_me_destroy (void)
167
 
{
168
 
        e_contact_address_free (me->addr1);
169
 
        e_contact_address_free (me->addr2);
170
 
 
171
 
        if (me->contact)
172
 
                g_object_unref (me->contact);
173
 
        if (me->book)
174
 
                g_object_unref (me->book);
175
 
        if (me->dialog)
176
 
                g_object_unref (me->dialog);
177
 
 
178
 
        g_free (me->email[0]);
179
 
        g_free (me->email[1]);
180
 
        g_free (me->email[2]);
181
 
        g_free (me->email[3]);
182
 
 
183
 
        g_free (me->person);
184
 
        g_free (me->login);
185
 
        g_free (me->username);
186
 
        g_free (me);
187
 
        me = NULL;
188
 
}
189
 
 
190
 
static void
191
 
about_me_update_email (GnomeAboutMe *me)
192
 
{
193
 
        GList *attrs = NULL;
194
 
        gint i;
195
 
 
196
 
        for (i = 0; i < EMAIL_SLOTS; ++i) {
197
 
                if (me->email[i] != NULL) {
198
 
                        EVCardAttribute *attr;
199
 
                        const gchar *type = me->email_types[i];
200
 
 
201
 
                        attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
202
 
 
203
 
                        e_vcard_attribute_add_param_with_value (attr,
204
 
                                                                e_vcard_attribute_param_new (EVC_TYPE),
205
 
                                                                type ? type : ATTRIBUTE_OTHER);
206
 
 
207
 
                        e_vcard_attribute_add_value (attr, me->email[i]);
208
 
                        attrs = g_list_append (attrs, attr);
209
 
                }
210
 
        }
211
 
 
212
 
        e_contact_set_attributes (me->contact, E_CONTACT_EMAIL, attrs);
213
 
 
214
 
        g_list_foreach (attrs, (GFunc) e_vcard_attribute_free, NULL);
215
 
        g_list_free (attrs);
216
 
}
217
 
 
218
 
static void
219
 
about_me_commit (GnomeAboutMe *me)
220
 
{
221
 
        EContactName *name;
222
 
 
223
 
        char *strings[4], **stringptr;
224
 
        char *fileas;
225
 
 
226
 
        name = NULL;
227
 
 
228
 
        if (me->create_self) {
229
 
                if (me->username == NULL)
230
 
                        fileas = g_strdup ("Myself");
231
 
                else {
232
 
                        name = e_contact_name_from_string (me->username);
233
 
 
234
 
                        stringptr = strings;
235
 
                        if (name->family && *name->family)
236
 
                                *(stringptr++) = name->family;
237
 
                        if (name->given && *name->given)
238
 
                                *(stringptr++) = name->given;
239
 
                        *stringptr = NULL;
240
 
                        fileas = g_strjoinv (", ", strings);
241
 
                }
242
 
 
243
 
                e_contact_set (me->contact, E_CONTACT_FILE_AS, fileas);
244
 
                e_contact_set (me->contact, E_CONTACT_NICKNAME, me->login);
245
 
                e_contact_set (me->contact, E_CONTACT_FULL_NAME, me->username);
246
 
 
247
 
                e_contact_name_free (name);
248
 
                g_free (fileas);
249
 
        }
250
 
 
251
 
        about_me_update_email (me);
252
 
 
253
 
        if (me->create_self) {
254
 
                e_book_add_contact (me->book, me->contact, NULL);
255
 
                e_book_set_self (me->book, me->contact, NULL);
256
 
        } else {
257
 
                if (!e_book_commit_contact (me->book, me->contact, NULL))
258
 
                        g_warning ("Could not save contact information");
259
 
        }
260
 
 
261
 
        me->create_self = FALSE;
262
 
}
263
 
 
264
 
static gboolean
265
 
about_me_commit_from_timeout (GnomeAboutMe *me)
266
 
{
267
 
        about_me_commit (me);
268
 
 
269
 
        return FALSE;
270
 
}
271
 
 
272
 
static gboolean
273
 
about_me_focus_out (GtkWidget *widget, GdkEventFocus *event, GnomeAboutMe *unused)
274
 
{
275
 
        gchar *str;
276
 
        const gchar *wid;
277
 
        gint i;
278
 
 
279
 
        if (me == NULL)
280
 
                return FALSE;
281
 
 
282
 
        wid = gtk_buildable_get_name (GTK_BUILDABLE (widget));
283
 
 
284
 
        if (wid == NULL)
285
 
                return FALSE;
286
 
 
287
 
        for (i = 0; ids[i].wid != NULL; i++)
288
 
                if (strcmp (ids[i].wid, wid) == 0)
289
 
                        break;
290
 
 
291
 
        if (GTK_IS_ENTRY (widget)) {
292
 
                str = gtk_editable_get_chars (GTK_EDITABLE (widget), 0, -1);
293
 
        } else if (GTK_IS_TEXT_VIEW (widget)) {
294
 
                GtkTextBuffer   *buffer;
295
 
                GtkTextIter      iter_start;
296
 
                GtkTextIter      iter_end;
297
 
 
298
 
                buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
299
 
                gtk_text_buffer_get_start_iter (buffer, &iter_start);
300
 
                iter_end = iter_start;
301
 
                gtk_text_iter_forward_to_end (&iter_end);
302
 
                str = gtk_text_iter_get_text (&iter_start, &iter_end);
303
 
        } else {
304
 
                return FALSE;
305
 
        }
306
 
 
307
 
        if (i == EMAIL_HOME || i == EMAIL_WORK) {
308
 
 
309
 
                g_free (me->email[ids[i].cid]);
310
 
                if (str[0] == '\0')
311
 
                        me->email[ids[i].cid] = NULL;
312
 
                else
313
 
                        me->email[ids[i].cid] = g_strdup (str);
314
 
                me->email_types[ids[i].cid] = (i == EMAIL_HOME) ? ATTRIBUTE_HOME : ATTRIBUTE_WORK;
315
 
        /* FIXME: i'm getting an empty address field in evolution */
316
 
        } else if (i >= ADDRESS_HOME && i < ADDRESS_WORK) {
317
 
                about_me_set_address_field (me->addr1, ids[i].cid, str);
318
 
                e_contact_set (me->contact, E_CONTACT_ADDRESS_HOME, me->addr1);
319
 
        } else if (i >= ADDRESS_WORK) {
320
 
                about_me_set_address_field (me->addr2, ids[i].cid, str);
321
 
                e_contact_set (me->contact, E_CONTACT_ADDRESS_WORK, me->addr2);
322
 
        } else {
323
 
                e_contact_set (me->contact, ids[i].cid, str);
324
 
        }
325
 
 
326
 
        g_free (str);
327
 
 
328
 
        if (me->commit_timeout_id) {
329
 
                g_source_remove (me->commit_timeout_id);
330
 
        }
331
 
 
332
 
        me->commit_timeout_id = g_timeout_add (600, (GSourceFunc) about_me_commit_from_timeout, me);
333
 
 
334
 
        return FALSE;
335
 
}
336
 
 
337
 
/*
338
 
 * Helpers
339
 
 */
340
 
 
341
 
static gchar *
342
 
about_me_get_address_field (EContactAddress *addr, guint cid)
343
 
{
344
 
        gchar *str;
345
 
 
346
 
        if (addr == NULL) {
347
 
                return NULL;
348
 
        }
349
 
 
350
 
        switch (cid) {
351
 
                case ADDRESS_STREET:
352
 
                        str = addr->street;
353
 
                        break;
354
 
                case ADDRESS_POBOX:
355
 
                        str = addr->po;
356
 
                        break;
357
 
                case ADDRESS_LOCALITY:
358
 
                        str = addr->locality;
359
 
                        break;
360
 
                case ADDRESS_CODE:
361
 
                        str = addr->code;
362
 
                        break;
363
 
                case ADDRESS_REGION:
364
 
                        str = addr->region;
365
 
                        break;
366
 
                case ADDRESS_COUNTRY:
367
 
                        str = addr->country;
368
 
                        break;
369
 
                default:
370
 
                        str = NULL;
371
 
                        break;
372
 
        }
373
 
 
374
 
        return str;
375
 
}
376
 
 
377
 
static void
378
 
about_me_set_address_field (EContactAddress *addr, guint cid, gchar *str)
379
 
{
380
 
        switch (cid) {
381
 
                case ADDRESS_STREET:
382
 
                        g_free (addr->street);
383
 
                        addr->street = g_strdup (str);
384
 
                        break;
385
 
                case ADDRESS_POBOX:
386
 
                        g_free (addr->po);
387
 
                        addr->po = g_strdup (str);
388
 
                        break;
389
 
                case ADDRESS_LOCALITY:
390
 
                        g_free (addr->locality);
391
 
                        addr->locality = g_strdup (str);
392
 
                        break;
393
 
                case ADDRESS_CODE:
394
 
                        g_free (addr->code);
395
 
                        addr->code = g_strdup (str);
396
 
                        break;
397
 
                case ADDRESS_REGION:
398
 
                        g_free (addr->region);
399
 
                        addr->region = g_strdup (str);
400
 
                        break;
401
 
                case ADDRESS_COUNTRY:
402
 
                        g_free (addr->country);
403
 
                        addr->country = g_strdup (str);
404
 
                        break;
405
 
        }
406
 
}
407
 
 
408
 
static void
409
 
about_me_setup_email (GnomeAboutMe *me)
410
 
{
411
 
        GList *attrs, *la;
412
 
        gboolean has_home = FALSE, has_work = FALSE;
413
 
        guint i;
414
 
 
415
 
        attrs = e_contact_get_attributes (me->contact, E_CONTACT_EMAIL);
416
 
 
417
 
        for (la = attrs, i = 0; la; la = la->next, ++i) {
418
 
                EVCardAttribute *a = la->data;
419
 
 
420
 
                me->email[i] = e_vcard_attribute_get_value (a);
421
 
                if (e_vcard_attribute_has_type (a, ATTRIBUTE_HOME)) {
422
 
                        me->email_types[i] = ATTRIBUTE_HOME;
423
 
                        if (!has_home) {
424
 
                                ids[EMAIL_HOME].cid = i;
425
 
                                has_home = TRUE;
426
 
                        }
427
 
                } else if (e_vcard_attribute_has_type (a, ATTRIBUTE_WORK)) {
428
 
                        me->email_types[i] = ATTRIBUTE_WORK;
429
 
                        if (!has_work) {
430
 
                                ids[EMAIL_WORK].cid = i;
431
 
                                has_work = TRUE;
432
 
                        }
433
 
                } else {
434
 
                        me->email_types[i] = ATTRIBUTE_OTHER;
435
 
                }
436
 
 
437
 
                e_vcard_attribute_free (a);
438
 
        }
439
 
 
440
 
        g_list_free (attrs);
441
 
 
442
 
        if (ids[EMAIL_HOME].cid == ids[EMAIL_WORK].cid) {
443
 
                if (has_home)
444
 
                        ids[EMAIL_WORK].cid = 1;
445
 
                else
446
 
                        ids[EMAIL_HOME].cid = 0;
447
 
        }
448
 
 
449
 
        me->email_types[ids[EMAIL_WORK].cid] = ATTRIBUTE_WORK;
450
 
        me->email_types[ids[EMAIL_HOME].cid] = ATTRIBUTE_HOME;
451
 
}
452
 
 
453
 
/**
454
 
 * about_me_load_string_field:
455
 
 *
456
 
 * wid: UI widget name
457
 
 * cid: id of the field (EDS id)
458
 
 * aid: position in the array WidToCid
459
 
 **/
460
 
 
461
 
static void
462
 
about_me_load_string_field (GnomeAboutMe *me, const gchar *wid, guint cid, guint aid)
463
 
{
464
 
        GtkWidget   *widget;
465
 
        GtkBuilder  *dialog;
466
 
        const gchar *str;
467
 
 
468
 
        dialog = me->dialog;
469
 
 
470
 
        widget = WID (wid);
471
 
 
472
 
        if (me->create_self == TRUE) {
473
 
                g_signal_connect (widget, "focus-out-event", G_CALLBACK (about_me_focus_out), me);
474
 
                return;
475
 
        }
476
 
 
477
 
        if (aid == EMAIL_HOME || aid == EMAIL_WORK) {
478
 
                str = e_contact_get_const (me->contact, E_CONTACT_EMAIL_1 + cid);
479
 
        } else if (aid >= ADDRESS_HOME && aid < ADDRESS_WORK) {
480
 
                str = about_me_get_address_field (me->addr1, cid);
481
 
        } else if (aid >= ADDRESS_WORK) {
482
 
                str = about_me_get_address_field (me->addr2, cid);
483
 
        } else {
484
 
                str = e_contact_get_const (me->contact, cid);
485
 
        }
486
 
 
487
 
        str = str ? str : "";
488
 
 
489
 
        if (GTK_IS_ENTRY (widget)) {
490
 
                gtk_entry_set_text (GTK_ENTRY (widget), str);
491
 
        } else if (GTK_IS_TEXT_VIEW (widget)) {
492
 
                GtkTextBuffer *buffer;
493
 
 
494
 
                buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
495
 
                gtk_text_buffer_set_text (buffer, str, -1);
496
 
        }
497
 
 
498
 
        g_signal_connect (widget, "focus-out-event", G_CALLBACK (about_me_focus_out), me);
499
 
}
500
 
 
501
 
static void
502
 
about_me_load_photo (GnomeAboutMe *me, EContact *contact)
503
 
{
504
 
        GtkBuilder    *dialog;
505
 
        EContactPhoto *photo;
506
 
 
507
 
        dialog = me->dialog;
508
 
 
509
 
        if (me->person)
510
 
                e_image_chooser_set_from_file (E_IMAGE_CHOOSER (me->image_chooser), me->person);
511
 
 
512
 
        photo = e_contact_get (contact, E_CONTACT_PHOTO);
513
 
 
514
 
        if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
515
 
                me->have_image = TRUE;
516
 
                e_image_chooser_set_image_data (E_IMAGE_CHOOSER (me->image_chooser),
517
 
                                                (char *) photo->data.inlined.data, photo->data.inlined.length);
518
 
                e_contact_photo_free (photo);
519
 
        } else {
520
 
                me->have_image = FALSE;
521
 
        }
522
 
}
523
 
 
524
 
static void
525
 
about_me_update_photo (GnomeAboutMe *me)
526
 
{
527
 
        GtkBuilder    *dialog;
528
 
        EContactPhoto *photo;
529
 
        gchar         *file;
530
 
        GError        *error;
531
 
 
532
 
        guchar        *data;
533
 
        gsize          length;
534
 
 
535
 
        dialog = me->dialog;
536
 
 
537
 
 
538
 
        if (me->image_changed && me->have_image) {
539
 
                GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
540
 
                GdkPixbuf *pixbuf, *scaled;
541
 
                int height, width;
542
 
                gboolean do_scale = FALSE;
543
 
                float scale;
544
 
 
545
 
                e_image_chooser_get_image_data (E_IMAGE_CHOOSER (me->image_chooser), (char **) &data, &length);
546
 
 
547
 
                /* Before updating the image in EDS scale it to a reasonable size
548
 
                   so that the user doesn't get an application that does not respond
549
 
                   or that takes 100% CPU */
550
 
                gdk_pixbuf_loader_write (loader, data, length, NULL);
551
 
                gdk_pixbuf_loader_close (loader, NULL);
552
 
 
553
 
                pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
554
 
 
555
 
                if (pixbuf)
556
 
                        g_object_ref (pixbuf);
557
 
 
558
 
                g_object_unref (loader);
559
 
 
560
 
                height = gdk_pixbuf_get_height (pixbuf);
561
 
                width = gdk_pixbuf_get_width (pixbuf);
562
 
 
563
 
                if (height >= width && height > MAX_HEIGHT) {
564
 
                        scale = (float)MAX_HEIGHT/height;
565
 
                        do_scale = TRUE;
566
 
                } else if (width > height && width > MAX_WIDTH) {
567
 
                        scale = (float)MAX_WIDTH/width;
568
 
                        do_scale = TRUE;
569
 
                }
570
 
 
571
 
                if (do_scale) {
572
 
                        char *scaled_data = NULL;
573
 
                        gsize scaled_length;
574
 
 
575
 
                        scaled = gdk_pixbuf_scale_simple (pixbuf, width*scale, height*scale, GDK_INTERP_BILINEAR);
576
 
                        gdk_pixbuf_save_to_buffer (scaled, &scaled_data, &scaled_length, "png", NULL,
577
 
                                                   "compression", "9", NULL);
578
 
 
579
 
                        g_free (data);
580
 
                        data = (guchar *) scaled_data;
581
 
                        length = scaled_length;
582
 
                }
583
 
 
584
 
                photo = g_new0 (EContactPhoto, 1);
585
 
                photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
586
 
                photo->data.inlined.data = data;
587
 
                photo->data.inlined.length = length;
588
 
                e_contact_set (me->contact, E_CONTACT_PHOTO, photo);
589
 
 
590
 
                /* Save the image for GDM */
591
 
                /* FIXME: I would have to read the default used by the gdmgreeter program */
592
 
                error = NULL;
593
 
                file = g_build_filename (g_get_home_dir (), ".face", NULL);
594
 
                if (g_file_set_contents (file,
595
 
                                         (gchar *) photo->data.inlined.data,
596
 
                                         photo->data.inlined.length,
597
 
                                         &error) != FALSE) {
598
 
                        g_chmod (file, 0644);
599
 
                } else {
600
 
                        g_warning ("Could not create %s: %s", file, error->message);
601
 
                        g_error_free (error);
602
 
                }
603
 
 
604
 
                g_free (file);
605
 
 
606
 
                e_contact_photo_free (photo);
607
 
 
608
 
        } else if (me->image_changed && !me->have_image) {
609
 
                /* Update the image in the card */
610
 
                e_contact_set (me->contact, E_CONTACT_PHOTO, NULL);
611
 
 
612
 
                file = g_build_filename (g_get_home_dir (), ".face", NULL);
613
 
 
614
 
                g_unlink (file);
615
 
 
616
 
                g_free (file);
617
 
        }
618
 
 
619
 
        about_me_commit (me);
620
 
}
621
 
 
622
 
static void
623
 
about_me_load_info (GnomeAboutMe *me)
624
 
{
625
 
        gint i;
626
 
 
627
 
        if (me->create_self == FALSE) {
628
 
                me->addr1 = e_contact_get (me->contact, E_CONTACT_ADDRESS_HOME);
629
 
                if (me->addr1 == NULL)
630
 
                        me->addr1 = g_new0 (EContactAddress, 1);
631
 
                me->addr2 = e_contact_get (me->contact, E_CONTACT_ADDRESS_WORK);
632
 
                if (me->addr2 == NULL)
633
 
                        me->addr2 = g_new0 (EContactAddress, 1);
634
 
        } else {
635
 
                me->addr1 = g_new0 (EContactAddress, 1);
636
 
                me->addr2 = g_new0 (EContactAddress, 1);
637
 
        }
638
 
 
639
 
        for (i = 0; ids[i].wid != NULL; i++) {
640
 
                about_me_load_string_field (me, ids[i].wid, ids[i].cid, i);
641
 
        }
642
 
 
643
 
        set_fingerprint_label (me->enable_fingerprint_button,
644
 
                               me->disable_fingerprint_button);
645
 
}
646
 
 
647
 
static void
648
 
about_me_update_preview (GtkFileChooser *chooser,
649
 
                         GnomeAboutMe   *me)
650
 
{
651
 
        gchar *uri;
652
 
 
653
 
        uri = gtk_file_chooser_get_preview_uri (chooser);
654
 
 
655
 
        if (uri) {
656
 
                GtkWidget *image;
657
 
                GdkPixbuf *pixbuf = NULL;
658
 
                GFile *file;
659
 
                GFileInfo *file_info;
660
 
 
661
 
                if (!me->thumbs)
662
 
                        me->thumbs = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
663
 
 
664
 
                file = g_file_new_for_uri (uri);
665
 
                file_info = g_file_query_info (file,
666
 
                                               G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
667
 
                                               G_FILE_QUERY_INFO_NONE,
668
 
                                               NULL, NULL);
669
 
                g_object_unref (file);
670
 
 
671
 
                if (file_info != NULL) {
672
 
                        const gchar *content_type;
673
 
 
674
 
                        content_type = g_file_info_get_content_type (file_info);
675
 
                        if (content_type) {
676
 
                                gchar *mime_type;
677
 
 
678
 
                                mime_type = g_content_type_get_mime_type (content_type);
679
 
 
680
 
                                pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (me->thumbs,
681
 
                                                                                     uri,
682
 
                                                                                     mime_type);
683
 
                                g_free (mime_type);
684
 
                        }
685
 
                        g_object_unref (file_info);
686
 
                }
687
 
 
688
 
                image = gtk_file_chooser_get_preview_widget (chooser);
689
 
 
690
 
                if (pixbuf != NULL) {
691
 
                        gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
692
 
                        g_object_unref (pixbuf);
693
 
                } else {
694
 
                        gtk_image_set_from_stock (GTK_IMAGE (image),
695
 
                                                  "gtk-dialog-question",
696
 
                                                  GTK_ICON_SIZE_DIALOG);
697
 
                }
698
 
        }
699
 
        gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
700
 
}
701
 
 
702
 
static void
703
 
about_me_image_clicked_cb (GtkWidget *button, GnomeAboutMe *me)
704
 
{
705
 
        GtkFileChooser *chooser_dialog;
706
 
        gint response;
707
 
        GtkBuilder *dialog;
708
 
        GtkWidget  *image;
709
 
        const gchar *chooser_dir = DATADIR"/pixmaps/faces";
710
 
        const gchar *pics_dir;
711
 
        GtkFileFilter *filter;
712
 
 
713
 
        dialog = me->dialog;
714
 
 
715
 
        chooser_dialog = GTK_FILE_CHOOSER (
716
 
                         gtk_file_chooser_dialog_new (_("Select Image"), GTK_WINDOW (WID ("about-me-dialog")),
717
 
                                                        GTK_FILE_CHOOSER_ACTION_OPEN,
718
 
                                                        _("No Image"), GTK_RESPONSE_NO,
719
 
                                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
720
 
                                                        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
721
 
                                                        NULL));
722
 
        gtk_window_set_modal (GTK_WINDOW (chooser_dialog), TRUE);
723
 
        gtk_dialog_set_default_response (GTK_DIALOG (chooser_dialog), GTK_RESPONSE_ACCEPT);
724
 
 
725
 
        gtk_file_chooser_add_shortcut_folder (chooser_dialog, chooser_dir, NULL);
726
 
        pics_dir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
727
 
        if (pics_dir != NULL)
728
 
                gtk_file_chooser_add_shortcut_folder (chooser_dialog, pics_dir, NULL);
729
 
 
730
 
        if (!g_file_test (chooser_dir, G_FILE_TEST_IS_DIR))
731
 
                chooser_dir = g_get_home_dir ();
732
 
 
733
 
        gtk_file_chooser_set_current_folder (chooser_dialog, chooser_dir);
734
 
        gtk_file_chooser_set_use_preview_label (chooser_dialog, FALSE);
735
 
 
736
 
        image = gtk_image_new ();
737
 
        gtk_file_chooser_set_preview_widget (chooser_dialog, image);
738
 
        gtk_widget_set_size_request (image, 128, -1);
739
 
 
740
 
        gtk_widget_show (image);
741
 
 
742
 
        g_signal_connect (chooser_dialog, "update-preview",
743
 
                          G_CALLBACK (about_me_update_preview), me);
744
 
 
745
 
        filter = gtk_file_filter_new ();
746
 
        gtk_file_filter_set_name (filter, _("Images"));
747
 
        gtk_file_filter_add_pixbuf_formats (filter);
748
 
        gtk_file_chooser_add_filter (chooser_dialog, filter);
749
 
        filter = gtk_file_filter_new ();
750
 
        gtk_file_filter_set_name (filter, _("All Files"));
751
 
        gtk_file_filter_add_pattern(filter, "*");
752
 
        gtk_file_chooser_add_filter (chooser_dialog, filter);
753
 
 
754
 
        response = gtk_dialog_run (GTK_DIALOG (chooser_dialog));
755
 
 
756
 
        if (response == GTK_RESPONSE_ACCEPT) {
757
 
                gchar* filename;
758
 
 
759
 
                filename = gtk_file_chooser_get_filename (chooser_dialog);
760
 
                me->have_image = TRUE;
761
 
                me->image_changed = TRUE;
762
 
 
763
 
                e_image_chooser_set_from_file (E_IMAGE_CHOOSER (me->image_chooser), filename);
764
 
                g_free (filename);
765
 
                about_me_update_photo (me);
766
 
        } else if (response == GTK_RESPONSE_NO) {
767
 
                me->have_image = FALSE;
768
 
                me->image_changed = TRUE;
769
 
                e_image_chooser_set_from_file (E_IMAGE_CHOOSER (me->image_chooser), me->person);
770
 
                about_me_update_photo (me);
771
 
        }
772
 
 
773
 
        gtk_widget_destroy (GTK_WIDGET (chooser_dialog));
774
 
}
775
 
 
776
 
static void
777
 
about_me_image_changed_cb (GtkWidget *widget, GnomeAboutMe *me)
778
 
{
779
 
        me->have_image = TRUE;
780
 
        me->image_changed = TRUE;
781
 
        about_me_update_photo (me);
782
 
}
783
 
 
784
 
/* About Me Dialog Callbacks */
785
 
 
786
 
static void
787
 
about_me_icon_theme_changed (GtkWindow    *window,
788
 
                             GtkIconTheme *theme)
789
 
{
790
 
        GtkIconInfo *icon;
791
 
 
792
 
        icon = gtk_icon_theme_lookup_icon (me->theme, "stock_person", 80, 0);
793
 
        if (icon == NULL) {
794
 
                g_debug ("Icon not found");
795
 
        }
796
 
        g_free (me->person);
797
 
        me->person = g_strdup (gtk_icon_info_get_filename (icon));
798
 
 
799
 
        gtk_icon_info_free (icon);
800
 
 
801
 
        if (me->have_image)
802
 
                e_image_chooser_set_from_file (E_IMAGE_CHOOSER (me->image_chooser), me->person);
803
 
}
804
 
 
805
 
static void
806
 
about_me_button_clicked_cb (GtkDialog *dialog, gint response_id, GnomeAboutMe *me)
807
 
{
808
 
        if (response_id == GTK_RESPONSE_HELP)
809
 
                g_print ("Help goes here");
810
 
        else {
811
 
                if (me->commit_timeout_id) {
812
 
                        g_source_remove (me->commit_timeout_id);
813
 
                        about_me_commit (me);
814
 
                }
815
 
 
816
 
                about_me_destroy ();
817
 
                gtk_main_quit ();
818
 
        }
819
 
}
820
 
 
821
 
static void
822
 
about_me_passwd_clicked_cb (GtkWidget *button, GnomeAboutMe *me)
823
 
{
824
 
        GtkBuilder *dialog;
825
 
 
826
 
        dialog = me->dialog;
827
 
        gnome_about_me_password (GTK_WINDOW (WID ("about-me-dialog")));
828
 
}
829
 
 
830
 
static void
831
 
about_me_fingerprint_button_clicked_cb (GtkWidget *button, GnomeAboutMe *me)
832
 
{
833
 
        fingerprint_button_clicked (me->dialog,
834
 
                                    me->enable_fingerprint_button,
835
 
                                    me->disable_fingerprint_button);
836
 
}
837
 
 
838
 
static gint
839
 
about_me_setup_dialog (void)
840
 
{
841
 
        GtkWidget    *widget;
842
 
        GtkWidget    *main_dialog;
843
 
        GtkIconInfo  *icon;
844
 
        GtkBuilder   *dialog;
845
 
        GError       *error = NULL;
846
 
        GList        *chain;
847
 
        gchar        *str;
848
 
 
849
 
        me = g_new0 (GnomeAboutMe, 1);
850
 
 
851
 
        dialog = gtk_builder_new ();
852
 
        gtk_builder_add_from_file (dialog, GNOMECC_UI_DIR "/gnome-about-me-dialog.ui", NULL);
853
 
 
854
 
        me->image_chooser = e_image_chooser_new ();
855
 
        gtk_container_add (GTK_CONTAINER (WID ("button-image")), me->image_chooser);
856
 
 
857
 
        if (dialog == NULL) {
858
 
                about_me_destroy ();
859
 
                return -1;
860
 
        }
861
 
 
862
 
        me->dialog = dialog;
863
 
 
864
 
        /* Connect the close button signal */
865
 
        main_dialog = WID ("about-me-dialog");
866
 
        g_signal_connect (main_dialog, "response",
867
 
                          G_CALLBACK (about_me_button_clicked_cb), me);
868
 
 
869
 
        gtk_window_set_resizable (GTK_WINDOW (main_dialog), FALSE);
870
 
        capplet_set_icon (main_dialog, "user-info");
871
 
 
872
 
        /* Setup theme details */
873
 
        me->screen = gtk_window_get_screen (GTK_WINDOW (main_dialog));
874
 
        me->theme = gtk_icon_theme_get_for_screen (me->screen);
875
 
 
876
 
        icon = gtk_icon_theme_lookup_icon (me->theme, "stock_person", 80, 0);
877
 
        if (icon != NULL) {
878
 
                me->person = g_strdup (gtk_icon_info_get_filename (icon));
879
 
                gtk_icon_info_free (icon);
880
 
        }
881
 
 
882
 
        g_signal_connect_object (me->theme, "changed",
883
 
                                 G_CALLBACK (about_me_icon_theme_changed),
884
 
                                 main_dialog,
885
 
                                 G_CONNECT_SWAPPED);
886
 
 
887
 
        /* Get the self contact */
888
 
        if (!e_book_get_self (&me->contact, &me->book, &error)) {
889
 
                if (error->code == E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED) {
890
 
                        about_me_error (NULL, _("There was an error while trying to get the addressbook information\n" \
891
 
                                                "Evolution Data Server can't handle the protocol"));
892
 
                        g_clear_error (&error);
893
 
                        about_me_destroy ();
894
 
                        return -1;
895
 
                }
896
 
 
897
 
                g_clear_error (&error);
898
 
 
899
 
                me->create_self = TRUE;
900
 
                me->contact = e_contact_new ();
901
 
 
902
 
                if (me->book == NULL) {
903
 
                        me->book = e_book_new_system_addressbook (&error);
904
 
                        if (me->book == NULL || error != NULL) {
905
 
                                g_error ("%s", error->message);
906
 
                                g_clear_error (&error);
907
 
                        }
908
 
 
909
 
                        if (e_book_open (me->book, FALSE, NULL) == FALSE) {
910
 
                                about_me_error (GTK_WINDOW (main_dialog),
911
 
                                                _("Unable to open address book"));
912
 
                                g_clear_error (&error);
913
 
                        }
914
 
                }
915
 
        } else {
916
 
                about_me_setup_email (me);
917
 
        }
918
 
 
919
 
        me->login = g_strdup (g_get_user_name ());
920
 
        me->username = g_strdup (g_get_real_name ());
921
 
 
922
 
        /* Contact Tab */
923
 
        about_me_load_photo (me, me->contact);
924
 
 
925
 
        widget = WID ("fullname");
926
 
        str = g_strdup_printf ("<b><span size=\"xx-large\">%s</span></b>", me->username);
927
 
 
928
 
        gtk_label_set_markup (GTK_LABEL (widget), str);
929
 
        g_free (str);
930
 
 
931
 
        widget = WID ("login");
932
 
        gtk_label_set_text (GTK_LABEL (widget), me->login);
933
 
 
934
 
        str = g_strdup_printf (_("About %s"), me->username);
935
 
        gtk_window_set_title (GTK_WINDOW (main_dialog), str);
936
 
        g_free (str);
937
 
 
938
 
        widget = WID ("password");
939
 
        g_signal_connect (widget, "clicked",
940
 
                          G_CALLBACK (about_me_passwd_clicked_cb), me);
941
 
 
942
 
        widget = WID ("button-image");
943
 
        g_signal_connect (widget, "clicked",
944
 
                          G_CALLBACK (about_me_image_clicked_cb), me);
945
 
 
946
 
        me->enable_fingerprint_button = WID ("enable_fingerprint_button");
947
 
        me->disable_fingerprint_button = WID ("disable_fingerprint_button");
948
 
 
949
 
        g_signal_connect (me->enable_fingerprint_button, "clicked",
950
 
                          G_CALLBACK (about_me_fingerprint_button_clicked_cb), me);
951
 
        g_signal_connect (me->disable_fingerprint_button, "clicked",
952
 
                          G_CALLBACK (about_me_fingerprint_button_clicked_cb), me);
953
 
 
954
 
        g_signal_connect (me->image_chooser, "changed",
955
 
                          G_CALLBACK (about_me_image_changed_cb), me);
956
 
 
957
 
        /* Address tab: set up the focus chains */
958
 
        chain = g_list_prepend (NULL, WID ("addr-country-1"));
959
 
        chain = g_list_prepend (chain, WID ("addr-po-1"));
960
 
        chain = g_list_prepend (chain, WID ("addr-region-1"));
961
 
        chain = g_list_prepend (chain, WID ("addr-code-1"));
962
 
        chain = g_list_prepend (chain, WID ("addr-locality-1"));
963
 
        chain = g_list_prepend (chain, WID ("addr-scrolledwindow-1"));
964
 
        widget = WID ("addr-table-1");
965
 
        gtk_container_set_focus_chain (GTK_CONTAINER (widget), chain);
966
 
        g_list_free (chain);
967
 
 
968
 
        chain = g_list_prepend (NULL, WID ("addr-country-2"));
969
 
        chain = g_list_prepend (chain, WID ("addr-po-2"));
970
 
        chain = g_list_prepend (chain, WID ("addr-region-2"));
971
 
        chain = g_list_prepend (chain, WID ("addr-code-2"));
972
 
        chain = g_list_prepend (chain, WID ("addr-locality-2"));
973
 
        chain = g_list_prepend (chain, WID ("addr-scrolledwindow-2"));
974
 
        widget = WID ("addr-table-2");
975
 
        gtk_container_set_focus_chain (GTK_CONTAINER (widget), chain);
976
 
        g_list_free (chain);
977
 
 
978
 
        about_me_load_info (me);
979
 
 
980
 
        gtk_widget_show_all (main_dialog);
981
 
 
982
 
        return 0;
983
 
}
984
 
 
985
 
int
986
 
main (int argc, char **argv)
987
 
{
988
 
        int rc = 0;
989
 
 
990
 
        capplet_init (NULL, &argc, &argv);
991
 
 
992
 
        if (!g_thread_supported ())
993
 
                g_thread_init (NULL);
994
 
 
995
 
        dbus_g_object_register_marshaller (fprintd_marshal_VOID__STRING_BOOLEAN,
996
 
                                           G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID);
997
 
 
998
 
        rc = about_me_setup_dialog ();
999
 
 
1000
 
        if (rc != -1) {
1001
 
                gtk_main ();
1002
 
        }
1003
 
 
1004
 
        return rc;
1005
 
}