Optimization of history load.
Formerly, each widget loaded its history self in its constructor. Thus, history file was read as many times as many widgets with history are in dialog. Now all widget histories are read from ${XDG_CACHE_HOME}/mc/history file at one time after dialog initialization. The ev_history_load_save_t event is apllied to load histories. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Этот коммит содержится в:
родитель
cff5925598
Коммит
82b27ead4d
@ -14,6 +14,7 @@
|
||||
#define MCEVENT_GROUP_VIEWER "Viewer"
|
||||
|
||||
/* Events */
|
||||
#define MCEVENT_HISTORY_LOAD "history_load"
|
||||
#define MCEVENT_HISTORY_SAVE "history_save"
|
||||
|
||||
/*** enums ***************************************************************************************/
|
||||
@ -65,6 +66,7 @@ typedef struct
|
||||
} ret;
|
||||
} ev_background_parent_call_t;
|
||||
|
||||
/* MCEVENT_GROUP_DIALOG:history_load */
|
||||
/* MCEVENT_GROUP_DIALOG:history_save */
|
||||
struct mc_config_t;
|
||||
struct Widget;
|
||||
|
@ -142,6 +142,31 @@ dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t msg, gboolean reverse, int flag
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Read histories from the ${XDG_CACHE_HOME}/mc/history file
|
||||
*/
|
||||
static void
|
||||
dlg_read_history (Dlg_head * h)
|
||||
{
|
||||
char *profile;
|
||||
ev_history_load_save_t event_data;
|
||||
|
||||
if (num_history_items_recorded == 0) /* this is how to disable */
|
||||
return;
|
||||
|
||||
profile = g_build_filename (mc_config_get_cache_path (), MC_HISTORY_FILE, NULL);
|
||||
event_data.cfg = mc_config_init (profile);
|
||||
event_data.receiver = NULL;
|
||||
|
||||
/* create all histories in dialog */
|
||||
mc_event_raise (h->event_group, MCEVENT_HISTORY_LOAD, &event_data);
|
||||
|
||||
mc_config_deinit (event_data.cfg);
|
||||
g_free (profile);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
dlg_unfocus (Dlg_head * h)
|
||||
{
|
||||
@ -1082,6 +1107,7 @@ init_dlg (Dlg_head * h)
|
||||
|
||||
h->callback (h, NULL, DLG_INIT, 0, NULL);
|
||||
dlg_broadcast_msg (h, WIDGET_INIT, FALSE);
|
||||
dlg_read_history (h);
|
||||
}
|
||||
|
||||
h->state = DLG_ACTIVE;
|
||||
|
@ -130,22 +130,17 @@ history_dlg_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, vo
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
This loads the history of an input line to the widget. It is called
|
||||
with the widgets history name on creation of the widget, and returns
|
||||
the GList list.
|
||||
/**
|
||||
* Load the history from the ${XDG_CACHE_HOME}/mc/history file.
|
||||
* It is called with the widgets history name and returns the GList list.
|
||||
*/
|
||||
|
||||
GList *
|
||||
history_get (const char *input_name)
|
||||
{
|
||||
size_t i;
|
||||
GList *hist = NULL;
|
||||
char *profile;
|
||||
mc_config_t *cfg;
|
||||
char **keys;
|
||||
size_t keys_num = 0;
|
||||
GIConv conv = INVALID_CONV;
|
||||
GString *buffer;
|
||||
|
||||
if (num_history_items_recorded == 0) /* this is how to disable */
|
||||
return NULL;
|
||||
@ -155,8 +150,34 @@ history_get (const char *input_name)
|
||||
profile = g_build_filename (mc_config_get_cache_path (), MC_HISTORY_FILE, NULL);
|
||||
cfg = mc_config_init (profile);
|
||||
|
||||
hist = history_load (cfg, input_name);
|
||||
|
||||
mc_config_deinit (cfg);
|
||||
g_free (profile);
|
||||
|
||||
return hist;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Load history form the mc_config
|
||||
*/
|
||||
GList *
|
||||
history_load (struct mc_config_t * cfg, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
GList *hist = NULL;
|
||||
char **keys;
|
||||
size_t keys_num = 0;
|
||||
GIConv conv = INVALID_CONV;
|
||||
GString *buffer;
|
||||
|
||||
if (name == NULL || *name == '\0')
|
||||
return NULL;
|
||||
|
||||
/* get number of keys */
|
||||
keys = mc_config_get_keys (cfg, input_name, &keys_num);
|
||||
keys = mc_config_get_keys (cfg, name, &keys_num);
|
||||
g_strfreev (keys);
|
||||
|
||||
/* create charset conversion handler to convert strings
|
||||
@ -172,7 +193,7 @@ history_get (const char *input_name)
|
||||
char *this_entry;
|
||||
|
||||
g_snprintf (key, sizeof (key), "%lu", (unsigned long) i);
|
||||
this_entry = mc_config_get_string_raw (cfg, input_name, key, "");
|
||||
this_entry = mc_config_get_string_raw (cfg, name, key, "");
|
||||
|
||||
if (this_entry == NULL)
|
||||
continue;
|
||||
@ -195,8 +216,6 @@ history_get (const char *input_name)
|
||||
g_string_free (buffer, TRUE);
|
||||
if (conv != INVALID_CONV)
|
||||
str_close_conv (conv);
|
||||
mc_config_deinit (cfg);
|
||||
g_free (profile);
|
||||
|
||||
/* return pointer to the last entry in the list */
|
||||
return g_list_last (hist);
|
||||
|
@ -21,7 +21,10 @@ extern int num_history_items_recorded;
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
||||
/* read history to the mc_config, but don't save config to file */
|
||||
GList *history_get (const char *input_name);
|
||||
/* load history form the mc_config */
|
||||
GList *history_load (struct mc_config_t * cfg, const char *name);
|
||||
/* save history to the mc_config, but don't save config to file */
|
||||
void history_save (struct mc_config_t * cfg, const char *name, GList * h);
|
||||
#if 0
|
||||
|
@ -758,6 +758,48 @@ input_execute_cmd (WInput * in, unsigned long command)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* "history_load" event handler */
|
||||
static gboolean
|
||||
input_load_history (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WInput *in = (WInput *) init_data;
|
||||
ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
|
||||
const char *def_text;
|
||||
size_t buffer_len;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
|
||||
in->history = history_load (ev->cfg, in->history_name);
|
||||
|
||||
if (in->init_text == NULL)
|
||||
def_text = "";
|
||||
else if (in->init_text == INPUT_LAST_TEXT)
|
||||
{
|
||||
if (in->history != NULL && in->history->data != NULL)
|
||||
def_text = (const char *) in->history->data;
|
||||
else
|
||||
def_text = "";
|
||||
|
||||
in->init_text = NULL;
|
||||
}
|
||||
else
|
||||
def_text = in->init_text;
|
||||
|
||||
buffer_len = strlen (def_text);
|
||||
buffer_len = 1 + max ((size_t) in->field_width, buffer_len);
|
||||
in->current_max_size = buffer_len;
|
||||
if (buffer_len > (size_t) in->field_width)
|
||||
in->buffer = g_realloc (in->buffer, buffer_len);
|
||||
strcpy (in->buffer, def_text);
|
||||
in->point = str_length (in->buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* "history_save" event handler */
|
||||
static gboolean
|
||||
input_save_history (const gchar * event_group_name, const gchar * event_name,
|
||||
@ -801,10 +843,11 @@ input_destroy (WInput * in)
|
||||
g_list_foreach (in->history, (GFunc) g_free, NULL);
|
||||
g_list_free (in->history);
|
||||
}
|
||||
g_free (in->history_name);
|
||||
|
||||
g_free (in->buffer);
|
||||
input_free_completions (in);
|
||||
g_free (in->history_name);
|
||||
g_free (in->init_text);
|
||||
|
||||
g_free (kill_buffer);
|
||||
kill_buffer = NULL;
|
||||
@ -866,37 +909,11 @@ WInput *
|
||||
input_new (int y, int x, const int *input_colors, int width, const char *def_text,
|
||||
const char *histname, input_complete_t completion_flags)
|
||||
{
|
||||
WInput *in = g_new (WInput, 1);
|
||||
size_t initial_buffer_len;
|
||||
WInput *in;
|
||||
|
||||
in = g_new (WInput, 1);
|
||||
init_widget (&in->widget, y, x, 1, width, input_callback, input_event);
|
||||
|
||||
/* history setup */
|
||||
in->history_name = NULL;
|
||||
in->history = NULL;
|
||||
if ((histname != NULL) && (*histname != '\0'))
|
||||
{
|
||||
in->history_name = g_strdup (histname);
|
||||
in->history = history_get (histname);
|
||||
}
|
||||
|
||||
if (def_text == NULL)
|
||||
def_text = "";
|
||||
else if (def_text == INPUT_LAST_TEXT)
|
||||
{
|
||||
if ((in->history != NULL) && (in->history->data != NULL))
|
||||
def_text = (char *) in->history->data;
|
||||
else
|
||||
def_text = "";
|
||||
}
|
||||
|
||||
initial_buffer_len = strlen (def_text);
|
||||
initial_buffer_len = 1 + max ((size_t) width, initial_buffer_len);
|
||||
in->widget.options |= W_IS_INPUT;
|
||||
in->completions = NULL;
|
||||
in->completion_flags = completion_flags;
|
||||
in->current_max_size = initial_buffer_len;
|
||||
in->buffer = g_new (char, initial_buffer_len);
|
||||
|
||||
memmove (in->color, input_colors, sizeof (input_colors_t));
|
||||
|
||||
@ -908,11 +925,26 @@ input_new (int y, int x, const int *input_colors, int width, const char *def_tex
|
||||
in->mark = 0;
|
||||
in->need_push = TRUE;
|
||||
in->is_password = FALSE;
|
||||
|
||||
strcpy (in->buffer, def_text);
|
||||
in->point = str_length (in->buffer);
|
||||
in->charpoint = 0;
|
||||
|
||||
/* in->buffer will be corrected in "history_load" event handler */
|
||||
in->current_max_size = width + 1;
|
||||
in->buffer = g_new0 (char, in->current_max_size);
|
||||
in->point = 0;
|
||||
|
||||
in->init_text = (def_text == INPUT_LAST_TEXT) ? INPUT_LAST_TEXT : g_strdup (def_text);
|
||||
|
||||
in->completions = NULL;
|
||||
in->completion_flags = completion_flags;
|
||||
|
||||
/* prepare to history setup */
|
||||
in->history_name = NULL;
|
||||
in->history = NULL;
|
||||
if ((histname != NULL) && (*histname != '\0'))
|
||||
in->history_name = g_strdup (histname);
|
||||
|
||||
/* history will be loaded later */
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
@ -927,6 +959,8 @@ input_callback (Widget * w, widget_msg_t msg, int parm)
|
||||
switch (msg)
|
||||
{
|
||||
case WIDGET_INIT:
|
||||
/* subscribe to "history_load" event */
|
||||
mc_event_add (w->owner->event_group, MCEVENT_HISTORY_LOAD, input_load_history, w, NULL);
|
||||
/* subscribe to "history_save" event */
|
||||
mc_event_add (w->owner->event_group, MCEVENT_HISTORY_SAVE, input_save_history, w, NULL);
|
||||
return MSG_HANDLED;
|
||||
@ -971,6 +1005,8 @@ input_callback (Widget * w, widget_msg_t msg, int parm)
|
||||
return MSG_HANDLED;
|
||||
|
||||
case WIDGET_DESTROY:
|
||||
/* unsubscribe from "history_load" event */
|
||||
mc_event_del (w->owner->event_group, MCEVENT_HISTORY_LOAD, input_load_history, w);
|
||||
/* unsubscribe from "history_save" event */
|
||||
mc_event_del (w->owner->event_group, MCEVENT_HISTORY_SAVE, input_save_history, w);
|
||||
input_destroy (in);
|
||||
|
@ -46,22 +46,23 @@ typedef int input_colors_t[WINPUTC_COUNT_COLORS];
|
||||
typedef struct
|
||||
{
|
||||
Widget widget;
|
||||
input_colors_t color;
|
||||
int point; /* cursor position in the input line in characters */
|
||||
int mark; /* the mark position in characters */
|
||||
gboolean highlight; /* there is a selected block */
|
||||
int term_first_shown; /* column of the first shown character */
|
||||
size_t current_max_size; /* maximum length of input line (bytes) */
|
||||
int field_width; /* width of the editing field */
|
||||
input_colors_t color;
|
||||
gboolean first; /* is first keystroke? */
|
||||
int disable_update; /* do we want to skip updates? */
|
||||
gboolean is_password; /* is this a password input line? */
|
||||
char *init_text; /* initial text of input line */
|
||||
char *buffer; /* pointer to editing buffer */
|
||||
char *history_name; /* name of history for loading and saving */
|
||||
GList *history; /* the history */
|
||||
gboolean need_push; /* need to push the current Input on hist? */
|
||||
char **completions; /* possible completions array */
|
||||
input_complete_t completion_flags;
|
||||
char *history_name; /* name of history for loading and saving */
|
||||
char charbuf[MB_LEN_MAX]; /* buffer for multibytes characters */
|
||||
size_t charpoint; /* point to end of mulibyte sequence in charbuf */
|
||||
} WInput;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "lib/vfs/vfs.h" /* For vfs_translate_url() */
|
||||
#include "lib/strutil.h"
|
||||
#include "lib/widget.h"
|
||||
#include "lib/event.h"
|
||||
|
||||
#include "src/consaver/cons.saver.h"
|
||||
#include "src/viewer/mcviewer.h" /* The view widget */
|
||||
@ -911,6 +912,14 @@ set_display_type (int num, panel_view_mode_t type)
|
||||
{
|
||||
WPanel *panel = (WPanel *) new_widget;
|
||||
|
||||
/* if existing panel changed type to view_listing, then load history */
|
||||
if (old_widget != NULL)
|
||||
{
|
||||
ev_history_load_save_t event_data = { NULL, new_widget };
|
||||
|
||||
mc_event_raise (midnight_dlg->event_group, MCEVENT_HISTORY_LOAD, &event_data);
|
||||
}
|
||||
|
||||
if (num == 0)
|
||||
left_panel = panel;
|
||||
else
|
||||
|
@ -1187,6 +1187,32 @@ panel_save_name (WPanel * panel)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* "history_load" event handler */
|
||||
static gboolean
|
||||
panel_load_history (const gchar * event_group_name, const gchar * event_name,
|
||||
gpointer init_data, gpointer data)
|
||||
{
|
||||
WPanel *p = (WPanel *) init_data;
|
||||
ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
|
||||
|
||||
(void) event_group_name;
|
||||
(void) event_name;
|
||||
|
||||
if (ev->receiver == NULL || ev->receiver == (Widget *) p)
|
||||
{
|
||||
if (ev->cfg != NULL)
|
||||
p->dir_history = history_load (ev->cfg, p->hist_name);
|
||||
else
|
||||
p->dir_history = history_get (p->hist_name);
|
||||
|
||||
directory_history_add (p, p->cwd);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* "history_save" event handler */
|
||||
static gboolean
|
||||
panel_save_history (const gchar * event_group_name, const gchar * event_name,
|
||||
@ -2930,6 +2956,8 @@ panel_callback (Widget * w, widget_msg_t msg, int parm)
|
||||
switch (msg)
|
||||
{
|
||||
case WIDGET_INIT:
|
||||
/* subscribe to "history_load" event */
|
||||
mc_event_add (w->owner->event_group, MCEVENT_HISTORY_LOAD, panel_load_history, w, NULL);
|
||||
/* subscribe to "history_save" event */
|
||||
mc_event_add (w->owner->event_group, MCEVENT_HISTORY_SAVE, panel_save_history, w, NULL);
|
||||
return MSG_HANDLED;
|
||||
@ -2982,6 +3010,8 @@ panel_callback (Widget * w, widget_msg_t msg, int parm)
|
||||
return panel_execute_cmd (panel, parm);
|
||||
|
||||
case WIDGET_DESTROY:
|
||||
/* unsubscribe from "history_load" event */
|
||||
mc_event_del (w->owner->event_group, MCEVENT_HISTORY_LOAD, panel_load_history, w);
|
||||
/* unsubscribe from "history_save" event */
|
||||
mc_event_del (w->owner->event_group, MCEVENT_HISTORY_SAVE, panel_save_history, w);
|
||||
panel_destroy (panel);
|
||||
@ -3578,8 +3608,7 @@ panel_new_with_dir (const char *panel_name, const char *wpath)
|
||||
strcpy (panel->lwd, ".");
|
||||
|
||||
panel->hist_name = g_strconcat ("Dir Hist ", panel_name, (char *) NULL);
|
||||
panel->dir_history = history_get (panel->hist_name);
|
||||
directory_history_add (panel, panel->cwd);
|
||||
/* directories history will be get later */
|
||||
|
||||
panel->dir.list = g_new (file_entry, MIN_FILES);
|
||||
panel->dir.size = MIN_FILES;
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user