regedit: grow hexedit buffer as the user types
authorChris Davis <cd.rattan@gmail.com>
Sat, 9 Aug 2014 20:39:59 +0000 (13:39 -0700)
committerMichael Adam <obnox@samba.org>
Wed, 1 Oct 2014 12:32:10 +0000 (14:32 +0200)
Signed-off-by: Chris Davis <cd.rattan@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
source3/utils/regedit_dialog.c
source3/utils/regedit_hexedit.c

index 6f0aedad5b1dbf8ace0c7fcbfe38d11a13deb77d..3dc18dd5ec798619f0ad28c315f3f57a4a0c2184 100644 (file)
@@ -1056,7 +1056,7 @@ struct dialog_section_hexedit {
        struct hexedit *buf;
 };
 
-#define HEXEDIT_MIN_SIZE 16
+#define HEXEDIT_MIN_SIZE 1
 static WERROR hexedit_create(struct dialog *dia,
                                struct dialog_section *section)
 {
index bdc425563898f24ea24ff11795f3a89589407ef9..8a7c8a16591f2a70e506d15ef09012daa8d31211 100644 (file)
@@ -223,17 +223,6 @@ static int offset_to_hex_col(size_t pos)
        return -1;
 }
 
-static bool scroll_down(struct hexedit *buf)
-{
-       if (buf->offset + bytes_per_screen(buf->win) >= buf->len) {
-               return false;
-       }
-
-       buf->offset += BYTES_PER_LINE;
-
-       return true;
-}
-
 static bool scroll_up(struct hexedit *buf)
 {
        if (buf->offset == 0) {
@@ -247,17 +236,34 @@ static bool scroll_up(struct hexedit *buf)
 
 static void cursor_down(struct hexedit *buf)
 {
+       size_t space;
+       bool need_refresh = false;
+
+       space = buf->offset + (buf->cursor_y + 1) * BYTES_PER_LINE;
+       if (space > buf->len) {
+               return;
+       }
+
        if (buf->cursor_y + 1 == max_rows(buf->win)) {
-               if (scroll_down(buf)) {
-                       hexedit_refresh(buf);
-               }
+               buf->offset += BYTES_PER_LINE;
+               need_refresh = true;
        } else {
-               if (buf->cursor_offset + BYTES_PER_LINE >= buf->len) {
-                       return;
-               }
                buf->cursor_y++;
        }
 
+       if (buf->cursor_offset + BYTES_PER_LINE > buf->len) {
+               buf->nibble = 0;
+               buf->cursor_offset = buf->len;
+               buf->cursor_line_offset = buf->len - space;
+               if (buf->cursor_x >= ASCII_COL) {
+                       buf->cursor_x = ASCII_COL + buf->cursor_line_offset;
+               } else {
+                       buf->cursor_x = offset_to_hex_col(buf->cursor_line_offset);
+               }
+       }
+       if (need_refresh) {
+               hexedit_refresh(buf);
+       }
        calc_cursor_offset(buf);
 }
 
@@ -308,7 +314,7 @@ static void cursor_left(struct hexedit *buf)
        } else if (buf->cursor_x == ASCII_COL) {
                size_t off = buf->offset + buf->cursor_y * BYTES_PER_LINE;
                if (off + 7 >= buf->len) {
-                       size_t lastpos = buf->len - off - 1;
+                       size_t lastpos = buf->len - off;
                        buf->cursor_x = offset_to_hex_col(lastpos) + 1;
                        buf->cursor_line_offset = lastpos;
                } else {
@@ -342,7 +348,7 @@ static void cursor_right(struct hexedit *buf)
                return;
        }
        if ((buf->cursor_x >= ASCII_COL || buf->nibble == 1) &&
-           buf->cursor_offset + 1 == buf->len) {
+           buf->cursor_offset == buf->len) {
                if (buf->cursor_x < ASCII_COL) {
                        new_x = ASCII_COL;
                        buf->cursor_line_offset = 0;
@@ -383,6 +389,10 @@ static void do_edit(struct hexedit *buf, int c)
                return;
        }
 
+       if (buf->cursor_offset == buf->len) {
+               hexedit_resize_buffer(buf, buf->len + 1);
+       }
+
        byte = buf->data + buf->cursor_offset;
 
        if (buf->cursor_x >= ASCII_COL) {
@@ -395,7 +405,11 @@ static void do_edit(struct hexedit *buf, int c)
                }
                mvwaddch(buf->win, buf->cursor_y,
                         ASCII_COL + buf->cursor_line_offset, c);
-               cursor_right(buf);
+               if (buf->cursor_x + 1 != ASCII_COL_END) {
+                       cursor_right(buf);
+               } else {
+                       cursor_down(buf);
+               }
        } else {
                if (!isxdigit(c)) {
                        return;
@@ -423,8 +437,12 @@ static void do_edit(struct hexedit *buf, int c)
 
                if (buf->cursor_x + 1 != HEX_COL2_END) {
                        cursor_right(buf);
+               } else {
+                       cursor_down(buf);
                }
        }
+
+       hexedit_refresh(buf);
 }
 
 void hexedit_driver(struct hexedit *buf, int c)
@@ -458,7 +476,7 @@ WERROR hexedit_resize_buffer(struct hexedit *buf, size_t newsz)
 {
        /* reset the cursor if it'll be out of bounds
           after the resize */
-       if (buf->cursor_offset >= newsz) {
+       if (buf->cursor_offset > newsz) {
                buf->cursor_y = 0;
                buf->cursor_x = HEX_COL1;
                buf->offset = 0;
@@ -470,12 +488,16 @@ WERROR hexedit_resize_buffer(struct hexedit *buf, size_t newsz)
        if (newsz > buf->len) {
                if (newsz > buf->alloc_size) {
                        uint8_t *d;
-                       d = talloc_realloc(buf, buf->data, uint8_t, newsz);
+                       buf->alloc_size *= 2;
+                       if (newsz > buf->alloc_size) {
+                               buf->alloc_size = newsz;
+                       }
+                       d = talloc_realloc(buf, buf->data, uint8_t,
+                                          buf->alloc_size);
                        if (d == NULL) {
                                return WERR_NOMEM;
                        }
                        buf->data = d;
-                       buf->alloc_size = newsz;
                }
                memset(buf->data + buf->len, '\0', newsz - buf->len);
                buf->len = newsz;