diff options
Diffstat (limited to 'xbmc/settings/dialogs')
-rw-r--r-- | xbmc/settings/dialogs/CMakeLists.txt | 13 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogContentSettings.cpp | 428 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogContentSettings.h | 91 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp | 452 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogLibExportSettings.h | 60 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettingsBase.cpp | 972 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettingsBase.h | 189 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp | 64 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h | 34 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettingsManualBase.cpp | 1617 | ||||
-rw-r--r-- | xbmc/settings/dialogs/GUIDialogSettingsManualBase.h | 650 |
11 files changed, 4570 insertions, 0 deletions
diff --git a/xbmc/settings/dialogs/CMakeLists.txt b/xbmc/settings/dialogs/CMakeLists.txt new file mode 100644 index 0000000..631e86c --- /dev/null +++ b/xbmc/settings/dialogs/CMakeLists.txt @@ -0,0 +1,13 @@ +set(SOURCES GUIDialogContentSettings.cpp + GUIDialogLibExportSettings.cpp + GUIDialogSettingsBase.cpp + GUIDialogSettingsManagerBase.cpp + GUIDialogSettingsManualBase.cpp) + +set(HEADERS GUIDialogContentSettings.h + GUIDialogLibExportSettings.h + GUIDialogSettingsBase.h + GUIDialogSettingsManagerBase.h + GUIDialogSettingsManualBase.h) + +core_add_library(settings_dialogs) diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.cpp b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp new file mode 100644 index 0000000..da4caf1 --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogContentSettings.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIDialogContentSettings.h" + +#include "ServiceBroker.h" +#include "addons/AddonManager.h" +#include "addons/AddonSystemSettings.h" +#include "addons/gui/GUIDialogAddonSettings.h" +#include "addons/gui/GUIWindowAddonBrowser.h" +#include "dialogs/GUIDialogKaiToast.h" +#include "dialogs/GUIDialogSelect.h" +#include "filesystem/AddonsDirectory.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "settings/lib/Setting.h" +#include "settings/lib/SettingsManager.h" +#include "settings/windows/GUIControlSettings.h" +#include "utils/log.h" +#include "video/VideoInfoScanner.h" + +#include <limits.h> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#define SETTING_CONTENT_TYPE "contenttype" +#define SETTING_SCRAPER_LIST "scraperlist" +#define SETTING_SCRAPER_SETTINGS "scrapersettings" +#define SETTING_SCAN_RECURSIVE "scanrecursive" +#define SETTING_USE_DIRECTORY_NAMES "usedirectorynames" +#define SETTING_CONTAINS_SINGLE_ITEM "containssingleitem" +#define SETTING_EXCLUDE "exclude" +#define SETTING_NO_UPDATING "noupdating" +#define SETTING_ALL_EXTERNAL_AUDIO "allexternalaudio" + +using namespace ADDON; + + +CGUIDialogContentSettings::CGUIDialogContentSettings() + : CGUIDialogSettingsManualBase(WINDOW_DIALOG_CONTENT_SETTINGS, "DialogSettings.xml") +{ } + +void CGUIDialogContentSettings::SetContent(CONTENT_TYPE content) +{ + m_content = m_originalContent = content; +} + +void CGUIDialogContentSettings::ResetContent() +{ + SetContent(CONTENT_NONE); +} + +void CGUIDialogContentSettings::SetScanSettings(const VIDEO::SScanSettings &scanSettings) +{ + m_scanRecursive = (scanSettings.recurse > 0 && !scanSettings.parent_name) || + (scanSettings.recurse > 1 && scanSettings.parent_name); + m_useDirectoryNames = scanSettings.parent_name; + m_exclude = scanSettings.exclude; + m_containsSingleItem = scanSettings.parent_name_root; + m_noUpdating = scanSettings.noupdate; + m_allExternalAudio = scanSettings.m_allExtAudio; +} + +bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr& scraper, CONTENT_TYPE content /* = CONTENT_NONE */) +{ + VIDEO::SScanSettings dummy; + return Show(scraper, dummy, content); +} + +bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr& scraper, VIDEO::SScanSettings& settings, CONTENT_TYPE content /* = CONTENT_NONE */) +{ + CGUIDialogContentSettings *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogContentSettings>(WINDOW_DIALOG_CONTENT_SETTINGS); + if (dialog == NULL) + return false; + + if (scraper != NULL) + { + dialog->SetContent(content != CONTENT_NONE ? content : scraper->Content()); + dialog->SetScraper(scraper); + // toast selected but disabled scrapers + if (CServiceBroker::GetAddonMgr().IsAddonDisabled(scraper->ID())) + CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(24024), scraper->Name(), 2000, true); + } + + dialog->SetScanSettings(settings); + dialog->Open(); + + bool confirmed = dialog->IsConfirmed(); + if (confirmed) + { + scraper = dialog->GetScraper(); + content = dialog->GetContent(); + + settings.m_allExtAudio = dialog->GetUseAllExternalAudio(); + + if (scraper == NULL || content == CONTENT_NONE) + settings.exclude = dialog->GetExclude(); + else + { + settings.exclude = false; + settings.noupdate = dialog->GetNoUpdating(); + scraper->SetPathSettings(content, ""); + + if (content == CONTENT_TVSHOWS) + { + settings.parent_name = settings.parent_name_root = dialog->GetContainsSingleItem(); + settings.recurse = 0; + } + else if (content == CONTENT_MOVIES || content == CONTENT_MUSICVIDEOS) + { + if (dialog->GetUseDirectoryNames()) + { + settings.parent_name = true; + settings.parent_name_root = false; + settings.recurse = dialog->GetScanRecursive() ? INT_MAX : 1; + + if (dialog->GetContainsSingleItem()) + { + settings.parent_name_root = true; + settings.recurse = 0; + } + } + else + { + settings.parent_name = false; + settings.parent_name_root = false; + settings.recurse = dialog->GetScanRecursive() ? INT_MAX : 0; + } + } + } + } + + // now that we have evaluated all settings we need to reset the content + dialog->ResetContent(); + + return confirmed; +} + +void CGUIDialogContentSettings::OnInitWindow() +{ + CGUIDialogSettingsManualBase::OnInitWindow(); +} + +void CGUIDialogContentSettings::OnSettingChanged(const std::shared_ptr<const CSetting>& setting) +{ + if (setting == NULL) + return; + + CGUIDialogSettingsManualBase::OnSettingChanged(setting); + + const std::string &settingId = setting->GetId(); + if (settingId == SETTING_CONTAINS_SINGLE_ITEM) + m_containsSingleItem = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + else if (settingId == SETTING_NO_UPDATING) + m_noUpdating = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + else if (settingId == SETTING_USE_DIRECTORY_NAMES) + m_useDirectoryNames = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + else if (settingId == SETTING_SCAN_RECURSIVE) + { + m_scanRecursive = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + GetSettingsManager()->SetBool(SETTING_CONTAINS_SINGLE_ITEM, false); + } + else if (settingId == SETTING_EXCLUDE) + m_exclude = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + else if (settingId == SETTING_ALL_EXTERNAL_AUDIO) + m_allExternalAudio = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); +} + +void CGUIDialogContentSettings::OnSettingAction(const std::shared_ptr<const CSetting>& setting) +{ + if (setting == NULL) + return; + + CGUIDialogSettingsManualBase::OnSettingAction(setting); + + const std::string &settingId = setting->GetId(); + + if (settingId == SETTING_CONTENT_TYPE) + { + std::vector<std::pair<std::string, int>> labels; + if (m_content == CONTENT_ALBUMS || m_content == CONTENT_ARTISTS) + { + labels.emplace_back(ADDON::TranslateContent(m_content, true), m_content); + } + else + { + labels.emplace_back(ADDON::TranslateContent(CONTENT_NONE, true), CONTENT_NONE); + labels.emplace_back(ADDON::TranslateContent(CONTENT_MOVIES, true), CONTENT_MOVIES); + labels.emplace_back(ADDON::TranslateContent(CONTENT_TVSHOWS, true), CONTENT_TVSHOWS); + labels.emplace_back(ADDON::TranslateContent(CONTENT_MUSICVIDEOS, true), CONTENT_MUSICVIDEOS); + } + std::sort(labels.begin(), labels.end()); + + CGUIDialogSelect *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT); + if (dialog) + { + dialog->SetHeading(CVariant{ 20344 }); //Label "This directory contains" + + int iIndex = 0; + int iSelected = 0; + for (const auto &label : labels) + { + dialog->Add(label.first); + + if (m_content == label.second) + iSelected = iIndex; + iIndex++; + } + + dialog->SetSelected(iSelected); + + dialog->Open(); + // Selected item has not changes - in case of cancel or the user selecting the same item + int newSelected = dialog->GetSelectedItem(); + if (!dialog->IsConfirmed() || newSelected < 0 || newSelected == iSelected) + return; + + auto selected = labels.at(newSelected); + m_content = static_cast<CONTENT_TYPE>(selected.second); + + AddonPtr scraperAddon; + if (!CAddonSystemSettings::GetInstance().GetActive(ADDON::ScraperTypeFromContent(m_content), scraperAddon) && m_content != CONTENT_NONE) + return; + + m_scraper = std::dynamic_pointer_cast<CScraper>(scraperAddon); + + SetupView(); + SetFocusToSetting(SETTING_CONTENT_TYPE); + } + } + else if (settingId == SETTING_SCRAPER_LIST) + { + ADDON::AddonType type = ADDON::ScraperTypeFromContent(m_content); + std::string currentScraperId; + if (m_scraper != nullptr) + currentScraperId = m_scraper->ID(); + std::string selectedAddonId = currentScraperId; + + if (CGUIWindowAddonBrowser::SelectAddonID(type, selectedAddonId, false) == 1 + && selectedAddonId != currentScraperId) + { + AddonPtr scraperAddon; + if (CServiceBroker::GetAddonMgr().GetAddon(selectedAddonId, scraperAddon, + ADDON::OnlyEnabled::CHOICE_YES)) + { + m_scraper = std::dynamic_pointer_cast<CScraper>(scraperAddon); + SetupView(); + SetFocusToSetting(SETTING_SCRAPER_LIST); + } + else + { + CLog::Log(LOGERROR, "{} - Could not get settings for addon: {}", __FUNCTION__, + selectedAddonId); + } + } + } + else if (settingId == SETTING_SCRAPER_SETTINGS) + CGUIDialogAddonSettings::ShowForAddon(m_scraper, false); +} + +bool CGUIDialogContentSettings::Save() +{ + //Should be saved by caller of ::Show + return true; +} + +void CGUIDialogContentSettings::SetupView() +{ + CGUIDialogSettingsManualBase::SetupView(); + SetHeading(20333); + + SET_CONTROL_HIDDEN(CONTROL_SETTINGS_CUSTOM_BUTTON); + SET_CONTROL_LABEL(CONTROL_SETTINGS_OKAY_BUTTON, 186); + SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON, 222); + + SetLabel2(SETTING_CONTENT_TYPE, ADDON::TranslateContent(m_content, true)); + + if (m_content == CONTENT_NONE) + { + ToggleState(SETTING_SCRAPER_LIST, false); + ToggleState(SETTING_SCRAPER_SETTINGS, false); + } + else + { + ToggleState(SETTING_SCRAPER_LIST, true); + if (m_scraper != NULL && !CServiceBroker::GetAddonMgr().IsAddonDisabled(m_scraper->ID())) + { + SetLabel2(SETTING_SCRAPER_LIST, m_scraper->Name()); + if (m_scraper && m_scraper->Supports(m_content) && m_scraper->HasSettings()) + ToggleState(SETTING_SCRAPER_SETTINGS, true); + else + ToggleState(SETTING_SCRAPER_SETTINGS, false); + } + else + { + SetLabel2(SETTING_SCRAPER_LIST, g_localizeStrings.Get(231)); //Set label2 to "None" + ToggleState(SETTING_SCRAPER_SETTINGS, false); + } + } +} + +void CGUIDialogContentSettings::InitializeSettings() +{ + CGUIDialogSettingsManualBase::InitializeSettings(); + + if (m_content == CONTENT_NONE) + m_showScanSettings = false; + else if (m_scraper != NULL && !CServiceBroker::GetAddonMgr().IsAddonDisabled(m_scraper->ID())) + m_showScanSettings = true; + + std::shared_ptr<CSettingCategory> category = AddCategory("contentsettings", -1); + if (category == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogContentSettings: unable to setup settings"); + return; + } + + std::shared_ptr<CSettingGroup> group = AddGroup(category); + if (group == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogContentSettings: unable to setup settings"); + return; + } + + AddButton(group, SETTING_CONTENT_TYPE, 20344, SettingLevel::Basic); + AddButton(group, SETTING_SCRAPER_LIST, 38025, SettingLevel::Basic); + std::shared_ptr<CSettingAction> subsetting = AddButton(group, SETTING_SCRAPER_SETTINGS, 10004, SettingLevel::Basic); + if (subsetting != NULL) + subsetting->SetParent(SETTING_SCRAPER_LIST); + + std::shared_ptr<CSettingGroup> groupDetails = AddGroup(category, 20322); + if (groupDetails == NULL) + { + CLog::Log(LOGERROR, "CGUIDialogContentSettings: unable to setup scanning settings"); + return; + } + switch (m_content) + { + case CONTENT_TVSHOWS: + { + AddToggle(groupDetails, SETTING_CONTAINS_SINGLE_ITEM, 20379, SettingLevel::Basic, m_containsSingleItem, false, m_showScanSettings); + AddToggle(groupDetails, SETTING_NO_UPDATING, 20432, SettingLevel::Basic, m_noUpdating, false, m_showScanSettings); + AddToggle(groupDetails, SETTING_ALL_EXTERNAL_AUDIO, 39120, SettingLevel::Basic, + m_allExternalAudio, false, m_showScanSettings); + break; + } + + case CONTENT_MOVIES: + case CONTENT_MUSICVIDEOS: + { + AddToggle(groupDetails, SETTING_USE_DIRECTORY_NAMES, m_content == CONTENT_MOVIES ? 20329 : 20330, SettingLevel::Basic, m_useDirectoryNames, false, m_showScanSettings); + std::shared_ptr<CSettingBool> settingScanRecursive = AddToggle(groupDetails, SETTING_SCAN_RECURSIVE, 20346, SettingLevel::Basic, m_scanRecursive, false, m_showScanSettings); + std::shared_ptr<CSettingBool> settingContainsSingleItem = AddToggle(groupDetails, SETTING_CONTAINS_SINGLE_ITEM, 20383, SettingLevel::Basic, m_containsSingleItem, false, m_showScanSettings); + AddToggle(groupDetails, SETTING_NO_UPDATING, 20432, SettingLevel::Basic, m_noUpdating, false, m_showScanSettings); + AddToggle(groupDetails, SETTING_ALL_EXTERNAL_AUDIO, 39120, SettingLevel::Basic, + m_allExternalAudio, false, m_showScanSettings); + + // define an enable dependency with (m_useDirectoryNames && !m_containsSingleItem) || !m_useDirectoryNames + CSettingDependency dependencyScanRecursive(SettingDependencyType::Enable, GetSettingsManager()); + dependencyScanRecursive.Or() + ->Add(CSettingDependencyConditionCombinationPtr((new CSettingDependencyConditionCombination(BooleanLogicOperationAnd, GetSettingsManager())) // m_useDirectoryNames && !m_containsSingleItem + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_USE_DIRECTORY_NAMES, "true", SettingDependencyOperator::Equals, false, GetSettingsManager()))) // m_useDirectoryNames + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_CONTAINS_SINGLE_ITEM, "false", SettingDependencyOperator::Equals, false, GetSettingsManager()))))) // !m_containsSingleItem + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_USE_DIRECTORY_NAMES, "false", SettingDependencyOperator::Equals, false, GetSettingsManager()))); // !m_useDirectoryNames + + // define an enable dependency with m_useDirectoryNames && !m_scanRecursive + CSettingDependency dependencyContainsSingleItem(SettingDependencyType::Enable, GetSettingsManager()); + dependencyContainsSingleItem.And() + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_USE_DIRECTORY_NAMES, "true", SettingDependencyOperator::Equals, false, GetSettingsManager()))) // m_useDirectoryNames + ->Add(CSettingDependencyConditionPtr(new CSettingDependencyCondition(SETTING_SCAN_RECURSIVE, "false", SettingDependencyOperator::Equals, false, GetSettingsManager()))); // !m_scanRecursive + + SettingDependencies deps; + deps.push_back(dependencyScanRecursive); + settingScanRecursive->SetDependencies(deps); + + deps.clear(); + deps.push_back(dependencyContainsSingleItem); + settingContainsSingleItem->SetDependencies(deps); + break; + } + + case CONTENT_ALBUMS: + case CONTENT_ARTISTS: + break; + + case CONTENT_NONE: + default: + AddToggle(groupDetails, SETTING_EXCLUDE, 20380, SettingLevel::Basic, m_exclude, false, !m_showScanSettings); + AddToggle(groupDetails, SETTING_ALL_EXTERNAL_AUDIO, 39120, SettingLevel::Basic, + m_allExternalAudio, false, !m_showScanSettings); + break; + } +} + +void CGUIDialogContentSettings::SetLabel2(const std::string &settingid, const std::string &label) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != NULL && settingControl->GetControl() != NULL) + SET_CONTROL_LABEL2(settingControl->GetID(), label); +} + +void CGUIDialogContentSettings::ToggleState(const std::string &settingid, bool enabled) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != NULL && settingControl->GetControl() != NULL) + { + if (enabled) + CONTROL_ENABLE(settingControl->GetID()); + else + CONTROL_DISABLE(settingControl->GetID()); + } +} + +void CGUIDialogContentSettings::SetFocusToSetting(const std::string& settingid) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != NULL && settingControl->GetControl() != NULL) + SET_CONTROL_FOCUS(settingControl->GetID(), 0); +} diff --git a/xbmc/settings/dialogs/GUIDialogContentSettings.h b/xbmc/settings/dialogs/GUIDialogContentSettings.h new file mode 100644 index 0000000..c0d7c81 --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogContentSettings.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "addons/Scraper.h" +#include "settings/dialogs/GUIDialogSettingsManualBase.h" + +#include <map> +#include <utility> + +namespace VIDEO +{ + struct SScanSettings; +} +class CFileItemList; + +class CGUIDialogContentSettings : public CGUIDialogSettingsManualBase +{ +public: + CGUIDialogContentSettings(); + + // specialization of CGUIWindow + bool HasListItems() const override { return true; } + + CONTENT_TYPE GetContent() const { return m_content; } + void SetContent(CONTENT_TYPE content); + void ResetContent(); + + const ADDON::ScraperPtr& GetScraper() const { return m_scraper; } + void SetScraper(ADDON::ScraperPtr scraper) { m_scraper = std::move(scraper); } + + void SetScanSettings(const VIDEO::SScanSettings &scanSettings); + bool GetScanRecursive() const { return m_scanRecursive; } + bool GetUseDirectoryNames() const { return m_useDirectoryNames; } + bool GetContainsSingleItem() const { return m_containsSingleItem; } + bool GetExclude() const { return m_exclude; } + bool GetNoUpdating() const { return m_noUpdating; } + bool GetUseAllExternalAudio() const { return m_allExternalAudio; } + + static bool Show(ADDON::ScraperPtr& scraper, CONTENT_TYPE content = CONTENT_NONE); + static bool Show(ADDON::ScraperPtr& scraper, VIDEO::SScanSettings& settings, CONTENT_TYPE content = CONTENT_NONE); + +protected: + // specializations of CGUIWindow + void OnInitWindow() override; + + // implementations of ISettingCallback + void OnSettingChanged(const std::shared_ptr<const CSetting>& setting) override; + void OnSettingAction(const std::shared_ptr<const CSetting>& setting) override; + + // specialization of CGUIDialogSettingsBase + bool AllowResettingSettings() const override { return false; } + bool Save() override; + void SetupView() override; + + // specialization of CGUIDialogSettingsManualBase + void InitializeSettings() override; + +private: + void SetLabel2(const std::string &settingid, const std::string &label); + void ToggleState(const std::string &settingid, bool enabled); + using CGUIDialogSettingsManualBase::SetFocus; + void SetFocusToSetting(const std::string& settingid); + + /*! + * @brief The currently selected content type + */ + CONTENT_TYPE m_content = CONTENT_NONE; + /*! + * @brief The selected content type at dialog creation + */ + CONTENT_TYPE m_originalContent = CONTENT_NONE; + /*! + * @brief The currently selected scraper + */ + ADDON::ScraperPtr m_scraper; + + bool m_showScanSettings = false; + bool m_scanRecursive = false; + bool m_useDirectoryNames = false; + bool m_containsSingleItem = false; + bool m_exclude = false; + bool m_noUpdating = false; + bool m_allExternalAudio = false; +}; diff --git a/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp new file mode 100644 index 0000000..7e88553 --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp @@ -0,0 +1,452 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIDialogLibExportSettings.h" + +#include "ServiceBroker.h" +#include "Util.h" +#include "dialogs/GUIDialogFileBrowser.h" +#include "filesystem/Directory.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "messaging/helpers/DialogHelper.h" +#include "messaging/helpers/DialogOKHelper.h" +#include "settings/SettingUtils.h" +#include "settings/Settings.h" +#include "settings/SettingsComponent.h" +#include "settings/lib/Setting.h" +#include "settings/windows/GUIControlSettings.h" +#include "storage/MediaManager.h" +#include "utils/URIUtils.h" +#include "utils/log.h" + +#include <limits.h> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +using namespace ADDON; +using namespace KODI::MESSAGING; + +using KODI::MESSAGING::HELPERS::DialogResponse; + +CGUIDialogLibExportSettings::CGUIDialogLibExportSettings() + : CGUIDialogSettingsManualBase(WINDOW_DIALOG_LIBEXPORT_SETTINGS, "DialogSettings.xml") +{ } + +bool CGUIDialogLibExportSettings::Show(CLibExportSettings& settings) +{ + CGUIDialogLibExportSettings *dialog = CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogLibExportSettings>(WINDOW_DIALOG_LIBEXPORT_SETTINGS); + if (!dialog) + return false; + + // Get current export settings from service broker + const std::shared_ptr<CSettings> pSettings = CServiceBroker::GetSettingsComponent()->GetSettings(); + dialog->m_settings.SetExportType(pSettings->GetInt(CSettings::SETTING_MUSICLIBRARY_EXPORT_FILETYPE)); + dialog->m_settings.m_strPath = pSettings->GetString(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER); + dialog->m_settings.SetItemsToExport(pSettings->GetInt(CSettings::SETTING_MUSICLIBRARY_EXPORT_ITEMS)); + dialog->m_settings.m_unscraped = pSettings->GetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_UNSCRAPED); + dialog->m_settings.m_artwork = pSettings->GetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_ARTWORK); + dialog->m_settings.m_skipnfo = pSettings->GetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO); + dialog->m_settings.m_overwrite = pSettings->GetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_OVERWRITE); + + // Ensure NFO or art output enabled when albums exported (adjust old saved settings) + if (dialog->m_settings.IsItemExported(ELIBEXPORT_ALBUMS) && (dialog->m_settings.m_skipnfo && !dialog->m_settings.m_artwork)) + dialog->m_settings.m_skipnfo = false; + + dialog->m_destinationChecked = false; + dialog->Open(); + + bool confirmed = dialog->IsConfirmed(); + if (confirmed) + { + // Return the new settings (saved by service broker but avoids re-reading) + settings = dialog->m_settings; + } + return confirmed; +} + +void CGUIDialogLibExportSettings::OnInitWindow() +{ + CGUIDialogSettingsManualBase::OnInitWindow(); +} + +void CGUIDialogLibExportSettings::OnSettingChanged(const std::shared_ptr<const CSetting>& setting) +{ + if (!setting) + return; + + CGUIDialogSettingsManualBase::OnSettingChanged(setting); + + const std::string &settingId = setting->GetId(); + + if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_FILETYPE) + { + m_settings.SetExportType(std::static_pointer_cast<const CSettingInt>(setting)->GetValue()); + SetupView(); + SetFocus(CSettings::SETTING_MUSICLIBRARY_EXPORT_FILETYPE); + } + else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER) + { + m_settings.m_strPath = std::static_pointer_cast<const CSettingString>(setting)->GetValue(); + UpdateButtons(); + } + else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_OVERWRITE) + m_settings.m_overwrite = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_ITEMS) + { + m_settings.SetItemsToExport(GetExportItemsFromSetting(setting)); + if (m_settings.IsItemExported(ELIBEXPORT_ALBUMS) && (m_settings.m_skipnfo && !m_settings.m_artwork)) + { + m_settings.m_skipnfo = false; + m_settingNFO->SetValue(true); + UpdateToggles(); + } + UpdateDescription(); + } + else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_ARTWORK) + { + m_settings.m_artwork = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + if (m_settings.IsItemExported(ELIBEXPORT_ALBUMS) && (m_settings.m_skipnfo && !m_settings.m_artwork)) + { + m_settings.m_skipnfo = false; + m_settingNFO->SetValue(true); + } + UpdateToggles(); + } + else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_UNSCRAPED) + m_settings.m_unscraped = std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + else if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO) + { + m_settings.m_skipnfo = !std::static_pointer_cast<const CSettingBool>(setting)->GetValue(); + if (m_settings.IsItemExported(ELIBEXPORT_ALBUMS) && (m_settings.m_skipnfo && !m_settings.m_artwork)) + { + m_settings.m_artwork = true; + m_settingArt->SetValue(true); + } + UpdateToggles(); + } +} + +void CGUIDialogLibExportSettings::OnSettingAction(const std::shared_ptr<const CSetting>& setting) +{ + if (setting == NULL) + return; + + CGUIDialogSettingsManualBase::OnSettingAction(setting); + + const std::string &settingId = setting->GetId(); + + if (settingId == CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER && !m_settings.IsToLibFolders() && + !m_settings.IsArtistFoldersOnly()) + { + VECSOURCES shares; + CServiceBroker::GetMediaManager().GetLocalDrives(shares); + CServiceBroker::GetMediaManager().GetNetworkLocations(shares); + CServiceBroker::GetMediaManager().GetRemovableDrives(shares); + std::string strDirectory = m_settings.m_strPath; + if (!strDirectory.empty()) + { + URIUtils::AddSlashAtEnd(strDirectory); + bool bIsSource; + if (CUtil::GetMatchingSource(strDirectory, shares, bIsSource) < 0) // path is outside shares - add it as a separate one + { + CMediaSource share; + share.strName = g_localizeStrings.Get(13278); + share.strPath = strDirectory; + shares.push_back(share); + } + } + else + strDirectory = "default location"; + + if (CGUIDialogFileBrowser::ShowAndGetDirectory(shares, g_localizeStrings.Get(661), strDirectory, true)) + { + if (!strDirectory.empty()) + { + m_destinationChecked = true; + m_settings.m_strPath = strDirectory; + SetLabel2(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, strDirectory); + SetFocus(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER); + } + } + UpdateButtons(); + } +} + +bool CGUIDialogLibExportSettings::OnMessage(CGUIMessage& message) +{ + switch (message.GetMessage()) + { + case GUI_MSG_CLICKED: + { + int iControl = message.GetSenderId(); + if (iControl == CONTROL_SETTINGS_OKAY_BUTTON) + { + OnOK(); + return true; + } + } + break; + } + return CGUIDialogSettingsManualBase::OnMessage(message); +} + +void CGUIDialogLibExportSettings::OnOK() +{ + // Validate destination folder + if (m_settings.IsToLibFolders() || m_settings.IsArtistFoldersOnly()) + { + // Check artist info folder setting + std::string path = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_MUSICLIBRARY_ARTISTSFOLDER); + if (path.empty()) + { + //"Unable to export to library folders as the system artist information folder setting is empty" + //Settings (YES) button takes user to enter the artist info folder setting + if (HELPERS::ShowYesNoDialogText(20223, 38317, 186, 10004) == DialogResponse::CHOICE_YES) + { + m_confirmed = false; + Close(); + CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_SETTINGS_MEDIA, CSettings::SETTING_MUSICLIBRARY_ARTISTSFOLDER); + } + return; + } + } + else if (!m_destinationChecked) + { + // ELIBEXPORT_SINGLEFILE or LIBEXPORT_SEPARATEFILES + // Check that destination folder exists + if (!XFILE::CDirectory::Exists(m_settings.m_strPath)) + { + HELPERS::ShowOKDialogText(CVariant{ 38300 }, CVariant{ 38318 }); + return; + } + } + m_confirmed = true; + Save(); + Close(); +} + +bool CGUIDialogLibExportSettings::Save() +{ + CLog::Log(LOGINFO, "CGUIDialogMusicExportSettings: Save() called"); + const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings(); + settings->SetInt(CSettings::SETTING_MUSICLIBRARY_EXPORT_FILETYPE, m_settings.GetExportType()); + settings->SetString(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, m_settings.m_strPath); + settings->SetInt(CSettings::SETTING_MUSICLIBRARY_EXPORT_ITEMS, m_settings.GetItemsToExport()); + settings->SetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_UNSCRAPED, m_settings.m_unscraped); + settings->SetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_OVERWRITE, m_settings.m_overwrite); + settings->SetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_ARTWORK, m_settings.m_artwork); + settings->SetBool(CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO, m_settings.m_skipnfo); + settings->Save(); + + return true; +} + +void CGUIDialogLibExportSettings::SetupView() +{ + CGUIDialogSettingsManualBase::SetupView(); + SetHeading(38300); + + SET_CONTROL_HIDDEN(CONTROL_SETTINGS_CUSTOM_BUTTON); + SET_CONTROL_LABEL(CONTROL_SETTINGS_OKAY_BUTTON, 38319); + SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON, 222); + + UpdateButtons(); + UpdateToggles(); + UpdateDescription(); +} + +void CGUIDialogLibExportSettings::UpdateButtons() +{ + // Enable Export button when destination folder has a path (but may not exist) + bool enableExport(true); + if (m_settings.IsSingleFile() || + m_settings.IsSeparateFiles()) + enableExport = !m_settings.m_strPath.empty(); + + CONTROL_ENABLE_ON_CONDITION(CONTROL_SETTINGS_OKAY_BUTTON, enableExport); + if (!enableExport) + SetFocus(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER); +} + +void CGUIDialogLibExportSettings::UpdateToggles() +{ + if (m_settings.IsSeparateFiles()) + ToggleState(CSettings::SETTING_MUSICLIBRARY_EXPORT_UNSCRAPED, !m_settings.m_skipnfo); + + if (!m_settings.IsItemExported(ELIBEXPORT_ALBUMS) && m_settings.m_skipnfo && !m_settings.m_artwork) + { + //"Output information to NFO files (currently exporting artist folders only)" + SetLabel(CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO, g_localizeStrings.Get(38310)); + ToggleState(CSettings::SETTING_MUSICLIBRARY_EXPORT_OVERWRITE, false); + } + else + { + //"Output information to NFO files" + SetLabel(CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO, g_localizeStrings.Get(38309)); + ToggleState(CSettings::SETTING_MUSICLIBRARY_EXPORT_OVERWRITE, true); + } +} + +void CGUIDialogLibExportSettings::UpdateDescription() +{ + if (m_settings.IsToLibFolders()) + { + // Destination button is description of what to library means + SetLabel(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, ""); + if (m_settings.IsItemExported(ELIBEXPORT_ALBUMS)) + if (m_settings.IsArtists()) + //"Artists exported to Artist Information Folder and albums to music folders" + SetLabel2(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, g_localizeStrings.Get(38322)); + else + //"Albums exported to music folders" + SetLabel2(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, g_localizeStrings.Get(38323)); + else + // "Artists exported to Artist Information Folder" + SetLabel2(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, g_localizeStrings.Get(38324)); + } + else if (m_settings.IsArtistFoldersOnly()) + { + // Destination button is description of what artist folders means + SetLabel(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, ""); + //"Artists folders created in Artist Information Folder" + SetLabel2(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, g_localizeStrings.Get(38325)); + } + else + { + SetLabel2(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, m_settings.m_strPath); + SetLabel(CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, g_localizeStrings.Get(38305)); + } +} + +void CGUIDialogLibExportSettings::InitializeSettings() +{ + CGUIDialogSettingsManualBase::InitializeSettings(); + + std::shared_ptr<CSettingCategory> category = AddCategory("exportsettings", -1); + if (!category) + { + CLog::Log(LOGERROR, "CGUIDialogLibExportSettings: unable to setup settings"); + return; + } + + std::shared_ptr<CSettingGroup> groupDetails = AddGroup(category); + if (!groupDetails) + { + CLog::Log(LOGERROR, "CGUIDialogLibExportSettings: unable to setup settings"); + return; + } + + TranslatableIntegerSettingOptions entries; + + entries.push_back(TranslatableIntegerSettingOption(38301, ELIBEXPORT_SINGLEFILE)); + entries.push_back(TranslatableIntegerSettingOption(38303, ELIBEXPORT_TOLIBRARYFOLDER)); + entries.push_back(TranslatableIntegerSettingOption(38302, ELIBEXPORT_SEPARATEFILES)); + entries.push_back(TranslatableIntegerSettingOption(38321, ELIBEXPORT_ARTISTFOLDERS)); + AddList(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_FILETYPE, 38304, SettingLevel::Basic, m_settings.GetExportType(), entries, 38304); // "Choose kind of export output" + AddButton(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_FOLDER, 38305, SettingLevel::Basic); + + entries.clear(); + if (!m_settings.IsArtistFoldersOnly()) + entries.push_back(TranslatableIntegerSettingOption(132, ELIBEXPORT_ALBUMS)); //ablums + if (m_settings.IsSingleFile()) + entries.push_back(TranslatableIntegerSettingOption(134, ELIBEXPORT_SONGS)); //songs + entries.push_back( + TranslatableIntegerSettingOption(38043, ELIBEXPORT_ALBUMARTISTS)); //album artists + entries.push_back(TranslatableIntegerSettingOption(38312, ELIBEXPORT_SONGARTISTS)); //song artists + entries.push_back( + TranslatableIntegerSettingOption(38313, ELIBEXPORT_OTHERARTISTS)); //other artists + + std::vector<int> items; + if (m_settings.IsArtistFoldersOnly()) + { + // Only artists, not albums, at least album artists + items = m_settings.GetLimitedItems(ELIBEXPORT_ALBUMARTISTS + ELIBEXPORT_SONGARTISTS + ELIBEXPORT_OTHERARTISTS); + if (items.size() == 0) + items.emplace_back(ELIBEXPORT_ALBUMARTISTS); + } + else if (!m_settings.IsSingleFile()) + { + // No songs unless single file export, at least album artists + items = m_settings.GetLimitedItems(ELIBEXPORT_ALBUMS + ELIBEXPORT_ALBUMARTISTS + ELIBEXPORT_SONGARTISTS + ELIBEXPORT_OTHERARTISTS); + if (items.size() == 0) + items.emplace_back(ELIBEXPORT_ALBUMARTISTS); + } + else + items = m_settings.GetExportItems(); + + AddList(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_ITEMS, 38306, SettingLevel::Basic, items, entries, 133, 1); + + if (m_settings.IsToLibFolders() || m_settings.IsSeparateFiles()) + { + m_settingNFO = AddToggle(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_SKIPNFO, 38309, SettingLevel::Basic, !m_settings.m_skipnfo); + if (m_settings.IsSeparateFiles()) + AddToggle(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_UNSCRAPED, 38308, SettingLevel::Basic, m_settings.m_unscraped); + m_settingArt = AddToggle(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_ARTWORK, 38307, SettingLevel::Basic, m_settings.m_artwork); + AddToggle(groupDetails, CSettings::SETTING_MUSICLIBRARY_EXPORT_OVERWRITE, 38311, SettingLevel::Basic, m_settings.m_overwrite); + } +} + +void CGUIDialogLibExportSettings::SetLabel2(const std::string &settingid, const std::string &label) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != nullptr && settingControl->GetControl() != nullptr) + SET_CONTROL_LABEL2(settingControl->GetID(), label); +} + +void CGUIDialogLibExportSettings::SetLabel(const std::string &settingid, const std::string &label) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != nullptr && settingControl->GetControl() != nullptr) + SetControlLabel(settingControl->GetID(), label); +} + +void CGUIDialogLibExportSettings::ToggleState(const std::string & settingid, bool enabled) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != nullptr && settingControl->GetControl() != nullptr) + { + if (enabled) + CONTROL_ENABLE(settingControl->GetID()); + else + CONTROL_DISABLE(settingControl->GetID()); + } +} + +void CGUIDialogLibExportSettings::SetFocus(const std::string &settingid) +{ + BaseSettingControlPtr settingControl = GetSettingControl(settingid); + if (settingControl != NULL && settingControl->GetControl() != NULL) + SET_CONTROL_FOCUS(settingControl->GetID(), 0); +} + +int CGUIDialogLibExportSettings::GetExportItemsFromSetting(const SettingConstPtr& setting) +{ + std::shared_ptr<const CSettingList> settingList = std::static_pointer_cast<const CSettingList>(setting); + if (settingList->GetElementType() != SettingType::Integer) + { + CLog::Log(LOGERROR, "CGUIDialogLibExportSettings::{} - wrong items element type", __FUNCTION__); + return 0; + } + int exportitems = 0; + std::vector<CVariant> list = CSettingUtils::GetList(settingList); + for (const auto &value : list) + { + if (!value.isInteger()) + { + CLog::Log(LOGERROR, "CGUIDialogLibExportSettings::{} - wrong items value type", __FUNCTION__); + return 0; + } + exportitems += static_cast<int>(value.asInteger()); + } + return exportitems; +} diff --git a/xbmc/settings/dialogs/GUIDialogLibExportSettings.h b/xbmc/settings/dialogs/GUIDialogLibExportSettings.h new file mode 100644 index 0000000..4c861ba --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogLibExportSettings.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2017-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "settings/LibExportSettings.h" +#include "settings/dialogs/GUIDialogSettingsManualBase.h" + +#include <map> + +class CGUIDialogLibExportSettings : public CGUIDialogSettingsManualBase +{ +public: + CGUIDialogLibExportSettings(); + + // specialization of CGUIWindow + bool HasListItems() const override { return true; } + static bool Show(CLibExportSettings& settings); + +protected: + // specializations of CGUIWindow + void OnInitWindow() override; + + // implementations of ISettingCallback + void OnSettingChanged(const std::shared_ptr<const CSetting>& setting) override; + void OnSettingAction(const std::shared_ptr<const CSetting>& setting) override; + + // specialization of CGUIDialogSettingsBase + bool OnMessage(CGUIMessage& message) override; + bool AllowResettingSettings() const override { return false; } + bool Save() override; + void SetupView() override; + + // specialization of CGUIDialogSettingsManualBase + void InitializeSettings() override; + + void OnOK(); + void UpdateButtons(); + +private: + void SetLabel2(const std::string &settingid, const std::string &label); + void SetLabel(const std::string &settingid, const std::string &label); + void ToggleState(const std::string &settingid, bool enabled); + + using CGUIDialogSettingsManualBase::SetFocus; + void SetFocus(const std::string &settingid); + static int GetExportItemsFromSetting(const SettingConstPtr& setting); + void UpdateToggles(); + void UpdateDescription(); + + CLibExportSettings m_settings; + bool m_destinationChecked = false; + std::shared_ptr<CSettingBool> m_settingNFO; + std::shared_ptr<CSettingBool> m_settingArt; +}; diff --git a/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp b/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp new file mode 100644 index 0000000..32d3958 --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogSettingsBase.cpp @@ -0,0 +1,972 @@ +/* + * Copyright (C) 2014-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIDialogSettingsBase.h" + +#include "GUIUserMessages.h" +#include "ServiceBroker.h" +#include "dialogs/GUIDialogYesNo.h" +#include "guilib/GUIColorButtonControl.h" +#include "guilib/GUIComponent.h" +#include "guilib/GUIControlGroupList.h" +#include "guilib/GUIEditControl.h" +#include "guilib/GUIImage.h" +#include "guilib/GUILabelControl.h" +#include "guilib/GUIRadioButtonControl.h" +#include "guilib/GUISettingsSliderControl.h" +#include "guilib/GUISpinControlEx.h" +#include "guilib/GUIToggleButtonControl.h" +#include "guilib/GUIWindowManager.h" +#include "guilib/LocalizeStrings.h" +#include "input/Key.h" +#include "settings/SettingControl.h" +#include "settings/lib/SettingSection.h" +#include "settings/windows/GUIControlSettings.h" +#include "utils/StringUtils.h" +#include "utils/Variant.h" + +#include <set> +#include <string> +#include <vector> + +#if defined(TARGET_WINDOWS) // disable 4355: 'this' used in base member initializer list +#pragma warning(push) +#pragma warning(disable : 4355) +#endif // defined(TARGET_WINDOWS) + +#define CATEGORY_GROUP_ID 3 +#define SETTINGS_GROUP_ID 5 + +#define CONTROL_DEFAULT_BUTTON 7 +#define CONTROL_DEFAULT_RADIOBUTTON 8 +#define CONTROL_DEFAULT_SPIN 9 +#define CONTROL_DEFAULT_CATEGORY_BUTTON 10 +#define CONTROL_DEFAULT_SEPARATOR 11 +#define CONTROL_DEFAULT_EDIT 12 +#define CONTROL_DEFAULT_SLIDER 13 +#define CONTROL_DEFAULT_SETTING_LABEL 14 +#define CONTROL_DEFAULT_COLORBUTTON 15 + +CGUIDialogSettingsBase::CGUIDialogSettingsBase(int windowId, const std::string& xmlFile) + : CGUIDialog(windowId, xmlFile), + m_iSetting(0), + m_iCategory(0), + m_resetSetting(NULL), + m_dummyCategory(NULL), + m_pOriginalSpin(NULL), + m_pOriginalSlider(NULL), + m_pOriginalRadioButton(NULL), + m_pOriginalColorButton(nullptr), + m_pOriginalCategoryButton(NULL), + m_pOriginalButton(NULL), + m_pOriginalEdit(NULL), + m_pOriginalImage(NULL), + m_pOriginalGroupTitle(NULL), + m_newOriginalEdit(false), + m_delayedTimer(this), + m_confirmed(false), + m_focusedControl(0), + m_fadedControl(0) +{ + m_loadType = KEEP_IN_MEMORY; +} + +CGUIDialogSettingsBase::~CGUIDialogSettingsBase() +{ + FreeControls(); + DeleteControls(); +} + +bool CGUIDialogSettingsBase::OnMessage(CGUIMessage& message) +{ + switch (message.GetMessage()) + { + case GUI_MSG_WINDOW_INIT: + { + m_delayedSetting.reset(); + if (message.GetParam1() != WINDOW_INVALID) + { // coming to this window first time (ie not returning back from some other window) + // so we reset our section and control states + m_iCategory = 0; + ResetControlStates(); + } + + if (AllowResettingSettings()) + { + m_resetSetting = std::make_shared<CSettingAction>(SETTINGS_RESET_SETTING_ID); + m_resetSetting->SetLabel(10041); + m_resetSetting->SetHelp(10045); + m_resetSetting->SetControl(CreateControl("button")); + } + + m_dummyCategory = std::make_shared<CSettingCategory>(SETTINGS_EMPTY_CATEGORY_ID); + m_dummyCategory->SetLabel(10046); + m_dummyCategory->SetHelp(10047); + break; + } + + case GUI_MSG_WINDOW_DEINIT: + { + // cancel any delayed changes + if (m_delayedSetting != NULL) + { + m_delayedTimer.Stop(); + CGUIMessage message(GUI_MSG_UPDATE_ITEM, GetID(), m_delayedSetting->GetID()); + OnMessage(message); + } + + CGUIDialog::OnMessage(message); + FreeControls(); + return true; + } + + case GUI_MSG_FOCUSED: + { + CGUIDialog::OnMessage(message); + m_focusedControl = GetFocusedControlID(); + + // cancel any delayed changes + if (m_delayedSetting != NULL && m_delayedSetting->GetID() != m_focusedControl) + { + m_delayedTimer.Stop(); + // param1 = 1 for "reset the control if it's invalid" + CGUIMessage message(GUI_MSG_UPDATE_ITEM, GetID(), m_delayedSetting->GetID(), 1); + CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(message, GetID()); + } + // update the value of the previous setting (in case it was invalid) + else if (m_iSetting >= CONTROL_SETTINGS_START_CONTROL && + m_iSetting < (int)(CONTROL_SETTINGS_START_CONTROL + m_settingControls.size())) + { + BaseSettingControlPtr control = GetSettingControl(m_iSetting); + if (control != NULL && control->GetSetting() != NULL && !control->IsValid()) + { + // param1 = 1 for "reset the control if it's invalid" + // param2 = 1 for "only update the current value" + CGUIMessage message(GUI_MSG_UPDATE_ITEM, GetID(), m_iSetting, 1, 1); + CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(message, GetID()); + } + } + + CVariant description; + + // check if we have changed the category and need to create new setting controls + if (m_focusedControl >= CONTROL_SETTINGS_START_BUTTONS && + m_focusedControl < (int)(CONTROL_SETTINGS_START_BUTTONS + m_categories.size())) + { + int categoryIndex = m_focusedControl - CONTROL_SETTINGS_START_BUTTONS; + SettingCategoryPtr category = m_categories.at(categoryIndex); + if (categoryIndex != m_iCategory) + { + if (!category->CanAccess()) + { + // unable to go to this category - focus the previous one + SET_CONTROL_FOCUS(CONTROL_SETTINGS_START_BUTTONS + m_iCategory, 0); + return false; + } + + m_iCategory = categoryIndex; + CreateSettings(); + } + + description = category->GetHelp(); + } + else if (m_focusedControl >= CONTROL_SETTINGS_START_CONTROL && + m_focusedControl < (int)(CONTROL_SETTINGS_START_CONTROL + m_settingControls.size())) + { + m_iSetting = m_focusedControl; + std::shared_ptr<CSetting> setting = GetSettingControl(m_focusedControl)->GetSetting(); + if (setting != NULL) + description = setting->GetHelp(); + } + + // set the description of the currently focused category/setting + if (description.isInteger() || (description.isString() && !description.empty())) + SetDescription(description); + + return true; + } + + case GUI_MSG_CLICKED: + { + int iControl = message.GetSenderId(); + if (iControl == CONTROL_SETTINGS_OKAY_BUTTON) + { + if (OnOkay()) + { + Close(); + return true; + } + + return false; + } + + if (iControl == CONTROL_SETTINGS_CANCEL_BUTTON) + { + OnCancel(); + Close(); + return true; + } + + BaseSettingControlPtr control = GetSettingControl(iControl); + if (control != NULL) + OnClick(control); + + break; + } + + case GUI_MSG_UPDATE_ITEM: + { + if (m_delayedSetting != NULL && m_delayedSetting->GetID() == message.GetControlId()) + { + // first get the delayed setting and reset its member variable + // to avoid handling the delayed setting twice in case the OnClick() + // performed later causes the window to be deinitialized (e.g. when + // changing the language) + BaseSettingControlPtr delayedSetting = m_delayedSetting; + m_delayedSetting.reset(); + + // if updating the setting fails and param1 has been specifically set + // we need to call OnSettingChanged() to restore a valid value in the + // setting control + if (!delayedSetting->OnClick() && message.GetParam1() != 0) + OnSettingChanged(delayedSetting->GetSetting()); + return true; + } + + if (message.GetControlId() >= CONTROL_SETTINGS_START_CONTROL && + message.GetControlId() < (int)(CONTROL_SETTINGS_START_CONTROL + m_settingControls.size())) + { + BaseSettingControlPtr settingControl = GetSettingControl(message.GetControlId()); + if (settingControl.get() != NULL && settingControl->GetSetting() != NULL) + { + settingControl->UpdateFromSetting(message.GetParam2() != 0); + return true; + } + } + break; + } + + case GUI_MSG_UPDATE: + { + if (IsActive() && HasID(message.GetSenderId())) + { + int focusedControl = GetFocusedControlID(); + CreateSettings(); + SET_CONTROL_FOCUS(focusedControl, 0); + } + break; + } + + default: + break; + } + + return CGUIDialog::OnMessage(message); +} + +bool CGUIDialogSettingsBase::OnAction(const CAction& action) +{ + switch (action.GetID()) + { + case ACTION_SETTINGS_RESET: + { + OnResetSettings(); + return true; + } + + case ACTION_DELETE_ITEM: + { + if (m_iSetting >= CONTROL_SETTINGS_START_CONTROL && + m_iSetting < (int)(CONTROL_SETTINGS_START_CONTROL + m_settingControls.size())) + { + auto settingControl = GetSettingControl(m_iSetting); + if (settingControl != nullptr) + { + std::shared_ptr<CSetting> setting = settingControl->GetSetting(); + if (setting != nullptr) + { + setting->Reset(); + return true; + } + } + } + break; + } + + default: + break; + } + + return CGUIDialog::OnAction(action); +} + +bool CGUIDialogSettingsBase::OnBack(int actionID) +{ + m_lastControlID = 0; // don't save the control as we go to a different window each time + + // if the setting dialog is not a window but a dialog we need to close differently + if (!IsDialog()) + return CGUIWindow::OnBack(actionID); + + return CGUIDialog::OnBack(actionID); +} + +void CGUIDialogSettingsBase::DoProcess(unsigned int currentTime, CDirtyRegionList& dirtyregions) +{ + // update alpha status of current button + CGUIControl* control = GetFirstFocusableControl(CONTROL_SETTINGS_START_BUTTONS + m_iCategory); + if (control) + { + if (m_fadedControl && + (m_fadedControl != control->GetID() || m_fadedControl == m_focusedControl)) + { + if (control->GetControlType() == CGUIControl::GUICONTROL_BUTTON) + static_cast<CGUIButtonControl*>(control)->SetAlpha(0xFF); + else + static_cast<CGUIButtonControl*>(control)->SetSelected(false); + m_fadedControl = 0; + } + + if (!control->HasFocus()) + { + m_fadedControl = control->GetID(); + if (control->GetControlType() == CGUIControl::GUICONTROL_BUTTON) + static_cast<CGUIButtonControl*>(control)->SetAlpha(0x80); + else if (control->GetControlType() == CGUIControl::GUICONTROL_TOGGLEBUTTON) + static_cast<CGUIButtonControl*>(control)->SetSelected(true); + else + m_fadedControl = 0; + + if (m_fadedControl) + control->SetFocus(true); + } + } + CGUIDialog::DoProcess(currentTime, dirtyregions); +} + +void CGUIDialogSettingsBase::OnInitWindow() +{ + m_confirmed = false; + SetupView(); + CGUIDialog::OnInitWindow(); +} + +void CGUIDialogSettingsBase::SetupControls(bool createSettings /* = true */) +{ + // cleanup first, if necessary + FreeControls(); + + // get all controls + m_pOriginalSpin = dynamic_cast<CGUISpinControlEx*>(GetControl(CONTROL_DEFAULT_SPIN)); + m_pOriginalSlider = dynamic_cast<CGUISettingsSliderControl*>(GetControl(CONTROL_DEFAULT_SLIDER)); + m_pOriginalRadioButton = + dynamic_cast<CGUIRadioButtonControl*>(GetControl(CONTROL_DEFAULT_RADIOBUTTON)); + m_pOriginalCategoryButton = + dynamic_cast<CGUIButtonControl*>(GetControl(CONTROL_DEFAULT_CATEGORY_BUTTON)); + m_pOriginalButton = dynamic_cast<CGUIButtonControl*>(GetControl(CONTROL_DEFAULT_BUTTON)); + m_pOriginalImage = dynamic_cast<CGUIImage*>(GetControl(CONTROL_DEFAULT_SEPARATOR)); + m_pOriginalEdit = dynamic_cast<CGUIEditControl*>(GetControl(CONTROL_DEFAULT_EDIT)); + m_pOriginalGroupTitle = + dynamic_cast<CGUILabelControl*>(GetControl(CONTROL_DEFAULT_SETTING_LABEL)); + m_pOriginalColorButton = + dynamic_cast<CGUIColorButtonControl*>(GetControl(CONTROL_DEFAULT_COLORBUTTON)); + + // if there's no edit control but there's a button control use that instead + if (m_pOriginalEdit == nullptr && m_pOriginalButton != nullptr) + { + m_pOriginalEdit = new CGUIEditControl(*m_pOriginalButton); + m_newOriginalEdit = true; + } + + // hide all default controls by default + if (m_pOriginalSpin != nullptr) + m_pOriginalSpin->SetVisible(false); + if (m_pOriginalSlider != nullptr) + m_pOriginalSlider->SetVisible(false); + if (m_pOriginalRadioButton != nullptr) + m_pOriginalRadioButton->SetVisible(false); + if (m_pOriginalButton != nullptr) + m_pOriginalButton->SetVisible(false); + if (m_pOriginalCategoryButton != nullptr) + m_pOriginalCategoryButton->SetVisible(false); + if (m_pOriginalEdit != nullptr) + m_pOriginalEdit->SetVisible(false); + if (m_pOriginalImage != nullptr) + m_pOriginalImage->SetVisible(false); + if (m_pOriginalGroupTitle != nullptr) + m_pOriginalGroupTitle->SetVisible(false); + if (m_pOriginalColorButton != nullptr) + m_pOriginalColorButton->SetVisible(false); + + // get the section + SettingSectionPtr section = GetSection(); + if (section == NULL) + return; + + // update the screen string + if (section->GetLabel() >= 0) + SetHeading(section->GetLabel()); + + // get the categories we need + m_categories = section->GetCategories((SettingLevel)GetSettingLevel()); + if (m_categories.empty()) + m_categories.push_back(m_dummyCategory); + + if (m_pOriginalCategoryButton != NULL) + { + // setup our control groups... + CGUIControlGroupList* group = + dynamic_cast<CGUIControlGroupList*>(GetControl(CATEGORY_GROUP_ID)); + if (!group) + return; + + // go through the categories and create the necessary buttons + int buttonIdOffset = 0; + for (SettingCategoryList::const_iterator category = m_categories.begin(); + category != m_categories.end(); ++category) + { + CGUIButtonControl* pButton = NULL; + if (m_pOriginalCategoryButton->GetControlType() == CGUIControl::GUICONTROL_TOGGLEBUTTON) + pButton = new CGUIToggleButtonControl( + *static_cast<CGUIToggleButtonControl*>(m_pOriginalCategoryButton)); + else if (m_pOriginalCategoryButton->GetControlType() == CGUIControl::GUICONTROL_COLORBUTTON) + pButton = new CGUIColorButtonControl( + *static_cast<CGUIColorButtonControl*>(m_pOriginalCategoryButton)); + else + pButton = new CGUIButtonControl(*m_pOriginalCategoryButton); + pButton->SetLabel(GetSettingsLabel(*category)); + pButton->SetID(CONTROL_SETTINGS_START_BUTTONS + buttonIdOffset); + pButton->SetVisible(true); + pButton->AllocResources(); + + group->AddControl(pButton); + buttonIdOffset++; + } + } + + if (createSettings) + CreateSettings(); + + // set focus correctly depending on whether there are categories visible or not + if (m_pOriginalCategoryButton == NULL && + (m_defaultControl <= 0 || m_defaultControl == CATEGORY_GROUP_ID)) + m_defaultControl = SETTINGS_GROUP_ID; + else if (m_pOriginalCategoryButton != NULL && m_defaultControl <= 0) + m_defaultControl = CATEGORY_GROUP_ID; +} + +void CGUIDialogSettingsBase::FreeControls() +{ + // clear the category group + CGUIControlGroupList* control = + dynamic_cast<CGUIControlGroupList*>(GetControl(CATEGORY_GROUP_ID)); + if (control) + { + control->FreeResources(); + control->ClearAll(); + } + m_categories.clear(); + FreeSettingsControls(); +} + +void CGUIDialogSettingsBase::DeleteControls() +{ + if (m_newOriginalEdit) + { + delete m_pOriginalEdit; + m_pOriginalEdit = NULL; + } + + m_resetSetting.reset(); + m_dummyCategory.reset(); +} + +void CGUIDialogSettingsBase::FreeSettingsControls() +{ + // clear the settings group + CGUIControlGroupList* control = + dynamic_cast<CGUIControlGroupList*>(GetControl(SETTINGS_GROUP_ID)); + if (control) + { + control->FreeResources(); + control->ClearAll(); + } + + for (std::vector<BaseSettingControlPtr>::iterator control = m_settingControls.begin(); + control != m_settingControls.end(); ++control) + (*control)->Clear(); + + m_settingControls.clear(); +} + +void CGUIDialogSettingsBase::OnTimeout() +{ + UpdateSettingControl(m_delayedSetting, true); +} + +void CGUIDialogSettingsBase::OnSettingChanged(const std::shared_ptr<const CSetting>& setting) +{ + if (setting == NULL || setting->GetType() == SettingType::Unknown || + setting->GetType() == SettingType::Action) + return; + + UpdateSettingControl(setting->GetId(), true); +} + +void CGUIDialogSettingsBase::OnSettingPropertyChanged( + const std::shared_ptr<const CSetting>& setting, const char* propertyName) +{ + if (setting == NULL || propertyName == NULL) + return; + + UpdateSettingControl(setting->GetId()); +} + +std::string CGUIDialogSettingsBase::GetLocalizedString(uint32_t labelId) const +{ + return g_localizeStrings.Get(labelId); +} + +void CGUIDialogSettingsBase::SetupView() +{ + SetupControls(); +} + +std::set<std::string> CGUIDialogSettingsBase::CreateSettings() +{ + FreeSettingsControls(); + + std::set<std::string> settingMap; + + if (m_categories.size() <= 0) + return settingMap; + + if (m_iCategory < 0 || m_iCategory >= (int)m_categories.size()) + m_iCategory = 0; + + CGUIControlGroupList* group = dynamic_cast<CGUIControlGroupList*>(GetControl(SETTINGS_GROUP_ID)); + if (group == NULL) + return settingMap; + + SettingCategoryPtr category = m_categories.at(m_iCategory); + if (category == NULL) + return settingMap; + + // set the description of the current category + SetDescription(category->GetHelp()); + + const SettingGroupList& groups = category->GetGroups((SettingLevel)GetSettingLevel()); + int iControlID = CONTROL_SETTINGS_START_CONTROL; + bool first = true; + for (SettingGroupList::const_iterator groupIt = groups.begin(); groupIt != groups.end(); + ++groupIt) + { + if (*groupIt == NULL) + continue; + + const SettingList& settings = (*groupIt)->GetSettings((SettingLevel)GetSettingLevel()); + if (settings.size() <= 0) + continue; + + std::shared_ptr<const CSettingControlTitle> title = + std::dynamic_pointer_cast<const CSettingControlTitle>((*groupIt)->GetControl()); + bool hideSeparator = title ? title->IsSeparatorHidden() : false; + bool separatorBelowGroupLabel = title ? title->IsSeparatorBelowLabel() : false; + int groupLabel = (*groupIt)->GetLabel(); + + // hide the separator for the first settings grouplist if it + // is the very first item in the list (also above the label) + if (first) + { + first = false; + if (groupLabel <= 0) + hideSeparator = true; + } + else if (!separatorBelowGroupLabel && !hideSeparator) + AddSeparator(group->GetWidth(), iControlID); + + if (groupLabel > 0) + AddGroupLabel(*groupIt, group->GetWidth(), iControlID); + + if (separatorBelowGroupLabel && !hideSeparator) + AddSeparator(group->GetWidth(), iControlID); + + for (SettingList::const_iterator settingIt = settings.begin(); settingIt != settings.end(); + ++settingIt) + { + const std::shared_ptr<CSetting>& pSetting = *settingIt; + settingMap.insert(pSetting->GetId()); + AddSetting(pSetting, group->GetWidth(), iControlID); + } + } + + if (AllowResettingSettings() && !settingMap.empty()) + { + // add "Reset" control + AddSeparator(group->GetWidth(), iControlID); + AddSetting(m_resetSetting, group->GetWidth(), iControlID); + } + + // update our settings (turns controls on/off as appropriate) + UpdateSettings(); + + group->SetInvalid(); + + return settingMap; +} + +std::string CGUIDialogSettingsBase::GetSettingsLabel(const std::shared_ptr<ISetting>& pSetting) +{ + return GetLocalizedString(pSetting->GetLabel()); +} + +void CGUIDialogSettingsBase::UpdateSettings() +{ + for (std::vector<BaseSettingControlPtr>::iterator it = m_settingControls.begin(); + it != m_settingControls.end(); ++it) + { + BaseSettingControlPtr pSettingControl = *it; + std::shared_ptr<CSetting> pSetting = pSettingControl->GetSetting(); + CGUIControl* pControl = pSettingControl->GetControl(); + if (pSetting == NULL || pControl == NULL) + continue; + + pSettingControl->UpdateFromSetting(); + } +} + +CGUIControl* CGUIDialogSettingsBase::AddSetting(const std::shared_ptr<CSetting>& pSetting, + float width, + int& iControlID) +{ + if (pSetting == NULL) + return NULL; + + BaseSettingControlPtr pSettingControl; + CGUIControl* pControl = NULL; + + // determine the label and any possible indentation in case of sub settings + std::string label = GetSettingsLabel(pSetting); + int parentLevels = 0; + std::shared_ptr<CSetting> parentSetting = GetSetting(pSetting->GetParent()); + while (parentSetting != NULL) + { + parentLevels++; + parentSetting = GetSetting(parentSetting->GetParent()); + } + + if (parentLevels > 0) + { + // add additional 2 spaces indentation for anything past one level + std::string indentation; + for (int index = 1; index < parentLevels; index++) + indentation.append(" "); + label = StringUtils::Format(g_localizeStrings.Get(168), indentation, label); + } + + // create the proper controls + if (!pSetting->GetControl()) + return NULL; + + std::string controlType = pSetting->GetControl()->GetType(); + if (controlType == "toggle") + { + if (m_pOriginalRadioButton != NULL) + pControl = m_pOriginalRadioButton->Clone(); + if (pControl == NULL) + return NULL; + + static_cast<CGUIRadioButtonControl*>(pControl)->SetLabel(label); + pSettingControl.reset(new CGUIControlRadioButtonSetting( + static_cast<CGUIRadioButtonControl*>(pControl), iControlID, pSetting, this)); + } + else if (controlType == "spinner") + { + if (m_pOriginalSpin != NULL) + pControl = new CGUISpinControlEx(*m_pOriginalSpin); + if (pControl == NULL) + return NULL; + + static_cast<CGUISpinControlEx*>(pControl)->SetText(label); + pSettingControl.reset(new CGUIControlSpinExSetting(static_cast<CGUISpinControlEx*>(pControl), + iControlID, pSetting, this)); + } + else if (controlType == "edit") + { + if (m_pOriginalEdit != NULL) + pControl = new CGUIEditControl(*m_pOriginalEdit); + if (pControl == NULL) + return NULL; + + static_cast<CGUIEditControl*>(pControl)->SetLabel(label); + pSettingControl.reset(new CGUIControlEditSetting(static_cast<CGUIEditControl*>(pControl), + iControlID, pSetting, this)); + } + else if (controlType == "list") + { + if (m_pOriginalButton != NULL) + pControl = new CGUIButtonControl(*m_pOriginalButton); + if (pControl == NULL) + return NULL; + + static_cast<CGUIButtonControl*>(pControl)->SetLabel(label); + pSettingControl.reset(new CGUIControlListSetting(static_cast<CGUIButtonControl*>(pControl), + iControlID, pSetting, this)); + } + else if (controlType == "button" || controlType == "slider") + { + if (controlType == "button" || + std::static_pointer_cast<const CSettingControlSlider>(pSetting->GetControl())->UsePopup()) + { + if (m_pOriginalButton != NULL) + pControl = new CGUIButtonControl(*m_pOriginalButton); + if (pControl == NULL) + return NULL; + + static_cast<CGUIButtonControl*>(pControl)->SetLabel(label); + pSettingControl.reset(new CGUIControlButtonSetting(static_cast<CGUIButtonControl*>(pControl), + iControlID, pSetting, this)); + } + else + { + if (m_pOriginalSlider != NULL) + pControl = m_pOriginalSlider->Clone(); + if (pControl == NULL) + return NULL; + + static_cast<CGUISettingsSliderControl*>(pControl)->SetText(label); + pSettingControl.reset(new CGUIControlSliderSetting( + static_cast<CGUISettingsSliderControl*>(pControl), iControlID, pSetting, this)); + } + } + else if (controlType == "range") + { + if (m_pOriginalSlider != NULL) + pControl = m_pOriginalSlider->Clone(); + if (pControl == NULL) + return NULL; + + static_cast<CGUISettingsSliderControl*>(pControl)->SetText(label); + pSettingControl.reset(new CGUIControlRangeSetting( + static_cast<CGUISettingsSliderControl*>(pControl), iControlID, pSetting, this)); + } + else if (controlType == "label") + { + if (m_pOriginalButton != NULL) + pControl = new CGUIButtonControl(*m_pOriginalButton); + if (pControl == NULL) + return NULL; + + static_cast<CGUIButtonControl*>(pControl)->SetLabel(label); + pSettingControl.reset(new CGUIControlLabelSetting(static_cast<CGUIButtonControl*>(pControl), + iControlID, pSetting, this)); + } + else if (controlType == "colorbutton") + { + if (m_pOriginalColorButton) + pControl = m_pOriginalColorButton->Clone(); + if (pControl == nullptr) + return nullptr; + + static_cast<CGUIColorButtonControl*>(pControl)->SetLabel(label); + pSettingControl.reset(new CGUIControlColorButtonSetting( + static_cast<CGUIColorButtonControl*>(pControl), iControlID, pSetting, this)); + } + else + return nullptr; + + if (pSetting->GetControl()->GetDelayed()) + pSettingControl->SetDelayed(); + + return AddSettingControl(pControl, pSettingControl, width, iControlID); +} + +CGUIControl* CGUIDialogSettingsBase::AddSeparator(float width, int& iControlID) +{ + if (m_pOriginalImage == NULL) + return NULL; + + CGUIControl* pControl = new CGUIImage(*m_pOriginalImage); + if (pControl == NULL) + return NULL; + + return AddSettingControl(pControl, + BaseSettingControlPtr(new CGUIControlSeparatorSetting( + static_cast<CGUIImage*>(pControl), iControlID, this)), + width, iControlID); +} + +CGUIControl* CGUIDialogSettingsBase::AddGroupLabel(const std::shared_ptr<CSettingGroup>& group, + float width, + int& iControlID) +{ + if (m_pOriginalGroupTitle == NULL) + return NULL; + + CGUIControl* pControl = new CGUILabelControl(*m_pOriginalGroupTitle); + if (pControl == NULL) + return NULL; + + static_cast<CGUILabelControl*>(pControl)->SetLabel(GetSettingsLabel(group)); + + return AddSettingControl(pControl, + BaseSettingControlPtr(new CGUIControlGroupTitleSetting( + static_cast<CGUILabelControl*>(pControl), iControlID, this)), + width, iControlID); +} + +CGUIControl* CGUIDialogSettingsBase::AddSettingControl(CGUIControl* pControl, + BaseSettingControlPtr pSettingControl, + float width, + int& iControlID) +{ + if (pControl == NULL) + { + pSettingControl.reset(); + return NULL; + } + + pControl->SetID(iControlID++); + pControl->SetVisible(true); + pControl->SetWidth(width); + + CGUIControlGroupList* group = dynamic_cast<CGUIControlGroupList*>(GetControl(SETTINGS_GROUP_ID)); + if (group != NULL) + { + pControl->AllocResources(); + group->AddControl(pControl); + } + m_settingControls.push_back(pSettingControl); + + return pControl; +} + +void CGUIDialogSettingsBase::SetHeading(const CVariant& label) +{ + SetControlLabel(CONTROL_SETTINGS_LABEL, label); +} + +void CGUIDialogSettingsBase::SetDescription(const CVariant& label) +{ + SetControlLabel(CONTROL_SETTINGS_DESCRIPTION, label); +} + +void CGUIDialogSettingsBase::OnResetSettings() +{ + if (CGUIDialogYesNo::ShowAndGetInput(CVariant{10041}, CVariant{10042})) + { + for (std::vector<BaseSettingControlPtr>::iterator it = m_settingControls.begin(); + it != m_settingControls.end(); ++it) + { + std::shared_ptr<CSetting> setting = (*it)->GetSetting(); + if (setting != NULL) + setting->Reset(); + } + } +} + +void CGUIDialogSettingsBase::OnClick(const BaseSettingControlPtr& pSettingControl) +{ + if (AllowResettingSettings() && + pSettingControl->GetSetting()->GetId() == SETTINGS_RESET_SETTING_ID) + { + OnAction(CAction(ACTION_SETTINGS_RESET)); + return; + } + + // we need to first set the delayed setting and then execute OnClick() + // because OnClick() triggers OnSettingChanged() and there we need to + // know if the changed setting is delayed or not + if (pSettingControl->IsDelayed()) + { + m_delayedSetting = pSettingControl; + // for some controls we need to update its displayed data/text before + // OnClick() is called after the delay timer has expired because + // otherwise the displayed value of the control does not match with + // the user's interaction + pSettingControl->UpdateFromControl(); + + // either start or restart the delay timer which will result in a call to + // the control's OnClick() method to update the setting's value + if (m_delayedTimer.IsRunning()) + m_delayedTimer.Restart(); + else + m_delayedTimer.Start(GetDelayMs()); + + return; + } + + // if changing the setting fails + // we need to restore the proper state + if (!pSettingControl->OnClick()) + pSettingControl->UpdateFromSetting(); +} + +void CGUIDialogSettingsBase::UpdateSettingControl(const std::string& settingId, + bool updateDisplayOnly /* = false */) +{ + if (settingId.empty()) + return; + + return UpdateSettingControl(GetSettingControl(settingId), updateDisplayOnly); +} + +void CGUIDialogSettingsBase::UpdateSettingControl(const BaseSettingControlPtr& pSettingControl, + bool updateDisplayOnly /* = false */) +{ + if (pSettingControl == NULL) + return; + + // we send a thread message so that it's processed the following frame (some settings won't + // like being changed during Render()) + // param2 = 1 for "only update the current value" + CGUIMessage message(GUI_MSG_UPDATE_ITEM, GetID(), pSettingControl->GetID(), 0, + updateDisplayOnly ? 1 : 0); + CServiceBroker::GetGUI()->GetWindowManager().SendThreadMessage(message, GetID()); +} + +void CGUIDialogSettingsBase::SetControlLabel(int controlId, const CVariant& label) +{ + if (GetControl(controlId) == NULL) + return; + + if (label.isString()) + SET_CONTROL_LABEL(controlId, label.asString()); + else if (label.isInteger() && label.asInteger() >= 0) + { + int labelId = static_cast<uint32_t>(label.asInteger()); + std::string localizedString = GetLocalizedString(labelId); + if (!localizedString.empty()) + SET_CONTROL_LABEL(controlId, localizedString); + else + SET_CONTROL_LABEL(controlId, labelId); + } + else + SET_CONTROL_LABEL(controlId, ""); +} + +BaseSettingControlPtr CGUIDialogSettingsBase::GetSettingControl(const std::string& strSetting) +{ + for (std::vector<BaseSettingControlPtr>::iterator control = m_settingControls.begin(); + control != m_settingControls.end(); ++control) + { + if ((*control)->GetSetting() != NULL && (*control)->GetSetting()->GetId() == strSetting) + return *control; + } + + return BaseSettingControlPtr(); +} + +BaseSettingControlPtr CGUIDialogSettingsBase::GetSettingControl(int controlId) +{ + if (controlId < CONTROL_SETTINGS_START_CONTROL || + controlId >= (int)(CONTROL_SETTINGS_START_CONTROL + m_settingControls.size())) + return BaseSettingControlPtr(); + + return m_settingControls[controlId - CONTROL_SETTINGS_START_CONTROL]; +} diff --git a/xbmc/settings/dialogs/GUIDialogSettingsBase.h b/xbmc/settings/dialogs/GUIDialogSettingsBase.h new file mode 100644 index 0000000..a633c65 --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogSettingsBase.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2014-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "guilib/GUIDialog.h" +#include "settings/SettingControl.h" +#include "settings/lib/ISettingCallback.h" +#include "threads/Timer.h" +#include "utils/ILocalizer.h" + +#include <set> +#include <vector> + +#define CONTROL_SETTINGS_LABEL 2 +#define CONTROL_SETTINGS_DESCRIPTION 6 + +#define CONTROL_SETTINGS_OKAY_BUTTON 28 +#define CONTROL_SETTINGS_CANCEL_BUTTON 29 +#define CONTROL_SETTINGS_CUSTOM_BUTTON 30 + +#define CONTROL_SETTINGS_START_BUTTONS -100 +#define CONTROL_SETTINGS_START_CONTROL -80 + +#define SETTINGS_RESET_SETTING_ID "settings.reset" +#define SETTINGS_EMPTY_CATEGORY_ID "categories.empty" + +class CGUIControl; +class CGUIControlBaseSetting; +class CGUIImage; +class CGUISpinControlEx; +class CGUIEditControl; +class CGUIButtonControl; +class CGUIRadioButtonControl; +class CGUISettingsSliderControl; +class CGUILabelControl; +class CGUIColorButtonControl; + +class CSetting; +class CSettingAction; +class CSettingCategory; +class CSettingGroup; +class CSettingSection; + +class CVariant; + +class ISetting; + +typedef std::shared_ptr<CGUIControlBaseSetting> BaseSettingControlPtr; + +class CGUIDialogSettingsBase : public CGUIDialog, + public CSettingControlCreator, + public ILocalizer, + protected ITimerCallback, + protected ISettingCallback +{ +public: + CGUIDialogSettingsBase(int windowId, const std::string& xmlFile); + ~CGUIDialogSettingsBase() override; + + // specializations of CGUIControl + bool OnMessage(CGUIMessage& message) override; + bool OnAction(const CAction& action) override; + bool OnBack(int actionID) override; + void DoProcess(unsigned int currentTime, CDirtyRegionList& dirtyregions) override; + + virtual bool IsConfirmed() const { return m_confirmed; } + + // implementation of ILocalizer + std::string Localize(std::uint32_t code) const override { return GetLocalizedString(code); } + +protected: + // specializations of CGUIWindow + void OnInitWindow() override; + + // implementations of ITimerCallback + void OnTimeout() override; + + // implementations of ISettingCallback + void OnSettingChanged(const std::shared_ptr<const CSetting>& setting) override; + void OnSettingPropertyChanged(const std::shared_ptr<const CSetting>& setting, + const char* propertyName) override; + + // new virtual methods + virtual bool AllowResettingSettings() const { return true; } + virtual int GetSettingLevel() const { return 0; } + virtual std::shared_ptr<CSettingSection> GetSection() = 0; + virtual std::shared_ptr<CSetting> GetSetting(const std::string& settingId) = 0; + virtual std::chrono::milliseconds GetDelayMs() const { return std::chrono::milliseconds(1500); } + virtual std::string GetLocalizedString(uint32_t labelId) const; + + virtual bool OnOkay() + { + m_confirmed = true; + return true; + } + virtual void OnCancel() {} + + virtual void SetupView(); + virtual std::set<std::string> CreateSettings(); + virtual void UpdateSettings(); + + /*! + \brief Get the name for the setting entry + + Used as virtual to allow related settings dialog to give a std::string name of the setting. + If not used on own dialog class it handle the string from int CSetting::GetLabel(), + This must also be used if on related dialog no special entry is wanted. + + \param pSetting Base settings class which need the name + \return Name used on settings dialog + */ + virtual std::string GetSettingsLabel(const std::shared_ptr<ISetting>& pSetting); + + virtual CGUIControl* AddSetting(const std::shared_ptr<CSetting>& pSetting, + float width, + int& iControlID); + virtual CGUIControl* AddSettingControl(CGUIControl* pControl, + BaseSettingControlPtr pSettingControl, + float width, + int& iControlID); + + virtual void SetupControls(bool createSettings = true); + virtual void FreeControls(); + virtual void DeleteControls(); + virtual void FreeSettingsControls(); + + virtual void SetHeading(const CVariant& label); + virtual void SetDescription(const CVariant& label); + + virtual void OnResetSettings(); + + /*! + \brief A setting control has been interacted with by the user + + This method is called when the user manually interacts (clicks, + edits) with a setting control. It contains handling for both + delayed and undelayed settings and either starts the delay timer + or triggers the setting change which, on success, results in a + callback to OnSettingChanged(). + + \param pSettingControl Setting control that has been interacted with + */ + virtual void OnClick(const BaseSettingControlPtr& pSettingControl); + + void UpdateSettingControl(const std::string& settingId, bool updateDisplayOnly = false); + void UpdateSettingControl(const BaseSettingControlPtr& pSettingControl, + bool updateDisplayOnly = false); + void SetControlLabel(int controlId, const CVariant& label); + + BaseSettingControlPtr GetSettingControl(const std::string& setting); + BaseSettingControlPtr GetSettingControl(int controlId); + + CGUIControl* AddSeparator(float width, int& iControlID); + CGUIControl* AddGroupLabel(const std::shared_ptr<CSettingGroup>& group, + float width, + int& iControlID); + + std::vector<std::shared_ptr<CSettingCategory>> m_categories; + std::vector<BaseSettingControlPtr> m_settingControls; + + int m_iSetting; + int m_iCategory; + std::shared_ptr<CSettingAction> m_resetSetting; + std::shared_ptr<CSettingCategory> m_dummyCategory; + + CGUISpinControlEx* m_pOriginalSpin; + CGUISettingsSliderControl* m_pOriginalSlider; + CGUIRadioButtonControl* m_pOriginalRadioButton; + CGUIColorButtonControl* m_pOriginalColorButton; + CGUIButtonControl* m_pOriginalCategoryButton; + CGUIButtonControl* m_pOriginalButton; + CGUIEditControl* m_pOriginalEdit; + CGUIImage* m_pOriginalImage; + CGUILabelControl* m_pOriginalGroupTitle; + bool m_newOriginalEdit; + + BaseSettingControlPtr + m_delayedSetting; ///< Current delayed setting \sa CBaseSettingControl::SetDelayed() + CTimer m_delayedTimer; ///< Delayed setting timer + + bool m_confirmed; + int m_focusedControl, m_fadedControl; +}; diff --git a/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp new file mode 100644 index 0000000..e01edfb --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIDialogSettingsManagerBase.h" + +#include "settings/lib/SettingsManager.h" + +#include <cassert> + +CGUIDialogSettingsManagerBase::CGUIDialogSettingsManagerBase(int windowId, const std::string &xmlFile) + : CGUIDialogSettingsBase(windowId, xmlFile) +{ } + +CGUIDialogSettingsManagerBase::~CGUIDialogSettingsManagerBase() = default; + +std::shared_ptr<CSetting> CGUIDialogSettingsManagerBase::GetSetting(const std::string &settingId) +{ + assert(GetSettingsManager() != nullptr); + + return GetSettingsManager()->GetSetting(settingId); +} + +bool CGUIDialogSettingsManagerBase::OnOkay() +{ + if (Save()) + { + CGUIDialogSettingsBase::OnOkay(); + return true; + } + + return false; +} + +std::set<std::string> CGUIDialogSettingsManagerBase::CreateSettings() +{ + assert(GetSettingsManager() != nullptr); + + std::set<std::string> settings = CGUIDialogSettingsBase::CreateSettings(); + + if (!settings.empty()) + GetSettingsManager()->RegisterCallback(this, settings); + + return settings; +} + +void CGUIDialogSettingsManagerBase::FreeSettingsControls() +{ + CGUIDialogSettingsBase::FreeSettingsControls(); + + if (GetSettingsManager() != nullptr) + GetSettingsManager()->UnregisterCallback(this); +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManagerBase::CreateControl(const std::string &controlType) const +{ + assert(GetSettingsManager() != nullptr); + + return GetSettingsManager()->CreateControl(controlType); +} diff --git a/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h new file mode 100644 index 0000000..42c3c31 --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "settings/dialogs/GUIDialogSettingsBase.h" + +class CSettingsManager; + +class CGUIDialogSettingsManagerBase : public CGUIDialogSettingsBase +{ +public: + CGUIDialogSettingsManagerBase(int windowId, const std::string &xmlFile); + ~CGUIDialogSettingsManagerBase() override; + +protected: + virtual bool Save() = 0; + virtual CSettingsManager* GetSettingsManager() const = 0; + + // implementation of CGUIDialogSettingsBase + std::shared_ptr<CSetting> GetSetting(const std::string &settingId) override; + bool OnOkay() override; + + std::set<std::string> CreateSettings() override; + void FreeSettingsControls() override; + + // implementation of ISettingControlCreator + std::shared_ptr<ISettingControl> CreateControl(const std::string &controlType) const override; +}; diff --git a/xbmc/settings/dialogs/GUIDialogSettingsManualBase.cpp b/xbmc/settings/dialogs/GUIDialogSettingsManualBase.cpp new file mode 100644 index 0000000..84114db --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogSettingsManualBase.cpp @@ -0,0 +1,1617 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIDialogSettingsManualBase.h" + +#include "settings/SettingAddon.h" +#include "settings/SettingDateTime.h" +#include "settings/SettingPath.h" +#include "settings/SettingUtils.h" +#include "settings/lib/Setting.h" +#include "settings/lib/SettingSection.h" +#include "settings/lib/SettingsManager.h" +#include "utils/StringUtils.h" +#include "utils/Variant.h" + +#include <string> +#include <vector> + +CGUIDialogSettingsManualBase::CGUIDialogSettingsManualBase(int windowId, const std::string &xmlFile) + : CGUIDialogSettingsManagerBase(windowId, xmlFile) + , m_settingsManager(nullptr) +{ } + +CGUIDialogSettingsManualBase::~CGUIDialogSettingsManualBase() +{ + if (GetSettingsManager() != nullptr) + { + GetSettingsManager()->Clear(); + m_section = nullptr; + delete GetSettingsManager(); + } +} + +void CGUIDialogSettingsManualBase::SetupView() +{ + InitializeSettings(); + + if (GetSettingsManager() != nullptr) + { + // add the created setting section to the settings manager and mark it as ready + GetSettingsManager()->AddSection(m_section); + GetSettingsManager()->SetInitialized(); + GetSettingsManager()->SetLoaded(); + } + + CGUIDialogSettingsBase::SetupView(); +} + +CSettingsManager* CGUIDialogSettingsManualBase::GetSettingsManager() const +{ + if (m_settingsManager == nullptr) + m_settingsManager = new CSettingsManager(); + + return m_settingsManager; +} + +void CGUIDialogSettingsManualBase::InitializeSettings() +{ + if (GetSettingsManager() != nullptr) + { + GetSettingsManager()->Clear(); + m_section = NULL; + + // create a std::make_shared<section + m_section = std::make_shared<CSettingSection>(GetProperty("xmlfile").asString(), GetSettingsManager()); + } +} + +SettingCategoryPtr CGUIDialogSettingsManualBase::AddCategory(const std::string &id, int label, int help /* = -1 */) +{ + if (id.empty()) + return NULL; + + SettingCategoryPtr category = std::make_shared<CSettingCategory>(id, GetSettingsManager()); + if (category == NULL) + return NULL; + + category->SetLabel(label); + if (help >= 0) + category->SetHelp(help); + + m_section->AddCategory(category); + return category; +} + +SettingGroupPtr CGUIDialogSettingsManualBase::AddGroup(const SettingCategoryPtr& category, + int label /* = -1 */, + int help /* = -1 */, + bool separatorBelowLabel /* = true */, + bool hideSeparator /* = false */) +{ + if (category == NULL) + return NULL; + + size_t groups = category->GetGroups().size(); + + SettingGroupPtr group = std::make_shared<CSettingGroup>(StringUtils::Format("{0}", groups + 1), GetSettingsManager()); + if (group == NULL) + return NULL; + + if (label >= 0) + group->SetLabel(label); + if (help >= 0) + group->SetHelp(help); + group->SetControl(GetTitleControl(separatorBelowLabel, hideSeparator)); + + category->AddGroup(group); + return group; +} + +std::shared_ptr<CSettingBool> CGUIDialogSettingsManualBase::AddToggle(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + bool value, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingBool> setting = std::make_shared<CSettingBool>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetCheckmarkControl(delayed)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddEdit( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int minimum /* = 0 */, + int step /* = 1 */, + int maximum /* = 0 */, + bool verifyNewValue /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, minimum, step, maximum, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetEditControl("integer", delayed, false, verifyNewValue, heading)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingNumber> CGUIDialogSettingsManualBase::AddEdit( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float value, + float minimum /* = 0.0f */, + float step /* = 1.0f */, + float maximum /* = 0.0f */, + bool verifyNewValue /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingNumber> setting = std::make_shared<CSettingNumber>(id, label, value, minimum, step, maximum, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetEditControl("number", delayed, false, verifyNewValue, heading)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingString> CGUIDialogSettingsManualBase::AddEdit(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty /* = false */, + bool hidden /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> setting = std::make_shared<CSettingString>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetEditControl("string", delayed, hidden, false, heading)); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingString> CGUIDialogSettingsManualBase::AddIp(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> setting = std::make_shared<CSettingString>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetEditControl("ip", delayed, false, false, heading)); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingString> CGUIDialogSettingsManualBase::AddPasswordMd5( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> setting = std::make_shared<CSettingString>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetEditControl("md5", delayed, false, false, heading)); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingAction> CGUIDialogSettingsManualBase::AddButton( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& data /* = "" */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingAction> setting = std::make_shared<CSettingAction>(id, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetButtonControl("action", delayed)); + setting->SetData(data); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingString> CGUIDialogSettingsManualBase::AddInfoLabelButton( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& info, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> setting = std::make_shared<CSettingString>(id, label, info, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetButtonControl("infolabel", false)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingAddon> CGUIDialogSettingsManualBase::AddAddon( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + ADDON::AddonType addonType, + bool allowEmpty /* = false */, + int heading /* = -1 */, + bool hideValue /* = false */, + bool showInstalledAddons /* = true */, + bool showInstallableAddons /* = false */, + bool showMoreAddons /* = true */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingAddon> setting = std::make_shared<CSettingAddon>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetButtonControl("addon", delayed, heading, hideValue, showInstalledAddons, showInstallableAddons, showMoreAddons)); + setting->SetAddonType(addonType); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingPath> CGUIDialogSettingsManualBase::AddPath( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool writable /* = true */, + const std::vector<std::string>& sources /* = std::vector<std::string>() */, + bool allowEmpty /* = false */, + int heading /* = -1 */, + bool hideValue /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingPath> setting = std::make_shared<CSettingPath>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetButtonControl("path", delayed, heading, hideValue)); + setting->SetWritable(writable); + setting->SetSources(sources); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingDate> CGUIDialogSettingsManualBase::AddDate(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingDate> setting = std::make_shared<CSettingDate>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetButtonControl("date", delayed, heading)); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingTime> CGUIDialogSettingsManualBase::AddTime(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty /* = false */, + int heading /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingTime> setting = std::make_shared<CSettingTime>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetButtonControl("time", delayed, heading)); + setting->SetAllowEmpty(allowEmpty); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingString> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + StringSettingOptionsFiller filler, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || filler == NULL || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> setting = std::make_shared<CSettingString>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("string", delayed)); + setting->SetOptionsFiller(filler, this); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSpinner(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int minimum, + int step, + int maximum, + int formatLabel /* = -1 */, + int minimumLabel /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("string", delayed, minimumLabel, formatLabel)); + setting->SetMinimum(minimum); + setting->SetStep(step); + setting->SetMaximum(maximum); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int minimum, + int step, + int maximum, + const std::string& formatString, + int minimumLabel /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("string", delayed, minimumLabel, -1, formatString)); + setting->SetMinimum(minimum); + setting->SetStep(step); + setting->SetMaximum(maximum); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const TranslatableIntegerSettingOptions& entries, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || entries.empty() || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("string", delayed)); + setting->SetTranslatableOptions(entries); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const IntegerSettingOptions& entries, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || entries.empty() || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("string", delayed)); + setting->SetOptions(entries); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + IntegerSettingOptionsFiller filler, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || filler == NULL || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("string", delayed)); + setting->SetOptionsFiller(filler, this); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingNumber> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float value, + float minimum, + float step, + float maximum, + int formatLabel /* = -1 */, + int minimumLabel /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingNumber> setting = std::make_shared<CSettingNumber>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("number", delayed, minimumLabel, formatLabel)); + setting->SetMinimum(static_cast<double>(minimum)); + setting->SetStep(static_cast<double>(step)); + setting->SetMaximum(static_cast<double>(maximum)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingNumber> CGUIDialogSettingsManualBase::AddSpinner( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float value, + float minimum, + float step, + float maximum, + const std::string& formatString, + int minimumLabel /* = -1 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingNumber> setting = std::make_shared<CSettingNumber>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSpinnerControl("number", delayed, minimumLabel, -1, formatString)); + setting->SetMinimum(static_cast<double>(minimum)); + setting->SetStep(static_cast<double>(step)); + setting->SetMaximum(static_cast<double>(maximum)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingString> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + StringSettingOptionsFiller filler, + int heading, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || filler == NULL || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> setting = std::make_shared<CSettingString>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetListControl("string", false, heading, false, nullptr, details)); + setting->SetOptionsFiller(filler, this); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const TranslatableIntegerSettingOptions& entries, + int heading, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || entries.empty() || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetListControl("integer", false, heading, false, nullptr, details)); + setting->SetTranslatableOptions(entries); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const IntegerSettingOptions& entries, + int heading, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || entries.empty() || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetListControl("integer", false, heading, false, nullptr, details)); + setting->SetOptions(entries); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + IntegerSettingOptionsFiller filler, + int heading, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || filler == NULL || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetListControl("integer", false, heading, false, nullptr, details)); + setting->SetOptionsFiller(filler, this); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<std::string> values, + StringSettingOptionsFiller filler, + int heading, + int minimumItems /* = 0 */, + int maximumItems /* = -1 */, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || filler == NULL || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingString> settingDefinition = std::make_shared<CSettingString>(id, GetSettingsManager()); + if (settingDefinition == NULL) + return NULL; + + settingDefinition->SetOptionsFiller(filler, this); + + std::shared_ptr<CSettingList> setting = std::make_shared<CSettingList>(id, settingDefinition, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + std::vector<CVariant> valueList; + for (std::vector<std::string>::const_iterator itValue = values.begin(); itValue != values.end(); ++itValue) + valueList.emplace_back(*itValue); + SettingList settingValues; + if (!CSettingUtils::ValuesToList(setting, valueList, settingValues)) + return NULL; + // setting the default will also set the actual value on an unchanged setting + setting->SetDefault(settingValues); + + setting->SetControl(GetListControl("string", false, heading, true, nullptr, details)); + setting->SetMinimumItems(minimumItems); + setting->SetMaximumItems(maximumItems); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<int> values, + const TranslatableIntegerSettingOptions& entries, + int heading, + int minimumItems /* = 0 */, + int maximumItems /* = -1 */, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || entries.empty() || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> settingDefinition = std::make_shared<CSettingInt>(id, GetSettingsManager()); + if (settingDefinition == NULL) + return NULL; + + settingDefinition->SetTranslatableOptions(entries); + + std::shared_ptr<CSettingList> setting = std::make_shared<CSettingList>(id, settingDefinition, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + std::vector<CVariant> valueList; + for (std::vector<int>::const_iterator itValue = values.begin(); itValue != values.end(); ++itValue) + valueList.emplace_back(*itValue); + SettingList settingValues; + if (!CSettingUtils::ValuesToList(setting, valueList, settingValues)) + return NULL; + // setting the default will also set the actual value on an unchanged setting + setting->SetDefault(settingValues); + + setting->SetControl(GetListControl("integer", false, heading, true, nullptr, details)); + setting->SetMinimumItems(minimumItems); + setting->SetMaximumItems(maximumItems); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<int> values, + const IntegerSettingOptions& entries, + int heading, + int minimumItems /* = 0 */, + int maximumItems /* = -1 */, + bool visible /* = true */, + int help /* = -1 */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || entries.empty() || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> settingDefinition = std::make_shared<CSettingInt>(id, GetSettingsManager()); + if (settingDefinition == NULL) + return NULL; + + settingDefinition->SetOptions(entries); + + std::shared_ptr<CSettingList> setting = std::make_shared<CSettingList>(id, settingDefinition, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + std::vector<CVariant> valueList; + for (std::vector<int>::const_iterator itValue = values.begin(); itValue != values.end(); ++itValue) + valueList.emplace_back(*itValue); + SettingList settingValues; + if (!CSettingUtils::ValuesToList(setting, valueList, settingValues)) + return NULL; + // setting the default will also set the actual value on an unchanged setting + setting->SetDefault(settingValues); + + setting->SetControl(GetListControl("integer", false, heading, true, nullptr, details)); + setting->SetMinimumItems(minimumItems); + setting->SetMaximumItems(maximumItems); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddList( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<int> values, + IntegerSettingOptionsFiller filler, + int heading, + int minimumItems /* = 0 */, + int maximumItems /* = -1 */, + bool visible /* = true */, + int help /* = -1 */, + SettingControlListValueFormatter formatter /* = NULL */, + bool details /* = false */) +{ + if (group == NULL || id.empty() || label < 0 || filler == NULL || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> settingDefinition = std::make_shared<CSettingInt>(id, GetSettingsManager()); + if (settingDefinition == NULL) + return NULL; + + settingDefinition->SetOptionsFiller(filler, this); + + std::shared_ptr<CSettingList> setting = std::make_shared<CSettingList>(id, settingDefinition, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + std::vector<CVariant> valueList; + for (std::vector<int>::const_iterator itValue = values.begin(); itValue != values.end(); ++itValue) + valueList.emplace_back(*itValue); + SettingList settingValues; + if (!CSettingUtils::ValuesToList(setting, valueList, settingValues)) + return NULL; + // setting the default will also set the actual value on an unchanged setting + setting->SetDefault(settingValues); + + setting->SetControl(GetListControl("integer", false, heading, true, formatter, details)); + setting->SetMinimumItems(minimumItems); + setting->SetMaximumItems(maximumItems); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddPercentageSlider( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int formatLabel, + int step /* = 1 */, + int heading /* = -1 */, + bool usePopup /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSliderControl("percentage", delayed, heading, usePopup, formatLabel)); + setting->SetMinimum(0); + setting->SetStep(step); + setting->SetMaximum(100); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddPercentageSlider( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const std::string& formatString, + int step /* = 1 */, + int heading /* = -1 */, + bool usePopup /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSliderControl("percentage", delayed, heading, usePopup, -1, formatString)); + setting->SetMinimum(0); + setting->SetStep(step); + setting->SetMaximum(100); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSlider(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int formatLabel, + int minimum, + int step, + int maximum, + int heading /* = -1 */, + bool usePopup /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSliderControl("integer", delayed, heading, usePopup, formatLabel)); + setting->SetMinimum(minimum); + setting->SetStep(step); + setting->SetMaximum(maximum); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingInt> CGUIDialogSettingsManualBase::AddSlider( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const std::string& formatString, + int minimum, + int step, + int maximum, + int heading /* = -1 */, + bool usePopup /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> setting = std::make_shared<CSettingInt>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSliderControl("integer", delayed, heading, usePopup, -1, formatString)); + setting->SetMinimum(minimum); + setting->SetStep(step); + setting->SetMaximum(maximum); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingNumber> CGUIDialogSettingsManualBase::AddSlider( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float value, + int formatLabel, + float minimum, + float step, + float maximum, + int heading /* = -1 */, + bool usePopup /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingNumber> setting = std::make_shared<CSettingNumber>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSliderControl("number", delayed, heading, usePopup, formatLabel)); + setting->SetMinimum(static_cast<double>(minimum)); + setting->SetStep(static_cast<double>(step)); + setting->SetMaximum(static_cast<double>(maximum)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingNumber> CGUIDialogSettingsManualBase::AddSlider( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float value, + const std::string& formatString, + float minimum, + float step, + float maximum, + int heading /* = -1 */, + bool usePopup /* = false */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingNumber> setting = std::make_shared<CSettingNumber>(id, label, value, GetSettingsManager()); + if (setting == NULL) + return NULL; + + setting->SetControl(GetSliderControl("number", delayed, heading, usePopup, -1, formatString)); + setting->SetMinimum(static_cast<double>(minimum)); + setting->SetStep(static_cast<double>(step)); + setting->SetMaximum(static_cast<double>(maximum)); + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddPercentageRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int valueFormatLabel, + int step /* = 1 */, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, 0, step, 100, "percentage", formatLabel, valueFormatLabel, "", delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddPercentageRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + const std::string& valueFormatString /* = "{:d} %" */, + int step /* = 1 */, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, 0, step, 100, "percentage", formatLabel, -1, valueFormatString, delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddRange(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + int valueFormatLabel, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "integer", formatLabel, valueFormatLabel, "", delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& valueFormatString /* = "{:d}" */, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "integer", formatLabel, -1, valueFormatString, delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddRange(const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float valueLower, + float valueUpper, + float minimum, + float step, + float maximum, + int valueFormatLabel, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "number", formatLabel, valueFormatLabel, "", delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float valueLower, + float valueUpper, + float minimum, + float step, + float maximum, + const std::string& valueFormatString /* = "{:.1f}" */, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "number", formatLabel, -1, valueFormatString, delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddDateRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + int valueFormatLabel, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "date", formatLabel, valueFormatLabel, "", delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddDateRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& valueFormatString /* = "" */, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "date", formatLabel, -1, valueFormatString, delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddTimeRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + int valueFormatLabel, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "time", formatLabel, valueFormatLabel, "", delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddTimeRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& valueFormatString /* = "mm:ss" */, + int formatLabel /* = 21469 */, + bool delayed /* = false */, + bool visible /* = true */, + int help /* = -1 */) +{ + return AddRange(group, id, label, level, valueLower, valueUpper, minimum, step, maximum, "time", formatLabel, -1, valueFormatString, delayed, visible, help); +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& format, + int formatLabel, + int valueFormatLabel, + const std::string& valueFormatString, + bool delayed, + bool visible, + int help) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingInt> settingDefinition = std::make_shared<CSettingInt>(id, GetSettingsManager()); + if (settingDefinition == NULL) + return NULL; + + settingDefinition->SetMinimum(minimum); + settingDefinition->SetStep(step); + settingDefinition->SetMaximum(maximum); + + std::shared_ptr<CSettingList> setting = std::make_shared<CSettingList>(id, settingDefinition, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + std::vector<CVariant> valueList; + valueList.emplace_back(valueLower); + valueList.emplace_back(valueUpper); + SettingList settingValues; + if (!CSettingUtils::ValuesToList(setting, valueList, settingValues)) + return NULL; + // setting the default will also set the actual value on an unchanged setting + setting->SetDefault(settingValues); + + setting->SetControl(GetRangeControl(format, delayed, formatLabel, valueFormatLabel, valueFormatString)); + setting->SetMinimumItems(2); + setting->SetMaximumItems(2); + + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +std::shared_ptr<CSettingList> CGUIDialogSettingsManualBase::AddRange( + const SettingGroupPtr& group, + const std::string& id, + int label, + SettingLevel level, + float valueLower, + float valueUpper, + float minimum, + float step, + float maximum, + const std::string& format, + int formatLabel, + int valueFormatLabel, + const std::string& valueFormatString, + bool delayed, + bool visible, + int help) +{ + if (group == NULL || id.empty() || label < 0 || + GetSetting(id) != NULL) + return NULL; + + std::shared_ptr<CSettingNumber> settingDefinition = std::make_shared<CSettingNumber>(id, GetSettingsManager()); + if (settingDefinition == NULL) + return NULL; + + settingDefinition->SetMinimum(static_cast<double>(minimum)); + settingDefinition->SetStep(static_cast<double>(step)); + settingDefinition->SetMaximum(static_cast<double>(maximum)); + + std::shared_ptr<CSettingList> setting = std::make_shared<CSettingList>(id, settingDefinition, label, GetSettingsManager()); + if (setting == NULL) + return NULL; + + std::vector<CVariant> valueList; + valueList.emplace_back(valueLower); + valueList.emplace_back(valueUpper); + SettingList settingValues; + if (!CSettingUtils::ValuesToList(setting, valueList, settingValues)) + return NULL; + // setting the default will also set the actual value on an unchanged setting + setting->SetDefault(settingValues); + + setting->SetControl(GetRangeControl(format, delayed, formatLabel, valueFormatLabel, valueFormatString)); + setting->SetMinimumItems(2); + setting->SetMaximumItems(2); + + setSettingDetails(setting, level, visible, help); + + group->AddSetting(setting); + return setting; +} + +void CGUIDialogSettingsManualBase::setSettingDetails(const std::shared_ptr<CSetting>& setting, + SettingLevel level, + bool visible, + int help) +{ + if (setting == NULL) + return; + + if (level < SettingLevel::Basic) + level = SettingLevel::Basic; + else if (level > SettingLevel::Expert) + level = SettingLevel::Expert; + + setting->SetLevel(level); + setting->SetVisible(visible); + if (help >= 0) + setting->SetHelp(help); +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetCheckmarkControl(bool delayed /* = false */) +{ + std::shared_ptr<CSettingControlCheckmark> control = std::make_shared<CSettingControlCheckmark>(); + control->SetDelayed(delayed); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetTitleControl(bool separatorBelowLabel /* = true */, bool hideSeparator /* = false */) +{ + std::shared_ptr<CSettingControlTitle> control = std::make_shared<CSettingControlTitle>(); + control->SetSeparatorBelowLabel(separatorBelowLabel); + control->SetSeparatorHidden(hideSeparator); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetEditControl(const std::string &format, bool delayed /* = false */, bool hidden /* = false */, bool verifyNewValue /* = false */, int heading /* = -1 */) +{ + std::shared_ptr<CSettingControlEdit> control = std::make_shared<CSettingControlEdit>(); + if (!control->SetFormat(format)) + return NULL; + + control->SetDelayed(delayed); + control->SetHidden(hidden); + control->SetVerifyNewValue(verifyNewValue); + control->SetHeading(heading); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetButtonControl(const std::string &format, bool delayed /* = false */, int heading /* = -1 */, bool hideValue /* = false */, + bool showInstalledAddons /* = true */, bool showInstallableAddons /* = false */, bool showMoreAddons /* = true */) +{ + std::shared_ptr<CSettingControlButton> control = std::make_shared<CSettingControlButton>(); + if (!control->SetFormat(format)) + return NULL; + + control->SetDelayed(delayed); + control->SetHeading(heading); + control->SetHideValue(hideValue); + control->SetShowInstalledAddons(showInstalledAddons); + control->SetShowInstallableAddons(showInstallableAddons); + control->SetShowMoreAddons(showMoreAddons); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetSpinnerControl(const std::string &format, bool delayed /* = false */, int minimumLabel /* = -1 */, int formatLabel /* = -1 */, const std::string &formatString /* = "" */) +{ + std::shared_ptr<CSettingControlSpinner> control = std::make_shared<CSettingControlSpinner>(); + if (!control->SetFormat(format)) + return NULL; + + control->SetDelayed(delayed); + if (formatLabel >= 0) + control->SetFormatLabel(formatLabel); + if (!formatString.empty()) + control->SetFormatString(formatString); + if (minimumLabel >= 0) + control->SetMinimumLabel(minimumLabel); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetListControl( + const std::string& format, + bool delayed /* = false */, + int heading /* = -1 */, + bool multiselect /* = false */, + SettingControlListValueFormatter formatter /* = NULL */, + bool details /* = false */) +{ + std::shared_ptr<CSettingControlList> control = std::make_shared<CSettingControlList>(); + if (!control->SetFormat(format)) + return NULL; + + control->SetDelayed(delayed); + control->SetHeading(heading); + control->SetMultiSelect(multiselect); + control->SetFormatter(formatter); + control->SetUseDetails(details); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetSliderControl(const std::string &format, bool delayed /* = false */, int heading /* = -1 */, bool usePopup /* = false */, + int formatLabel /* = -1 */, const std::string &formatString /* = "" */) +{ + std::shared_ptr<CSettingControlSlider> control = std::make_shared<CSettingControlSlider>(); + if (!control->SetFormat(format)) + return NULL; + + control->SetDelayed(delayed); + if (heading >= 0) + control->SetHeading(heading); + control->SetPopup(usePopup); + if (formatLabel >= 0) + control->SetFormatLabel(formatLabel); + if (!formatString.empty()) + control->SetFormatString(formatString); + + return control; +} + +std::shared_ptr<ISettingControl> CGUIDialogSettingsManualBase::GetRangeControl(const std::string &format, bool delayed /* = false */, int formatLabel /* = -1 */, + int valueFormatLabel /* = -1 */, const std::string &valueFormatString /* = "" */) +{ + std::shared_ptr<CSettingControlRange> control = std::make_shared<CSettingControlRange>(); + if (!control->SetFormat(format)) + return NULL; + + control->SetDelayed(delayed); + if (formatLabel >= 0) + control->SetFormatLabel(formatLabel); + if (valueFormatLabel >= 0) + control->SetValueFormatLabel(valueFormatLabel); + if (!valueFormatString.empty()) + control->SetValueFormat(valueFormatString); + + return control; +} diff --git a/xbmc/settings/dialogs/GUIDialogSettingsManualBase.h b/xbmc/settings/dialogs/GUIDialogSettingsManualBase.h new file mode 100644 index 0000000..338259c --- /dev/null +++ b/xbmc/settings/dialogs/GUIDialogSettingsManualBase.h @@ -0,0 +1,650 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "addons/IAddon.h" +#include "settings/dialogs/GUIDialogSettingsManagerBase.h" +#include "settings/lib/SettingDefinitions.h" +#include "settings/lib/SettingLevel.h" + +#include <map> +#include <memory> +#include <string> +#include <vector> + +class CSetting; +class CSettingAction; +class CSettingAddon; +class CSettingBool; +class CSettingCategory; +class CSettingDate; +class CSettingGroup; +class CSettingInt; +class CSettingList; +class CSettingNumber; +class CSettingPath; +class CSettingSection; +class CSettingString; +class CSettingsManager; +class CSettingTime; + +class CGUIDialogSettingsManualBase : public CGUIDialogSettingsManagerBase +{ +public: + CGUIDialogSettingsManualBase(int windowId, const std::string &xmlFile); + ~CGUIDialogSettingsManualBase() override; + +protected: + // implementation of CGUIDialogSettingsBase + std::shared_ptr<CSettingSection> GetSection() override { return m_section; } + void SetupView() override; + + // implementation of CGUIDialogSettingsManagerBase + CSettingsManager* GetSettingsManager() const override; + + virtual void InitializeSettings(); + + std::shared_ptr<CSettingCategory> AddCategory(const std::string &id, int label, int help = -1); + std::shared_ptr<CSettingGroup> AddGroup(const std::shared_ptr<CSettingCategory>& category, + int label = -1, + int help = -1, + bool separatorBelowLabel = true, + bool hideSeparator = false); + // checkmark control + std::shared_ptr<CSettingBool> AddToggle(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + bool value, + bool delayed = false, + bool visible = true, + int help = -1); + // edit controls + std::shared_ptr<CSettingInt> AddEdit(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int minimum = 0, + int step = 1, + int maximum = 0, + bool verifyNewValue = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingNumber> AddEdit(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float value, + float minimum = 0.0f, + float step = 1.0f, + float maximum = 0.0f, + bool verifyNewValue = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingString> AddEdit(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty = false, + bool hidden = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingString> AddIp(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingString> AddPasswordMd5(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + // button controls + std::shared_ptr<CSettingAction> AddButton(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& data = "", + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingString> AddInfoLabelButton(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& info, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingAddon> AddAddon(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + ADDON::AddonType addonType, + bool allowEmpty = false, + int heading = -1, + bool hideValue = false, + bool showInstalledAddons = true, + bool showInstallableAddons = false, + bool showMoreAddons = true, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingPath> AddPath( + const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool writable = true, + const std::vector<std::string>& sources = std::vector<std::string>(), + bool allowEmpty = false, + int heading = -1, + bool hideValue = false, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingDate> AddDate(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingTime> AddTime(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + bool allowEmpty = false, + int heading = -1, + bool delayed = false, + bool visible = true, + int help = -1); + + // spinner controls + std::shared_ptr<CSettingString> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + StringSettingOptionsFiller filler, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int minimum, + int step, + int maximum, + int formatLabel = -1, + int minimumLabel = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int minimum, + int step, + int maximum, + const std::string& formatString, + int minimumLabel = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const TranslatableIntegerSettingOptions& entries, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const IntegerSettingOptions& entries, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + IntegerSettingOptionsFiller filler, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingNumber> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float value, + float minimum, + float step, + float maximum, + int formatLabel = -1, + int minimumLabel = -1, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingNumber> AddSpinner(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float value, + float minimum, + float step, + float maximum, + const std::string& formatString, + int minimumLabel = -1, + bool delayed = false, + bool visible = true, + int help = -1); + + // list controls + std::shared_ptr<CSettingString> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + const std::string& value, + StringSettingOptionsFiller filler, + int heading, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingInt> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const TranslatableIntegerSettingOptions& entries, + int heading, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingInt> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const IntegerSettingOptions& entries, + int heading, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingInt> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + IntegerSettingOptionsFiller filler, + int heading, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingList> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<std::string> values, + StringSettingOptionsFiller filler, + int heading, + int minimumItems = 0, + int maximumItems = -1, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingList> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<int> values, + const TranslatableIntegerSettingOptions& entries, + int heading, + int minimumItems = 0, + int maximumItems = -1, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingList> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<int> values, + const IntegerSettingOptions& entries, + int heading, + int minimumItems = 0, + int maximumItems = -1, + bool visible = true, + int help = -1, + bool details = false); + std::shared_ptr<CSettingList> AddList(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + std::vector<int> values, + IntegerSettingOptionsFiller filler, + int heading, + int minimumItems = 0, + int maximumItems = -1, + bool visible = true, + int help = -1, + SettingControlListValueFormatter formatter = nullptr, + bool details = false); + + // slider controls + std::shared_ptr<CSettingInt> AddPercentageSlider(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int formatLabel, + int step = 1, + int heading = -1, + bool usePopup = false, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddPercentageSlider(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const std::string& formatString, + int step = 1, + int heading = -1, + bool usePopup = false, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSlider(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + int formatLabel, + int minimum, + int step, + int maximum, + int heading = -1, + bool usePopup = false, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingInt> AddSlider(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int value, + const std::string& formatString, + int minimum, + int step, + int maximum, + int heading = -1, + bool usePopup = false, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingNumber> AddSlider(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float value, + int formatLabel, + float minimum, + float step, + float maximum, + int heading = -1, + bool usePopup = false, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingNumber> AddSlider(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float value, + const std::string& formatString, + float minimum, + float step, + float maximum, + int heading = -1, + bool usePopup = false, + bool delayed = false, + bool visible = true, + int help = -1); + + // range controls + std::shared_ptr<CSettingList> AddPercentageRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int valueFormatLabel, + int step = 1, + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddPercentageRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + const std::string& valueFormatString = "{:d} %", + int step = 1, + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + int valueFormatLabel, + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& valueFormatString = "{:d}", + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float valueLower, + float valueUpper, + float minimum, + float step, + float maximum, + int valueFormatLabel, + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float valueLower, + float valueUpper, + float minimum, + float step, + float maximum, + const std::string& valueFormatString = "{:.1f}", + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddDateRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + int valueFormatLabel, + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddDateRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& valueFormatString = "", + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddTimeRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + int valueFormatLabel, + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + std::shared_ptr<CSettingList> AddTimeRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& valueFormatString = "mm:ss", + int formatLabel = 21469, + bool delayed = false, + bool visible = true, + int help = -1); + + std::shared_ptr<ISettingControl> GetTitleControl(bool separatorBelowLabel = true, bool hideSeparator = false); + std::shared_ptr<ISettingControl> GetCheckmarkControl(bool delayed = false); + std::shared_ptr<ISettingControl> GetEditControl(const std::string &format, bool delayed = false, bool hidden = false, bool verifyNewValue = false, int heading = -1); + std::shared_ptr<ISettingControl> GetButtonControl(const std::string &format, bool delayed = false, int heading = -1, bool hideValue = false, bool showInstalledAddons = true, + bool showInstallableAddons = false, bool showMoreAddons = true); + std::shared_ptr<ISettingControl> GetSpinnerControl(const std::string &format, bool delayed = false, int minimumLabel = -1, int formatLabel = -1, const std::string &formatString = ""); + std::shared_ptr<ISettingControl> GetListControl( + const std::string& format, + bool delayed = false, + int heading = -1, + bool multiselect = false, + SettingControlListValueFormatter formatter = nullptr, + bool details = false); + std::shared_ptr<ISettingControl> GetSliderControl(const std::string &format, bool delayed = false, int heading = -1, bool usePopup = false, int formatLabel = -1, const std::string &formatString = ""); + std::shared_ptr<ISettingControl> GetRangeControl(const std::string &format, bool delayed = false, int formatLabel = -1, int valueFormatLabel = -1, const std::string &valueFormatString = ""); + +private: + std::shared_ptr<CSettingList> AddRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + int valueLower, + int valueUpper, + int minimum, + int step, + int maximum, + const std::string& format, + int formatLabel, + int valueFormatLabel, + const std::string& valueFormatString, + bool delayed, + bool visible, + int help); + std::shared_ptr<CSettingList> AddRange(const std::shared_ptr<CSettingGroup>& group, + const std::string& id, + int label, + SettingLevel level, + float valueLower, + float valueUpper, + float minimum, + float step, + float maximum, + const std::string& format, + int formatLabel, + int valueFormatLabel, + const std::string& valueFormatString, + bool delayed, + bool visible, + int help); + + void setSettingDetails(const std::shared_ptr<CSetting>& setting, + SettingLevel level, + bool visible, + int help); + + mutable CSettingsManager *m_settingsManager; + std::shared_ptr<CSettingSection> m_section; +}; |