[accounts-dialog] Use unique display names if real names clash
- From: Matthias Clasen <matthiasc src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [accounts-dialog] Use unique display names if real names clash
- Date: Sun, 24 Jan 2010 08:05:38 +0000 (UTC)
commit 391024867429ba756c85ed17eacd9fbae7752812
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Jan 24 03:03:25 2010 -0500
Use unique display names if real names clash
src/main.c | 8 ++-
src/um-user-manager.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
src/um-user-manager.h | 2 +-
src/um-user.c | 82 ++++++++++++++++++++++++++++++-------
src/um-user.h | 3 +
5 files changed, 181 insertions(+), 20 deletions(-)
---
diff --git a/src/main.c b/src/main.c
index bb60f28..36dd6ef 100644
--- a/src/main.c
+++ b/src/main.c
@@ -136,7 +136,7 @@ user_added (UmUserManager *um, UmUser *user, UserAccountDialog *d)
pixbuf = um_user_render_icon (user, TRUE, 48);
text = g_strdup_printf ("<b>%s</b>\n<i>%s</i>",
- um_user_get_real_name (user),
+ um_user_get_display_name (user),
um_account_type_get_name (um_user_get_account_type (user)));
if (um_user_get_uid (user) == getuid ()) {
@@ -234,7 +234,7 @@ user_changed (UmUserManager *um, UmUser *user, UserAccountDialog *d)
if (current == user) {
pixbuf = um_user_render_icon (user, TRUE, 48);
text = g_strdup_printf ("<b>%s</b>\n<i>%s</i>",
- um_user_get_real_name (user),
+ um_user_get_display_name (user),
um_account_type_get_name (um_user_get_account_type (user)));
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
@@ -904,6 +904,9 @@ users_loaded (UmUserManager *manager,
list = um_user_manager_list_users (d->um);
g_debug ("Got %d users\n", g_slist_length (list));
+
+ g_signal_connect (d->um, "user-changed", G_CALLBACK (user_changed), d);
+
for (l = list; l; l = l->next) {
user = l->data;
g_debug ("adding user %s\n", um_user_get_real_name (user));
@@ -913,7 +916,6 @@ users_loaded (UmUserManager *manager,
g_signal_connect (d->um, "user-added", G_CALLBACK (user_added), d);
g_signal_connect (d->um, "user-removed", G_CALLBACK (user_removed), d);
- g_signal_connect (d->um, "user-changed", G_CALLBACK (user_changed), d);
}
static void
diff --git a/src/um-user-manager.c b/src/um-user-manager.c
index 695037c..7330e91 100644
--- a/src/um-user-manager.c
+++ b/src/um-user-manager.c
@@ -104,10 +104,90 @@ um_user_manager_class_init (UmUserManagerClass *klass)
G_TYPE_NONE, 1, UM_TYPE_USER);
}
+
+/* We maintain a ring for each group of users with the same real name.
+ * We need this to pick the right display names.
+ */
+static void
+remove_user_from_dupe_ring (UmUserManager *manager,
+ UmUser *user)
+{
+ GList *dupes;
+ UmUser *dup;
+
+ um_user_show_short_display_name (user);
+
+ dupes = g_object_get_data (user, "dupes");
+
+ if (dupes == NULL) {
+ return;
+ }
+
+ if (dupes->next == dupes->prev) {
+ dup = dupes->next->data;
+ um_user_show_short_display_name (dup);
+ g_signal_emit (manager, signals[USER_CHANGED], 0, dup);
+
+ g_list_free_1 (dupes->next);
+ g_object_set_data (dup, "dupes", NULL);
+ }
+ else {
+ dupes->next->prev = dupes->prev;
+ dupes->prev->next = dupes->next;
+ }
+
+ g_list_free_1 (dupes);
+ g_object_set_data (user, "dupes", NULL);
+}
+
+static gboolean
+match_real_name_hrfunc (gpointer key,
+ gpointer value,
+ gpointer user)
+{
+ return (value != user && g_strcmp0 (um_user_get_real_name (user), um_user_get_real_name (value)) == 0);
+}
+
+static void
+add_user_to_dupe_ring (UmUserManager *manager,
+ UmUser *user)
+{
+ UmUser *dup;
+ GList *dupes;
+ GList *l;
+
+ dup = g_hash_table_find (manager->user_by_object_path,
+ match_real_name_hrfunc, user);
+
+ if (!dup) {
+ return;
+ }
+
+ um_user_show_full_display_name (user);
+
+ dupes = g_object_get_data (dup, "dupes");
+ if (!dupes) {
+ um_user_show_full_display_name (dup);
+ g_signal_emit (manager, signals[USER_CHANGED], 0, dup);
+ dupes = g_list_append (NULL, dup);
+ g_object_set_data (dup, "dupes", dupes);
+ dupes->next = dupes->prev = dupes;
+ }
+
+ l = g_list_append (NULL, user);
+ g_object_set_data (user, "dupes", l);
+ l->prev = dupes->prev;
+ dupes->prev->next = l;
+ l->next = dupes;
+ dupes->prev = l;
+}
+
static void
user_changed_handler (UmUser *user,
UmUserManager *manager)
{
+ remove_user_from_dupe_ring (manager, user);
+ add_user_to_dupe_ring (manager, user);
g_signal_emit (manager, signals[USER_CHANGED], 0, user);
}
@@ -125,10 +205,14 @@ user_added_handler (DBusGProxy *proxy,
user = um_user_new_from_object_path (object_path);
if (!user)
return;
+
+ add_user_to_dupe_ring (manager, user);
+
g_signal_connect (user, "changed",
G_CALLBACK (user_changed_handler), manager);
g_hash_table_insert (manager->user_by_object_path, (gpointer)um_user_get_object_path (user), g_object_ref (user));
g_hash_table_insert (manager->user_by_name, (gpointer)um_user_get_user_name (user), g_object_ref (user));
+
g_signal_emit (manager, signals[USER_ADDED], 0, user);
g_object_unref (user);
}
@@ -144,6 +228,9 @@ user_deleted_handler (DBusGProxy *proxy,
user = g_hash_table_lookup (manager->user_by_object_path, object_path);
g_object_ref (user);
g_signal_handlers_disconnect_by_func (user, user_changed_handler, manager);
+
+ remove_user_from_dupe_ring (manager, user);
+
g_hash_table_remove (manager->user_by_object_path, um_user_get_object_path (user));
g_hash_table_remove (manager->user_by_name, um_user_get_user_name (user));
g_signal_emit (manager, signals[USER_REMOVED], 0, user);
@@ -237,12 +324,31 @@ um_user_manager_init (UmUserManager *manager)
}
static void
+clear_dup (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ GList *dupes;
+
+ /* don't bother maintaining the ring, we're destroying the
+ * entire hash table anyway
+ */
+ dupes = g_object_get_data (value, "dupes");
+
+ if (dupes) {
+ g_list_free_1 (dupes);
+ g_object_set_data (value, "dupes", NULL);
+ }
+}
+
+static void
um_user_manager_finalize (GObject *object)
{
UmUserManager *manager;
manager = UM_USER_MANAGER (object);
+ g_hash_table_foreach (manager->user_by_object_path, clear_dup, NULL);
g_hash_table_destroy (manager->user_by_object_path);
g_hash_table_destroy (manager->user_by_name);
diff --git a/src/um-user-manager.h b/src/um-user-manager.h
index fe8b193..a25b36a 100644
--- a/src/um-user-manager.h
+++ b/src/um-user-manager.h
@@ -45,7 +45,7 @@ typedef struct
GHashTable *user_by_object_path;
GHashTable *user_by_name;
- gboolean no_service;
+ gboolean no_service;
} UmUserManager;
typedef struct
diff --git a/src/um-user.c b/src/um-user.c
index 0d12b80..756e3c9 100644
--- a/src/um-user.c
+++ b/src/um-user.c
@@ -182,6 +182,8 @@ struct _UmUser {
gchar *object_path;
UserProperties *props;
+
+ gchar *display_name;
};
typedef struct _UmUserClass
@@ -260,6 +262,15 @@ um_user_get_real_name (UmUser *user)
}
const gchar *
+um_user_get_display_name (UmUser *user)
+{
+ g_return_val_if_fail (UM_IS_USER (user), NULL);
+
+ return user->display_name ? user->display_name
+ : user->props->real_name;
+}
+
+const gchar *
um_user_get_user_name (UmUser *user)
{
g_return_val_if_fail (UM_IS_USER (user), NULL);
@@ -665,8 +676,8 @@ um_user_get_language (UmUser *user)
{
g_return_val_if_fail (UM_IS_USER (user), NULL);
- if (*user->props->language == '\0')
- return NULL;
+ if (*user->props->language == '\0')
+ return NULL;
return user->props->language;
}
@@ -742,6 +753,10 @@ changed_handler (DBusGProxy *proxy,
UmUser *user = UM_USER (data);
if (update_info (user)) {
+ if (user->display_name != NULL) {
+ um_user_show_full_display_name (user);
+ }
+
g_signal_emit (user, signals[CHANGED], 0);
}
}
@@ -1020,37 +1035,37 @@ gboolean
um_user_is_logged_in (UmUser *user)
{
DBusGProxy *proxy;
- GPtrArray *array;
- GError *error;
- gint n_sessions;
+ GPtrArray *array;
+ GError *error;
+ gint n_sessions;
proxy = dbus_g_proxy_new_for_name (user->bus,
- "org.freedesktop.ConsoleKit",
+ "org.freedesktop.ConsoleKit",
"/org/freedesktop/ConsoleKit/Manager",
"org.freedesktop.ConsoleKit.Manager");
- array = NULL;
- error = NULL;
+ array = NULL;
+ error = NULL;
if (!dbus_g_proxy_call (proxy,
"GetSessionsForUnixUser",
&error,
G_TYPE_UINT, um_user_get_uid (user),
G_TYPE_INVALID,
- dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &array,
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &array,
G_TYPE_INVALID)) {
g_warning ("GetSessionsForUnixUser failed: %s", error->message);
- g_error_free (error);
- return FALSE;
- }
+ g_error_free (error);
+ return FALSE;
+ }
- n_sessions = array->len;
+ n_sessions = array->len;
g_ptr_array_foreach (array, (GFunc)g_free, NULL);
- g_ptr_array_free (array, TRUE);
+ g_ptr_array_free (array, TRUE);
- g_object_unref (proxy);
+ g_object_unref (proxy);
- return n_sessions > 0;
+ return n_sessions > 0;
}
@@ -1071,3 +1086,38 @@ um_user_set_automatic_login (UmUser *user,
}
}
+void
+um_user_show_full_display_name (UmUser *user)
+{
+ char *uniq_name;
+
+ g_return_if_fail (UM_IS_USER (user));
+
+ if (user->props->real_name != NULL) {
+ uniq_name = g_strdup_printf ("%s (%s)",
+ user->props->real_name,
+ user->props->user_name);
+ } else {
+ uniq_name = NULL;
+ }
+
+ if (uniq_name && g_strcmp0 (uniq_name, user->display_name) != 0) {
+ g_free (user->display_name);
+ user->display_name = uniq_name;
+ }
+ else {
+ g_free (uniq_name);
+ }
+}
+
+void
+um_user_show_short_display_name (UmUser *user)
+{
+ g_return_if_fail (UM_IS_USER (user));
+
+ if (user->display_name) {
+ g_free (user->display_name);
+ user->display_name = NULL;
+ }
+}
+
diff --git a/src/um-user.h b/src/um-user.h
index 5f0e50d..6c487b6 100644
--- a/src/um-user.h
+++ b/src/um-user.h
@@ -97,6 +97,9 @@ GdkPixbuf *um_user_render_icon (UmUser *user,
gint um_user_collate (UmUser *user1,
UmUser *user2);
+void um_user_show_short_display_name (UmUser *user);
+void um_user_show_full_display_name (UmUser *user);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]