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.
9 #include "GUIDialogContentSettings.h"
11 #include "ServiceBroker.h"
12 #include "addons/AddonManager.h"
13 #include "addons/AddonSystemSettings.h"
14 #include "addons/gui/GUIDialogAddonSettings.h"
15 #include "addons/gui/GUIWindowAddonBrowser.h"
16 #include "dialogs/GUIDialogKaiToast.h"
17 #include "dialogs/GUIDialogSelect.h"
18 #include "filesystem/AddonsDirectory.h"
19 #include "guilib/GUIComponent.h"
20 #include "guilib/GUIWindowManager.h"
21 #include "guilib/LocalizeStrings.h"
22 #include "settings/lib/Setting.h"
23 #include "settings/lib/SettingsManager.h"
24 #include "settings/windows/GUIControlSettings.h"
25 #include "utils/log.h"
26 #include "video/VideoInfoScanner.h"
35 #define SETTING_CONTENT_TYPE "contenttype"
36 #define SETTING_SCRAPER_LIST "scraperlist"
37 #define SETTING_SCRAPER_SETTINGS "scrapersettings"
38 #define SETTING_SCAN_RECURSIVE "scanrecursive"
39 #define SETTING_USE_DIRECTORY_NAMES "usedirectorynames"
40 #define SETTING_CONTAINS_SINGLE_ITEM "containssingleitem"
41 #define SETTING_EXCLUDE "exclude"
42 #define SETTING_NO_UPDATING "noupdating"
43 #define SETTING_ALL_EXTERNAL_AUDIO "allexternalaudio"
45 using namespace ADDON
;
48 CGUIDialogContentSettings::CGUIDialogContentSettings()
49 : CGUIDialogSettingsManualBase(WINDOW_DIALOG_CONTENT_SETTINGS
, "DialogSettings.xml")
52 void CGUIDialogContentSettings::SetContent(CONTENT_TYPE content
)
54 m_content
= m_originalContent
= content
;
57 void CGUIDialogContentSettings::ResetContent()
59 SetContent(CONTENT_NONE
);
62 void CGUIDialogContentSettings::SetScanSettings(const VIDEO::SScanSettings
&scanSettings
)
64 m_scanRecursive
= (scanSettings
.recurse
> 0 && !scanSettings
.parent_name
) ||
65 (scanSettings
.recurse
> 1 && scanSettings
.parent_name
);
66 m_useDirectoryNames
= scanSettings
.parent_name
;
67 m_exclude
= scanSettings
.exclude
;
68 m_containsSingleItem
= scanSettings
.parent_name_root
;
69 m_noUpdating
= scanSettings
.noupdate
;
70 m_allExternalAudio
= scanSettings
.m_allExtAudio
;
73 bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr
& scraper
, CONTENT_TYPE content
/* = CONTENT_NONE */)
75 VIDEO::SScanSettings dummy
;
76 return Show(scraper
, dummy
, content
);
79 bool CGUIDialogContentSettings::Show(ADDON::ScraperPtr
& scraper
, VIDEO::SScanSettings
& settings
, CONTENT_TYPE content
/* = CONTENT_NONE */)
81 CGUIDialogContentSettings
*dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogContentSettings
>(WINDOW_DIALOG_CONTENT_SETTINGS
);
87 dialog
->SetContent(content
!= CONTENT_NONE
? content
: scraper
->Content());
88 dialog
->SetScraper(scraper
);
89 // toast selected but disabled scrapers
90 if (CServiceBroker::GetAddonMgr().IsAddonDisabled(scraper
->ID()))
91 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error
, g_localizeStrings
.Get(24024), scraper
->Name(), 2000, true);
94 dialog
->SetScanSettings(settings
);
97 bool confirmed
= dialog
->IsConfirmed();
100 scraper
= dialog
->GetScraper();
101 content
= dialog
->GetContent();
103 settings
.m_allExtAudio
= dialog
->GetUseAllExternalAudio();
105 if (scraper
== NULL
|| content
== CONTENT_NONE
)
106 settings
.exclude
= dialog
->GetExclude();
109 settings
.exclude
= false;
110 settings
.noupdate
= dialog
->GetNoUpdating();
111 scraper
->SetPathSettings(content
, "");
113 if (content
== CONTENT_TVSHOWS
)
115 settings
.parent_name
= settings
.parent_name_root
= dialog
->GetContainsSingleItem();
116 settings
.recurse
= 0;
118 else if (content
== CONTENT_MOVIES
|| content
== CONTENT_MUSICVIDEOS
)
120 if (dialog
->GetUseDirectoryNames())
122 settings
.parent_name
= true;
123 settings
.parent_name_root
= false;
124 settings
.recurse
= dialog
->GetScanRecursive() ? INT_MAX
: 1;
126 if (dialog
->GetContainsSingleItem())
128 settings
.parent_name_root
= true;
129 settings
.recurse
= 0;
134 settings
.parent_name
= false;
135 settings
.parent_name_root
= false;
136 settings
.recurse
= dialog
->GetScanRecursive() ? INT_MAX
: 0;
142 // now that we have evaluated all settings we need to reset the content
143 dialog
->ResetContent();
148 void CGUIDialogContentSettings::OnInitWindow()
150 CGUIDialogSettingsManualBase::OnInitWindow();
153 void CGUIDialogContentSettings::OnSettingChanged(const std::shared_ptr
<const CSetting
>& setting
)
158 CGUIDialogSettingsManualBase::OnSettingChanged(setting
);
160 const std::string
&settingId
= setting
->GetId();
161 if (settingId
== SETTING_CONTAINS_SINGLE_ITEM
)
162 m_containsSingleItem
= std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue();
163 else if (settingId
== SETTING_NO_UPDATING
)
164 m_noUpdating
= std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue();
165 else if (settingId
== SETTING_USE_DIRECTORY_NAMES
)
166 m_useDirectoryNames
= std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue();
167 else if (settingId
== SETTING_SCAN_RECURSIVE
)
169 m_scanRecursive
= std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue();
170 GetSettingsManager()->SetBool(SETTING_CONTAINS_SINGLE_ITEM
, false);
172 else if (settingId
== SETTING_EXCLUDE
)
173 m_exclude
= std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue();
174 else if (settingId
== SETTING_ALL_EXTERNAL_AUDIO
)
175 m_allExternalAudio
= std::static_pointer_cast
<const CSettingBool
>(setting
)->GetValue();
178 void CGUIDialogContentSettings::OnSettingAction(const std::shared_ptr
<const CSetting
>& setting
)
183 CGUIDialogSettingsManualBase::OnSettingAction(setting
);
185 const std::string
&settingId
= setting
->GetId();
187 if (settingId
== SETTING_CONTENT_TYPE
)
189 std::vector
<std::pair
<std::string
, int>> labels
;
190 if (m_content
== CONTENT_ALBUMS
|| m_content
== CONTENT_ARTISTS
)
192 labels
.emplace_back(ADDON::TranslateContent(m_content
, true), m_content
);
196 labels
.emplace_back(ADDON::TranslateContent(CONTENT_NONE
, true), CONTENT_NONE
);
197 labels
.emplace_back(ADDON::TranslateContent(CONTENT_MOVIES
, true), CONTENT_MOVIES
);
198 labels
.emplace_back(ADDON::TranslateContent(CONTENT_TVSHOWS
, true), CONTENT_TVSHOWS
);
199 labels
.emplace_back(ADDON::TranslateContent(CONTENT_MUSICVIDEOS
, true), CONTENT_MUSICVIDEOS
);
201 std::sort(labels
.begin(), labels
.end());
203 CGUIDialogSelect
*dialog
= CServiceBroker::GetGUI()->GetWindowManager().GetWindow
<CGUIDialogSelect
>(WINDOW_DIALOG_SELECT
);
206 dialog
->SetHeading(CVariant
{ 20344 }); //Label "This directory contains"
210 for (const auto &label
: labels
)
212 dialog
->Add(label
.first
);
214 if (m_content
== label
.second
)
219 dialog
->SetSelected(iSelected
);
222 // Selected item has not changes - in case of cancel or the user selecting the same item
223 int newSelected
= dialog
->GetSelectedItem();
224 if (!dialog
->IsConfirmed() || newSelected
< 0 || newSelected
== iSelected
)
227 auto selected
= labels
.at(newSelected
);
228 m_content
= static_cast<CONTENT_TYPE
>(selected
.second
);
230 AddonPtr scraperAddon
;
231 if (!CAddonSystemSettings::GetInstance().GetActive(ADDON::ScraperTypeFromContent(m_content
), scraperAddon
) && m_content
!= CONTENT_NONE
)
234 m_scraper
= std::dynamic_pointer_cast
<CScraper
>(scraperAddon
);
237 SetFocusToSetting(SETTING_CONTENT_TYPE
);
240 else if (settingId
== SETTING_SCRAPER_LIST
)
242 ADDON::AddonType type
= ADDON::ScraperTypeFromContent(m_content
);
243 std::string currentScraperId
;
244 if (m_scraper
!= nullptr)
245 currentScraperId
= m_scraper
->ID();
246 std::string selectedAddonId
= currentScraperId
;
248 if (CGUIWindowAddonBrowser::SelectAddonID(type
, selectedAddonId
, false) == 1
249 && selectedAddonId
!= currentScraperId
)
251 AddonPtr scraperAddon
;
252 if (CServiceBroker::GetAddonMgr().GetAddon(selectedAddonId
, scraperAddon
,
253 ADDON::OnlyEnabled::CHOICE_YES
))
255 m_scraper
= std::dynamic_pointer_cast
<CScraper
>(scraperAddon
);
257 SetFocusToSetting(SETTING_SCRAPER_LIST
);
261 CLog::Log(LOGERROR
, "{} - Could not get settings for addon: {}", __FUNCTION__
,
266 else if (settingId
== SETTING_SCRAPER_SETTINGS
)
267 CGUIDialogAddonSettings::ShowForAddon(m_scraper
, false);
270 bool CGUIDialogContentSettings::Save()
272 //Should be saved by caller of ::Show
276 void CGUIDialogContentSettings::SetupView()
278 CGUIDialogSettingsManualBase::SetupView();
281 SET_CONTROL_HIDDEN(CONTROL_SETTINGS_CUSTOM_BUTTON
);
282 SET_CONTROL_LABEL(CONTROL_SETTINGS_OKAY_BUTTON
, 186);
283 SET_CONTROL_LABEL(CONTROL_SETTINGS_CANCEL_BUTTON
, 222);
285 SetLabel2(SETTING_CONTENT_TYPE
, ADDON::TranslateContent(m_content
, true));
287 if (m_content
== CONTENT_NONE
)
289 ToggleState(SETTING_SCRAPER_LIST
, false);
290 ToggleState(SETTING_SCRAPER_SETTINGS
, false);
294 ToggleState(SETTING_SCRAPER_LIST
, true);
295 if (m_scraper
!= NULL
&& !CServiceBroker::GetAddonMgr().IsAddonDisabled(m_scraper
->ID()))
297 SetLabel2(SETTING_SCRAPER_LIST
, m_scraper
->Name());
298 if (m_scraper
&& m_scraper
->Supports(m_content
) && m_scraper
->HasSettings())
299 ToggleState(SETTING_SCRAPER_SETTINGS
, true);
301 ToggleState(SETTING_SCRAPER_SETTINGS
, false);
305 SetLabel2(SETTING_SCRAPER_LIST
, g_localizeStrings
.Get(231)); //Set label2 to "None"
306 ToggleState(SETTING_SCRAPER_SETTINGS
, false);
311 void CGUIDialogContentSettings::InitializeSettings()
313 CGUIDialogSettingsManualBase::InitializeSettings();
315 if (m_content
== CONTENT_NONE
)
316 m_showScanSettings
= false;
317 else if (m_scraper
!= NULL
&& !CServiceBroker::GetAddonMgr().IsAddonDisabled(m_scraper
->ID()))
318 m_showScanSettings
= true;
320 std::shared_ptr
<CSettingCategory
> category
= AddCategory("contentsettings", -1);
321 if (category
== NULL
)
323 CLog::Log(LOGERROR
, "CGUIDialogContentSettings: unable to setup settings");
327 std::shared_ptr
<CSettingGroup
> group
= AddGroup(category
);
330 CLog::Log(LOGERROR
, "CGUIDialogContentSettings: unable to setup settings");
334 AddButton(group
, SETTING_CONTENT_TYPE
, 20344, SettingLevel::Basic
);
335 AddButton(group
, SETTING_SCRAPER_LIST
, 38025, SettingLevel::Basic
);
336 std::shared_ptr
<CSettingAction
> subsetting
= AddButton(group
, SETTING_SCRAPER_SETTINGS
, 10004, SettingLevel::Basic
);
337 if (subsetting
!= NULL
)
338 subsetting
->SetParent(SETTING_SCRAPER_LIST
);
340 std::shared_ptr
<CSettingGroup
> groupDetails
= AddGroup(category
, 20322);
341 if (groupDetails
== NULL
)
343 CLog::Log(LOGERROR
, "CGUIDialogContentSettings: unable to setup scanning settings");
348 case CONTENT_TVSHOWS
:
350 AddToggle(groupDetails
, SETTING_CONTAINS_SINGLE_ITEM
, 20379, SettingLevel::Basic
, m_containsSingleItem
, false, m_showScanSettings
);
351 AddToggle(groupDetails
, SETTING_NO_UPDATING
, 20432, SettingLevel::Basic
, m_noUpdating
, false, m_showScanSettings
);
352 AddToggle(groupDetails
, SETTING_ALL_EXTERNAL_AUDIO
, 39120, SettingLevel::Basic
,
353 m_allExternalAudio
, false, m_showScanSettings
);
358 case CONTENT_MUSICVIDEOS
:
360 AddToggle(groupDetails
, SETTING_USE_DIRECTORY_NAMES
, m_content
== CONTENT_MOVIES
? 20329 : 20330, SettingLevel::Basic
, m_useDirectoryNames
, false, m_showScanSettings
);
361 std::shared_ptr
<CSettingBool
> settingScanRecursive
= AddToggle(groupDetails
, SETTING_SCAN_RECURSIVE
, 20346, SettingLevel::Basic
, m_scanRecursive
, false, m_showScanSettings
);
362 std::shared_ptr
<CSettingBool
> settingContainsSingleItem
= AddToggle(groupDetails
, SETTING_CONTAINS_SINGLE_ITEM
, 20383, SettingLevel::Basic
, m_containsSingleItem
, false, m_showScanSettings
);
363 AddToggle(groupDetails
, SETTING_NO_UPDATING
, 20432, SettingLevel::Basic
, m_noUpdating
, false, m_showScanSettings
);
364 AddToggle(groupDetails
, SETTING_ALL_EXTERNAL_AUDIO
, 39120, SettingLevel::Basic
,
365 m_allExternalAudio
, false, m_showScanSettings
);
367 // define an enable dependency with (m_useDirectoryNames && !m_containsSingleItem) || !m_useDirectoryNames
368 CSettingDependency
dependencyScanRecursive(SettingDependencyType::Enable
, GetSettingsManager());
369 dependencyScanRecursive
.Or()
370 ->Add(CSettingDependencyConditionCombinationPtr(
371 (new CSettingDependencyConditionCombination(
372 BooleanLogicOperationAnd
,
373 GetSettingsManager())) // m_useDirectoryNames && !m_containsSingleItem
374 ->Add(std::make_shared
<CSettingDependencyCondition
>(
375 SETTING_USE_DIRECTORY_NAMES
, "true", SettingDependencyOperator::Equals
, false,
376 GetSettingsManager())) // m_useDirectoryNames
377 ->Add(std::make_shared
<CSettingDependencyCondition
>(
378 SETTING_CONTAINS_SINGLE_ITEM
, "false", SettingDependencyOperator::Equals
,
379 false, GetSettingsManager())))) // !m_containsSingleItem
380 ->Add(std::make_shared
<CSettingDependencyCondition
>(
381 SETTING_USE_DIRECTORY_NAMES
, "false", SettingDependencyOperator::Equals
, false,
382 GetSettingsManager())); // !m_useDirectoryNames
384 // define an enable dependency with m_useDirectoryNames && !m_scanRecursive
385 CSettingDependency
dependencyContainsSingleItem(SettingDependencyType::Enable
, GetSettingsManager());
386 dependencyContainsSingleItem
.And()
387 ->Add(std::make_shared
<CSettingDependencyCondition
>(
388 SETTING_USE_DIRECTORY_NAMES
, "true", SettingDependencyOperator::Equals
, false,
389 GetSettingsManager())) // m_useDirectoryNames
390 ->Add(std::make_shared
<CSettingDependencyCondition
>(
391 SETTING_SCAN_RECURSIVE
, "false", SettingDependencyOperator::Equals
, false,
392 GetSettingsManager())); // !m_scanRecursive
394 SettingDependencies deps
;
395 deps
.push_back(dependencyScanRecursive
);
396 settingScanRecursive
->SetDependencies(deps
);
399 deps
.push_back(dependencyContainsSingleItem
);
400 settingContainsSingleItem
->SetDependencies(deps
);
405 case CONTENT_ARTISTS
:
410 AddToggle(groupDetails
, SETTING_EXCLUDE
, 20380, SettingLevel::Basic
, m_exclude
, false, !m_showScanSettings
);
411 AddToggle(groupDetails
, SETTING_ALL_EXTERNAL_AUDIO
, 39120, SettingLevel::Basic
,
412 m_allExternalAudio
, false, !m_showScanSettings
);
417 void CGUIDialogContentSettings::SetLabel2(const std::string
&settingid
, const std::string
&label
)
419 BaseSettingControlPtr settingControl
= GetSettingControl(settingid
);
420 if (settingControl
!= NULL
&& settingControl
->GetControl() != NULL
)
421 SET_CONTROL_LABEL2(settingControl
->GetID(), label
);
424 void CGUIDialogContentSettings::ToggleState(const std::string
&settingid
, bool enabled
)
426 BaseSettingControlPtr settingControl
= GetSettingControl(settingid
);
427 if (settingControl
!= NULL
&& settingControl
->GetControl() != NULL
)
430 CONTROL_ENABLE(settingControl
->GetID());
432 CONTROL_DISABLE(settingControl
->GetID());
436 void CGUIDialogContentSettings::SetFocusToSetting(const std::string
& settingid
)
438 BaseSettingControlPtr settingControl
= GetSettingControl(settingid
);
439 if (settingControl
!= NULL
&& settingControl
->GetControl() != NULL
)
440 SET_CONTROL_FOCUS(settingControl
->GetID(), 0);