summaryrefslogtreecommitdiff
path: root/source3/utils/regedit_dialog.c
diff options
context:
space:
mode:
authorC. Davis <cd.rattan@gmail.com>2012-08-06 19:11:13 -0700
committerMichael Adam <obnox@samba.org>2013-04-29 13:06:03 +0200
commitdb5295a7dc61056092b43523409fd11b147e031d (patch)
tree5f294dd3e87ef3f3b64579210cca989f24807753 /source3/utils/regedit_dialog.c
parent3c14ab13b19fd11f728d61b7f467b09c4e06fc02 (diff)
downloadsamba-db5295a7dc61056092b43523409fd11b147e031d.tar.gz
samba-db5295a7dc61056092b43523409fd11b147e031d.tar.bz2
samba-db5295a7dc61056092b43523409fd11b147e031d.zip
regedit: Some work on dialogs.
* Make dialogs modal with a separate getch() loop to avoid extra complexity keeping track of dialogs and getting the result. * Start work on the value editor dialog. Reviewed-by: Andreas Schneider <asn@samba.org> Reviewed-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3/utils/regedit_dialog.c')
-rw-r--r--source3/utils/regedit_dialog.c229
1 files changed, 212 insertions, 17 deletions
diff --git a/source3/utils/regedit_dialog.c b/source3/utils/regedit_dialog.c
index b5e41ee901..7c4a0bb918 100644
--- a/source3/utils/regedit_dialog.c
+++ b/source3/utils/regedit_dialog.c
@@ -19,7 +19,11 @@
#include "includes.h"
#include "regedit_dialog.h"
+#include "regedit_valuelist.h"
+#include "util_reg.h"
+#include "lib/registry/registry.h"
#include <stdarg.h>
+#include <form.h>
static int dialog_free(struct dialog *dia)
{
@@ -226,30 +230,221 @@ struct dialog *dialog_confirm_new(TALLOC_CTX *ctx, const char *title,
return dia;
}
-void dialog_set_cb(struct dialog *dia, dialogfn fn, void *arg)
+static int handle_menu_input(MENU *menu, int c)
{
- dia->dialogcb = fn;
- dia->dialogarg = arg;
+ ITEM *item;
+
+ switch (c) {
+ case KEY_LEFT:
+ menu_driver(menu, REQ_LEFT_ITEM);
+ break;
+ case KEY_RIGHT:
+ menu_driver(menu, REQ_RIGHT_ITEM);
+ break;
+ case KEY_ENTER:
+ case '\n':
+ item = current_item(menu);
+ return (int)(uintptr_t)item_userptr(item);
+ }
+
+ return -1;
+}
+
+int dialog_modal_loop(struct dialog *dia)
+{
+ int c;
+ int selection = -1;
+
+ keypad(dia->window, true);
+ update_panels();
+ doupdate();
+
+ while (selection == -1) {
+ c = wgetch(dia->window);
+ selection = handle_menu_input(dia->choices, c);
+ update_panels();
+ doupdate();
+ }
+
+ talloc_free(dia);
+
+ return selection;
}
-void dialog_driver(struct dialog *dia, enum dialog_op op)
+static void handle_form_input(FORM *frm, int c)
{
- switch (op) {
- case DIALOG_LEFT:
- menu_driver(dia->choices, REQ_LEFT_ITEM);
+ switch (c) {
+ case '\n':
+ form_driver(frm, REQ_NEW_LINE);
+ break;
+ case KEY_UP:
+ form_driver(frm, REQ_UP_CHAR);
+ break;
+ case KEY_DOWN:
+ form_driver(frm, REQ_DOWN_CHAR);
+ break;
+ case '\b':
+ case KEY_BACKSPACE:
+ form_driver(frm, REQ_DEL_PREV);
+ break;
+ case KEY_LEFT:
+ form_driver(frm, REQ_LEFT_CHAR);
break;
- case DIALOG_RIGHT:
- menu_driver(dia->choices, REQ_RIGHT_ITEM);
+ case KEY_RIGHT:
+ form_driver(frm, REQ_RIGHT_CHAR);
break;
- case DIALOG_ENTER:
- if (dia->dialogcb) {
- ITEM *item;
- int selection;
-
- item = current_item(dia->choices);
- selection = (int)(uintptr_t)item_userptr(item);
- dia->dialogcb(dia, selection, dia->dialogarg);
+ default:
+ form_driver(frm, c);
+ break;
+ }
+}
+
+#define MAX_FIELDS 8
+
+enum input_section {
+ IN_NAME,
+ IN_DATA,
+ IN_MENU
+};
+
+static void fill_value_buffer(TALLOC_CTX *ctx, FIELD *fld, const struct value_item *vitem)
+{
+ char *tmp;
+
+ switch (vitem->type) {
+ case REG_DWORD: {
+ uint32_t v = 0;
+ if (vitem->data.length >= 4) {
+ v = IVAL(vitem->data.data, 0);
}
+ tmp = talloc_asprintf(ctx, "0x%x", v);
+ set_field_buffer(fld, 0, tmp);
+ talloc_free(tmp);
break;
}
+ case REG_SZ:
+ case REG_EXPAND_SZ: {
+ const char *s;
+
+ if (!pull_reg_sz(ctx, &vitem->data, &s)) {
+ break;
+ }
+ set_field_buffer(fld, 0, s);
+ break;
+ }
+
+ }
+}
+
+static void set_value(TALLOC_CTX *ctx, FIELD *fld, struct registry_key *key,
+ const struct value_item *vitem)
+{
+}
+
+int dialog_edit_value(TALLOC_CTX *ctx, struct registry_key *key,
+ const struct value_item *vitem, WINDOW *below)
+{
+ struct dialog *dia;
+ const char *choices[] = {
+ "Ok",
+ "Cancel",
+ NULL
+ };
+ char *title;
+ int nlines, ncols;
+ int rv = -1;
+ WINDOW *input_win;
+ FORM *input;
+ FIELD *field[MAX_FIELDS];
+ enum input_section section;
+
+ title = talloc_asprintf(ctx, "Edit %s value", str_regtype(vitem->type));
+ if (title == NULL) {
+ return -1;
+ }
+
+ nlines = 15;
+ ncols = 50;
+ dia = dialog_choice_center_new(ctx, title, choices, nlines, ncols, below);
+ if (dia == NULL) {
+ goto finish;
+ }
+
+ memset(field, '\0', sizeof(*field) * MAX_FIELDS);
+ field[0] = new_field(1, ncols - 4, 1, 1, 0, 0);
+ field[1] = new_field(1, ncols - 4, 4, 1, 0, 0);
+
+ set_field_back(field[0], A_UNDERLINE);
+ set_field_back(field[1], A_UNDERLINE);
+ field_opts_off(field[0], O_BLANK | O_AUTOSKIP | O_STATIC);
+ field_opts_off(field[1], O_BLANK | O_AUTOSKIP | O_STATIC);
+
+ if (vitem) {
+ set_field_buffer(field[0], 0, vitem->value_name);
+ field_opts_off(field[0], O_EDIT);
+ fill_value_buffer(dia, field[1], vitem);
+ }
+
+ input = new_form(field);
+ form_opts_off(input, O_NL_OVERLOAD | O_BS_OVERLOAD);
+
+ input_win = derwin(dia->sub_window, nlines - 3, ncols - 3, 0, 0);
+
+ set_form_win(input, dia->sub_window);
+ set_form_sub(input, input_win);
+ post_form(input);
+ mvwprintw(dia->sub_window, 0, 0, "Name");
+ mvwprintw(dia->sub_window, 3, 0, "Data");
+
+ keypad(dia->window, true);
+ update_panels();
+ doupdate();
+
+ section = IN_NAME;
+
+ while (1) {
+ int c = wgetch(dia->window);
+ if (c == '\t') {
+ switch (section) {
+ case IN_NAME:
+ section = IN_DATA;
+ set_current_field(input, field[1]);
+ break;
+ case IN_DATA:
+ section = IN_MENU;
+ menu_driver(dia->choices, REQ_FIRST_ITEM);
+ break;
+ case IN_MENU:
+ section = IN_NAME;
+ set_current_field(input, field[0]);
+ break;
+ }
+ continue;
+ }
+
+ if (section == IN_NAME || section == IN_DATA) {
+ handle_form_input(input, c);
+ } else {
+ rv = handle_menu_input(dia->choices, c);
+ if (rv != -1) {
+ goto finish;
+ }
+ }
+
+ update_panels();
+ doupdate();
+ }
+
+finish:
+ if (title) {
+ talloc_free(title);
+ }
+ if (dia) {
+ talloc_free(dia);
+ }
+ if (rv == DIALOG_OK) {
+ //set_value
+ }
+
+ return rv;
}