⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bookmarks.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
字号:
/* bookmarks.c * (c) 2002 Petr 'Brain' Kulhavy, Karel 'Clock' Kulhavy * This file is a part of the Links program, released under GPL. */#include <stdio.h>#include <string.h>#include "links.h"#define SEARCH_IN_URL#ifdef SEARCH_IN_URL#define SHOW_URL#endifint bookmarks_codepage=0;int can_write_bookmarks=0;	/* global flag if we can write bookmarks */unsigned char bookmarks_file[MAX_STR_LEN]="";void *bookmark_new_item(void *);unsigned char *bookmark_type_item(struct terminal *, void *, int);void bookmark_delete_item(void *);void bookmark_edit_item(struct dialog_data *,void *,void (*)(struct dialog_data *,void *,void *,struct list_description *),void *, unsigned char);void bookmark_copy_item(void *, void *);void bookmark_goto_item(struct session *, void *);void *bookmark_default_value(struct session*, unsigned char);void *bookmark_find_item(void *start, unsigned char *str, int direction);void free_bookmarks(void);void bookmark_edit_item_fn(struct dialog_data *);void bookmark_edit_done(void *);void bookmark_edit_abort(struct dialog_data *);struct bookmark_list *previous_on_this_level(struct bookmark_list *);void add_bookmark(unsigned char *, unsigned char *, int);void create_initial_bookmarks(void);void load_bookmarks(void);struct list bookmarks={&bookmarks,&bookmarks,0,-1,NULL};struct history bookmark_search_history = { 0, { &bookmark_search_history.items, &bookmark_search_history.items } };/* when you change anything, don't forget to change it in reinit_bookmarks too !*/struct bookmark_ok_struct{	void (*fn)(struct dialog_data *,void *,void *,struct list_description *);	void *data;		struct dialog_data *dlg;};struct bookmark_list{	/* common for all lists */	struct bookmark_list *next;	struct bookmark_list *prev;	unsigned char type;  	int depth;	void *fotr;	/* bookmark specific */	unsigned char *title;	unsigned char *url;};struct list_description bookmark_ld={	1,  /* 0= flat; 1=tree */	&bookmarks,  /* list */	bookmark_new_item,	/* no codepage translations */	bookmark_edit_item,	/* translate when create dialog and translate back when ok is pressed */	bookmark_default_value,	/* codepage translation from current_page_encoding to UTF8 */	bookmark_delete_item,	/* no codepage translations */	bookmark_copy_item,	/* no codepage translations */	bookmark_type_item,	/* no codepage translations (bookmarks are internally in UTF8) */	bookmark_find_item,	&bookmark_search_history,	0,		/* this is set in init_bookmarks function */	60,  /* width of main window */	15,  /* # of items in main window */	T_BOOKMARK,	T_BOOKMARKS_ALREADY_IN_USE,	T_BOOKMARK_MANAGER,	T_DELETE_BOOKMARK,	T_GOTO,	bookmark_goto_item,	/* FIXME: should work (URL in UTF8), but who knows? */	0,0,0,0,  /* internal vars */	0, /* modified */	NULL,	NULL,	0,};struct kawasaki{	unsigned char *title;	unsigned char *url;};/* clears the bookmark list */void free_bookmarks(void) {	struct bookmark_list *bm;	foreach(bm, bookmarks) {		mem_free(bm->title);		mem_free(bm->url);	}	free_list(bookmarks);	free_list(bookmark_search_history.items);}/* called before exiting the links */void finalize_bookmarks(void){	save_bookmarks();	free_bookmarks();}/* allocates struct kawasaki and puts current page title and url *//* type: 0=item, 1=directory *//* on error returns NULL */void *bookmark_default_value(struct session *ses, unsigned char type){	struct kawasaki *zelena;	unsigned char *txt;	txt=mem_alloc(MAX_STR_LEN);		zelena=mem_alloc(sizeof(struct kawasaki));	zelena->url=NULL;	zelena->title=NULL;	if (get_current_url(ses,txt,MAX_STR_LEN))	{		if (ses->screen->f_data)		{			struct conv_table* ct;						ct=get_translation_table(ses->term->spec->charset,bookmark_ld.codepage);			zelena->url=convert_string(ct,txt,strlen(txt),NULL);			clr_white(zelena->url);		}		else			zelena->url=stracpy(txt);	}	if (get_current_title(ses,txt,MAX_STR_LEN))  /* ses->screen->f_data must exist here */	{		struct conv_table* ct;				ct=get_translation_table(ses->term->spec->charset,bookmark_ld.codepage);		zelena->title=convert_string(ct,txt,strlen(txt),NULL);		clr_white(zelena->title);	}	mem_free(txt);	return zelena;}void bookmark_copy_item(void *in, void *out){	struct bookmark_list *item_in=(struct bookmark_list*)in;	struct bookmark_list *item_out=(struct bookmark_list*)out;	item_out->type=item_in->type;	item_out->depth=item_in->depth;	if (item_out->title)	{		mem_free(item_out->title);		item_out->title=stracpy(item_in->title);	}	else internal("Bookmarks inconsistency.\n");	if (item_out->url)	{		mem_free(item_out->url);		item_out->url=stracpy(item_in->url);	}	else internal("Bookmarks inconsistency.\n");	return;}unsigned char *bm_add_msg[] = {	TEXT(T_NNAME),	TEXT(T_URL),};/* Called to setup the add bookmark dialog */void bookmark_edit_item_fn(struct dialog_data *dlg){	int max = 0, min = 0;	int w, rw;	int y = gf_val(-1, -1*G_BFU_FONT_SIZE);	struct terminal *term;	int a;	if (dlg->win->term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE);	term = dlg->win->term;		for (a=0;a<dlg->n-2;a++)	{		max_text_width(term, bm_add_msg[a], &max, AL_LEFT);		min_text_width(term, bm_add_msg[a], &min, AL_LEFT);	}	max_buttons_width(term, dlg->items + dlg->n-2, 2, &max);	min_buttons_width(term, dlg->items + dlg->n-2, 2, &min);	w = term->x * 9 / 10 - 2 * DIALOG_LB;		/*if (w > max) w = max;*/	if (w < min) w = min;	/*	if (w > term->x - 2 * DIALOG_LB) w = term->x - 2 * DIALOG_LB;	if (w < 1) w = 1;	*/	/*w = rw = gf_val(50,30*G_BFU_FONT_SIZE);*/	rw = w;		for (a=0;a<dlg->n-2;a++)	{		dlg_format_text_and_field(dlg, NULL, bm_add_msg[a], &dlg->items[a], 0, &y, w, &rw, COLOR_DIALOG_TEXT, AL_LEFT);		y += gf_val(1,1*G_BFU_FONT_SIZE);	}	dlg_format_buttons(dlg, NULL, dlg->items+dlg->n-2, 2, 0, &y, w, &rw, AL_CENTER);	w = rw;	dlg->xw = w + 2 * DIALOG_LB;	dlg->yw = y + 2 * DIALOG_TB;	center_dlg(dlg);	draw_dlg(dlg);	y = dlg->y + DIALOG_TB;	if (dlg->win->term->spec->braille) y += gf_val(1, G_BFU_FONT_SIZE);	for (a=0;a<dlg->n-2;a++)	{		dlg_format_text_and_field(dlg, term, bm_add_msg[a], &dlg->items[a], dlg->x + DIALOG_LB, &y, w, NULL, COLOR_DIALOG_TEXT, AL_LEFT);		y+=gf_val(1,G_BFU_FONT_SIZE);	}	dlg_format_buttons(dlg, term, &dlg->items[dlg->n-2], 2, dlg->x + DIALOG_LB, &y, w, NULL, AL_CENTER);}/* Puts url and title into the bookmark item */void bookmark_edit_done(void *data){	struct dialog *d=(struct dialog*)data;	struct bookmark_list *item=(struct bookmark_list *)d->udata;	unsigned char *title, *url;	struct bookmark_ok_struct* s=(struct bookmark_ok_struct*)d->udata2;	int a;	if ((item->type)&1)a=4; /* folder */	else a=5;	title = (unsigned char *)&d->items[a];	url = title + MAX_STR_LEN;	if (item->title)	{		struct conv_table* ct;				mem_free(item->title);		ct=get_translation_table(s->dlg->win->term->spec->charset,bookmark_ld.codepage);		item->title=convert_string(ct,title,strlen(title),NULL);		clr_white(item->title);	}	if (item->url)	{		struct conv_table* ct;				mem_free(item->url);		ct=get_translation_table(s->dlg->win->term->spec->charset,bookmark_ld.codepage);		item->url=convert_string(ct,url,strlen(url),NULL);		clr_white(item->url);	}	s->fn(s->dlg,s->data,item,&bookmark_ld);	d->udata=0;  /* for abort function */}/* destroys an item, this function is called when edit window is aborted */void bookmark_edit_abort(struct dialog_data *data){	struct bookmark_list *item=(struct bookmark_list*)data->dlg->udata;	struct dialog *dlg=data->dlg;	mem_free(dlg->udata2);	if (item)bookmark_delete_item(item);}/* dlg_title is TITLE_EDIT or TITLE_ADD *//* edit item function */void bookmark_edit_item(struct dialog_data *dlg,void *data,void (*ok_fn)(struct dialog_data *,void * ,void *, struct list_description *),void * ok_arg, unsigned char dlg_title){	struct bookmark_list *item=(struct bookmark_list *)data;	unsigned char *title, *url;	struct dialog *d;	struct bookmark_ok_struct *s;	int a;		/* Create the dialog */	s=mem_alloc(sizeof(struct bookmark_ok_struct));	s->fn=ok_fn;	s->data=ok_arg;	s->dlg=dlg;			if ((item->type)&1)a=4; /* folder */	else a=5;	d = mem_calloc(sizeof(struct dialog) + a * sizeof(struct dialog_item) + 2 * MAX_STR_LEN);	title = (unsigned char *)&d->items[a];	url = title + MAX_STR_LEN;	{		unsigned char *txt;		struct conv_table* ct;				ct=get_translation_table(bookmark_ld.codepage,dlg->win->term->spec->charset);		txt=convert_string(ct,item->title,strlen(item->title),NULL);		clr_white(txt);		safe_strncpy(title,txt,MAX_STR_LEN);		mem_free(txt);		txt=convert_string(ct,item->url,strlen(item->url),NULL);		clr_white(txt);		safe_strncpy(url,txt,MAX_STR_LEN);		mem_free(txt);	}	switch (dlg_title)	{		case TITLE_EDIT:		if ((item->type)&1)d->title=TEXT(T_EDIT_FOLDER);		else d->title=TEXT(T_EDIT_BOOKMARK);		break;		case TITLE_ADD:		if ((item->type)&1)d->title=TEXT(T_ADD_FOLDER);		else d->title=TEXT(T_ADD_BOOKMARK);		break;		default:		internal("Unsupported dialog title.\n");	}	d->fn = bookmark_edit_item_fn;	d->udata=data;  /* item */	d->udata2=s;	d->refresh = bookmark_edit_done;	d->abort = bookmark_edit_abort;	d->refresh_data = d;	d->items[0].type = D_FIELD;	d->items[0].dlen = MAX_STR_LEN;	d->items[0].data = title;	d->items[0].fn = check_nonempty;	a=0;	if (!((item->type)&1))  /* item */	{		d->items[1].type = D_FIELD;		d->items[1].dlen = MAX_STR_LEN;		d->items[1].data = url;		d->items[1].fn = check_nonempty;		a++;	}	d->items[a+1].type = D_BUTTON;	d->items[a+1].gid = B_ENTER;	d->items[a+1].fn = ok_dialog;	d->items[a+1].text = TEXT(T_OK);		d->items[a+2].type = D_BUTTON;	d->items[a+2].gid = B_ESC;	d->items[a+2].text = TEXT(T_CANCEL);	d->items[a+2].fn = cancel_dialog;		d->items[a+3].type = D_END;		do_dialog(dlg->win->term, d, getml(d, NULL));}/* create new bookmark item and returns pointer to it, on error returns 0*//* bookmark is filled with given data, data are deallocated afterwards */void *bookmark_new_item(void * data){	struct bookmark_list *b;	struct kawasaki *zelena=(struct kawasaki *)data;	b=mem_alloc(sizeof(struct bookmark_list));		b->url=mem_alloc(1);	b->title=mem_alloc(1);		*(b->url)=0;  /* empty strings */	*(b->title)=0;	if (!zelena) return b;		if (zelena->title)	{		add_to_strn(&(b->title),zelena->title);		mem_free(zelena->title);	}	if (zelena->url)	{		add_to_strn(&(b->url),zelena->url);		mem_free(zelena->url);	}	mem_free(zelena);	return b;}/* allocate string and print bookmark into it *//* x: 0=type all, 1=type title only */unsigned char *bookmark_type_item(struct terminal *term, void *data, int x){	unsigned char *txt, *txt1;	struct bookmark_list* item=(struct bookmark_list*)data;	struct conv_table *table;	if (item==(struct bookmark_list*)(void *)&bookmarks)   /* head */		return stracpy(_(TEXT(T_BOOKMARKS),term));	txt=stracpy(item->title);#ifdef SHOW_URL	x=0;#endif	if (!x&&!((item->type)&1))	{		add_to_strn(&txt,"   (");		if (item->url)add_to_strn(&txt,item->url);		add_to_strn(&txt,")");	}	table=get_translation_table(bookmark_ld.codepage,term->spec->charset);	txt1=convert_string(table,txt,strlen(txt),NULL);	clr_white(txt1);	mem_free(txt);	return txt1;}/* goto bookmark (called when goto button is pressed) */void bookmark_goto_item(struct session *ses, void *i){	struct bookmark_list *item=(struct bookmark_list*)i;	goto_url(ses,item->url);}/* delete bookmark from list */void bookmark_delete_item(void *data){	struct bookmark_list* item=(struct bookmark_list*)data;	struct bookmark_list *prev=item->prev;	struct bookmark_list *next=item->next;	if (list_empty(*item)||((struct list*)data==&bookmarks))return;  /* empty list or head */	if (item->url)mem_free(item->url);	if (item->title)mem_free(item->title);	if (next)next->prev=item->prev;	if (prev)prev->next=item->next;	mem_free(item);}static int substr_utf8(unsigned char *string, unsigned char *substr){	int r;	string = unicode_upcase_string(string);	substr = unicode_upcase_string(substr);	r = !!strstr(string, substr);	mem_free(string);	mem_free(substr);	return r;}void * bookmark_find_item(void *start, unsigned char *str, int direction){	struct bookmark_list *b,*s=(struct bookmark_list *)start;			if (direction==1)	{		for (b=s->next; b!=s; b=b->next)			if (b->depth>-1)			{				if (b->title && substr_utf8(b->title,str)) return b;#ifdef SEARCH_IN_URL				if (b->url && casestrstr(b->url,str)) return b; #endif			}	}	else	{		for (b=s->prev; b!=s; b=b->prev)			if (b->depth>-1)			{				if (b->title && substr_utf8(b->title,str)) return b;#ifdef SEARCH_IN_URL				if (b->url && casestrstr(b->url,str)) return b; #endif			}	}	if (b==s&&b->depth>-1&&b->title && substr_utf8(b->title,str)) return b;#ifdef SEARCH_IN_URL	if (b==s&&b->depth>-1&&b->url && casestrstr(b->url,str)) return b; #endif	return NULL;}/* returns previous item in the same folder and with same the depth, or father if there's no previous item *//* we suppose that previous items have correct pointer fotr */struct bookmark_list *previous_on_this_level(struct bookmark_list *item){	struct bookmark_list *p;	for (p=item->prev;p->depth>item->depth;p=p->fotr);	return p;}/* create new bookmark at the end of the list *//* if url is NULL, create folder *//* both strings are null terminated */void add_bookmark(unsigned char *title, unsigned char *url, int depth){	struct bookmark_list *b,*p;	struct document_options *dop;	if (!title) return;		b=mem_alloc(sizeof(struct bookmark_list));		dop=mem_calloc(sizeof(struct document_options));	dop->cp=bookmarks_codepage;		{		struct conv_table* ct;				ct=get_translation_table(bookmarks_codepage,bookmark_ld.codepage);		b->title=convert_string(ct,title,strlen(title),dop);		clr_white(b->title);	}		if (url)	{		struct conv_table* ct;				dop->plain=1;		ct=get_translation_table(bookmarks_codepage,bookmark_ld.codepage);		b->url=convert_string(ct,url,strlen(url),dop);		clr_white(b->url);		dop->plain=0;		b->type=0;	}	else 	{		b->url=mem_alloc(1);		*(b->url)=0;		b->type=1;	}		b->depth=depth;	p=bookmarks.prev;	b->prev=p;	b->next=(struct bookmark_list *)(void *)&bookmarks;	p->next=b;	bookmarks.prev=b;		p=previous_on_this_level(b);	if (p->depth<b->depth)b->fotr=p;   /* directory b belongs into */	else b->fotr=p->fotr;	mem_free(dop);}/* Created pre-cooked bookmarks */void create_initial_bookmarks(void){	bookmarks_codepage=get_cp_index("8859-2");	add_bookmark("Links",NULL,0);	add_bookmark("English",NULL,1);	add_bookmark("Calibration Procedure","http://atrey.karlin.mff.cuni.cz/~clock/twibright/links/calibration.html",2);	add_bookmark("Links Homepage","http://atrey.karlin.mff.cuni.cz/~clock/twibright/links/",2);	add_bookmark("Links Manual","http://links.twibright.com/user_en.html",2);	add_bookmark("萫sky",NULL,1);	add_bookmark("Kalibra鑞

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -