Merge pull request #4775 from jmarshallnz/empty_episode_playcount
[vuplus_xbmc] / xbmc / input / KeyboardLayoutConfiguration.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "KeyboardLayoutConfiguration.h"
22 #include "utils/CharsetConverter.h"
23 #include "utils/XBMCTinyXML.h"
24
25 using namespace std;
26 CKeyboardLayoutConfiguration g_keyboardLayoutConfiguration;
27
28 CKeyboardLayoutConfiguration::CKeyboardLayoutConfiguration()
29 {
30   SetDefaults();
31 }
32
33
34 CKeyboardLayoutConfiguration::~CKeyboardLayoutConfiguration()
35 {
36   SetDefaults();
37 }
38
39 void CKeyboardLayoutConfiguration::SetDefaults()
40 {
41   m_changeXbmcCharRegardlessModifiers.clear();
42   m_changeXbmcCharWithRalt.clear();
43   m_deriveXbmcCharFromVkeyRegardlessModifiers.clear();
44   m_deriveXbmcCharFromVkeyWithShift.clear();
45   m_deriveXbmcCharFromVkeyWithRalt.clear();
46 }
47
48 bool CKeyboardLayoutConfiguration::Load(const CStdString& strFileName)
49 {
50   SetDefaults();
51
52   CXBMCTinyXML xmlDoc;
53   if (!xmlDoc.LoadFile(strFileName))
54   {
55     CLog::Log(LOGINFO, "unable to load %s: %s at line %d", strFileName.c_str(), xmlDoc.ErrorDesc(), xmlDoc.ErrorRow());
56     return false;
57   }
58
59   TiXmlElement* pRootElement = xmlDoc.RootElement();
60   CStdString strValue = pRootElement->Value();
61   if (strValue != CStdString("keyboard_layout"))
62   {
63     CLog::Log(LOGERROR, "%s Doesn't contain <keyboard_layout>", strFileName.c_str());
64     return false;
65   }
66
67   CLog::Log(LOGDEBUG, "reading char2char ");
68   const TiXmlElement* pMapChangeXbmcCharRegardlessModifiers = pRootElement->FirstChildElement("char2char");
69   readCharMapFromXML(pMapChangeXbmcCharRegardlessModifiers, m_changeXbmcCharRegardlessModifiers, ("char2char"));
70
71   CLog::Log(LOGDEBUG, "reading char2char_ralt ");
72   const TiXmlElement* pMapChangeXbmcCharWithRalt = pRootElement->FirstChildElement("char2char_ralt");
73   readCharMapFromXML(pMapChangeXbmcCharWithRalt, m_changeXbmcCharWithRalt, ("char2char_ralt"));
74
75   CLog::Log(LOGDEBUG, "reading vkey2char ");
76   const TiXmlElement* pMapDeriveXbmcCharFromVkeyRegardlessModifiers = pRootElement->FirstChildElement("vkey2char");
77   readByteMapFromXML(pMapDeriveXbmcCharFromVkeyRegardlessModifiers, m_deriveXbmcCharFromVkeyRegardlessModifiers, ("vkey2char"));
78
79   CLog::Log(LOGDEBUG, "reading vkey2char_shift ");
80   const TiXmlElement* pMapDeriveXbmcCharFromVkeyWithShift = pRootElement->FirstChildElement("vkey2char_shift");
81   readByteMapFromXML(pMapDeriveXbmcCharFromVkeyWithShift, m_deriveXbmcCharFromVkeyWithShift, ("vkey2char_shift"));
82
83   CLog::Log(LOGDEBUG, "reading vkey2char_ralt ");
84   const TiXmlElement* pMapDeriveXbmcCharFromVkeyWithRalt = pRootElement->FirstChildElement("vkey2char_ralt");
85   readByteMapFromXML(pMapDeriveXbmcCharFromVkeyWithRalt, m_deriveXbmcCharFromVkeyWithRalt, ("vkey2char_ralt"));
86
87   return true;
88 }
89
90 void CKeyboardLayoutConfiguration::readCharMapFromXML(const TiXmlElement* pXMLMap, map<WCHAR, WCHAR>& charToCharMap, const char* mapRootElement)
91 {
92   if (pXMLMap && !pXMLMap->NoChildren())
93   { // map keys
94     const TiXmlElement* pEntry = pXMLMap->FirstChildElement();
95     while (pEntry)
96     {
97       CStdString strInChar = pEntry->Attribute("inchar");
98       CStdString strOutChar = pEntry->Attribute("outchar");
99       if (strInChar.length() > 0 && strOutChar.length() > 0)
100       {
101         CStdStringW fromStr;
102         g_charsetConverter.utf8ToW(strInChar, fromStr);
103         CStdStringW toStr;
104         g_charsetConverter.utf8ToW(strOutChar, toStr);
105         if (fromStr.size()==1 && toStr.size()==1)
106         {
107           charToCharMap.insert(pair<WCHAR, WCHAR>(fromStr[0], toStr[0]));
108           CLog::Log(LOGDEBUG, "insert map entry from %c to %c ", fromStr[0], toStr[0]);
109         }
110         else
111         {
112           CLog::Log(LOGERROR, "String from %ls or to %ls does not have the expected length of 1", fromStr.c_str(), toStr.c_str());
113         }
114       }
115       else
116       {
117         CLog::Log(LOGERROR, "map entry misses attribute <inchar> or <outchar> or content of them");
118       }
119       pEntry = pEntry->NextSiblingElement();
120     }
121   }
122   else
123   {
124     CLog::Log(LOGDEBUG, "XML-Configuration doesn't contain expected map root element %s", mapRootElement);
125   }
126 }
127
128 void CKeyboardLayoutConfiguration::readByteMapFromXML(const TiXmlElement* pXMLMap, map<BYTE, WCHAR>& charToCharMap, const char* mapRootElement)
129 {
130   if (pXMLMap && !pXMLMap->NoChildren())
131   { // map keys
132     const TiXmlElement* pEntry = pXMLMap->FirstChildElement();
133     while (pEntry)
134     {
135       CStdString strInHex = pEntry->Attribute("inhex");
136       CStdString strOutChar = pEntry->Attribute("outchar");
137       if (strInHex.length() > 0 && strOutChar.length() > 0)
138       {
139         CStdString hexValue = strInHex;
140         CStdStringW toStr;
141         g_charsetConverter.utf8ToW(strOutChar, toStr);
142
143         int from;
144         if (sscanf(hexValue.c_str(), "%x", (unsigned int *)&from))
145         {
146           if (from != 0) // eats nearly any typing error as 0: catch it:
147           {
148             if (from < 256)
149             {
150               if (toStr.size()==1)
151               {
152                     charToCharMap.insert(pair<BYTE, WCHAR>(from, toStr[0]));
153                     CLog::Log(LOGDEBUG, "insert map entry from %d to %c ", from, toStr[0]);
154               }
155               else
156               {
157                 CLog::Log(LOGERROR, "String to %ls does not have the expected length of >=1", toStr.c_str());
158               }
159             }
160             else
161             {
162               CLog::Log(LOGERROR, "From value %d was greater than 255! ", from);
163             }
164           }
165           else
166           {
167             CLog::Log(LOGERROR, "Scanned from-value %d as 0 probably a (typing?) error! ", from);
168           }
169         }
170         else
171         {
172             CLog::Log(LOGERROR, "Could not scan from-value %s (was no valid hex value) ", hexValue.c_str());
173         }
174       }
175       else
176       {
177         CLog::Log(LOGERROR, "map entry misses attribute <inhex> or <outchar> or content of them");
178       }
179       pEntry = pEntry->NextSiblingElement();
180     }
181   }
182   else
183   {
184     CLog::Log(LOGERROR, "XML-Configuration doesn't contain expected map root element %s", mapRootElement);
185   }
186 }
187
188 bool CKeyboardLayoutConfiguration::containsChangeXbmcCharRegardlessModifiers(WCHAR key)
189 {
190   bool result = m_changeXbmcCharRegardlessModifiers.find(key) != m_changeXbmcCharRegardlessModifiers.end();
191 #ifdef DEBUG_KEYBOARD_GETCHAR
192   CLog::Log(LOGDEBUG, "found containsChangeXbmcCharRegardlessModifiers key char %c: bool: %d ", key, result);
193 #endif
194   return result;
195 }
196
197 bool CKeyboardLayoutConfiguration::containsChangeXbmcCharWithRalt(WCHAR key)
198 {
199   bool result = m_changeXbmcCharWithRalt.find(key) != m_changeXbmcCharWithRalt.end();
200 #ifdef DEBUG_KEYBOARD_GETCHAR
201   CLog::Log(LOGDEBUG, "found containsChangeXbmcCharWithRalt key char %c: bool: %d ", key, result);
202 #endif
203   return result;
204 }
205
206 bool CKeyboardLayoutConfiguration::containsDeriveXbmcCharFromVkeyRegardlessModifiers(BYTE key)
207 {
208   bool result = m_deriveXbmcCharFromVkeyRegardlessModifiers.find(key) != m_deriveXbmcCharFromVkeyRegardlessModifiers.end();
209 #ifdef DEBUG_KEYBOARD_GETCHAR
210   CLog::Log(LOGDEBUG, "found containsDeriveXbmcCharFromVkeyRegardlessModifiers key vkey %d: bool: %d ", key, result);
211 #endif
212   return result;
213 }
214
215 bool CKeyboardLayoutConfiguration::containsDeriveXbmcCharFromVkeyWithShift(BYTE key)
216 {
217   bool result = m_deriveXbmcCharFromVkeyWithShift.find(key) != m_deriveXbmcCharFromVkeyWithShift.end();
218 #ifdef DEBUG_KEYBOARD_GETCHAR
219   CLog::Log(LOGDEBUG, "found containsDeriveXbmcCharFromVkeyWithShift key vkey %d: bool: %d ", key, result);
220 #endif
221   return result;
222 }
223
224 bool CKeyboardLayoutConfiguration::containsDeriveXbmcCharFromVkeyWithRalt(BYTE key)
225 {
226   bool result = m_deriveXbmcCharFromVkeyWithRalt.find(key) != m_deriveXbmcCharFromVkeyWithRalt.end();
227 #ifdef DEBUG_KEYBOARD_GETCHAR
228   CLog::Log(LOGDEBUG, "found containsDeriveXbmcCharFromVkeyWithRalt key vkey %d: bool: %d ", key, result);
229 #endif
230   return result;
231 }
232
233 WCHAR CKeyboardLayoutConfiguration::valueOfChangeXbmcCharRegardlessModifiers(WCHAR key)
234 {
235   WCHAR result = (m_changeXbmcCharRegardlessModifiers.find(key))->second;
236 #ifdef DEBUG_KEYBOARD_GETCHAR
237   CLog::Log(LOGDEBUG, "found valueOfChangeXbmcCharRegardlessModifiers for char key %c: char %c ", key, result);
238 #endif
239   return result;
240 }
241
242 WCHAR CKeyboardLayoutConfiguration::valueOfChangeXbmcCharWithRalt(WCHAR key)
243 {
244   WCHAR result = (m_changeXbmcCharWithRalt.find(key))->second;
245 #ifdef DEBUG_KEYBOARD_GETCHAR
246   CLog::Log(LOGDEBUG, "found valueOfChangeXbmcCharWithRalt for char key %c: char %c ", key, result);
247 #endif
248   return result;
249 }
250
251 WCHAR CKeyboardLayoutConfiguration::valueOfDeriveXbmcCharFromVkeyRegardlessModifiers(BYTE key)
252 {
253   WCHAR result = (m_deriveXbmcCharFromVkeyRegardlessModifiers.find(key))->second;
254 #ifdef DEBUG_KEYBOARD_GETCHAR
255   CLog::Log(LOGDEBUG, "found valueOfDeriveXbmcCharFromVkeyRegardlessModifiers for key vkey %d: char %c ", key, result);
256 #endif
257   return result;
258 }
259
260 WCHAR CKeyboardLayoutConfiguration::valueOfDeriveXbmcCharFromVkeyWithShift(BYTE key)
261 {
262   WCHAR result = (m_deriveXbmcCharFromVkeyWithShift.find(key))->second;
263 #ifdef DEBUG_KEYBOARD_GETCHAR
264   CLog::Log(LOGDEBUG, "found valueOfDeriveXbmcCharFromVkeyWithShift for key vkey %d: char %c ", key, result);
265 #endif
266   return result;
267 }
268
269 WCHAR CKeyboardLayoutConfiguration::valueOfDeriveXbmcCharFromVkeyWithRalt(BYTE key)
270 {
271   WCHAR result = (m_deriveXbmcCharFromVkeyWithRalt.find(key))->second;
272 #ifdef DEBUG_KEYBOARD_GETCHAR
273   CLog::Log(LOGDEBUG, "found valueOfDeriveXbmcCharFromVkeyWithRalt for key vkey %d: char %c ", key, result);
274 #endif
275   return result;
276 }
277
278