2011-10-15 14:56:47 +04:00
|
|
|
/*
|
|
|
|
Widgets for the Midnight Commander
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2023-01-03 11:30:57 +03:00
|
|
|
Copyright (C) 1994-2023
|
2014-02-12 10:33:10 +04:00
|
|
|
Free Software Foundation, Inc.
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
Authors:
|
|
|
|
Radek Doulik, 1994, 1995
|
|
|
|
Miguel de Icaza, 1994, 1995
|
|
|
|
Jakub Jelinek, 1995
|
|
|
|
Andrej Borsenkow, 1996
|
|
|
|
Norbert Warmuth, 1997
|
2021-10-23 20:43:38 +03:00
|
|
|
Andrew Borodin <aborodin@vmail.ru>, 2009-2022
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
This file is part of the Midnight Commander.
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander is free software: you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation, either version 3 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
The Midnight Commander is distributed in the hope that it will be useful,
|
2010-11-12 11:03:57 +03:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2011-10-15 14:56:47 +04:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2010-11-12 11:03:57 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file input.c
|
|
|
|
* \brief Source: WInput widget
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
#include "lib/global.h"
|
|
|
|
|
|
|
|
#include "lib/tty/tty.h"
|
|
|
|
#include "lib/tty/key.h" /* XCTRL and ALT macros */
|
|
|
|
#include "lib/fileloc.h"
|
|
|
|
#include "lib/skin.h"
|
|
|
|
#include "lib/strutil.h"
|
|
|
|
#include "lib/util.h"
|
|
|
|
#include "lib/widget.h"
|
2011-02-17 12:24:53 +03:00
|
|
|
#include "lib/event.h" /* mc_event_raise() */
|
2019-07-28 15:24:00 +03:00
|
|
|
#include "lib/mcconfig.h" /* mc_config_history_*() */
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
|
2016-02-07 11:47:58 +03:00
|
|
|
gboolean quote = FALSE;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-07-14 21:34:55 +04:00
|
|
|
const global_keymap_t *input_map = NULL;
|
2011-02-16 18:19:48 +03:00
|
|
|
|
2014-03-25 13:37:57 +04:00
|
|
|
/* Color styles for input widgets */
|
|
|
|
input_colors_t input_colors;
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/*** file scope macro definitions ****************************************************************/
|
|
|
|
|
|
|
|
#define LARGE_HISTORY_BUTTON 1
|
|
|
|
|
|
|
|
#ifdef LARGE_HISTORY_BUTTON
|
|
|
|
#define HISTORY_BUTTON_WIDTH 3
|
|
|
|
#else
|
|
|
|
#define HISTORY_BUTTON_WIDTH 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define should_show_history_button(in) \
|
2022-05-01 10:43:33 +03:00
|
|
|
(in->history.list != NULL && WIDGET (in)->rect.cols > HISTORY_BUTTON_WIDTH * 2 + 1 \
|
2012-06-20 15:09:44 +04:00
|
|
|
&& WIDGET (in)->owner != NULL)
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
/*** file scope type declarations ****************************************************************/
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/*** file scope variables ************************************************************************/
|
|
|
|
|
|
|
|
/* Input widgets have a global kill ring */
|
|
|
|
/* Pointer to killed data */
|
|
|
|
static char *kill_buffer = NULL;
|
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-12 11:03:57 +03:00
|
|
|
/*** file scope functions ************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-07-01 12:50:03 +04:00
|
|
|
static size_t
|
2020-12-22 16:02:40 +03:00
|
|
|
get_history_length (GList * history)
|
2011-07-01 12:50:03 +04:00
|
|
|
{
|
|
|
|
size_t len = 0;
|
|
|
|
|
2020-12-22 16:02:40 +03:00
|
|
|
for (; history != NULL; history = g_list_previous (history))
|
2011-07-01 12:50:03 +04:00
|
|
|
len++;
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
static void
|
|
|
|
draw_history_button (WInput * in)
|
|
|
|
{
|
|
|
|
char c;
|
2016-04-10 10:49:31 +03:00
|
|
|
gboolean disabled;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
if (g_list_next (in->history.current) == NULL)
|
2012-04-27 21:18:21 +04:00
|
|
|
c = '^';
|
2013-11-05 13:52:13 +04:00
|
|
|
else if (g_list_previous (in->history.current) == NULL)
|
2012-04-27 21:18:21 +04:00
|
|
|
c = 'v';
|
|
|
|
else
|
|
|
|
c = '|';
|
|
|
|
|
2022-05-01 10:43:33 +03:00
|
|
|
widget_gotoyx (in, 0, WIDGET (in)->rect.cols - HISTORY_BUTTON_WIDTH);
|
2016-04-10 12:26:48 +03:00
|
|
|
disabled = widget_get_state (WIDGET (in), WST_DISABLED);
|
2010-11-12 11:03:57 +03:00
|
|
|
tty_setcolor (disabled ? DISABLED_COLOR : in->color[WINPUTC_HISTORY]);
|
2012-07-16 16:14:33 +04:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
#ifdef LARGE_HISTORY_BUTTON
|
2012-07-16 16:14:33 +04:00
|
|
|
tty_print_string ("[ ]");
|
2022-05-01 10:43:33 +03:00
|
|
|
widget_gotoyx (in, 0, WIDGET (in)->rect.cols - HISTORY_BUTTON_WIDTH + 1);
|
2010-11-12 11:03:57 +03:00
|
|
|
#endif
|
2012-07-16 16:14:33 +04:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
tty_print_char (c);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
input_mark_cmd (WInput * in, gboolean mark)
|
|
|
|
{
|
2014-08-02 17:39:04 +04:00
|
|
|
in->mark = mark ? in->point : -1;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
input_eval_marks (WInput * in, long *start_mark, long *end_mark)
|
|
|
|
{
|
2014-08-02 17:39:04 +04:00
|
|
|
if (in->mark >= 0)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2016-04-07 10:52:04 +03:00
|
|
|
*start_mark = MIN (in->mark, in->point);
|
|
|
|
*end_mark = MAX (in->mark, in->point);
|
2010-11-12 11:03:57 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
2014-08-02 17:39:04 +04:00
|
|
|
|
|
|
|
*start_mark = *end_mark = -1;
|
|
|
|
return FALSE;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
do_show_hist (WInput * in)
|
|
|
|
{
|
2011-07-01 12:50:03 +04:00
|
|
|
size_t len;
|
2019-07-27 11:44:00 +03:00
|
|
|
history_descriptor_t hd;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
len = get_history_length (in->history.list);
|
2011-07-01 12:50:03 +04:00
|
|
|
|
2022-05-01 10:43:33 +03:00
|
|
|
history_descriptor_init (&hd, WIDGET (in)->rect.y, WIDGET (in)->rect.x, in->history.list,
|
2019-07-27 11:44:00 +03:00
|
|
|
g_list_position (in->history.list, in->history.list));
|
|
|
|
history_show (&hd);
|
|
|
|
|
2020-02-21 18:24:59 +03:00
|
|
|
/* in->history.list was destroyed in history_show().
|
Fix various typos in the source code (closes MidnightCommander/mc#177).
Found via `codespell -S
po,doc,./misc/syntax,./src/vfs/extfs/helpers/README.it -L
parm,rouge,sav,ect,vie,te,dum,clen,wee,dynamc,childs,ths,fo,nin,unx,nd,iif,iterm,ser,makrs,wil`
Co-authored-by: Yury V. Zaytsev <yury@shurup.com>
Signed-off-by: Kian-Meng Ang <kianmeng@cpan.org>
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
2023-01-10 06:02:52 +03:00
|
|
|
* Apply new history and current position to avoid use-after-free. */
|
2019-07-27 11:44:00 +03:00
|
|
|
in->history.list = hd.list;
|
2020-02-21 18:24:59 +03:00
|
|
|
in->history.current = in->history.list;
|
2019-07-27 11:44:00 +03:00
|
|
|
if (hd.text != NULL)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2019-07-27 11:44:00 +03:00
|
|
|
input_assign_text (in, hd.text);
|
|
|
|
g_free (hd.text);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
2011-07-01 12:50:03 +04:00
|
|
|
|
|
|
|
/* Has history cleaned up or not? */
|
2013-11-05 13:52:13 +04:00
|
|
|
if (len != get_history_length (in->history.list))
|
|
|
|
in->history.changed = TRUE;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
2012-04-05 13:51:06 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2012-08-31 18:05:29 +04:00
|
|
|
/**
|
|
|
|
* Strip password from incomplete url (just user:pass@host without VFS prefix).
|
2012-04-05 13:51:06 +04:00
|
|
|
*
|
|
|
|
* @param url partial URL
|
|
|
|
* @return newly allocated string without password
|
|
|
|
*/
|
|
|
|
|
|
|
|
static char *
|
2012-04-14 09:27:13 +04:00
|
|
|
input_history_strip_password (char *url)
|
2012-04-05 13:51:06 +04:00
|
|
|
{
|
|
|
|
char *at, *delim, *colon;
|
|
|
|
|
|
|
|
at = strrchr (url, '@');
|
|
|
|
if (at == NULL)
|
|
|
|
return g_strdup (url);
|
|
|
|
|
|
|
|
/* TODO: handle ':' and '@' in password */
|
|
|
|
|
|
|
|
delim = strstr (url, VFS_PATH_URL_DELIMITER);
|
|
|
|
if (delim != NULL)
|
|
|
|
colon = strchr (delim + strlen (VFS_PATH_URL_DELIMITER), ':');
|
|
|
|
else
|
|
|
|
colon = strchr (url, ':');
|
|
|
|
|
2012-06-18 20:56:19 +04:00
|
|
|
/* if 'colon' before 'at', 'colon' delimits user and password: user:password@host */
|
|
|
|
/* if 'colon' after 'at', 'colon' delimits host and port: user@host:port */
|
|
|
|
if (colon != NULL && colon > at)
|
|
|
|
colon = NULL;
|
|
|
|
|
2012-04-05 13:51:06 +04:00
|
|
|
if (colon == NULL)
|
|
|
|
return g_strdup (url);
|
|
|
|
*colon = '\0';
|
|
|
|
|
2016-03-25 21:33:44 +03:00
|
|
|
return g_strconcat (url, at, (char *) NULL);
|
2012-04-05 13:51:06 +04:00
|
|
|
}
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
2021-12-04 14:22:16 +03:00
|
|
|
input_push_history (WInput * in)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
char *t;
|
|
|
|
gboolean empty;
|
|
|
|
|
2022-08-03 16:51:09 +03:00
|
|
|
t = g_strstrip (input_get_text (in));
|
2010-11-12 11:03:57 +03:00
|
|
|
empty = *t == '\0';
|
2021-12-04 14:22:16 +03:00
|
|
|
if (!empty)
|
|
|
|
{
|
|
|
|
g_free (t);
|
2022-08-03 16:51:09 +03:00
|
|
|
t = input_get_text (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2021-12-04 14:26:27 +03:00
|
|
|
if (in->history.name != NULL && in->strip_password)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
We got string user:pass@host without any VFS prefixes
|
|
|
|
and vfs_path_to_str_flags (t, VPF_STRIP_PASSWORD) doesn't work.
|
|
|
|
Therefore we want to strip password in separate algorithm
|
|
|
|
*/
|
|
|
|
char *url_with_stripped_password;
|
|
|
|
|
|
|
|
url_with_stripped_password = input_history_strip_password (t);
|
|
|
|
g_free (t);
|
|
|
|
t = url_with_stripped_password;
|
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
if (in->history.list == NULL || in->history.list->data == NULL
|
|
|
|
|| strcmp (in->history.list->data, t) != 0 || in->history.changed)
|
2011-07-01 12:50:03 +04:00
|
|
|
{
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.list = list_append_unique (in->history.list, t);
|
|
|
|
in->history.current = in->history.list;
|
|
|
|
in->history.changed = TRUE;
|
2011-07-01 12:50:03 +04:00
|
|
|
}
|
2011-07-09 12:55:30 +04:00
|
|
|
else
|
|
|
|
g_free (t);
|
2011-07-08 20:48:17 +04:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
in->need_push = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
move_buffer_backward (WInput * in, int start, int end)
|
|
|
|
{
|
|
|
|
int str_len;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
str_len = str_length (in->buffer->str);
|
2010-11-12 11:03:57 +03:00
|
|
|
if (start >= str_len || end > str_len + 1)
|
|
|
|
return;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
start = str_offset_to_pos (in->buffer->str, start);
|
|
|
|
end = str_offset_to_pos (in->buffer->str, end);
|
|
|
|
g_string_erase (in->buffer, start, end - start);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
beginning_of_line (WInput * in)
|
|
|
|
{
|
|
|
|
in->point = 0;
|
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
end_of_line (WInput * in)
|
|
|
|
{
|
2021-10-10 17:08:52 +03:00
|
|
|
in->point = str_length (in->buffer->str);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
backward_char (WInput * in)
|
|
|
|
{
|
|
|
|
if (in->point > 0)
|
2021-10-10 17:08:52 +03:00
|
|
|
{
|
|
|
|
const char *act;
|
|
|
|
|
|
|
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
|
|
|
in->point -= str_cprev_noncomb_char (&act, in->buffer->str);
|
|
|
|
}
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
forward_char (WInput * in)
|
|
|
|
{
|
|
|
|
const char *act;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
2010-11-12 11:03:57 +03:00
|
|
|
if (act[0] != '\0')
|
|
|
|
in->point += str_cnext_noncomb_char (&act);
|
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
forward_word (WInput * in)
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
p = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
|
|
|
|
|
|
|
for (; p[0] != '\0' && (str_isspace (p) || str_ispunct (p)); in->point++)
|
2010-11-12 11:03:57 +03:00
|
|
|
str_cnext_char (&p);
|
2021-10-10 17:08:52 +03:00
|
|
|
|
|
|
|
for (; p[0] != '\0' && !str_isspace (p) && !str_ispunct (p); in->point++)
|
2010-11-12 11:03:57 +03:00
|
|
|
str_cnext_char (&p);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
backward_word (WInput * in)
|
|
|
|
{
|
2015-01-21 10:12:08 +03:00
|
|
|
const char *p;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
p = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
for (; p != in->buffer->str; in->point--)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2015-01-21 10:12:08 +03:00
|
|
|
const char *p_tmp;
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
p_tmp = p;
|
|
|
|
str_cprev_char (&p);
|
|
|
|
if (!str_isspace (p) && !str_ispunct (p))
|
|
|
|
{
|
|
|
|
p = p_tmp;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-10-10 17:08:52 +03:00
|
|
|
|
|
|
|
for (; p != in->buffer->str; in->point--)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
str_cprev_char (&p);
|
|
|
|
if (str_isspace (p) || str_ispunct (p))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
backward_delete (WInput * in)
|
|
|
|
{
|
2021-10-10 17:08:52 +03:00
|
|
|
const char *act;
|
2010-11-12 11:03:57 +03:00
|
|
|
int start;
|
|
|
|
|
|
|
|
if (in->point == 0)
|
|
|
|
return;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
|
|
|
start = in->point - str_cprev_noncomb_char (&act, in->buffer->str);
|
2010-11-12 11:03:57 +03:00
|
|
|
move_buffer_backward (in, start, in->point);
|
|
|
|
in->charpoint = 0;
|
|
|
|
in->need_push = TRUE;
|
|
|
|
in->point = start;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
2021-10-23 20:40:17 +03:00
|
|
|
copy_region (WInput * in, int start, int end)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2021-10-23 20:40:17 +03:00
|
|
|
int first = MIN (start, end);
|
|
|
|
int last = MAX (start, end);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
if (last == first)
|
|
|
|
{
|
|
|
|
/* Copy selected files to clipboard */
|
2013-07-23 02:16:20 +04:00
|
|
|
mc_event_raise (MCEVENT_GROUP_FILEMANAGER, "panel_save_current_file_to_clip_file", NULL);
|
2010-11-12 11:03:57 +03:00
|
|
|
/* try use external clipboard utility */
|
2011-02-17 12:24:53 +03:00
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
|
2010-11-12 11:03:57 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (kill_buffer);
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
first = str_offset_to_pos (in->buffer->str, first);
|
|
|
|
last = str_offset_to_pos (in->buffer->str, last);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
kill_buffer = g_strndup (in->buffer->str + first, last - first);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-02-17 12:24:53 +03:00
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", kill_buffer);
|
2010-11-12 11:03:57 +03:00
|
|
|
/* try use external clipboard utility */
|
2011-02-17 12:24:53 +03:00
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_to_ext_clip", NULL);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2021-12-04 13:47:03 +03:00
|
|
|
static void
|
|
|
|
delete_region (WInput * in, int start, int end)
|
|
|
|
{
|
|
|
|
int first = MIN (start, end);
|
|
|
|
int last = MAX (start, end);
|
|
|
|
|
|
|
|
input_mark_cmd (in, FALSE);
|
|
|
|
in->point = first;
|
2021-12-04 13:54:22 +03:00
|
|
|
move_buffer_backward (in, first, last);
|
2021-12-04 13:47:03 +03:00
|
|
|
in->charpoint = 0;
|
|
|
|
in->need_push = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static cb_ret_t
|
|
|
|
insert_char (WInput * in, int c_code)
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
long m1, m2;
|
|
|
|
size_t ins_point;
|
|
|
|
|
|
|
|
if (input_eval_marks (in, &m1, &m2))
|
|
|
|
delete_region (in, m1, m2);
|
|
|
|
|
|
|
|
if (c_code == -1)
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
if (in->charpoint >= MB_LEN_MAX)
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
|
|
|
in->charbuf[in->charpoint] = c_code;
|
|
|
|
in->charpoint++;
|
|
|
|
|
|
|
|
res = str_is_valid_char (in->charbuf, in->charpoint);
|
|
|
|
if (res < 0)
|
|
|
|
{
|
|
|
|
if (res != -2)
|
|
|
|
in->charpoint = 0; /* broken multibyte char, skip */
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
in->need_push = TRUE;
|
|
|
|
ins_point = str_offset_to_pos (in->buffer->str, in->point);
|
|
|
|
g_string_insert_len (in->buffer, ins_point, in->charbuf, in->charpoint);
|
|
|
|
in->point++;
|
|
|
|
in->charpoint = 0;
|
|
|
|
|
|
|
|
return MSG_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
delete_char (WInput * in)
|
|
|
|
{
|
|
|
|
const char *act;
|
|
|
|
int end;
|
|
|
|
|
|
|
|
act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
|
|
|
|
end = in->point + str_cnext_noncomb_char (&act);
|
|
|
|
move_buffer_backward (in, in->point, end);
|
|
|
|
in->charpoint = 0;
|
|
|
|
in->need_push = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
static void
|
|
|
|
kill_word (WInput * in)
|
|
|
|
{
|
|
|
|
int old_point = in->point;
|
|
|
|
int new_point;
|
|
|
|
|
|
|
|
forward_word (in);
|
|
|
|
new_point = in->point;
|
|
|
|
in->point = old_point;
|
|
|
|
|
|
|
|
delete_region (in, old_point, new_point);
|
|
|
|
in->need_push = TRUE;
|
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
back_kill_word (WInput * in)
|
|
|
|
{
|
|
|
|
int old_point = in->point;
|
|
|
|
int new_point;
|
|
|
|
|
|
|
|
backward_word (in);
|
|
|
|
new_point = in->point;
|
|
|
|
in->point = old_point;
|
|
|
|
|
|
|
|
delete_region (in, old_point, new_point);
|
|
|
|
in->need_push = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
yank (WInput * in)
|
|
|
|
{
|
|
|
|
if (kill_buffer != NULL)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
in->charpoint = 0;
|
|
|
|
for (p = kill_buffer; *p != '\0'; p++)
|
|
|
|
insert_char (in, *p);
|
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
kill_line (WInput * in)
|
|
|
|
{
|
|
|
|
int chp;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
chp = str_offset_to_pos (in->buffer->str, in->point);
|
2010-11-12 11:03:57 +03:00
|
|
|
g_free (kill_buffer);
|
2021-10-10 17:08:52 +03:00
|
|
|
kill_buffer = g_strndup (in->buffer->str + chp, in->buffer->len - chp);
|
|
|
|
g_string_set_size (in->buffer, chp);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
clear_line (WInput * in)
|
|
|
|
{
|
2011-06-30 21:51:38 +04:00
|
|
|
in->need_push = TRUE;
|
2021-10-10 17:08:52 +03:00
|
|
|
g_string_set_size (in->buffer, 0);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->point = 0;
|
2014-08-02 17:39:04 +04:00
|
|
|
in->mark = -1;
|
2010-11-12 11:03:57 +03:00
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
2011-06-30 21:51:38 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
static void
|
|
|
|
ins_from_clip (WInput * in)
|
|
|
|
{
|
|
|
|
char *p = NULL;
|
2022-06-18 17:23:18 +03:00
|
|
|
ev_clipboard_text_from_file_t event_data = { NULL, FALSE };
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
/* try use external clipboard utility */
|
2011-02-17 12:24:53 +03:00
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_file_from_ext_clip", NULL);
|
|
|
|
|
|
|
|
event_data.text = &p;
|
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_from_file", &event_data);
|
|
|
|
if (event_data.ret)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
char *pp;
|
|
|
|
|
|
|
|
for (pp = p; *pp != '\0'; pp++)
|
|
|
|
insert_char (in, *pp);
|
|
|
|
|
|
|
|
g_free (p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
hist_prev (WInput * in)
|
|
|
|
{
|
|
|
|
GList *prev;
|
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
if (in->history.list == NULL)
|
2010-11-12 11:03:57 +03:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (in->need_push)
|
2021-12-04 14:22:16 +03:00
|
|
|
input_push_history (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
prev = g_list_previous (in->history.current);
|
2010-11-12 11:03:57 +03:00
|
|
|
if (prev != NULL)
|
|
|
|
{
|
|
|
|
input_assign_text (in, (char *) prev->data);
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.current = prev;
|
|
|
|
in->history.changed = TRUE;
|
2010-11-12 11:03:57 +03:00
|
|
|
in->need_push = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
hist_next (WInput * in)
|
|
|
|
{
|
2011-06-30 21:49:17 +04:00
|
|
|
GList *next;
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
if (in->need_push)
|
|
|
|
{
|
2021-12-04 14:22:16 +03:00
|
|
|
input_push_history (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
input_assign_text (in, "");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
if (in->history.list == NULL)
|
2010-11-12 11:03:57 +03:00
|
|
|
return;
|
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
next = g_list_next (in->history.current);
|
2011-06-30 21:49:17 +04:00
|
|
|
if (next == NULL)
|
2012-04-27 21:18:21 +04:00
|
|
|
{
|
2010-11-12 11:03:57 +03:00
|
|
|
input_assign_text (in, "");
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.current = in->history.list;
|
2012-04-27 21:18:21 +04:00
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
else
|
|
|
|
{
|
2011-06-30 21:49:17 +04:00
|
|
|
input_assign_text (in, (char *) next->data);
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.current = next;
|
|
|
|
in->history.changed = TRUE;
|
2010-11-12 11:03:57 +03:00
|
|
|
in->need_push = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
|
|
|
port_region_marked_for_delete (WInput * in)
|
|
|
|
{
|
2021-10-10 17:08:52 +03:00
|
|
|
g_string_set_size (in->buffer, 0);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->point = 0;
|
|
|
|
in->first = FALSE;
|
|
|
|
in->charpoint = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static cb_ret_t
|
2015-11-21 18:15:11 +03:00
|
|
|
input_execute_cmd (WInput * in, long command)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
cb_ret_t res = MSG_HANDLED;
|
|
|
|
|
2015-01-21 10:00:00 +03:00
|
|
|
switch (command)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2015-01-21 10:00:00 +03:00
|
|
|
case CK_MarkLeft:
|
|
|
|
case CK_MarkRight:
|
|
|
|
case CK_MarkToWordBegin:
|
|
|
|
case CK_MarkToWordEnd:
|
|
|
|
case CK_MarkToHome:
|
|
|
|
case CK_MarkToEnd:
|
|
|
|
/* a highlight command like shift-arrow */
|
2014-08-02 17:39:04 +04:00
|
|
|
if (in->mark < 0)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
input_mark_cmd (in, FALSE); /* clear */
|
|
|
|
input_mark_cmd (in, TRUE); /* marking on */
|
|
|
|
}
|
2015-01-21 10:00:00 +03:00
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_WordRight:
|
|
|
|
case CK_WordLeft:
|
|
|
|
case CK_Right:
|
|
|
|
case CK_Left:
|
2014-08-02 17:39:04 +04:00
|
|
|
if (in->mark >= 0)
|
2010-11-12 11:03:57 +03:00
|
|
|
input_mark_cmd (in, FALSE);
|
2015-01-21 10:00:00 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (command)
|
|
|
|
{
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Home:
|
|
|
|
case CK_MarkToHome:
|
2010-11-12 11:03:57 +03:00
|
|
|
beginning_of_line (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_End:
|
|
|
|
case CK_MarkToEnd:
|
2010-11-12 11:03:57 +03:00
|
|
|
end_of_line (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Left:
|
|
|
|
case CK_MarkLeft:
|
2010-11-12 11:03:57 +03:00
|
|
|
backward_char (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_WordLeft:
|
|
|
|
case CK_MarkToWordBegin:
|
2010-11-12 11:03:57 +03:00
|
|
|
backward_word (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Right:
|
|
|
|
case CK_MarkRight:
|
2010-11-12 11:03:57 +03:00
|
|
|
forward_char (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_WordRight:
|
|
|
|
case CK_MarkToWordEnd:
|
2010-11-12 11:03:57 +03:00
|
|
|
forward_word (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_BackSpace:
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
long m1, m2;
|
2014-08-02 17:39:04 +04:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
if (input_eval_marks (in, &m1, &m2))
|
|
|
|
delete_region (in, m1, m2);
|
2014-08-02 17:39:04 +04:00
|
|
|
else
|
|
|
|
backward_delete (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Delete:
|
2010-11-12 11:03:57 +03:00
|
|
|
if (in->first)
|
|
|
|
port_region_marked_for_delete (in);
|
2014-08-02 17:39:04 +04:00
|
|
|
else
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
long m1, m2;
|
2014-08-02 17:39:04 +04:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
if (input_eval_marks (in, &m1, &m2))
|
|
|
|
delete_region (in, m1, m2);
|
2014-08-02 17:39:04 +04:00
|
|
|
else
|
|
|
|
delete_char (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_DeleteToWordEnd:
|
2010-11-12 11:03:57 +03:00
|
|
|
kill_word (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_DeleteToWordBegin:
|
2010-11-12 11:03:57 +03:00
|
|
|
back_kill_word (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Mark:
|
2010-11-12 11:03:57 +03:00
|
|
|
input_mark_cmd (in, TRUE);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Remove:
|
2016-04-07 10:52:04 +03:00
|
|
|
delete_region (in, in->point, MAX (in->mark, 0));
|
2010-11-12 11:03:57 +03:00
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_DeleteToEnd:
|
2010-11-12 11:03:57 +03:00
|
|
|
kill_line (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Clear:
|
2010-11-12 11:03:57 +03:00
|
|
|
clear_line (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Store:
|
2016-04-07 10:52:04 +03:00
|
|
|
copy_region (in, MAX (in->mark, 0), in->point);
|
2010-11-12 11:03:57 +03:00
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Cut:
|
2014-08-02 17:39:04 +04:00
|
|
|
{
|
|
|
|
long m;
|
|
|
|
|
2016-04-07 10:52:04 +03:00
|
|
|
m = MAX (in->mark, 0);
|
2014-08-02 17:39:04 +04:00
|
|
|
copy_region (in, m, in->point);
|
|
|
|
delete_region (in, in->point, m);
|
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Yank:
|
2010-11-12 11:03:57 +03:00
|
|
|
yank (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Paste:
|
2010-11-12 11:03:57 +03:00
|
|
|
ins_from_clip (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_HistoryPrev:
|
2010-11-12 11:03:57 +03:00
|
|
|
hist_prev (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_HistoryNext:
|
2010-11-12 11:03:57 +03:00
|
|
|
hist_next (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_History:
|
2010-11-12 11:03:57 +03:00
|
|
|
do_show_hist (in);
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Complete:
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
res = MSG_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
2015-01-21 10:00:00 +03:00
|
|
|
switch (command)
|
|
|
|
{
|
|
|
|
case CK_MarkLeft:
|
|
|
|
case CK_MarkRight:
|
|
|
|
case CK_MarkToWordBegin:
|
|
|
|
case CK_MarkToWordEnd:
|
|
|
|
case CK_MarkToHome:
|
|
|
|
case CK_MarkToEnd:
|
|
|
|
/* do nothing */
|
|
|
|
break;
|
|
|
|
default:
|
2014-08-02 17:39:04 +04:00
|
|
|
in->mark = -1;
|
2015-01-21 10:00:00 +03:00
|
|
|
break;
|
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-05-03 17:24:56 +04:00
|
|
|
/* "history_load" event handler */
|
|
|
|
static gboolean
|
|
|
|
input_load_history (const gchar * event_group_name, const gchar * event_name,
|
|
|
|
gpointer init_data, gpointer data)
|
|
|
|
{
|
2012-10-11 12:25:07 +04:00
|
|
|
WInput *in = INPUT (init_data);
|
2011-05-03 17:24:56 +04:00
|
|
|
ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
|
|
|
|
|
|
|
|
(void) event_group_name;
|
|
|
|
(void) event_name;
|
|
|
|
|
2019-07-28 15:24:00 +03:00
|
|
|
in->history.list = mc_config_history_load (ev->cfg, in->history.name);
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.current = in->history.list;
|
2011-05-03 17:24:56 +04:00
|
|
|
|
2013-09-21 14:53:39 +04:00
|
|
|
if (in->init_from_history)
|
2011-05-03 17:24:56 +04:00
|
|
|
{
|
2013-09-21 14:53:39 +04:00
|
|
|
const char *def_text = "";
|
|
|
|
|
2013-11-05 13:52:13 +04:00
|
|
|
if (in->history.list != NULL && in->history.list->data != NULL)
|
|
|
|
def_text = (const char *) in->history.list->data;
|
2011-05-03 17:24:56 +04:00
|
|
|
|
2013-09-21 14:53:39 +04:00
|
|
|
input_assign_text (in, def_text);
|
2011-05-03 17:24:56 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-05-02 13:44:47 +04:00
|
|
|
/* "history_save" event handler */
|
|
|
|
static gboolean
|
|
|
|
input_save_history (const gchar * event_group_name, const gchar * event_name,
|
|
|
|
gpointer init_data, gpointer data)
|
|
|
|
{
|
2012-10-11 12:25:07 +04:00
|
|
|
WInput *in = INPUT (init_data);
|
2011-05-02 13:44:47 +04:00
|
|
|
|
|
|
|
(void) event_group_name;
|
|
|
|
(void) event_name;
|
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (!in->is_password && (DIALOG (WIDGET (in)->owner)->ret_value != B_CANCEL))
|
2011-05-02 13:44:47 +04:00
|
|
|
{
|
|
|
|
ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
|
|
|
|
|
2021-12-04 14:22:16 +03:00
|
|
|
input_push_history (in);
|
2013-11-05 13:52:13 +04:00
|
|
|
if (in->history.changed)
|
2019-07-28 15:24:00 +03:00
|
|
|
mc_config_history_save (ev->cfg, in->history.name, in->history.list);
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.changed = FALSE;
|
2011-05-02 13:44:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
static void
|
|
|
|
input_destroy (WInput * in)
|
|
|
|
{
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-05-02 13:44:47 +04:00
|
|
|
/* clean history */
|
2013-11-05 13:52:13 +04:00
|
|
|
if (in->history.list != NULL)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2011-05-02 13:44:47 +04:00
|
|
|
/* history is already saved before this moment */
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.list = g_list_first (in->history.list);
|
2013-11-04 12:09:13 +04:00
|
|
|
g_list_free_full (in->history.list, g_free);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
2013-11-05 13:52:13 +04:00
|
|
|
g_free (in->history.name);
|
2021-10-10 17:08:52 +03:00
|
|
|
g_string_free (in->buffer, TRUE);
|
2014-08-05 11:18:30 +04:00
|
|
|
MC_PTR_FREE (kill_buffer);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
/**
|
|
|
|
* Calculates the buffer index (aka "point") corresponding to some screen coordinate.
|
|
|
|
*/
|
2010-11-12 11:03:57 +03:00
|
|
|
static int
|
2016-01-19 15:04:48 +03:00
|
|
|
input_screen_to_point (const WInput * in, int x)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2016-01-19 15:04:48 +03:00
|
|
|
x += in->term_first_shown;
|
2014-08-02 21:01:53 +04:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
if (x < 0)
|
|
|
|
return 0;
|
2011-03-21 16:43:56 +03:00
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
if (x < str_term_width1 (in->buffer->str))
|
|
|
|
return str_column_to_pos (in->buffer->str, x);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
return str_length (in->buffer->str);
|
2016-01-19 15:04:48 +03:00
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2011-03-21 16:43:56 +03:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
static void
|
|
|
|
input_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event)
|
|
|
|
{
|
|
|
|
/* save point between MSG_MOUSE_DOWN and MSG_MOUSE_DRAG */
|
|
|
|
static int prev_point = 0;
|
|
|
|
WInput *in = INPUT (w);
|
2011-03-21 16:43:56 +03:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
switch (msg)
|
|
|
|
{
|
|
|
|
case MSG_MOUSE_DOWN:
|
2016-08-09 09:35:27 +03:00
|
|
|
widget_select (w);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2022-05-01 10:43:33 +03:00
|
|
|
if (event->x >= w->rect.cols - HISTORY_BUTTON_WIDTH && should_show_history_button (in))
|
2010-11-12 11:03:57 +03:00
|
|
|
do_show_hist (in);
|
|
|
|
else
|
|
|
|
{
|
2020-12-06 18:21:08 +03:00
|
|
|
in->first = FALSE;
|
2016-01-19 15:04:48 +03:00
|
|
|
input_mark_cmd (in, FALSE);
|
|
|
|
input_set_point (in, input_screen_to_point (in, event->x));
|
|
|
|
/* save point for the possible following MSG_MOUSE_DRAG action */
|
|
|
|
prev_point = in->point;
|
2014-08-02 21:01:53 +04:00
|
|
|
}
|
2016-01-19 15:04:48 +03:00
|
|
|
break;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
case MSG_MOUSE_DRAG:
|
|
|
|
/* start point: set marker using point before first MSG_MOUSE_DRAG action */
|
|
|
|
if (in->mark < 0)
|
|
|
|
in->mark = prev_point;
|
2014-08-02 21:01:53 +04:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
input_set_point (in, input_screen_to_point (in, event->x));
|
|
|
|
break;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2016-01-19 15:04:48 +03:00
|
|
|
default:
|
|
|
|
/* don't create highlight region of 0 length */
|
|
|
|
if (in->mark == in->point)
|
|
|
|
input_mark_cmd (in, FALSE);
|
|
|
|
break;
|
|
|
|
}
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/*** public functions ****************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/** Create new instance of WInput object.
|
|
|
|
* @param y Y coordinate
|
|
|
|
* @param x X coordinate
|
|
|
|
* @param input_colors Array of used colors
|
|
|
|
* @param width Widget width
|
|
|
|
* @param def_text Default text filled in widget
|
|
|
|
* @param histname Name of history
|
|
|
|
* @param completion_flags Flags for specify type of completions
|
2012-11-05 17:57:50 +04:00
|
|
|
* @return WInput object
|
2010-11-12 11:03:57 +03:00
|
|
|
*/
|
|
|
|
WInput *
|
2014-03-25 13:37:57 +04:00
|
|
|
input_new (int y, int x, const int *colors, int width, const char *def_text,
|
2010-11-12 11:03:57 +03:00
|
|
|
const char *histname, input_complete_t completion_flags)
|
|
|
|
{
|
2022-05-21 16:11:06 +03:00
|
|
|
WRect r = { y, x, 1, width };
|
2011-05-03 17:24:56 +04:00
|
|
|
WInput *in;
|
2012-06-20 15:09:44 +04:00
|
|
|
Widget *w;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-05-03 17:24:56 +04:00
|
|
|
in = g_new (WInput, 1);
|
2012-06-20 15:09:44 +04:00
|
|
|
w = WIDGET (in);
|
2022-05-21 16:11:06 +03:00
|
|
|
widget_init (w, &r, input_callback, input_mouse_callback);
|
2016-06-07 15:03:20 +03:00
|
|
|
w->options |= WOP_SELECTABLE | WOP_IS_INPUT | WOP_WANT_CURSOR;
|
2017-03-08 14:41:35 +03:00
|
|
|
w->keymap = input_map;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2014-03-25 13:37:57 +04:00
|
|
|
in->color = colors;
|
2010-11-12 11:03:57 +03:00
|
|
|
in->first = TRUE;
|
2014-08-02 17:39:04 +04:00
|
|
|
in->mark = -1;
|
2010-11-12 11:03:57 +03:00
|
|
|
in->term_first_shown = 0;
|
|
|
|
in->disable_update = 0;
|
|
|
|
in->is_password = FALSE;
|
2012-04-05 13:51:06 +04:00
|
|
|
in->strip_password = FALSE;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2011-05-03 17:24:56 +04:00
|
|
|
/* in->buffer will be corrected in "history_load" event handler */
|
2021-10-10 17:08:52 +03:00
|
|
|
in->buffer = g_string_sized_new (width);
|
2011-05-03 17:24:56 +04:00
|
|
|
|
2013-09-21 14:53:39 +04:00
|
|
|
/* init completions before input_assign_text() call */
|
2011-05-03 17:24:56 +04:00
|
|
|
in->completions = NULL;
|
|
|
|
in->completion_flags = completion_flags;
|
|
|
|
|
2013-09-21 14:53:39 +04:00
|
|
|
in->init_from_history = (def_text == INPUT_LAST_TEXT);
|
|
|
|
|
|
|
|
if (in->init_from_history || def_text == NULL)
|
|
|
|
def_text = "";
|
|
|
|
|
|
|
|
input_assign_text (in, def_text);
|
|
|
|
|
2011-05-03 17:24:56 +04:00
|
|
|
/* prepare to history setup */
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.list = NULL;
|
|
|
|
in->history.current = NULL;
|
|
|
|
in->history.changed = FALSE;
|
|
|
|
in->history.name = NULL;
|
2011-05-03 17:24:56 +04:00
|
|
|
if ((histname != NULL) && (*histname != '\0'))
|
2013-11-05 13:52:13 +04:00
|
|
|
in->history.name = g_strdup (histname);
|
2011-05-03 17:24:56 +04:00
|
|
|
/* history will be loaded later */
|
|
|
|
|
2012-09-09 18:02:29 +04:00
|
|
|
in->label = NULL;
|
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
cb_ret_t
|
2012-06-26 11:52:21 +04:00
|
|
|
input_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2012-10-11 12:25:07 +04:00
|
|
|
WInput *in = INPUT (w);
|
2016-09-27 13:53:17 +03:00
|
|
|
WDialog *h = DIALOG (w->owner);
|
2010-11-12 11:03:57 +03:00
|
|
|
cb_ret_t v;
|
|
|
|
|
|
|
|
switch (msg)
|
|
|
|
{
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_INIT:
|
2011-05-03 17:24:56 +04:00
|
|
|
/* subscribe to "history_load" event */
|
2016-09-27 13:53:17 +03:00
|
|
|
mc_event_add (h->event_group, MCEVENT_HISTORY_LOAD, input_load_history, w, NULL);
|
2011-05-02 13:44:47 +04:00
|
|
|
/* subscribe to "history_save" event */
|
2016-09-27 13:53:17 +03:00
|
|
|
mc_event_add (h->event_group, MCEVENT_HISTORY_SAVE, input_save_history, w, NULL);
|
2016-04-10 12:26:48 +03:00
|
|
|
if (in->label != NULL)
|
|
|
|
widget_set_state (WIDGET (in->label), WST_DISABLED, widget_get_state (w, WST_DISABLED));
|
2011-05-02 13:44:47 +04:00
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_KEY:
|
2010-11-12 11:03:57 +03:00
|
|
|
if (parm == XCTRL ('q'))
|
|
|
|
{
|
2016-02-07 11:47:58 +03:00
|
|
|
quote = TRUE;
|
2010-11-12 11:03:57 +03:00
|
|
|
v = input_handle_char (in, ascii_alpha_to_cntrl (tty_getch ()));
|
2016-02-07 11:47:58 +03:00
|
|
|
quote = FALSE;
|
2010-11-12 11:03:57 +03:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Keys we want others to handle */
|
|
|
|
if (parm == KEY_UP || parm == KEY_DOWN || parm == ESC_CHAR
|
|
|
|
|| parm == KEY_F (10) || parm == '\n')
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
|
|
|
|
/* When pasting multiline text, insert literal Enter */
|
|
|
|
if ((parm & ~KEY_M_MASK) == '\n')
|
|
|
|
{
|
2016-02-07 11:47:58 +03:00
|
|
|
quote = TRUE;
|
2010-11-12 11:03:57 +03:00
|
|
|
v = input_handle_char (in, '\n');
|
2016-02-07 11:47:58 +03:00
|
|
|
quote = FALSE;
|
2010-11-12 11:03:57 +03:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
return input_handle_char (in, parm);
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_ACTION:
|
2010-11-12 11:03:57 +03:00
|
|
|
return input_execute_cmd (in, parm);
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_DRAW:
|
2010-11-12 11:03:57 +03:00
|
|
|
input_update (in, FALSE);
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2016-04-10 12:26:48 +03:00
|
|
|
case MSG_ENABLE:
|
|
|
|
case MSG_DISABLE:
|
|
|
|
if (in->label != NULL)
|
|
|
|
widget_set_state (WIDGET (in->label), WST_DISABLED, msg == MSG_DISABLE);
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_CURSOR:
|
2021-10-10 17:08:52 +03:00
|
|
|
widget_gotoyx (in, 0, str_term_width2 (in->buffer->str, in->point) - in->term_first_shown);
|
2010-11-12 11:03:57 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_DESTROY:
|
2011-05-03 17:24:56 +04:00
|
|
|
/* unsubscribe from "history_load" event */
|
2016-09-27 13:53:17 +03:00
|
|
|
mc_event_del (h->event_group, MCEVENT_HISTORY_LOAD, input_load_history, w);
|
2011-05-02 13:44:47 +04:00
|
|
|
/* unsubscribe from "history_save" event */
|
2016-09-27 13:53:17 +03:00
|
|
|
mc_event_del (h->event_group, MCEVENT_HISTORY_SAVE, input_save_history, w);
|
2010-11-12 11:03:57 +03:00
|
|
|
input_destroy (in);
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
|
|
|
default:
|
2012-09-28 15:05:43 +04:00
|
|
|
return widget_default_callback (w, sender, msg, parm, data);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2014-03-25 13:37:57 +04:00
|
|
|
void
|
|
|
|
input_set_default_colors (void)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2014-03-25 13:37:57 +04:00
|
|
|
input_colors[WINPUTC_MAIN] = INPUT_COLOR;
|
|
|
|
input_colors[WINPUTC_MARK] = INPUT_MARK_COLOR;
|
|
|
|
input_colors[WINPUTC_UNCHANGED] = INPUT_UNCHANGED_COLOR;
|
|
|
|
input_colors[WINPUTC_HISTORY] = INPUT_HISTORY_COLOR;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
cb_ret_t
|
|
|
|
input_handle_char (WInput * in, int key)
|
|
|
|
{
|
|
|
|
cb_ret_t v;
|
2015-11-21 18:15:11 +03:00
|
|
|
long command;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2016-02-07 11:47:58 +03:00
|
|
|
if (quote)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
v = insert_char (in, key);
|
|
|
|
input_update (in, TRUE);
|
2016-02-07 11:47:58 +03:00
|
|
|
quote = FALSE;
|
2010-11-12 11:03:57 +03:00
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2017-03-08 14:41:35 +03:00
|
|
|
command = widget_lookup_key (WIDGET (in), key);
|
2011-02-20 18:23:32 +03:00
|
|
|
if (command == CK_IgnoreKey)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
|
|
|
if (key > 255)
|
|
|
|
return MSG_NOT_HANDLED;
|
|
|
|
if (in->first)
|
|
|
|
port_region_marked_for_delete (in);
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
v = insert_char (in, key);
|
2020-12-06 18:21:08 +03:00
|
|
|
input_update (in, TRUE);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-12-06 18:21:08 +03:00
|
|
|
gboolean keep_first;
|
|
|
|
|
2011-01-21 11:47:27 +03:00
|
|
|
if (command != CK_Complete)
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
input_execute_cmd (in, command);
|
|
|
|
v = MSG_HANDLED;
|
2020-12-06 18:21:08 +03:00
|
|
|
/* if in->first == TRUE and history or completion window was cancelled,
|
|
|
|
keep "first" state */
|
|
|
|
keep_first = in->first && (command == CK_History || command == CK_Complete);
|
|
|
|
input_update (in, !keep_first);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
|
|
|
input_assign_text (WInput * in, const char *text)
|
|
|
|
{
|
2013-09-21 14:53:39 +04:00
|
|
|
if (text == NULL)
|
|
|
|
text = "";
|
|
|
|
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2014-08-02 17:39:04 +04:00
|
|
|
in->mark = -1;
|
2010-11-12 11:03:57 +03:00
|
|
|
in->need_push = TRUE;
|
|
|
|
in->charpoint = 0;
|
2021-10-10 17:08:52 +03:00
|
|
|
g_string_assign (in->buffer, text);
|
|
|
|
in->point = str_length (in->buffer->str);
|
2012-04-27 21:18:21 +04:00
|
|
|
input_update (in, TRUE);
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2016-03-30 13:42:03 +03:00
|
|
|
|
2010-11-12 11:03:57 +03:00
|
|
|
/* Inserts text in input line */
|
|
|
|
void
|
|
|
|
input_insert (WInput * in, const char *text, gboolean insert_extra_space)
|
|
|
|
{
|
|
|
|
input_disable_update (in);
|
|
|
|
while (*text != '\0')
|
2010-11-22 17:15:28 +03:00
|
|
|
input_handle_char (in, (unsigned char) *text++); /* unsigned extension char->int */
|
2010-11-12 11:03:57 +03:00
|
|
|
if (insert_extra_space)
|
|
|
|
input_handle_char (in, ' ');
|
|
|
|
input_enable_update (in);
|
|
|
|
input_update (in, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
|
|
|
input_set_point (WInput * in, int pos)
|
|
|
|
{
|
|
|
|
int max_pos;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
max_pos = str_length (in->buffer->str);
|
2016-04-07 10:52:04 +03:00
|
|
|
pos = MIN (pos, max_pos);
|
2010-11-12 11:03:57 +03:00
|
|
|
if (pos != in->point)
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->point = pos;
|
|
|
|
in->charpoint = 0;
|
|
|
|
input_update (in, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
|
|
|
input_update (WInput * in, gboolean clear_first)
|
|
|
|
{
|
2022-05-01 10:43:33 +03:00
|
|
|
Widget *wi = WIDGET (in);
|
|
|
|
const WRect *w = &wi->rect;
|
2010-11-12 11:03:57 +03:00
|
|
|
int has_history = 0;
|
|
|
|
int buf_len;
|
|
|
|
const char *cp;
|
|
|
|
int pw;
|
|
|
|
|
|
|
|
if (in->disable_update != 0)
|
|
|
|
return;
|
|
|
|
|
2013-09-21 15:04:05 +04:00
|
|
|
/* don't draw widget not put into dialog */
|
2022-05-01 10:43:33 +03:00
|
|
|
if (wi->owner == NULL || !widget_get_state (WIDGET (wi->owner), WST_ACTIVE))
|
2013-09-21 15:04:05 +04:00
|
|
|
return;
|
|
|
|
|
2020-12-06 18:21:08 +03:00
|
|
|
if (clear_first)
|
|
|
|
in->first = FALSE;
|
|
|
|
|
2013-09-21 15:04:05 +04:00
|
|
|
if (should_show_history_button (in))
|
|
|
|
has_history = HISTORY_BUTTON_WIDTH;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
buf_len = str_length (in->buffer->str);
|
2013-09-21 15:04:05 +04:00
|
|
|
|
|
|
|
/* Adjust the mark */
|
2016-04-07 10:52:04 +03:00
|
|
|
in->mark = MIN (in->mark, buf_len);
|
2013-09-21 15:04:05 +04:00
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
pw = str_term_width2 (in->buffer->str, in->point);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
/* Make the point visible */
|
2013-10-23 09:56:12 +04:00
|
|
|
if ((pw < in->term_first_shown) || (pw >= in->term_first_shown + w->cols - has_history))
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2013-10-23 09:56:12 +04:00
|
|
|
in->term_first_shown = pw - (w->cols / 3);
|
2010-11-12 11:03:57 +03:00
|
|
|
if (in->term_first_shown < 0)
|
|
|
|
in->term_first_shown = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (has_history != 0)
|
|
|
|
draw_history_button (in);
|
|
|
|
|
2022-05-01 10:43:33 +03:00
|
|
|
if (widget_get_state (wi, WST_DISABLED))
|
2010-11-12 11:03:57 +03:00
|
|
|
tty_setcolor (DISABLED_COLOR);
|
|
|
|
else if (in->first)
|
|
|
|
tty_setcolor (in->color[WINPUTC_UNCHANGED]);
|
|
|
|
else
|
|
|
|
tty_setcolor (in->color[WINPUTC_MAIN]);
|
|
|
|
|
2019-10-16 13:07:24 +03:00
|
|
|
widget_gotoyx (in, 0, 0);
|
2010-11-12 11:03:57 +03:00
|
|
|
|
|
|
|
if (!in->is_password)
|
|
|
|
{
|
2014-08-02 17:39:04 +04:00
|
|
|
if (in->mark < 0)
|
2021-10-10 17:08:52 +03:00
|
|
|
tty_print_string (str_term_substring (in->buffer->str, in->term_first_shown,
|
2013-10-23 09:56:12 +04:00
|
|
|
w->cols - has_history));
|
2010-11-12 11:03:57 +03:00
|
|
|
else
|
|
|
|
{
|
|
|
|
long m1, m2;
|
|
|
|
|
|
|
|
if (input_eval_marks (in, &m1, &m2))
|
|
|
|
{
|
|
|
|
tty_setcolor (in->color[WINPUTC_MAIN]);
|
2021-10-10 17:08:52 +03:00
|
|
|
cp = str_term_substring (in->buffer->str, in->term_first_shown,
|
|
|
|
w->cols - has_history);
|
2010-11-12 11:03:57 +03:00
|
|
|
tty_print_string (cp);
|
|
|
|
tty_setcolor (in->color[WINPUTC_MARK]);
|
|
|
|
if (m1 < in->term_first_shown)
|
|
|
|
{
|
2019-10-16 13:07:24 +03:00
|
|
|
widget_gotoyx (in, 0, 0);
|
2021-10-10 17:08:52 +03:00
|
|
|
m1 = in->term_first_shown;
|
|
|
|
m2 -= m1;
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-10-10 17:08:52 +03:00
|
|
|
int buf_width;
|
2010-11-12 11:03:57 +03:00
|
|
|
|
2019-10-16 13:07:24 +03:00
|
|
|
widget_gotoyx (in, 0, m1 - in->term_first_shown);
|
2021-10-10 17:08:52 +03:00
|
|
|
buf_width = str_term_width2 (in->buffer->str, m1);
|
|
|
|
m2 = MIN (m2 - m1,
|
|
|
|
(w->cols - has_history) - (buf_width - in->term_first_shown));
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
2021-10-10 17:08:52 +03:00
|
|
|
|
|
|
|
tty_print_string (str_term_substring (in->buffer->str, m1, m2));
|
2010-11-12 11:03:57 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
int i;
|
|
|
|
|
2021-10-10 17:08:52 +03:00
|
|
|
cp = str_term_substring (in->buffer->str, in->term_first_shown, w->cols - has_history);
|
2011-10-27 17:23:21 +04:00
|
|
|
tty_setcolor (in->color[WINPUTC_MAIN]);
|
2013-10-23 09:56:12 +04:00
|
|
|
for (i = 0; i < w->cols - has_history; i++)
|
2010-11-12 11:03:57 +03:00
|
|
|
{
|
2011-10-27 17:23:21 +04:00
|
|
|
if (i < (buf_len - in->term_first_shown) && cp[0] != '\0')
|
|
|
|
tty_print_char ('*');
|
|
|
|
else
|
|
|
|
tty_print_char (' ');
|
2010-11-12 11:03:57 +03:00
|
|
|
if (cp[0] != '\0')
|
|
|
|
str_cnext_char (&cp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
|
|
|
input_enable_update (WInput * in)
|
|
|
|
{
|
|
|
|
in->disable_update--;
|
|
|
|
input_update (in, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
void
|
|
|
|
input_disable_update (WInput * in)
|
|
|
|
{
|
|
|
|
in->disable_update++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-07-01 12:50:03 +04:00
|
|
|
/**
|
|
|
|
* Cleans the input line and adds the current text to the history
|
|
|
|
*
|
|
|
|
* @param in the input line
|
|
|
|
*/
|
2010-11-12 11:03:57 +03:00
|
|
|
void
|
|
|
|
input_clean (WInput * in)
|
|
|
|
{
|
2021-12-04 14:22:16 +03:00
|
|
|
input_push_history (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->need_push = TRUE;
|
2021-10-10 17:08:52 +03:00
|
|
|
g_string_set_size (in->buffer, 0);
|
2010-11-12 11:03:57 +03:00
|
|
|
in->point = 0;
|
|
|
|
in->charpoint = 0;
|
2014-08-02 17:39:04 +04:00
|
|
|
in->mark = -1;
|
2020-04-09 08:11:24 +03:00
|
|
|
input_complete_free (in);
|
2010-11-12 11:03:57 +03:00
|
|
|
input_update (in, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|