📄 listedit.c
字号:
{ if (((item->type)&3)==1)/* closed folder */ last_closed=item; if ((item->depth)<=depth)break; item=item->fotr; } return last_closed;}#ifdef Gstatic int get_total_items(struct list_description *ld){ struct list*l=ld->list; int count=0; do{ l=next_in_tree(ld,l); count++; }while(l!=ld->list); return count;}static int get_scroll_pos(struct list_description *ld){ struct list*l; int count; for (l=ld->list,count=0;l!=ld->win_offset;l=next_in_tree(ld,l),count++); return count;}static int get_visible_items(struct list_description *ld){ struct list*l=ld->win_offset; int count=0; do{ l=next_in_tree(ld,l); count++; }while(count<ld->n_items&&l!=ld->list); return count;}static struct list *find_last_in_window(struct list_description *ld){ struct list*l=ld->win_offset; struct list *x=l; int count=0; do{ l=next_in_tree(ld,l); count++; if (l!=ld->list&&count!=ld->n_items)x=l; }while(count<ld->n_items&&l!=ld->list); return x;}#endifstatic int get_win_pos(struct list_description *ld){ struct list*l; int count; for (l=ld->win_offset,count=0;l!=ld->current_pos;l=next_in_tree(ld,l),count++); return count;}static void unselect_in_folder(struct list_description *ld, struct list *l){ int depth; depth=l->depth; for(l=l->next;l!=ld->list&&l->depth>depth;l=l->next) l->type&=~4;}/* aux function for list_item_add */void list_insert_behind_item(struct dialog_data *dlg, void *p, void *i, struct list_description *ld){ struct list *item=(struct list *)i; struct list *pos=(struct list *)p; struct list *a; struct redraw_data rd; /* BEFORE: ... <----> pos <--(possible invisible items)--> a <----> ... *//* AFTER: ... <----> pos <--(possible invisible items)--> item <----> a <----> ... */ a=next_in_tree(ld,pos); ((struct list*)(a->prev))->next=item; item->prev=a->prev; item->next=a; a->prev=item; /* if list is flat a->fotr will contain nosenses, but it won't crash ;-) */ if (((pos->type)&3)==3||(pos->depth)==-1){item->fotr=pos;item->depth=pos->depth+1;} /* open directory or head */ else {item->fotr=pos->fotr;item->depth=pos->depth;} ld->current_pos=next_in_tree(ld,ld->current_pos); /* ld->current_pos->next==item */ ld->win_pos++; if (ld->win_pos>ld->n_items-1) /* scroll down */ { ld->win_pos=ld->n_items-1; ld->win_offset=next_in_tree(ld,ld->win_offset); } ld->modified=1; rd.ld=ld; rd.dlg=dlg; rd.n=0; draw_to_window(dlg->win,redraw_list,&rd);}/* aux function for list_item_edit *//* copies data of src to dest and calls free on the src *//* first argument is argument passed to user function */void list_copy_item(struct dialog_data *dlg, void *d, void *s, struct list_description *ld){ struct list *src=(struct list *)s; struct list *dest=(struct list *)d; struct redraw_data rd; dlg=dlg; ld->copy_item(src,dest); ld->delete_item(src); ld->modified=1; /* called after an successful edit */ rd.ld=ld; rd.dlg=dlg; rd.n=0; draw_to_window(dlg->win,redraw_list,&rd);}/* creates new item (calling new_item function) and calls edit_item function */int list_item_add(struct dialog_data *dlg,struct dialog_item_data *useless){ struct list_description *ld=(struct list_description*)(dlg->dlg->udata2); struct list *item=ld->current_pos; struct list *new_item; useless=useless; if (!(new_item=ld->new_item(ld->default_value((struct session*)(dlg->dlg->udata),0))))return 1; new_item->prev=0; new_item->next=0; new_item->type=0; new_item->depth=0; ld->edit_item(dlg,new_item,list_insert_behind_item,item,TITLE_ADD); return 0;}/* like list_item_add but creates folder */int list_folder_add(struct dialog_data *dlg,struct dialog_item_data *useless){ struct list_description *ld=(struct list_description*)(dlg->dlg->udata2); struct list *item=ld->current_pos; struct list *new_item; useless=useless; if (!(new_item=ld->new_item(NULL)))return 1; new_item->prev=0; new_item->next=0; new_item->type=1; new_item->depth=0; ld->edit_item(dlg,new_item,list_insert_behind_item,item,TITLE_ADD); return 0;}int list_item_edit(struct dialog_data *dlg,struct dialog_item_data *useless){ struct list_description *ld=(struct list_description*)(dlg->dlg->udata2); struct list *item=ld->current_pos; struct list *new_item; useless=useless; if (item==ld->list)return 0; /* head */ if (!(new_item=ld->new_item(NULL)))return 1; new_item->prev=0; new_item->next=0; ld->copy_item(item,new_item); ld->edit_item(dlg,new_item,list_copy_item,item,TITLE_EDIT); return 0;}static inline int is_parent(struct list_description *ld, struct list *item, struct list *parent){ struct list *l; if (ld->type) for (l=item;l->depth>=0;l=l->fotr) if (l==parent) return 1; return 0;} int list_item_move(struct dialog_data *dlg,struct dialog_item_data *useless){ struct list_description *ld=(struct list_description*)(dlg->dlg->udata2); struct list *i; struct list *behind=ld->current_pos; struct redraw_data rd; int window_moved=0; int count=0; useless=useless; if (ld->current_pos->type&4) /* odznacime current_pos, kdyby nahodou byla oznacena */ { count++; ld->current_pos->type&=~4; } for (i=ld->list->next;i!=ld->list;) { struct list *next=next_in_tree(ld,i); struct list *prev=i->prev; struct list *behind_next=next_in_tree(ld,behind); /* to se musi pocitat pokazdy, protoze by se nam mohlo stat, ze to je taky oznaceny */ struct list *item_last=next->prev; /* last item of moved block */ if (is_parent(ld, ld->current_pos, i)) /* we're moving directory into itself - let's behave like item was not selected */ { i->type&=~4; i=next; count++; continue; } if (!(i->type&4)){i=next;continue;} if ((i->type&3)==3) /* dirty trick */ { i->type&=~2; next=next_in_tree(ld,i); prev=i->prev; item_last=next->prev; i->type|=2; } if (i==ld->win_offset) { window_moved=1; if (next!=ld->list)ld->win_offset=next; } /* upravime fotrisko a hloubku */ if (ld->type) { int a=i->depth; struct list *l=i; if (((behind->type)&3)==3||behind==ld->list)/* open folder or head */ {i->fotr=behind;i->depth=behind->depth+1;} else {i->fotr=behind->fotr;i->depth=behind->depth;} a=i->depth-a; /* poopravime hloubku v adresari */ if (l!=item_last) { do{ l=l->next; l->depth+=a; } while(l!=item_last); } } if (behind_next==i)goto predratovano; /* to uz je vsechno, akorat menime hloubku */ /* predratujeme ukazatele kolem bloku na stare pozici */ prev->next=next; next->prev=prev; /* posuneme na novou pozici (tesne pred behind_next) */ i->prev=behind_next->prev; ((struct list*)(behind_next->prev))->next=i; item_last->next=behind_next; behind_next->prev=item_last;predratovano: /* odznacime */ i->type&=~4; unselect_in_folder(ld,i); /* upravime pointery pro dalsi krok */ behind=i; i=next; count++; } if (window_moved) { ld->current_pos=ld->win_offset; ld->win_pos=0; } else ld->win_pos=get_win_pos(ld); if (!count) msg_box( dlg->win->term, /* terminal */ NULL, /* blocks to free */ TEXT(T_MOVE), /* title */ AL_CENTER, /* alignment */ TEXT(T_NO_ITEMS_SELECTED), /* text */ NULL, /* data */ 1, /* # of buttons */ TEXT(T_OK),NULL,B_ESC|B_ENTER /* button1 */ ); else { ld->modified=1; rd.ld=ld; rd.dlg=dlg; rd.n=0; draw_to_window(dlg->win,redraw_list,&rd); } return 0;}/* unselect all items */int list_item_unselect(struct dialog_data *dlg,struct dialog_item_data *useless){ struct list_description *ld=(struct list_description*)(dlg->dlg->udata2); struct list *item=ld->current_pos; struct redraw_data rd; useless=useless; item=ld->list; do{ item->type&=~4; item=item->next; }while(item!=ld->list); rd.ld=ld; rd.dlg=dlg; rd.n=0; draw_to_window(dlg->win,redraw_list,&rd); return 0;}/* user button function - calls button_fn with current item */int list_item_button(struct dialog_data *dlg, struct dialog_item_data *useless){ struct list_description *ld=(struct list_description*)(dlg->dlg->udata2); struct list *item=ld->current_pos; struct session *ses=(struct session *)(dlg->dlg->udata); if (!(ld->button_fn))internal("Links got schizophrenia! Call "BOHNICE".\n"); if (item==(ld->list)||list_empty(*item))return 0; /* head or empty list */ if (ld->type&&((item->type)&1))return 0; /* this is tree list and item is directory */ ld->button_fn(ses,item); cancel_dialog(dlg, useless); return 0;}struct ve_skodarne_je_jeste_vetsi_narez{ struct list_description* ld; struct dialog_data *dlg; struct list* item;};/* when delete is confirmed adjusts current_pos and calls delete function */static void delete_ok(void * data){ struct list_description* ld=((struct ve_skodarne_je_jeste_vetsi_narez*)data)->ld; struct list* item=((struct ve_skodarne_je_jeste_vetsi_narez*)data)->item; struct dialog_data* dlg=((struct ve_skodarne_je_jeste_vetsi_narez*)data)->dlg; struct redraw_data rd; /* strong premise: we can't delete head of the list */ if (ld->current_pos->next!=ld->list) { if (ld->current_pos == ld->win_offset) ld->win_offset = ld->current_pos->next; ld->current_pos=ld->current_pos->next; } else /* last item */ { if (!(ld->win_pos)) /* only one line on the screen */ ld->win_offset=prev_in_tree(ld,ld->win_offset); else ld->win_pos--; ld->current_pos=prev_in_tree(ld,ld->current_pos); } ld->delete_item(item); rd.ld=ld; rd.dlg=dlg; rd.n=0; ld->modified=1; draw_to_window(dlg->win,redraw_list,&rd);}/* when delete folder is confirmed adjusts current_pos and calls delete function */static void delete_folder_recursively(void * data){ struct list_description* ld=((struct ve_skodarne_je_jeste_vetsi_narez*)data)->ld; struct list* item=((struct ve_skodarne_je_jeste_vetsi_narez*)data)->item; struct dialog_data* dlg=((struct ve_skodarne_je_jeste_vetsi_narez*)data)->dlg; struct redraw_data rd; struct list *i,*j; int depth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -