Merge branch '2313_history'

* 2313_history:
  Handle directory history of panel.
  Handle history of input line.
  Ticket #2313: CK_History removes CK_HistoryNext entries
This commit is contained in:
Andrew Borodin 2012-06-11 15:02:46 +04:00
commit d7a1af740e
6 changed files with 109 additions and 69 deletions

View File

@ -2,7 +2,7 @@
Widgets for the Midnight Commander Widgets for the Midnight Commander
Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, Copyright (C) 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2009, 2010, 2011 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2012
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
Authors: Authors:
@ -11,7 +11,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 Andrew Borodin <aborodin@vmail.ru>, 2009, 2010, 2011, 2012
This file is part of the Midnight Commander. This file is part of the Midnight Commander.
@ -287,7 +287,7 @@ history_save (struct mc_config_t *cfg, const char *name, GList * h)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
char * char *
history_show (GList ** history, Widget * widget) history_show (GList ** history, Widget * widget, int current)
{ {
GList *z, *hlist = NULL, *hi; GList *z, *hlist = NULL, *hi;
size_t maxlen, i, count = 0; size_t maxlen, i, count = 0;
@ -342,7 +342,10 @@ history_show (GList ** history, Widget * widget)
{ {
/* draw list entries from bottom upto top */ /* draw list entries from bottom upto top */
listbox_set_list (query_list, hlist); listbox_set_list (query_list, hlist);
listbox_select_last (query_list); if (current < 0 || (size_t) current >= count)
listbox_select_last (query_list);
else
listbox_select_entry (query_list, count - 1 - (size_t) current);
} }
else else
{ {
@ -350,6 +353,8 @@ history_show (GList ** history, Widget * widget)
/* revert history direction */ /* revert history direction */
hlist = g_list_reverse (hlist); hlist = g_list_reverse (hlist);
listbox_set_list (query_list, hlist); listbox_set_list (query_list, hlist);
if (current > 0)
listbox_select_entry (query_list, current);
} }
if (run_dlg (query_dlg) != B_CANCEL) if (run_dlg (query_dlg) != B_CANCEL)

View File

@ -29,7 +29,7 @@ GList *history_load (struct mc_config_t * cfg, const char *name);
void history_save (struct mc_config_t * cfg, const char *name, GList * h); void history_save (struct mc_config_t * cfg, const char *name, GList * h);
/* for repositioning of history dialog we should pass widget to this /* for repositioning of history dialog we should pass widget to this
* function, as position of history dialog depends on widget's position */ * function, as position of history dialog depends on widget's position */
char *history_show (GList ** history, Widget * widget); char *history_show (GList ** history, Widget * widget, int current);
/*** inline functions ****************************************************************************/ /*** inline functions ****************************************************************************/

View File

@ -105,7 +105,13 @@ draw_history_button (WInput * in)
char c; char c;
gboolean disabled = (((Widget *) in)->options & W_DISABLED) != 0; gboolean disabled = (((Widget *) in)->options & W_DISABLED) != 0;
c = in->history->next ? (in->history->prev ? '|' : 'v') : '^'; if (g_list_next (in->history_current) == NULL)
c = '^';
else if (g_list_previous (in->history_current) == NULL)
c = 'v';
else
c = '|';
widget_move (&in->widget, 0, in->field_width - HISTORY_BUTTON_WIDTH); widget_move (&in->widget, 0, in->field_width - HISTORY_BUTTON_WIDTH);
tty_setcolor (disabled ? DISABLED_COLOR : in->color[WINPUTC_HISTORY]); tty_setcolor (disabled ? DISABLED_COLOR : in->color[WINPUTC_HISTORY]);
#ifdef LARGE_HISTORY_BUTTON #ifdef LARGE_HISTORY_BUTTON
@ -191,7 +197,7 @@ do_show_hist (WInput * in)
len = get_history_length (in->history); len = get_history_length (in->history);
r = history_show (&in->history, &in->widget); r = history_show (&in->history, &in->widget, g_list_position (in->history_current, in->history));
if (r != NULL) if (r != NULL)
{ {
input_assign_text (in, r); input_assign_text (in, r);
@ -268,6 +274,7 @@ push_history (WInput * in, const char *text)
in->history_changed) in->history_changed)
{ {
in->history = list_append_unique (in->history, t); in->history = list_append_unique (in->history, t);
in->history_current = in->history;
in->history_changed = TRUE; in->history_changed = TRUE;
} }
else else
@ -628,12 +635,12 @@ hist_prev (WInput * in)
if (in->need_push) if (in->need_push)
push_history (in, in->buffer); push_history (in, in->buffer);
prev = g_list_previous (in->history); prev = g_list_previous (in->history_current);
if (prev != NULL) if (prev != NULL)
{ {
in->history = prev;
in->history_changed = TRUE;
input_assign_text (in, (char *) prev->data); input_assign_text (in, (char *) prev->data);
in->history_current = prev;
in->history_changed = TRUE;
in->need_push = FALSE; in->need_push = FALSE;
} }
} }
@ -655,14 +662,17 @@ hist_next (WInput * in)
if (in->history == NULL) if (in->history == NULL)
return; return;
next = g_list_next (in->history); next = g_list_next (in->history_current);
if (next == NULL) if (next == NULL)
{
input_assign_text (in, ""); input_assign_text (in, "");
in->history_current = in->history;
}
else else
{ {
in->history = next;
in->history_changed = TRUE;
input_assign_text (in, (char *) next->data); input_assign_text (in, (char *) next->data);
in->history_current = next;
in->history_changed = TRUE;
in->need_push = FALSE; in->need_push = FALSE;
} }
} }
@ -826,6 +836,7 @@ input_load_history (const gchar * event_group_name, const gchar * event_name,
(void) event_name; (void) event_name;
in->history = history_load (ev->cfg, in->history_name); in->history = history_load (ev->cfg, in->history_name);
in->history_current = in->history;
if (in->init_text == NULL) if (in->init_text == NULL)
def_text = ""; def_text = "";
@ -1005,6 +1016,7 @@ input_new (int y, int x, const int *input_colors, int width, const char *def_tex
/* prepare to history setup */ /* prepare to history setup */
in->history = NULL; in->history = NULL;
in->history_current = NULL;
in->history_changed = FALSE; in->history_changed = FALSE;
in->history_name = NULL; in->history_name = NULL;
if ((histname != NULL) && (*histname != '\0')) if ((histname != NULL) && (*histname != '\0'))
@ -1182,12 +1194,13 @@ input_assign_text (WInput * in, const char *text)
{ {
input_free_completions (in); input_free_completions (in);
g_free (in->buffer); g_free (in->buffer);
in->buffer = g_strdup (text); /* was in->buffer->text */ in->current_max_size = strlen (text) + 1;
in->current_max_size = strlen (in->buffer) + 1; in->buffer = g_strndup (text, in->current_max_size); /* was in->buffer->text */
in->point = str_length (in->buffer); in->point = str_length (in->buffer);
in->mark = 0; in->mark = 0;
in->need_push = TRUE; in->need_push = TRUE;
in->charpoint = 0; in->charpoint = 0;
input_update (in, TRUE);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

View File

@ -60,6 +60,7 @@ typedef struct
char *buffer; /* pointer to editing buffer */ char *buffer; /* pointer to editing buffer */
char *history_name; /* name of history for loading and saving */ char *history_name; /* name of history for loading and saving */
GList *history; /* the history */ GList *history; /* the history */
GList *history_current; /* current history item */
gboolean history_changed; /* the history has changed */ gboolean history_changed; /* the history has changed */
gboolean need_push; /* need to push the current Input on hist? */ gboolean need_push; /* need to push the current Input on hist? */
gboolean strip_password; /* need to strip password before placing string to history */ gboolean strip_password; /* need to strip password before placing string to history */

View File

@ -1382,6 +1382,18 @@ panel_save_name (WPanel * panel)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static void
directory_history_add (struct WPanel *panel, const vfs_path_t * vpath)
{
char *tmp;
tmp = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
panel->dir_history = list_append_unique (panel->dir_history, tmp);
panel->dir_history_current = panel->dir_history;
}
/* --------------------------------------------------------------------------------------------- */
/* "history_load" event handler */ /* "history_load" event handler */
static gboolean static gboolean
panel_load_history (const gchar * event_group_name, const gchar * event_name, panel_load_history (const gchar * event_group_name, const gchar * event_name,
@ -1395,16 +1407,12 @@ panel_load_history (const gchar * event_group_name, const gchar * event_name,
if (ev->receiver == NULL || ev->receiver == (Widget *) p) if (ev->receiver == NULL || ev->receiver == (Widget *) p)
{ {
char *tmp_path;
tmp_path = vfs_path_to_str (p->cwd_vpath);
if (ev->cfg != NULL) if (ev->cfg != NULL)
p->dir_history = history_load (ev->cfg, p->hist_name); p->dir_history = history_load (ev->cfg, p->hist_name);
else else
p->dir_history = history_get (p->hist_name); p->dir_history = history_get (p->hist_name);
directory_history_add (p, tmp_path); directory_history_add (p, p->cwd_vpath);
g_free (tmp_path);
} }
return TRUE; return TRUE;
@ -3074,18 +3082,26 @@ _do_panel_cd (WPanel * panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_
static void static void
directory_history_next (WPanel * panel) directory_history_next (WPanel * panel)
{ {
GList *nextdir; gboolean ok;
nextdir = g_list_next (panel->dir_history); do
if (nextdir != NULL)
{ {
vfs_path_t *data_vpath; GList *next;
data_vpath = vfs_path_from_str ((char *) nextdir->data); ok = TRUE;
if (_do_panel_cd (panel, data_vpath, cd_exact)) next = g_list_next (panel->dir_history_current);
panel->dir_history = nextdir; if (next != NULL)
vfs_path_free (data_vpath); {
vfs_path_t *data_vpath;
data_vpath = vfs_path_from_str ((char *) next->data);
ok = _do_panel_cd (panel, data_vpath, cd_exact);
vfs_path_free (data_vpath);
panel->dir_history_current = next;
}
/* skip directories that present in history but absent in file system */
} }
while (!ok);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -3093,19 +3109,26 @@ directory_history_next (WPanel * panel)
static void static void
directory_history_prev (WPanel * panel) directory_history_prev (WPanel * panel)
{ {
GList *prevdir; gboolean ok;
prevdir = g_list_previous (panel->dir_history); do
if (prevdir != NULL)
{ {
vfs_path_t *data_vpath; GList *prev;
data_vpath = vfs_path_from_str ((char *) prevdir->data); ok = TRUE;
if (_do_panel_cd (panel, data_vpath, cd_exact)) prev = g_list_previous (panel->dir_history_current);
panel->dir_history = prevdir; if (prev != NULL)
vfs_path_free (data_vpath); {
vfs_path_t *data_vpath;
data_vpath = vfs_path_from_str ((char *) prev->data);
ok = _do_panel_cd (panel, data_vpath, cd_exact);
vfs_path_free (data_vpath);
panel->dir_history_current = prev;
}
/* skip directories that present in history but absent in file system */
} }
while (!ok);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -3114,27 +3137,46 @@ static void
directory_history_list (WPanel * panel) directory_history_list (WPanel * panel)
{ {
char *s; char *s;
gboolean ok = FALSE;
size_t pos;
s = history_show (&panel->dir_history, &panel->widget); pos = g_list_position (panel->dir_history_current, panel->dir_history);
s = history_show (&panel->dir_history, &panel->widget, pos);
if (s != NULL) if (s != NULL)
{ {
vfs_path_t *s_vpath; vfs_path_t *s_vpath;
s_vpath = vfs_path_from_str (s); s_vpath = vfs_path_from_str (s);
if (_do_panel_cd (panel, s_vpath, cd_exact)) ok = _do_panel_cd (panel, s_vpath, cd_exact);
{ if (ok)
char *tmp_path; directory_history_add (panel, panel->cwd_vpath);
tmp_path = vfs_path_to_str (panel->cwd_vpath);
directory_history_add (panel, tmp_path);
g_free (tmp_path);
}
else else
message (D_ERROR, MSG_ERROR, _("Cannot change directory")); message (D_ERROR, MSG_ERROR, _("Cannot change directory"));
vfs_path_free (s_vpath); vfs_path_free (s_vpath);
g_free (s); g_free (s);
} }
if (!ok)
{
/* Since history is fully modified in history_show(), panel->dir_history actually
* points to the invalid place. Try restore current postition here. */
size_t i;
panel->dir_history_current = panel->dir_history;
for (i = 0; i <= pos; i++)
{
GList *prev;
prev = g_list_previous (panel->dir_history_current);
if (prev == NULL)
break;
panel->dir_history_current = prev;
}
}
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -4407,13 +4449,7 @@ do_panel_cd (struct WPanel *panel, const vfs_path_t * new_dir_vpath, enum cd_enu
r = _do_panel_cd (panel, new_dir_vpath, cd_type); r = _do_panel_cd (panel, new_dir_vpath, cd_type);
if (r) if (r)
{ directory_history_add (panel, panel->cwd_vpath);
char *tmp_path;
tmp_path = vfs_path_to_str (panel->cwd_vpath);
directory_history_add (panel, tmp_path);
g_free (tmp_path);
}
return r; return r;
} }
@ -4571,20 +4607,6 @@ update_panels (panel_update_flags_t flags, const char *current_file)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
void
directory_history_add (struct WPanel *panel, const char *dir)
{
vfs_path_t *vpath;
char *tmp;
vpath = vfs_path_from_str (dir);
tmp = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD);
vfs_path_free (vpath);
panel->dir_history = list_append_unique (panel->dir_history, tmp);
}
/* --------------------------------------------------------------------------------------------- */
gsize gsize
panel_get_num_of_sortable_fields (void) panel_get_num_of_sortable_fields (void)
{ {

View File

@ -91,6 +91,7 @@ typedef struct WPanel
vfs_path_t *cwd_vpath; /* Current Working Directory */ vfs_path_t *cwd_vpath; /* Current Working Directory */
vfs_path_t *lwd_vpath; /* Last Working Directory */ vfs_path_t *lwd_vpath; /* Last Working Directory */
GList *dir_history; /* directory history */ GList *dir_history; /* directory history */
GList *dir_history_current; /* pointer to the current history item */
char *hist_name; /* directory history name for history file */ char *hist_name; /* directory history name for history file */
int count; /* Number of files in dir structure */ int count; /* Number of files in dir structure */
int marked; /* Count of marked files */ int marked; /* Count of marked files */
@ -163,8 +164,6 @@ void do_file_mark (WPanel * panel, int idx, int val);
gboolean do_panel_cd (struct WPanel *panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type); gboolean do_panel_cd (struct WPanel *panel, const vfs_path_t * new_dir_vpath, enum cd_enum cd_type);
void directory_history_add (struct WPanel *panel, const char *dir);
vfs_path_t *remove_encoding_from_path (const vfs_path_t * vpath); vfs_path_t *remove_encoding_from_path (const vfs_path_t * vpath);
gsize panel_get_num_of_sortable_fields (void); gsize panel_get_num_of_sortable_fields (void);