/* * Take "Open..." and 'O' and produce the string "Open...\tCtrl+O". * This function also sets an object's shortcut key, which is the * underlined letter in a menu item in Windows or X-Windows. */ static void setmenustring(object obj, char *buf, const char *name, int key) { char search[256]; int ch, where, source, dest = 0; char *extra = "\tCtrl+"; set_search_string(search, name, key); ch = find_shortcut(obj, search); if (ch) /* found a valid shortcut key */ { obj->shortcut = toupper(ch); /* case-insensitive */ where = find_char(ch, name); for (source=0; source < where; source++) { int mb_len; int i; mbstate_t mb_st; mbs_init(mb_st); mb_len = Rf_mbrtowc(NULL, name + source, MB_CUR_MAX, &mb_st); if ( mb_len > 1 ) { for (i = 0 ; i < mb_len ; i++) buf[dest++] = name[source+i]; source += mb_len-1; } else if(name[source] == '&') { /* skip it */ } else buf[dest++] = name[source]; } buf[dest++] = '&'; for (; name[source]; source++) buf[dest++] = name[source]; } else /* no shortcut key, just copy the name string except '&' */ { for (source = 0; name[source]; source++) if(name[source] != '&') buf[dest++] = name[source]; } if (key) { for (source=0; extra[source]; source++) buf[dest++] = extra[source]; buf[dest++] = key; } buf[dest] = '\0'; }
/* Handle one menu */ pt_menuitem getmenuoption( pt_menu menu, char top, char left, char startopt) // Return item chosen or NULL if ESC was hit. { int curr,i; char asc,scan; char numitems; pt_menuitem ci; // Current item calc_visible(menu); numitems = menu->numvisible; // Setup status line gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage); // Initialise current menu item curr = next_visible(menu,startopt); gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,1); gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); printmenuitem(menu->items[curr]->status,ms->statusattr); while (1) // Forever { printmenu(menu,curr,top,left); ci = menu->items[curr]; asc = getch(&scan); switch (scan) { case HOMEKEY: curr = next_visible(menu,0); break; case ENDKEY: curr = prev_visible(menu,numitems-1); break; case PAGEDN: for (i=0; i < 5; i++) curr = next_visible(menu,curr+1); break; case PAGEUP: for (i=0; i < 5; i++) curr = prev_visible(menu,curr-1); break; case UPARROW: curr = prev_visible(menu,curr-1); break; case DNARROW: curr = next_visible(menu,curr+1); break; case LTARROW: case ESCAPE: return NULL; break; case RTARROW: case ENTERA: case ENTERB: if (ci->action == OPT_INACTIVE) break; if (ci->action == OPT_CHECKBOX) break; if (ci->action == OPT_SEP) break; if (ci->action == OPT_EXITMENU) return NULL; // As if we hit Esc return ci; break; case SPACEKEY: if (ci->action != OPT_CHECKBOX) break; ci->itemdata.checked = !ci->itemdata.checked; // Call handler to see it anything needs to be done if (ci->handler != NULL) ci->handler(ms,ci); break; default: // Check if this is a shortcut key if (((asc >= 'A') && (asc <= 'Z')) || ((asc >= 'a') && (asc <= 'z')) || ((asc >= '0') && (asc <= '9'))) curr = find_shortcut(menu,asc,curr); break; } // Update status line gotoxy(ms->minrow+ms->statline,ms->mincol,ms->menupage); cprint(ms->spacechar,ms->statusattr[NOHLITE],ms->numcols,ms->menupage); printmenuitem(menu->items[curr]->status,ms->statusattr); } return NULL; // Should never come here }