summaryrefslogtreecommitdiffstats
path: root/xbmc/settings/dialogs
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/settings/dialogs')
-rw-r--r--xbmc/settings/dialogs/CMakeLists.txt13
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.cpp428
-rw-r--r--xbmc/settings/dialogs/GUIDialogContentSettings.h91
-rw-r--r--xbmc/settings/dialogs/GUIDialogLibExportSettings.cpp452
-rw-r--r--xbmc/settings/dialogs/GUIDialogLibExportSettings.h60
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsBase.cpp972
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsBase.h189
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsManagerBase.cpp64
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsManagerBase.h34
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsManualBase.cpp1617
-rw-r--r--xbmc/settings/dialogs/GUIDialogSettingsManualBase.h650
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;
+};