/* * Do the :menu command and relatives. */ void ex_menu ( exarg_T *eap /* Ex command arguments */ ) { char_u *menu_path; int modes; char_u *map_to; int noremap; int silent = FALSE; int special = FALSE; int unmenu; char_u *map_buf; char_u *arg; char_u *p; int i; int pri_tab[MENUDEPTH + 1]; int enable = MAYBE; /* TRUE for "menu enable", FALSE for "menu * disable */ vimmenu_T menuarg; modes = get_menu_cmd_modes(eap->cmd, eap->forceit, &noremap, &unmenu); arg = eap->arg; for (;; ) { if (STRNCMP(arg, "<script>", 8) == 0) { noremap = REMAP_SCRIPT; arg = skipwhite(arg + 8); continue; } if (STRNCMP(arg, "<silent>", 8) == 0) { silent = TRUE; arg = skipwhite(arg + 8); continue; } if (STRNCMP(arg, "<special>", 9) == 0) { special = TRUE; arg = skipwhite(arg + 9); continue; } break; } /* Locate an optional "icon=filename" argument. */ if (STRNCMP(arg, "icon=", 5) == 0) { arg += 5; while (*arg != NUL && *arg != ' ') { if (*arg == '\\') STRMOVE(arg, arg + 1); mb_ptr_adv(arg); } if (*arg != NUL) { *arg++ = NUL; arg = skipwhite(arg); } } /* * Fill in the priority table. */ for (p = arg; *p; ++p) if (!VIM_ISDIGIT(*p) && *p != '.') break; if (vim_iswhite(*p)) { for (i = 0; i < MENUDEPTH && !vim_iswhite(*arg); ++i) { pri_tab[i] = getdigits_int(&arg); if (pri_tab[i] == 0) pri_tab[i] = 500; if (*arg == '.') ++arg; } arg = skipwhite(arg); } else if (eap->addr_count && eap->line2 != 0) { pri_tab[0] = eap->line2; i = 1; } else i = 0; while (i < MENUDEPTH) pri_tab[i++] = 500; pri_tab[MENUDEPTH] = -1; /* mark end of the table */ /* * Check for "disable" or "enable" argument. */ if (STRNCMP(arg, "enable", 6) == 0 && vim_iswhite(arg[6])) { enable = TRUE; arg = skipwhite(arg + 6); } else if (STRNCMP(arg, "disable", 7) == 0 && vim_iswhite(arg[7])) { enable = FALSE; arg = skipwhite(arg + 7); } /* * If there is no argument, display all menus. */ if (*arg == NUL) { show_menus(arg, modes); return; } menu_path = arg; if (*menu_path == '.') { EMSG2(_(e_invarg2), menu_path); goto theend; } map_to = menu_translate_tab_and_shift(arg); /* * If there is only a menu name, display menus with that name. */ if (*map_to == NUL && !unmenu && enable == MAYBE) { show_menus(menu_path, modes); goto theend; } else if (*map_to != NUL && (unmenu || enable != MAYBE)) { EMSG(_(e_trailing)); goto theend; } if (enable != MAYBE) { /* * Change sensitivity of the menu. * For the PopUp menu, remove a menu for each mode separately. * Careful: menu_nable_recurse() changes menu_path. */ if (STRCMP(menu_path, "*") == 0) /* meaning: do all menus */ menu_path = (char_u *)""; if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); menu_nable_recurse(root_menu, p, MENU_ALL_MODES, enable); free(p); } } menu_nable_recurse(root_menu, menu_path, modes, enable); } else if (unmenu) { /* * Delete menu(s). */ if (STRCMP(menu_path, "*") == 0) /* meaning: remove all menus */ menu_path = (char_u *)""; /* * For the PopUp menu, remove a menu for each mode separately. */ if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); remove_menu(&root_menu, p, MENU_ALL_MODES, TRUE); free(p); } } /* Careful: remove_menu() changes menu_path */ remove_menu(&root_menu, menu_path, modes, FALSE); } else { /* * Add menu(s). * Replace special key codes. */ if (STRICMP(map_to, "<nop>") == 0) { /* "<Nop>" means nothing */ map_to = (char_u *)""; map_buf = NULL; } else if (modes & MENU_TIP_MODE) map_buf = NULL; /* Menu tips are plain text. */ else map_to = replace_termcodes(map_to, &map_buf, FALSE, TRUE, special); menuarg.modes = modes; menuarg.noremap[0] = noremap; menuarg.silent[0] = silent; add_menu_path(menu_path, &menuarg, pri_tab, map_to ); /* * For the PopUp menu, add a menu for each mode separately. */ if (menu_is_popup(menu_path)) { for (i = 0; i < MENU_INDEX_TIP; ++i) if (modes & (1 << i)) { p = popup_mode_name(menu_path, i); // Include all modes, to make ":amenu" work menuarg.modes = modes; add_menu_path(p, &menuarg, pri_tab, map_to); free(p); } } free(map_buf); } theend: ; }
/* * Return TRUE if "name" can be a menu in the MenuBar. */ int menu_is_menubar(char_u *name) { return !menu_is_popup(name) && !menu_is_toolbar(name) && *name != MNU_HIDDEN_CHAR; }
/* * Return TRUE if the menu is hidden: Starts with ']' */ static int menu_is_hidden(char_u *name) { return (name[0] == ']') || (menu_is_popup(name) && name[5] != NUL); }
/* * Destroy the machine specific menu widget. */ void gui_mch_destroy_menu(vimmenu_T *menu) { UINT i, j; char pants[80]; /*<VN> hack*/ #ifdef FEAT_TOOLBAR /* * is this a toolbar button? */ if (menu->submenu_id == (HMENU)-1) { int iButton; iButton = SendMessage(s_toolbarhwnd, TB_COMMANDTOINDEX, (WPARAM)menu->id, 0); SendMessage(s_toolbarhwnd, TB_DELETEBUTTON, (WPARAM)iButton, 0); } else #endif { /* * negri: horrible API bug when running 16-bit programs under Win9x or * NT means that we can't use MF_BYCOMMAND for menu items which have * submenus, including the top-level headings. We have to find the menu * item and use MF_BYPOSITION instead. :-p */ if (menu->parent != NULL && menu_is_popup(menu->parent->dname) && menu->parent->submenu_id != NULL) RemoveMenu(menu->parent->submenu_id, menu->id, MF_BYCOMMAND); else if (menu->submenu_id == NULL) RemoveMenu(s_menuBar, menu->id, MF_BYCOMMAND); else if (menu->parent != NULL) { i = GetMenuItemCount(menu->parent->submenu_id); for (j = 0; j < i; ++j) { GetMenuString(menu->parent->submenu_id, j, pants, 80, MF_BYPOSITION); if (strcmp(pants, menu->name) == 0) { RemoveMenu(menu->parent->submenu_id, j, MF_BYPOSITION); break; } } } else { i = GetMenuItemCount(s_menuBar); for (j = 0; j < i; ++j) { GetMenuString(s_menuBar, j, pants, 80, MF_BYPOSITION); if (strcmp(pants, menu->name) == 0) { RemoveMenu(s_menuBar, j, MF_BYPOSITION); break; } } } if (menu->submenu_id != NULL) DestroyMenu(menu->submenu_id); } DrawMenuBar(s_hwnd); }