summaryrefslogtreecommitdiffstats
path: root/xbmc/addons/gui/GUIDialogAddonSettings.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /xbmc/addons/gui/GUIDialogAddonSettings.cpp
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/addons/gui/GUIDialogAddonSettings.cpp')
-rw-r--r--xbmc/addons/gui/GUIDialogAddonSettings.cpp484
1 files changed, 484 insertions, 0 deletions
diff --git a/xbmc/addons/gui/GUIDialogAddonSettings.cpp b/xbmc/addons/gui/GUIDialogAddonSettings.cpp
new file mode 100644
index 0000000..bc794d4
--- /dev/null
+++ b/xbmc/addons/gui/GUIDialogAddonSettings.cpp
@@ -0,0 +1,484 @@
+/*
+ * 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 "GUIDialogAddonSettings.h"
+
+#include "FileItem.h"
+#include "GUIPassword.h"
+#include "GUIUserMessages.h"
+#include "ServiceBroker.h"
+#include "addons/AddonManager.h"
+#include "addons/settings/AddonSettings.h"
+#include "dialogs/GUIDialogSelect.h"
+#include "dialogs/GUIDialogYesNo.h"
+#include "guilib/GUIComponent.h"
+#include "guilib/GUIWindowManager.h"
+#include "guilib/LocalizeStrings.h"
+#include "guilib/WindowIDs.h"
+#include "input/Key.h"
+#include "messaging/helpers/DialogOKHelper.h"
+#include "settings/Settings.h"
+#include "settings/SettingsComponent.h"
+#include "settings/lib/SettingSection.h"
+#include "settings/lib/SettingsManager.h"
+#include "utils/StringUtils.h"
+#include "utils/Variant.h"
+#include "utils/log.h"
+#include "view/ViewStateSettings.h"
+
+#define CONTROL_BTN_LEVELS 20
+
+using namespace ADDON;
+using namespace KODI::MESSAGING;
+
+CGUIDialogAddonSettings::CGUIDialogAddonSettings()
+ : CGUIDialogSettingsManagerBase(WINDOW_DIALOG_ADDON_SETTINGS, "DialogAddonSettings.xml")
+{
+}
+
+bool CGUIDialogAddonSettings::OnMessage(CGUIMessage& message)
+{
+ switch (message.GetMessage())
+ {
+ case GUI_MSG_CLICKED:
+ {
+ if (message.GetSenderId() == CONTROL_SETTINGS_CUSTOM_BUTTON)
+ {
+ OnResetSettings();
+ return true;
+ }
+ break;
+ }
+
+ case GUI_MSG_SETTING_UPDATED:
+ {
+ const std::string& settingId = message.GetStringParam(0);
+ const std::string& settingValue = message.GetStringParam(1);
+ const ADDON::AddonInstanceId instanceId = message.GetParam1();
+
+ if (instanceId != m_instanceId)
+ {
+ CLog::Log(LOGERROR,
+ "CGUIDialogAddonSettings::{}: Set value \"{}\" from add-on \"{}\" called with "
+ "invalid instance id (given: {}, needed: {})",
+ __func__, m_addon->ID(), settingId, instanceId, m_instanceId);
+ break;
+ }
+
+ std::shared_ptr<CSetting> setting = GetSettingsManager()->GetSetting(settingId);
+ if (setting != nullptr)
+ {
+ setting->FromString(settingValue);
+ return true;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return CGUIDialogSettingsManagerBase::OnMessage(message);
+}
+
+bool CGUIDialogAddonSettings::OnAction(const CAction& action)
+{
+ switch (action.GetID())
+ {
+ case ACTION_SETTINGS_LEVEL_CHANGE:
+ {
+ // Test if we can access the new level
+ if (!g_passwordManager.CheckSettingLevelLock(
+ CViewStateSettings::GetInstance().GetNextSettingLevel(), true))
+ return false;
+
+ CViewStateSettings::GetInstance().CycleSettingLevel();
+ CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
+
+ // try to keep the current position
+ std::string oldCategory;
+ if (m_iCategory >= 0 && m_iCategory < static_cast<int>(m_categories.size()))
+ oldCategory = m_categories[m_iCategory]->GetId();
+
+ SET_CONTROL_LABEL(CONTROL_BTN_LEVELS,
+ 10036 +
+ static_cast<int>(CViewStateSettings::GetInstance().GetSettingLevel()));
+ // only re-create the categories, the settings will be created later
+ SetupControls(false);
+
+ m_iCategory = 0;
+ // try to find the category that was previously selected
+ if (!oldCategory.empty())
+ {
+ for (int i = 0; i < static_cast<int>(m_categories.size()); i++)
+ {
+ if (m_categories[i]->GetId() == oldCategory)
+ {
+ m_iCategory = i;
+ break;
+ }
+ }
+ }
+
+ CreateSettings();
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ return CGUIDialogSettingsManagerBase::OnAction(action);
+}
+
+bool CGUIDialogAddonSettings::ShowForAddon(const ADDON::AddonPtr& addon,
+ bool saveToDisk /* = true */)
+{
+ if (!addon)
+ {
+ CLog::LogF(LOGERROR, "No addon given!");
+ return false;
+ }
+
+ if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
+ return false;
+
+ if (addon->SupportsInstanceSettings())
+ return ShowForMultipleInstances(addon, saveToDisk);
+ else
+ return ShowForSingleInstance(addon, saveToDisk);
+}
+
+bool CGUIDialogAddonSettings::ShowForSingleInstance(
+ const ADDON::AddonPtr& addon,
+ bool saveToDisk,
+ ADDON::AddonInstanceId instanceId /* = ADDON::ADDON_SETTINGS_ID */)
+{
+ if (!addon->HasSettings(instanceId))
+ {
+ // addon does not support settings, inform user
+ HELPERS::ShowOKDialogText(CVariant{24000}, CVariant{24030});
+ return false;
+ }
+
+ // Create the dialog
+ CGUIDialogAddonSettings* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogAddonSettings>(
+ WINDOW_DIALOG_ADDON_SETTINGS);
+ if (!dialog)
+ {
+ CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_ADDON_SETTINGS instance!");
+ return false;
+ }
+
+ dialog->m_addon = addon;
+ dialog->m_instanceId = instanceId;
+ dialog->m_saveToDisk = saveToDisk;
+
+ dialog->Open();
+
+ if (!dialog->IsConfirmed())
+ {
+ addon->ReloadSettings(instanceId);
+ return false;
+ }
+
+ if (saveToDisk)
+ addon->SaveSettings(instanceId);
+
+ return true;
+}
+
+bool CGUIDialogAddonSettings::ShowForMultipleInstances(const ADDON::AddonPtr& addon,
+ bool saveToDisk)
+{
+ CGUIDialogSelect* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(
+ WINDOW_DIALOG_SELECT);
+ if (!dialog)
+ {
+ CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_SELECT instance!");
+ return false;
+ }
+
+ int lastSelected = -1;
+ while (true)
+ {
+ std::vector<ADDON::AddonInstanceId> ids = addon->GetKnownInstanceIds();
+ std::sort(ids.begin(), ids.end(), [](const auto& a, const auto& b) { return a < b; });
+
+ dialog->Reset();
+ dialog->SetHeading(10012); // Add-on configurations and settings
+ dialog->SetUseDetails(false);
+
+ CFileItemList itemsInstances;
+ ADDON::AddonInstanceId highestId = 0;
+ for (const auto& id : ids)
+ {
+ std::string name;
+ addon->GetSettingString(ADDON_SETTING_INSTANCE_NAME_VALUE, name, id);
+ if (name.empty())
+ name = g_localizeStrings.Get(13205); // Unknown
+
+ bool enabled = false;
+ addon->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, enabled, id);
+
+ const std::string label = StringUtils::Format(
+ g_localizeStrings.Get(10020), name,
+ g_localizeStrings.Get(enabled ? 305 : 13106)); // Edit "config name" [enabled state]
+
+ const CFileItemPtr item = std::make_shared<CFileItem>(label);
+ item->SetProperty("id", id);
+ item->SetProperty("name", name);
+ itemsInstances.Add(item);
+
+ if (id > highestId)
+ highestId = id;
+ }
+
+ CFileItemList itemsGeneral;
+
+ const ADDON::AddonInstanceId addInstanceId = highestId + 1;
+ const ADDON::AddonInstanceId removeInstanceId = highestId + 2;
+
+ CFileItemPtr item =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(10014)); // Add add-on configuration
+ item->SetProperty("id", addInstanceId);
+ itemsGeneral.Add(item);
+
+ if (ids.size() > 1) // Forbid removal of last instance
+ {
+ item =
+ std::make_shared<CFileItem>(g_localizeStrings.Get(10015)); // Remove add-on configuration
+ item->SetProperty("id", removeInstanceId);
+ itemsGeneral.Add(item);
+ }
+
+ if (addon->HasSettings(ADDON_SETTINGS_ID))
+ {
+ item = std::make_shared<CFileItem>(g_localizeStrings.Get(10013)); // Edit Add-on settings
+ item->SetProperty("id", ADDON_SETTINGS_ID);
+ itemsGeneral.Add(item);
+ }
+
+ for (auto& it : itemsGeneral)
+ dialog->Add(*it);
+
+ for (auto& it : itemsInstances)
+ dialog->Add(*it);
+
+ // Select last selected item, first instance config item or first item
+ if (lastSelected >= 0)
+ dialog->SetSelected(lastSelected);
+ else
+ dialog->SetSelected(itemsInstances.Size() > 0 ? itemsGeneral.Size() : 0);
+
+ dialog->Open();
+
+ if (dialog->IsButtonPressed() || !dialog->IsConfirmed())
+ break;
+
+ lastSelected = dialog->GetSelectedItem();
+
+ item = dialog->GetSelectedFileItem();
+ ADDON::AddonInstanceId instanceId = item->GetProperty("id").asInteger();
+
+ if (instanceId == addInstanceId)
+ {
+ instanceId = highestId + 1;
+
+ addon->GetSettings(instanceId);
+ addon->UpdateSettingString(ADDON_SETTING_INSTANCE_NAME_VALUE, "", instanceId);
+ addon->UpdateSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, true, instanceId);
+ addon->SaveSettings(instanceId);
+
+ if (ShowForSingleInstance(addon, saveToDisk, instanceId))
+ {
+ CServiceBroker::GetAddonMgr().PublishInstanceAdded(addon->ID(), instanceId);
+ }
+ else
+ {
+ // Remove instance settings if not succeeded (e.g. dialog cancelled)
+ addon->DeleteInstanceSettings(instanceId);
+ }
+ }
+ else if (instanceId == removeInstanceId)
+ {
+ dialog->Reset();
+ dialog->SetHeading(10010); // Select add-on configuration to remove
+ dialog->SetUseDetails(false);
+
+ for (auto& it : itemsInstances)
+ {
+ CFileItem item(*it);
+ item.SetLabel((*it).GetProperty("name").asString());
+ dialog->Add(item);
+ }
+
+ dialog->SetSelected(0);
+ dialog->Open();
+
+ if (!dialog->IsButtonPressed() && dialog->IsConfirmed())
+ {
+ item = dialog->GetSelectedFileItem();
+ const std::string label = StringUtils::Format(
+ g_localizeStrings.Get(10019),
+ item->GetProperty("name")
+ .asString()); // Do you want to remove the add-on configuration "config name"?
+
+ if (CGUIDialogYesNo::ShowAndGetInput(10009, // Confirm add-on configuration removal
+ label))
+ {
+ instanceId = item->GetProperty("id").asInteger();
+ addon->DeleteInstanceSettings(instanceId);
+ CServiceBroker::GetAddonMgr().PublishInstanceRemoved(addon->ID(), instanceId);
+ }
+ }
+ }
+ else
+ {
+ // edit instance settings or edit addon settings selected; open settings dialog
+
+ bool enabled = false;
+ addon->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, enabled, instanceId);
+
+ if (ShowForSingleInstance(addon, saveToDisk, instanceId) && instanceId != ADDON_SETTINGS_ID)
+ {
+ // Publish new/removed instance configuration and start the use of new instance
+ bool enabledNow = false;
+ addon->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, enabledNow, instanceId);
+ if (enabled != enabledNow)
+ {
+ if (enabledNow)
+ CServiceBroker::GetAddonMgr().PublishInstanceAdded(addon->ID(), instanceId);
+ else
+ CServiceBroker::GetAddonMgr().PublishInstanceRemoved(addon->ID(), instanceId);
+ }
+ }
+ }
+
+ // refresh selection dialog content...
+
+ } // while (true)
+
+ return true;
+}
+
+void CGUIDialogAddonSettings::SaveAndClose()
+{
+ if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
+ return;
+
+ // get the dialog
+ CGUIDialogAddonSettings* dialog =
+ CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogAddonSettings>(
+ WINDOW_DIALOG_ADDON_SETTINGS);
+ if (dialog == nullptr || !dialog->IsActive())
+ return;
+
+ // check if we need to save the settings
+ if (dialog->m_saveToDisk && dialog->m_addon != nullptr)
+ dialog->m_addon->SaveSettings(dialog->m_instanceId);
+
+ // close the dialog
+ dialog->Close();
+}
+
+std::string CGUIDialogAddonSettings::GetCurrentAddonID() const
+{
+ if (m_addon == nullptr)
+ return "";
+
+ return m_addon->ID();
+}
+
+void CGUIDialogAddonSettings::SetupView()
+{
+ if (m_addon == nullptr || m_addon->GetSettings(m_instanceId) == nullptr)
+ return;
+
+ auto settings = m_addon->GetSettings(m_instanceId);
+ if (!settings->IsLoaded())
+ return;
+
+ CGUIDialogSettingsManagerBase::SetupView();
+
+ // set addon id as window property
+ SetProperty("Addon.ID", m_addon->ID());
+
+ // set heading
+ SetHeading(StringUtils::Format("$LOCALIZE[10004] - {}",
+ m_addon->Name())); // "Settings - AddonName"
+
+ // set control labels
+ SET_CONTROL_LABEL(CONTROL_SETTINGS_OKAY_BUTTON, 186);
+ SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON, 222);
+ SET_CONTROL_LABEL(CONTROL_SETTINGS_CUSTOM_BUTTON, 409);
+ SET_CONTROL_LABEL(CONTROL_BTN_LEVELS,
+ 10036 + static_cast<int>(CViewStateSettings::GetInstance().GetSettingLevel()));
+}
+
+std::string CGUIDialogAddonSettings::GetLocalizedString(uint32_t labelId) const
+{
+ std::string label = g_localizeStrings.GetAddonString(m_addon->ID(), labelId);
+ if (!label.empty())
+ return label;
+
+ return CGUIDialogSettingsManagerBase::GetLocalizedString(labelId);
+}
+
+std::string CGUIDialogAddonSettings::GetSettingsLabel(const std::shared_ptr<ISetting>& setting)
+{
+ if (setting == nullptr)
+ return "";
+
+ std::string label = GetLocalizedString(setting->GetLabel());
+ if (!label.empty())
+ return label;
+
+ // try the addon settings
+ label = m_addon->GetSettings(m_instanceId)->GetSettingLabel(setting->GetLabel());
+ if (!label.empty())
+ return label;
+
+ return CGUIDialogSettingsManagerBase::GetSettingsLabel(setting);
+}
+
+int CGUIDialogAddonSettings::GetSettingLevel() const
+{
+ return static_cast<int>(CViewStateSettings::GetInstance().GetSettingLevel());
+}
+
+std::shared_ptr<CSettingSection> CGUIDialogAddonSettings::GetSection()
+{
+ const auto settingsManager = GetSettingsManager();
+ if (settingsManager == nullptr)
+ return nullptr;
+
+ const auto sections = settingsManager->GetSections();
+ if (!sections.empty())
+ return sections.front();
+
+ return nullptr;
+}
+
+CSettingsManager* CGUIDialogAddonSettings::GetSettingsManager() const
+{
+ if (m_addon == nullptr || m_addon->GetSettings(m_instanceId) == nullptr)
+ return nullptr;
+
+ return m_addon->GetSettings(m_instanceId)->GetSettingsManager();
+}
+
+void CGUIDialogAddonSettings::OnSettingAction(const std::shared_ptr<const CSetting>& setting)
+{
+ if (m_addon == nullptr || m_addon->GetSettings(m_instanceId) == nullptr)
+ return;
+
+ m_addon->GetSettings(m_instanceId)->OnSettingAction(setting);
+}