Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[addons] add interface callbacks to read addon settings
Some addons (also Screensaver) use own settings. With this becomes the
support added on new way to read them on addon.

Due to the big use of them is it added to the addon base interface and not
separated to another.
  • Loading branch information
AlwinEsch committed May 25, 2017
1 parent 6dc5f2f commit 2298e93
Show file tree
Hide file tree
Showing 3 changed files with 260 additions and 1 deletion.
116 changes: 116 additions & 0 deletions xbmc/addons/AddonDll.cpp
Expand Up @@ -21,6 +21,8 @@
#include "AddonDll.h"

#include "AddonStatusHandler.h"
#include "GUIUserMessages.h"
#include "addons/GUIDialogAddonSettings.h"
#include "events/EventLog.h"
#include "events/NotificationEvent.h"
#include "guilib/GUIWindowManager.h"
Expand Down Expand Up @@ -546,6 +548,8 @@ bool CAddonDll::InitInterface(KODI_HANDLE firstKodiInstance)
m_interface.toKodi.get_addon_path = get_addon_path;
m_interface.toKodi.get_base_user_path = get_base_user_path;
m_interface.toKodi.addon_log_msg = addon_log_msg;
m_interface.toKodi.get_setting = get_setting;
m_interface.toKodi.set_setting = set_setting;
m_interface.toKodi.free_string = free_string;

return true;
Expand Down Expand Up @@ -622,6 +626,118 @@ void CAddonDll::addon_log_msg(void* kodiBase, const int addonLogLevel, const cha
CLog::Log(logLevel, "AddOnLog: %s: %s", addon->Name().c_str(), strMessage);
}

bool CAddonDll::get_setting(void* kodiBase, const char* settingName, void* settingValue)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (addon == nullptr || settingName == nullptr || settingValue == nullptr)
{
CLog::Log(LOGERROR, "kodi::General::%s - invalid data (addon='%p', settingName='%p', settingValue='%p')",
__FUNCTION__, addon, settingName, settingValue);

return false;
}

CLog::Log(LOGDEBUG, "kodi::General::%s - add-on '%s' requests setting '%s'",
__FUNCTION__, addon->Name().c_str(), settingName);

if (!addon->ReloadSettings())
{
CLog::Log(LOGERROR, "kodi::General::%s - could't get settings for add-on '%s'", __FUNCTION__, addon->Name().c_str());
return false;
}

const TiXmlElement *category = addon->GetSettingsXML()->FirstChildElement("category");
if (!category) // add a default one...
category = addon->GetSettingsXML();

while (category)
{
const TiXmlElement *setting = category->FirstChildElement("setting");
while (setting)
{
const std::string id = XMLUtils::GetAttribute(setting, "id");
const std::string type = XMLUtils::GetAttribute(setting, "type");

if (id == settingName && !type.empty())
{
if (type == "text" || type == "ipaddress" ||
type == "folder" || type == "action" ||
type == "music" || type == "pictures" ||
type == "programs" || type == "fileenum" ||
type == "file" || type == "labelenum")
{
*(char**) settingValue = strdup(addon->GetSetting(id).c_str());
return true;
}
else if (type == "number" || type == "enum")
{
*(int*) settingValue = (int) atoi(addon->GetSetting(id).c_str());
return true;
}
else if (type == "bool")
{
*(bool*) settingValue = (bool) (addon->GetSetting(id) == "true" ? true : false);
return true;
}
else if (type == "slider")
{
const char *option = setting->Attribute("option");
if (option && strcmpi(option, "int") == 0)
{
*(int*) settingValue = (int) atoi(addon->GetSetting(id).c_str());
return true;
}
else
{
*(float*) settingValue = (float) atof(addon->GetSetting(id).c_str());
return true;
}
}
}
setting = setting->NextSiblingElement("setting");
}
category = category->NextSiblingElement("category");
}
CLog::Log(LOGERROR, "kodi::General::%s - can't find setting '%s' in '%s'", __FUNCTION__, settingName, addon->Name().c_str());

return false;
}

bool CAddonDll::set_setting(void* kodiBase, const char* settingName, const char* settingValue)
{
CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
if (addon == nullptr || settingName == nullptr || settingValue == nullptr)
{
CLog::Log(LOGERROR, "kodi::General::%s - invalid data (addon='%p', settingName='%p', settingValue='%p')",
__FUNCTION__, addon, settingName, settingValue);

return false;
}

bool save = true;
if (g_windowManager.IsWindowActive(WINDOW_DIALOG_ADDON_SETTINGS))
{
CGUIDialogAddonSettings* dialog = g_windowManager.GetWindow<CGUIDialogAddonSettings>(WINDOW_DIALOG_ADDON_SETTINGS);
if (dialog->GetCurrentID() == addon->ID())
{
CGUIMessage message(GUI_MSG_SETTING_UPDATED, 0, 0);
std::vector<std::string> params;
params.push_back(settingName);
params.push_back(settingValue);
message.SetStringParams(params);
g_windowManager.SendThreadMessage(message, WINDOW_DIALOG_ADDON_SETTINGS);
save=false;
}
}
if (save)
{
addon->UpdateSetting(settingName, settingValue);
addon->SaveSettings();
}

return true;
}

void CAddonDll::free_string(void* kodiBase, char* str)
{
if (str)
Expand Down
2 changes: 2 additions & 0 deletions xbmc/addons/AddonDll.h
Expand Up @@ -124,6 +124,8 @@ namespace ADDON
static char* get_addon_path(void* kodiBase);
static char* get_base_user_path(void* kodiBase);
static void addon_log_msg(void* kodiBase, const int addonLogLevel, const char* strMessage);
static bool get_setting(void* kodiBase, const char* settingName, void* settingValue);
static bool set_setting(void* kodiBase, const char* settingName, const char* settingValue);
static void free_string(void* kodiBase, char* str);
//@}
};
Expand Down
143 changes: 142 additions & 1 deletion xbmc/addons/kodi-addon-dev-kit/include/kodi/AddonBase.h
Expand Up @@ -163,10 +163,12 @@ typedef struct AddonToKodiFuncTable_Addon
KODI_HANDLE kodiBase;

// Function addresses used for callbacks from addon to Kodi
void (*free_string)(void* kodiBase, char* str);
char* (*get_addon_path)(void* kodiBase);
char* (*get_base_user_path)(void* kodiBase);
void (*addon_log_msg)(void* kodiBase, const int loglevel, const char *msg);
void (*free_string)(void* kodiBase, char* str);
bool (*get_setting)(void* kodiBase, const char* settingName, void *settingValue);
bool (*set_setting)(void* kodiBase, const char* settingName, const char* settingValue);

} AddonToKodiFuncTable_Addon;

Expand Down Expand Up @@ -406,6 +408,145 @@ inline void Log(const AddonLog loglevel, const char* format, ...)
} /* namespace kodi */
//------------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline bool CheckSettingString(const std::string& settingName, std::string& settingValue)
{
char * buffer = nullptr;
bool ret = ::kodi::addon::CAddonBase::m_interface->toKodi.get_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), &buffer);
if (buffer)
{
if (ret)
settingValue = buffer;
::kodi::addon::CAddonBase::m_interface->toKodi.free_string(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, buffer);
}
return ret;
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline std::string GetSettingString(const std::string& settingName)
{
std::string settingValue;
CheckSettingString(settingName, settingValue);
return settingValue;
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline void SetSettingString(const std::string& settingName, const std::string& settingValue)
{
::kodi::addon::CAddonBase::m_interface->toKodi.set_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), settingValue.c_str());
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline bool CheckSettingInt(const std::string& settingName, int& settingValue)
{
return ::kodi::addon::CAddonBase::m_interface->toKodi.get_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), &settingValue);
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline int GetSettingInt(const std::string& settingName)
{
int settingValue = 0;
CheckSettingInt(settingName, settingValue);
return settingValue;
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline void SetSettingInt(const std::string& settingName, int settingValue)
{
char buffer[33];
snprintf(buffer, sizeof(buffer), "%i", settingValue);
::kodi::addon::CAddonBase::m_interface->toKodi.set_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), buffer);
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline bool CheckSettingBoolean(const std::string& settingName, bool& settingValue)
{
return ::kodi::addon::CAddonBase::m_interface->toKodi.get_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), &settingValue);
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline bool GetSettingBoolean(const std::string& settingName)
{
bool settingValue = false;
CheckSettingBoolean(settingName, settingValue);
return settingValue;
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline void SetSettingBoolean(const std::string& settingName, bool settingValue)
{
::kodi::addon::CAddonBase::m_interface->toKodi.set_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), settingValue ? "true" : "false");
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline bool CheckSettingFloat(const std::string& settingName, float& settingValue)
{
return ::kodi::addon::CAddonBase::m_interface->toKodi.get_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), &settingValue);
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline float GetSettingFloat(const std::string& settingName)
{
float settingValue = 0.0f;
CheckSettingFloat(settingName, settingValue);
return settingValue;
}
} /* namespace kodi */
//----------------------------------------------------------------------------

//============================================================================
namespace kodi {
///
inline void SetSettingFloat(const std::string& settingName, float settingValue)
{
char buffer[50];
snprintf(buffer, sizeof(buffer), "%f", settingValue);
::kodi::addon::CAddonBase::m_interface->toKodi.set_setting(::kodi::addon::CAddonBase::m_interface->toKodi.kodiBase, settingName.c_str(), buffer);
}
} /* namespace kodi */
//----------------------------------------------------------------------------

/*! addon creation macro
* @todo cleanup this stupid big macro
Expand Down

0 comments on commit 2298e93

Please sign in to comment.