/** Sets the predecessor of a Menuitem item to itemid (for wizzards) * i.e. the menuitem to go to after hitting "Enter" on item. * * @return 0 on success and -1 otherwise */ int set_predecessor(MenuItem *item, char *itemid, Client *c) { // no sense to call this function on a null item assert(item != NULL); debug(RPT_DEBUG, "%s(%s, %s, %d)", __FUNCTION__, item->id, itemid, c->sock); // handle these special if (strcmp("_quit_", itemid) != 0 && strcmp("_close_", itemid) != 0 && strcmp("_none_", itemid) != 0) { MenuItem *predecessor = menuitem_search(itemid, c); if ( ! predecessor) { sock_printf_error(c->sock, "Cannot find predecessor '%s'" " for item '%s'\n", itemid, item->id); return -1; } } debug(RPT_DEBUG, "%s( Client [%d], ... )" " setting '%s's predecessor from '%s' to '%s'", __FUNCTION__, c->sock, item->id, item->predecessor_id, itemid); if (item->predecessor_id) free(item->predecessor_id); item->predecessor_id = strdup(itemid); return 0; }
/** Sets the successor of a Menuitem item to itemid (for wizzards) i.e. the * menuitem to go to after hitting "Enter" on item. Checks that a matching * menu item can be found. Checks if item is not a menu. (If you would * redefine the meaning of "Enter" for a menu it would not be useful * anymore.) * * @return 0 on success and -1 otherwise */ int set_successor(MenuItem *item, char *itemid, Client *c) { // no sense to call this function on a null item assert(item != NULL); debug(RPT_DEBUG, "%s(%s, %s, %d)", __FUNCTION__, item->id, itemid, c->sock); // handle these special if (strcmp("_quit_", itemid) != 0 && strcmp("_close_", itemid) != 0 && strcmp("_none_", itemid) != 0) { MenuItem *successor = menuitem_search(itemid, c); if ( ! successor) { sock_printf_error(c->sock, "Cannot find successor '%s'" " for item '%s'\n", itemid, item->id); return -1; } } if (item->type == MENUITEM_MENU) { sock_printf_error(c->sock, "Cannot set successor of '%s':" " wrong type '%s'\n", item->id, menuitem_type_to_typename(item->type)); return -1; } debug (RPT_DEBUG, "%s( Client [%d], ... )" " setting '%s's successor from '%s' to '%s'", __FUNCTION__, c->sock, item->id, item->successor_id, itemid); if (item->successor_id) free(item->successor_id); item->successor_id = strdup(itemid); return 0; }
static void handle_successor(void) { MenuItem *successor; MenuItem *item = (active_menuitem->type == MENUITEM_MENU) ? menu_get_item_for_successor_check(active_menuitem) : active_menuitem; assert(item != NULL); debug(RPT_DEBUG, "%s: Switching to registered successor '%s' of '%s'.", __FUNCTION__, item->successor_id, item->id); successor = menuitem_search(item->successor_id, (Client *) active_menuitem->client); if (successor == NULL) { /* * note: if _quit_, _close_, _none_ get here this would be an * implementation error - they should have been handled via * different MENURESULT codes. */ report(RPT_ERR, "%s: cannot find successor '%s' of '%s'.", __FUNCTION__, item->successor_id, item->id); return; } switch (successor->type) { case MENUITEM_ACTION: case MENUITEM_CHECKBOX: case MENUITEM_RING: if (active_menuitem != successor->parent) menuscreen_switch_item(successor->parent); /* this won't work for hidden subitems */ menu_select_subitem(active_menuitem, item->successor_id); menuitem_update_screen(active_menuitem, menuscreen); break; default: if ((successor->parent != NULL) && (successor->parent->type == MENUITEM_MENU)) { /* update parent menu too */ menu_select_subitem(successor->parent, successor->id); } menuscreen_switch_item(successor); break; } }
/*************************************************************** * Requests the menu system to display the given menu screen. Depending on * the setting of the LCDPROC_PERMISSIVE_MENU_GOTO it is impossible * to go to a menu of another client (or the server menus). Same * restriction applies to the optional predecessor_id * * Usage: menu_goto <id> [<predecessor_id>] */ int menu_goto_func (Client * c, int argc, char **argv) { char * menu_id; Menu * menu; debug (RPT_DEBUG, "%s( Client [%d], %s, %s )", __FUNCTION__, c->sock, (argc > 1 ? argv[1] : "<null>"), (argc > 2 ? argv[2] : "<null>") ); if (!c->ack) return 1; if ((argc < 2 ) || (argc > 3)) { sock_send_error(c->sock, "Usage: menu_goto <menuid> [<predecessor_id>]\n"); return 0; } menu_id = argv[1]; if ( menu_id[0] == 0 ) { /* No menu specified = client's main menu */ menu = c->menu; } else { /* A specified menu */ menu = menuitem_search(menu_id, c); } if (!menu) { sock_send_error(c->sock, "Cannot find menu id\n"); return 0; } if (argc > 2 ) set_predecessor(menu, argv[2], c); menuscreen_goto (menu); /* Failure is not returned (Robijn) */ sock_send_string(c->sock, "success\n"); return 0; }