X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/6faa62390b8b3ce7827320be9fcd3af9b5552648..1bcd69c4cfd2f1080014b792a1dc15ed1883f1c5:/disobedience/users.c diff --git a/disobedience/users.c b/disobedience/users.c index 5509aa1..6835d27 100644 --- a/disobedience/users.c +++ b/disobedience/users.c @@ -27,6 +27,15 @@ static GtkWidget *users_window; static GtkListStore *users_list; static GtkTreeSelection *users_selection; +static GtkWidget *users_details_window; +static GtkWidget *users_details_name; +static GtkWidget *users_details_email; +static GtkWidget *users_details_password; +static GtkWidget *users_details_password2; +//static GtkWidget *users_details_rights; + +static const char *users_who, *users_email, *users_rights, *users_password; + static int usercmp(const void *a, const void *b) { return strcmp(*(char **)a, *(char **)b); } @@ -63,6 +72,186 @@ static char *users_getuser(void) { return 0; } +/** @brief Text should be visible */ +#define DETAIL_VISIBLE 1 + +/** @brief Text should be editable */ +#define DETAIL_EDITABLE 2 + +static GtkWidget *users_detail_generic(GtkWidget *table, + int *rowp, + const char *title, + GtkWidget *selector) { + const int row = (*rowp)++; + GtkWidget *const label = gtk_label_new(title); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0); + gtk_table_attach(GTK_TABLE(table), + label, + 0, 1, /* left/right_attach */ + row, row+1, /* top/bottom_attach */ + GTK_FILL, /* xoptions */ + 0, /* yoptions */ + 1, 1); /* x/ypadding */ + gtk_table_attach(GTK_TABLE(table), + selector, + 1, 2, /* left/right_attach */ + row, row + 1, /* top/bottom_attach */ + GTK_EXPAND|GTK_FILL, /* xoptions */ + GTK_FILL, /* yoptions */ + 1, 1); /* x/ypadding */ + return selector; +} + +/** @brief Add a row to the user details table + * @param table Containin table widget + * @param rowp Pointer to row number, incremented + * @param title Label for this row + * @param value Initial value or NULL + * @param flags Flags word + * @return The text entry widget + */ +static GtkWidget *users_add_detail(GtkWidget *table, + int *rowp, + const char *title, + const char *value, + unsigned flags) { + GtkWidget *entry = gtk_entry_new(); + + gtk_entry_set_visibility(GTK_ENTRY(entry), + !!(flags & DETAIL_VISIBLE)); + gtk_editable_set_editable(GTK_EDITABLE(entry), + !!(flags & DETAIL_EDITABLE)); + if(value) + gtk_entry_set_text(GTK_ENTRY(entry), value); + return users_detail_generic(table, rowp, title, entry); +} + +/** @brief Add a checkbox for a right + * @param table Containing table + * @param rowp Pointer to row number, incremented + * @param title Label for this row + * @param value Right bit (masked but not necessarily normalized) + * @return Checkbox widget + */ +static GtkWidget *users_add_right(GtkWidget *table, + int *rowp, + const char *title, + rights_type value) { + GtkWidget *check = gtk_check_button_new(); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), !!value); + return users_detail_generic(table, rowp, title, check); +} + +/** @brief Add a checkbox for a three-right group + * @param table Containing table + * @param rowp Pointer to row number, incremented + * @param title Label for this row + * @param bits Rights bits (not masked or normalized) + * @param mask Mask for this group (must be 7.2^n) + * @param checks Where to store triple of check widgets + * @return Checkbox widget + */ +static void users_add_right_group(GtkWidget *table, + int *rowp, + const char *title, + rights_type bits, + rights_type mask, + GtkWidget *checks[3]) { + GtkWidget *any = gtk_check_button_new_with_label("Any"); + GtkWidget *mine = gtk_check_button_new_with_label("Own"); + GtkWidget *random = gtk_check_button_new_with_label("Random"); + GtkWidget *hbox = gtk_hbox_new(FALSE, 2); + + /* Discard irrelevant bits */ + bits &= mask; + /* Shift down to bits 0-2; the mask is always 3 contiguous bits */ + bits /= (mask / 7); + /* If _ANY is set then the other two are implied; we'll take them out when we + * set. */ + if(bits & 1) + bits = 7; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(any), !!(bits & 1)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mine), !!(bits & 2)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(random), !!(bits & 4)); + gtk_box_pack_start(GTK_BOX(hbox), any, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), mine, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), random, FALSE, FALSE, 0); + if(checks) { + checks[0] = any; + checks[1] = mine; + checks[2] = random; + } + users_detail_generic(table, rowp, title, hbox); +} + +/** @brief Create the user details window + * @param title Window title + * @param name User name (users_edit()) or NULL (users_add()) + * @param email Email address + * @param rights User rights string + * @param password Password + * + * This is used both by users_add() and users_edit(). + * + * The window contains: + * - display or edit fields for the username + * - edit fields for the email address + * - two hidden edit fields for the password (they must match) + * - check boxes for the rights + */ +static void users_makedetails(const char *title, + const char *name, + const char *email, + const char *rights, + const char *password) { + GtkWidget *table; + int row = 0; + rights_type r = 0; + + /* Create the window */ + users_details_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_style(users_details_window, tool_style); + g_signal_connect(users_details_window, "destroy", + G_CALLBACK(gtk_widget_destroyed), &users_details_window); + gtk_window_set_title(GTK_WINDOW(users_details_window), title); + gtk_window_set_transient_for(GTK_WINDOW(users_details_window), + GTK_WINDOW(users_window)); + table = gtk_table_new(4, 2, FALSE/*!homogeneous*/); + + users_details_name = users_add_detail(table, &row, "Username", name, + (name ? 0 : DETAIL_EDITABLE) + |DETAIL_VISIBLE); + + users_details_email = users_add_detail(table, &row, "Email", email, + DETAIL_EDITABLE|DETAIL_VISIBLE); + + users_details_password = users_add_detail(table, &row, "Password", + password, + DETAIL_EDITABLE); + users_details_password2 = users_add_detail(table, &row, "Password", + password, + DETAIL_EDITABLE); + + parse_rights(rights, &r, 1); + users_add_right(table, &row, "Read operations", r & RIGHT_READ); + users_add_right(table, &row, "Play track", r & RIGHT_PLAY); + users_add_right_group(table, &row, "Move", r, RIGHT_MOVE__MASK, NULL); + users_add_right_group(table, &row, "Remove", r, RIGHT_REMOVE__MASK, NULL); + users_add_right_group(table, &row, "Scratch", r, RIGHT_SCRATCH__MASK, NULL); + users_add_right(table, &row, "Set volume", r & RIGHT_VOLUME); + users_add_right(table, &row, "Admin operations", r & RIGHT_ADMIN); + users_add_right(table, &row, "Rescan", r & RIGHT_RESCAN); + users_add_right(table, &row, "Register new users", r & RIGHT_REGISTER); + users_add_right(table, &row, "Modify own userinfo", r & RIGHT_USERINFO); + users_add_right(table, &row, "Modify track preferences", r & RIGHT_PREFS); + users_add_right(table, &row, "Modify global preferences", r & RIGHT_GLOBAL_PREFS); + users_add_right(table, &row, "Pause/resume tracks", r & RIGHT_PAUSE); + + gtk_container_add(GTK_CONTAINER(users_details_window), table); + gtk_widget_show_all(users_details_window); +} + static void users_add(GtkButton attribute((unused)) *button, gpointer attribute((unused)) userdata) { } @@ -119,9 +308,32 @@ static void users_delete(GtkButton attribute((unused)) *button, } } +static void users_got_email(void attribute((unused)) *v, const char *value) { + users_email = value; +} + +static void users_got_rights(void attribute((unused)) *v, const char *value) { + users_rights = value; +} + +static void users_got_password(void attribute((unused)) *v, const char *value) { + users_password = value; + users_makedetails("editing user details", + users_who, + users_email, + users_rights, + users_password); +} + static void users_edit(GtkButton attribute((unused)) *button, gpointer attribute((unused)) userdata) { - + if(!(users_who = users_getuser())) + return; + /* Schedule user lookups for all the properties we know about. This is all a + * bit ad-hoc but will do for now. */ + disorder_eclient_userinfo(client, users_got_email, users_who, "email", 0); + disorder_eclient_userinfo(client, users_got_rights, users_who, "rights", 0); + disorder_eclient_userinfo(client, users_got_password, users_who, "password", 0); } static const struct button users_buttons[] = {