[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / addons / interfaces / General.cpp
blobbe45ce5a41a4994bf9884205908ed8230a32686c
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "General.h"
11 #include "CompileInfo.h"
12 #include "LangInfo.h"
13 #include "ServiceBroker.h"
14 #include "addons/AddonManager.h"
15 #include "addons/AddonVersion.h"
16 #include "addons/binary-addons/AddonDll.h"
17 #include "addons/kodi-dev-kit/include/kodi/General.h"
18 #include "application/ApplicationComponents.h"
19 #include "application/ApplicationPowerHandling.h"
20 #include "dialogs/GUIDialogKaiToast.h"
21 #include "input/keyboard/KeyboardLayout.h"
22 #include "input/keyboard/KeyboardLayoutManager.h"
23 #include "settings/Settings.h"
24 #include "settings/SettingsComponent.h"
25 #include "utils/CharsetConverter.h"
26 #include "utils/Digest.h"
27 #include "utils/LangCodeExpander.h"
28 #include "utils/MemUtils.h"
29 #include "utils/StringUtils.h"
30 #include "utils/log.h"
32 #include <string.h>
34 using namespace kodi; // addon-dev-kit namespace
35 using namespace KODI;
36 using UTILITY::CDigest;
38 namespace ADDON
41 void Interface_General::Init(AddonGlobalInterface* addonInterface)
43 addonInterface->toKodi->kodi = static_cast<AddonToKodiFuncTable_kodi*>(malloc(sizeof(AddonToKodiFuncTable_kodi)));
45 addonInterface->toKodi->kodi->unknown_to_utf8 = unknown_to_utf8;
46 addonInterface->toKodi->kodi->get_language = get_language;
47 addonInterface->toKodi->kodi->queue_notification = queue_notification;
48 addonInterface->toKodi->kodi->get_md5 = get_md5;
49 addonInterface->toKodi->kodi->get_region = get_region;
50 addonInterface->toKodi->kodi->get_free_mem = get_free_mem;
51 addonInterface->toKodi->kodi->get_global_idle_time = get_global_idle_time;
52 addonInterface->toKodi->kodi->is_addon_avilable = is_addon_avilable;
53 addonInterface->toKodi->kodi->kodi_version = kodi_version;
54 addonInterface->toKodi->kodi->get_current_skin_id = get_current_skin_id;
55 addonInterface->toKodi->kodi->get_keyboard_layout = get_keyboard_layout;
56 addonInterface->toKodi->kodi->change_keyboard_layout = change_keyboard_layout;
59 void Interface_General::DeInit(AddonGlobalInterface* addonInterface)
61 if (addonInterface->toKodi && /* <-- needed as long as the old addon way is used */
62 addonInterface->toKodi->kodi)
64 free(addonInterface->toKodi->kodi);
65 addonInterface->toKodi->kodi = nullptr;
69 char* Interface_General::unknown_to_utf8(void* kodiBase, const char* source, bool* ret, bool failOnBadChar)
71 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
72 if (!addon || !source || !ret)
74 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', source='{}', ret='{}')",
75 __FUNCTION__, kodiBase, static_cast<const void*>(source), static_cast<void*>(ret));
76 return nullptr;
79 std::string string;
80 *ret = g_charsetConverter.unknownToUTF8(source, string, failOnBadChar);
81 char* buffer = strdup(string.c_str());
82 return buffer;
85 char* Interface_General::get_language(void* kodiBase, int format, bool region)
87 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
88 if (!addon)
90 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}')", __FUNCTION__,
91 kodiBase);
92 return nullptr;
95 std::string string = g_langInfo.GetEnglishLanguageName();
96 switch (format)
98 case LANG_FMT_ISO_639_1:
100 std::string langCode;
101 g_LangCodeExpander.ConvertToISO6391(string, langCode);
102 string = langCode;
103 if (region)
105 std::string region2Code;
106 g_LangCodeExpander.ConvertToISO6391(g_langInfo.GetRegionLocale(), region2Code);
107 if (!region2Code.empty())
108 string += "-" + region2Code;
110 break;
112 case LANG_FMT_ISO_639_2:
114 std::string langCode;
115 g_LangCodeExpander.ConvertToISO6392B(string, langCode);
116 string = langCode;
117 if (region)
119 std::string region3Code;
120 g_LangCodeExpander.ConvertToISO6392B(g_langInfo.GetRegionLocale(), region3Code);
121 if (!region3Code.empty())
122 string += "-" + region3Code;
124 break;
126 case LANG_FMT_ENGLISH_NAME:
127 default:
129 if (region)
130 string += "-" + g_langInfo.GetCurrentRegion();
131 break;
135 char* buffer = strdup(string.c_str());
136 return buffer;
139 bool Interface_General::queue_notification(void* kodiBase, int type, const char* header,
140 const char* message, const char* imageFile,
141 unsigned int displayTime, bool withSound,
142 unsigned int messageTime)
144 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
145 if (addon == nullptr || message == nullptr)
147 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', message='{}')",
148 __FUNCTION__, kodiBase, static_cast<const void*>(message));
149 return false;
152 std::string usedHeader;
153 if (header && strlen(header) > 0)
154 usedHeader = header;
155 else
156 usedHeader = addon->Name();
158 QueueMsg qtype = static_cast<QueueMsg>(type);
160 if (qtype != QUEUE_OWN_STYLE)
162 CGUIDialogKaiToast::eMessageType usedType;
163 switch (qtype)
165 case QueueMsg::QUEUE_WARNING:
166 usedType = CGUIDialogKaiToast::Warning;
167 withSound = true;
168 CLog::Log(LOGDEBUG, "Interface_General::{} - {} - Warning Message: '{}'", __FUNCTION__,
169 addon->Name(), message);
170 break;
171 case QueueMsg::QUEUE_ERROR:
172 usedType = CGUIDialogKaiToast::Error;
173 withSound = true;
174 CLog::Log(LOGDEBUG, "Interface_General::{} - {} - Error Message : '{}'", __FUNCTION__,
175 addon->Name(), message);
176 break;
177 case QueueMsg::QUEUE_INFO:
178 default:
179 usedType = CGUIDialogKaiToast::Info;
180 withSound = false;
181 CLog::Log(LOGDEBUG, "Interface_General::{} - {} - Info Message : '{}'", __FUNCTION__,
182 addon->Name(), message);
183 break;
186 if (imageFile && strlen(imageFile) > 0)
188 CLog::Log(LOGERROR,
189 "Interface_General::{} - To use given image file '{}' must be type value set to "
190 "'QUEUE_OWN_STYLE'",
191 __FUNCTION__, imageFile);
194 CGUIDialogKaiToast::QueueNotification(usedType, usedHeader, message, 3000, withSound);
196 else
198 CGUIDialogKaiToast::QueueNotification(imageFile, usedHeader, message, displayTime, withSound, messageTime);
200 return true;
203 void Interface_General::get_md5(void* kodiBase, const char* text, char* md5)
205 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
206 if (addon == nullptr || text == nullptr)
208 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', text='{}')",
209 __FUNCTION__, kodiBase, static_cast<const void*>(text));
210 return;
213 std::string md5Int = CDigest::Calculate(CDigest::Type::MD5, std::string(text));
214 strncpy(md5, md5Int.c_str(), 40);
217 char* Interface_General::get_region(void* kodiBase, const char* id)
219 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
220 if (addon == nullptr || id == nullptr)
222 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', id='{}')", __FUNCTION__,
223 kodiBase, static_cast<const void*>(id));
224 return nullptr;
227 std::string result;
228 if (StringUtils::CompareNoCase(id, "datelong") == 0)
230 result = g_langInfo.GetDateFormat(true);
231 StringUtils::Replace(result, "DDDD", "%A");
232 StringUtils::Replace(result, "MMMM", "%B");
233 StringUtils::Replace(result, "D", "%d");
234 StringUtils::Replace(result, "YYYY", "%Y");
236 else if (StringUtils::CompareNoCase(id, "dateshort") == 0)
238 result = g_langInfo.GetDateFormat(false);
239 StringUtils::Replace(result, "MM", "%m");
240 StringUtils::Replace(result, "DD", "%d");
241 #ifdef TARGET_WINDOWS
242 StringUtils::Replace(result, "M", "%#m");
243 StringUtils::Replace(result, "D", "%#d");
244 #else
245 StringUtils::Replace(result, "M", "%-m");
246 StringUtils::Replace(result, "D", "%-d");
247 #endif
248 StringUtils::Replace(result, "YYYY", "%Y");
250 else if (StringUtils::CompareNoCase(id, "tempunit") == 0)
251 result = g_langInfo.GetTemperatureUnitString();
252 else if (StringUtils::CompareNoCase(id, "speedunit") == 0)
253 result = g_langInfo.GetSpeedUnitString();
254 else if (StringUtils::CompareNoCase(id, "time") == 0)
256 result = g_langInfo.GetTimeFormat();
257 StringUtils::Replace(result, "H", "%H");
258 StringUtils::Replace(result, "h", "%I");
259 StringUtils::Replace(result, "mm", "%M");
260 StringUtils::Replace(result, "ss", "%S");
261 StringUtils::Replace(result, "xx", "%p");
263 else if (StringUtils::CompareNoCase(id, "meridiem") == 0)
264 result = StringUtils::Format("{}/{}", g_langInfo.GetMeridiemSymbol(MeridiemSymbolAM),
265 g_langInfo.GetMeridiemSymbol(MeridiemSymbolPM));
266 else
268 CLog::Log(LOGERROR, "Interface_General::{} - add-on '{}' requests invalid id '{}'",
269 __FUNCTION__, addon->Name(), id);
270 return nullptr;
273 char* buffer = strdup(result.c_str());
274 return buffer;
277 void Interface_General::get_free_mem(void* kodiBase, long* free, long* total, bool as_bytes)
279 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
280 if (addon == nullptr || free == nullptr || total == nullptr)
282 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', free='{}', total='{}')",
283 __FUNCTION__, kodiBase, static_cast<void*>(free), static_cast<void*>(total));
284 return;
287 KODI::MEMORY::MemoryStatus stat;
288 KODI::MEMORY::GetMemoryStatus(&stat);
289 *free = static_cast<long>(stat.availPhys);
290 *total = static_cast<long>(stat.totalPhys);
291 if (!as_bytes)
293 *free = *free / ( 1024 * 1024 );
294 *total = *total / ( 1024 * 1024 );
298 int Interface_General::get_global_idle_time(void* kodiBase)
300 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
301 if (addon == nullptr)
303 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}')", __FUNCTION__,
304 kodiBase);
305 return -1;
308 auto& components = CServiceBroker::GetAppComponents();
309 const auto appPower = components.GetComponent<CApplicationPowerHandling>();
310 return appPower->GlobalIdleTime();
313 bool Interface_General::is_addon_avilable(void* kodiBase,
314 const char* id,
315 char** version,
316 bool* enabled)
318 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
319 if (addon == nullptr || id == nullptr || version == nullptr || enabled == nullptr)
321 CLog::Log(
322 LOGERROR,
323 "Interface_General::{} - invalid data (addon='{}', id='{}', version='{}', enabled='{}')",
324 __FUNCTION__, kodiBase, static_cast<const void*>(id), static_cast<void*>(version),
325 static_cast<void*>(enabled));
326 return false;
329 AddonPtr addonInfo;
330 if (!CServiceBroker::GetAddonMgr().GetAddon(id, addonInfo, OnlyEnabled::CHOICE_NO))
331 return false;
333 *version = strdup(addonInfo->Version().asString().c_str());
334 *enabled = !CServiceBroker::GetAddonMgr().IsAddonDisabled(id);
335 return true;
338 void Interface_General::kodi_version(void* kodiBase, char** compile_name, int* major, int* minor, char** revision, char** tag, char** tagversion)
340 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
341 if (addon == nullptr || compile_name == nullptr || major == nullptr || minor == nullptr ||
342 revision == nullptr || tag == nullptr || tagversion == nullptr)
344 CLog::Log(LOGERROR,
345 "Interface_General::{} - invalid data (addon='{}', compile_name='{}', major='{}', "
346 "minor='{}', revision='{}', tag='{}', tagversion='{}')",
347 __FUNCTION__, kodiBase, static_cast<void*>(compile_name), static_cast<void*>(major),
348 static_cast<void*>(minor), static_cast<void*>(revision), static_cast<void*>(tag),
349 static_cast<void*>(tagversion));
350 return;
353 *compile_name = strdup(CCompileInfo::GetAppName());
354 *major = CCompileInfo::GetMajor();
355 *minor = CCompileInfo::GetMinor();
356 *revision = strdup(CCompileInfo::GetSCMID());
357 std::string tagStr = CCompileInfo::GetSuffix();
358 if (StringUtils::StartsWithNoCase(tagStr, "alpha"))
360 *tag = strdup("alpha");
361 *tagversion = strdup(StringUtils::Mid(tagStr, 5).c_str());
363 else if (StringUtils::StartsWithNoCase(tagStr, "beta"))
365 *tag = strdup("beta");
366 *tagversion = strdup(StringUtils::Mid(tagStr, 4).c_str());
368 else if (StringUtils::StartsWithNoCase(tagStr, "rc"))
370 *tag = strdup("releasecandidate");
371 *tagversion = strdup(StringUtils::Mid(tagStr, 2).c_str());
373 else if (tagStr.empty())
374 *tag = strdup("stable");
375 else
376 *tag = strdup("prealpha");
379 char* Interface_General::get_current_skin_id(void* kodiBase)
381 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
382 if (addon == nullptr)
384 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}')", __FUNCTION__,
385 kodiBase);
386 return nullptr;
389 return strdup(CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOOKANDFEEL_SKIN).c_str());
392 bool Interface_General::get_keyboard_layout(void* kodiBase, char** layout_name, int modifier_key, AddonKeyboardKeyTable* c_layout)
394 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
395 if (addon == nullptr || c_layout == nullptr || layout_name == nullptr)
397 CLog::Log(LOGERROR,
398 "Interface_General::{} - invalid data (addon='{}', c_layout='{}', layout_name='{}')",
399 __FUNCTION__, kodiBase, static_cast<void*>(c_layout),
400 static_cast<void*>(layout_name));
401 return false;
404 std::string activeLayout = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT);
406 KEYBOARD::CKeyboardLayout layout;
407 if (!CServiceBroker::GetKeyboardLayoutManager()->GetLayout(activeLayout, layout))
408 return false;
410 *layout_name = strdup(layout.GetName().c_str());
412 unsigned int modifiers = KEYBOARD::CKeyboardLayout::ModifierKeyNone;
413 if (modifier_key & STD_KB_MODIFIER_KEY_SHIFT)
414 modifiers |= KEYBOARD::CKeyboardLayout::ModifierKeyShift;
415 if (modifier_key & STD_KB_MODIFIER_KEY_SYMBOL)
416 modifiers |= KEYBOARD::CKeyboardLayout::ModifierKeySymbol;
418 for (unsigned int row = 0; row < STD_KB_BUTTONS_MAX_ROWS; row++)
420 for (unsigned int column = 0; column < STD_KB_BUTTONS_PER_ROW; column++)
422 std::string label = layout.GetCharAt(row, column, modifiers);
423 c_layout->keys[row][column] = strdup(label.c_str());
427 return true;
430 bool Interface_General::change_keyboard_layout(void* kodiBase, char** layout_name)
432 CAddonDll* addon = static_cast<CAddonDll*>(kodiBase);
433 if (addon == nullptr || layout_name == nullptr)
435 CLog::Log(LOGERROR, "Interface_General::{} - invalid data (addon='{}', layout_name='{}')",
436 __FUNCTION__, kodiBase, static_cast<void*>(layout_name));
437 return false;
440 std::vector<KEYBOARD::CKeyboardLayout> layouts;
441 unsigned int currentLayout = 0;
443 const KEYBOARD::KeyboardLayouts& keyboardLayouts =
444 CServiceBroker::GetKeyboardLayoutManager()->GetLayouts();
445 const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
446 std::vector<CVariant> layoutNames = settings->GetList(CSettings::SETTING_LOCALE_KEYBOARDLAYOUTS);
447 std::string activeLayout = settings->GetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT);
449 for (const auto& layoutName : layoutNames)
451 const auto keyboardLayout = keyboardLayouts.find(layoutName.asString());
452 if (keyboardLayout != keyboardLayouts.end())
454 layouts.emplace_back(keyboardLayout->second);
455 if (layoutName.asString() == activeLayout)
456 currentLayout = layouts.size() - 1;
460 currentLayout++;
461 if (currentLayout >= layouts.size())
462 currentLayout = 0;
463 KEYBOARD::CKeyboardLayout layout =
464 layouts.empty() ? KEYBOARD::CKeyboardLayout() : layouts[currentLayout];
465 CServiceBroker::GetSettingsComponent()->GetSettings()->SetString(CSettings::SETTING_LOCALE_ACTIVEKEYBOARDLAYOUT, layout.GetName());
467 *layout_name = strdup(layout.GetName().c_str());
468 return true;
471 } /* namespace ADDON */