2 * Copyright (C) 2005-2013 Team XBMC
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)
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.
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/>.
21 #include "Peripheral.h"
22 #include "peripherals/Peripherals.h"
23 #include "utils/log.h"
24 #include "utils/StringUtils.h"
25 #include "settings/Setting.h"
26 #include "utils/XBMCTinyXML.h"
27 #include "utils/URIUtils.h"
28 #include "guilib/LocalizeStrings.h"
30 using namespace PERIPHERALS;
33 CPeripheral::CPeripheral(const PeripheralScanResult& scanResult) :
34 m_type(scanResult.m_mappedType),
35 m_busType(scanResult.m_busType),
36 m_mappedBusType(scanResult.m_mappedBusType),
37 m_strLocation(scanResult.m_strLocation),
38 m_strDeviceName(scanResult.m_strDeviceName),
39 m_strFileLocation(StringUtils::EmptyString),
40 m_iVendorId(scanResult.m_iVendorId),
41 m_iProductId(scanResult.m_iProductId),
42 m_strVersionInfo(g_localizeStrings.Get(13205)), // "unknown"
43 m_bInitialised(false),
47 PeripheralTypeTranslator::FormatHexString(scanResult.m_iVendorId, m_strVendorId);
48 PeripheralTypeTranslator::FormatHexString(scanResult.m_iProductId, m_strProductId);
49 m_strFileLocation.Format(scanResult.m_iSequence > 0 ? "peripherals://%s/%s_%d.dev" : "peripherals://%s/%s.dev", PeripheralTypeTranslator::BusTypeToString(scanResult.m_busType), scanResult.m_strLocation.c_str(), scanResult.m_iSequence);
52 CPeripheral::~CPeripheral(void)
54 PersistSettings(true);
56 for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++)
57 delete m_subDevices.at(iSubdevicePtr);
63 bool CPeripheral::operator ==(const CPeripheral &right) const
65 return m_type == right.m_type &&
66 m_strLocation == right.m_strLocation &&
67 m_iVendorId == right.m_iVendorId &&
68 m_iProductId == right.m_iProductId;
71 bool CPeripheral::operator !=(const CPeripheral &right) const
73 return !(*this == right);
76 bool CPeripheral::HasFeature(const PeripheralFeature feature) const
80 for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++)
82 if (m_features.at(iFeaturePtr) == feature)
91 for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++)
93 if (m_subDevices.at(iSubdevicePtr)->HasFeature(feature))
104 void CPeripheral::GetFeatures(std::vector<PeripheralFeature> &features) const
106 for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++)
107 features.push_back(m_features.at(iFeaturePtr));
109 for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++)
110 m_subDevices.at(iSubdevicePtr)->GetFeatures(features);
113 bool CPeripheral::Initialise(void)
124 g_peripherals.GetSettingsFromMapping(*this);
125 m_strSettingsFile.Format("special://profile/peripheral_data/%s_%s_%s.xml", PeripheralTypeTranslator::BusTypeToString(m_mappedBusType), m_strVendorId.c_str(), m_strProductId.c_str());
126 LoadPersistedSettings();
128 for (unsigned int iFeaturePtr = 0; iFeaturePtr < m_features.size(); iFeaturePtr++)
130 PeripheralFeature feature = m_features.at(iFeaturePtr);
131 bReturn &= InitialiseFeature(feature);
134 for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++)
135 bReturn &= m_subDevices.at(iSubdevicePtr)->Initialise();
139 CLog::Log(LOGDEBUG, "%s - initialised peripheral on '%s' with %d features and %d sub devices",
140 __FUNCTION__, m_strLocation.c_str(), (int)m_features.size(), (int)m_subDevices.size());
141 m_bInitialised = true;
147 void CPeripheral::GetSubdevices(vector<CPeripheral *> &subDevices) const
149 for (unsigned int iSubdevicePtr = 0; iSubdevicePtr < m_subDevices.size(); iSubdevicePtr++)
150 subDevices.push_back(m_subDevices.at(iSubdevicePtr));
153 bool CPeripheral::IsMultiFunctional(void) const
155 return m_subDevices.size() > 0;
158 vector<CSetting *> CPeripheral::GetSettings(void) const
160 vector<CSetting *> settings;
161 for (map<CStdString, CSetting *>::const_iterator it = m_settings.begin(); it != m_settings.end(); it++)
162 settings.push_back(it->second);
166 void CPeripheral::AddSetting(const CStdString &strKey, const CSetting *setting)
170 CLog::Log(LOGERROR, "%s - invalid setting", __FUNCTION__);
174 if (!HasSetting(strKey))
176 switch(setting->GetType())
178 case SettingTypeBool:
180 const CSettingBool *mappedSetting = (const CSettingBool *) setting;
181 CSettingBool *boolSetting = new CSettingBool(strKey, *mappedSetting);
184 boolSetting->SetVisible(mappedSetting->IsVisible());
185 m_settings.insert(make_pair(strKey, boolSetting));
189 case SettingTypeInteger:
191 const CSettingInt *mappedSetting = (const CSettingInt *) setting;
192 CSettingInt *intSetting = new CSettingInt(strKey, *mappedSetting);
195 intSetting->SetVisible(mappedSetting->IsVisible());
196 m_settings.insert(make_pair(strKey, intSetting));
200 case SettingTypeNumber:
202 const CSettingNumber *mappedSetting = (const CSettingNumber *) setting;
203 CSettingNumber *floatSetting = new CSettingNumber(strKey, *mappedSetting);
206 floatSetting->SetVisible(mappedSetting->IsVisible());
207 m_settings.insert(make_pair(strKey, floatSetting));
211 case SettingTypeString:
213 const CSettingString *mappedSetting = (const CSettingString *) setting;
214 CSettingString *stringSetting = new CSettingString(strKey, *mappedSetting);
217 stringSetting->SetVisible(mappedSetting->IsVisible());
218 m_settings.insert(make_pair(strKey, stringSetting));
223 //TODO add more types if needed
229 bool CPeripheral::HasSetting(const CStdString &strKey) const
231 map<CStdString, CSetting *>:: const_iterator it = m_settings.find(strKey);
232 return it != m_settings.end();
235 bool CPeripheral::HasSettings(void) const
237 return m_settings.size() > 0;
240 bool CPeripheral::HasConfigurableSettings(void) const
243 map<CStdString, CSetting *>::const_iterator it = m_settings.begin();
244 while (it != m_settings.end() && !bReturn)
246 if ((*it).second->IsVisible())
258 bool CPeripheral::GetSettingBool(const CStdString &strKey) const
260 map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey);
261 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeBool)
263 CSettingBool *boolSetting = (CSettingBool *) (*it).second;
265 return boolSetting->GetValue();
271 int CPeripheral::GetSettingInt(const CStdString &strKey) const
273 map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey);
274 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeInteger)
276 CSettingInt *intSetting = (CSettingInt *) (*it).second;
278 return intSetting->GetValue();
284 float CPeripheral::GetSettingFloat(const CStdString &strKey) const
286 map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey);
287 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeNumber)
289 CSettingNumber *floatSetting = (CSettingNumber *) (*it).second;
291 return (float)floatSetting->GetValue();
297 const CStdString CPeripheral::GetSettingString(const CStdString &strKey) const
299 map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey);
300 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeString)
302 CSettingString *stringSetting = (CSettingString *) (*it).second;
304 return stringSetting->GetValue();
307 return StringUtils::EmptyString;
310 bool CPeripheral::SetSetting(const CStdString &strKey, bool bValue)
312 bool bChanged(false);
313 map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
314 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeBool)
316 CSettingBool *boolSetting = (CSettingBool *) (*it).second;
319 bChanged = boolSetting->GetValue() != bValue;
320 boolSetting->SetValue(bValue);
321 if (bChanged && m_bInitialised)
322 m_changedSettings.insert(strKey);
328 bool CPeripheral::SetSetting(const CStdString &strKey, int iValue)
330 bool bChanged(false);
331 map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
332 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeInteger)
334 CSettingInt *intSetting = (CSettingInt *) (*it).second;
337 bChanged = intSetting->GetValue() != iValue;
338 intSetting->SetValue(iValue);
339 if (bChanged && m_bInitialised)
340 m_changedSettings.insert(strKey);
346 bool CPeripheral::SetSetting(const CStdString &strKey, float fValue)
348 bool bChanged(false);
349 map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
350 if (it != m_settings.end() && (*it).second->GetType() == SettingTypeNumber)
352 CSettingNumber *floatSetting = (CSettingNumber *) (*it).second;
355 bChanged = floatSetting->GetValue() != fValue;
356 floatSetting->SetValue(fValue);
357 if (bChanged && m_bInitialised)
358 m_changedSettings.insert(strKey);
364 void CPeripheral::SetSettingVisible(const CStdString &strKey, bool bSetTo)
366 map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
367 if (it != m_settings.end())
368 (*it).second->SetVisible(bSetTo);
371 bool CPeripheral::IsSettingVisible(const CStdString &strKey) const
373 map<CStdString, CSetting *>::const_iterator it = m_settings.find(strKey);
374 if (it != m_settings.end())
375 return (*it).second->IsVisible();
379 bool CPeripheral::SetSetting(const CStdString &strKey, const CStdString &strValue)
381 bool bChanged(false);
382 map<CStdString, CSetting *>::iterator it = m_settings.find(strKey);
383 if (it != m_settings.end())
385 if ((*it).second->GetType() == SettingTypeString)
387 CSettingString *stringSetting = (CSettingString *) (*it).second;
390 bChanged = !StringUtils::EqualsNoCase(stringSetting->GetValue(), strValue);
391 stringSetting->SetValue(strValue);
392 if (bChanged && m_bInitialised)
393 m_changedSettings.insert(strKey);
396 else if ((*it).second->GetType() == SettingTypeInteger)
397 bChanged = SetSetting(strKey, (int) (strValue.IsEmpty() ? 0 : atoi(strValue.c_str())));
398 else if ((*it).second->GetType() == SettingTypeNumber)
399 bChanged = SetSetting(strKey, (float) (strValue.IsEmpty() ? 0 : atof(strValue.c_str())));
400 else if ((*it).second->GetType() == SettingTypeBool)
401 bChanged = SetSetting(strKey, strValue.Equals("1"));
406 void CPeripheral::PersistSettings(bool bExiting /* = false */)
409 TiXmlElement node("settings");
410 doc.InsertEndChild(node);
411 for (map<CStdString, CSetting *>::const_iterator itr = m_settings.begin(); itr != m_settings.end(); itr++)
413 TiXmlElement nodeSetting("setting");
414 nodeSetting.SetAttribute("id", itr->first.c_str());
416 switch ((*itr).second->GetType())
418 case SettingTypeString:
420 CSettingString *stringSetting = (CSettingString *) (*itr).second;
422 strValue = stringSetting->GetValue();
425 case SettingTypeInteger:
427 CSettingInt *intSetting = (CSettingInt *) (*itr).second;
429 strValue.Format("%d", intSetting->GetValue());
432 case SettingTypeNumber:
434 CSettingNumber *floatSetting = (CSettingNumber *) (*itr).second;
436 strValue.Format("%.2f", floatSetting->GetValue());
439 case SettingTypeBool:
441 CSettingBool *boolSetting = (CSettingBool *) (*itr).second;
443 strValue.Format("%d", boolSetting->GetValue() ? 1:0);
449 nodeSetting.SetAttribute("value", strValue.c_str());
450 doc.RootElement()->InsertEndChild(nodeSetting);
453 doc.SaveFile(m_strSettingsFile);
457 for (set<CStdString>::const_iterator it = m_changedSettings.begin(); it != m_changedSettings.end(); it++)
458 OnSettingChanged(*it);
460 m_changedSettings.clear();
463 void CPeripheral::LoadPersistedSettings(void)
466 if (doc.LoadFile(m_strSettingsFile))
468 const TiXmlElement *setting = doc.RootElement()->FirstChildElement("setting");
471 CStdString strId(setting->Attribute("id"));
472 CStdString strValue(setting->Attribute("value"));
473 SetSetting(strId, strValue);
475 setting = setting->NextSiblingElement("setting");
480 void CPeripheral::ResetDefaultSettings(void)
483 g_peripherals.GetSettingsFromMapping(*this);
485 map<CStdString, CSetting *>::iterator it = m_settings.begin();
486 while (it != m_settings.end())
488 m_changedSettings.insert((*it).first);
495 void CPeripheral::ClearSettings(void)
497 map<CStdString, CSetting *>::iterator it = m_settings.begin();
498 while (it != m_settings.end())
506 bool CPeripheral::operator ==(const PeripheralScanResult& right) const
508 return m_strLocation.Equals(right.m_strLocation);
511 bool CPeripheral::operator !=(const PeripheralScanResult& right) const
513 return !(*this == right);