2
* Fast User Switch Applet: fusa-user-menu-item.c
4
* Copyright (C) 2005 James M. Cape <jcape@ignore-your.tv>.
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 of the License, or
9
* (at your option) any later version.
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.
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 02111-1307 USA
23
#include <glib/gi18n.h>
26
#include <sys/types.h>
30
#include <gtk/gtkbutton.h>
31
#include <gtk/gtkdialog.h>
32
#include <gtk/gtkhbox.h>
33
#include <gtk/gtkiconfactory.h>
34
#include <gtk/gtkicontheme.h>
35
#include <gtk/gtkimage.h>
36
#include <gtk/gtklabel.h>
37
#include <gtk/gtkradiobutton.h>
38
#include <gtk/gtkstock.h>
39
#include <gtk/gtkvbox.h>
41
#include "fusa-user-menu-item.h"
48
#define DEFAULT_ICON_SIZE 24
49
#define CLOSE_ENOUGH_SIZE 2
51
/* ********************** *
52
* Private Enumerations *
53
* ********************** */
63
/* ******************** *
64
* Private Structures *
65
* ******************** */
67
struct _FusaUserMenuItem
69
GtkImageMenuItem parent;
76
gulong user_notify_id;
77
gulong user_icon_changed_id;
78
gulong user_displays_changed_id;
82
struct _FusaUserMenuItemClass
84
GtkImageMenuItemClass parent_class;
88
/* ********************* *
89
* Function Prototypes *
90
* ********************* */
92
/* GObject Functions */
93
static void fusa_user_menu_item_set_property (GObject *object,
97
static void fusa_user_menu_item_get_property (GObject *object,
101
static void fusa_user_menu_item_finalize (GObject *object);
103
/* FusaUser Callbacks */
104
static void user_notify_cb (GObject *object,
107
static void user_icon_changed_cb (FusaUser *user,
109
static void user_displays_changed_cb (FusaUser *user,
111
static void user_weak_notify (gpointer data,
114
/* Widget Callbacks */
115
static void image_style_set_cb (GtkWidget *widget,
118
static void label_style_set_cb (GtkWidget *widget,
122
/* Utility Functions */
123
static void reset_label (FusaUserMenuItem *item);
124
static void reset_icon (FusaUserMenuItem *item);
127
/* ******************* *
128
* GType Declaration *
129
* ******************* */
131
G_DEFINE_TYPE (FusaUserMenuItem, fusa_user_menu_item, GTK_TYPE_IMAGE_MENU_ITEM);
134
/* ***************** *
136
* ***************** */
139
fusa_user_menu_item_class_init (FusaUserMenuItemClass *class)
141
GObjectClass *gobject_class;
143
gobject_class = G_OBJECT_CLASS (class);
145
gobject_class->set_property = fusa_user_menu_item_set_property;
146
gobject_class->get_property = fusa_user_menu_item_get_property;
147
gobject_class->finalize = fusa_user_menu_item_finalize;
149
g_object_class_install_property (gobject_class,
151
g_param_spec_object ("user",
153
_("The user this menu item represents."),
156
G_PARAM_CONSTRUCT_ONLY)));
157
g_object_class_install_property (gobject_class,
159
g_param_spec_int ("icon-size",
161
_("The size of the icon to use."),
162
12, G_MAXINT, DEFAULT_ICON_SIZE,
167
fusa_user_menu_item_init (FusaUserMenuItem *item)
169
item->icon_size = DEFAULT_ICON_SIZE;
171
item->image = gtk_image_new ();
172
g_signal_connect (item->image, "style-set",
173
G_CALLBACK (image_style_set_cb), item);
174
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), item->image);
175
gtk_widget_show (item->image);
177
item->label = gtk_label_new (NULL);
178
gtk_label_set_use_markup (GTK_LABEL (item->label), TRUE);
179
gtk_misc_set_alignment (GTK_MISC (item->label), 0.0, 0.5);
180
g_signal_connect (item->label, "style-set",
181
G_CALLBACK (label_style_set_cb), item);
182
gtk_container_add (GTK_CONTAINER (item), item->label);
183
gtk_widget_show (item->label);
187
/* ******************* *
188
* GObject Functions *
189
* ******************* */
192
fusa_user_menu_item_set_property (GObject *object,
197
FusaUserMenuItem *item;
199
item = FUSA_USER_MENU_ITEM (object);
204
item->user = g_value_get_object (value);
205
g_object_weak_ref (G_OBJECT (item->user), user_weak_notify, item);
206
item->user_notify_id =
207
g_signal_connect (item->user, "notify",
208
G_CALLBACK (user_notify_cb), item);
209
item->user_icon_changed_id =
210
g_signal_connect (item->user, "icon-changed",
211
G_CALLBACK (user_icon_changed_cb), item);
212
item->user_displays_changed_id =
213
g_signal_connect (item->user, "displays-changed",
214
G_CALLBACK (user_displays_changed_cb), item);
216
if (gtk_widget_get_style (GTK_WIDGET (object)))
223
fusa_user_menu_item_set_icon_size (item, g_value_get_int (value));
226
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
232
fusa_user_menu_item_get_property (GObject *object,
237
FusaUserMenuItem *item;
239
item = FUSA_USER_MENU_ITEM (object);
244
g_value_set_object (value, item->user);
247
g_value_set_int (value, item->icon_size);
250
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
256
fusa_user_menu_item_finalize (GObject *object)
258
FusaUserMenuItem *item;
260
item = FUSA_USER_MENU_ITEM (object);
264
g_signal_handler_disconnect (item->user, item->user_notify_id);
265
g_signal_handler_disconnect (item->user, item->user_icon_changed_id);
266
g_signal_handler_disconnect (item->user, item->user_displays_changed_id);
267
g_object_weak_unref (G_OBJECT (item->user), user_weak_notify, object);
270
if (G_OBJECT_CLASS (fusa_user_menu_item_parent_class)->finalize)
271
(*G_OBJECT_CLASS (fusa_user_menu_item_parent_class)->finalize) (object);
275
/* ******************** *
276
* FusaUser Callbacks *
277
* ******************** */
280
user_notify_cb (GObject *object,
284
if (!pspec || !pspec->name)
287
if (strcmp (pspec->name, "user-name") == 0 ||
288
strcmp (pspec->name, "display-name") == 0)
293
user_icon_changed_cb (FusaUser *user,
296
if (gtk_widget_has_screen (data))
301
user_displays_changed_cb (FusaUser *user,
304
if (gtk_widget_has_screen (data))
307
if (fusa_user_get_uid (user) == getuid ())
308
gtk_widget_set_sensitive (data, (fusa_user_get_n_displays (user) > 1));
310
gtk_widget_set_sensitive (data, TRUE);
314
user_weak_notify (gpointer data,
317
FUSA_USER_MENU_ITEM (data)->user = NULL;
319
gtk_widget_destroy (data);
323
/* ****************** *
325
* ****************** */
328
image_style_set_cb (GtkWidget *widget,
336
label_style_set_cb (GtkWidget *widget,
344
/* ******************* *
345
* Utility Functions *
346
* ******************* */
349
reset_label (FusaUserMenuItem *item)
358
text = g_strconcat ("<b>",
359
fusa_user_get_display_name (item->user),
362
fusa_user_get_user_name (item->user),
366
gtk_label_set_markup (GTK_LABEL (item->label), text);
369
layout = gtk_label_get_layout (GTK_LABEL (item->label));
370
pango_layout_get_pixel_size (layout, NULL, &height);
372
if (height > (item->icon_size + CLOSE_ENOUGH_SIZE))
373
gtk_label_set_markup (GTK_LABEL (item->label),
374
fusa_user_get_display_name (item->user));
378
reset_icon (FusaUserMenuItem *item)
382
if (!item->user || !gtk_widget_has_screen (GTK_WIDGET (item)))
385
g_assert (item->icon_size != 0);
387
pixbuf = fusa_user_render_icon (item->user, GTK_WIDGET (item),
389
fusa_user_get_n_displays (item->user));
390
gtk_image_set_from_pixbuf (GTK_IMAGE (item->image), pixbuf);
391
g_object_unref (pixbuf);
395
/* ************************************************************************** *
397
* ************************************************************************** */
400
fusa_user_menu_item_new (FusaUser *user)
402
g_return_val_if_fail (FUSA_IS_USER (user), NULL);
404
return g_object_new (FUSA_TYPE_USER_MENU_ITEM, "user", user, NULL);
408
fusa_user_menu_item_get_user (FusaUserMenuItem *item)
410
g_return_val_if_fail (FUSA_IS_USER_MENU_ITEM (item), NULL);
416
fusa_user_menu_item_get_icon_size (FusaUserMenuItem *item)
418
g_return_val_if_fail (FUSA_IS_USER_MENU_ITEM (item), -1);
420
return item->icon_size;
424
fusa_user_menu_item_set_icon_size (FusaUserMenuItem *item,
427
g_return_if_fail (FUSA_IS_USER_MENU_ITEM (item));
428
g_return_if_fail (pixel_size != 0);
431
item->icon_size = DEFAULT_ICON_SIZE;
433
item->icon_size = pixel_size;
435
if (gtk_widget_get_style (GTK_WIDGET (item)))
440
g_object_notify (G_OBJECT (item), "icon-size");