[accounts-dialog/control-center-panel: 4/15] Various fixes
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [accounts-dialog/control-center-panel: 4/15] Various fixes
- Date: Mon, 14 Jun 2010 05:05:43 +0000 (UTC)
commit a2ce590b4937f5f0c1089ce2974c591114b70aee
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Jun 12 23:31:15 2010 -0400
Various fixes
src/um-login-options.c | 2 +-
src/um-photo-dialog.c | 12 +-
src/um-photo-dialog.h | 3 +-
src/um-user-module.c | 41 ++
src/um-user-panel.c | 1695 +++++++++++++++++++++++++++++++++++++++++++++
src/um-user-panel.h | 59 ++
src/user-panel.desktop.in | 9 +
7 files changed, 1810 insertions(+), 11 deletions(-)
---
diff --git a/src/um-login-options.c b/src/um-login-options.c
index 5330112..9fa74ed 100644
--- a/src/um-login-options.c
+++ b/src/um-login-options.c
@@ -423,7 +423,7 @@ um_login_options_free (UmLoginOptions *um)
if (um->proxy)
g_object_unref (um->proxy);
if (um->connection)
- g_object_unref (um->connection);
+ dbus_g_connection_unref (um->connection);
g_free (um);
}
diff --git a/src/um-photo-dialog.c b/src/um-photo-dialog.c
index e97f97d..b2e1677 100644
--- a/src/um-photo-dialog.c
+++ b/src/um-photo-dialog.c
@@ -42,7 +42,6 @@
#define ROW_SPAN 6
struct _UmPhotoDialog {
- GtkWidget *parent_window;
GtkWidget *photo_popup;
GtkWidget *popup_button;
GtkWidget *crop_area;
@@ -91,7 +90,7 @@ um_photo_dialog_crop (UmPhotoDialog *um,
GtkWidget *frame;
dialog = gtk_dialog_new_with_buttons ("",
- GTK_WINDOW (um->parent_window),
+ GTK_WINDOW (gtk_widget_get_toplevel (um->popup_button)),
GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_CANCEL,
GTK_RESPONSE_REJECT,
@@ -211,7 +210,7 @@ um_photo_dialog_select_file (UmPhotoDialog *um)
GtkWidget *preview;
chooser = gtk_file_chooser_dialog_new (_("Browse for more pictures"),
- GTK_WINDOW (um->parent_window),
+ GTK_WINDOW (gtk_widget_get_toplevel (um->popup_button)),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
@@ -289,7 +288,7 @@ webcam_icon_selected (GtkMenuItem *menuitem,
window = cheese_avatar_chooser_new ();
gtk_window_set_transient_for (GTK_WINDOW (window),
- GTK_WINDOW (um->parent_window));
+ GTK_WINDOW (gtk_widget_get_toplevel (um->popup_button)));
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
g_signal_connect (G_OBJECT (window), "response",
G_CALLBACK (webcam_response_cb), um);
@@ -529,7 +528,7 @@ popup_button_focus_changed (GObject *button,
}
UmPhotoDialog *
-um_photo_dialog_new (GtkWidget *button, GtkWidget *parent)
+um_photo_dialog_new (GtkWidget *button)
{
UmPhotoDialog *um;
@@ -552,9 +551,6 @@ um_photo_dialog_new (GtkWidget *button, GtkWidget *parent)
g_signal_connect (um->photo_popup, "unmap",
G_CALLBACK (on_photo_popup_unmap), um);
- /* Parent window */
- um->parent_window = parent;
-
return um;
}
diff --git a/src/um-photo-dialog.h b/src/um-photo-dialog.h
index f5a9b5f..3f0c404 100644
--- a/src/um-photo-dialog.h
+++ b/src/um-photo-dialog.h
@@ -29,8 +29,7 @@ G_BEGIN_DECLS
typedef struct _UmPhotoDialog UmPhotoDialog;
-UmPhotoDialog *um_photo_dialog_new (GtkWidget *button,
- GtkWidget *parent);
+UmPhotoDialog *um_photo_dialog_new (GtkWidget *button);
void um_photo_dialog_free (UmPhotoDialog *dialog);
void um_photo_dialog_set_user (UmPhotoDialog *dialog,
UmUser *user);
diff --git a/src/um-user-module.c b/src/um-user-module.c
new file mode 100644
index 0000000..d96ed40
--- /dev/null
+++ b/src/um-user-module.c
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2009-2010 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by: Matthias Clasen <mclasen redhat com>
+ */
+
+#include <config.h>
+
+#include "um-user-panel.h"
+
+#include <glib/gi18n.h>
+
+void
+g_io_module_load (GIOModule *module)
+{
+ bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+ /* register the panel */
+ um_user_panel_register (module);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+}
diff --git a/src/um-user-panel.c b/src/um-user-panel.c
new file mode 100644
index 0000000..4a1ef3b
--- /dev/null
+++ b/src/um-user-panel.c
@@ -0,0 +1,1695 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2009-2010 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include "um-user-panel.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <unique/unique.h>
+#include <polkit/polkit.h>
+#include <polkitgtk/polkitgtk.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#ifdef HAVE_CHEESE
+#include <gst/gst.h>
+#endif /* HAVE_CHEESE */
+
+#include "marshal.h"
+
+#include "um-user.h"
+#include "um-user-manager.h"
+
+#include "um-account-dialog.h"
+#include "um-language-dialog.h"
+#include "um-login-options.h"
+#include "um-password-dialog.h"
+#include "um-photo-dialog.h"
+#include "um-fingerprint-dialog.h"
+#include "um-utils.h"
+#include "um-strength-bar.h"
+#include "gdm-languages.h"
+
+G_DEFINE_DYNAMIC_TYPE (UmUserPanel, um_user_panel, CC_TYPE_PANEL)
+
+#define UM_USER_PANEL_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), UM_TYPE_USER_PANEL, UmUserPanelPrivate))
+
+struct _UmUserPanelPrivate {
+ UmUserManager *um;
+ GtkBuilder *builder;
+
+ GtkWidget *notebook;
+ GtkWidget *lock_button;
+ GtkWidget *language_chooser;
+
+ UmAccountDialog *account_dialog;
+ UmPasswordDialog *password_dialog;
+ UmPhotoDialog *photo_dialog;
+ UmLoginOptions *login_options;
+
+ PolkitAuthority *authority;
+};
+
+static GtkWidget *
+get_widget (UmUserPanelPrivate *d, const char *name)
+{
+ return (GtkWidget *)gtk_builder_get_object (d->builder, name);
+}
+
+enum {
+ USER_COL,
+ FACE_COL,
+ NAME_COL,
+ USER_ROW_COL,
+ TITLE_COL,
+ HEADING_ROW_COL,
+ SORT_KEY_COL,
+ NUM_USER_LIST_COLS
+};
+
+static UmUser *
+get_selected_user (UmUserPanelPrivate *d)
+{
+ GtkTreeView *tv;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ UmUser *user;
+
+ tv = (GtkTreeView *)get_widget (d, "list-treeview");
+ store = (GtkListStore *)gtk_tree_view_get_model (tv);
+ selection = gtk_tree_view_get_selection (tv);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
+ return user;
+ }
+
+ return NULL;
+}
+
+static void
+user_added (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
+{
+ GtkWidget *widget;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GtkTreeIter dummy;
+ GdkPixbuf *pixbuf;
+ gchar *text;
+ GtkTreeSelection *selection;
+ gint sort_key;
+
+ g_debug ("user added: %d %s\n", um_user_get_uid (user), um_user_get_real_name (user));
+ widget = get_widget (d, "list-treeview");
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+ store = GTK_LIST_STORE (model);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
+
+ pixbuf = um_user_render_icon (user, TRUE, 48);
+ text = g_strdup_printf ("<b>%s</b>\n<i>%s</i>",
+ um_user_get_display_name (user),
+ um_account_type_get_name (um_user_get_account_type (user)));
+
+ if (um_user_get_uid (user) == getuid ()) {
+ sort_key = 1;
+ }
+ else {
+ sort_key = 3;
+ }
+ gtk_list_store_append (store, &iter);
+
+ gtk_list_store_set (store, &iter,
+ USER_COL, user,
+ FACE_COL, pixbuf,
+ NAME_COL, text,
+ USER_ROW_COL, TRUE,
+ TITLE_COL, NULL,
+ HEADING_ROW_COL, FALSE,
+ SORT_KEY_COL, sort_key,
+ -1);
+ g_object_unref (pixbuf);
+ g_free (text);
+
+ if (sort_key == 1 &&
+ !gtk_tree_selection_get_selected (selection, &model, &dummy)) {
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+}
+
+static void
+get_previous_user_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkTreeIter *prev)
+{
+ GtkTreePath *path;
+ UmUser *user;
+
+ path = gtk_tree_model_get_path (model, iter);
+ while (gtk_tree_path_prev (path)) {
+ gtk_tree_model_get_iter (model, prev, path);
+ gtk_tree_model_get (model, prev, USER_COL, &user, -1);
+ if (user) {
+ g_object_unref (user);
+ break;
+ }
+ }
+ gtk_tree_path_free (path);
+}
+
+static gboolean
+get_next_user_row (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkTreeIter *next)
+{
+ UmUser *user;
+
+ *next = *iter;
+ while (gtk_tree_model_iter_next (model, next)) {
+ gtk_tree_model_get (model, next, USER_COL, &user, -1);
+ if (user) {
+ g_object_unref (user);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+user_removed (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
+{
+ GtkTreeView *tv;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkListStore *store;
+ GtkTreeIter iter, next;
+ UmUser *u;
+
+ g_debug ("user removed: %s\n", um_user_get_user_name (user));
+ tv = (GtkTreeView *)get_widget (d, "list-treeview");
+ selection = gtk_tree_view_get_selection (tv);
+ model = gtk_tree_view_get_model (tv);
+ store = GTK_LIST_STORE (model);
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ gtk_tree_model_get (model, &iter, USER_COL, &u, -1);
+
+ if (u != NULL) {
+ if (um_user_get_uid (user) == um_user_get_uid (u)) {
+ if (!get_next_user_row (model, &iter, &next))
+ get_previous_user_row (model, &iter, &next);
+ gtk_list_store_remove (store, &iter);
+ gtk_tree_selection_select_iter (selection, &next);
+ g_object_unref (u);
+ break;
+ }
+ g_object_unref (u);
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+}
+
+static void show_user (UmUser *user, UmUserPanelPrivate *d);
+
+static void
+user_changed (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
+{
+ GtkTreeView *tv;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ UmUser *current;
+ GdkPixbuf *pixbuf;
+ char *text;
+
+ tv = (GtkTreeView *)get_widget (d, "list-treeview");
+ model = gtk_tree_view_get_model (tv);
+ selection = gtk_tree_view_get_selection (tv);
+
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ gtk_tree_model_get (model, &iter, USER_COL, ¤t, -1);
+ 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_display_name (user),
+ um_account_type_get_name (um_user_get_account_type (user)));
+
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+ USER_COL, user,
+ FACE_COL, pixbuf,
+ NAME_COL, text,
+ -1);
+ g_object_unref (pixbuf);
+ g_free (text);
+ g_object_unref (current);
+
+ break;
+ }
+ if (current)
+ g_object_unref (current);
+
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get (model, &iter, USER_COL, ¤t, -1);
+
+ if (current == user) {
+ show_user (user, d);
+ }
+ if (current)
+ g_object_unref (current);
+ }
+}
+
+static void
+select_created_user (UmUser *user, UmUserPanelPrivate *d)
+{
+ GtkTreeView *tv;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ UmUser *current;
+ GtkTreePath *path;
+
+ tv = (GtkTreeView *)get_widget (d, "list-treeview");
+ model = gtk_tree_view_get_model (tv);
+ selection = gtk_tree_view_get_selection (tv);
+
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ gtk_tree_model_get (model, &iter, USER_COL, ¤t, -1);
+ if (user == current) {
+ path = gtk_tree_model_get_path (model, &iter);
+ gtk_tree_view_scroll_to_cell (tv, path, NULL, FALSE, 0.0, 0.0);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+ break;
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+}
+
+static void
+add_user (GtkButton *button, UmUserPanelPrivate *d)
+{
+ um_account_dialog_show (d->account_dialog,
+ GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)),
+ (UserCreatedCallback)select_created_user, d);
+}
+
+static void
+delete_user_done (UmUserManager *manager,
+ GAsyncResult *res,
+ UmUserPanelPrivate *d)
+{
+ GError *error;
+
+ error = NULL;
+ if (!um_user_manager_delete_user_finish (manager, res, &error)) {
+ if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED)) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("Failed to delete user"));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "%s", error->message);
+
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
+ }
+ g_error_free (error);
+ }
+}
+
+static void
+delete_user_response (GtkWidget *dialog,
+ gint response_id,
+ UmUserPanelPrivate *d)
+{
+ UmUser *user;
+ gboolean remove_files;
+
+ gtk_widget_destroy (dialog);
+
+ if (response_id == GTK_RESPONSE_CANCEL) {
+ return;
+ }
+ else if (response_id == GTK_RESPONSE_NO) {
+ remove_files = TRUE;
+ }
+ else {
+ remove_files = FALSE;
+ }
+
+ user = get_selected_user (d);
+
+ um_user_manager_delete_user (d->um,
+ user,
+ remove_files,
+ (GAsyncReadyCallback)delete_user_done,
+ d,
+ NULL);
+
+ g_object_unref (user);
+}
+
+static void
+delete_user (GtkButton *button, UmUserPanelPrivate *d)
+{
+ UmUser *user;
+ GtkWidget *dialog;
+
+ user = get_selected_user (d);
+ if (user == NULL) {
+ return;
+ }
+ else if (um_user_get_uid (user) == getuid ()) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)),
+ 0,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ _("You cannot delete your own account."));
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ }
+ else if (um_user_is_logged_in (user)) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)),
+ 0,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ _("%s is still logged in"),
+ um_user_get_real_name (user));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("Deleting a user while they are logged in can leave the system in an inconsistent state."));
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ }
+ else {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)),
+ 0,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("Do you want to keep %s's files?"),
+ um_user_get_real_name (user));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("It is possible to keep the home directory, mail spool and temporary files around when deleting a user account."));
+
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ _("_Delete Files"), GTK_RESPONSE_NO,
+ _("_Keep Files"), GTK_RESPONSE_YES,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ NULL);
+
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "system-users");
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (delete_user_response), d);
+ }
+
+ g_signal_connect (dialog, "close",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+
+ gtk_window_present (GTK_WINDOW (dialog));
+
+}
+
+static const char *
+nonempty (const char *str)
+{
+ return (str == NULL || str[0] == 0) ? "\xe2\x80\x94" : str;
+}
+
+static void language_changed (GtkComboBox *combo, UmUserPanelPrivate *d);
+
+static void
+show_user (UmUser *user, UmUserPanelPrivate *d)
+{
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *label2;
+ GtkWidget *label3;
+ GdkPixbuf *pixbuf;
+ const char *text;
+ char *language;
+ GtkWidget *combo;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *widget;
+
+ pixbuf = um_user_render_icon (user, FALSE, 48);
+ image = get_widget (d, "user-icon-image");
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
+ image = get_widget (d, "user-icon-image2");
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
+ g_object_unref (pixbuf);
+
+ um_photo_dialog_set_user (d->photo_dialog, user);
+
+ label = get_widget (d, "full-name-value-label");
+ gtk_label_set_text (GTK_LABEL (label), um_user_get_real_name (user));
+ gtk_widget_set_tooltip_text (label, um_user_get_user_name (user));
+
+ label = get_widget (d, "full-name-button-label");
+ gtk_label_set_text (GTK_LABEL (label), um_user_get_real_name (user));
+ widget = get_widget (d, "full-name-button");
+ gtk_widget_set_tooltip_text (label, um_user_get_user_name (user));
+ widget = get_widget (d, "full-name-entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), um_user_get_real_name (user));
+
+ label = get_widget (d, "account-type-value-label");
+ gtk_label_set_text (GTK_LABEL (label), um_account_type_get_name (um_user_get_account_type (user)));
+ label = get_widget (d, "account-type-button-label");
+ gtk_label_set_text (GTK_LABEL (label), um_account_type_get_name (um_user_get_account_type (user)));
+ combo = get_widget (d, "account-type-combo");
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ gint t;
+ gtk_tree_model_get (model, &iter, 1, &t, -1);
+ if (t == um_user_get_account_type (user)) {
+ gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+
+ if (um_user_get_locked (user)) {
+ text = C_("Password mode", "Account disabled");
+ }
+ else {
+ switch (um_user_get_password_mode (user)) {
+ case UM_PASSWORD_MODE_REGULAR:
+ text = "\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2\xe2\x80\xa2";
+ break;
+ case UM_PASSWORD_MODE_SET_AT_LOGIN:
+ text = C_("Password mode", "To be set at next login");
+ break;
+ case UM_PASSWORD_MODE_NONE:
+ text = C_("Password mode", "None");
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ }
+ label = get_widget (d, "account-password-value-label");
+ gtk_label_set_text (GTK_LABEL (label), text);
+ label = get_widget (d, "account-password-button-label");
+ gtk_label_set_text (GTK_LABEL (label), text);
+
+ text = um_user_get_email (user);
+ widget = get_widget (d, "account-email-value-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "account-email-button-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "account-email-entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), text);
+
+ widget = get_widget (d, "account-language-combo");
+ g_signal_handlers_block_by_func (widget, language_changed, d);
+ um_add_user_languages (widget);
+
+ text = um_user_get_language (user);
+ if (text) {
+ um_select_language (widget, text);
+ language = gdm_get_language_from_name (text, NULL);
+ }
+ else {
+ const gchar *locale;
+ locale = (const gchar *) setlocale (LC_MESSAGES, NULL);
+ if (locale) {
+ gchar *name;
+ name = gdm_normalize_language_name (locale);
+ um_select_language (widget, name);
+ language = gdm_get_language_from_name (name, NULL);
+ g_free (name);
+ } else {
+ language = g_strdup (nonempty (""));
+ }
+ }
+ label = get_widget (d, "account-language-value-label");
+ gtk_label_set_text (GTK_LABEL (label), language);
+ label = get_widget (d, "account-language-button-label");
+ gtk_label_set_text (GTK_LABEL (label), language);
+ g_free (language);
+ g_signal_handlers_unblock_by_func (widget, language_changed, d);
+
+ text = um_user_get_location (user);
+ label = get_widget (d, "account-location-value-label");
+ gtk_label_set_text (GTK_LABEL (label), nonempty (text));
+ label = get_widget (d, "account-location-button-label");
+ gtk_label_set_text (GTK_LABEL (label), nonempty (text));
+ label = get_widget (d, "account-location-entry");
+ gtk_entry_set_text (GTK_ENTRY (label), text);
+
+ widget = get_widget (d, "account-fingerprint-notebook");
+ label = get_widget (d, "account-fingerprint-label");
+ label2 = get_widget (d, "account-fingerprint-value-label");
+ label3 = get_widget (d, "account-fingerprint-button-label");
+ if (um_user_get_uid (user) != getuid() ||
+ !set_fingerprint_label (label2, label3)) {
+ gtk_widget_hide (label);
+ gtk_widget_hide (widget);
+ } else {
+ gtk_widget_show (label);
+ gtk_widget_show (widget);
+ }
+}
+
+static void lockbutton_changed (PolkitLockButton *button, gpointer data);
+
+static void
+selected_user_changed (GtkTreeSelection *selection, UmUserPanelPrivate *d)
+{
+ GtkWidget *widget;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ UmUser *user;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get (model, &iter, USER_COL, &user, -1);
+ show_user (user, d);
+
+ lockbutton_changed (POLKIT_LOCK_BUTTON (d->lock_button), d);
+
+ g_object_unref (user);
+ }
+}
+
+static void
+name_style_set (GtkWidget *widget, GtkStyle *previous_style, UmUserPanelPrivate *d)
+{
+ PangoFontDescription *desc;
+ gint size;
+
+ desc = pango_font_description_copy (widget->style->font_desc);
+ size = pango_font_description_get_size (desc);
+ pango_font_description_set_size (desc, 1.2 * size);
+ pango_font_description_set_weight (desc, PANGO_WEIGHT_BOLD);
+
+ g_signal_handlers_block_by_func (widget, name_style_set, d);
+ gtk_widget_modify_font (widget, desc);
+ g_signal_handlers_unblock_by_func (widget, name_style_set, d);
+
+ pango_font_description_free (desc);
+}
+
+static void
+change_name_start (GtkButton *button, UmUserPanelPrivate *d)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 2);
+}
+
+static void
+change_name_done (GtkWidget *entry,
+ UmUserPanelPrivate *d)
+{
+ const gchar *text;
+ UmUser *user;
+
+ user = get_selected_user (d);
+
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (g_strcmp0 (text, um_user_get_location (user)) != 0) {
+ um_user_set_real_name (user, text);
+ }
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 1);
+}
+
+static void
+change_name_canceled (UmUserPanelPrivate *d)
+{
+ UmUser *user;
+ const gchar *text;
+ GtkWidget *widget;
+
+ user = get_selected_user (d);
+ text = um_user_get_real_name (user);
+
+ widget = get_widget (d, "full-name-value-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "full-name-button-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "full-name-entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), text);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 1);
+}
+
+static void
+change_name_activate (GtkWidget *widget,
+ UmUserPanelPrivate *d)
+{
+ change_name_done (widget, d);
+}
+
+static gboolean
+change_name_focus_out (GtkWidget *widget,
+ GdkEventFocus *event,
+ UmUserPanelPrivate *d)
+{
+ change_name_done (widget, d);
+
+ return FALSE;
+}
+
+static gboolean
+change_name_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ UmUserPanelPrivate *d)
+{
+ if (event->keyval == GDK_Escape) {
+ change_name_canceled (d);
+ }
+
+ return FALSE;
+}
+
+static void
+change_account_type_authorized_cb (GObject *source,
+ GAsyncResult *res,
+ UmUserPanelPrivate *d)
+{
+ GError *error;
+ PolkitAuthorizationResult *result;
+ gboolean is_authorized;
+
+ error = NULL;
+ is_authorized = FALSE;
+ result = polkit_authority_check_authorization_finish (d->authority,
+ res,
+ &error);
+ if (error) {
+ g_warning ("polkit check failed: %s", error->message);
+ g_error_free (error);
+ }
+ else {
+ if (polkit_authorization_result_get_is_authorized (result)) {
+ is_authorized = TRUE;
+ }
+
+ g_object_unref (result);
+ }
+
+ if (is_authorized) {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook")), 2);
+ }
+}
+
+static void
+change_account_type_start (GtkButton *button,
+ UmUserPanelPrivate *d)
+{
+ PolkitSubject *subject;
+
+ subject = polkit_unix_process_new (getpid ());
+
+ polkit_authority_check_authorization (d->authority,
+ subject,
+ "org.freedesktop.accounts.user-administration",
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
+ NULL,
+ (GAsyncReadyCallback)change_account_type_authorized_cb,
+ d);
+
+ g_object_unref (subject);
+}
+
+static void
+account_type_changed (GtkComboBox *combo,
+ UmUserPanelPrivate *d)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint t;
+ UmUser *user;
+
+ user = get_selected_user (d);
+ model = gtk_combo_box_get_model (combo);
+ gtk_combo_box_get_active_iter (combo, &iter);
+ gtk_tree_model_get (model, &iter, 1, &t, -1);
+
+ if (t != um_user_get_account_type (user)) {
+ um_user_set_account_type (user, t);
+ }
+}
+
+static void
+language_response (GtkDialog *dialog,
+ gint response_id,
+ UmUserPanelPrivate *d)
+{
+ GtkWidget *widget;
+ UmUser *user;
+ gchar *lang;
+ const gchar *text;
+ gchar *language;
+
+ user = get_selected_user (d);
+ widget = get_widget (d, "account-language-combo");
+ if (response_id == GTK_RESPONSE_OK) {
+ lang = um_language_chooser_get_language (GTK_WIDGET (dialog));
+ um_user_set_language (user, lang);
+ um_select_language (widget, lang);
+ language = g_strdup (nonempty (lang));
+ g_free (lang);
+ }
+ else {
+ text = um_user_get_language (user);
+ if (text) {
+ um_select_language (widget, text);
+ language = gdm_get_language_from_name (text, NULL);
+ }
+ else {
+ const gchar *locale;
+ locale = (const gchar *) setlocale (LC_MESSAGES, NULL);
+ if (locale) {
+ char *name;
+ name = gdm_normalize_language_name (locale);
+ um_select_language (widget, name);
+ language = gdm_get_language_from_name (name, NULL);
+ g_free (name);
+ } else {
+ language = g_strdup (nonempty (""));
+ }
+ }
+ }
+
+ gtk_label_set_text (GTK_LABEL (get_widget (d, "account-language-value-label")), language);
+ gtk_label_set_text (GTK_LABEL (get_widget (d, "account-language-button-label")), language);
+ g_free (language);
+
+ gtk_widget_hide (GTK_WIDGET (dialog));
+ gtk_widget_set_sensitive (widget, TRUE);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-language-notebook")), 1);
+}
+
+static gboolean
+finish_language_chooser (UmUserPanelPrivate *d)
+{
+ GtkWidget *combo;
+
+ combo = get_widget (d, "account-language-combo");
+ d->language_chooser = um_language_chooser_new ();
+ gtk_window_set_transient_for (GTK_WINDOW (d->language_chooser),
+ GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)));
+ g_signal_connect (d->language_chooser, "response",
+ G_CALLBACK (language_response), d);
+ g_signal_connect (d->language_chooser, "delete-event",
+ G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+
+ gdk_window_set_cursor (gtk_widget_get_window (gtk_widget_get_toplevel (d->notebook)), NULL);
+ gtk_window_present (GTK_WINDOW (d->language_chooser));
+ gtk_widget_set_sensitive (GTK_WIDGET (combo), FALSE);
+
+ return FALSE;
+}
+
+static void
+language_changed (GtkComboBox *combo,
+ UmUserPanelPrivate *d)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *lang;
+ UmUser *user;
+ GdkCursor *cursor;
+
+ if (!gtk_combo_box_get_active_iter (combo, &iter))
+ return;
+
+ user = get_selected_user (d);
+ model = gtk_combo_box_get_model (combo);
+
+ gtk_tree_model_get (model, &iter, 0, &lang, -1);
+ if (lang) {
+ if (g_strcmp0 (lang, um_user_get_language (user)) != 0) {
+ um_user_set_language (user, lang);
+ }
+ g_free (lang);
+ return;
+ }
+
+ if (d->language_chooser) {
+ gtk_window_present (GTK_WINDOW (d->language_chooser));
+ gtk_widget_set_sensitive (GTK_WIDGET (combo), FALSE);
+ return;
+ }
+
+ cursor = gdk_cursor_new (GDK_WATCH);
+ gdk_window_set_cursor (gtk_widget_get_window (gtk_widget_get_toplevel (d->notebook)),
+ cursor);
+ gdk_cursor_unref (cursor);
+
+ g_idle_add ((GSourceFunc)finish_language_chooser, d);
+}
+
+static gboolean
+language_key_press (GtkWidget *combo,
+ GdkEventKey *event,
+ UmUserPanelPrivate *d)
+{
+ GtkWidget *nb;
+
+ if (event->keyval == GDK_Escape) {
+ nb = get_widget (d, "account-language-notebook");
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), 1);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+change_password (GtkButton *button, UmUserPanelPrivate *d)
+{
+ UmUser *user;
+
+ user = get_selected_user (d);
+
+ um_password_dialog_set_user (d->password_dialog, user);
+ um_password_dialog_show (d->password_dialog,
+ GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)));
+
+ g_object_unref (user);
+}
+
+static void
+change_email_start (GtkButton *button,
+ UmUserPanelPrivate *d)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 2);
+}
+
+static void
+change_email_done (GtkWidget *entry,
+ UmUserPanelPrivate *d)
+{
+ const gchar *text;
+ UmUser *user;
+
+ user = get_selected_user (d);
+
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (g_strcmp0 (text, um_user_get_email (user)) != 0) {
+ um_user_set_email (user, text);
+ }
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 1);
+}
+
+static void
+change_email_canceled (UmUserPanelPrivate *d)
+{
+ UmUser *user;
+ const gchar *text;
+ GtkWidget *widget;
+
+ user = get_selected_user (d);
+ text = um_user_get_email (user);
+
+ widget = get_widget (d, "account-email-value-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "account-email-button-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "account-email-entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), text);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 1);
+}
+
+static void
+change_email_activate (GtkWidget *widget,
+ UmUserPanelPrivate *d)
+{
+ change_email_done (widget, d);
+}
+
+static gboolean
+change_email_focus_out (GtkWidget *widget,
+ GdkEventFocus *event,
+ UmUserPanelPrivate *d)
+{
+ change_email_done (widget, d);
+
+ return FALSE;
+}
+
+static gboolean
+change_email_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ UmUserPanelPrivate *d)
+{
+ if (event->keyval == GDK_Escape) {
+ change_email_canceled (d);
+ }
+
+ return FALSE;
+}
+
+static void
+change_location_start (GtkButton *button,
+ UmUserPanelPrivate *d)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 2);
+}
+
+static void
+change_location_done (GtkWidget *entry,
+ UmUserPanelPrivate *d)
+{
+ const gchar *text;
+ UmUser *user;
+
+ user = get_selected_user (d);
+
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
+ if (g_strcmp0 (text, um_user_get_location (user)) != 0) {
+ um_user_set_location (user, text);
+ }
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 1);
+}
+
+static void
+change_location_canceled (UmUserPanelPrivate *d)
+{
+ UmUser *user;
+ const gchar *text;
+ GtkWidget *widget;
+
+ user = get_selected_user (d);
+ text = um_user_get_location (user);
+
+ widget = get_widget (d, "account-location-value-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "account-location-button-label");
+ gtk_label_set_text (GTK_LABEL (widget), nonempty (text));
+ widget = get_widget (d, "account-location-entry");
+ gtk_entry_set_text (GTK_ENTRY (widget), text);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 1);
+}
+
+static void
+change_location_activate (GtkWidget *widget,
+ UmUserPanelPrivate *d)
+{
+ change_location_done (widget, d);
+}
+
+static gboolean
+change_location_focus_out (GtkWidget *widget,
+ GdkEventFocus *event,
+ UmUserPanelPrivate *d)
+{
+ change_location_done (widget, d);
+
+ return FALSE;
+}
+
+static gboolean
+change_location_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ UmUserPanelPrivate *d)
+{
+ if (event->keyval == GDK_Escape) {
+ change_location_canceled (d);
+ }
+
+ return FALSE;
+}
+
+static void
+change_language_start (GtkButton *button,
+ UmUserPanelPrivate *d)
+{
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-language-notebook")), 2);
+}
+
+static void
+change_fingerprint (GtkButton *button, UmUserPanelPrivate *d)
+{
+ GtkWidget *label, *label2;
+ UmUser *user;
+
+ user = get_selected_user (d);
+ g_assert (g_strcmp0 (g_get_user_name (), um_user_get_user_name (user)) == 0);
+
+ label = get_widget (d, "account-fingerprint-value-label");
+ label2 = get_widget (d, "account-fingerprint-button-label");
+ fingerprint_button_clicked (GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)), label, label2, user);
+ g_object_unref (user);
+}
+
+static void
+toggle_login_options (GtkButton *button, UmUserPanelPrivate *d)
+{
+ GtkWidget *widget;
+ gboolean active;
+ GtkWidget *list;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ widget = get_widget (d, "top-level-notebook");
+ list = get_widget (d, "list-treeview");
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
+ if (active) {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 1);
+ gtk_tree_selection_unselect_all (selection);
+ }
+ else {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
+ if (!gtk_tree_selection_get_selected (selection, NULL, NULL)) {
+ gtk_tree_model_get_iter_first (model, &iter);
+ do {
+ gint sort_key;
+
+ gtk_tree_model_get (model, &iter, SORT_KEY_COL, &sort_key, -1);
+
+ if (sort_key == 1) {
+ /* select the current user */
+ gtk_tree_selection_select_iter (selection, &iter);
+ break;
+ }
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+ }
+}
+
+static gint
+sort_users (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer data)
+{
+ UmUser *ua, *ub;
+ gint sa, sb;
+ gint result;
+
+ gtk_tree_model_get (model, a, USER_COL, &ua, SORT_KEY_COL, &sa, -1);
+ gtk_tree_model_get (model, b, USER_COL, &ub, SORT_KEY_COL, &sb, -1);
+
+ if (sa < sb) {
+ result = -1;
+ }
+ else if (sa > sb) {
+ result = 1;
+ }
+ else {
+ result = um_user_collate (ua, ub);
+ }
+
+ if (ua) {
+ g_object_unref (ua);
+ }
+ if (ub) {
+ g_object_unref (ub);
+ }
+
+ return result;
+}
+
+static gboolean
+dont_select_headings (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean selected,
+ gpointer data)
+{
+ GtkTreeIter iter;
+ gboolean is_user;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, USER_ROW_COL, &is_user, -1);
+
+ return is_user;
+}
+
+static void
+users_loaded (UmUserManager *manager,
+ UmUserPanelPrivate *d)
+{
+ GSList *list, *l;
+ UmUser *user;
+ GtkWidget *dialog;
+
+ if (um_user_manager_no_service (d->um)) {
+ dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (d->notebook)),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_OTHER,
+ GTK_BUTTONS_CLOSE,
+ _("Failed to contact the accounts service"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("Please make sure that the AccountService is installed and enabled."));
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_show (dialog);
+ }
+
+ 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));
+ user_added (d->um, user, d);
+ }
+ g_slist_free (list);
+
+ g_signal_connect (d->um, "user-added", G_CALLBACK (user_added), d);
+ g_signal_connect (d->um, "user-removed", G_CALLBACK (user_removed), d);
+}
+
+static void
+lockbutton_changed (PolkitLockButton *button,
+ gpointer data)
+{
+ UmUserPanelPrivate *d = data;
+ gboolean is_authorized;
+ gboolean self_selected;
+ UmUser *user;
+ GtkWidget *widget;
+
+ user = get_selected_user (d);
+ if (!user) {
+ return;
+ }
+
+ is_authorized = polkit_lock_button_get_is_authorized (button);
+ self_selected = um_user_get_uid (user) == geteuid ();
+
+ widget = get_widget (d, "add-user-button");
+ gtk_widget_set_sensitive (widget, is_authorized);
+ if (is_authorized) {
+ setup_tooltip_with_embedded_icon (widget, _("Create a user"), NULL, NULL);
+ }
+ else {
+ setup_tooltip_with_embedded_icon (widget,
+ _("To create a user,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ }
+
+ widget = get_widget (d, "delete-user-button");
+ gtk_widget_set_sensitive (widget, is_authorized && !self_selected);
+ if (is_authorized) {
+ setup_tooltip_with_embedded_icon (widget, _("Delete the selected user"), NULL, NULL);
+ }
+ else {
+ setup_tooltip_with_embedded_icon (widget,
+ _("To delete the selected user,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ }
+
+ if (is_authorized) {
+ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook"))) == 0) {
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook")), 1);
+ }
+ }
+ else {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-type-notebook")), 0);
+ }
+
+ if (is_authorized || self_selected) {
+ gtk_widget_show (get_widget (d, "user-icon-button"));
+ gtk_widget_hide (get_widget (d, "user-icon-nonbutton"));
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-language-notebook")), 1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-password-notebook")), 1);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-fingerprint-notebook")), 1);
+ }
+ else {
+ gtk_widget_hide (get_widget (d, "user-icon-button"));
+ gtk_widget_show (get_widget (d, "user-icon-nonbutton"));
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "full-name-notebook")), 0);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-email-notebook")), 0);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-language-notebook")), 0);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-location-notebook")), 0);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-password-notebook")), 0);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (get_widget (d, "account-fingerprint-notebook")), 0);
+ }
+
+ um_password_dialog_set_privileged (d->password_dialog, is_authorized);
+}
+
+static void
+focus_moved (GtkWindow *window,
+ GtkWidget *widget,
+ UmUserPanelPrivate *d)
+{
+ GtkWidget *nb;
+
+ nb = get_widget (d, "account-type-notebook");
+
+ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)) == 2 &&
+ (!widget || !gtk_widget_is_ancestor (widget, nb))) {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), 1);
+ }
+
+ nb = get_widget (d, "account-language-notebook");
+
+ if (gtk_notebook_get_current_page (GTK_NOTEBOOK (nb)) == 2 &&
+ (!widget || !gtk_widget_is_ancestor (widget, nb))) {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), 1);
+ }
+}
+
+static gboolean
+match_user (GtkTreeModel *model,
+ gint column,
+ const gchar *key,
+ GtkTreeIter *iter,
+ gpointer search_data)
+{
+ UmUser *user;
+ const gchar *name;
+ gchar *normalized_key = NULL;
+ gchar *normalized_name = NULL;
+ gchar *case_normalized_key = NULL;
+ gchar *case_normalized_name = NULL;
+ gchar *p;
+ gboolean result = TRUE;
+ gint i;
+
+ gtk_tree_model_get (model, iter, USER_COL, &user, -1);
+
+ if (!user) {
+ goto out;
+ }
+
+ normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
+ if (!normalized_key) {
+ goto out;
+ }
+
+ case_normalized_key = g_utf8_casefold (normalized_key, -1);
+
+ for (i = 0; i < 2; i++) {
+ if (i == 0)
+ name = um_user_get_real_name (user);
+ else
+ name = um_user_get_user_name (user);
+
+ g_free (normalized_name);
+ normalized_name = g_utf8_normalize (name, -1, G_NORMALIZE_ALL);
+ if (normalized_name) {
+ g_free (case_normalized_name);
+ case_normalized_name = g_utf8_casefold (normalized_name, -1);
+ p = strstr (case_normalized_name, case_normalized_key);
+
+ /* poor man's \b */
+ if (p == case_normalized_name || (p && p[-1] == ' ')) {
+ result = FALSE;
+ break;
+ }
+ }
+ }
+
+ out:
+ if (user) {
+ g_object_unref (user);
+ }
+ g_free (normalized_key);
+ g_free (case_normalized_key);
+ g_free (normalized_name);
+ g_free (case_normalized_name);
+
+ return result;
+}
+
+static void
+setup_main_window (UmUserPanelPrivate *d)
+{
+ GtkWidget *window;
+ GtkWidget *userlist;
+ GtkTreeModel *model;
+ GtkListStore *store;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell;
+ GtkTreeSelection *selection;
+ GtkWidget *button;
+ GtkTreeIter iter;
+ gint expander_size;
+ GtkWidget *box;
+
+ window = get_widget (d, "user-account-window");
+ g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
+
+ userlist = get_widget (d, "list-treeview");
+ store = gtk_list_store_new (NUM_USER_LIST_COLS,
+ UM_TYPE_USER,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
+ G_TYPE_INT);
+ model = (GtkTreeModel *)store;
+ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (model), sort_users, NULL, NULL);
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (userlist), model);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (userlist), USER_COL);
+ gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (userlist),
+ match_user, NULL, NULL);
+
+ g_signal_connect (d->um, "users-loaded", G_CALLBACK (users_loaded), d);
+
+ gtk_widget_style_get (userlist, "expander-size", &expander_size, NULL);
+ gtk_tree_view_set_level_indentation (GTK_TREE_VIEW (userlist), - (expander_size + 6));
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ TITLE_COL, "<small><span foreground=\"#555555\">My Account</span></small>",
+ HEADING_ROW_COL, TRUE,
+ SORT_KEY_COL, 0,
+ -1);
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ TITLE_COL, "<small><span foreground=\"#555555\">Other Accounts</span></small>",
+ HEADING_ROW_COL, TRUE,
+ SORT_KEY_COL, 2,
+ -1);
+
+ column = gtk_tree_view_column_new ();
+ cell = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, FALSE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "pixbuf", FACE_COL);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "visible", USER_ROW_COL);
+ cell = gtk_cell_renderer_text_new ();
+ g_object_set (cell, "ellipsize", PANGO_ELLIPSIZE_END, "width-chars", 18, NULL);
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "markup", NAME_COL);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "visible", USER_ROW_COL);
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (column), cell, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "markup", TITLE_COL);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (column), cell, "visible", HEADING_ROW_COL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (userlist), column);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (userlist));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+ g_signal_connect (selection, "changed", G_CALLBACK (selected_user_changed), d);
+ gtk_tree_selection_set_select_function (selection, dont_select_headings, NULL, NULL);
+
+ button = get_widget (d, "add-user-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (add_user), d);
+
+ button = get_widget (d, "delete-user-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (delete_user), d);
+
+ button = get_widget (d, "user-icon-nonbutton");
+ setup_tooltip_with_embedded_icon (button,
+ _("To make changes,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "full-name-value-label");
+ setup_tooltip_with_embedded_icon (button,
+ _("To make changes,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "full-name-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (change_name_start), d);
+ button = get_widget (d, "full-name-entry");
+ g_signal_connect (button, "style-set", G_CALLBACK (name_style_set), d);
+ g_signal_connect (button, "activate", G_CALLBACK (change_name_activate), d);
+ g_signal_connect (button, "focus-out-event", G_CALLBACK (change_name_focus_out), d);
+ g_signal_connect (button, "key-press-event", G_CALLBACK (change_name_key_press), d);
+
+ button = get_widget (d, "account-type-value-label");
+ setup_tooltip_with_embedded_icon (button,
+ _("To change the account type,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "account-type-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (change_account_type_start), d);
+ button = get_widget (d, "account-type-combo");
+ g_signal_connect (button, "changed", G_CALLBACK (account_type_changed), d);
+
+ button = get_widget (d, "account-password-value-label");
+ setup_tooltip_with_embedded_icon (button,
+ _("To make changes,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "account-password-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (change_password), d);
+
+ button = get_widget (d, "account-email-value-label");
+ setup_tooltip_with_embedded_icon (button,
+ _("To make changes,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "account-email-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (change_email_start), d);
+ button = get_widget (d, "account-email-entry");
+ g_signal_connect (button, "activate", G_CALLBACK (change_email_activate), d);
+ g_signal_connect (button, "focus-out-event", G_CALLBACK (change_email_focus_out), d);
+ g_signal_connect (button, "key-press-event", G_CALLBACK (change_email_key_press), d);
+
+ button = get_widget (d, "account-language-value-label");
+ setup_tooltip_with_embedded_icon (button,
+ _("To make changes,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "account-language-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (change_language_start), d);
+ button = get_widget (d, "account-language-combo");
+ g_signal_connect (button, "changed", G_CALLBACK (language_changed), d);
+ g_signal_connect (button, "key-press-event", G_CALLBACK (language_key_press), d);
+
+ /* ugly hack to catch the combo boxes losing focus */
+ g_signal_connect (window, "set-focus", G_CALLBACK (focus_moved), d);
+
+ button = get_widget (d, "account-location-value-label");
+ setup_tooltip_with_embedded_icon (button,
+ _("To make changes,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ g_signal_connect (button, "button-release-event",
+ G_CALLBACK (show_tooltip_now), NULL);
+
+ button = get_widget (d, "account-location-button");
+ g_signal_connect (button, "clicked", G_CALLBACK (change_location_start), d);
+ button = get_widget (d, "account-location-entry");
+ g_signal_connect (button, "activate", G_CALLBACK (change_location_activate), d);
+ g_signal_connect (button, "focus-out-event", G_CALLBACK (change_location_focus_out), d);
+ g_signal_connect (button, "key-press-event", G_CALLBACK (change_location_key_press), d);
+
+ button = get_widget (d, "account-fingerprint-button");
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (change_fingerprint), d);
+
+ button = polkit_lock_button_new ("org.freedesktop.accounts.user-administration");
+ gtk_widget_show (button);
+ box = get_widget (d, "userlist-vbox");
+ gtk_box_pack_end (GTK_BOX (box), button, FALSE, FALSE, 0);
+ g_signal_connect (button, "changed",
+ G_CALLBACK (lockbutton_changed), d);
+ lockbutton_changed (POLKIT_LOCK_BUTTON (button), d);
+ d->lock_button = button;
+
+ button = get_widget (d, "add-user-button");
+ setup_tooltip_with_embedded_icon (button,
+ _("To create a user,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+ button = get_widget (d, "delete-user-button");
+ setup_tooltip_with_embedded_icon (button,
+ _("To delete the selected user,\nclick the * icon first"),
+ "*",
+ "stock_lock");
+}
+
+static void
+um_user_panel_init (UmUserPanel *self)
+{
+ UmUserPanelPrivate *d;
+ GError *error;
+ volatile GType type;
+ const gchar *filename;
+ GtkWidget *button;
+
+ dbus_g_object_register_marshaller (fprintd_marshal_VOID__STRING_BOOLEAN,
+ G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID);
+
+ d = self->priv = UM_USER_PANEL_PRIVATE (self);
+
+ /* register types that the builder might need */
+ type = um_strength_bar_get_type ();
+
+ d->builder = gtk_builder_new ();
+ d->um = um_user_manager_ref_default ();
+
+ filename = UIDIR "/user-accounts-dialog.ui";
+ if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+ filename = "../data/user-accounts-dialog.ui";
+ error = NULL;
+ if (!gtk_builder_add_from_file (d->builder, filename, &error)) {
+ g_error ("%s", error->message);
+ g_error_free (error);
+ exit (1);
+ }
+
+ d->authority = polkit_authority_get ();
+
+ setup_main_window (d);
+ d->login_options = um_login_options_new (d->builder);
+ d->account_dialog = um_account_dialog_new ();
+ d->password_dialog = um_password_dialog_new ();
+ button = get_widget (d, "user-icon-button");
+ d->notebook = get_widget (d, "top-level-notebook");
+ d->photo_dialog = um_photo_dialog_new (button);
+ gtk_widget_reparent (d->notebook, GTK_WIDGET (self));
+}
+
+static void
+um_user_panel_dispose (GObject *object)
+{
+ UmUserPanelPrivate *priv = UM_USER_PANEL (object)->priv;
+
+ if (priv->um)
+ {
+ g_object_unref (priv->um);
+ priv->um = NULL;
+ }
+
+ if (priv->builder)
+ {
+ g_object_unref (priv->builder);
+ priv->builder = NULL;
+ }
+
+ if (priv->account_dialog)
+ {
+ um_account_dialog_free (priv->account_dialog);
+ priv->account_dialog = NULL;
+ }
+
+ if (priv->password_dialog)
+ {
+ um_password_dialog_free (priv->password_dialog);
+ priv->password_dialog = NULL;
+ }
+
+ if (priv->photo_dialog)
+ {
+ um_photo_dialog_free (priv->photo_dialog);
+ priv->photo_dialog = NULL;
+ }
+
+ if (priv->login_options)
+ {
+ um_login_options_free (priv->login_options);
+ priv->login_options = NULL;
+ }
+
+ if (priv->authority)
+ {
+ g_object_unref (priv->authority);
+ priv->authority = NULL;
+ }
+
+ G_OBJECT_CLASS (um_user_panel_parent_class)->dispose (object);
+}
+
+static void
+um_user_panel_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (um_user_panel_parent_class)->finalize (object);
+}
+
+static void
+um_user_panel_class_init (UmUserPanelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (UmUserPanelPrivate));
+
+ object_class->dispose = um_user_panel_dispose;
+ object_class->finalize = um_user_panel_finalize;
+}
+
+static void
+um_user_panel_class_finalize (UmUserPanelClass *klass)
+{
+}
+
+void
+um_user_panel_register (GIOModule *module)
+{
+ um_user_panel_register_type (G_TYPE_MODULE (module));
+ g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
+ UM_TYPE_USER_PANEL,
+ "users", 0);
+}
diff --git a/src/um-user-panel.h b/src/um-user-panel.h
new file mode 100644
index 0000000..4f5aec0
--- /dev/null
+++ b/src/um-user-panel.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2009-2010 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Written by: Matthias Clasen <mclasen redhat com>
+ */
+
+#ifndef _UM_USER_PANEL_H
+#define _UM_USER_PANEL_H
+
+#include <libgnome-control-center/cc-panel.h>
+
+G_BEGIN_DECLS
+
+#define UM_TYPE_USER_PANEL um_user_panel_get_type()
+
+#define UM_USER_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UM_TYPE_USER_PANEL, UmUserPanel))
+#define UM_USER_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UM_TYPE_USER_PANEL, UmUserPanelClass))
+#define UM_IS_USER_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UM_TYPE_USER_PANEL))
+#define UM_IS_USER_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UM_TYPE_USER_PANEL))
+#define UM_USER_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UM_TYPE_USER_PANEL, UmUserPanelClass))
+
+typedef struct _UmUserPanel UmUserPanel;
+typedef struct _UmUserPanelClass UmUserPanelClass;
+typedef struct _UmUserPanelPrivate UmUserPanelPrivate;
+
+struct _UmUserPanel
+{
+ CcPanel parent;
+
+ UmUserPanelPrivate *priv;
+};
+
+struct _UmUserPanelClass
+{
+ CcPanelClass parent_class;
+};
+
+GType um_user_panel_get_type (void) G_GNUC_CONST;
+
+void um_user_panel_register (GIOModule *module);
+
+G_END_DECLS
+
+#endif /* _UM_USER_PANEL_H */
diff --git a/src/user-panel.desktop.in b/src/user-panel.desktop.in
new file mode 100644
index 0000000..f2ece0d
--- /dev/null
+++ b/src/user-panel.desktop.in
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Users
+Comment=Add or remove users
+Categories=System;Settings;
+Icon=system-users
+Exec=gnome-control-center users
+Type=Application
+Terminal=false
+X-GNOME-Settings-Panel=users
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]