/* * workshop_menu_begin() is passed the menu name. We determine its mnemonic * here and store its name and priority. */ void workshop_menu_begin( char *label) { vimmenu_T *menu; /* pointer to last menu */ int menuPriority = 0; /* priority of new menu */ char mnembuf[64]; /* store menubar mnemonics here */ char *name; /* label with a mnemonic */ char *p; /* used to find mnemonics */ int idx; /* index into mnembuf */ #ifdef WSDEBUG_TRACE if (WSDLEVEL(WS_TRACE_VERBOSE | WS_TRACE)) wstrace("workshop_menu_begin()\n"); #endif /* * Look through all existing (non-PopUp and non-Toolbar) menus * and gather their mnemonics. Use this list to decide what * mnemonic should be used for label. */ idx = 0; mnembuf[idx++] = 'H'; /* H is mnemonic for Help */ for (menu = root_menu; menu != NULL; menu = menu->next) { if (menu_is_menubar(menu->name)) { p = strchr((char *)menu->name, '&'); if (p != NULL) mnembuf[idx++] = *++p; } if (menu->next != NULL && strcmp((char *) menu->next->dname, "Help") == 0) { menuPriority = menu->priority + 10; break; } } mnembuf[idx++] = NUL; name = addUniqueMnemonic(mnembuf, label); sprintf(curMenuName, "%s", name); sprintf(curMenuPriority, "%d.0", menuPriority); }
/* * Add a sub menu to the menu bar. */ void gui_mch_add_menu( vimmenu_T *menu, int pos) { vimmenu_T *parent = menu->parent; menu->submenu_id = CreatePopupMenu(); menu->id = s_menu_id++; if (menu_is_menubar(menu->name)) { InsertMenu((parent == NULL) ? s_menuBar : parent->submenu_id, (UINT)pos, MF_POPUP | MF_STRING | MF_BYPOSITION, (UINT)menu->submenu_id, menu->name); } /* Fix window size if menu may have wrapped */ if (parent == NULL) gui_mswin_get_menu_height(!gui.starting); }
/* * Add the menu with the given name to the menu hierarchy */ static int add_menu_path ( char_u *menu_path, vimmenu_T *menuarg, /* passes modes, iconfile, iconidx, icon_builtin, silent[0], noremap[0] */ int *pri_tab, char_u *call_data ) { char_u *path_name; int modes = menuarg->modes; vimmenu_T **menup; vimmenu_T *menu = NULL; vimmenu_T *parent; vimmenu_T **lower_pri; char_u *p; char_u *name; char_u *dname; char_u *next_name; int i; int c; int d; int pri_idx = 0; int old_modes = 0; int amenu; char_u *en_name; char_u *map_to = NULL; /* Make a copy so we can stuff around with it, since it could be const */ path_name = vim_strsave(menu_path); menup = &root_menu; parent = NULL; name = path_name; while (*name) { /* Get name of this element in the menu hierarchy, and the simplified * name (without mnemonic and accelerator text). */ next_name = menu_name_skip(name); map_to = menutrans_lookup(name, (int)STRLEN(name)); if (map_to != NULL) { en_name = name; name = map_to; } else en_name = NULL; dname = menu_text(name, NULL, NULL); if (dname == NULL) goto erret; if (*dname == NUL) { /* Only a mnemonic or accelerator is not valid. */ EMSG(_("E792: Empty menu name")); goto erret; } /* See if it's already there */ lower_pri = menup; menu = *menup; while (menu != NULL) { if (menu_name_equal(name, menu) || menu_name_equal(dname, menu)) { if (*next_name == NUL && menu->children != NULL) { if (!sys_menu) EMSG(_("E330: Menu path must not lead to a sub-menu")); goto erret; } if (*next_name != NUL && menu->children == NULL ) { if (!sys_menu) EMSG(_(e_notsubmenu)); goto erret; } break; } menup = &menu->next; /* Count menus, to find where this one needs to be inserted. * Ignore menus that are not in the menubar (PopUp and Toolbar) */ if (parent != NULL || menu_is_menubar(menu->name)) { if (menu->priority <= pri_tab[pri_idx]) { lower_pri = menup; } } menu = menu->next; } if (menu == NULL) { if (*next_name == NUL && parent == NULL) { EMSG(_("E331: Must not add menu items directly to menu bar")); goto erret; } if (menu_is_separator(dname) && *next_name != NUL) { EMSG(_("E332: Separator cannot be part of a menu path")); goto erret; } /* Not already there, so lets add it */ menu = xcalloc(1, sizeof(vimmenu_T)); menu->modes = modes; menu->enabled = MENU_ALL_MODES; menu->name = vim_strsave(name); /* separate mnemonic and accelerator text from actual menu name */ menu->dname = menu_text(name, &menu->mnemonic, &menu->actext); if (en_name != NULL) { menu->en_name = vim_strsave(en_name); menu->en_dname = menu_text(en_name, NULL, NULL); } else { menu->en_name = NULL; menu->en_dname = NULL; } menu->priority = pri_tab[pri_idx]; menu->parent = parent; /* * Add after menu that has lower priority. */ menu->next = *lower_pri; *lower_pri = menu; old_modes = 0; } else { old_modes = menu->modes; /* * If this menu option was previously only available in other * modes, then make sure it's available for this one now * Also enable a menu when it's created or changed. */ { menu->modes |= modes; menu->enabled |= modes; } } menup = &menu->children; parent = menu; name = next_name; free(dname); dname = NULL; if (pri_tab[pri_idx + 1] != -1) ++pri_idx; } free(path_name); /* * Only add system menu items which have not been defined yet. * First check if this was an ":amenu". */ amenu = ((modes & (MENU_NORMAL_MODE | MENU_INSERT_MODE)) == (MENU_NORMAL_MODE | MENU_INSERT_MODE)); if (sys_menu) modes &= ~old_modes; if (menu != NULL && modes) { p = (call_data == NULL) ? NULL : vim_strsave(call_data); /* loop over all modes, may add more than one */ for (i = 0; i < MENU_MODES; ++i) { if (modes & (1 << i)) { /* free any old menu */ free_menu_string(menu, i); /* For "amenu", may insert an extra character. * Don't do this if adding a tearbar (addtearoff == FALSE). * Don't do this for "<Nop>". */ c = 0; d = 0; if (amenu && call_data != NULL && *call_data != NUL ) { switch (1 << i) { case MENU_VISUAL_MODE: case MENU_SELECT_MODE: case MENU_OP_PENDING_MODE: case MENU_CMDLINE_MODE: c = Ctrl_C; break; case MENU_INSERT_MODE: c = Ctrl_BSL; d = Ctrl_O; break; } } if (c != 0) { menu->strings[i] = xmalloc(STRLEN(call_data) + 5 ); menu->strings[i][0] = c; if (d == 0) STRCPY(menu->strings[i] + 1, call_data); else { menu->strings[i][1] = d; STRCPY(menu->strings[i] + 2, call_data); } if (c == Ctrl_C) { int len = (int)STRLEN(menu->strings[i]); /* Append CTRL-\ CTRL-G to obey 'insertmode'. */ menu->strings[i][len] = Ctrl_BSL; menu->strings[i][len + 1] = Ctrl_G; menu->strings[i][len + 2] = NUL; } } else menu->strings[i] = p; menu->noremap[i] = menuarg->noremap[0]; menu->silent[i] = menuarg->silent[0]; } } #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32) \ && (defined(FEAT_BEVAL) || defined(FEAT_GUI_GTK)) /* Need to update the menu tip. */ if (modes & MENU_TIP_MODE) gui_mch_menu_set_tip(menu); #endif } return OK; erret: free(path_name); free(dname); /* Delete any empty submenu we added before discovering the error. Repeat * for higher levels. */ while (parent != NULL && parent->children == NULL) { if (parent->parent == NULL) menup = &root_menu; else menup = &parent->parent->children; for (; *menup != NULL && *menup != parent; menup = &((*menup)->next)) ; if (*menup == NULL) /* safety check */ break; parent = parent->parent; free_menu(menup); } return FAIL; }