Ticket #3225: first Backspace/Delete ignored after mouse click in an input widget.

Initial commit: WInput: refactoring of text marking.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2014-08-02 17:39:04 +04:00
parent aa6ad4804b
commit ddd336ad4d
2 changed files with 36 additions and 54 deletions

View File

@ -10,7 +10,7 @@
Jakub Jelinek, 1995 Jakub Jelinek, 1995
Andrej Borsenkow, 1996 Andrej Borsenkow, 1996
Norbert Warmuth, 1997 Norbert Warmuth, 1997
Andrew Borodin <aborodin@vmail.ru>, 2009, 2010, 2013 Andrew Borodin <aborodin@vmail.ru>, 2009-2014
This file is part of the Midnight Commander. This file is part of the Midnight Commander.
@ -127,27 +127,10 @@ draw_history_button (WInput * in)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static void
input_set_markers (WInput * in, long m1)
{
in->mark = m1;
}
/* --------------------------------------------------------------------------------------------- */
static void static void
input_mark_cmd (WInput * in, gboolean mark) input_mark_cmd (WInput * in, gboolean mark)
{ {
if (mark == 0) in->mark = mark ? in->point : -1;
{
in->highlight = FALSE;
input_set_markers (in, 0);
}
else
{
in->highlight = TRUE;
input_set_markers (in, in->point);
}
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -155,17 +138,15 @@ input_mark_cmd (WInput * in, gboolean mark)
static gboolean static gboolean
input_eval_marks (WInput * in, long *start_mark, long *end_mark) input_eval_marks (WInput * in, long *start_mark, long *end_mark)
{ {
if (in->highlight) if (in->mark >= 0)
{ {
*start_mark = min (in->mark, in->point); *start_mark = min (in->mark, in->point);
*end_mark = max (in->mark, in->point); *end_mark = max (in->mark, in->point);
return TRUE; return TRUE;
} }
else
{ *start_mark = *end_mark = -1;
*start_mark = *end_mark = 0; return FALSE;
return FALSE;
}
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -315,13 +296,11 @@ static cb_ret_t
insert_char (WInput * in, int c_code) insert_char (WInput * in, int c_code)
{ {
int res; int res;
long m1, m2;
if (input_eval_marks (in, &m1, &m2))
delete_region (in, m1, m2);
if (in->highlight)
{
long m1, m2;
if (input_eval_marks (in, &m1, &m2))
delete_region (in, m1, m2);
}
if (c_code == -1) if (c_code == -1)
return MSG_NOT_HANDLED; return MSG_NOT_HANDLED;
@ -603,8 +582,7 @@ clear_line (WInput * in)
in->need_push = TRUE; in->need_push = TRUE;
in->buffer[0] = '\0'; in->buffer[0] = '\0';
in->point = 0; in->point = 0;
in->mark = 0; in->mark = -1;
in->highlight = FALSE;
in->charpoint = 0; in->charpoint = 0;
} }
@ -710,7 +688,7 @@ input_execute_cmd (WInput * in, unsigned long command)
command == CK_MarkToWordBegin || command == CK_MarkToWordEnd || command == CK_MarkToWordBegin || command == CK_MarkToWordEnd ||
command == CK_MarkToHome || command == CK_MarkToEnd) command == CK_MarkToHome || command == CK_MarkToEnd)
{ {
if (!in->highlight) if (in->mark < 0)
{ {
input_mark_cmd (in, FALSE); /* clear */ input_mark_cmd (in, FALSE); /* clear */
input_mark_cmd (in, TRUE); /* marking on */ input_mark_cmd (in, TRUE); /* marking on */
@ -723,7 +701,7 @@ input_execute_cmd (WInput * in, unsigned long command)
case CK_WordLeft: case CK_WordLeft:
case CK_Right: case CK_Right:
case CK_Left: case CK_Left:
if (in->highlight) if (in->mark >= 0)
input_mark_cmd (in, FALSE); input_mark_cmd (in, FALSE);
} }
@ -754,26 +732,27 @@ input_execute_cmd (WInput * in, unsigned long command)
forward_word (in); forward_word (in);
break; break;
case CK_BackSpace: case CK_BackSpace:
if (in->highlight)
{ {
long m1, m2; long m1, m2;
if (input_eval_marks (in, &m1, &m2)) if (input_eval_marks (in, &m1, &m2))
delete_region (in, m1, m2); delete_region (in, m1, m2);
else
backward_delete (in);
} }
else
backward_delete (in);
break; break;
case CK_Delete: case CK_Delete:
if (in->first) if (in->first)
port_region_marked_for_delete (in); port_region_marked_for_delete (in);
else if (in->highlight) else
{ {
long m1, m2; long m1, m2;
if (input_eval_marks (in, &m1, &m2)) if (input_eval_marks (in, &m1, &m2))
delete_region (in, m1, m2); delete_region (in, m1, m2);
else
delete_char (in);
} }
else
delete_char (in);
break; break;
case CK_DeleteToWordEnd: case CK_DeleteToWordEnd:
kill_word (in); kill_word (in);
@ -785,7 +764,7 @@ input_execute_cmd (WInput * in, unsigned long command)
input_mark_cmd (in, TRUE); input_mark_cmd (in, TRUE);
break; break;
case CK_Remove: case CK_Remove:
delete_region (in, in->point, in->mark); delete_region (in, in->point, max (in->mark, 0));
break; break;
case CK_DeleteToEnd: case CK_DeleteToEnd:
kill_line (in); kill_line (in);
@ -794,11 +773,16 @@ input_execute_cmd (WInput * in, unsigned long command)
clear_line (in); clear_line (in);
break; break;
case CK_Store: case CK_Store:
copy_region (in, in->mark, in->point); copy_region (in, max (in->mark, 0), in->point);
break; break;
case CK_Cut: case CK_Cut:
copy_region (in, in->mark, in->point); {
delete_region (in, in->point, in->mark); long m;
m = max (in->mark, 0);
copy_region (in, m, in->point);
delete_region (in, in->point, m);
}
break; break;
case CK_Yank: case CK_Yank:
yank (in); yank (in);
@ -825,7 +809,7 @@ input_execute_cmd (WInput * in, unsigned long command)
if (command != CK_MarkLeft && command != CK_MarkRight && if (command != CK_MarkLeft && command != CK_MarkRight &&
command != CK_MarkToWordBegin && command != CK_MarkToWordEnd && command != CK_MarkToWordBegin && command != CK_MarkToWordEnd &&
command != CK_MarkToHome && command != CK_MarkToEnd) command != CK_MarkToHome && command != CK_MarkToEnd)
in->highlight = FALSE; in->mark = -1;
return res; return res;
} }
@ -949,7 +933,7 @@ input_event (Gpm_Event * event, void *data)
} }
/* A lone up mustn't do anything */ /* A lone up mustn't do anything */
if (in->highlight && (event->type & (GPM_UP | GPM_DRAG)) != 0) if (in->mark >= 0 && (event->type & (GPM_UP | GPM_DRAG)) != 0)
return MOU_NORMAL; return MOU_NORMAL;
if ((event->type & GPM_DRAG) == 0) if ((event->type & GPM_DRAG) == 0)
@ -1006,7 +990,7 @@ input_new (int y, int x, const int *colors, int width, const char *def_text,
in->color = colors; in->color = colors;
in->first = TRUE; in->first = TRUE;
in->highlight = FALSE; in->mark = -1;
in->term_first_shown = 0; in->term_first_shown = 0;
in->disable_update = 0; in->disable_update = 0;
in->is_password = FALSE; in->is_password = FALSE;
@ -1194,7 +1178,7 @@ input_assign_text (WInput * in, const char *text)
text = ""; text = "";
input_free_completions (in); input_free_completions (in);
in->mark = 0; in->mark = -1;
in->need_push = TRUE; in->need_push = TRUE;
in->charpoint = 0; in->charpoint = 0;
@ -1289,7 +1273,7 @@ input_update (WInput * in, gboolean clear_first)
if (!in->is_password) if (!in->is_password)
{ {
if (!in->highlight) if (in->mark < 0)
tty_print_string (str_term_substring (in->buffer, in->term_first_shown, tty_print_string (str_term_substring (in->buffer, in->term_first_shown,
w->cols - has_history)); w->cols - has_history));
else else
@ -1375,8 +1359,7 @@ input_clean (WInput * in)
in->buffer[0] = '\0'; in->buffer[0] = '\0';
in->point = 0; in->point = 0;
in->charpoint = 0; in->charpoint = 0;
in->mark = 0; in->mark = -1;
in->highlight = FALSE;
input_free_completions (in); input_free_completions (in);
input_update (in, FALSE); input_update (in, FALSE);
} }

View File

@ -48,8 +48,7 @@ typedef struct
Widget widget; Widget widget;
const int *color; const int *color;
int point; /* cursor position in the input line in characters */ int point; /* cursor position in the input line in characters */
int mark; /* the mark position in characters */ int mark; /* the mark position in characters; negative value means no marked text */
gboolean highlight; /* there is a selected block */
int term_first_shown; /* column of the first shown character */ int term_first_shown; /* column of the first shown character */
size_t current_max_size; /* maximum length of input line (bytes) */ size_t current_max_size; /* maximum length of input line (bytes) */
gboolean first; /* is first keystroke? */ gboolean first; /* is first keystroke? */