[Windows] Fix driver version detection of AMD RDNA+ GPU on Windows 10
[xbmc.git] / xbmc / addons / gui / GUIDialogAddonSettings.cpp
blob60cbaa2a2ea29b6291362a065460c8bcf6af76b8
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "GUIDialogAddonSettings.h"
11 #include "FileItem.h"
12 #include "FileItemList.h"
13 #include "GUIPassword.h"
14 #include "GUIUserMessages.h"
15 #include "ServiceBroker.h"
16 #include "addons/AddonManager.h"
17 #include "addons/addoninfo/AddonType.h"
18 #include "addons/settings/AddonSettings.h"
19 #include "dialogs/GUIDialogSelect.h"
20 #include "dialogs/GUIDialogYesNo.h"
21 #include "guilib/GUIComponent.h"
22 #include "guilib/GUIWindowManager.h"
23 #include "guilib/LocalizeStrings.h"
24 #include "guilib/WindowIDs.h"
25 #include "input/actions/Action.h"
26 #include "input/actions/ActionIDs.h"
27 #include "messaging/helpers/DialogOKHelper.h"
28 #include "settings/Settings.h"
29 #include "settings/SettingsComponent.h"
30 #include "settings/lib/SettingSection.h"
31 #include "settings/lib/SettingsManager.h"
32 #include "utils/StringUtils.h"
33 #include "utils/Variant.h"
34 #include "utils/log.h"
35 #include "view/ViewStateSettings.h"
37 #define CONTROL_BTN_LEVELS 20
39 using namespace ADDON;
40 using namespace KODI::MESSAGING;
42 CGUIDialogAddonSettings::CGUIDialogAddonSettings()
43 : CGUIDialogSettingsManagerBase(WINDOW_DIALOG_ADDON_SETTINGS, "DialogAddonSettings.xml")
47 bool CGUIDialogAddonSettings::OnMessage(CGUIMessage& message)
49 switch (message.GetMessage())
51 case GUI_MSG_CLICKED:
53 if (message.GetSenderId() == CONTROL_SETTINGS_CUSTOM_BUTTON)
55 OnResetSettings();
56 return true;
58 break;
61 case GUI_MSG_SETTING_UPDATED:
63 const std::string& settingId = message.GetStringParam(0);
64 const std::string& settingValue = message.GetStringParam(1);
65 const ADDON::AddonInstanceId instanceId = message.GetParam1();
67 if (instanceId != m_instanceId)
69 CLog::Log(LOGERROR,
70 "CGUIDialogAddonSettings::{}: Set value \"{}\" from add-on \"{}\" called with "
71 "invalid instance id (given: {}, needed: {})",
72 __func__, m_addon->ID(), settingId, instanceId, m_instanceId);
73 break;
76 std::shared_ptr<CSetting> setting = GetSettingsManager()->GetSetting(settingId);
77 if (setting != nullptr)
79 setting->FromString(settingValue);
80 return true;
82 break;
85 default:
86 break;
89 return CGUIDialogSettingsManagerBase::OnMessage(message);
92 bool CGUIDialogAddonSettings::OnAction(const CAction& action)
94 switch (action.GetID())
96 case ACTION_SETTINGS_LEVEL_CHANGE:
98 // Test if we can access the new level
99 if (!g_passwordManager.CheckSettingLevelLock(
100 CViewStateSettings::GetInstance().GetNextSettingLevel(), true))
101 return false;
103 CViewStateSettings::GetInstance().CycleSettingLevel();
104 CServiceBroker::GetSettingsComponent()->GetSettings()->Save();
106 // try to keep the current position
107 std::string oldCategory;
108 if (m_iCategory >= 0 && m_iCategory < static_cast<int>(m_categories.size()))
109 oldCategory = m_categories[m_iCategory]->GetId();
111 SET_CONTROL_LABEL(CONTROL_BTN_LEVELS,
112 10036 +
113 static_cast<int>(CViewStateSettings::GetInstance().GetSettingLevel()));
114 // only re-create the categories, the settings will be created later
115 SetupControls(false);
117 m_iCategory = 0;
118 // try to find the category that was previously selected
119 if (!oldCategory.empty())
121 for (int i = 0; i < static_cast<int>(m_categories.size()); i++)
123 if (m_categories[i]->GetId() == oldCategory)
125 m_iCategory = i;
126 break;
131 CreateSettings();
132 return true;
135 default:
136 break;
139 return CGUIDialogSettingsManagerBase::OnAction(action);
142 bool CGUIDialogAddonSettings::ShowForAddon(const ADDON::AddonPtr& addon,
143 bool saveToDisk /* = true */)
145 if (!addon)
147 CLog::LogF(LOGERROR, "No addon given!");
148 return false;
151 if (addon->Type() == ADDON::AddonType::GAME_CONTROLLER)
153 CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_DIALOG_GAME_CONTROLLERS,
154 addon->ID());
155 return true;
158 if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
159 return false;
161 if (addon->SupportsInstanceSettings())
162 return ShowForMultipleInstances(addon, saveToDisk);
163 else
164 return ShowForSingleInstance(addon, saveToDisk);
167 bool CGUIDialogAddonSettings::ShowForSingleInstance(
168 const ADDON::AddonPtr& addon,
169 bool saveToDisk,
170 ADDON::AddonInstanceId instanceId /* = ADDON::ADDON_SETTINGS_ID */)
172 if (!addon->HasSettings(instanceId))
174 // addon does not support settings, inform user
175 HELPERS::ShowOKDialogText(CVariant{24000}, CVariant{24030});
176 return false;
179 // Create the dialog
180 CGUIDialogAddonSettings* dialog =
181 CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogAddonSettings>(
182 WINDOW_DIALOG_ADDON_SETTINGS);
183 if (!dialog)
185 CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_ADDON_SETTINGS instance!");
186 return false;
189 dialog->m_addon = addon;
190 dialog->m_instanceId = instanceId;
191 dialog->m_saveToDisk = saveToDisk;
193 dialog->Open();
195 if (!dialog->IsConfirmed())
197 addon->ReloadSettings(instanceId);
198 return false;
201 if (saveToDisk)
202 addon->SaveSettings(instanceId);
204 return true;
207 bool CGUIDialogAddonSettings::ShowForMultipleInstances(const ADDON::AddonPtr& addon,
208 bool saveToDisk)
210 CGUIDialogSelect* dialog =
211 CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogSelect>(
212 WINDOW_DIALOG_SELECT);
213 if (!dialog)
215 CLog::LogF(LOGERROR, "Unable to get WINDOW_DIALOG_SELECT instance!");
216 return false;
219 int lastSelected = -1;
220 while (true)
222 std::vector<ADDON::AddonInstanceId> ids = addon->GetKnownInstanceIds();
223 std::sort(ids.begin(), ids.end(), [](const auto& a, const auto& b) { return a < b; });
225 dialog->Reset();
226 dialog->SetHeading(10012); // Add-on configurations and settings
227 dialog->SetUseDetails(false);
229 CFileItemList itemsInstances;
230 ADDON::AddonInstanceId highestId = 0;
231 for (const auto& id : ids)
233 std::string name;
234 addon->GetSettingString(ADDON_SETTING_INSTANCE_NAME_VALUE, name, id);
235 if (name.empty())
236 name = g_localizeStrings.Get(13205); // Unknown
238 bool enabled = false;
239 addon->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, enabled, id);
241 const std::string label = StringUtils::Format(
242 g_localizeStrings.Get(10020), name,
243 g_localizeStrings.Get(enabled ? 305 : 13106)); // Edit "config name" [enabled state]
245 const CFileItemPtr item = std::make_shared<CFileItem>(label);
246 item->SetProperty("id", id);
247 item->SetProperty("name", name);
248 itemsInstances.Add(item);
250 if (id > highestId)
251 highestId = id;
254 CFileItemList itemsGeneral;
256 const ADDON::AddonInstanceId addInstanceId = highestId + 1;
257 const ADDON::AddonInstanceId removeInstanceId = highestId + 2;
259 CFileItemPtr item =
260 std::make_shared<CFileItem>(g_localizeStrings.Get(10014)); // Add add-on configuration
261 item->SetProperty("id", addInstanceId);
262 itemsGeneral.Add(item);
264 if (ids.size() > 1) // Forbid removal of last instance
266 item =
267 std::make_shared<CFileItem>(g_localizeStrings.Get(10015)); // Remove add-on configuration
268 item->SetProperty("id", removeInstanceId);
269 itemsGeneral.Add(item);
272 if (addon->HasSettings(ADDON_SETTINGS_ID))
274 item = std::make_shared<CFileItem>(g_localizeStrings.Get(10013)); // Edit Add-on settings
275 item->SetProperty("id", ADDON_SETTINGS_ID);
276 itemsGeneral.Add(item);
279 for (auto& it : itemsGeneral)
280 dialog->Add(*it);
282 for (auto& it : itemsInstances)
283 dialog->Add(*it);
285 // Select last selected item, first instance config item or first item
286 if (lastSelected >= 0)
287 dialog->SetSelected(lastSelected);
288 else
289 dialog->SetSelected(itemsInstances.Size() > 0 ? itemsGeneral.Size() : 0);
291 dialog->Open();
293 if (dialog->IsButtonPressed() || !dialog->IsConfirmed())
294 break;
296 lastSelected = dialog->GetSelectedItem();
298 item = dialog->GetSelectedFileItem();
299 ADDON::AddonInstanceId instanceId = item->GetProperty("id").asInteger();
301 if (instanceId == addInstanceId)
303 instanceId = highestId + 1;
305 addon->GetSettings(instanceId);
306 addon->UpdateSettingString(ADDON_SETTING_INSTANCE_NAME_VALUE, "", instanceId);
307 addon->UpdateSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, true, instanceId);
308 addon->SaveSettings(instanceId);
310 if (ShowForSingleInstance(addon, saveToDisk, instanceId))
312 CServiceBroker::GetAddonMgr().PublishInstanceAdded(addon->ID(), instanceId);
314 else
316 // Remove instance settings if not succeeded (e.g. dialog cancelled)
317 addon->DeleteInstanceSettings(instanceId);
320 else if (instanceId == removeInstanceId)
322 dialog->Reset();
323 dialog->SetHeading(10010); // Select add-on configuration to remove
324 dialog->SetUseDetails(false);
326 for (auto& it : itemsInstances)
328 CFileItem item(*it);
329 item.SetLabel((*it).GetProperty("name").asString());
330 dialog->Add(item);
333 dialog->SetSelected(0);
334 dialog->Open();
336 if (!dialog->IsButtonPressed() && dialog->IsConfirmed())
338 item = dialog->GetSelectedFileItem();
339 const std::string label = StringUtils::Format(
340 g_localizeStrings.Get(10019),
341 item->GetProperty("name")
342 .asString()); // Do you want to remove the add-on configuration "config name"?
344 if (CGUIDialogYesNo::ShowAndGetInput(10009, // Confirm add-on configuration removal
345 label))
347 instanceId = item->GetProperty("id").asInteger();
348 addon->DeleteInstanceSettings(instanceId);
349 CServiceBroker::GetAddonMgr().PublishInstanceRemoved(addon->ID(), instanceId);
353 else
355 // edit instance settings or edit addon settings selected; open settings dialog
357 bool enabled = false;
358 addon->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, enabled, instanceId);
360 if (ShowForSingleInstance(addon, saveToDisk, instanceId) && instanceId != ADDON_SETTINGS_ID)
362 // Publish new/removed instance configuration and start the use of new instance
363 bool enabledNow = false;
364 addon->GetSettingBool(ADDON_SETTING_INSTANCE_ENABLED_VALUE, enabledNow, instanceId);
365 if (enabled != enabledNow)
367 if (enabledNow)
368 CServiceBroker::GetAddonMgr().PublishInstanceAdded(addon->ID(), instanceId);
369 else
370 CServiceBroker::GetAddonMgr().PublishInstanceRemoved(addon->ID(), instanceId);
375 // refresh selection dialog content...
377 } // while (true)
379 return true;
382 void CGUIDialogAddonSettings::SaveAndClose()
384 if (!g_passwordManager.CheckMenuLock(WINDOW_ADDON_BROWSER))
385 return;
387 // get the dialog
388 CGUIDialogAddonSettings* dialog =
389 CServiceBroker::GetGUI()->GetWindowManager().GetWindow<CGUIDialogAddonSettings>(
390 WINDOW_DIALOG_ADDON_SETTINGS);
391 if (dialog == nullptr || !dialog->IsActive())
392 return;
394 // check if we need to save the settings
395 if (dialog->m_saveToDisk && dialog->m_addon != nullptr)
396 dialog->m_addon->SaveSettings(dialog->m_instanceId);
398 // close the dialog
399 dialog->Close();
402 std::string CGUIDialogAddonSettings::GetCurrentAddonID() const
404 if (m_addon == nullptr)
405 return "";
407 return m_addon->ID();
410 void CGUIDialogAddonSettings::SetupView()
412 if (m_addon == nullptr || m_addon->GetSettings(m_instanceId) == nullptr)
413 return;
415 auto settings = m_addon->GetSettings(m_instanceId);
416 if (!settings->IsLoaded())
417 return;
419 CGUIDialogSettingsManagerBase::SetupView();
421 // set addon id as window property
422 SetProperty("Addon.ID", m_addon->ID());
424 // set heading
425 SetHeading(StringUtils::Format("$LOCALIZE[10004] - {}",
426 m_addon->Name())); // "Settings - AddonName"
428 // set control labels
429 SET_CONTROL_LABEL(CONTROL_SETTINGS_OKAY_BUTTON, 186);
430 SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON, 222);
431 SET_CONTROL_LABEL(CONTROL_SETTINGS_CUSTOM_BUTTON, 409);
432 SET_CONTROL_LABEL(CONTROL_BTN_LEVELS,
433 10036 + static_cast<int>(CViewStateSettings::GetInstance().GetSettingLevel()));
436 std::string CGUIDialogAddonSettings::GetLocalizedString(uint32_t labelId) const
438 std::string label = g_localizeStrings.GetAddonString(m_addon->ID(), labelId);
439 if (!label.empty())
440 return label;
442 return CGUIDialogSettingsManagerBase::GetLocalizedString(labelId);
445 std::string CGUIDialogAddonSettings::GetSettingsLabel(const std::shared_ptr<ISetting>& setting)
447 if (setting == nullptr)
448 return "";
450 std::string label = GetLocalizedString(setting->GetLabel());
451 if (!label.empty())
452 return label;
454 // try the addon settings
455 label = m_addon->GetSettings(m_instanceId)->GetSettingLabel(setting->GetLabel());
456 if (!label.empty())
457 return label;
459 return CGUIDialogSettingsManagerBase::GetSettingsLabel(setting);
462 int CGUIDialogAddonSettings::GetSettingLevel() const
464 return static_cast<int>(CViewStateSettings::GetInstance().GetSettingLevel());
467 std::shared_ptr<CSettingSection> CGUIDialogAddonSettings::GetSection()
469 const auto settingsManager = GetSettingsManager();
470 if (settingsManager == nullptr)
471 return nullptr;
473 const auto sections = settingsManager->GetSections();
474 if (!sections.empty())
475 return sections.front();
477 return nullptr;
480 CSettingsManager* CGUIDialogAddonSettings::GetSettingsManager() const
482 if (m_addon == nullptr || m_addon->GetSettings(m_instanceId) == nullptr)
483 return nullptr;
485 return m_addon->GetSettings(m_instanceId)->GetSettingsManager();
488 void CGUIDialogAddonSettings::OnSettingAction(const std::shared_ptr<const CSetting>& setting)
490 if (m_addon == nullptr || m_addon->GetSettings(m_instanceId) == nullptr)
491 return;
493 m_addon->GetSettings(m_instanceId)->OnSettingAction(setting);