New 'Goto' dialog implementation in viewer.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>

Removed mcview_moveto_addr_cmd, mcview_moveto_line_cmd,
mcview_moveto_cmd.

Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
This commit is contained in:
Andrew Borodin 2010-01-12 11:28:03 +00:00 committed by Ilia Maslakov
parent b1de9bbd80
commit e3589ee4d8
4 changed files with 157 additions and 66 deletions

View File

@ -27,6 +27,7 @@
#define MC_HISTORY_FM_PANEL_FILTER "mc.fm.panel-filter"
#define MC_HISTORY_FM_MENU_EXEC_PARAM "mc.fm.menu.exec.parameter"
#define MC_HISTORY_VIEW_GOTO "mc.view.goto"
#define MC_HISTORY_VIEW_GOTO_LINE "mc.view.goto-line"
#define MC_HISTORY_VIEW_GOTO_ADDR "mc.view.goto-addr"
#define MC_HISTORY_VIEW_SEARCH_REGEX "mc.view.search.regex"

View File

@ -206,50 +206,6 @@ mcview_cmk_moveto_bottom (void *w, int n)
/* --------------------------------------------------------------------------------------------- */
static inline void
mcview_moveto_line_cmd (mcview_t *view)
{
char *answer, *answer_end, prompt[BUF_SMALL];
off_t line, col;
mcview_offset_to_coord (view, &line, &col, view->dpy_start);
g_snprintf (prompt, sizeof (prompt),
_(" The current line number is %lld.\n"
" Enter the new line number:"), (long long)(line + 1));
answer = input_dialog (_(" Goto line "), prompt, MC_HISTORY_VIEW_GOTO_LINE, "");
if (answer != NULL && answer[0] != '\0') {
errno = 0;
line = strtoul (answer, &answer_end, 10);
if (errno == 0 && *answer_end == '\0' && line >= 1)
mcview_moveto (view, line - 1, 0);
}
g_free (answer);
}
static inline void
mcview_moveto_addr_cmd (mcview_t *view)
{
char *line, *error, prompt[BUF_SMALL], prompt_format[BUF_SMALL];
g_snprintf (prompt_format, sizeof (prompt_format),
_(" The current address is %s.\n"
" Enter the new address:"), "0x%08" OFFSETTYPE_PRIX "");
g_snprintf (prompt, sizeof (prompt), prompt_format, view->hex_cursor);
line = input_dialog (_(" Goto Address "), prompt, MC_HISTORY_VIEW_GOTO_ADDR, "");
if ((line != NULL) && (*line != '\0')) {
off_t addr;
addr = strtoul (line, &error, 0);
if ((*error == '\0') && mcview_get_byte (view, addr, NULL))
mcview_moveto_offset (view, addr);
else
message (D_ERROR, _("Warning"), _(" Invalid address "));
}
g_free (line);
}
/* --------------------------------------------------------------------------------------------- */
static void
mcview_hook (void *v)
{
@ -359,13 +315,20 @@ mcview_execute_cmd (mcview_t *view, unsigned long command)
mcview_update (view); /* FIXME: view->dirty++ ? */
break;
case CK_ViewGoto:
if (view->hex_mode)
mcview_moveto_addr_cmd (view);
{
off_t addr;
if (mcview_dialog_goto (view, &addr)) {
if (addr < 0)
message (D_ERROR, _("Warning"), _("Invalid value"));
else
mcview_moveto_line_cmd (view);
mcview_moveto_offset (view, addr);
}
view->dirty++;
mcview_update (view); /* FIXME: unneeded? */
break;
}
case CK_ViewHexEditSave:
mcview_hexedit_save_changes (view);
break;

View File

@ -40,12 +40,14 @@
#include <stdlib.h>
#include <sys/types.h>
#include "../src/global.h"
#include "../src/search/search.h"
#include "../src/global.h"
#include "../src/wtools.h"
#include "../src/history.h"
#include "../src/charsets.h"
#include "../src/strutil.h"
#include "internal.h"
@ -127,28 +129,154 @@ mcview_dialog_search (mcview_t * view)
g_free (view->last_search_string);
view->last_search_string = exp;
exp = NULL;
if (view->search_nroff_seq)
if (view->search_nroff_seq != NULL)
mcview_nroff_seq_free (&(view->search_nroff_seq));
if (view->search)
if (view->search != NULL)
mc_search_free (view->search);
view->search = mc_search_new (view->last_search_string, -1);
view->search_nroff_seq = mcview_nroff_seq_new (view);
if (!view->search) {
g_free (exp);
return FALSE;
}
if (view->search != NULL) {
view->search->search_type = view->search_type;
view->search->is_all_charsets = view->search_all_codepages;
view->search->is_case_sentitive = view->search_case;
view->search->search_fn = mcview_search_cmd_callback;
view->search->update_fn = mcview_search_update_cmd_callback;
view->search->whole_words = view->whole_words;
}
return (view->search != NULL);
}
/* --------------------------------------------------------------------------------------------- */
gboolean
mcview_dialog_goto (mcview_t *view, off_t *offset)
{
typedef enum {
MC_VIEW_GOTO_LINENUM = 0,
MC_VIEW_GOTO_PERCENT = 1,
MC_VIEW_GOTO_OFFSET_DEC = 2,
MC_VIEW_GOTO_OFFSET_HEX = 3
} mcview_goto_type_t;
const char *mc_view_goto_str[] =
{
N_("&Line number (decimal)"),
N_("Pe&rcents"),
N_("&Decimal offset"),
N_("He&xadecimal offset")
};
const int goto_dlg_height = 12;
int goto_dlg_width = 40;
static mcview_goto_type_t current_goto_type = MC_VIEW_GOTO_LINENUM;
size_t i;
size_t num_of_types = sizeof (mc_view_goto_str) /sizeof (mc_view_goto_str[0]);
char *exp = NULL;
int qd_result;
gboolean res = FALSE;
QuickWidget quick_widgets[] =
{
QUICK_BUTTON (6, 10, goto_dlg_height - 3, goto_dlg_height, N_("&Cancel"), B_CANCEL, NULL),
QUICK_BUTTON (2, 10, goto_dlg_height - 3, goto_dlg_height, N_("&OK"), B_ENTER, NULL),
QUICK_RADIO (3, goto_dlg_width, 4, goto_dlg_height,
num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type),
QUICK_INPUT (3, goto_dlg_width, 2, goto_dlg_height,
INPUT_LAST_TEXT, goto_dlg_width - 6, 0, MC_HISTORY_VIEW_GOTO, &exp),
QUICK_END
};
QuickDialog Quick_input =
{
goto_dlg_width, goto_dlg_height, -1, -1,
N_("Goto"), "[Input Line Keys]",
quick_widgets, FALSE
};
#ifdef ENABLE_NLS
for (i = 0; i < num_of_types; i++)
mc_view_goto_str [i] = _(mc_view_goto_str [i]);
quick_widgets[0].u.button.text = _(quick_widgets[0].u.button.text);
quick_widgets[1].u.button.text = _(quick_widgets[1].u.button.text);
#endif
/* calculate widget coordinates */
{
int b0_len, b1_len, len;
const int button_gap = 2;
/* preliminary dialog width */
goto_dlg_width = max (goto_dlg_width, str_term_width1 (Quick_input.title) + 4);
/* length of radiobuttons */
for (i = 0; i < num_of_types; i++)
goto_dlg_width = max (goto_dlg_width, str_term_width1 (mc_view_goto_str [i]) + 10);
/* length of buttons */
b0_len = str_term_width1 (quick_widgets[0].u.button.text) + 3;
b1_len = str_term_width1 (quick_widgets[1].u.button.text) + 5; /* default button */
len = b0_len + b1_len + button_gap * 2;
/* dialog width */
Quick_input.xlen = max (goto_dlg_width, len + 6);
/* correct widget coordinates */
for (i = sizeof (quick_widgets)/sizeof (quick_widgets[0]); i > 0; i--)
quick_widgets[i - 1].x_divisions = Quick_input.xlen;
/* input length */
quick_widgets[3].u.input.len = Quick_input.xlen - 6;
/* button positions */
quick_widgets[1].relative_x = Quick_input.xlen/2 - len/2;
quick_widgets[0].relative_x = quick_widgets[1].relative_x + b1_len + button_gap;
}
/* run dialog*/
qd_result = quick_dialog (&Quick_input);
*offset = -1;
/* check input line value */
if ((qd_result != B_CANCEL) && (exp != NULL) && (exp[0] != '\0')) {
int base = (current_goto_type == MC_VIEW_GOTO_OFFSET_HEX) ? 16 : 10;
off_t addr;
char *error;
res = TRUE;
addr = strtoll (exp, &error, base);
if ((*error == '\0') && (addr >= 0)) {
switch (current_goto_type) {
case MC_VIEW_GOTO_LINENUM:
mcview_coord_to_offset (view, offset, addr, 0);
break;
case MC_VIEW_GOTO_PERCENT:
if (addr > 100)
addr = 100;
*offset = addr * mcview_get_filesize (view) / 100;
break;
case MC_VIEW_GOTO_OFFSET_DEC:
*offset = addr;
break;
case MC_VIEW_GOTO_OFFSET_HEX:
*offset = addr;
break;
default:
break;
}
*offset = mcview_bol (view, *offset);
}
}
g_free (exp);
return TRUE;
return res;
}

View File

@ -38,7 +38,6 @@ enum view_ds {
DS_STRING /* Data comes from a string in memory */
};
enum ccache_type {
CCACHE_OFFSET,
CCACHE_LINECOL
@ -64,7 +63,6 @@ struct area {
screen_dimen height, width;
};
/* A cache entry for mapping offsets into line/column pairs and vice versa.
* cc_offset, cc_line, and cc_column are the 0-based values of the offset,
* line and column of that cache entry. cc_nroff_column is the column
@ -238,7 +236,8 @@ void mcview_set_datasource_vfs_pipe (mcview_t *, int);
void mcview_set_datasource_string (mcview_t *, const char *);
/* dialog.c: */
gboolean mcview_dialog_search (mcview_t *);
gboolean mcview_dialog_search (mcview_t *view);
gboolean mcview_dialog_goto (mcview_t *view, off_t *offset);
/* display.c: */
void mcview_update (mcview_t *view);