1 /*
2  *  Copyright (C) 2015-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #include "ControllerFeature.h"
10 
11 #include "Controller.h"
12 #include "ControllerDefinitions.h"
13 #include "ControllerTranslator.h"
14 #include "guilib/LocalizeStrings.h"
15 #include "utils/XMLUtils.h"
16 #include "utils/log.h"
17 
18 #include <sstream>
19 
20 using namespace KODI;
21 using namespace GAME;
22 using namespace JOYSTICK;
23 
CControllerFeature(int labelId)24 CControllerFeature::CControllerFeature(int labelId)
25 {
26   Reset();
27   m_labelId = labelId;
28 }
29 
Reset(void)30 void CControllerFeature::Reset(void)
31 {
32   *this = CControllerFeature();
33 }
34 
operator =(const CControllerFeature & rhs)35 CControllerFeature& CControllerFeature::operator=(const CControllerFeature& rhs)
36 {
37   if (this != &rhs)
38   {
39     m_controller = rhs.m_controller;
40     m_type = rhs.m_type;
41     m_category = rhs.m_category;
42     m_categoryLabelId = rhs.m_categoryLabelId;
43     m_strName = rhs.m_strName;
44     m_labelId = rhs.m_labelId;
45     m_inputType = rhs.m_inputType;
46     m_keycode = rhs.m_keycode;
47   }
48   return *this;
49 }
50 
CategoryLabel() const51 std::string CControllerFeature::CategoryLabel() const
52 {
53   std::string categoryLabel;
54 
55   if (m_categoryLabelId >= 0 && m_controller != nullptr)
56     categoryLabel = g_localizeStrings.GetAddonString(m_controller->ID(), m_categoryLabelId);
57 
58   if (categoryLabel.empty())
59     categoryLabel = g_localizeStrings.Get(m_categoryLabelId);
60 
61   return categoryLabel;
62 }
63 
Label() const64 std::string CControllerFeature::Label() const
65 {
66   std::string label;
67 
68   if (m_labelId >= 0 && m_controller != nullptr)
69     label = g_localizeStrings.GetAddonString(m_controller->ID(), m_labelId);
70 
71   if (label.empty())
72     label = g_localizeStrings.Get(m_labelId);
73 
74   return label;
75 }
76 
Deserialize(const TiXmlElement * pElement,const CController * controller,FEATURE_CATEGORY category,int categoryLabelId)77 bool CControllerFeature::Deserialize(const TiXmlElement* pElement,
78                                      const CController* controller,
79                                      FEATURE_CATEGORY category,
80                                      int categoryLabelId)
81 {
82   Reset();
83 
84   if (!pElement)
85     return false;
86 
87   std::string strType(pElement->Value());
88 
89   // Type
90   m_type = CControllerTranslator::TranslateFeatureType(strType);
91   if (m_type == FEATURE_TYPE::UNKNOWN)
92   {
93     CLog::Log(LOGDEBUG, "Invalid feature: <%s> ", pElement->Value());
94     return false;
95   }
96 
97   // Cagegory was obtained from parent XML node
98   m_category = category;
99   m_categoryLabelId = categoryLabelId;
100 
101   // Name
102   m_strName = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_FEATURE_NAME);
103   if (m_strName.empty())
104   {
105     CLog::Log(LOGERROR, "<%s> tag has no \"%s\" attribute", strType.c_str(),
106               LAYOUT_XML_ATTR_FEATURE_NAME);
107     return false;
108   }
109 
110   // Label ID
111   std::string strLabel = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_FEATURE_LABEL);
112   if (strLabel.empty())
113     CLog::Log(LOGDEBUG, "<%s> tag has no \"%s\" attribute", strType.c_str(),
114               LAYOUT_XML_ATTR_FEATURE_LABEL);
115   else
116     std::istringstream(strLabel) >> m_labelId;
117 
118   // Input type
119   if (m_type == FEATURE_TYPE::SCALAR)
120   {
121     std::string strInputType = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_INPUT_TYPE);
122     if (strInputType.empty())
123     {
124       CLog::Log(LOGERROR, "<%s> tag has no \"%s\" attribute", strType.c_str(),
125                 LAYOUT_XML_ATTR_INPUT_TYPE);
126       return false;
127     }
128     else
129     {
130       m_inputType = CControllerTranslator::TranslateInputType(strInputType);
131       if (m_inputType == INPUT_TYPE::UNKNOWN)
132       {
133         CLog::Log(LOGERROR, "<%s> tag - attribute \"%s\" is invalid: \"%s\"", strType.c_str(),
134                   LAYOUT_XML_ATTR_INPUT_TYPE, strInputType.c_str());
135         return false;
136       }
137     }
138   }
139 
140   // Keycode
141   if (m_type == FEATURE_TYPE::KEY)
142   {
143     std::string strSymbol = XMLUtils::GetAttribute(pElement, LAYOUT_XML_ATTR_KEY_SYMBOL);
144     if (strSymbol.empty())
145     {
146       CLog::Log(LOGERROR, "<%s> tag has no \"%s\" attribute", strType.c_str(),
147                 LAYOUT_XML_ATTR_KEY_SYMBOL);
148       return false;
149     }
150     else
151     {
152       m_keycode = CControllerTranslator::TranslateKeysym(strSymbol);
153       if (m_keycode == XBMCK_UNKNOWN)
154       {
155         CLog::Log(LOGERROR, "<%s> tag - attribute \"%s\" is invalid: \"%s\"", strType.c_str(),
156                   LAYOUT_XML_ATTR_KEY_SYMBOL, strSymbol.c_str());
157         return false;
158       }
159     }
160   }
161 
162   // Save controller for string translation
163   m_controller = controller;
164 
165   return true;
166 }
167