/* ---------------------------------------------------------------- * * cbx_files.c * * Xlib - wrappers and convenience functions * * v4.00 2002-03-27 auto-managed windows / MainWindow [CCB] * 4.070 2015-02-03 use CXT_OpenMainWindow() * * ---------------------------------------------------------------- */ #define IS_CXTLIB_C /* DEFINEs -------------------------------------------------------- */ #ifndef DEBUG #define DEBUG 1 /* debug level */ #endif #define CBX_MAX_FILES 4096 #define CBX_MAX_LEN 256 #define BELL ((char)7) #ifdef FONTSIZE #define PXh FONTSIZE #else #define PXh 14 /* default fontsize */ #endif #define PXw (10+(PXh-14)/2) #define XXh (PXh+4) #define PREFUN __func__ /* INCLUDEs ------------------------------------------------------- */ #define _REENTRANT #include /* malloc(),free() */ #include #include /* strcpy(),strlen() */ #include /* chdir() */ #include "cxt.h" /* STATICs -------------------------------------------------------- */ static int fs_done; static int cbx_readdir(char*,char*,char**); static int fs_create_listbox(MainWindow*,Listbox*,int,int,int,int,int, char*,char*,char**); static void fs_dclick(void); /* ---------------------------------------------------------------- */ /* FileSelector */ /* ---------------------------------------------------------------- */ Bool CBX_FileSelector(char *path,char *filter,char *filename,int n,int pos) { MainWindow box; Listbox lb; Button rebut,okbut,cabut; /* re-scan, ok, cancel */ EditWindow fiwin,pawin; /* filter , path */ XSizeHints hint; XEvent event; const int PAx=2,PAy=2,PAw=25*PXw,w=PAx+PAw+PXw/2; const int LBx=2,LBy=PAy+XXh+PXw/2,LBw=PAw,LBh=PXh+2; const int FIx=7*PXw,FIy=LBy+n*LBh+PXh/2,FIw=8*PXw; const int REx=FIx+FIw+2*PXw,REy=FIy,REw=8*PXw; const int OKw=5*PXw,OKx=(w/3)-OKw/2,OKy=FIy+XXh+PXh; const int CAy=OKy,CAw=7*PXw,h=OKy+XXh+PXh/2,CAx=(2*w)/3-(CAw/2); int slpt=0; char *flist[CBX_MAX_FILES],buffer[1024]; (void)CXT_OpenMainWindow(&box,CBX_CENTER,w,h,&hint,"File Selector Box", "FileSel",True); (void)CBX_CreateAutoOutput(&box,&pawin,PAx,PAy,PAw,XXh,path); (void)CBX_CreateEditWindow(&box,&fiwin,FIx,FIy,FIw,XXh,2,filter,0); (void)CBX_CreateButton(&box,&rebut,REx,REy,REw,XXh,"re-scan"); (void)CBX_CreateButton(&box,&okbut,OKx,OKy,OKw,XXh,"OK"); (void)CBX_CreateButton(&box,&cabut,CAx,CAy,CAw,XXh,"cancel"); flist[0] = (char*)malloc(CBX_MAX_FILES*CBX_MAX_LEN*sizeof(char)/4); lb.listbox = 0; (void)fs_create_listbox(&box,&lb,LBx,LBy,LBw,LBh,n,path,filter,flist); fs_done = 0; do { /* event loop */ while (!CBX_AutoEvent(&box,&event,&slpt)) { CBX_Sleep(&slpt,5,200); } if (!CBX_HandleListbox(&event,&lb,fs_dclick)) { switch (event.type) { case Expose: /* expose event */ if (event.xexpose.count != 0) break; CBX_RedrawListbox(&lb,True); CBX_UpdateEditWindow(&fiwin); CBX_UpdateButton(&rebut); CBX_UpdateButton(&okbut); CBX_UpdateButton(&cabut); CBX_DrawString(&box,5,FIy+PXh,"Filter"); break; case KeyPress: /* key pressed */ if (event.xkey.window == fiwin.win) { /* filter window */ if (CBX_HandleEditWindow(&fiwin,(XKeyEvent*)&event)) { (void)fs_create_listbox(&box,&lb,LBx,LBy,LBw,LBh,n,pawin.text, fiwin.text,flist); } } break; case EnterNotify: /* window-enter event */ case LeaveNotify: /* window-leave event */ if (event.xcrossing.window == fiwin.win) { CBX_CrossEditWindow(&fiwin,event.type); } break; case ButtonPress: /* button-press event */ if (event.xbutton.button != 1) break; if (event.xbutton.window == rebut.win) { /* re-scan button */ if (CBX_HandleButton(&rebut) != CBX_PRESSED) break; (void)fs_create_listbox(&box,&lb,LBx,LBy,LBw,LBh,n,pawin.text, fiwin.text,flist); CBX_ReleaseButton(&rebut); } else if (event.xbutton.window == okbut.win) { /* OK button */ if (CBX_HandleButton(&okbut) == CBX_PRESSED) fs_done = 1; } else if (event.xbutton.window == cabut.win) { /* cancel button */ if (CBX_HandleButton(&cabut) == CBX_PRESSED) fs_done = -1; } break; default: fprintf(stderr,"%s(): unknown event.type= %d\n",PREFUN,event.type); break; } } /* endif(HandleListbox) */ if (fs_done > 0) { /* ok */ #if (DEBUG > 1) fprintf(stderr,"lb.sel=%d, lb.pos=%d\n",lb.sel,lb.pos); #endif if (lb.sel < 0) { /* no selection */ fprintf(stderr,"%s(): no filename selected%c\n",PREFUN,BELL); fs_done = 0; CBX_ReleaseButton(&okbut); } else { strcpy(buffer,flist[lb.sel]); #if (DEBUG > 1) fprintf(stderr,"path=%s, filename=%s\n",pawin.text,buffer); #endif if (buffer[strlen(buffer)-1] == '/') { /* is directory */ (void)chdir(buffer); /* go there */ getcwd(pawin.text,sizeof(pawin.text)-1); /* get new path */ CBX_UpdateEditWindow(&pawin); (void)fs_create_listbox(&box,&lb,LBx,LBy,LBw,LBh,n,pawin.text, fiwin.text,flist); fs_done = 0; } } /* endif(lb.sel < 0) */ } /* endif(fs_done > 0) */ } while (fs_done == 0); if (fs_done > -2) CBX_CloseMainWindow(&box); /* cleanup */ free((void*)flist[0]); if (fs_done > 0) { /* copy selection */ (void)strcpy(filename,buffer); (void)strcpy(path,pawin.text); (void)strcpy(filter,fiwin.text); #if (DEBUG > 1) fprintf(stderr,"%s, %s, %s\n",filename,path,filter); #endif return(True); } return(False); } /* ---------------------------------------------------------------- */ static int fs_create_listbox(MainWindow* mw,Listbox* lb,int x,int y, int w,int h, int n,char* path,char* filter, char** flist) { int nfiles; nfiles = cbx_readdir(path,filter,flist); /* re-scan path */ if (CBX_IsWindow(lb->listbox)) { /* window exists */ (void)CBX_Lock(0); XDestroyWindow(mw->disp,lb->listbox); CBX_Unlock(); } (void)CBX_CreateListbox(mw,lb,x,y,w,h,n,flist,nfiles); return(nfiles); } /* ---------------------------------------------------------------- */ static void fs_dclick(void) { fs_done = 1; } /* ---------------------------------------------------------------- */ static int cbx_readdir(char *path,char *filter,char **list) { int i=0; char cmd[128],buffer[1024]; FILE *pp; if (chdir(path) == -1) return(0); (void)strcpy(cmd,"ls -1dF *"); if ((pp=popen(cmd,"r")) == NULL) return(0); if (strcmp(path,"/")) { /* parent directory */ (void)strcpy(list[i],"../"); list[i+1] = list[i]+strlen(list[i])+1; i++; } while (fgets(buffer,sizeof(buffer)-1,pp) != NULL) { buffer[strlen(buffer)-1] = '\0'; /* remove */ if (buffer[strlen(buffer)-1] != '/') continue; (void)strcpy(list[i],buffer); list[i+1] = list[i] + strlen(buffer) + 1; if (++i == CBX_MAX_FILES) break; } pclose(pp); if (i == CBX_MAX_FILES) return(i); sprintf(cmd,"ls -1dF %s",filter); if ((pp=popen(cmd,"r")) == NULL) return(i); while (fgets(buffer,sizeof(buffer)-1,pp) != NULL) { buffer[strlen(buffer)-1] = '\0'; /* remove */ if (buffer[strlen(buffer)-1] == '/') continue; if (buffer[strlen(buffer)-1] == '*') buffer[strlen(buffer)-1] = '\0'; if (buffer[strlen(buffer)-1] == '@') buffer[strlen(buffer)-1] = '\0'; (void)strcpy(list[i],buffer); list[i+1] = list[i] + strlen(buffer) + 1; if (++i == CBX_MAX_FILES) break; } pclose(pp); return(i); } /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */