📄 getfiles.c
字号:
mString = XmStringCreateLtoR(string, XmSTRING_DEFAULT_CHARSET); SET_ONE_RSRC(ErrorDialog, XmNmessageString, mString); XmStringFree(mString); ManageDialogCenteredOnPointer(ErrorDialog); while (!ErrorDone) XtAppProcessEvent (XtWidgetToApplicationContext(ErrorDialog), XtIMAll); XtUnmanageChild(ErrorDialog);}static void newFileOKCB(Widget w, Boolean *client_data, XmFileSelectionBoxCallbackStruct *call_data){ char *filename; /* name of chosen file */ int fd; /* file descriptor */ int length; /* length of file name */ int response; /* response to dialog */ struct stat buf; /* status from fstat */ XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename); SelectResult = GFN_OK; length = strlen(filename); if (length == 0 || filename[length-1] == '/') { doErrorDialog("Please supply a name for the file", NULL); XtFree(filename); return; }#ifdef VMS if (strchr(filename,';') && (fd = open(filename, O_RDONLY, 0)) != -1) {#else /* not VMS*/ if ((fd = open(filename, O_RDONLY, 0)) != -1) { /* exists */#endif /*VMS*/ fstat(fd, &buf); close(fd); if (buf.st_mode & S_IFDIR) { doErrorDialog("Error: %s is a directory", filename); XtFree(filename); return; } response = doYesNoDialog(filename);#ifdef VMS if (response) { if (access(filename, 2) != 0) { /* have write/delete access? */ doErrorDialog("Error: can't overwrite %s ", filename); XtFree(filename); return; } } else {#else if (!response) {#endif /*VMS*/ return; } } else { if ((fd = creat(filename, PERMS)) == -1) { doErrorDialog("Error: can't create %s ", filename); XtFree(filename); return; } else { close(fd); remove(filename); } } XtFree(filename); *client_data = True; /* done with dialog */}static void newFileCancelCB(Widget w, Boolean *client_data, caddr_t call_data){ SelectResult = GFN_CANCEL; *client_data = True;}static void newHelpCB(Widget w, Widget helpPanel, caddr_t call_data){ ManageDialogCenteredOnPointer(helpPanel);}static void existOkCB(Widget w, Boolean * client_data, XmFileSelectionBoxCallbackStruct *call_data){ char *filename; /* name of chosen file */ int fd; /* file descriptor */ int length; /* length of file name */ XmStringGetLtoR(call_data->value, XmSTRING_DEFAULT_CHARSET, &filename); SelectResult = GFN_OK; length = strlen(filename); if (length == 0 || filename[length-1] == '/') { doErrorDialog("Please select a file to open", NULL); XtFree(filename); return; } else if ((fd = open(filename, O_RDONLY,0)) == -1) { doErrorDialog("Error: can't open %s ", filename); XtFree(filename); return; } else close(fd); XtFree(filename); *client_data = True; /* done with dialog */}static void existCancelCB(Widget w, Boolean * client_data, caddr_t call_data){ SelectResult = GFN_CANCEL; *client_data = True; /* done with dialog */}static void yesNoOKCB(Widget w, caddr_t client_data, caddr_t call_data){ YesNoResult = ynYes;}static void existHelpCB(Widget w, Widget helpPanel, caddr_t call_data){ ManageDialogCenteredOnPointer(helpPanel);}static void errorOKCB(Widget w, caddr_t client_data, caddr_t call_data){ ErrorDone = True;}static void yesNoCancelCB(Widget w, caddr_t client_data, caddr_t call_data){ YesNoResult = ynNo;}static Widget createPanelHelp(Widget parent, const char *helpText, const char *title){ Arg al[20]; int ac; Widget form, text, button; XmString st1; ac = 0; form = CreateFormDialog(parent, "helpForm", al, ac); ac = 0; XtSetArg (al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg (al[ac], XmNtopAttachment, XmATTACH_NONE); ac++; XtSetArg(al[ac], XmNlabelString, st1=XmStringCreateLtoR ("Dismiss", XmSTRING_DEFAULT_CHARSET)); ac++; button = XmCreatePushButtonGadget(form, "dismiss", al, ac); XtAddCallback(button, XmNactivateCallback, (XtCallbackProc)helpDismissCB, (char *)form); XmStringFree(st1); XtManageChild(button); SET_ONE_RSRC(form, XmNdefaultButton, button); ac = 0; XtSetArg(al[ac], XmNrows, 15); ac++; XtSetArg(al[ac], XmNcolumns, 60); ac++; XtSetArg(al[ac], XmNresizeHeight, False); ac++; XtSetArg(al[ac], XmNtraversalOn, False); ac++; XtSetArg(al[ac], XmNwordWrap, True); ac++; XtSetArg(al[ac], XmNscrollHorizontal, False); ac++; XtSetArg(al[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++; XtSetArg(al[ac], XmNeditable, False); ac++; XtSetArg(al[ac], XmNvalue, helpText); ac++; XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_WIDGET); ac++; XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(al[ac], XmNbottomWidget, button); ac++; text = XmCreateScrolledText(form, "helpText", al, ac); AddMouseWheelSupport(text); XtManageChild(text); SET_ONE_RSRC(XtParent(form), XmNtitle, title); return form;}static void helpDismissCB(Widget w, Widget helpPanel, caddr_t call_data){ XtUnmanageChild(helpPanel);}/*** Add ability for user to type filenames to a list widget*/static void makeListTypeable(Widget listW){ XtAddEventHandler(listW, KeyPressMask, False, listCharEH, NULL);}/*** Action procedure for processing characters typed in a list, finds the** first item matching the characters typed so far.*/static int nKeystrokes = 0; /* Global key stroke history counter */static void listCharEH(Widget w, XtPointer callData, XEvent *event, Boolean *continueDispatch){ char charString[5], c, *itemString; int nChars, nItems, i, cmp, selectPos, topPos, nVisible; XmString *items; KeySym kSym; char name[MAXPATHLEN], path[MAXPATHLEN]; static char keystrokes[MAX_LIST_KEYSTROKES]; static Time lastKeyTime = 0; /* Get the ascii character code represented by the event */ nChars = XLookupString((XKeyEvent *)event, charString, sizeof(charString), &kSym, NULL); c = charString[0]; /* Process selected control keys, but otherwise ignore the keystroke if it isn't a single printable ascii character */ *continueDispatch = False; if (kSym==XK_BackSpace || kSym==XK_Delete) { nKeystrokes = nKeystrokes > 0 ? nKeystrokes-1 : 0; return; } else if (kSym==XK_Clear || kSym==XK_Cancel || kSym==XK_Break) { nKeystrokes = 0; return; } else if (nChars!=1 || c<0x021 || c>0x07e) { *continueDispatch = True; return; } /* Throw out keystrokes and start keystroke accumulation over from scratch if user waits more than MAX_LIST_KESTROKE_WAIT milliseconds */ if (((XKeyEvent *)event)->time - lastKeyTime > MAX_LIST_KESTROKE_WAIT) nKeystrokes = 0; lastKeyTime = ((XKeyEvent *)event)->time; /* Accumulate the current keystroke, just beep if there are too many */ if (nKeystrokes >= MAX_LIST_KEYSTROKES) XBell(XtDisplay(w), 0); else#ifdef VMS keystrokes[nKeystrokes++] = toupper(c);#else keystrokes[nKeystrokes++] = c;#endif /* Get the items (filenames) in the list widget */ XtVaGetValues(w, XmNitems, &items, XmNitemCount, &nItems, NULL); /* compare them with the accumulated user keystrokes & decide the appropriate line in the list widget to select */ selectPos = 0; for (i=0; i<nItems; i++) { XmStringGetLtoR(items[i], XmSTRING_DEFAULT_CHARSET, &itemString); if (ParseFilename(itemString, name, path) != 0) { XtFree(itemString); return; } XtFree(itemString); cmp = strncmp(name, keystrokes, nKeystrokes); if (cmp == 0) { selectPos = i+1; break; } else if (cmp > 0) { selectPos = i; break; } } /* Make the selection, and make sure it will be visible */ XmListSelectPos(w, selectPos, True); if (selectPos == 0) /* XmListSelectPos curiously returns 0 for last item */ selectPos = nItems + 1; XtVaGetValues(w, XmNtopItemPosition, &topPos, XmNvisibleItemCount, &nVisible, NULL); if (selectPos < topPos) XmListSetPos(w, selectPos-2 > 1 ? selectPos-2 : 1); else if (selectPos > topPos+nVisible-1) XmListSetBottomPos(w, selectPos+2 <= nItems ? selectPos+2 : 0); /* For LessTif 0.89.9. Obsolete now? */ XmListSelectPos(w, selectPos, True);}/*** Replacement directory and file search procedures for the file selection** box to re-sort the items in a standard order. This is a patch, and not** a very good one, for the problem that in some Motif versions, the directory** list is sorted differently, such that typing of filenames fails because** it expects strcmp alphabetical order, as opposed to strcasecmp. Most** users prefer the old ordering, which is what this enforces, but if** ifdefs can be found that will correctly predict the ordering and adjust** listCharEH above, instead of resorting to re-sorting, it should be done.** This obviously wastes valuable time as the selection box is popping up** and should be removed. These routines also leak memory like a seive,** because Motif's inconsistent treatment of memory in list widgets does** not allow us to free lists that we pass in, and most Motif versions** don't clean it up properly.*/static void replacementDirSearchProc(Widget w, XtPointer searchData){ Boolean updated; /* Call the original search procedure to do the actual search */ (*OrigDirSearchProc)(w, searchData); /* Refreshing a list clears the keystroke history, even if no update. */ nKeystrokes = 0; XtVaGetValues(w, XmNlistUpdated, &updated, NULL); if (!updated) return; /* Sort the items in the list */ sortWidgetList(XmFileSelectionBoxGetChild(w, XmDIALOG_DIR_LIST));}static void replacementFileSearchProc(Widget w, XtPointer searchData){ Boolean updated; /* Call the original search procedure to do the actual search */ (*OrigFileSearchProc)(w, searchData); /* Refreshing a list clears the keystroke history, even if no update. */ nKeystrokes = 0; XtVaGetValues(w, XmNlistUpdated, &updated, NULL); if (!updated) return; /* Sort the items in the list */ sortWidgetList(XmFileSelectionBoxGetChild(w, XmDIALOG_LIST));}/*** Sort the items in a list widget "listWidget"*/static void sortWidgetList(Widget listWidget){ XmString *items, *sortedItems; int nItems, i; XtVaGetValues(listWidget, XmNitems, &items, XmNitemCount, &nItems, NULL); sortedItems = (XmString *)XtMalloc(sizeof(XmString) * nItems); for (i=0; i<nItems; i++) sortedItems[i] = XmStringCopy(items[i]); qsort(sortedItems, nItems, sizeof(XmString), compareXmStrings); XmListReplaceItemsPos(listWidget, sortedItems, nItems, 1); for (i=0; i<nItems; i++) XmStringFree(sortedItems[i]); XtFree((char *)sortedItems);}/*** Compare procedure for qsort for sorting a list of XmStrings*/static int compareXmStrings(const void *string1, const void *string2){ char *s1, *s2; int result; XmStringGetLtoR(*(XmString *)string1, XmSTRING_DEFAULT_CHARSET, &s1); XmStringGetLtoR(*(XmString *)string2, XmSTRING_DEFAULT_CHARSET, &s2); result = strcmp(s1, s2); XtFree(s1); XtFree(s2); return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -