X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=filebrowser%2Fselfile.c;h=729453b3a5434a4af67d0165a2b463612aec7f5f;hb=919bb8ce56406c6059ec9d3221d1bc96ad388d1c;hp=2e3495589291cf45700edfcd2816971b1d3453b0;hpb=d2f43d6c61f76a5b3999db2f5a0c8b23b2387a42;p=xboard.git diff --git a/filebrowser/selfile.c b/filebrowser/selfile.c index 2e34955..729453b 100644 --- a/filebrowser/selfile.c +++ b/filebrowser/selfile.c @@ -60,17 +60,9 @@ 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" +#include "../gettext.h" #ifndef MAXPATHLEN #define MAXPATHLEN 1024 @@ -80,17 +72,29 @@ extern char SFstatChar(struct stat*); extern char *getwd(); #endif /* !defined(SVR4) && !defined(SYSV) && !defined(USG) */ +#ifdef ENABLE_NLS +# define _(s) gettext (s) +# define N_(s) gettext_noop (s) +#else +# define _(s) (s) +# define N_(s) s +#endif + + 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,7 +137,9 @@ XtAppContext SFapp; int SFpathScrollWidth, SFvScrollHeight, SFhScrollWidth; -char SFtextBuffer[MAXPATHLEN]; +char SFtextBuffer[MAXPATHLEN+1]; + +char SFfilterBuffer[MAXPATHLEN+1]; XtIntervalId SFdirModTimerId; @@ -161,6 +167,13 @@ SFexposeList(w, n, event, cont) 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 */ static void SFmodVerifyCallback(w, client_data, event, cont) @@ -173,11 +186,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; } } @@ -231,6 +263,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; @@ -253,7 +298,7 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) i = 0; XtSetArg(arglist[i], XtNtransientFor, toplevel); i++; - selFile = XtAppCreateShell("Browse", "SelFile", + selFile = XtAppCreateShell(_("Browse"), "SelFile", transientShellWidgetClass, SFdisplay, arglist, i); /* Add WM_DELETE_WINDOW protocol */ @@ -337,7 +382,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++; @@ -348,21 +393,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++; @@ -450,6 +530,9 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) SFhSliderMovedCallback, (XtPointer)(intptr_t) n); XtAddCallback(selFileHScrolls[n], XtNscrollProc, SFhAreaSelectedCallback, (XtPointer)(intptr_t) n); + + XtAddEventHandler(selFileVScrolls[n], ButtonPressMask, False, + SFwheelProc, (XtPointer)(intptr_t) n); // [HGM] couplemouse wheel to v-scroll } i = 0; @@ -498,6 +581,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]), @@ -514,7 +598,7 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) XtAddEventHandler(selFileLists[n], LeaveWindowMask, False, SFleaveList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], PointerMotionMask, False, - SFmotionList, (XtPointer)(intptr_t) n); + (XtEventHandler) SFmotionList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], ButtonPressMask, False, SFbuttonPressList, (XtPointer)(intptr_t) n); XtAddEventHandler(selFileLists[n], ButtonReleaseMask, False, @@ -523,6 +607,9 @@ SFcreateWidgets(toplevel, prompt, ok, cancel) XtAddEventHandler(selFileField, KeyPressMask, False, SFmodVerifyCallback, (XtPointer) NULL); + XtAddEventHandler(filterField, KeyReleaseMask, False, + SFmodVerifyCallback, (XtPointer) 1); + XtSetKeyboardFocus(selFileForm, selFileField); SFapp = XtWidgetToApplicationContext(selFile); @@ -601,8 +688,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); @@ -649,13 +763,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; @@ -667,21 +782,20 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, FILE *fp; if (!prompt) { - prompt = "Pathname:"; + prompt = _("Pathname:"); } if (!ok) { - ok = "OK"; + ok = _("OK"); } if (!cancel) { - cancel = "Cancel"; + cancel = _("Cancel"); } - if(SFpathFlag != (mode && mode[0] == 'p')) { // [HGM] ignore everything that is not a directory - if(SFdirs) XtFree(SFdirs); - SFdirs = NULL; // kludge to throw away all cached info - SFpathFlag = !SFpathFlag; + 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) { @@ -703,6 +817,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); @@ -712,7 +834,7 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, if (!getwd(SFstartDir)) { #endif /* defined(SVR4) || defined(SYSV) || defined(USG) */ - XtAppError(SFapp, "XsraSelFile: can't get current directory"); + XtAppError(SFapp, _("XsraSelFile: can't get current directory")); } (void) strcat(SFstartDir, "/"); (void) strncpy(SFcurrentDir, SFstartDir, MAXPATHLEN); @@ -761,8 +883,8 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, SFprepareToReturn(); return stderr; } - if (fp = SFopenFile(*name_return, mode, - prompt, failed)) { + if ((!(*name_return)[0] || (*name_return)[strlen(*name_return)-1] != '/') && // [HGM] refuse directories + (fp = SFopenFile(*name_return, mode, prompt, failed))) { SFprepareToReturn(); return fp; } @@ -770,9 +892,11 @@ XsraSelFile(toplevel, prompt, ok, cancel, failed, break; case SEL_FILE_CANCEL: SFprepareToReturn(); + SFsetText(SFlastPath); return NULL; case SEL_FILE_NULL: break; } } + }