diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/input/KeyboardLayoutManager.cpp | |
parent | Initial commit. (diff) | |
download | kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip |
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/input/KeyboardLayoutManager.cpp')
-rw-r--r-- | xbmc/input/KeyboardLayoutManager.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/xbmc/input/KeyboardLayoutManager.cpp b/xbmc/input/KeyboardLayoutManager.cpp new file mode 100644 index 0000000..66ed817 --- /dev/null +++ b/xbmc/input/KeyboardLayoutManager.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2015-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 "KeyboardLayoutManager.h" + +#include "FileItem.h" +#include "ServiceBroker.h" +#include "URL.h" +#include "filesystem/Directory.h" +#include "settings/lib/Setting.h" +#include "settings/lib/SettingDefinitions.h" +#include "utils/XBMCTinyXML.h" +#include "utils/log.h" + +#include <algorithm> + +#define KEYBOARD_LAYOUTS_PATH "special://xbmc/system/keyboardlayouts" + +CKeyboardLayoutManager::~CKeyboardLayoutManager() +{ + Unload(); +} + +bool CKeyboardLayoutManager::Load(const std::string& path /* = "" */) +{ + std::string layoutDirectory = path; + if (layoutDirectory.empty()) + layoutDirectory = KEYBOARD_LAYOUTS_PATH; + + if (!XFILE::CDirectory::Exists(layoutDirectory)) + { + CLog::Log(LOGWARNING, + "CKeyboardLayoutManager: unable to load keyboard layouts from non-existing directory " + "\"{}\"", + layoutDirectory); + return false; + } + + CFileItemList layouts; + if (!XFILE::CDirectory::GetDirectory(CURL(layoutDirectory), layouts, ".xml", + XFILE::DIR_FLAG_DEFAULTS) || + layouts.IsEmpty()) + { + CLog::Log(LOGWARNING, "CKeyboardLayoutManager: no keyboard layouts found in {}", + layoutDirectory); + return false; + } + + CLog::Log(LOGINFO, "CKeyboardLayoutManager: loading keyboard layouts from {}...", + layoutDirectory); + size_t oldLayoutCount = m_layouts.size(); + for (int i = 0; i < layouts.Size(); i++) + { + std::string layoutPath = layouts[i]->GetPath(); + if (layoutPath.empty()) + continue; + + CXBMCTinyXML xmlDoc; + if (!xmlDoc.LoadFile(layoutPath)) + { + CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unable to open {}", layoutPath); + continue; + } + + const TiXmlElement* rootElement = xmlDoc.RootElement(); + if (rootElement == NULL) + { + CLog::Log(LOGWARNING, "CKeyboardLayoutManager: missing or invalid XML root element in {}", + layoutPath); + continue; + } + + if (rootElement->ValueStr() != "keyboardlayouts") + { + CLog::Log(LOGWARNING, "CKeyboardLayoutManager: unexpected XML root element \"{}\" in {}", + rootElement->Value(), layoutPath); + continue; + } + + const TiXmlElement* layoutElement = rootElement->FirstChildElement("layout"); + while (layoutElement != NULL) + { + CKeyboardLayout layout; + if (!layout.Load(layoutElement)) + CLog::Log(LOGWARNING, "CKeyboardLayoutManager: failed to load {}", layoutPath); + else if (m_layouts.find(layout.GetIdentifier()) != m_layouts.end()) + CLog::Log(LOGWARNING, + "CKeyboardLayoutManager: duplicate layout with identifier \"{}\" in {}", + layout.GetIdentifier(), layoutPath); + else + { + CLog::Log(LOGDEBUG, "CKeyboardLayoutManager: keyboard layout \"{}\" successfully loaded", + layout.GetIdentifier()); + m_layouts.insert(std::make_pair(layout.GetIdentifier(), layout)); + } + + layoutElement = layoutElement->NextSiblingElement(); + } + } + + return m_layouts.size() > oldLayoutCount; +} + +void CKeyboardLayoutManager::Unload() +{ + m_layouts.clear(); +} + +bool CKeyboardLayoutManager::GetLayout(const std::string& name, CKeyboardLayout& layout) const +{ + if (name.empty()) + return false; + + KeyboardLayouts::const_iterator it = m_layouts.find(name); + if (it == m_layouts.end()) + return false; + + layout = it->second; + return true; +} + +namespace +{ +inline bool LayoutSort(const StringSettingOption& i, const StringSettingOption& j) +{ + return (i.value < j.value); +} +} // namespace + +void CKeyboardLayoutManager::SettingOptionsKeyboardLayoutsFiller( + const SettingConstPtr& setting, + std::vector<StringSettingOption>& list, + std::string& current, + void* data) +{ + for (const auto& it : CServiceBroker::GetKeyboardLayoutManager()->m_layouts) + { + std::string name = it.second.GetName(); + list.emplace_back(name, name); + } + + std::sort(list.begin(), list.end(), LayoutSort); +} |