~ubuntu-branches/ubuntu/trusty/unity-control-center/trusty

« back to all changes in this revision

Viewing changes to panels/user-accounts/um-photo-dialog.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2014-01-08 16:29:18 UTC
  • Revision ID: package-import@ubuntu.com-20140108162918-g29dd08tr913y2qh
Tags: upstream-14.04.0
ImportĀ upstreamĀ versionĀ 14.04.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright 2009-2010  Red Hat, Inc,
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 *
 
19
 * Written by: Matthias Clasen <mclasen@redhat.com>
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <stdlib.h>
 
25
 
 
26
#include <glib.h>
 
27
#include <glib/gi18n.h>
 
28
#include <gtk/gtk.h>
 
29
#define GNOME_DESKTOP_USE_UNSTABLE_API
 
30
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
 
31
 
 
32
#ifdef HAVE_CHEESE
 
33
#include <cheese-avatar-chooser.h>
 
34
#include <cheese-camera-device.h>
 
35
#include <cheese-camera-device-monitor.h>
 
36
#endif /* HAVE_CHEESE */
 
37
 
 
38
#include "um-photo-dialog.h"
 
39
#include "um-user-manager.h"
 
40
#include "um-crop-area.h"
 
41
#include "um-utils.h"
 
42
 
 
43
#define ROW_SPAN 6
 
44
 
 
45
struct _UmPhotoDialog {
 
46
        GtkWidget *photo_popup;
 
47
        GtkWidget *popup_button;
 
48
        GtkWidget *crop_area;
 
49
 
 
50
#ifdef HAVE_CHEESE
 
51
        CheeseCameraDeviceMonitor *monitor;
 
52
        GtkWidget *take_photo_menuitem;
 
53
        guint num_cameras;
 
54
#endif /* HAVE_CHEESE */
 
55
 
 
56
        GnomeDesktopThumbnailFactory *thumb_factory;
 
57
 
 
58
        UmUser *user;
 
59
};
 
60
 
 
61
static void
 
62
crop_dialog_response (GtkWidget     *dialog,
 
63
                      gint           response_id,
 
64
                      UmPhotoDialog *um)
 
65
{
 
66
        GdkPixbuf *pb, *pb2;
 
67
 
 
68
        if (response_id != GTK_RESPONSE_ACCEPT) {
 
69
                um->crop_area = NULL;
 
70
                gtk_widget_destroy (dialog);
 
71
                return;
 
72
        }
 
73
 
 
74
        pb = um_crop_area_get_picture (UM_CROP_AREA (um->crop_area));
 
75
        pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
 
76
 
 
77
        um_user_set_icon_data (um->user, pb2);
 
78
 
 
79
        g_object_unref (pb2);
 
80
        g_object_unref (pb);
 
81
 
 
82
        um->crop_area = NULL;
 
83
        gtk_widget_destroy (dialog);
 
84
}
 
85
 
 
86
static void
 
87
um_photo_dialog_crop (UmPhotoDialog *um,
 
88
                      GdkPixbuf     *pixbuf)
 
89
{
 
90
        GtkWidget *dialog;
 
91
        GtkWidget *frame;
 
92
 
 
93
        dialog = gtk_dialog_new_with_buttons ("",
 
94
                                              GTK_WINDOW (gtk_widget_get_toplevel (um->popup_button)),
 
95
                                              0,
 
96
                                              GTK_STOCK_CANCEL,
 
97
                                              GTK_RESPONSE_REJECT,
 
98
                                              _("Select"),
 
99
                                              GTK_RESPONSE_ACCEPT,
 
100
                                              NULL);
 
101
        gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 
102
 
 
103
        gtk_window_set_icon_name (GTK_WINDOW (dialog), "system-users");
 
104
 
 
105
        g_signal_connect (G_OBJECT (dialog), "response",
 
106
                          G_CALLBACK (crop_dialog_response), um);
 
107
 
 
108
        /* Content */
 
109
        um->crop_area           = um_crop_area_new ();
 
110
        um_crop_area_set_min_size (UM_CROP_AREA (um->crop_area), 48, 48);
 
111
        um_crop_area_set_constrain_aspect (UM_CROP_AREA (um->crop_area), TRUE);
 
112
        um_crop_area_set_picture (UM_CROP_AREA (um->crop_area), pixbuf);
 
113
        frame                   = gtk_frame_new (NULL);
 
114
        gtk_container_add (GTK_CONTAINER (frame), um->crop_area);
 
115
        gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
 
116
 
 
117
        gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
 
118
                            frame,
 
119
                            TRUE, TRUE, 8);
 
120
 
 
121
        gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300);
 
122
 
 
123
        gtk_widget_show_all (dialog);
 
124
}
 
125
 
 
126
static void
 
127
file_chooser_response (GtkDialog     *chooser,
 
128
                       gint           response,
 
129
                       UmPhotoDialog *um)
 
130
{
 
131
        gchar *filename;
 
132
        GError *error;
 
133
        GdkPixbuf *pixbuf;
 
134
 
 
135
        if (response != GTK_RESPONSE_ACCEPT) {
 
136
                gtk_widget_destroy (GTK_WIDGET (chooser));
 
137
                return;
 
138
        }
 
139
 
 
140
        filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
 
141
 
 
142
        error = NULL;
 
143
        pixbuf = gdk_pixbuf_new_from_file (filename, &error);
 
144
        if (pixbuf == NULL) {
 
145
                g_warning ("Failed to load %s: %s", filename, error->message);
 
146
                g_error_free (error);
 
147
        }
 
148
        g_free (filename);
 
149
 
 
150
        gtk_widget_destroy (GTK_WIDGET (chooser));
 
151
 
 
152
        um_photo_dialog_crop (um, pixbuf);
 
153
        g_object_unref (pixbuf);
 
154
}
 
155
 
 
156
static void
 
157
update_preview (GtkFileChooser               *chooser,
 
158
                GnomeDesktopThumbnailFactory *thumb_factory)
 
159
{
 
160
        gchar *uri;
 
161
 
 
162
        uri = gtk_file_chooser_get_preview_uri (chooser);
 
163
 
 
164
        if (uri) {
 
165
                GdkPixbuf *pixbuf = NULL;
 
166
                const gchar *mime_type = NULL;
 
167
                GFile *file;
 
168
                GFileInfo *file_info;
 
169
                GtkWidget *preview;
 
170
 
 
171
                preview = gtk_file_chooser_get_preview_widget (chooser);
 
172
 
 
173
                file = g_file_new_for_uri (uri);
 
174
                file_info = g_file_query_info (file,
 
175
                                               G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
 
176
                                               G_FILE_QUERY_INFO_NONE,
 
177
                                               NULL, NULL);
 
178
                g_object_unref (file);
 
179
 
 
180
                if (file_info != NULL) {
 
181
                        mime_type = g_file_info_get_content_type (file_info);
 
182
                        g_object_unref (file_info);
 
183
                }
 
184
 
 
185
                if (mime_type) {
 
186
                        pixbuf = gnome_desktop_thumbnail_factory_generate_thumbnail (thumb_factory,
 
187
                                                                                     uri,
 
188
                                                                                     mime_type);
 
189
                }
 
190
 
 
191
                gtk_dialog_set_response_sensitive (GTK_DIALOG (chooser),
 
192
                                                   GTK_RESPONSE_ACCEPT,
 
193
                                                   (pixbuf != NULL));
 
194
 
 
195
                if (pixbuf != NULL) {
 
196
                        gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
 
197
                        g_object_unref (pixbuf);
 
198
                }
 
199
                else {
 
200
                        gtk_image_set_from_stock (GTK_IMAGE (preview),
 
201
                                                  GTK_STOCK_DIALOG_QUESTION,
 
202
                                                  GTK_ICON_SIZE_DIALOG);
 
203
                }
 
204
 
 
205
                g_free (uri);
 
206
        }
 
207
 
 
208
        gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
 
209
}
 
210
 
 
211
static void
 
212
um_photo_dialog_select_file (UmPhotoDialog *um)
 
213
{
 
214
        GtkWidget *chooser;
 
215
        const gchar *folder;
 
216
        GtkWidget *preview;
 
217
 
 
218
        chooser = gtk_file_chooser_dialog_new (_("Browse for more pictures"),
 
219
                                               GTK_WINDOW (gtk_widget_get_toplevel (um->popup_button)),
 
220
                                               GTK_FILE_CHOOSER_ACTION_OPEN,
 
221
                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
222
                                               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
 
223
                                               NULL);
 
224
 
 
225
        gtk_window_set_modal (GTK_WINDOW (chooser), TRUE);
 
226
 
 
227
        preview = gtk_image_new ();
 
228
        gtk_widget_set_size_request (preview, 128, -1);
 
229
        gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (chooser), preview);
 
230
        gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (chooser), FALSE);
 
231
        gtk_widget_show (preview);
 
232
        g_signal_connect (chooser, "update-preview",
 
233
                          G_CALLBACK (update_preview), um->thumb_factory);
 
234
 
 
235
        folder = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES);
 
236
        if (folder)
 
237
                gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser),
 
238
                                                     folder);
 
239
 
 
240
        g_signal_connect (chooser, "response",
 
241
                          G_CALLBACK (file_chooser_response), um);
 
242
 
 
243
        gtk_window_present (GTK_WINDOW (chooser));
 
244
}
 
245
 
 
246
static void
 
247
none_icon_selected (GtkMenuItem   *menuitem,
 
248
                    UmPhotoDialog *um)
 
249
{
 
250
        um_user_set_icon_file (um->user, NULL);
 
251
}
 
252
 
 
253
static void
 
254
file_icon_selected (GtkMenuItem   *menuitem,
 
255
                    UmPhotoDialog *um)
 
256
{
 
257
        um_photo_dialog_select_file (um);
 
258
}
 
259
 
 
260
#ifdef HAVE_CHEESE
 
261
static gboolean
 
262
destroy_chooser (GtkWidget *chooser)
 
263
{
 
264
        gtk_widget_destroy (chooser);
 
265
        return FALSE;
 
266
}
 
267
 
 
268
static void
 
269
webcam_response_cb (GtkDialog     *dialog,
 
270
                    int            response,
 
271
                    UmPhotoDialog  *um)
 
272
{
 
273
        if (response == GTK_RESPONSE_ACCEPT) {
 
274
                GdkPixbuf *pb, *pb2;
 
275
 
 
276
                g_object_get (G_OBJECT (dialog), "pixbuf", &pb, NULL);
 
277
                pb2 = gdk_pixbuf_scale_simple (pb, 96, 96, GDK_INTERP_BILINEAR);
 
278
 
 
279
                um_user_set_icon_data (um->user, pb2);
 
280
 
 
281
                g_object_unref (pb2);
 
282
                g_object_unref (pb);
 
283
        }
 
284
        if (response != GTK_RESPONSE_DELETE_EVENT &&
 
285
            response != GTK_RESPONSE_NONE)
 
286
                g_idle_add ((GSourceFunc) destroy_chooser, dialog);
 
287
}
 
288
 
 
289
static void
 
290
webcam_icon_selected (GtkMenuItem   *menuitem,
 
291
                      UmPhotoDialog *um)
 
292
{
 
293
        GtkWidget *window;
 
294
 
 
295
        window = cheese_avatar_chooser_new ();
 
296
        gtk_window_set_transient_for (GTK_WINDOW (window),
 
297
                                      GTK_WINDOW (gtk_widget_get_toplevel (um->popup_button)));
 
298
        gtk_window_set_modal (GTK_WINDOW (window), TRUE);
 
299
        g_signal_connect (G_OBJECT (window), "response",
 
300
                          G_CALLBACK (webcam_response_cb), um);
 
301
        gtk_widget_show (window);
 
302
}
 
303
 
 
304
static void
 
305
update_photo_menu_status (UmPhotoDialog *um)
 
306
{
 
307
        if (um->num_cameras == 0)
 
308
                gtk_widget_set_sensitive (um->take_photo_menuitem, FALSE);
 
309
        else
 
310
                gtk_widget_set_sensitive (um->take_photo_menuitem, TRUE);
 
311
}
 
312
 
 
313
static void
 
314
device_added (CheeseCameraDeviceMonitor *monitor,
 
315
              CheeseCameraDevice        *device,
 
316
              UmPhotoDialog             *um)
 
317
{
 
318
        um->num_cameras++;
 
319
        update_photo_menu_status (um);
 
320
}
 
321
 
 
322
static void
 
323
device_removed (CheeseCameraDeviceMonitor *monitor,
 
324
                const char                *id,
 
325
                UmPhotoDialog             *um)
 
326
{
 
327
        um->num_cameras--;
 
328
        update_photo_menu_status (um);
 
329
}
 
330
 
 
331
#endif /* HAVE_CHEESE */
 
332
 
 
333
static void
 
334
stock_icon_selected (GtkMenuItem   *menuitem,
 
335
                     UmPhotoDialog *um)
 
336
{
 
337
        const char *filename;
 
338
 
 
339
        filename = g_object_get_data (G_OBJECT (menuitem), "filename");
 
340
        um_user_set_icon_file (um->user, filename);
 
341
}
 
342
 
 
343
static GtkWidget *
 
344
menu_item_for_filename (UmPhotoDialog *um,
 
345
                        const char    *filename)
 
346
{
 
347
        GtkWidget *image, *menuitem;
 
348
        GFile *file;
 
349
        GIcon *icon;
 
350
 
 
351
        file = g_file_new_for_path (filename);
 
352
        icon = g_file_icon_new (file);
 
353
        g_object_unref (file);
 
354
        image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_DIALOG);
 
355
        g_object_unref (icon);
 
356
 
 
357
        menuitem = gtk_menu_item_new ();
 
358
        gtk_container_add (GTK_CONTAINER (menuitem), image);
 
359
        gtk_widget_show_all (menuitem);
 
360
 
 
361
        g_object_set_data_full (G_OBJECT (menuitem), "filename",
 
362
                                g_strdup (filename), (GDestroyNotify) g_free);
 
363
        g_signal_connect (G_OBJECT (menuitem), "activate",
 
364
                          G_CALLBACK (stock_icon_selected), um);
 
365
 
 
366
        return menuitem;
 
367
}
 
368
 
 
369
static void
 
370
setup_photo_popup (UmPhotoDialog *um)
 
371
{
 
372
        GtkWidget *menu, *menuitem, *image;
 
373
        guint x, y;
 
374
        const gchar * const * dirs;
 
375
        guint i;
 
376
        GDir *dir;
 
377
        const char *face;
 
378
        gboolean none_item_shown;
 
379
        gboolean added_faces;
 
380
 
 
381
        menu = gtk_menu_new ();
 
382
 
 
383
        x = 0;
 
384
        y = 0;
 
385
        none_item_shown = added_faces = FALSE;
 
386
 
 
387
        dirs = g_get_system_data_dirs ();
 
388
        for (i = 0; dirs[i] != NULL; i++) {
 
389
                char *path;
 
390
 
 
391
                path = g_build_filename (dirs[i], "pixmaps", "faces", NULL);
 
392
                dir = g_dir_open (path, 0, NULL);
 
393
                if (dir == NULL) {
 
394
                        g_free (path);
 
395
                        continue;
 
396
                }
 
397
 
 
398
                while ((face = g_dir_read_name (dir)) != NULL) {
 
399
                        char *filename;
 
400
 
 
401
                        added_faces = TRUE;
 
402
 
 
403
                        filename = g_build_filename (path, face, NULL);
 
404
                        menuitem = menu_item_for_filename (um, filename);
 
405
                        g_free (filename);
 
406
                        if (menuitem == NULL)
 
407
                                continue;
 
408
 
 
409
                        gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
 
410
                                         x, x + 1, y, y + 1);
 
411
                        gtk_widget_show (menuitem);
 
412
 
 
413
                        x++;
 
414
                        if (x >= ROW_SPAN - 1) {
 
415
                                y++;
 
416
                                x = 0;
 
417
                        }
 
418
                }
 
419
                g_dir_close (dir);
 
420
                g_free (path);
 
421
 
 
422
                if (added_faces)
 
423
                        break;
 
424
        }
 
425
 
 
426
        if (!added_faces)
 
427
                goto skip_faces;
 
428
 
 
429
        image = gtk_image_new_from_icon_name ("avatar-default", GTK_ICON_SIZE_DIALOG);
 
430
        menuitem = gtk_menu_item_new ();
 
431
        gtk_container_add (GTK_CONTAINER (menuitem), image);
 
432
        gtk_widget_show_all (menuitem);
 
433
        gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
 
434
                         x, x + 1, y, y + 1);
 
435
        g_signal_connect (G_OBJECT (menuitem), "activate",
 
436
                          G_CALLBACK (none_icon_selected), um);
 
437
        gtk_widget_show (menuitem);
 
438
        none_item_shown = TRUE;
 
439
        y++;
 
440
 
 
441
skip_faces:
 
442
        if (!none_item_shown) {
 
443
                menuitem = gtk_menu_item_new_with_label (_("Disable image"));
 
444
                gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
 
445
                                 0, ROW_SPAN - 1, y, y + 1);
 
446
                g_signal_connect (G_OBJECT (menuitem), "activate",
 
447
                                  G_CALLBACK (none_icon_selected), um);
 
448
                gtk_widget_show (menuitem);
 
449
                y++;
 
450
        }
 
451
 
 
452
        /* Separator */
 
453
        menuitem = gtk_separator_menu_item_new ();
 
454
        gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
 
455
                         0, ROW_SPAN - 1, y, y + 1);
 
456
        gtk_widget_show (menuitem);
 
457
 
 
458
        y++;
 
459
 
 
460
#ifdef HAVE_CHEESE
 
461
        um->take_photo_menuitem = gtk_menu_item_new_with_label (_("Take a photo..."));
 
462
        gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (um->take_photo_menuitem),
 
463
                         0, ROW_SPAN - 1, y, y + 1);
 
464
        g_signal_connect (G_OBJECT (um->take_photo_menuitem), "activate",
 
465
                          G_CALLBACK (webcam_icon_selected), um);
 
466
        gtk_widget_set_sensitive (um->take_photo_menuitem, FALSE);
 
467
        gtk_widget_show (um->take_photo_menuitem);
 
468
 
 
469
        um->monitor = cheese_camera_device_monitor_new ();
 
470
        g_signal_connect (G_OBJECT (um->monitor), "added",
 
471
                          G_CALLBACK (device_added), um);
 
472
        g_signal_connect (G_OBJECT (um->monitor), "removed",
 
473
                          G_CALLBACK (device_removed), um);
 
474
        cheese_camera_device_monitor_coldplug (um->monitor);
 
475
 
 
476
        y++;
 
477
#endif /* HAVE_CHEESE */
 
478
 
 
479
        menuitem = gtk_menu_item_new_with_label (_("Browse for more pictures..."));
 
480
        gtk_menu_attach (GTK_MENU (menu), GTK_WIDGET (menuitem),
 
481
                         0, ROW_SPAN - 1, y, y + 1);
 
482
        g_signal_connect (G_OBJECT (menuitem), "activate",
 
483
                          G_CALLBACK (file_icon_selected), um);
 
484
        gtk_widget_show (menuitem);
 
485
 
 
486
        um->photo_popup = menu;
 
487
}
 
488
 
 
489
static void
 
490
popup_icon_menu (GtkToggleButton *button, UmPhotoDialog *um)
 
491
{
 
492
        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) && !gtk_widget_get_visible (um->photo_popup)) {
 
493
                gtk_menu_popup (GTK_MENU (um->photo_popup),
 
494
                                NULL, NULL,
 
495
                                (GtkMenuPositionFunc) popup_menu_below_button, um->popup_button,
 
496
                                0, gtk_get_current_event_time ());
 
497
        } else {
 
498
                gtk_menu_popdown (GTK_MENU (um->photo_popup));
 
499
        }
 
500
}
 
501
 
 
502
static gboolean
 
503
on_popup_button_button_pressed (GtkToggleButton *button,
 
504
                                GdkEventButton *event,
 
505
                                UmPhotoDialog  *um)
 
506
{
 
507
        if (event->button == 1) {
 
508
                if (!gtk_widget_get_visible (um->photo_popup)) {
 
509
                        popup_icon_menu (button, um);
 
510
                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
 
511
                } else {
 
512
                        gtk_menu_popdown (GTK_MENU (um->photo_popup));
 
513
                        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
 
514
                }
 
515
 
 
516
                return TRUE;
 
517
        }
 
518
 
 
519
        return FALSE;
 
520
}
 
521
 
 
522
static void
 
523
on_photo_popup_unmap (GtkWidget     *popup_menu,
 
524
                      UmPhotoDialog *um)
 
525
{
 
526
        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (um->popup_button), FALSE);
 
527
}
 
528
 
 
529
static void
 
530
popup_button_draw (GtkWidget      *widget,
 
531
                   cairo_t        *cr,
 
532
                   UmPhotoDialog  *um)
 
533
{
 
534
        if (gtk_widget_get_state (gtk_bin_get_child (GTK_BIN (widget))) != GTK_STATE_PRELIGHT &&
 
535
            !gtk_widget_is_focus (widget)) {
 
536
                return;
 
537
        }
 
538
 
 
539
        down_arrow (gtk_widget_get_style_context (widget),
 
540
                    cr,
 
541
                    gtk_widget_get_allocated_width (widget) - 12,
 
542
                    gtk_widget_get_allocated_height (widget) - 12,
 
543
                    12, 12);
 
544
}
 
545
 
 
546
static void
 
547
popup_button_focus_changed (GObject       *button,
 
548
                            GParamSpec    *pspec,
 
549
                            UmPhotoDialog *um)
 
550
{
 
551
        gtk_widget_queue_draw (gtk_bin_get_child (GTK_BIN (button)));
 
552
}
 
553
 
 
554
UmPhotoDialog *
 
555
um_photo_dialog_new (GtkWidget *button)
 
556
{
 
557
        UmPhotoDialog *um;
 
558
 
 
559
        um = g_new0 (UmPhotoDialog, 1);
 
560
 
 
561
        um->thumb_factory = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
 
562
 
 
563
        /* Set up the popup */
 
564
        um->popup_button = button;
 
565
        setup_photo_popup (um);
 
566
        g_signal_connect (button, "toggled",
 
567
                          G_CALLBACK (popup_icon_menu), um);
 
568
        g_signal_connect (button, "button-press-event",
 
569
                          G_CALLBACK (on_popup_button_button_pressed), um);
 
570
        g_signal_connect (button, "notify::is-focus",
 
571
                          G_CALLBACK (popup_button_focus_changed), um);
 
572
        g_signal_connect_after (button, "draw",
 
573
                                G_CALLBACK (popup_button_draw), um);
 
574
 
 
575
        g_signal_connect (um->photo_popup, "unmap",
 
576
                          G_CALLBACK (on_photo_popup_unmap), um);
 
577
 
 
578
        return um;
 
579
}
 
580
 
 
581
void
 
582
um_photo_dialog_free (UmPhotoDialog *um)
 
583
{
 
584
        gtk_widget_destroy (um->photo_popup);
 
585
 
 
586
        if (um->thumb_factory)
 
587
                g_object_unref (um->thumb_factory);
 
588
#ifdef HAVE_CHEESE
 
589
        if (um->monitor)
 
590
                g_object_unref (um->monitor);
 
591
#endif
 
592
        if (um->user)
 
593
                g_object_unref (um->user);
 
594
 
 
595
        g_free (um);
 
596
}
 
597
 
 
598
static void
 
599
clear_tip (GtkMenuItem  *item,
 
600
           gpointer      user_data)
 
601
{
 
602
        GList *children;
 
603
        GtkWidget *image;
 
604
        GIcon *icon, *icon2;
 
605
        const char *filename;
 
606
 
 
607
        /* Not a stock icon? */
 
608
        filename = g_object_get_data (G_OBJECT (item), "filename");
 
609
        if (filename == NULL)
 
610
                return;
 
611
 
 
612
        children = gtk_container_get_children (GTK_CONTAINER (item));
 
613
        image = children->data;
 
614
        g_assert (image != NULL);
 
615
        g_list_free (children);
 
616
 
 
617
        gtk_image_get_gicon (GTK_IMAGE (image), &icon, NULL);
 
618
 
 
619
        if (G_IS_EMBLEMED_ICON (icon))
 
620
                icon2 = g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon));
 
621
        else
 
622
                return;
 
623
 
 
624
        gtk_image_set_from_gicon (GTK_IMAGE (image), icon2, GTK_ICON_SIZE_DIALOG);
 
625
        g_object_unref (icon);
 
626
}
 
627
 
 
628
static void
 
629
set_tip (GtkWidget  *item,
 
630
         const char *tip,
 
631
         GEmblem    *emblem)
 
632
{
 
633
        GList *children;
 
634
        GtkWidget *image;
 
635
        GIcon *icon, *icon2;
 
636
 
 
637
        children = gtk_container_get_children (GTK_CONTAINER (item));
 
638
        image = children->data;
 
639
        g_assert (image != NULL);
 
640
        g_list_free (children);
 
641
 
 
642
        gtk_image_get_gicon (GTK_IMAGE (image), &icon, NULL);
 
643
        if (G_IS_EMBLEMED_ICON (icon)) {
 
644
                return;
 
645
        }
 
646
 
 
647
        icon2 = g_emblemed_icon_new (icon, emblem);
 
648
        gtk_image_set_from_gicon (GTK_IMAGE (image), icon2, GTK_ICON_SIZE_DIALOG);
 
649
 
 
650
        gtk_widget_set_tooltip_text (GTK_WIDGET (item), tip);
 
651
}
 
652
 
 
653
void
 
654
um_photo_dialog_set_user (UmPhotoDialog *um,
 
655
                          UmUser        *user)
 
656
{
 
657
        UmUserManager *manager;
 
658
        GSList *list, *l;
 
659
        UmUser *u;
 
660
        GIcon *icon;
 
661
        GEmblem *emblem;
 
662
        GList *children, *c;
 
663
 
 
664
        g_return_if_fail (um != NULL);
 
665
 
 
666
        if (um->user) {
 
667
                g_object_unref (um->user);
 
668
                um->user = NULL;
 
669
        }
 
670
        um->user = user;
 
671
 
 
672
        if (um->user) {
 
673
                g_object_ref (um->user);
 
674
 
 
675
                children = gtk_container_get_children (GTK_CONTAINER (um->photo_popup));
 
676
                g_list_foreach (children, (GFunc) clear_tip, NULL);
 
677
 
 
678
                manager = um_user_manager_ref_default ();
 
679
                list = um_user_manager_list_users (manager);
 
680
                g_object_unref (manager);
 
681
 
 
682
                icon = g_themed_icon_new ("avatar-default");
 
683
                emblem = g_emblem_new (icon);
 
684
                g_object_unref (icon);
 
685
 
 
686
                for (l = list; l; l = l->next) {
 
687
                        const char *filename;
 
688
 
 
689
                        u = l->data;
 
690
                        if (u == user)
 
691
                                continue;
 
692
                        filename = um_user_get_icon_file (u);
 
693
                        if (filename  == NULL)
 
694
                                continue;
 
695
                        for (c = children; c; c = c->next) {
 
696
                                const char *f;
 
697
 
 
698
                                f = g_object_get_data (G_OBJECT (c->data), "filename");
 
699
                                if (f == NULL)
 
700
                                        continue;
 
701
                                if (strcmp (f, filename) == 0) {
 
702
                                        char *tip;
 
703
 
 
704
                                        tip = g_strdup_printf (_("Used by %s"),
 
705
                                                               um_user_get_real_name (u));
 
706
                                        set_tip (GTK_WIDGET (c->data), tip, emblem);
 
707
                                        g_free (tip);
 
708
                                        break;
 
709
                                }
 
710
                        }
 
711
                }
 
712
                g_slist_free (list);
 
713
 
 
714
                g_object_unref (emblem);
 
715
        }
 
716
}
 
717