⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usercmds.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
int DoNamedBGMenuCmd(WindowInfo *window, const char *itemName){    int i;        for (i=0; i<NBGMenuItems; i++) {    	if (!strcmp(BGMenuItems[i]->name, itemName)) {    	    DoMacro(window, BGMenuItems[i]->cmd, "background menu macro");    	    return True;    	}    }    return False;}/*** Update all of the Shell or Macro menus of all editor windows.*/static void updateMenus(int menuType){    WindowInfo *w;    for (w=WindowList; w!=NULL; w=w->next)	updateMenu(w, menuType);}/*** Updates either the Shell menu or the Macro menu of "window", depending on** value of "menuType"*/static void updateMenu(WindowInfo *window, int menuType){    Widget btn, menuPane, subPane, newSubPane;    int nListItems, n;    menuItemRec *f, **itemList;    menuTreeItem *menuTree;    int i, nTreeEntries, isDefaultLM;    char *hierName, *namePtr, *subMenuName, *subSep, *strippedName, *name;        /* Fetch the appropriate menu pane and item list for this menu type */    if (menuType == SHELL_CMDS) {    	menuPane = window->shellMenuPane;    	itemList = ShellMenuItems;    	nListItems = NShellMenuItems;    } else if (menuType == MACRO_CMDS) {    	menuPane = window->macroMenuPane;    	itemList = MacroMenuItems;    	nListItems = NMacroMenuItems;    } else { /* BG_MENU_CMDS */    	menuPane = window->bgMenuPane;    	itemList = BGMenuItems;    	nListItems = NBGMenuItems;    }        /* Remove all of the existing user commands from the menu */    removeMenuItems(menuPane);        /* Allocate storage for structures to help find sub-menus */    menuTree = (menuTreeItem *)XtMalloc(sizeof(menuTreeItem) * nListItems);    nTreeEntries = 0;        /* Harmless kludge: undo and redo items are marked specially if found       in the background menu, and used to dim/undim with edit menu */    window->bgMenuUndoItem = NULL;    window->bgMenuRedoItem = NULL;        /*    ** Add items to the list, creating hierarchical sub-menus as necessary,    ** and skipping items not intended for this language mode    */    for (n=0; n<nListItems; n++) {    	f = itemList[n];		/* Eliminate items meant for other language modes, strip @ sign parts.	   If the language mode is "*", scan the list for an item with the	   same name and a language mode specified.  If one is found, skip	   the item in favor of the exact match. */	strippedName = findStripLanguageMode(f->name, window->languageMode,		&isDefaultLM);    	if (strippedName == NULL)	    continue;		/* not a valid entry for the language */	if (isDefaultLM) {	    for (i=0; i<nListItems; i++) {		name = findStripLanguageMode(itemList[i]->name,			window->languageMode, &isDefaultLM);		if (name!=NULL && !isDefaultLM && !strcmp(name, strippedName)) {		    XtFree(name); /* item with matching language overrides */		    break;		}		XtFree(name);	    }	    if (i != nListItems) {		XtFree(strippedName);		continue;	    }	}		/* create/find sub-menus, stripping off '>' until item name is	   reached, then create the menu item */	namePtr = strippedName;	subPane = menuPane;	for (;;) {	    subSep = strchr(namePtr, '>');	    if (subSep == NULL) {		btn = createUserMenuItem(subPane, namePtr, f, n,			(XtCallbackProc)(menuType == SHELL_CMDS ? shellMenuCB :			(menuType == MACRO_CMDS ? macroMenuCB : bgMenuCB)),			(XtPointer)window);		if (menuType == BG_MENU_CMDS && !strcmp(f->cmd, "undo()\n"))		    window->bgMenuUndoItem = btn;		else if (menuType == BG_MENU_CMDS && !strcmp(f->cmd,"redo()\n"))		    window->bgMenuRedoItem = btn;		UpdateAccelLockPatch(window->splitPane, btn);		break;	    }	    hierName = copySubstring(strippedName, subSep - strippedName);	    newSubPane = findInMenuTree(menuTree, nTreeEntries, hierName);	    if (newSubPane == NULL) {		subMenuName = copySubstring(namePtr, subSep - namePtr);	    	newSubPane = createUserSubMenu(subPane, subMenuName);		XtFree(subMenuName);		menuTree[nTreeEntries].name = hierName;		menuTree[nTreeEntries++].menuPane = newSubPane;	    } else		XtFree(hierName);	    subPane = newSubPane;	    namePtr = subSep + 1;	}	XtFree(strippedName);    }        /* Free the structure used to keep track of sub-menus durring creation */    for (i=0; i<nTreeEntries; i++)	XtFree(menuTree[i].name);    XtFree((char *)menuTree);        /* Set the proper sensitivity of items which may be dimmed */    SetBGMenuUndoSensitivity(window, XtIsSensitive(window->undoItem));    SetBGMenuRedoSensitivity(window, XtIsSensitive(window->redoItem));    DimSelectionDepUserMenuItems(window, window->buffer->primary.selected);}/*** Find the widget corresponding to a hierarchical menu name (a>b>c...)*/static Widget findInMenuTree(menuTreeItem *menuTree, int nTreeEntries,	const char *hierName){    int i;        for (i=0; i<nTreeEntries; i++)	if (!strcmp(hierName, menuTree[i].name))	    return menuTree[i].menuPane;    return NULL;}static char *copySubstring(const char *string, int length){    char *retStr = XtMalloc(length + 1);        strncpy(retStr, string, length);    retStr[length] = '\0';    return retStr;}/*** Look for at signs (@) in the string menuItemName, and match them** against the current language mode.  If there are no @ signs, just** return an allocated copy of menuItemName.  If there are @ signs, match** the following text against languageMode, and return NULL if none match,** or an allocated copy of menuItemName stripped of @ parts.  If the** language name is "*", sets isDefaultLM to true.*/static char *findStripLanguageMode(const char *menuItemName, int languageMode,	int *isDefaultLM){    char *atPtr, *firstAtPtr, *endPtr;    int lmNameLen;        atPtr = firstAtPtr = strchr(menuItemName, '@');    *isDefaultLM = False;    if (atPtr == NULL)    {        return XtNewString(menuItemName);    }    if (!strcmp(atPtr+1, "*")) {	/* only language is "*": this is for all but language specific macros */	*isDefaultLM = True;	return copySubstring(menuItemName, firstAtPtr-menuItemName);    }    if (languageMode == PLAIN_LANGUAGE_MODE)	return NULL;    for (;;) {	for(endPtr=atPtr+1; isalnum((unsigned char)*endPtr) || *endPtr=='_' || 	      	*endPtr=='-' || *endPtr==' ' || *endPtr=='+' || *endPtr=='$' || 	      	*endPtr=='#'; endPtr++);	lmNameLen = endPtr-atPtr-1;	if (!strncmp(LanguageModeName(languageMode), atPtr+1, lmNameLen) &&		LanguageModeName(languageMode)[lmNameLen] == '\0')	    return copySubstring(menuItemName, firstAtPtr-menuItemName);	atPtr = strchr(atPtr+1, '@');	if (atPtr == NULL)	    return NULL;    }}    		static Widget createUserMenuItem(Widget menuPane, char *name, menuItemRec *f,	int index, XtCallbackProc cbRtn, XtPointer cbArg){    XmString st1, st2;    char accText[MAX_ACCEL_LEN], accKeys[MAX_ACCEL_LEN+5];    Widget btn;        generateAcceleratorString(accText, f->modifiers, f->keysym);    genAccelEventName(accKeys, f->modifiers, f->keysym);    st1=XmStringCreateSimple(name);    st2=XmStringCreateSimple(accText);    btn = XtVaCreateManagedWidget("cmd", xmPushButtonWidgetClass, menuPane,     	    XmNlabelString, st1,    	    XmNacceleratorText, st2,    	    XmNaccelerator, accKeys,    	    XmNmnemonic, f->mnemonic,    	    XmNuserData, index+10, NULL);    XtAddCallback(btn, XmNactivateCallback, cbRtn, cbArg);    XmStringFree(st1);    XmStringFree(st2);    return btn;}/*** Add a user-defined sub-menu to an established pull-down menu, marking** it's userData field with TEMPORARY_MENU_ITEM so it can be found and** removed later if the menu is redefined.  Returns the menu pane of the** new sub menu.*/static Widget createUserSubMenu(Widget parent, char *label){    Widget menu;    XmString st1;    static Arg args[1] = {{XmNuserData, (XtArgVal)TEMPORARY_MENU_ITEM}};       menu = CreatePulldownMenu(parent, "userPulldown", args, 1);    XtVaCreateManagedWidget("userCascade", xmCascadeButtonWidgetClass, parent,     	    XmNlabelString, st1=XmStringCreateSimple(label),    	    XmNsubMenuId, menu, XmNuserData, TEMPORARY_MENU_ITEM, NULL);    XmStringFree(st1);    return menu;}static void removeMenuItems(Widget menuPane){    WidgetList items, itemList;    Widget subMenuID;    XtPointer userData;    int n;    Cardinal nItems;        /* Fetch the list of children from the menu pane, and make a copy       (because the widget alters this list as you delete widgets) */    XtVaGetValues(menuPane, XmNchildren, &itemList, XmNnumChildren, &nItems,	    NULL);    items = (WidgetList)XtMalloc(sizeof(Widget) * nItems);    memcpy(items, itemList, sizeof(Widget) * nItems);        /* Delete all of the widgets not marked as PERMANENT_MENU_ITEM */    for (n=0; n<(int)nItems; n++) {	XtVaGetValues(items[n], XmNuserData, &userData, NULL);    	if (userData !=  (XtPointer)PERMANENT_MENU_ITEM) {    	    if (XtClass(items[n]) == xmCascadeButtonWidgetClass) {		XtVaGetValues(items[n], XmNsubMenuId, &subMenuID, NULL);		removeMenuItems(subMenuID);#if XmVersion < 2000  /* Skipping this creates a memory and server resource		   leak (though both are reclaimed on window closing).  In		   Motif 2.0 (and beyond?) there is a potential crash during		   phase 2 widget destruction in "SetCascadeField", and in		   Motif 1.2 there are free-memory reads.  I would really like		   to be able to destroy this. */		XtDestroyWidget(subMenuID);#endif	    } else /* remove accel. before destroy or lose it forever */    		XtVaSetValues(items[n], XmNaccelerator, NULL, NULL);    	    /* unmanaging before destroying stops parent from displaying */    	    XtUnmanageChild(items[n]);    	    XtDestroyWidget(items[n]);    	}    }    XtFree((char *)items);}static void dismissCB(Widget w, XtPointer clientData, XtPointer callData){    userCmdDialog *ucd = (userCmdDialog *)clientData;        /* Mark that there's no longer a (macro, bg, or shell) dialog up */    if (ucd->dialogType == SHELL_CMDS)    	ShellCmdDialog = NULL;    else if (ucd->dialogType == MACRO_CMDS)    	MacroCmdDialog = NULL;    else	BGMenuCmdDialog = NULL;    /* pop down and destroy the dialog (memory for ucd is freed in the       destroy callback) */    XtDestroyWidget(ucd->dlogShell);}static void okCB(Widget w, XtPointer clientData, XtPointer callData){    userCmdDialog *ucd = (userCmdDialog *)clientData;        /* Read the dialog fields, and update the menus */    if (!applyDialogChanges(ucd))    	return;        /* Mark that there's no longer a (macro, bg, or shell) dialog up */    if (ucd->dialogType == SHELL_CMDS)    	ShellCmdDialog = NULL;    else if (ucd->dialogType == MACRO_CMDS)    	MacroCmdDialog = NULL;    else	BGMenuCmdDialog = NULL;    /* pop down and destroy the dialog (memory for ucd is freed in the       destroy callback) */    XtDestroyWidget(ucd->dlogShell);}static void applyCB(Widget w, XtPointer clientData, XtPointer callData){    applyDialogChanges((userCmdDialog *)clientData);}static void checkCB(Widget w, XtPointer clientData, XtPointer callData){    userCmdDialog *ucd = (userCmdDialog *)clientData;        if (checkMacro(ucd))    {        DialogF(DF_INF, ucd->dlogShell, 1, "Macro",                "Macro compiled without error", "Dismiss");    }}static int checkMacro(userCmdDialog *ucd){    menuItemRec *f;        f = readDialogFields(ucd, False);    if (f == NULL)	return False;    if (!checkMacroText(f->cmd, ucd->dlogShell, ucd->cmdTextW)) {	freeMenuItemRec(f);	return False;    }    return True;}static int checkMacroText(char *macro, Widget errorParent, Widget errFocus){    Program *prog;    char *errMsg, *stoppedAt;    prog = ParseMacro(macro, &errMsg, &stoppedAt);    if (prog == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -