/* $Id: history.c,v 1.11 2003/09/26 17:59:51 ukai Exp $ */
#include "fm.h"
#ifdef USE_HISTORY
Buffer *
historyBuffer(Hist *hist)
{
Str src = Strnew();
HistItem *item;
char *p, *q;
/* FIXME: gettextize? */
Strcat_charp(src, "<html>\n<head><title>History Page</title></head>\n");
Strcat_charp(src, "<body>\n<h1>History Page</h1>\n<hr>\n");
Strcat_charp(src, "<ol>\n");
if (hist && hist->list) {
for (item = hist->list->last; item; item = item->prev) {
q = html_quote((char *)item->ptr);
if (DecodeURL)
p = html_quote(url_decode2((char *)item->ptr, NULL));
else
p = q;
Strcat_charp(src, "<li><a href=\"");
Strcat_charp(src, q);
Strcat_charp(src, "\">");
Strcat_charp(src, p);
Strcat_charp(src, "</a>\n");
}
}
Strcat_charp(src, "</ol>\n</body>\n</html>");
return loadHTMLString(src);
}
void
loadHistory(Hist *hist)
{
FILE *f;
Str line;
if (hist == NULL)
return;
if ((f = fopen(rcFile(HISTORY_FILE), "rt")) == NULL)
return;
while (!feof(f)) {
line = Strfgets(f);
Strchop(line);
Strremovefirstspaces(line);
Strremovetrailingspaces(line);
if (line->length == 0)
continue;
pushHist(hist, url_quote(line->ptr));
}
fclose(f);
}
void
saveHistory(Hist *hist, size_t size)
{
FILE *f;
HistItem *item;
char *tmpf;
if (hist == NULL || hist->list == NULL)
return;
tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
if ((f = fopen(tmpf, "w")) == NULL) {
/* FIXME: gettextize? */
disp_err_message("Can't open history", FALSE);
return;
}
for (item = hist->list->first; item && hist->list->nitem > size;
item = item->next)
size++;
for (; item; item = item->next)
fprintf(f, "%s\n", (char *)item->ptr);
if (fclose(f) == EOF) {
/* FIXME: gettextize? */
disp_err_message("Can't save history", FALSE);
return;
}
rename(tmpf, rcFile(HISTORY_FILE));
}
#endif /* USE_HISTORY */
Hist *
newHist()
{
Hist *hist;
hist = New(Hist);
hist->list = (HistList *)newGeneralList();
hist->current = NULL;
hist->hash = NULL;
return hist;
}
Hist *
copyHist(Hist *hist)
{
Hist *new;
HistItem *item;
if (hist == NULL)
return NULL;
new = newHist();
for (item = hist->list->first; item; item = item->next)
pushHist(new, (char *)item->ptr);
return new;
}
HistItem *
unshiftHist(Hist *hist, char *ptr)
{
HistItem *item;
if (hist == NULL || hist->list == NULL)
return NULL;
item = (HistItem *)newListItem((void *)allocStr(ptr, -1),
(ListItem *)hist->list->first, NULL);
if (hist->list->first)
hist->list->first->prev = item;
else
hist->list->last = item;
hist->list->first = item;
hist->list->nitem++;
return item;
}
HistItem *
pushHist(Hist *hist, char *ptr)
{
HistItem *item;
if (hist == NULL || hist->list == NULL)
return NULL;
item = (HistItem *)newListItem((void *)allocStr(ptr, -1),
NULL, (ListItem *)hist->list->last);
if (hist->list->last)
hist->list->last->next = item;
else
hist->list->first = item;
hist->list->last = item;
hist->list->nitem++;
return item;
}
/* Don't mix pushHashHist() and pushHist()/unshiftHist(). */
HistItem *
pushHashHist(Hist *hist, char *ptr)
{
HistItem *item;
if (hist == NULL || hist->list == NULL)
return NULL;
item = getHashHist(hist, ptr);
if (item) {
if (item->next)
item->next->prev = item->prev;
else /* item == hist->list->last */
hist->list->last = item->prev;
if (item->prev)
item->prev->next = item->next;
else /* item == hist->list->first */
hist->list->first = item->next;
hist->list->nitem--;
}
item = pushHist(hist, ptr);
putHash_sv(hist->hash, ptr, (void *)item);
return item;
}
HistItem *
getHashHist(Hist *hist, char *ptr)
{
HistItem *item;
if (hist == NULL || hist->list == NULL)
return NULL;
if (hist->hash == NULL) {
hist->hash = newHash_sv(HIST_HASH_SIZE);
for (item = hist->list->first; item; item = item->next)
putHash_sv(hist->hash, (char *)item->ptr, (void *)item);
}
return (HistItem *)getHash_sv(hist->hash, ptr, NULL);
}
char *
lastHist(Hist *hist)
{
if (hist == NULL || hist->list == NULL)
return NULL;
if (hist->list->last) {
hist->current = hist->list->last;
return (char *)hist->current->ptr;
}
return NULL;
}
char *
nextHist(Hist *hist)
{
if (hist == NULL || hist->list == NULL)
return NULL;
if (hist->current && hist->current->next) {
hist->current = hist->current->next;
return (char *)hist->current->ptr;
}
return NULL;
}
char *
prevHist(Hist *hist)
{
if (hist == NULL || hist->list == NULL)
return NULL;
if (hist->current && hist->current->prev) {
hist->current = hist->current->prev;
return (char *)hist->current->ptr;
}
return NULL;
}