From 5a6def03b6bb3aff664c130889338300204e0c98 Mon Sep 17 00:00:00 2001
From: Yona-TYT <yonatan.el.amigo@gmail.com>
Date: Tue, 4 Aug 2026 09:41:38 -0400
Subject: [PATCH] get shortcut key list

---
 src/simutrans/script/api/api_scenario.cc | 199 ++++++++++++-----------
 1 file changed, 106 insertions(+), 93 deletions(-)

diff --git a/src/simutrans/script/api/api_scenario.cc b/src/simutrans/script/api/api_scenario.cc
index 9fc80a06d..4c7d8beff 100644
--- a/src/simutrans/script/api/api_scenario.cc
+++ b/src/simutrans/script/api/api_scenario.cc
@@ -57,91 +57,107 @@ static plainstring koord3d_to_string_intern(koord3d k)
 	return k.get_str();
 }
 
-static plainstring get_tool_key_intern(uint16 tool_id)
+/**
+ * Converts a tool's command_key / command_flags into a readable string.
+ * Examples: "r", "^s", "+F10", "COMMA", "NUM_5", "#1234"
+ */
+static plainstring key_to_string(const tool_t *tool)
+{
+    if (tool == NULL) {
+        return "";
+    }
+
+    // just to save some typing ...
+    const uint16 key = tool->command_key;
+
+    // no binding => finish
+    if (key == 0  ||  key == 0xFFFF) {
+        return "";
+    }
+
+    char mod[2];
+    mod[0] = tool->command_flags == 2 ? '+' : (tool->command_flags == 1 ? '^' : 0);
+    mod[1] = 0;
+
+    // keypad
+    if (key >= SIM_KEYCODE_NUMPAD_BASE  &&  key < SIM_KEYCODE_NUMPAD_BASE + 10) {
+        char str[8];
+        sprintf(str, "%sNUM_%d", mod, key - SIM_KEYCODE_NUMPAD_BASE);
+        return str;
+    }
+
+    // function keys
+    if (key >= SIM_KEYCODE_F1  &&  key <= SIM_KEYCODE_F15) {
+        char str[8];
+        sprintf(str, "%sF%d", mod, key - SIM_KEYCODE_F1 + 1);
+        return str;
+    }
+
+    // special keys
+    switch (key) {
+        case ',':                   return "COMMA";
+        // case SIM_KEYCODE_SCROLLLOCK: return "SCROLLLOCK";
+        case SIM_KEYCODE_PAUSE:     return "PAUSE";
+        case SIM_KEYCODE_HOME:      return "HOME";
+        case SIM_KEYCODE_END:       return "END";
+        case SIM_KEYCODE_SPACE:     return "SPACE";
+        case SIM_KEYCODE_ESCAPE:    return "ESC";
+        case SIM_KEYCODE_DELETE:    return "DELETE";
+        case SIM_KEYCODE_BACKSPACE: return "BACKSPACE";
+    }
+
+    if (key < 32) {
+        char str[6];
+        sprintf(str, "^%c", key + 64);
+        return str;
+    }
+
+    if (key < 127) {
+        char str[2];
+        str[0] = (char)key;
+        str[1] = 0;
+        return str;
+    }
+
+    char str[10];
+    sprintf(str, "%s#%d", mod, key);
+    return str;
+}
+
+/**
+ * Returns all shortcut keys bound to the given tool id.
+ * A tool may have more than one binding (menuconf.tab base entry
+ * and additional toolbar entries create separate instances that
+ * share the same id but can carry different keys).
+ * @param tool_id full tool id (category | local index)
+ * @returns array of hotkey strings; empty array if none
+ */
+static vector_tpl<plainstring> const& get_tool_keys_intern(uint16 tool_id)
 {
-	vector_tpl<tool_t *> *tool_list;
-	uint16 category = tool_id & 0xF000;
-	uint16 local_id = tool_id & 0x0FFF;
-
-	switch (category) {
-		case GENERAL_TOOL:
-			tool_list = &tool_t::general_tool;
-			break;
-		case SIMPLE_TOOL:
-			tool_list = &tool_t::simple_tool;
-			break;
-		case DIALOGE_TOOL:
-			tool_list = &tool_t::dialog_tool;
-			break;
-		case TOOLBAR_TOOL:
-			return "";
-		default:
-			return "";
-	}
-	if (!tool_list || local_id >= tool_list->get_count()) {
-		return "";
-	}
-
-	tool_t *tool = (*tool_list)[local_id];
-	if (!tool) {
-		return "";
-	}
-
-	// just to save some typing ...
-	const uint16 key = tool->command_key;
-
-	// no binding => finish
-	if (key == 0 || key == 0xFFFF) {
-		return "";
-	}
-
-	char mod[2];
-	mod[0] = tool->command_flags == 2 ? '+' : (tool->command_flags == 1 ? '^' : 0);
-	mod[1] = 0;
-
-	// keypad
-	if (key >= SIM_KEYCODE_NUMPAD_BASE && key < SIM_KEYCODE_NUMPAD_BASE + 10) {
-		char str[8];
-		sprintf(str, "%sNUM_%d", mod, key - SIM_KEYCODE_NUMPAD_BASE);
-		return str;
-	}
-
-	// function keys
-	if (key >= SIM_KEYCODE_F1 && key <= SIM_KEYCODE_F15) {
-		char str[8];
-		sprintf(str, "%sF%d", mod, key - SIM_KEYCODE_F1 + 1);
-		return str;
-	}
-
-	// speacial keys
-	switch (key) {
-	case ',': return "COMMA";
-		//		case SIM_KEYCODE_SCROLLLOCK: return "SCROLLLOCK";
-	case SIM_KEYCODE_PAUSE: return "PAUSE";
-	case SIM_KEYCODE_HOME: return "HOME";
-	case SIM_KEYCODE_END: return "END";
-	case SIM_KEYCODE_SPACE: return "SPACE";
-	case SIM_KEYCODE_ESCAPE: return "ESC";
-	case SIM_KEYCODE_DELETE: return "DELETE";
-	case SIM_KEYCODE_BACKSPACE: return "BACKSPACE";
-	}
-
-	if (key < 32) {
-		char str[6];
-		sprintf(str, "^%c", key + 64);
-		return str;
-	}
-
-	if (key < 127) {
-		char str[2];
-		str[0] = key;
-		str[1] = 0;
-		return str;
-	}
-
-	char str[10];
-	sprintf(str, "%s#%d", mod, key);
-	return str;
+    static vector_tpl<plainstring> keys;
+    keys.clear();
+
+    for (tool_t *const tool : tool_t::char_to_tool) {
+        if (tool == NULL  ||  tool->get_id() != tool_id) {
+            continue;
+        }
+        plainstring const keystr = key_to_string(tool);
+        if (strempty(keystr.c_str())) {
+            continue;
+        }
+        // avoid duplicates
+        bool already = false;
+        for (plainstring const& k : keys) {
+            if (strcmp(k.c_str(), keystr.c_str()) == 0) {
+                already = true;
+                break;
+            }
+        }
+        if (!already) {
+            keys.append(keystr);
+        }
+    }
+    return keys;
 }
 
 void export_string_methods(HSQUIRRELVM vm)
@@ -203,15 +219,12 @@ void export_string_methods(HSQUIRRELVM vm)
 	 */
 	register_method(vm, &difftick_to_string_intern, "difftick_to_string");
 
-	/**
-	* Gets the tool_key (shortcut key) associated with a general tool by its ID.
-	* The ID corresponds to the index used in menuconf.tab (e.g. 0 = query tool, 1 = remover, etc.).
-	* Returns the hotkey as a string (e.g. "r", "M", "COMMA, "^s, "+F10", "#1234") without quotation marks
-	* or an empty string if there is no hotkey or invalid ID.
-	* @param tool_id the numeric ID of the general tool (as defined in menuconf.tab)
-	* @returns a string representing the hotkey, or empty if none or invalid
-	*/
-	register_method(vm, &get_tool_key_intern, "get_tool_key");
+    /**
+     * Gets all shortcut keys associated with a tool by its ID.
+     * @param tool_id the numeric ID of the tool
+     * @returns array of hotkey strings (empty array if none)
+     */
+    register_method(vm, &get_tool_keys_intern, "get_tool_keys");
 }
 
 
-- 
2.43.0

