summaryrefslogtreecommitdiff
path: root/source3/utils
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
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')
-rw-r--r--source3/utils/regedit.c89
-rw-r--r--source3/utils/regedit_dialog.c229
-rw-r--r--source3/utils/regedit_dialog.h20
3 files changed, 246 insertions, 92 deletions
diff --git a/source3/utils/regedit.c b/source3/utils/regedit.c
index 14215cb775..cf97668494 100644
--- a/source3/utils/regedit.c
+++ b/source3/utils/regedit.c
@@ -38,7 +38,6 @@ struct regedit {
struct value_list *vl;
struct tree_view *keys;
bool tree_input;
- struct dialog *dia;
};
/* load all available hives */
@@ -102,32 +101,6 @@ static void print_heading(WINDOW *win, bool selected, const char *str)
wrefresh(win);
}
-static void delete_key_callback(struct dialog *dia, int selection, void *arg)
-{
- struct regedit *regedit = arg;
-
- //mvwprintw(regedit->main_window, 1, 0, "Selection: %d", selection);
-
- if (selection == DIALOG_OK) {
- /* TODO */
- }
-
- talloc_free(regedit->dia);
- regedit->dia = NULL;
-}
-
-static void delete_value_callback(struct dialog *dia, int selection, void *arg)
-{
- struct regedit *regedit = arg;
-
- if (selection == DIALOG_OK) {
- /* TODO */
- }
-
- talloc_free(regedit->dia);
- regedit->dia = NULL;
-}
-
static void handle_tree_input(struct regedit *regedit, int c)
{
struct tree_node *node;
@@ -165,15 +138,21 @@ static void handle_tree_input(struct regedit *regedit, int c)
}
break;
case 'd':
- case 'D':
+ case 'D': {
+ struct dialog *dia;
+ int sel;
+
node = item_userptr(current_item(regedit->keys->menu));
- regedit->dia = dialog_confirm_new(regedit, "Delete Key",
- regedit->main_window,
- "Really delete key \"%s\"?",
- node->name);
- dialog_set_cb(regedit->dia, delete_key_callback, regedit);
+ dia = dialog_confirm_new(regedit, "Delete Key",
+ regedit->main_window,
+ "Really delete key \"%s\"?",
+ node->name);
+ sel = dialog_modal_loop(dia);
+ mvwprintw(regedit->main_window, 1, 0, "Sel: %d", sel);
+ /* TODO */
break;
}
+ }
tree_view_show(regedit->keys);
value_list_show(regedit->vl);
@@ -190,17 +169,28 @@ static void handle_value_input(struct regedit *regedit, int c)
case KEY_UP:
menu_driver(regedit->vl->menu, REQ_UP_ITEM);
break;
+ case '\n':
case KEY_ENTER:
+ vitem = item_userptr(current_item(regedit->vl->menu));
+ if (vitem) {
+ struct tree_node *node;
+ node = item_userptr(current_item(regedit->keys->menu));
+ dialog_edit_value(regedit, node->key, vitem, regedit->main_window);
+ }
break;
case 'd':
case 'D':
vitem = item_userptr(current_item(regedit->vl->menu));
if (vitem) {
- regedit->dia = dialog_confirm_new(regedit, "Delete Value",
- regedit->main_window,
- "Really delete value \"%s\"?",
- vitem->value_name);
- dialog_set_cb(regedit->dia, delete_value_callback, regedit);
+ struct dialog *dia;
+ int sel;
+
+ dia = dialog_confirm_new(regedit, "Delete Value",
+ regedit->main_window,
+ "Really delete value \"%s\"?",
+ vitem->value_name);
+ sel = dialog_modal_loop(dia);
+ mvwprintw(regedit->main_window, 1, 0, "Sel: %d", sel);
}
break;
}
@@ -208,22 +198,6 @@ static void handle_value_input(struct regedit *regedit, int c)
value_list_show(regedit->vl);
}
-static void handle_dialog_input(struct regedit *regedit, int c)
-{
- switch (c) {
- case KEY_LEFT:
- dialog_driver(regedit->dia, DIALOG_LEFT);
- break;
- case KEY_RIGHT:
- dialog_driver(regedit->dia, DIALOG_RIGHT);
- break;
- case '\n':
- case KEY_ENTER:
- dialog_driver(regedit->dia, DIALOG_ENTER);
- break;
- }
-}
-
static void handle_main_input(struct regedit *regedit, int c)
{
switch (c) {
@@ -296,12 +270,7 @@ static void display_test_window(TALLOC_CTX *mem_ctx,
update_panels();
doupdate();
while ((c = wgetch(regedit->main_window)) != 'q') {
- if (regedit->dia) {
- handle_dialog_input(regedit, c);
- } else {
- handle_main_input(regedit, c);
- }
-
+ handle_main_input(regedit, c);
update_panels();
doupdate();
}
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;
}
diff --git a/source3/utils/regedit_dialog.h b/source3/utils/regedit_dialog.h
index 461de43b82..de6c5bc982 100644
--- a/source3/utils/regedit_dialog.h
+++ b/source3/utils/regedit_dialog.h
@@ -24,10 +24,6 @@
#include <panel.h>
#include <menu.h>
-struct dialog;
-
-typedef void (*dialogfn)(struct dialog *, int, void *);
-
struct dialog {
WINDOW *window;
WINDOW *sub_window;
@@ -35,8 +31,6 @@ struct dialog {
PANEL *panel;
MENU *choices;
ITEM **choice_items;
- dialogfn dialogcb;
- void *dialogarg;
};
struct dialog *dialog_new(TALLOC_CTX *ctx, const char *title, int nlines,
@@ -56,19 +50,15 @@ struct dialog *dialog_choice_center_new(TALLOC_CTX *ctx, const char *title,
struct dialog *dialog_confirm_new(TALLOC_CTX *ctx, const char *title,
WINDOW *below, const char *msg, ...);
-void dialog_set_cb(struct dialog *dia, dialogfn fn, void *arg);
-
-enum dialog_op {
- DIALOG_LEFT,
- DIALOG_RIGHT,
- DIALOG_ENTER
-};
-
enum dialog_selection {
DIALOG_OK = 0,
DIALOG_CANCEL = 1
};
-void dialog_driver(struct dialog *dia, enum dialog_op op);
+int dialog_modal_loop(struct dialog *dia);
+
+struct registry_key;
+struct value_item;
+int dialog_edit_value(TALLOC_CTX *ctx, struct registry_key *key, const struct value_item *vitem, WINDOW *below);
#endif