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

📄 listedit.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 5 页
字号:
/* listedit.c * (c) 2002 Petr 'Brain' Kulhavy * This file is a part of the Links program, released under GPL. */#include "links.h"/*                                    (#####)                                  (#########)                             ))))  (######)                            ,C--O   (###)      _________________                            |`:, \  ~~        |.  ,       v  , .|                            `-__o  ~~  ;      |  ZAKAZ KOURENI  |                            / _  \     `      |.               .|                           | ( \__`_=k==      `~~~~~~~~~~~~~~~~~'                           | `-/__---'                           |=====C/                           `.   ),'                             \  /                             ||_|                             || |__                             ||____)                         v v  v   ,       ,v                     KONECNE NEJAKE KOMENTARE...*//* Klikani myssi (nebo mysijou, jak rika Mikulas) v list-okne: * (hrozne dulezity komentar ;-P ) * * Klikani je vyreseno nasledovne, pokud ma nekdo lepsi napad, nebo nejake * vyhrady, tak at mi je posle. * * Prostredni tlacitko+pohyb je scroll nahoru/dolu. Levym tlacitkem se nastavi * kurzor (cerna lista) na konkretni polozku. Kdyz se levym klikne na adresar * (na ty graficke nesmysly, ne na ten text), tak se adresar toggle * otevre/zavre. Prave tlacitko oznaci/odznaci polozku/adresar. *//* Premistovani polozek: * * Pravym tlacitkem se oznaci/odznaci polozka. Cudlikem "Odznacit vse" se * vsechny polozky odznaci. Cudlik "Prestehovat" presune vsechny oznacene * polozky za aktualni pozici, v tom poradi, jak jsou v seznamu. Pri zavreni * adresare se vsechny polozky v adresari odznaci. */ /* Prekreslovani grafickych nesmyslu v okenku je samozrejme bez jedineho  *                                                               v * bliknuti. Ne jako nejmenovane browsery... Proste obraz jako BIC (TM) *//* Ovladani klavesnici: * sipky, page up, page down, home end			pohyb * +							otevri adresar * -							zavri adresar * mezera						toggle adresar * ins, *, 8, i						toggle oznacit * ?, /, N, n						hledani nahoru, dolu, znova, znova na druhou stranu *//*  * Struktura struct list_decription obsahuje popis seznamu. Tenhle file * obsahuje obecne funkce k obsluze seznamu. Pomoci struct list_description se * seznam customizuje. Obecne funkce volaji funkce z list_description.  * * Jedina funkce z tohoto filu, ktera se vola zvenku, je create_list_window. Ta * vyrobi a obstarava okno pro obsluhu seznamu. *  * Obecny list neresi veci jako nahravani seznamu z filu, ukladani na disk * atd.(tyhle funkce si uzivatel musi napsat sam). Resi vlastne jenom to velke * okno na manipulaci se seznamem. *//* * Aby bylo konzistentni pridavani a editovani polozek, tak se musi pytlacit. * * To znamena, ze pri pridavani polozky do listu se vyrobi nova polozka * (NEPRIDA se do seznamu), pusti se edit a po zmacknuti OK se polozka prida do * seznamu. Pri zmacknuti cancel, se polozka smaze.  * * Pri editovani polozky se vyrobi nova polozka, zkopiruje se do ni obsah te * puvodni (od toho tam je funkce copy_item), pak se zavola edit a podobne jako * v predchozim pripade: pri cancel se polozka smaze, pri OK se zkopiruje do * puvodni polozky a smaze se taky. * * O smazani polozky pri cancelu se bude starat uzivatelska funkce edit_item * sama. Funkce edit_item po zmacknuti OK zavola funkci, kterou dostane. Jako * 1. argument ji da data, ktera dostane, jako 2. argument ji preda pointer na * item. *//* * Seznam je definovan ve struct list. Muze byt bud placaty nebo stromovy. * * K placatemu asi neni co dodat. U placateho se ignoruje hloubka a neexistuji * adresare - vsechny polozky jsou si rovny (typ polozky se ignoruje). * * Stromovy seznam: * Kazdy clen seznamu ma flag sbaleno/rozbaleno. U itemy se to ignoruje, u * adresare to znamena, zda se zobrazuje obsah nebo ne. Aby rozbaleno/sbaleno * bylo u vsech prvku adresare, to by neslo: kdybych mel adresar a v nem dalsi * adresar, tak bych u toho vnoreneho adresare nevedel, jestli to * sbaleno/rozbaleno je od toho vnoreneho adresare, nebo od toho nad nim.  * * Clenove seznamu maji hloubku - cislo od 0 vyse. Cim je prvek hloubeji ve * strukture, tim je hloubka vyssi. Obsah adresare s hloubkou x je souvisly blok * nasledujicich prvku s hloubkou >x. * * Hlava ma hloubku -1 a zobrazuje se taky jako clen seznamu (aby se dal * zobrazit prazdny seznam a dalo se do nej pridavat), takze se da vlastne cely * seznam zabalit/rozbalit. Hlava sice nema data, ale funkce type_item ji musi * umet zobrazit. Jako popis bude psat fixni text, napriklad "Bookmarks". * * Pro urychleni vykreslovani kazdy prvek v seznamu s adresarema obsahuje * pointer na otce (polozka fotr). U plocheho seznamu se tento pointer * ignoruje. * * Strukturu stromu bude vykreslovat obecna funkce (v tomto filu), protoze v * obecnem listu je struktura uz zachycena. *//*  * V hlavnim okne se da nadefinovat 1 uzivatelske tlacitko. Polozka button ve * struct list_description obsahuje popisku tlacitka (kod stringu v * prekodovavacich tabulkach). Funkce button_fn je zavolana pri stisku * tlacitka, jako argument (void *) dostane aktualni polozku.  Pokud je * button_fn NULL, tlacitko se nekona. * * Toto tlacitko se da vyuzit napriklad u bookmarku, kde je potreba [ Goto ]. * * Kdyz bude potreba predavat obsluzne funkci tlacitka nejake dalsi argumenty, * tak se pripadne definice obsluzne funkce prepise. * * Tlacitko funguje jen na polozky. Nefunguje na adresare (pokud se jedna o * stromovy list) ani na hlavu. *//* Jak funguje default_value: * kdyz se zmackne tlacitko add, zavola se funkce default_value, ktera si * naalokuje nejaky data pro new_item. Do funkce default_value se treba u * bookmarku umisti okopirovani altualniho nazvu a url stranky. Pak se zavola * new_item, ktera si prislusne hodnoty dekoduje a pomoci nich vyplni novou * polozku. Funkce new_item pak MUSI data dealokovat. Pokud funkce new_item * dostane misto pointeru s daty NULL, vyrobi prazdnou polozku. * * Default value musi vratit hodnoty v kodovani uvedenem v list_description *//* Pristupovani z vice linksu: *  * ... se neresi - je zakazano. K tomu slouzi polozka open ve struct * list_description, ktera rika, jestli je okno uz otevrene, nebo ne. *//* Prekodovavani znakovych sad: *  * type_item vraci text prekodovany do kodovani terminalu, ktery dostane. *//* struct list *current_pos;   current cursor position in the list *//* struct list *win_offset;    item at the top of the window *//* int win_pos;                current y position in the window */#define BOHNICE "+420-2-84016111"#define BFU_ELEMENT_PIPE 0#define BFU_ELEMENT_TEE 1#define BFU_ELEMENT_CLOSED 2#define BFU_ELEMENT_OPEN 3/* for mouse scrolling */long last_mouse_y;#ifdef G	#define sirka_scrollovadla (G_SCROLL_BAR_WIDTH<<1)#else	#define sirka_scrollovadla 0#endif/* prototypes */int draw_bfu_element(struct terminal *, int, int, unsigned, long, long, unsigned char, unsigned char);struct list *next_in_tree(struct list_description *, struct list *);struct list *prev_in_tree(struct list_description *, struct list *);void list_insert_behind_item(struct dialog_data *, void *, void *, struct list_description *);void list_copy_item(struct dialog_data *, void *, void *, struct list_description *);int list_item_add(struct dialog_data *, struct dialog_item_data *);int list_folder_add(struct dialog_data *, struct dialog_item_data *);int list_item_edit(struct dialog_data *, struct dialog_item_data *);int list_item_move(struct dialog_data *, struct dialog_item_data *);int list_item_unselect(struct dialog_data *, struct dialog_item_data *);int list_item_button(struct dialog_data *, struct dialog_item_data *);int is_empty_dir(struct list_description *, struct list *);int list_item_delete(struct dialog_data *, struct dialog_item_data *);void redraw_list_line(struct terminal *, void *);void scroll_list(struct terminal *, void *);int list_event_handler(struct dialog_data *, struct event *);void create_list_window_fn(struct dialog_data *);void close_list_window(struct dialog_data *);/* This function uses these defines from setup.h: *  * BFU_GRX_WIDTH * BFU_GRX_HEIGHT * BFU_ELEMENT_WIDTH *//* draws one of BFU elements: | |- [-] [+] *//* BFU elements are used in the list window *//* this function also defines shape and size of the elements *//* returns width of the BFU element (all elements have the same size, but sizes differ if we're in text mode or in graphics mode) */int draw_bfu_element(struct terminal * term, int x, int y, unsigned c, long b, long f, unsigned char type, unsigned char selected){	if (!F){		unsigned char vertical=179;		unsigned char horizontal=196;		unsigned char tee=195;		switch (type)		{			case BFU_ELEMENT_PIPE:			c|=ATTR_FRAME;			set_char(term,x,y,c+' ');			set_char(term,x+1,y,c+vertical);			set_char(term,x+2,y,c+' ');			set_char(term,x+3,y,c+' ');			set_char(term,x+4,y,c+' ');			break;			case BFU_ELEMENT_TEE:			c|=ATTR_FRAME;			set_char(term,x,y,c+' ');			set_char(term,x+1,y,c+tee);			set_char(term,x+2,y,c+horizontal);			set_char(term,x+3,y,c+horizontal);			set_char(term,x+4,y,c+' ');			break;			case BFU_ELEMENT_CLOSED:			set_char(term,x,y,c+'[');			set_char(term,x+1,y,c+'+');			set_char(term,x+2,y,c+']');			c|=ATTR_FRAME;			set_char(term,x+3,y,c+horizontal);			set_char(term,x+4,y,c+' ');			break;			case BFU_ELEMENT_OPEN:			set_char(term,x,y,c+'[');			set_char(term,x+1,y,c+'-');			set_char(term,x+2,y,c+']');			c|=ATTR_FRAME;			set_char(term,x+3,y,c+horizontal);			set_char(term,x+4,y,c+' ');			break;			default:			internal("draw_bfu_element: unknown BFU element type %d.\n",type);		}		if (selected)set_char(term,x+4,y,c+'*');		return BFU_ELEMENT_WIDTH;  /* BFU element size in text mode */#ifdef G	}else{		struct graphics_device *dev=term->dev;		struct rect r;		restrict_clip_area(dev,&r,x,y,x+5*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT);		switch (type)		{			case BFU_ELEMENT_PIPE:			/* pipe */			drv->draw_vline(dev,x+1*BFU_GRX_WIDTH,y,y+BFU_GRX_HEIGHT,f);			drv->draw_vline(dev,x+1+1*BFU_GRX_WIDTH,y,y+BFU_GRX_HEIGHT,f);			/* clear the rest */			drv->fill_area(dev,x,y,x+1*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+1*BFU_GRX_WIDTH,y,x+4*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			break;			case BFU_ELEMENT_TEE:			/* tee */			drv->draw_vline(dev,x+1*BFU_GRX_WIDTH,y,y+BFU_GRX_HEIGHT,f);			drv->draw_vline(dev,x+1+1*BFU_GRX_WIDTH,y,y+BFU_GRX_HEIGHT,f);			drv->draw_hline(dev,x+1*BFU_GRX_WIDTH,y+.5*BFU_GRX_HEIGHT,x+1+3.5*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+1*BFU_GRX_WIDTH,y-1+.5*BFU_GRX_HEIGHT,x+1+3.5*BFU_GRX_WIDTH,f);			/* clear the rest */			drv->fill_area(dev,x,y,x+1*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+BFU_GRX_WIDTH,y+.5*BFU_GRX_HEIGHT+1,x+1+3.5*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+BFU_GRX_WIDTH,y,x+1+3.5*BFU_GRX_WIDTH,y-1+.5*BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+1+3.5*BFU_GRX_WIDTH,y,x+4*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			break;			case BFU_ELEMENT_CLOSED:			/* vertical line of the + */			drv->draw_vline(dev,x+1*BFU_GRX_WIDTH,y+1+.25*BFU_GRX_HEIGHT,y-1+.75*BFU_GRX_HEIGHT,f);			drv->draw_vline(dev,x+1+1*BFU_GRX_WIDTH,y+1+.25*BFU_GRX_HEIGHT,y-1+.75*BFU_GRX_HEIGHT,f);			/* clear around the + */			drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y+3,x+1.5*BFU_GRX_WIDTH,y+1+.25*BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y-1+.75*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y+1+.25*BFU_GRX_HEIGHT,x+BFU_GRX_WIDTH,y-1+.5*BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+BFU_GRX_WIDTH,y+1+.25*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,y-1+.5*BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y+1+.5*BFU_GRX_HEIGHT,x+BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+BFU_GRX_WIDTH,y+1+.5*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			case BFU_ELEMENT_OPEN:			/* box */			drv->draw_vline(dev,x+2,y+1,y-1+BFU_GRX_HEIGHT,f);			drv->draw_vline(dev,x+3,y+1,y-1+BFU_GRX_HEIGHT,f);			drv->draw_vline(dev,x-1+2*BFU_GRX_WIDTH,y+1,y-1+BFU_GRX_HEIGHT,f);			drv->draw_vline(dev,x-2+2*BFU_GRX_WIDTH,y+1,y-1+BFU_GRX_HEIGHT,f);			drv->draw_hline(dev,x+4,y+1,x-2+2*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+4,y+2,x-2+2*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+4,y-2+BFU_GRX_HEIGHT,x-2+2*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+4,y-3+BFU_GRX_HEIGHT,x-2+2*BFU_GRX_WIDTH,f);			/* horizontal line of the - */			drv->draw_hline(dev,x+2+.5*BFU_GRX_WIDTH,y+.5*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+2+.5*BFU_GRX_WIDTH,y-1+.5*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,f);			/* line to title */			drv->draw_hline(dev,x+2*BFU_GRX_WIDTH,y+(BFU_GRX_HEIGHT>>1),x+1+3.5*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+2*BFU_GRX_WIDTH,y-1+(BFU_GRX_HEIGHT>>1),x+1+3.5*BFU_GRX_WIDTH,f);			/* top and bottom short vertical line */			drv->draw_hline(dev,x+1*BFU_GRX_WIDTH,y,x+2+1*BFU_GRX_WIDTH,f);			drv->draw_hline(dev,x+1*BFU_GRX_WIDTH,y-1+BFU_GRX_HEIGHT,x+2+1*BFU_GRX_WIDTH,f);			/* clear the rest */			drv->draw_vline(dev,x,y,y+BFU_GRX_HEIGHT,b);			drv->draw_vline(dev,x+1,y,y+BFU_GRX_HEIGHT,b);			drv->draw_hline(dev,x+2,y,x+BFU_GRX_WIDTH,b);			drv->draw_hline(dev,x+2,y-1+BFU_GRX_HEIGHT,x+BFU_GRX_WIDTH,b);			drv->draw_hline(dev,x+2+BFU_GRX_WIDTH,y,x+2*BFU_GRX_WIDTH,b);			drv->draw_hline(dev,x+2+BFU_GRX_WIDTH,y-1+BFU_GRX_HEIGHT,x+2*BFU_GRX_WIDTH,b);			drv->fill_area(dev,x+2*BFU_GRX_WIDTH,y,x+1+3.5*BFU_GRX_WIDTH,y+.5*BFU_GRX_HEIGHT-1,b);			drv->fill_area(dev,x+2*BFU_GRX_WIDTH,y+1+.5*BFU_GRX_HEIGHT,x+1+3.5*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+4,y+3,x+2+.5*BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+1.5*BFU_GRX_WIDTH,y+3,x-2+2*BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y+3,x+1.5*BFU_GRX_WIDTH,y+1+.25*BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y-1+.75*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			if (type==BFU_ELEMENT_OPEN)			{				drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y+3,x+1.5*BFU_GRX_WIDTH,y-1+.5*BFU_GRX_HEIGHT,b);				drv->fill_area(dev,x+2+.5*BFU_GRX_WIDTH,y+1+.5*BFU_GRX_HEIGHT,x+1.5*BFU_GRX_WIDTH,y-3+BFU_GRX_HEIGHT,b);			}			drv->fill_area(dev,x+1+3.5*BFU_GRX_WIDTH,y,x+4*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			break;			default:			internal("draw_bfu_element: unknown BFU element type %d.\n",type);		}		if (!selected)			drv->fill_area(dev,x+4*BFU_GRX_WIDTH,y,x+5*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);		else		{			drv->fill_area(dev,x+4*BFU_GRX_WIDTH,y,x+4.25*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+4.25*BFU_GRX_WIDTH,y,x+4.75*BFU_GRX_WIDTH,y+2.5*BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+4.25*BFU_GRX_WIDTH,y+.25*BFU_GRX_HEIGHT,x+4.75*BFU_GRX_WIDTH,y+.75*BFU_GRX_HEIGHT,f);			drv->fill_area(dev,x+4.25*BFU_GRX_WIDTH,y+.75*BFU_GRX_HEIGHT,x+4.75*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);			drv->fill_area(dev,x+4.75*BFU_GRX_WIDTH,y,x+5*BFU_GRX_WIDTH,y+BFU_GRX_HEIGHT,b);		}				drv->set_clip_area(dev, &r);		return BFU_ELEMENT_WIDTH;#endif	}}/* aux structure for parameter exchange for redrawing list window */struct redraw_data{	struct list_description *ld;	struct dialog_data *dlg;	int n;};void redraw_list(struct terminal *term, void *bla);void list_find_next(struct redraw_data *, int);void list_search_for_back(struct redraw_data *, unsigned char *);void list_search_for(struct redraw_data *, unsigned char *);/* returns next visible item in tree list *//* works only with visible items (head or any item returned by this function) *//* when list is flat returns next item */struct list *next_in_tree(struct list_description *ld, struct list *item){	int depth=item->depth;	/* flat list */	if (!(ld->type))return item->next;		if (!((item->type)&1)||((item->type)&2))  /* item or opened folder */		return item->next;	/* skip content of this folder */	do item=item->next; while (item->depth>depth);   /* must stop on head 'cause it's depth is -1 */	return item;}/* returns previous visible item in tree list *//* works only with visible items (head or any item returned by this function) *//* when list is flat returns previous item */struct list *prev_in_tree(struct list_description *ld, struct list *item){	struct list *last_closed;	int depth=item->depth;		/* flat list */	if (!(ld->type))return item->prev;		if (item==ld->list)depth=0;	/* items with same or lower depth must be visible, because current item is visible */	if ((((struct list*)(item->prev))->depth)<=(item->depth))return item->prev;	/* find item followed with opened fotr's only */	/* searched item is last closed folder (going up from item) or item->prev */	last_closed=item->prev;	item=item->prev;	while (1)

⌨️ 快捷键说明

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