Permalink
Cannot retrieve contributors at this time
/* | |
* Copyright (C) 2017-2018 Team Kodi | |
* This file is part of Kodi - https://kodi.tv | |
* | |
* SPDX-License-Identifier: GPL-2.0-or-later | |
* See LICENSES/README.md for more information. | |
*/ | |
#include "WindowTranslator.h" | |
#include "Application.h" | |
#include "ServiceBroker.h" | |
#include "guilib/WindowIDs.h" | |
#include "pvr/PVRManager.h" | |
#include "pvr/guilib/PVRGUIActions.h" | |
#include "utils/StringUtils.h" | |
#include "utils/log.h" | |
#include <algorithm> | |
#include <cstring> | |
#include <stdlib.h> | |
const CWindowTranslator::WindowMapByName CWindowTranslator::WindowMappingByName = { | |
{"home", WINDOW_HOME}, | |
{"programs", WINDOW_PROGRAMS}, | |
{"pictures", WINDOW_PICTURES}, | |
{"filemanager", WINDOW_FILES}, | |
{"settings", WINDOW_SETTINGS_MENU}, | |
{"music", WINDOW_MUSIC_NAV}, | |
{"videos", WINDOW_VIDEO_NAV}, | |
{"tvchannels", WINDOW_TV_CHANNELS}, | |
{"tvrecordings", WINDOW_TV_RECORDINGS}, | |
{"tvguide", WINDOW_TV_GUIDE}, | |
{"tvtimers", WINDOW_TV_TIMERS}, | |
{"tvsearch", WINDOW_TV_SEARCH}, | |
{"radiochannels", WINDOW_RADIO_CHANNELS}, | |
{"radiorecordings", WINDOW_RADIO_RECORDINGS}, | |
{"radioguide", WINDOW_RADIO_GUIDE}, | |
{"radiotimers", WINDOW_RADIO_TIMERS}, | |
{"radiosearch", WINDOW_RADIO_SEARCH}, | |
{"gamecontrollers", WINDOW_DIALOG_GAME_CONTROLLERS}, | |
{"games", WINDOW_GAMES}, | |
{"pvrguidecontrols", WINDOW_DIALOG_PVR_GUIDE_CONTROLS}, | |
{"pvrguideinfo", WINDOW_DIALOG_PVR_GUIDE_INFO}, | |
{"pvrrecordinginfo", WINDOW_DIALOG_PVR_RECORDING_INFO}, | |
{"pvrradiordsinfo", WINDOW_DIALOG_PVR_RADIO_RDS_INFO}, | |
{"pvrtimersetting", WINDOW_DIALOG_PVR_TIMER_SETTING}, | |
{"pvrgroupmanager", WINDOW_DIALOG_PVR_GROUP_MANAGER}, | |
{"pvrchannelmanager", WINDOW_DIALOG_PVR_CHANNEL_MANAGER}, | |
{"pvrguidesearch", WINDOW_DIALOG_PVR_GUIDE_SEARCH}, | |
{"pvrchannelscan", WINDOW_DIALOG_PVR_CHANNEL_SCAN}, | |
{"pvrupdateprogress", WINDOW_DIALOG_PVR_UPDATE_PROGRESS}, | |
{"pvrosdchannels", WINDOW_DIALOG_PVR_OSD_CHANNELS}, | |
{"pvrchannelguide", WINDOW_DIALOG_PVR_CHANNEL_GUIDE}, | |
{"pvrosdguide", WINDOW_DIALOG_PVR_CHANNEL_GUIDE}, // backward compatibility to v17 | |
{"pvrosdteletext", WINDOW_DIALOG_OSD_TELETEXT}, | |
{"systeminfo", WINDOW_SYSTEM_INFORMATION}, | |
{"screencalibration", WINDOW_SCREEN_CALIBRATION}, | |
{"systemsettings", WINDOW_SETTINGS_SYSTEM}, | |
{"servicesettings", WINDOW_SETTINGS_SERVICE}, | |
{"pvrsettings", WINDOW_SETTINGS_MYPVR}, | |
{"playersettings", WINDOW_SETTINGS_PLAYER}, | |
{"mediasettings", WINDOW_SETTINGS_MEDIA}, | |
{"interfacesettings", WINDOW_SETTINGS_INTERFACE}, | |
{"appearancesettings", WINDOW_SETTINGS_INTERFACE}, // backward compatibility to v16 | |
{"gamesettings", WINDOW_SETTINGS_MYGAMES}, | |
{"videoplaylist", WINDOW_VIDEO_PLAYLIST}, | |
{"loginscreen", WINDOW_LOGIN_SCREEN}, | |
{"profiles", WINDOW_SETTINGS_PROFILES}, | |
{"skinsettings", WINDOW_SKIN_SETTINGS}, | |
{"addonbrowser", WINDOW_ADDON_BROWSER}, | |
{"yesnodialog", WINDOW_DIALOG_YES_NO}, | |
{"progressdialog", WINDOW_DIALOG_PROGRESS}, | |
{"virtualkeyboard", WINDOW_DIALOG_KEYBOARD}, | |
{"volumebar", WINDOW_DIALOG_VOLUME_BAR}, | |
{"submenu", WINDOW_DIALOG_SUB_MENU}, | |
{"favourites", WINDOW_DIALOG_FAVOURITES}, | |
{"contextmenu", WINDOW_DIALOG_CONTEXT_MENU}, | |
{"notification", WINDOW_DIALOG_KAI_TOAST}, | |
{"numericinput", WINDOW_DIALOG_NUMERIC}, | |
{"gamepadinput", WINDOW_DIALOG_GAMEPAD}, | |
{"shutdownmenu", WINDOW_DIALOG_BUTTON_MENU}, | |
{"playercontrols", WINDOW_DIALOG_PLAYER_CONTROLS}, | |
{"playerprocessinfo", WINDOW_DIALOG_PLAYER_PROCESS_INFO}, | |
{"seekbar", WINDOW_DIALOG_SEEK_BAR}, | |
{"musicosd", WINDOW_DIALOG_MUSIC_OSD}, | |
{"addonsettings", WINDOW_DIALOG_ADDON_SETTINGS}, | |
{"visualisationpresetlist", WINDOW_DIALOG_VIS_PRESET_LIST}, | |
{"osdcmssettings", WINDOW_DIALOG_CMS_OSD_SETTINGS}, | |
{"osdvideosettings", WINDOW_DIALOG_VIDEO_OSD_SETTINGS}, | |
{"osdaudiosettings", WINDOW_DIALOG_AUDIO_OSD_SETTINGS}, | |
{"osdsubtitlesettings", WINDOW_DIALOG_SUBTITLE_OSD_SETTINGS}, | |
{"videobookmarks", WINDOW_DIALOG_VIDEO_BOOKMARKS}, | |
{"filebrowser", WINDOW_DIALOG_FILE_BROWSER}, | |
{"networksetup", WINDOW_DIALOG_NETWORK_SETUP}, | |
{"mediasource", WINDOW_DIALOG_MEDIA_SOURCE}, | |
{"profilesettings", WINDOW_DIALOG_PROFILE_SETTINGS}, | |
{"locksettings", WINDOW_DIALOG_LOCK_SETTINGS}, | |
{"contentsettings", WINDOW_DIALOG_CONTENT_SETTINGS}, | |
{"libexportsettings", WINDOW_DIALOG_LIBEXPORT_SETTINGS}, | |
{"songinformation", WINDOW_DIALOG_SONG_INFO}, | |
{"smartplaylisteditor", WINDOW_DIALOG_SMART_PLAYLIST_EDITOR}, | |
{"smartplaylistrule", WINDOW_DIALOG_SMART_PLAYLIST_RULE}, | |
{"busydialog", WINDOW_DIALOG_BUSY}, | |
{"busydialognocancel", WINDOW_DIALOG_BUSY_NOCANCEL}, | |
{"pictureinfo", WINDOW_DIALOG_PICTURE_INFO}, | |
{"fullscreeninfo", WINDOW_DIALOG_FULLSCREEN_INFO}, | |
{"sliderdialog", WINDOW_DIALOG_SLIDER}, | |
{"addoninformation", WINDOW_DIALOG_ADDON_INFO}, | |
{"subtitlesearch", WINDOW_DIALOG_SUBTITLES}, | |
{"musicplaylist", WINDOW_MUSIC_PLAYLIST}, | |
{"musicplaylisteditor", WINDOW_MUSIC_PLAYLIST_EDITOR}, | |
{"infoprovidersettings", WINDOW_DIALOG_INFOPROVIDER_SETTINGS}, | |
{"teletext", WINDOW_DIALOG_OSD_TELETEXT}, | |
{"selectdialog", WINDOW_DIALOG_SELECT}, | |
{"musicinformation", WINDOW_DIALOG_MUSIC_INFO}, | |
{"okdialog", WINDOW_DIALOG_OK}, | |
{"movieinformation", WINDOW_DIALOG_VIDEO_INFO}, | |
{"textviewer", WINDOW_DIALOG_TEXT_VIEWER}, | |
{"fullscreenvideo", WINDOW_FULLSCREEN_VIDEO}, | |
// Virtual window for fullscreen radio, uses WINDOW_FULLSCREEN_VIDEO as | |
// fallback | |
{"fullscreenlivetv", WINDOW_FULLSCREEN_LIVETV}, | |
// Live TV channel preview | |
{"fullscreenlivetvpreview", WINDOW_FULLSCREEN_LIVETV_PREVIEW}, | |
// Live TV direct channel number input | |
{"fullscreenlivetvinput", WINDOW_FULLSCREEN_LIVETV_INPUT}, | |
// Virtual window for fullscreen radio, uses WINDOW_VISUALISATION as fallback | |
{"fullscreenradio", WINDOW_FULLSCREEN_RADIO}, | |
// PVR Radio channel preview | |
{"fullscreenradiopreview", WINDOW_FULLSCREEN_RADIO_PREVIEW}, | |
// PVR radio direct channel number input | |
{"fullscreenradioinput", WINDOW_FULLSCREEN_RADIO_INPUT}, | |
{"fullscreengame", WINDOW_FULLSCREEN_GAME}, | |
{"visualisation", WINDOW_VISUALISATION}, | |
{"slideshow", WINDOW_SLIDESHOW}, | |
{"weather", WINDOW_WEATHER}, | |
{"screensaver", WINDOW_SCREENSAVER}, | |
{"videoosd", WINDOW_DIALOG_VIDEO_OSD}, | |
{"videomenu", WINDOW_VIDEO_MENU}, | |
{"videotimeseek", WINDOW_VIDEO_TIME_SEEK}, | |
{"splash", WINDOW_SPLASH}, | |
{"startwindow", WINDOW_START}, | |
{"startup", WINDOW_STARTUP_ANIM}, | |
{"peripheralsettings", WINDOW_DIALOG_PERIPHERAL_SETTINGS}, | |
{"extendedprogressdialog", WINDOW_DIALOG_EXT_PROGRESS}, | |
{"mediafilter", WINDOW_DIALOG_MEDIA_FILTER}, | |
{"addon", WINDOW_ADDON_START}, | |
{"eventlog", WINDOW_EVENT_LOG}, | |
{"tvtimerrules", WINDOW_TV_TIMER_RULES}, | |
{"radiotimerrules", WINDOW_RADIO_TIMER_RULES}, | |
{"gameosd", WINDOW_DIALOG_GAME_OSD}, | |
{"gamevideofilter", WINDOW_DIALOG_GAME_VIDEO_FILTER}, | |
{"gamestretchmode", WINDOW_DIALOG_GAME_STRETCH_MODE}, | |
{"gamevolume", WINDOW_DIALOG_GAME_VOLUME}, | |
{"gameadvancedsettings", WINDOW_DIALOG_GAME_ADVANCED_SETTINGS}, | |
{"gamevideorotation", WINDOW_DIALOG_GAME_VIDEO_ROTATION}, | |
}; | |
namespace | |
{ | |
struct FallbackWindowMapping | |
{ | |
int origin; | |
int target; | |
}; | |
static const std::vector<FallbackWindowMapping> FallbackWindows = { | |
{WINDOW_FULLSCREEN_LIVETV, WINDOW_FULLSCREEN_VIDEO}, | |
{WINDOW_FULLSCREEN_LIVETV_INPUT, WINDOW_FULLSCREEN_LIVETV}, | |
{WINDOW_FULLSCREEN_LIVETV_PREVIEW, WINDOW_FULLSCREEN_LIVETV}, | |
{WINDOW_FULLSCREEN_RADIO, WINDOW_VISUALISATION}, | |
{WINDOW_FULLSCREEN_RADIO_INPUT, WINDOW_FULLSCREEN_RADIO}, | |
{WINDOW_FULLSCREEN_RADIO_PREVIEW, WINDOW_FULLSCREEN_RADIO}, | |
}; | |
} // anonymous namespace | |
bool CWindowTranslator::WindowNameCompare::operator()(const WindowMapItem& lhs, | |
const WindowMapItem& rhs) const | |
{ | |
return std::strcmp(lhs.windowName, rhs.windowName) < 0; | |
} | |
bool CWindowTranslator::WindowIDCompare::operator()(const WindowMapItem& lhs, | |
const WindowMapItem& rhs) const | |
{ | |
return lhs.windowId < rhs.windowId; | |
} | |
void CWindowTranslator::GetWindows(std::vector<std::string>& windowList) | |
{ | |
windowList.clear(); | |
windowList.reserve(WindowMappingByName.size()); | |
for (auto itMapping : WindowMappingByName) | |
windowList.emplace_back(itMapping.windowName); | |
} | |
int CWindowTranslator::TranslateWindow(const std::string& window) | |
{ | |
std::string strWindow(window); | |
if (strWindow.empty()) | |
return WINDOW_INVALID; | |
StringUtils::ToLower(strWindow); | |
// Eliminate .xml | |
if (StringUtils::EndsWith(strWindow, ".xml")) | |
strWindow = strWindow.substr(0, strWindow.size() - 4); | |
// window12345, for custom window to be keymapped | |
if (strWindow.length() > 6 && StringUtils::StartsWith(strWindow, "window")) | |
strWindow = strWindow.substr(6); | |
// Drop "my" prefix | |
if (StringUtils::StartsWith(strWindow, "my")) | |
strWindow = strWindow.substr(2); | |
if (StringUtils::IsNaturalNumber(strWindow)) | |
{ | |
// Allow a full window ID or a delta ID | |
int iWindow = atoi(strWindow.c_str()); | |
if (iWindow > WINDOW_INVALID) | |
return iWindow; | |
return WINDOW_HOME + iWindow; | |
} | |
// Run through the window structure | |
auto it = WindowMappingByName.find(WindowMapItem{strWindow.c_str()}); | |
if (it != WindowMappingByName.end()) | |
return it->windowId; | |
CLog::Log(LOGERROR, "Window Translator: Can't find window %s", window.c_str()); | |
return WINDOW_INVALID; | |
} | |
std::string CWindowTranslator::TranslateWindow(int windowId) | |
{ | |
static auto reverseWindowMapping = CreateWindowMappingByID(); | |
windowId = GetVirtualWindow(windowId); | |
auto it = reverseWindowMapping.find(WindowMapItem{"", windowId}); | |
if (it != reverseWindowMapping.end()) | |
return it->windowName; | |
return ""; | |
} | |
int CWindowTranslator::GetFallbackWindow(int windowId) | |
{ | |
auto it = std::find_if( | |
FallbackWindows.begin(), FallbackWindows.end(), | |
[windowId](const FallbackWindowMapping& mapping) { return mapping.origin == windowId; }); | |
if (it != FallbackWindows.end()) | |
return it->target; | |
// For add-on windows use WINDOW_ADDON_START because ID is dynamic | |
if (WINDOW_ADDON_START < windowId && windowId <= WINDOW_ADDON_END) | |
return WINDOW_ADDON_START; | |
return -1; | |
} | |
CWindowTranslator::WindowMapByID CWindowTranslator::CreateWindowMappingByID() | |
{ | |
WindowMapByID reverseWindowMapping; | |
reverseWindowMapping.insert(WindowMappingByName.begin(), WindowMappingByName.end()); | |
return reverseWindowMapping; | |
} | |
int CWindowTranslator::GetVirtualWindow(int windowId) | |
{ | |
if (windowId == WINDOW_FULLSCREEN_VIDEO) | |
{ | |
// check if we're in a DVD menu | |
if (g_application.GetAppPlayer().IsInMenu()) | |
return WINDOW_VIDEO_MENU; | |
// special casing for Live TV | |
else if (g_application.CurrentFileItem().HasPVRChannelInfoTag()) | |
{ | |
if (CServiceBroker::GetPVRManager() | |
.GUIActions() | |
->GetChannelNumberInputHandler() | |
.HasChannelNumber()) | |
return WINDOW_FULLSCREEN_LIVETV_INPUT; | |
else if (CServiceBroker::GetPVRManager().GUIActions()->GetChannelNavigator().IsPreview()) | |
return WINDOW_FULLSCREEN_LIVETV_PREVIEW; | |
else | |
return WINDOW_FULLSCREEN_LIVETV; | |
} | |
// special casing for numeric seek | |
else if (g_application.GetAppPlayer().GetSeekHandler().HasTimeCode()) | |
return WINDOW_VIDEO_TIME_SEEK; | |
} | |
else if (windowId == WINDOW_VISUALISATION) | |
{ | |
// special casing for PVR radio | |
if (g_application.CurrentFileItem().HasPVRChannelInfoTag()) | |
{ | |
if (CServiceBroker::GetPVRManager() | |
.GUIActions() | |
->GetChannelNumberInputHandler() | |
.HasChannelNumber()) | |
return WINDOW_FULLSCREEN_RADIO_INPUT; | |
else if (CServiceBroker::GetPVRManager().GUIActions()->GetChannelNavigator().IsPreview()) | |
return WINDOW_FULLSCREEN_RADIO_PREVIEW; | |
else | |
return WINDOW_FULLSCREEN_RADIO; | |
} | |
// special casing for numeric seek | |
else if (g_application.GetAppPlayer().GetSeekHandler().HasTimeCode()) | |
return WINDOW_VIDEO_TIME_SEEK; | |
} | |
return windowId; | |
} |