int CGUIWindowAddonBrowser::SelectAddonID(const vector<ADDON::TYPE> &types, vector<string> &addonIDs, bool showNone /* = false */, bool showDetails /* = true */, bool multipleSelection /* = true */, bool showInstalled /* = true */, bool showInstallable /* = false */, bool showMore /* = true */) { // if we shouldn't show neither installed nor installable addons the list will be empty if (!showInstalled && !showInstallable) return 0; // can't show the "Get More" button if we already show installable addons if (showInstallable) showMore = false; CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); if (!dialog) return 0; // get rid of any invalid addon types vector<ADDON::TYPE> validTypes(types.size()); std::copy_if(types.begin(), types.end(), validTypes.begin(), [](ADDON::TYPE type) { return type != ADDON_UNKNOWN; }); if (validTypes.empty()) return 0; // get all addons to show VECADDONS addons; if (showInstalled) { for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { VECADDONS typeAddons; if (*type == ADDON_AUDIO) CAddonsDirectory::GetScriptsAndPlugins("audio", typeAddons); else if (*type == ADDON_EXECUTABLE) CAddonsDirectory::GetScriptsAndPlugins("executable", typeAddons); else if (*type == ADDON_IMAGE) CAddonsDirectory::GetScriptsAndPlugins("image", typeAddons); else if (*type == ADDON_VIDEO) CAddonsDirectory::GetScriptsAndPlugins("video", typeAddons); else CAddonMgr::Get().GetAddons(*type, typeAddons); addons.insert(addons.end(), typeAddons.begin(), typeAddons.end()); } } if (showInstallable || showMore) { VECADDONS installableAddons; CAddonDatabase database; if (database.Open() && database.GetAddons(installableAddons)) { for (ADDON::IVECADDONS addon = installableAddons.begin(); addon != installableAddons.end();) { AddonPtr pAddon = *addon; // check if the addon matches one of the provided addon types bool matchesType = false; for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (pAddon->IsType(*type)) { matchesType = true; break; } } // only show addons that match one of the provided addon types and that aren't disabled if (matchesType && !CAddonMgr::Get().IsAddonDisabled(pAddon->ID())) { // check if the addon is installed bool isInstalled = CAddonMgr::Get().IsAddonInstalled(pAddon->ID()); // check if the addon is installed or can be installed if ((showInstallable || showMore) && !isInstalled && CAddonMgr::Get().CanAddonBeInstalled(pAddon)) { ++addon; continue; } } addon = installableAddons.erase(addon); } if (showInstallable) addons.insert(addons.end(), installableAddons.begin(), installableAddons.end()); else if (showMore) showMore = !installableAddons.empty(); } } if (addons.empty() && !showNone) return 0; // turn the addons into items std::map<std::string, AddonPtr> addonMap; CFileItemList items; for (ADDON::IVECADDONS addon = addons.begin(); addon != addons.end(); ++addon) { CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addon, (*addon)->ID())); if (!items.Contains(item->GetPath())) { items.Add(item); addonMap.insert(std::make_pair(item->GetPath(), *addon)); } } if (items.IsEmpty() && !showNone) return 0; std::string heading; for (vector<ADDON::TYPE>::const_iterator type = validTypes.begin(); type != validTypes.end(); ++type) { if (!heading.empty()) heading += ", "; heading += TranslateType(*type, true); } dialog->SetHeading(CVariant{std::move(heading)}); dialog->Reset(); dialog->SetUseDetails(showDetails); if (multipleSelection) { showNone = false; showMore = false; dialog->EnableButton(true, 186); } else if (showMore) dialog->EnableButton(true, 21452); if (showNone) { CFileItemPtr item(new CFileItem("", false)); item->SetLabel(g_localizeStrings.Get(231)); item->SetLabel2(g_localizeStrings.Get(24040)); item->SetIconImage("DefaultAddonNone.png"); item->SetSpecialSort(SortSpecialOnTop); items.Add(item); } items.Sort(SortByLabel, SortOrderAscending); if (addonIDs.size() > 0) { for (vector<string>::const_iterator it = addonIDs.begin(); it != addonIDs.end() ; ++it) { CFileItemPtr item = items.Get(*it); if (item) item->Select(true); } } dialog->SetItems(&items); dialog->SetMultiSelection(multipleSelection); dialog->Open(); // if the "Get More" button has been pressed and we haven't shown the // installable addons so far show a list of installable addons if (showMore&& dialog->IsButtonPressed()) return SelectAddonID(types, addonIDs, showNone, showDetails, multipleSelection, false, true, false); if (!dialog->IsConfirmed()) return 0; addonIDs.clear(); const CFileItemList& list = dialog->GetSelectedItems(); for (int i = 0; i < list.Size(); i++) { const CFileItemPtr& item = list.Get(i); // check if one of the selected addons needs to be installed if (showInstallable) { std::map<std::string, AddonPtr>::const_iterator itAddon = addonMap.find(item->GetPath()); if (itAddon != addonMap.end()) { const AddonPtr& addon = itAddon->second; // if the addon isn't installed we need to install it if (!CAddonMgr::Get().IsAddonInstalled(addon->ID())) { AddonPtr installedAddon; if (!CAddonInstaller::Get().InstallModal(addon->ID(), installedAddon, false)) continue; } // if the addon is disabled we need to enable it if (CAddonMgr::Get().IsAddonDisabled(addon->ID())) CAddonMgr::Get().EnableAddon(addon->ID()); } } addonIDs.push_back(item->GetPath()); } return 1; }
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString path1(strPath); URIUtils::RemoveSlashAtEnd(path1); CURL path(path1); items.ClearProperties(); items.SetContent("addons"); VECADDONS addons; // get info from repository bool reposAsFolders = true; if (path.GetHostName().Equals("enabled")) { CAddonMgr::Get().GetAllAddons(addons, true); items.SetProperty("reponame",g_localizeStrings.Get(24062)); items.SetLabel(g_localizeStrings.Get(24062)); } else if (path.GetHostName().Equals("disabled")) { // grab all disabled addons, including disabled repositories reposAsFolders = false; CAddonMgr::Get().GetAllAddons(addons, false, true); items.SetProperty("reponame",g_localizeStrings.Get(24039)); items.SetLabel(g_localizeStrings.Get(24039)); } else if (path.GetHostName().Equals("outdated")) { reposAsFolders = false; CAddonMgr::Get().GetAllOutdatedAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24043)); items.SetLabel(g_localizeStrings.Get(24043)); } else if (path.GetHostName().Equals("repos")) { CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true); items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons } else if (path.GetHostName().Equals("sources")) { return GetScriptsAndPlugins(path.GetFileName(), items); } else if (path.GetHostName().Equals("all")) { CAddonDatabase database; database.Open(); database.GetAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24032)); items.SetLabel(g_localizeStrings.Get(24032)); } else if (path.GetHostName().Equals("search")) { CStdString search(path.GetFileName()); if (search.IsEmpty() && !GetKeyboardInput(16017, search)) return false; items.SetProperty("reponame",g_localizeStrings.Get(283)); items.SetLabel(g_localizeStrings.Get(283)); CAddonDatabase database; database.Open(); database.Search(search, addons); GenerateListing(path, addons, items, true); path.SetFileName(search); items.SetPath(path.Get()); return true; } else { reposAsFolders = false; AddonPtr addon; CAddonMgr::Get().GetAddon(path.GetHostName(),addon); if (!addon) return false; // ensure our repos are up to date CAddonInstaller::Get().UpdateRepos(false, true); CAddonDatabase database; database.Open(); database.GetRepository(addon->ID(),addons); items.SetProperty("reponame",addon->Name()); items.SetLabel(addon->Name()); } if (path.GetFileName().IsEmpty()) { if (!path.GetHostName().Equals("repos")) { for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i) { for (unsigned int j=0;j<addons.size();++j) { if (addons[j]->IsType((TYPE)i)) { CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true))); item->SetPath(URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false))); item->m_bIsFolder = true; CStdString thumb = GetIcon((TYPE)i); if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb)) item->SetArt("thumb", thumb); items.Add(item); break; } } } items.SetPath(strPath); return true; } } else { TYPE type = TranslateType(path.GetFileName()); items.SetProperty("addoncategory",TranslateType(type, true)); items.SetLabel(TranslateType(type, true)); items.SetPath(strPath); // FIXME: Categorisation of addons needs adding here for (unsigned int j=0;j<addons.size();++j) { if (!addons[j]->IsType(type)) addons.erase(addons.begin()+j--); } } items.SetPath(strPath); GenerateListing(path, addons, items, reposAsFolders); // check for available updates if (path.GetHostName().Equals("enabled")) { CAddonDatabase database; database.Open(); for (int i=0;i<items.Size();++i) { AddonPtr addon2; database.GetAddon(items[i]->GetProperty("Addon.ID").asString(),addon2); if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version").asString()) && !database.IsAddonBlacklisted(addon2->ID(),addon2->Version().c_str())) { items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068)); items[i]->SetProperty("Addon.UpdateAvail", true); } } } if (path.GetHostName().Equals("repos") && items.Size() > 1) { CFileItemPtr item(new CFileItem("addons://all/",true)); item->SetLabel(g_localizeStrings.Get(24032)); items.Add(item); } return true; }
bool CLangInfo::SetLanguage(bool& fallback, const std::string &strLanguage /* = "" */, bool reloadServices /* = true */) { fallback = false; std::string language = strLanguage; if (language.empty()) { language = CSettings::GetInstance().GetString(CSettings::SETTING_LOCALE_LANGUAGE); if (language.empty()) { CLog::Log(LOGFATAL, "CLangInfo: cannot load empty language."); return false; } } LanguageResourcePtr languageAddon = GetLanguageAddon(language); if (languageAddon == NULL) { CLog::Log(LOGWARNING, "CLangInfo: unable to load language \"%s\". Trying to determine matching language addon...", language.c_str()); // we may have to fall back to the default language std::string defaultLanguage = static_cast<CSettingString*>(CSettings::GetInstance().GetSetting(CSettings::SETTING_LOCALE_LANGUAGE))->GetDefault(); std::string newLanguage = defaultLanguage; // try to determine a language addon matching the given language in name if (!ADDON::CLanguageResource::FindLanguageAddonByName(language, newLanguage)) { CLog::Log(LOGWARNING, "CLangInfo: unable to find an installed language addon matching \"%s\". Trying to find an installable language...", language.c_str()); bool foundMatchingAddon = false; CAddonDatabase addondb; if (addondb.Open()) { // update the addon repositories to check if there's a matching language addon available for download CAddonInstaller::GetInstance().UpdateRepos(true, true); ADDON::VECADDONS languageAddons; if (addondb.GetAddons(languageAddons, ADDON::ADDON_RESOURCE_LANGUAGE) && !languageAddons.empty()) { // try to get the proper language addon by its name from all available language addons if (ADDON::CLanguageResource::FindLanguageAddonByName(language, newLanguage, languageAddons)) { if (CAddonInstaller::GetInstance().Install(newLanguage, true, "", false, false)) { CLog::Log(LOGINFO, "CLangInfo: successfully installed language addon \"%s\" matching current language \"%s\"", newLanguage.c_str(), language.c_str()); foundMatchingAddon = true; } else CLog::Log(LOGERROR, "CLangInfo: failed to installed language addon \"%s\" matching current language \"%s\"", newLanguage.c_str(), language.c_str()); } else CLog::Log(LOGERROR, "CLangInfo: unable to match old language \"%s\" to any available language addon", language.c_str()); } else CLog::Log(LOGERROR, "CLangInfo: no language addons available to match against \"%s\"", language.c_str()); } else CLog::Log(LOGERROR, "CLangInfo: unable to open addon database to look for a language addon matching \"%s\"", language.c_str()); // if the new language matches the default language we are loading the // default language as a fallback if (!foundMatchingAddon && newLanguage == defaultLanguage) { CLog::Log(LOGINFO, "CLangInfo: fall back to the default language \"%s\"", defaultLanguage.c_str()); fallback = true; } } if (!CSettings::GetInstance().SetString(CSettings::SETTING_LOCALE_LANGUAGE, newLanguage)) return false; CSettings::GetInstance().Save(); return true; } CLog::Log(LOGINFO, "CLangInfo: loading %s language information...", language.c_str()); if (!Load(language)) { CLog::LogF(LOGFATAL, "CLangInfo: failed to load %s language information", language.c_str()); return false; } CLog::Log(LOGINFO, "CLangInfo: loading %s language strings...", language.c_str()); if (!g_localizeStrings.Load(GetLanguagePath(), language)) { CLog::LogF(LOGFATAL, "CLangInfo: failed to load %s language strings", language.c_str()); return false; } if (reloadServices) { // also tell our weather and skin to reload as these are localized g_weatherManager.Refresh(); g_PVRManager.LocalizationChanged(); CApplicationMessenger::GetInstance().PostMsg(TMSG_EXECUTE_BUILT_IN, -1, -1, nullptr, "ReloadSkin"); } return true; }
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString path1(strPath); CUtil::RemoveSlashAtEnd(path1); CURL path(path1); items.ClearProperties(); items.SetContent("addons"); VECADDONS addons; // get info from repository bool reposAsFolders = true; if (path.GetHostName().Equals("enabled")) { CAddonMgr::Get().GetAllAddons(addons, true); items.SetProperty("reponame",g_localizeStrings.Get(24062)); } else if (path.GetHostName().Equals("disabled")) { // grab all disabled addons, including disabled repositories reposAsFolders = false; CAddonMgr::Get().GetAllAddons(addons, false, true); items.SetProperty("reponame",g_localizeStrings.Get(24039)); } else if (path.GetHostName().Equals("outdated")) { reposAsFolders = false; CAddonMgr::Get().GetAllOutdatedAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24043)); } else if (path.GetHostName().Equals("repos")) { CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true); } else if (path.GetHostName().Equals("sources")) { return GetScriptsAndPlugins(path.GetFileName(), items); } else if (path.GetHostName().Equals("all")) { CAddonDatabase database; database.Open(); database.GetAddons(addons); items.SetProperty("reponame",g_localizeStrings.Get(24032)); } else { AddonPtr addon; CAddonMgr::Get().GetAddon(path.GetHostName(),addon); if (!addon) return false; CAddonDatabase database; database.Open(); if (!database.GetRepository(addon->ID(),addons)) { RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(addon); addons = CRepositoryUpdateJob::GrabAddons(repo,false); } items.SetProperty("reponame",addon->Name()); } if (path.GetFileName().IsEmpty()) { if (!path.GetHostName().Equals("repos")) { for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i) { for (unsigned int j=0;j<addons.size();++j) { if (addons[j]->IsType((TYPE)i)) { CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true))); item->m_strPath = CUtil::AddFileToFolder(strPath,TranslateType((TYPE)i,false)); item->m_bIsFolder = true; CStdString thumb = GetIcon((TYPE)i); if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb)) item->SetThumbnailImage(thumb); items.Add(item); break; } } } items.m_strPath = strPath; return true; } } else { TYPE type = TranslateType(path.GetFileName()); items.SetProperty("addoncategory",TranslateType(type, true)); items.m_strPath = strPath; // FIXME: Categorisation of addons needs adding here for (unsigned int j=0;j<addons.size();++j) { if (!addons[j]->IsType(type)) addons.erase(addons.begin()+j--); } } items.m_strPath = strPath; GenerateListing(path, addons, items, reposAsFolders); // check for available updates if (path.GetHostName().Equals("enabled")) { CAddonDatabase database; database.Open(); for (int i=0;i<items.Size();++i) { AddonPtr addon2; database.GetAddon(items[i]->GetProperty("Addon.ID"),addon2); if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version"))) { items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068)); items[i]->SetProperty("Addon.UpdateAvail","true"); } } } if (path.GetHostName().Equals("repos") && items.Size() > 1) { CFileItemPtr item(new CFileItem("addons://all/",true)); item->SetLabel(g_localizeStrings.Get(24032)); items.Add(item); } return true; }