[gnome-system-tools/users-ui-redesign] Implement user profiles dialog and label



commit 0ef8d13237275e6b1449ccc393220bf8250bf105
Author: Milan Bouchet-Valat <nalimilan club fr>
Date:   Tue Nov 17 13:27:41 2009 +0100

    Implement user profiles dialog and label
    
    We now dynamically create radio buttons for every profile instead of using a combo box, and preselect the current one. A "Custom" button is enabled when the user does not fit any profile, which will have no effect if selected. If a different profile is chosen, the user will be added to the profile groups, removed from other profiles groups, and changed shell. Other settings won't be changed to avoid breaking the account. Remove obsolete code handling profiles combo box: table_set_default_profile() and on_user_settings_profile_changed().

 interfaces/users.ui       |   43 +++++++++++++++++++---------
 src/users/callbacks.c     |   19 ------------
 src/users/table.c         |   68 +++++++++++++++++++++++++++-----------------
 src/users/user-settings.c |   58 +++++++++++++++++++++++++++++++++++++-
 src/users/user-settings.h |    3 ++
 5 files changed, 130 insertions(+), 61 deletions(-)
---
diff --git a/interfaces/users.ui b/interfaces/users.ui
index b8636fc..3ae6d21 100644
--- a/interfaces/users.ui
+++ b/interfaces/users.ui
@@ -277,6 +277,7 @@
                   <object class="GtkLabel" id="user_settings_profile">
                     <property name="visible">True</property>
                     <property name="label">Desktop user</property>
+                    <property name="width_chars">30</property>
                     <attributes>
                       <attribute name="weight" value="bold"/>
                     </attributes>
@@ -2667,10 +2668,10 @@
         <property name="orientation">vertical</property>
         <property name="spacing">24</property>
         <child>
-          <object class="GtkTable" id="table47">
+          <object class="GtkTable" id="user_profile_table">
             <property name="visible">True</property>
-            <property name="n_rows">2</property>
-            <property name="n_columns">2</property>
+            <property name="n_rows">3</property>
+            <property name="n_columns">3</property>
             <property name="column_spacing">12</property>
             <property name="row_spacing">12</property>
             <child>
@@ -2681,6 +2682,7 @@
                 <property name="icon_name">stock_person</property>
               </object>
               <packing>
+                <property name="right_attach">2</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options">GTK_FILL</property>
                 <property name="y_padding">12</property>
@@ -2720,36 +2722,49 @@
                 </child>
               </object>
               <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="left_attach">2</property>
+                <property name="right_attach">3</property>
                 <property name="x_options">GTK_FILL</property>
                 <property name="y_options"></property>
               </packing>
             </child>
             <child>
-              <object class="GtkComboBox" id="user_settings_profile_menu">
+              <object class="GtkRadioButton" id="user_profile_custom">
+                <property name="label" translatable="yes">_Custom</property>
                 <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
+                <property name="active">True</property>
+                <property name="draw_indicator">True</property>
               </object>
               <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
+                <property name="right_attach">3</property>
                 <property name="top_attach">1</property>
                 <property name="bottom_attach">2</property>
-                <property name="y_options"></property>
+                <property name="y_options">GTK_FILL</property>
               </packing>
             </child>
             <child>
               <object class="GtkLabel" id="label2">
                 <property name="visible">True</property>
-                <property name="label" translatable="yes">Account _type:</property>
-                <property name="use_underline">True</property>
-                <property name="mnemonic_widget">user_settings_profile_menu</property>
+                <property name="label" translatable="yes">This account is using special settings that have been defined manually. Use the Advanced dialog to tune them.</property>
+                <property name="justify">fill</property>
+                <property name="wrap">True</property>
+                <attributes>
+                  <attribute name="size" value="9500"/>
+                </attributes>
               </object>
               <packing>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
+                <property name="left_attach">1</property>
+                <property name="right_attach">3</property>
+                <property name="top_attach">2</property>
+                <property name="bottom_attach">3</property>
               </packing>
             </child>
+            <child>
+              <placeholder/>
+            </child>
           </object>
           <packing>
             <property name="position">1</property>
diff --git a/src/users/callbacks.c b/src/users/callbacks.c
index bd4eb8a..db88143 100644
--- a/src/users/callbacks.c
+++ b/src/users/callbacks.c
@@ -555,25 +555,6 @@ on_user_settings_login_changed (GtkEditable *editable,
 }
 
 void
-on_user_settings_profile_changed (GtkWidget *widget, gpointer data)
-{
-	GtkTreeModel *model;
-	GtkTreeIter iter;
-	gchar *profile_name;
-	GstUserProfile *profile;
-
-	model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget));
-
-	if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter))
-		return;
-
-	gtk_tree_model_get (model, &iter, 0, &profile_name, -1);
-	profile = gst_user_profiles_set_current (GST_USERS_TOOL (tool)->profiles, profile_name);
-
-	g_free (profile_name);
-}
-
-void
 on_groups_dialog_show_help (GtkWidget *widget, gpointer data)
 {
 	GstDialog *dialog = GST_DIALOG (data);
diff --git a/src/users/table.c b/src/users/table.c
index 4780611..99bff20 100644
--- a/src/users/table.c
+++ b/src/users/table.c
@@ -118,37 +118,54 @@ setup_shells_combo (GstUsersTool *tool)
 	gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (combo), 0);
 }
 
-static void
-setup_profiles_combo (void)
-{
-	GtkWidget *combo = gst_dialog_get_widget (tool->main_dialog, "user_settings_profile_menu");
-	GtkTreeModel *model;
-	GtkCellRenderer *cell;
-
-	cell = gtk_cell_renderer_text_new();
-	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo), cell, TRUE);
-	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT (combo), cell, "text", 0, NULL);
-
-	model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
-	gtk_combo_box_set_model (GTK_COMBO_BOX (combo), model);
-	g_object_unref (model);
-}
-
 void
 table_populate_profiles (GstUsersTool *tool,
 			 GList        *names)
 {
-	GtkWidget *combo;
-	GtkTreeModel *model;
-	GtkTreeIter iter;
+	GtkWidget *table;
+	GtkWidget *radio;
+	GHashTable *radios;
+	GHashTableIter iter;
+	gpointer value;
+	static int ncols, nrows; /* original size of the table */
+	int i;
+
+	table = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "user_profile_table");
+	radios = g_object_get_data (G_OBJECT (table), "radio_buttons");
+
+	/* create the hash table to hold references to radio buttons */
+	if (radios == NULL) {
+		/* keys are names owned by GstUserProfiles, values are pointers:
+		 * no need to free anything */
+		radios = g_hash_table_new (g_str_hash, g_str_equal);
+		g_object_set_data (G_OBJECT (table), "radio_buttons", radios);
+		g_object_get (G_OBJECT (table), "n-rows", &nrows, "n-columns", &ncols, NULL);
+	}
+	else {
+		/* free the radio buttons if they were already here */
+		g_hash_table_iter_init (&iter, radios);
+		while (g_hash_table_iter_next (&iter, NULL, &value)) {
+			gtk_widget_destroy (GTK_WIDGET (value));
+		}
+
+		g_hash_table_remove_all (radios);
+	}
 
-	combo = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "user_settings_profile_menu");
-	model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
-	gtk_list_store_clear (GTK_LIST_STORE (model));
+	/* increase table's size based on it's "empty" size */
+	gtk_table_resize (GTK_TABLE (table), g_list_length (names) + nrows, ncols);
 
-	while (names) {
-		gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-		gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, names->data, -1);
+	radio = gst_dialog_get_widget (GST_TOOL (tool)->main_dialog, "user_profile_custom");
+
+	for (i = 0; names; i++) {
+		radio = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio),
+		                                                     (char *) names->data);
+
+		gtk_table_attach_defaults (GTK_TABLE (table),
+		                           radio, 0, ncols,
+		                           nrows + i, nrows + i + 1);
+		gtk_widget_show (radio);
+
+		g_hash_table_replace (radios, (char *) names->data, radio);
 		names = names->next;
 	}
 }
@@ -162,7 +179,6 @@ create_tables (GstUsersTool *tool)
 	create_group_members_table ();
 
 	/* not strictly tables, but uses a model */
-	setup_profiles_combo ();
 	setup_groups_combo ();
 	setup_shells_combo (tool);
 }
diff --git a/src/users/user-settings.c b/src/users/user-settings.c
index 6998fd9..bbd51b6 100644
--- a/src/users/user-settings.c
+++ b/src/users/user-settings.c
@@ -423,11 +423,12 @@ user_settings_set (OobsUser *user)
 {
 	OobsUsersConfig *config;
 	OobsGroup *no_passwd_login_group;
-	GtkWidget *dialog, *widget, *notice;
+	GtkWidget *dialog, *widget, *widget2, *notice;
 	const gchar *login = NULL;
 	gchar *title;
 	gint uid;
 	GdkPixbuf *face;
+	GstUserProfile *profile;
 
 	notice = gst_dialog_get_widget (tool->main_dialog, "user_settings_uid_disabled");
 
@@ -499,6 +500,19 @@ user_settings_set (OobsUser *user)
 	widget = gst_dialog_get_widget (tool->main_dialog, "user_settings_passwd2");
 	set_entry_text (widget, NULL);
 
+	widget = gst_dialog_get_widget (tool->main_dialog, "user_settings_profile");
+	widget2 = gst_dialog_get_widget (tool->main_dialog, "edit_user_profile_button");
+	profile = gst_user_profiles_get_for_user (GST_USERS_TOOL (tool)->profiles,
+	                                          user, FALSE);
+	if (is_user_root (user)) {
+		gtk_widget_set_sensitive (widget2, FALSE);
+		gtk_label_set_text (GTK_LABEL (widget), _("Superuser"));
+	}
+	else {
+		gtk_widget_set_sensitive (widget2, TRUE);
+		gtk_label_set_text (GTK_LABEL (widget), profile ? profile->name : _("Custom"));
+	}
+
 	/* set always the first page */
 	widget = gst_dialog_get_widget (tool->main_dialog, "user_settings_notebook");
 	gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), 0);
@@ -988,19 +1002,59 @@ on_edit_user_profile (GtkButton *button, gpointer user_data)
 	GtkWidget *user_profile_entry;
 	GtkWidget *face_image;
 	GtkWidget *name_label;
+	GtkWidget *table;
+	GtkWidget *radio;
+	GtkWidget *custom_radio;
+	GHashTable *radios;
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
 	OobsUser *user;
+	GstUserProfile *profile;
+	gchar *name;
 
 	user_profile_dialog = gst_dialog_get_widget (tool->main_dialog, "user_profile_dialog");
 	face_image = gst_dialog_get_widget (tool->main_dialog, "user_profile_face");
 	name_label = gst_dialog_get_widget (tool->main_dialog, "user_profile_name");
+	table = gst_dialog_get_widget (tool->main_dialog, "user_profile_table");
+	custom_radio = gst_dialog_get_widget (tool->main_dialog, "user_profile_custom");
 
 	user = users_table_get_current ();
 
+	/* select the profile that matches the user settings, if any */
+	profile = gst_user_profiles_get_for_user (GST_USERS_TOOL (tool)->profiles,
+	                                          user, FALSE);
+	radios = (GHashTable *) g_object_get_data (G_OBJECT (table), "radio_buttons");
+
+	if (profile) {
+		radio = g_hash_table_lookup (radios, profile->name);
+		gtk_widget_set_sensitive (custom_radio, FALSE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+	}
+	else {
+		gtk_widget_set_sensitive (custom_radio, TRUE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (custom_radio), TRUE);
+	}
+
 	response = run_edit_dialog (GTK_DIALOG (user_profile_dialog),
 	                            GTK_IMAGE (face_image), GTK_LABEL (name_label));
 
+	/* If a profile is selected, apply it (the "custom" radio button does nothing).
+	 * For an existing user, this only means changing shell and privilege groups,
+	 * since other settings would break many things. */
+	g_hash_table_iter_init (&iter, radios);
+	while (g_hash_table_iter_next (&iter, &key, &value))
+		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (value))) {
+			profile = gst_user_profiles_get_from_name (GST_USERS_TOOL (tool)->profiles,
+			                                           (char *) key);
+			gst_user_profiles_apply (GST_USERS_TOOL (tool)->profiles,
+			                         profile, user, FALSE);
+			break;
+		}
+
 	if (response == GTK_RESPONSE_OK) {
-		gst_tool_commit (tool, GST_USERS_TOOL (tool)->users_config);
+		if (gst_tool_commit (tool, GST_USERS_TOOL (tool)->users_config) == OOBS_RESULT_OK)
+			gst_tool_commit (tool, GST_USERS_TOOL (tool)->groups_config);
 	}
 
 	g_object_unref (user);
diff --git a/src/users/user-settings.h b/src/users/user-settings.h
index 7586d09..028ef2c 100644
--- a/src/users/user-settings.h
+++ b/src/users/user-settings.h
@@ -25,6 +25,9 @@
 #define __USER_SETTINGS_H
 
 #include <gtk/gtk.h>
+#include "gst-tool.h"
+#include "users-tool.h"
+#include "user-profiles.h"
 
 #define NO_PASSWD_LOGIN_GROUP "nopasswdlogin"
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]