| 49 | |
| 50 | |
| 51 | ResultType UserMenu::Invoke(ResultToken &aResultToken, int aID, int aFlags, ExprTokenType *aParam[], int aParamCount) |
| 52 | { |
| 53 | LPTSTR param1 = (aParamCount || IS_INVOKE_SET) ? ParamIndexToString(0, _f_number_buf) : _T(""); |
| 54 | |
| 55 | bool ignore_existing_items = false; // These are used to simplify M_Insert, combining it with M_Add. |
| 56 | UserMenuItem **insert_at = nullptr; // |
| 57 | |
| 58 | auto member = MemberID(aID); |
| 59 | switch (member) |
| 60 | { |
| 61 | case M_Show: |
| 62 | return Display(true, ParamIndexToOptionalInt(0, COORD_UNSPECIFIED), ParamIndexToOptionalInt(1, COORD_UNSPECIFIED)); |
| 63 | |
| 64 | case M_Insert: |
| 65 | if (*param1) // i.e. caller specified where to insert. |
| 66 | { |
| 67 | bool search_by_pos; |
| 68 | UserMenuItem *insert_before, *prev_item; |
| 69 | if ( !(insert_before = FindItem(param1, prev_item, search_by_pos)) ) |
| 70 | { |
| 71 | // The item wasn't found. Treat it as an error unless it is the position |
| 72 | // immediately after the last item. |
| 73 | if ( !(search_by_pos && ATOI(param1) == (int)mMenuItemCount + 1) ) |
| 74 | _o_throw(_T("Nonexistent menu item."), param1); |
| 75 | } |
| 76 | // To simplify insertion, give AddItem() a pointer to the variable within the |
| 77 | // linked-list which points to the item, rather than a pointer to the item itself: |
| 78 | insert_at = prev_item ? &prev_item->mNextMenuItem : &mFirstMenuItem; |
| 79 | } |
| 80 | member = M_Add; // For a later section. |
| 81 | ignore_existing_items = true; |
| 82 | ++aParam; |
| 83 | --aParamCount; |
| 84 | param1 = ParamIndexToOptionalString(0, _f_number_buf); |
| 85 | // FALL THROUGH to the next section: |
| 86 | case M_Add: |
| 87 | if (*param1) // Since a menu item name was given, it's not a separator line. |
| 88 | break; // Let a later switch() handle it. |
| 89 | return AddItem(_T(""), g_script.GetFreeMenuItemID(), NULL, NULL, _T(""), insert_at); // Even separators get an ID, so that they can be modified later using the position& notation. |
| 90 | |
| 91 | case M_Delete: |
| 92 | if (aParamCount) // Since a menu item name was given, an item is being deleted, not the whole menu. |
| 93 | // aParamCount vs *param1: seems best to differentiate between Menu.Delete() and Menu.Delete(""). |
| 94 | break; // Let a later switch() handle it. |
| 95 | if (!DeleteAllItems()) |
| 96 | _o_throw(_T("Can't delete items (in use?).")); |
| 97 | return OK; |
| 98 | |
| 99 | case P_Default: |
| 100 | if (IS_INVOKE_SET) |
| 101 | { |
| 102 | if (*param1) // Since a menu item has been specified, let a later switch() handle it. |
| 103 | break; |
| 104 | return SetDefault(); |
| 105 | } |
| 106 | _o_return(mDefault ? mDefault->mName : _T("")); |
| 107 | |
| 108 | case M_AddStandard: |
nothing calls this directly
no test coverage detected