Merge pull request #26293 from the-black-eagle/mka_read_more_tags
[xbmc.git] / xbmc / input / actions / ActionTranslator.cpp
blob4fc972688a379cb3d8a31efdfce275b5a75e9c64
1 /*
2 * Copyright (C) 2005-2024 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "ActionTranslator.h"
11 #include "ActionIDs.h"
12 #include "interfaces/builtins/Builtins.h"
13 #include "utils/StringUtils.h"
14 #include "utils/log.h"
16 #include <map>
18 using namespace KODI;
19 using namespace ACTION;
21 namespace
23 using ActionName = std::string;
24 using ActionID = unsigned int;
26 static const std::map<ActionName, ActionID> ActionMappings = {
27 {"left", ACTION_MOVE_LEFT},
28 {"right", ACTION_MOVE_RIGHT},
29 {"up", ACTION_MOVE_UP},
30 {"down", ACTION_MOVE_DOWN},
31 {"pageup", ACTION_PAGE_UP},
32 {"pagedown", ACTION_PAGE_DOWN},
33 {"select", ACTION_SELECT_ITEM},
34 {"highlight", ACTION_HIGHLIGHT_ITEM},
35 {"parentdir", ACTION_NAV_BACK}, // backward compatibility
36 {"parentfolder", ACTION_PARENT_DIR},
37 {"back", ACTION_NAV_BACK},
38 {"menu", ACTION_MENU},
39 {"previousmenu", ACTION_PREVIOUS_MENU},
40 {"info", ACTION_SHOW_INFO},
41 {"pause", ACTION_PAUSE},
42 {"stop", ACTION_STOP},
43 {"skipnext", ACTION_NEXT_ITEM},
44 {"skipprevious", ACTION_PREV_ITEM},
45 {"fullscreen", ACTION_SHOW_GUI},
46 {"aspectratio", ACTION_ASPECT_RATIO},
47 {"stepforward", ACTION_STEP_FORWARD},
48 {"stepback", ACTION_STEP_BACK},
49 {"bigstepforward", ACTION_BIG_STEP_FORWARD},
50 {"bigstepback", ACTION_BIG_STEP_BACK},
51 {"chapterorbigstepforward", ACTION_CHAPTER_OR_BIG_STEP_FORWARD},
52 {"chapterorbigstepback", ACTION_CHAPTER_OR_BIG_STEP_BACK},
53 {"osd", ACTION_SHOW_OSD},
54 {"showsubtitles", ACTION_SHOW_SUBTITLES},
55 {"nextsubtitle", ACTION_NEXT_SUBTITLE},
56 {"previoussubtitle", ACTION_PREV_SUBTITLE},
57 {"browsesubtitle", ACTION_BROWSE_SUBTITLE},
58 {"cyclesubtitle", ACTION_CYCLE_SUBTITLE},
59 {"dialogselectvideo", ACTION_DIALOG_SELECT_VIDEO},
60 {"dialogselectaudio", ACTION_DIALOG_SELECT_AUDIO},
61 {"dialogselectsubtitle", ACTION_DIALOG_SELECT_SUBTITLE},
62 {"playerdebug", ACTION_PLAYER_DEBUG},
63 {"playerdebugvideo", ACTION_PLAYER_DEBUG_VIDEO},
64 {"codecinfo", ACTION_PLAYER_PROCESS_INFO},
65 {"playerprocessinfo", ACTION_PLAYER_PROCESS_INFO},
66 {"playerprogramselect", ACTION_PLAYER_PROGRAM_SELECT},
67 {"playerresolutionselect", ACTION_PLAYER_RESOLUTION_SELECT},
68 {"nextpicture", ACTION_NEXT_PICTURE},
69 {"previouspicture", ACTION_PREV_PICTURE},
70 {"zoomout", ACTION_ZOOM_OUT},
71 {"zoomin", ACTION_ZOOM_IN},
72 {"playlist", ACTION_SHOW_PLAYLIST},
73 {"queue", ACTION_QUEUE_ITEM},
74 {"playnext", ACTION_QUEUE_ITEM_NEXT},
75 {"zoomnormal", ACTION_ZOOM_LEVEL_NORMAL},
76 {"zoomlevel1", ACTION_ZOOM_LEVEL_1},
77 {"zoomlevel2", ACTION_ZOOM_LEVEL_2},
78 {"zoomlevel3", ACTION_ZOOM_LEVEL_3},
79 {"zoomlevel4", ACTION_ZOOM_LEVEL_4},
80 {"zoomlevel5", ACTION_ZOOM_LEVEL_5},
81 {"zoomlevel6", ACTION_ZOOM_LEVEL_6},
82 {"zoomlevel7", ACTION_ZOOM_LEVEL_7},
83 {"zoomlevel8", ACTION_ZOOM_LEVEL_8},
84 {"zoomlevel9", ACTION_ZOOM_LEVEL_9},
85 {"nextcalibration", ACTION_CALIBRATE_SWAP_ARROWS},
86 {"resetcalibration", ACTION_CALIBRATE_RESET},
87 {"analogmove", ACTION_ANALOG_MOVE},
88 {"analogmovexleft", ACTION_ANALOG_MOVE_X_LEFT},
89 {"analogmovexright", ACTION_ANALOG_MOVE_X_RIGHT},
90 {"analogmoveyup", ACTION_ANALOG_MOVE_Y_UP},
91 {"analogmoveydown", ACTION_ANALOG_MOVE_Y_DOWN},
92 {"rotate", ACTION_ROTATE_PICTURE_CW},
93 {"rotateccw", ACTION_ROTATE_PICTURE_CCW},
94 {"close", ACTION_NAV_BACK}, // backwards compatibility
95 {"subtitledelayminus", ACTION_SUBTITLE_DELAY_MIN},
96 {"subtitledelay", ACTION_SUBTITLE_DELAY},
97 {"subtitledelayplus", ACTION_SUBTITLE_DELAY_PLUS},
98 {"audiodelayminus", ACTION_AUDIO_DELAY_MIN},
99 {"audiodelay", ACTION_AUDIO_DELAY},
100 {"audiodelayplus", ACTION_AUDIO_DELAY_PLUS},
101 {"subtitleshiftup", ACTION_SUBTITLE_VSHIFT_UP},
102 {"subtitleshiftdown", ACTION_SUBTITLE_VSHIFT_DOWN},
103 {"subtitlealign", ACTION_SUBTITLE_ALIGN},
104 {"audionextlanguage", ACTION_AUDIO_NEXT_LANGUAGE},
105 {"verticalshiftup", ACTION_VSHIFT_UP},
106 {"verticalshiftdown", ACTION_VSHIFT_DOWN},
107 {"nextresolution", ACTION_CHANGE_RESOLUTION},
108 {"audiotoggledigital", ACTION_TOGGLE_DIGITAL_ANALOG},
109 {"number0", REMOTE_0},
110 {"number1", REMOTE_1},
111 {"number2", REMOTE_2},
112 {"number3", REMOTE_3},
113 {"number4", REMOTE_4},
114 {"number5", REMOTE_5},
115 {"number6", REMOTE_6},
116 {"number7", REMOTE_7},
117 {"number8", REMOTE_8},
118 {"number9", REMOTE_9},
119 {"smallstepback", ACTION_SMALL_STEP_BACK},
120 {"fastforward", ACTION_PLAYER_FORWARD},
121 {"rewind", ACTION_PLAYER_REWIND},
122 {"tempoup", ACTION_PLAYER_INCREASE_TEMPO},
123 {"tempodown", ACTION_PLAYER_DECREASE_TEMPO},
124 {"play", ACTION_PLAYER_PLAY},
125 {"playpause", ACTION_PLAYER_PLAYPAUSE},
126 {"switchplayer", ACTION_SWITCH_PLAYER},
127 {"delete", ACTION_DELETE_ITEM},
128 {"copy", ACTION_COPY_ITEM},
129 {"move", ACTION_MOVE_ITEM},
130 {"screenshot", ACTION_TAKE_SCREENSHOT},
131 {"rename", ACTION_RENAME_ITEM},
132 {"togglewatched", ACTION_TOGGLE_WATCHED},
133 {"scanitem", ACTION_SCAN_ITEM},
134 {"reloadkeymaps", ACTION_RELOAD_KEYMAPS},
135 {"volumeup", ACTION_VOLUME_UP},
136 {"volumedown", ACTION_VOLUME_DOWN},
137 {"mute", ACTION_MUTE},
138 {"backspace", ACTION_BACKSPACE},
139 {"scrollup", ACTION_SCROLL_UP},
140 {"scrolldown", ACTION_SCROLL_DOWN},
141 {"analogfastforward", ACTION_ANALOG_FORWARD},
142 {"analogrewind", ACTION_ANALOG_REWIND},
143 {"moveitemup", ACTION_MOVE_ITEM_UP},
144 {"moveitemdown", ACTION_MOVE_ITEM_DOWN},
145 {"contextmenu", ACTION_CONTEXT_MENU},
146 {"shift", ACTION_SHIFT},
147 {"symbols", ACTION_SYMBOLS},
148 {"cursorleft", ACTION_CURSOR_LEFT},
149 {"cursorright", ACTION_CURSOR_RIGHT},
150 {"showtime", ACTION_SHOW_OSD_TIME},
151 {"analogseekforward", ACTION_ANALOG_SEEK_FORWARD},
152 {"analogseekback", ACTION_ANALOG_SEEK_BACK},
153 {"showpreset", ACTION_VIS_PRESET_SHOW},
154 {"nextpreset", ACTION_VIS_PRESET_NEXT},
155 {"previouspreset", ACTION_VIS_PRESET_PREV},
156 {"lockpreset", ACTION_VIS_PRESET_LOCK},
157 {"randompreset", ACTION_VIS_PRESET_RANDOM},
158 {"increasevisrating", ACTION_VIS_RATE_PRESET_PLUS},
159 {"decreasevisrating", ACTION_VIS_RATE_PRESET_MINUS},
160 {"showvideomenu", ACTION_SHOW_VIDEOMENU},
161 {"enter", ACTION_ENTER},
162 {"increaserating", ACTION_INCREASE_RATING},
163 {"decreaserating", ACTION_DECREASE_RATING},
164 {"setrating", ACTION_SET_RATING},
165 {"togglefullscreen", ACTION_TOGGLE_FULLSCREEN},
166 {"nextscene", ACTION_NEXT_SCENE},
167 {"previousscene", ACTION_PREV_SCENE},
168 {"nextletter", ACTION_NEXT_LETTER},
169 {"prevletter", ACTION_PREV_LETTER},
170 {"jumpsms2", ACTION_JUMP_SMS2},
171 {"jumpsms3", ACTION_JUMP_SMS3},
172 {"jumpsms4", ACTION_JUMP_SMS4},
173 {"jumpsms5", ACTION_JUMP_SMS5},
174 {"jumpsms6", ACTION_JUMP_SMS6},
175 {"jumpsms7", ACTION_JUMP_SMS7},
176 {"jumpsms8", ACTION_JUMP_SMS8},
177 {"jumpsms9", ACTION_JUMP_SMS9},
178 {"filter", ACTION_FILTER},
179 {"filterclear", ACTION_FILTER_CLEAR},
180 {"filtersms2", ACTION_FILTER_SMS2},
181 {"filtersms3", ACTION_FILTER_SMS3},
182 {"filtersms4", ACTION_FILTER_SMS4},
183 {"filtersms5", ACTION_FILTER_SMS5},
184 {"filtersms6", ACTION_FILTER_SMS6},
185 {"filtersms7", ACTION_FILTER_SMS7},
186 {"filtersms8", ACTION_FILTER_SMS8},
187 {"filtersms9", ACTION_FILTER_SMS9},
188 {"firstpage", ACTION_FIRST_PAGE},
189 {"lastpage", ACTION_LAST_PAGE},
190 {"guiprofile", ACTION_GUIPROFILE_BEGIN},
191 {"red", ACTION_TELETEXT_RED},
192 {"green", ACTION_TELETEXT_GREEN},
193 {"yellow", ACTION_TELETEXT_YELLOW},
194 {"blue", ACTION_TELETEXT_BLUE},
195 {"increasepar", ACTION_INCREASE_PAR},
196 {"decreasepar", ACTION_DECREASE_PAR},
197 {"volampup", ACTION_VOLAMP_UP},
198 {"volampdown", ACTION_VOLAMP_DOWN},
199 {"volumeamplification", ACTION_VOLAMP},
200 {"createbookmark", ACTION_CREATE_BOOKMARK},
201 {"createepisodebookmark", ACTION_CREATE_EPISODE_BOOKMARK},
202 {"settingsreset", ACTION_SETTINGS_RESET},
203 {"settingslevelchange", ACTION_SETTINGS_LEVEL_CHANGE},
204 {"togglefont", ACTION_TOGGLE_FONT},
205 {"videonextstream", ACTION_VIDEO_NEXT_STREAM},
207 // 3D movie playback/GUI
208 {"stereomode", ACTION_STEREOMODE_SELECT}, // cycle 3D modes, for now an alias for next
209 {"nextstereomode", ACTION_STEREOMODE_NEXT},
210 {"previousstereomode", ACTION_STEREOMODE_PREVIOUS},
211 {"togglestereomode", ACTION_STEREOMODE_TOGGLE},
212 {"stereomodetomono", ACTION_STEREOMODE_TOMONO},
214 // HDR display support
215 {"hdrtoggle", ACTION_HDR_TOGGLE},
217 // Tone mapping
218 {"cycletonemapmethod", ACTION_CYCLE_TONEMAP_METHOD},
220 // PVR actions
221 {"channelup", ACTION_CHANNEL_UP},
222 {"channeldown", ACTION_CHANNEL_DOWN},
223 {"previouschannelgroup", ACTION_PREVIOUS_CHANNELGROUP},
224 {"nextchannelgroup", ACTION_NEXT_CHANNELGROUP},
225 {"playpvr", ACTION_PVR_PLAY},
226 {"playpvrtv", ACTION_PVR_PLAY_TV},
227 {"playpvrradio", ACTION_PVR_PLAY_RADIO},
228 {"record", ACTION_RECORD},
229 {"togglecommskip", ACTION_TOGGLE_COMMSKIP},
230 {"showtimerrule", ACTION_PVR_SHOW_TIMER_RULE},
231 {"channelnumberseparator", ACTION_CHANNEL_NUMBER_SEP},
233 // Mouse actions
234 {"leftclick", ACTION_MOUSE_LEFT_CLICK},
235 {"rightclick", ACTION_MOUSE_RIGHT_CLICK},
236 {"middleclick", ACTION_MOUSE_MIDDLE_CLICK},
237 {"doubleclick", ACTION_MOUSE_DOUBLE_CLICK},
238 {"longclick", ACTION_MOUSE_LONG_CLICK},
239 {"wheelup", ACTION_MOUSE_WHEEL_UP},
240 {"wheeldown", ACTION_MOUSE_WHEEL_DOWN},
241 {"mousedrag", ACTION_MOUSE_DRAG},
242 {"mousedragend", ACTION_MOUSE_DRAG_END},
243 {"mousemove", ACTION_MOUSE_MOVE},
245 // Touch
246 {"tap", ACTION_TOUCH_TAP},
247 {"longpress", ACTION_TOUCH_LONGPRESS},
248 {"pangesture", ACTION_GESTURE_PAN},
249 {"zoomgesture", ACTION_GESTURE_ZOOM},
250 {"rotategesture", ACTION_GESTURE_ROTATE},
251 {"swipeleft", ACTION_GESTURE_SWIPE_LEFT},
252 {"swiperight", ACTION_GESTURE_SWIPE_RIGHT},
253 {"swipeup", ACTION_GESTURE_SWIPE_UP},
254 {"swipedown", ACTION_GESTURE_SWIPE_DOWN},
256 // Voice
257 {"voicerecognizer", ACTION_VOICE_RECOGNIZE},
259 // Do nothing / error action
260 {"error", ACTION_ERROR},
261 {"noop", ACTION_NOOP}};
262 } // namespace
264 void CActionTranslator::GetActions(std::vector<std::string>& actionList)
266 actionList.reserve(ActionMappings.size());
267 for (auto& actionMapping : ActionMappings)
268 actionList.push_back(actionMapping.first);
271 bool CActionTranslator::IsAnalog(unsigned int actionID)
273 switch (actionID)
275 case ACTION_ANALOG_SEEK_FORWARD:
276 case ACTION_ANALOG_SEEK_BACK:
277 case ACTION_SCROLL_UP:
278 case ACTION_SCROLL_DOWN:
279 case ACTION_ANALOG_FORWARD:
280 case ACTION_ANALOG_REWIND:
281 case ACTION_ANALOG_MOVE:
282 case ACTION_ANALOG_MOVE_X_LEFT:
283 case ACTION_ANALOG_MOVE_X_RIGHT:
284 case ACTION_ANALOG_MOVE_Y_UP:
285 case ACTION_ANALOG_MOVE_Y_DOWN:
286 case ACTION_CURSOR_LEFT:
287 case ACTION_CURSOR_RIGHT:
288 case ACTION_VOLUME_UP:
289 case ACTION_VOLUME_DOWN:
290 case ACTION_ZOOM_IN:
291 case ACTION_ZOOM_OUT:
292 return true;
293 default:
294 return false;
298 bool CActionTranslator::TranslateString(std::string strAction, unsigned int& actionId)
300 actionId = ACTION_NONE;
302 if (strAction.empty())
303 return false;
305 StringUtils::ToLower(strAction);
307 auto it = ActionMappings.find(strAction);
308 if (it != ActionMappings.end())
309 actionId = it->second;
310 else if (CBuiltins::GetInstance().HasCommand(strAction))
311 actionId = ACTION_BUILT_IN_FUNCTION;
313 if (actionId == ACTION_NONE)
315 CLog::Log(LOGERROR, "Keymapping error: no such action '{}' defined", strAction);
316 return false;
319 return true;