X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=filebrowser%2Fselfile.c;h=71dcd8cd4dc137c820416b00051c5a4892afd342;hb=4eec2ced245a4f86a63ca03781250cc6c82cddf2;hp=860ed8b4e60727ffeff42b0cab973ea54c667e16;hpb=b4c2ef53cf5a608a9488ed5cf53da908e9553d21;p=xboard.git diff --git a/filebrowser/selfile.c b/filebrowser/selfile.c index 860ed8b..71dcd8c 100644 --- a/filebrowser/selfile.c +++ b/filebrowser/selfile.c @@ -60,17 +60,8 @@ extern int errno; #include #include -#include "selfile.h" #include "xstat.h" - -/* added missing prototypes */ -extern void SFdrawList(int,int); -extern void SFinitFont(); -extern void SFcreateGC(); -extern int SFchdir(char *); -extern void SFupdatePath(); -extern void SFsetText(char *); -extern char SFstatChar(struct stat*); +#include "selfile.h" #ifndef MAXPATHLEN #define MAXPATHLEN 1024 @@ -83,14 +74,17 @@ extern char *getwd(); int SFstatus = SEL_FILE_NULL; char - SFstartDir[MAXPATHLEN], - SFcurrentPath[MAXPATHLEN], - SFcurrentDir[MAXPATHLEN]; + SFstartDir[MAXPATHLEN+1], + SFcurrentPath[MAXPATHLEN+1], + SFlastPath[MAXPATHLEN+1], + SFcurrentDir[MAXPATHLEN+1]; Widget selFile, selFileCancel, selFileField, + selFileMess, + filterField, selFileForm, selFileHScroll, selFileHScrolls[3], @@ -133,12 +127,16 @@ XtAppContext SFapp; int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth; -char SFtextBuffer[MAXPATHLEN]; +char SFtextBuffer[MAXPATHLEN+1]; + +char SFfilterBuffer[MAXPATHLEN+1]; XtIntervalId SFdirModTimerId; int (*SFfunc)(); +Boolean SFpathFlag; // [HGM] + static char *oneLineTextEditTranslations = "\ Return: redraw-display()\n\ CtrlM: redraw-display()\n\ @@ -156,7 +154,14 @@ SFexposeList(w, n, event, cont) return; } - SFdrawList((int)n, SF_DO_NOT_SCROLL); + SFdrawList((int)(intptr_t)n, SF_DO_NOT_SCROLL); +} + +void +SFpurge() +{ + if(SFdirs) XtFree((XtPointer) SFdirs); + SFdirs = NULL; // kludge to throw away all cached info } /* ARGSUSED */ @@ -171,11 +176,30 @@ SFmodVerifyCallback(w, client_data, event, cont) if ( (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) && - ((*buf) == '\r') + ((*buf) == '\r' || *buf == 033) ) { - SFstatus = SEL_FILE_OK; + if(client_data) { + Arg args[10]; char *p; + if(*buf == 033) { // [HGM] esc in filter: restore and give focus to path + XtSetArg(args[0], XtNstring, SFfilterBuffer); + XtSetValues(filterField, args, 1); + XtSetKeyboardFocus(selFileForm, selFileField); + SFstatus = SEL_FILE_TEXT; + return; + } else + if(!SFpathFlag) // [HGM] cr: fetch current extenson filter + { + XtSetArg(args[0], XtNstring, &p); + XtGetValues(filterField, args, 1); + if(strcmp(SFfilterBuffer, p)) SFpurge(); + strncpy(SFfilterBuffer, p, 40); + SFstatus = SEL_FILE_TEXT; + } + return; + } + SFstatus = (*buf == 033 ? SEL_FILE_CANCEL : SEL_FILE_OK); } else { - SFstatus = SEL_FILE_TEXT; + if(!client_data) SFstatus = SEL_FILE_TEXT; } } @@ -229,6 +253,19 @@ static XtActionsRec actions[] = { {"SelFileDismiss", SFdismissAction}, }; +void SFsetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b) +{ + XtSetKeyboardFocus((Widget) data, w); +} + +void SFwheelProc(Widget w, XtPointer data, XEvent *event, Boolean *b) +{ // [HGM] mouse-wheel callback scrolls lists + int dir, n = (intptr_t) data; + if(event->xbutton.button == Button4) dir = -2; // kludge to indicate relative motion + if(event->xbutton.button == Button5) dir = -1; + SFvSliderMovedCallback(w, n, dir); +} + static void SFcreateWidgets(toplevel, prompt, ok, cancel) Widget toplevel; @@ -335,7 +372,7 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) XtSetArg(arglist[i], XtNborderColor, SFfore); i++; XtSetArg(arglist[i], XtNfromVert, selFilePrompt); i++; - XtSetArg(arglist[i], XtNvertDistance, 10); i++; + XtSetArg(arglist[i], XtNvertDistance, 5); i++; XtSetArg(arglist[i], XtNresizable, True); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; @@ -346,21 +383,56 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) XtSetArg(arglist[i], XtNeditType, XawtextEdit); i++; XtSetArg(arglist[i], XtNwrap, XawtextWrapWord); i++; XtSetArg(arglist[i], XtNresize, XawtextResizeHeight); i++; - XtSetArg(arglist[i], XtNuseStringInPlace, True); i++; selFileField = XtCreateManagedWidget("selFileField", asciiTextWidgetClass, selFileForm, arglist, i); XtOverrideTranslations(selFileField, XtParseTranslationTable(oneLineTextEditTranslations)); - XtSetKeyboardFocus(selFileForm, selFileField); + XtAddEventHandler(selFileField, ButtonPressMask, False, SFsetFocus, (XtPointer) selFileForm); + + i = 0; + XtSetArg(arglist[i], XtNlabel, "Filter on extensions:"); i++; + XtSetArg(arglist[i], XtNvertDistance, 5); i++; + XtSetArg(arglist[i], XtNfromVert, selFileField); i++; + XtSetArg(arglist[i], XtNresizable, True); i++; + XtSetArg(arglist[i], XtNtop, XtChainTop); i++; + XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; + XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; + XtSetArg(arglist[i], XtNright, XtChainLeft); i++; + XtSetArg(arglist[i], XtNborderWidth, 0); i++; + selFileMess = XtCreateManagedWidget("selFileMess", + labelWidgetClass, selFileForm, arglist, i); + + i = 0; + XtSetArg(arglist[i], XtNwidth, NR * listWidth + (NR - 1) * listSpacing + 4); + i++; + XtSetArg(arglist[i], XtNborderColor, SFfore); i++; + XtSetArg(arglist[i], XtNvertDistance, 5); i++; + XtSetArg(arglist[i], XtNfromVert, selFileMess); i++; + XtSetArg(arglist[i], XtNresizable, True); i++; + XtSetArg(arglist[i], XtNtop, XtChainTop); i++; + XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; + XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; + XtSetArg(arglist[i], XtNright, XtChainLeft); i++; + XtSetArg(arglist[i], XtNlength, MAXPATHLEN); i++; + XtSetArg(arglist[i], XtNeditType, XawtextEdit); i++; + XtSetArg(arglist[i], XtNwrap, XawtextWrapWord); i++; + XtSetArg(arglist[i], XtNresize, XawtextResizeHeight); i++; + XtSetArg(arglist[i], XtNuseStringInPlace, False); i++; + filterField = XtCreateManagedWidget("filterField", + asciiTextWidgetClass, selFileForm, arglist, i); + + XtOverrideTranslations(filterField, + XtParseTranslationTable(oneLineTextEditTranslations)); + XtAddEventHandler(filterField, ButtonPressMask, False, SFsetFocus, (XtPointer) selFileForm); i = 0; XtSetArg(arglist[i], XtNorientation, XtorientHorizontal); i++; XtSetArg(arglist[i], XtNwidth, SFpathScrollWidth); i++; XtSetArg(arglist[i], XtNheight, scrollThickness); i++; XtSetArg(arglist[i], XtNborderColor, SFfore); i++; - XtSetArg(arglist[i], XtNfromVert, selFileField); i++; - XtSetArg(arglist[i], XtNvertDistance, 30); i++; + XtSetArg(arglist[i], XtNfromVert, filterField); i++; + XtSetArg(arglist[i], XtNvertDistance, 10); i++; XtSetArg(arglist[i], XtNtop, XtChainTop); i++; XtSetArg(arglist[i], XtNbottom, XtChainTop); i++; XtSetArg(arglist[i], XtNleft, XtChainLeft); i++; @@ -428,9 +500,9 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) scrollbarWidgetClass, selFileLists[n], arglist, i); XtAddCallback(selFileVScrolls[n], XtNjumpProc, - SFvFloatSliderMovedCallback, (XtPointer) n); + SFvFloatSliderMovedCallback, (XtPointer)(intptr_t) n); XtAddCallback(selFileVScrolls[n], XtNscrollProc, - SFvAreaSelectedCallback, (XtPointer) n); + SFvAreaSelectedCallback, (XtPointer)(intptr_t) n); i = 0; @@ -445,9 +517,12 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) scrollbarWidgetClass, selFileLists[n], arglist, i); XtAddCallback(selFileHScrolls[n], XtNjumpProc, - SFhSliderMovedCallback, (XtPointer) n); + SFhSliderMovedCallback, (XtPointer)(intptr_t) n); XtAddCallback(selFileHScrolls[n], XtNscrollProc, - SFhAreaSelectedCallback, (XtPointer) n); + SFhAreaSelectedCallback, (XtPointer)(intptr_t) n); + + XtAddEventHandler(selFileVScrolls[n], ButtonPressMask, False, + SFwheelProc, (XtPointer)(intptr_t) n); // [HGM] couplemouse wheel to v-scroll } i = 0; @@ -496,6 +571,7 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) XDefineCursor(SFdisplay, XtWindow(selFileForm), xtermCursor); XDefineCursor(SFdisplay, XtWindow(selFileField), xtermCursor); + XDefineCursor(SFdisplay, XtWindow(filterField), xtermCursor); for (n = 0; n < NR; n++) { XDefineCursor(SFdisplay, XtWindow(selFileLists[n]), @@ -506,21 +582,24 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) for (n = 0; n < NR; n++) { XtAddEventHandler(selFileLists[n], ExposureMask, True, - SFexposeList, (XtPointer) n); + SFexposeList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], EnterWindowMask, False, - SFenterList, (XtPointer) n); + SFenterList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], LeaveWindowMask, False, - SFleaveList, (XtPointer) n); + SFleaveList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], PointerMotionMask, False, - SFmotionList, (XtPointer) n); + (XtEventHandler) SFmotionList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], ButtonPressMask, False, - SFbuttonPressList, (XtPointer) n); + SFbuttonPressList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False, - SFbuttonReleaseList, (XtPointer) n); + SFbuttonReleaseList, (XtPointer)(intptr_t) n); } XtAddEventHandler(selFileField, KeyPressMask, False, SFmodVerifyCallback, (XtPointer) NULL); + XtAddEventHandler(filterField, KeyReleaseMask, False, + SFmodVerifyCallback, (XtPointer) 1); + XtSetKeyboardFocus(selFileForm, selFileField); SFapp = XtWidgetToApplicationContext(selFile); @@ -599,8 +678,35 @@ SFopenFile(name, mode, prompt, failed) } void +SFupdateTextBuffer() +{ + Arg arglist[2]; + int i; + char *v; + + i = 0; + XtSetArg(arglist[i], XtNstring, &v); i++; + XtGetValues(selFileField, arglist, i); + strncpy(SFtextBuffer, v, MAXPATHLEN); +} + +void +SFsetText(path) + char *path; +{ + Arg arglist[2]; + int i; + + i = 0; + XtSetArg(arglist[i], XtNstring, path); i++; + XtSetValues(selFileField, arglist, i); + XawTextSetInsertionPoint(selFileField, strlen(path)); +} + +void SFtextChanged() { + SFupdateTextBuffer(); if ((SFtextBuffer[0] == '/') || (SFtextBuffer[0] == '~')) { (void) strncpy(SFcurrentPath, SFtextBuffer, MAXPATHLEN); @@ -647,13 +753,14 @@ SFprepareToReturn() FILE * XsraSelFile(toplevel, prompt, ok, cancel, failed, - init_path, mode, show_entry, name_return) + init_path, filter, mode, show_entry, name_return) Widget toplevel; char *prompt; char *ok; char *cancel; char *failed; char *init_path; + char *filter; char *mode; int (*show_entry)(); char **name_return; @@ -676,6 +783,11 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, cancel = "Cancel"; } + if(SFpathFlag != (mode && mode[0] == 'p') || strcmp(SFfilterBuffer, filter)) { + SFpurge(); + SFpathFlag = (mode && mode[0] == 'p'); // [HGM] ignore everything that is not a directory + } + if (firstTime) { firstTime = 0; SFdisplay = XtDisplay(toplevel); @@ -695,6 +807,14 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, XtSetValues(selFileCancel, arglist, i); } + i = 0; + XtSetArg(arglist[i], XtNstring, filter); i++; + XtSetValues(filterField, arglist, i); + + strncpy(SFfilterBuffer, filter, MAXPATHLEN-1); + SFupdateTextBuffer(); + strncpy(SFlastPath, SFtextBuffer, MAXPATHLEN-1); // remember for cancel + SFpositionWidget(selFile); XtMapWidget(selFile); @@ -749,8 +869,12 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, break; case SEL_FILE_OK: *name_return = SFgetText(); - if (fp = SFopenFile(*name_return, mode, - prompt, failed)) { + if(mode && (mode[0] == 'p' || mode[0] == 'f')) { // [HGM] for use in file-option browse button + SFprepareToReturn(); + return stderr; + } + if ((*name_return)[strlen(*name_return)-1] != '/' && // [HGM] refuse directories + (fp = SFopenFile(*name_return, mode, prompt, failed))) { SFprepareToReturn(); return fp; } @@ -758,9 +882,11 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, break; case SEL_FILE_CANCEL: SFprepareToReturn(); + SFsetText(SFlastPath); return NULL; case SEL_FILE_NULL: break; } } + }