📄 filedialog.c
字号:
#include "filedialog.h"FileDialog::FileDialog(){ diritems=NULL; dirmenu=NULL; filelist=NULL; strcpy(locate[0],"File List"); strcpy(locate[1],"Location"); strcpy(locate[2],"Filter"); strcpy(locate[3],"*"); diritemscount=0; curitem=0; memset(filename[0],0,MAXFIELDLEN); memset(filename[1],0,MAXFIELDLEN); strcpy(filename[1],"*"); active=FILELIST; }void FileDialog::FreeFileList(){ int i=0; if (filelist) { for (i = 0; i <diritemscount; i++) if (filelist[i]) free(filelist[i]); free(filelist); filelist=NULL; } if(dirmenu!=NULL) { unpost_menu(dirmenu); free_menu(dirmenu); } for(int i = 0; i < diritemscount; ++i) { if(diritems[i]!=NULL) free_item(diritems[i]); } diritemscount=0; curitem=0;}void FileDialog::FreeLocate(){ if(locatefrm!=NULL) { unpost_form(locatefrm); free_form(locatefrm); } if(locatefld[0]!=NULL) free_field(locatefld[0]); if(locatefld[1]!=NULL) free_field(locatefld[1]);}FileDialog::~FileDialog(){ FreeFileList(); FreeLocate();}int FileDialog::InitFileDialog(int Height,int Width,int Color,int Shadow,int FontStyle,int WinType,int basedlg,char *Title){ int ret=FALSE; if(WinType==DIALOG_FILEOPEN) ret=InitDialog(Height,Width,Color,Shadow,FontStyle,WinType,basedlg,"[Open]"); else if(WinType==DIALOG_FILESAVE) ret=InitDialog(Height,Width,Color,Shadow,FontStyle,WinType,basedlg,"[Save]"); else if(WinType==DIALOG_FILESAVEAS) ret=InitDialog(Height,Width,Color,Shadow,FontStyle,WinType,basedlg,"[Save As]"); else ret=InitDialog(Height,Width,Color,Shadow,FontStyle,WinType,basedlg,"[Unknown]"); if (ret==FALSE) goto failure; ret=DrawFileDialog(); if (ret==FALSE) goto failure; curs_set(0); wrefresh(basewin); vscroll.InitVScroll(y+2,x+width-2,height-5,1,COLOR_BLUE_YELLOW,A_BOLD,VSCROLL_BORDER); vscroll.ChangePos(); failure: return ret;}int FileDialog::DrawFileDialog(){ int rows,cols; int ret=TRUE; wattron(basewin,COLOR_PAIR(color)); mvwprintw(basewin,1,1,locate[0]); mvwprintw(basewin,height-3,1,locate[1]); mvwprintw(basewin,height-2,1,locate[2]); wattroff(basewin,COLOR_PAIR(color)); ret=FileList(getcwd(filename[0],MAXFIELDLEN)); if(ret==FALSE) goto failure; locatefld[0] = new_field(1, width-sizeof(locate[2])-1, 0, 0, 0, 0); locatefld[1] = new_field(1, width-sizeof(locate[2])-1, 1, 0, 0, 0); locatefld[2] = NULL; set_field_back(locatefld[0], COLOR_PAIR(COLOR_WHITE_BLUE)|A_UNDERLINE); set_field_back(locatefld[1], COLOR_PAIR(COLOR_WHITE_BLUE)|A_UNDERLINE); field_opts_on(locatefld[0], O_ACTIVE); field_opts_on(locatefld[1], O_ACTIVE); field_opts_off(locatefld[0],O_AUTOSKIP); field_opts_off(locatefld[1],O_AUTOSKIP); field_opts_off(locatefld[0],O_STATIC); field_opts_off(locatefld[1],O_STATIC); set_max_field(locatefld[0],MAXFIELDLEN); set_max_field(locatefld[1],MAXFIELDLEN); set_field_buffer(locatefld[0],0,filename[0]); set_field_buffer(locatefld[1],0,locate[3]); locatefrm = new_form(locatefld); scale_form(locatefrm,&rows,&cols); set_current_field(locatefrm, locatefld[0]); set_form_win(locatefrm, basewin); set_form_sub(locatefrm, derwin(basewin,2,cols,height-3,sizeof(locate[2]))); post_form(locatefrm); curitem=0;failure: return ret;}void FileDialog::ReDrawFileDialog(){ ReDrawDialog(); wattron(basewin,COLOR_PAIR(color)); mvwprintw(basewin,1,1,locate[0]); mvwprintw(basewin,height-3,1,locate[1]); mvwprintw(basewin,height-2,1,locate[2]); wattroff(basewin,COLOR_PAIR(color)); unpost_menu(dirmenu); post_menu(dirmenu); unpost_form(locatefrm); post_form(locatefrm); wrefresh(basewin); vscroll.ReDraw(); vscroll.ChangePos(diritemscount,curitem);}int FileDialog::FileList(char *cwd) //cwd allow directory only{ int ret=FALSE; int i,j,k; struct dirent **list; struct stat buf; if(access(cwd,R_OK|X_OK)==-1) //list dir right denied! goto failure; if(chdir(filename[0])) goto failure; FreeFileList(); k=scandir(cwd,&list,0,alphasort); if (k<0) goto failure; for(diritemscount=0,j=0;j<k;j++) { stat(list[j]->d_name,&buf); if(fnmatch(filename[1],list[j]->d_name,0)==0 || strcmp(list[j]->d_name,".")==0 || strcmp(list[j]->d_name,"..")==0 || S_ISDIR(buf.st_mode)) diritemscount++; } if ( (filelist=(char **)malloc(sizeof(char *)*diritemscount)) ==NULL) goto failure; memset(filelist, 0, sizeof(char*)*diritemscount); diritems = (ITEM **)calloc(diritemscount+1, sizeof(ITEM *)); for(j = 0,i = 0; i < k && j<diritemscount; ++i) { stat(list[i]->d_name,&buf); if(fnmatch(filename[1],list[i]->d_name,0)==0 || strcmp(list[i]->d_name,".")==0 || strcmp(list[i]->d_name,"..")==0 || S_ISDIR(buf.st_mode)) { filelist[j]=(char*)malloc(sizeof(char *)*MAXFIELDLEN); if( filelist[j] ==NULL) goto nomem; memset(filelist[j], 0, sizeof(char *)*MAXFIELDLEN); strcpy(filelist[j],list[i]->d_name); if(S_ISDIR(buf.st_mode)) strcat(filelist[j],"/"); diritems[j] = new_item(filelist[j], NULL); j++; } free(list[i]); } free(list); diritems[diritemscount] = (ITEM *)NULL; dirmenu = new_menu((ITEM **)diritems); set_menu_fore(dirmenu, COLOR_PAIR(COLOR_WHITE_BLACK) | A_REVERSE); set_menu_back(dirmenu, COLOR_PAIR(COLOR_WHITE_BLACK)); set_menu_win(dirmenu, basewin); set_menu_sub(dirmenu, derwin(basewin,height-5,width-3,2,1)); set_menu_format(dirmenu, height-5, 1); draw_box (2,1,height-5,width-3,' '|COLOR_PAIR(COLOR_WHITE_BLACK),' '); set_menu_mark(dirmenu, ""); post_menu(dirmenu); ret=TRUE; goto success;nomem: while(j>0) { if(filelist[j-1]) free(filelist[j-1]); j--; } free(filelist); filelist=NULL;failure: return ret;success: return ret;}int FileDialog::FileDialogDriver(){ int ret=0; int ch; int exist=TRUE; while(exist && (ch = wgetch(basewin))) { switch(ch) { case KEY_DOWN: if(active==FILELIST) { char str[MAXFIELDLEN]; menu_driver(dirmenu,REQ_DOWN_ITEM); getcwd(str,MAXFIELDLEN); if(strlen(str)>1) strcat(str,"/"); strcat(str,item_name(current_item(dirmenu))); set_field_buffer(locatefld[0],0,str); strcpy(filename[0],str); curitem=(curitem+1<diritemscount)?(curitem+1):(curitem); vscroll.ChangePos(diritemscount,curitem); } else if(active==FILELOCATE) { form_driver(locatefrm,REQ_NEXT_FIELD); form_driver(locatefrm,REQ_END_LINE); } break; case KEY_UP: if(active==FILELIST) { char str[MAXFIELDLEN]; menu_driver(dirmenu,REQ_UP_ITEM); getcwd(str,MAXFIELDLEN); if(strlen(str)>1) strcat(str,"/"); strcat(str,item_name(current_item(dirmenu))); set_field_buffer(locatefld[0],0,str); strcpy(filename[0],str); curitem=(curitem>0)?(curitem-1):(curitem); vscroll.ChangePos(diritemscount,curitem); } else if(active==FILELOCATE) { form_driver(locatefrm,REQ_PREV_FIELD); form_driver(locatefrm,REQ_END_LINE); } break; case KEY_LEFT: if(active==FILELOCATE) form_driver(locatefrm,REQ_PREV_CHAR); break; case KEY_RIGHT: if(active==FILELOCATE) form_driver(locatefrm,REQ_NEXT_CHAR); break; case KEY_NPAGE: if(active==FILELIST) { char str[MAXFIELDLEN]; menu_driver(dirmenu,REQ_SCR_DPAGE); getcwd(str,MAXFIELDLEN); if(strlen(str)>1) strcat(str,"/"); strcat(str,item_name(current_item(dirmenu))); set_field_buffer(locatefld[0],0,str); strcpy(filename[0],str); curitem=(curitem+height-5<diritemscount)?(curitem+height-5):(curitem); vscroll.ChangePos(diritemscount,curitem); } break; case KEY_PPAGE: if(active==FILELIST) { char str[MAXFIELDLEN]; menu_driver(dirmenu,REQ_SCR_UPAGE); getcwd(str,MAXFIELDLEN); if(strlen(str)>1) strcat(str,"/"); strcat(str,item_name(current_item(dirmenu))); set_field_buffer(locatefld[0],0,str); strcpy(filename[0],str); curitem=(curitem-height+5>0)?(curitem-height+5):(curitem); vscroll.ChangePos(diritemscount,curitem); } break; case KEY_HOME: if(active==FILELOCATE) form_driver(locatefrm,REQ_BEG_LINE); break; case KEY_END: if(active==FILELOCATE) form_driver(locatefrm,REQ_END_LINE); break; case KEY_DC: if(active==FILELOCATE) form_driver(locatefrm,REQ_DEL_CHAR); break; case KEY_BACKSPACE: if(active==FILELOCATE) form_driver(locatefrm,REQ_DEL_PREV); break; case KEY_TAB: if(active==FILELIST) { curs_set(1); form_driver(locatefrm,REQ_FIRST_FIELD); form_driver(locatefrm,REQ_END_LINE); active=FILELOCATE; } else if(active==FILELOCATE) { int mode=0; if(wintype==DIALOG_FILEOPEN) mode=ZC_READ; else if(wintype==DIALOG_FILESAVE || wintype==DIALOG_FILESAVEAS) mode=ZC_WRITE; form_driver(locatefrm,REQ_VALIDATION); curs_set(0); active=OKCANCEL; ret=DialogDriver(); if(ret==BUTOK || ret==BUTCANCEL) { if(ret==BUTOK) { strcpy(filename[0],trimleft(field_buffer(locatefld[0],0))); trimright(filename[0],filename[0]); strcpy(filename[1],trimleft(field_buffer(locatefld[1],0))); trimright(filename[1],filename[1]); AnaDirFile(mode,&exist,&ret); active=FILELIST; } else exist=FALSE; } else active=FILELIST; } break; case 0xA: { int mode=0; if(wintype==DIALOG_FILEOPEN) mode=ZC_READ; else if(wintype==DIALOG_FILESAVE || wintype==DIALOG_FILESAVEAS) mode=ZC_WRITE; if(active==FILELIST) { AnaDirFile(mode,&exist,&ret); } else if(active==FILELOCATE) { int index=field_index(current_field(locatefrm)); form_driver(locatefrm,REQ_VALIDATION); strcpy(filename[0],trimleft(field_buffer(locatefld[0],0))); trimright(filename[0],filename[0]); strcpy(filename[1],trimleft(field_buffer(locatefld[1],0))); trimright(filename[1],filename[1]); AnaDirFile(mode,&exist,&ret); if(index==0) { form_driver(locatefrm,REQ_FIRST_FIELD); } else { form_driver(locatefrm,REQ_LAST_FIELD); } form_driver(locatefrm,REQ_END_LINE); } break; } default: if(active==FILELOCATE) form_driver(locatefrm,ch); break; } } return ret;}void FileDialog::AnaDirFile(int mode,int *ext, int *rt){ if(AccessOK(mode)==TRUE) { struct stat buf; stat(filename[0],&buf); if(S_ISDIR(buf.st_mode)) { if(FileList(filename[0])==FALSE) { ErrMsg(OKONLYDLG,ERR_LISTFILE); refreshmainwnd(); ReDrawFileDialog(); goto over; } set_field_buffer(locatefld[0],0,filename[0]); curitem=0; vscroll.ChangePos(diritemscount,curitem); } else if(mode==ZC_READ) { SetFileName(); *ext=FALSE; *rt=BUTOK; } else if(mode==ZC_WRITE) { if(CheckSaveFile()==TRUE) { *ext=FALSE; *rt=BUTOK; } } } else //AccessOK return FALSE { ErrMsg(OKONLYDLG,ERR_NORIGHT); refreshmainwnd(); ReDrawFileDialog(); curs_set(1); }over: return;}BOOL FileDialog::AccessOK(int mode){ BOOL ret=FALSE; char tmp[MAXFIELDLEN]; strcpy(tmp,filename[0]); if(mode&ZC_READ) { if(access(tmp,R_OK)==0) ret=TRUE; } if(mode&ZC_WRITE) { if(access(tmp,F_OK)==-1) //not exist,maybe create a new file { getpath(tmp); if(strlen(tmp)<strlen(filename[0]) && access(tmp,W_OK|F_OK)==0) //in the case of /home/pretty/ ret=TRUE; } else //exist { if(access(tmp,W_OK)==0) //has right { ret=TRUE; } } } if(mode&ZC_EXEC) { ErrMsg(OKONLYDLG,"Unknown Error!"); } return ret;}void FileDialog::SetFileName(){ strncpy(msg.fileobj.filename,filename[0],MAXFIELDLEN); msg.fileobj.type=wintype; return;}BOOL FileDialog::CheckSaveFile(){ BOOL ret=FALSE; char tmp[MAXFIELDLEN]; if(access(filename[0],F_OK)==0) //file exist { curs_set(0); strcpy(tmp,filename[0]); if(ErrMsg(OKCANCELDLG,strcat(tmp,ERR_OVERRIDE))==BUTOK) { strncpy(msg.fileobj.filename,filename[0],MAXFIELDLEN); msg.fileobj.type=wintype; ret=TRUE; } refreshmainwnd(); ReDrawFileDialog(); curs_set(1); form_driver(locatefrm,REQ_FIRST_FIELD); form_driver(locatefrm,REQ_END_LINE); active=FILELOCATE; } else { SetFileName(); ret=TRUE; } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -